|
|
|
@ -1,17 +1,32 @@ |
|
|
|
package com.elink.esua.epdc.optimize.modules.deptlevel.service.impl; |
|
|
|
|
|
|
|
import cn.hutool.core.collection.CollUtil; |
|
|
|
import cn.hutool.core.util.ArrayUtil; |
|
|
|
import com.alibaba.fastjson.JSONArray; |
|
|
|
import com.alibaba.fastjson.JSONObject; |
|
|
|
import com.elink.esua.epdc.commons.mybatis.service.impl.BaseServiceImpl; |
|
|
|
import com.elink.esua.epdc.commons.tools.constant.NumConstant; |
|
|
|
import com.elink.esua.epdc.commons.tools.constant.OrganizationTypeConstant; |
|
|
|
import com.elink.esua.epdc.commons.tools.constant.StrConstant; |
|
|
|
import com.elink.esua.epdc.commons.tools.exception.RenException; |
|
|
|
import com.elink.esua.epdc.commons.tools.redis.RedisUtils; |
|
|
|
import com.elink.esua.epdc.dto.DeptLevelAndLeaderDTO; |
|
|
|
import com.elink.esua.epdc.dto.DeptOption; |
|
|
|
import com.elink.esua.epdc.optimize.constant.OptimizeConstant; |
|
|
|
import com.elink.esua.epdc.optimize.constant.OptimizeRedisKeys; |
|
|
|
import com.elink.esua.epdc.optimize.modules.deptlevel.dao.OptSysDeptDao; |
|
|
|
import com.elink.esua.epdc.optimize.modules.deptlevel.entity.OptSysDeptEntity; |
|
|
|
import com.elink.esua.epdc.optimize.modules.deptlevel.service.OptSysDeptService; |
|
|
|
import com.elink.esua.epdc.optimize.utils.DeptUtils; |
|
|
|
import com.google.common.collect.Lists; |
|
|
|
import com.google.common.collect.Maps; |
|
|
|
import org.apache.commons.lang3.StringUtils; |
|
|
|
import org.springframework.beans.factory.annotation.Autowired; |
|
|
|
import org.springframework.stereotype.Service; |
|
|
|
|
|
|
|
import java.util.List; |
|
|
|
import java.util.Map; |
|
|
|
import java.util.stream.Collectors; |
|
|
|
|
|
|
|
/** |
|
|
|
* 部门相关业务实现 |
|
|
|
@ -22,6 +37,9 @@ import java.util.List; |
|
|
|
@Service |
|
|
|
public class OptSysDeptServiceImpl extends BaseServiceImpl<OptSysDeptDao, OptSysDeptEntity> implements OptSysDeptService { |
|
|
|
|
|
|
|
@Autowired |
|
|
|
private RedisUtils redisUtils; |
|
|
|
|
|
|
|
@Override |
|
|
|
public List<DeptLevelAndLeaderDTO> listChildDeptLevelById(String typeKey, Long deptId) { |
|
|
|
OptSysDeptEntity parentDept = baseDao.selectById(deptId); |
|
|
|
@ -52,6 +70,208 @@ public class OptSysDeptServiceImpl extends BaseServiceImpl<OptSysDeptDao, OptSys |
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
@Override |
|
|
|
public DeptOption getDeptOption(Long userId, List<Long> dataScopeDeptIdList, String... typeKeys) { |
|
|
|
if (null == userId || CollUtil.isEmpty(dataScopeDeptIdList)) { |
|
|
|
return new DeptOption(); |
|
|
|
} |
|
|
|
// 是否需要对数据权限部门进行二次筛选
|
|
|
|
boolean filterDataScope = false; |
|
|
|
if (ArrayUtil.isEmpty(typeKeys)) { |
|
|
|
typeKeys = new String[]{OptimizeConstant.COMPLETE_DEPT_LEVEL_KEY}; |
|
|
|
} else { |
|
|
|
filterDataScope = true; |
|
|
|
} |
|
|
|
// 先从redis获取,减少重复查询
|
|
|
|
String redisKey = OptimizeRedisKeys.getUserDeptLevelOptionKey(userId, StringUtils.join(escapeDeptTypeKey(typeKeys), StrConstant.HYPHEN)); |
|
|
|
Object obj = redisUtils.get(redisKey); |
|
|
|
if (null != obj) { |
|
|
|
return (DeptOption) obj; |
|
|
|
} |
|
|
|
// 根据部门类型,二次筛选数据权限部门
|
|
|
|
if (filterDataScope) { |
|
|
|
dataScopeDeptIdList = baseDao.selectListDeptIdByTypeKeyAndScope(dataScopeDeptIdList, typeKeys); |
|
|
|
if (CollUtil.isEmpty(dataScopeDeptIdList)) { |
|
|
|
return new DeptOption(); |
|
|
|
} |
|
|
|
} |
|
|
|
// 组装部门层级结构
|
|
|
|
DeptOption deptOption = packageDeptOptionByUser(dataScopeDeptIdList); |
|
|
|
// 存入redis,超时时长设置为一小时
|
|
|
|
redisUtils.set(redisKey, deptOption, RedisUtils.HOUR_ONE_EXPIRE); |
|
|
|
|
|
|
|
return deptOption; |
|
|
|
} |
|
|
|
|
|
|
|
/** |
|
|
|
* 根据部门数据权限组装部门层级结构 |
|
|
|
* |
|
|
|
* @param dataScopeDeptList |
|
|
|
* @return com.elink.esua.epdc.dto.DeptOption |
|
|
|
* @author work@yujt.net.cn |
|
|
|
* @date 2020/5/26 10:27 |
|
|
|
*/ |
|
|
|
private DeptOption packageDeptOptionByUser(List<Long> dataScopeDeptList) { |
|
|
|
// 通过用户部门权限 获取第一级部门节点
|
|
|
|
List<OptSysDeptEntity> headDepts = baseDao.selectListHeadDeptNode(dataScopeDeptList); |
|
|
|
if (CollUtil.isEmpty(headDepts)) { |
|
|
|
return new DeptOption(); |
|
|
|
} |
|
|
|
List<Long> holdDataScope = dataScopeDeptList.stream().filter(id -> null != id).collect(Collectors.toList()); |
|
|
|
// 某个部门id 声明变量,方便操作数据
|
|
|
|
Long deptId; |
|
|
|
// 取第几级机构
|
|
|
|
int startLevel = NumConstant.ONE_NEG; |
|
|
|
// 用于循环计数
|
|
|
|
int loopIndex = NumConstant.ZERO; |
|
|
|
|
|
|
|
// 存放上级节点的主键,查询下级节点用
|
|
|
|
List<Long> parentDeptIdList = Lists.newArrayList(); |
|
|
|
// 所有父级节点 此处为第一次获取,为顶级节点
|
|
|
|
JSONArray parentNodeArray = new JSONArray(); |
|
|
|
JSONObject node; |
|
|
|
for (int i = 0; i < headDepts.size(); i++) { |
|
|
|
// 父节点主键
|
|
|
|
deptId = headDepts.get(i).getId(); |
|
|
|
if (holdDataScope.contains(deptId)) { |
|
|
|
startLevel = NumConstant.ZERO; |
|
|
|
} |
|
|
|
parentDeptIdList.add(deptId); |
|
|
|
|
|
|
|
node = new JSONObject(); |
|
|
|
node.put("label", headDepts.get(i).getName()); |
|
|
|
node.put("value", String.valueOf(deptId)); |
|
|
|
parentNodeArray.add(node); |
|
|
|
} |
|
|
|
// 用于存放 每次组装好的 某一级节点。
|
|
|
|
List<JSONArray> cache = Lists.newArrayList(); |
|
|
|
cache.add(parentNodeArray); |
|
|
|
Map<String, Object> object; |
|
|
|
while (CollUtil.isNotEmpty(dataScopeDeptList) && CollUtil.isNotEmpty(parentDeptIdList)) { |
|
|
|
|
|
|
|
loopIndex++; |
|
|
|
// 通过上级节点组装所有下级节点
|
|
|
|
object = this.packageChildrenNodeArray(parentNodeArray, dataScopeDeptList, parentDeptIdList); |
|
|
|
parentDeptIdList = (List<Long>) object.get("pids"); |
|
|
|
if (startLevel == NumConstant.ONE_NEG) { |
|
|
|
List<Long> collect = parentDeptIdList.stream().filter(id -> holdDataScope.contains(id)).collect(Collectors.toList()); |
|
|
|
if (CollUtil.isNotEmpty(collect)) { |
|
|
|
startLevel = loopIndex; |
|
|
|
} |
|
|
|
} |
|
|
|
dataScopeDeptList = (List<Long>) object.get("scope"); |
|
|
|
parentNodeArray = (JSONArray) object.get("node"); |
|
|
|
cache.add(parentNodeArray); |
|
|
|
} |
|
|
|
|
|
|
|
DeptOption option = new DeptOption(); |
|
|
|
option.setOptions(cache.get(startLevel)); |
|
|
|
|
|
|
|
return option; |
|
|
|
} |
|
|
|
|
|
|
|
/** |
|
|
|
* 将数组内元素进行一对一替换,用于拼接rediskey时缩短字符串长度 |
|
|
|
* |
|
|
|
* @param typeKeys 一个以上的机构类别关键字 |
|
|
|
* @return java.lang.String[] |
|
|
|
* @author work@yujt.net.cn |
|
|
|
* @date 2020/5/26 10:45 |
|
|
|
*/ |
|
|
|
private String[] escapeDeptTypeKey(String[] typeKeys) { |
|
|
|
String[] escapeTypeKeys = new String[typeKeys.length]; |
|
|
|
for (int i = 0; i < typeKeys.length; i++) { |
|
|
|
String typeKey = typeKeys[i]; |
|
|
|
switch (typeKey) { |
|
|
|
case OrganizationTypeConstant.ORG_TYPE_DISTRICT_DEPT: |
|
|
|
escapeTypeKeys[i] = NumConstant.ZERO_STR; |
|
|
|
break; |
|
|
|
case OrganizationTypeConstant.ORG_TYPE_DISTRICT_PARTY: |
|
|
|
escapeTypeKeys[i] = NumConstant.ONE_STR; |
|
|
|
break; |
|
|
|
case OrganizationTypeConstant.ORG_TYPE_STREET_DEPT: |
|
|
|
escapeTypeKeys[i] = NumConstant.THREE_STR; |
|
|
|
break; |
|
|
|
case OrganizationTypeConstant.ORG_TYPE_STREET_PARTY: |
|
|
|
escapeTypeKeys[i] = NumConstant.FOUR_STR; |
|
|
|
break; |
|
|
|
case OrganizationTypeConstant.ORG_TYPE_COMMUNITY_PARTY: |
|
|
|
escapeTypeKeys[i] = NumConstant.FIVE_STR; |
|
|
|
break; |
|
|
|
case OrganizationTypeConstant.ORG_TYPE_GRID_PARTY: |
|
|
|
escapeTypeKeys[i] = String.valueOf(NumConstant.SIX); |
|
|
|
break; |
|
|
|
case OptimizeConstant.COMPLETE_DEPT_LEVEL_KEY: |
|
|
|
escapeTypeKeys[i] = String.valueOf(NumConstant.ONE_HUNDRED); |
|
|
|
break; |
|
|
|
default: |
|
|
|
throw new RenException("非法的机构类别"); |
|
|
|
} |
|
|
|
} |
|
|
|
return escapeTypeKeys; |
|
|
|
} |
|
|
|
|
|
|
|
/** |
|
|
|
* 组装下级结构节点 |
|
|
|
* |
|
|
|
* @param allParentNode 所有的上级机构节点 |
|
|
|
* @param dataScopeDeptList 拥有数据权限的部门 |
|
|
|
* @param parentDeptIdList 上级部门id |
|
|
|
* @return java.util.Map<java.lang.String, java.lang.Object> |
|
|
|
* @author work@yujt.net.cn |
|
|
|
* @date 2019/11/29 10:27 |
|
|
|
*/ |
|
|
|
private Map<String, Object> packageChildrenNodeArray(JSONArray allParentNode, List<Long> dataScopeDeptList, List<Long> parentDeptIdList) { |
|
|
|
|
|
|
|
List<OptSysDeptEntity> childDepts = baseDao.selectChildrenDeptNode(dataScopeDeptList, parentDeptIdList); |
|
|
|
|
|
|
|
List newParentDeptIdList = Lists.newArrayList(); |
|
|
|
|
|
|
|
// 用于存储所有子节点
|
|
|
|
JSONArray allChildrenNodeList = new JSONArray(); |
|
|
|
// 某个父节点下所有的子节点
|
|
|
|
JSONArray childrenNodeList; |
|
|
|
// 单个 子节点
|
|
|
|
JSONObject nodeChild; |
|
|
|
// 单个 父节点
|
|
|
|
JSONObject nodeParent; |
|
|
|
Long deptId; |
|
|
|
|
|
|
|
for (int i = 0; i < allParentNode.size(); i++) { |
|
|
|
|
|
|
|
nodeParent = allParentNode.getJSONObject(i); |
|
|
|
// 用于存储 一个父节点的所有下级节点
|
|
|
|
childrenNodeList = new JSONArray(); |
|
|
|
|
|
|
|
for (int j = 0; j < childDepts.size(); j++) { |
|
|
|
deptId = childDepts.get(j).getId(); |
|
|
|
|
|
|
|
if (nodeParent.get("value").equals(String.valueOf(childDepts.get(j).getPid()))) { |
|
|
|
nodeChild = new JSONObject(); |
|
|
|
nodeChild.put("label", childDepts.get(j).getName()); |
|
|
|
nodeChild.put("value", String.valueOf(deptId)); |
|
|
|
childrenNodeList.add(nodeChild); |
|
|
|
|
|
|
|
allChildrenNodeList.add(nodeChild); |
|
|
|
newParentDeptIdList.add(deptId); |
|
|
|
} |
|
|
|
} |
|
|
|
if (childrenNodeList.size() > 0) { |
|
|
|
nodeParent.put("children", childrenNodeList); |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
List<Long> newDataScopeList = dataScopeDeptList.stream() |
|
|
|
.filter(did -> !newParentDeptIdList.contains(did)) |
|
|
|
.collect(Collectors.toList()); |
|
|
|
|
|
|
|
Map<String, Object> result = Maps.newHashMap(); |
|
|
|
result.put("node", allChildrenNodeList); |
|
|
|
result.put("scope", newDataScopeList); |
|
|
|
result.put("pids", newParentDeptIdList); |
|
|
|
return result; |
|
|
|
} |
|
|
|
|
|
|
|
/** |
|
|
|
* 组装所有子部门(父部门直属)的层级关系 |
|
|
|
* |
|
|
|
|