zhangherong
2025-06-25 23855599412c4d61b38d78f0f3abd3430a48b5b1
lxzn-module-system/lxzn-system-biz/src/main/java/org/jeecg/modules/system/service/impl/SysUserServiceImpl.java
¶Ô±ÈÐÂÎļþ
@@ -0,0 +1,809 @@
package org.jeecg.modules.system.service.impl;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.core.toolkit.CollectionUtils;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang3.StringUtils;
import org.jeecg.common.api.vo.Result;
import org.jeecg.common.constant.CacheConstant;
import org.jeecg.common.constant.CommonConstant;
import org.jeecg.common.constant.enums.RoleIndexConfigEnum;
import org.jeecg.common.desensitization.annotation.SensitiveEncode;
import org.jeecg.common.system.vo.DictModel;
import org.jeecg.common.system.vo.LoginUser;
import org.jeecg.common.system.vo.SysUserCacheInfo;
import org.jeecg.common.util.DateUtils;
import org.jeecg.common.util.PasswordUtil;
import org.jeecg.common.util.UUIDGenerator;
import org.jeecg.common.util.oConvertUtils;
import org.jeecg.modules.base.service.BaseCommonService;
import org.jeecg.modules.system.entity.*;
import org.jeecg.modules.system.mapper.*;
import org.jeecg.modules.system.model.SysUserSysDepartModel;
import org.jeecg.modules.system.service.ISysDictService;
import org.jeecg.modules.system.service.ISysUserService;
import org.jeecg.modules.system.vo.MdcUserProVo;
import org.jeecg.modules.system.vo.SysUserDepVo;
import org.jeecg.modules.system.vo.UserSelector;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.cache.annotation.CacheEvict;
import org.springframework.cache.annotation.Cacheable;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import javax.annotation.Resource;
import java.util.*;
import java.util.stream.Collectors;
/**
 * <p>
 * ç”¨æˆ·è¡¨ æœåŠ¡å®žçŽ°ç±»
 * </p>
 *
 * @Author: scott
 * @Date: 2018-12-20
 */
@Service
@Slf4j
public class SysUserServiceImpl extends ServiceImpl<SysUserMapper, SysUser> implements ISysUserService {
   @Autowired
   private SysUserMapper userMapper;
   @Autowired
   private SysPermissionMapper sysPermissionMapper;
   @Autowired
   private SysUserRoleMapper sysUserRoleMapper;
   @Autowired
   private SysUserDepartMapper sysUserDepartMapper;
   @Autowired
   private SysDepartMapper sysDepartMapper;
   @Autowired
   private SysRoleMapper sysRoleMapper;
   @Autowired
   private SysDepartRoleUserMapper departRoleUserMapper;
   @Autowired
   private SysDepartRoleMapper sysDepartRoleMapper;
   @Resource
   private BaseCommonService baseCommonService;
   @Autowired
   private SysThirdAccountMapper sysThirdAccountMapper;
   @Autowired
   ThirdAppWechatEnterpriseServiceImpl wechatEnterpriseService;
   @Autowired
   ThirdAppDingtalkServiceImpl dingtalkService;
   @Autowired
   SysRoleIndexMapper sysRoleIndexMapper;
   @Resource
   MdcUserProductionMapper mdcUserProductionMapper;
   @Resource
   private ISysDictService sysDictService;
   @Resource
   private MdcProductionEquipmentMapper mdcProductionEquipmentMapper;
   @Resource
   private DncDevicePermissionMapper dncDevicePermissionMapper;
    @Override
    @CacheEvict(value = {CacheConstant.SYS_USERS_CACHE}, allEntries = true)
    public Result<?> resetPassword(String username, String oldpassword, String newpassword, String confirmpassword) {
        SysUser user = userMapper.getUserByName(username);
        String passwordEncode = PasswordUtil.encrypt(username, oldpassword, user.getSalt());
        if (!user.getPassword().equals(passwordEncode)) {
            return Result.error("旧密码输入错误!");
        }
        if (oConvertUtils.isEmpty(newpassword)) {
            return Result.error("新密码不允许为空!");
        }
        if (!newpassword.equals(confirmpassword)) {
            return Result.error("两次输入密码不一致!");
        }
      //设置密码更新时间
      //sysUser.setPasswordTime(new Date());
      //设置密码首次登录失效
      //sysUser.setPasswordFlag(CommonConstant.DEL_FLAG_0);
        String password = PasswordUtil.encrypt(username, newpassword, user.getSalt());
        this.userMapper.update(new SysUser().setPassword(password).setPasswordTime(new Date()).setPasswordFlag(CommonConstant.DEL_FLAG_0), new LambdaQueryWrapper<SysUser>().eq(SysUser::getId, user.getId()));
        return Result.ok("密码重置成功!");
    }
    @Override
    @CacheEvict(value = {CacheConstant.SYS_USERS_CACHE}, allEntries = true)
    public Result<?> changePassword(SysUser sysUser) {
        String salt = oConvertUtils.randomGen(8);
        sysUser.setSalt(salt);
      //设置密码更新时间
      sysUser.setPasswordTime(new Date());
      //管理员修改密码,设置用户首次登录
      //sysUser.setPasswordFlag();
        String password = sysUser.getPassword();
        String passwordEncode = PasswordUtil.encrypt(sysUser.getUsername(), password, salt);
        sysUser.setPassword(passwordEncode);
        this.userMapper.updateById(sysUser);
        return Result.ok("密码修改成功!");
    }
    @Override
    @CacheEvict(value={CacheConstant.SYS_USERS_CACHE}, allEntries=true)
   @Transactional(rollbackFor = Exception.class)
   public boolean deleteUser(String userId) {
      //1.删除用户
      this.removeById(userId);
      return false;
   }
   @Override
    @CacheEvict(value={CacheConstant.SYS_USERS_CACHE}, allEntries=true)
   @Transactional(rollbackFor = Exception.class)
   public boolean deleteBatchUsers(String userIds) {
      //1.删除用户
      this.removeByIds(Arrays.asList(userIds.split(",")));
      return false;
   }
   @Override
   public SysUser getUserByName(String username) {
      return userMapper.getUserByName(username);
   }
   @Override
   @Transactional(rollbackFor = Exception.class)
   public void addUserWithRole(SysUser user, String roles) {
      this.save(user);
      if(oConvertUtils.isNotEmpty(roles)) {
         String[] arr = roles.split(",");
         for (String roleId : arr) {
            SysUserRole userRole = new SysUserRole(user.getId(), roleId);
            sysUserRoleMapper.insert(userRole);
         }
      }
   }
   @Override
   @CacheEvict(value= {CacheConstant.SYS_USERS_CACHE}, allEntries=true)
   @Transactional(rollbackFor = Exception.class)
   public void editUserWithRole(SysUser user, String roles) {
      this.updateById(user);
      //先删后加
      sysUserRoleMapper.delete(new QueryWrapper<SysUserRole>().lambda().eq(SysUserRole::getUserId, user.getId()));
      if(oConvertUtils.isNotEmpty(roles)) {
         String[] arr = roles.split(",");
         for (String roleId : arr) {
            SysUserRole userRole = new SysUserRole(user.getId(), roleId);
            sysUserRoleMapper.insert(userRole);
         }
      }
   }
   @Override
   public List<String> getRole(String username) {
      return sysUserRoleMapper.getRoleByUserName(username);
   }
   /**
    * èŽ·å–åŠ¨æ€é¦–é¡µè·¯ç”±é…ç½®
    * @param username
    * @param version
    * @return
    */
   @Override
   public SysRoleIndex getDynamicIndexByUserRole(String username,String version) {
      List<String> roles = sysUserRoleMapper.getRoleByUserName(username);
      String componentUrl = RoleIndexConfigEnum.getIndexByRoles(roles);
      SysRoleIndex roleIndex = new SysRoleIndex(componentUrl);
      //只有 X-Version=v3 çš„æ—¶å€™ï¼Œæ‰è¯»å–sys_role_index表获取角色首页配置
      if (oConvertUtils.isNotEmpty(version) && roles!=null && roles.size()>0) {
         LambdaQueryWrapper<SysRoleIndex> routeIndexQuery = new LambdaQueryWrapper();
         //用户所有角色
         routeIndexQuery.in(SysRoleIndex::getRoleCode, roles);
         //角色首页状态0:未开启  1:开启
         routeIndexQuery.eq(SysRoleIndex::getStatus, CommonConstant.STATUS_1);
         //优先级正序排序
         routeIndexQuery.orderByAsc(SysRoleIndex::getPriority);
         List<SysRoleIndex> list = sysRoleIndexMapper.selectList(routeIndexQuery);
         if (null != list && list.size() > 0) {
            roleIndex = list.get(0);
         }
      }
      //如果componentUrl为空,则返回空
      if(oConvertUtils.isEmpty(roleIndex.getComponent())){
         return null;
      }
      return roleIndex;
   }
   /**
    * é€šè¿‡ç”¨æˆ·åèŽ·å–ç”¨æˆ·è§’è‰²é›†åˆ
    * @param username ç”¨æˆ·å
     * @return è§’色集合
    */
   @Override
   public Set<String> getUserRolesSet(String username) {
      // æŸ¥è¯¢ç”¨æˆ·æ‹¥æœ‰çš„角色集合
      List<String> roles = sysUserRoleMapper.getRoleByUserName(username);
      log.info("-------通过数据库读取用户拥有的角色Rules------username: " + username + ",Roles size: " + (roles == null ? 0 : roles.size()));
      return new HashSet<>(roles);
   }
   /**
    * é€šè¿‡ç”¨æˆ·åèŽ·å–ç”¨æˆ·æƒé™é›†åˆ
    *
    * @param username ç”¨æˆ·å
    * @return æƒé™é›†åˆ
    */
   @Override
   public Set<String> getUserPermissionsSet(String username) {
      Set<String> permissionSet = new HashSet<>();
      List<SysPermission> permissionList = sysPermissionMapper.queryByUser(username);
      for (SysPermission po : permissionList) {
//         // TODO URL规则有问题?
//         if (oConvertUtils.isNotEmpty(po.getUrl())) {
//            permissionSet.add(po.getUrl());
//         }
         if (oConvertUtils.isNotEmpty(po.getPerms())) {
            permissionSet.add(po.getPerms());
         }
      }
      log.info("-------通过数据库读取用户拥有的权限Perms------username: "+ username+",Perms size: "+ (permissionSet==null?0:permissionSet.size()) );
      return permissionSet;
   }
   /**
    * å‡çº§SpringBoot2.6.6,不允许循环依赖
    * @author:qinfeng
    * @update: 2022-04-07
    * @param username
    * @return
    */
   @Override
   public SysUserCacheInfo getCacheUser(String username) {
      SysUserCacheInfo info = new SysUserCacheInfo();
      info.setOneDepart(true);
      if(oConvertUtils.isEmpty(username)) {
         return null;
      }
      //查询用户信息
      SysUser sysUser = userMapper.getUserByName(username);
      if(sysUser!=null) {
         info.setSysUserCode(sysUser.getUsername());
         info.setSysUserName(sysUser.getRealname());
         info.setSysOrgCode(sysUser.getOrgCode());
      }
      //多部门支持in查询
      List<SysDepart> list = sysDepartMapper.queryUserDeparts(sysUser.getId());
      List<String> sysMultiOrgCode = new ArrayList<String>();
      if(list==null || list.size()==0) {
         //当前用户无部门
         //sysMultiOrgCode.add("0");
      }else if(list.size()==1) {
         sysMultiOrgCode.add(list.get(0).getOrgCode());
      }else {
         info.setOneDepart(false);
         for (SysDepart dpt : list) {
            sysMultiOrgCode.add(dpt.getOrgCode());
         }
      }
      info.setSysMultiOrgCode(sysMultiOrgCode);
      return info;
   }
    /**
     * æ ¹æ®éƒ¨é—¨Id查询
     * @param page
     * @param departId éƒ¨é—¨id
     * @param username ç”¨æˆ·è´¦æˆ·åç§°
     * @return
     */
   @Override
   public IPage<SysUser> getUserByDepId(Page<SysUser> page, String departId,String username) {
      return userMapper.getUserByDepId(page, departId,username);
   }
   @Override
   public IPage<SysUser> getUserByDepIds(Page<SysUser> page, List<String> departIds, String username) {
      return userMapper.getUserByDepIds(page, departIds,username);
   }
   @Override
   public Map<String, String> getDepNamesByUserIds(List<String> userIds) {
      List<SysUserDepVo> list = this.baseMapper.getDepNamesByUserIds(userIds);
      Map<String, String> res = new HashMap(5);
      list.forEach(item -> {
               if (res.get(item.getUserId()) == null) {
                  res.put(item.getUserId(), item.getDepartName());
               } else {
                  res.put(item.getUserId(), res.get(item.getUserId()) + "," + item.getDepartName());
               }
            }
      );
      return res;
   }
   //update-begin-author:taoyan date:2022-9-13 for: VUEN-2245【漏洞】发现新漏洞待处理20220906 ----sql注入  æ–¹æ³•没有使用,注掉
/*   @Override
   public IPage<SysUser> getUserByDepartIdAndQueryWrapper(Page<SysUser> page, String departId, QueryWrapper<SysUser> queryWrapper) {
      LambdaQueryWrapper<SysUser> lambdaQueryWrapper = queryWrapper.lambda();
      lambdaQueryWrapper.eq(SysUser::getDelFlag, CommonConstant.DEL_FLAG_0);
        lambdaQueryWrapper.inSql(SysUser::getId, "SELECT user_id FROM sys_user_depart WHERE dep_id = '" + departId + "'");
        return userMapper.selectPage(page, lambdaQueryWrapper);
   }*/
   //update-end-author:taoyan date:2022-9-13 for: VUEN-2245【漏洞】发现新漏洞待处理20220906 ----sql注入 æ–¹æ³•没有使用,注掉
   @Override
   public IPage<SysUserSysDepartModel> queryUserByOrgCode(String orgCode, SysUser userParams, IPage page) {
      List<SysUserSysDepartModel> list = baseMapper.getUserByOrgCode(page, orgCode, userParams);
      Integer total = baseMapper.getUserByOrgCodeTotal(orgCode, userParams);
      IPage<SysUserSysDepartModel> result = new Page<>(page.getCurrent(), page.getSize(), total);
      result.setRecords(list);
      return result;
   }
    /**
     * æ ¹æ®è§’色Id查询
     * @param page
     * @param roleId è§’色id
     * @param username ç”¨æˆ·è´¦æˆ·åç§°
     * @return
     */
   @Override
   public IPage<SysUser> getUserByRoleId(Page<SysUser> page, String roleId, String username) {
      return userMapper.getUserByRoleId(page,roleId,username);
   }
   @Override
   @CacheEvict(value= {CacheConstant.SYS_USERS_CACHE}, key="#username")
   public void updateUserDepart(String username,String orgCode) {
      baseMapper.updateUserDepart(username, orgCode);
   }
   @Override
   public SysUser getUserByPhone(String phone) {
      return userMapper.getUserByPhone(phone);
   }
   @Override
   public SysUser getUserByEmail(String email) {
      return userMapper.getUserByEmail(email);
   }
   @Override
   @Transactional(rollbackFor = Exception.class)
   public void addUserWithDepart(SysUser user, String selectedParts) {
//      this.save(user);  //保存角色的时候已经添加过一次了
      if(oConvertUtils.isNotEmpty(selectedParts)) {
         String[] arr = selectedParts.split(",");
         for (String deaprtId : arr) {
            SysUserDepart userDeaprt = new SysUserDepart(user.getId(), deaprtId);
            sysUserDepartMapper.insert(userDeaprt);
         }
      }
   }
   @Override
   @Transactional(rollbackFor = Exception.class)
   @CacheEvict(value={CacheConstant.SYS_USERS_CACHE}, allEntries=true)
   public void editUserWithDepart(SysUser user, String departs) {
        //更新角色的时候已经更新了一次了,可以再跟新一次
      this.updateById(user);
      String[] arr = {};
      if(oConvertUtils.isNotEmpty(departs)){
         arr = departs.split(",");
      }
      //查询已关联部门
      List<SysUserDepart> userDepartList = sysUserDepartMapper.selectList(new QueryWrapper<SysUserDepart>().lambda().eq(SysUserDepart::getUserId, user.getId()));
      if(userDepartList != null && userDepartList.size()>0){
         for(SysUserDepart depart : userDepartList ){
            //修改已关联部门删除部门用户角色关系
            if(!Arrays.asList(arr).contains(depart.getDepId())){
               List<SysDepartRole> sysDepartRoleList = sysDepartRoleMapper.selectList(
                     new QueryWrapper<SysDepartRole>().lambda().eq(SysDepartRole::getDepartId,depart.getDepId()));
               List<String> roleIds = sysDepartRoleList.stream().map(SysDepartRole::getId).collect(Collectors.toList());
               if(roleIds != null && roleIds.size()>0){
                  departRoleUserMapper.delete(new QueryWrapper<SysDepartRoleUser>().lambda().eq(SysDepartRoleUser::getUserId, user.getId())
                        .in(SysDepartRoleUser::getDroleId,roleIds));
               }
            }
         }
      }
      //先删后加
      sysUserDepartMapper.delete(new QueryWrapper<SysUserDepart>().lambda().eq(SysUserDepart::getUserId, user.getId()));
      if(oConvertUtils.isNotEmpty(departs)) {
         for (String departId : arr) {
            SysUserDepart userDepart = new SysUserDepart(user.getId(), departId);
            sysUserDepartMapper.insert(userDepart);
         }
      }
   }
   /**
      * æ ¡éªŒç”¨æˆ·æ˜¯å¦æœ‰æ•ˆ
    * @param sysUser
    * @return
    */
   @Override
   public Result<?> checkUserIsEffective(SysUser sysUser, String loginType) {
      Result<?> result = new Result<Object>();
      //情况1:根据用户信息查询,该用户不存在
      if (sysUser == null) {
         result.error500("该用户不存在,请注册");
         baseCommonService.addLog("用户登录失败,用户不存在!", CommonConstant.LOG_TYPE_1, null);
         return result;
      }
      //情况2:根据用户信息查询,该用户已注销
      //update-begin---author:王帅   Date:20200601  for:if条件永远为falsebug------------
      if (CommonConstant.DEL_FLAG_1.equals(sysUser.getDelFlag())) {
      //update-end---author:王帅   Date:20200601  for:if条件永远为falsebug------------
         baseCommonService.addLog("用户登录失败,用户名:" + sysUser.getUsername() + "已注销!", CommonConstant.LOG_TYPE_1, null);
         result.error500("该用户已注销");
         return result;
      }
      //情况3:根据用户信息查询,该用户已冻结
      if (CommonConstant.USER_FREEZE.equals(sysUser.getStatus())) {
         baseCommonService.addLog("用户登录失败,用户名:" + sysUser.getUsername() + "已冻结!", CommonConstant.LOG_TYPE_1, null);
         result.error500("该用户已冻结");
         return result;
      }
      //情况4:根据用户信息查询,该用户密码系首次使用,需修改密码
      List<DictModel> dictList = sysDictService.queryEnableDictItemsByCode(CommonConstant.DICT_USER_FIRST_LOGIN);
      if (!"terminal".equals(loginType) && dictList != null && !dictList.isEmpty()) {
         if (CommonConstant.DEL_FLAG_1.equals(Integer.valueOf(dictList.get(0).getValue())) && CommonConstant.DEL_FLAG_1.equals(sysUser.getPasswordFlag())) {
            baseCommonService.addLog("用户登录失败,用户名:" + sysUser.getUsername() + "系首次登录系统,请重置密码!", CommonConstant.LOG_TYPE_1, null);
            result.setCode(5001);
            result.setMessage("用户密码系默认密码,需重置密码后重新登录密码!");
            result.setSuccess(false);
            return result;
         }
      }
      //情况5:根据用户信息查询,该用户密码是否已过更改周期
      Date passwordTime = sysUser.getPasswordTime();
      //Integer passwordExpirationPeriod = CommonConstant.PASSWORD_EXPIRATION_PERIOD;
      List<DictModel> dictModelList = sysDictService.queryEnableDictItemsByCode(CommonConstant.DICT_PASSWORD_EXPIRATION);
      if (dictModelList != null && !dictModelList.isEmpty()) {
         Integer passwordExpirationPeriod = Integer.valueOf(dictModelList.get(0).getValue());
         Date dayAfter = DateUtils.getDayAfter(passwordTime, passwordExpirationPeriod);
         if (new Date().after(dayAfter)) {
            baseCommonService.addLog("用户登录失败,用户名:" + sysUser.getUsername() + "密码已过有效期,请重置密码!", CommonConstant.LOG_TYPE_1, null);
            result.setCode(5002);
            result.setMessage("用户密码已过有效期,请重置密码!");
            result.setSuccess(false);
            return result;
         }
      }
      return result;
   }
   @Override
   public List<SysUser> queryLogicDeleted() {
      return this.queryLogicDeleted(null);
   }
   @Override
   public List<SysUser> queryLogicDeleted(LambdaQueryWrapper<SysUser> wrapper) {
      if (wrapper == null) {
         wrapper = new LambdaQueryWrapper<>();
      }
      wrapper.eq(SysUser::getDelFlag, CommonConstant.DEL_FLAG_1);
      return userMapper.selectLogicDeleted(wrapper);
   }
   @Override
   @CacheEvict(value={CacheConstant.SYS_USERS_CACHE}, allEntries=true)
   public boolean revertLogicDeleted(List<String> userIds, SysUser updateEntity) {
      return userMapper.revertLogicDeleted(userIds, updateEntity) > 0;
   }
   @Override
   @Transactional(rollbackFor = Exception.class)
   public boolean removeLogicDeleted(List<String> userIds) {
      // 1. åˆ é™¤ç”¨æˆ·
      int line = userMapper.deleteLogicDeleted(userIds);
      // 2. åˆ é™¤ç”¨æˆ·éƒ¨é—¨å…³ç³»
      line += sysUserDepartMapper.delete(new LambdaQueryWrapper<SysUserDepart>().in(SysUserDepart::getUserId, userIds));
      // 3. åˆ é™¤ç”¨æˆ·äº§çº¿å…³ç³»
      line += mdcUserProductionMapper.delete(new LambdaQueryWrapper<MdcUserProduction>().in(MdcUserProduction::getUserId, userIds));
      //3. åˆ é™¤ç”¨æˆ·è§’色关系
      line += sysUserRoleMapper.delete(new LambdaQueryWrapper<SysUserRole>().in(SysUserRole::getUserId, userIds));
      //4.同步删除第三方App的用户
      try {
         dingtalkService.removeThirdAppUser(userIds);
         wechatEnterpriseService.removeThirdAppUser(userIds);
      } catch (Exception e) {
         log.error("同步删除第三方App的用户失败:", e);
      }
      //5. åˆ é™¤ç¬¬ä¸‰æ–¹ç”¨æˆ·è¡¨ï¼ˆå› ä¸ºç¬¬4步需要用到第三方用户表,所以在他之后删)
      line += sysThirdAccountMapper.delete(new LambdaQueryWrapper<SysThirdAccount>().in(SysThirdAccount::getSysUserId, userIds));
      return line != 0;
   }
    @Override
    @Transactional(rollbackFor = Exception.class)
    public boolean updateNullPhoneEmail() {
        userMapper.updateNullByEmptyString("email");
        userMapper.updateNullByEmptyString("phone");
        return true;
    }
   @Override
   public void saveThirdUser(SysUser sysUser) {
      //保存用户
      String userid = UUIDGenerator.generate();
      sysUser.setId(userid);
      baseMapper.insert(sysUser);
      //获取第三方角色
      SysRole sysRole = sysRoleMapper.selectOne(new LambdaQueryWrapper<SysRole>().eq(SysRole::getRoleCode, "third_role"));
      //保存用户角色
      SysUserRole userRole = new SysUserRole();
      userRole.setRoleId(sysRole.getId());
      userRole.setUserId(userid);
      sysUserRoleMapper.insert(userRole);
   }
   @Override
   public List<SysUser> queryByDepIds(List<String> departIds, String username) {
      return userMapper.queryByDepIds(departIds,username);
   }
   @Override
   @Transactional(rollbackFor = Exception.class)
   public void saveUser(SysUser user, String selectedRoles, String selectedDeparts, String selectedProductions) {
      //step.1 ä¿å­˜ç”¨æˆ·
      this.save(user);
      //step.2 ä¿å­˜è§’色
      if(oConvertUtils.isNotEmpty(selectedRoles)) {
         String[] arr = selectedRoles.split(",");
         for (String roleId : arr) {
            SysUserRole userRole = new SysUserRole(user.getId(), roleId);
            sysUserRoleMapper.insert(userRole);
         }
      }
      //step.3 ä¿å­˜æ‰€å±žéƒ¨é—¨
      if(oConvertUtils.isNotEmpty(selectedDeparts)) {
         String[] arr = selectedDeparts.split(",");
         for (String deaprtId : arr) {
            SysUserDepart userDeaprt = new SysUserDepart(user.getId(), deaprtId);
            sysUserDepartMapper.insert(userDeaprt);
         }
      }
      String[] arr = {};
      //step.4 ä¿å­˜æ‰€å±žäº§çº¿
      if (oConvertUtils.isNotEmpty(selectedProductions)) {
         arr = selectedProductions.split(",");
         for (String productionId : arr) {
            MdcUserProduction mdcUserProduction = new MdcUserProduction(user.getId(), productionId);
            mdcUserProductionMapper.insert(mdcUserProduction);
         }
      }
      //step.5 ä¿å­˜è®¾å¤‡æƒé™
      List<String> EquipmentIds= mdcProductionEquipmentMapper.selectList(new QueryWrapper<MdcProductionEquipment>().in("production_id",arr))
            .stream().map(MdcProductionEquipment::getEquipmentId).collect(Collectors.toList());
      if (oConvertUtils.isNotEmpty(EquipmentIds)) {
         for (String equipmentId : EquipmentIds) {
            DncDevicePermission dncDevicePermission=new DncDevicePermission();
            dncDevicePermission.setDeviceId(equipmentId);
            dncDevicePermission.setUserId(user.getId());
            dncDevicePermissionMapper.insert(dncDevicePermission);
         }
      }
   }
   @Override
   @Transactional(rollbackFor = Exception.class)
   @CacheEvict(value={CacheConstant.SYS_USERS_CACHE}, allEntries=true)
   public void editUser(SysUser user, String roles, String departs, String productions) {
      //step.1 ä¿®æ”¹ç”¨æˆ·åŸºç¡€ä¿¡æ¯
      this.updateById(user);
      //step.2 ä¿®æ”¹è§’色
      //处理用户角色 å…ˆåˆ åŽåŠ 
      sysUserRoleMapper.delete(new QueryWrapper<SysUserRole>().lambda().eq(SysUserRole::getUserId, user.getId()));
      if(oConvertUtils.isNotEmpty(roles)) {
         String[] arr = roles.split(",");
         for (String roleId : arr) {
            SysUserRole userRole = new SysUserRole(user.getId(), roleId);
            sysUserRoleMapper.insert(userRole);
         }
      }
      //step.3 ä¿®æ”¹éƒ¨é—¨
      String[] arr = {};
      if(oConvertUtils.isNotEmpty(departs)){
         arr = departs.split(",");
      }
      //查询已关联部门
      List<SysUserDepart> userDepartList = sysUserDepartMapper.selectList(new QueryWrapper<SysUserDepart>().lambda().eq(SysUserDepart::getUserId, user.getId()));
      if(userDepartList != null && userDepartList.size()>0){
         for(SysUserDepart depart : userDepartList ){
            //修改已关联部门删除部门用户角色关系
            if(!Arrays.asList(arr).contains(depart.getDepId())){
               List<SysDepartRole> sysDepartRoleList = sysDepartRoleMapper.selectList(
                     new QueryWrapper<SysDepartRole>().lambda().eq(SysDepartRole::getDepartId,depart.getDepId()));
               List<String> roleIds = sysDepartRoleList.stream().map(SysDepartRole::getId).collect(Collectors.toList());
               if(roleIds != null && roleIds.size()>0){
                  departRoleUserMapper.delete(new QueryWrapper<SysDepartRoleUser>().lambda().eq(SysDepartRoleUser::getUserId, user.getId())
                        .in(SysDepartRoleUser::getDroleId,roleIds));
               }
            }
         }
      }
      //先删后加
      sysUserDepartMapper.delete(new QueryWrapper<SysUserDepart>().lambda().eq(SysUserDepart::getUserId, user.getId()));
      if(oConvertUtils.isNotEmpty(departs)) {
         for (String departId : arr) {
            SysUserDepart userDepart = new SysUserDepart(user.getId(), departId);
            sysUserDepartMapper.insert(userDepart);
         }
      }
      //step.4 ä¿®æ”¹äº§çº¿
      String[] array = {};
      if(oConvertUtils.isNotEmpty(productions)){
         array = productions.split(",");
      }
      //先删后加
      mdcUserProductionMapper.delete(new QueryWrapper<MdcUserProduction>().lambda().eq(MdcUserProduction::getUserId, user.getId()));
      if (oConvertUtils.isNotEmpty(productions)) {
         for (String productionId : array) {
            MdcUserProduction mdcUserProduction = new MdcUserProduction(user.getId(), productionId);
            mdcUserProductionMapper.insert(mdcUserProduction);
         }
      }
      //step.5 ä¿®æ”¹è®¾å¤‡æƒé™
      //先删后加
      dncDevicePermissionMapper.delete(new QueryWrapper<DncDevicePermission>().lambda().eq(DncDevicePermission::getUserId, user.getId()));
      List<String> EquipmentIds= mdcProductionEquipmentMapper.selectList(new QueryWrapper<MdcProductionEquipment>().in("production_id",array))
            .stream().map(MdcProductionEquipment::getEquipmentId).collect(Collectors.toList());
      if (oConvertUtils.isNotEmpty(EquipmentIds)) {
         for (String equipmentId : EquipmentIds) {
            DncDevicePermission dncDevicePermission=new DncDevicePermission();
            dncDevicePermission.setDeviceId(equipmentId);
            dncDevicePermission.setUserId(user.getId());
            dncDevicePermissionMapper.insert(dncDevicePermission);
         }
      }
      //step.6 ä¿®æ”¹æ‰‹æœºå·å’Œé‚®ç®±
      // æ›´æ–°æ‰‹æœºå·ã€é‚®ç®±ç©ºå­—符串为 null
      userMapper.updateNullByEmptyString("email");
      userMapper.updateNullByEmptyString("phone");
   }
   @Override
   public List<String> userIdToUsername(Collection<String> userIdList) {
      LambdaQueryWrapper<SysUser> queryWrapper = new LambdaQueryWrapper<>();
      queryWrapper.in(SysUser::getId, userIdList);
      List<SysUser> userList = super.list(queryWrapper);
      return userList.stream().map(SysUser::getUsername).collect(Collectors.toList());
   }
   @Override
   @Cacheable(cacheNames=CacheConstant.SYS_USERS_CACHE, key="#username")
   @SensitiveEncode
   public LoginUser getEncodeUserInfo(String username){
      if(oConvertUtils.isEmpty(username)) {
         return null;
      }
      LoginUser loginUser = new LoginUser();
      SysUser sysUser = userMapper.getUserByName(username);
      if(sysUser==null) {
         return null;
      }
      BeanUtils.copyProperties(sysUser, loginUser);
      return loginUser;
   }
   @Override
   public Map<String, String> getProNamesByUserIds(List<String> userIds) {
      List<MdcUserProVo> list = this.baseMapper.getProNamesByUserIds(userIds);
      Map<String, String> res = new HashMap<>(5);
      list.forEach(item -> {
         if (res.get(item.getUserId()) == null) {
            res.put(item.getUserId(), item.getProductionName());
         } else {
            res.put(item.getUserId(), res.get(item.getUserId()) + "," + item.getProductionName());
         }
      });
      return res;
   }
   // æ ¹æ®è§’色Id查询该角色下的所有用户信息
   @Override
   public List<SysUser> getAllUsersByRoleId(String roleId) {
      return userMapper.getAllUsersByRoleId(roleId);
   }
   /**
    * æ ¹æ®è§’色编码查询用户id集合
    */
   @Override
   public List<String> getUserByRoleCode(String roleCode) {
      return this.baseMapper.getUserByRoleCode(roleCode);
   }
   /**
    * æ ¹æ®è§’色编码和设备编号查询用户
    */
   @Override
   public List<SysUser> getEquipmentAdmin(String roleCode, String equipmentId) {
      return this.baseMapper.getEquipmentAdmin(roleCode, equipmentId);
   }
   @Override
   public List<UserSelector> selectOperatorList(String equipmentCode, String productionId, String positionCode) {
      LambdaQueryWrapper<SysUser> queryWrapper = new LambdaQueryWrapper<>();
      queryWrapper.eq(SysUser::getPost, positionCode);
      if(StringUtils.isNotBlank(equipmentCode)) {
         queryWrapper.and(q -> q.isNull(SysUser::getEquipmentIds).or().eq(SysUser::getEquipmentIds, "").or().like(SysUser::getEquipmentIds, equipmentCode));
      }
      if(StringUtils.isNotBlank(productionId)) {
         queryWrapper.exists("select 1 from mdc_user_production t where t.user_id=sys_user.id and t.pro_id={0}", productionId);
      }
      queryWrapper.eq(SysUser::getDelFlag, CommonConstant.DEL_FLAG_0);
      queryWrapper.eq(SysUser::getStatus, CommonConstant.DEL_FLAG_1);
      queryWrapper.orderByDesc(SysUser::getId);
      List<SysUser> sysUsers = userMapper.selectList(queryWrapper);
      List<UserSelector> collect = sysUsers.stream().map(user -> new UserSelector(user.getId(), user.getUsername(), user.getRealname())).collect(Collectors.toList());
      return collect;
   }
   @Override
   public List<UserSelector> selectOperatorList(String positionCode) {
      LambdaQueryWrapper<SysUser> queryWrapper = new LambdaQueryWrapper<>();
      queryWrapper.eq(SysUser::getPost, positionCode);
      queryWrapper.eq(SysUser::getDelFlag, CommonConstant.DEL_FLAG_0);
      queryWrapper.eq(SysUser::getStatus, CommonConstant.DEL_FLAG_1);
      queryWrapper.orderByDesc(SysUser::getId);
      List<SysUser> sysUsers = userMapper.selectList(queryWrapper);
      List<UserSelector> collect = sysUsers.stream().map(user -> new UserSelector(user.getId(), user.getUsername(), user.getRealname())).collect(Collectors.toList());
      return collect;
   }
   /**
    * æ ¹æ®ç”¨æˆ·åæ‰¹é‡èŽ·å–çœŸå®žå§“åæ˜ å°„
    * @param userNames ç”¨æˆ·ååˆ—表
    * @return ç”¨æˆ·å->真实姓名的映射(不存在时值为null)
    */
   @Override
   public Map<String, String> getUserRealNamesByUserNames(List<String> userNames) {
      if (CollectionUtils.isEmpty(userNames)) {
         return Collections.emptyMap();
      }
      // åŽ»é‡å¹¶è¿‡æ»¤ç©ºå€¼
      Set<String> uniqueNames = userNames.stream()
            .filter(StringUtils::isNotBlank)
            .collect(Collectors.toSet());
      if (uniqueNames.isEmpty()) {
         return Collections.emptyMap();
      }
      // æ‰¹é‡æŸ¥è¯¢ï¼ˆè‡ªåŠ¨å¤„ç†IN语句分片)
      List<SysUser> users = userMapper.selectUsersByNames(new ArrayList<>(uniqueNames));
      // æž„建映射关系
      return users.stream()
            .collect(Collectors.toMap(
                  SysUser::getUsername,
                  SysUser::getRealname,
                  (existing, replacement) -> existing // é‡å¤é”®å¤„理
            ));
   }
}