| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123 |
- 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<AdminUserResponse> listUsers(Integer pageNum, Integer pageSize,
- Long userId, String phone, String nickname, String role) {
- Page<User> page = new Page<>(pageNum, pageSize);
- LambdaQueryWrapper<User> 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<User> userPage = userMapper.selectPage(page, wrapper);
- Page<AdminUserResponse> 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<User>()
- .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();
- }
- }
|