答辩预览版

master
pan 3 years ago
parent 7e43a143a5
commit 99b2545925
  1. 144
      module/src/main/kotlin/com/gyf/csams/module/ShareVo.kt
  2. 6
      src/main/kotlin/com/gyf/csams/Application.kt
  3. 77
      src/main/kotlin/com/gyf/csams/Controller.kt
  4. 67
      src/main/kotlin/com/gyf/csams/Dao.kt
  5. 3
      src/main/kotlin/com/gyf/csams/MySQL.kt
  6. 385
      src/main/kotlin/com/gyf/csams/Service.kt
  7. 19
      test/ApplicationTest.kt

@ -1,7 +1,5 @@
package com.gyf.csams.module
import java.util.*
data class ApiResponse<T>(val code: Int = 200, val message: String, val body: T? = null)
class Simple {
@ -183,8 +181,6 @@ data class UserLoginVo(
override val clientType: ClientType = ClientType.Foreground
) : BaseLoginVo()
data class UserResDto(val password: String)
data class ManagerLoginVo(
val account: String,
override val password: String, override val device: String
@ -262,55 +258,6 @@ data class SendBBSVo(val content:String,
*/
data class SearchCommentVo(val activityId: Int)
/**
* 题型
*
*/
enum class ExamType(val type: String) {
//选择题
CQ("选择题"),
//开放题
OQ("开放题")
}
abstract class Exam {
abstract val examType: ExamType
//**TODO 题目反序列化
abstract val question:String
// abstract val question: StringForm
}
/**
* 选择题
*
* @property examType 题型描述
* @property answers 答案
* @property rightAnswer 正确答案
* @property question 问题
* TODO 题目反序列化
*/
data class ChoiceQuestionVo(
override val examType: ExamType = ExamType.CQ,
// val answers: List<StringForm>,
val answers: List<String>,
val rightAnswer: Int,
override val question: String
) : Exam()
/**
* 开放题
*
* @property examType 题型描述
* @property question 问题
* TODO 题目反序列化
*/
data class OpenQuestionsVo(
override val examType: ExamType = ExamType.OQ, override val question: String
) : Exam()
data class LeaveMessageFormatVo(val message: String, val user: UserInfoVo)
@ -393,6 +340,15 @@ data class AssociationMainVo(
val photos: List<AssociationActPhotoVo>? = null
)
/**
* 通用审核进度
*
* @property checkStatus
* @property applyTime
* @property firstCause
* @property lastCause
* @property result
*/
data class AuditCheckVo(
val checkStatus: CheckStatus,
val applyTime: Long,
@ -435,8 +391,10 @@ abstract class AuditVo {
*
*/
data class AuditAssociationVo(
val name: String, val desc: String,
val logo: String, override val audit: AuditLoggingVo
val name: String,
val desc: String,
val logo: String,
override val audit: AuditLoggingVo
) : AuditVo()
/**
@ -510,7 +468,6 @@ data class ActivityApplyVo(
*
*/
data class AuditActVo(
val auditId: Int,
val activityVo: ActivityVo,
override val audit: AuditLoggingVo
) : AuditVo()
@ -522,7 +479,6 @@ data class AuditActVo(
* @property auditCheckVo
*/
data class ActivityCheckVo(
val activityId:Int,
val activityVo: ActivityVo,
val auditCheckVo: AuditCheckVo
)
@ -591,24 +547,80 @@ data class ManagerActVo(
data class AllOfficerVo(
val secretariat: MutableList<ManagerInfoVo>,
val propaganda: MutableList<ManagerInfoVo>,
val publicRelationsDepartment: MutableList<ManagerInfoVo>
val secretariat: List<ManagerInfoVo>,
val propaganda: List<ManagerInfoVo>,
val publicRelationsDepartment: List<ManagerInfoVo>
)
/**
* 换名申请表
*
* @property studentId 学号
* @property oldName 社团原名
* @property newName 社团新名
* @property reason 申请理由
* @property cause 申请理由
*/
data class RenameVo(
val studentId: String,
val oldName: String,
val renameId:Int?=null,
val newName: String,
val reason: String
val cause: String
)
/**
* 前台申请换名
*
* @property rename
*/
data class RenameApplyVo(
val associationId: Int,
val rename:RenameVo,
override val token: Token,
override val clientType: ClientType = ClientType.Foreground
):ClientBaseVo()
/**
* 社团命名审核记录
*
* @property renameVo
* @property audit
*/
data class AuditRenameVo(
val associationVo: AssociationVo,
val renameVo: RenameVo,
override val audit: AuditLoggingVo
):AuditVo()
/**
* 重命名审核进度
*
* @property renameVo
* @property auditCheckVo
*/
data class RenameCheckVo(
val renameVo: RenameVo,
val auditCheckVo: AuditCheckVo
)
/**
* 主页轮播
*
* @property url
*/
data class MainActivityPhotoVo(val url:String, val activityVo: ActivityVo,val associationVo: AssociationVo)
/**
* 更新社团
*
* @property associationVo
* @property token
* @property clientType
*/
data class UpdateAssociationVo(val associationVo: AssociationVo,
override val token: Token,
override val clientType: ClientType
):ClientBaseVo()
data class ManagerDutyVo(val manager: ManagerInfoVo,val people:Int)
data class ManagerDutySumVo(val secretariat:ManagerDutyVo,
val propaganda:ManagerDutyVo,
val publicRelationsDepartment:ManagerDutyVo)

@ -7,8 +7,6 @@ import io.ktor.http.*
fun main(args: Array<String>): Unit = io.ktor.server.netty.EngineMain.main(args)
@Suppress("unused") // Referenced in application.conf
@kotlin.jvm.JvmOverloads
fun Application.module() {
install(CORS) {
method(HttpMethod.Options)
@ -41,7 +39,9 @@ fun Application.Controller() {
/**
* 初始化log
*/
listOf(MainService,AccountService,FileService,AssociationService,BackgroundService,NotificationService,ActivityService).forEach {
listOf(MainService,AccountService,FileService,AssociationService,
BackgroundService,NotificationService,ActivityService,
RenameService).forEach {
it.init(environment)
}

@ -144,6 +144,18 @@ fun Application.AccountController() {
}
}
route("/load/manager"){
post{
call.withToken<OnlyToken> {
call.respond(ApiResponse(message = "部门概况信息加载成功",body=BackgroundService.load()))
}
}
post("/detail"){
call.withToken<OnlyToken> {
call.respond(ApiResponse(message = "部门详情加载成功",body=BackgroundService.loadDetail()))
}
}
}
post(path = "/logout") {
@ -178,6 +190,13 @@ fun Application.MainController() {
call.respond(ApiResponse(message = "留言获取成功", body = s))
}
}
post("/hotActivity"){
call.withToken<OnlyToken> {
call.respond(ApiResponse(message = "活动轮播图获取成功",
body=ActivityService.random()))
}
}
}
}
}
@ -319,6 +338,7 @@ object AuditController{
/**
* 社团接口
*
*/
fun Application.AssociationController() {
routing {
@ -330,6 +350,23 @@ fun Application.AssociationController() {
check(AssociationService)
read(AssociationService,Associations)
route("/rename"){
register(RenameService)
accept(RenameService)
audit(RenameService)
check(RenameService)
read(RenameService,Renames)
}
post("/update"){
call.withToken<UpdateAssociationVo> {
AssociationService.update(vo=it.associationVo)
call.respond(ApiResponse(message = "社团更新成功",body = true))
}
}
post("/uploadLogo") {
log.info("开始上传logo")
@ -349,19 +386,35 @@ fun Application.AssociationController() {
log.info("----end-----")
}
post("/list"){
log.info("开始查询社团")
call.withToken<SearchAssociationVo>{
try {
call.respond(ApiResponse(message = "社团列表检索完成",body=AssociationService.load(vo=it)))
} catch (e: Exception) {
log.error(e)
call.respond(ApiResponse(message = "社团列表检索失败",body=null))
route("/list"){
post{
log.info("开始查询社团")
call.withToken<SearchAssociationVo>{
try {
call.respond(ApiResponse(message = "社团列表检索完成",body=AssociationService.load(vo=it)))
} catch (e: Exception) {
log.error(e)
call.respond(ApiResponse(message = "社团列表检索失败",body=null))
}
}
log.info("----end-----")
}
post("/all"){
log.info("获取所有社团")
call.withToken<OnlyToken>{
try {
call.respond(ApiResponse(message = "社团列表检索完成",body=AssociationService.loadAll()))
} catch (e: Exception) {
log.error(e)
call.respond(ApiResponse(message = "社团列表检索失败",body=null))
}
}
log.info("----end-----")
}
log.info("----end-----")
}
route("/load"){
post{
log.info("社团id查询")
@ -404,6 +457,12 @@ fun Application.ActivityController(){
check(ActivityService)
read(ActivityService,Activities)
post("/list/all"){
call.withToken<OnlyToken> {
call.respond(ApiResponse(message = "活动信息加载",body = ActivityService.listAll()))
}
}
post("/load"){
val searchActivityVo=call.receive<SearchActivityVo>()
call.respond(ApiResponse(message = "活动列表加载成功",body = ActivityService.load(vo=searchActivityVo)))

@ -184,7 +184,7 @@ class Association(id:EntityID<Int>):AbstractAudit(id){
var name by Associations.name
var desc by Associations.desc
var logo by ImageFile referencedOn Associations.logo
val level by Associations.level
var level by Associations.level
var faculty by Associations.faculty
override var audit by AuditLogging referencedOn Associations.auditId
@ -367,4 +367,69 @@ class ActivityComment(id:EntityID<Int>):IntEntity(id){
var createTime by ActivityComments.createTime
var user by User referencedOn ActivityComments.userId
var activity by Activity referencedOn ActivityComments.activityId
}
@TableComment("社团重命名记录")
object Renames:AbstractAudits(){
@TableComment("新名称")
val newName:Column<String> = varchar("new_name",length = 10)
@TableComment("换名理由")
val cause:Column<String> = varchar("cause",length = 30)
@TableComment("重命名社团")
val associationId:Column<EntityID<Int>> = reference("association_id",Associations)
@TableComment("审核信息")
override val auditId:Column<EntityID<Int>> = reference("audit_id",AuditLeggings)
}
class Rename(id:EntityID<Int>):AbstractAudit(id){
companion object:IntEntityClass<Rename>(Renames)
var newName by Renames.newName
var cause by Renames.cause
var association by Association referencedOn Renames.associationId
override var audit by AuditLogging referencedOn Renames.auditId
override fun notificationName(): String {
return "${association.name} -> $newName"
}
}
@TableComment("题库")
object Questions:IntIdTable(){
@TableComment("问题")
val question:Column<String> = varchar("question",30)
@TableComment("选项A")
val optionsA:Column<String> = varchar("optionsA",15)
@TableComment("选项B")
val optionsB:Column<String> = varchar("optionsB",15)
@TableComment("选项C")
val optionsC:Column<String> = varchar("optionsC",15)
@TableComment("选项D")
val optionsD:Column<String> = varchar("optionsD",15)
@TableComment("所属社团")
val associationId:Column<EntityID<Int>> = reference("association_id",Associations)
}
class Question(id:EntityID<Int>):IntEntity(id){
companion object:IntEntityClass<Question>(Questions)
var question by Questions.question
var optionsA by Questions.optionsA
var optionsB by Questions.optionsB
var optionsC by Questions.optionsC
var optionsD by Questions.optionsD
}
@TableComment("试卷")
object TestPapers:IntIdTable(){
@TableComment("问题")
val questionId:Column<EntityID<Int>> = reference("question_id",Questions)
}

@ -41,7 +41,8 @@ fun Application.MySQL() {
fun initTable(){
transaction {
val tableList= arrayOf(Users,UserTokens,Managers,ManagerTokens,AuditLeggings,LeaveMessages,
ImageFiles,Associations,AssociationMembers,Notifications,Activities,PhotoAlbums,ActivityComments)
ImageFiles,Associations,AssociationMembers,Notifications,Activities,PhotoAlbums,ActivityComments,
Renames)
SchemaUtils.createMissingTablesAndColumns(*tableList)
updateComment(*tableList)

@ -6,6 +6,7 @@ import com.gyf.csams.module.*
import io.ktor.application.*
import io.ktor.http.content.*
import io.ktor.util.*
import org.jetbrains.exposed.dao.IntEntityClass
import org.jetbrains.exposed.dao.id.EntityID
import org.jetbrains.exposed.dao.id.IntIdTable
import org.jetbrains.exposed.sql.*
@ -46,16 +47,16 @@ object AccountService : AbstractService() {
/**
* 注册
*/
fun register(userVo: UserRegVo): UserResDto? {
fun register(userVo: UserRegVo): String? {
try {
return transaction {
val originPassword = if (environment.developmentMode) "12345678" else randomNum(8)
val originPassword = randomNum(8)
User.new {
studentId = userVo.studentId
name = userVo.name
password = originPassword.md5()
}
return@transaction UserResDto(password = originPassword)
return@transaction originPassword
}
} catch (e: Exception) {
log.error("注册失败,发生异常:$e")
@ -248,10 +249,10 @@ object AccountService : AbstractService() {
}
fun <T : ClientBaseVo> validToken(vo: T): Boolean {
return if (vo.clientType == ClientType.Foreground) {
validUserToken(vo.token)
} else {
validManagerToken(vo.token)
return when(vo.clientType){
ClientType.Foreground->validUserToken(vo.token)
ClientType.Background-> validManagerToken(vo.token)
else->throw IllegalArgumentException("不清楚是来自哪个平台的token信息")
}
}
@ -438,7 +439,7 @@ abstract class AuditService<T, E, F> : AbstractService() {
* @param receiverId
* @param content
*/
protected fun foreground(receiverId: Int, content: String) {
private fun foreground(receiverId: Int, content: String) {
Notification.new {
this.title = dataType
this.content = content
@ -454,7 +455,7 @@ abstract class AuditService<T, E, F> : AbstractService() {
* 前台任务通知管理员处理
*
*/
protected fun background(content: String, duty: Duty) {
private fun background(content: String, duty: Duty) {
Manager.find { Managers.duty eq duty.name }.apply {
if (count() == 0L) {
log.warn("找不到适当的${duty.desc}处理此任务")
@ -481,6 +482,10 @@ abstract class AuditService<T, E, F> : AbstractService() {
*/
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 {
return row.find { table.auditId eq auditId } .firstOrNull() ?: throw AuditIdError(auditId)
}
/**
* 更新审核结果
*
@ -508,7 +513,7 @@ abstract class AuditService<T, E, F> : AbstractService() {
* 通过审核后
*
*/
protected abstract fun afterAudit(entity: AbstractAudit)
protected open fun afterAudit(entity: AbstractAudit){}
/**
* 资料受理
@ -602,19 +607,36 @@ abstract class AuditService<T, E, F> : AbstractService() {
}
}
//过滤完成的审核记录?(可多次提交的资料)
open val isFilter:Boolean=true
/**
* 审核进度查询
* TODO 审核进度查询
*
*/
open fun read(vo: OnlyToken, table: IntIdTable): F? {
fun read(vo: OnlyToken, table: IntIdTable): F? {
return transaction {
table.innerJoin(AuditLeggings).innerJoin(Users)
.slice(listOf(table.id))
.select {Users.id eq vo.token.id}
.firstOrNull()
?.let { it ->
getCheckVo(id = it[table.id])
}
if(isFilter){
val nextAudit = AuditLeggings.alias("nextAudit")
table.innerJoin(AuditLeggings)
.innerJoin(nextAudit, { AuditLeggings.nextAudit }, { nextAudit[AuditLeggings.id] })
.innerJoin(Users)
.slice(listOf(table.id))
.select {Users.id eq vo.token.id and (nextAudit[AuditLeggings.result] neq true)}
.firstOrNull()
?.let { it ->
getCheckVo(id = it[table.id])
}
}else {
table.innerJoin(AuditLeggings).innerJoin(Users)
.slice(listOf(table.id))
.select { Users.id eq vo.token.id }
.firstOrNull()
?.let { it ->
getCheckVo(id = it[table.id])
}
}
}
}
@ -625,7 +647,7 @@ abstract class AuditService<T, E, F> : AbstractService() {
return AuditCheckVo(
checkStatus = when {
audit.nextAudit == null && audit.manager == null -> CheckStatus.WaitFirst
audit.nextAudit == null && audit.manager != 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?.result == null -> CheckStatus.AcceptLast
else -> CheckStatus.Finish
@ -647,6 +669,19 @@ abstract class AuditService<T, E, F> : AbstractService() {
abstract fun audit(vo: OnlyToken): List<E>
protected fun <T : AbstractAudit> createSortedBy(table: IntEntityClass<T>): List<T> {
return table.all().sortedBy {
//按初审受理>等待复审>复审受理>完成审核 排序
when {
it.audit.nextAudit == null && it.audit.manager == null -> 1
it.audit.nextAudit == null && it.audit.manager != null -> 2
it.audit.nextAudit != null && it.audit.nextAudit?.manager == null -> 3
it.audit.nextAudit != null && it.audit.nextAudit?.result == null -> 4
else -> 5
}
}
}
protected fun toAuditLoggingVo(it: AuditLogging?): AuditLoggingVo? {
return it?.let { logging ->
val auditLogging = AuditLoggingVo(
@ -671,6 +706,17 @@ abstract class AuditService<T, E, F> : AbstractService() {
auditLogging
}
}
protected fun createNotifications(vo:ClientBaseVo,user:User){
foreground(
receiverId = vo.token.id,
content = "您成功提交了一份${dataType},请耐心等待后台受理"
)
background(
content = "用户${user.name}提交了一份${dataType}需要您进行受理",
duty = Duty.PamphaBhusal
)
}
}
/**
@ -681,11 +727,12 @@ object AssociationService : AuditService<AssociationRegVo, AuditAssociationVo, A
override val dataType: String = "社团注册资料"
override fun findEntity(auditId: Int): AbstractAudit {
return Association.find { Associations.auditId eq auditId }.firstOrNull() ?: throw AuditIdError(auditId)
return testFind(Associations,Association,auditId)
}
override fun afterAudit(entity: AbstractAudit) {
override val isFilter: Boolean = false
override fun afterAudit(entity: AbstractAudit) {
AssociationMember.new {
user = entity.audit.user
this.association = Association.find { Associations.auditId eq entity.audit.id }.firstOrNull()
@ -696,6 +743,35 @@ object AssociationService : AuditService<AssociationRegVo, AuditAssociationVo, A
}
}
fun Association.set(vo:AssociationRegVo,user:User){
name = vo.name
desc = vo.desc
logo = ImageFile.findById(vo.fileId) ?: throw FileIdError(vo.fileId)
this.audit = AuditLogging.new {
this.user = user
}
}
fun loadAll():List<AssociationVo>{
return transaction {
Association.all().map {
toAssociationVo(it)
}
}
}
fun update(vo:AssociationVo){
transaction {
Association.findById(vo.associationId).let {
if(it==null){
throw AssociationIdError(vo.associationId)
}else{
it.level=vo.level?.name
}
}
}
}
/**
* 注册社团
*
@ -708,15 +784,8 @@ object AssociationService : AuditService<AssociationRegVo, AuditAssociationVo, A
val user = User.findById(vo.token.id) ?: throw UserIdError(vo.token.id)
if (vo.associationId != null) {
log.info("再次提交【${vo.name}】注册资料")
val association = Association.findById(vo.associationId!!) ?: throw AuditIdError(vo.associationId!!)
association.apply {
name = vo.name
desc = vo.desc
logo = ImageFile.findById(vo.fileId) ?: throw FileIdError(vo.fileId)
this.audit = AuditLogging.new {
this.user = user
}
}
(Association.findById(vo.associationId!!) ?: throw AuditIdError(vo.associationId!!))
.set(vo=vo,user=user)
} else {
val associationMember = AssociationMember.find { AssociationMembers.userId eq user.id }.firstOrNull()
val association: Association? = associationMember?.association
@ -725,12 +794,7 @@ object AssociationService : AuditService<AssociationRegVo, AuditAssociationVo, A
association != null && association.audit.result == null -> throw IllegalArgumentException("您已经提交过${dataType},请耐心等待后台管理员处理")
association == null -> {
Association.new {
name = vo.name
desc = vo.desc
logo = ImageFile.findById(vo.fileId) ?: throw FileIdError(vo.fileId)
this.audit = AuditLogging.new {
this.user = user
}
set(vo=vo,user=user)
faculty = faculty(user.studentId).name
}
@ -738,9 +802,7 @@ object AssociationService : AuditService<AssociationRegVo, AuditAssociationVo, A
}
}
foreground(receiverId = vo.token.id, content = "您成功提交了一份${dataType},请耐心等待后台受理")
background(content = "用户${user.name}提交了一份${dataType}需要您进行受理", duty = Duty.PamphaBhusal)
createNotifications(vo=vo,user=user)
log.info("未审核社团:${vo.name}创建成功")
}
}
@ -777,7 +839,8 @@ object AssociationService : AuditService<AssociationRegVo, AuditAssociationVo, A
return (Association.findById(id) ?: throw AssociationIdError(id.value)).let {
AssociationCheckVo(
associationVo = toAssociationVo(it),
auditCheckVo = toCheckVo(it.audit), fileId = it.logo.id.value
auditCheckVo = toCheckVo(it.audit),
fileId = it.logo.id.value
)
}
}
@ -790,16 +853,7 @@ object AssociationService : AuditService<AssociationRegVo, AuditAssociationVo, A
*/
override fun audit(vo: OnlyToken): List<AuditAssociationVo> {
return transaction {
return@transaction Association.all().sortedBy {
//按初审受理>等待复审>复审受理>完成审核 排序
when {
it.audit.nextAudit == null && it.audit.manager == null -> 1
it.audit.nextAudit == null && it.audit.manager != null -> 2
it.audit.nextAudit != null && it.audit.nextAudit?.manager == null -> 3
it.audit.nextAudit != null && it.audit.nextAudit?.result == null -> 4
else -> 5
}
}.map {
return@transaction createSortedBy(Association).map {
val audit = toAuditLoggingVo(it.audit) ?: throw IllegalArgumentException("转换审核记录出错!!!!")
AuditAssociationVo(name = it.name, desc = it.desc, logo = it.logo.filepath, audit = audit)
}.apply {
@ -872,17 +926,44 @@ object AssociationService : AuditService<AssociationRegVo, AuditAssociationVo, A
}
}
/**
* 活动服务
*/
object ActivityService : AuditService<ActivityApplyVo, AuditActVo,ActivityCheckVo>() {
override val dataType: String = "活动申请书"
override fun findEntity(auditId: Int): AbstractAudit {
return Activity.find { Activities.auditId eq auditId }.firstOrNull() ?: throw AuditIdError(auditId)
return testFind(Activities,Activity,auditId)
}
override fun afterAudit(entity: AbstractAudit) {
/**
* 查看活动信息
*
*/
fun listAll():List<ManagerActVo>{
return transaction {
Activity.all().map {
ManagerActVo(association = AssociationService.toAssociationVo(it.association),
score = (1..5).random(),activityVo = toActivityVo(it))
}
}
}
/**
* 主页活动图片
*
* @return
*/
fun random():List<MainActivityPhotoVo>{
return transaction {
PhotoAlbum.all().shuffled().map {
MainActivityPhotoVo(url=it.photo.filepath,
activityVo = toActivityVo(it.activity),
associationVo = AssociationService.toAssociationVo(it.activity.association))
}
}
}
/**
@ -989,18 +1070,16 @@ object ActivityService : AuditService<ActivityApplyVo, AuditActVo,ActivityCheckV
}
}
override fun read(vo: OnlyToken, table: IntIdTable): ActivityCheckVo? {
val nextAudit = AuditLeggings.alias("nextAudit")
return transaction {
table.innerJoin(AuditLeggings)
.innerJoin(nextAudit, { AuditLeggings.nextAudit }, { nextAudit[AuditLeggings.id] })
.innerJoin(Users)
.slice(listOf(table.id))
.select {Users.id eq vo.token.id and (nextAudit[AuditLeggings.result] neq true)}
.firstOrNull()
?.let { it ->
getCheckVo(id = it[table.id])
}
fun Activity.set(activityVo:ActivityVo,user:User){
activityName = activityVo.activityName
activityTime = activityVo.activityTime.toLocalDateTime()
activityAddress = activityVo.activityAddress
activityDesc = activityVo.activityDesc
activitySize = activityVo.activitySize
audit = AuditLogging.new {
this.user = user
}
}
@ -1015,43 +1094,25 @@ object ActivityService : AuditService<ActivityApplyVo, AuditActVo,ActivityCheckV
if (vo.activityVo.activityId != null) {
//再次提交
log.info("再次提交【${vo.activityVo.activityName}${dataType}")
val activity = Activity.findById(vo.activityVo.activityId!!) ?: throw ActivityIdError(vo.activityVo.activityId!!)
activity.apply {
activityName = vo.activityVo.activityName
activityTime = vo.activityVo.activityTime.toLocalDateTime()
activityAddress = vo.activityVo.activityAddress
activityDesc = vo.activityVo.activityDesc
activitySize = vo.activityVo.activitySize
this.audit = AuditLogging.new {
this.user = user
}
}
(Activity.findById(vo.activityVo.activityId!!) ?: throw ActivityIdError(vo.activityVo.activityId!!))
.set(activityVo = vo.activityVo,user=user)
} else {
//首次提交
//申请活动的限制
val activityMember = AssociationMember.find { AssociationMembers.userId eq user.id }.firstOrNull()
when {
activityMember == null -> throw IllegalArgumentException("非社团成员无法申请活动")
!activityMember.isHead -> throw java.lang.IllegalArgumentException("不是社团团长无法申请活动")
!activityMember.isHead -> throw IllegalArgumentException("不是社团团长无法申请活动")
else -> {
Activity.new {
activityName = vo.activityVo.activityName
activityTime = vo.activityVo.activityTime.toLocalDateTime()
activityAddress = vo.activityVo.activityAddress
activityDesc = vo.activityVo.activityDesc
activitySize = vo.activityVo.activitySize
association =
Association.findById(vo.associationId) ?: throw AssociationIdError(vo.associationId)
audit = AuditLogging.new {
this.user = user
}
set(vo.activityVo,user=user)
association = Association.findById(vo.associationId) ?: throw AssociationIdError(vo.associationId)
}
}
}
}
foreground(receiverId = vo.token.id, content = "您成功提交了一份${dataType},请耐心等待后台受理")
background(content = "用户${user.name}提交了一份${dataType}需要您进行受理", duty = Duty.PamphaBhusal)
createNotifications(vo=vo,user=user)
}
}
@ -1066,21 +1127,9 @@ object ActivityService : AuditService<ActivityApplyVo, AuditActVo,ActivityCheckV
override fun audit(vo: OnlyToken): List<AuditActVo> {
return transaction {
//TODO sortedBy这一段需要封装
return@transaction Activity.all().sortedBy {
//按初审受理>等待复审>复审受理>完成审核 排序
when {
it.audit.nextAudit == null && it.audit.manager == null -> 1
it.audit.nextAudit == null && it.audit.manager != null -> 2
it.audit.nextAudit != null && it.audit.nextAudit?.manager == null -> 3
it.audit.nextAudit != null && it.audit.nextAudit?.result == null -> 4
else -> 5
}
}.map {
return@transaction createSortedBy(Activity).map {
val audit = toAuditLoggingVo(it.audit) ?: throw IllegalArgumentException("转换审核记录出错!!!!")
AuditActVo(
activityVo = toActivityVo(activity = it), audit = audit, auditId = it.id.value
)
AuditActVo(activityVo = toActivityVo(activity = it), audit = audit)
}.apply {
log.info("找到${this.size}${dataType}")
}
@ -1091,13 +1140,93 @@ object ActivityService : AuditService<ActivityApplyVo, AuditActVo,ActivityCheckV
return (Activity.findById(id) ?: throw ActivityIdError(id.value)).let {
ActivityCheckVo(
activityVo = toActivityVo(activity = it),
auditCheckVo = toCheckVo(it.audit),
activityId = it.id.value
auditCheckVo = toCheckVo(it.audit)
)
}
}
}
/**
* 重命名服务
*/
object RenameService : AuditService<RenameApplyVo,AuditRenameVo,RenameCheckVo>(){
override val dataType: String = "换名申请表"
fun Rename.set(vo:RenameVo,user:User){
newName=vo.newName
cause=vo.cause
audit=AuditLogging.new {
this.user = user
}
}
//TODO 类型自动转换
override fun afterAudit(entity: AbstractAudit) {
if(entity is Rename){
entity.association.name=entity.newName
}
}
override fun register(vo: RenameApplyVo) {
transaction {
vo.rename.renameId.also {
val user = User.findById(vo.token.id) ?: throw UserIdError(vo.token.id)
if (it != null) {
//再次提交
(Rename.findById(it) ?: throw IllegalArgumentException("无法根据[id=${it}]找到${dataType}")).set(
vo = vo.rename,
user = user
)
} else {
//重新提交
val activityMember = AssociationMember.find { AssociationMembers.userId eq user.id }.firstOrNull()
when {
activityMember == null -> throw IllegalArgumentException("非社团成员无法申请社团换名")
!activityMember.isHead -> throw IllegalArgumentException("非社团团长无法申请社团换名")
else -> {
Rename.new {
set(vo = vo.rename, user = user)
association =
Association.findById(vo.associationId) ?: throw AssociationIdError(vo.associationId)
}
}
}
}
createNotifications(vo = vo, user = user)
}
}
}
override fun findEntity(auditId: Int): AbstractAudit {
return testFind(Renames,Rename,auditId)
}
private fun toRenameVo(rename: Rename):RenameVo{
return RenameVo(renameId = rename.id.value,newName = rename.newName,cause = rename.cause)
}
override fun getCheckVo(id: EntityID<Int>): RenameCheckVo {
return (Rename.findById(id)?:throw IllegalArgumentException("找不到[id=${id}]${dataType}")).let {
RenameCheckVo(renameVo = toRenameVo(it),auditCheckVo = toCheckVo(it.audit))
}
}
override fun audit(vo: OnlyToken): List<AuditRenameVo> {
return transaction {
return@transaction createSortedBy(Rename).map {
val audit = toAuditLoggingVo(it.audit) ?: throw IllegalArgumentException("转换审核记录出错!!!!")
AuditRenameVo(renameVo = toRenameVo(rename = it),audit = audit,associationVo = AssociationService.toAssociationVo(it.association))
}.apply {
log.info("找到${this.size}${ActivityService.dataType}")
}
}
}
}
/**
* 通知服务
*/
@ -1180,6 +1309,52 @@ object BackgroundService : AbstractService() {
}
fun toManagerVo(manager: Manager):ManagerInfoVo{
return ManagerInfoVo(duty = manager.duty.let { Duty.valueOf(it) },name=manager.name,
headImg = manager.headImg?.filepath,desc = manager.desc)
}
/**
* 加载部门部长和总人数
*
*/
fun load():ManagerDutySumVo{
return transaction {
val secretariat=Manager.find { Managers.duty eq Duty.SecretaryOfTheMinister.name }.first()
val secretariatCount=Manager.find{ Managers.duty eq Duty.SecretaryDepartmentOfficer.name }.count()
val propaganda=Manager.find {Managers.duty eq Duty.PropagandaDepartment.name }.first()
val propagandaCount=Manager.find{ Managers.duty eq Duty.PublicityDepartmentOfficer.name }.count()
val publicRelationsDepartment=Manager.find{ Managers.duty eq Duty.LiaisonMinister.name }.first()
val publicRelationsDepartmentCount=Manager.find{ Managers.duty eq Duty.LiaisonOfficer.name }.count()
ManagerDutySumVo(secretariat = ManagerDutyVo(manager = toManagerVo(secretariat),people = secretariatCount.toInt()),
propaganda = ManagerDutyVo(manager = toManagerVo(propaganda),people = propagandaCount.toInt()),
publicRelationsDepartment = ManagerDutyVo(manager = toManagerVo(publicRelationsDepartment),
people=publicRelationsDepartmentCount.toInt()))
}
}
/**
* 加载部门详细信息
*
* @return
*/
fun loadDetail():AllOfficerVo{
return transaction {
val secretariat=Manager.find{ Managers.duty eq Duty.SecretaryDepartmentOfficer.name }.map {
toManagerVo(it)
}
val propaganda=Manager.find {Managers.duty eq Duty.PublicityDepartmentOfficer.name }.map {
toManagerVo(it)
}
val publicRelationsDepartment=Manager.find { Managers.duty eq Duty.LiaisonOfficer.name }.map {
toManagerVo(it)
}
AllOfficerVo(secretariat=secretariat,propaganda = propaganda,publicRelationsDepartment=publicRelationsDepartment)
}
}
private fun createManager(duty: Duty, num: Int = 1): MutableList<InitManagerDto> {
val managerList = mutableListOf<InitManagerDto>()
repeat(num) {

@ -12,7 +12,12 @@ import com.gyf.csams.module.UserRegVo
import io.ktor.config.*
import io.ktor.http.*
import io.ktor.server.testing.*
import org.jetbrains.exposed.sql.SqlExpressionBuilder.eq
import org.jetbrains.exposed.sql.SqlExpressionBuilder.neq
import org.jetbrains.exposed.sql.alias
import org.jetbrains.exposed.sql.and
import org.jetbrains.exposed.sql.innerJoin
import org.jetbrains.exposed.sql.select
import org.jetbrains.exposed.sql.transactions.transaction
import java.io.File
import java.time.LocalDateTime
@ -84,9 +89,17 @@ class ApplicationTest {
@Test
fun testEntryId() {
initApp {
transaction {
val c= updateComment(UserTokens)
println(c)
transaction {
val nextAudit = AuditLeggings.alias("nextAudit")
Activities.innerJoin(AuditLeggings)
.innerJoin(nextAudit, { AuditLeggings.nextAudit }, { nextAudit[AuditLeggings.id] })
.innerJoin(Users)
.slice(listOf(Activities.id))
.select {Users.id eq 1 and (nextAudit[AuditLeggings.result] neq true)}
.firstOrNull()
?.let { it ->
ActivityService.getCheckVo(id = it[Activities.id])
}.let { println(it) }
}
}
}

Loading…
Cancel
Save