AdminUserService.java 4.9 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123
  1. package com.xuekairui.user.service;
  2. import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
  3. import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
  4. import com.xuekairui.common.BusinessException;
  5. import com.xuekairui.common.ErrorCode;
  6. import com.xuekairui.user.dto.AdminUserResponse;
  7. import com.xuekairui.user.dto.UpdateRoleRequest;
  8. import com.xuekairui.user.entity.User;
  9. import com.xuekairui.user.enums.UserRole;
  10. import com.xuekairui.user.mapper.UserMapper;
  11. import lombok.RequiredArgsConstructor;
  12. import lombok.extern.slf4j.Slf4j;
  13. import org.springframework.stereotype.Service;
  14. import org.springframework.transaction.annotation.Transactional;
  15. import java.util.Objects;
  16. /**
  17. * 运营用户管理服务
  18. */
  19. @Slf4j
  20. @Service
  21. @RequiredArgsConstructor
  22. public class AdminUserService {
  23. private final UserMapper userMapper;
  24. /**
  25. * 分页查询用户列表(支持按ID精确/手机号模糊/昵称模糊/角色精确查询)
  26. * 无删除接口,用户数据不可删除。
  27. */
  28. public Page<AdminUserResponse> listUsers(Integer pageNum, Integer pageSize,
  29. Long userId, String phone, String nickname, String role) {
  30. Page<User> page = new Page<>(pageNum, pageSize);
  31. LambdaQueryWrapper<User> wrapper = new LambdaQueryWrapper<>();
  32. if (userId != null) {
  33. wrapper.eq(User::getId, userId);
  34. }
  35. if (phone != null && !phone.isBlank()) {
  36. wrapper.like(User::getPhone, phone);
  37. }
  38. if (nickname != null && !nickname.isBlank()) {
  39. wrapper.like(User::getNickname, nickname);
  40. }
  41. if (role != null && !role.isBlank()) {
  42. wrapper.eq(User::getRole, UserRole.fromCode(role));
  43. }
  44. wrapper.orderByDesc(User::getCreateTime);
  45. Page<User> userPage = userMapper.selectPage(page, wrapper);
  46. Page<AdminUserResponse> resultPage = new Page<>(userPage.getCurrent(), userPage.getSize(), userPage.getTotal());
  47. resultPage.setRecords(userPage.getRecords().stream()
  48. .map(this::toResponse)
  49. .toList());
  50. return resultPage;
  51. }
  52. /**
  53. * 修改用户角色(仅超级管理员可调用)
  54. */
  55. @Transactional
  56. public AdminUserResponse updateUserRole(Long userId, UpdateRoleRequest request, Long operatorId) {
  57. User user = userMapper.selectById(userId);
  58. if (user == null) {
  59. throw new BusinessException(ErrorCode.USER_NOT_FOUND);
  60. }
  61. UserRole targetRole = UserRole.fromCode(request.getRole());
  62. UserRole currentRole = user.getRole() != null ? user.getRole() : UserRole.USER;
  63. // 禁止取消最后一个超级管理员
  64. if (currentRole == UserRole.SUPER_ADMIN && targetRole != UserRole.SUPER_ADMIN) {
  65. long otherSuperAdminCount = userMapper.selectCount(
  66. new LambdaQueryWrapper<User>()
  67. .eq(User::getRole, UserRole.SUPER_ADMIN)
  68. .ne(User::getId, userId));
  69. if (otherSuperAdminCount == 0) {
  70. throw new BusinessException(ErrorCode.BUSINESS_ERROR, "系统中至少保留一个超级管理员");
  71. }
  72. }
  73. // 防止操作人取消自己的超级管理员权限后系统无超级管理员
  74. if (Objects.equals(operatorId, userId)
  75. && currentRole == UserRole.SUPER_ADMIN
  76. && targetRole != UserRole.SUPER_ADMIN) {
  77. throw new BusinessException(ErrorCode.BUSINESS_ERROR, "不能取消自己的超级管理员权限");
  78. }
  79. user.setRole(targetRole);
  80. userMapper.updateById(user);
  81. log.info("操作人{}修改用户{}角色为{}", operatorId, userId, targetRole.getCode());
  82. return toResponse(user);
  83. }
  84. /**
  85. * 强制踢出用户(递增 tokenVersion,所有 Token 立即失效)
  86. */
  87. public void kickUser(Long userId, Long operatorId) {
  88. User user = userMapper.selectById(userId);
  89. if (user == null) {
  90. throw new BusinessException(ErrorCode.USER_NOT_FOUND);
  91. }
  92. long newVersion = (user.getTokenVersion() != null ? user.getTokenVersion() : 0L) + 1;
  93. user.setTokenVersion(newVersion);
  94. // 同时清空 Refresh Token,防止旧 Refresh Token 还能刷新
  95. user.setRefreshTokenHash(null);
  96. user.setRefreshTokenStatus(null);
  97. userMapper.updateById(user);
  98. log.info("管理员{}强制踢出用户{},新tokenVersion={}", operatorId, userId, newVersion);
  99. }
  100. private AdminUserResponse toResponse(User user) {
  101. return AdminUserResponse.builder()
  102. .id(user.getId())
  103. .phone(user.getPhone())
  104. .nickname(user.getNickname())
  105. .role(user.getRole() != null ? user.getRole().getCode() : UserRole.USER.getCode())
  106. .status(user.getStatus())
  107. .createTime(user.getCreateTime())
  108. .build();
  109. }
  110. }