ludc
2023-11-30 1b8098b7f79b66a80e5ca49d8765606cb5fa0408
Source/UBCS/ubcs-service/ubcs-user/src/main/java/com/vci/ubcs/system/user/service/impl/UserServiceImpl.java
@@ -19,9 +19,13 @@
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.metadata.IPage;
import com.baomidou.mybatisplus.core.toolkit.Wrappers;
import com.vci.ubcs.starter.web.util.VciBaseUtil;
import com.vci.ubcs.system.cache.DictCache;
import com.vci.ubcs.system.cache.NacosConfigCache;
import com.vci.ubcs.system.cache.ParamCache;
import com.vci.ubcs.system.cache.SysCache;
import com.vci.ubcs.system.entity.Strategy;
@@ -32,6 +36,7 @@
import com.vci.ubcs.system.user.cache.UserCache;
import com.vci.ubcs.system.user.entity.*;
import com.vci.ubcs.system.user.enums.UserEnum;
import com.vci.ubcs.system.user.enums.UserStatus;
import com.vci.ubcs.system.user.excel.UserExcel;
import com.vci.ubcs.system.user.mapper.UserMapper;
import com.vci.ubcs.system.user.service.IUserDeptService;
@@ -40,22 +45,24 @@
import com.vci.ubcs.system.user.vo.UserVO;
import com.vci.ubcs.system.user.wrapper.UserWrapper;
import lombok.RequiredArgsConstructor;
import org.springblade.core.log.annotation.GrantLog;
import org.springblade.core.log.exception.ServiceException;
import org.springblade.core.mp.base.BaseServiceImpl;
import org.springblade.core.mp.support.Condition;
import org.springblade.core.mp.support.Query;
import org.springblade.core.secure.BladeUser;
import org.springblade.core.secure.utils.AuthUtil;
import org.springblade.core.tenant.BladeTenantProperties;
import org.springblade.core.tool.api.R;
import org.springblade.core.tool.constant.BladeConstant;
import org.springblade.core.tool.support.Kv;
import org.springblade.core.tool.utils.*;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.util.DigestUtils;
import java.util.*;
import java.util.stream.Collectors;
import static com.vci.ubcs.common.constant.CommonConstant.DEFAULT_PARAM_PASSWORD;
@@ -74,21 +81,21 @@
   private final IUserOauthService userOauthService;
   private final ISysClient sysClient;
   private final BladeTenantProperties tenantProperties;
   //拿到配置的超管id
   @Value("${user-info.id}")
   private String adminUserId;
   @Override
   @Transactional(rollbackFor = Exception.class)
   public boolean submit(User user) {
      if (StringUtil.isBlank(user.getTenantId())) {
         user.setTenantId(BladeConstant.ADMIN_TENANT_ID);
         // 默认设置为管理组下的用户
         user.setTenantId(NacosConfigCache.getAdminUserInfo().getTenantId());
      }
      String tenantId = user.getTenantId();
      //Tenant tenant = SysCache.getTenant(tenantId);
      if (Func.isNotEmpty(user.getPassword())) {
         user.setPassword(DigestUtil.encrypt(user.getPassword()));
      }
      if(Func.isEmpty(user.getUserStatus())){
         user.setUserStatus(UserStatus.Enable.getValue());
      }
      Long userCount = baseMapper.selectCount(Wrappers.<User>query().lambda().eq(User::getTenantId, tenantId).eq(User::getAccount, user.getAccount()));
      if (userCount > 0L && Func.isEmpty(user.getId())) {
@@ -103,7 +110,7 @@
      Boolean flag = true;
      for (User user : users){
         if (StringUtil.isBlank(user.getTenantId())) {
            user.setTenantId(BladeConstant.ADMIN_TENANT_ID);
            user.setTenantId(NacosConfigCache.getAdminUserInfo().getTenantId());
         }
         String tenantId = user.getTenantId();
         if (Func.isNotEmpty(user.getPassword())) {
@@ -121,6 +128,7 @@
   @Override
   @Transactional(rollbackFor = Exception.class)
   @GrantLog("grantUser")
   public boolean updateUser(User user) {
      String tenantId = user.getTenantId();
      Long userCount = baseMapper.selectCount(
@@ -129,6 +137,7 @@
            .eq(User::getAccount, user.getAccount())
            .notIn(User::getId, user.getId())
      );
      // 判断是否被修改为已存在的用户名
      if (userCount > 0L) {
         throw new ServiceException(StringUtil.format("当前用户 [{}] 已存在!", user.getAccount()));
      }
@@ -141,8 +150,41 @@
      return updateById(user);
   }
   /**
    * 根据旧账号,修改为新账号名
    * @param oldAccount
    * @param newAccount
    * @return
    */
   @Override
   public boolean updateByAccount(String oldAccount,String newAccount) {
      User user = this.userByAccount(AuthUtil.getTenantId(), oldAccount);
      if(Func.isEmpty(user)){
         return true;
      }
      user.setAccount(newAccount);
      return this.updateUser(user);
   }
   /**
    * 据账号,修改为用户状态
    * @param accounts
    * @param status
    * @return
    */
   @Override
   public boolean updateStatusByAccount(String accounts, String status) {
      LambdaUpdateWrapper<User> updateWrapper = Wrappers.<User>update()
         .lambda().in(User::getAccount, accounts)
         .set(User::getUserStatus, status);
      return this.update(updateWrapper);
   }
   private boolean submitUserDept(User user) {
      List<Long> deptIdList = Func.toLongList(user.getDeptId());
      if(deptIdList.isEmpty()){
         return true;
      }
      List<UserDept> userDeptList = new ArrayList<>();
      deptIdList.forEach(deptId -> {
         UserDept userDept = new UserDept();
@@ -158,6 +200,21 @@
   public IPage<User> selectUserPage(IPage<User> page, User user, Long deptId, String tenantId) {
      List<Long> deptIdList = SysCache.getDeptChildIds(deptId);
      return page.setRecords(baseMapper.selectUserPage(page, user, deptIdList, tenantId));
   }
   @Override
   public List<User> selectAllUser(User user, Long deptId){
      List<Long> deptIdList = SysCache.getDeptChildIds(deptId);
      List<User> users = baseMapper.selectUserPage(user, deptIdList, (VciBaseUtil.checkAdminTenant() ? StringPool.EMPTY : AuthUtil.getTenantId()));
      return users;
   }
   @Override
   public List<User> selectAllUser(){
      LambdaQueryWrapper<User> wrapper=   Wrappers.lambdaQuery();
      wrapper.eq(User::getIsDeleted,0);
      List<User> users = baseMapper.selectList(wrapper);
      return users;
   }
   @Override
@@ -205,13 +262,20 @@
   @Override
   public UserInfo userInfo(String tenantId, String account) {
      User user = baseMapper.getUser(tenantId, account);
      User user = baseMapper.getUser(tenantId, account,null);
      return buildUserInfo(user);
   }
   @Override
   public UserInfo userInfo(String tenantId, String account,String name) {
      User user = baseMapper.getUser(tenantId, account,name);
      UserInfo userInfo = buildUserInfo(user);
      return null;
   }
   @Override
   public UserInfo userInfo(String tenantId, String account, UserEnum userEnum) {
      User user = baseMapper.getUser(tenantId, account);
      User user = baseMapper.getUser(tenantId, account,null);
      return buildUserInfo(user, userEnum);
   }
@@ -223,6 +287,7 @@
      if (ObjectUtil.isEmpty(user)) {
         return null;
      }
      user.setDeptName(Func.join(SysCache.getDeptNames(user.getDeptId())));
      UserInfo userInfo = new UserInfo();
      userInfo.setUser(user);
      if (Func.isNotEmpty(user)) {
@@ -289,6 +354,16 @@
      return this.update(user, Wrappers.<User>update().lambda().in(User::getId, Func.toLongList(userIds)));
   }
   /**
    * 授权日志插入操作
    * @param res
    */
   @Override
   @GrantLog("grantUser")
   public boolean grantLog(String res, boolean isException){
      return true;
   }
   @Override
   public boolean resetPassword(String userIds) {
      User user = new User();
@@ -308,6 +383,10 @@
      }
      //获取用户采用的密码策略
      Strategy strategy = sysClient.getByUserId(userId).getData();
      // 几乎不会出现这种情况
      if(ObjectUtil.isEmpty(strategy)) {
         throw new ServiceException("当前用户未应用密码策略!");
      }
      //密码长度校验
      if(newPassword1.length() < strategy.getMinPwdLen() || newPassword1.length() > strategy.getMaxPwdLen()){
         throw new ServiceException("密码中必须含有【"+strategy.getCombinationNames()+"】中的【"+strategy.getRequiredType()+"】种密码组合方式,且密码长度必须在【"+strategy.getMinPwdLen()+"-"+strategy.getMaxPwdLen()+"】范围内");
@@ -319,7 +398,7 @@
         if(reqType>=strategy.getRequiredType()){
            break;
         }
         if(!Func.isEmpty(RegexUtil.findResult(regexs.get(i),newPassword1))){
         if(RegexUtil.find(regexs.get(i),newPassword1)){
            reqType++;
         }
      }
@@ -327,12 +406,13 @@
      if(reqType<strategy.getRequiredType()){
         throw new ServiceException(resException);
      }
      // 是否属于组合方式中的类型
      // 是否属于组合方式中的类型,以前是密码必须是包含在组合方式中的类型
      String regex = sysClient.getRegex(Arrays.asList(strategy.getCombinationIds().split(","))).getData();
      regex = "^"+regex+"{"+strategy.getRequiredType()+",}$";
      boolean result = RegexUtil.find(regex, newPassword1);
      if(!result){
         throw new ServiceException(resException);
         throw new ServiceException("密码中只能存在【"+strategy.getCombinationNames()+"】中包含的字符!");
         //throw new ServiceException(resException);
      }
      //修改密码同时,改变用户信息中的密码修改状态字段,密码修改时间
      return this.update(Wrappers.<User>update().lambda()
@@ -353,6 +433,7 @@
   @Override
   @Transactional(rollbackFor = Exception.class)
   public void importUser(List<UserExcel> data, Boolean isCovered) {
      ArrayList<User> addUsers = new ArrayList<>();
      data.forEach(userExcel -> {
         User user = Objects.requireNonNull(BeanUtil.copy(userExcel, User.class));
         // 设置用户平台
@@ -380,8 +461,10 @@
         // 获取默认密码配置
         String initPassword = ParamCache.getValue(DEFAULT_PARAM_PASSWORD);
         user.setPassword(initPassword);
         this.submit(user);
         addUsers.add(user);
         //this.submit(user);
      });
      this.submitList(addUsers);
   }
   @Override
@@ -418,6 +501,7 @@
      boolean oauthTemp = userOauthService.updateById(userOauth);
      return (userTemp && oauthTemp);
   }
   @Override
   public boolean updatePlatform(Long userId, Integer userType, String userExt) {
      if (userType.equals(UserEnum.WEB.getCategory())) {
@@ -479,16 +563,21 @@
   @Override
   public Long checkRenAndExpr(Long userId) {
      //超级管理员直接返回不需要提醒密码修改
      if(adminUserId.equals(userId)){
      if(NacosConfigCache.getAdminUserInfo().getUserId().equals(userId)){
         return 0L;
      }
      QueryWrapper<User> wrapper = Wrappers.<User>query().eq("ID", userId);
      User dbUser = this.getOne(wrapper);
      //获取到密码修改时间
      Date pwdUpdateTime = this.getOne(Wrappers.<User>query().eq("ID", userId)).getPwdUpdateTime();
      Date pwdUpdateTime = Func.isNotEmpty(dbUser) ? dbUser.getPwdUpdateTime():new Date();
      Long pwdupdateday = 0L;
      if(!Func.isEmpty(pwdUpdateTime)){
         pwdupdateday = dateToDay(pwdUpdateTime);
      }
      Strategy strategy = sysClient.getByUserId(userId).getData();
      if(Func.isEmpty(strategy)){
         throw new ServiceException("密码策略查询为空,请检查当前租户下是否存在默认密码策略!");
      }
      //是否提醒通过最后一次修改密码的时间加上过期时间减去当前时间,如果小于过期提醒时间就进行提醒,如果<=0就提醒必须修改密码
      long reminder = pwdupdateday+strategy.getExpirationTime()-dateToDay(new Date());
      //提醒用户必须修改密码
@@ -510,7 +599,46 @@
   }
   /**
    * 时间格式转天
    * 获取到指定身份权限的用户列表
    * @param user 用户查询的用户信息,如租户信息,通常为自动注入,前端可选择不传
    * @param roleName 要查询的角色身份
    * @return
    */
   @Override
   public List<Map<String,String>> getByRoleUserList(BladeUser user, String roleName) {
      // 考虑到一个用户可以拥有多种角色权限,而用户关联角色权限是用role_id字段用逗号分隔角色id的,直接采用子查询来in查询不能实现,所以先查询角色id
      R<String> roleIds = sysClient.getRoleIds(user.getTenantId(), roleName);
      if(!roleIds.isSuccess()){
         throw new ServiceException("系统服务feign接口调用错误!");
      }
      if(Func.isBlank(roleIds.getData())){
         return new ArrayList<>();
      }
      List<Map<String,String>> list = new ArrayList<>();
      Arrays.stream(roleIds.getData().split(",")).forEach(item->{
         list.addAll(this.baseMapper.getUserMap(item,user.getUserId().toString()));
      });
      // 去除重复
      return list.stream().distinct().collect(Collectors.toList());
   }
   /***
    * 更新用户启用停用状态
    * @param userIds
    * @param status
    * @return
    */
   @Override
   public boolean updateUserStatus(String userIds, boolean status) {
      Integer userStatus = 0;
      if(!status){
         userStatus = 1;
      }
      return this.update(Wrappers.<User>lambdaUpdate().in(User::getId, Func.toLongList(userIds)).set(User::getUserStatus,userStatus));
   }
   /**
    * 日期时间格式转天
    * @param date
    * @return
    */