package com.xuekairui.user.service; import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper; import com.baomidou.mybatisplus.extension.plugins.pagination.Page; import com.xuekairui.common.BusinessException; import com.xuekairui.common.ErrorCode; import com.xuekairui.user.dto.AdminUserResponse; import com.xuekairui.user.dto.UpdateRoleRequest; import com.xuekairui.user.entity.User; import com.xuekairui.user.enums.UserRole; import com.xuekairui.user.mapper.UserMapper; import lombok.RequiredArgsConstructor; import lombok.extern.slf4j.Slf4j; import org.springframework.stereotype.Service; import org.springframework.transaction.annotation.Transactional; import java.util.Objects; /** * 运营用户管理服务 */ @Slf4j @Service @RequiredArgsConstructor public class AdminUserService { private final UserMapper userMapper; /** * 分页查询用户列表(支持按ID精确/手机号模糊/昵称模糊/角色精确查询) * 无删除接口,用户数据不可删除。 */ public Page listUsers(Integer pageNum, Integer pageSize, Long userId, String phone, String nickname, String role) { Page page = new Page<>(pageNum, pageSize); LambdaQueryWrapper wrapper = new LambdaQueryWrapper<>(); if (userId != null) { wrapper.eq(User::getId, userId); } if (phone != null && !phone.isBlank()) { wrapper.like(User::getPhone, phone); } if (nickname != null && !nickname.isBlank()) { wrapper.like(User::getNickname, nickname); } if (role != null && !role.isBlank()) { wrapper.eq(User::getRole, UserRole.fromCode(role)); } wrapper.orderByDesc(User::getCreateTime); Page userPage = userMapper.selectPage(page, wrapper); Page resultPage = new Page<>(userPage.getCurrent(), userPage.getSize(), userPage.getTotal()); resultPage.setRecords(userPage.getRecords().stream() .map(this::toResponse) .toList()); return resultPage; } /** * 修改用户角色(仅超级管理员可调用) */ @Transactional public AdminUserResponse updateUserRole(Long userId, UpdateRoleRequest request, Long operatorId) { User user = userMapper.selectById(userId); if (user == null) { throw new BusinessException(ErrorCode.USER_NOT_FOUND); } UserRole targetRole = UserRole.fromCode(request.getRole()); UserRole currentRole = user.getRole() != null ? user.getRole() : UserRole.USER; // 禁止取消最后一个超级管理员 if (currentRole == UserRole.SUPER_ADMIN && targetRole != UserRole.SUPER_ADMIN) { long otherSuperAdminCount = userMapper.selectCount( new LambdaQueryWrapper() .eq(User::getRole, UserRole.SUPER_ADMIN) .ne(User::getId, userId)); if (otherSuperAdminCount == 0) { throw new BusinessException(ErrorCode.BUSINESS_ERROR, "系统中至少保留一个超级管理员"); } } // 防止操作人取消自己的超级管理员权限后系统无超级管理员 if (Objects.equals(operatorId, userId) && currentRole == UserRole.SUPER_ADMIN && targetRole != UserRole.SUPER_ADMIN) { throw new BusinessException(ErrorCode.BUSINESS_ERROR, "不能取消自己的超级管理员权限"); } user.setRole(targetRole); userMapper.updateById(user); log.info("操作人{}修改用户{}角色为{}", operatorId, userId, targetRole.getCode()); return toResponse(user); } /** * 强制踢出用户(递增 tokenVersion,所有 Token 立即失效) */ public void kickUser(Long userId, Long operatorId) { User user = userMapper.selectById(userId); if (user == null) { throw new BusinessException(ErrorCode.USER_NOT_FOUND); } long newVersion = (user.getTokenVersion() != null ? user.getTokenVersion() : 0L) + 1; user.setTokenVersion(newVersion); // 同时清空 Refresh Token,防止旧 Refresh Token 还能刷新 user.setRefreshTokenHash(null); user.setRefreshTokenStatus(null); userMapper.updateById(user); log.info("管理员{}强制踢出用户{},新tokenVersion={}", operatorId, userId, newVersion); } private AdminUserResponse toResponse(User user) { return AdminUserResponse.builder() .id(user.getId()) .phone(user.getPhone()) .nickname(user.getNickname()) .role(user.getRole() != null ? user.getRole().getCode() : UserRole.USER.getCode()) .status(user.getStatus()) .createTime(user.getCreateTime()) .build(); } }