Source/UBCS-WEB/src/api/system/classifyAuth.js
@@ -16,4 +16,14 @@ method: 'post', data: data }) } export const getAuthButtonList = (params) => { return request({ url: '/api/ubcs-system/classifyAuth/getAuthButtonList', method: 'get', params: { ...params } }) } Source/UBCS-WEB/src/components/Theme/ClassifyAuthDialog.vue
@@ -96,7 +96,7 @@ // 对话框显示控制 isShowDialog: this.visible, isLoading: false, tableHeight: '520px', tableHeight: 'calc(100vh - 550px)', classifyAuthData: [], //列头 classifyAuthHeader: [], @@ -160,7 +160,7 @@ let item = { oid: authData.oid, roleData: authData.roleId, classifyItem: this.classifyData.text, classifyItem: this.classifyData.label, uuid: uuidv4(),//生成唯一的id } //将按钮设置进去 @@ -191,7 +191,7 @@ addClassifyAuth() { let item = { roleData: this.roleList[0].id, classifyItem: this.classifyData.text, classifyItem: this.classifyData.label, uuid: uuidv4(),//生成唯一的id } //将按钮设置进去 Source/UBCS/ubcs-service-api/ubcs-code-api/src/main/java/com/vci/ubcs/code/feign/ICodeClassifyClient.java
@@ -21,7 +21,9 @@ import com.vci.ubcs.code.vo.pagemodel.CodeClassifyTemplateAttrVO; import com.vci.ubcs.starter.revision.model.TreeQueryObject; import com.vci.ubcs.starter.web.pagemodel.Tree; import org.springblade.core.launch.constant.AppConstant; import org.springblade.core.mp.support.BladePage; import org.springblade.core.tool.api.R; import org.springframework.cloud.openfeign.FeignClient; import org.springframework.web.bind.annotation.GetMapping; import org.springframework.web.bind.annotation.PostMapping; @@ -37,7 +39,7 @@ * @since 2023-04-06 */ @FeignClient( value = "ubcs-code" value = AppConstant.APPLICATION_NAME_CODE ) public interface ICodeClassifyClient { @@ -45,7 +47,9 @@ String TOP = API_PREFIX + "/top"; String CODE_CLASSIFY_TREE=API_PREFIX+"/referCodeClassifyTree"; String CODE_ATTRIBUTE_LIST=API_PREFIX+"/listCodeAttributeByClassId"; String CODE_ALL_PARENT_OID=API_PREFIX+"/selectAllParentOid"; String CODE_GETBYID="/getById"; /** * 获取主题库定义表列表 * @@ -64,6 +68,14 @@ @PostMapping(CODE_CLASSIFY_TREE) public List<Tree> referCodeClassifyTree(@RequestBody TreeQueryObject treeQueryObject); /** * 获取所有上级节点的oid * @param oid * @return */ @PostMapping(CODE_ALL_PARENT_OID) public R<List<String> > selectAllParentOid(@RequestParam("oid") String oid); /*** * 获取主数据模板属性信息 * @param codeClassifyId Source/UBCS/ubcs-service-api/ubcs-system-api/src/main/java/com/vci/ubcs/system/feign/ISysClient.java
@@ -78,6 +78,7 @@ String STRATEGYBYID = API_PREFIX + "/query-userid"; String REGEX = API_PREFIX + "/combination-regex"; String REGEXONE = API_PREFIX + "/combination-regex-one"; String GETVIEWCLASSIFY = API_PREFIX + "/get-view-classify"; /** * 获取菜单 @@ -390,4 +391,7 @@ @PostMapping(REGEXONE) R<List<String>> getRegexByList(@RequestBody List<String> combinationIds); @GetMapping(GETVIEWCLASSIFY) R<List<String>> getViewClassByRoleIds(@RequestParam("roleIds") List<String> roleIds); } Source/UBCS/ubcs-service-api/ubcs-system-api/src/main/java/com/vci/ubcs/system/feign/ISysClientFallback.java
@@ -199,5 +199,10 @@ return R.fail("获取数据失败"); } @Override public R<List<String>> getViewClassByRoleIds(List<String> roleIds) { return R.fail("获取数据失败"); } } Source/UBCS/ubcs-service/ubcs-code/src/main/java/com/vci/ubcs/code/feign/CodeClassifyClient.java
@@ -32,6 +32,7 @@ import org.springblade.core.mp.support.Condition; import org.springblade.core.mp.support.Query; import com.vci.ubcs.code.service.ICodeClassifyService; import org.springblade.core.tool.api.R; import org.springframework.web.bind.annotation.GetMapping; import org.springframework.web.bind.annotation.PostMapping; import org.springframework.web.bind.annotation.RequestBody; @@ -51,11 +52,9 @@ @AllArgsConstructor public class CodeClassifyClient implements ICodeClassifyClient { private final ICodeClassifyService plCodeClassifyService; private final ICodeClassifyTemplateAttrService codeClassifyTemplateAttrService; private final ICodeClassifyService codeClassifyService; private final MdmEngineService engineService; CodeClassifyMapper codeClassifyMapper; private final CodeClassifyMapper codeClassifyMapper; @Override @GetMapping(TOP) @@ -67,6 +66,15 @@ return BladePage.of(page); } /** * 获取所有上级节点的oid * @param oid * @return */ public R<List<String>> selectAllParentOid(String oid){ return R.data(codeClassifyService.selectAllParentOid(oid)); } /*** * 获取主题库分类层级树 * @param treeQueryObject @@ -75,7 +83,7 @@ @Override @PostMapping(CODE_CLASSIFY_TREE) public List<Tree> referCodeClassifyTree(TreeQueryObject treeQueryObject) { return plCodeClassifyService.treeCodeClassify(treeQueryObject); return codeClassifyService.treeCodeClassify(treeQueryObject); } @Override @@ -94,7 +102,7 @@ @Override @GetMapping(CODE_GETBYID) public CodeClassify getById(String classifyId) { return plCodeClassifyService.getById(classifyId); return codeClassifyService.getById(classifyId); } Source/UBCS/ubcs-service/ubcs-code/src/main/java/com/vci/ubcs/code/mapper/CodeClassifyMapper.java
@@ -53,6 +53,13 @@ Map<String,String> selectAllLevelChildOid(@Param("oid") String oid); /** * 查询所有上层父节点的oid * @param oid * @return */ List<String> selectAllParentOid(@Param("oid") String oid); /** * 校验是否包含子节点 * * @param oid 分类的主键 Source/UBCS/ubcs-service/ubcs-code/src/main/java/com/vci/ubcs/code/service/ICodeClassifyService.java
@@ -224,6 +224,13 @@ List<CodeClassify> selectAllLevelParents(String oid); /** * 获取所有上级节点的oid * @param oid * @return */ List<String> selectAllParentOid(String oid); /** * 主键获取主题库分类 * @param oid 主键 * @return 主题库分类显示对象 Source/UBCS/ubcs-service/ubcs-code/src/main/java/com/vci/ubcs/code/service/impl/CodeClassifyServiceImpl.java
@@ -49,6 +49,7 @@ import com.vci.ubcs.starter.web.util.LangBaseUtil; import com.vci.ubcs.starter.web.util.VciBaseUtil; import com.vci.ubcs.system.cache.NacosConfigCache; import com.vci.ubcs.system.feign.ISysClient; import org.apache.poi.hssf.util.HSSFColor; import org.slf4j.Logger; import org.slf4j.LoggerFactory; @@ -92,7 +93,7 @@ private IBtmTypeClient btmTypeClient; @Resource private CommonsMapper commonsMapper; private ISysClient sysClient; /** * 日志 @@ -582,18 +583,67 @@ return s.getId() + " " + s.getName() + (FrameworkDataLCStatus.DISABLED.getValue().equalsIgnoreCase(s .getLcStatus()) ? (" 【停用】 ") : ""); }); Iterator var6 = tree.listIterator(); while(var6.hasNext()){ Tree trees = (Tree) var6.next(); boolean checkHasChild=codeClassifyMapper.checkHasChild(trees.getOid()); if(checkHasChild){ trees.setLeaf(false); }else{ trees.setLeaf(true); //超管显示所有分类 if(VciBaseUtil.checkAdminTenant()){ Iterator var6 = tree.listIterator(); while(var6.hasNext()){ Tree trees = (Tree) var6.next(); boolean checkHasChild=codeClassifyMapper.checkHasChild(trees.getOid()); if(checkHasChild){ trees.setLeaf(false); }else{ trees.setLeaf(true); } } }else { // 那些分类具备查看权限 R<List<String>> viewClassByRoleIds = sysClient.getViewClassByRoleIds(Arrays.asList(AuthUtil.getUser().getRoleId().split(","))); // 请求失败或者请求得到的具备查看权限的分类id集合为空 if(!viewClassByRoleIds.isSuccess() && !viewClassByRoleIds.getData().isEmpty()){ return new ArrayList<>(); } // 过滤 filterTreeNodes(tree,viewClassByRoleIds.getData()); } return tree; } /** * 分类授权过滤掉没有权限的分类 * @param trees * @param classifyIds */ private void filterTreeNodes(List<Tree> trees, List<String> classifyIds) { Iterator<Tree> iterator = trees.iterator(); while (iterator.hasNext()) { Tree tree = iterator.next(); Boolean checkHasChild = codeClassifyMapper.checkHasChild(tree.getOid()); tree.setLeaf(!checkHasChild); if (classifyIds.contains(tree.getOid())) { // 如果顶层节点存在于 classifyIds 中,直接保留其子节点集合 continue; } if (tree.getChildren() != null && !tree.getChildren().isEmpty()) { filterTreeNodes(tree.getChildren(), classifyIds); } if (!hasMatchingChild(tree, classifyIds)) { iterator.remove(); } } } private boolean hasMatchingChild(Tree tree, List<String> classifyIds) { if (classifyIds.contains(tree.getOid())) { return true; } if (tree.getChildren() != null) { for (Tree child : tree.getChildren()) { if (hasMatchingChild(child, classifyIds)) { return true; } } } return false; } /** @@ -1408,6 +1458,19 @@ } /** * 查询所有上层父节点的oid * @param oid * @return */ @Override public List<String> selectAllParentOid(String oid){ if(Func.isBlank(oid)){ return new ArrayList<>(); } return this.codeClassifyMapper.selectAllParentOid(oid); } /** * 使用分类主键获取分类相关的所有信息 * * @param codeClassifyOid 分类的主键 Source/UBCS/ubcs-service/ubcs-code/src/main/resources/mapper/CodeCLassifyMapper.xml
@@ -60,6 +60,13 @@ PRIOR OID = parentCodeClassifyOid </select> <select id="selectAllParentOid" resultType="java.lang.String"> SELECT oid FROM PL_CODE_CLASSIFY START WITH oid = #{oid} CONNECT BY PRIOR PARENTCODECLASSIFYOID = oid </select> <select id="checkHasChild" resultType="java.lang.Boolean"> <![CDATA[select count(oid) from PL_CODE_CLASSIFY Source/UBCS/ubcs-service/ubcs-system/pom.xml
@@ -55,6 +55,12 @@ </exclusion> </exclusions> </dependency> <dependency> <groupId>com.vci.ubcs</groupId> <artifactId>ubcs-code-api</artifactId> <version>3.0.1.RELEASE</version> <scope>compile</scope> </dependency> </dependencies> <build> Source/UBCS/ubcs-service/ubcs-system/src/main/java/com/vci/ubcs/system/feign/SysClient.java
@@ -62,6 +62,8 @@ private final IMdmCountConfigService mdmCountConfigService; private final IClassifyAuthService classifyAuthService; @Override @GetMapping(MENU) public R<Menu> getMenu(Long id) { @@ -262,4 +264,8 @@ return R.data(mdmCountConfigService.getMdmCountConfig(userId)); } public R<List<String>> getViewClassByRoleIds(List<String> roleIds){ return R.data(classifyAuthService.getViewClassByRoleIds(roleIds)); } } Source/UBCS/ubcs-service/ubcs-system/src/main/java/com/vci/ubcs/system/mapper/ClassifyAuthMapper.java
@@ -14,4 +14,6 @@ List<ClassifyAuth> getClassifyAuthList(@Param("classifyId") String classifyId); List<String> getViewClassByRoleIds(@Param("roleIds") List<String> roleIds); } Source/UBCS/ubcs-service/ubcs-system/src/main/java/com/vci/ubcs/system/service/IClassifyAuthService.java
@@ -37,4 +37,11 @@ */ Map<String,Boolean> getAuthButtonList(String classifyId); /** * 根据角色id查看有哪些分类具备查看权限 * @param roleIds * @return */ List<String> getViewClassByRoleIds(List<String> roleIds); } Source/UBCS/ubcs-service/ubcs-system/src/main/java/com/vci/ubcs/system/service/impl/ClassifyAuthServiceImpl.java
@@ -4,6 +4,7 @@ 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.entity.ClassifyAuth; import com.vci.ubcs.system.entity.Menu; @@ -37,6 +38,8 @@ private final IMenuService menuService; private final ICodeClassifyClient codeClassifyClient; /** * 分类授权保存接口 * @param classifyAuthList @@ -48,6 +51,17 @@ if(classifyAuthList.isEmpty()){ R.fail("授权列表不能为空!"); } // 判重,查看是否存在同一个classid下配置了相同的角色 Map<String, Long> roleidCounts = classifyAuthList.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()); // 删除 @@ -75,10 +89,10 @@ LambdaQueryWrapper<ClassifyAuth> wrapper = Wrappers.<ClassifyAuth>query() .lambda().eq(ClassifyAuth::getClassifyId,classifyAuthVO.getClassifyId()); 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); } /** @@ -87,12 +101,37 @@ * @return */ public Map<String,Boolean> getAuthButtonList(String classifyId){ if(Func.isBlank(classifyId)){ return new HashMap<>(); } //查询分类节点的所有父级节点 R<List<String>> listR = codeClassifyClient.selectAllParentOid(classifyId); if (!listR.isSuccess() && !listR.getData().isEmpty()) { throw new ServiceException("获取分类信息失败!"); } // 返回的分类oid是当前节点为第一个,后面依次是他的上层节点 List<String> classifyOidList = listR.getData(); 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.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)) .in(ClassifyAuth::getRoleId, roleIds) ); if(!classifyAuths.isEmpty()){ break; } } } //出现了错误数据,同一个角色和同一个分类id存在多条授权记录 if(classifyAuths.size()>1){ throw new ServiceException("角色和分类配置存在多条记录,请联系管理人员清理错误配置!"); } @@ -116,4 +155,17 @@ return buttonMaps; } /** * 根据角色id查看有哪些分类具备查看权限 * @param roleIds * @return */ @Override public List<String> getViewClassByRoleIds(List<String> roleIds) { if(roleIds.isEmpty()){ return new ArrayList<>(); } return this.classifyAuthMapper.getViewClassByRoleIds(roleIds); } } Source/UBCS/ubcs-service/ubcs-system/src/main/resources/mapper/ClassifyAuthMapper.xml
@@ -9,7 +9,26 @@ </resultMap> <select id="getClassifyAuthList" resultMap="classifyAuthMap"> SELECT * FROM PL_ORG_CLASSIFYAUTH WHERE CLASSIFY_ID = #{classifyId}; SELECT * FROM PL_ORG_CLASSIFYAUTH WHERE CLASSIFY_ID = #{classifyId}; </select> <select id="getViewClassByRoleIds" resultType="java.lang.String"> SELECT CLASSIFY_ID FROM PL_ORG_CLASSIFYAUTH WHERE <if test="roleIds != null and ! roleIds.isEmpty() and roleIds.size() > 0"> ROLE_ID IN <foreach item="item" index="index" collection="roleIds" open="(" separator="," close=")"> #{item} </foreach> </if> AND BUTTON_IDS LIKE CONCAT('%', CONCAT((SELECT ID FROM PL_SYS_MENU WHERE CODE = 'classify_view'), '%')) </select>