申请入团

master
pan 3 years ago
parent 484ecc4ad9
commit d340be70e4
  1. 14
      build.gradle.kts
  2. 44
      module/src/main/kotlin/com/gyf/csams/module/ShareVo.kt
  3. 6
      src/main/kotlin/com/gyf/csams/Controller.kt
  4. 36
      src/main/kotlin/com/gyf/csams/Dao.kt
  5. 2
      src/main/kotlin/com/gyf/csams/MySQL.kt
  6. 121
      src/main/kotlin/com/gyf/csams/Service.kt
  7. 3
      src/main/resources/application.conf
  8. 0
      src/main/resources/logback.xml
  9. 0
      src/main/resources/static/image/.gitkeep
  10. 10
      src/test/kotlin/ApplicationTest.kt
  11. 0
      src/test/resources/static/image/.gitkeep

@ -64,9 +64,13 @@ dependencies {
testImplementation("io.ktor:ktor-server-tests:$ktor_version")
}
//
//kotlin.sourceSets["main"].kotlin.srcDirs("src")
//kotlin.sourceSets["test"].kotlin.srcDirs("test")
kotlin.sourceSets["main"].kotlin.srcDirs("src")
kotlin.sourceSets["test"].kotlin.srcDirs("test")
sourceSets["main"].resources.srcDirs("resources")
sourceSets["test"].resources.srcDirs("testresources")
listOf("main","test").forEach {
kotlin.sourceSets[it].apply {
kotlin.srcDirs("src/${name}/kotlin")
resources.srcDirs("src/${name}/resources")
}
}

@ -626,7 +626,7 @@ data class ManagerDutySumVo(val secretariat: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)
data class ExamVo(val questionId:Int?=null,val question:String,val optionsA:String,val optionsB:String,val optionsC:String,val optionsD:String,val rightOption:Int)
/**
* 更新题库
@ -641,32 +641,12 @@ data class AddExamVo(val questions:List<ExamVo>,
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 SearchExamVo(val associationId:Int, override val token: Token,
override val clientType: ClientType=ClientType.Foreground):ClientBaseVo()
/**
* 试题
*
*/
data class AnswerVo(val examVo: ExamVo,val answer:Int?=null,val paperVo: TestPaperVo)
data class ApplyAnswerVo(val examVo: ExamVo,val answer:Int)
/**
* 答题记录
*
* @property questionId
* @property paperId
* @property answer
*/
data class ApplyAnswerVo(val questionId:Int,val paperId:Int,val answer:Int)
/**
* 答卷
*
@ -675,21 +655,15 @@ data class ApplyAnswerVo(val questionId:Int,val paperId:Int,val answer:Int)
* @property clientType
*/
data class AddAnswerVo(val answers:List<ApplyAnswerVo>,
val associationId:Int,
override val token: Token, override val clientType: ClientType=ClientType.Foreground):ClientBaseVo()
override val token: Token,
val associationId: Int,
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()
/**
* 申请入团检查
*/

@ -375,7 +375,7 @@ fun Application.AssociationController() {
post("/check/apply"){
call.withToken<ApplyAssociationVo> {
call.withToken<SearchExamVo> {
try {
val body=AssociationService.applyAssociation(vo = it)
call.respond(ApiResponse(message = "入团验证信息获取成功",body =body))
@ -387,7 +387,7 @@ fun Application.AssociationController() {
}
post("/create/paper"){
call.withToken<ApplyAssociationVo> {
call.withToken<SearchExamVo> {
try {
call.respond(ApiResponse(message = "试卷创建成功,请开始作答",body = AssociationService.createPaper(vo=it)))
} catch (e: Exception) {
@ -411,7 +411,7 @@ fun Application.AssociationController() {
post("/check/join"){
call.withToken<ApplyAssociationVo> {
call.withToken<SearchExamVo> {
try {
call.respond(ApiResponse(message = "入团记录查询成功",body=AssociationService.joinAssociation(vo=it)))
} catch (e: Exception) {

@ -1,7 +1,6 @@
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.IntEntityClass
import org.jetbrains.exposed.dao.id.EntityID
@ -433,44 +432,23 @@ class Question(id:EntityID<Int>):IntEntity(id){
var association by Association referencedOn Questions.associationId
}
@TableComment("试卷")
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("问题")
val questionId:Column<EntityID<Int>> = reference("question_id",Questions)
@TableComment("答案")
val answer:Column<Int?> = integer("answer").nullable()
val answer:Column<Int> = integer("answer")
@TableComment("试卷")
val paperId:Column<EntityID<Int>> = reference("paper_id",TestPapers)
@TableComment("入团申请记录")
val joinId:Column<EntityID<Int>> = reference("join_id",JoinAssociations)
}
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
var join by JoinAssociation referencedOn Answers.joinId
}
@TableComment("入团申请记录")
@ -487,9 +465,6 @@ object JoinAssociations:IntIdTable(){
@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()
}
@ -498,7 +473,6 @@ 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 {
val tableList= arrayOf(Users,UserTokens,Managers,ManagerTokens,AuditLeggings,LeaveMessages,
ImageFiles,Associations,AssociationMembers,Notifications,Activities,PhotoAlbums,ActivityComments,
Renames,Questions,TestPapers,Answers,JoinAssociations)
Renames,Questions,Answers,JoinAssociations)
SchemaUtils.createMissingTablesAndColumns(*tableList)
updateComment(*tableList)

@ -44,13 +44,19 @@ object AccountService : AbstractService() {
}
}
fun toUserInfo(user: User):UserInfoVo{
return UserInfoVo(name = user.name, headImg = user.headImg?.filepath, desc = user.desc)
}
/**
* 注册
*/
fun register(userVo: UserRegVo): String? {
try {
return transaction {
val originPassword = randomNum(8)
val originPassword = if(environment.developmentMode) (1..8).joinToString("") else randomNum(8)
log.info("密码:${originPassword}")
User.new {
studentId = userVo.studentId
name = userVo.name
@ -324,7 +330,7 @@ object MainService : AbstractService() {
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)
user = AccountService.toUserInfo(user = it.user)
)
}
}
@ -342,8 +348,10 @@ object FileService : AbstractService() {
super.init(environment)
this.uploadDir = environment.config.property("ktor.deployment.filePath").getString()
log.info(this::class.java.classLoader.getResource("")?.path)
filePath =
this::class.java.classLoader.getResource(uploadDir)?.path ?: throw IllegalArgumentException("初始化资源目录失败")
environment.classLoader.getResource(uploadDir)?.path ?: throw IllegalArgumentException("初始化资源目录失败")
File(filePath).let {
when {
it.exists() -> log.info("上传路径[${filePath}]已存在")
@ -690,12 +698,7 @@ abstract class AuditService<T, E, F> : AbstractService() {
return it?.let { logging ->
val auditLogging = AuditLoggingVo(
id = logging.id.value,
user =
UserInfoVo(
name = logging.user.name,
headImg = logging.user.headImg?.filepath,
desc = logging.user.desc
),
user = AccountService.toUserInfo(user = logging.user),
applyTime = logging.applyTime.toLong(),
manager = logging.manager?.let {
ManagerInfoVo(
@ -775,7 +778,7 @@ object AssociationService : AuditService<AssociationRegVo, AuditAssociationVo, A
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)
optionsB = question.optionsB,optionsC = question.optionsC,optionsD = question.optionsD,rightOption = question.answer)
}
/**
@ -798,37 +801,43 @@ object AssociationService : AuditService<AssociationRegVo, AuditAssociationVo, A
*/
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)
val association=Association.findById(vo.associationId)?:throw AssociationIdError(vo.associationId)
val join=createJoin(association=association,user = user)
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}]的问题")
val id=it.examVo.questionId?:throw IllegalArgumentException("问题id不存在")
val question=Question.findById(id)?:throw IllegalArgumentException("不存在[id=${id}]的问题")
Answer.new {
this.question=question
answer=it.answer
this.paper=paper
answer= it.answer
this.join=join
}
}
createJoin(association = association,user=user)
}
}
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())
}
/**
* 显示答卷
*
* @param vo
* @return
*/
fun showAnswer(vo:ShowAnswerVo):List<AnswerVo>{
fun showAnswer(vo:ShowAnswerVo):List<ApplyAnswerVo>{
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()))
Answer.find{ Answers.joinId eq join.id }.map {
ApplyAnswerVo(examVo = toExamVo(it.question),answer = it.answer)
}
}
}
@ -840,21 +849,10 @@ object AssociationService : AuditService<AssociationRegVo, AuditAssociationVo, A
* @param association
* @param user
*/
private fun createJoin(association: Association,user:User){
JoinAssociation.new {
private fun createJoin(association: Association,user:User):JoinAssociation{
return 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
}
}
}
}
@ -864,23 +862,11 @@ object AssociationService : AuditService<AssociationRegVo, AuditAssociationVo, A
* @param vo
* @return
*/
fun createPaper(vo:ApplyAssociationVo):List<ExamVo>{
fun createPaper(vo:SearchExamVo):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 {
it.shuffled().map {
toExamVo(question = it)
}
}
@ -888,11 +874,23 @@ object AssociationService : AuditService<AssociationRegVo, AuditAssociationVo, A
}
private fun createJoinNotification(user:User, association:Association){
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
}
}
}
/**
* 申请入团
*
*/
fun applyAssociation(vo:ApplyAssociationVo):ApplyAssociationResultVo{
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)
@ -910,6 +908,7 @@ object AssociationService : AuditService<AssociationRegVo, AuditAssociationVo, A
//免试入团申请
else{
createJoin(association=association,user=user)
createJoinNotification(association=association,user=user)
ApplyAssociationResultVo(result = true,hasPaper = false)
}
}
@ -920,19 +919,11 @@ object AssociationService : AuditService<AssociationRegVo, AuditAssociationVo, A
* 入团申请记录
*
*/
fun joinAssociation(vo:ApplyAssociationVo):List<JoinAssociationVo>{
fun joinAssociation(vo:SearchExamVo):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)
JoinAssociation.find { JoinAssociations.associationId eq association.id }.sortedByDescending { it.applyTime }.map {
toJoinVo(join=it)
}
}
}
@ -1001,7 +992,7 @@ object AssociationService : AuditService<AssociationRegVo, AuditAssociationVo, A
optionsB = exam.optionsB
optionsC = exam.optionsC
optionsD = exam.optionsD
this.answer = exam.answer
this.answer = exam.rightOption
this.association = association
}
} else {
@ -1012,7 +1003,7 @@ object AssociationService : AuditService<AssociationRegVo, AuditAssociationVo, A
optionsB = exam.optionsB
optionsC = exam.optionsC
optionsD = exam.optionsD
this.answer = exam.answer
this.answer = exam.rightOption
}
}
}
@ -1286,7 +1277,7 @@ object ActivityService : AuditService<ActivityApplyVo, AuditActVo, ActivityCheck
return transaction {
ActivityComment.find { ActivityComments.activityId eq vo.activityId }.map {
BBSVo(
user = UserInfoVo(name = it.user.name, headImg = it.user.headImg?.filepath, desc = it.user.desc),
user = AccountService.toUserInfo(it.user),
createTime = it.createTime.toLong(), content = it.content
)
}

@ -1,4 +1,6 @@
ktor {
#开发模式
development = true
deployment {
port = 8080
port = ${?PORT}
@ -12,6 +14,7 @@ ktor {
maxSize = 20
}
filePath = static/image
#免重启自动重载classes目录
watch = [ classes ]
}

@ -132,8 +132,12 @@ class ApplicationTest {
fun testAudit(){
initApp {
transaction {
Notification.all().sortedByDescending { it.createTime }.forEach {
println(it.createTime)
JoinAssociation.all().sortedBy { it.applyTime.toLong() }.forEach {
println(it.applyTime)
}
println("排序")
JoinAssociation.all().sortedByDescending { it.applyTime.toLong() }.forEach {
println(it.applyTime)
}
}
}
@ -156,7 +160,7 @@ class ApplicationTest {
@Test
fun testStringFormat(){
println(LocalDateTime.now())
(1..8).joinToString("").let { println(it) }
}
/**
* 文档生成
Loading…
Cancel
Save