package org.dromara.system.service.impl; import cn.hutool.core.bean.BeanUtil; import cn.hutool.core.collection.CollUtil; import cn.hutool.core.convert.Convert; import cn.hutool.core.util.ArrayUtil; import cn.hutool.core.util.ObjectUtil; import com.baomidou.mybatisplus.core.conditions.Wrapper; import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper; import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper; import com.baomidou.mybatisplus.core.conditions.update.LambdaUpdateWrapper; import com.baomidou.mybatisplus.core.toolkit.Wrappers; import com.baomidou.mybatisplus.extension.plugins.pagination.Page; import lombok.RequiredArgsConstructor; import lombok.extern.slf4j.Slf4j; import org.dromara.common.core.constant.CacheNames; import org.dromara.common.core.constant.SystemConstants; import org.dromara.common.core.domain.dto.UserDTO; import org.dromara.common.core.exception.ServiceException; import org.dromara.common.core.service.UserService; import org.dromara.common.core.utils.*; import org.dromara.common.mybatis.core.page.PageQuery; import org.dromara.common.mybatis.core.page.TableDataInfo; import org.dromara.common.satoken.utils.LoginHelper; import org.dromara.system.domain.*; import org.dromara.system.domain.bo.SysUserBo; import org.dromara.system.domain.vo.SysPostVo; import org.dromara.system.domain.vo.SysRoleVo; import org.dromara.system.domain.vo.SysUserExportVo; import org.dromara.system.domain.vo.SysUserVo; import org.dromara.system.mapper.*; import org.dromara.system.service.ISysUserService; import org.springframework.cache.annotation.CacheEvict; import org.springframework.cache.annotation.Cacheable; import org.springframework.stereotype.Service; import org.springframework.transaction.annotation.Transactional; import java.util.ArrayList; import java.util.List; import java.util.Map; import java.util.Set; /** * 用户 业务层处理 * * @author Lion Li */ @Slf4j @RequiredArgsConstructor @Service public class SysUserServiceImpl implements ISysUserService, UserService { private final SysUserMapper baseMapper; private final SysDeptMapper deptMapper; private final SysRoleMapper roleMapper; private final SysPostMapper postMapper; private final SysUserRoleMapper userRoleMapper; private final SysUserPostMapper userPostMapper; @Override public TableDataInfo selectPageUserList(SysUserBo user, PageQuery pageQuery) { Page page = baseMapper.selectPageUserList(pageQuery.build(), this.buildQueryWrapper(user)); return TableDataInfo.build(page); } /** * 根据条件分页查询用户列表 * * @param user 用户信息 * @return 用户信息集合信息 */ @Override public List selectUserExportList(SysUserBo user) { return baseMapper.selectUserExportList(this.buildQueryWrapper(user)); } private Wrapper buildQueryWrapper(SysUserBo user) { Map params = user.getParams(); QueryWrapper wrapper = Wrappers.query(); wrapper.eq("u.del_flag", SystemConstants.NORMAL) .eq(ObjectUtil.isNotNull(user.getUserId()), "u.user_id", user.getUserId()) .like(StringUtils.isNotBlank(user.getUserName()), "u.user_name", user.getUserName()) .eq(StringUtils.isNotBlank(user.getStatus()), "u.status", user.getStatus()) .like(StringUtils.isNotBlank(user.getPhonenumber()), "u.phonenumber", user.getPhonenumber()) .between(params.get("beginTime") != null && params.get("endTime") != null, "u.create_time", params.get("beginTime"), params.get("endTime")) .and(ObjectUtil.isNotNull(user.getDeptId()), w -> { List deptList = deptMapper.selectListByParentId(user.getDeptId()); List ids = StreamUtils.toList(deptList, SysDept::getDeptId); ids.add(user.getDeptId()); w.in("u.dept_id", ids); }).orderByAsc("u.user_id"); if (StringUtils.isNotBlank(user.getExcludeUserIds())) { wrapper.notIn("u.user_id", StringUtils.splitTo(user.getExcludeUserIds(), Convert::toLong)); } return wrapper; } /** * 根据条件分页查询已分配用户角色列表 * * @param user 用户信息 * @return 用户信息集合信息 */ @Override public TableDataInfo selectAllocatedList(SysUserBo user, PageQuery pageQuery) { QueryWrapper wrapper = Wrappers.query(); wrapper.eq("u.del_flag", SystemConstants.NORMAL) .eq(ObjectUtil.isNotNull(user.getRoleId()), "r.role_id", user.getRoleId()) .like(StringUtils.isNotBlank(user.getUserName()), "u.user_name", user.getUserName()) .eq(StringUtils.isNotBlank(user.getStatus()), "u.status", user.getStatus()) .like(StringUtils.isNotBlank(user.getPhonenumber()), "u.phonenumber", user.getPhonenumber()) .orderByAsc("u.user_id"); Page page = baseMapper.selectAllocatedList(pageQuery.build(), wrapper); return TableDataInfo.build(page); } /** * 根据条件分页查询未分配用户角色列表 * * @param user 用户信息 * @return 用户信息集合信息 */ @Override public TableDataInfo selectUnallocatedList(SysUserBo user, PageQuery pageQuery) { List userIds = userRoleMapper.selectUserIdsByRoleId(user.getRoleId()); QueryWrapper wrapper = Wrappers.query(); wrapper.eq("u.del_flag", SystemConstants.NORMAL) .and(w -> w.ne("r.role_id", user.getRoleId()).or().isNull("r.role_id")) .notIn(CollUtil.isNotEmpty(userIds), "u.user_id", userIds) .like(StringUtils.isNotBlank(user.getUserName()), "u.user_name", user.getUserName()) .like(StringUtils.isNotBlank(user.getPhonenumber()), "u.phonenumber", user.getPhonenumber()) .orderByAsc("u.user_id"); Page page = baseMapper.selectUnallocatedList(pageQuery.build(), wrapper); return TableDataInfo.build(page); } /** * 通过用户名查询用户 * * @param userName 用户名 * @return 用户对象信息 */ @Override public SysUserVo selectUserByUserName(String userName) { return baseMapper.selectVoOne(new LambdaQueryWrapper().eq(SysUser::getUserName, userName)); } /** * 通过手机号查询用户 * * @param phonenumber 手机号 * @return 用户对象信息 */ @Override public SysUserVo selectUserByPhonenumber(String phonenumber) { return baseMapper.selectVoOne(new LambdaQueryWrapper().eq(SysUser::getPhonenumber, phonenumber)); } /** * 通过用户ID查询用户 * * @param userId 用户ID * @return 用户对象信息 */ @Override public SysUserVo selectUserById(Long userId) { SysUserVo user = baseMapper.selectVoById(userId); if (ObjectUtil.isNull(user)) { return user; } user.setRoles(roleMapper.selectRolesByUserId(user.getUserId())); return user; } /** * 通过用户ID串查询用户 * * @param userIds 用户ID串 * @param deptId 部门id * @return 用户列表信息 */ @Override public List selectUserByIds(List userIds, Long deptId) { return baseMapper.selectUserList(new LambdaQueryWrapper() .select(SysUser::getUserId, SysUser::getUserName, SysUser::getNickName) .eq(SysUser::getStatus, SystemConstants.NORMAL) .eq(ObjectUtil.isNotNull(deptId), SysUser::getDeptId, deptId) .in(CollUtil.isNotEmpty(userIds), SysUser::getUserId, userIds)); } /** * 查询用户所属角色组 * * @param userId 用户ID * @return 结果 */ @Override public String selectUserRoleGroup(Long userId) { List list = roleMapper.selectRolesByUserId(userId); if (CollUtil.isEmpty(list)) { return StringUtils.EMPTY; } return StreamUtils.join(list, SysRoleVo::getRoleName); } /** * 查询用户所属岗位组 * * @param userId 用户ID * @return 结果 */ @Override public String selectUserPostGroup(Long userId) { List list = postMapper.selectPostsByUserId(userId); if (CollUtil.isEmpty(list)) { return StringUtils.EMPTY; } return StreamUtils.join(list, SysPostVo::getPostName); } /** * 校验用户名称是否唯一 * * @param user 用户信息 * @return 结果 */ @Override public boolean checkUserNameUnique(SysUserBo user) { boolean exist = baseMapper.exists(new LambdaQueryWrapper() .eq(SysUser::getUserName, user.getUserName()) .ne(ObjectUtil.isNotNull(user.getUserId()), SysUser::getUserId, user.getUserId())); return !exist; } /** * 校验手机号码是否唯一 * * @param user 用户信息 */ @Override public boolean checkPhoneUnique(SysUserBo user) { boolean exist = baseMapper.exists(new LambdaQueryWrapper() .eq(SysUser::getPhonenumber, user.getPhonenumber()) .ne(ObjectUtil.isNotNull(user.getUserId()), SysUser::getUserId, user.getUserId())); return !exist; } /** * 校验email是否唯一 * * @param user 用户信息 */ @Override public boolean checkEmailUnique(SysUserBo user) { boolean exist = baseMapper.exists(new LambdaQueryWrapper() .eq(SysUser::getEmail, user.getEmail()) .ne(ObjectUtil.isNotNull(user.getUserId()), SysUser::getUserId, user.getUserId())); return !exist; } /** * 校验用户是否允许操作 * * @param userId 用户ID */ @Override public void checkUserAllowed(Long userId) { if (ObjectUtil.isNotNull(userId) && LoginHelper.isSuperAdmin(userId)) { throw new ServiceException("不允许操作超级管理员用户"); } } /** * 校验用户是否有数据权限 * * @param userId 用户id */ @Override public void checkUserDataScope(Long userId) { if (ObjectUtil.isNull(userId)) { return; } if (LoginHelper.isSuperAdmin()) { return; } if (baseMapper.countUserById(userId) == 0) { throw new ServiceException("没有权限访问用户数据!"); } } /** * 新增保存用户信息 * * @param user 用户信息 * @return 结果 */ @Override @Transactional(rollbackFor = Exception.class) public int insertUser(SysUserBo user) { SysUser sysUser = MapstructUtils.convert(user, SysUser.class); // 新增用户信息 int rows = baseMapper.insert(sysUser); user.setUserId(sysUser.getUserId()); // 新增用户岗位关联 insertUserPost(user, false); // 新增用户与角色管理 insertUserRole(user, false); return rows; } /** * 注册用户信息 * * @param user 用户信息 * @return 结果 */ @Override public boolean registerUser(SysUserBo user, String tenantId) { user.setCreateBy(0L); user.setUpdateBy(0L); SysUser sysUser = MapstructUtils.convert(user, SysUser.class); sysUser.setTenantId(tenantId); return baseMapper.insert(sysUser) > 0; } /** * 修改保存用户信息 * * @param user 用户信息 * @return 结果 */ @Override @CacheEvict(cacheNames = CacheNames.SYS_NICKNAME, key = "#user.userId") @Transactional(rollbackFor = Exception.class) public int updateUser(SysUserBo user) { // 新增用户与角色管理 insertUserRole(user, true); // 新增用户与岗位管理 insertUserPost(user, true); SysUser sysUser = MapstructUtils.convert(user, SysUser.class); // 防止错误更新后导致的数据误删除 int flag = baseMapper.updateById(sysUser); if (flag < 1) { throw new ServiceException("修改用户" + user.getUserName() + "信息失败"); } return flag; } /** * 用户授权角色 * * @param userId 用户ID * @param roleIds 角色组 */ @Override @Transactional(rollbackFor = Exception.class) public void insertUserAuth(Long userId, Long[] roleIds) { insertUserRole(userId, roleIds, true); } /** * 修改用户状态 * * @param userId 用户ID * @param status 帐号状态 * @return 结果 */ @Override public int updateUserStatus(Long userId, String status) { return baseMapper.update(null, new LambdaUpdateWrapper() .set(SysUser::getStatus, status) .eq(SysUser::getUserId, userId)); } /** * 修改用户基本信息 * * @param user 用户信息 * @return 结果 */ @CacheEvict(cacheNames = CacheNames.SYS_NICKNAME, key = "#user.userId") @Override public int updateUserProfile(SysUserBo user) { return baseMapper.update(null, new LambdaUpdateWrapper() .set(ObjectUtil.isNotNull(user.getNickName()), SysUser::getNickName, user.getNickName()) .set(SysUser::getPhonenumber, user.getPhonenumber()) .set(SysUser::getEmail, user.getEmail()) .set(SysUser::getSex, user.getSex()) .eq(SysUser::getUserId, user.getUserId())); } /** * 修改用户头像 * * @param userId 用户ID * @param avatar 头像地址 * @return 结果 */ @Override public boolean updateUserAvatar(Long userId, Long avatar) { return baseMapper.update(null, new LambdaUpdateWrapper() .set(SysUser::getAvatar, avatar) .eq(SysUser::getUserId, userId)) > 0; } /** * 重置用户密码 * * @param userId 用户ID * @param password 密码 * @return 结果 */ @Override public int resetUserPwd(Long userId, String password) { return baseMapper.update(null, new LambdaUpdateWrapper() .set(SysUser::getPassword, password) .eq(SysUser::getUserId, userId)); } /** * 新增用户角色信息 * * @param user 用户对象 * @param clear 清除已存在的关联数据 */ private void insertUserRole(SysUserBo user, boolean clear) { this.insertUserRole(user.getUserId(), user.getRoleIds(), clear); } /** * 新增用户岗位信息 * * @param user 用户对象 * @param clear 清除已存在的关联数据 */ private void insertUserPost(SysUserBo user, boolean clear) { Long[] posts = user.getPostIds(); if (ArrayUtil.isNotEmpty(posts)) { if (clear) { // 删除用户与岗位关联 userPostMapper.delete(new LambdaQueryWrapper().eq(SysUserPost::getUserId, user.getUserId())); } // 新增用户与岗位管理 List list = StreamUtils.toList(List.of(posts), postId -> { SysUserPost up = new SysUserPost(); up.setUserId(user.getUserId()); up.setPostId(postId); return up; }); userPostMapper.insertBatch(list); } } /** * 新增用户角色信息 * * @param userId 用户ID * @param roleIds 角色组 * @param clear 清除已存在的关联数据 */ private void insertUserRole(Long userId, Long[] roleIds, boolean clear) { if (ArrayUtil.isNotEmpty(roleIds)) { List roleList = new ArrayList<>(List.of(roleIds)); if (!LoginHelper.isSuperAdmin(userId)) { roleList.remove(SystemConstants.SUPER_ADMIN_ID); } // 判断是否具有此角色的操作权限 List roles = roleMapper.selectRoleList( new QueryWrapper().in("r.role_id", roleList)); if (CollUtil.isEmpty(roles)) { throw new ServiceException("没有权限访问角色的数据"); } if (clear) { // 删除用户与角色关联 userRoleMapper.delete(new LambdaQueryWrapper().eq(SysUserRole::getUserId, userId)); } // 新增用户与角色管理 List list = StreamUtils.toList(roleList, roleId -> { SysUserRole ur = new SysUserRole(); ur.setUserId(userId); ur.setRoleId(roleId); return ur; }); userRoleMapper.insertBatch(list); } } /** * 通过用户ID删除用户 * * @param userId 用户ID * @return 结果 */ @Override @Transactional(rollbackFor = Exception.class) public int deleteUserById(Long userId) { // 删除用户与角色关联 userRoleMapper.delete(new LambdaQueryWrapper().eq(SysUserRole::getUserId, userId)); // 删除用户与岗位表 userPostMapper.delete(new LambdaQueryWrapper().eq(SysUserPost::getUserId, userId)); // 防止更新失败导致的数据删除 int flag = baseMapper.deleteById(userId); if (flag < 1) { throw new ServiceException("删除用户失败!"); } return flag; } /** * 批量删除用户信息 * * @param userIds 需要删除的用户ID * @return 结果 */ @Override @Transactional(rollbackFor = Exception.class) public int deleteUserByIds(Long[] userIds) { for (Long userId : userIds) { checkUserAllowed(userId); checkUserDataScope(userId); } List ids = List.of(userIds); // 删除用户与角色关联 userRoleMapper.delete(new LambdaQueryWrapper().in(SysUserRole::getUserId, ids)); // 删除用户与岗位表 userPostMapper.delete(new LambdaQueryWrapper().in(SysUserPost::getUserId, ids)); // 防止更新失败导致的数据删除 int flag = baseMapper.deleteByIds(ids); if (flag < 1) { throw new ServiceException("删除用户失败!"); } return flag; } /** * 通过部门id查询当前部门所有用户 * * @param deptId 部门ID * @return 用户信息集合信息 */ @Override public List selectUserListByDept(Long deptId) { LambdaQueryWrapper lqw = Wrappers.lambdaQuery(); lqw.eq(SysUser::getDeptId, deptId); lqw.orderByAsc(SysUser::getUserId); return baseMapper.selectVoList(lqw); } /** * 通过用户ID查询用户账户 * * @param userId 用户ID * @return 用户账户 */ @Cacheable(cacheNames = CacheNames.SYS_USER_NAME, key = "#userId") @Override public String selectUserNameById(Long userId) { SysUser sysUser = baseMapper.selectOne(new LambdaQueryWrapper() .select(SysUser::getUserName).eq(SysUser::getUserId, userId)); return ObjectUtils.notNullGetter(sysUser, SysUser::getUserName); } /** * 通过用户ID查询用户账户 * * @param userId 用户ID * @return 用户账户 */ @Override @Cacheable(cacheNames = CacheNames.SYS_NICKNAME, key = "#userId") public String selectNicknameById(Long userId) { SysUser sysUser = baseMapper.selectOne(new LambdaQueryWrapper() .select(SysUser::getNickName).eq(SysUser::getUserId, userId)); return ObjectUtils.notNullGetter(sysUser, SysUser::getNickName); } /** * 通过用户ID查询用户账户 * * @param userIds 用户ID 多个用逗号隔开 * @return 用户账户 */ @Override public String selectNicknameByIds(String userIds) { List list = new ArrayList<>(); for (Long id : StringUtils.splitTo(userIds, Convert::toLong)) { String nickname = SpringUtils.getAopProxy(this).selectNicknameById(id); if (StringUtils.isNotBlank(nickname)) { list.add(nickname); } } return String.join(StringUtils.SEPARATOR, list); } /** * 通过用户ID查询用户手机号 * * @param userId 用户id * @return 用户手机号 */ @Override public String selectPhonenumberById(Long userId) { SysUser sysUser = baseMapper.selectOne(new LambdaQueryWrapper() .select(SysUser::getPhonenumber).eq(SysUser::getUserId, userId)); return ObjectUtils.notNullGetter(sysUser, SysUser::getPhonenumber); } /** * 通过用户ID查询用户邮箱 * * @param userId 用户id * @return 用户邮箱 */ @Override public String selectEmailById(Long userId) { SysUser sysUser = baseMapper.selectOne(new LambdaQueryWrapper() .select(SysUser::getEmail).eq(SysUser::getUserId, userId)); return ObjectUtils.notNullGetter(sysUser, SysUser::getEmail); } /** * 通过用户ID查询用户列表 * * @param userIds 用户ids * @return 用户列表 */ @Override public List selectListByIds(List userIds) { if (CollUtil.isEmpty(userIds)) { return List.of(); } List list = baseMapper.selectVoList(new LambdaQueryWrapper() .select(SysUser::getUserId, SysUser::getUserName, SysUser::getNickName, SysUser::getEmail, SysUser::getPhonenumber) .eq(SysUser::getStatus, SystemConstants.NORMAL) .in(SysUser::getUserId, userIds)); return BeanUtil.copyToList(list, UserDTO.class); } /** * 通过角色ID查询用户ID * * @param roleIds 角色ids * @return 用户ids */ @Override public List selectUserIdsByRoleIds(List roleIds) { if (CollUtil.isEmpty(roleIds)) { return List.of(); } List userRoles = userRoleMapper.selectList( new LambdaQueryWrapper().in(SysUserRole::getRoleId, roleIds)); return StreamUtils.toList(userRoles, SysUserRole::getUserId); } /** * 通过角色ID查询用户 * * @param roleIds 角色ids * @return 用户 */ @Override public List selectUsersByRoleIds(List roleIds) { if (CollUtil.isEmpty(roleIds)) { return List.of(); } // 通过角色ID获取用户角色信息 List userRoles = userRoleMapper.selectList( new LambdaQueryWrapper().in(SysUserRole::getRoleId, roleIds)); // 获取用户ID列表 Set userIds = StreamUtils.toSet(userRoles, SysUserRole::getUserId); return selectListByIds(new ArrayList<>(userIds)); } /** * 通过部门ID查询用户 * * @param deptIds 部门ids * @return 用户 */ @Override public List selectUsersByDeptIds(List deptIds) { if (CollUtil.isEmpty(deptIds)) { return List.of(); } List list = baseMapper.selectVoList(new LambdaQueryWrapper() .select(SysUser::getUserId, SysUser::getUserName, SysUser::getNickName, SysUser::getEmail, SysUser::getPhonenumber) .eq(SysUser::getStatus, SystemConstants.NORMAL) .in(SysUser::getDeptId, deptIds)); return BeanUtil.copyToList(list, UserDTO.class); } /** * 通过岗位ID查询用户 * * @param postIds 岗位ids * @return 用户 */ @Override public List selectUsersByPostIds(List postIds) { if (CollUtil.isEmpty(postIds)) { return List.of(); } // 通过岗位ID获取用户岗位信息 List userPosts = userPostMapper.selectList( new LambdaQueryWrapper().in(SysUserPost::getPostId, postIds)); // 获取用户ID列表 Set userIds = StreamUtils.toSet(userPosts, SysUserPost::getUserId); return selectListByIds(new ArrayList<>(userIds)); } }