关于【erp等企业高级信息系统中组织层级树生成】快捷优化方案讲解
关于【erp等企业高级信息系统中组织层级树生成】快捷优化方案讲解
先不说如何优化,我们先分析一下现有的方案是一个什么方式。再通过现有方案产生的问题痛点来致命一击:
一、我们需要了解一下一些前提知识:
(1)什么是组织层级树:
如以上示例,那么我们如何将此组织树存储于数据库中
(2)组织层级树存储表结构设计
二、在原来的生成层级树是通过每条sql生成的。效率极慢,没个树都得执行一条sql。
都知道,在sql中使用递归查询,是允许的,但不是最优的。最优方案,就是在每一个执行流程的每一个节点进行一定的效率优化,在代码正确且规范的前提下,优化空间基本上都是从逻辑角度进行优化的。
下面我根据本人的实际开发中的erp项目的具体需求来进行分析解读,每个节点上的优化方案:
1.原型图:
以上需求就是,在erp信息化管理系统中的一个模块分支,对于其中的组织划分管理,在我们项目中,实际的功能作用是通过树状结构图,来清晰明了的展示每一个机构节点的上下层级关系,以及对应节点上的基础信息,人员信息,设备配置信息,程序配置等等。那么在一个系统中,这个组织树是有很多棵的,且每一颗的组织树都是完全不一样的,长度不一样,宽度分支也不一样。并且这个组织树对于每一个登录的用户来说,都是不一样的,如果用户A赋予了组织树A的所有数据权限,那么当用户A登录我们的erp系统时候,看到的组织树列表中,组织树A就是一个“完整”的组织树。如果用户A赋予了组织树B的某一个节点的数据权限,那么该用户看到组织树列表中,组织树B就是一个只有一个节点的一个“完整”的组织树。这也是组织权限的一个设计概念。对于每个用户的权限范围内的组织树权限来说,可以这样认为,每一个用户的组织树列表的数据权限都是不一样的,那么对于向用户进行展示,是需要实时解析用户的组织权限,且通过组织权限来实时动态生成对应的权限范围内的组织树结构。
2、大致的概念说了一遍,那么我们根据每一个模块的需求,来细说一下该套组织树的具体应用场景。
在此项目中,组织树充当的角色是一个部门组织,每个部门组织上都有对应的设备,这些设备呢,也可以通过虚拟物流的形式进行在不同的组织树上,不同的组织节点上进行物流运输,那么这些设备,也可以进行相应的运行操作,每次运行都会产生一条运行数据,那么这些运行数据都会详细的标明这条数据是在哪颗组织树上,哪个节点上,的哪台设备上的哪个时间点产生,等等数据。
那么这些数据的数据量是很庞大的,在现有的系统的,承受的数据量已经超过900万条。
那么这批数据,我们是需要进行一个数据统计的,这也是做erp系统中最重要的一个范畴,数据统计。
那么组织结构有什么作用呢?就是给用户提供一个树形展示选择,让用户可以很灵活的选择每个组织节点的信息,然后后台通过用户的组织权限进行过滤,给用户反馈对应权限内的数据。
貼一个实际的案例:
在上图中,我们可以通过前端控件,弹出一个选择框,选择框支持多选,且跨项目选择,那么我们可以将选择的组织节点发送给后端,后端再根据提交请求的用户的组织权限,解析,然后反馈数据给前端。
3.前端展示也差不多了,那么我们通过后台源码来分析
3.1获取用户权限内的组织树集合(部分源码展示)
/**
* Copyright (C), 2019-2019, CHANGEMAX
* FileName: AuthoritySerivce
* Author: WangJi
* Date: 2019/7/5 13:31
* Description:
* History:
* <author> <time> <version> <desc>
* 作者姓名 修改时间 版本号 描述
*/
package com.zk.usercenter.service;
import com.zk.common.pojo.dto.JcRankdiagramDTO;
import com.zk.common.pojo.vo.OrgTreeVO;
import com.zk.common.result.ApiResult;
import com.zk.common.result.ServiceApiResult;
import javax.validation.constraints.NotBlank;
import java.util.List;
import java.util.Map;
import java.util.Set;
/**
* 〈一句话功能简述〉<br>
* 〈〉
*
* @author WangJi
* @create 2019/7/5
* @since 1.0.0
*/
public interface AuthorityOrgService {
ServiceApiResult<Map<String, String>> getOrgFullName(
@NotBlank String appAbbreviation, @NotBlank String userId, JcRankdiagramDTO jcRankdiagramDTO);
ApiResult getUserAuthorityOrgTreeVOList(
@NotBlank String appAbbreviation, @NotBlank String userId, JcRankdiagramDTO jcRankdiagramDTO);
ServiceApiResult<List<OrgTreeVO>> getServiceUserAuthorityOrgTreeVOList(
@NotBlank String appAbbreviation, @NotBlank String userId, JcRankdiagramDTO jcRankdiagramDTO);
Set<String> getAuthorityDeptIdSet(@NotBlank String appAbbreviation, @NotBlank String userId,
List<String> selectNodeIdList, JcRankdiagramDTO jcRankdiagramDTO);
Set<String> getAuthorityClassIdSet(@NotBlank String appAbbreviation, @NotBlank String userId);
}
/**
* Copyright (C), 2019-2019, CHANGEMAX
* FileName: AuthoritySerivceImpl
* Author: WangJi
* Date: 2019/7/5 13:30
* Description: 权限业务
* History:
* <author> <time> <version> <desc>
* 作者姓名 修改时间 版本号 描述
* <p>
* <p>
* <p>
* eg:
* 此业务类方法为获取每个用户的权限树相关方法:
* 方法1.getFuzzyQueryUserAuthorityOrgTreeVOList:模糊查询权限项目树
* 方法2.getUserAuthorityOrgTreeVOList:获取权限之内的组织树
* 方法3.getSectionUserAuthorityOrgTreeVOList:通过前端传来的 orgIdPOList 参数生成用户权限的组织树 部分:
* 方法4.getAuthorityDeptIdSet:通过前端传来的 orgIdPOList 参数进行解析生成deptIdSet集合:
*
*
* 1.对于组织权限存储形式,我们是将其用字符串形式存储于redis中,具体存储样式,以下示例为实际存储数据:
* zkhzyl-,2-,xhrsbx-,zkkjbj-,hzdsfyspx-,...,jhstcsm-
*
* (1)其表示含义为【classId-departmentId】,如“zkhzyl-zkhzyljishubu”,其解读意义为该用户拥有“zkhzyl”
* 分类(项目)下的某一个节点“zkhzyljishubu”下所有的组织数据权限;
*
* (2)如果为【classId-】形式,如“zkhzyl-”,其解读意义为该用户拥有“zkhzyl”分类(项目)下的所有节点的所有的组织数据权限;
*
*
* 2.对于本人设计[用户权限内的完整组织树]获取解决方案实现流程为:
* (1).获取redis中用户组织权限串
* (2).解析用户组织权限串
* (3).获取数据库中组织机构集
* (4).获取权限内的完整组织树
* (5).返回权限内的完整组织树结果
*
* 其余权限组织操作都是基于该【用户权限内的完整组织树】进行一系列数据摘取;
*
*
* 3.对于理解方面,可以抽象理解为果树,如果你对你拥有能够摘取的果树中进行果子摘取,你对其中一个节点进行果子摘取,
* 那么该节点下所有的果子,节点都会摘取下来。
*
*
* 4.对于如何运用该用户权限内的组织树去实际查询操作,设计的方案是,将你需要查询的每个分类(项目)下的需要查询的每个节点(deptId)
* 全部获取成一个Set<String> 集合,在我们需要查询的sql语句的where部分进行or循环即可限定组织数据权限
*
*
* 5.关于OrgUtils2中工具类,皆为辅助查询,生成树工具方法
*/
package com.zk.usercenter.service.impl;
import com.zk.common.pojo.dto.JcRankdiagramDTO;
import com.zk.common.pojo.vo.OrgTreeVO;
import com.zk.common.result.ApiResult;
import com.zk.common.result.ServiceApiResult;
import com.zk.common.utils.OrgUtils;
import com.zk.common.utils.StringUtils;
import com.zk.usercenter.dao.AuthorityDAO;
import com.zk.usercenter.po.JcRankdiagramPO;
import com.zk.usercenter.service.AuthorityOrgService;
import com.zk.usercenter.service.PermissionService;
import org.apache.commons.collections4.MapUtils;
import org.apache.commons.collections4.CollectionUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import javax.validation.constraints.NotBlank;
import java.util.*;
/**
* 〈一句话功能简述〉<br>
* 〈权限业务〉
*
* @author WangJi
* @create 2019/7/5
* @since 1.0.0
*/
@Service
public class AuthorityOrgServiceImpl implements AuthorityOrgService {
private static final Logger logger = LoggerFactory.getLogger(AuthorityOrgServiceImpl.class);
private static final String DEFAULT_PERMISSION_NAME = "组织权限";
@Autowired
private PermissionService permissionService;
@Autowired
private AuthorityDAO authorityDAO;
/**
* 通过权限获取组织树,并且生成每一个节点上的机构名称全称
* @param userId
* @param jcRankdiagramDTO
* @return
*/
@Override
public ServiceApiResult<Map<String, String>> getOrgFullName(
@NotBlank String appAbbreviation,
@NotBlank String userId,
JcRankdiagramDTO jcRankdiagramDTO
) {
ServiceApiResult<Map<String, String>> serviceApiResult = new ServiceApiResult<>();
//0.分析参数
if (StringUtils.isEmpty(userId)) {
logger.error("userId is null.");
serviceApiResult.setError("userId is null.");
return serviceApiResult;
}
String permissionName = jcRankdiagramDTO.getPermissionName();
permissionName = (StringUtils.isBlank(permissionName)) ? DEFAULT_PERMISSION_NAME : permissionName;
//1.获取redis中用户组织权限串
List<String> permissionList = permissionService.getDataPermissionInternal(appAbbreviation, userId, permissionName);
if (null == permissionList || permissionList.size() == 0) {
logger.info("org authority is null.");
serviceApiResult.setError("org authority is null.");
return serviceApiResult;
}
//2.解析组织权限串
LinkedHashMap<String, Set<String>> permissionIdMap = null;
LinkedHashSet<String> classIdSet = null;
try {
Map<String, Object> processPermissionMap = analysisSuthorityPermissionList(permissionList);
permissionIdMap = (LinkedHashMap<String, Set<String>>) processPermissionMap.get("permissionIdMap");
classIdSet = (LinkedHashSet<String>) processPermissionMap.get("classIdSet");
if (CollectionUtils.isEmpty(classIdSet) || MapUtils.isEmpty(permissionIdMap)) {
logger.info("classIdSet or permissionIdMap is null.");
serviceApiResult.setError("classIdSet or permissionIdMap is null.");
return serviceApiResult;
}
} catch (Exception e) {
e.printStackTrace();
logger.error("org authority is exception. {}", e.getMessage());
serviceApiResult.setError("org authority is exception.");
return serviceApiResult;
}
//3.对classIdSet进行不必要classId查询筛选去除
LinkedHashSet<String> classIdSetParamSet = jcRankdiagramDTO.getClassIdSet();
if (CollectionUtils.isNotEmpty(classIdSetParamSet)) {
LinkedHashSet<String> newclassIdSetParamt = new LinkedHashSet<>(classIdSetParamSet.size() * 4 / 3);
for (String classIdParam : classIdSetParamSet) {
if (classIdSet.contains(classIdParam)) {
newclassIdSetParamt.add(classIdParam);
}
}
classIdSet = newclassIdSetParamt;
}
jcRankdiagramDTO.setClassIdSet(classIdSet);
//4.获取数据库中组织机构集
List<JcRankdiagramPO> jcRankdiagramPOList = authorityDAO.getRankdiagramPOList(jcRankdiagramDTO);
if (CollectionUtils.isEmpty(jcRankdiagramPOList)) {
logger.info("database org list is null.");
serviceApiResult.setError("database org list is null.");
return serviceApiResult;
}
//5.获取权限内的完整组织树
List<OrgTreeVO> orgTreeVOList = null;
try {
orgTreeVOList = getPermissionOrgTreeVOList(jcRankdiagramPOList, permissionIdMap);
} catch (Exception e) {
e.printStackTrace();
logger.error("get user org tree is exception, {}", e.getMessage());
serviceApiResult.setError("get user org tree is exception.");
return serviceApiResult;
}
//6.生成每个节点上的机构全称
Map<String, String> map = OrgUtils.getAnyNodeOrgFullName(orgTreeVOList);
serviceApiResult.setData(map);
return serviceApiResult;
}
/**
* 获取权限之内的组织树,对外
* @param userId
* @param jcRankdiagramDTO
* @return
*/
@Override
public ApiResult getUserAuthorityOrgTreeVOList(@NotBlank String appAbbreviation,
@NotBlank String userId, JcRankdiagramDTO jcRankdiagramDTO) {
ApiResult apiResult = new ApiResult();
List<OrgTreeVO> orgTreeVOList = getUserAuthorityOrgTreeVOListObject(appAbbreviation, userId, jcRankdiagramDTO);
//5.返回结果
apiResult.setData(orgTreeVOList);
return apiResult;
}
/**
* 获取权限之内的组织树,服务调用
* @param userId
* @param jcRankdiagramDTO
* @return
*/
@Override
public ServiceApiResult<List<OrgTreeVO>> getServiceUserAuthorityOrgTreeVOList(@NotBlank String appAbbreviation,
@NotBlank String userId,
JcRankdiagramDTO jcRankdiagramDTO
) {
ServiceApiResult<List<OrgTreeVO>> apiResult = new ServiceApiResult<>();
List<OrgTreeVO> orgTreeVOList = getUserAuthorityOrgTreeVOListObject(appAbbreviation, userId, jcRankdiagramDTO);
//5.返回结果
apiResult.setData(orgTreeVOList);
return apiResult;
}
/**
* 获取权限之内的组织树
* @param userId
* @param jcRankdiagramDTO
* @return
*/
private List<OrgTreeVO> getUserAuthorityOrgTreeVOListObject(
@NotBlank String appAbbreviation, @NotBlank String userId,
JcRankdiagramDTO jcRankdiagramDTO
) {
jcRankdiagramDTO = (null == jcRankdiagramDTO) ? new JcRankdiagramDTO() : jcRankdiagramDTO;
ServiceApiResult<List<OrgTreeVO>> apiResult = new ServiceApiResult<>();
//0.分析参数
if (StringUtils.isEmpty(userId)) {
logger.error("userId is null.");
throw new RuntimeException("请登录后操作。");
}
String permissionName = jcRankdiagramDTO.getPermissionName();
permissionName = (StringUtils.isBlank(permissionName)) ? DEFAULT_PERMISSION_NAME : permissionName;
//1.获取redis中用户组织权限串
List<String> permissionList = permissionService.getDataPermissionInternal(appAbbreviation, userId, permissionName);
if (CollectionUtils.isEmpty(permissionList)) {
logger.info("user org authority is null, userId:{}", userId);
throw new RuntimeException("您尚未配置数据权限,请联系管理员。");
}
//2.解析组织权限串
LinkedHashMap<String, Set<String>> permissionIdMap = null;
LinkedHashSet<String> classIdSet = null;
try {
Map<String, Object> processPermissionMap = analysisSuthorityPermissionList(permissionList);
permissionIdMap = (LinkedHashMap<String, Set<String>>) processPermissionMap.get("permissionIdMap");
classIdSet = (LinkedHashSet<String>) processPermissionMap.get("classIdSet");
if (CollectionUtils.isEmpty(classIdSet) || MapUtils.isEmpty(permissionIdMap)) {
logger.info("classIdSet or permissionIdMap is null, userId:{}", userId);
throw new RuntimeException("您尚未配置数据权限,请联系管理员。");
}
} catch (Exception e) {
e.printStackTrace();
logger.error("org authority is exception. {}", e.getMessage());
throw new RuntimeException("org authority is exception.");
}
//3.对classIdSet进行不必要classId查询筛选去除
LinkedHashSet<String> classIdSetParamSet = jcRankdiagramDTO.getClassIdSet();
if (CollectionUtils.isNotEmpty(classIdSetParamSet)) {
LinkedHashSet<String> newclassIdSetParamt = new LinkedHashSet<>(classIdSetParamSet.size() * 4 / 3);
for (String classIdParam : classIdSetParamSet) {
if (classIdSet.contains(classIdParam)) {
newclassIdSetParamt.add(classIdParam);
}
}
classIdSet = newclassIdSetParamt;
if (CollectionUtils.isEmpty(classIdSet)) {
logger.info("classIdSet or permissionIdMap is null, userId:{},classIdSetParamSet:{}", userId, classIdSetParamSet);
throw new RuntimeException("您尚未配置数据权限,请联系管理员。");
}
}
jcRankdiagramDTO.setClassIdSet(classIdSet);
//3.获取数据库中组织机构集
List<JcRankdiagramPO> jcRankdiagramPOList = authorityDAO.getRankdiagramPOList(jcRankdiagramDTO);
if (CollectionUtils.isEmpty(jcRankdiagramPOList)) {
logger.info("database org list is null.");
throw new RuntimeException("没有找到匹配的记录");
}
//4.获取权限内的完整组织树
List<OrgTreeVO> orgTreeVOList = null;
try {
orgTreeVOList = getPermissionOrgTreeVOList(jcRankdiagramPOList, permissionIdMap);
apiResult.setData(orgTreeVOList);
} catch (Exception e) {
e.printStackTrace();
logger.error("get user org tree is exception, {}", e.getMessage());
throw new RuntimeException("get user org tree is exception.");
}
return orgTreeVOList;
}
/**
* 通过 selectNodeIdList 参数进行过滤解析生成deptIdSet集合
* @param userId
* @param selectNodeIdList
* @param jcRankdiagramDTO
* @return
*/
@Override
public Set<String> getAuthorityDeptIdSet(
@NotBlank String appAbbreviation, @NotBlank String userId,
List<String> selectNodeIdList, JcRankdiagramDTO jcRankdiagramDTO) {
jcRankdiagramDTO = (null == jcRankdiagramDTO) ? new JcRankdiagramDTO() : jcRankdiagramDTO;
//0.分析参数
if (StringUtils.isEmpty(userId)) {
logger.error("userId is null.");
throw new RuntimeException("userId is null.");
}
String permissionName = jcRankdiagramDTO.getPermissionName();
permissionName = (StringUtils.isBlank(permissionName)) ? DEFAULT_PERMISSION_NAME : permissionName;
//1.获取redis中用户组织权限串
List<String> permissionList = permissionService.getDataPermissionInternal("SAAS", userId, permissionName);
if (CollectionUtils.isEmpty(permissionList)) {
logger.info("user org authority is null, userId:{}", userId);
throw new RuntimeException("user org authority is null.");
}
//2.解析组织权限串
LinkedHashMap<String, Set<String>> permissionIdMap = null;
LinkedHashSet<String> classIdSet = null;
try {
Map<String, Object> processPermissionMap = analysisSuthorityPermissionList(permissionList);
permissionIdMap = (LinkedHashMap<String, Set<String>>) processPermissionMap.get("permissionIdMap");
classIdSet = (LinkedHashSet<String>) processPermissionMap.get("classIdSet");
if (CollectionUtils.isEmpty(classIdSet) || MapUtils.isEmpty(permissionIdMap)) {
logger.info("classIdSet or permissionIdMap is null, userId:{}", userId);
throw new RuntimeException("classIdSet or permissionIdMap is null,");
}
} catch (Exception e) {
e.printStackTrace();
logger.error("analysis org authority is exception. {}", e.getMessage());
throw new RuntimeException("analysis org authority is exception.");
}
jcRankdiagramDTO.setClassIdSet(classIdSet);
//3.获取数据库中组织机构集
List<JcRankdiagramPO> jcRankdiagramPOList = authorityDAO.getRankdiagramPOList(jcRankdiagramDTO);
if (CollectionUtils.isEmpty(jcRankdiagramPOList)) {
logger.info("database org list is null.");
throw new RuntimeException("database org list is null.");
}
//4.获取权限内的搜索id完整组织树
List<OrgTreeVO> orgTreeVOList = null;
try {
orgTreeVOList = getPermissionOrgTreeVOList(jcRankdiagramPOList, permissionIdMap);
} catch (Exception e) {
e.printStackTrace();
logger.error("org authority is exception. {}", e.getMessage());
throw new RuntimeException("org authority is exception.");
}
Set<String> anthorityDeptIdSet = null;
//6.对权限内组织树进行节点deptId获取
try {
anthorityDeptIdSet = OrgUtils.getAuthoritySelectDeptIdSet(orgTreeVOList, selectNodeIdList);
} catch (Exception e) {
e.printStackTrace();
logger.error("analysis user authority org tree node is excaption, {}", e.getMessage());
throw new RuntimeException("analysis user authority org tree node is excaption!");
}
return anthorityDeptIdSet;
}
/**
* 获取用户权限内的classId
* @param userId
* @return
*/
@Override
public Set<String> getAuthorityClassIdSet(@NotBlank String appAbbreviation, @NotBlank String userId) {
//1.获取redis中用户组织权限串
List<String> permissionList = permissionService.getDataPermissionInternal(appAbbreviation, userId, DEFAULT_PERMISSION_NAME);
if (CollectionUtils.isEmpty(permissionList)) {
logger.info("user org authority is null, userId:{}", userId);
throw new RuntimeException("user org authority is null.");
}
//2.解析组织权限串
LinkedHashMap<String, Set<String>> permissionIdMap = null;
LinkedHashSet<String> classIdSet = null;
try {
Map<String, Object> processPermissionMap = analysisSuthorityPermissionList(permissionList);
permissionIdMap = (LinkedHashMap<String, Set<String>>) processPermissionMap.get("permissionIdMap");
classIdSet = (LinkedHashSet<String>) processPermissionMap.get("classIdSet");
if (CollectionUtils.isEmpty(classIdSet) || MapUtils.isEmpty(permissionIdMap)) {
logger.info("classIdSet or permissionIdMap is null, userId:{}", userId);
throw new RuntimeException("classIdSet or permissionIdMap is null,");
}
} catch (Exception e) {
e.printStackTrace();
logger.error("analysis org authority is exception. {}", e.getMessage());
throw new RuntimeException("analysis org authority is exception.");
}
return classIdSet;
}
/**
* 获取相对完整的组织树
*
* @param jcRankdiagramPOList
* @return
*/
private List<OrgTreeVO> getCompletePermissionOrgTreeVOList(List<JcRankdiagramPO> jcRankdiagramPOList) throws Exception {
logger.info("get relatively complete org tree start.");
//获取所有父机构id
Set<String> parentIdSet = getParentIdSet(jcRankdiagramPOList);
//生成整个权限组织树
List<OrgTreeVO> completePermissionOrgTreeVOList = null;
try {
completePermissionOrgTreeVOList = recursiveCompletePermissionOrgTreeVOList(
jcRankdiagramPOList,
parentIdSet,
10,
0,
"-1",
"",
"");
} catch (Exception e) {
e.printStackTrace();
logger.error("get relatively complete org tree is exception! {}", e.getMessage());
throw new RuntimeException("get relatively complete org tree is exception!");
}
logger.info("get relatively complete org tree end.");
return completePermissionOrgTreeVOList;
}
/**
* 获取权限内的完整组织树
*
* @param jcRankdiagramPOList
* @param permissionIdMap
* @return
*/
private List<OrgTreeVO> getPermissionOrgTreeVOList(
List<JcRankdiagramPO> jcRankdiagramPOList, Map<String, Set<String>> permissionIdMap
) throws Exception {
//获取相对完整的组织树
List<OrgTreeVO> completePermissionOrgTreeVOList = getCompletePermissionOrgTreeVOList(jcRankdiagramPOList);
//对组织树进行权限筛选去除,得到权限之内的权限 小树
List<OrgTreeVO> permissionOrgTreeVOList = new ArrayList<>();
try {
permissionIdMap.forEach((permissionClassId, permissionDeptIdSet) -> {
if (permissionDeptIdSet != null && permissionDeptIdSet.size() > 0) {
logger.info(
"The fineness mechanism of the current authority, {}, {}",
permissionClassId, permissionDeptIdSet.toArray()
);
permissionDeptIdSet.forEach(permissionDeptId -> {
OrgTreeVO directOrgTreeVO = getPermissionOrgTreeVO(
completePermissionOrgTreeVOList,
permissionClassId,
permissionDeptId,
10,
0);
//将不为空符合条件对象进行归集
if (null != directOrgTreeVO) {
permissionOrgTreeVOList.add(directOrgTreeVO);
}
});
} else {
//拥有整个当前权限机构
completePermissionOrgTreeVOList.forEach(orgTreeVO -> {
if (permissionClassId.equals(orgTreeVO.getClassId())) {
permissionOrgTreeVOList.add(orgTreeVO);
}
});
}
});
} catch (Exception e) {
e.printStackTrace();
logger.error("Get the complete organization tree within the permissions, organize");
throw new RuntimeException("Get the complete organization tree within the permissions, organize");
}
List<OrgTreeVO> orgTreeVOList = mergOrgTreeVOList(permissionOrgTreeVOList);
return orgTreeVOList;
}
/**
* 将oldOrgTreeVOList整理归并为newOrgTreeVOList
*
* @param oldOrgTreeVOList
* @return
*/
private List<OrgTreeVO> mergOrgTreeVOList(List<OrgTreeVO> oldOrgTreeVOList) throws Exception {
logger.info("mergOrgTreeVOList, Organize the organization tree into the class organization!");
Map<String, OrgTreeVO> newOrgTreeVOMap = new HashMap<>();
try {
oldOrgTreeVOList.forEach(oldOrgTreeVO -> {
String classId = oldOrgTreeVO.getClassId();
String className = oldOrgTreeVO.getClassName();
if (newOrgTreeVOMap.containsKey(classId)) {
newOrgTreeVOMap.get(classId).getChildren().add(oldOrgTreeVO);
} else {
OrgTreeVO newOrgTreeVO = new OrgTreeVO();
newOrgTreeVO.setClassId(classId);
newOrgTreeVO.setClassName(className);
newOrgTreeVO.setId(classId);
newOrgTreeVO.setText(className);
List<OrgTreeVO> children = new ArrayList<>();
children.add(oldOrgTreeVO);
newOrgTreeVO.setChildren(children);
newOrgTreeVOMap.put(classId, newOrgTreeVO);
}
});
} catch (Exception e) {
e.printStackTrace();
logger.error("mergOrgTreeVOList--->oldOrgTreeVOList-->newOrgTreeVOMap conversion exception!");
throw new RuntimeException("org tree conversion exception!");
}
List<OrgTreeVO> newOrgTreeVOList = new ArrayList<>(newOrgTreeVOMap.size());
try {
newOrgTreeVOMap.forEach((classId, newOrgTreeVO) -> {
newOrgTreeVOList.add(newOrgTreeVO);
});
} catch (Exception e) {
e.printStackTrace();
logger.error("mergOrgTreeVOList--->newOrgTreeVOMap-->newOrgTreeVOList conversion exception!");
throw new RuntimeException("org tree conversion exception!");
}
return newOrgTreeVOList;
}
/**
* 获取总权限树详细权限树
*
* @param orgTreeVOList
* @param permissionClassId
* @param permissionDeptId
* @return
*/
private OrgTreeVO getPermissionOrgTreeVO(
List<OrgTreeVO> orgTreeVOList, String permissionClassId,
String permissionDeptId, final Integer maxLevelNum, Integer upperLevelNum
) {
if (upperLevelNum > maxLevelNum) {
return null;
}
if (CollectionUtils.isEmpty(orgTreeVOList)) {
return null;
}
for (OrgTreeVO currOrgTreeVO : orgTreeVOList) {
String deptId = currOrgTreeVO.getDeptId();
String classId = currOrgTreeVO.getClassId();
List<OrgTreeVO> nextLevelChildren = currOrgTreeVO.getChildren();
//当前组织currClassId符合需求
if (permissionClassId.equals(classId)) {
//当前组织符合需求组织id,直接返回当前组织
if (permissionDeptId.equals(deptId)) {
return currOrgTreeVO;
} else {
Integer currLevelNum = 1 + upperLevelNum;
//当前组织currClassId符合需求classId,但deptId不符,继续向下递归
OrgTreeVO permissionOrgTreeVO = getPermissionOrgTreeVO(
nextLevelChildren,
permissionClassId,
permissionDeptId,
maxLevelNum,
currLevelNum
);
//返回符合条件且不为空的对象
if (null != permissionOrgTreeVO) {
return permissionOrgTreeVO;
}
}
}
}
return null;
}
/**
* 获取完整权限组织树
*
* @param jcRankdiagramPOList
* @param currLevelParentIdSet
* @param currLevelParentId
* @return
*/
private List<OrgTreeVO> recursiveCompletePermissionOrgTreeVOList(
final List<JcRankdiagramPO> jcRankdiagramPOList, Set<String> currLevelParentIdSet,
final Integer maxLevelNum, Integer upperLevelNum,
String currLevelParentId, String currClassId, String currClassName
) {
//递归获取权限完整组织树
if (upperLevelNum >= maxLevelNum) {
//递归获取权限完整组织树组织层级达到上限值
return null;
}
List<OrgTreeVO> children = new ArrayList<>();
for (JcRankdiagramPO jcRankdiagramPO : jcRankdiagramPOList) {
String deptId = jcRankdiagramPO.getDeptId();
String deptName = jcRankdiagramPO.getDeptName();
String classId = jcRankdiagramPO.getClassId();
String parentId = jcRankdiagramPO.getParentId();
String className = jcRankdiagramPO.getClassName();
if (currLevelParentId.equals(parentId)) {
//递归获取权限完整组织树当前组织为上一层组织的子组织
currLevelParentIdSet.remove(currLevelParentId);
OrgTreeVO orgTreeVO = new OrgTreeVO();
orgTreeVO.setId(deptId);
orgTreeVO.setText(deptName);
orgTreeVO.setDeptId(deptId);
orgTreeVO.setDeptName(deptName);
if ("-1".equals(parentId)) {
// 递归获取权限完整组织树当前机构为第一层机构
orgTreeVO.setParentId(classId);
currClassId = classId;
orgTreeVO.setClassId(classId);
currClassName = className;
orgTreeVO.setClassName(className);
} else {
orgTreeVO.setParentId(parentId);
orgTreeVO.setClassId(currClassId);
orgTreeVO.setClassName(currClassName);
}
if (currLevelParentIdSet.contains(deptId)) {
// 递归获取权限完整组织树当前机构存在子机构,需继续向下递归
Integer currLevelNum = 1 + upperLevelNum;
orgTreeVO.setChildren(
recursiveCompletePermissionOrgTreeVOList(
jcRankdiagramPOList,
currLevelParentIdSet,
maxLevelNum,
currLevelNum,
deptId,
currClassId,
currClassName));
}
children.add(orgTreeVO);
}
}
return children;
}
/**
* 获取所有权限内的父id
*
* @param jcRankdiagramPOList
* @return
*/
private Set<String> getParentIdSet(List<JcRankdiagramPO> jcRankdiagramPOList) throws Exception {
logger.info("get all authority is parent id.");
Set<String> parentIdSet = new HashSet<>();
try {
jcRankdiagramPOList.forEach(jcRankdiagramPO -> {
parentIdSet.add(jcRankdiagramPO.getParentId());
});
} catch (Exception e) {
e.printStackTrace();
logger.error("get all authority is parent id is excaption!");
throw new RuntimeException("get all authority is parent id is excaption!");
}
return parentIdSet;
}
/**
* 整理redis中权限机构
*
* @param orgDataPermissionList
* @return
*/
private Map<String, Object> analysisSuthorityPermissionList(List<String> orgDataPermissionList) throws Exception {
logger.info("analysis suthority permission org start.");
LinkedHashMap<String, Set<String>> permissionIdMap = new LinkedHashMap<>();
LinkedHashSet<String> classIdSet = new LinkedHashSet<>();
orgDataPermissionList.forEach(orgData -> {
List<String> spliceIdList = Arrays.asList(orgData.split(","));//组织ID集
spliceIdList.forEach(spliceId -> {
String[] classIdAndDeptIdArray = spliceId.split("-");
String classId = classIdAndDeptIdArray[0];
classIdSet.add(classId);
if (permissionIdMap.containsKey(classId)) {
if (classIdAndDeptIdArray.length > 1) {
String deptId = classIdAndDeptIdArray[1];
if (StringUtils.isNotBlank(deptId)) {
permissionIdMap.get(classId).add(deptId);
}
}
} else {
Set<String> deptIdSet = new HashSet<>();
if (classIdAndDeptIdArray.length > 1) {
String deptId = classIdAndDeptIdArray[1];
if (StringUtils.isNotBlank(deptId)) {
deptIdSet.add(deptId);
}
}
permissionIdMap.put(classId, deptIdSet);
}
});
});
Map<String, Object> map = new HashMap<>();
map.put("permissionIdMap", permissionIdMap);
map.put("classIdSet", classIdSet);
logger.info("analysis suthority permission org ok!");
return map;
}
}
//
// Source code recreated from a .class file by IntelliJ IDEA
// (powered by Fernflower decompiler)
//
package com.changemax.common.utils;
import com.zk.common.pojo.po.SecondarySubOrgPO;
import com.zk.common.pojo.vo.OrgTreeVO;
import java.util.ArrayList;
import java.util.Collection;
import java.util.HashMap;
import java.util.HashSet;
import java.util.Iterator;
import java.util.List;
import java.util.Map;
import java.util.Set;
import java.util.function.Consumer;
import javax.validation.constraints.NotBlank;
import org.apache.commons.collections4.CollectionUtils;
import org.apache.commons.collections4.MapUtils;
public class OrgUtils {
public OrgUtils() {
}
public static Set<String> getAllAuthorityDeptIdSet(List<OrgTreeVO> orgTreeVOList) {
if (CollectionUtils.isEmpty(orgTreeVOList)) {
return null;
} else {
Set<String> deptIdSet = new HashSet();
Iterator var2 = orgTreeVOList.iterator();
while(var2.hasNext()) {
OrgTreeVO orgTreeVO = (OrgTreeVO)var2.next();
String deptId = orgTreeVO.getDeptId();
List<OrgTreeVO> children = orgTreeVO.getChildren();
if (StringUtils.isNotBlank(deptId)) {
deptIdSet.add(deptId);
}
Set<String> nextDeptIdSet = getAllAuthorityDeptIdSet(children);
if (CollectionUtils.isNotEmpty(nextDeptIdSet)) {
deptIdSet.addAll(nextDeptIdSet);
}
}
return deptIdSet;
}
}
private static Set<String> getSubDeptIdSet(OrgTreeVO childOrgTreeVO) {
Set<String> deptIdSet = new HashSet();
deptIdSet.add(childOrgTreeVO.getDeptId());
List<OrgTreeVO> children = childOrgTreeVO.getChildren();
if (CollectionUtils.isNotEmpty(children)) {
children.forEach((subOrgTreeVO) -> {
Set<String> subDeptIdSet = getSubDeptIdSet(subOrgTreeVO);
if (CollectionUtils.isNotEmpty(subDeptIdSet)) {
deptIdSet.addAll(subDeptIdSet);
}
});
return deptIdSet;
} else {
return deptIdSet;
}
}
public static Map<String, String> getAnyNodeOrgFullName(List<OrgTreeVO> orgTreeVOList) {
if (CollectionUtils.isEmpty(orgTreeVOList)) {
return null;
} else {
Map<String, String> map = new HashMap();
Iterator var2 = orgTreeVOList.iterator();
while(var2.hasNext()) {
OrgTreeVO orgTreeVO = (OrgTreeVO)var2.next();
if (null != orgTreeVO) {
Map<String, String> childrenMap = getAnyNodeOrgFullName(" / ", "", orgTreeVO);
if (MapUtils.isNotEmpty(childrenMap)) {
map.putAll(childrenMap);
}
}
}
return map;
}
}
private static Map<String, String> getAnyNodeOrgFullName(String separator, String upperOrgFullName, OrgTreeVO orgTreeVO) {
if (null == orgTreeVO) {
return null;
} else {
String currId = orgTreeVO.getId();
String currText = orgTreeVO.getText();
List<OrgTreeVO> currChildren = orgTreeVO.getChildren();
Map<String, String> currMap = new HashMap();
String currOrgFullName = currText;
if (StringUtils.isNotBlank(upperOrgFullName)) {
currOrgFullName = upperOrgFullName + separator + currText;
}
currMap.put(currId, currOrgFullName);
if (CollectionUtils.isNotEmpty(currChildren)) {
Iterator var8 = currChildren.iterator();
while(var8.hasNext()) {
OrgTreeVO currChildrenOrgTreeVO = (OrgTreeVO)var8.next();
Map<String, String> currChildrenMap = getAnyNodeOrgFullName(separator, currOrgFullName, currChildrenOrgTreeVO);
if (MapUtils.isNotEmpty(currChildrenMap)) {
currMap.putAll(currChildrenMap);
}
}
}
return currMap;
}
}
public static String getOrganization(Map<String, String> orgFullNameMap, @NotBlank String classId, @NotBlank String departmentId) {
if (MapUtils.isEmpty(orgFullNameMap)) {
return " - ";
} else if (StringUtils.isBlank(classId) && StringUtils.isBlank(departmentId)) {
return " - ";
} else {
String currId = StringUtils.isNotBlank(departmentId) ? departmentId : classId;
return (String)orgFullNameMap.get(currId);
}
}
public static List<SecondarySubOrgPO> getSecondarySubOrgPOList(List<OrgTreeVO> orgTreeVOList, List<String> selectNodeIdList) {
if (!CollectionUtils.isEmpty(orgTreeVOList) && !CollectionUtils.isEmpty(selectNodeIdList)) {
List<String> newSelectNodeIdList = getHaveParentIdNodeId(orgTreeVOList, selectNodeIdList);
List<SecondarySubOrgPO> secondarySubOrgPOList = new ArrayList();
newSelectNodeIdList.forEach((selectNodeId) -> {
orgTreeVOList.forEach((orgTreeVO) -> {
String id = orgTreeVO.getId();
String deptId = orgTreeVO.getDeptId();
String deptName = orgTreeVO.getDeptName();
List<OrgTreeVO> children = orgTreeVO.getChildren();
if (StringUtils.equals(selectNodeId, id)) {
if (CollectionUtils.isNotEmpty(children)) {
Iterator var8 = children.iterator();
while(var8.hasNext()) {
OrgTreeVO childOrgTreeVO = (OrgTreeVO)var8.next();
SecondarySubOrgPO secondarySubOrgPOx = new SecondarySubOrgPO();
secondarySubOrgPOx.setOrgId(childOrgTreeVO.getDeptId());
secondarySubOrgPOx.setOrgName(childOrgTreeVO.getDeptName());
Set<String> childDeptIdSet = getSubDeptIdSet(childOrgTreeVO);
secondarySubOrgPOx.setChildDeptIdSet(childDeptIdSet);
secondarySubOrgPOList.add(secondarySubOrgPOx);
}
} else {
SecondarySubOrgPO secondarySubOrgPO = new SecondarySubOrgPO();
secondarySubOrgPO.setOrgId(deptId);
secondarySubOrgPO.setOrgName(deptName);
Set<String> childDeptIdSetx = getSubDeptIdSet(orgTreeVO);
secondarySubOrgPO.setChildDeptIdSet(childDeptIdSetx);
secondarySubOrgPOList.add(secondarySubOrgPO);
}
} else {
List<SecondarySubOrgPO> childrenSecondarySubOrgPOList = getSecondarySubOrgPOList(children, newSelectNodeIdList);
if (CollectionUtils.isNotEmpty(childrenSecondarySubOrgPOList)) {
secondarySubOrgPOList.addAll(childrenSecondarySubOrgPOList);
}
}
});
});
return secondarySubOrgPOList;
} else {
return null;
}
}
private static List<String> getHaveParentIdNodeId(List<OrgTreeVO> orgTreeVOList, List<String> selectNodeIdList) {
if (!CollectionUtils.isEmpty(orgTreeVOList) && !CollectionUtils.isEmpty((Collection)selectNodeIdList)) {
Map<String, String> haveParentIdNodeIdMap = getAllHaveParentIdNodeId(orgTreeVOList);
if (MapUtils.isNotEmpty(haveParentIdNodeIdMap)) {
List<String> newSelectNodeIdList = new ArrayList(((List)selectNodeIdList).size());
((List)selectNodeIdList).forEach((selectNodeId) -> {
if (!haveParentIdNodeIdMap.containsKey(selectNodeId) || StringUtils.isBlank((String)haveParentIdNodeIdMap.get(selectNodeId)) || !selectNodeIdList.contains(haveParentIdNodeIdMap.get(selectNodeId))) {
newSelectNodeIdList.add(selectNodeId);
}
});
selectNodeIdList = newSelectNodeIdList;
}
return (List)selectNodeIdList;
} else {
return null;
}
}
private static Map<String, String> getAllHaveParentIdNodeId(List<OrgTreeVO> orgTreeVOList) {
if (CollectionUtils.isEmpty(orgTreeVOList)) {
return null;
} else {
Map<String, String> haveParentIdNodeIdMap = new HashMap();
orgTreeVOList.forEach((orgTreeVO) -> {
String id = orgTreeVO.getId();
String parentId = orgTreeVO.getParentId();
List<OrgTreeVO> children = orgTreeVO.getChildren();
haveParentIdNodeIdMap.put(id, parentId);
if (CollectionUtils.isNotEmpty(children)) {
Map<String, String> childrenHaveParentIdNodeIdMap = getAllHaveParentIdNodeId(children);
if (MapUtils.isNotEmpty(childrenHaveParentIdNodeIdMap)) {
haveParentIdNodeIdMap.putAll(childrenHaveParentIdNodeIdMap);
}
}
});
return haveParentIdNodeIdMap;
}
}
public static List<OrgTreeVO> getPermissionOrgTreeVOList(List<OrgTreeVO> orgTreeVOList, List<String> selectNodeIdList) {
if (!CollectionUtils.isEmpty(orgTreeVOList) && !CollectionUtils.isEmpty(selectNodeIdList)) {
Iterator var2 = orgTreeVOList.iterator();
while(var2.hasNext()) {
OrgTreeVO orgTreeVO = (OrgTreeVO)var2.next();
String id = orgTreeVO.getId();
String parentId = orgTreeVO.getParentId();
List<OrgTreeVO> children = orgTreeVO.getChildren();
Iterator var7 = selectNodeIdList.iterator();
while(var7.hasNext()) {
String selectNodeId = (String)var7.next();
if (StringUtils.equals(selectNodeId, id)) {
if (selectNodeIdList.indexOf(parentId) <= 0) {
List<OrgTreeVO> currOrgTreeVOList = new ArrayList(1);
currOrgTreeVOList.add(orgTreeVO);
return currOrgTreeVOList;
}
} else {
List<OrgTreeVO> childrenOrgTreeVOList = getPermissionOrgTreeVOList(children, selectNodeIdList);
if (CollectionUtils.isNotEmpty(childrenOrgTreeVOList)) {
return childrenOrgTreeVOList;
}
}
}
}
return null;
} else {
return null;
}
}
public static Set<String> getAuthoritySelectDeptIdSet(List<OrgTreeVO> sectionUserAuthorityOrgTreeVOList, List<String> selectNodeIdList) {
Set<String> authoritySelectDeptIdSet = null;
Set<String> authorityDeptIdSet = getAllAuthorityDeptIdSet(sectionUserAuthorityOrgTreeVOList);
if (CollectionUtils.isNotEmpty(selectNodeIdList)) {
if (CollectionUtils.isNotEmpty(authorityDeptIdSet)) {
Set<String> authoritySelectDeptIdSet = new HashSet(selectNodeIdList.size() * 4 / 3);
selectNodeIdList.forEach((selectNodeId) -> {
if (authorityDeptIdSet.contains(selectNodeId)) {
authoritySelectDeptIdSet.add(selectNodeId);
}
});
authoritySelectDeptIdSet = authoritySelectDeptIdSet;
}
} else {
authoritySelectDeptIdSet = authorityDeptIdSet;
}
return (Set)authoritySelectDeptIdSet;
}
private static Set<String> getSubDeptIdByNodeId(OrgTreeVO orgTreeVO, String selectNodeId, boolean isConform) {
if (null == orgTreeVO) {
return null;
} else {
String currNodeId = orgTreeVO.getId();
String currClassId = orgTreeVO.getClassId();
String currDeptId = orgTreeVO.getDeptId();
List<OrgTreeVO> currChildren = orgTreeVO.getChildren();
Set<String> currDeptIdSet = new HashSet();
if (isConform) {
if (StringUtils.isNotBlank(currDeptId)) {
currDeptIdSet.add(currDeptId);
}
if (CollectionUtils.isNotEmpty(currChildren)) {
currChildren.forEach((currChildrenOrgTreeVO) -> {
Set<String> currChildrenDeptIdSet = getSubDeptIdByNodeId(currChildrenOrgTreeVO, selectNodeId, true);
if (CollectionUtils.isNotEmpty(currChildrenDeptIdSet)) {
currDeptIdSet.addAll(currChildrenDeptIdSet);
}
});
}
} else if (StringUtils.isNotBlank(currNodeId) && selectNodeId.equals(currNodeId)) {
currDeptIdSet.add(currDeptId);
if (CollectionUtils.isNotEmpty(currChildren)) {
currChildren.forEach((currChildrenOrgTreeVO) -> {
Set<String> currChildrenDeptIdSet = getSubDeptIdByNodeId(currChildrenOrgTreeVO, selectNodeId, true);
if (CollectionUtils.isNotEmpty(currChildrenDeptIdSet)) {
currDeptIdSet.addAll(currChildrenDeptIdSet);
}
});
}
} else if (CollectionUtils.isNotEmpty(currChildren)) {
currChildren.forEach((currChildrenOrgTreeVO) -> {
Set<String> currChildrenDeptIdSet = getSubDeptIdByNodeId(currChildrenOrgTreeVO, selectNodeId, false);
if (CollectionUtils.isNotEmpty(currChildrenDeptIdSet)) {
currDeptIdSet.addAll(currChildrenDeptIdSet);
}
});
}
return currDeptIdSet;
}
}
}
<select id="getRankdiagramPOList" parameterType="com.zk.common.pojo.dto.JcRankdiagramDTO"
resultType="com.zk.usercenter.po.JcRankdiagramPO">
select
jr.department_id as "deptId",
concat(jd.dept_name,
case when jr.is_deleted = 1 then ' (该组织已解绑)' else '' end,
case when jd2.is_enable = 1 then ' (该层级已禁用)' else '' end
) as "deptName",
jr.class_id as "classId",
jr.parent_id as "parentId",
jc.class_name as "className"
from jc_rankdiagram as jr
inner join jc_department as jd on jd.department_id = jr.department_id
inner join project_classification as pc on pc.class_id = jr.class_id
inner join project_profile as pp on pp.project_id = pc.project_id
inner join jc_classification as jc on jc.class_id = jr.class_id
inner join jc_departmentrank as jd2 on jd2.rank_id = jr.rank_id and jd2.rank_type = jr.rank_type
<where>
<if test="classIdSet != null and classIdSet.size() > 0">
and
<foreach collection="classIdSet" item="classId" open="(" separator="or"
close=")">
jr.class_id = #{classId}
</foreach>
</if>
<if test="isDeleted != null">
and jr.is_deleted = #{isDeleted,jdbcType=INTEGER}
</if>
<if test="classChargeType != null and classChargeType != '' ">
and pp.charge_type = #{classChargeType,jdbcType=VARCHAR}
</if>
<if test="selectedClassName != null and selectedClassName != '' ">
and jc.class_name like concat('%', #{selectedClassName,jdbcType=VARCHAR}, '%')
</if>
</where>
</select>
/**
* Copyright (C), 2019-2019, ZHIKANG
* FileName: AuthorityDAO
* Author: WangJi
* Date: 2019/7/5 14:20
* Description:
* History:
* <author> <time> <version> <desc>
* 作者姓名 修改时间 版本号 描述
*/
package com.zk.usercenter.dao;
import com.zk.common.pojo.dto.JcRankdiagramDTO;
import com.zk.usercenter.po.JcRankdiagramPO;
import org.springframework.stereotype.Repository;
import java.util.List;
/**
* 〈一句话功能简述〉<br>
* 〈〉
*
* @author WangJi
* @create 2019/7/5
* @since 1.0.0
*/
@Repository
public interface AuthorityDAO {
List<JcRankdiagramPO> getRankdiagramPOList(JcRankdiagramDTO jcRankdiagramDTO);
}
/**
* 获取项目权限
*
* @param userId
* @return
*/
@Override
public ServiceApiResult<List<String>> getProjectPermission(@NotBlank String appAbbreviation, @NotBlank String userId) {
ServiceApiResult<List<String>> apiResult = new ServiceApiResult<List<String>>();
UserInfoVO userInfoVO = secUserService.getUserInfoVOByUserId(appAbbreviation, userId);
List<String> list = userInfoVO.getDataPermission().get("项目权限");
List<String> ret = new ArrayList<>();
boolean allFlag = false;
if (list != null && list.size() != 0) {
for (String i : list) {
if (allFlag) {
break;
}
List<String> tmp = Arrays.asList(i.split(","));
if (tmp.size() != 0) {
for (String j : tmp) {
if (StringUtils.equals("1", j)) {
ret.add(userInfoVO.getUserBasic().getMobile());
} else if (StringUtils.equals("ALL", StringUtils.upperCase(j))) {
allFlag = true;
break;
} else {
ret.add(j);
}
}
}
}
if (allFlag) {
ret.clear();
ret.add("ALL");
apiResult.setData(ret);
return apiResult;
} else {
apiResult.setData(ret);
return apiResult;
}
}
return null;
}
至于具体的逻辑上的优化方案,大家可以参照以上源码分析,切记,不可放弃每一个细节。