|
@@ -1,25 +1,7 @@
|
|
|
-/*
|
|
|
- * Copyright (c) 2018-2028, Chill Zhuang All rights reserved.
|
|
|
- *
|
|
|
- * Redistribution and use in source and binary forms, with or without
|
|
|
- * modification, are permitted provided that the following conditions are met:
|
|
|
- *
|
|
|
- * Redistributions of source code must retain the above copyright notice,
|
|
|
- * this list of conditions and the following disclaimer.
|
|
|
- * Redistributions in binary form must reproduce the above copyright
|
|
|
- * notice, this list of conditions and the following disclaimer in the
|
|
|
- * documentation and/or other materials provided with the distribution.
|
|
|
- * Neither the name of the dreamlu.net developer nor the names of its
|
|
|
- * contributors may be used to endorse or promote products derived from
|
|
|
- * this software without specific prior written permission.
|
|
|
- * Author: Chill 庄骞 (smallchill@163.com)
|
|
|
- */
|
|
|
package org.springblade.system.user.service.impl;
|
|
|
|
|
|
-
|
|
|
-import cn.hutool.crypto.SecureUtil;
|
|
|
-import cn.hutool.crypto.digest.MD5;
|
|
|
-import com.alibaba.nacos.common.utils.MD5Utils;
|
|
|
+import com.alibaba.fastjson.JSON;
|
|
|
+import com.alibaba.fastjson.JSONArray;
|
|
|
import com.alibaba.nacos.common.utils.StringUtils;
|
|
|
import com.baomidou.mybatisplus.core.conditions.Wrapper;
|
|
|
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
|
|
@@ -32,7 +14,6 @@ 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;
|
|
@@ -41,15 +22,17 @@ import org.springblade.core.tool.jackson.JsonUtil;
|
|
|
import org.springblade.core.tool.support.Kv;
|
|
|
import org.springblade.core.tool.utils.*;
|
|
|
import org.springblade.manager.dto.SaveUserInfoByProjectDTO;
|
|
|
+import org.springblade.manager.entity.ContractInfo;
|
|
|
import org.springblade.manager.feign.ContractClient;
|
|
|
-import org.springblade.manager.feign.SaveUserInfoByProjectClient;
|
|
|
+import org.springblade.manager.vo.WbsTreeContractLazyQueryInfoVO;
|
|
|
+import org.springblade.manager.vo.WbsTreeContractLazyVO;
|
|
|
import org.springblade.system.cache.DictCache;
|
|
|
-import org.springblade.system.cache.ParamCache;
|
|
|
import org.springblade.system.cache.SysCache;
|
|
|
import org.springblade.system.entity.Dept;
|
|
|
import org.springblade.system.entity.Tenant;
|
|
|
import org.springblade.system.enums.DictEnum;
|
|
|
import org.springblade.system.feign.ISysClient;
|
|
|
+import org.springblade.system.user.bean.NodeVO;
|
|
|
import org.springblade.system.user.cache.UserCache;
|
|
|
import org.springblade.system.user.dto.UserDTO;
|
|
|
import org.springblade.system.user.entity.*;
|
|
@@ -59,37 +42,47 @@ import org.springblade.system.user.mapper.UserMapper;
|
|
|
import org.springblade.system.user.service.IUserDeptService;
|
|
|
import org.springblade.system.user.service.IUserOauthService;
|
|
|
import org.springblade.system.user.service.IUserService;
|
|
|
-import org.springblade.system.user.vo.UserContractInfoVO;
|
|
|
import org.springblade.system.user.vo.UserVO;
|
|
|
import org.springblade.system.user.wrapper.UserWrapper;
|
|
|
+import org.springframework.beans.factory.annotation.Autowired;
|
|
|
+import org.springframework.data.redis.core.StringRedisTemplate;
|
|
|
import org.springframework.jdbc.core.BeanPropertyRowMapper;
|
|
|
import org.springframework.jdbc.core.JdbcTemplate;
|
|
|
+import org.springframework.scheduling.annotation.Scheduled;
|
|
|
import org.springframework.stereotype.Service;
|
|
|
import org.springframework.transaction.annotation.Transactional;
|
|
|
-import sun.security.rsa.RSASignature;
|
|
|
|
|
|
import java.util.*;
|
|
|
+import java.util.concurrent.ConcurrentHashMap;
|
|
|
+import java.util.concurrent.locks.ReentrantLock;
|
|
|
+import java.util.function.Function;
|
|
|
import java.util.stream.Collectors;
|
|
|
|
|
|
-import static org.springblade.common.constant.CommonConstant.DEFAULT_PARAM_PASSWORD;
|
|
|
-
|
|
|
-/**
|
|
|
- * 服务实现类
|
|
|
- *
|
|
|
- * @author Chill
|
|
|
- */
|
|
|
@Service
|
|
|
@AllArgsConstructor
|
|
|
public class UserServiceImpl extends BaseServiceImpl<UserMapper, User> implements IUserService {
|
|
|
- private static final String GUEST_NAME = "guest";
|
|
|
|
|
|
+ static {
|
|
|
+ /*parallelStream并行流粒度*/
|
|
|
+ System.setProperty("java.util.concurrent.ForkJoinPool.common.parallelism", "6");
|
|
|
+ }
|
|
|
+
|
|
|
+ /*存储当前合同段contractId对应的合同段树*/
|
|
|
+ private final Map<String, List<WbsTreeContractLazyVO>> localCacheNodes = new ConcurrentHashMap<>();
|
|
|
+ /*存储当前合同段contractId_tableOwner对应的资料查询信息*/
|
|
|
+ private final Map<String, List<WbsTreeContractLazyQueryInfoVO>> localCacheQueryInfos = new ConcurrentHashMap<>();
|
|
|
+ /*存储当前合同段contractId_tableOwner对应的节点数量统计缓存信息*/
|
|
|
+ private final Map<String, List<WbsTreeContractLazyVO>> localCacheParentCountNodes = new ConcurrentHashMap<>();
|
|
|
+
|
|
|
+ private static final String GUEST_NAME = "guest";
|
|
|
private final IUserDeptService userDeptService;
|
|
|
private final IUserOauthService userOauthService;
|
|
|
private final ISysClient sysClient;
|
|
|
private final BladeTenantProperties tenantProperties;
|
|
|
private final ContractClient contractClient;
|
|
|
- private final SaveUserInfoByProjectClient saveUserInfoByProjectClient;
|
|
|
private final JdbcTemplate jdbcTemplate;
|
|
|
+ @Autowired
|
|
|
+ StringRedisTemplate redisTemplate;
|
|
|
|
|
|
|
|
|
@Override
|
|
@@ -121,13 +114,13 @@ public class UserServiceImpl extends BaseServiceImpl<UserMapper, User> implement
|
|
|
}
|
|
|
|
|
|
// 内控修改 当为部门负责人不为空时 执行
|
|
|
- if (StringUtil.isNotBlank(user.getIsLeader())){
|
|
|
+ if (StringUtil.isNotBlank(user.getIsLeader())) {
|
|
|
// 由于一个部门只有一个负责人 需要修改 之前的部门负责人
|
|
|
- String [] leader = Func.toStrArray(user.getIsLeader());
|
|
|
- for (String deptId : leader){
|
|
|
- String reData = deptId+",";
|
|
|
- String eqSql = "update blade_user set is_leader = null where is_leader='"+deptId+"' ";
|
|
|
- String fiSql = "update blade_user set is_leader = REPLACE(is_leader,"+reData+",'') where FIND_IN_SET('"+deptId+"',is_leader) ";
|
|
|
+ String[] leader = Func.toStrArray(user.getIsLeader());
|
|
|
+ for (String deptId : leader) {
|
|
|
+ String reData = deptId + ",";
|
|
|
+ String eqSql = "update blade_user set is_leader = null where is_leader='" + deptId + "' ";
|
|
|
+ String fiSql = "update blade_user set is_leader = REPLACE(is_leader," + reData + ",'') where FIND_IN_SET('" + deptId + "',is_leader) ";
|
|
|
jdbcTemplate.execute(eqSql);
|
|
|
jdbcTemplate.execute(fiSql);
|
|
|
}
|
|
@@ -233,13 +226,13 @@ public class UserServiceImpl extends BaseServiceImpl<UserMapper, User> implement
|
|
|
throw new ServiceException(StringUtil.format("当前用户 [{}] 已存在!", user.getAccount()));
|
|
|
}
|
|
|
// 内控修改 当为部门负责人不为空时 执行
|
|
|
- if (StringUtil.isNotBlank(user.getIsLeader())){
|
|
|
+ if (StringUtil.isNotBlank(user.getIsLeader())) {
|
|
|
// 由于一个部门只有一个负责人 需要修改 之前的部门负责人
|
|
|
- String [] leader = Func.toStrArray(user.getIsLeader());
|
|
|
- for (String deptId : leader){
|
|
|
- String reData = deptId+",";
|
|
|
- String eqSql = "update blade_user set is_leader = REPLACE(is_leader,'"+deptId+"','') where FIND_IN_SET('"+deptId+"',is_leader) ";
|
|
|
- String fiSql = "update blade_user set is_leader = REPLACE(is_leader,'"+reData+"','') where FIND_IN_SET('"+deptId+"',is_leader) ";
|
|
|
+ String[] leader = Func.toStrArray(user.getIsLeader());
|
|
|
+ for (String deptId : leader) {
|
|
|
+ String reData = deptId + ",";
|
|
|
+ String eqSql = "update blade_user set is_leader = REPLACE(is_leader,'" + deptId + "','') where FIND_IN_SET('" + deptId + "',is_leader) ";
|
|
|
+ String fiSql = "update blade_user set is_leader = REPLACE(is_leader,'" + reData + "','') where FIND_IN_SET('" + deptId + "',is_leader) ";
|
|
|
jdbcTemplate.execute(fiSql);
|
|
|
jdbcTemplate.execute(eqSql);
|
|
|
}
|
|
@@ -269,9 +262,9 @@ public class UserServiceImpl extends BaseServiceImpl<UserMapper, User> implement
|
|
|
public boolean updateUserInfo(User user) {
|
|
|
|
|
|
// 当为内控是 可以修改密码
|
|
|
- if( StringUtils.isNotEmpty(user.getUserType()) && user.getUserType().equals("5") && StringUtil.isNotBlank(user.getPassword())){
|
|
|
+ if (StringUtils.isNotEmpty(user.getUserType()) && user.getUserType().equals("5") && StringUtil.isNotBlank(user.getPassword())) {
|
|
|
user.setPassword(DigestUtil.encrypt(user.getPassword()));
|
|
|
- }else{
|
|
|
+ } else {
|
|
|
user.setPassword(null);
|
|
|
}
|
|
|
return updateById(user);
|
|
@@ -690,4 +683,612 @@ public class UserServiceImpl extends BaseServiceImpl<UserMapper, User> implement
|
|
|
public List<User> selectUserAll() {
|
|
|
return baseMapper.selectList(Wrappers.<User>query().lambda());
|
|
|
}
|
|
|
+
|
|
|
+ @Override
|
|
|
+ public List<WbsTreeContractLazyVO> lazyQueryContractWbsTree(String id, String contractId, String contractIdRelation, String tableOwner) {
|
|
|
+ if (org.apache.commons.lang.StringUtils.isEmpty(tableOwner)) {
|
|
|
+ throw new ServiceException("tableOwner is not null");
|
|
|
+ }
|
|
|
+ if (cn.hutool.core.util.ObjectUtil.isNotEmpty(contractId)) {
|
|
|
+ ContractInfo contractInfo = jdbcTemplate.query("SELECT contract_name,contract_type FROM m_contract_info WHERE id = " + contractId, new BeanPropertyRowMapper<>(ContractInfo.class)).stream().findAny().orElse(null);
|
|
|
+ if (contractInfo != null) {
|
|
|
+ /*施工合同段*/
|
|
|
+ if (new Integer(1).equals(contractInfo.getContractType())) {
|
|
|
+ //获取当前层懒加载节点
|
|
|
+ String sql = "select p_key_id,contract_id,(SELECT id FROM u_contract_tree_drawings where process_id = p_key_id and is_deleted = 0 limit 1) AS drawingsId,id,parent_id,node_type,type,wbs_type,is_concrete,major_data_type,partition_code,old_id,contract_id_relation,is_concealed_works_node,CASE (SELECT count(1) FROM u_tree_contract_first AS tcf WHERE tcf.is_deleted = 0 AND tcf.wbs_node_id = a.p_key_id) WHEN 0 THEN 'false' ELSE 'true' END AS isFirst,IFNULL(if(length(trim(full_name))>0,full_name,node_name),node_name) AS title,(SELECT CASE WHEN count(1) > 0 THEN 1 ELSE 0 END FROM m_wbs_tree_contract b WHERE b.parent_id = a.id AND b.type = 1 and b.status = 1 AND b.contract_id = " + contractId + " AND b.is_deleted = 0 ) AS hasChildren from m_wbs_tree_contract a where a.node_type != 111 and a.type = 1 and a.status = 1 and a.is_deleted = 0 and parent_id = " + (org.apache.commons.lang.StringUtils.isNotEmpty(id) ? id : 0) + " and contract_id = " + contractId + " ORDER BY a.sort,title,a.create_time";
|
|
|
+ List<WbsTreeContractLazyVO> lazyNodes = jdbcTemplate.query(sql, new BeanPropertyRowMapper<>(WbsTreeContractLazyVO.class));
|
|
|
+ if (lazyNodes.size() > 0) {
|
|
|
+
|
|
|
+ /*根节点直接返回*/
|
|
|
+ if (lazyNodes.stream().anyMatch(f -> f.getParentId().equals(0L))) {
|
|
|
+ for (WbsTreeContractLazyVO lazyNode : lazyNodes) {
|
|
|
+ lazyNode.setSubmitCounts(0);
|
|
|
+ lazyNode.setColorStatus(2);
|
|
|
+ lazyNode.setType(lazyNode.getNodeType());
|
|
|
+ lazyNode.setNotExsitChild(!lazyNode.getHasChildren().equals(1));
|
|
|
+ lazyNode.setPrimaryKeyId(lazyNode.getPKeyId());
|
|
|
+ lazyNode.setTitle(contractInfo.getContractName());
|
|
|
+ }
|
|
|
+ return lazyNodes;
|
|
|
+ }
|
|
|
+
|
|
|
+ //获取本地缓存节点信息
|
|
|
+ List<WbsTreeContractLazyVO> nodesAll = this.getNodeAll(contractId);
|
|
|
+ List<WbsTreeContractLazyVO> distinctNodesAll = nodesAll.stream()
|
|
|
+ .collect(Collectors.collectingAndThen(
|
|
|
+ Collectors.toCollection(() -> new TreeSet<>(Comparator.comparing(WbsTreeContractLazyVO::getPKeyId))),
|
|
|
+ ArrayList::new
|
|
|
+ ));
|
|
|
+
|
|
|
+ //所有最底层节点
|
|
|
+ List<WbsTreeContractLazyVO> distinctLowestNodesAll = distinctNodesAll.stream().filter(f -> f.getHasChildren().equals(0)).collect(Collectors.collectingAndThen(
|
|
|
+ Collectors.toCollection(() -> new TreeSet<>(Comparator.comparing(WbsTreeContractLazyVO::getPKeyId))),
|
|
|
+ ArrayList::new
|
|
|
+ ));
|
|
|
+
|
|
|
+ //获取本地缓存资料信息
|
|
|
+ List<WbsTreeContractLazyQueryInfoVO> queryInfoList = this.getQueryInfoList(contractId, tableOwner);
|
|
|
+
|
|
|
+ Map<Long, Integer> queryInfoMaps = queryInfoList.stream().filter(f -> cn.hutool.core.util.ObjectUtil.isNotEmpty(f.getWbsId()))
|
|
|
+ .collect(Collectors.toMap(WbsTreeContractLazyQueryInfoVO::getWbsId, WbsTreeContractLazyQueryInfoVO::getStatus, (existingValue, newValue) -> existingValue));
|
|
|
+ List<Long> pKeyIdList = new ArrayList<>(queryInfoMaps.keySet());
|
|
|
+
|
|
|
+ /*处理数量*/
|
|
|
+ //填报过的所有最底层节点
|
|
|
+ List<WbsTreeContractLazyVO> lowestNodesTB = distinctLowestNodesAll.parallelStream().filter(f -> pKeyIdList.contains(f.getPKeyId())).collect(Collectors.toList());
|
|
|
+ List<Long> lowestNodeParentIdsTB = lowestNodesTB.parallelStream().map(WbsTreeContractLazyVO::getParentId).collect(Collectors.toList());
|
|
|
+ //获取本地缓存节点数量统计
|
|
|
+ List<WbsTreeContractLazyVO> resultParentNodesTB = this.getCachedParentCountNodes(contractId, lowestNodeParentIdsTB, nodesAll, tableOwner);
|
|
|
+
|
|
|
+ /*List<WbsTreeContractLazyVO> resultParentNodesTB = new ArrayList<>();
|
|
|
+ long startTime1 = System.currentTimeMillis();
|
|
|
+ this.recursiveGetParentNodes(resultParentNodesTB, lowestNodeParentIdsTB, nodesAll);
|
|
|
+ long endTime1 = System.currentTimeMillis();
|
|
|
+ long executionTime1 = endTime1 - startTime1;
|
|
|
+ System.out.println("合同段 " + contractId + " wbs节点树 数量计算 执行时间:" + executionTime1 + " ms");*/
|
|
|
+
|
|
|
+ //最底层节点颜色构造后Map
|
|
|
+ Map<Long, WbsTreeContractLazyVO> lowestNodesMap = lowestNodesTB.stream()
|
|
|
+ .peek(vo -> {
|
|
|
+ Integer colorStatus = queryInfoMaps.get(vo.getPKeyId());
|
|
|
+ if (colorStatus != null) {
|
|
|
+ //任务状态0=未上报=颜色2蓝色、任务状态1=待审批=颜色3橙色、任务状态2=已审批=颜色4绿色、
|
|
|
+ ///*任务状态3=已废除=颜色1黑色*/(2023年10月16日13:59:00 已废除改为=颜色2蓝色)
|
|
|
+ vo.setColorStatus(colorStatus == 0 ? 2 : (colorStatus == 1 ? 3 : (colorStatus == 2 ? 4 : 2)));
|
|
|
+ } else {
|
|
|
+ //未填报的=颜色1黑色
|
|
|
+ vo.setColorStatus(1);
|
|
|
+ }
|
|
|
+ }).collect(Collectors.toMap(WbsTreeContractLazyVO::getPKeyId, Function.identity()));
|
|
|
+
|
|
|
+ /*处理颜色*/
|
|
|
+ long startTime = System.currentTimeMillis();
|
|
|
+ //先将WbsTreeContractLazyVO转为NodeVO
|
|
|
+ List<NodeVO> nodeVOList = distinctNodesAll.stream().map(this::convertToNodeVO).collect(Collectors.toList());
|
|
|
+ //转为Map<Long, NodeVO>
|
|
|
+ Map<Long, NodeVO> nodeVOMap = nodeVOList.stream().collect(Collectors.toMap(NodeVO::getId, vo -> vo, (existing, replacement) -> existing));
|
|
|
+ //把distinctNodesAll把所有节点转为树形结构,再转为List<NodeVO>对象
|
|
|
+ List<NodeVO> treeNodeVOList = this.buildNodeTreeByStream(distinctNodesAll, lowestNodesMap);
|
|
|
+ //处理节点颜色
|
|
|
+ NodeVO.calculateStatusToDFS(treeNodeVOList, nodeVOMap);
|
|
|
+ //把树形结构转为普通List集合
|
|
|
+ List<NodeVO> nodeVOS = this.flattenTree(treeNodeVOList);
|
|
|
+ //获取所有节点颜色Map
|
|
|
+ Map<Long, Integer> nodeColorStatusMap = nodeVOS.stream().collect(Collectors.toMap(NodeVO::getPKeyId, NodeVO::getStatus, (existing, replacement) -> existing));
|
|
|
+ long endTime = System.currentTimeMillis();
|
|
|
+ long executionTime = endTime - startTime;
|
|
|
+ System.out.println("合同段 " + contractId + " 处理颜色 执行时间:" + executionTime + " ms");
|
|
|
+
|
|
|
+ /*处理最终结果集*/
|
|
|
+ if (lazyNodes.size() > 0) {
|
|
|
+ //处理填报数量
|
|
|
+ Map<Long, Integer> countMap = new HashMap<>();
|
|
|
+ for (WbsTreeContractLazyVO node : resultParentNodesTB) {
|
|
|
+ Long key = node.getPKeyId();
|
|
|
+ if (countMap.containsKey(key)) {
|
|
|
+ countMap.put(key, countMap.get(key) + 1);
|
|
|
+ } else {
|
|
|
+ countMap.put(key, 1);
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
+ //返回最终结果集
|
|
|
+ for (WbsTreeContractLazyVO lazyNodeVO : lazyNodes) {
|
|
|
+ lazyNodeVO.setType(lazyNodeVO.getNodeType()); //前端显示需要一样的,所以修改成一样的
|
|
|
+ lazyNodeVO.setNotExsitChild(!lazyNodeVO.getHasChildren().equals(1));
|
|
|
+ lazyNodeVO.setPrimaryKeyId(lazyNodeVO.getPKeyId());
|
|
|
+ if (lazyNodeVO.getParentId() == 0L) {
|
|
|
+ if (cn.hutool.core.util.ObjectUtil.isNotEmpty(contractInfo.getContractName())) {
|
|
|
+ lazyNodeVO.setTitle(contractInfo.getContractName());
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
+ //设置数量
|
|
|
+ lazyNodeVO.setSubmitCounts(cn.hutool.core.util.ObjectUtil.isNotEmpty(countMap.get(lazyNodeVO.getPKeyId())) ? countMap.get(lazyNodeVO.getPKeyId()) : (cn.hutool.core.util.ObjectUtil.isNotEmpty(queryInfoMaps.get(lazyNodeVO.getPKeyId())) ? 1 : 0));
|
|
|
+
|
|
|
+ //设置颜色
|
|
|
+ if (lazyNodeVO.getSubmitCounts().equals(0)) {
|
|
|
+ lazyNodeVO.setColorStatus(1);
|
|
|
+ continue;
|
|
|
+ }
|
|
|
+
|
|
|
+ Integer parentColorStatus = nodeColorStatusMap.get(lazyNodeVO.getPKeyId());
|
|
|
+ if (parentColorStatus != null) {
|
|
|
+ lazyNodeVO.setColorStatus(parentColorStatus);
|
|
|
+ } else {
|
|
|
+ WbsTreeContractLazyVO lowestNode = lowestNodesMap.get(lazyNodeVO.getPKeyId());
|
|
|
+ if (lowestNode != null) {
|
|
|
+ lazyNodeVO.setColorStatus(lowestNode.getColorStatus());
|
|
|
+ }
|
|
|
+ }
|
|
|
+ }
|
|
|
+ }
|
|
|
+ return lazyNodes;
|
|
|
+ }
|
|
|
+
|
|
|
+ /*监理、业主合同段*/
|
|
|
+ } else if (new Integer("2").equals(contractInfo.getContractType()) || new Integer("3").equals(contractInfo.getContractType())) {
|
|
|
+ List<WbsTreeContractLazyVO> lazyNodesAll = new ArrayList<>();
|
|
|
+ List<String> contractIds = new ArrayList<>();
|
|
|
+ if (cn.hutool.core.util.ObjectUtil.isNotEmpty(contractIdRelation) && cn.hutool.core.util.ObjectUtil.isNotEmpty(id)) {
|
|
|
+ //非根节点时选择加载施工合同段的树
|
|
|
+ contractIds.add(contractIdRelation);
|
|
|
+ } else {
|
|
|
+ //根节点时默认加载所有施工合同段的树
|
|
|
+ contractIds = this.contractClient.getProcessContractByJLContractId(contractId);
|
|
|
+ }
|
|
|
+ if (cn.hutool.core.util.ObjectUtil.isEmpty(contractIds) || contractIds.size() <= 0) {
|
|
|
+ return null;
|
|
|
+ }
|
|
|
+ for (String sgContractId : contractIds) {
|
|
|
+ ContractInfo sgContractInfo = jdbcTemplate.query("select contract_name from m_contract_info where id = " + sgContractId, new BeanPropertyRowMapper<>(ContractInfo.class)).stream().findAny().orElse(null);
|
|
|
+ if (sgContractInfo != null) {
|
|
|
+ List<WbsTreeContractLazyVO> lazyNodes = jdbcTemplate.query("select p_key_id,contract_id,(SELECT id FROM u_contract_tree_drawings where process_id = p_key_id and is_deleted = 0 limit 1) AS drawingsId,id,parent_id,node_type,type,wbs_type,major_data_type,partition_code,old_id,contract_id_relation,is_concealed_works_node,CASE (SELECT count(1) FROM u_tree_contract_first AS tcf WHERE tcf.is_deleted = 0 AND tcf.wbs_node_id = a.p_key_id) WHEN 0 THEN 'false' ELSE 'true' END AS isFirst,IFNULL(if(length(trim(full_name))>0,full_name,node_name),node_name) AS title,(SELECT CASE WHEN count(1) > 0 THEN 1 ELSE 0 END FROM m_wbs_tree_contract b WHERE b.parent_id = a.id AND b.type = 1 and b.status = 1 AND b.contract_id = " + sgContractId + " AND b.is_deleted = 0 ) AS hasChildren from m_wbs_tree_contract a where a.node_type != 111 and a.type = 1 and a.status = 1 and a.is_deleted = 0 and parent_id = " + (org.apache.commons.lang.StringUtils.isNotEmpty(id) ? id : 0) + " and contract_id = " + sgContractId + " ORDER BY a.sort,title,a.create_time", new BeanPropertyRowMapper<>(WbsTreeContractLazyVO.class));
|
|
|
+ if (lazyNodes.size() > 0) {
|
|
|
+
|
|
|
+ if (lazyNodes.stream().anyMatch(f -> f.getParentId().equals(0L))) {
|
|
|
+ for (WbsTreeContractLazyVO lazyNode : lazyNodes) {
|
|
|
+ lazyNode.setSubmitCounts(0);
|
|
|
+ lazyNode.setColorStatus(2);
|
|
|
+ lazyNode.setType(lazyNode.getNodeType());
|
|
|
+ lazyNode.setNotExsitChild(!lazyNode.getHasChildren().equals(1));
|
|
|
+ lazyNode.setPrimaryKeyId(lazyNode.getPKeyId());
|
|
|
+ lazyNode.setContractIdRelation(sgContractId);
|
|
|
+ lazyNode.setTitle(sgContractInfo.getContractName());
|
|
|
+ }
|
|
|
+ return lazyNodes;
|
|
|
+ }
|
|
|
+
|
|
|
+ List<WbsTreeContractLazyVO> nodesAll = this.getNodeAll(sgContractId);
|
|
|
+ List<WbsTreeContractLazyVO> distinctNodesAll = nodesAll.stream()
|
|
|
+ .collect(Collectors.collectingAndThen(
|
|
|
+ Collectors.toCollection(() -> new TreeSet<>(Comparator.comparing(WbsTreeContractLazyVO::getPKeyId))),
|
|
|
+ ArrayList::new
|
|
|
+ ));
|
|
|
+ List<WbsTreeContractLazyVO> distinctLowestNodesAll = distinctNodesAll.stream().filter(f -> f.getHasChildren().equals(0)).collect(Collectors.collectingAndThen(
|
|
|
+ Collectors.toCollection(() -> new TreeSet<>(Comparator.comparing(WbsTreeContractLazyVO::getPKeyId))),
|
|
|
+ ArrayList::new
|
|
|
+ ));
|
|
|
+
|
|
|
+ List<WbsTreeContractLazyQueryInfoVO> queryInfoList = this.getQueryInfoList(sgContractId, tableOwner);
|
|
|
+
|
|
|
+ Map<Long, Integer> queryInfoMaps = queryInfoList.stream().filter(f -> cn.hutool.core.util.ObjectUtil.isNotEmpty(f.getWbsId()))
|
|
|
+ .collect(Collectors.toMap(WbsTreeContractLazyQueryInfoVO::getWbsId, WbsTreeContractLazyQueryInfoVO::getStatus, (existingValue, newValue) -> existingValue));
|
|
|
+ List<Long> pKeyIdList = new ArrayList<>(queryInfoMaps.keySet());
|
|
|
+
|
|
|
+ List<WbsTreeContractLazyVO> lowestNodesTB = distinctLowestNodesAll.parallelStream().filter(f -> pKeyIdList.contains(f.getPKeyId())).collect(Collectors.toList());
|
|
|
+ List<Long> lowestNodeParentIdsTB = lowestNodesTB.parallelStream().map(WbsTreeContractLazyVO::getParentId).collect(Collectors.toList());
|
|
|
+
|
|
|
+ List<WbsTreeContractLazyVO> resultParentNodesTB = this.getCachedParentCountNodes(sgContractId, lowestNodeParentIdsTB, nodesAll, tableOwner);
|
|
|
+
|
|
|
+ Map<Long, WbsTreeContractLazyVO> lowestNodesMap = lowestNodesTB.stream()
|
|
|
+ .peek(vo -> {
|
|
|
+ Integer colorStatus = queryInfoMaps.get(vo.getPKeyId());
|
|
|
+ if (colorStatus != null) {
|
|
|
+ vo.setColorStatus(colorStatus == 0 ? 2 : (colorStatus == 1 ? 3 : (colorStatus == 2 ? 4 : 2)));
|
|
|
+ } else {
|
|
|
+ vo.setColorStatus(1);
|
|
|
+ }
|
|
|
+ }).collect(Collectors.toMap(WbsTreeContractLazyVO::getPKeyId, Function.identity()));
|
|
|
+
|
|
|
+ List<NodeVO> nodeVOList = distinctNodesAll.stream().map(this::convertToNodeVO).collect(Collectors.toList());
|
|
|
+ Map<Long, NodeVO> nodeVOMap = nodeVOList.stream().collect(Collectors.toMap(NodeVO::getId, vo -> vo, (existing, replacement) -> existing));
|
|
|
+ List<NodeVO> treeNodeVOList = this.buildNodeTreeByStream(distinctNodesAll, lowestNodesMap);
|
|
|
+ NodeVO.calculateStatusToDFS(treeNodeVOList, nodeVOMap);
|
|
|
+ List<NodeVO> nodeVOS = this.flattenTree(treeNodeVOList);
|
|
|
+ Map<Long, Integer> nodeColorStatusMap = nodeVOS.stream().collect(Collectors.toMap(NodeVO::getPKeyId, NodeVO::getStatus, (existing, replacement) -> existing));
|
|
|
+
|
|
|
+ if (lazyNodes.size() > 0) {
|
|
|
+ Map<Long, Integer> countMap = new HashMap<>();
|
|
|
+ for (WbsTreeContractLazyVO node : resultParentNodesTB) {
|
|
|
+ Long key = node.getPKeyId();
|
|
|
+ if (countMap.containsKey(key)) {
|
|
|
+ countMap.put(key, countMap.get(key) + 1);
|
|
|
+ } else {
|
|
|
+ countMap.put(key, 1);
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
+ for (WbsTreeContractLazyVO lazyNodeVO : lazyNodes) {
|
|
|
+ lazyNodeVO.setType(lazyNodeVO.getNodeType());
|
|
|
+ lazyNodeVO.setNotExsitChild(!lazyNodeVO.getHasChildren().equals(1));
|
|
|
+ lazyNodeVO.setPrimaryKeyId(lazyNodeVO.getPKeyId());
|
|
|
+ lazyNodeVO.setContractIdRelation(sgContractId);
|
|
|
+ if (lazyNodeVO.getParentId() == 0L) {
|
|
|
+ if (cn.hutool.core.util.ObjectUtil.isNotEmpty(sgContractInfo.getContractName())) {
|
|
|
+ lazyNodeVO.setTitle(sgContractInfo.getContractName());
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
+ lazyNodeVO.setSubmitCounts(cn.hutool.core.util.ObjectUtil.isNotEmpty(countMap.get(lazyNodeVO.getPKeyId())) ? countMap.get(lazyNodeVO.getPKeyId()) : (cn.hutool.core.util.ObjectUtil.isNotEmpty(queryInfoMaps.get(lazyNodeVO.getPKeyId())) ? 1 : 0));
|
|
|
+ if (lazyNodeVO.getSubmitCounts().equals(0)) {
|
|
|
+ lazyNodeVO.setColorStatus(1);
|
|
|
+ continue;
|
|
|
+ }
|
|
|
+
|
|
|
+ Integer parentColorStatus = nodeColorStatusMap.get(lazyNodeVO.getPKeyId());
|
|
|
+ if (parentColorStatus != null) {
|
|
|
+ lazyNodeVO.setColorStatus(parentColorStatus);
|
|
|
+ } else {
|
|
|
+ WbsTreeContractLazyVO lowestNode = lowestNodesMap.get(lazyNodeVO.getPKeyId());
|
|
|
+ if (lowestNode != null) {
|
|
|
+ lazyNodeVO.setColorStatus(lowestNode.getColorStatus());
|
|
|
+ }
|
|
|
+ }
|
|
|
+ }
|
|
|
+ }
|
|
|
+ lazyNodesAll.addAll(lazyNodes);
|
|
|
+ }
|
|
|
+ }
|
|
|
+ }
|
|
|
+ return lazyNodesAll;
|
|
|
+ }
|
|
|
+ }
|
|
|
+ }
|
|
|
+ return null;
|
|
|
+ }
|
|
|
+
|
|
|
+ /*非批量电签时,清理缓存,如资料填报保存、任务上报等*/
|
|
|
+ @Override
|
|
|
+ public void deleteContractLocalCache(String contractId) {
|
|
|
+ /*删除节点缓存*/
|
|
|
+ localCacheNodes.remove(contractId);
|
|
|
+
|
|
|
+ /*删除资料缓存*/
|
|
|
+ Iterator<Map.Entry<String, List<WbsTreeContractLazyQueryInfoVO>>> iterator_1 = localCacheQueryInfos.entrySet().iterator();
|
|
|
+ while (iterator_1.hasNext()) {
|
|
|
+ Map.Entry<String, List<WbsTreeContractLazyQueryInfoVO>> entry = iterator_1.next();
|
|
|
+ String cacheKey = entry.getKey();
|
|
|
+ if (cacheKey.startsWith(contractId + "_")) {
|
|
|
+ iterator_1.remove();
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
+ /*删除节点计算统计缓存*/
|
|
|
+ Iterator<Map.Entry<String, List<WbsTreeContractLazyVO>>> iterator_2 = localCacheParentCountNodes.entrySet().iterator();
|
|
|
+ while (iterator_2.hasNext()) {
|
|
|
+ Map.Entry<String, List<WbsTreeContractLazyVO>> entry = iterator_2.next();
|
|
|
+ String cacheKey = entry.getKey();
|
|
|
+ if (cacheKey.startsWith(contractId + "_")) {
|
|
|
+ iterator_2.remove();
|
|
|
+ }
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
+ /*定时清理缓存(本地+Redis)信息,不在批量电签时删除,批量电签是多线程,会一直删除,导致缓存基本不生效*/
|
|
|
+ @Scheduled(fixedRate = 120000) //每2分钟执行一次
|
|
|
+ public void clearContractLocalCacheAndRedisCache() {
|
|
|
+ //获取锁
|
|
|
+ ReentrantLock lock = new ReentrantLock();
|
|
|
+ lock.lock();
|
|
|
+ try {
|
|
|
+ //清除本地缓存
|
|
|
+ localCacheNodes.clear();
|
|
|
+ localCacheQueryInfos.clear();
|
|
|
+ localCacheParentCountNodes.clear();
|
|
|
+
|
|
|
+ //清除RedisWbs树节点缓存
|
|
|
+ Set<String> keysByNodes = redisTemplate.keys("blade-manager::contract:wbstree:*");
|
|
|
+ if (keysByNodes != null) {
|
|
|
+ redisTemplate.delete(keysByNodes);
|
|
|
+ }
|
|
|
+ } finally {
|
|
|
+ //释放锁
|
|
|
+ lock.unlock();
|
|
|
+ System.out.println("定时执行任务:{clearContractLocalCacheAndRedisCache} 完成 ... ");
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
+ /**
|
|
|
+ * 获取当前合同段所有节点缓存
|
|
|
+ *
|
|
|
+ * @param contractId
|
|
|
+ * @return
|
|
|
+ */
|
|
|
+ public List<WbsTreeContractLazyVO> getNodeAll(String contractId) {
|
|
|
+ //获取本地缓存
|
|
|
+ List<WbsTreeContractLazyVO> nodesAll = localCacheNodes.get(contractId);
|
|
|
+
|
|
|
+ if (nodesAll == null || nodesAll.isEmpty()) {
|
|
|
+ //从Redis获取数据
|
|
|
+ Object data = redisTemplate.opsForValue().get("blade-manager::contract:wbstree:" + contractId);
|
|
|
+ if (data != null) {
|
|
|
+ nodesAll = JSON.parseArray(data.toString(), WbsTreeContractLazyVO.class);
|
|
|
+ //更新本地缓存
|
|
|
+ localCacheNodes.put(contractId, nodesAll);
|
|
|
+ } else {
|
|
|
+ //返回数据库数据
|
|
|
+ long startTime = System.currentTimeMillis();
|
|
|
+
|
|
|
+ /*分页查询,每次5000条*/
|
|
|
+ int pageSize = 5000;
|
|
|
+ int pageNumber = 1;
|
|
|
+ int offset;
|
|
|
+
|
|
|
+ nodesAll = new ArrayList<>();
|
|
|
+ List<WbsTreeContractLazyVO> nodesAllPage;
|
|
|
+ do {
|
|
|
+ offset = (pageNumber - 1) * pageSize;
|
|
|
+ nodesAllPage = jdbcTemplate.query(
|
|
|
+ "SELECT p_key_id, id, parent_id FROM m_wbs_tree_contract " +
|
|
|
+ "WHERE type = 1 " +
|
|
|
+ "AND status = 1 " +
|
|
|
+ "AND is_deleted = 0 " +
|
|
|
+ "AND contract_id = ? " +
|
|
|
+ "LIMIT ? OFFSET ?",
|
|
|
+ new Object[]{contractId, pageSize, offset},
|
|
|
+ new BeanPropertyRowMapper<>(WbsTreeContractLazyVO.class)
|
|
|
+ );
|
|
|
+ nodesAll.addAll(nodesAllPage);
|
|
|
+ pageNumber++;
|
|
|
+ } while (nodesAllPage.size() == pageSize);
|
|
|
+
|
|
|
+ long endTime = System.currentTimeMillis();
|
|
|
+ long executionTime = endTime - startTime;
|
|
|
+ System.out.println("合同段 " + contractId + " 查询所有wbs节点树 执行时间:" + executionTime + " ms");
|
|
|
+
|
|
|
+ if (nodesAll.size() > 0) {
|
|
|
+ //判断是否有子级,赋值
|
|
|
+ Map<Long, List<WbsTreeContractLazyVO>> groupedByParentId = nodesAll.stream().collect(Collectors.groupingBy(WbsTreeContractLazyVO::getParentId));
|
|
|
+ for (WbsTreeContractLazyVO vo : nodesAll) {
|
|
|
+ if (vo.getParentId() == 0) {
|
|
|
+ vo.setHasChildren(1);
|
|
|
+ }
|
|
|
+ List<WbsTreeContractLazyVO> childNodes = groupedByParentId.getOrDefault(vo.getId(), null);
|
|
|
+ if (childNodes != null && childNodes.size() > 0) {
|
|
|
+ vo.setHasChildren(1);
|
|
|
+ } else {
|
|
|
+ vo.setHasChildren(0);
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
+ //存储到Redis中
|
|
|
+ JSONArray array = JSONArray.parseArray(JSON.toJSONString(nodesAll));
|
|
|
+ redisTemplate.opsForValue().set("blade-manager::contract:wbstree:" + contractId, JSON.toJSON(array).toString());
|
|
|
+
|
|
|
+ //更新本地缓存
|
|
|
+ localCacheNodes.put(contractId, nodesAll);
|
|
|
+ }
|
|
|
+ }
|
|
|
+ }
|
|
|
+ return nodesAll;
|
|
|
+ }
|
|
|
+
|
|
|
+ /**
|
|
|
+ * 获取节点数量统计缓存
|
|
|
+ *
|
|
|
+ * @param contractId
|
|
|
+ * @param lowestNodeParentIdsTB
|
|
|
+ * @param nodesAll
|
|
|
+ * @return
|
|
|
+ */
|
|
|
+ public List<WbsTreeContractLazyVO> getCachedParentCountNodes(String contractId, List<Long> lowestNodeParentIdsTB, List<WbsTreeContractLazyVO> nodesAll, String tableOwner) {
|
|
|
+ //从本地缓存获取数据
|
|
|
+ String cacheKey = contractId + "_" + tableOwner;
|
|
|
+ List<WbsTreeContractLazyVO> resultParentNodesTB = localCacheParentCountNodes.get(cacheKey);
|
|
|
+
|
|
|
+ if (resultParentNodesTB == null || resultParentNodesTB.isEmpty()) {
|
|
|
+
|
|
|
+ //从Redis获取数据
|
|
|
+ Object data = redisTemplate.opsForValue().get("blade-manager::contract:wbstree:byParentCountNodes:" + cacheKey);
|
|
|
+ if (data != null) {
|
|
|
+ resultParentNodesTB = JSON.parseArray(data.toString(), WbsTreeContractLazyVO.class);
|
|
|
+ //更新本地缓存
|
|
|
+ localCacheParentCountNodes.put(cacheKey, resultParentNodesTB);
|
|
|
+
|
|
|
+ } else {
|
|
|
+ /*重新计算,进行递归获取父节点计数统计*/
|
|
|
+ resultParentNodesTB = new ArrayList<>();
|
|
|
+ long startTime = System.currentTimeMillis();
|
|
|
+
|
|
|
+ this.recursiveGetParentNodes(resultParentNodesTB, lowestNodeParentIdsTB, nodesAll);
|
|
|
+
|
|
|
+ long endTime = System.currentTimeMillis();
|
|
|
+ long executionTime = endTime - startTime;
|
|
|
+ System.out.println("合同段 " + contractId + " wbs节点树 数量计算 执行时间:" + executionTime + " ms");
|
|
|
+
|
|
|
+ if (resultParentNodesTB.size() > 0) {
|
|
|
+ //存储到Redis中
|
|
|
+ JSONArray array = JSONArray.parseArray(JSON.toJSONString(resultParentNodesTB));
|
|
|
+ redisTemplate.opsForValue().set("blade-manager::contract:wbstree:byParentCountNodes:" + cacheKey, JSON.toJSON(array).toString());
|
|
|
+
|
|
|
+ //更新本地缓存
|
|
|
+ localCacheParentCountNodes.put(cacheKey, resultParentNodesTB);
|
|
|
+ }
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
+ return resultParentNodesTB;
|
|
|
+ }
|
|
|
+
|
|
|
+ /**
|
|
|
+ * 构造从最底层节点获取他的所有父级,并统计出现次数(父级Id=子级parentId)
|
|
|
+ *
|
|
|
+ * @param result 结果集
|
|
|
+ * @param lowestNodeParentIds 最底层节点ParentIds
|
|
|
+ * @param nodesAll 所有节点
|
|
|
+ */
|
|
|
+ public void recursiveGetParentNodes(List<WbsTreeContractLazyVO> result, List<Long> lowestNodeParentIds, List<WbsTreeContractLazyVO> nodesAll) {
|
|
|
+ if (lowestNodeParentIds.isEmpty()) {
|
|
|
+ return;
|
|
|
+ }
|
|
|
+
|
|
|
+ Map<Long, Long> parentIdGroup = lowestNodeParentIds.stream()
|
|
|
+ .collect(Collectors.groupingByConcurrent(Function.identity(), Collectors.counting()));
|
|
|
+
|
|
|
+ List<WbsTreeContractLazyVO> collectedNodes = parentIdGroup.entrySet().parallelStream()
|
|
|
+ .flatMap(entry -> {
|
|
|
+ List<WbsTreeContractLazyVO> nodes = nodesAll.stream()
|
|
|
+ .filter(f -> entry.getKey().equals(f.getId()))
|
|
|
+ .collect(Collectors.toList());
|
|
|
+
|
|
|
+ if (entry.getValue() > 1L) {
|
|
|
+ nodes = nodes.stream().limit(1)
|
|
|
+ .flatMap(node -> Collections.nCopies(entry.getValue().intValue(), node).stream())
|
|
|
+ .collect(Collectors.toList());
|
|
|
+ }
|
|
|
+
|
|
|
+ return nodes.stream();
|
|
|
+ })
|
|
|
+ .collect(Collectors.toList());
|
|
|
+
|
|
|
+ List<Long> collect = collectedNodes.stream()
|
|
|
+ .map(WbsTreeContractLazyVO::getParentId)
|
|
|
+ .collect(Collectors.toList());
|
|
|
+
|
|
|
+ if (!collect.isEmpty()) {
|
|
|
+ result.addAll(collectedNodes);
|
|
|
+ this.recursiveGetParentNodes(result, collect, nodesAll);
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
+ /**
|
|
|
+ * 获取当前合同段所有填报资料缓存信息
|
|
|
+ *
|
|
|
+ * @param contractId
|
|
|
+ * @param tableOwner
|
|
|
+ * @return
|
|
|
+ */
|
|
|
+ public List<WbsTreeContractLazyQueryInfoVO> getQueryInfoList(String contractId, String tableOwner) {
|
|
|
+ //从本地缓存获取
|
|
|
+ String cacheKey = contractId + "_" + tableOwner;
|
|
|
+ List<WbsTreeContractLazyQueryInfoVO> cachedQueryInfoList = localCacheQueryInfos.get(cacheKey);
|
|
|
+
|
|
|
+ if (cachedQueryInfoList != null && !cachedQueryInfoList.isEmpty()) {
|
|
|
+ return cachedQueryInfoList;
|
|
|
+ }
|
|
|
+
|
|
|
+ //从Redis获取数据
|
|
|
+ Object dataInformationQuery = redisTemplate.opsForValue().get("blade-manager::contract:wbstree:byInformationQuery:" + cacheKey);
|
|
|
+
|
|
|
+ List<WbsTreeContractLazyQueryInfoVO> queryInfoList = new ArrayList<>();
|
|
|
+ if (dataInformationQuery != null) {
|
|
|
+ queryInfoList = JSON.parseArray(dataInformationQuery.toString(), WbsTreeContractLazyQueryInfoVO.class);
|
|
|
+ //更新本地缓存
|
|
|
+ localCacheQueryInfos.put(cacheKey, queryInfoList);
|
|
|
+
|
|
|
+ } else {
|
|
|
+ //返回数据库数据
|
|
|
+ long startTime = System.currentTimeMillis();
|
|
|
+
|
|
|
+ /*分页查询,每次5000条*/
|
|
|
+ int pageSize = 5000;
|
|
|
+ int pageNumber = 1;
|
|
|
+ int offset;
|
|
|
+
|
|
|
+ List<WbsTreeContractLazyQueryInfoVO> queryInfoListPage;
|
|
|
+
|
|
|
+ do {
|
|
|
+ offset = (pageNumber - 1) * pageSize;
|
|
|
+ queryInfoListPage = jdbcTemplate.query(
|
|
|
+ "SELECT wbs_id, status FROM u_information_query " +
|
|
|
+ "WHERE type = 1 " +
|
|
|
+ "AND contract_id = ? " +
|
|
|
+ "AND classify = ? " +
|
|
|
+ "LIMIT ? OFFSET ?",
|
|
|
+ new Object[]{contractId, tableOwner, pageSize, offset},
|
|
|
+ new BeanPropertyRowMapper<>(WbsTreeContractLazyQueryInfoVO.class));
|
|
|
+ queryInfoList.addAll(queryInfoListPage);
|
|
|
+ pageNumber++;
|
|
|
+ } while (queryInfoListPage.size() == pageSize);
|
|
|
+
|
|
|
+ long endTime = System.currentTimeMillis();
|
|
|
+ long executionTime = endTime - startTime;
|
|
|
+ System.out.println("合同段 " + contractId + " 查询所有资料信息 执行时间:" + executionTime + " ms");
|
|
|
+
|
|
|
+ if (queryInfoList.size() > 0) {
|
|
|
+ JSONArray array = JSONArray.parseArray(JSON.toJSONString(queryInfoList));
|
|
|
+
|
|
|
+ //存储到Redis中
|
|
|
+ redisTemplate.opsForValue().set("blade-manager::contract:wbstree:byInformationQuery:" + cacheKey, JSON.toJSON(array).toString());
|
|
|
+
|
|
|
+ //更新本地缓存
|
|
|
+ localCacheQueryInfos.put(cacheKey, queryInfoList);
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
+ return queryInfoList;
|
|
|
+ }
|
|
|
+
|
|
|
+ //转换VO
|
|
|
+ public NodeVO convertToNodeVO(WbsTreeContractLazyVO wbsTreeContractLazyVO) {
|
|
|
+ NodeVO nodeVO = new NodeVO();
|
|
|
+ nodeVO.setId(wbsTreeContractLazyVO.getId());
|
|
|
+ nodeVO.setParentId(wbsTreeContractLazyVO.getParentId());
|
|
|
+ nodeVO.setPKeyId(wbsTreeContractLazyVO.getPKeyId());
|
|
|
+ nodeVO.setStatus(cn.hutool.core.util.ObjectUtil.isNotEmpty(wbsTreeContractLazyVO.getColorStatus()) ? wbsTreeContractLazyVO.getColorStatus() : 1);
|
|
|
+ return nodeVO;
|
|
|
+ }
|
|
|
+
|
|
|
+ /**
|
|
|
+ * 构造树形结构数据 (解决节点颜色问题)
|
|
|
+ *
|
|
|
+ * @param distinctNodesAll 去重后所有节点数据
|
|
|
+ * @return
|
|
|
+ */
|
|
|
+ public List<NodeVO> buildNodeTreeByStream(List<WbsTreeContractLazyVO> distinctNodesAll,
|
|
|
+ Map<Long, WbsTreeContractLazyVO> lowestNodesMap) {
|
|
|
+ List<WbsTreeContractLazyVO> list = distinctNodesAll.stream().filter(f -> f.getParentId().equals(0L)).collect(Collectors.toList());
|
|
|
+ Map<Long, List<WbsTreeContractLazyVO>> map = distinctNodesAll.stream().collect(Collectors.groupingBy(WbsTreeContractLazyVO::getParentId));
|
|
|
+ return recursionFnNodeTree(list, map, lowestNodesMap);
|
|
|
+ }
|
|
|
+
|
|
|
+ public List<NodeVO> recursionFnNodeTree(List<WbsTreeContractLazyVO> list, Map<Long, List<WbsTreeContractLazyVO>> map,
|
|
|
+ Map<Long, WbsTreeContractLazyVO> lowestNodesMap) {
|
|
|
+ List<NodeVO> result = new ArrayList<>();
|
|
|
+ for (WbsTreeContractLazyVO vo : list) {
|
|
|
+ if (vo.getHasChildren().equals(0)) {
|
|
|
+ WbsTreeContractLazyVO lowestNodeVO = lowestNodesMap.getOrDefault(vo.getPKeyId(), null);
|
|
|
+ if (lowestNodeVO != null && cn.hutool.core.util.ObjectUtil.isNotEmpty(lowestNodeVO.getColorStatus())) {
|
|
|
+ //最底层颜色初始化
|
|
|
+ vo.setColorStatus(lowestNodeVO.getColorStatus());
|
|
|
+ }
|
|
|
+ } else {
|
|
|
+ //非最底层节点,颜色默认=1黑色
|
|
|
+ vo.setColorStatus(1);
|
|
|
+ }
|
|
|
+ //转换为NodeVO
|
|
|
+ NodeVO nodeVO = convertToNodeVO(vo);
|
|
|
+ List<WbsTreeContractLazyVO> childrenList = map.get(vo.getId());
|
|
|
+ if (childrenList != null && !childrenList.isEmpty()) {
|
|
|
+ nodeVO.setChildren(recursionFnNodeTree(childrenList, map, lowestNodesMap));
|
|
|
+ }
|
|
|
+ result.add(nodeVO);
|
|
|
+ }
|
|
|
+ return result;
|
|
|
+ }
|
|
|
+
|
|
|
+ //把树形结构转为普通List
|
|
|
+ public List<NodeVO> flattenTree(List<NodeVO> tree) {
|
|
|
+ List<NodeVO> result = new ArrayList<>();
|
|
|
+ for (NodeVO node : tree) {
|
|
|
+ result.add(node);
|
|
|
+ if (node.getChildren() != null && !node.getChildren().isEmpty()) {
|
|
|
+ result.addAll(flattenTree(node.getChildren()));
|
|
|
+ node.setChildren(null);
|
|
|
+ }
|
|
|
+ }
|
|
|
+ return result;
|
|
|
+ }
|
|
|
+
|
|
|
}
|