From 1b5c6cb58af9d44d7365dedcb0d20caf198bef21 Mon Sep 17 00:00:00 2001 From: pan <1029559041@qq.com> Date: Thu, 27 May 2021 23:51:55 +0800 Subject: [PATCH] =?UTF-8?q?=E5=A2=9E=E5=8A=A0=E7=AE=A1=E7=90=86=E5=91=98?= =?UTF-8?q?=E7=99=BB=E5=BD=95=E6=8E=A5=E5=8F=A3=20=E5=A2=9E=E5=8A=A0?= =?UTF-8?q?=E7=AE=A1=E7=90=86=E5=91=98=E4=BB=A4=E7=89=8C=E8=A1=A8?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/Controller.kt | 36 ++++++++++---- src/Dao.kt | 30 ++++++++--- src/MySQL.kt | 2 +- src/Service.kt | 107 +++++++++++++++++++++++++++++++++------- src/Vo.kt | 33 +++++++------ test/ApplicationTest.kt | 5 ++ 6 files changed, 162 insertions(+), 51 deletions(-) diff --git a/src/Controller.kt b/src/Controller.kt index 91bd4f3..f412029 100644 --- a/src/Controller.kt +++ b/src/Controller.kt @@ -50,21 +50,37 @@ fun Application.AccountController() { } } + //TODO 封装前后台登录逻辑 route(path = "/login") { - post { - val userLoginVo = call.receive() - environment.log.info("执行登陆") - val token = AccountService.login(userLoginVo, call.request.host()) - environment.log.info("登录请求处理完毕") - call.respond(ApiResponse(message = if (token != null) "登陆成功" else "账号或密码错误!!!", body = token)) + route(path = ReceiverType.Foreground.name.toLowerCase()){ + post { + val userLoginVo = call.receive() + val token = AccountService.login(userLoginVo, call.request.host()) + call.respond(ApiResponse(message = if (token != null) "登陆成功" else "账号或密码错误!!!", body = token)) + } + post("/token"){ + val tokenVo = call.receive() + val isValid = AccountService.validToken(tokenVo) + call.respond(ApiResponse(message = if (isValid) "令牌合法" else "令牌不合法", body = isValid)) + } + } - post(path = "/token") { - val tokenVo = call.receive() - val isValid = AccountService.validToken(tokenVo) - call.respond(ApiResponse(message = if (isValid) "令牌合法" else "令牌不合法", body = isValid)) + route(path = ReceiverType.Background.name.toLowerCase()){ + post{ + val managerLoginVo = call.receive() + val token = AccountService.login(managerLoginVo, call.request.host()) + call.respond(ApiResponse(message = if (token != null) "登陆成功" else "账号或密码错误!!!", body = token)) + } + post("/token"){ + val tokenVo = call.receive() + val isValid = AccountService.validManagerToken(tokenVo) + call.respond(ApiResponse(message = if (isValid) "令牌合法" else "令牌不合法", body = isValid)) + } } } + + post(path = "/logout") { environment.log.info("退出登录") val userLogoutVo = call.receive() diff --git a/src/Dao.kt b/src/Dao.kt index 183e3e1..0cd8a2b 100644 --- a/src/Dao.kt +++ b/src/Dao.kt @@ -30,12 +30,7 @@ class User(id:EntityID):IntEntity(id){ var password by Users.password } -@TableComment("用户授权令牌") -object UserTokens: IntIdTable(){ - - @TableComment("授权用户") - val userId:Column> = reference("user_id",Users) - +open class BaseTokens:IntIdTable(){ @TableComment("令牌") val token:Column = varchar(name="token",length = 32) @@ -49,6 +44,12 @@ object UserTokens: IntIdTable(){ val device:Column = varchar(name="device",length = 256) } +@TableComment("用户授权令牌") +object UserTokens: BaseTokens(){ + @TableComment("授权用户") + val userId:Column> = reference("user_id",Users) +} + class UserToken(id:EntityID):IntEntity(id){ companion object:IntEntityClass(UserTokens) var user by User referencedOn UserTokens.userId @@ -58,6 +59,23 @@ class UserToken(id:EntityID):IntEntity(id){ var device by UserTokens.device } +@TableComment("管理员授权令牌") +object ManagerTokens:BaseTokens(){ + @TableComment("授权管理员") + val managerId:Column> = reference("manager_id",Managers) +} + +class ManagerToken(id:EntityID):IntEntity(id){ + companion object:IntEntityClass(ManagerTokens) + var manager by Manager referencedOn ManagerTokens.managerId + var token by ManagerTokens.token + var ip by ManagerTokens.ip + var createTime by ManagerTokens.createTime + var device by ManagerTokens.device +} + + + @TableComment("留言") object LeaveMessages:IntIdTable(){ @TableComment("留言用户") diff --git a/src/MySQL.kt b/src/MySQL.kt index f3e341c..377b3e2 100644 --- a/src/MySQL.kt +++ b/src/MySQL.kt @@ -40,7 +40,7 @@ fun Application.MySQL(testing: Boolean = false){ fun initTable(){ transaction { - val tableList= arrayOf(Users,UserTokens,LeaveMessages,ImageFiles,Associations,Managers,CheckForms,Notifications) + val tableList= arrayOf(Users,UserTokens,LeaveMessages,ImageFiles,Associations,Managers,CheckForms,Notifications,ManagerTokens) SchemaUtils.createMissingTablesAndColumns(*tableList) updateComment(*tableList) diff --git a/src/Service.kt b/src/Service.kt index fbe77dc..ffaad85 100644 --- a/src/Service.kt +++ b/src/Service.kt @@ -56,14 +56,12 @@ object AccountService:AbstractService() { } /** - * 登录 + * 前台登录 * - * @param userLoginVo 登陆表单 */ fun login(userLoginVo: UserLoginVo,_ip:String):Token?{ return transaction { val matchUser=User.find { Users.studentId eq userLoginVo.studentId }.firstOrNull() - when { matchUser==null -> { log.warn("学号:${userLoginVo.studentId}不存在") @@ -89,6 +87,43 @@ object AccountService:AbstractService() { } } + fun login(managerLoginVo: ManagerLoginVo, _ip:String):Token?{ + return transaction { + val matchUser=Manager.find { Managers.account eq managerLoginVo.account }.firstOrNull() + when { + matchUser==null -> { + log.warn("学号:${managerLoginVo.account}不存在") + return@transaction null + } + managerLoginVo.password.md5() != matchUser.password -> { + log.warn("密码:${managerLoginVo.password}错误") + return@transaction null + } + else -> { + val token=ManagerToken.new{ + manager=matchUser + ip=_ip + device=managerLoginVo.device + token=listOf(matchUser.id,ip,device).joinToString(separator = ('a' .. 'z').random().toString()).md5() + } + token.flush() + return@transaction Token(id = matchUser.id.value,token = token.token, + createTime = token.createTime.toEpochSecond( + ZoneOffset.of("+8"))) + } + } + } + } + + fun validManagerToken(token:Token):Boolean{ + return transaction { + !ManagerToken.find { + ManagerTokens.managerId eq token.id + ManagerTokens.token eq token.token + }.empty() + } + } + fun validToken(token: Token):Boolean{ return transaction { !UserToken.find { @@ -256,11 +291,19 @@ object FileService:AbstractService(){ } } + + /** * 社团服务 */ object AssociationService: AbstractService() { + /** + * 注册社团 + * + * @param vo + * @return + */ fun register(vo:RegAssociationVo):Boolean{ return try { transaction { @@ -275,6 +318,14 @@ object AssociationService: AbstractService() { receiverId=vo.token.id receiverClient=ReceiverType.Foreground.name } + val user=User.findById(vo.token.id) + if(user!=null) { + BackgroundService.createBackgroundNotification(title = "审核注册社团",content = "用户${user.name}提交了一份社团资料需要您进行受理", + duty = Duty.PamphaBhusal) + }else{ + log.warn("无法根据token id:${vo.token.id}查找到用户名") + } + return@transaction true } log.info("未审核社团创建成功") true @@ -285,7 +336,7 @@ object AssociationService: AbstractService() { } } -enum class ManagerType(val desc:String,val level:Int){ +enum class Duty(val desc:String, val level:Int){ Teacher("老师",1), PamphaBhusal("总部长",2), SecretaryOfTheMinister("秘书部部长",3), @@ -338,7 +389,6 @@ object NotificationService:AbstractService(){ } /** - * TODO * * @param vo * @return @@ -373,17 +423,38 @@ object BackgroundService:AbstractService(){ initManager() } - private fun createManager(type:ManagerType, num:Int=1): MutableList { + /** + * 前台任务通知管理员处理 + * + */ + fun createBackgroundNotification(content:String,title:String,duty: Duty){ + Manager.find { Managers.duty eq duty.name }.apply { + if(count()==0L){ + log.warn("找不到适当的${duty.desc}处理此任务") + }else{ + forEach { + Notification.new { + this.title = title + this.content = content + receiverId= it.id.value + receiverClient=ReceiverType.Background.name + } + } + } + } + } + + private fun createManager(duty:Duty, num:Int=1): MutableList { val managerList= mutableListOf() repeat(num){ val originPassword=randomNum() Manager.new { account= randomNum() password = originPassword.md5() - duty=type.name - level=type.level + this.duty =duty.name + level=duty.level }.apply { - managerList.add(InitManagerDto(account=account,originPassword=originPassword)) + managerList.add(InitManagerDto(account=account,originPassword=originPassword,duty=duty)) } } return managerList @@ -398,20 +469,20 @@ object BackgroundService:AbstractService(){ Manager.count().let { it -> if (it.toInt() == 0) { val allManager = mutableListOf() - allManager.addAll(createManager(ManagerType.Teacher, 1)) - allManager.addAll(createManager(ManagerType.PamphaBhusal, 1)) - allManager.addAll(createManager(ManagerType.SecretaryOfTheMinister, 1)) - allManager.addAll(createManager(ManagerType.PropagandaDepartment, 1)) - allManager.addAll(createManager(ManagerType.LiaisonMinister, 1)) + allManager.addAll(createManager(Duty.Teacher, 1)) + allManager.addAll(createManager(Duty.PamphaBhusal, 1)) + allManager.addAll(createManager(Duty.SecretaryOfTheMinister, 1)) + allManager.addAll(createManager(Duty.PropagandaDepartment, 1)) + allManager.addAll(createManager(Duty.LiaisonMinister, 1)) arrayOf( - ManagerType.SecretaryDepartmentOfficer, - ManagerType.PublicityDepartmentOfficer, - ManagerType.LiaisonOfficer + Duty.SecretaryDepartmentOfficer, + Duty.PublicityDepartmentOfficer, + Duty.LiaisonOfficer ).forEach { allManager.addAll(createManager(it, 3)) } allManager.forEach { - file.appendText("${it.account}------${it.originPassword}\n") + file.appendText("${it.account}------${it.originPassword}------${it.duty.desc}\n") } log.info("共生成${allManager.size}个管理员账号") } else { diff --git a/src/Vo.kt b/src/Vo.kt index 86bab83..64833ce 100644 --- a/src/Vo.kt +++ b/src/Vo.kt @@ -15,27 +15,29 @@ class Simple { } } -/** - * 用户注册表单 - * - * @property studentId 学号 - * @property name 姓名 - */ + data class UserVo(val studentId:String,val name:String) -/** - * 用户登陆表单 - * - * @property studentId 学号 - * @property password 密码 - * @property device 设备型号 - */ -data class UserLoginVo(val studentId: String,val password: String,val device: String) +sealed class BaseLoginVo{ + abstract val password: String + abstract val device: String + abstract val clientType:ReceiverType +} + +data class UserLoginVo(val studentId: String, + override val password: String, override val device: String, + override val clientType: ReceiverType=ReceiverType.Foreground +):BaseLoginVo() data class UserLogoutVo(val userId:Int) data class UserResDto(val password:String) +data class ManagerLoginVo(val account:String, + override val password:String, override val device:String):BaseLoginVo() { + override val clientType: ReceiverType=ReceiverType.Background +} + data class Token(val token:String, val createTime:Long, val id:Int) sealed class BaseVo{ @@ -45,7 +47,6 @@ sealed class BaseVo{ data class LeaveMessageVo(val message: String, override val token:Token):BaseVo() data class OnlyToken(override val token: Token):BaseVo() -//data class PageVo(val pageSize:Int=10,val page:, override val token: Token):BaseVo() data class LeaveMessageDto(val message: String,val user: UserVo) @@ -55,7 +56,7 @@ data class ImageFileDto(val filepath:String,val md5:String,val createTime: Long, data class RegAssociationDto(val name:String,val desc:String,val logo:ImageFileDto) -data class InitManagerDto(val account:String,val originPassword:String) +data class InitManagerDto(val account: String, val originPassword: String, val duty: Duty) data class PageDto(val currentPage:Long,val pageSize:Int=10) diff --git a/test/ApplicationTest.kt b/test/ApplicationTest.kt index b1263d9..62c2243 100644 --- a/test/ApplicationTest.kt +++ b/test/ApplicationTest.kt @@ -93,6 +93,11 @@ class ApplicationTest { println(format.format) } + @Test + fun testLowerCase(){ + println(ReceiverType.Foreground.name.toLowerCase()) + } + /** * 文档生成 */