|
|
|
@ -1,13 +1,30 @@ |
|
|
|
|
package com.gyf.csams |
|
|
|
|
|
|
|
|
|
import io.ktor.application.* |
|
|
|
|
import io.ktor.http.content.* |
|
|
|
|
import org.jetbrains.exposed.sql.deleteWhere |
|
|
|
|
import org.jetbrains.exposed.sql.transactions.transaction |
|
|
|
|
import org.slf4j.LoggerFactory |
|
|
|
|
import org.slf4j.Logger |
|
|
|
|
import java.io.File |
|
|
|
|
import java.time.ZoneOffset |
|
|
|
|
import kotlin.properties.Delegates |
|
|
|
|
|
|
|
|
|
interface BaseService{ |
|
|
|
|
fun init(environment:ApplicationEnvironment) |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
abstract class AbstractService:BaseService{ |
|
|
|
|
protected lateinit var log:Logger |
|
|
|
|
override fun init(environment: ApplicationEnvironment) { |
|
|
|
|
this.log=environment.log |
|
|
|
|
} |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
object AccountService { |
|
|
|
|
private val logger = LoggerFactory.getLogger(AccountService::class.java) |
|
|
|
|
/** |
|
|
|
|
* 账号服务 |
|
|
|
|
*/ |
|
|
|
|
object AccountService:AbstractService() { |
|
|
|
|
/** |
|
|
|
|
* 检查学号是否已注册,true=已注册 |
|
|
|
|
*/ |
|
|
|
@ -23,16 +40,16 @@ object AccountService { |
|
|
|
|
fun register(userVo: UserVo): UserResDto? { |
|
|
|
|
try { |
|
|
|
|
return transaction { |
|
|
|
|
val _pwd = randomNum(8) |
|
|
|
|
val originPassword = randomNum(8) |
|
|
|
|
User.new { |
|
|
|
|
studentId=userVo.studentId |
|
|
|
|
name=userVo.name |
|
|
|
|
password=_pwd.md5() |
|
|
|
|
password=originPassword.md5() |
|
|
|
|
} |
|
|
|
|
return@transaction UserResDto(password=_pwd) |
|
|
|
|
return@transaction UserResDto(password=originPassword) |
|
|
|
|
} |
|
|
|
|
} catch (e: Exception) { |
|
|
|
|
logger.error("注册失败,发生异常:$e") |
|
|
|
|
log.error("注册失败,发生异常:$e") |
|
|
|
|
return null |
|
|
|
|
} |
|
|
|
|
} |
|
|
|
@ -44,35 +61,35 @@ object AccountService { |
|
|
|
|
*/ |
|
|
|
|
fun login(userLoginVo: UserLoginVo,_ip:String):Token?{ |
|
|
|
|
return transaction { |
|
|
|
|
val user=User.find { Users.studentId eq userLoginVo.studentId }.firstOrNull() |
|
|
|
|
val matchUser=User.find { Users.studentId eq userLoginVo.studentId }.firstOrNull() |
|
|
|
|
|
|
|
|
|
when { |
|
|
|
|
user==null -> { |
|
|
|
|
logger.warn("学号:${userLoginVo.studentId}不存在") |
|
|
|
|
matchUser==null -> { |
|
|
|
|
log.warn("学号:${userLoginVo.studentId}不存在") |
|
|
|
|
return@transaction null |
|
|
|
|
} |
|
|
|
|
userLoginVo.password.md5() != user.password -> { |
|
|
|
|
logger.warn("密码:${userLoginVo.password}错误") |
|
|
|
|
userLoginVo.password.md5() != matchUser.password -> { |
|
|
|
|
log.warn("密码:${userLoginVo.password}错误") |
|
|
|
|
return@transaction null |
|
|
|
|
} |
|
|
|
|
else -> { |
|
|
|
|
val token=UserToken.new{ |
|
|
|
|
studentId=userLoginVo.studentId |
|
|
|
|
user=matchUser |
|
|
|
|
ip=_ip |
|
|
|
|
device=userLoginVo.device |
|
|
|
|
token=listOf(studentId,ip,device).joinToString(separator = ('a' .. 'z').random().toString()).md5() |
|
|
|
|
token=listOf(matchUser.id,ip,device).joinToString(separator = ('a' .. 'z').random().toString()).md5() |
|
|
|
|
} |
|
|
|
|
token.flush() |
|
|
|
|
return@transaction Token(studentId = userLoginVo.studentId,token = token.token, |
|
|
|
|
return@transaction Token(userId = matchUser.id.value,token = token.token, |
|
|
|
|
createTime = token.createTime.toEpochSecond( |
|
|
|
|
ZoneOffset.of("+8")),name=user.name) |
|
|
|
|
ZoneOffset.of("+8"))) |
|
|
|
|
} |
|
|
|
|
} |
|
|
|
|
} |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
fun validToken(token: Token):Boolean{ |
|
|
|
|
return validToken(TokenVo(token = token.token,studentId = token.studentId)) |
|
|
|
|
return validToken(TokenVo(token = token.token,userId = token.userId)) |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
/** |
|
|
|
@ -84,37 +101,40 @@ object AccountService { |
|
|
|
|
fun validToken(tokenVo: TokenVo):Boolean{ |
|
|
|
|
return transaction { |
|
|
|
|
!UserToken.find { |
|
|
|
|
UserTokens.studentId eq tokenVo.studentId |
|
|
|
|
UserTokens.userId eq tokenVo.userId |
|
|
|
|
UserTokens.token eq tokenVo.token |
|
|
|
|
}.empty() |
|
|
|
|
} |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
fun logout(studentId:String):Boolean{ |
|
|
|
|
fun logout(userId:Int):Boolean{ |
|
|
|
|
return transaction { |
|
|
|
|
UserTokens.deleteWhere { UserTokens.studentId eq studentId }>0 |
|
|
|
|
UserTokens.deleteWhere { UserTokens.userId eq userId }>0 |
|
|
|
|
} |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
fun test(){ |
|
|
|
|
logger.info("开始测试") |
|
|
|
|
log.info("开始测试") |
|
|
|
|
transaction { |
|
|
|
|
logger.info("查询到个${User.count()}用户") |
|
|
|
|
log.info("查询到个${User.count()}用户") |
|
|
|
|
} |
|
|
|
|
logger.info("结束测试") |
|
|
|
|
log.info("结束测试") |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
object MainService{ |
|
|
|
|
private val logger = LoggerFactory.getLogger(MainService::class.java) |
|
|
|
|
|
|
|
|
|
var maxSize:Int=20 |
|
|
|
|
/** |
|
|
|
|
* 主页服务 |
|
|
|
|
*/ |
|
|
|
|
object MainService:AbstractService(){ |
|
|
|
|
private var maxSize by Delegates.notNull<Int>() |
|
|
|
|
|
|
|
|
|
fun register(maxSize:Int){ |
|
|
|
|
this.maxSize=maxSize |
|
|
|
|
override fun init(environment:ApplicationEnvironment){ |
|
|
|
|
super.init(environment) |
|
|
|
|
this.maxSize=environment.config.property("ktor.deployment.leaveMessage.maxSize").getString().toInt() |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
/** |
|
|
|
|
* 创建留言信息 |
|
|
|
|
* |
|
|
|
@ -125,32 +145,219 @@ object MainService{ |
|
|
|
|
return if(leaveMessageVo.message.isNotEmpty()){ |
|
|
|
|
return transaction { |
|
|
|
|
val count=LeaveMessage.count().toInt() |
|
|
|
|
logger.info("系统留言数:$count,限制数:$maxSize") |
|
|
|
|
log.info("系统留言数:$count,限制数:$maxSize") |
|
|
|
|
if(count>= maxSize){ |
|
|
|
|
LeaveMessage.all().sortedBy { it.createTime }.subList(0, count-maxSize).forEach { |
|
|
|
|
it.delete() |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
} |
|
|
|
|
logger.info("保存留言:${leaveMessageVo.message}") |
|
|
|
|
log.info("保存留言:${leaveMessageVo.message}") |
|
|
|
|
LeaveMessage.new { |
|
|
|
|
studentId = leaveMessageVo.token.studentId |
|
|
|
|
user= User.findById(leaveMessageVo.token.userId)?:throw IllegalArgumentException("非法id") |
|
|
|
|
message = leaveMessageVo.message |
|
|
|
|
} |
|
|
|
|
logger.info("留言保存成功") |
|
|
|
|
log.info("留言保存成功") |
|
|
|
|
return@transaction true |
|
|
|
|
} |
|
|
|
|
}else{ |
|
|
|
|
logger.info("留言不能为空") |
|
|
|
|
log.info("留言不能为空") |
|
|
|
|
false |
|
|
|
|
} |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
fun getAllLeaveMessage():List<LeaveMessageFormatVo>{ |
|
|
|
|
fun getAllLeaveMessage():List<LeaveMessageDto>{ |
|
|
|
|
return transaction { |
|
|
|
|
logger.info("获取所有留言") |
|
|
|
|
log.info("获取所有留言") |
|
|
|
|
|
|
|
|
|
return@transaction LeaveMessage.all().toList().map { |
|
|
|
|
LeaveMessageFormatVo(message = "${User.find { Users.studentId eq it.studentId }.first().name}说:${it.message}",studentId = it.studentId) |
|
|
|
|
LeaveMessageDto( |
|
|
|
|
message = "${it.user.name}说:${it.message}", |
|
|
|
|
user = UserVo(studentId = it.user.studentId, name = it.user.name) |
|
|
|
|
) |
|
|
|
|
} |
|
|
|
|
} |
|
|
|
|
} |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
/** |
|
|
|
|
* 文件管理服务 |
|
|
|
|
*/ |
|
|
|
|
object FileService:AbstractService(){ |
|
|
|
|
private lateinit var uploadDir:String |
|
|
|
|
private lateinit var filePath:String |
|
|
|
|
|
|
|
|
|
override fun init(environment:ApplicationEnvironment){ |
|
|
|
|
super.init(environment) |
|
|
|
|
this.uploadDir= environment.config.property("ktor.deployment.filePath").getString() |
|
|
|
|
val resourcePath =this::class.java.classLoader.getResource("")?.path ?: throw IllegalArgumentException("初始化资源目录失败") |
|
|
|
|
File(resourcePath, uploadDir).apply { |
|
|
|
|
when{ |
|
|
|
|
!exists()&&mkdir()-> { |
|
|
|
|
log.info("图片上传路径[${absolutePath}]初始化成功") |
|
|
|
|
this@FileService.filePath=absolutePath |
|
|
|
|
} |
|
|
|
|
exists()->{ |
|
|
|
|
log.info("图片上传路径[${absolutePath}]已存在") |
|
|
|
|
this@FileService.filePath=absolutePath |
|
|
|
|
} |
|
|
|
|
else->throw IllegalArgumentException("图片上传路径[${absolutePath}]初始化失败") |
|
|
|
|
} |
|
|
|
|
} |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
private fun save(id: String, path:String, file: File):Int{ |
|
|
|
|
return transaction { |
|
|
|
|
return@transaction ImageFile.new { |
|
|
|
|
userId = id |
|
|
|
|
filepath = path |
|
|
|
|
md5 = file.readBytes().md5() |
|
|
|
|
} |
|
|
|
|
}.id.value |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
private inline fun <reified T:PartData> getPartData(map:Map<String?, PartData>, key:String):T{ |
|
|
|
|
if(map.containsKey(key)){ |
|
|
|
|
val obj= map[key] |
|
|
|
|
if(obj is T){ |
|
|
|
|
return obj |
|
|
|
|
}else{ |
|
|
|
|
throw IllegalArgumentException("类型错误") |
|
|
|
|
} |
|
|
|
|
} |
|
|
|
|
throw IllegalArgumentException("找不到key:${key}") |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
fun storeFile(data:List<PartData>):List<Int>?{ |
|
|
|
|
val map=data.associateBy { |
|
|
|
|
it.name |
|
|
|
|
}.toMutableMap() |
|
|
|
|
log.info("map=${map}") |
|
|
|
|
val userId=getPartData<PartData.FormItem>(map,"id").value |
|
|
|
|
val token= getPartData<PartData.FormItem>(map,"token").value |
|
|
|
|
val tokenVo=TokenVo(token=token,userId=userId.toInt()) |
|
|
|
|
if(AccountService.validToken(tokenVo)){ |
|
|
|
|
map.remove("id") |
|
|
|
|
map.remove("token") |
|
|
|
|
val fileIds= mutableListOf<Int>() |
|
|
|
|
map.forEach{ |
|
|
|
|
val value=it.value |
|
|
|
|
if(value is PartData.FileItem){ |
|
|
|
|
val fileBytes = value.streamProvider().readBytes() |
|
|
|
|
val fileName=value.originalFileName?:throw IllegalArgumentException("参数异常") |
|
|
|
|
val format = fileBytes.getFormat() |
|
|
|
|
val fullFileName="${fileName}.${format.format}" |
|
|
|
|
log.info("fullFileName=$fullFileName") |
|
|
|
|
val file=File(filePath,fullFileName).apply { |
|
|
|
|
writeBytes(fileBytes) |
|
|
|
|
} |
|
|
|
|
val fileId= save(id = userId,"${uploadDir}/${fullFileName}",file=file) |
|
|
|
|
fileIds.add(fileId) |
|
|
|
|
} |
|
|
|
|
} |
|
|
|
|
return fileIds |
|
|
|
|
}else{ |
|
|
|
|
return null |
|
|
|
|
} |
|
|
|
|
} |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
/** |
|
|
|
|
* 社团服务 |
|
|
|
|
*/ |
|
|
|
|
object AssociationService: AbstractService() { |
|
|
|
|
|
|
|
|
|
fun register(vo:RegAssociationVo):Boolean{ |
|
|
|
|
return try { |
|
|
|
|
transaction { |
|
|
|
|
Association.new { |
|
|
|
|
name=vo.name |
|
|
|
|
desc=vo.desc |
|
|
|
|
logo=ImageFile.findById(vo.fileId) ?: throw IllegalArgumentException("文件id不存在!") |
|
|
|
|
} |
|
|
|
|
} |
|
|
|
|
log.info("未审核社团创建成功") |
|
|
|
|
true |
|
|
|
|
} catch (e: Exception) { |
|
|
|
|
log.error(e.stackTraceToString()) |
|
|
|
|
false |
|
|
|
|
} |
|
|
|
|
} |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
enum class ManagerType(val desc:String,val level:Int){ |
|
|
|
|
Teacher("老师",1), |
|
|
|
|
PamphaBhusal("总部长",2), |
|
|
|
|
SecretaryOfTheMinister("秘书部部长",3), |
|
|
|
|
PropagandaDepartment("宣传部部长",3), |
|
|
|
|
LiaisonMinister("外联部部长",3), |
|
|
|
|
SecretaryDepartmentOfficer("秘书部干事",4), |
|
|
|
|
PublicityDepartmentOfficer("宣传部干事",4), |
|
|
|
|
LiaisonOfficer("外联部干事",4) |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
object NotificationService:AbstractService(){ |
|
|
|
|
|
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
/** |
|
|
|
|
* 后台服务 |
|
|
|
|
*/ |
|
|
|
|
object BackgroundService:AbstractService(){ |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
override fun init(environment: ApplicationEnvironment) { |
|
|
|
|
super.init(environment) |
|
|
|
|
initManager() |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
private fun createManager(type:ManagerType, num:Int=1): MutableList<InitManagerDto> { |
|
|
|
|
val managerList= mutableListOf<InitManagerDto>() |
|
|
|
|
repeat(num){ |
|
|
|
|
val originPassword=randomNum() |
|
|
|
|
Manager.new { |
|
|
|
|
account= randomNum() |
|
|
|
|
password = originPassword.md5() |
|
|
|
|
duty=type.name |
|
|
|
|
level=type.level |
|
|
|
|
}.apply { |
|
|
|
|
managerList.add(InitManagerDto(account=account,originPassword=originPassword)) |
|
|
|
|
} |
|
|
|
|
} |
|
|
|
|
return managerList |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
//初始化管理员 |
|
|
|
|
private fun initManager(){ |
|
|
|
|
transaction { |
|
|
|
|
val resourcePath =this::class.java.classLoader.getResource("")?.path ?: throw IllegalArgumentException("初始化资源目录失败") |
|
|
|
|
val file=File(resourcePath,"管理员账号.txt") |
|
|
|
|
if(!file.exists()) { |
|
|
|
|
Manager.count().let { it -> |
|
|
|
|
if (it.toInt() == 0) { |
|
|
|
|
val allManager = mutableListOf<InitManagerDto>() |
|
|
|
|
allManager.addAll(createManager(ManagerType.Teacher, 1)) |
|
|
|
|
allManager.addAll(createManager(ManagerType.PamphaBhusal, 1)) |
|
|
|
|
allManager.addAll(createManager(ManagerType.SecretaryOfTheMinister, 1)) |
|
|
|
|
allManager.addAll(createManager(ManagerType.PropagandaDepartment, 1)) |
|
|
|
|
allManager.addAll(createManager(ManagerType.LiaisonMinister, 1)) |
|
|
|
|
arrayOf( |
|
|
|
|
ManagerType.SecretaryDepartmentOfficer, |
|
|
|
|
ManagerType.PublicityDepartmentOfficer, |
|
|
|
|
ManagerType.LiaisonOfficer |
|
|
|
|
).forEach { |
|
|
|
|
allManager.addAll(createManager(it, 3)) |
|
|
|
|
} |
|
|
|
|
allManager.forEach { |
|
|
|
|
file.appendText("${it.account}------${it.originPassword}\n") |
|
|
|
|
} |
|
|
|
|
log.info("共生成${allManager.size}个管理员账号") |
|
|
|
|
} else { |
|
|
|
|
log.info("不需要生成管理员") |
|
|
|
|
} |
|
|
|
|
} |
|
|
|
|
} |
|
|
|
|
} |
|
|
|
|
} |
|
|
|
|