ludc
2024-07-10 4d571ecaabae01dc825f01ce92ff4a5023f56fb0
Source/UBCS/ubcs-service/ubcs-system/src/main/java/com/vci/ubcs/system/service/impl/ClassifyAuthServiceImpl.java
@@ -4,20 +4,23 @@
import com.baomidou.mybatisplus.core.conditions.update.LambdaUpdateWrapper;
import com.baomidou.mybatisplus.core.toolkit.Wrappers;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.vci.ubcs.code.feign.ICodeClassifyClient;
import com.vci.ubcs.starter.web.util.VciBaseUtil;
import com.vci.ubcs.system.dto.ClassifyAuthDTO;
import com.vci.ubcs.system.entity.ClassifyAuth;
import com.vci.ubcs.system.entity.Menu;
import com.vci.ubcs.system.mapper.ClassifyAuthMapper;
import com.vci.ubcs.system.service.IClassifyAuthService;
import com.vci.ubcs.system.service.IMenuService;
import com.vci.ubcs.system.service.IRoleService;
import com.vci.ubcs.system.vo.ClassifyAuthVO;
import com.vci.ubcs.system.vo.MenuVO;
import com.vci.ubcs.system.wrapper.ClassifyAuthWrapper;
import lombok.AllArgsConstructor;
import org.springblade.core.log.exception.ServiceException;
import org.springblade.core.secure.utils.AuthUtil;
import org.springblade.core.tool.api.R;
import org.springblade.core.tool.utils.Func;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
@@ -25,7 +28,7 @@
import java.util.stream.Collectors;
/**
 * 分类授权
 * 分类授权,数据授权
 * @author ludc
 * @date 2023/12/25 15:35
 */
@@ -37,29 +40,64 @@
   private final IMenuService menuService;
   private final ICodeClassifyClient codeClassifyClient;
   private final IRoleService roleService;
   /**
    * 三员管理角色编号配置:分别为系统管理员,安全管理员,审计管理员顺序
    */
   @Value("#{'${ssa.ssa-names}'.split(',')}")
   private List<String> SSANAMES;
   /**
    * 分类授权保存接口
    * @param classifyAuthList
    * @param classifyAuthListDTO
    * @return
    */
   @Override
   @Transactional(rollbackFor = Exception.class)
   public R submit(List<ClassifyAuth> classifyAuthList) {
      if(classifyAuthList.isEmpty()){
   public R submit(ClassifyAuthDTO classifyAuthListDTO) throws ServiceException{
      // 是清空授权列表
      if(classifyAuthListDTO.getIsCLear()){
         if(Func.isEmpty(classifyAuthListDTO.getClassifyId())){
            return R.fail("清空授权列表时,未获取到分类id");
         }
         this.classifyAuthMapper.delete(
            Wrappers.<ClassifyAuth>update()
            .lambda().eq(ClassifyAuth::getClassifyId, classifyAuthListDTO.getClassifyId())
            .eq(ClassifyAuth::getAuthType,classifyAuthListDTO.getAuthType())
         );
         return R.success("授权列表清空成功");
      }
      if(!classifyAuthListDTO.getIsCLear() && classifyAuthListDTO.getClassifyAuthList().isEmpty()){
         R.fail("授权列表不能为空!");
      }
      // 判重,查看是否存在同一个classid下配置了相同的角色
      Map<String, Long> roleidCounts = classifyAuthListDTO.getClassifyAuthList().stream()
         .collect(Collectors.groupingBy(ClassifyAuth::getRoleId, Collectors.counting()));
      // 检查是否有roleid出现次数大于1的情况
      boolean hasDuplicateRoleid = roleidCounts.values().stream()
         .anyMatch(count -> count > 1);
      if(hasDuplicateRoleid){
         R.fail("角色和分类已经存在,请重新配置!");
      }
      // 如果传过来的集合中该分类id下删除了部分角色的授权,就需要将该库中classifyId下不存在的数据删掉
      List<String> roleIds = classifyAuthList.stream().map(ClassifyAuth::getRoleId).collect(Collectors.toList());
      List<String> roleIds = classifyAuthListDTO.getClassifyAuthList().stream().map(ClassifyAuth::getRoleId).collect(Collectors.toList());
      // 删除
      LambdaUpdateWrapper<ClassifyAuth> updateWrapper = Wrappers.<ClassifyAuth>update()
         .lambda().eq(ClassifyAuth::getClassifyId, classifyAuthList.get(0).getClassifyId())
         .lambda().eq(ClassifyAuth::getClassifyId, classifyAuthListDTO.getClassifyAuthList().get(0).getClassifyId())
         .eq(ClassifyAuth::getAuthType,classifyAuthListDTO.getAuthType())
         .notIn(ClassifyAuth::getRoleId, roleIds);
      try {
         this.classifyAuthMapper.delete(updateWrapper);
      }catch (Exception e){
         throw new ServiceException("分类授权过程中出现错误,错误原因:"+e.getMessage());
      }
      return R.status(saveOrUpdateBatch(classifyAuthList));
      return R.status(saveOrUpdateBatch(classifyAuthListDTO.getClassifyAuthList()));
   }
   /**
@@ -73,41 +111,24 @@
         throw new ServiceException("缺少必传参数分类id");
      }
      LambdaQueryWrapper<ClassifyAuth> wrapper = Wrappers.<ClassifyAuth>query()
         .lambda().eq(ClassifyAuth::getClassifyId,classifyAuthVO.getClassifyId());
         .lambda().eq(ClassifyAuth::getClassifyId,classifyAuthVO.getClassifyId())
         .eq(ClassifyAuth::getAuthType,classifyAuthVO.getAuthType());
      List<ClassifyAuth> classifyAuths = this.classifyAuthMapper.selectList(wrapper);
      if(!classifyAuths.isEmpty()){
         return ClassifyAuthWrapper.build().listVO(classifyAuths);
      if(classifyAuths.isEmpty()){
         return new ArrayList<ClassifyAuthVO>();
      }
      return new ArrayList<ClassifyAuthVO>();
      return ClassifyAuthWrapper.build().listVO(classifyAuths);
   }
   /**
    * 查询该分类下,当前登录的角色有哪些按钮权限
    * @param classifyId
    * @param menuCode
    * @param authType
    * @return
    */
   public Map<String,Boolean> getAuthButtonList(String classifyId){
      final String roleIds = AuthUtil.getUser().getRoleId();
      // 先查询按钮id列表
      LambdaQueryWrapper<ClassifyAuth> wrapper = Wrappers.<ClassifyAuth>query()
         .lambda().eq(ClassifyAuth::getClassifyId, classifyId)
         .in(ClassifyAuth::getRoleId, roleIds);
      List<ClassifyAuth> classifyAuths = this.classifyAuthMapper.selectList(wrapper);
      if(classifyAuths.size()>1){
         throw new ServiceException("角色和分类配置存在多条记录,请联系管理人员清理错误配置!");
      }
      // 是否为超管
      Boolean isAdmin = VciBaseUtil.checkAdminTenant();
      // 未配置按钮权限
      if(!isAdmin && (classifyAuths.isEmpty() || Func.isBlank(classifyAuths.get(0).getButtonIds()))){
         return new HashMap<>();
      }
      List<String> condition1 = new ArrayList<>();
      // 如果不是超管用户
      if(!isAdmin){
         condition1.addAll(Arrays.asList(classifyAuths.get(0).getButtonIds().split(",")));
      }
      List<Menu> menuList = menuService.getMenuListById(condition1,"1648879284590858241");
   public Map<String,Boolean> getAuthButtonList(String classifyId,String menuCode,String authType){
      List<Menu> menuList = this.getButtonList(classifyId, menuCode, authType);
      if(menuList.isEmpty()){
         return new HashMap<>();
      }
@@ -116,4 +137,137 @@
      return buttonMaps;
   }
   /**
    * 查询该主数据下,当前登录的角色有哪些按钮菜单权限
    * @param classifyId
    * @param menuCode
    * @param authType
    * @return
    */
   public List<Menu> getAuthMenuButtonList(String classifyId,String menuCode,String authType){
      List<Menu> buttonList = getButtonList(classifyId, menuCode, authType);
      return buttonList;
   }
   private List<Menu> getButtonList(String classifyId,String menuCode,String authType){
      if(Func.isBlank(classifyId)){
         throw new ServiceException("必传参数分类oid不能为空!");
      }
      //查询分类节点的所有父级节点
      R<List<String>> listR = codeClassifyClient.selectAllParentOid(classifyId);
      if (!listR.isSuccess() && !listR.getData().isEmpty()) {
         throw new ServiceException("获取分类信息失败!");
      }
      // 返回的分类oid是当前节点为第一个,后面依次是他的上层节点
      List<String> classifyOidList = listR.getData();
      final List<String> roleIds = Func.toStrList(",",AuthUtil.getUser().getRoleId());
      // 先查询按钮id列表
      LambdaQueryWrapper<ClassifyAuth> wrapper = Wrappers.<ClassifyAuth>query()
         .lambda().eq(ClassifyAuth::getClassifyId, classifyId)
         .eq(ClassifyAuth::getAuthType,authType)
         .in(ClassifyAuth::getRoleId, roleIds);
      List<ClassifyAuth> classifyAuths = this.classifyAuthMapper.selectList(wrapper);
      //如果当前分类没有找到授权配置,就依次从当前节点往上层节点找授权配置,找到了就停止,没找到就一直找到最后
      if(classifyAuths.isEmpty()){
         // 下标从1开始因为当前节点0已经查询过
         for (int i = 1; i < classifyOidList.size(); i++) {
            classifyAuths = this.classifyAuthMapper.selectList(
               Wrappers.<ClassifyAuth>query()
                  .lambda().eq(ClassifyAuth::getClassifyId, classifyOidList.get(i))
                  .eq(ClassifyAuth::getAuthType,authType)
                  .in(ClassifyAuth::getRoleId, roleIds)
            );
            //只要当前节点的上层节点中找到了分类授权信息就不再继续往上找了
            if(!classifyAuths.isEmpty()){
               break;
            }
         }
      }
      //出现了多条数据
      if(classifyAuths.size()>1){
         // 校验是否存在错误数据,同一个角色和同一个分类id存在多条授权记录
         List<ClassifyAuth> finalClassifyAuths = classifyAuths;
         boolean hasDuplicate = classifyAuths.stream()
            .anyMatch(auth1 -> finalClassifyAuths.stream()
               .filter(auth2 -> auth1 != auth2)
               .anyMatch(auth2 -> auth1.getRoleId().equals(auth2.getRoleId()) && auth1.getClassifyId().equals(auth2.getClassifyId())));
         if (hasDuplicate) {
            throw new ServiceException("角色和分类配置存在多条记录,请联系管理人员清理错误配置!");
         }
      }
      // 是否为超管
      Boolean isAdmin = VciBaseUtil.checkAdminTenant();
      // 未配置按钮权限
      if(!isAdmin && (classifyAuths.isEmpty() || Func.isBlank(classifyAuths.get(0).getButtonIds()))){
         return new ArrayList<>();
      }
      List<String> ids = new ArrayList<>();
      // 如果不是超管用户
      if(!isAdmin){
         String concatenatedButtonIds = classifyAuths.stream()
            .map(ClassifyAuth::getButtonIds) // 获取每个classifyAuths对象的buttonIds
            .collect(Collectors.joining(",")); // 用逗号分隔拼接成一个字符串
         ids.addAll(Arrays.asList(concatenatedButtonIds.split(",")));
      }
      return menuService.getMenuListByCode(ids,menuCode,roleIds);
   }
   /**
    * 根据角色id查看有哪些分类具备查看权限
    * @param roleIds
    * @return
    */
   @Override
   public List<String> getViewClassByRoleIds(List<String> roleIds,String authType,String buttonCode,String menuCode) {
      if(roleIds.isEmpty()){
         return new ArrayList<>();
      }
      return this.classifyAuthMapper.getViewClassByRoleIds(roleIds, authType,buttonCode,menuCode);
   }
   /**
    * 根据角色名称分类id授予默认的分类权限和主数据访问权限
    * @param classifyAuthDTO
    * @return
    */
   @Transactional(rollbackFor = Exception.class)
   public R saveAddClassifyDefaultAuth(ClassifyAuthDTO classifyAuthDTO) throws ServiceException{
      if (Func.isEmpty(classifyAuthDTO.getClassifyId())) {
         return R.fail("未获取到分类id");
      }
      // 配置的系统管理员名称
      String sysAdmin = SSANAMES.get(0);
      List<ClassifyAuth> classifyAuths = new ArrayList<>();
      //先默认生成系统管理员的授权数据
      ClassifyAuth classifyAuth = new ClassifyAuth();
      classifyAuth.setClassifyId(classifyAuthDTO.getClassifyId());
      classifyAuth.setAuthType("classify_auth");
      String roleIds = roleService.getRoleIds(AuthUtil.getTenantId(), sysAdmin);
      if(Func.isBlank(roleIds)){
         return R.fail(AuthUtil.getTenantId()+"租户下未找到,名为"+sysAdmin+"系统管理员角色!");
      }
      classifyAuth.setRoleId(roleIds);
      List<Menu> classifyTreeMenus = menuService.getButtonsByRoleId(roleIds, "classifyTree");
      if(!classifyTreeMenus.isEmpty()){
         String menuIds = classifyTreeMenus.stream()
            .map(menu -> String.valueOf(menu.getId()))
            .collect(Collectors.joining(","));
         classifyAuth.setButtonIds(menuIds);
         classifyAuths.add(classifyAuth);
      }
      /*ClassifyAuth dataAuth = new ClassifyAuth();
      dataAuth.setAuthType("data_auth");
      dataAuth.setClassifyId(classifyAuthDTO.getClassifyId());
      dataAuth.setRoleId(roleIds);
      List<Menu> masterDatas = menuService.getButtonsByRoleId(roleIds, classifyAuthDTO.getClassId());
      if(!masterDatas.isEmpty()){
         String menuIds = masterDatas.stream()
            .map(menu -> String.valueOf(menu.getId()))
            .collect(Collectors.joining(","));
         dataAuth.setButtonIds(menuIds);
         classifyAuths.add(dataAuth);
      }*/
      return R.status(this.saveBatch(classifyAuths));
   }
}