diff --git a/module/src/main/kotlin/com/gyf/csams/module/ShareVo.kt b/module/src/main/kotlin/com/gyf/csams/module/ShareVo.kt index 446850b..67b4d7c 100644 --- a/module/src/main/kotlin/com/gyf/csams/module/ShareVo.kt +++ b/module/src/main/kotlin/com/gyf/csams/module/ShareVo.kt @@ -696,5 +696,27 @@ data class AuditJoinVo(val joinId:Int, val result:Boolean, override val clientType: ClientType=ClientType.Foreground ):ClientBaseVo() +/** + * 组成申请社团试卷的题库最小题目数量 + */ +const val QUESTION_MIN_SIZE=5 + +enum class TendencyType(val desc:String){ + Like("点赞"), + Collect("收藏") +} + +data class TendencyVo(val activityId: Int, val type:TendencyType, + override val token: Token, + override val clientType: ClientType=ClientType.Foreground +):ClientBaseVo() + +data class CheckTendencyVo(val activityId: Int, override val token: Token, + override val clientType: ClientType=ClientType.Foreground):ClientBaseVo() + +data class CheckTendencyResVo(val hasLike:Boolean, val hasCollect:Boolean) + +data class FindTendencyVo(val type:TendencyType, override val token: Token, + override val clientType: ClientType=ClientType.Foreground):ClientBaseVo() + -const val QUESTION_MIN_SIZE=5 \ No newline at end of file diff --git a/src/main/kotlin/com/gyf/csams/Controller.kt b/src/main/kotlin/com/gyf/csams/Controller.kt index 93197a0..65ccae8 100644 --- a/src/main/kotlin/com/gyf/csams/Controller.kt +++ b/src/main/kotlin/com/gyf/csams/Controller.kt @@ -564,6 +564,41 @@ fun Application.ActivityController(){ check(ActivityService) read(ActivityService,Activities) + post("/tendency"){ + call.withToken { + try { + ActivityService.tendency(vo=it) + call.respond(ApiResponse(message = "${it.type.desc}成功",body = true)) + } catch (e: Exception) { + log.error(e) + call.respond(ApiResponse(message = "${it.type.desc}失败",body = false)) + } + } + } + + post("/tendency/check"){ + call.withToken { + try { + call.respond(ApiResponse(message = "活动倾向查询成功",body=ActivityService.checkTendency(vo=it))) + } catch (e: Exception) { + log.error(e) + call.respond(ApiResponse(message = "活动倾向查询失败",body=null)) + } + + } + } + + post("/tendency/find"){ + call.withToken { + try { + call.respond(ApiResponse(message = "活动倾向查询成功",body=ActivityService.findTendency(vo=it))) + } catch (e: Exception) { + log.error(e) + call.respond(ApiResponse(message = "活动倾向查询失败",body=null)) + } + } + } + post("/list/all"){ call.withToken { call.respond(ApiResponse(message = "活动信息加载",body = ActivityService.listAll())) diff --git a/src/main/kotlin/com/gyf/csams/Dao.kt b/src/main/kotlin/com/gyf/csams/Dao.kt index c947c2f..019956f 100644 --- a/src/main/kotlin/com/gyf/csams/Dao.kt +++ b/src/main/kotlin/com/gyf/csams/Dao.kt @@ -1,6 +1,7 @@ package com.gyf.csams +import com.gyf.csams.JoinAssociations.defaultExpression import org.jetbrains.exposed.dao.IntEntity import org.jetbrains.exposed.dao.IntEntityClass import org.jetbrains.exposed.dao.id.EntityID @@ -477,3 +478,26 @@ class JoinAssociation(id:EntityID):IntEntity(id){ var applyTime by JoinAssociations.applyTime var auditTime by JoinAssociations.auditTime } + +@TableComment("用户倾向") +object Tendencies:IntIdTable(){ + @TableComment("点赞用户") + val userId:Column> = reference("user_id",Users) + + @TableComment("点赞活动") + val activityId:Column> = reference("activity_id",Activities) + + @TableComment("点赞时间") + val createTime:Column = datetime("create_time").defaultExpression(CurrentDateTime()) + + @TableComment("倾向类型") + val type:Column = integer("type") +} + +class Tendency(id:EntityID):IntEntity(id){ + companion object:IntEntityClass(Tendencies) + var user by User referencedOn Tendencies.userId + var activity by Activity referencedOn Tendencies.activityId + val createTime by Tendencies.createTime + var type by Tendencies.type +} diff --git a/src/main/kotlin/com/gyf/csams/MySQL.kt b/src/main/kotlin/com/gyf/csams/MySQL.kt index 0709261..90234ae 100644 --- a/src/main/kotlin/com/gyf/csams/MySQL.kt +++ b/src/main/kotlin/com/gyf/csams/MySQL.kt @@ -42,7 +42,7 @@ fun initTable(){ transaction { val tableList= arrayOf(Users,UserTokens,Managers,ManagerTokens,AuditLeggings,LeaveMessages, ImageFiles,Associations,AssociationMembers,Notifications,Activities,PhotoAlbums,ActivityComments, - Renames,Questions,Answers,JoinAssociations) + Renames,Questions,Answers,JoinAssociations,Tendencies) SchemaUtils.createMissingTablesAndColumns(*tableList) updateComment(*tableList) diff --git a/src/main/kotlin/com/gyf/csams/Service.kt b/src/main/kotlin/com/gyf/csams/Service.kt index 131d6ba..2783d9b 100644 --- a/src/main/kotlin/com/gyf/csams/Service.kt +++ b/src/main/kotlin/com/gyf/csams/Service.kt @@ -44,7 +44,7 @@ object AccountService : AbstractService() { } } - fun toUserInfo(user: User):UserInfoVo{ + fun toUserInfo(user: User): UserInfoVo { return UserInfoVo(name = user.name, headImg = user.headImg?.filepath, desc = user.desc) } @@ -55,7 +55,7 @@ object AccountService : AbstractService() { try { return transaction { - val originPassword = if(environment.developmentMode) (1..8).joinToString("") else randomNum(8) + val originPassword = if (environment.developmentMode) (1..8).joinToString("") else randomNum(8) log.info("密码:${originPassword}") User.new { studentId = userVo.studentId @@ -156,15 +156,15 @@ object AccountService : AbstractService() { } } - fun uploadHeadImg(data: List){ - val userId=data.getFormParam("id").toInt() + fun uploadHeadImg(data: List) { + val userId = data.getFormParam("id").toInt() transaction { - val fileIds =FileService.storeFile(data) - if(fileIds?.isNotEmpty()==true){ - val fileId=fileIds.first() - val user=User.findById(userId)?:throw UserIdError(userId) + val fileIds = FileService.storeFile(data) + if (fileIds?.isNotEmpty() == true) { + val fileId = fileIds.first() + val user = User.findById(userId) ?: throw UserIdError(userId) user.apply { - headImg=ImageFile.findById(fileId)?:throw FileIdError(fileId) + headImg = ImageFile.findById(fileId) ?: throw FileIdError(fileId) } } } @@ -172,34 +172,34 @@ object AccountService : AbstractService() { fun refreshInfo(vo: InfoUpdateVo): PersonInfoVo { return transaction { - when(vo.clientType){ - ClientType.Foreground->{ + when (vo.clientType) { + ClientType.Foreground -> { val matchUser = User.findById(vo.token.id) ?: throw UserIdError(vo.token.id) matchUser.apply { vo.name?.let { - matchUser.name=it + matchUser.name = it } vo.desc?.let { - matchUser.desc=it + matchUser.desc = it } } val token = UserToken.find { UserTokens.userId eq matchUser.id }.firstOrNull() ?: throw IllegalArgumentException("无法根据[userId=${matchUser.id}]找到token") - tokenRes(token=token,matchUser = matchUser) + tokenRes(token = token, matchUser = matchUser) } - ClientType.Background->{ - val matchManager = Manager.findById(vo.token.id)?:throw ManagerIdError(vo.token.id) + ClientType.Background -> { + val matchManager = Manager.findById(vo.token.id) ?: throw ManagerIdError(vo.token.id) matchManager.apply { vo.name?.let { - matchManager.name=it + matchManager.name = it } vo.desc?.let { - matchManager.desc=it + matchManager.desc = it } } - val token=ManagerToken.find { ManagerTokens.managerId eq matchManager.id }.firstOrNull() + val token = ManagerToken.find { ManagerTokens.managerId eq matchManager.id }.firstOrNull() ?: throw IllegalArgumentException("无法根据[matchId=${matchManager.id}]找到token") - tokenRes(token=token,matchManager=matchManager) + tokenRes(token = token, matchManager = matchManager) } } } @@ -658,19 +658,23 @@ abstract class AuditService : AbstractService() { return transaction { if (isFilter) { // val nextAudit = AuditLeggings.alias("nextAudit") - val c=table.innerJoin(AuditLeggings) + val c = table.innerJoin(AuditLeggings) // .innerJoin(nextAudit, { AuditLeggings.nextAudit }, { nextAudit[AuditLeggings.id] }) .innerJoin(Users) - .slice(listOf(table.id,AuditLeggings.result,AuditLeggings.nextAudit)) - .select { Users.id eq vo.token.id} + .slice(listOf(table.id, AuditLeggings.result, AuditLeggings.nextAudit)) + .select { Users.id eq vo.token.id } .filter { log.info("it[AuditLeggings.result]=${it[AuditLeggings.result]},it[AuditLeggings.nextAudit]=${it[AuditLeggings.nextAudit]}") - it[AuditLeggings.result]==null|| it[AuditLeggings.nextAudit]?.let { it1 -> AuditLogging.findById(it1)?.result } ==null + it[AuditLeggings.result] == null || it[AuditLeggings.nextAudit]?.let { it1 -> + AuditLogging.findById( + it1 + )?.result + } == null } log.info("size:${c.size}") - if(c.size==1){ + if (c.size == 1) { getCheckVo(c.first()[table.id]) - }else{ + } else { null } } else { @@ -809,9 +813,16 @@ object AssociationService : AuditService{ + fun loadExam(vo: SearchExamVo): List { return transaction { Question.find { Questions.associationId eq vo.associationId }.map { toExamVo(question = it) @@ -832,32 +843,34 @@ object AssociationService : AuditService0 - return JoinAssociationVo(id=join.id.value,user = AccountService.toUserInfo(join.user), - associationVo = toAssociationVo(join.association),hasPaper = hasPaper,result = join.result, - applyTime = join.applyTime.toLong(),auditTime = join.auditTime?.toLong()) + private fun toJoinVo(join: JoinAssociation): JoinAssociationVo { + val hasPaper = Answer.find { Answers.joinId eq join.id.value }.count() > 0 + return JoinAssociationVo( + id = join.id.value, user = AccountService.toUserInfo(join.user), + associationVo = toAssociationVo(join.association), hasPaper = hasPaper, result = join.result, + applyTime = join.applyTime.toLong(), auditTime = join.auditTime?.toLong() + ) } /** @@ -866,11 +879,11 @@ object AssociationService : AuditService{ + fun showAnswer(vo: ShowAnswerVo): List { return transaction { - val join=JoinAssociation.findById(vo.joinId)?:throw IllegalArgumentException("找不到[id=${vo.joinId}]申请记录") - Answer.find{ Answers.joinId eq join.id }.map { - ApplyAnswerVo(examVo = toExamVo(it.question),answer = it.answer) + val join = JoinAssociation.findById(vo.joinId) ?: throw IllegalArgumentException("找不到[id=${vo.joinId}]申请记录") + Answer.find { Answers.joinId eq join.id }.map { + ApplyAnswerVo(examVo = toExamVo(it.question), answer = it.answer) } } } @@ -882,10 +895,10 @@ object AssociationService : AuditService{ + fun createPaper(vo: SearchExamVo): List { return transaction { - val association= Association.findById(vo.associationId)?:throw AssociationIdError(vo.associationId) + val association = Association.findById(vo.associationId) ?: throw AssociationIdError(vo.associationId) Question.find { Questions.associationId eq association.id }.let { it -> it.shuffled().map { toExamVo(question = it) @@ -907,9 +920,11 @@ object AssociationService : AuditService - //题库需要满足最少题目数才能生成试卷 - if(it.count()>=QUESTION_MIN_SIZE){ - ApplyAssociationResultVo(result = true,hasPaper = true) - } - //免试入团申请 - else{ - createJoin(association=association,user=user) - createJoinNotification(association=association,user=user) - ApplyAssociationResultVo(result = true,hasPaper = false) - } - } + fun applyAssociation(vo: SearchExamVo): ApplyAssociationResultVo { + return transaction { + val user = User.findById(vo.token.id) ?: throw UserIdError(vo.token.id) + val association = Association.findById(vo.associationId) ?: throw AssociationIdError(vo.associationId) + JoinAssociation.find { JoinAssociations.userId eq vo.token.id and (JoinAssociations.result eq null) } + .firstOrNull().let { + if (it != null) { + return@transaction ApplyAssociationResultVo(associationVo = toAssociationVo(it.association)) + } + } + + Question.find { Questions.associationId eq association.id }.let { it -> + //题库需要满足最少题目数才能生成试卷 + if (it.count() >= QUESTION_MIN_SIZE) { + ApplyAssociationResultVo(result = true, hasPaper = true) + } + //免试入团申请 + else { + createJoin(association = association, user = user) + createJoinNotification(association = association, user = user) + ApplyAssociationResultVo(result = true, hasPaper = false) + } + } } } @@ -952,11 +968,12 @@ object AssociationService : AuditService{ + fun joinAssociation(vo: SearchExamVo): List { return transaction { - val association=Association.findById(vo.associationId)?:throw AssociationIdError(vo.associationId) - JoinAssociation.find { JoinAssociations.associationId eq association.id }.sortedByDescending { it.applyTime }.map { - toJoinVo(join=it) + val association = Association.findById(vo.associationId) ?: throw AssociationIdError(vo.associationId) + JoinAssociation.find { JoinAssociations.associationId eq association.id } + .sortedByDescending { it.applyTime }.map { + toJoinVo(join = it) } } } @@ -965,16 +982,16 @@ object AssociationService : AuditService + vo.questions.forEach { exam -> exam.questionId.let { if (it == null) { Question.new { @@ -1228,6 +1244,52 @@ object ActivityService : AuditService { + val user=User.findById(userId)?:throw UserIdError(userId) + val activity=Activity.findById(activityId)?:throw ActivityIdError(activityId) + return Tendency.find { Tendencies.userId eq user.id and (Tendencies.activityId eq activity.id) and + (Tendencies.type eq type.ordinal) } + } + + + + fun checkTendency(vo: CheckTendencyVo):CheckTendencyResVo{ + return transaction { + val hasLike= checkTendency(userId = vo.token.id,activityId = vo.activityId,type = TendencyType.Like).count()==1L + val hasCollect=checkTendency(userId = vo.token.id,activityId = vo.activityId,type = TendencyType.Collect).count()==1L + CheckTendencyResVo(hasLike=hasLike,hasCollect=hasCollect) + } + } + + fun findTendency(vo:FindTendencyVo):List{ + return transaction { + val user=User.findById(vo.token.id)?:throw UserIdError(vo.token.id) + Tendency.find { Tendencies.userId eq user.id and (Tendencies.type eq vo.type.ordinal) }.map { + toActivityVo(activity = it.activity) + } + } + } + + /** + * 活动倾向 + * + */ + fun tendency(vo: TendencyVo) { + transaction { + checkTendency(userId = vo.token.id,activityId = vo.activityId,type = vo.type).apply { + if (count() == 1L) { + first().delete() + } else { + Tendency.new { + this.user= User[vo.token.id] + this.activity= Activity[vo.activityId] + this.type=vo.type.ordinal + } + } + } + } + } + /** * 查看活动信息 *