From f0f49b6d4c74eb0acbbfa5c1dc059608d3a5ac50 Mon Sep 17 00:00:00 2001 From: FatttSnake Date: Tue, 28 Nov 2023 18:16:45 +0800 Subject: [PATCH] Add user management api --- .../controller/permission/UserController.kt | 66 ++++++- .../api/converter/permission/UserConverter.kt | 81 ++++++++- .../fatweb/api/entity/common/ResponseCode.kt | 1 + .../api/mapper/permission/UserMapper.kt | 7 + .../api/param/authentication/UserAddParam.kt | 42 +++++ .../param/authentication/UserDeleteParam.kt | 15 ++ .../api/param/authentication/UserGetParam.kt | 19 ++ .../param/authentication/UserUpdateParam.kt | 42 +++++ .../api/service/permission/IUserService.kt | 24 ++- .../permission/impl/UserServiceImpl.kt | 172 +++++++++++++++++- .../permission/UserWithPasswordRoleInfoVo.kt | 63 +++++++ .../mapper/permission/UserMapper.xml | 109 +++++++++++ 12 files changed, 627 insertions(+), 14 deletions(-) create mode 100644 src/main/kotlin/top/fatweb/api/param/authentication/UserAddParam.kt create mode 100644 src/main/kotlin/top/fatweb/api/param/authentication/UserDeleteParam.kt create mode 100644 src/main/kotlin/top/fatweb/api/param/authentication/UserGetParam.kt create mode 100644 src/main/kotlin/top/fatweb/api/param/authentication/UserUpdateParam.kt create mode 100644 src/main/kotlin/top/fatweb/api/vo/permission/UserWithPasswordRoleInfoVo.kt diff --git a/src/main/kotlin/top/fatweb/api/controller/permission/UserController.kt b/src/main/kotlin/top/fatweb/api/controller/permission/UserController.kt index 9ce09ca..d4a435e 100644 --- a/src/main/kotlin/top/fatweb/api/controller/permission/UserController.kt +++ b/src/main/kotlin/top/fatweb/api/controller/permission/UserController.kt @@ -2,12 +2,17 @@ package top.fatweb.api.controller.permission import io.swagger.v3.oas.annotations.Operation import io.swagger.v3.oas.annotations.tags.Tag -import org.springframework.web.bind.annotation.GetMapping -import org.springframework.web.bind.annotation.RequestMapping -import org.springframework.web.bind.annotation.RestController -import top.fatweb.api.converter.permission.UserConverter +import jakarta.validation.Valid +import org.springframework.web.bind.annotation.* +import top.fatweb.api.entity.common.ResponseCode import top.fatweb.api.entity.common.ResponseResult +import top.fatweb.api.param.authentication.UserAddParam +import top.fatweb.api.param.authentication.UserDeleteParam +import top.fatweb.api.param.authentication.UserGetParam +import top.fatweb.api.param.authentication.UserUpdateParam import top.fatweb.api.service.permission.IUserService +import top.fatweb.api.vo.PageVo +import top.fatweb.api.vo.permission.UserWithPasswordRoleInfoVo import top.fatweb.api.vo.permission.UserWithPowerInfoVo import top.fatweb.api.vo.permission.UserWithRoleInfoVo @@ -27,15 +32,60 @@ class UserController( @GetMapping("info") fun getInfo(): ResponseResult { userService.getInfo()?.let { - return ResponseResult.databaseSuccess(data = UserConverter.userToUserWithPowerInfoVo(it)) + return ResponseResult.databaseSuccess(data = it) } ?: let { return ResponseResult.databaseFail() } } - @Operation(summary = "获取用户列表") + @Operation(summary = "获取用户") @GetMapping - fun get(): ResponseResult> { + fun get(@Valid userGetParam: UserGetParam?): ResponseResult> { return ResponseResult.databaseSuccess( - data = userService.getList().map { UserConverter.userToUserWithRoleInfoVo(it) }) + data = userService.getPage(userGetParam) + ) + } + + @Operation(summary = "获取单个用户") + @GetMapping("/{id}") + fun getOne(@PathVariable id: Long): ResponseResult { + return userService.getOne(id)?.let { + ResponseResult.databaseSuccess(data = it) + } ?: let { + ResponseResult.databaseFail(ResponseCode.DATABASE_NO_RECORD_FOUND) + } + } + + @Operation(summary = "添加用户") + @PostMapping + fun add(@Valid @RequestBody userAddParam: UserAddParam): ResponseResult { + return userService.add(userAddParam)?.let { + ResponseResult.databaseSuccess( + ResponseCode.DATABASE_INSERT_SUCCESS, data = it + ) + } ?: let { ResponseResult.databaseFail(ResponseCode.DATABASE_INSERT_FAILED) } + } + + @Operation(summary = "修改用户") + @PutMapping + fun update(@Valid @RequestBody userUpdateParam: UserUpdateParam): ResponseResult { + return userService.update(userUpdateParam)?.let { + ResponseResult.databaseSuccess( + ResponseCode.DATABASE_INSERT_SUCCESS, data = it + ) + } ?: let { ResponseResult.databaseFail(ResponseCode.DATABASE_INSERT_FAILED) } + } + + @Operation(summary = "删除用户") + @DeleteMapping("/{id}") + fun delete(@PathVariable id: Long): ResponseResult { + userService.deleteOne(id) + return ResponseResult.databaseSuccess(ResponseCode.DATABASE_DELETE_SUCCESS) + } + + @Operation(summary = "批量删除用户") + @DeleteMapping + fun deleteList(@Valid @RequestBody userDeleteParam: UserDeleteParam): ResponseResult { + userService.delete(userDeleteParam) + return ResponseResult.databaseSuccess(ResponseCode.DATABASE_DELETE_SUCCESS) } } diff --git a/src/main/kotlin/top/fatweb/api/converter/permission/UserConverter.kt b/src/main/kotlin/top/fatweb/api/converter/permission/UserConverter.kt index 477aab7..a64c869 100644 --- a/src/main/kotlin/top/fatweb/api/converter/permission/UserConverter.kt +++ b/src/main/kotlin/top/fatweb/api/converter/permission/UserConverter.kt @@ -1,8 +1,18 @@ package top.fatweb.api.converter.permission +import com.baomidou.mybatisplus.core.metadata.IPage +import top.fatweb.api.entity.permission.Group +import top.fatweb.api.entity.permission.Role import top.fatweb.api.entity.permission.User +import top.fatweb.api.entity.permission.UserInfo import top.fatweb.api.param.authentication.LoginParam -import top.fatweb.api.vo.permission.* +import top.fatweb.api.param.authentication.UserAddParam +import top.fatweb.api.param.authentication.UserUpdateParam +import top.fatweb.api.vo.PageVo +import top.fatweb.api.vo.permission.UserWithPasswordRoleInfoVo +import top.fatweb.api.vo.permission.UserWithPowerInfoVo +import top.fatweb.api.vo.permission.UserWithRoleInfoVo +import top.fatweb.avatargenerator.GitHubAvatar /** * User converter @@ -11,6 +21,7 @@ import top.fatweb.api.vo.permission.* * @since 1.0.0 */ object UserConverter { + fun loginParamToUser(loginParam: LoginParam) = User().apply { username = loginParam.username password = loginParam.password @@ -69,4 +80,72 @@ object UserConverter { GroupConverter.groupToGroupVo(it) } ) + + fun userToUserWithPasswordRoleInfoVo(user: User) = UserWithPasswordRoleInfoVo( + id = user.id, + username = user.username, + password = user.password, + locking = user.locking?.let { it == 1 }, + expiration = user.expiration, + credentialsExpiration = user.credentialsExpiration, + enable = user.enable?.let { it == 1 }, + currentLoginTime = user.currentLoginTime, + currentLoginIp = user.currentLoginIp, + lastLoginTime = user.lastLoginTime, + lastLoginIp = user.lastLoginIp, + createTime = user.createTime, + updateTime = user.updateTime, + userInfo = user.userInfo?.let { + UserInfoConverter.userInfoToUserInfoVo(it) + }, + roles = user.roles?.map { + RoleConverter.roleToRoleVo(it) + }, + groups = user.groups?.map { + GroupConverter.groupToGroupVo(it) + } + ) + + fun userAddParamToUser(userAddParam: UserAddParam) = User().apply { + username = userAddParam.username + password = userAddParam.password + locking = if (userAddParam.locking) 1 else 0 + expiration = userAddParam.expiration + credentialsExpiration = userAddParam.credentialsExpiration + enable = if (userAddParam.enable) 1 else 0 + userInfo = UserInfo().apply { + nickname = userAddParam.nickname ?: userAddParam.username + avatar = userAddParam.avatar ?: GitHubAvatar.newAvatarBuilder().build() + .createAsBase64((Long.MIN_VALUE..Long.MAX_VALUE).random()) + email = userAddParam.email + } + roles = userAddParam.roleIds?.map { Role().apply { id = it } } + groups = userAddParam.groupIds?.map { Group().apply { id = it } } + } + + fun userUpdateParamToUser(userUpdateParam: UserUpdateParam) = User().apply { + id = userUpdateParam.id + username = userUpdateParam.username + locking = if (userUpdateParam.locking && userUpdateParam.id != 0L) 1 else 0 + expiration = if (userUpdateParam.id != 0L) userUpdateParam.expiration else null + credentialsExpiration = userUpdateParam.credentialsExpiration + enable = if (userUpdateParam.enable || userUpdateParam.id == 0L) 1 else 0 + userInfo = UserInfo().apply { + nickname = userUpdateParam.nickname + avatar = userUpdateParam.avatar + email = userUpdateParam.email + } + roles = userUpdateParam.roleIds?.map { Role().apply { id = it } } + groups = userUpdateParam.groupIds?.map { Group().apply { id = it } } + } + + fun userPageToUserWithRoleInfoPageVo(userPage: IPage) = PageVo( + total = userPage.total, + pages = userPage.pages, + size = userPage.size, + current = userPage.current, + records = userPage.records.map { + userToUserWithRoleInfoVo(it) + } + ) } \ No newline at end of file diff --git a/src/main/kotlin/top/fatweb/api/entity/common/ResponseCode.kt b/src/main/kotlin/top/fatweb/api/entity/common/ResponseCode.kt index 15c8283..78a040f 100644 --- a/src/main/kotlin/top/fatweb/api/entity/common/ResponseCode.kt +++ b/src/main/kotlin/top/fatweb/api/entity/common/ResponseCode.kt @@ -42,6 +42,7 @@ enum class ResponseCode(val code: Int) { DATABASE_DELETE_FILED(BusinessCode.DATABASE, 35), DATABASE_EXECUTE_ERROR(BusinessCode.DATABASE, 50), DATABASE_DUPLICATE_KEY(BusinessCode.DATABASE, 51), + DATABASE_NO_RECORD_FOUND(BusinessCode.DATABASE, 52), API_AVATAR_SUCCESS(BusinessCode.API_AVATAR, 0), API_AVATAR_ERROR(BusinessCode.API_AVATAR, 50); diff --git a/src/main/kotlin/top/fatweb/api/mapper/permission/UserMapper.kt b/src/main/kotlin/top/fatweb/api/mapper/permission/UserMapper.kt index e69df51..ebf38d5 100644 --- a/src/main/kotlin/top/fatweb/api/mapper/permission/UserMapper.kt +++ b/src/main/kotlin/top/fatweb/api/mapper/permission/UserMapper.kt @@ -1,6 +1,7 @@ package top.fatweb.api.mapper.permission import com.baomidou.mybatisplus.core.mapper.BaseMapper +import com.baomidou.mybatisplus.core.metadata.IPage import org.apache.ibatis.annotations.Mapper import org.apache.ibatis.annotations.Param import top.fatweb.api.entity.permission.User @@ -15,5 +16,11 @@ import top.fatweb.api.entity.permission.User interface UserMapper : BaseMapper { fun getOneWithPowerInfoByUsername(@Param("username")username: String): User? + fun selectPage(page: IPage, searchValue: String?, searchRegex: Boolean): IPage + + fun getWithRoleInfoByList(userIds: List): List? + + fun getOneWithRoleInfo(id: Long): User? + fun getListWithRoleInfo(): List } diff --git a/src/main/kotlin/top/fatweb/api/param/authentication/UserAddParam.kt b/src/main/kotlin/top/fatweb/api/param/authentication/UserAddParam.kt new file mode 100644 index 0000000..900a9c8 --- /dev/null +++ b/src/main/kotlin/top/fatweb/api/param/authentication/UserAddParam.kt @@ -0,0 +1,42 @@ +package top.fatweb.api.param.authentication + +import io.swagger.v3.oas.annotations.media.Schema +import jakarta.validation.constraints.NotBlank +import java.time.LocalDateTime + +@Schema(description = "用户添加请求参数") +data class UserAddParam( + @Schema(description = "用户名") + @field:NotBlank(message = "Username can not be blank") + val username: String?, + + @Schema(description = "密码(为空自动生成随机密码)") + val password: String?, + + @Schema(description = "锁定") + val locking: Boolean = false, + + @Schema(description = "过期时间") + val expiration: LocalDateTime?, + + @Schema(description = "认证过期时间") + val credentialsExpiration: LocalDateTime?, + + @Schema(description = "启用") + val enable: Boolean = true, + + @Schema(description = "昵称") + val nickname: String?, + + @Schema(description = "头像") + val avatar: String?, + + @Schema(description = "邮箱") + val email: String?, + + @Schema(description = "角色 ID 列表") + val roleIds: List?, + + @Schema(description = "用户组 ID 列表") + val groupIds: List? +) diff --git a/src/main/kotlin/top/fatweb/api/param/authentication/UserDeleteParam.kt b/src/main/kotlin/top/fatweb/api/param/authentication/UserDeleteParam.kt new file mode 100644 index 0000000..0f3a0f8 --- /dev/null +++ b/src/main/kotlin/top/fatweb/api/param/authentication/UserDeleteParam.kt @@ -0,0 +1,15 @@ +package top.fatweb.api.param.authentication + +import io.swagger.v3.oas.annotations.media.Schema + +/** + * User delete param + * + * @author FatttSnake, fatttsnake@gmail.com + * @since 1.0.0 + */ +@Schema(description = "用户删除请求参数") +data class UserDeleteParam( + @Schema(description = "用户 ID 列表") + val ids: List +) diff --git a/src/main/kotlin/top/fatweb/api/param/authentication/UserGetParam.kt b/src/main/kotlin/top/fatweb/api/param/authentication/UserGetParam.kt new file mode 100644 index 0000000..769aaf0 --- /dev/null +++ b/src/main/kotlin/top/fatweb/api/param/authentication/UserGetParam.kt @@ -0,0 +1,19 @@ +package top.fatweb.api.param.authentication + +import io.swagger.v3.oas.annotations.media.Schema +import top.fatweb.api.param.PageSortParam + +/** + * User get param + * + * @author FatttSnake, fatttsnake@gmail.com + * @since 1.0.0 + */ +@Schema(description = "用户查询请求参数") +data class UserGetParam( + @Schema(description = "查询内容") + val searchValue: String? = null, + + @Schema(description = "查询使用正则表达式", allowableValues = ["true", "false"]) + val searchRegex: Boolean = false, +) : PageSortParam() diff --git a/src/main/kotlin/top/fatweb/api/param/authentication/UserUpdateParam.kt b/src/main/kotlin/top/fatweb/api/param/authentication/UserUpdateParam.kt new file mode 100644 index 0000000..70d80cb --- /dev/null +++ b/src/main/kotlin/top/fatweb/api/param/authentication/UserUpdateParam.kt @@ -0,0 +1,42 @@ +package top.fatweb.api.param.authentication + +import io.swagger.v3.oas.annotations.media.Schema +import jakarta.validation.constraints.NotNull +import java.time.LocalDateTime + +@Schema(description = "用户更新请求参数") +data class UserUpdateParam( + @Schema(description = "用户 ID") + @field:NotNull(message = "ID can not be null") + val id: Long?, + + @Schema(description = "用户名") + val username: String?, + + @Schema(description = "锁定") + val locking: Boolean = false, + + @Schema(description = "过期时间") + val expiration: LocalDateTime?, + + @Schema(description = "认证过期时间") + val credentialsExpiration: LocalDateTime?, + + @Schema(description = "启用") + val enable: Boolean = true, + + @Schema(description = "昵称") + val nickname: String?, + + @Schema(description = "头像") + val avatar: String?, + + @Schema(description = "邮箱") + val email: String?, + + @Schema(description = "角色 ID 列表") + val roleIds: List?, + + @Schema(description = "用户组 ID 列表") + val groupIds: List? +) diff --git a/src/main/kotlin/top/fatweb/api/service/permission/IUserService.kt b/src/main/kotlin/top/fatweb/api/service/permission/IUserService.kt index e46f957..a9cfc1c 100644 --- a/src/main/kotlin/top/fatweb/api/service/permission/IUserService.kt +++ b/src/main/kotlin/top/fatweb/api/service/permission/IUserService.kt @@ -2,6 +2,14 @@ package top.fatweb.api.service.permission import com.baomidou.mybatisplus.extension.service.IService import top.fatweb.api.entity.permission.User +import top.fatweb.api.param.authentication.UserAddParam +import top.fatweb.api.param.authentication.UserDeleteParam +import top.fatweb.api.param.authentication.UserGetParam +import top.fatweb.api.param.authentication.UserUpdateParam +import top.fatweb.api.vo.PageVo +import top.fatweb.api.vo.permission.UserWithPasswordRoleInfoVo +import top.fatweb.api.vo.permission.UserWithPowerInfoVo +import top.fatweb.api.vo.permission.UserWithRoleInfoVo /** * User service interface @@ -12,7 +20,19 @@ import top.fatweb.api.entity.permission.User interface IUserService : IService { fun getUserWithPower(username: String): User? - fun getInfo(): User? + fun getInfo(): UserWithPowerInfoVo? - fun getList(): List + fun getPage(userGetParam: UserGetParam?): PageVo + + fun getOne(id: Long): UserWithRoleInfoVo? + + fun getList(): List + + fun add(userAddParam: UserAddParam): UserWithPasswordRoleInfoVo? + + fun update(userUpdateParam: UserUpdateParam): UserWithRoleInfoVo? + + fun deleteOne(id: Long) + + fun delete(userDeleteParam: UserDeleteParam) } diff --git a/src/main/kotlin/top/fatweb/api/service/permission/impl/UserServiceImpl.kt b/src/main/kotlin/top/fatweb/api/service/permission/impl/UserServiceImpl.kt index c3da7e3..6fb6f6a 100644 --- a/src/main/kotlin/top/fatweb/api/service/permission/impl/UserServiceImpl.kt +++ b/src/main/kotlin/top/fatweb/api/service/permission/impl/UserServiceImpl.kt @@ -1,11 +1,28 @@ package top.fatweb.api.service.permission.impl +import com.baomidou.mybatisplus.extension.kotlin.KtQueryWrapper +import com.baomidou.mybatisplus.extension.plugins.pagination.Page import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl +import org.springframework.security.crypto.password.PasswordEncoder import org.springframework.stereotype.Service +import org.springframework.transaction.annotation.Transactional +import top.fatweb.api.converter.permission.UserConverter import top.fatweb.api.entity.permission.User +import top.fatweb.api.entity.permission.UserGroup +import top.fatweb.api.entity.permission.UserInfo +import top.fatweb.api.entity.permission.UserRole import top.fatweb.api.mapper.permission.UserMapper +import top.fatweb.api.param.authentication.UserAddParam +import top.fatweb.api.param.authentication.UserDeleteParam +import top.fatweb.api.param.authentication.UserGetParam +import top.fatweb.api.param.authentication.UserUpdateParam import top.fatweb.api.service.permission.* +import top.fatweb.api.util.PageUtil +import top.fatweb.api.util.StrUtil import top.fatweb.api.util.WebUtil +import top.fatweb.api.vo.PageVo +import top.fatweb.api.vo.permission.UserWithPasswordRoleInfoVo +import top.fatweb.api.vo.permission.UserWithRoleInfoVo /** * User service implement @@ -15,10 +32,14 @@ import top.fatweb.api.util.WebUtil */ @Service class UserServiceImpl( + private val passwordEncoder: PasswordEncoder, + private val userInfoService: IUserInfoService, private val moduleService: IModuleService, private val menuService: IMenuService, private val elementService: IElementService, - private val operationService: IOperationService + private val operationService: IOperationService, + private val userRoleService: IUserRoleService, + private val userGroupService: IUserGroupService ) : ServiceImpl(), IUserService { override fun getUserWithPower(username: String): User? { val user = baseMapper.getOneWithPowerInfoByUsername(username) @@ -34,7 +55,152 @@ class UserServiceImpl( return user } - override fun getInfo() = WebUtil.getLoginUsername()?.let { getUserWithPower(it) } ?: let { null } + override fun getInfo() = WebUtil.getLoginUsername() + ?.let { username -> getUserWithPower(username)?.let { UserConverter.userToUserWithPowerInfoVo(it) } } - override fun getList() = baseMapper.getListWithRoleInfo() + override fun getPage(userGetParam: UserGetParam?): PageVo { + val userIdsPage = Page(userGetParam?.currentPage ?: 1, userGetParam?.pageSize ?: 20) + + PageUtil.setPageSort(userGetParam, userIdsPage) + + val userIdsIPage = + baseMapper.selectPage(userIdsPage, userGetParam?.searchValue, userGetParam?.searchRegex ?: false) + val userPage = Page(userIdsIPage.current, userIdsIPage.size, userIdsIPage.total) + if (userIdsIPage.total > 0) { + userPage.setRecords(baseMapper.getWithRoleInfoByList(userIdsIPage.records)) + } + + return UserConverter.userPageToUserWithRoleInfoPageVo(userPage) + } + + override fun getOne(id: Long) = + baseMapper.getOneWithRoleInfo(id)?.let { UserConverter.userToUserWithRoleInfoVo(it) } + + override fun getList() = baseMapper.getListWithRoleInfo().map { UserConverter.userToUserWithRoleInfoVo(it) } + + @Transactional + override fun add(userAddParam: UserAddParam): UserWithPasswordRoleInfoVo? { + val rawPassword = + if (userAddParam.password.isNullOrBlank()) StrUtil.getRandomPassword(10) else userAddParam.password + val user = UserConverter.userAddParamToUser(userAddParam) + + user.apply { + password = passwordEncoder.encode(rawPassword) + } + + if (baseMapper.insert(user) == 1) { + user.userInfo?.let { userInfoService.save(it.apply { userId = user.id }) } + + if (!user.roles.isNullOrEmpty()) { + userRoleService.saveBatch(user.roles!!.map { + UserRole().apply { + userId = user.id + roleId = it.id + } + }) + } + + if (!user.groups.isNullOrEmpty()) { + userGroupService.saveBatch(user.groups!!.map { + UserGroup().apply { + userId = user.id + groupId = it.id + } + }) + } + + user.password = rawPassword + + return UserConverter.userToUserWithPasswordRoleInfoVo(user) + } + + return null + } + + @Transactional + override fun update(userUpdateParam: UserUpdateParam): UserWithRoleInfoVo? { + val user = UserConverter.userUpdateParamToUser(userUpdateParam) + + val oldRoleList = userRoleService.list( + KtQueryWrapper(UserRole()).select(UserRole::roleId).eq(UserRole::userId, userUpdateParam.id) + ).map { it.roleId } + val addRoleIds = HashSet() + val removeRoleIds = HashSet() + userUpdateParam.roleIds?.forEach { addRoleIds.add(it) } + oldRoleList.forEach { + if (it != null) { + removeRoleIds.add(it) + } + } + removeRoleIds.removeAll(addRoleIds) + oldRoleList.toSet().let { addRoleIds.removeAll(it) } + + val oldGroupList = userGroupService.list( + KtQueryWrapper(UserGroup()).select(UserGroup::groupId).eq(UserGroup::userId, userUpdateParam.id) + ).map { it.groupId } + val addGroupIds = HashSet() + val removeGroupIds = HashSet() + userUpdateParam.groupIds?.forEach { addGroupIds.add(it) } + oldGroupList.forEach { + if (it != null) { + removeGroupIds.add(it) + } + } + removeGroupIds.removeAll(addGroupIds) + oldGroupList.toSet().let { addGroupIds.removeAll(it) } + + baseMapper.updateById(user) + + user.userInfo?.let { userInfo -> + userInfoService.getOne( + KtQueryWrapper(UserInfo()).select(UserInfo::id).eq(UserInfo::userId, userUpdateParam.id) + )?.let { + userInfo.id = it.id + userInfoService.updateById(userInfo) + } + } + + removeRoleIds.forEach { + userRoleService.remove( + KtQueryWrapper(UserRole()).eq( + UserRole::userId, userUpdateParam.id + ).eq(UserRole::roleId, it) + ) + } + + addRoleIds.forEach { + userRoleService.save(UserRole().apply { + userId = userUpdateParam.id + roleId = it + }) + } + + removeGroupIds.forEach { + userGroupService.remove( + KtQueryWrapper(UserGroup()).eq( + UserGroup::userId, userUpdateParam.id + ).eq(UserGroup::groupId, it) + ) + } + + addGroupIds.forEach { + userGroupService.save(UserGroup().apply { + userId = userUpdateParam.id + groupId = it + }) + } + + return UserConverter.userToUserWithRoleInfoVo(user) + } + + override fun deleteOne(id: Long) { + this.delete(UserDeleteParam(listOf(id))) + } + + override fun delete(userDeleteParam: UserDeleteParam) { + baseMapper.deleteBatchIds(userDeleteParam.ids) + userInfoService.remove(KtQueryWrapper(UserInfo()).`in`(UserInfo::userId, userDeleteParam.ids)) + userRoleService.remove(KtQueryWrapper(UserRole()).`in`(UserRole::userId, userDeleteParam.ids)) + userGroupService.remove(KtQueryWrapper(UserGroup()).`in`(UserGroup::userId, userDeleteParam.ids)) + } } diff --git a/src/main/kotlin/top/fatweb/api/vo/permission/UserWithPasswordRoleInfoVo.kt b/src/main/kotlin/top/fatweb/api/vo/permission/UserWithPasswordRoleInfoVo.kt new file mode 100644 index 0000000..df16848 --- /dev/null +++ b/src/main/kotlin/top/fatweb/api/vo/permission/UserWithPasswordRoleInfoVo.kt @@ -0,0 +1,63 @@ +package top.fatweb.api.vo.permission + +import com.fasterxml.jackson.databind.annotation.JsonSerialize +import com.fasterxml.jackson.databind.ser.std.ToStringSerializer +import io.swagger.v3.oas.annotations.media.Schema +import java.time.LocalDateTime + +/** + * User with role information value object + * + * @author FatttSnake, fatttsnake@gmail.com + * @since 1.0.0 + */ +@Schema(description = "用户密码角色信息返回参数") +data class UserWithPasswordRoleInfoVo( + @JsonSerialize(using = ToStringSerializer::class) + val id: Long?, + + @Schema(description = "用户名", example = "User") + val username: String?, + + @Schema(description = "密码") + val password: String?, + + @Schema(description = "是否锁定", example = "false") + val locking: Boolean?, + + @Schema(description = "过期时间", example = "1900-01-01T00:00:00.000Z") + val expiration: LocalDateTime?, + + @Schema(description = "认证过期时间", example = "1900-01-01T00:00:00.000Z") + val credentialsExpiration: LocalDateTime?, + + @Schema(description = "是否启用", example = "true") + val enable: Boolean?, + + @Schema(description = "当前登录时间", example = "1900-01-01T00:00:00.000Z") + val currentLoginTime: LocalDateTime?, + + @Schema(description = "当前登录 IP", example = "1.1.1.1") + val currentLoginIp: String?, + + @Schema(description = "最后登录时间", example = "1900-01-01T00:00:00.000Z") + val lastLoginTime: LocalDateTime?, + + @Schema(description = "最后登录 IP", example = "1.1.1.1") + val lastLoginIp: String?, + + @Schema(description = "创建时间", example = "1900-01-01T00:00:00.000Z") + val createTime: LocalDateTime?, + + @Schema(description = "修改时间", example = "1900-01-01T00:00:00.000Z") + val updateTime: LocalDateTime?, + + @Schema(description = "用户资料") + val userInfo: UserInfoVo?, + + @Schema(description = "角色列表") + val roles: List?, + + @Schema(description = "用户组列表") + val groups: List? +) \ No newline at end of file diff --git a/src/main/resources/mapper/permission/UserMapper.xml b/src/main/resources/mapper/permission/UserMapper.xml index 1639122..6eb6207 100644 --- a/src/main/resources/mapper/permission/UserMapper.xml +++ b/src/main/resources/mapper/permission/UserMapper.xml @@ -58,6 +58,115 @@ and t_user.username = #{username}; + + + + + +