Selaa lähdekoodia

Merge branch 'master' of http://47.110.251.215:3000/java_org/bladex

huangtf 2 vuotta sitten
vanhempi
commit
38b0734261
36 muutettua tiedostoa jossa 931 lisäystä ja 251 poistoa
  1. 40 0
      blade-common/src/main/java/org/springblade/common/utils/FileUtils.java
  2. 3 0
      blade-service-api/blade-business-api/src/main/java/org/springblade/business/feign/ArchiveFileClient.java
  3. 7 2
      blade-service-api/blade-business-api/src/main/java/org/springblade/business/feign/InformationQueryClient.java
  4. 7 0
      blade-service-api/blade-manager-api/src/main/java/org/springblade/manager/dto/FormData.java
  5. 9 0
      blade-service-api/blade-manager-api/src/main/java/org/springblade/manager/dto/FormulaDataBlockVo.java
  6. 0 5
      blade-service-api/blade-manager-api/src/main/java/org/springblade/manager/dto/RangeInfo.java
  7. 28 0
      blade-service-api/blade-manager-api/src/main/java/org/springblade/manager/entity/FormulaDataBlock.java
  8. 3 0
      blade-service-api/blade-manager-api/src/main/java/org/springblade/manager/feign/WbsTreeContractClient.java
  9. 17 0
      blade-service/blade-archive/src/main/java/org/springblade/archive/controller/ArchiveFileController.java
  10. 152 130
      blade-service/blade-business/src/main/java/org/springblade/business/controller/InformationWriteQueryController.java
  11. 20 0
      blade-service/blade-business/src/main/java/org/springblade/business/feignClient/ArchiveFileClientImpl.java
  12. 6 0
      blade-service/blade-business/src/main/java/org/springblade/business/feignClient/InformationQueryClientImpl.java
  13. 2 0
      blade-service/blade-business/src/main/java/org/springblade/business/mapper/ArchiveFileMapper.java
  14. 6 0
      blade-service/blade-business/src/main/java/org/springblade/business/mapper/ArchiveFileMapper.xml
  15. 4 2
      blade-service/blade-business/src/main/java/org/springblade/business/mapper/InformationQueryMapper.xml
  16. 4 0
      blade-service/blade-business/src/main/java/org/springblade/business/service/IInformationQueryService.java
  17. 8 1
      blade-service/blade-business/src/main/java/org/springblade/business/service/impl/InformationQueryServiceImpl.java
  18. 6 0
      blade-service/blade-manager/pom.xml
  19. 30 0
      blade-service/blade-manager/src/main/java/com/mixsmart/utils/CustomFunction.java
  20. 40 5
      blade-service/blade-manager/src/main/java/com/mixsmart/utils/FormulaUtils.java
  21. 4 94
      blade-service/blade-manager/src/main/java/com/mixsmart/utils/StringUtils.java
  22. 9 1
      blade-service/blade-manager/src/main/java/org/springblade/manager/feign/WbsTreeContractClientImpl.java
  23. 25 0
      blade-service/blade-manager/src/main/java/org/springblade/manager/formula/ElementBlock.java
  24. 55 0
      blade-service/blade-manager/src/main/java/org/springblade/manager/formula/ItemBlock.java
  25. 18 0
      blade-service/blade-manager/src/main/java/org/springblade/manager/formula/NodeTable.java
  26. 32 0
      blade-service/blade-manager/src/main/java/org/springblade/manager/formula/TableEleKey.java
  27. 10 0
      blade-service/blade-manager/src/main/java/org/springblade/manager/formula/impl/AssessmentForm.java
  28. 52 0
      blade-service/blade-manager/src/main/java/org/springblade/manager/formula/impl/Measurement.java
  29. 1 1
      blade-service/blade-manager/src/main/java/org/springblade/manager/formula/impl/TableElementConverter.java
  30. 11 0
      blade-service/blade-manager/src/main/java/org/springblade/manager/mapper/FormulaDataBlockMapper.java
  31. 2 0
      blade-service/blade-manager/src/main/java/org/springblade/manager/mapper/WbsTreeContractMapper.java
  32. 9 0
      blade-service/blade-manager/src/main/java/org/springblade/manager/mapper/WbsTreeContractMapper.xml
  33. 14 0
      blade-service/blade-manager/src/main/java/org/springblade/manager/service/IFormulaDataBlockService.java
  34. 32 0
      blade-service/blade-manager/src/main/java/org/springblade/manager/service/impl/FormulaDataBlockServiceImpl.java
  35. 263 7
      blade-service/blade-manager/src/main/java/org/springblade/manager/service/impl/FormulaServiceImpl.java
  36. 2 3
      blade-service/blade-manager/src/main/java/org/springblade/manager/service/impl/WbsTreeContractServiceImpl.java

+ 40 - 0
blade-common/src/main/java/org/springblade/common/utils/FileUtils.java

@@ -9,6 +9,7 @@ import java.io.FileOutputStream;
 import java.io.IOException;
 import java.net.URL;
 import java.net.URLConnection;
+import java.text.DecimalFormat;
 import java.util.ArrayList;
 import java.util.List;
 import java.util.Objects;
@@ -58,4 +59,43 @@ public class FileUtils  {
         return  reData;
     }
 
+    //获取OSS文件总大小
+    public static Long getOssFileSizeCount(List<String> fileList){
+        Long count = 0L;
+        if(fileList!=null){
+            for(String fileUrl:fileList){
+                try {
+                    URLConnection  openConnection = new URL(fileUrl).openConnection();
+                    count += openConnection.getContentLength();
+
+                } catch (IOException e) {
+                    e.printStackTrace();
+                }
+            }
+        }
+        return count;
+    }
+
+    /**
+     * 根据字节返回文件大小
+     */
+    public static String formatSize(long fileS) {
+        DecimalFormat df = new DecimalFormat("#.00");
+        String fileSizeString = "";
+        String wrongSize = "0B";
+        if (fileS == 0) {
+            return wrongSize;
+        }
+        if (fileS < 1024) {
+            fileSizeString = df.format((double) fileS) + "B";
+        } else if (fileS < 1048576) {
+            fileSizeString = df.format((double) fileS / 1024) + "KB";
+        } else if (fileS < 1073741824) {
+            fileSizeString = df.format((double) fileS / 1048576) + "MB";
+        } else {
+            fileSizeString = df.format((double) fileS / 1073741824) + "GB";
+        }
+        return fileSizeString;
+    }
+
 }

+ 3 - 0
blade-service-api/blade-business-api/src/main/java/org/springblade/business/feign/ArchiveFileClient.java

@@ -70,4 +70,7 @@ public interface ArchiveFileClient {
 
     @PostMapping(API_PREFIX + "/getAllArchiveFileByContractType")
     List<Map<String,Object>> getAllArchiveFileByContractType(@RequestBody Long projectId);
+
+    @PostMapping(API_PREFIX + "/getAllArchiveFileSize")
+    Long getAllArchiveFileSize(@RequestBody Long projectId);
 }

+ 7 - 2
blade-service-api/blade-business-api/src/main/java/org/springblade/business/feign/InformationQueryClient.java

@@ -28,11 +28,12 @@ public interface InformationQueryClient {
 
     /**
      * 获取当前合同树和所有已填报表信息
+     *
      * @param contractId
      * @return
      */
     @PostMapping(API_PREFIX + "/getTreeAllTable")
-    Map<String,Long> getTreeAllTable(@RequestParam String contractId);
+    Map<String, Long> getTreeAllTable(@RequestParam String contractId);
 
     /**
      * 保存填报时新增或修改填报资料记录表数据
@@ -64,6 +65,10 @@ public interface InformationQueryClient {
 
     // 更新redis数据
     @PostMapping(API_PREFIX + "/AsyncWbsTree")
-    void  AsyncWbsTree(@RequestParam String primaryKeyId,@RequestParam String parentId,@RequestParam String contractId,@RequestParam String contractIdRelation,@RequestParam String classifyType);
+    void AsyncWbsTree(@RequestParam String primaryKeyId, @RequestParam String parentId, @RequestParam String contractId, @RequestParam String contractIdRelation, @RequestParam String classifyType);
+
+    // 删除更新redis数据
+    @PostMapping(API_PREFIX + "/delAsyncWbsTree")
+    void delAsyncWbsTree(@RequestParam String parentId, @RequestParam String contractId,@RequestParam String classifyType);
 
 }

+ 7 - 0
blade-service-api/blade-manager-api/src/main/java/org/springblade/manager/dto/FormData.java

@@ -133,6 +133,13 @@ public class FormData {
             return msg;
         }
     }
+    public Integer getMaxRow(){
+        return coordsList.stream().mapToInt(Coords::getY).max().orElse(0);
+    }
+    public Integer getMaxCol(){
+        return coordsList.stream().mapToInt(Coords::getX).max().orElse(0);
+    }
+
 
     /**是否还需要执行公式*/
     public Boolean verify(){

+ 9 - 0
blade-service-api/blade-manager-api/src/main/java/org/springblade/manager/dto/FormulaDataBlockVo.java

@@ -0,0 +1,9 @@
+package org.springblade.manager.dto;
+
+/**
+ * @author yangyj
+ * @Date 2023/4/13 15:57
+ * @description TODO
+ */
+public class FormulaDataBlockVo {
+}

+ 0 - 5
blade-service-api/blade-manager-api/src/main/java/org/springblade/manager/dto/RangeInfo.java

@@ -2,15 +2,10 @@ package org.springblade.manager.dto;
 
 import com.alibaba.fastjson.annotation.JSONField;
 import io.swagger.annotations.ApiModelProperty;
-import lombok.Data;
 import org.springblade.common.utils.BaseUtils;
 import org.springblade.core.tool.utils.Func;
-import org.springblade.core.tool.utils.StringUtil;
-
 import java.util.Arrays;
 import java.util.List;
-import java.util.regex.Matcher;
-import java.util.regex.Pattern;
 import java.util.stream.Collectors;
 
 /**

+ 28 - 0
blade-service-api/blade-manager-api/src/main/java/org/springblade/manager/entity/FormulaDataBlock.java

@@ -0,0 +1,28 @@
+package org.springblade.manager.entity;
+
+import com.baomidou.mybatisplus.annotation.IdType;
+import com.baomidou.mybatisplus.annotation.TableId;
+import com.baomidou.mybatisplus.annotation.TableName;
+import io.swagger.annotations.ApiModelProperty;
+import lombok.Data;
+
+/**
+ * @author yangyj
+ * @Date 2023/4/13 15:40
+ * @description TODO
+ */
+@Data
+@TableName("m_formula_data_block")
+public class FormulaDataBlock {
+    @ApiModelProperty("主键id")
+    @TableId(
+            value = "id",
+            type = IdType.ASSIGN_ID
+    )
+    private Long id;
+    private Integer type;
+    /**sub work*/
+    private Long swId;
+    private Long contractId;
+    private String val;
+}

+ 3 - 0
blade-service-api/blade-manager-api/src/main/java/org/springblade/manager/feign/WbsTreeContractClient.java

@@ -166,4 +166,7 @@ public interface WbsTreeContractClient {
     @GetMapping(API_PREFIX + "/queryWbsTreeContractTreeLazy")
     List<WbsTreeContractTreeVOS> queryWbsTreeContractTreeLazy(@RequestParam String contractId,@RequestParam Long parseLong);
 
+    @GetMapping(API_PREFIX + "/getAllTableFileSize")
+    Long getAllTableFileSize(@RequestParam Long projectId);
+
 }

+ 17 - 0
blade-service/blade-archive/src/main/java/org/springblade/archive/controller/ArchiveFileController.java

@@ -24,6 +24,7 @@ import org.springblade.evisa.feign.EVisaClient;
 import org.springblade.manager.entity.ArchiveTree;
 import org.springblade.manager.entity.ArchiveTreeContract;
 import org.springblade.manager.feign.ArchiveTreeContractClient;
+import org.springblade.manager.feign.WbsTreeContractClient;
 import org.springblade.resource.feign.IOSSClient;
 import org.springframework.web.bind.annotation.*;
 import org.springframework.web.multipart.MultipartFile;
@@ -52,6 +53,7 @@ public class ArchiveFileController extends BladeController {
     private final IOSSClient iossClient;
     private final ArchiveTreeContractClient archiveTreeContractClient;
     private final EVisaClient eVisaClient;
+    private final WbsTreeContractClient wbsTreeContractClient;
     /**
      * 上传文件
      *
@@ -276,4 +278,19 @@ public class ArchiveFileController extends BladeController {
         List<Map<String, Object>> mapList = archiveFileClient.getAllArchiveFileByContractType(projectId);
         return R.data(mapList);
     }
+
+    /**
+     * 档案统计-档案总存储
+     */
+    @GetMapping("/allArchiveFileSize")
+    @ApiOperationSupport(order = 3)
+    @ApiOperation(value = "档案统计-档案总存储")
+    public R allArchiveFileSize(Long projectId) {
+        //统计案卷文件大小
+        Long fileSize = archiveFileClient.getAllArchiveFileSize(projectId);
+        //统计表单数据大小
+        Long tableSize = wbsTreeContractClient.getAllTableFileSize(projectId);
+        String size = org.springblade.common.utils.FileUtils.formatSize(fileSize + tableSize);
+        return R.data(size);
+    }
 }

+ 152 - 130
blade-service/blade-business/src/main/java/org/springblade/business/controller/InformationWriteQueryController.java

@@ -58,6 +58,7 @@ import org.springblade.core.boot.ctrl.BladeController;
 
 import java.io.IOException;
 import java.util.*;
+import java.util.function.Function;
 import java.util.stream.Collectors;
 
 /**
@@ -1403,7 +1404,7 @@ public class InformationWriteQueryController extends BladeController {
                     }
 
                     // 组织复制值Sql
-                    if (nodeTabColsMap != null && node.getType() == 2) {
+                    if (nodeTabColsMap != null && node.getType() == 2 && StringUtils.isNotEmpty(newData.getInitTableName())) {
                         String tableName = newData.getInitTableName();
                         String col = nodeTabColsMap.get(tableName);
                         String colVal = nodeTabColsMap.get(tableName);
@@ -1437,6 +1438,7 @@ public class InformationWriteQueryController extends BladeController {
              *      2.2 如果点击选择的是当前复制节点本身的同等级节点,那么复制对应表数据,如果没有对应表,那么跳过。
              */
         } else if (("2").equals(vo.getCopyType())) {
+
             //获取需要复制到的位置节点信息的集合
             List<CopyContractTreeNodeVO.CopyBatch> copyBatches = vo.getCopyBatchToPaths();
             if (copyBatches.size() > 0) {
@@ -1454,8 +1456,9 @@ public class InformationWriteQueryController extends BladeController {
                 }
 
                 //结果集
-                List<WbsTreeContract> addChildNodesAll = new ArrayList<>();
-                List<WbsTreeContract> addChildNodesTablesAll = new ArrayList<>();
+                List<WbsTreeContract> addNodeList = new ArrayList<>();
+                List<WbsTreeContract> addTabList = new ArrayList<>();
+                List<WbsTreeContract> asyncWbsTreeNodes = new ArrayList<>();
                 Set<WbsTreeContract> addChildNodesTablesOldAll = new HashSet<>();
                 List<String> resultTablesData = new ArrayList<>();
 
@@ -1467,6 +1470,9 @@ public class InformationWriteQueryController extends BladeController {
                     tabOwner = "1,2,3";
                 } else if (("2").equals(vo.getClassifyType())) {
                     tabOwner = "4,5,6";
+                } else if (vo.getIsCopyData() == 0 && StringUtils.isEmpty(tabOwner)) {
+                    //如果选择的是否复制数据=0(否),默认所属方123456
+                    tabOwner = "1,2,3,4,5,6";
                 }
 
                 //解析位置信息,进行复制数据构造
@@ -1475,6 +1481,7 @@ public class InformationWriteQueryController extends BladeController {
                         //首先查询需要复制的节点的信息
                         WbsTreeContract needCopyNode = this.wbsTreeContractClient.getContractNodeByPrimaryKeyId(vo.getNeedCopyPrimaryKeyId());
                         WbsTreeContract toCopyNode = toCopyNodes.get(i);
+                        asyncWbsTreeNodes.add(toCopyNode);
                         CopyContractTreeNodeVO.CopyBatch toCopyVO = copyBatches.get(i);
 
                         if (toCopyNode != null && toCopyVO != null && needCopyNode != null) {
@@ -1502,16 +1509,12 @@ public class InformationWriteQueryController extends BladeController {
                                     addChildNodesTablesOldAll.addAll(oldTab);
 
                                     //构造新的节点、表、数据
-                                    this.addCopyNodesAndTabsBuildData(addChildNodes, addChildNodesTables, needCopyNode, toCopyNode, resultTablesData, 1, tabOwner, vo.getIsCopyData());
-
-                                    //返回结果集
-                                    addChildNodesAll.addAll(addChildNodes);
-                                    addChildNodesTablesAll.addAll(addChildNodesTables);
+                                    this.addCopyNodesAndTabsBuildData(addNodeList, addTabList, addChildNodes, addChildNodesTables, needCopyNode, toCopyNode, resultTablesData, 1, tabOwner, vo.getIsCopyData());
 
                                     //1.2 选择同父级的同级节点,只复制数据
                                 } else if (needCopyNode.getParentId().equals(toCopyNode.getParentId())) {
                                     //构造数据
-                                    this.addCopyTabData(needCopyNode, toCopyNode, tabOwner, resultTablesData, addChildNodesTablesOldAll, addChildNodesTablesAll, vo.getIsCopyData());
+                                    this.addCopyTabData(needCopyNode, toCopyNode, tabOwner, resultTablesData, addChildNodesTablesOldAll, addTabList, vo.getIsCopyData());
                                 }
 
                                 //TODO 跨节点复制
@@ -1541,16 +1544,12 @@ public class InformationWriteQueryController extends BladeController {
                                     addChildNodesTablesOldAll.addAll(oldTab);
 
                                     //构造新的节点、表、数据
-                                    this.addCopyNodesAndTabsBuildData(addChildNodes, addChildNodesTables, needCopyNode, toCopyNode, resultTablesData, 0, tabOwner, vo.getIsCopyData());
-
-                                    //返回结果集
-                                    addChildNodesAll.addAll(addChildNodes);
-                                    addChildNodesTablesAll.addAll(addChildNodesTables);
+                                    this.addCopyNodesAndTabsBuildData(addNodeList, addTabList, addChildNodes, addChildNodesTables, needCopyNode, toCopyNode, resultTablesData, 0, tabOwner, vo.getIsCopyData());
 
                                     //2.2 如果点击选择的是当前复制节点本身的同等级节点,那么就只复制数据。(如果是跨节点,类型相同的情况下,只复制数据)
                                 } else if (needCopyNode.getNodeType().equals(toCopyNode.getNodeType()) && !needCopyNode.getParentId().equals(toCopyNode.getParentId())) {
                                     //构造数据
-                                    this.addCopyTabData(needCopyNode, toCopyNode, tabOwner, resultTablesData, addChildNodesTablesOldAll, addChildNodesTablesAll, vo.getIsCopyData());
+                                    this.addCopyTabData(needCopyNode, toCopyNode, tabOwner, resultTablesData, addChildNodesTablesOldAll, addTabList, vo.getIsCopyData());
                                 }
                             }
                         }
@@ -1558,21 +1557,22 @@ public class InformationWriteQueryController extends BladeController {
                 }
 
                 //节点
-                if (addChildNodesAll.size() > 0) {
-                    wbsTreeContractClient.saveBatch(addChildNodesAll);
+                if (addNodeList.size() > 0) {
+                    wbsTreeContractClient.saveBatch(addNodeList);
                     //更新redis缓存
-                    Map<Long, List<WbsTreeContract>> collect = addChildNodesAll.stream().filter(f -> new Integer(1).equals(f.getType()) && ObjectUtil.isNotEmpty(f.getParentId())).collect(Collectors.groupingBy(WbsTreeContract::getParentId));
-                    for (Map.Entry<Long, List<WbsTreeContract>> longListEntry : collect.entrySet()) {
-                        informationQueryService.AsyncWbsTree("", longListEntry.getKey().toString(), contractId, "", "1");
+                    if (asyncWbsTreeNodes.size() > 0) {
+                        for (WbsTreeContract asyncWbsTreeNode : asyncWbsTreeNodes) {
+                            informationQueryService.AsyncWbsTree("", asyncWbsTreeNode.getParentId() + "", contractId, "", "1");
+                        }
                     }
                 }
                 //元素表
-                if (addChildNodesTablesAll.size() > 0) {
-                    wbsTreeContractClient.saveBatch(addChildNodesTablesAll);
+                if (addTabList.size() > 0) {
+                    wbsTreeContractClient.saveBatch(addTabList);
 
                     //表单文件附件
                     if (addChildNodesTablesOldAll.size() > 0 && vo.getIsCopyData() == 1) {
-                        this.addCopyTabFile(addChildNodesTablesAll, addChildNodesTablesOldAll);
+                        this.addCopyTabFile(addTabList, addChildNodesTablesOldAll);
                     }
                 }
                 //实体表数据
@@ -1674,7 +1674,7 @@ public class InformationWriteQueryController extends BladeController {
     /**
      * 新增复制的节点、表的数据构造
      */
-    private void addCopyNodesAndTabsBuildData(List<WbsTreeContract> needNodes, List<WbsTreeContract> needTabs, WbsTreeContract needCopyNode, WbsTreeContract toCopyNode, List<String> resultTablesData, Integer isSameNode, String tabOwner, Integer isCopyData) {
+    private void addCopyNodesAndTabsBuildData(List<WbsTreeContract> addNodeList, List<WbsTreeContract> addTabList, List<WbsTreeContract> needNodes, List<WbsTreeContract> needTabs, WbsTreeContract needCopyNode, WbsTreeContract toCopyNode, List<String> resultTablesData, Integer isSameNode, String tabOwner, Integer isCopyData) {
         int var = 0;
         if (needNodes.size() == 1) {
             //判断是否为最下级节点
@@ -1689,54 +1689,66 @@ public class InformationWriteQueryController extends BladeController {
             //构造节点
             Long id = SnowFlakeUtil.getId();
             for (WbsTreeContract needNode : needNodes) {
-                if (isSameNode == 0) {
-                    //跨节点复制,更改父级id
-                    needNode.setParentId(toCopyNode.getId());
+                WbsTreeContract obj = BeanUtil.copyProperties(needNode, WbsTreeContract.class);
+                if (obj != null) {
+                    if (isSameNode == 0) {
+                        //跨节点复制,更改父级id
+                        obj.setParentId(toCopyNode.getId());
+                        //设置祖级id
+                        String[] split = obj.getAncestors().split(",");
+                        String lastId = split[split.length - 1];
+                        obj.setAncestors(obj.getAncestors().replace(lastId, toCopyNode.getId().toString()));
+                    }
+                    obj.setOldId(needNode.getId() + "");
+                    obj.setPKeyId(SnowFlakeUtil.getId());
+                    obj.setId(id);
+                    obj.setNodeName(toCopyNode.getNodeName());
+                    obj.setFullName(toCopyNode.getNodeName());
+                    obj.setPartitionCode(toCopyNode.getPartitionCode());
+                    obj.setCreateTime(new Date());
+                    addNodeList.add(obj);
+                    break;
                 }
-                needNode.setOldId(needNode.getId() + "");
-                needNode.setPKeyId(SnowFlakeUtil.getId());
-                needNode.setId(id);
-                needNode.setNodeName(toCopyNode.getNodeName());
-                needNode.setFullName(toCopyNode.getNodeName());
-                needNode.setPartitionCode(toCopyNode.getPartitionCode());
-                break;
             }
             //构造当前节点下所有元素表
             for (WbsTreeContract needTab : needTabs) {
                 if (StringUtils.isEmpty(needTab.getInitTableName())) {
                     continue;
                 }
-                Long oldPKeyId = needTab.getPKeyId();
-
-                Long tabId = SnowFlakeUtil.getId();
-                needTab.setAncestors(needTab.getAncestors().replace(needTab.getParentId().toString(), id.toString()));
-                needTab.setId(tabId);
-                needTab.setParentId(id);
-                needTab.setPKeyId(SnowFlakeUtil.getId());
-                //初始化是否显示表格,默认显示
-                needTab.setIsBussShow(1);
-                //初始化表格是否上传附件,默认未上传
-                needTab.setTabFileType(1);
-                //初始化单表是否可以预览,默认不能
-                needTab.setIsTabPdf(1);
-                //初始化PDF路径
-                needTab.setPdfUrl(null);
-
-                //表单所属方,只有勾选了对应的所属方权限才复制数据;勾选了复制数据才能复制,否则只是创建节点、表
-                if (tabOwner.contains(needTab.getTableOwner()) && isCopyData == 1) {
-                    //获取实体表列对象
-                    List<QueryProcessDataVO> nodeTabColOneTab = informationQueryService.getNodeChildTabColsAllByTabName(needTab.getInitTableName());
-                    //转化为map
-                    Map<String, String> nodeTabColsMap = nodeTabColOneTab.stream().collect(Collectors.toMap(QueryProcessDataVO::getQueryType, QueryProcessDataVO::getAncestors, (key1, key2) -> key2));
-                    //组织复制表的数据的sql
-                    if (nodeTabColsMap.size() > 0) {
-                        StringBuilder copyDataSql = new StringBuilder();
-                        String tableName = needTab.getInitTableName();
-                        String col = nodeTabColsMap.get(tableName);
-                        String colVal = nodeTabColsMap.get(tableName);
-                        colVal = colVal.replaceAll("id,p_key_id,", "'" + SnowFlakeUtil.getId() + "' as id,'" + needTab.getPKeyId() + "' as p_key_id,");
-                        copyDataSql.append("insert into ").append(tableName).append("  (").append(col).append(") select ").append(colVal).append(" from ").append(tableName).append(" where p_key_id='").append(oldPKeyId).append("' ;");
-                        resultTablesData.add(copyDataSql.toString());
+                WbsTreeContract obj = BeanUtil.copyProperties(needTab, WbsTreeContract.class);
+                if (obj != null) {
+                    Long oldPKeyId = needTab.getPKeyId();
+                    obj.setAncestors(needTab.getAncestors().replace(needTab.getParentId().toString(), id.toString()));
+                    obj.setId(SnowFlakeUtil.getId());
+                    obj.setParentId(id);
+                    obj.setPKeyId(SnowFlakeUtil.getId());
+                    //初始化是否显示表格,默认显示
+                    obj.setIsBussShow(1);
+                    //初始化表格是否上传附件,默认未上传
+                    obj.setTabFileType(1);
+                    //初始化单表是否可以预览,默认不能
+                    obj.setIsTabPdf(1);
+                    //初始化PDF路径
+                    obj.setPdfUrl(null);
+                    obj.setCreateTime(new Date());
+                    addTabList.add(obj);
+
+                    //表单所属方,只有勾选了对应的所属方权限才复制数据;勾选了复制数据才能复制,否则只是创建节点、表
+                    if (tabOwner.contains(obj.getTableOwner()) && isCopyData == 1) {
+                        //获取实体表列对象
+                        List<QueryProcessDataVO> nodeTabColOneTab = informationQueryService.getNodeChildTabColsAllByTabName(obj.getInitTableName());
+                        //转化为map
+                        Map<String, String> nodeTabColsMap = nodeTabColOneTab.stream().collect(Collectors.toMap(QueryProcessDataVO::getQueryType, QueryProcessDataVO::getAncestors, (key1, key2) -> key2));
+                        //组织复制表的数据的sql
+                        if (nodeTabColsMap.size() > 0) {
+                            StringBuilder copyDataSql = new StringBuilder();
+                            String tableName = obj.getInitTableName();
+                            String col = nodeTabColsMap.get(tableName);
+                            String colVal = nodeTabColsMap.get(tableName);
+                            colVal = colVal.replaceAll("id,p_key_id,", "'" + SnowFlakeUtil.getId() + "' as id,'" + obj.getPKeyId() + "' as p_key_id,");
+                            copyDataSql.append("insert into ").append(tableName).append("  (").append(col).append(") select ").append(colVal).append(" from ").append(tableName).append(" where p_key_id='").append(oldPKeyId).append("' ;");
+                            resultTablesData.add(copyDataSql.toString());
+                        }
                     }
                 }
             }
@@ -1749,70 +1761,81 @@ public class InformationWriteQueryController extends BladeController {
             Map<Long, Long> parentIdToId = new HashMap<>();
             Map<Long, List<WbsTreeContract>> tabMap = needTabs.stream().collect(Collectors.groupingBy(WbsTreeContract::getParentId));
 
+            //获取节点下所有表的key
+            List<String> initTabNames = needTabs.stream().map(WbsTreeContract::getInitTableName).distinct().filter(ObjectUtil::isNotEmpty).collect(Collectors.toList());
+            String joined = StringUtils.join(initTabNames, ",");
+            joined = "'" + joined.replaceAll(",", "','") + "'";
+            Map<String, QueryProcessDataVO> tabColsAllByTabNameMaps = jdbcTemplate.query("SELECT table_name as queryType, GROUP_CONCAT(COLUMN_name) as ancestors from information_schema.COLUMNS where table_name in (" + joined + ") GROUP BY table_name", new BeanPropertyRowMapper<>(QueryProcessDataVO.class)).stream().collect(Collectors.toMap(QueryProcessDataVO::getQueryType, Function.identity()));
             for (WbsTreeContract node : needNodes) {
                 Long oldId = node.getId();
-                //构造节点
-                Long newParentId;
-                if (parentIdToId.size() > 0) {
-                    //去数据源节点获取父级id对应的新id,设置成重设后的新的父级id
-                    newParentId = parentIdToId.get(node.getParentId());
-                } else {
-                    //根节点
-                    newParentId = toCopyNode.getId();
-                }
-                if (ObjectUtils.isEmpty(newParentId)) {
-                    newParentId = toCopyNode.getId();
-                }
-                node.setPKeyId(SnowFlakeUtil.getId());
-                node.setOldId(node.getId().toString());
-                Long id = SnowFlakeUtil.getId();
-                //数据源节点的老id与新的id的Map,作为下一级的节点的父级id的替换
-                parentIdToId.put(node.getId(), id);
-                //重设祖级id
-                node.setAncestors(node.getAncestors().replace(node.getParentId().toString(), id.toString()));
-                //重设Id
-                node.setId(id);
-                node.setParentId(newParentId);
-
-                //构造当前节点下所有元素表
-                List<WbsTreeContract> tabs = tabMap.get(oldId);
-                //构造节点下的表
-                if (tabs != null && tabs.size() > 0) {
-                    for (WbsTreeContract needTab : tabs) {
-                        if (StringUtils.isEmpty(needTab.getInitTableName())) {
-                            continue;
-                        }
-                        Long oldPKeyId = needTab.getPKeyId();
-
-                        Long tabId = SnowFlakeUtil.getId();
-                        needTab.setAncestors(needTab.getAncestors().replace(needTab.getParentId().toString(), id.toString()));
-                        needTab.setId(tabId);
-                        needTab.setParentId(id);
-                        needTab.setPKeyId(SnowFlakeUtil.getId());
-                        //初始化是否显示表格,默认显示
-                        needTab.setIsBussShow(1);
-                        //初始化表格是否上传附件,默认未上传
-                        needTab.setTabFileType(1);
-                        //初始化单表是否可以预览,默认不能
-                        needTab.setIsTabPdf(1);
-                        //初始化PDF路径
-                        needTab.setPdfUrl(null);
-
-                        //表单所属方,只有勾选了对应的所属方权限才复制数据;勾选了复制数据才能复制,否则只是创建节点、表
-                        if (tabOwner.contains(needTab.getTableOwner()) && isCopyData == 1) {
-                            //获取实体表列对象
-                            List<QueryProcessDataVO> nodeTabColOneTab = informationQueryService.getNodeChildTabColsAllByTabName(needTab.getInitTableName());
-                            //转化为map
-                            Map<String, String> nodeTabColsMap = nodeTabColOneTab.stream().collect(Collectors.toMap(QueryProcessDataVO::getQueryType, QueryProcessDataVO::getAncestors, (key1, key2) -> key2));
-                            //组织复制表的数据的sql
-                            if (nodeTabColsMap.size() > 0) {
-                                StringBuilder copyDataSql = new StringBuilder();
+                WbsTreeContract obj = BeanUtil.copyProperties(node, WbsTreeContract.class);
+                if (obj != null) {
+                    //构造节点
+                    Long newParentId;
+                    if (parentIdToId.size() > 0) {
+                        //去数据源节点获取父级id对应的新id,设置成重设后的新的父级id
+                        newParentId = parentIdToId.get(node.getParentId());
+                    } else {
+                        //根节点
+                        newParentId = toCopyNode.getId();
+                    }
+                    if (ObjectUtils.isEmpty(newParentId)) {
+                        newParentId = toCopyNode.getId();
+                    }
+                    obj.setPKeyId(SnowFlakeUtil.getId());
+                    obj.setOldId(node.getId().toString());
+                    Long id = SnowFlakeUtil.getId();
+                    //数据源节点的老id与新的id的Map,作为下一级的节点的父级id的替换
+                    parentIdToId.put(node.getId(), id);
+                    //重设祖级id
+                    this.restoreParent(obj, parentIdToId);
+                    //重设Id
+                    obj.setId(id);
+                    obj.setParentId(newParentId);
+                    obj.setCreateTime(new Date());
+                    addNodeList.add(obj);
+
+                    //构造当前节点下所有元素表
+                    List<WbsTreeContract> tabs = tabMap.get(oldId);
+                    //构造节点下的表
+                    if (tabs != null && tabs.size() > 0) {
+                        for (WbsTreeContract needTab : tabs) {
+                            if (StringUtils.isEmpty(needTab.getInitTableName())) {
+                                continue;
+                            }
+                            WbsTreeContract objTab = BeanUtil.copyProperties(needTab, WbsTreeContract.class);
+                            if (objTab != null) {
+                                Long oldPKeyId = needTab.getPKeyId();
                                 String tableName = needTab.getInitTableName();
-                                String col = nodeTabColsMap.get(tableName);
-                                String colVal = nodeTabColsMap.get(tableName);
-                                colVal = colVal.replaceAll("id,p_key_id,", "'" + SnowFlakeUtil.getId() + "' as id,'" + needTab.getPKeyId() + "' as p_key_id,");
-                                copyDataSql.append("insert into ").append(tableName).append("  (").append(col).append(") select ").append(colVal).append(" from ").append(tableName).append(" where p_key_id='").append(oldPKeyId).append("' ;");
-                                resultTablesData.add(copyDataSql.toString());
+                                Long tabId = SnowFlakeUtil.getId();
+                                objTab.setAncestors(needTab.getAncestors().replace(needTab.getParentId().toString(), id.toString()));
+                                objTab.setId(tabId);
+                                objTab.setParentId(id);
+                                objTab.setPKeyId(SnowFlakeUtil.getId());
+                                //初始化是否显示表格,默认显示
+                                objTab.setIsBussShow(1);
+                                //初始化表格是否上传附件,默认未上传
+                                objTab.setTabFileType(1);
+                                //初始化单表是否可以预览,默认不能
+                                objTab.setIsTabPdf(1);
+                                //初始化PDF路径
+                                objTab.setPdfUrl(null);
+                                objTab.setCreateTime(new Date());
+                                addTabList.add(objTab);
+
+                                //表单所属方,只有勾选了对应的所属方权限才复制数据;勾选了复制数据才能复制,否则只是创建节点、表
+                                if (tabOwner.contains(needTab.getTableOwner()) && isCopyData == 1 && tabColsAllByTabNameMaps.size() > 0) {
+                                    QueryProcessDataVO queryProcessDataVO = tabColsAllByTabNameMaps.get(tableName);
+                                    //组织复制表的数据的sql
+                                    if (queryProcessDataVO != null) {
+                                        StringBuilder copyDataSql = new StringBuilder();
+                                        String col = queryProcessDataVO.getAncestors();
+                                        String colVal = queryProcessDataVO.getAncestors();
+                                        colVal = colVal.replaceAll("id,p_key_id,", "'" + SnowFlakeUtil.getId() + "' as id,'" + needTab.getPKeyId() + "' as p_key_id,");
+                                        copyDataSql.append("insert into ").append(tableName).append("  (").append(col).append(") select ").append(colVal).append(" from ").append(tableName).append(" where p_key_id='").append(oldPKeyId).append("' ;");
+                                        resultTablesData.add(copyDataSql.toString());
+                                    }
+                                }
                             }
                         }
                     }
@@ -1827,12 +1850,15 @@ public class InformationWriteQueryController extends BladeController {
             } else {
                 //跨节点
                 toCopyNode.setParentId(toCopyNodeOldId);
+                //重设祖级id
+                toCopyNode.setAncestors(needCopyNode.getAncestors().replace(needCopyNode.getParentId().toString(), toCopyNode.getId().toString()));
             }
             toCopyNode.setPKeyId(SnowFlakeUtil.getId());
             toCopyNode.setNodeName(toCopyNode.getNodeName());
             toCopyNode.setFullName(toCopyNode.getNodeName());
             toCopyNode.setPartitionCode(toCopyNode.getPartitionCode());
             needNodes.add(toCopyNode);
+            addNodeList.add(toCopyNode);
         }
     }
 
@@ -2069,7 +2095,6 @@ public class InformationWriteQueryController extends BladeController {
                             this.createLedger(newData, saveLedger, nodeMap, null);
                         }
                     });
-
                 });
             }
         }
@@ -2941,9 +2966,6 @@ public class InformationWriteQueryController extends BladeController {
         return R.data(wbsTreeContractTreeVOS);
     }
 
-
-    // set的处理
-
     /**
      * 修改
      */

+ 20 - 0
blade-service/blade-business/src/main/java/org/springblade/business/feignClient/ArchiveFileClientImpl.java

@@ -12,6 +12,8 @@ import org.springblade.business.feign.ArchiveFileClient;
 import org.springblade.business.mapper.ArchiveFileMapper;
 import org.springblade.business.service.IArchiveFileService;
 import org.springblade.business.vo.ArchiveFileVO;
+import org.springblade.common.utils.FileUtils;
+import org.springblade.common.vo.FileSize;
 import org.springblade.manager.entity.ContractInfo;
 import org.springblade.manager.feign.ContractClient;
 import org.springframework.web.bind.annotation.RestController;
@@ -161,4 +163,22 @@ public class ArchiveFileClientImpl implements ArchiveFileClient {
         mapList.add(map3);
         return mapList;
     }
+
+    @Override
+    public Long getAllArchiveFileSize(Long projectId) {
+        //获取所有文件的url
+        List<ArchiveFile> archiveFileList = fileMapper.getAllArchiveFileUrl(projectId);
+        List<String> list = new ArrayList<>();
+        for (ArchiveFile file : archiveFileList) {
+            if (StringUtils.isNotBlank(file.getFileUrl())){
+                list.add(file.getFileUrl());
+            }
+            if (StringUtils.isNotBlank(file.getPdfFileUrl())){
+                list.add(file.getPdfFileUrl());
+            }
+        }
+        //从阿里云返回文件大小
+        Long sizeCount = FileUtils.getOssFileSizeCount(list);
+        return sizeCount;
+    }
 }

+ 6 - 0
blade-service/blade-business/src/main/java/org/springblade/business/feignClient/InformationQueryClientImpl.java

@@ -79,4 +79,10 @@ public class InformationQueryClientImpl implements InformationQueryClient {
     public void AsyncWbsTree(String primaryKeyId, String parentId, String contractId, String contractIdRelation, String classifyType) {
         iInformationQueryService.AsyncWbsTree(primaryKeyId,parentId,contractId,contractIdRelation,classifyType);
     }
+
+    @Override
+    public void delAsyncWbsTree(String parentId, String contractId, String classifyType) {
+        iInformationQueryService.delAsyncWbsTree(parentId,contractId,classifyType);
+    }
+
 }

+ 2 - 0
blade-service/blade-business/src/main/java/org/springblade/business/mapper/ArchiveFileMapper.java

@@ -70,4 +70,6 @@ public interface ArchiveFileMapper extends BaseMapper<ArchiveFile> {
 	public List<ArchiveFile> getListByProjectId(@Param("projectId") Long projectId);
 
 	List<ArchiveFileVO> getAllArchiveFileByContractType(@Param("projectId")Long projectId);
+
+	List<ArchiveFile> getAllArchiveFileUrl(@Param("projectId")Long projectId);
 }

+ 6 - 0
blade-service/blade-business/src/main/java/org/springblade/business/mapper/ArchiveFileMapper.xml

@@ -281,4 +281,10 @@
         FROM u_archive_file uaf inner join m_archive_tree_contract matc on uaf.node_id =matc.id
         WHERE  uaf.project_id = #{projectId};
     </select>
+    <select id="getAllArchiveFileUrl" resultType="org.springblade.business.entity.ArchiveFile">
+        SELECT uaf.file_url ,uaf.pdf_file_url
+        FROM u_archive_file uaf
+        WHERE  uaf.project_id = #{projectId};
+    </select>
+
 </mapper>

+ 4 - 2
blade-service/blade-business/src/main/java/org/springblade/business/mapper/InformationQueryMapper.xml

@@ -146,7 +146,7 @@
                    WHEN (c.allCount + 1) = c.submitCounts and notExsitChild = 'true' THEN 3
                    WHEN c.allCount = c.appCount and notExsitChild = 'false' THEN 4
                    WHEN (c.allCount + 1) = c.appCount and notExsitChild = 'true' THEN 4
-                   WHEN c.savaCont >= 1 or c.submitCounts >= 1 or c.appCount >= 1 THEN 2
+                   -- WHEN c.savaCont >= 1 or c.submitCounts >= 1 or c.appCount >= 1 THEN 2
                    ELSE 1 END AS colorStatus
         from (
                  SELECT wtc.sort,
@@ -182,7 +182,9 @@
         END AS isFirst,
 			 ( SELECT count(1) from m_wbs_tree_contract where id in(SELECT parent_id from m_wbs_tree_contract a where a.is_deleted=0 and a.type=2 and table_owner in(1,2,3)) and contract_id=wtc.contract_id and type =1 and is_deleted=0 and (FIND_IN_SET(wtc.id,ancestors) or wtc.p_key_id=p_key_id)
 				) as allCount,
-			 (SELECT count(1) from u_information_query b where b.wbs_id in(SELECT p_key_id from m_wbs_tree_contract a where (FIND_IN_SET(wtc.id,a.ancestors) or wtc.p_key_id=a.p_key_id) and a.is_deleted=0 ) and b.`status`='0' and b.is_deleted=0 and b.classify=1 and b.contract_id=wtc.contract_id ) as savaCont,
+			 (SELECT count(1) from u_information_query b where b.wbs_id in(SELECT p_key_id from m_wbs_tree_contract a
+                where (FIND_IN_SET(wtc.id,a.ancestors) or wtc.p_key_id=a.p_key_id) and a.is_deleted=0 ) and b.`status`='0'
+                and b.is_deleted=0 and b.classify=1 and b.contract_id=wtc.contract_id ) as savaCont,
 			 (SELECT count(1) from u_information_query b where b.wbs_id in(SELECT p_key_id from m_wbs_tree_contract a where (FIND_IN_SET(wtc.id,a.ancestors) or wtc.p_key_id=a.p_key_id) and a.is_deleted=0 ) and b.`status`='1' and b.is_deleted=0 and b.classify=1 and b.contract_id=wtc.contract_id) as submitCounts,
 			 (SELECT count(1) from u_information_query b where b.wbs_id in(SELECT p_key_id from m_wbs_tree_contract a where (FIND_IN_SET(wtc.id,a.ancestors) or wtc.p_key_id=a.p_key_id) and a.is_deleted=0 ) and b.`status`='2' and b.is_deleted=0 and b.classify=1 and b.contract_id=wtc.contract_id) as appCount
 				FROM

+ 4 - 0
blade-service/blade-business/src/main/java/org/springblade/business/service/IInformationQueryService.java

@@ -134,4 +134,8 @@ public interface IInformationQueryService extends BaseService<InformationQuery>
 
     //变更节点
     void  AsyncWbsTree(String primaryKeyId,String parentId,String contractId,String contractIdRelation,String classifyType);
+
+    //删除变更节点
+    void  delAsyncWbsTree(String parentId, String contractId, String classifyType);
+
 }

+ 8 - 1
blade-service/blade-business/src/main/java/org/springblade/business/service/impl/InformationQueryServiceImpl.java

@@ -105,7 +105,7 @@ public class InformationQueryServiceImpl extends BaseServiceImpl<InformationQuer
             }
             if (tableList != null && tableList.size() > 0) {
                 //删除掉无法溯源的数据
-                tableList.removeIf(node -> node.getIsTypePrivatePid() == null || node.getIsTypePrivatePid() <= 0 || StringUtils.isEmpty(node.getIsTypePrivatePid().toString()) || node.getHtmlUrl()==null );
+                tableList.removeIf(node -> node.getIsTypePrivatePid() == null || node.getIsTypePrivatePid() <= 0 || StringUtils.isEmpty(node.getIsTypePrivatePid().toString()) || node.getHtmlUrl() == null);
                 List<Long> privatePIdList = tableList.stream().map(WbsTreeContract::getIsTypePrivatePid).distinct().collect(Collectors.toList());
                 return JSONArray.parseArray(JSONObject.toJSONString(privatePIdList), String.class);
 
@@ -728,4 +728,11 @@ public class InformationQueryServiceImpl extends BaseServiceImpl<InformationQuer
         JSONArray array = JSONArray.parseArray(JSON.toJSONString(wbsTreeContractTreeVOS));
         RedisTemplate.opsForValue().set("blade-manager::contract:wbstree:" + dataInfoId, JSON.toJSON(array).toString());
     }
+
+    @Override
+    public void delAsyncWbsTree(String parentId, String contractId, String classifyType) {
+        String dataInfoId = contractId + "_" + parentId + "_" + classifyType;
+        RedisTemplate.delete("blade-manager::contract:wbstree:" + dataInfoId);
+    }
+
 }

+ 6 - 0
blade-service/blade-manager/pom.xml

@@ -155,6 +155,12 @@
             <version>2.9.1.RELEASE</version>
             <scope>compile</scope>
         </dependency>
+        <!-- https://mvnrepository.com/artifact/org.apache.commons/commons-text -->
+        <dependency>
+            <groupId>org.apache.commons</groupId>
+            <artifactId>commons-text</artifactId>
+            <version>1.10.0</version>
+        </dependency>
     </dependencies>
     <build>
         <plugins>

+ 30 - 0
blade-service/blade-manager/src/main/java/com/mixsmart/utils/CustomFunction.java

@@ -4,6 +4,7 @@ package com.mixsmart.utils;
 import cn.hutool.core.date.*;
 import cn.hutool.core.util.ArrayUtil;
 import cn.hutool.core.util.NumberUtil;
+import com.alibaba.fastjson.JSON;
 import com.jfireel.expression.node.CalculateNode;
 import com.jfireel.expression.node.impl.OperatorResultNode;
 import com.jfireel.expression.node.impl.StaticObjectMethodNode;
@@ -12,6 +13,9 @@ import com.jfireel.expression.token.Token;
 import org.apache.commons.collections4.MapUtils;
 import org.jsoup.Jsoup;
 import org.springblade.core.tool.utils.*;
+import org.springblade.manager.formula.ElementBlock;
+import org.springblade.manager.formula.ItemBlock;
+
 import java.io.FileInputStream;
 import java.math.BigDecimal;
 import java.text.ParseException;
@@ -2570,5 +2574,31 @@ public class CustomFunction {
 		return "";
 	}
 
+//	public static void main(String[] args) {
+//		ElementBlock eb =new ElementBlock();
+//		eb.setCode("m_xxxx_:key_x");
+//		eb.setPass(5);
+//		eb.setTotal(5);
+//		eb.setSort(16);
+//		List<ItemBlock> list = new ArrayList<>();
+//		eb.setList(list);
+//		ItemBlock ib = new ItemBlock();
+//		ib.setDev("±5");
+//		ib.setPkeyId(123456789L);
+//		ib.setS("12/25/36");
+//		ib.setD("12,12/25,23/36,35");
+//		list.add(ib);
+//		ItemBlock ib2 = new ItemBlock();
+//		ib2.setDev("±5");
+//		ib2.setPkeyId(123456789L);
+//		ib2.setS("12");
+//		ib2.setD("12,12");
+//		list.add(ib2);
+//		String json=JSON.toJSONString(eb);
+//		System.out.println(json);
+//		ElementBlock ebj= JSON.parseObject(json,ElementBlock.class);
+//		System.out.println();
+//	}
+
 
 }

+ 40 - 5
blade-service/blade-manager/src/main/java/com/mixsmart/utils/FormulaUtils.java

@@ -3,6 +3,8 @@ package com.mixsmart.utils;
 
 import com.alibaba.fastjson.JSONArray;
 import com.alibaba.fastjson.JSONObject;
+import org.apache.commons.text.similarity.JaccardSimilarity;
+import org.springblade.core.tool.utils.BeanUtil;
 import org.springblade.core.tool.utils.Func;
 import org.springblade.manager.bean.TableInfo;
 import org.springblade.manager.dto.Coords;
@@ -41,6 +43,40 @@ public class FormulaUtils {
         return map;
     }
 
+    /**
+     * @Description  字符串相似度
+     * @Param [s1, s2]
+     * @return double
+     * @Author yangyj
+     * @Date 2023.04.12 18:01
+     **/
+    public static double getJaccardSimilarity(String s1, String s2) {
+
+        Set<Character> set1 = new HashSet<>();
+        Set<Character> set2 = new HashSet<>();
+
+        for (char c : s1.toCharArray()) {
+            set1.add(c);
+        }
+
+        for (char c : s2.toCharArray()) {
+            set2.add(c);
+        }
+
+        Set<Character> intersection = new HashSet<>(set1);
+        intersection.retainAll(set2);
+
+        Set<Character> union = new HashSet<>(set1);
+        union.addAll(set2);
+
+        return (double) intersection.size() / union.size();
+    }
+
+    public static  Double similarity(String s1,String s2){
+        return getJaccardSimilarity(parseItemName(s1),parseItemName(s2));
+    }
+
+
 
     /**
      * result[0]^2+result[1]^2=result[2]^2  result[] 元素均为正整数
@@ -278,16 +314,15 @@ public class FormulaUtils {
         //huangjn 每份填报数据的id,目前日志专用
     }
 
-    /*从元素名称中解析项目名称*/
+    /**从元素名称中解析项目名称*/
     public static  String parseItemName(String eName){
         String[] candidate= StringUtils.handleNull(eName).replaceAll("^[^\\u4e00-\\u9fa5]+","").replaceAll("\\s+","").split("[((].+[))]|_");
         if(candidate.length>0){
-           return Arrays.stream(candidate).filter(e->!e.contains("实测项目")&&!e.contains("△")).findFirst().orElse(eName);
+           return Arrays.stream(candidate).filter(e->!e.contains("实测项目")&&!e.contains("△")).findFirst().orElse(eName).replaceAll("实测值?|偏差值?|设计值?","");
         }
         return eName;
     }
 
-//    public static void main(String[] args) {
-//        System.out.println(parseItemName("实 测 项 目_3△_内轮廓高度(mm)_不小于设计值_实测值或实测偏差值"));
-//    }
+
+
 }

+ 4 - 94
blade-service/blade-manager/src/main/java/com/mixsmart/utils/StringUtils.java

@@ -326,20 +326,7 @@ public class StringUtils {
 		return serialNum;
 	}
 	
-	
-	/**
-	 * 生成序列号;
-	 * TODO 改为采用UUID生成序列号
-	 * 生成的序列号;如:U+时间+5位随机序列号
-	 * 如:U141264925197606685
-	 * @return 返回系统自动生成的序列号
-	 */
-	public static String createSerialNum() {
-		/*long time = System.currentTimeMillis();
-		return "U"+time+randomNum(5);*/
-	    return uuid();
-	}
-	
+
 	/**
 	 * 生成UUID序列号
 	 * @return 返回UUID
@@ -378,86 +365,9 @@ public class StringUtils {
 	public static String trimFileSuffix(String fileName) {
 		return fileName.substring(0,fileName.lastIndexOf("."));
 	}
+
 	
-	
-	/**
-	 * 大写字母直接用下划线分割,并把大写转换为小写 <br />
-	 * 如:HelloWorld转换为hello_world
-	 * @param value
-	 * @return 返回处理结果
-	 */
-	public static String upperSeparateUnderline(String value) {
-		StringBuilder strBuilder = null;
-		if(isNotEmpty(value)) {
-		    strBuilder = new StringBuilder();
-			byte[] values = value.getBytes();
-			for (int i = 0; i < values.length; i++) {
-				if(values[i]>=65 && values[i]<=90) {
-					if(i>0 && i<(values.length-1)) {
-					    strBuilder.append("_"+(char)((int)values[i]+32));
-					} else {
-					    strBuilder.append(String.valueOf((char)((int)values[i]+32)));
-					}
-				} else {
-				    strBuilder.append(String.valueOf((char)values[i]));
-				}
-			}
-			values = null;
-		}
-		return strBuilder != null ? strBuilder.toString() : null;
-	}
-	
-	/**
-	 * 首字母转为大写
-	 * @param value
-	 * @return 返回处理后的结果
-	 */
-	public static String firstToUppercase(String value) {
-		if(isNotEmpty(value)) {
-			String firstChar = value.substring(0, 1);
-			String otherChar = value.substring(1);
-			firstChar = firstChar.toUpperCase();
-			value = firstChar+otherChar;
-		}
-		return value;
-	}
-	
-	
-	/**
-	 * 过滤HTML标签.
-	 * @param htmlContent
-	 * @return 返回过滤后的结果
-	 */
-	public static String html2Text(String htmlContent) {
-		if(isEmpty(htmlContent))
-			return htmlContent;
-		Pattern pScript, pStyle, pHtml; //定义规则
-	    Matcher mScript, mStyle, mHtml; //匹配规则
-	    
-	    //定义script的正则表达式{或<script[^>]*?>[\\s\\S]*?<\\/script>
-        String regExScript = "<[\\s]*?script[^>]*?>[\\s\\S]*?<[\\s]*?\\/[\\s]*?script[\\s]*?>"; 
-        //定义style的正则表达式{或<style[^>]*?>[\\s\\S]*?<\\/style>
-        String regExStyle = "<[\\s]*?style[^>]*?>[\\s\\S]*?<[\\s]*?\\/[\\s]*?style[\\s]*?>";
-         //定义HTML标签的正则表达式
-        String regExHtml = "<[^>]+>";
-        
-        //过滤script标签
-        pScript = Pattern.compile(regExScript, Pattern.CASE_INSENSITIVE);
-        mScript = pScript.matcher(htmlContent);
-        htmlContent = mScript.replaceAll(""); 
-
-        //过滤style标签
-        pStyle = Pattern.compile(regExStyle, Pattern.CASE_INSENSITIVE);
-        mStyle = pStyle.matcher(htmlContent);
-        htmlContent = mStyle.replaceAll(""); 
-
-        //过滤html标签
-        pHtml = Pattern.compile(regExHtml, Pattern.CASE_INSENSITIVE);
-        mHtml = pHtml.matcher(htmlContent);
-        htmlContent = mHtml.replaceAll("");
-	    
-		return htmlContent;
-	}
+
 	
 	
 	/**
@@ -667,7 +577,7 @@ public class StringUtils {
 	public static boolean isContains(String value,String contain) {
 		boolean is = false;
 		if(!isEmpty(value) && null != contain) {
-			is = value.indexOf(contain)>-1?true:false;
+			is = value.contains(contain) ?true:false;
 		}
 		return is;
 	}

+ 9 - 1
blade-service/blade-manager/src/main/java/org/springblade/manager/feign/WbsTreeContractClientImpl.java

@@ -11,6 +11,7 @@ import org.springblade.common.constant.CommonConstant;
 import org.springblade.common.utils.CommonUtil;
 import org.springblade.core.tool.node.ForestNodeMerger;
 import org.springblade.manager.entity.*;
+import org.springblade.manager.mapper.WbsTreeContractMapper;
 import org.springblade.manager.service.IContractInfoService;
 import org.springblade.manager.service.IWbsTreeContractService;
 import org.springblade.manager.service.impl.WbsTreeContractServiceImpl;
@@ -36,6 +37,8 @@ public class WbsTreeContractClientImpl implements WbsTreeContractClient {
 
     private final ISysClient sysClient;
 
+    private final WbsTreeContractMapper wbsTreeContractMapper;
+
     @Override
     public WbsTreeContract queryContractTreeNodeByPKeyId(Long toCopyNodePKeyId) {
         return this.wbsTreeContractService.getOne(Wrappers.<WbsTreeContract>lambdaQuery().eq(WbsTreeContract::getPKeyId, toCopyNodePKeyId));
@@ -107,7 +110,7 @@ public class WbsTreeContractClientImpl implements WbsTreeContractClient {
 
     @Override
     public Boolean saveBatch(List<WbsTreeContract> list) {
-        return this.wbsTreeContractServiceImpl.saveOrUpdateBatch(list, 1000);
+        return this.wbsTreeContractServiceImpl.insertBatch(list, 1000);
     }
 
     @Override
@@ -258,6 +261,11 @@ public class WbsTreeContractClientImpl implements WbsTreeContractClient {
         return null;
     }
 
+    @Override
+    public Long getAllTableFileSize(Long projectId) {
+        return wbsTreeContractMapper.getAllTableFileSize(projectId);
+    }
+
     private void foreachSetChildList(List<WbsTreeContractTreeVOS> vosResult, List<WbsTreeContractVO> voList) {
         voList.forEach(vo -> {
             WbsTreeContractTreeVOS vos = new WbsTreeContractTreeVOS();

+ 25 - 0
blade-service/blade-manager/src/main/java/org/springblade/manager/formula/ElementBlock.java

@@ -0,0 +1,25 @@
+package org.springblade.manager.formula;
+
+import com.alibaba.fastjson.annotation.JSONField;
+import com.fasterxml.jackson.annotation.JsonIgnore;
+import lombok.Data;
+
+import java.util.List;
+
+/**
+ * @author yangyj
+ * @Date 2023/4/14 14:57
+ * @description TODO
+ */
+
+@Data
+public class ElementBlock {
+
+    @JSONField(name="c")
+    private String code;
+    @JSONField(name="m")
+    private String eName;
+    @JSONField(name="v")
+    private List<ItemBlock>  list;
+
+}

+ 55 - 0
blade-service/blade-manager/src/main/java/org/springblade/manager/formula/ItemBlock.java

@@ -0,0 +1,55 @@
+package org.springblade.manager.formula;
+
+import com.alibaba.fastjson.annotation.JSONField;
+import com.mixsmart.utils.StringUtils;
+import lombok.Data;
+import java.util.Arrays;
+import java.util.List;
+import java.util.stream.Collectors;
+
+/**
+ * @author yangyj
+ * @Date 2023/4/14 14:45
+ * @description TODO
+ */
+@Data
+public class ItemBlock {
+    @JSONField(serialize = false)
+    private String code;
+    @JSONField(serialize = false)
+    private String key;
+    /**对应工序流水号*/
+    @JSONField(name="p")
+    private Long pkeyId;
+    /**实测值*/
+    @JSONField(name="d")
+    private List<List<Double>> data;
+    /**设计值*/
+    @JSONField(name="s")
+    private List<Double> designs;
+    /**合格率*/
+    @JSONField(name="a")
+    private Integer subPass;
+    /**小计*/
+    @JSONField(name="t")
+    private Integer subTotal;
+    /**偏差范围*/
+    @JSONField(name="x")
+    private String dev;
+    public void setD(String d){
+        if(StringUtils.isNotEmpty(d)){
+           this.data= Arrays.stream(d.split("/")).map(e-> Arrays.stream(e.split(",")).map(Double::parseDouble).collect(Collectors.toList())).collect(Collectors.toList());
+        }
+    }
+    public void setS(String s){
+        if(StringUtils.isNotEmpty(s)){
+            this.designs= Arrays.stream(s.split("/")).map(Double::parseDouble).collect(Collectors.toList());
+        }
+    }
+
+    @JSONField(serialize = false)
+    public String getKey(){
+        return code+":"+pkeyId;
+    }
+
+}

+ 18 - 0
blade-service/blade-manager/src/main/java/org/springblade/manager/formula/NodeTable.java

@@ -0,0 +1,18 @@
+package org.springblade.manager.formula;
+
+import lombok.Data;
+
+/**
+ * @author yangyj
+ * @Date 2023/4/11 17:20
+ * @description 分项节点表信息映射
+ */
+@Data
+public class NodeTable {
+    private String nodeName;
+    private Long nodeId;
+    private String tabName;
+    private String initTableName;
+    private Long tabId;
+    private String url;
+}

+ 32 - 0
blade-service/blade-manager/src/main/java/org/springblade/manager/formula/TableEleKey.java

@@ -0,0 +1,32 @@
+package org.springblade.manager.formula;
+
+import com.mixsmart.utils.FormulaUtils;
+import lombok.Data;
+import org.springblade.core.tool.utils.Func;
+
+/**
+ * @author yangyj
+ * @Date 2023/4/11 17:29
+ * @description TODO
+ */
+@Data
+public class TableEleKey {
+    private String tabName;
+    private String initTableName;
+    private String eName;
+    private Long elementId;
+    private String eKey;
+    private String cpStr;
+    public String getCode(){
+        if(initTableName!=null&&eKey!=null){
+            return initTableName+":"+eKey;
+        }
+        return "";
+    }
+    public Double getDegree(){
+        if(Func.isNotBlank(cpStr)&&Func.isNotEmpty(eName)){
+        return     FormulaUtils.getJaccardSimilarity(cpStr,FormulaUtils.parseItemName(eName));
+        }
+        return 0d;
+    }
+}

+ 10 - 0
blade-service/blade-manager/src/main/java/org/springblade/manager/formula/impl/AssessmentForm.java

@@ -0,0 +1,10 @@
+package org.springblade.manager.formula.impl;
+
+/**
+ * @author yangyj
+ * @Date 2023/4/11 14:52
+ * @description 评定记录表
+ */
+public class AssessmentForm {
+
+}

+ 52 - 0
blade-service/blade-manager/src/main/java/org/springblade/manager/formula/impl/Measurement.java

@@ -0,0 +1,52 @@
+package org.springblade.manager.formula.impl;
+
+import com.mixsmart.utils.FormulaUtils;
+import lombok.Data;
+import org.springblade.core.tool.utils.Func;
+import org.springblade.manager.dto.FormData;
+
+import java.util.List;
+
+/**
+ * @author yangyj
+ * @Date 2023/4/11 15:11
+ * @description 检查内容
+ */
+@Data
+public class Measurement {
+    /**实测值*/
+    private FormData value;
+    /**合格率*/
+    private FormData pass;
+    /**合格判断*/
+    private FormData judge;
+    private String design;
+    private String dev;
+    private List<String> list;
+    private String point;
+    private String valueCode;
+    private String designCode;
+    private String valueName;
+    private String designName;
+    public Measurement(String point) {
+        this.point = point;
+    }
+    public Measurement() {
+    }
+    /**是否匹配成功*/
+    public Boolean isMatching(){
+           return value!=null&&pass!=null&&judge!=null;
+    }
+    public void flush(){
+        this.value.setFinished(true);
+        this.value.setUpdate(1);
+        this.value.setFormula(null);
+        this.pass.setFinished(true);
+        this.pass.setUpdate(1);
+        this.pass.setFormula(null);
+        this.judge.setFinished(true);
+        this.judge.setUpdate(1);
+        this.judge.setFormula(null);
+    }
+
+}

+ 1 - 1
blade-service/blade-manager/src/main/java/org/springblade/manager/formula/impl/TableElementConverter.java

@@ -188,7 +188,7 @@ public class TableElementConverter implements ITableElementConverter {
     public void after() {
         /*这个方法的核心就是把fds的数据按照既定格式(key_xxx_val_y_x)回写到tableInfo,对fds进行tableName分组,非空循环写人*/
         LinkedHashMap<String,List<KeyMapper>> tabs = keyMappers.stream().collect(Collectors.groupingBy(KeyMapper::getCode,LinkedHashMap::new,Collectors.toList()));
-        List<FormData> updateList = this.formDataMap.values().stream().filter(e->e.getUpdate()==1).collect(Collectors.toList());
+        List<FormData> updateList = this.formDataMap.values().stream().filter(e->e.getUpdate()==1&&e.isCurrentNodeElement).collect(Collectors.toList());
         if(Func.isNotEmpty(updateList)){
             for (FormData fd : updateList) {
                 if(fd.getUpdate().equals(1)){

+ 11 - 0
blade-service/blade-manager/src/main/java/org/springblade/manager/mapper/FormulaDataBlockMapper.java

@@ -0,0 +1,11 @@
+package org.springblade.manager.mapper;
+
+import com.baomidou.mybatisplus.core.mapper.BaseMapper;
+import org.springblade.manager.entity.FormulaDataBlock;
+
+
+/**
+ * @author yangyj
+ */
+public interface FormulaDataBlockMapper extends BaseMapper<FormulaDataBlock> {
+}

+ 2 - 0
blade-service/blade-manager/src/main/java/org/springblade/manager/mapper/WbsTreeContractMapper.java

@@ -84,4 +84,6 @@ public interface WbsTreeContractMapper extends EasyBaseMapper<WbsTreeContract> {
 
     void updateDeletedByIds(@Param("ids") List<Long> ids);
 
+    Long getAllTableFileSize(@Param("projectId") Long projectId);
+
 }

+ 9 - 0
blade-service/blade-manager/src/main/java/org/springblade/manager/mapper/WbsTreeContractMapper.xml

@@ -632,4 +632,13 @@
         SELECT b.* from u_operation_log a,blade_user b where a.operation_account=b.account and a.operation_type=1 and  a.business_id like concat('%', #{sonId}, '%')
         group by b.id
     </select>
+    <select id="getAllTableFileSize" resultType="java.lang.Long">
+        select sum(DATA_LENGTH)
+        from information_schema.tables
+        where table_schema='bladex'
+        AND table_name in (SELECT mwtc.init_table_name
+                           FROM m_wbs_tree_contract mwtc
+                           WHERE mwtc.project_id =#{projectId} and mwtc.init_table_name is NOT NULL and mwtc.init_table_name != ''
+                           GROUP by mwtc.init_table_name );
+    </select>
 </mapper>

+ 14 - 0
blade-service/blade-manager/src/main/java/org/springblade/manager/service/IFormulaDataBlockService.java

@@ -0,0 +1,14 @@
+package org.springblade.manager.service;
+
+import com.baomidou.mybatisplus.extension.service.IService;
+import org.springblade.manager.entity.FormulaDataBlock;
+import org.springblade.manager.formula.ElementBlock;
+
+import java.util.List;
+
+/**
+ * @author yangyj
+ */
+public interface IFormulaDataBlockService extends IService<FormulaDataBlock> {
+    FormulaDataBlock queryOption(Long contractId, Long swId , Integer type);
+}

+ 32 - 0
blade-service/blade-manager/src/main/java/org/springblade/manager/service/impl/FormulaDataBlockServiceImpl.java

@@ -0,0 +1,32 @@
+package org.springblade.manager.service.impl;
+
+import com.baomidou.mybatisplus.core.toolkit.Wrappers;
+import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
+import lombok.RequiredArgsConstructor;
+import org.springblade.core.tool.utils.Func;
+import org.springblade.manager.entity.FormulaDataBlock;
+import org.springblade.manager.mapper.FormulaDataBlockMapper;
+import org.springblade.manager.service.IFormulaDataBlockService;
+import org.springframework.stereotype.Service;
+import java.util.List;
+
+/**
+ * @author yangyj
+ * @Date 2023/4/13 15:46
+ * @description TODO
+ */
+@Service
+@RequiredArgsConstructor
+public class FormulaDataBlockServiceImpl extends ServiceImpl<FormulaDataBlockMapper, FormulaDataBlock> implements IFormulaDataBlockService {
+
+    @Override
+    public FormulaDataBlock queryOption(Long contractId, Long swId, Integer type) {
+        List<FormulaDataBlock> dataBlockList = this.list(Wrappers.<FormulaDataBlock>lambdaQuery().eq(FormulaDataBlock::getContractId,contractId).eq(FormulaDataBlock::getSwId,swId).eq(FormulaDataBlock::getType,type));
+         if(Func.isNotEmpty(dataBlockList)){
+             return dataBlockList.get(0);
+         }
+        return null;
+    }
+
+
+}

+ 263 - 7
blade-service/blade-manager/src/main/java/org/springblade/manager/service/impl/FormulaServiceImpl.java

@@ -22,9 +22,9 @@ import org.springblade.core.tool.utils.*;
 import org.springblade.manager.bean.TableInfo;
 import org.springblade.manager.dto.*;
 import org.springblade.manager.entity.*;
-import org.springblade.manager.formula.FormulaStrategyFactory;
-import org.springblade.manager.formula.KeyMapper;
+import org.springblade.manager.formula.*;
 import org.springblade.manager.formula.impl.CompositeDataAccess;
+import org.springblade.manager.formula.impl.Measurement;
 import org.springblade.manager.formula.impl.SubTable;
 import org.springblade.manager.formula.impl.TableElementConverter;
 import org.springblade.manager.mapper.FormulaMapper;
@@ -41,6 +41,7 @@ import java.io.File;
 import java.io.FileInputStream;
 import java.io.FileNotFoundException;
 import java.util.*;
+import java.util.concurrent.atomic.AtomicBoolean;
 import java.util.concurrent.atomic.AtomicInteger;
 import java.util.regex.Matcher;
 import java.util.regex.Pattern;
@@ -68,7 +69,8 @@ public class FormulaServiceImpl extends BaseServiceImpl<FormulaMapper, Formula>
     private final IWbsTreeService wbsTreeService;
     private final JdbcTemplate jdbcTemplate;
     private final IFormulaOptionService formulaOptionService;
-    private final ITextdictInfoService textdictInfoService;
+    private final ITextdictInfoService textDictInfoService;
+    private final IFormulaDataBlockService formulaDataBlockService;
 
     /**  private final Container env;*/
     private   TableElementConverter tec;
@@ -190,9 +192,162 @@ public class FormulaServiceImpl extends BaseServiceImpl<FormulaMapper, Formula>
            /*数据格式 {tablename:{keyxxx:{option:[1|0]}}}*/
            this.constantMap.put(FMOT,JSON.parseObject(formulaOption.getVal(),LinkedHashMap.class));
         }
+        /*评定表*/
+        assessmentForm();
         return this;
     }
 
+    public void assessmentForm(){
+        if(tec.getTableAll().stream().anyMatch(e->StringUtils.isEquals(e.getTableType(),5))){
+            /*评定节点*/
+            AppWbsTreeContractVO one =tec.getTableAll().get(0);
+            List<String> ancestor=new ArrayList<>(Arrays.asList(one.getAncestors().split(",")));
+            Collections.reverse(ancestor);
+            FormulaDataBlock fdb = this.formulaDataBlockService.queryOption(Long.parseLong(one.getContractId()),Long.parseLong(ancestor.get(1)),0);
+            if(fdb!=null&&Func.isNotBlank(fdb.getVal())){
+                List<ElementBlock> elementBlockList =JSON.parseArray(fdb.getVal(),ElementBlock.class);
+                Map<String, Measurement> itemsMap = new HashMap<>();
+                this.formDataMap.values().forEach(e->{
+                    String eName=e.getEName();
+                    if(eName.contains("实测")&&!eName.contains("平均")){
+                        String point  =FormulaUtils.parseItemName(eName);
+                        Measurement measurement = itemsMap.computeIfAbsent(point,k->new Measurement(point));
+                        if(eName.contains("偏差")){
+                            measurement.setValue(e);
+                        }else if(eName.contains("率")){
+                            measurement.setPass(e);
+                        }else if(eName.contains("判")){
+                            measurement.setJudge(e);
+                        }
+                    }
+                });
+                if(itemsMap.size()>0){
+                    AtomicBoolean update= new AtomicBoolean(false);
+                    itemsMap.values().stream().filter(Measurement::isMatching).forEach(t->{
+                        ElementBlock g=null;
+                        FormData vfd=t.getValue();
+                        if(vfd.executable()&&vfd.getFormula().getRelyList()!=null){
+                            List<String> relyList = vfd.getFormula().getRelyList();
+                           Optional<ElementBlock> op= elementBlockList.stream().filter(e->relyList.contains(e.getCode())).findAny();
+                           if(op.isPresent()){
+                               g=op.get();
+                           }
+                        }
+                        if(g==null){
+                            Optional<ElementBlock> op=   elementBlockList.stream().filter(w->FormulaUtils.similarity(w.getEName(),t.getPoint())>0.6).reduce((a, b) -> Comparator.<Double>reverseOrder().compare(FormulaUtils.similarity(a.getEName(),t.getPoint()), FormulaUtils.similarity(b.getEName(),t.getPoint())) <= 0 ? a : b);
+                            if(op.isPresent()){
+                                g=op.get();
+                            }
+                        }
+                        if(g!=null){
+                            List<ItemBlock> itemBlockList =g.getList();
+                            int originSize=itemBlockList.size();
+                            List<Long> ids = this.jdbcTemplate.queryForList("select b.p_key_id from m_wbs_tree_contract a join m_wbs_tree_contract b on (a.parent_id=b.parent_id and a.contract_id=b.contract_id) where a.p_key_id="+tec.getCurrentNode().getPkId()+" and b.is_deleted=0 and b.node_type=6",Long.class);
+                            itemBlockList.removeIf(ik->!ids.contains(ik.getPkeyId()));
+                            if(itemBlockList.size()>0){
+                                int total=itemBlockList.stream().mapToInt(ItemBlock::getSubTotal).sum();
+                                int passNum=itemBlockList.stream().mapToInt(ItemBlock::getSubPass).sum();
+                                double passRate=100*(double)passNum/(double) total;
+                                FormulaUtils.write(t.getPass(),StringUtils.number2String(passRate,1),null);
+                                if(passRate>=60){
+                                    FormulaUtils.write(t.getJudge(),"合格",null);
+                                }
+                                itemBlockList.sort(Comparator.comparingInt(a->ids.indexOf(a.getPkeyId())));
+                                FormulaUtils.write(t.getValue(),itemBlockList.stream().map(ItemBlock::getData).flatMap(v->v.stream().flatMap(Collection::stream)).collect(Collectors.toList()),true);
+
+//                                   if(t.getValue().getEName().contains("±")){
+//                                       /*存在偏差范围则获取的是偏差值:实测-设计*/
+//                                       FormulaUtils.write(t.getValue(),itemBlockList.stream().flatMap(b->{
+//                                           List<Double> result=new ArrayList<>();
+//                                           List<List<Double>> datas=b.getData();
+//                                           List<Double> designs=b.getDesigns();
+//                                           for(int i=0;i<datas.size();i++){
+//                                               int j=Math.min(designs.size()-1,i);
+//                                               double des=designs.get(j);
+//                                               datas.get(i).forEach(d->result.add(d-des));
+//                                           }
+//                                           return  result.stream();
+//                                       }).collect(Collectors.toList()),true);
+//                                   }else{
+//                                      FormulaUtils.write(t.getValue(),itemBlockList.stream().map(ItemBlock::getData).flatMap(v->v.stream().flatMap(Collection::stream)).collect(Collectors.toList()),true);
+//                                   }
+                            }
+                            t.flush();
+                            if(originSize>0&&originSize!=itemBlockList.size()){
+                                g.setList(itemBlockList);
+                                update.set(true);
+                            }
+                        }
+                    });
+                    if(update.get()){
+                        this.formulaDataBlockService.saveOrUpdate(fdb);
+                    }
+                }
+
+            }
+        }
+    }
+
+
+    /**评定表自动匹配*/
+//    public  void  doForAssessmentForm(){
+//        try {
+//            List<String> tableNames = tec.getTableAll().stream().filter(e->StringUtils.isEquals(e.getTableType(),5)).map(AppWbsTreeContractVO::getInitTableName).collect(Collectors.toList());
+//            if(Func.isNotEmpty(tableNames)){
+//                   List<Map<String,Object>> mapList=this.jdbcTemplate.queryForList("select  k.node_name nodeName,k.p_key_id nodeId ,c.node_name tabName,c.sort,c.init_table_name initTableName,c.p_key_id tabId,c.html_url url   from (select b.id,b.node_name,b.sort ,b.p_key_id from (select * from m_wbs_tree_contract  where p_key_id="+tec.getCurrentNode().getPkId()+") a join  m_wbs_tree_contract b on b.parent_id=a.parent_id where  b.contract_id="+tec.getContractId()+" and b.is_deleted=0 and b.node_type=6 ) k join m_wbs_tree_contract c on c.parent_id = k.id  where  c.contract_id="+tec.getContractId()+" and c.is_deleted=0 and c.table_owner in(1,2,3) ORDER BY k.sort ,c.sort,c.p_key_id");
+//                   if(Func.isNotEmpty(mapList)){
+//                       List<NodeTable> nodeTables =mapList.stream().map(e->BeanUtil.toBean(e,NodeTable.class)).collect(Collectors.toList());
+//                       List<String> exclude=tec.getTableAll().stream().map(AppWbsTreeContractVO::getInitTableName).collect(Collectors.toList());
+//                       List<Map<String,Object>> keyMapList= this.jdbcTemplate.queryForList("select a.tab_ch_name tabName,a.tab_en_name initTableName,b.e_name eName,b.id elementId,b.e_key  eKey from m_table_info a join m_wbs_form_element b on b.f_id=a.id where a.tab_en_name in ('"+nodeTables.stream().map(NodeTable::getInitTableName).distinct().filter(e->!exclude.contains(e)).collect(Collectors.joining("','"))+"') and b.is_deleted=0");
+//                       List<TableEleKey> tableEleKeys=keyMapList.stream().map(e->BeanUtil.toBean(e,TableEleKey.class)).collect(Collectors.toList());
+//                       Map<String, Measurement> itemsMap = new HashMap<>();
+//                       this.formDataMap.values().forEach(e->{
+//                           String eName=e.getEName();
+//                           if(eName.contains("实测")&&!eName.contains("平均")){
+//                               String point  =FormulaUtils.parseItemName(eName);
+//                               Measurement measurement = itemsMap.computeIfAbsent(point,k->new Measurement(point));
+//                               if(eName.contains("偏差")){
+//                                   measurement.setValue(e);
+//                               }else if(eName.contains("率")){
+//                                   measurement.setPass(e);
+//                               }else if(eName.contains("判")){
+//                                   measurement.setJudge(e);
+//                               }
+//                           }
+//                       });
+//
+//                      Map<Boolean,List<TableEleKey>> tmpMap=   tableEleKeys.stream().collect(Collectors.partitioningBy(t->t.getTabName().contains("质量检验")));
+//                       List<TableEleKey> tableEleKeysA= tmpMap.get(false);
+//                       List<TableEleKey> tableEleKeysB=tmpMap.get(true);
+//                       itemsMap.values().forEach(e->{
+//                           //tableEleKeys.stream().filter(tk -> !tk.getTabName().contains("质量检验")).reduce((a, b) -> FormulaUtils.getJaccardSimilarity(e.getValue().getEName(), a.getEName()) - FormulaUtils.getJaccardSimilarity(e.getValue().getEName(), b.getEName()) >= 0 ? a : b).ifPresent(source -> e.setValueCode(source.getCode()));
+//                           List<TableEleKey> target=tableEleKeysA.stream().sorted(Comparator.comparingDouble(tk->FormulaUtils.getJaccardSimilarity(e.getPoint(),FormulaUtils.parseItemName(tk.getEName())))).collect(Collectors.toList());
+//                           //List<TableEleKey> target1=tableEleKeysA.stream().sorted(Comparator.comparingDouble(TableEleKey::getDegree).reversed()).collect(Collectors.toList());
+//                           Collections.reverse(target);
+//                           target=target.stream().limit(3).collect(Collectors.toList());
+//                           target.forEach(g->{
+//                               String eName=g.getEName();
+//                               String code =g.getCode();
+//                               if(eName.contains("实测")&&!eName.contains("设计")&&!eName.contains("偏")){
+//                                   e.setValueCode(code);
+//                                   e.setValueName(eName);
+//                               }else if(eName.contains("设计")&&!eName.contains("偏")){
+//                                   e.setDesignCode(code);
+//                                   e.setDesignName(eName);
+//                               }else if(eName.contains("偏")){
+//
+//                               }
+//                           });
+//                       });
+//                       tec.getLog().append("【评定表实测项目匹配度】");
+//                       System.out.println();
+//                   }
+//            }
+//        }catch (Exception e){
+//            e.printStackTrace();
+//        }
+//    }
+
     public void missingFill(List<String> missingList){
         /*数据池里面没有任何元素匹配和当前依赖匹配*/
         if(Func.isNotEmpty(missingList)){
@@ -200,7 +355,7 @@ public class FormulaServiceImpl extends BaseServiceImpl<FormulaMapper, Formula>
             Map<String, Object> elementInfoMap=this.getElementInfoByCodes(String.join(",",missingList));
             /*1从当前节点其它表格中查找匹配的元素*/
             List<String> removeList=new ArrayList<>();
-            if(false) {//全加载后,关闭当前节的搜索,假如后期改成依赖加载可以再次利用
+            if(false) {/*全加载后,关闭当前节的搜索,假如后期改成依赖加载可以再次利用*/
                 for (String r : missingList) {
                     String tn = r.substring(0, r.indexOf(StringPool.COLON));
                     String key = r.substring(r.indexOf(StringPool.COLON) + 1);
@@ -396,7 +551,7 @@ public class FormulaServiceImpl extends BaseServiceImpl<FormulaMapper, Formula>
 
     /*汇总阶段执行的公式*/
     public void summaryPre(){
-        this.formDataList.stream().filter(e->StringUtils.isEquals("CKI",e.getFormula().getNumber())||StringUtils.isEquals("CKD",e.getFormula().getNumber())).forEach(t->this.summary.add(t));
+        this.formDataList.stream().filter(FormData::executable).filter(e->StringUtils.isEquals("CKI",e.getFormula().getNumber())||StringUtils.isEquals("CKD",e.getFormula().getNumber())).forEach(t->this.summary.add(t));
         this.formDataList.removeAll(this.summary);
         /*监表的处理*/
         Optional<AppWbsTreeContractVO> aop=tec.getTableAll().stream().filter(e->e.getNodeName().contains("A15")).findAny();
@@ -586,6 +741,7 @@ public class FormulaServiceImpl extends BaseServiceImpl<FormulaMapper, Formula>
         try {
             /*检验单附表处理*/
             List<FormData> inspectionList = new ArrayList<>();
+            /*0检验表1评定表*/
             this.tec.getTableAll().stream().filter(e -> e.getNodeName().contains("检验单") || e.getNodeName().contains("评定表")).forEach(e -> {
                 /*获取所有挂在表里的元素映射关系*/
                 this.tec.getKeyMappers().stream().filter(p -> p.getPkId().equals(e.getPKeyId())).forEach(k -> {
@@ -654,6 +810,7 @@ public class FormulaServiceImpl extends BaseServiceImpl<FormulaMapper, Formula>
                             String values=subTableInfo.stream().map(TableInfo::getDataMap).map(m->m.get(StringUtils.handleNull(e.get("ekey")))).filter(StringUtils::isNotEmpty).collect(Collectors.joining(";;"));
                             FormData tmp=  createFormDataFast(StringUtils.handleNull(e.get("ename")),StringUtils.handleNull(e.get("code")),values);
                             if(tmp!=null){
+                                tmp.setIsCurrentNodeElement(true);
                                 this.formDataMap.put(tmp.getCode(),tmp);
                                 this.formDataList.add(tmp);
                             }
@@ -697,11 +854,15 @@ public class FormulaServiceImpl extends BaseServiceImpl<FormulaMapper, Formula>
                     sta.flush();
                 }
             }
+
         } catch (Exception e) {
             this.tec.getLog().append("【").append("附表异常").append("】");
             e.printStackTrace();
         }
     }
+
+
+
     /**汇总处理*/
     public void summaryCalc(){
         if(this.summary.size()>0){
@@ -720,6 +881,101 @@ public class FormulaServiceImpl extends BaseServiceImpl<FormulaMapper, Formula>
                    e.setUpdate(1);
                 }
             });
+            /*分项汇总*/
+            doForDataBlock();
+        }
+    }
+
+
+    /**分项汇总数据*/
+    public void   doForDataBlock(){
+        try {
+            AppWbsTreeContractVO one =tec.getTableAll().get(0);
+            List<String> ancestor=new ArrayList<>(Arrays.asList(one.getAncestors().split(",")));
+            Collections.reverse(ancestor);
+            FormulaDataBlock fdb = this.formulaDataBlockService.queryOption(Long.parseLong(one.getContractId()),Long.parseLong(ancestor.get(1)),0);
+            List<ElementBlock> elementBlockList=new ArrayList<>();
+            Map<String,ElementBlock> elementBlockMap =new HashMap<>();
+            Map<String,ItemBlock>itemBlockMap =new HashMap<>();
+            if(fdb==null){
+                fdb=new FormulaDataBlock();
+                fdb.setContractId(tec.getContractId());
+                fdb.setSwId(Long.parseLong(ancestor.get(1)));
+                fdb.setType(0);
+                fdb.setVal("[]");
+            }
+            if(Func.isNotBlank(fdb.getVal())) {
+                elementBlockList = JSON.parseArray(fdb.getVal(), ElementBlock.class);
+                elementBlockList.forEach(eb->{
+                    elementBlockMap.put(eb.getCode(),eb);
+                    List<ItemBlock> itemBlockList =eb.getList();
+                    if(itemBlockList.size()>0){
+                        itemBlockList.forEach(ib->{
+                            ib.setCode(eb.getCode());
+                            itemBlockMap.put(ib.getKey(),ib);
+                        });
+                    }
+                });
+            }
+            List<ElementBlock> finalElementBlockList = elementBlockList;
+            this.checkItems.stream().filter(e->!e.empty()).forEach(c->{
+                     ElementBlock eb =elementBlockMap.get(c.getCode());
+                     ItemBlock targetItem=itemBlockMap.get(c.getCode()+":"+tec.getCurrentNode().getPkId());
+                     List<Object> list = c.getValues().stream().map(ElementData::getValue).filter(StringUtils::isNotEmpty).collect(Collectors.toList());
+                     /*1.无任何记录,当前页无数据,则不需要处理 2.存在记录当前无数据,则要消除 3.没有记录当前有数据,则需要增加 4.有记录有当前记录,则需更新*/
+                     if(Func.isNotEmpty(list)||targetItem!=null){
+                         FormData designList=tec.getFormDataMap().values().stream().filter(t->StringUtils.isEquals(FormulaUtils.parseItemName(t.getEName()),FormulaUtils.parseItemName(c.getEName()))&&t.getEName().contains("设计")&&StringUtils.isEquals(t.getTableName(),c.getTableName())).collect(Collectors.toList()).get(0);
+                         FormData pass=tec.getFormDataMap().values().stream().filter(t->StringUtils.isEquals(FormulaUtils.parseItemName(t.getEName()),FormulaUtils.parseItemName(c.getEName()))&&t.getEName().contains("合格")&&StringUtils.isEquals(t.getTableName(),c.getTableName())).collect(Collectors.toList()).get(0);
+                         if(targetItem==null){
+                             if(eb==null){
+                                 eb=new ElementBlock();
+                                 eb.setCode(c.getCode());
+                                 eb.setEName(c.getEName());
+                                 eb.setList(new ArrayList<>());
+                                 finalElementBlockList.add(eb);
+                                 elementBlockMap.put(eb.getCode(),eb);
+                             }
+                             targetItem = new ItemBlock();
+                             targetItem.setCode(c.getCode());
+                             targetItem.setPkeyId(tec.getCurrentNode().getPkId());
+                             eb.getList().add(targetItem);
+                             itemBlockMap.put(targetItem.getKey(),targetItem);
+                         }
+                         if(Func.isNotEmpty(list)){
+                             targetItem.setSubTotal(list.size());
+                             targetItem.setDesigns(designList.getValues().stream().map(ElementData::getValue).flatMap(e->CustomFunction.obj2ListNe(e).stream()).filter(StringUtils::isNumber).map(StringUtils::obj2Double).collect(Collectors.toList()));
+                             AtomicInteger index= new AtomicInteger();
+                             int len=targetItem.getDesigns().size();
+                             if(len>0){
+                                 targetItem.setData(new ArrayList<>(list.stream().map(StringUtils::obj2Double).collect(Collectors.groupingBy(k -> index.getAndIncrement() / len,LinkedHashMap::new,Collectors.toList())).values()));
+                             }else{
+                                 targetItem.setData(Collections.singletonList(list.stream().map(StringUtils::obj2Double).collect(Collectors.toList())));
+                             }
+                             if(pass!=null&&!pass.empty()){
+                                 targetItem.setSubPass((int)Math.round(list.size()*StringUtils.obj2Double(pass.getValues().get(0).getValue())/100));
+                             }else{
+                                 targetItem.setSubPass(list.size());
+                             }
+                         }else{
+                             eb.getList().remove(targetItem);
+                         }
+                     }
+//                if(c.executable()){
+//                    /*主要是获取实测值,合格率,合格数量*/
+//                    List<String> relyCode = c.getFormula().getRelyList();
+//                    if(Func.isNotEmpty(relyCode)){
+//                        List<FormData> designList=  tec.getFormDataMap().values().stream().filter(t->relyCode.contains(t.getCode())&&t.getEName().contains("设计")).collect(Collectors.toList());
+//                        if(designList.size()>0){
+//                            FormData design =designList.get(0);
+//
+//                        }
+//                    }
+//                }
+            });
+            fdb.setVal(JSON.toJSONString(elementBlockList));
+            this.formulaDataBlockService.saveOrUpdate(fdb);
+        }catch (Exception e){
+            e.printStackTrace();
         }
     }
 
@@ -824,7 +1080,7 @@ public  List<ElementData> setScale(Integer scale,List<ElementData> data){
             }
         }
         /*检查超页情况*/
-        this.formDataMap.values().stream().filter(e->e.getUpdate()==1&&e.getAddPages()>0).sorted(Comparator.comparing(FormData::getAddPages).reversed())
+        this.formDataMap.values().stream().filter(e->e.getIsCurrentNodeElement()&&e.getUpdate()==1&&e.getAddPages()>0).sorted(Comparator.comparing(FormData::getAddPages).reversed())
                         .collect(Collectors.groupingBy(FormData::getTableName,LinkedHashMap::new,Collectors.toList())).values()
                         .forEach(l->copy(l.get(0)));
     }
@@ -1409,7 +1665,7 @@ public  List<ElementData> setScale(Integer scale,List<ElementData> data){
         QueryWrapper<TextdictInfo> queryWrapper = new QueryWrapper<>();
         queryWrapper.eq("type", 4);
         queryWrapper.eq("tab_id", wbsTreeContract.getIsTypePrivatePid());
-        final List<TextdictInfo> textdictInfos = textdictInfoService.getBaseMapper().selectList(queryWrapper);
+        final List<TextdictInfo> textdictInfos = textDictInfoService.getBaseMapper().selectList(queryWrapper);
         if (!textdictInfos.isEmpty()) {
             for (TextdictInfo textdictInfo : textdictInfos) {
                 if (reData.containsKey(textdictInfo.getColKey())) {

+ 2 - 3
blade-service/blade-manager/src/main/java/org/springblade/manager/service/impl/WbsTreeContractServiceImpl.java

@@ -152,7 +152,7 @@ public class WbsTreeContractServiceImpl extends BaseServiceImpl<WbsTreeContractM
                     }
                 }
             });
-            if (wbsTreeContractResultData.size()>0){
+            if (wbsTreeContractResultData.size() > 0) {
                 this.insertBatch(wbsTreeContractResultData, 1000);
             }
 
@@ -188,9 +188,8 @@ public class WbsTreeContractServiceImpl extends BaseServiceImpl<WbsTreeContractM
                 List<WbsTreeContract> delObjList = list.stream().filter(f -> ids1.contains(f.getId())).collect(Collectors.toList());
                 Map<Long, List<WbsTreeContract>> collect = delObjList.stream().filter(f -> ObjectUtil.isNotEmpty(f.getParentId())).collect(Collectors.groupingBy(WbsTreeContract::getParentId));
                 for (Map.Entry<Long, List<WbsTreeContract>> longListEntry : collect.entrySet()) {
-                    informationQueryClient.AsyncWbsTree(longListEntry.getKey().toString() + "", longListEntry.getKey() + "", pawDTO.getContractId(), "", "1");
+                    informationQueryClient.delAsyncWbsTree(longListEntry.getKey().toString() + "", pawDTO.getContractId() + "", "1");
                 }
-
             }
 
             //TODO ---------新增---------