|
@@ -0,0 +1,1017 @@
|
|
|
+package org.springblade.manager.service.impl;
|
|
|
+
|
|
|
+import cn.hutool.core.date.DateTime;
|
|
|
+import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
|
|
|
+import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
|
|
|
+import com.baomidou.mybatisplus.core.toolkit.StringUtils;
|
|
|
+import com.baomidou.mybatisplus.core.toolkit.Wrappers;
|
|
|
+import com.google.common.collect.Lists;
|
|
|
+import org.apache.commons.lang.ObjectUtils;
|
|
|
+import org.springblade.common.constant.CommonConstant;
|
|
|
+import org.springblade.common.utils.SnowFlakeUtil;
|
|
|
+import org.springblade.core.log.exception.ServiceException;
|
|
|
+import org.springblade.core.tool.utils.*;
|
|
|
+import org.springblade.manager.entity.*;
|
|
|
+import org.springblade.manager.enums.WbsSyncTypeEnum;
|
|
|
+import org.springblade.manager.mapper.*;
|
|
|
+import org.springblade.system.cache.ParamCache;
|
|
|
+import org.springframework.beans.factory.annotation.Autowired;
|
|
|
+import org.springframework.scheduling.annotation.Async;
|
|
|
+import org.springframework.stereotype.Service;
|
|
|
+
|
|
|
+import java.io.File;
|
|
|
+import java.util.*;
|
|
|
+import java.util.function.Function;
|
|
|
+import java.util.stream.Collectors;
|
|
|
+
|
|
|
+/**
|
|
|
+ * Wbs 同步功能Service
|
|
|
+ *
|
|
|
+ * @author LHB
|
|
|
+ */
|
|
|
+@Service
|
|
|
+public class WbsSynchronousServiceImpl {
|
|
|
+
|
|
|
+ //电签
|
|
|
+ @Autowired
|
|
|
+ private TextdictInfoMapper textdictInfoMapper;
|
|
|
+ //合同wbs
|
|
|
+ @Autowired
|
|
|
+ private WbsTreeContractMapper wbsTreeContractMapper;
|
|
|
+ //合同
|
|
|
+ @Autowired
|
|
|
+ private ContractInfoMapper contractInfoMapper;
|
|
|
+ //项目wbs
|
|
|
+ @Autowired
|
|
|
+ private WbsTreePrivateMapper wbsTreePrivateMapper;
|
|
|
+ //系统wbs
|
|
|
+ @Autowired
|
|
|
+ private WbsTreeMapper wbsTreeMapper;
|
|
|
+ //项目
|
|
|
+ @Autowired
|
|
|
+ private ProjectInfoMapper projectInfoMapper;
|
|
|
+ //同步信息
|
|
|
+ @Autowired
|
|
|
+ private WbsTreeSynchronousRecordMapper synchronousRecordMapper;
|
|
|
+
|
|
|
+
|
|
|
+ @Async("taskExecutor1")
|
|
|
+ public void syncExecute(WbsTreeSynchronousRecord wbsTreeSynchronousRecord) {
|
|
|
+ // 类型枚举 WbsSyncTypeEnum.ALREADY_FILLED_IN_NOT_REPORTED
|
|
|
+ //范围 1.项目,2.合同
|
|
|
+ Integer range = wbsTreeSynchronousRecord.getRange();
|
|
|
+ if (range == 1) {
|
|
|
+ insertPrivateNode(wbsTreeSynchronousRecord);
|
|
|
+ } else if (range == 2) {
|
|
|
+ insertContractNode(wbsTreeSynchronousRecord);
|
|
|
+ } else {
|
|
|
+ throw new ServiceException("同步类型错误");
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
+ /**
|
|
|
+ * 项目同步 获取源节点数据和当前节点数据
|
|
|
+ *
|
|
|
+ * @param wbsTreeSynchronousRecord
|
|
|
+ */
|
|
|
+ public void insertPrivateNode(WbsTreeSynchronousRecord wbsTreeSynchronousRecord) {
|
|
|
+ //同步类型 1.新增表单,2.新增节点,3.删除节点,4.删除表单,5.修改节点,6.修改表单,7.修改节点表单
|
|
|
+ String type = wbsTreeSynchronousRecord.getType();
|
|
|
+ List<Integer> collect = Arrays.stream(type.split(",")).map(Integer::parseInt).collect(Collectors.toList());
|
|
|
+
|
|
|
+ // 选中节点
|
|
|
+ String nodeId = wbsTreeSynchronousRecord.getNodeId();
|
|
|
+ String[] nodeIds = nodeId.split(",");
|
|
|
+
|
|
|
+ //选中表单
|
|
|
+ String formIds = wbsTreeSynchronousRecord.getFormIds();
|
|
|
+ List<Long> formList;
|
|
|
+ if (StringUtil.isNotBlank(formIds)) {
|
|
|
+ formList = Arrays.stream(formIds.split(",")).map(Long::parseLong).collect(Collectors.toList());
|
|
|
+ } else {
|
|
|
+ formList = null;
|
|
|
+ }
|
|
|
+ for (String primaryKeyId : nodeIds) {
|
|
|
+ if (StringUtils.isNotEmpty(primaryKeyId)) {
|
|
|
+ //获取当前节点对应节点信息
|
|
|
+ WbsTreePrivate wbsTreePrivate = wbsTreePrivateMapper.selectOne(Wrappers.<WbsTreePrivate>lambdaQuery().eq(WbsTreePrivate::getPKeyId, primaryKeyId));
|
|
|
+ //获取项目信息
|
|
|
+ ProjectInfo projectInfo = projectInfoMapper.selectOne(Wrappers.<ProjectInfo>lambdaQuery().eq(ProjectInfo::getId, wbsTreePrivate.getProjectId()));
|
|
|
+ //当前项目模板对应的节点信息
|
|
|
+ List<WbsTreePrivate> templateNodes = new ArrayList<>();
|
|
|
+ //质检
|
|
|
+ //当前节点引用的模板为公有模板
|
|
|
+
|
|
|
+ if (("public").equals(projectInfo.getReferenceWbsTemplateType())) {
|
|
|
+ //当前节点对应的模板节点信息
|
|
|
+ WbsTree wbsTreeTemplate = wbsTreeMapper.selectOne(Wrappers.<WbsTree>lambdaQuery()
|
|
|
+ .eq(WbsTree::getId, wbsTreePrivate.getTreePId()));
|
|
|
+ //获取模板中当前节点的子节点的数据------------------------------------------------------------------------------------------------------------------------
|
|
|
+ LambdaQueryWrapper<WbsTree> wrapperTree = Wrappers.lambdaQuery();
|
|
|
+ wrapperTree.eq(WbsTree::getWbsId, wbsTreePrivate.getWbsId())
|
|
|
+ .eq(WbsTree::getIsDeleted, 0);
|
|
|
+ if (wbsTreeTemplate.getParentId() != 0) {
|
|
|
+ wrapperTree.apply("FIND_IN_SET({0},ancestors)", wbsTreeTemplate.getId());
|
|
|
+ }
|
|
|
+ //模板节点的所有子节点信息
|
|
|
+ List<WbsTree> wbsTrees = wbsTreeMapper.selectList(wrapperTree);
|
|
|
+ //3、获取需要新增的节点或者表单节点信息 以及他们对应的父级节点信息--------------------------------------------------------------------------------------------
|
|
|
+ if (CollectionUtil.isEmpty(wbsTrees)) {
|
|
|
+ System.out.println("模板节点未找到");
|
|
|
+ continue;
|
|
|
+ }
|
|
|
+ templateNodes = BeanUtil.copyProperties(wbsTrees, WbsTreePrivate.class);
|
|
|
+ templateNodes.forEach(f -> f.setTreePId(f.getId()));
|
|
|
+
|
|
|
+ } else if (("private").equals(projectInfo.getReferenceWbsTemplateType())) {
|
|
|
+ //根据wbsTreePrivate的wbsId=私有引用的pKeyId来获取引用树根节点
|
|
|
+ WbsTreePrivate wbsTreePrivateRoot = wbsTreePrivateMapper.selectOne(Wrappers.<WbsTreePrivate>lambdaQuery()
|
|
|
+ .eq(WbsTreePrivate::getPKeyId, wbsTreePrivate.getWbsId()));
|
|
|
+
|
|
|
+ //获取当前选中节点与私有模板对应的节点信息 父级模板项目的当前选中节点
|
|
|
+ wbsTreePrivateRoot = wbsTreePrivateMapper.selectOne(Wrappers.<WbsTreePrivate>lambdaQuery()
|
|
|
+ .eq(WbsTreePrivate::getProjectId, wbsTreePrivateRoot.getProjectId())
|
|
|
+ .eq(WbsTreePrivate::getTreePId, wbsTreePrivate.getTreePId()));
|
|
|
+
|
|
|
+ //获取模板中当前节点的子节点的数据------------------------------------------------------------------------------------------------------------------------
|
|
|
+ LambdaQueryWrapper<WbsTreePrivate> wrapperPrivate = Wrappers.lambdaQuery();
|
|
|
+ wrapperPrivate.eq(WbsTreePrivate::getProjectId, wbsTreePrivateRoot.getProjectId())
|
|
|
+ .eq(WbsTreePrivate::getIsDeleted, 0);
|
|
|
+ //判断如果为顶级顶级节点
|
|
|
+ if (wbsTreePrivate.getTreePId() != 0) {
|
|
|
+ wrapperPrivate.apply("FIND_IN_SET({0},ancestors_p_id)", wbsTreePrivateRoot.getPId());
|
|
|
+ }
|
|
|
+ templateNodes = wbsTreePrivateMapper.selectList(wrapperPrivate);
|
|
|
+ }
|
|
|
+
|
|
|
+ if (CollectionUtil.isEmpty(templateNodes)) {
|
|
|
+ System.out.println("未找到模板对应节点");
|
|
|
+ continue;
|
|
|
+ }
|
|
|
+
|
|
|
+
|
|
|
+ //2、获取当前节点的子节点的数据------------------------------------------------------------------------------------------------------------------------
|
|
|
+ LambdaQueryWrapper<WbsTreePrivate> wrapperPrivate = Wrappers.lambdaQuery();
|
|
|
+ wrapperPrivate.eq(WbsTreePrivate::getWbsId, wbsTreePrivate.getWbsId()).eq(WbsTreePrivate::getIsDeleted, 0);
|
|
|
+ //判断如果为顶级顶级节点
|
|
|
+ if (wbsTreePrivate.getTreePId() != 0) {
|
|
|
+ wrapperPrivate.apply("FIND_IN_SET({0},ancestors_p_id)", wbsTreePrivate.getPId());
|
|
|
+ }
|
|
|
+
|
|
|
+ //当前表节点下的节点信息
|
|
|
+ List<WbsTreePrivate> wbsTreePrivates = wbsTreePrivateMapper.selectList(wrapperPrivate);
|
|
|
+
|
|
|
+ if (wbsTreePrivates.isEmpty()) {
|
|
|
+ System.out.println("未找到模板对应节点");
|
|
|
+ continue;
|
|
|
+ }
|
|
|
+
|
|
|
+ //获取id 和 tree_p_id 组成的集合
|
|
|
+ Set<Long> ids = wbsTreePrivates.stream().map(WbsTreePrivate::getTreePId).collect(Collectors.toSet());
|
|
|
+ //3.1筛选出需要新增的节点
|
|
|
+ List<WbsTreePrivate> addPrivateNodes = templateNodes.stream()
|
|
|
+ .filter(f -> !ids.contains(f.getTreePId()))
|
|
|
+ .collect(Collectors.toList());
|
|
|
+
|
|
|
+ //新增数据二次筛选 只保留任务选中的表单 但可能新增的数据包含新节点
|
|
|
+ if (CollectionUtil.isNotEmpty(formList)) {
|
|
|
+ addPrivateNodes = addPrivateNodes.stream().filter(f -> f.getType() == 1 || formList.contains(f.getPKeyId())).collect(Collectors.toList());
|
|
|
+ }
|
|
|
+
|
|
|
+ //筛选出需要更新的节点 同时做数据隔离
|
|
|
+ List<WbsTreePrivate> editPrivateNodes = new ArrayList<>();
|
|
|
+ for (WbsTreePrivate templateNode : templateNodes) {
|
|
|
+ //更新只跟新表单
|
|
|
+ if (templateNode.getType() == 2) {
|
|
|
+ for (WbsTreePrivate editPrivateNode : wbsTreePrivates) {
|
|
|
+ // 判断模板表与项目表 html是否一致
|
|
|
+ if (ObjectUtils.equals(templateNode.getTreePId(), editPrivateNode.getTreePId())) {
|
|
|
+ if (editPrivateNode.getExcelId() == null
|
|
|
+ || editPrivateNode.getHtmlUrl() == null
|
|
|
+ || ObjectUtils.equals(templateNode.getExcelId(), editPrivateNode.getExcelId())
|
|
|
+ || ObjectUtils.equals(templateNode.getHtmlUrl(), editPrivateNode.getHtmlUrl())) {
|
|
|
+
|
|
|
+ //清表
|
|
|
+ if (collect.contains(2)) {
|
|
|
+ editPrivateNode.setExcelId(templateNode.getExcelId());
|
|
|
+ editPrivateNode.setInitTableName(templateNode.getInitTableName());
|
|
|
+ editPrivateNode.setHtmlUrl(templateNode.getHtmlUrl());
|
|
|
+ if (templateNode.getExcelId() != null) {
|
|
|
+ editPrivateNode.setIsLinkTable(2);
|
|
|
+ }
|
|
|
+
|
|
|
+ }
|
|
|
+ //元素 是与表绑定的
|
|
|
+ if (collect.contains(3)) {
|
|
|
+ editPrivateNode.setInitTableName(templateNode.getInitTableName());
|
|
|
+ }
|
|
|
+
|
|
|
+
|
|
|
+ //排序
|
|
|
+ if (collect.contains(7)) {
|
|
|
+ editPrivateNode.setSort(templateNode.getSort());
|
|
|
+ }
|
|
|
+
|
|
|
+ editPrivateNodes.add(editPrivateNode);
|
|
|
+ }
|
|
|
+ }
|
|
|
+ }
|
|
|
+ }
|
|
|
+ }
|
|
|
+ //修改数据二次筛选 只保留任务选中的表单 但可能新增的数据包含新节点
|
|
|
+ if (CollectionUtil.isNotEmpty(formList)) {
|
|
|
+ editPrivateNodes = editPrivateNodes.stream().filter(f -> formList.contains(f.getPKeyId())).collect(Collectors.toList());
|
|
|
+ }
|
|
|
+
|
|
|
+
|
|
|
+
|
|
|
+ Collections.sort(collect);
|
|
|
+ for (Integer i : collect) {
|
|
|
+ switch (i) {
|
|
|
+ //添加表单
|
|
|
+ case 1:
|
|
|
+ insertPrivateForm(wbsTreePrivates, addPrivateNodes);
|
|
|
+ //如果同时选择新增表单和其他的同步类型 在操作其他类型的时候需要添加新的表单
|
|
|
+ if (CollectionUtil.isNotEmpty(addPrivateNodes)) {
|
|
|
+ editPrivateNodes.addAll(addPrivateNodes.stream().filter(f -> f.getType() == 2).collect(Collectors.toList()));
|
|
|
+ }
|
|
|
+ break;
|
|
|
+ //清表
|
|
|
+ case 2:
|
|
|
+ //元素
|
|
|
+ case 3:
|
|
|
+ //排序
|
|
|
+ case 7:
|
|
|
+ //元素配置
|
|
|
+ for (WbsTreePrivate editPrivateNode : editPrivateNodes) {
|
|
|
+ wbsTreePrivateMapper.updateById(editPrivateNode);
|
|
|
+ }
|
|
|
+ break;
|
|
|
+ //电签 如果有数据 与节点绑定
|
|
|
+ case 4:
|
|
|
+ //默认值 如果有数据 与节点绑定
|
|
|
+ case 6:
|
|
|
+
|
|
|
+ updateEViSa(collect, wbsTreeSynchronousRecord.getTemplateId(), projectInfo.getId(),templateNodes, editPrivateNodes);
|
|
|
+
|
|
|
+
|
|
|
+ break;
|
|
|
+
|
|
|
+
|
|
|
+ //公式配置
|
|
|
+ case 5:
|
|
|
+ break;
|
|
|
+
|
|
|
+
|
|
|
+ default:
|
|
|
+ break;
|
|
|
+ }
|
|
|
+ }
|
|
|
+ }
|
|
|
+ }
|
|
|
+ wbsTreeSynchronousRecord.setStatus(2);
|
|
|
+ synchronousRecordMapper.updateById(wbsTreeSynchronousRecord);
|
|
|
+ }
|
|
|
+
|
|
|
+
|
|
|
+ /**
|
|
|
+ * 合同段同步 获取源节点数据和当前节点数据
|
|
|
+ */
|
|
|
+ public void insertContractNode(WbsTreeSynchronousRecord wbsTreeSynchronousRecord) {
|
|
|
+ //同步类型 1.新增表单,2.新增节点,3.删除节点,4.删除表单,5.修改节点,6.修改表单,7.修改节点表单
|
|
|
+ String type = wbsTreeSynchronousRecord.getType();
|
|
|
+ List<Integer> collect = Arrays.stream(type.split(",")).map(Integer::parseInt).collect(Collectors.toList());
|
|
|
+
|
|
|
+ // 选中节点
|
|
|
+ String nodeId = wbsTreeSynchronousRecord.getNodeId();
|
|
|
+ if (StringUtil.isBlank(nodeId)) {
|
|
|
+ return;
|
|
|
+ }
|
|
|
+ String[] nodeIds = nodeId.split(",");
|
|
|
+ //选中表单
|
|
|
+ String formIds = wbsTreeSynchronousRecord.getFormIds();
|
|
|
+ List<Long> formList;
|
|
|
+ if (StringUtil.isNotBlank(formIds)) {
|
|
|
+ formList = Arrays.stream(formIds.split(",")).map(Long::parseLong).collect(Collectors.toList());
|
|
|
+ } else {
|
|
|
+ formList = null;
|
|
|
+ }
|
|
|
+
|
|
|
+ //获取当前项目所有合同---------------------------------------------------------------------------------------------------
|
|
|
+ List<ContractInfo> contractInfos = contractInfoMapper.selectContractIdByProjectId(String.valueOf(wbsTreeSynchronousRecord.getProjectId()));
|
|
|
+
|
|
|
+
|
|
|
+ for (String primaryKeyId : nodeIds) {
|
|
|
+
|
|
|
+ //获取当前节点对应节点信息
|
|
|
+ WbsTreePrivate wbsTreePrivate = wbsTreePrivateMapper.selectOne(Wrappers.<WbsTreePrivate>lambdaQuery()
|
|
|
+ .eq(WbsTreePrivate::getPKeyId, primaryKeyId));
|
|
|
+
|
|
|
+ //当前项目选中的节点 获取当前节点的所有子节点数据
|
|
|
+ //1、获取当前节点的子节点 表单的数据------------------------------------------------------------------------------------------------------------------------
|
|
|
+ LambdaQueryWrapper<WbsTreePrivate> wrapperPrivate = Wrappers.lambdaQuery();
|
|
|
+ wrapperPrivate
|
|
|
+ .eq(WbsTreePrivate::getWbsId, wbsTreePrivate.getWbsId())
|
|
|
+ .eq(WbsTreePrivate::getIsDeleted, 0);
|
|
|
+ //判断如果为顶级顶级节点
|
|
|
+ if (wbsTreePrivate.getTreePId() != 0) {
|
|
|
+ wrapperPrivate.apply("FIND_IN_SET({0},ancestors_p_id)", wbsTreePrivate.getPId());
|
|
|
+ }
|
|
|
+ //当前项目的子节点数据
|
|
|
+ List<WbsTreePrivate> wbsTreePrivates = wbsTreePrivateMapper.selectList(wrapperPrivate);
|
|
|
+
|
|
|
+ if (wbsTreePrivates.isEmpty()) {
|
|
|
+ System.out.println("无法找到模板对应节点,请检查模板节点");
|
|
|
+ continue;
|
|
|
+ }
|
|
|
+
|
|
|
+ //合同同步
|
|
|
+ for (ContractInfo contractInfo : contractInfos) {
|
|
|
+ //获取合同下当前节点的数据
|
|
|
+ WbsTreeContract wbsTreeContract = wbsTreeContractMapper.selectOne(Wrappers.<WbsTreeContract>lambdaQuery()
|
|
|
+ .eq(WbsTreeContract::getContractId, contractInfo.getId())
|
|
|
+ .eq(WbsTreeContract::getIsTypePrivatePid, primaryKeyId));
|
|
|
+ //如果没有查询到,表示该合同下不存在该节点
|
|
|
+ if (wbsTreeContract == null) {
|
|
|
+ //不能抛异常 不然就会中止程序 开发阶段先抛异常,后续统一处理
|
|
|
+ System.out.println("当前节点不存在");
|
|
|
+ continue;
|
|
|
+ }
|
|
|
+
|
|
|
+
|
|
|
+ //获取合同 当前节点的所有子节点数据
|
|
|
+ LambdaQueryWrapper<WbsTreeContract> wrapperContract = Wrappers.lambdaQuery();
|
|
|
+ wrapperContract
|
|
|
+ .eq(WbsTreeContract::getContractId, contractInfo.getId())
|
|
|
+ .eq(WbsTreeContract::getIsDeleted, 0);
|
|
|
+ //判断如果为顶级顶级节点
|
|
|
+ if (wbsTreeContract.getTreePId() != 0) {
|
|
|
+ wrapperPrivate.apply("FIND_IN_SET({0},ancestors_p_id)", wbsTreeContract.getPId());
|
|
|
+ }
|
|
|
+
|
|
|
+ //当前合同的子节点数据
|
|
|
+ List<WbsTreeContract> wbsTreeContracts = wbsTreeContractMapper.selectList(wrapperContract);
|
|
|
+
|
|
|
+ //合同段节点对应的项目id
|
|
|
+ List<Long> typePrivateIds = wbsTreeContracts.stream().map(WbsTreeContract::getIsTypePrivatePid).collect(Collectors.toList());
|
|
|
+
|
|
|
+ //需要新增的表单
|
|
|
+ List<WbsTreePrivate> addPrivateNodes = wbsTreePrivates.stream().filter(f -> !typePrivateIds.contains(f.getPKeyId())).collect(Collectors.toList());
|
|
|
+
|
|
|
+ //如果没有选中 则默认同步所有
|
|
|
+ if (CollectionUtil.isNotEmpty(formList)) {
|
|
|
+ //二次筛选 只保留任务选中的表单 但可能新增的数据包含新节点
|
|
|
+ List<Long> finalFormList = formList;
|
|
|
+ addPrivateNodes = addPrivateNodes.stream().filter(f -> f.getType() == 1 || finalFormList.contains(f.getPKeyId())).collect(Collectors.toList());
|
|
|
+ }
|
|
|
+
|
|
|
+ //筛选出需要更新的节点 同时做数据隔离
|
|
|
+ List<WbsTreeContract> editContractNodes = new ArrayList<>();
|
|
|
+ for (WbsTreePrivate templateNode : wbsTreePrivates) {
|
|
|
+ //更新只跟新表单
|
|
|
+ if (templateNode.getType() == 2) {
|
|
|
+ for (WbsTreeContract editContractNode : wbsTreeContracts) {
|
|
|
+ // 判断模板表与项目表 html是否一致
|
|
|
+ if (ObjectUtils.equals(templateNode.getId(), editContractNode.getId())) {
|
|
|
+ if (editContractNode.getExcelId() == null
|
|
|
+ || editContractNode.getHtmlUrl() == null
|
|
|
+ || ObjectUtils.equals(templateNode.getExcelId(), editContractNode.getExcelId())
|
|
|
+ || ObjectUtils.equals(templateNode.getHtmlUrl(), editContractNode.getHtmlUrl())) {
|
|
|
+
|
|
|
+ //清表
|
|
|
+ if (collect.contains(2)) {
|
|
|
+ editContractNode.setExcelId(templateNode.getExcelId());
|
|
|
+ editContractNode.setInitTableName(templateNode.getInitTableName());
|
|
|
+ editContractNode.setHtmlUrl(templateNode.getHtmlUrl());
|
|
|
+ if (templateNode.getExcelId() != null) {
|
|
|
+ editContractNode.setIsLinkTable(2);
|
|
|
+ }
|
|
|
+
|
|
|
+ }
|
|
|
+ //公式
|
|
|
+ if (collect.contains(3)) {
|
|
|
+ editContractNode.setInitTableName(templateNode.getInitTableName());
|
|
|
+ }
|
|
|
+
|
|
|
+
|
|
|
+ //排序
|
|
|
+ if (collect.contains(7)) {
|
|
|
+ editContractNode.setSort(templateNode.getSort());
|
|
|
+ }
|
|
|
+
|
|
|
+ editContractNodes.add(editContractNode);
|
|
|
+ }
|
|
|
+ }
|
|
|
+ }
|
|
|
+ }
|
|
|
+ }
|
|
|
+ //修改数据二次筛选 只保留任务选中的表单 但可能新增的数据包含新节点
|
|
|
+ if (CollectionUtil.isNotEmpty(formList)) {
|
|
|
+ editContractNodes = editContractNodes.stream().filter(f -> formList.contains(f.getPKeyId())).collect(Collectors.toList());
|
|
|
+ }
|
|
|
+
|
|
|
+ //合同段新增节点
|
|
|
+ List<WbsTreeContract> addContractNode = null;
|
|
|
+ if (addPrivateNodes != null) {
|
|
|
+ addContractNode = BeanUtil.copyProperties(addPrivateNodes, WbsTreeContract.class);
|
|
|
+ }
|
|
|
+
|
|
|
+
|
|
|
+ Collections.sort(collect);
|
|
|
+ for (Integer i : collect) {
|
|
|
+ switch (i) {
|
|
|
+ //添加表单
|
|
|
+ case 1:
|
|
|
+ insertContractForm(contractInfo, wbsTreePrivates, addContractNode);
|
|
|
+ //如果同时选择新增表单和其他的同步类型 在操作其他类型的时候需要添加新的表单
|
|
|
+ if (CollectionUtil.isNotEmpty(addContractNode)) {
|
|
|
+ editContractNodes.addAll(addContractNode.stream().filter(f -> f.getType() == 2).collect(Collectors.toList()));
|
|
|
+ }
|
|
|
+ break;
|
|
|
+ //更新
|
|
|
+ case 2:
|
|
|
+ if (CollectionUtil.isNotEmpty(editContractNodes)) {
|
|
|
+ for (WbsTreeContract editContractNode : editContractNodes) {
|
|
|
+ wbsTreeContractMapper.updateById(editContractNode);
|
|
|
+ }
|
|
|
+ }
|
|
|
+ break;
|
|
|
+ case 3:
|
|
|
+ break;
|
|
|
+ case 5:
|
|
|
+ break;
|
|
|
+ //排序
|
|
|
+ case 7:
|
|
|
+
|
|
|
+ if (CollectionUtil.isNotEmpty(editContractNodes)) {
|
|
|
+ for (WbsTreeContract editContractNode : editContractNodes) {
|
|
|
+ wbsTreeContractMapper.updateById(editContractNode);
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
+ break;
|
|
|
+ default:
|
|
|
+ break;
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
+ }
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
+
|
|
|
+ /**
|
|
|
+ * 项目
|
|
|
+ * 类型 1 添加表单
|
|
|
+ *
|
|
|
+ * @param wbsTreePrivates 当前项目对应节点的子节点
|
|
|
+ * @param addPrivateNodes 需要新增的节点
|
|
|
+ */
|
|
|
+ public void insertPrivateForm(List<WbsTreePrivate> wbsTreePrivates, List<WbsTreePrivate> addPrivateNodes) {
|
|
|
+ List<WbsTreePrivate> addData = new ArrayList<>();
|
|
|
+
|
|
|
+ //------------------------------------------------新增-------------------------------------------------------------------------
|
|
|
+ if (CollectionUtil.isNotEmpty(addPrivateNodes)) {
|
|
|
+ //先给每个新增节点赋唯一id,项目id,父级id
|
|
|
+ addPrivateNodes.forEach(f -> f.setPKeyId(SnowFlakeUtil.getId()));
|
|
|
+
|
|
|
+ //给每一个节点的父级id
|
|
|
+ for (WbsTreePrivate addPrivateNode : addPrivateNodes) {
|
|
|
+ if (addPrivateNode.getParentId() == 0) {
|
|
|
+ continue;
|
|
|
+ }
|
|
|
+
|
|
|
+ //查询出当前模板节点的父节点 去获取对应项目节点 如果父节点为0就跳过
|
|
|
+ List<WbsTreePrivate> addPrivateParentNodes = wbsTreePrivates.stream().filter(f -> f.getTreePId().equals(addPrivateNode.getParentId())).collect(Collectors.toList());
|
|
|
+ //如果没有数据 就表示这条数据的父节点也时新增节点 就需要从新增节点集合中找父级节点
|
|
|
+ if (addPrivateParentNodes.isEmpty()) {
|
|
|
+ addPrivateParentNodes = addPrivateNodes.stream().filter(f -> f.getId().equals(addPrivateNode.getParentId())).collect(Collectors.toList());
|
|
|
+ }
|
|
|
+ //如果现在还找不到当前节点的父节点就表示数据有问题
|
|
|
+ if (addPrivateParentNodes.isEmpty()) {
|
|
|
+ //TODO
|
|
|
+ continue;
|
|
|
+ }
|
|
|
+ //当前新增节点的父节点
|
|
|
+ WbsTreePrivate parent = addPrivateParentNodes.get(0);
|
|
|
+
|
|
|
+ addPrivateNode.setPId(parent.getPKeyId());
|
|
|
+ addPrivateNode.setWbsId(parent.getWbsId());
|
|
|
+ addPrivateNode.setWbsType(parent.getWbsType());
|
|
|
+ addPrivateNode.setIsAddConceal(0);
|
|
|
+ addPrivateNode.setProjectId(parent.getProjectId());
|
|
|
+ //TODO 后续如果把p_key_id改成了id做 唯一id
|
|
|
+ addPrivateNode.setTreePId(addPrivateNode.getId());
|
|
|
+ //后续如果使用id做当前表主键 则先在赋值treePid之后再去赋值id addPrivateNode.setId(SnowFlakeUtil.getId());
|
|
|
+ //更新创建时间
|
|
|
+ addPrivateNode.setCreateTime(DateTime.now());
|
|
|
+ }
|
|
|
+ addData.addAll(addPrivateNodes);
|
|
|
+ }
|
|
|
+ //设置html_url----------------------------------------------------------------------------------------------------------
|
|
|
+ //如果有新增的数据 旧设置html_url
|
|
|
+ if (CollectionUtil.isNotEmpty(addData)) {
|
|
|
+ try {
|
|
|
+ String file_path = ParamCache.getValue(CommonConstant.SYS_LOCAL_URL);
|
|
|
+ Set<String> urls = new HashSet<>();
|
|
|
+ for (WbsTreePrivate tree : addData) {
|
|
|
+ if (org.apache.commons.lang3.StringUtils.isNotBlank(tree.getHtmlUrl())) {
|
|
|
+ String[] split = tree.getHtmlUrl().split("/");
|
|
|
+ String htmlUrl = file_path + "privateUrlCopy/" + tree.getPdfUrl() + "/" + split[split.length - 1];
|
|
|
+ if (!urls.contains(tree.getHtmlUrl())) {
|
|
|
+ urls.add(tree.getHtmlUrl());
|
|
|
+ File file_in = ResourceUtil.getFile(tree.getHtmlUrl());
|
|
|
+ if (!file_in.exists() || file_in.length() == 0) {
|
|
|
+ continue;
|
|
|
+ }
|
|
|
+ File file_out = ResourceUtil.getFile(htmlUrl);
|
|
|
+ FileUtil.copy(file_in, file_out);
|
|
|
+ }
|
|
|
+ tree.setHtmlUrl(htmlUrl);
|
|
|
+ }
|
|
|
+ }
|
|
|
+ } catch (Exception e) {
|
|
|
+ System.out.println("重置表单路径错误" + e.getMessage());
|
|
|
+ }
|
|
|
+ //查询出当前项目所有节点---------------------------------------------------------------------------------------------------
|
|
|
+ List<WbsTreePrivate> addList = wbsTreePrivateMapper.selectList(Wrappers.<WbsTreePrivate>lambdaQuery()
|
|
|
+ .select(WbsTreePrivate::getPKeyId, WbsTreePrivate::getPId)
|
|
|
+ .eq(WbsTreePrivate::getIsDeleted, 0)
|
|
|
+ .eq(WbsTreePrivate::getProjectId, addData.get(0).getProjectId()));
|
|
|
+
|
|
|
+ addList.addAll(addData);
|
|
|
+ //组合祖级路径 根据当前选中节点为开始
|
|
|
+ Map<Long, WbsTreePrivate> collect = addList.stream().collect(Collectors.toMap(WbsTreePrivate::getPKeyId, Function.identity()));
|
|
|
+
|
|
|
+ addData.forEach(node -> {
|
|
|
+ String correctAncestors = createAncestorsPId(node, collect);
|
|
|
+ node.setAncestorsPId(correctAncestors);
|
|
|
+ });
|
|
|
+
|
|
|
+ //新增-----------------------------------------------------------------------------------------------------------------
|
|
|
+ List<List<WbsTreePrivate>> partition = Lists.partition(addData, 1000);
|
|
|
+ Integer count = 0;
|
|
|
+ for (List<WbsTreePrivate> data : partition) {
|
|
|
+ //单个批次一个事务,只会回滚当前批次数据
|
|
|
+ Integer i = wbsTreePrivateMapper.insertBatchSomeColumn(data);
|
|
|
+ //如果失败 -- - - - - 继续执行 或者把当前节点的p_key_id 记录到某个地方 方便后续处理
|
|
|
+ if (i == 0) {
|
|
|
+ List<Long> collect1 = addData.stream().map(WbsTreePrivate::getPKeyId).collect(Collectors.toList());
|
|
|
+ //这里可以保存到数据库指定错误日志表
|
|
|
+
|
|
|
+ }
|
|
|
+
|
|
|
+ count += i;
|
|
|
+ }
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
+ /**
|
|
|
+ * 合同段添加表单
|
|
|
+ * 合同段添加表单
|
|
|
+ */
|
|
|
+ public void insertContractForm(ContractInfo contractInfo, List<WbsTreePrivate> wbsTreePrivates, List<WbsTreeContract> addContractNodes) {
|
|
|
+ List<WbsTreeContract> addData = new ArrayList<>();
|
|
|
+
|
|
|
+
|
|
|
+ if (CollectionUtil.isNotEmpty(addContractNodes)) {
|
|
|
+ //源节点数据
|
|
|
+ List<WbsTreeContract> wbsTreeContracts = BeanUtil.copyProperties(wbsTreePrivates, WbsTreeContract.class);
|
|
|
+
|
|
|
+
|
|
|
+ //选给新增的节点赋值
|
|
|
+ addContractNodes.forEach(f -> {
|
|
|
+ f.setPKeyId(SnowFlakeUtil.getId());
|
|
|
+ });
|
|
|
+
|
|
|
+ for (WbsTreeContract addContractNode : addContractNodes) {
|
|
|
+ if (addContractNode.getParentId() == 0) {
|
|
|
+ continue;
|
|
|
+ }
|
|
|
+
|
|
|
+ //查询出当前模板节点的父节点 去获取对应项目节点 如果父节点为0就跳过
|
|
|
+ List<WbsTreeContract> addContractParentNodes = wbsTreeContracts.stream().filter(f -> f.getTreePId().equals(addContractNode.getParentId())).collect(Collectors.toList());
|
|
|
+
|
|
|
+ //如果没有数据 就表示这条数据的父节点也时新增节点 就需要从新增节点集合中找父级节点
|
|
|
+ if (addContractParentNodes.isEmpty()) {
|
|
|
+ addContractParentNodes = addContractNodes.stream().filter(f -> f.getId().equals(addContractNode.getParentId())).collect(Collectors.toList());
|
|
|
+ }
|
|
|
+ //如果现在还找不到当前节点的父节点就表示数据有问题
|
|
|
+ if (addContractParentNodes.isEmpty()) {
|
|
|
+ //TODO
|
|
|
+ continue;
|
|
|
+ }
|
|
|
+ //当前新增节点的父节点
|
|
|
+ WbsTreeContract parent = addContractParentNodes.get(0);
|
|
|
+
|
|
|
+ addContractNode.setIsBussShow(1);
|
|
|
+ addContractNode.setIsDeleted(0);
|
|
|
+ addContractNode.setStatus(1);
|
|
|
+ //记录原始表的pKeyId
|
|
|
+ addContractNode.setIsTypePrivatePid(parent.getPKeyId());
|
|
|
+ addContractNode.setParentId(parent.getId());
|
|
|
+ addContractNode.setAncestors(parent.getAncestors() + "," + parent.getId());
|
|
|
+ //TODO
|
|
|
+ addContractNode.setTreePId(addContractNode.getId());
|
|
|
+ //TODO
|
|
|
+ addContractNode.setPId(parent.getPKeyId());
|
|
|
+ //TODO
|
|
|
+ addContractNode.setContractId(parent.getContractId());
|
|
|
+ addContractNode.setContractId(String.valueOf(contractInfo.getId()));
|
|
|
+ //更新创建时间
|
|
|
+ addContractNode.setCreateTime(DateTime.now());
|
|
|
+ }
|
|
|
+ addData.addAll(addContractNodes);
|
|
|
+ }
|
|
|
+
|
|
|
+
|
|
|
+ //查询出当前项目所有节点---------------------------------------------------------------------------------------------------
|
|
|
+ List<WbsTreeContract> addList = wbsTreeContractMapper.selectList(Wrappers.<WbsTreeContract>lambdaQuery()
|
|
|
+ .select(WbsTreeContract::getPKeyId, WbsTreeContract::getPId)
|
|
|
+ .eq(WbsTreeContract::getIsDeleted, 0)
|
|
|
+ .eq(WbsTreeContract::getContractId, contractInfo.getId()));
|
|
|
+
|
|
|
+ addList.addAll(addData);
|
|
|
+
|
|
|
+
|
|
|
+ //组合祖级路径 根据当前选中节点为开始
|
|
|
+ Map<Long, WbsTreeContract> collect = addList.stream().collect(Collectors.toMap(WbsTreeContract::getPKeyId, Function.identity()));
|
|
|
+
|
|
|
+ addData.forEach(node -> {
|
|
|
+ //通过转换为WbsTreePrivate的方式 去获取祖级节点
|
|
|
+ String correctAncestors = createAncestorsPId(node, collect);
|
|
|
+ node.setAncestorsPId(correctAncestors);
|
|
|
+ });
|
|
|
+
|
|
|
+ //新增-----------------------------------------------------------------------------------------------------------------
|
|
|
+ List<List<WbsTreeContract>> partition = Lists.partition(addData, 1000);
|
|
|
+ for (List<WbsTreeContract> data : partition) {
|
|
|
+ //单个批次一个事务,只会回滚当前批次数据
|
|
|
+ Integer i = wbsTreeContractMapper.insertBatchSomeColumn(data);
|
|
|
+ //如果失败 -- - - - - 继续执行 或者把当前节点的p_key_id 记录到某个地方 方便后续处理
|
|
|
+ if (i == 0) {
|
|
|
+ List<Long> collect1 = addData.stream().map(WbsTreeContract::getPKeyId).collect(Collectors.toList());
|
|
|
+ //这里可以保存到数据库指定错误日志表
|
|
|
+ }
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
+
|
|
|
+ /**
|
|
|
+ * 项目同步电签
|
|
|
+ *
|
|
|
+ * @param collect 需要修改的节点
|
|
|
+ * @param templateId 同步源项目ID
|
|
|
+ * @param projectId 当前项目ID
|
|
|
+ * @param editPrivateNodes 模板对应的节点
|
|
|
+ * @param editPrivateNodes 需要修改的节点
|
|
|
+ */
|
|
|
+ private void updateEViSa(List<Integer> collect, Long templateId, Long projectId, List<WbsTreePrivate> treePrivates,List<WbsTreePrivate> editPrivateNodes) {
|
|
|
+
|
|
|
+
|
|
|
+
|
|
|
+ //封装map
|
|
|
+
|
|
|
+ List<Long> privateIds = editPrivateNodes.stream().map(WbsTreePrivate::getPKeyId).collect(Collectors.toList());
|
|
|
+
|
|
|
+ //源项目电签和默认值信息
|
|
|
+ List<TextdictInfo> tempTextDictInfo = textdictInfoMapper.selectList(Wrappers.<TextdictInfo>lambdaQuery()
|
|
|
+ .eq(TextdictInfo::getProjectId, templateId)
|
|
|
+ .eq(TextdictInfo::getIsDeleted, 0)
|
|
|
+ .in(TextdictInfo::getTabId, privateIds)
|
|
|
+ .in(TextdictInfo::getType, 2, 4, 6));
|
|
|
+
|
|
|
+ Map<Integer, List<TextdictInfo>> tempTextDictInfoMap = tempTextDictInfo.stream().collect(Collectors.groupingBy(TextdictInfo::getType));
|
|
|
+
|
|
|
+
|
|
|
+
|
|
|
+
|
|
|
+
|
|
|
+ //电签
|
|
|
+ if (collect.contains(3)) {
|
|
|
+ List<TextdictInfo> tempViSa = new ArrayList<>();
|
|
|
+ //个人电签
|
|
|
+ List<TextdictInfo> tempMyViSa = tempTextDictInfoMap.get(2);
|
|
|
+ if (CollectionUtil.isNotEmpty(tempMyViSa)) {
|
|
|
+ tempViSa.addAll(tempMyViSa);
|
|
|
+
|
|
|
+ }
|
|
|
+ //企业电签
|
|
|
+ List<TextdictInfo> tempEnterViSa = tempTextDictInfoMap.get(6);
|
|
|
+ if (CollectionUtil.isNotEmpty(tempEnterViSa)) {
|
|
|
+ tempViSa.addAll(tempEnterViSa);
|
|
|
+ }
|
|
|
+
|
|
|
+ if (CollectionUtil.isNotEmpty(tempViSa)) {
|
|
|
+ for (TextdictInfo textdictInfo : tempViSa) {
|
|
|
+ textdictInfo.setId(SnowFlakeUtil.getId());
|
|
|
+ textdictInfo.setProjectId(String.valueOf(projectId));
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
+ }
|
|
|
+ //默认值
|
|
|
+ if (collect.contains(5)) {
|
|
|
+ List<TextdictInfo> tempDefault = tempTextDictInfoMap.get(4);
|
|
|
+ if(CollectionUtil.isNotEmpty(tempDefault)){
|
|
|
+
|
|
|
+ for (TextdictInfo textdictInfo : tempDefault) {
|
|
|
+ textdictInfo.setId(SnowFlakeUtil.getId());
|
|
|
+ textdictInfo.setProjectId(String.valueOf(projectId));
|
|
|
+ }
|
|
|
+
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
+
|
|
|
+ }
|
|
|
+
|
|
|
+
|
|
|
+ /**
|
|
|
+ * 20250414-lhb-新增
|
|
|
+ * 创建祖级路径
|
|
|
+ * <p>
|
|
|
+ * 该方法用于构建给定节点的祖先路径标识符(PId)字符串
|
|
|
+ * 它通过追溯节点的父节点,直到达到根节点或满足特定条件为止
|
|
|
+ *
|
|
|
+ * @param node WbsTreeContract类型的节点,表示需要构建路径的起始节点
|
|
|
+ * @param nodeMap 一个映射,其键为节点ID,值为WbsTreeContract类型的节点对象,用于快速查找节点
|
|
|
+ * @return 返回一个字符串,表示构建的祖先路径标识符序列,以逗号分隔
|
|
|
+ */
|
|
|
+ private String createAncestorsPId(WbsTreePrivate node, Map<Long, WbsTreePrivate> nodeMap) {
|
|
|
+ // 初始化路径列表,用于存储祖先节点的ID
|
|
|
+ List<Long> path = new ArrayList<>();
|
|
|
+ // 从给定的节点开始
|
|
|
+ WbsTreePrivate current = node;
|
|
|
+ // 初始化访问集合,用于检测循环引用
|
|
|
+ Set<Long> visited = new HashSet<>();
|
|
|
+
|
|
|
+ while (true) {
|
|
|
+ // 检查当前节点是否为根节点或无效节点
|
|
|
+ if (current == null || current.getPId() == null ||
|
|
|
+ current.getPId() == 0 || current.getPId().equals(current.getPKeyId())) {
|
|
|
+ break;
|
|
|
+ }
|
|
|
+
|
|
|
+ // 检测循环引用
|
|
|
+ if (visited.contains(current.getPId())) {
|
|
|
+ break;
|
|
|
+ }
|
|
|
+ // 将当前节点的ID添加到已访问集合中
|
|
|
+ visited.add(current.getPKeyId());
|
|
|
+
|
|
|
+ // 从映射中获取当前节点的父节点
|
|
|
+ current = nodeMap.get(current.getPId());
|
|
|
+ // 如果父节点存在,则将其ID添加到路径列表的开头
|
|
|
+ if (current != null) {
|
|
|
+ path.add(0, current.getPKeyId());
|
|
|
+ }
|
|
|
+
|
|
|
+ // 安全限制,防止路径过长导致性能问题
|
|
|
+ if (path.size() > 50) {
|
|
|
+ break;
|
|
|
+ }
|
|
|
+ }
|
|
|
+ // 将根节点ID(0)添加到路径的最前面,表示路径的起点
|
|
|
+ path.add(0, 0L);
|
|
|
+ // 将路径列表转换为字符串并返回
|
|
|
+ return String.join(",", path.stream().map(String::valueOf).toArray(String[]::new));
|
|
|
+ }
|
|
|
+
|
|
|
+ /**
|
|
|
+ * 20250414-lhb-新增
|
|
|
+ * 创建祖级路径
|
|
|
+ * <p>
|
|
|
+ * 该方法用于构建给定节点的祖先路径标识符(PId)字符串
|
|
|
+ * 它通过追溯节点的父节点,直到达到根节点或满足特定条件为止
|
|
|
+ *
|
|
|
+ * @param node WbsTreeContract类型的节点,表示需要构建路径的起始节点
|
|
|
+ * @param nodeMap 一个映射,其键为节点ID,值为WbsTreeContract类型的节点对象,用于快速查找节点
|
|
|
+ * @return 返回一个字符串,表示构建的祖先路径标识符序列,以逗号分隔
|
|
|
+ */
|
|
|
+ private String createAncestorsPId(WbsTreeContract node, Map<Long, WbsTreeContract> nodeMap) {
|
|
|
+ // 初始化路径列表,用于存储祖先节点的ID
|
|
|
+ List<Long> path = new ArrayList<>();
|
|
|
+ // 从给定的节点开始
|
|
|
+ WbsTreeContract current = node;
|
|
|
+ // 初始化访问集合,用于检测循环引用
|
|
|
+ Set<Long> visited = new HashSet<>();
|
|
|
+
|
|
|
+ while (true) {
|
|
|
+ // 检查当前节点是否为根节点或无效节点
|
|
|
+ if (current == null || current.getPId() == null ||
|
|
|
+ current.getPId() == 0 || current.getPId().equals(current.getPKeyId())) {
|
|
|
+ break;
|
|
|
+ }
|
|
|
+
|
|
|
+ // 检测循环引用
|
|
|
+ if (visited.contains(current.getPId())) {
|
|
|
+ break;
|
|
|
+ }
|
|
|
+ // 将当前节点的ID添加到已访问集合中
|
|
|
+ visited.add(current.getPKeyId());
|
|
|
+
|
|
|
+ // 从映射中获取当前节点的父节点
|
|
|
+ current = nodeMap.get(current.getPId());
|
|
|
+ // 如果父节点存在,则将其ID添加到路径列表的开头
|
|
|
+ if (current != null) {
|
|
|
+ path.add(0, current.getPKeyId());
|
|
|
+ }
|
|
|
+
|
|
|
+ // 安全限制,防止路径过长导致性能问题
|
|
|
+ if (path.size() > 50) {
|
|
|
+ break;
|
|
|
+ }
|
|
|
+ }
|
|
|
+ // 将根节点ID(0)添加到路径的最前面,表示路径的起点
|
|
|
+ path.add(0, 0L);
|
|
|
+ // 将路径列表转换为字符串并返回
|
|
|
+ return String.join(",", path.stream().map(String::valueOf).toArray(String[]::new));
|
|
|
+ }
|
|
|
+
|
|
|
+
|
|
|
+ /**
|
|
|
+ * 根据选中节点id 同步新增节点和新增表单
|
|
|
+ *
|
|
|
+ * @param primaryKeyId
|
|
|
+ * @return
|
|
|
+ */
|
|
|
+
|
|
|
+ public void test(String primaryKeyId) {
|
|
|
+
|
|
|
+ if (StringUtils.isNotEmpty(primaryKeyId)) {
|
|
|
+ //获取当前节点对应节点信息
|
|
|
+ WbsTreePrivate wbsTreePrivate = wbsTreePrivateMapper.selectOne(Wrappers.<WbsTreePrivate>lambdaQuery().eq(WbsTreePrivate::getPKeyId, primaryKeyId));
|
|
|
+
|
|
|
+ //获取项目信息
|
|
|
+ ProjectInfo projectInfo = projectInfoMapper.selectOne(Wrappers.<ProjectInfo>lambdaQuery().eq(ProjectInfo::getId, wbsTreePrivate.getProjectId()));
|
|
|
+
|
|
|
+ //当前项目模板对应的节点信息
|
|
|
+
|
|
|
+ List<WbsTreePrivate> templateNodes = new ArrayList<>();
|
|
|
+
|
|
|
+ //结果集
|
|
|
+ List<WbsTreePrivate> addData = new ArrayList<>();
|
|
|
+ //质检
|
|
|
+ //当前节点引用的模板为公有模板
|
|
|
+
|
|
|
+ if (("public").equals(projectInfo.getReferenceWbsTemplateType())) {
|
|
|
+ //当前节点对应的模板节点信息
|
|
|
+ WbsTree wbsTreeTemplate = wbsTreeMapper.selectOne(Wrappers.<WbsTree>lambdaQuery()
|
|
|
+ .eq(WbsTree::getId, wbsTreePrivate.getTreePId()));
|
|
|
+ //获取模板中当前节点的子节点的数据------------------------------------------------------------------------------------------------------------------------
|
|
|
+ LambdaQueryWrapper<WbsTree> wrapperTree = Wrappers.lambdaQuery();
|
|
|
+ wrapperTree.eq(WbsTree::getWbsId, wbsTreePrivate.getWbsId())
|
|
|
+ .eq(WbsTree::getIsDeleted, 0);
|
|
|
+ if (wbsTreeTemplate.getParentId() != 0) {
|
|
|
+ wrapperTree.apply("FIND_IN_SET({0},ancestors)", wbsTreeTemplate.getId());
|
|
|
+ }
|
|
|
+ //模板节点的所有子节点信息
|
|
|
+ List<WbsTree> wbsTrees = wbsTreeMapper.selectList(wrapperTree);
|
|
|
+ //3、获取需要新增的节点或者表单节点信息 以及他们对应的父级节点信息--------------------------------------------------------------------------------------------
|
|
|
+ if (CollectionUtil.isEmpty(wbsTrees)) {
|
|
|
+ throw new ServiceException("模板节点未找到");
|
|
|
+ }
|
|
|
+ templateNodes = BeanUtil.copyProperties(wbsTrees, WbsTreePrivate.class);
|
|
|
+
|
|
|
+ } else if (("private").equals(projectInfo.getReferenceWbsTemplateType())) {
|
|
|
+ //根据wbsTreePrivate的wbsId=私有引用的pKeyId来获取引用树根节点
|
|
|
+ WbsTreePrivate wbsTreePrivateRoot = wbsTreePrivateMapper.selectOne(Wrappers.<WbsTreePrivate>lambdaQuery()
|
|
|
+ .eq(WbsTreePrivate::getPKeyId, wbsTreePrivate.getWbsId()));
|
|
|
+
|
|
|
+ //获取当前选中节点与私有模板对应的节点信息 父级模板项目的当前选中节点
|
|
|
+ wbsTreePrivateRoot = wbsTreePrivateMapper.selectOne(Wrappers.<WbsTreePrivate>lambdaQuery()
|
|
|
+ .eq(WbsTreePrivate::getProjectId, wbsTreePrivateRoot.getProjectId())
|
|
|
+ .eq(WbsTreePrivate::getTreePId, wbsTreePrivate.getTreePId()));
|
|
|
+
|
|
|
+ //获取模板中当前节点的子节点的数据------------------------------------------------------------------------------------------------------------------------
|
|
|
+ LambdaQueryWrapper<WbsTreePrivate> wrapperPrivate = Wrappers.lambdaQuery();
|
|
|
+ wrapperPrivate.eq(WbsTreePrivate::getProjectId, wbsTreePrivateRoot.getProjectId())
|
|
|
+ .eq(WbsTreePrivate::getIsDeleted, 0);
|
|
|
+ //判断如果为顶级顶级节点
|
|
|
+ if (wbsTreePrivate.getTreePId() != 0) {
|
|
|
+ wrapperPrivate.apply("FIND_IN_SET({0},ancestors_p_id)", wbsTreePrivateRoot.getPId());
|
|
|
+ }
|
|
|
+ templateNodes = wbsTreePrivateMapper.selectList(wrapperPrivate);
|
|
|
+ }
|
|
|
+
|
|
|
+ if (CollectionUtil.isEmpty(templateNodes)) {
|
|
|
+ throw new ServiceException("未找到模板对应节点");
|
|
|
+ }
|
|
|
+
|
|
|
+
|
|
|
+ //2、获取当前节点的子节点的数据------------------------------------------------------------------------------------------------------------------------
|
|
|
+ LambdaQueryWrapper<WbsTreePrivate> wrapperPrivate = Wrappers.lambdaQuery();
|
|
|
+ wrapperPrivate.eq(WbsTreePrivate::getWbsId, wbsTreePrivate.getWbsId()).eq(WbsTreePrivate::getIsDeleted, 0);
|
|
|
+ //判断如果为顶级顶级节点
|
|
|
+ if (wbsTreePrivate.getTreePId() != 0) {
|
|
|
+ wrapperPrivate.apply("FIND_IN_SET({0},ancestors_p_id)", wbsTreePrivate.getPId());
|
|
|
+ }
|
|
|
+ List<WbsTreePrivate> wbsTreePrivates = wbsTreePrivateMapper.selectList(wrapperPrivate);
|
|
|
+
|
|
|
+ if (wbsTreePrivates.isEmpty()) {
|
|
|
+ throw new ServiceException("无法找到模板对应节点,请检查模板节点");
|
|
|
+ }
|
|
|
+ //获取id 和 tree_p_id 组成的集合
|
|
|
+ Set<Long> ids = wbsTreePrivates.stream().map(WbsTreePrivate::getTreePId).collect(Collectors.toSet());
|
|
|
+ //3.1筛选出需要新增的节点
|
|
|
+ List<WbsTreePrivate> addPrivateNodes = templateNodes.stream()
|
|
|
+ .filter(f -> !ids.contains(f.getId()))
|
|
|
+ .collect(Collectors.toList());
|
|
|
+ //------------------------------------------------新增-------------------------------------------------------------------------
|
|
|
+ if (CollectionUtil.isNotEmpty(addPrivateNodes)) {
|
|
|
+ //先给每个新增节点赋唯一id,项目id,父级id
|
|
|
+ addPrivateNodes.forEach(f -> f.setPKeyId(SnowFlakeUtil.getId()));
|
|
|
+
|
|
|
+ //给每一个节点的父级id
|
|
|
+ for (WbsTreePrivate addPrivateNode : addPrivateNodes) {
|
|
|
+ if (addPrivateNode.getParentId() == 0) {
|
|
|
+ continue;
|
|
|
+ }
|
|
|
+
|
|
|
+ //查询出当前模板节点的父节点 去获取对应项目节点 如果父节点为0就跳过
|
|
|
+ List<WbsTreePrivate> addPrivateParentNodes = wbsTreePrivates.stream().filter(f -> f.getTreePId().equals(addPrivateNode.getParentId())).collect(Collectors.toList());
|
|
|
+ //如果没有数据 就表示这条数据的父节点也时新增节点 就需要从新增节点集合中找父级节点
|
|
|
+ if (addPrivateParentNodes.isEmpty()) {
|
|
|
+ addPrivateParentNodes = addPrivateNodes.stream().filter(f -> f.getId().equals(addPrivateNode.getParentId())).collect(Collectors.toList());
|
|
|
+ }
|
|
|
+ //如果现在还找不到当前节点的父节点就表示数据有问题
|
|
|
+ if (addPrivateParentNodes.isEmpty()) {
|
|
|
+ //TODO
|
|
|
+ continue;
|
|
|
+ }
|
|
|
+ //当前新增节点的父节点
|
|
|
+ WbsTreePrivate parent = addPrivateParentNodes.get(0);
|
|
|
+
|
|
|
+ addPrivateNode.setPId(parent.getPKeyId());
|
|
|
+ addPrivateNode.setWbsId(parent.getWbsId());
|
|
|
+ addPrivateNode.setWbsType(wbsTreePrivate.getWbsType());
|
|
|
+ addPrivateNode.setIsAddConceal(0);
|
|
|
+ addPrivateNode.setProjectId(wbsTreePrivate.getProjectId());
|
|
|
+ //TODO 后续如果把p_key_id改成了id做 唯一id
|
|
|
+ addPrivateNode.setTreePId(addPrivateNode.getId());
|
|
|
+ //后续如果使用id做当前表主键 则先在赋值treePid之后再去赋值id addPrivateNode.setId(SnowFlakeUtil.getId());
|
|
|
+ }
|
|
|
+ addData.addAll(addPrivateNodes);
|
|
|
+ }
|
|
|
+
|
|
|
+
|
|
|
+ //设置html_url----------------------------------------------------------------------------------------------------------
|
|
|
+ //如果有新增的数据 旧设置html_url
|
|
|
+ if (CollectionUtil.isNotEmpty(addData)) {
|
|
|
+ try {
|
|
|
+ String file_path = ParamCache.getValue(CommonConstant.SYS_LOCAL_URL);
|
|
|
+ Set<String> urls = new HashSet<>();
|
|
|
+ for (WbsTreePrivate tree : addData) {
|
|
|
+ if (org.apache.commons.lang3.StringUtils.isNotBlank(tree.getHtmlUrl())) {
|
|
|
+ String[] split = tree.getHtmlUrl().split("/");
|
|
|
+ String htmlUrl = file_path + "privateUrlCopy/" + tree.getPdfUrl() + "/" + split[split.length - 1];
|
|
|
+ if (!urls.contains(tree.getHtmlUrl())) {
|
|
|
+ urls.add(tree.getHtmlUrl());
|
|
|
+ File file_in = ResourceUtil.getFile(tree.getHtmlUrl());
|
|
|
+ if (!file_in.exists() || file_in.length() == 0) {
|
|
|
+ continue;
|
|
|
+ }
|
|
|
+ File file_out = ResourceUtil.getFile(htmlUrl);
|
|
|
+ FileUtil.copy(file_in, file_out);
|
|
|
+ }
|
|
|
+ tree.setHtmlUrl(htmlUrl);
|
|
|
+ }
|
|
|
+ }
|
|
|
+ } catch (Exception e) {
|
|
|
+ throw new ServiceException("重置表单路径错误");
|
|
|
+ }
|
|
|
+ //查询出当前项目所有节点---------------------------------------------------------------------------------------------------
|
|
|
+ List<WbsTreePrivate> addList = wbsTreePrivateMapper.selectList(Wrappers.<WbsTreePrivate>lambdaQuery()
|
|
|
+ .select(WbsTreePrivate::getPKeyId, WbsTreePrivate::getPId)
|
|
|
+ .eq(WbsTreePrivate::getIsDeleted, 0)
|
|
|
+ .eq(WbsTreePrivate::getProjectId, wbsTreePrivate.getProjectId()));
|
|
|
+
|
|
|
+ addList.addAll(addData);
|
|
|
+ //组合祖级路径 根据当前选中节点为开始
|
|
|
+ Map<Long, WbsTreePrivate> collect = addList.stream().collect(Collectors.toMap(WbsTreePrivate::getPKeyId, Function.identity()));
|
|
|
+
|
|
|
+ addData.forEach(node -> {
|
|
|
+ String correctAncestors = createAncestorsPId(node, collect);
|
|
|
+ node.setAncestorsPId(correctAncestors);
|
|
|
+ });
|
|
|
+
|
|
|
+ //新增-----------------------------------------------------------------------------------------------------------------
|
|
|
+ List<List<WbsTreePrivate>> partition = Lists.partition(addData, 1000);
|
|
|
+ for (List<WbsTreePrivate> data : partition) {
|
|
|
+ //单个批次一个事务,只会回滚当前批次数据
|
|
|
+ Integer i = wbsTreePrivateMapper.insertBatchSomeColumn(data);
|
|
|
+ //如果失败 -- - - - - 继续执行 或者把当前节点的p_key_id 记录到某个地方 方便后续处理
|
|
|
+ if (i == 0) {
|
|
|
+ List<Long> collect1 = addData.stream().map(WbsTreePrivate::getPKeyId).collect(Collectors.toList());
|
|
|
+ //这里可以保存到数据库指定错误日志表
|
|
|
+ throw new ServiceException("新增节点失败,请联系后台人员");
|
|
|
+ }
|
|
|
+ }
|
|
|
+ //记录同步信息
|
|
|
+ }
|
|
|
+ } else {
|
|
|
+ throw new ServiceException("未传指定参数,请联系后台人员");
|
|
|
+ }
|
|
|
+ }
|
|
|
+}
|