Browse Source

Merge remote-tracking branch 'origin/master' into master

yangyj 2 years ago
parent
commit
9c73a38b14

+ 14 - 0
blade-service-api/blade-manager-api/src/main/java/org/springblade/manager/vo/WbsTreeContractLazyQueryInfoVO.java

@@ -0,0 +1,14 @@
+package org.springblade.manager.vo;
+
+import lombok.Data;
+
+import java.io.Serializable;
+
+@Data
+public class WbsTreeContractLazyQueryInfoVO implements Serializable {
+
+    private Long wbsId;
+
+    private Integer status;
+
+}

+ 70 - 0
blade-service-api/blade-manager-api/src/main/java/org/springblade/manager/vo/WbsTreeContractLazyVO.java

@@ -0,0 +1,70 @@
+package org.springblade.manager.vo;
+
+import com.fasterxml.jackson.annotation.JsonProperty;
+import io.swagger.annotations.ApiModelProperty;
+import lombok.Data;
+
+import java.io.Serializable;
+
+/**
+ * 客户端合同段树懒加载VO
+ */
+@Data
+public class WbsTreeContractLazyVO implements Serializable {
+
+    @ApiModelProperty("节点主键pKeyId")
+    @JsonProperty(value = "pKeyId")
+    private Long pKeyId;
+
+    @ApiModelProperty("节点主键pKeyId别名,其他接口要用")
+    private Long primaryKeyId;
+
+    @ApiModelProperty("节点id")
+    private Long id;
+
+    @ApiModelProperty("节点父级id")
+    private Long parentId;
+
+    @ApiModelProperty("节点类型")
+    private Integer nodeType;
+
+    @ApiModelProperty("'1'节点 '2'表单")
+    private Integer type;
+
+    @ApiModelProperty("模板类型")
+    private Integer wbsType;
+
+    @ApiModelProperty("节点名称")
+    private String title;
+
+    @ApiModelProperty("内业资料类型")
+    private Integer majorDataType;
+
+    @ApiModelProperty("划分编号")
+    private String partitionCode;
+
+    @ApiModelProperty("填报数量")
+    private Integer submitCounts;
+
+    @ApiModelProperty("未填报1 、已填报-未上报2 、已填报-待审批3 、已审批4")
+    private Integer colorStatus;
+
+    @ApiModelProperty("原id")
+    private String oldId;
+
+    @ApiModelProperty("是否有下级")
+    private Integer hasChildren;
+
+    @ApiModelProperty("合同段关联id(监理、业主合同关联施工合同id)")
+    private String contractIdRelation;
+
+    @ApiModelProperty("是否存在下级")
+    private Boolean notExsitChild;
+
+    @ApiModelProperty("是否为首件")
+    private Boolean isFirst;
+
+    @ApiModelProperty(value = "是否为隐蔽工程节点 '0'否 '1'是")
+    private Integer isConcealedWorksNode;
+
+}

+ 22 - 16
blade-service/blade-business/src/main/java/org/springblade/business/controller/InformationWriteQueryController.java

@@ -1436,8 +1436,8 @@ public class InformationWriteQueryController extends BladeController {
                     }
                     newData.setCreateTime(new Date());
                     newData.setUpdateTime(new Date());
-                    //初始化是否显示表格,默认显示
-                    newData.setIsBussShow(1);
+                    //初始化是否显示表格,默认显示(2023年7月19日10:48:55需求更改:跟随原状态,原表单隐藏的,那么复制过来就是隐藏的)
+                    //newData.setIsBussShow(1);
                     //初始化表格是否上传附件,默认未上传
                     newData.setTabFileType(1);
                     //初始化单表是否可以预览,默认不能
@@ -1660,17 +1660,18 @@ public class InformationWriteQueryController extends BladeController {
                         //更新redis缓存
                         informationQueryService.delAsyncWbsTree(contractId);
                     }
+
                     //拼接操作记录
                     List<CopyContractTreeNodeVO.CopyBatch> list = vo.getCopyBatchToPaths();
                     Set<String> titles = new HashSet<>();
-                    list.stream().forEach(l -> titles.add(l.getTitle()));
+                    list.forEach(l -> titles.add(l.getTitle()));
                     StringBuilder addNames = new StringBuilder();
                     addNames.append("{");
                     for (String title : titles) {
-                        addNames.append(title + "-[");
+                        addNames.append(title).append("-[");
                         for (CopyContractTreeNodeVO.CopyBatch li : list) {
                             if (title.equals(li.getTitle())) {
-                                addNames.append(li.getNodeName() + ",");
+                                addNames.append(li.getNodeName()).append(",");
                             }
                         }
                         addNames.setLength(addNames.length() - 1);
@@ -1679,7 +1680,7 @@ public class InformationWriteQueryController extends BladeController {
                     addNames.setLength(addNames.length() - 1);
                     addNames.append("}");
                     needCopyNodeRoot.setNodeName(addNames.toString());
-//                    return R.success("操作成功");
+                    //return R.success("操作成功");
                     return this.saveOrCopyNodeTree2(addNodeList, null, 32, needCopyNodeRoot);
                 } else {
                     throw new ServiceException("没有找到需要复制的节点信息,请联系管理员");
@@ -1820,8 +1821,8 @@ public class InformationWriteQueryController extends BladeController {
                             objTab.setId(tabId);
                             objTab.setParentId(toCopyNode.getId());
                             objTab.setPKeyId(SnowFlakeUtil.getId());
-                            //初始化是否显示表格,默认显示
-                            objTab.setIsBussShow(1);
+                            //初始化是否显示表格,默认显示(2023年7月19日10:48:55需求更改:跟随原状态,原表单隐藏的,那么复制过来就是隐藏的)
+                            //objTab.setIsBussShow(1);
                             //初始化表格是否上传附件,默认未上传
                             objTab.setTabFileType(1);
                             //初始化单表是否可以预览,默认不能
@@ -1911,8 +1912,8 @@ public class InformationWriteQueryController extends BladeController {
                     obj.setId(SnowFlakeUtil.getId());
                     obj.setParentId(id);
                     obj.setPKeyId(SnowFlakeUtil.getId());
-                    //初始化是否显示表格,默认显示
-                    obj.setIsBussShow(1);
+                    //初始化是否显示表格,默认显示(2023年7月19日10:48:55需求更改:跟随原状态,原表单隐藏的,那么复制过来就是隐藏的)
+                    //obj.setIsBussShow(1);
                     //初始化表格是否上传附件,默认未上传
                     obj.setTabFileType(1);
                     //初始化单表是否可以预览,默认不能
@@ -2012,8 +2013,8 @@ public class InformationWriteQueryController extends BladeController {
                                 objTab.setId(tabId);
                                 objTab.setParentId(id);
                                 objTab.setPKeyId(SnowFlakeUtil.getId());
-                                //初始化是否显示表格,默认显示
-                                objTab.setIsBussShow(1);
+                                //初始化是否显示表格,默认显示(2023年7月19日10:48:55需求更改:跟随原状态,原表单隐藏的,那么复制过来就是隐藏的)
+                                //objTab.setIsBussShow(1);
                                 //初始化表格是否上传附件,默认未上传
                                 objTab.setTabFileType(1);
                                 //初始化单表是否可以预览,默认不能
@@ -2108,6 +2109,7 @@ public class InformationWriteQueryController extends BladeController {
     @PostMapping("/copyContractTreeNode12313212")
     @ApiOperationSupport(order = 15)
     @ApiOperation(value = "复制节点")
+    @Deprecated
     public R<Boolean> copyContractTreeNode123131231(@RequestBody CopyContractTreeNodeVO vo) {
         //首先查询需要复制的节点及其下级所有子节点的信息
         WbsTreeContract needCopyNode = this.wbsTreeContractClient.getContractNodeByPrimaryKeyId(vo.getNeedCopyPrimaryKeyId());
@@ -2335,11 +2337,13 @@ public class InformationWriteQueryController extends BladeController {
             if (contractNodeMap.containsKey(newData.getOldId())) {
                 WbsTreeContract contractNode = contractNodeMap.get(newData.getOldId());
                 if (contractNode.getParentId() != null && StringUtils.isNotEmpty(contractNode.getParentId().toString())) {
-                    WbsTreeContract parentNode;
+                    WbsTreeContract parentNode = null;
                     if (contractNodeMap.containsKey(contractNode.getParentId().toString())) {
                         parentNode = contractNodeMap.get(contractNode.getParentId().toString());
                     } else {
-                        parentNode = this.wbsTreeContractClient.queryCurrentNodeAllParent(Long.parseLong(contractNode.getContractId()), contractNode.getParentId());
+                        if (ObjectUtil.isNotEmpty(contractNode.getContractId())) {
+                            parentNode = this.wbsTreeContractClient.queryCurrentNodeAllParent(Long.parseLong(contractNode.getContractId()), contractNode.getParentId());
+                        }
                     }
 
                     if (parentNode != null) {
@@ -2351,11 +2355,13 @@ public class InformationWriteQueryController extends BladeController {
             if (projectNodeMap.containsKey(newData.getOldId())) {
                 WbsTreeContract contractNode = projectNodeMap.get(newData.getOldId());
                 if (contractNode.getParentId() != null && StringUtils.isNotEmpty(contractNode.getParentId().toString())) {
-                    WbsTreeContract parentNode;
+                    WbsTreeContract parentNode = null;
                     if (projectNodeMap.containsKey(contractNode.getParentId().toString())) {
                         parentNode = projectNodeMap.get(contractNode.getParentId().toString());
                     } else {
-                        parentNode = this.wbsTreeContractClient.queryCurrentNodeAllParent(Long.parseLong(contractNode.getContractId()), contractNode.getParentId());
+                        if (ObjectUtil.isNotEmpty(contractNode.getContractId())) {
+                            parentNode = this.wbsTreeContractClient.queryCurrentNodeAllParent(Long.parseLong(contractNode.getContractId()), contractNode.getParentId());
+                        }
                     }
                     if (parentNode != null) {
                         ledger.setStation(StringUtils.isNotEmpty(parentNode.getFullName()) ? parentNode.getFullName() : parentNode.getNodeName());

+ 1 - 1
blade-service/blade-control/src/main/java/org/springblade/control/controller/LogHistoryController.java

@@ -33,7 +33,7 @@ public class LogHistoryController extends BladeController {
         if (ObjectUtil.isNotEmpty(stringListMap)) {
             return R.data(logHistoryService.logList(dto));
         }
-        return R.fail(400, "没有查询到日志信息");
+        return null;
     }
 
     @PostMapping("/submit")

+ 13 - 0
blade-service/blade-control/src/main/java/org/springblade/control/service/impl/LogHistoryServiceImpl.java

@@ -14,6 +14,7 @@ import org.springblade.control.service.LogHistoryService;
 import org.springblade.control.vo.*;
 import org.springblade.core.log.exception.ServiceException;
 import org.springblade.core.mp.base.BaseServiceImpl;
+import org.springblade.core.redis.cache.BladeRedis;
 import org.springblade.core.secure.BladeUser;
 import org.springblade.core.secure.utils.SecureUtil;
 import org.springblade.core.tool.utils.BeanUtil;
@@ -26,6 +27,7 @@ import org.springframework.jdbc.core.JdbcTemplate;
 import org.springframework.stereotype.Service;
 
 import java.text.SimpleDateFormat;
+import java.time.Duration;
 import java.time.LocalDate;
 import java.time.ZoneId;
 import java.time.format.DateTimeFormatter;
@@ -43,6 +45,7 @@ public class LogHistoryServiceImpl extends BaseServiceImpl<LogHistoryMapper, Log
     private final ProjectCostBudgetServiceImpl projectCostBudgetServiceImpl;
     private final ProjectInfoServiceImpl projectInfoServiceImpl;
     private final TaskProcessServiceImpl taskProcessService;
+    private final BladeRedis bladeRedis;
 
     @Override
     public Map<String, List<LogHistoryInfoVO>> logList(LogHistoryInfoDTO dto) {
@@ -416,6 +419,13 @@ public class LogHistoryServiceImpl extends BaseServiceImpl<LogHistoryMapper, Log
                 throw new ServiceException("该任务不属于当前用户,操作失败");
             }
 
+            String redisLock = bladeRedis.get("logUser:id=" + SecureUtil.getUserId() + ":" + taskId);
+            if (StringUtils.isNotEmpty(redisLock) && redisLock.equals("task:id=" + taskId)) {
+                throw new ServiceException("当前用户已完成此任务的审批操作,请勿重复提交");
+            } else {
+                bladeRedis.setEx("logUser:id=" + SecureUtil.getUserId() + ":" + taskId, "taskPlan:id=" + taskId, Duration.ofMinutes(1));
+            }
+
             //新增计划任务是否逾期完成记录信息
             if (obj != null && ObjectUtil.isNotEmpty(obj.getPlanEndTime())) {
                 Date now = DateUtil.now();
@@ -481,6 +491,9 @@ public class LogHistoryServiceImpl extends BaseServiceImpl<LogHistoryMapper, Log
 
             //新增审批任务关联信息
             jdbcTemplate.execute("delete from c_expense_task_record where expense_info_type = 1 and expense_info_id = " + task.getId() + " ; insert into c_expense_task_record(id,task_id,expense_info_id,expense_info_type) values (" + SnowFlakeUtil.getId() + "," + taskProcessInfo.getId() + "," + task.getId() + ",1)");
+
+            //解锁
+            bladeRedis.del("logUser:id=" + SecureUtil.getUserId() + ":" + taskId);
             return true;
 
         } else {

+ 19 - 0
blade-service/blade-control/src/main/java/org/springblade/control/service/impl/TaskProcessServiceImpl.java

@@ -66,6 +66,7 @@ public class TaskProcessServiceImpl extends BaseServiceImpl<TaskProcessMapper, T
     private final ProjectInfoServiceImpl projectInfoServiceImpl;
     private final ProjectCostBudgetStatsServiceImpl projectCostBudgetStatsService;
     private final IOSSClient iossClient;
+    private final PlanInformServiceImpl planInformService;
 
     @Override
     public IPage<TaskProcessInfoVO> taskPage(IPage<TaskProcessInfo> page, TaskProcessInfoDTO dto) {
@@ -771,6 +772,15 @@ public class TaskProcessServiceImpl extends BaseServiceImpl<TaskProcessMapper, T
                     if (ObjectUtil.isEmpty(departmentHead)) {
                         throw new ServiceException("获取部门负责人失败,请联系管理员");
                     }
+
+                    //加锁
+                    String redisLock = bladeRedis.get("logUser:id=" + SecureUtil.getUserId() + ":" + taskId);
+                    if (StringUtils.isNotEmpty(redisLock) && redisLock.equals("task:id=" + taskId)) {
+                        throw new ServiceException("当前用户已完成此任务的审批操作,请勿重复提交");
+                    } else {
+                        bladeRedis.setEx("logUser:id=" + SecureUtil.getUserId() + ":" + taskId, "taskPlan:id=" + taskId, Duration.ofMinutes(1));
+                    }
+
                     if (dto.getUpdateType().equals("1")) {
                         //任务完成
                         TaskProcessInfo taskProcessInfo = new TaskProcessInfo();
@@ -857,7 +867,10 @@ public class TaskProcessServiceImpl extends BaseServiceImpl<TaskProcessMapper, T
                         jdbcTemplate.execute("delete from c_expense_task_record where expense_info_type = 1 and expense_info_id = " + planTaskInfo.getId() + " ; insert into c_expense_task_record(id,task_id,expense_info_id,expense_info_type) values (" + SnowFlakeUtil.getId() + "," + taskProcessInfo.getId() + "," + planTaskInfo.getId() + ",1)");
                     }
                 }
+                //解锁
+                bladeRedis.del("logUser:id=" + SecureUtil.getUserId() + ":" + taskId);
             }
+
             return true;
         }
         return false;
@@ -1074,6 +1087,12 @@ public class TaskProcessServiceImpl extends BaseServiceImpl<TaskProcessMapper, T
                         LocalDate localDate = taskPlanUpdateStatusInfo.getCompletionTime().toInstant().atZone(ZoneId.systemDefault()).toLocalDate();
                         projectCostBudgetService.taskFinishedStats(projectCostBudget.getId(), localDate);
                     }
+
+                    //日志信息
+                    TaskProcessInfo taskProcessInfo = jdbcTemplate.query("select task_name from c_task_process_info where id = " + approveTaskId, new BeanPropertyRowMapper<>(TaskProcessInfo.class)).stream().findAny().orElse(null);
+                    if (taskProcessInfo != null) {
+                        planInformService.taskFinishedInform(taskProcessInfo.getTaskName(), projectCostBudget.getTaskUser(), SecureUtil.getUserName());
+                    }
                 }
 
                 break;

+ 10 - 9
blade-service/blade-desk/src/main/java/org/springblade/desk/controller/LeaveController.java

@@ -54,14 +54,15 @@ public class LeaveController extends BladeController implements CacheNames {
         return R.data(detail);
     }
 
-//    /**
-//     * 新增或修改
-//     *
-//     * @param leave 请假信息
-//     */
-//    @PostMapping("start-process")
-//    public R startProcess(@RequestBody ProcessLeave leave) {
-//        return R.status(leaveService.startProcess(leave));
-//    }
+    /**
+     * 新增或修改
+     *
+     * @param leave 请假信息
+     */
+    @PostMapping("start-process")
+    public R startProcess(@RequestBody ProcessLeave leave) {
+        //return R.status(leaveService.startProcess(leave));
+        return null;
+    }
 
 }

+ 2 - 2
blade-service/blade-manager/src/main/java/org/springblade/manager/controller/ContractInfoController.java

@@ -725,8 +725,8 @@ public class ContractInfoController extends BladeController {
     @ApiOperation(value = "资料填报(资料查询)节点搜索输入框查询接口", notes = "传入合同段id、输入框搜索的queryValue")
     public R getTreeNodeByValueAndContractId(@RequestParam String queryValue, @RequestParam String contractId) {
         R list = contractInfoService.getTreeNodeByValueAndContractId(queryValue, contractId);
-        Object data = list.getData();
-        if (data != null) {
+        if (ObjectUtil.isNotEmpty(list) && ObjectUtil.isNotEmpty(list.getData())) {
+            Object data = list.getData();
             ContractInfo contractInfo = contractInfoService.getBaseMapper().selectById(contractId);
             if (data instanceof List) {
                 if (contractInfo.getContractType().equals(1)) {

+ 43 - 3
blade-service/blade-manager/src/main/java/org/springblade/manager/controller/WbsTreeContractController.java

@@ -1,5 +1,7 @@
 package org.springblade.manager.controller;
 
+import com.alibaba.fastjson.JSON;
+import com.alibaba.fastjson.JSONArray;
 import com.baomidou.mybatisplus.core.toolkit.Wrappers;
 import com.github.xiaoymin.knife4j.annotations.ApiOperationSupport;
 import io.swagger.annotations.*;
@@ -12,14 +14,15 @@ import org.springblade.manager.entity.ContractInfo;
 import org.springblade.manager.entity.WbsTreeContract;
 import org.springblade.manager.feign.ContractClient;
 import org.springblade.manager.service.IWbsTreeContractService;
-import org.springblade.manager.vo.AppWbsTreeContractVO;
-import org.springblade.manager.vo.WbsContractNodeVo;
-import org.springblade.manager.vo.WbsTreeContractVO4;
+import org.springblade.manager.vo.*;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.data.redis.core.StringRedisTemplate;
 import org.springframework.web.bind.annotation.*;
 import org.springframework.web.multipart.MultipartFile;
 
 import java.io.IOException;
 import java.util.*;
+import java.util.stream.Collectors;
 
 @RestController
 @AllArgsConstructor
@@ -29,6 +32,8 @@ public class WbsTreeContractController extends BladeController {
 
     private final IWbsTreeContractService iWbsTreeContractService;
     private final ContractClient contractClient;
+    @Autowired
+    StringRedisTemplate redisTemplate;
 
     @GetMapping("/search-node-tables")
     @ApiOperationSupport(order = 1)
@@ -168,4 +173,39 @@ public class WbsTreeContractController extends BladeController {
         return R.status(iWbsTreeContractService.syncTabData(pKeyId));
     }
 
+    /**
+     * 客户端懒加载获取合同段树(统计颜色、填报数量)
+     *
+     * @author liuYC
+     * @date 2023年7月17日10:28:49
+     */
+    @GetMapping("/lazyQueryContractWbsTree")
+    @ApiOperationSupport(order = 9)
+    @ApiOperation(value = "客户端懒加载获取合同段树(统计颜色、填报数量)", notes = "传入父级parentId、合同段contractId、关联contractIdRelation")
+    @ApiImplicitParams(value = {
+            @ApiImplicitParam(name = "primaryKeyId", value = "监理合同前端要的"),
+            @ApiImplicitParam(name = "parentId", value = "父节点id,为空则查询第一级节点"),
+            @ApiImplicitParam(name = "contractId", value = "合同段id"),
+            @ApiImplicitParam(name = "contractIdRelation", value = "合同段关联id(监理、业主合同关联施工合同id)"),
+            @ApiImplicitParam(name = "classifyType", value = "所属方,监理、总监办的资料查询使用,=1施工数据(默认),=2监理数据")
+    })
+    public R<List<WbsTreeContractLazyVO>> lazyQueryContractWbsTree(@RequestParam String primaryKeyId, @RequestParam String parentId, @RequestParam String contractId, @RequestParam String contractIdRelation, @RequestParam String classifyType) {
+        List<WbsTreeContractLazyVO> vos;
+        if (StringUtils.isNotEmpty(primaryKeyId)) {
+            parentId = primaryKeyId;
+        }
+        String dataInfoId = contractId + "_" + parentId + "_" + classifyType;
+        Object data = redisTemplate.opsForValue().get("blade-manager::contract:wbstree:" + dataInfoId);
+        if (data != null) {
+            vos = JSON.parseArray(data.toString(), WbsTreeContractLazyVO.class);
+        } else {
+            vos = iWbsTreeContractService.lazyQueryContractWbsTree(parentId, contractId, contractIdRelation);
+            if (vos != null) {
+                JSONArray array = JSONArray.parseArray(JSON.toJSONString(vos));
+                redisTemplate.opsForValue().set("blade-manager::contract:wbstree:" + dataInfoId, JSON.toJSON(array).toString());
+            }
+        }
+        return R.data(vos);
+    }
+
 }

+ 3 - 0
blade-service/blade-manager/src/main/java/org/springblade/manager/service/IWbsTreeContractService.java

@@ -60,4 +60,7 @@ public interface IWbsTreeContractService extends BaseService<WbsTreeContract> {
     boolean syncTabData(String pKeyId) throws Exception;
 
     void syncCurrentFormToAllContract(WbsTreePrivate wbsTreePrivate);
+
+    List<WbsTreeContractLazyVO> lazyQueryContractWbsTree(String id, String contractId, String contractIdRelation);
+
 }

+ 28 - 39
blade-service/blade-manager/src/main/java/org/springblade/manager/service/impl/ContractInfoServiceImpl.java

@@ -442,13 +442,8 @@ public class ContractInfoServiceImpl extends BaseServiceImpl<ContractInfoMapper,
         for (int i = reNodes.size() - 1; i >= 0; i--) {
             WbsTreeContractTreeAllVO node = reNodes.get(i);
             if (node.getChildren() != null && !node.getChildren().isEmpty()) {
-                long childSubmitCounts = 0L;
-                int colorStatus = 1;
-
-                boolean allChildStatusEquals3 = true;
-                boolean allChildStatusEquals4 = true;
-
                 //计数
+                long childSubmitCounts = 0L;
                 for (WbsTreeContractTreeAllVO child : node.getChildren()) {
                     if (child.getSubmitCounts() == 1L) {
                         childSubmitCounts++;
@@ -456,50 +451,44 @@ public class ContractInfoServiceImpl extends BaseServiceImpl<ContractInfoMapper,
                         childSubmitCounts = child.getSubmitCounts();
                     }
                 }
+                node.setSubmitCounts(childSubmitCounts);
 
                 //颜色
+                boolean allThree = true; //是否所有子节点的getColorStatus都等于3
+                boolean allFour = true; //是否所有子节点的getColorStatus都等于4
+                boolean hasTwo = false; //是否存在子节点的getColorStatus等于2
+                boolean hasOne = false; //是否存在子节点的getColorStatus等于1
+                boolean hasThreeOrFour = false; //是否存在子节点的getColorStatus等于3或4
                 for (WbsTreeContractTreeAllVO child : node.getChildren()) {
-                    if (ObjectUtils.isNotEmpty(child.getColorStatus())) {
-                        //只要有一个子级是已填报-未上报,那么上级默认已填报-未上报(蓝色)
-                        if (child.getColorStatus().equals(2)) {
-                            colorStatus = 2;
-                            break;
-                        }
-
-                        if (child.getColorStatus().equals(3)) {
-                            allChildStatusEquals4 = false;
-                            colorStatus = 4;
-
-                        } else if (child.getColorStatus().equals(4)) {
-                            allChildStatusEquals3 = false;
-                            colorStatus = 3;
-
-                        } else {
-                            allChildStatusEquals3 = false;
-                            allChildStatusEquals4 = false;
-                            colorStatus = 1;
-                            break;
-                        }
+                    if (child.getColorStatus() != 3) {
+                        allThree = false;
+                    }
+                    if (child.getColorStatus() != 4) {
+                        allFour = false;
+                    }
+                    if (child.getColorStatus() == 2) {
+                        hasTwo = true;
+                    }
+                    if (child.getColorStatus() == 1) {
+                        hasOne = true;
+                    }
+                    if (child.getColorStatus() == 3 || child.getColorStatus() == 4) {
+                        hasThreeOrFour = true;
                     }
                 }
-
-                //父节点计数
-                node.setSubmitCounts(childSubmitCounts);
-
-                //父节点颜色
-                if (allChildStatusEquals3) {
+                if (allThree) {
                     node.setColorStatus(3);
-                    continue;
-                }
-                if (allChildStatusEquals4) {
+                } else if (allFour) {
                     node.setColorStatus(4);
-                    continue;
+                } else if (hasTwo || (hasOne && hasThreeOrFour)) {
+                    node.setColorStatus(2);
+                } else {
+                    node.setColorStatus(1);
                 }
-                node.setColorStatus(colorStatus);
 
             } else if (node.getSubmitCounts() == 1L) {
                 node.setSubmitCounts(1L);
-                //最底层颜色
+                //最底层节点颜色
                 if (ObjectUtils.isNotEmpty(node.getColorStatus())) {
                     if (node.getColorStatus().equals(0)) { //任务状态=0,未上报
                         node.setColorStatus(2); //蓝色

+ 315 - 0
blade-service/blade-manager/src/main/java/org/springblade/manager/service/impl/WbsTreeContractServiceImpl.java

@@ -9,6 +9,7 @@ import com.baomidou.mybatisplus.core.toolkit.Wrappers;
 import com.google.common.collect.Lists;
 import lombok.AllArgsConstructor;
 import org.apache.commons.lang.StringUtils;
+import org.jetbrains.annotations.NotNull;
 import org.jsoup.Jsoup;
 import org.jsoup.nodes.Document;
 import org.jsoup.nodes.Element;
@@ -32,13 +33,16 @@ import org.springblade.manager.dto.WbsTreeContractDTO2;
 import org.springblade.manager.entity.*;
 import org.springblade.manager.excel.WbsExcelBatchUtil;
 import org.springblade.manager.excel.WbsExcelUtil;
+import org.springblade.manager.feign.ContractClient;
 import org.springblade.manager.mapper.ContractInfoMapper;
 import org.springblade.manager.mapper.WbsTreeContractMapper;
 import org.springblade.manager.mapper.WbsTreePrivateMapper;
 import org.springblade.manager.service.IWbsTreeContractService;
 import org.springblade.manager.vo.*;
 import org.springblade.system.cache.ParamCache;
+import org.springframework.jdbc.core.BeanPropertyRowMapper;
 import org.springframework.jdbc.core.JdbcTemplate;
+import org.springframework.jdbc.core.RowMapper;
 import org.springframework.stereotype.Service;
 import org.springframework.transaction.annotation.Transactional;
 import org.springframework.util.LinkedCaseInsensitiveMap;
@@ -49,11 +53,14 @@ import java.io.FileInputStream;
 import java.io.IOException;
 import java.io.InputStream;
 import java.math.BigInteger;
+import java.sql.ResultSet;
+import java.sql.SQLException;
 import java.util.*;
 import java.util.function.Function;
 import java.util.regex.Matcher;
 import java.util.regex.Pattern;
 import java.util.stream.Collectors;
+import java.util.stream.Stream;
 
 @Service
 @AllArgsConstructor
@@ -64,6 +71,7 @@ public class WbsTreeContractServiceImpl extends BaseServiceImpl<WbsTreeContractM
     private final ContractInfoMapper contractInfoMapper;
     private final JdbcTemplate jdbcTemplate;
     private final InformationQueryClient informationQueryClient;
+    private final ContractClient contractClient;
 
     @Override
     public List<WbsTreeContract> selectQueryCurrentNodeByAncestors(List<String> ids, String contractId) {
@@ -548,6 +556,313 @@ public class WbsTreeContractServiceImpl extends BaseServiceImpl<WbsTreeContractM
         baseMapper.syncCurrentFormToAllContract(wbsTreePrivate);
     }
 
+    @Override
+    public List<WbsTreeContractLazyVO> lazyQueryContractWbsTree(String id, String contractId, String contractIdRelation) {
+        if (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())) {
+                    //获取当前层懒加载节点
+                    List<WbsTreeContractLazyVO> lazyNodes = jdbcTemplate.query("select a.*,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.type = 1 and a.status = 1 and a.is_deleted = 0 and parent_id = " + (StringUtils.isNotEmpty(id) ? id : 0) + " and contract_id = " + contractId, new BeanPropertyRowMapper<>(WbsTreeContractLazyVO.class));
+                    if (lazyNodes.size() > 0) {
+                        //所有最底层节点
+                        List<WbsTreeContractLazyVO> lowestNodesAll = jdbcTemplate.query("select a.p_key_id,a.id,a.parent_id,(SELECT CASE WHEN count(1) > 0 THEN 1 ELSE 0 END FROM m_wbs_tree_contract b WHERE b.parent_id = a.id AND type = 1 AND b.contract_id = " + contractId + " AND b.is_deleted = 0 ) AS hasChildren from m_wbs_tree_contract a where type = 1 and status = 1 and is_deleted = 0 and contract_id = " + contractId + " HAVING hasChildren = 0", new BeanPropertyRowMapper<>(WbsTreeContractLazyVO.class));
+
+                        //获取当前合同段所有填报资料信息
+                        List<WbsTreeContractLazyQueryInfoVO> queryInfoList = jdbcTemplate.query("select wbs_id,status from u_information_query where type = 1 and contract_id = " + contractId, new BeanPropertyRowMapper<>(WbsTreeContractLazyQueryInfoVO.class));
+                        Map<Long, Integer> queryInfoMaps = queryInfoList.stream().distinct().collect(Collectors.toMap(WbsTreeContractLazyQueryInfoVO::getWbsId, WbsTreeContractLazyQueryInfoVO::getStatus));
+                        List<Long> pKeyIdList = new ArrayList<>(queryInfoMaps.keySet());
+
+                        //填报过的所有最底层节点
+                        List<WbsTreeContractLazyVO> lowestNodesTB = lowestNodesAll.stream().filter(f -> pKeyIdList.contains(f.getPKeyId())).collect(Collectors.toList());
+                        List<Long> lowestNodeParentIdsTB = lowestNodesTB.stream().map(WbsTreeContractLazyVO::getParentId).collect(Collectors.toList());
+
+                        //获取所有填报过的父级节点,处理数量
+                        List<WbsTreeContractLazyVO> resultParentNodes = new ArrayList<>();
+                        this.recursiveGetParentNodes(resultParentNodes, lowestNodeParentIdsTB, contractId);
+
+                        //所有节点Map
+                        List<WbsTreeContractLazyVO> distinctResultParentNodes = resultParentNodes.stream().distinct().collect(Collectors.toList());
+                        Map<Long, WbsTreeContractLazyVO> nodeMap = new HashMap<>();
+                        for (WbsTreeContractLazyVO node : distinctResultParentNodes) {
+                            nodeMap.put(node.getId(), node);
+                        }
+
+                        //最底层节点Map
+                        Map<Long, WbsTreeContractLazyVO> lowestNodesMap = lowestNodesAll.stream()
+                                .peek(vo -> {
+                                    Integer colorStatus = queryInfoMaps.get(vo.getPKeyId());
+                                    if (colorStatus != null) {
+                                        //任务状态0=未上报=颜色2蓝色、任务状态1=待审批=颜色3橙色、任务状态2=已审批=颜色4绿色、任务状态3=已废除=颜色1黑色
+                                        vo.setColorStatus(colorStatus == 0 ? 2 : (colorStatus == 1 ? 3 : (colorStatus == 2 ? 4 : 1)));
+                                    } else {
+                                        //未填报的=颜色1黑色
+                                        vo.setColorStatus(1);
+                                    }
+                                })
+                                .collect(Collectors.toMap(WbsTreeContractLazyVO::getPKeyId, Function.identity(), (obj1, obj2) -> obj1));
+
+                        //构造完成的所有最底层节点,处理父节点颜色
+                        this.recursiveParentNodeColorStatus(lowestNodesAll, nodeMap);
+
+                        //处理最终结果集
+                        if (lowestNodesAll.size() > 0) {
+                            //处理填报数量
+                            Map<Long, Integer> countMap = new HashMap<>();
+                            for (WbsTreeContractLazyVO node : resultParentNodes) {
+                                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.setNotExsitChild(!lazyNodeVO.getHasChildren().equals(1));
+                                lazyNodeVO.setPrimaryKeyId(lazyNodeVO.getPKeyId());
+                                if (lazyNodeVO.getParentId() == 0L) {
+                                    if (ObjectUtil.isNotEmpty(contractInfo.getContractName())) {
+                                        lazyNodeVO.setTitle(contractInfo.getContractName());
+                                    }
+                                }
+
+                                lazyNodeVO.setSubmitCounts(ObjectUtil.isNotEmpty(countMap.get(lazyNodeVO.getPKeyId())) ? countMap.get(lazyNodeVO.getPKeyId()) : (ObjectUtil.isNotEmpty(queryInfoMaps.get(lazyNodeVO.getPKeyId())) ? 1 : 0));
+
+                                WbsTreeContractLazyVO vo = nodeMap.get(lazyNodeVO.getId());
+                                if (vo != null) {
+                                    lazyNodeVO.setColorStatus(ObjectUtil.isNotEmpty(vo.getColorStatus()) ? vo.getColorStatus() : 1);
+                                } else {
+                                    WbsTreeContractLazyVO lowestNode = lowestNodesMap.get(lazyNodeVO.getPKeyId());
+                                    lazyNodeVO.setColorStatus(ObjectUtil.isNotEmpty(lowestNode) ? lowestNode.getColorStatus() : 1);
+                                }
+                            }
+                        }
+
+                        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 (ObjectUtil.isNotEmpty(contractIdRelation) && ObjectUtil.isNotEmpty(id)) {
+                        //非根节点时选择加载施工合同段的树
+                        contractIds.add(contractIdRelation);
+                    } else {
+                        //根节点时默认加载所有施工合同段的树
+                        contractIds = this.contractClient.getProcessContractByJLContractId(contractId);
+                    }
+                    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 a.*,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.type = 1 and a.status = 1 and a.is_deleted = 0 and parent_id = " + (StringUtils.isNotEmpty(id) ? id : 0) + " and contract_id = " + sgContractId, new BeanPropertyRowMapper<>(WbsTreeContractLazyVO.class));
+
+                            if (lazyNodes.size() > 0) {
+                                //所有最底层节点
+                                List<WbsTreeContractLazyVO> lowestNodesAll = jdbcTemplate.query("select a.p_key_id,a.id,a.parent_id,(SELECT CASE WHEN count(1) > 0 THEN 1 ELSE 0 END FROM m_wbs_tree_contract b WHERE b.parent_id = a.id AND type = 1 AND b.contract_id = " + sgContractId + " AND b.is_deleted = 0 ) AS hasChildren from m_wbs_tree_contract a where type = 1 and status = 1 and is_deleted = 0 and contract_id = " + sgContractId + " HAVING hasChildren = 0", new BeanPropertyRowMapper<>(WbsTreeContractLazyVO.class));
+
+                                //获取当前合同段所有填报资料信息
+                                List<WbsTreeContractLazyQueryInfoVO> queryInfoList = jdbcTemplate.query("select wbs_id,status from u_information_query where type = 1 and contract_id = " + sgContractId, new BeanPropertyRowMapper<>(WbsTreeContractLazyQueryInfoVO.class));
+                                Map<Long, Integer> queryInfoMaps = queryInfoList.stream().distinct().collect(Collectors.toMap(WbsTreeContractLazyQueryInfoVO::getWbsId, WbsTreeContractLazyQueryInfoVO::getStatus));
+                                List<Long> pKeyIdList = new ArrayList<>(queryInfoMaps.keySet());
+
+                                //填报过的所有最底层节点
+                                List<WbsTreeContractLazyVO> lowestNodesTB = lowestNodesAll.stream().filter(f -> pKeyIdList.contains(f.getPKeyId())).collect(Collectors.toList());
+                                List<Long> lowestNodeParentIdsTB = lowestNodesTB.stream().map(WbsTreeContractLazyVO::getParentId).collect(Collectors.toList());
+
+                                //获取所有填报过的父级节点,处理数量
+                                List<WbsTreeContractLazyVO> resultParentNodes = new ArrayList<>();
+                                this.recursiveGetParentNodes(resultParentNodes, lowestNodeParentIdsTB, sgContractId);
+
+                                //所有节点Map
+                                List<WbsTreeContractLazyVO> distinctResultParentNodes = resultParentNodes.stream().distinct().collect(Collectors.toList());
+                                Map<Long, WbsTreeContractLazyVO> nodeMap = new HashMap<>();
+                                for (WbsTreeContractLazyVO node : distinctResultParentNodes) {
+                                    nodeMap.put(node.getId(), node);
+                                }
+
+                                //最底层节点Map
+                                Map<Long, WbsTreeContractLazyVO> lowestNodesMap = lowestNodesAll.stream()
+                                        .peek(vo -> {
+                                            Integer colorStatus = queryInfoMaps.get(vo.getPKeyId());
+                                            if (colorStatus != null) {
+                                                //任务状态0=未上报=颜色2蓝色、任务状态1=待审批=颜色3橙色、任务状态2=已审批=颜色4绿色、任务状态3=已废除=颜色1黑色
+                                                vo.setColorStatus(colorStatus == 0 ? 2 : (colorStatus == 1 ? 3 : (colorStatus == 2 ? 4 : 1)));
+                                            } else {
+                                                //未填报的=颜色1黑色
+                                                vo.setColorStatus(1);
+                                            }
+                                        })
+                                        .collect(Collectors.toMap(WbsTreeContractLazyVO::getPKeyId, Function.identity(), (obj1, obj2) -> obj1));
+
+                                //构造完成的所有最底层节点,处理父节点颜色
+                                this.recursiveParentNodeColorStatus(lowestNodesAll, nodeMap);
+
+                                //处理最终结果集
+                                if (lowestNodesAll.size() > 0) {
+                                    //处理填报数量
+                                    Map<Long, Integer> countMap = new HashMap<>();
+                                    for (WbsTreeContractLazyVO node : resultParentNodes) {
+                                        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.setNotExsitChild(!lazyNodeVO.getHasChildren().equals(1));
+                                        lazyNodeVO.setPrimaryKeyId(lazyNodeVO.getPKeyId());
+                                        lazyNodeVO.setContractIdRelation(sgContractId);
+                                        if (lazyNodeVO.getParentId() == 0L) {
+                                            if (ObjectUtil.isNotEmpty(sgContractInfo.getContractName())) {
+                                                lazyNodeVO.setTitle(sgContractInfo.getContractName());
+                                            }
+                                        }
+
+                                        lazyNodeVO.setSubmitCounts(ObjectUtil.isNotEmpty(countMap.get(lazyNodeVO.getPKeyId())) ? countMap.get(lazyNodeVO.getPKeyId()) : (ObjectUtil.isNotEmpty(queryInfoMaps.get(lazyNodeVO.getPKeyId())) ? queryInfoMaps.get(lazyNodeVO.getPKeyId()) : 0));
+
+                                        WbsTreeContractLazyVO vo = nodeMap.get(lazyNodeVO.getId());
+                                        if (vo != null) {
+                                            lazyNodeVO.setColorStatus(ObjectUtil.isNotEmpty(vo.getColorStatus()) ? vo.getColorStatus() : 1);
+                                        } else {
+                                            WbsTreeContractLazyVO lowestNode = lowestNodesMap.get(lazyNodeVO.getPKeyId());
+                                            lazyNodeVO.setColorStatus(ObjectUtil.isNotEmpty(lowestNode) ? lowestNode.getColorStatus() : 1);
+                                        }
+                                    }
+                                }
+                                lazyNodesAll.addAll(lazyNodes);
+                            }
+                        }
+                    }
+                    return lazyNodesAll;
+                }
+            }
+        }
+        return null;
+    }
+
+    /**
+     * 反向递归获取父级(父级Id=子级parentId)
+     *
+     * @param result              结果集
+     * @param lowestNodeParentIds 最底层节点ParentIds
+     * @param contractId          施工合同段id
+     */
+    private void recursiveGetParentNodes(List<WbsTreeContractLazyVO> result, List<Long> lowestNodeParentIds, String contractId) {
+        if (lowestNodeParentIds.isEmpty()) {
+            return;
+        }
+
+        //父级Id与出现的次数Map
+        Map<Long, Long> parentIdGroup = lowestNodeParentIds.stream()
+                .collect(Collectors.groupingBy(Function.identity(), Collectors.counting()));
+
+        List<String> keysWithValueOne = new ArrayList<>();
+        Map<Long, Long> keysWithValueSome = new HashMap<>();
+
+        for (Map.Entry<Long, Long> entry : parentIdGroup.entrySet()) {
+            if (entry.getValue() == 1L) {
+                keysWithValueOne.add(entry.getKey().toString());
+            } else {
+                keysWithValueSome.put(entry.getKey(), entry.getValue());
+            }
+        }
+
+        //批量查询单次节点
+        List<WbsTreeContractLazyVO> parentNodes = new ArrayList<>();
+        if (keysWithValueOne.size() > 0) {
+            parentNodes = jdbcTemplate.query("select p_key_id,id,parent_id from m_wbs_tree_contract where is_deleted = 0 and status = 1 and type = 1 and id in (" + StringUtils.join(keysWithValueOne, ",") + ") and contract_id = " + contractId, new BeanPropertyRowMapper<>(WbsTreeContractLazyVO.class));
+        }
+
+        //批量查询多次节点
+        List<WbsTreeContractLazyVO> multipleParentNodes = new ArrayList<>();
+        for (Map.Entry<Long, Long> entry : keysWithValueSome.entrySet()) {
+            Long key = entry.getKey();
+            Long count = entry.getValue();
+
+            List<WbsTreeContractLazyVO> nodes = jdbcTemplate.query("select p_key_id,id,parent_id from m_wbs_tree_contract where is_deleted = 0 and status = 1 and type = 1 and id = " + key + " and contract_id = " + contractId, new BeanPropertyRowMapper<>(WbsTreeContractLazyVO.class));
+            if (!nodes.isEmpty()) {
+                multipleParentNodes.addAll(Collections.nCopies(count.intValue(), nodes.get(0)));
+            }
+        }
+
+        //结果集
+        List<Long> collect = Stream.concat(parentNodes.stream(), multipleParentNodes.stream())
+                .map(WbsTreeContractLazyVO::getParentId)
+                .collect(Collectors.toList());
+
+        if (!collect.isEmpty()) {
+            result.addAll(parentNodes);
+            result.addAll(multipleParentNodes);
+            this.recursiveGetParentNodes(result, collect, contractId);
+        }
+    }
+
+    /**
+     * 反向递归处理父节点颜色
+     *
+     * @param childNodeList 子级节点List
+     * @param nodeMap       所有节点Map
+     */
+    private void recursiveParentNodeColorStatus(List<WbsTreeContractLazyVO> childNodeList, Map<Long, WbsTreeContractLazyVO> nodeMap) {
+        if (childNodeList.size() > 0) {
+            List<WbsTreeContractLazyVO> parentNodeList = new ArrayList<>();
+            Map<Long, List<WbsTreeContractLazyVO>> lowestNodesParentGroup = childNodeList.stream().collect(Collectors.groupingBy(WbsTreeContractLazyVO::getParentId));
+            for (Map.Entry<Long, List<WbsTreeContractLazyVO>> oneParentGroups : lowestNodesParentGroup.entrySet()) {
+                Long parentId = oneParentGroups.getKey(); //父节点id
+                List<WbsTreeContractLazyVO> oneLevel = oneParentGroups.getValue(); //子节点分组
+                if (parentId != null && oneLevel.size() > 0) {
+                    WbsTreeContractLazyVO parentNode = nodeMap.get(parentId); //获取父节点
+                    if (parentNode != null) {
+                        boolean allThree = true; //是否所有子节点的getColorStatus都等于3
+                        boolean allFour = true; //是否所有子节点的getColorStatus都等于4
+                        boolean hasTwo = false; //是否存在子节点的getColorStatus等于2
+                        boolean hasOne = false; //是否存在子节点的getColorStatus等于1
+                        boolean hasThreeOrFour = false; //是否存在子节点的getColorStatus等于3或4
+                        for (WbsTreeContractLazyVO node : oneLevel) {
+                            if (node.getColorStatus() != 3) {
+                                allThree = false;
+                            }
+                            if (node.getColorStatus() != 4) {
+                                allFour = false;
+                            }
+                            if (node.getColorStatus() == 2) {
+                                hasTwo = true;
+                            }
+                            if (node.getColorStatus() == 1) {
+                                hasOne = true;
+                            }
+                            if (node.getColorStatus() == 3 || node.getColorStatus() == 4) {
+                                hasThreeOrFour = true;
+                            }
+                        }
+                        if (allThree) {
+                            parentNode.setColorStatus(3);
+                        } else if (allFour) {
+                            parentNode.setColorStatus(4);
+                        } else if (hasTwo || (hasOne && hasThreeOrFour)) {
+                            parentNode.setColorStatus(2);
+                        } else {
+                            parentNode.setColorStatus(1);
+                        }
+                        parentNodeList.add(parentNode);
+                    }
+                }
+            }
+            if (parentNodeList.size() > 0) { //递归处理父级颜色,当前父级作为下次循环子级
+                this.recursiveParentNodeColorStatus(parentNodeList, nodeMap);
+            }
+        }
+    }
+
     @Override
     public boolean syncTabData(String pKeyId) throws Exception {
         WbsTreeContract node = baseMapper.selectOne(Wrappers.<WbsTreeContract>lambdaQuery().eq(WbsTreeContract::getPKeyId, pKeyId));