题库接口

master
pan 4 years ago
parent 99b2545925
commit 484ecc4ad9
  1. 99
      module/src/main/kotlin/com/gyf/csams/module/ShareVo.kt
  2. 0
      resources/static/image/.gitkeep
  3. 95
      src/main/kotlin/com/gyf/csams/Controller.kt
  4. 72
      src/main/kotlin/com/gyf/csams/Dao.kt
  5. 2
      src/main/kotlin/com/gyf/csams/MySQL.kt
  6. 507
      src/main/kotlin/com/gyf/csams/Service.kt
  7. 3
      test/ApplicationTest.kt

@ -623,4 +623,101 @@ data class ManagerDutyVo(val manager: ManagerInfoVo,val people:Int)
data class ManagerDutySumVo(val secretariat:ManagerDutyVo, data class ManagerDutySumVo(val secretariat:ManagerDutyVo,
val propaganda:ManagerDutyVo, val propaganda:ManagerDutyVo,
val publicRelationsDepartment:ManagerDutyVo) val publicRelationsDepartment:ManagerDutyVo)
data class ExamVo(val questionId:Int?=null,val question:String,val optionsA:String,val optionsB:String,val optionsC:String,val optionsD:String,val answer:Int)
/**
* 更新题库
*
* @property questions
* @property token
* @property clientType
*/
data class AddExamVo(val questions:List<ExamVo>,
val deleteIds:List<Int>?=null,
override val token: Token,
override val clientType: ClientType=ClientType.Foreground,
val associationId:Int):ClientBaseVo()
data class SearchExamVo(val associationId:Int, override val token: Token, override val clientType: ClientType=ClientType.Foreground):ClientBaseVo()
/**
* 试卷
*
* @property user
* @property createTime
* @property applyTime
*/
data class TestPaperVo(val user: UserInfoVo,val createTime: Long,val applyTime: Long?)
/**
* 试题
*
*/
data class AnswerVo(val examVo: ExamVo,val answer:Int?=null,val paperVo: TestPaperVo)
/**
* 答题记录
*
* @property questionId
* @property paperId
* @property answer
*/
data class ApplyAnswerVo(val questionId:Int,val paperId:Int,val answer:Int)
/**
* 答卷
*
* @property answers
* @property token
* @property clientType
*/
data class AddAnswerVo(val answers:List<ApplyAnswerVo>,
val associationId:Int,
override val token: Token, override val clientType: ClientType=ClientType.Foreground):ClientBaseVo()
data class ShowAnswerVo(val joinId:Int, override val token: Token,
override val clientType: ClientType=ClientType.Foreground):ClientBaseVo()
/**
* 申请入团
*
* @property associationId
* @property token
* @property clientType
*/
data class ApplyAssociationVo(val associationId:Int, override val token: Token, override val clientType: ClientType=ClientType.Foreground):ClientBaseVo()
/**
* 申请入团检查
*/
data class ApplyAssociationResultVo(val result:Boolean?=null,val hasPaper:Boolean?=null,val associationVo: AssociationVo?=null)
/**
* 申请入团记录
*
*/
data class JoinAssociationVo(val id:Int,val user: UserInfoVo,
val associationVo: AssociationVo,
val hasPaper: Boolean,
val result: Boolean?=null,
val applyTime: Long,
val auditTime: Long?=null)
/**
* 审核结果
*
* @property joinId
* @property result
*/
data class AuditJoinVo(val joinId:Int, val result:Boolean,
override val token: Token,
override val clientType: ClientType=ClientType.Foreground
):ClientBaseVo()
const val QUESTION_MIN_SIZE=5

@ -350,6 +350,101 @@ fun Application.AssociationController() {
check(AssociationService) check(AssociationService)
read(AssociationService,Associations) read(AssociationService,Associations)
post("/update/exam"){
call.withToken<AddExamVo> {
try {
AssociationService.updateExam(vo=it)
call.respond(ApiResponse(message = "题库更新成功",body=true))
} catch (e: Exception) {
log.error(e)
call.respond(ApiResponse(message = "题库更新失败",body=false))
}
}
}
post("/load/exam"){
call.withToken<SearchExamVo> {
try {
call.respond(ApiResponse(message = "加载题库",body = AssociationService.loadExam(vo = it)))
} catch (e: Exception) {
log.error(e)
call.respond(ApiResponse(message = "题库加载失败",body = null))
}
}
}
post("/check/apply"){
call.withToken<ApplyAssociationVo> {
try {
val body=AssociationService.applyAssociation(vo = it)
call.respond(ApiResponse(message = "入团验证信息获取成功",body =body))
} catch (e: Exception) {
log.error(e)
call.respond(ApiResponse(message = "入团验证信息获取失败",body=null))
}
}
}
post("/create/paper"){
call.withToken<ApplyAssociationVo> {
try {
call.respond(ApiResponse(message = "试卷创建成功,请开始作答",body = AssociationService.createPaper(vo=it)))
} catch (e: Exception) {
log.error(e)
call.respond(ApiResponse(message = "试卷创建失败",body=null))
}
}
}
post("/apply/paper"){
call.withToken<AddAnswerVo> {
try {
AssociationService.applyAnswer(vo=it)
call.respond(ApiResponse(message = "提交成功",body = true))
} catch (e: Exception) {
log.error(e)
call.respond(ApiResponse(message = "提交成功",body = false))
}
}
}
post("/check/join"){
call.withToken<ApplyAssociationVo> {
try {
call.respond(ApiResponse(message = "入团记录查询成功",body=AssociationService.joinAssociation(vo=it)))
} catch (e: Exception) {
log.error(e)
call.respond(ApiResponse(message = "入团记录查询失败",body=null))
}
}
}
post("/audit/join"){
call.withToken<AuditJoinVo> {
try {
AssociationService.auditJoin(vo = it)
call.respond(ApiResponse(message = "审核成功",body=true))
} catch (e: Exception) {
log.error(e)
call.respond(ApiResponse(message = "审核失败",body=false))
}
}
}
post("/show/answer"){
call.withToken<ShowAnswerVo> {
try {
call.respond(ApiResponse(message = "查看答案成功",body = AssociationService.showAnswer(vo=it)))
} catch (e: Exception) {
log.error(e)
call.respond(ApiResponse(message = "查看答案失败",body=null))
}
}
}
route("/rename"){ route("/rename"){
register(RenameService) register(RenameService)

@ -1,5 +1,7 @@
package com.gyf.csams package com.gyf.csams
import com.gyf.csams.Notifications.defaultExpression
import com.gyf.csams.TestPapers.defaultExpression
import org.jetbrains.exposed.dao.IntEntity import org.jetbrains.exposed.dao.IntEntity
import org.jetbrains.exposed.dao.IntEntityClass import org.jetbrains.exposed.dao.IntEntityClass
import org.jetbrains.exposed.dao.id.EntityID import org.jetbrains.exposed.dao.id.EntityID
@ -413,6 +415,9 @@ object Questions:IntIdTable(){
@TableComment("选项D") @TableComment("选项D")
val optionsD:Column<String> = varchar("optionsD",15) val optionsD:Column<String> = varchar("optionsD",15)
@TableComment("答案")
val answer:Column<Int> = integer("answer")
@TableComment("所属社团") @TableComment("所属社团")
val associationId:Column<EntityID<Int>> = reference("association_id",Associations) val associationId:Column<EntityID<Int>> = reference("association_id",Associations)
} }
@ -424,12 +429,77 @@ class Question(id:EntityID<Int>):IntEntity(id){
var optionsB by Questions.optionsB var optionsB by Questions.optionsB
var optionsC by Questions.optionsC var optionsC by Questions.optionsC
var optionsD by Questions.optionsD var optionsD by Questions.optionsD
var answer by Questions.answer
var association by Association referencedOn Questions.associationId
} }
@TableComment("试卷") @TableComment("试卷")
object TestPapers:IntIdTable(){ object TestPapers:IntIdTable(){
@TableComment("答题用户")
val userId:Column<EntityID<Int>> = reference("user_id",Users)
@TableComment("生成时间")
val createTime:Column<LocalDateTime> = datetime("create_time").defaultExpression(CurrentDateTime())
@TableComment("提交时间")
val applyTime:Column<LocalDateTime?> = datetime("apply_time").nullable()
}
class TestPaper(id:EntityID<Int>):IntEntity(id){
companion object:IntEntityClass<TestPaper>(TestPapers)
var user by User referencedOn TestPapers.userId
var createTime by TestPapers.createTime
var applyTime by TestPapers.applyTime
}
@TableComment("试题")
object Answers:IntIdTable(){
@TableComment("问题") @TableComment("问题")
val questionId:Column<EntityID<Int>> = reference("question_id",Questions) val questionId:Column<EntityID<Int>> = reference("question_id",Questions)
@TableComment("答案")
val answer:Column<Int?> = integer("answer").nullable()
@TableComment("试卷")
val paperId:Column<EntityID<Int>> = reference("paper_id",TestPapers)
}
class Answer(id:EntityID<Int>):IntEntity(id){
companion object:IntEntityClass<Answer>(Answers)
var question by Question referencedOn Answers.questionId
var answer by Answers.answer
var paper by TestPaper referencedOn Answers.paperId
}
} @TableComment("入团申请记录")
object JoinAssociations:IntIdTable(){
@TableComment("申请人")
val userId:Column<EntityID<Int>> = reference("user_id",Users)
@TableComment("申请社团")
val associationId:Column<EntityID<Int>> = reference("association_id",Associations)
@TableComment("申请时间")
val applyTime:Column<LocalDateTime> = datetime("create_time").defaultExpression(CurrentDateTime())
@TableComment("审核时间")
val auditTime:Column<LocalDateTime?> = datetime("audit_time").nullable()
@TableComment("试卷")
val paperId:Column<EntityID<Int>?> = reference("paper_id",TestPapers).nullable()
@TableComment("申请结果")
val result:Column<Boolean?> = bool("result").nullable()
}
class JoinAssociation(id:EntityID<Int>):IntEntity(id){
companion object:IntEntityClass<JoinAssociation>(JoinAssociations)
var user by User referencedOn JoinAssociations.userId
var association by Association referencedOn JoinAssociations.associationId
var paper by TestPaper optionalReferencedOn JoinAssociations.paperId
var result by JoinAssociations.result
var applyTime by JoinAssociations.applyTime
var auditTime by JoinAssociations.auditTime
}

@ -42,7 +42,7 @@ fun initTable(){
transaction { transaction {
val tableList= arrayOf(Users,UserTokens,Managers,ManagerTokens,AuditLeggings,LeaveMessages, val tableList= arrayOf(Users,UserTokens,Managers,ManagerTokens,AuditLeggings,LeaveMessages,
ImageFiles,Associations,AssociationMembers,Notifications,Activities,PhotoAlbums,ActivityComments, ImageFiles,Associations,AssociationMembers,Notifications,Activities,PhotoAlbums,ActivityComments,
Renames) Renames,Questions,TestPapers,Answers,JoinAssociations)
SchemaUtils.createMissingTablesAndColumns(*tableList) SchemaUtils.createMissingTablesAndColumns(*tableList)
updateComment(*tableList) updateComment(*tableList)

@ -64,10 +64,10 @@ object AccountService : AbstractService() {
} }
} }
fun login(vo:BaseLoginVo,ip:String):OwnInfoVo{ fun login(vo: BaseLoginVo, ip: String): OwnInfoVo {
return when (vo) { return when (vo) {
is UserLoginVo -> login(vo,ip) is UserLoginVo -> login(vo, ip)
is ManagerLoginVo -> login(vo,ip) is ManagerLoginVo -> login(vo, ip)
else -> throw IllegalArgumentException("vo:${vo::class.java}类型不合法") else -> throw IllegalArgumentException("vo:${vo::class.java}类型不合法")
} }
} }
@ -199,7 +199,6 @@ object AccountService : AbstractService() {
} }
fun getManagerVo(token: Token): ManagerVo { fun getManagerVo(token: Token): ManagerVo {
return transaction { return transaction {
val c = ManagerToken.find { val c = ManagerToken.find {
@ -249,10 +248,10 @@ object AccountService : AbstractService() {
} }
fun <T : ClientBaseVo> validToken(vo: T): Boolean { fun <T : ClientBaseVo> validToken(vo: T): Boolean {
return when(vo.clientType){ return when (vo.clientType) {
ClientType.Foreground->validUserToken(vo.token) ClientType.Foreground -> validUserToken(vo.token)
ClientType.Background-> validManagerToken(vo.token) ClientType.Background -> validManagerToken(vo.token)
else->throw IllegalArgumentException("不清楚是来自哪个平台的token信息") else -> throw IllegalArgumentException("不清楚是来自哪个平台的token信息")
} }
} }
@ -343,7 +342,8 @@ object FileService : AbstractService() {
super.init(environment) super.init(environment)
this.uploadDir = environment.config.property("ktor.deployment.filePath").getString() this.uploadDir = environment.config.property("ktor.deployment.filePath").getString()
filePath = this::class.java.classLoader.getResource(uploadDir)?.path ?: throw IllegalArgumentException("初始化资源目录失败") filePath =
this::class.java.classLoader.getResource(uploadDir)?.path ?: throw IllegalArgumentException("初始化资源目录失败")
File(filePath).let { File(filePath).let {
when { when {
it.exists() -> log.info("上传路径[${filePath}]已存在") it.exists() -> log.info("上传路径[${filePath}]已存在")
@ -375,9 +375,9 @@ object FileService : AbstractService() {
throw IllegalArgumentException("找不到key:${key}") throw IllegalArgumentException("找不到key:${key}")
} }
fun List<PartData>.getFormParam(key:String):String{ fun List<PartData>.getFormParam(key: String): String {
forEach { forEach {
if(it.name==key && it is PartData.FormItem){ if (it.name == key && it is PartData.FormItem) {
return it.value return it.value
} }
} }
@ -385,9 +385,9 @@ object FileService : AbstractService() {
} }
fun storeFile(data: List<PartData>): List<Int>? { fun storeFile(data: List<PartData>): List<Int>? {
val userId = data.getFormParam(key="id") val userId = data.getFormParam(key = "id")
val token = data.getFormParam(key="token") val token = data.getFormParam(key = "token")
val createTime = data.getFormParam(key="createTime") val createTime = data.getFormParam(key = "createTime")
val tokenVo = Token(token = token, id = userId.toInt(), createTime = createTime.toLong()) val tokenVo = Token(token = token, id = userId.toInt(), createTime = createTime.toLong())
if (AccountService.validUserToken(tokenVo)) { if (AccountService.validUserToken(tokenVo)) {
val fileIds = mutableListOf<Int>() val fileIds = mutableListOf<Int>()
@ -482,8 +482,12 @@ abstract class AuditService<T, E, F> : AbstractService() {
*/ */
abstract fun findEntity(auditId: Int): AbstractAudit abstract fun findEntity(auditId: Int): AbstractAudit
protected inline fun <reified E:AbstractAudit,reified Row:IntEntityClass<E>,reified Table:AbstractAudits> testFind(table:Table,row:Row,auditId: Int): E { protected inline fun <reified E : AbstractAudit, reified Row : IntEntityClass<E>, reified Table : AbstractAudits> testFind(
return row.find { table.auditId eq auditId } .firstOrNull() ?: throw AuditIdError(auditId) table: Table,
row: Row,
auditId: Int
): E {
return row.find { table.auditId eq auditId }.firstOrNull() ?: throw AuditIdError(auditId)
} }
/** /**
@ -513,7 +517,7 @@ abstract class AuditService<T, E, F> : AbstractService() {
* 通过审核后 * 通过审核后
* *
*/ */
protected open fun afterAudit(entity: AbstractAudit){} protected open fun afterAudit(entity: AbstractAudit) {}
/** /**
* 资料受理 * 资料受理
@ -608,7 +612,7 @@ abstract class AuditService<T, E, F> : AbstractService() {
} }
//过滤完成的审核记录?(可多次提交的资料) //过滤完成的审核记录?(可多次提交的资料)
open val isFilter:Boolean=true open val isFilter: Boolean = true
/** /**
* TODO 审核进度查询 * TODO 审核进度查询
@ -616,19 +620,19 @@ abstract class AuditService<T, E, F> : AbstractService() {
*/ */
fun read(vo: OnlyToken, table: IntIdTable): F? { fun read(vo: OnlyToken, table: IntIdTable): F? {
return transaction { return transaction {
if(isFilter){ if (isFilter) {
val nextAudit = AuditLeggings.alias("nextAudit") val nextAudit = AuditLeggings.alias("nextAudit")
table.innerJoin(AuditLeggings) table.innerJoin(AuditLeggings)
.innerJoin(nextAudit, { AuditLeggings.nextAudit }, { nextAudit[AuditLeggings.id] }) .innerJoin(nextAudit, { AuditLeggings.nextAudit }, { nextAudit[AuditLeggings.id] })
.innerJoin(Users) .innerJoin(Users)
.slice(listOf(table.id)) .slice(listOf(table.id))
.select {Users.id eq vo.token.id and (nextAudit[AuditLeggings.result] neq true)} .select { Users.id eq vo.token.id and (nextAudit[AuditLeggings.result] neq true) }
.firstOrNull() .firstOrNull()
?.let { it -> ?.let { it ->
getCheckVo(id = it[table.id]) getCheckVo(id = it[table.id])
} }
}else { } else {
table.innerJoin(AuditLeggings).innerJoin(Users) table.innerJoin(AuditLeggings).innerJoin(Users)
.slice(listOf(table.id)) .slice(listOf(table.id))
.select { Users.id eq vo.token.id } .select { Users.id eq vo.token.id }
@ -647,7 +651,7 @@ abstract class AuditService<T, E, F> : AbstractService() {
return AuditCheckVo( return AuditCheckVo(
checkStatus = when { checkStatus = when {
audit.nextAudit == null && audit.manager == null -> CheckStatus.WaitFirst audit.nextAudit == null && audit.manager == null -> CheckStatus.WaitFirst
audit.nextAudit == null && audit.manager != null && audit.result==null -> CheckStatus.AcceptFirst audit.nextAudit == null && audit.manager != null && audit.result == null -> CheckStatus.AcceptFirst
audit.nextAudit != null && audit.nextAudit?.manager == null -> CheckStatus.WaitLast audit.nextAudit != null && audit.nextAudit?.manager == null -> CheckStatus.WaitLast
audit.nextAudit != null && audit.nextAudit?.result == null -> CheckStatus.AcceptLast audit.nextAudit != null && audit.nextAudit?.result == null -> CheckStatus.AcceptLast
else -> CheckStatus.Finish else -> CheckStatus.Finish
@ -655,7 +659,7 @@ abstract class AuditService<T, E, F> : AbstractService() {
applyTime = audit.applyTime.toLong(), applyTime = audit.applyTime.toLong(),
firstCause = audit.cause ?: "", firstCause = audit.cause ?: "",
lastCause = audit.nextAudit?.cause, lastCause = audit.nextAudit?.cause,
result=audit.nextAudit?.result==true result = audit.nextAudit?.result == true
) )
} }
@ -687,7 +691,11 @@ abstract class AuditService<T, E, F> : AbstractService() {
val auditLogging = AuditLoggingVo( val auditLogging = AuditLoggingVo(
id = logging.id.value, id = logging.id.value,
user = user =
UserInfoVo(name = logging.user.name, headImg = logging.user.headImg?.filepath, desc = logging.user.desc), UserInfoVo(
name = logging.user.name,
headImg = logging.user.headImg?.filepath,
desc = logging.user.desc
),
applyTime = logging.applyTime.toLong(), applyTime = logging.applyTime.toLong(),
manager = logging.manager?.let { manager = logging.manager?.let {
ManagerInfoVo( ManagerInfoVo(
@ -707,7 +715,7 @@ abstract class AuditService<T, E, F> : AbstractService() {
} }
} }
protected fun createNotifications(vo:ClientBaseVo,user:User){ protected fun createNotifications(vo: ClientBaseVo, user: User) {
foreground( foreground(
receiverId = vo.token.id, receiverId = vo.token.id,
content = "您成功提交了一份${dataType},请耐心等待后台受理" content = "您成功提交了一份${dataType},请耐心等待后台受理"
@ -727,7 +735,7 @@ object AssociationService : AuditService<AssociationRegVo, AuditAssociationVo, A
override val dataType: String = "社团注册资料" override val dataType: String = "社团注册资料"
override fun findEntity(auditId: Int): AbstractAudit { override fun findEntity(auditId: Int): AbstractAudit {
return testFind(Associations,Association,auditId) return testFind(Associations, Association, auditId)
} }
override val isFilter: Boolean = false override val isFilter: Boolean = false
@ -743,7 +751,7 @@ object AssociationService : AuditService<AssociationRegVo, AuditAssociationVo, A
} }
} }
fun Association.set(vo:AssociationRegVo,user:User){ fun Association.set(vo: AssociationRegVo, user: User) {
name = vo.name name = vo.name
desc = vo.desc desc = vo.desc
logo = ImageFile.findById(vo.fileId) ?: throw FileIdError(vo.fileId) logo = ImageFile.findById(vo.fileId) ?: throw FileIdError(vo.fileId)
@ -752,7 +760,12 @@ object AssociationService : AuditService<AssociationRegVo, AuditAssociationVo, A
} }
} }
fun loadAll():List<AssociationVo>{ /**
* 加载所有社团
*
* @return
*/
fun loadAll(): List<AssociationVo> {
return transaction { return transaction {
Association.all().map { Association.all().map {
toAssociationVo(it) toAssociationVo(it)
@ -760,13 +773,265 @@ object AssociationService : AuditService<AssociationRegVo, AuditAssociationVo, A
} }
} }
fun update(vo:AssociationVo){ private fun toExamVo(question:Question):ExamVo{
return ExamVo(questionId = question.id.value,question=question.question,optionsA = question.optionsA,
optionsB = question.optionsB,optionsC = question.optionsC,optionsD = question.optionsD,answer = question.answer)
}
/**
* 加载题库
*
* @param vo
* @return
*/
fun loadExam(vo:SearchExamVo):List<ExamVo>{
return transaction {
Question.find { Questions.associationId eq vo.associationId }.map {
toExamVo(question = it)
}
}
}
/**
* 提交答卷
*
*/
fun applyAnswer(vo:AddAnswerVo){
transaction {
val association= Association.findById(vo.associationId)?:throw AssociationIdError(vo.associationId)
val user=User.findById(vo.token.id)?:throw UserIdError(vo.token.id)
vo.answers.forEach {
val question=Question.findById(it.questionId)?:throw IllegalArgumentException("不存在[id=${it.questionId}]的问题")
val paper=TestPaper.findById(it.paperId)?:throw IllegalArgumentException("不存在[id=${it.paperId}]的问题")
Answer.new {
this.question=question
answer=it.answer
this.paper=paper
}
}
createJoin(association = association,user=user)
}
}
/**
* 显示答卷
*
* @param vo
* @return
*/
fun showAnswer(vo:ShowAnswerVo):List<AnswerVo>{
return transaction {
val join=JoinAssociation.findById(vo.joinId)?:throw IllegalArgumentException("找不到[id=${vo.joinId}]申请记录")
val paperId= join.paper?.id?:throw IllegalArgumentException("[id=${join.id}]没有关联试卷")
val paper=TestPaper.findById(paperId)?:throw IllegalArgumentException("[id=${paperId}]关联的试卷不存在")
Answer.find { Answers.paperId eq paperId}.map {
AnswerVo(examVo = toExamVo(it.question),answer = it.answer,paperVo =
TestPaperVo(user = UserInfoVo(name=join.user.name,headImg = join.user.headImg?.filepath,desc=join.user.desc),
createTime = paper.createTime.toLong(),applyTime = paper.applyTime?.toLong()))
}
}
}
/**
* 创建申请记录
*
* @param association
* @param user
*/
private fun createJoin(association: Association,user:User){
JoinAssociation.new {
this.association=association
this.user=user
}.apply {
//通知团长处理
AssociationMember.find { AssociationMembers.associationId eq association.id and
(AssociationMembers.isHead eq true) }.firstOrNull()?.apply {
Notification.new {
this.title = "入团申请通知"
this.content = "用户${user.name}申请加入社团"
this.receiverId = user.id.value
receiverClient = ClientType.Foreground.name
}
}
}
}
/**
* 生成试卷
*
* @param vo
* @return
*/
fun createPaper(vo:ApplyAssociationVo):List<ExamVo>{
return transaction {
val association= Association.findById(vo.associationId)?:throw AssociationIdError(vo.associationId)
val user=User.findById(vo.token.id)?:throw UserIdError(vo.token.id)
Question.find { Questions.associationId eq association.id }.let { it ->
val paper=TestPaper.new {
this.user=user
this.applyTime= LocalDateTime.now()
}
it.shuffled().apply {
forEach {
Answer.new {
this.paper=paper
this.question=it
}
}
}.map {
toExamVo(question = it)
}
}
}
}
/**
* 申请入团
*
*/
fun applyAssociation(vo:ApplyAssociationVo):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)
ApplyAssociationResultVo(result = true,hasPaper = false)
}
}
}
}
/**
* 入团申请记录
*
*/
fun joinAssociation(vo:ApplyAssociationVo):List<JoinAssociationVo>{
return transaction {
val association=Association.findById(vo.associationId)?:throw AssociationIdError(vo.associationId)
val user=User.findById(vo.token.id)?:throw UserIdError(vo.token.id)
JoinAssociation.find { JoinAssociations.associationId eq association.id }.map {
val userInfoVo=UserInfoVo(name = user.name,headImg = user.headImg?.filepath,desc=user.desc)
JoinAssociationVo(user = userInfoVo,
associationVo = toAssociationVo(it.association),
hasPaper = it.paper!=null,result = it.result,
applyTime = it.applyTime.toLong(),
auditTime = it.auditTime?.toLong(),id = it.id.value)
}
}
}
/**
* 审核入团申请
* @param vo
*/
fun auditJoin(vo:AuditJoinVo){
transaction {
val join=JoinAssociation.findById(vo.joinId)?:throw IllegalArgumentException("审核记录不存在")
join.result=vo.result
join.auditTime= LocalDateTime.now()
if(vo.result){
AssociationMember.new {
user=join.user
association=join.association
isHead=false
}
//入团申请通过,通知社团其他人
AssociationMember.find { AssociationMembers.associationId eq join.association.id }.forEach {
Notification.new {
this.title = "入团通知"
this.content = "欢迎新人${join.user.name}加入社团"
this.receiverId = it.user.id.value
receiverClient = ClientType.Foreground.name
}.apply {
log.info("通知前台用户${dataType}处理进度")
}
}
}
//把审核结果发送给申请人
Notification.new{
this.title="入团审核结果"
this.content="您申请加入${join.association.name}社团审核${if(vo.result)"通过" else "不通过"}"
this.receiverId=join.user.id.value
receiverClient=ClientType.Foreground.name
}
}
}
/**
* 更新题库
*
* @param vo
*/
fun updateExam(vo: AddExamVo) {
transaction {
val association=Association.findById(vo.associationId)?:throw IllegalArgumentException("找不到社团信息")
vo.deleteIds?.let {
//删除社团题目
Question.find { Questions.associationId eq association.id and (Questions.id inList it ) }.forEach {
log.info("删除[id=${it.id}]题目")
it.delete()
}
}
vo.questions.forEach {
exam->
exam.questionId.let {
if (it == null) {
Question.new {
question = exam.question
optionsA = exam.optionsA
optionsB = exam.optionsB
optionsC = exam.optionsC
optionsD = exam.optionsD
this.answer = exam.answer
this.association = association
}
} else {
log.info("更新[id=${it}]的题目")
Question.findById(it)?.apply {
question = exam.question
optionsA = exam.optionsA
optionsB = exam.optionsB
optionsC = exam.optionsC
optionsD = exam.optionsD
this.answer = exam.answer
}
}
}
}
}
}
/**
* 更新社团信息
*
* @param vo
*/
fun update(vo: AssociationVo) {
transaction { transaction {
Association.findById(vo.associationId).let { Association.findById(vo.associationId).let {
if(it==null){ if (it == null) {
throw AssociationIdError(vo.associationId) throw AssociationIdError(vo.associationId)
}else{ } else {
it.level=vo.level?.name it.level = vo.level?.name
} }
} }
} }
@ -785,7 +1050,7 @@ object AssociationService : AuditService<AssociationRegVo, AuditAssociationVo, A
if (vo.associationId != null) { if (vo.associationId != null) {
log.info("再次提交【${vo.name}】注册资料") log.info("再次提交【${vo.name}】注册资料")
(Association.findById(vo.associationId!!) ?: throw AuditIdError(vo.associationId!!)) (Association.findById(vo.associationId!!) ?: throw AuditIdError(vo.associationId!!))
.set(vo=vo,user=user) .set(vo = vo, user = user)
} else { } else {
val associationMember = AssociationMember.find { AssociationMembers.userId eq user.id }.firstOrNull() val associationMember = AssociationMember.find { AssociationMembers.userId eq user.id }.firstOrNull()
val association: Association? = associationMember?.association val association: Association? = associationMember?.association
@ -794,7 +1059,7 @@ object AssociationService : AuditService<AssociationRegVo, AuditAssociationVo, A
association != null && association.audit.result == null -> throw IllegalArgumentException("您已经提交过${dataType},请耐心等待后台管理员处理") association != null && association.audit.result == null -> throw IllegalArgumentException("您已经提交过${dataType},请耐心等待后台管理员处理")
association == null -> { association == null -> {
Association.new { Association.new {
set(vo=vo,user=user) set(vo = vo, user = user)
faculty = faculty(user.studentId).name faculty = faculty(user.studentId).name
} }
@ -802,7 +1067,7 @@ object AssociationService : AuditService<AssociationRegVo, AuditAssociationVo, A
} }
} }
createNotifications(vo=vo,user=user) createNotifications(vo = vo, user = user)
log.info("未审核社团:${vo.name}创建成功") log.info("未审核社团:${vo.name}创建成功")
} }
} }
@ -825,7 +1090,8 @@ object AssociationService : AuditService<AssociationRegVo, AuditAssociationVo, A
.select { .select {
nextAudit[AuditLeggings.result] eq true and (Associations.name like "%${vo.name}%") and (Associations.desc like "%${vo.desc}%") nextAudit[AuditLeggings.result] eq true and (Associations.name like "%${vo.name}%") and (Associations.desc like "%${vo.desc}%")
}.map { }.map {
val association=Association.findById(it[Associations.id])?:throw AssociationIdError(it[Associations.id].value) val association =
Association.findById(it[Associations.id]) ?: throw AssociationIdError(it[Associations.id].value)
toAssociationVo(association) toAssociationVo(association)
} }
} }
@ -929,24 +1195,26 @@ object AssociationService : AuditService<AssociationRegVo, AuditAssociationVo, A
/** /**
* 活动服务 * 活动服务
*/ */
object ActivityService : AuditService<ActivityApplyVo, AuditActVo,ActivityCheckVo>() { object ActivityService : AuditService<ActivityApplyVo, AuditActVo, ActivityCheckVo>() {
override val dataType: String = "活动申请书" override val dataType: String = "活动申请书"
override fun findEntity(auditId: Int): AbstractAudit { override fun findEntity(auditId: Int): AbstractAudit {
return testFind(Activities,Activity,auditId) return testFind(Activities, Activity, auditId)
} }
/** /**
* 查看活动信息 * 查看活动信息
* *
*/ */
fun listAll():List<ManagerActVo>{ fun listAll(): List<ManagerActVo> {
return transaction { return transaction {
Activity.all().map { Activity.all().map {
ManagerActVo(association = AssociationService.toAssociationVo(it.association), ManagerActVo(
score = (1..5).random(),activityVo = toActivityVo(it)) association = AssociationService.toAssociationVo(it.association),
score = (1..5).random(), activityVo = toActivityVo(it)
)
} }
} }
} }
@ -956,12 +1224,14 @@ object ActivityService : AuditService<ActivityApplyVo, AuditActVo,ActivityCheckV
* *
* @return * @return
*/ */
fun random():List<MainActivityPhotoVo>{ fun random(): List<MainActivityPhotoVo> {
return transaction { return transaction {
PhotoAlbum.all().shuffled().map { PhotoAlbum.all().shuffled().map {
MainActivityPhotoVo(url=it.photo.filepath, MainActivityPhotoVo(
url = it.photo.filepath,
activityVo = toActivityVo(it.activity), activityVo = toActivityVo(it.activity),
associationVo = AssociationService.toAssociationVo(it.activity.association)) associationVo = AssociationService.toAssociationVo(it.activity.association)
)
} }
} }
} }
@ -971,18 +1241,18 @@ object ActivityService : AuditService<ActivityApplyVo, AuditActVo,ActivityCheckV
* *
* @param data * @param data
*/ */
fun upload(data: List<PartData>){ fun upload(data: List<PartData>) {
val activityId=data.getFormParam("activityId") val activityId = data.getFormParam("activityId")
val name=data.getFormParam("name") val name = data.getFormParam("name")
transaction { transaction {
(Activity.findById(activityId.toInt())?:throw IllegalArgumentException("活动id参数有误:${activityId}")).apply { (Activity.findById(activityId.toInt()) ?: throw IllegalArgumentException("活动id参数有误:${activityId}")).apply {
val fileId=FileService.storeFile(data) val fileId = FileService.storeFile(data)
//保存到相册 //保存到相册
fileId?.forEach { fileId?.forEach {
PhotoAlbum.new { PhotoAlbum.new {
activity=this@apply activity = this@apply
photo=ImageFile.findById(it)?:throw FileIdError(it) photo = ImageFile.findById(it) ?: throw FileIdError(it)
this.name=name this.name = name
}.let { }.let {
log.info("保存照片:${it.name}") log.info("保存照片:${it.name}")
} }
@ -996,12 +1266,12 @@ object ActivityService : AuditService<ActivityApplyVo, AuditActVo,ActivityCheckV
* *
* @param vo * @param vo
*/ */
fun sendComment(vo:SendBBSVo){ fun sendComment(vo: SendBBSVo) {
transaction { transaction {
ActivityComment.new { ActivityComment.new {
content=vo.content content = vo.content
user=User.findById(vo.token.id)?:throw UserIdError(vo.token.id) user = User.findById(vo.token.id) ?: throw UserIdError(vo.token.id)
activity=Activity.findById(vo.activityId)?:throw ActivityIdError(vo.activityId) activity = Activity.findById(vo.activityId) ?: throw ActivityIdError(vo.activityId)
} }
} }
} }
@ -1012,11 +1282,13 @@ object ActivityService : AuditService<ActivityApplyVo, AuditActVo,ActivityCheckV
* @param vo * @param vo
* @return * @return
*/ */
fun loadComment(vo: SearchCommentVo):List<BBSVo>{ fun loadComment(vo: SearchCommentVo): List<BBSVo> {
return transaction { return transaction {
ActivityComment.find { ActivityComments.activityId eq vo.activityId }.map { ActivityComment.find { ActivityComments.activityId eq vo.activityId }.map {
BBSVo(user = UserInfoVo(name=it.user.name,headImg = it.user.headImg?.filepath,desc = it.user.desc), BBSVo(
createTime = it.createTime.toLong(),content = it.content) user = UserInfoVo(name = it.user.name, headImg = it.user.headImg?.filepath, desc = it.user.desc),
createTime = it.createTime.toLong(), content = it.content
)
} }
} }
} }
@ -1027,21 +1299,20 @@ object ActivityService : AuditService<ActivityApplyVo, AuditActVo,ActivityCheckV
* @param vo * @param vo
* @return * @return
*/ */
fun load(vo:SearchActivityPhotoVo):List<ActivityPhotoVo>{ fun load(vo: SearchActivityPhotoVo): List<ActivityPhotoVo> {
return transaction { return transaction {
PhotoAlbum.find { PhotoAlbums.activityId eq vo.activityId }.map { PhotoAlbum.find { PhotoAlbums.activityId eq vo.activityId }.map {
ActivityPhotoVo(name = it.name,url=it.photo.filepath) ActivityPhotoVo(name = it.name, url = it.photo.filepath)
} }
} }
} }
/** /**
* 活动列表 * 活动列表
* *
*/ */
fun load(vo:SearchActivityVo):List<ActivityVo>{ fun load(vo: SearchActivityVo): List<ActivityVo> {
return transaction { return transaction {
val nextAudit = AuditLeggings.alias("nextAudit") val nextAudit = AuditLeggings.alias("nextAudit")
return@transaction Activities.innerJoin(otherTable = AuditLeggings) return@transaction Activities.innerJoin(otherTable = AuditLeggings)
@ -1050,7 +1321,8 @@ object ActivityService : AuditService<ActivityApplyVo, AuditActVo,ActivityCheckV
.select { .select {
nextAudit[AuditLeggings.result] eq true and (Activities.associationId eq vo.associationId) nextAudit[AuditLeggings.result] eq true and (Activities.associationId eq vo.associationId)
}.map { }.map {
val activity=Activity.findById(it[Activities.id])?:throw ActivityIdError(it[Activities.id].value) val activity =
Activity.findById(it[Activities.id]) ?: throw ActivityIdError(it[Activities.id].value)
toActivityVo(activity = activity) toActivityVo(activity = activity)
} }
} }
@ -1062,17 +1334,19 @@ object ActivityService : AuditService<ActivityApplyVo, AuditActVo,ActivityCheckV
* @param vo * @param vo
* @return * @return
*/ */
fun show(vo:ShowActivityVo):ActivityDetailVo{ fun show(vo: ShowActivityVo): ActivityDetailVo {
return transaction { return transaction {
(Activity.findById(vo.activityId)?:throw ActivityIdError(vo.activityId)).let { (Activity.findById(vo.activityId) ?: throw ActivityIdError(vo.activityId)).let {
ActivityDetailVo(activityVo = toActivityVo(it),associationVo = AssociationService.toAssociationVo(it.association)) ActivityDetailVo(
activityVo = toActivityVo(it),
associationVo = AssociationService.toAssociationVo(it.association)
)
} }
} }
} }
fun Activity.set(activityVo: ActivityVo, user: User) {
fun Activity.set(activityVo:ActivityVo,user:User){
activityName = activityVo.activityName activityName = activityVo.activityName
activityTime = activityVo.activityTime.toLocalDateTime() activityTime = activityVo.activityTime.toLocalDateTime()
activityAddress = activityVo.activityAddress activityAddress = activityVo.activityAddress
@ -1095,7 +1369,7 @@ object ActivityService : AuditService<ActivityApplyVo, AuditActVo,ActivityCheckV
//再次提交 //再次提交
log.info("再次提交【${vo.activityVo.activityName}${dataType}") log.info("再次提交【${vo.activityVo.activityName}${dataType}")
(Activity.findById(vo.activityVo.activityId!!) ?: throw ActivityIdError(vo.activityVo.activityId!!)) (Activity.findById(vo.activityVo.activityId!!) ?: throw ActivityIdError(vo.activityVo.activityId!!))
.set(activityVo = vo.activityVo,user=user) .set(activityVo = vo.activityVo, user = user)
} else { } else {
//首次提交 //首次提交
//申请活动的限制 //申请活动的限制
@ -1105,18 +1379,19 @@ object ActivityService : AuditService<ActivityApplyVo, AuditActVo,ActivityCheckV
!activityMember.isHead -> throw IllegalArgumentException("不是社团团长无法申请活动") !activityMember.isHead -> throw IllegalArgumentException("不是社团团长无法申请活动")
else -> { else -> {
Activity.new { Activity.new {
set(vo.activityVo,user=user) set(vo.activityVo, user = user)
association = Association.findById(vo.associationId) ?: throw AssociationIdError(vo.associationId) association =
Association.findById(vo.associationId) ?: throw AssociationIdError(vo.associationId)
} }
} }
} }
} }
createNotifications(vo=vo,user=user) createNotifications(vo = vo, user = user)
} }
} }
private fun toActivityVo(activity:Activity):ActivityVo{ private fun toActivityVo(activity: Activity): ActivityVo {
return ActivityVo( return ActivityVo(
activityName = activity.activityName, activityTime = activity.activityTime.toLong(), activityName = activity.activityName, activityTime = activity.activityTime.toLong(),
activityAddress = activity.activityAddress, activityDesc = activity.activityDesc, activityAddress = activity.activityAddress, activityDesc = activity.activityDesc,
@ -1137,7 +1412,7 @@ object ActivityService : AuditService<ActivityApplyVo, AuditActVo,ActivityCheckV
} }
override fun getCheckVo(id: EntityID<Int>): ActivityCheckVo { override fun getCheckVo(id: EntityID<Int>): ActivityCheckVo {
return (Activity.findById(id) ?: throw ActivityIdError(id.value)).let { return (Activity.findById(id) ?: throw ActivityIdError(id.value)).let {
ActivityCheckVo( ActivityCheckVo(
activityVo = toActivityVo(activity = it), activityVo = toActivityVo(activity = it),
auditCheckVo = toCheckVo(it.audit) auditCheckVo = toCheckVo(it.audit)
@ -1150,13 +1425,13 @@ object ActivityService : AuditService<ActivityApplyVo, AuditActVo,ActivityCheckV
/** /**
* 重命名服务 * 重命名服务
*/ */
object RenameService : AuditService<RenameApplyVo,AuditRenameVo,RenameCheckVo>(){ object RenameService : AuditService<RenameApplyVo, AuditRenameVo, RenameCheckVo>() {
override val dataType: String = "换名申请表" override val dataType: String = "换名申请表"
fun Rename.set(vo:RenameVo,user:User){ fun Rename.set(vo: RenameVo, user: User) {
newName=vo.newName newName = vo.newName
cause=vo.cause cause = vo.cause
audit=AuditLogging.new { audit = AuditLogging.new {
this.user = user this.user = user
} }
} }
@ -1164,8 +1439,8 @@ object RenameService : AuditService<RenameApplyVo,AuditRenameVo,RenameCheckVo>()
//TODO 类型自动转换 //TODO 类型自动转换
override fun afterAudit(entity: AbstractAudit) { override fun afterAudit(entity: AbstractAudit) {
if(entity is Rename){ if (entity is Rename) {
entity.association.name=entity.newName entity.association.name = entity.newName
} }
} }
@ -1200,18 +1475,17 @@ object RenameService : AuditService<RenameApplyVo,AuditRenameVo,RenameCheckVo>()
} }
override fun findEntity(auditId: Int): AbstractAudit { override fun findEntity(auditId: Int): AbstractAudit {
return testFind(Renames,Rename,auditId) return testFind(Renames, Rename, auditId)
} }
private fun toRenameVo(rename: Rename):RenameVo{ private fun toRenameVo(rename: Rename): RenameVo {
return RenameVo(renameId = rename.id.value,newName = rename.newName,cause = rename.cause) return RenameVo(renameId = rename.id.value, newName = rename.newName, cause = rename.cause)
} }
override fun getCheckVo(id: EntityID<Int>): RenameCheckVo { override fun getCheckVo(id: EntityID<Int>): RenameCheckVo {
return (Rename.findById(id)?:throw IllegalArgumentException("找不到[id=${id}]${dataType}")).let { return (Rename.findById(id) ?: throw IllegalArgumentException("找不到[id=${id}]${dataType}")).let {
RenameCheckVo(renameVo = toRenameVo(it),auditCheckVo = toCheckVo(it.audit)) RenameCheckVo(renameVo = toRenameVo(it), auditCheckVo = toCheckVo(it.audit))
} }
} }
@ -1219,7 +1493,11 @@ object RenameService : AuditService<RenameApplyVo,AuditRenameVo,RenameCheckVo>()
return transaction { return transaction {
return@transaction createSortedBy(Rename).map { return@transaction createSortedBy(Rename).map {
val audit = toAuditLoggingVo(it.audit) ?: throw IllegalArgumentException("转换审核记录出错!!!!") val audit = toAuditLoggingVo(it.audit) ?: throw IllegalArgumentException("转换审核记录出错!!!!")
AuditRenameVo(renameVo = toRenameVo(rename = it),audit = audit,associationVo = AssociationService.toAssociationVo(it.association)) AuditRenameVo(
renameVo = toRenameVo(rename = it),
audit = audit,
associationVo = AssociationService.toAssociationVo(it.association)
)
}.apply { }.apply {
log.info("找到${this.size}${ActivityService.dataType}") log.info("找到${this.size}${ActivityService.dataType}")
} }
@ -1309,29 +1587,34 @@ object BackgroundService : AbstractService() {
} }
fun toManagerVo(manager: Manager):ManagerInfoVo{ fun toManagerVo(manager: Manager): ManagerInfoVo {
return ManagerInfoVo(duty = manager.duty.let { Duty.valueOf(it) },name=manager.name, return ManagerInfoVo(
headImg = manager.headImg?.filepath,desc = manager.desc) duty = manager.duty.let { Duty.valueOf(it) }, name = manager.name,
headImg = manager.headImg?.filepath, desc = manager.desc
)
} }
/** /**
* 加载部门部长和总人数 * 加载部门部长和总人数
* *
*/ */
fun load():ManagerDutySumVo{ fun load(): ManagerDutySumVo {
return transaction { return transaction {
val secretariat=Manager.find { Managers.duty eq Duty.SecretaryOfTheMinister.name }.first() val secretariat = Manager.find { Managers.duty eq Duty.SecretaryOfTheMinister.name }.first()
val secretariatCount=Manager.find{ Managers.duty eq Duty.SecretaryDepartmentOfficer.name }.count() val secretariatCount = Manager.find { Managers.duty eq Duty.SecretaryDepartmentOfficer.name }.count()
val propaganda=Manager.find {Managers.duty eq Duty.PropagandaDepartment.name }.first() val propaganda = Manager.find { Managers.duty eq Duty.PropagandaDepartment.name }.first()
val propagandaCount=Manager.find{ Managers.duty eq Duty.PublicityDepartmentOfficer.name }.count() val propagandaCount = Manager.find { Managers.duty eq Duty.PublicityDepartmentOfficer.name }.count()
val publicRelationsDepartment=Manager.find{ Managers.duty eq Duty.LiaisonMinister.name }.first() val publicRelationsDepartment = Manager.find { Managers.duty eq Duty.LiaisonMinister.name }.first()
val publicRelationsDepartmentCount=Manager.find{ Managers.duty eq Duty.LiaisonOfficer.name }.count() val publicRelationsDepartmentCount = Manager.find { Managers.duty eq Duty.LiaisonOfficer.name }.count()
ManagerDutySumVo(secretariat = ManagerDutyVo(manager = toManagerVo(secretariat),people = secretariatCount.toInt()), ManagerDutySumVo(
propaganda = ManagerDutyVo(manager = toManagerVo(propaganda),people = propagandaCount.toInt()), secretariat = ManagerDutyVo(manager = toManagerVo(secretariat), people = secretariatCount.toInt()),
publicRelationsDepartment = ManagerDutyVo(manager = toManagerVo(publicRelationsDepartment), propaganda = ManagerDutyVo(manager = toManagerVo(propaganda), people = propagandaCount.toInt()),
people=publicRelationsDepartmentCount.toInt())) publicRelationsDepartment = ManagerDutyVo(
manager = toManagerVo(publicRelationsDepartment),
people = publicRelationsDepartmentCount.toInt()
)
)
} }
} }
@ -1340,18 +1623,22 @@ object BackgroundService : AbstractService() {
* *
* @return * @return
*/ */
fun loadDetail():AllOfficerVo{ fun loadDetail(): AllOfficerVo {
return transaction { return transaction {
val secretariat=Manager.find{ Managers.duty eq Duty.SecretaryDepartmentOfficer.name }.map { val secretariat = Manager.find { Managers.duty eq Duty.SecretaryDepartmentOfficer.name }.map {
toManagerVo(it) toManagerVo(it)
} }
val propaganda=Manager.find {Managers.duty eq Duty.PublicityDepartmentOfficer.name }.map { val propaganda = Manager.find { Managers.duty eq Duty.PublicityDepartmentOfficer.name }.map {
toManagerVo(it) toManagerVo(it)
} }
val publicRelationsDepartment=Manager.find { Managers.duty eq Duty.LiaisonOfficer.name }.map { val publicRelationsDepartment = Manager.find { Managers.duty eq Duty.LiaisonOfficer.name }.map {
toManagerVo(it) toManagerVo(it)
} }
AllOfficerVo(secretariat=secretariat,propaganda = propaganda,publicRelationsDepartment=publicRelationsDepartment) AllOfficerVo(
secretariat = secretariat,
propaganda = propaganda,
publicRelationsDepartment = publicRelationsDepartment
)
} }
} }

@ -119,7 +119,8 @@ class ApplicationTest {
@Test @Test
fun test(){ fun test(){
println("12345678".substring(IntRange(4,5))) val c:String?=null
c.let { println(it) }
} }
@Test @Test

Loading…
Cancel
Save