|
|
|
package com.gyf.csams
|
|
|
|
|
|
|
|
import io.ktor.application.*
|
|
|
|
import io.ktor.http.content.*
|
|
|
|
import io.ktor.util.*
|
|
|
|
import org.jetbrains.exposed.sql.*
|
|
|
|
import org.jetbrains.exposed.sql.transactions.transaction
|
|
|
|
import org.slf4j.Logger
|
|
|
|
import java.io.File
|
|
|
|
import java.time.LocalDateTime
|
|
|
|
import kotlin.properties.Delegates
|
|
|
|
import kotlin.system.exitProcess
|
|
|
|
|
|
|
|
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 : AbstractService() {
|
|
|
|
/**
|
|
|
|
* 检查学号是否已注册,true=已注册
|
|
|
|
*/
|
|
|
|
fun registered(selectId: String): Boolean {
|
|
|
|
return transaction {
|
|
|
|
return@transaction !User.find { Users.studentId eq selectId }.empty()
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
/**
|
|
|
|
* 注册
|
|
|
|
*/
|
|
|
|
fun register(userVo: UserRegVo): UserResDto? {
|
|
|
|
try {
|
|
|
|
return transaction {
|
|
|
|
val originPassword = randomNum(8)
|
|
|
|
User.new {
|
|
|
|
studentId = userVo.studentId
|
|
|
|
name = userVo.name
|
|
|
|
password = originPassword.md5()
|
|
|
|
}
|
|
|
|
return@transaction UserResDto(password = originPassword)
|
|
|
|
}
|
|
|
|
} catch (e: Exception) {
|
|
|
|
log.error("注册失败,发生异常:$e")
|
|
|
|
return null
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
/**
|
|
|
|
* 前台登录
|
|
|
|
*
|
|
|
|
*/
|
|
|
|
fun login(userLoginVo: UserLoginVo, _ip: String): UserVo {
|
|
|
|
return transaction {
|
|
|
|
val matchUser = User.find { Users.studentId eq userLoginVo.studentId }.firstOrNull()
|
|
|
|
when {
|
|
|
|
matchUser == null -> {
|
|
|
|
log.warn("学号:${userLoginVo.studentId}不存在")
|
|
|
|
throw StudentIdError(userLoginVo.studentId)
|
|
|
|
}
|
|
|
|
userLoginVo.password.md5() != matchUser.password -> {
|
|
|
|
log.warn("密码:${userLoginVo.password}错误")
|
|
|
|
throw PasswordError(id = userLoginVo.studentId, password = userLoginVo.password)
|
|
|
|
}
|
|
|
|
else -> {
|
|
|
|
val token = UserToken.new {
|
|
|
|
user = matchUser
|
|
|
|
ip = _ip
|
|
|
|
device = userLoginVo.device
|
|
|
|
token =
|
|
|
|
listOf(matchUser.id, ip, device).joinToString(separator = ('a'..'z').random().toString())
|
|
|
|
.md5()
|
|
|
|
}
|
|
|
|
token.flush()
|
|
|
|
|
|
|
|
return@transaction UserVo(
|
|
|
|
studentId = matchUser.studentId, token =
|
|
|
|
Token(
|
|
|
|
id = matchUser.id.value, token = token.token,
|
|
|
|
createTime = token.createTime.format()
|
|
|
|
), name = matchUser.name,
|
|
|
|
headImg = matchUser.headImg?.filepath,
|
|
|
|
desc = matchUser.desc,
|
|
|
|
associationMemberVo = matchUser.associationMember?.let {
|
|
|
|
AssociationMemberVo(association = toAssociationVo(it.association),isHead = it.isHead) }
|
|
|
|
)
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
private fun toAssociationVo(vo:Association):AssociationVo{
|
|
|
|
return AssociationVo(id=vo.id.value,name = vo.name,desc = vo.desc,logo = vo.logo.filepath,
|
|
|
|
faculty = AssociationFaculty.valueOf(vo.faculty),level = vo.level?.let { AssociationLevel.valueOf(it) })
|
|
|
|
}
|
|
|
|
|
|
|
|
private fun tokenRes(token: ManagerToken, matchManager: Manager): ManagerVo {
|
|
|
|
return ManagerVo(
|
|
|
|
account = matchManager.account,
|
|
|
|
token = Token(
|
|
|
|
id = matchManager.id.value, token = token.token,
|
|
|
|
createTime = token.createTime.format()
|
|
|
|
),
|
|
|
|
desc = matchManager.desc,
|
|
|
|
duty = Duty.valueOf(matchManager.duty),
|
|
|
|
headImg = matchManager.headImg?.filepath, name = matchManager.name
|
|
|
|
)
|
|
|
|
}
|
|
|
|
|
|
|
|
private fun tokenRes(token:UserToken,matchUser:User):UserVo{
|
|
|
|
return UserVo(
|
|
|
|
studentId = matchUser.studentId, token =
|
|
|
|
Token(
|
|
|
|
id = matchUser.id.value, token = token.token,
|
|
|
|
createTime = token.createTime.format()
|
|
|
|
), name = matchUser.name,
|
|
|
|
headImg = matchUser.headImg?.filepath, desc = matchUser.desc,
|
|
|
|
associationMemberVo = matchUser.associationMember?.let {
|
|
|
|
AssociationMemberVo(association = toAssociationVo(it.association),isHead = it.isHead) }
|
|
|
|
)
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
fun login(managerLoginVo: ManagerLoginVo, _ip: String): ManagerVo {
|
|
|
|
return transaction {
|
|
|
|
val matchManager = Manager.find { Managers.account eq managerLoginVo.account }.firstOrNull()
|
|
|
|
when {
|
|
|
|
matchManager == null -> {
|
|
|
|
log.warn("账号:${managerLoginVo.account}不存在")
|
|
|
|
throw AccountError(managerLoginVo.account)
|
|
|
|
}
|
|
|
|
managerLoginVo.password.md5() != matchManager.password -> {
|
|
|
|
log.warn("密码:${managerLoginVo.password}错误")
|
|
|
|
throw PasswordError(id = managerLoginVo.account, password = managerLoginVo.password)
|
|
|
|
}
|
|
|
|
else -> {
|
|
|
|
val token = ManagerToken.new {
|
|
|
|
manager = matchManager
|
|
|
|
ip = _ip
|
|
|
|
device = managerLoginVo.device
|
|
|
|
token =
|
|
|
|
listOf(matchManager.id, ip, device).joinToString(separator = ('a'..'z').random().toString())
|
|
|
|
.md5()
|
|
|
|
}
|
|
|
|
token.flush()
|
|
|
|
|
|
|
|
return@transaction tokenRes(token, matchManager)
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
fun getManagerVo(token: Token): ManagerVo {
|
|
|
|
return transaction {
|
|
|
|
val c = ManagerToken.find {
|
|
|
|
ManagerTokens.managerId eq token.id
|
|
|
|
ManagerTokens.token eq token.token
|
|
|
|
}
|
|
|
|
if (!c.empty()) {
|
|
|
|
val manager = Manager.findById(token.id)
|
|
|
|
return@transaction tokenRes(token = c.first(),matchManager = manager!!)
|
|
|
|
} else {
|
|
|
|
throw IllegalArgumentException("token校验失败")
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
fun getUserVo(token: Token): UserVo {
|
|
|
|
return transaction {
|
|
|
|
val c= UserToken.find {
|
|
|
|
UserTokens.userId eq token.id
|
|
|
|
UserTokens.token eq token.token
|
|
|
|
}
|
|
|
|
if (!c.empty()) {
|
|
|
|
val user = User.findById(token.id)
|
|
|
|
return@transaction tokenRes(token = c.first(),matchUser = user!!)
|
|
|
|
} else {
|
|
|
|
throw IllegalArgumentException("token校验失败")
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
fun validManagerToken(token:Token):Boolean{
|
|
|
|
return transaction {
|
|
|
|
!ManagerToken.find {
|
|
|
|
ManagerTokens.managerId eq token.id
|
|
|
|
ManagerTokens.token eq token.token
|
|
|
|
}.empty()
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
fun validUserToken(token: Token):Boolean{
|
|
|
|
return transaction {
|
|
|
|
!UserToken.find {
|
|
|
|
UserTokens.userId eq token.id
|
|
|
|
UserTokens.token eq token.token
|
|
|
|
}.empty()
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
fun <T : ClientBaseVo> validToken(vo: T): Boolean {
|
|
|
|
return if (vo.clientType == ClientType.Foreground) {
|
|
|
|
validUserToken(vo.token)
|
|
|
|
} else {
|
|
|
|
validManagerToken(vo.token)
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
fun logout(vo: OnlyToken): Boolean {
|
|
|
|
return transaction {
|
|
|
|
if (vo.clientType == ClientType.Foreground)
|
|
|
|
UserTokens.deleteWhere { UserTokens.userId eq vo.token.id } > 0
|
|
|
|
else
|
|
|
|
ManagerTokens.deleteWhere { ManagerTokens.managerId eq vo.token.id } > 0
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
fun test() {
|
|
|
|
log.info("开始测试")
|
|
|
|
transaction {
|
|
|
|
log.info("查询到个${User.count()}用户")
|
|
|
|
}
|
|
|
|
log.info("结束测试")
|
|
|
|
}
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
/**
|
|
|
|
* 主页服务
|
|
|
|
*/
|
|
|
|
object MainService : AbstractService() {
|
|
|
|
private var maxSize by Delegates.notNull<Int>()
|
|
|
|
|
|
|
|
override fun init(environment: ApplicationEnvironment) {
|
|
|
|
super.init(environment)
|
|
|
|
this.maxSize = environment.config.property("ktor.deployment.leaveMessage.maxSize").getString().toInt()
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
/**
|
|
|
|
* 创建留言信息
|
|
|
|
*
|
|
|
|
* @param leaveMessageVo
|
|
|
|
* @return
|
|
|
|
*/
|
|
|
|
fun createMessage(leaveMessageVo: LeaveMessageVo): Boolean {
|
|
|
|
return if (leaveMessageVo.message.isNotEmpty()) {
|
|
|
|
return transaction {
|
|
|
|
val count = LeaveMessage.count().toInt()
|
|
|
|
log.info("系统留言数:$count,限制数:$maxSize")
|
|
|
|
if (count >= maxSize) {
|
|
|
|
LeaveMessage.all().sortedBy { it.createTime }.subList(0, count - maxSize).forEach {
|
|
|
|
it.delete()
|
|
|
|
}
|
|
|
|
|
|
|
|
}
|
|
|
|
log.info("保存留言:${leaveMessageVo.message}")
|
|
|
|
LeaveMessage.new {
|
|
|
|
user = User.findById(leaveMessageVo.token.id) ?: throw IllegalArgumentException("非法id")
|
|
|
|
message = leaveMessageVo.message
|
|
|
|
}
|
|
|
|
log.info("留言保存成功")
|
|
|
|
return@transaction true
|
|
|
|
}
|
|
|
|
} else {
|
|
|
|
log.info("留言不能为空")
|
|
|
|
false
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
fun getAllLeaveMessage(): List<LeaveMessageDto> {
|
|
|
|
return transaction {
|
|
|
|
log.info("获取所有留言")
|
|
|
|
|
|
|
|
return@transaction LeaveMessage.all().toList().map {
|
|
|
|
LeaveMessageDto(
|
|
|
|
message = "${it.user.name}说:${it.message}",
|
|
|
|
user = UserInfoVo(name = it.user.name, headImg = it.user.headImg?.filepath, desc = it.user.desc)
|
|
|
|
)
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
/**
|
|
|
|
* 文件管理服务
|
|
|
|
*/
|
|
|
|
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()
|
|
|
|
filePath =
|
|
|
|
this::class.java.classLoader.getResource(uploadDir)?.path ?: throw IllegalArgumentException("初始化资源目录失败")
|
|
|
|
log.info("上传路径[${filePath}]")
|
|
|
|
}
|
|
|
|
|
|
|
|
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 createTime = getPartData<PartData.FormItem>(map, "createTime").value
|
|
|
|
val tokenVo = Token(token = token, id = userId.toInt(), createTime = createTime.toLong())
|
|
|
|
if (AccountService.validUserToken(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)
|
|
|
|
}
|
|
|
|
log.info("文件成功保存到${file.absolutePath}")
|
|
|
|
val fileId = save(id = userId, "/${uploadDir}/${fullFileName}", file = file)
|
|
|
|
fileIds.add(fileId)
|
|
|
|
}
|
|
|
|
}
|
|
|
|
return fileIds
|
|
|
|
} else {
|
|
|
|
return null
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
/**
|
|
|
|
* 社团服务
|
|
|
|
*/
|
|
|
|
object AssociationService : AbstractService() {
|
|
|
|
|
|
|
|
/**
|
|
|
|
* 注册社团
|
|
|
|
*
|
|
|
|
* @param regVo
|
|
|
|
* @return
|
|
|
|
*/
|
|
|
|
fun register(regVo: AssociationRegVo) {
|
|
|
|
return transaction {
|
|
|
|
//再次申请
|
|
|
|
val user = User.findById(regVo.token.id) ?: throw UserIdError(regVo.token.id)
|
|
|
|
if(regVo.id!=null){
|
|
|
|
log.info("再次提交【${regVo.name}】注册资料")
|
|
|
|
val association= Association.findById(regVo.id)?:throw RegIdError(regVo.id)
|
|
|
|
val log = AuditLogging.new {
|
|
|
|
this.user = user
|
|
|
|
}
|
|
|
|
|
|
|
|
association.apply {
|
|
|
|
name = regVo.name
|
|
|
|
desc = regVo.desc
|
|
|
|
logo = ImageFile.findById(regVo.fileId) ?: throw FileIdError(regVo.fileId)
|
|
|
|
this.log = log
|
|
|
|
}
|
|
|
|
}else {
|
|
|
|
val association:Association?= AuditLogging.find { AuditLeggings.userId eq user.id }.firstOrNull()?.user?.associationMember?.association
|
|
|
|
when {
|
|
|
|
association != null && association.log.result == true -> throw IllegalArgumentException("您是社团团长不能再创建其他社团")
|
|
|
|
association != null && association.log.result == null -> throw IllegalArgumentException("您已经提交过社团注册资料,请耐心等待后台管理员处理")
|
|
|
|
association == null -> {
|
|
|
|
val log = AuditLogging.new {
|
|
|
|
this.user = user
|
|
|
|
}
|
|
|
|
Association.new {
|
|
|
|
name = regVo.name
|
|
|
|
desc = regVo.desc
|
|
|
|
logo = ImageFile.findById(regVo.fileId) ?: throw FileIdError(regVo.fileId)
|
|
|
|
this.log = log
|
|
|
|
faculty = user.faculty().name
|
|
|
|
}
|
|
|
|
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
Notification.new {
|
|
|
|
title = "注册社团"
|
|
|
|
content = "您成功提交了一份社团注册资料,请耐心等待后台受理"
|
|
|
|
receiverId = regVo.token.id
|
|
|
|
receiverClient = ClientType.Foreground.name
|
|
|
|
}
|
|
|
|
BackgroundService.createBackgroundNotification(
|
|
|
|
title = "审核注册社团", content = "用户${user.name}提交了一份社团资料需要您进行受理",
|
|
|
|
duty = Duty.PamphaBhusal
|
|
|
|
)
|
|
|
|
this@AssociationService.log.info("未审核社团:${regVo.name}创建成功")
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
/**
|
|
|
|
* 前台读取社团注册资料
|
|
|
|
*
|
|
|
|
*/
|
|
|
|
fun read(vo:OnlyToken):AssociationCheckVo?{
|
|
|
|
return transaction {
|
|
|
|
val association:Association?= AuditLogging.find { AuditLeggings.userId eq vo.token.id }.firstOrNull()?.user?.associationMember?.association
|
|
|
|
return@transaction association?.let {
|
|
|
|
AssociationCheckVo(id=it.id.value,name=it.name,desc=it.desc,logo = it.logo.filepath,
|
|
|
|
faculty = AssociationFaculty.valueOf(it.faculty),level = it.level?.let { it1 ->
|
|
|
|
AssociationLevel.valueOf(
|
|
|
|
it1
|
|
|
|
)
|
|
|
|
},checkStatus = when{
|
|
|
|
it.log.nextAudit == null && it.log.manager == null->CheckStatus.WaitFirst
|
|
|
|
it.log.nextAudit == null && it.log.manager != null->CheckStatus.AcceptFirst
|
|
|
|
it.log.nextAudit != null && it.log.nextAudit?.manager==null ->CheckStatus.WaitLast
|
|
|
|
it.log.nextAudit != null && it.log.nextAudit?.result==null ->CheckStatus.AcceptLast
|
|
|
|
else->CheckStatus.Finish
|
|
|
|
},applyTime = it.log.applyTime.format(),
|
|
|
|
firstCause = it.log.cause?:"",lastCause = it.log.nextAudit?.cause,
|
|
|
|
fileId = it.logo.id.value)
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
/**
|
|
|
|
* 注册资料受理
|
|
|
|
*
|
|
|
|
* @param vo
|
|
|
|
*/
|
|
|
|
fun accept(vo: AcceptRegAssociation) {
|
|
|
|
transaction {
|
|
|
|
val association= Association.find { Associations.logId eq vo.regId }.firstOrNull()?:throw RegIdError(vo.regId)
|
|
|
|
when (val manager = Manager.findById(vo.token.id)) {
|
|
|
|
null -> throw ManagerIdError(vo.token.id)
|
|
|
|
else -> {
|
|
|
|
association.apply {
|
|
|
|
if(vo.isFirstAccept) {
|
|
|
|
log.manager = manager
|
|
|
|
log.acceptTime = LocalDateTime.now()
|
|
|
|
}else{
|
|
|
|
log.nextAudit?.manager=manager
|
|
|
|
log.nextAudit?.acceptTime=LocalDateTime.now()
|
|
|
|
}
|
|
|
|
}
|
|
|
|
log.info("[${association.name}]社团注册资料已受理")
|
|
|
|
Notification.new {
|
|
|
|
title = "注册社团"
|
|
|
|
content = "您提交的[${association.name}]社团注册资料已受理"
|
|
|
|
receiverId = vo.token.id
|
|
|
|
receiverClient = ClientType.Foreground.name
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
/**
|
|
|
|
* 社团列表加载
|
|
|
|
*
|
|
|
|
* @param vo
|
|
|
|
* @return
|
|
|
|
*/
|
|
|
|
fun load(vo: SearchAssociationVo): List<AssociationVo> {
|
|
|
|
return transaction {
|
|
|
|
log.info("社团搜索条件[name=${vo.name},desc=${vo.desc}]")
|
|
|
|
|
|
|
|
val nextAudit=AuditLeggings.alias("nextAudit")
|
|
|
|
return@transaction Associations.innerJoin(otherTable = AuditLeggings).innerJoin(nextAudit,{AuditLeggings.nextAudit},{nextAudit[AuditLeggings.id]})
|
|
|
|
.slice(Associations.columns)
|
|
|
|
.select {
|
|
|
|
nextAudit[AuditLeggings.result] eq true and (Associations.name like "%${vo.name}%") and (Associations.desc like "%${vo.desc}%")
|
|
|
|
}.map {
|
|
|
|
val imageFile=ImageFile.findById(it[Associations.logo])?:throw FileIdError(it[Associations.logo].value)
|
|
|
|
|
|
|
|
AssociationVo(name = it[Associations.name],
|
|
|
|
id = it[Associations.id].value,
|
|
|
|
logo = imageFile.filepath,
|
|
|
|
desc = it[Associations.desc],
|
|
|
|
faculty = it[Associations.faculty].let { it1 ->
|
|
|
|
AssociationFaculty.valueOf(
|
|
|
|
it1
|
|
|
|
)
|
|
|
|
},
|
|
|
|
level = it[Associations.level]?.let { it1 -> AssociationLevel.valueOf(it1) })
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
private fun toAuditLoggingVo(it:AuditLogging?):AuditLoggingVo?{
|
|
|
|
return it?.let {
|
|
|
|
val auditLogging=AuditLoggingVo(id=it.id.value,user =
|
|
|
|
UserInfoVo(name = it.user.name,headImg = it.user.headImg?.filepath,desc = it.user.desc),applyTime = it.applyTime.format(),manager = it.manager?.let {
|
|
|
|
ManagerInfoVo(duty = Duty.valueOf(it.duty),name = it.name,headImg = it.headImg?.filepath,desc = it.desc) },
|
|
|
|
acceptTime = it.acceptTime?.format(),cause = it.cause,result = it.result,auditTime = it.auditTime?.format(),
|
|
|
|
nextAudit = toAuditLoggingVo(it.nextAudit))
|
|
|
|
auditLogging
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
fun loadAudit(vo: OnlyToken): List<DisposeRegInfoVo> {
|
|
|
|
return transaction {
|
|
|
|
return@transaction Association.all().map {
|
|
|
|
val log=toAuditLoggingVo(it.log)?:throw IllegalArgumentException("转换审核记录出错!!!!")
|
|
|
|
DisposeRegInfoVo(name = it.name,desc = it.desc,logo = it.logo.filepath,log=log)
|
|
|
|
}.apply {
|
|
|
|
log.info("找到${this.size}份社团注册资料")
|
|
|
|
}
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
/**
|
|
|
|
* 审核记录
|
|
|
|
*
|
|
|
|
* @param vo
|
|
|
|
*/
|
|
|
|
fun check(vo:CheckRegVo){
|
|
|
|
transaction {
|
|
|
|
try {
|
|
|
|
val association=Association.find { Associations.logId eq vo.regId }.firstOrNull()?:throw RegIdError(vo.regId)
|
|
|
|
val matchUser=User.findById(vo.token.id)?:throw UserIdError(vo.token.id)
|
|
|
|
association.log.apply {
|
|
|
|
if(nextAudit!=null){
|
|
|
|
nextAudit?.apply {
|
|
|
|
cause = vo.cause
|
|
|
|
result = vo.result
|
|
|
|
auditTime = LocalDateTime.now()
|
|
|
|
}
|
|
|
|
}else {
|
|
|
|
cause = vo.cause
|
|
|
|
result = vo.result
|
|
|
|
auditTime = LocalDateTime.now()
|
|
|
|
}
|
|
|
|
}.apply {
|
|
|
|
this@AssociationService.log.info("更新审核结果")
|
|
|
|
}
|
|
|
|
when{
|
|
|
|
association.log.nextAudit==null&&vo.result->{
|
|
|
|
val log = AuditLogging.new {
|
|
|
|
this.user = matchUser
|
|
|
|
}.apply {
|
|
|
|
this@AssociationService.log.info("构造复审记录")
|
|
|
|
}
|
|
|
|
association.log.nextAudit=log
|
|
|
|
BackgroundService.createBackgroundNotification(
|
|
|
|
title = "审核注册社团",
|
|
|
|
content = "总部长上报了一份社团注册资料需要您进行受理",
|
|
|
|
duty = Duty.Teacher
|
|
|
|
).apply {
|
|
|
|
this@AssociationService.log.info("通知老师复审社团注册资料")
|
|
|
|
}
|
|
|
|
Notification.new {
|
|
|
|
title = "注册社团"
|
|
|
|
content = "您提交的【${association.name}】社团注册资料初审通过,请耐心等待复审"
|
|
|
|
receiverId = matchUser.id.value
|
|
|
|
receiverClient = ClientType.Foreground.name
|
|
|
|
}.apply {
|
|
|
|
this@AssociationService.log.info("通知前台用户审核结果")
|
|
|
|
}
|
|
|
|
}
|
|
|
|
association.log.nextAudit==null&&!vo.result->{
|
|
|
|
Notification.new {
|
|
|
|
title = "注册社团"
|
|
|
|
content = "您提交的【${association.name}】社团注册资料初审不通过,可根据初审意见,重新申请\n" +
|
|
|
|
"【初审意见:${vo.cause},审核人:${association.log.manager?.desc?:""}】"
|
|
|
|
receiverId = matchUser.id.value
|
|
|
|
receiverClient = ClientType.Foreground.name
|
|
|
|
}.apply {
|
|
|
|
this@AssociationService.log.info("通知前台用户审核结果")
|
|
|
|
}
|
|
|
|
}
|
|
|
|
association.log.nextAudit!=null&&vo.result->{
|
|
|
|
AssociationMember.new {
|
|
|
|
this.association=association
|
|
|
|
isHead=true
|
|
|
|
}.apply {
|
|
|
|
matchUser.associationMember=this
|
|
|
|
this@AssociationService.log.info("初始化社团团长")
|
|
|
|
}
|
|
|
|
Notification.new {
|
|
|
|
title = "注册社团"
|
|
|
|
content = "您提交的【${association.name}】社团注册资料复审通过"
|
|
|
|
receiverId = matchUser.id.value
|
|
|
|
receiverClient = ClientType.Foreground.name
|
|
|
|
}.apply {
|
|
|
|
this@AssociationService.log.info("通知前台用户审核结果")
|
|
|
|
}
|
|
|
|
}
|
|
|
|
else->{
|
|
|
|
Notification.new {
|
|
|
|
title = "注册社团"
|
|
|
|
content = "您提交的【${association.name}】社团注册资料复审不通过,可根据复审意见,重新申请\n" +
|
|
|
|
"【复审意见:${vo.cause},审核人:${association.log.nextAudit?.manager?.desc?:""}】"
|
|
|
|
receiverId = matchUser.id.value
|
|
|
|
receiverClient = ClientType.Foreground.name
|
|
|
|
}.apply {
|
|
|
|
this@AssociationService.log.info("通知前台用户审核结果")
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
this@AssociationService.log.info("【${association.name}】社团注册资料审核完成")
|
|
|
|
} catch (e: Exception) {
|
|
|
|
rollback()
|
|
|
|
throw e
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
private fun toAssociationVo(it: Association):AssociationVo{
|
|
|
|
return AssociationVo(id=it.id.value,name=it.name,desc = it.desc,
|
|
|
|
logo = it.logo.filepath,faculty = AssociationFaculty.valueOf(it.faculty),
|
|
|
|
level = it.level?.let { AssociationLevel.valueOf(it) })
|
|
|
|
}
|
|
|
|
|
|
|
|
fun load(vo:ShowAssociationVo): AssociationMainVo {
|
|
|
|
return transaction {
|
|
|
|
val associationVo= (Association.findById(vo.id)?:throw AssociationIdError(vo.id)).let {
|
|
|
|
AssociationVo(id=it.id.value,name=it.name,desc = it.desc,
|
|
|
|
logo = it.logo.filepath,faculty = AssociationFaculty.valueOf(it.faculty),
|
|
|
|
level = it.level?.let { AssociationLevel.valueOf(it) })}
|
|
|
|
val head=Users.innerJoin(AssociationMembers)
|
|
|
|
.slice(Users.columns)
|
|
|
|
.select { AssociationMembers.isHead eq true and (AssociationMembers.associationId eq vo.id) }
|
|
|
|
.firstOrNull()?.let {
|
|
|
|
UserInfoVo(name = it[Users.name],headImg = it[Users.imgId]?.let { ImageFile.findById(it)?:throw FileIdError(it.value) }?.filepath,
|
|
|
|
desc = it[Users.desc])
|
|
|
|
|
|
|
|
}?:throw IllegalArgumentException("无法找到社团[${vo.id}]")
|
|
|
|
AssociationMainVo(associationVo = associationVo,head = head)
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
/**
|
|
|
|
* 通知服务
|
|
|
|
*/
|
|
|
|
object NotificationService : AbstractService() {
|
|
|
|
|
|
|
|
/**
|
|
|
|
* 拉取最新通知
|
|
|
|
*
|
|
|
|
* @param vo
|
|
|
|
* @return
|
|
|
|
*/
|
|
|
|
fun pull(vo: NotificationDto): List<NotificationVo> {
|
|
|
|
return transaction {
|
|
|
|
log.info("通知查询条件[receiverId=${vo.receiverId},receiverClient=${vo.receiverClient.name},pull=false]")
|
|
|
|
val notifications = Notification.find {
|
|
|
|
Notifications.pull eq false and
|
|
|
|
(Notifications.receiverId eq vo.receiverId) and
|
|
|
|
(Notifications.receiverClient eq vo.receiverClient.name)
|
|
|
|
}
|
|
|
|
log.info("获取${notifications.count()}条最新通知")
|
|
|
|
return@transaction notifications.map {
|
|
|
|
it.pull = true
|
|
|
|
NotificationVo(
|
|
|
|
title = it.title, id = it.id.value, content = it.content,
|
|
|
|
createTime = it.createTime.format()
|
|
|
|
)
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
/**
|
|
|
|
* 未读通知计数
|
|
|
|
*
|
|
|
|
* @param vo
|
|
|
|
* @return
|
|
|
|
*/
|
|
|
|
fun count(vo: NotificationDto): Long {
|
|
|
|
return transaction {
|
|
|
|
return@transaction Notification.find {
|
|
|
|
Notifications.read eq false and
|
|
|
|
(Notifications.receiverId eq vo.receiverId) and
|
|
|
|
(Notifications.receiverClient eq vo.receiverClient.name)
|
|
|
|
}.count().apply {
|
|
|
|
log.info("未读通知${this}条")
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
/**
|
|
|
|
*
|
|
|
|
* @param vo
|
|
|
|
* @return
|
|
|
|
*/
|
|
|
|
fun list(vo: NotificationDto): List<NotificationVo>? {
|
|
|
|
return vo.page?.let {
|
|
|
|
transaction {
|
|
|
|
log.info("page:${it}")
|
|
|
|
return@transaction Notification.find {
|
|
|
|
(Notifications.receiverId eq vo.receiverId) and
|
|
|
|
(Notifications.receiverClient eq vo.receiverClient.name)
|
|
|
|
}.limit(n = it.pageSize, offset = (it.currentPage - 1) * it.pageSize).map {
|
|
|
|
NotificationVo(
|
|
|
|
title = it.title,
|
|
|
|
id = it.id.value,
|
|
|
|
content = it.content,
|
|
|
|
createTime = it.createTime.format()
|
|
|
|
)
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
/**
|
|
|
|
* 后台服务
|
|
|
|
*/
|
|
|
|
object BackgroundService : AbstractService() {
|
|
|
|
|
|
|
|
|
|
|
|
override fun init(environment: ApplicationEnvironment) {
|
|
|
|
super.init(environment)
|
|
|
|
initManager()
|
|
|
|
}
|
|
|
|
|
|
|
|
/**
|
|
|
|
* 前台任务通知管理员处理
|
|
|
|
*
|
|
|
|
*/
|
|
|
|
fun createBackgroundNotification(content: String, title: String, duty: Duty) {
|
|
|
|
Manager.find { Managers.duty eq duty.name }.apply {
|
|
|
|
if (count() == 0L) {
|
|
|
|
log.warn("找不到适当的${duty.desc}处理此任务")
|
|
|
|
} else {
|
|
|
|
forEach {
|
|
|
|
Notification.new {
|
|
|
|
this.title = title
|
|
|
|
this.content = content
|
|
|
|
receiverId = it.id.value
|
|
|
|
receiverClient = ClientType.Background.name
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
private fun createManager(duty: Duty, num: Int = 1): MutableList<InitManagerDto> {
|
|
|
|
val managerList = mutableListOf<InitManagerDto>()
|
|
|
|
repeat(num) {
|
|
|
|
val originPassword = randomNum()
|
|
|
|
Manager.new {
|
|
|
|
account = randomNum()
|
|
|
|
password = originPassword.md5()
|
|
|
|
this.duty = duty.name
|
|
|
|
this.name = duty.desc
|
|
|
|
}.apply {
|
|
|
|
managerList.add(InitManagerDto(account = account, originPassword = originPassword, duty = duty))
|
|
|
|
}
|
|
|
|
}
|
|
|
|
return managerList
|
|
|
|
}
|
|
|
|
|
|
|
|
//初始化管理员
|
|
|
|
private fun initManager() {
|
|
|
|
transaction {
|
|
|
|
val resourcePath =
|
|
|
|
this::class.java.classLoader.getResource("")?.path ?: throw IllegalArgumentException("初始化资源目录失败")
|
|
|
|
val file = File(resourcePath, "管理员账号.txt")
|
|
|
|
try {
|
|
|
|
if (!file.exists()) {
|
|
|
|
Manager.count().let { it ->
|
|
|
|
if (it.toInt() == 0) {
|
|
|
|
val allManager = mutableListOf<InitManagerDto>()
|
|
|
|
allManager.addAll(createManager(Duty.Teacher, 1))
|
|
|
|
allManager.addAll(createManager(Duty.PamphaBhusal, 1))
|
|
|
|
allManager.addAll(createManager(Duty.SecretaryOfTheMinister, 1))
|
|
|
|
allManager.addAll(createManager(Duty.PropagandaDepartment, 1))
|
|
|
|
allManager.addAll(createManager(Duty.LiaisonMinister, 1))
|
|
|
|
arrayOf(
|
|
|
|
Duty.SecretaryDepartmentOfficer,
|
|
|
|
Duty.PublicityDepartmentOfficer,
|
|
|
|
Duty.LiaisonOfficer
|
|
|
|
).forEach {
|
|
|
|
allManager.addAll(createManager(it, 3))
|
|
|
|
}
|
|
|
|
allManager.forEach {
|
|
|
|
file.appendText("${it.account}------${it.originPassword}------${it.duty.desc}\n")
|
|
|
|
}
|
|
|
|
log.info("共生成${allManager.size}个管理员账号")
|
|
|
|
} else {
|
|
|
|
log.info("不需要生成管理员")
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
} catch (e: Exception) {
|
|
|
|
log.error(e)
|
|
|
|
exitProcess(0)
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|