Ver Fonte

Merge branch 'dev' of http://219.151.181.73:3000/zhuwei/bladex into dev

laibulaizheli há 3 semanas atrás
pai
commit
d5ead2afd1
26 ficheiros alterados com 954 adições e 129 exclusões
  1. 71 9
      blade-service/blade-archive/src/main/java/org/springblade/archive/mapper/ArchivesAutoMapper.xml
  2. 151 30
      blade-service/blade-business/src/main/java/org/springblade/business/controller/InformationWriteQueryController.java
  3. 2 2
      blade-service/blade-business/src/main/java/org/springblade/business/controller/NeiYeController.java
  4. 2 2
      blade-service/blade-business/src/main/java/org/springblade/business/controller/TaskController.java
  5. 1 1
      blade-service/blade-business/src/main/java/org/springblade/business/service/impl/TrialDeviceInfoServiceImpl.java
  6. 3 3
      blade-service/blade-business/src/main/java/org/springblade/business/service/impl/WeatherInfoServiceImpl.java
  7. 1 1
      blade-service/blade-control/src/main/java/org/springblade/control/service/impl/PublicScheduledTaskServiceImpl.java
  8. 2 2
      blade-service/blade-e-visa/src/main/java/org/springblade/evisa/controller/ArchiveController.java
  9. 1 1
      blade-service/blade-e-visa/src/main/java/org/springblade/evisa/controller/EVController.java
  10. 3 1
      blade-service/blade-manager/src/main/java/org/springblade/manager/controller/ExcelTabController.java
  11. 17 2
      blade-service/blade-manager/src/main/java/org/springblade/manager/controller/TextdictInfoController.java
  12. 2 2
      blade-service/blade-manager/src/main/java/org/springblade/manager/controller/WbsParamController.java
  13. 19 2
      blade-service/blade-manager/src/main/java/org/springblade/manager/feign/ExcelTabClientImpl.java
  14. 1 1
      blade-service/blade-manager/src/main/java/org/springblade/manager/job/SystemMsgJob.java
  15. 7 0
      blade-service/blade-manager/src/main/java/org/springblade/manager/mapper/WbsFormElementMapper.java
  16. 10 0
      blade-service/blade-manager/src/main/java/org/springblade/manager/mapper/WbsFormElementMapper.xml
  17. 7 0
      blade-service/blade-manager/src/main/java/org/springblade/manager/service/ITextdictInfoService.java
  18. 65 1
      blade-service/blade-manager/src/main/java/org/springblade/manager/service/impl/ExcelTabServiceImpl.java
  19. 1 1
      blade-service/blade-manager/src/main/java/org/springblade/manager/service/impl/TableInfoServiceImpl.java
  20. 129 0
      blade-service/blade-manager/src/main/java/org/springblade/manager/service/impl/TextdictInfoServiceImpl.java
  21. 128 56
      blade-service/blade-manager/src/main/java/org/springblade/manager/service/impl/WbsFormElementServiceImpl.java
  22. 321 2
      blade-service/blade-manager/src/main/java/org/springblade/manager/service/impl/WbsTreeContractServiceImpl.java
  23. 1 1
      blade-service/blade-manager/src/main/java/org/springblade/manager/service/impl/WbsTreePrivateServiceImpl.java
  24. 1 1
      blade-service/blade-manager/src/main/java/org/springblade/manager/service/impl/WbsTreeSynchronousRecordServiceImpl.java
  25. 7 7
      blade-service/blade-repair/src/main/java/org/springblade/repair/controller/CheckAndRepairController.java
  26. 1 1
      blade-service/blade-user/src/main/java/org/springblade/system/user/service/impl/UserServiceImpl.java

+ 71 - 9
blade-service/blade-archive/src/main/java/org/springblade/archive/mapper/ArchivesAutoMapper.xml

@@ -305,7 +305,29 @@
     </select>
 
     <select id="selectArchivesAutoFilePage" resultMap="archivesAutoResultMap">
-        select * from u_archives_auto u LEFT JOIN m_archive_tree_contract m ON u.node_id = m.id where u.is_deleted = 0
+        select
+            * ,
+            CAST(
+                CASE
+                    WHEN SUBSTRING_INDEX(file_number, '-', -1) REGEXP '^[0-9]+$'
+                        THEN SUBSTRING_INDEX(file_number, '-', -1)
+                    WHEN SUBSTRING_INDEX(file_number, '•', -1) REGEXP '^[0-9]+$'
+                        THEN SUBSTRING_INDEX(file_number, '•', -1)
+                    WHEN SUBSTRING_INDEX(file_number, '·', -1) REGEXP '^[0-9]+$'
+                        THEN SUBSTRING_INDEX(file_number, '·', -1)
+                    WHEN SUBSTRING_INDEX(file_number, '_', -1) REGEXP '^[0-9]+$'
+                        THEN SUBSTRING_INDEX(file_number, '_', -1)
+                    ELSE
+                        REVERSE(
+                            SUBSTRING(
+                                REVERSE(file_number),
+                                1,
+                                LENGTH(REVERSE(file_number)) - LENGTH(TRIM(LEADING '0123456789' FROM REVERSE(file_number)))
+                            )
+                        )
+                END AS UNSIGNED
+            ) AS trailing_number
+        from u_archives_auto u LEFT JOIN m_archive_tree_contract m ON u.node_id = m.id where u.is_deleted = 0
         <if test="vo.projectId != null and vo.projectId != ''">
             and u.project_id = #{vo.projectId}
         </if>
@@ -350,12 +372,12 @@
                 ORDER BY
                     m.tree_sort,
                     CASE WHEN u.file_number IS NULL THEN 1 ELSE 0 END,
-                    CAST(SUBSTRING_INDEX(file_number, '_', -1) AS SIGNED)
+                    trailing_number
             </when>
             <when test="vo.sortRuleType != null and vo.sortRuleType == 2 and vo.isArchive != null and vo.isArchive != ''">
                 order by
                     CASE WHEN u.file_number IS NULL THEN 1 ELSE 0 END,
-                    CAST(SUBSTRING_INDEX(file_number, '_', -1) AS SIGNED)
+                    trailing_number
             </when>
             <otherwise>
                 order by m.tree_sort,u.auto_file_sort is null ,u.auto_file_sort,u.file_number is null,
@@ -631,7 +653,27 @@
         where project_id = #{projectId} and is_deleted = 0;
     </select>
     <select id="pageByArchivesAuto" resultMap="archivesAutoResultMap">
-        select uaa.*
+        select uaa.*,
+            CAST(
+                CASE
+                    WHEN SUBSTRING_INDEX(file_number, '-', -1) REGEXP '^[0-9]+$'
+                        THEN SUBSTRING_INDEX(file_number, '-', -1)
+                    WHEN SUBSTRING_INDEX(file_number, '•', -1) REGEXP '^[0-9]+$'
+                        THEN SUBSTRING_INDEX(file_number, '•', -1)
+                    WHEN SUBSTRING_INDEX(file_number, '·', -1) REGEXP '^[0-9]+$'
+                        THEN SUBSTRING_INDEX(file_number, '·', -1)
+                    WHEN SUBSTRING_INDEX(file_number, '_', -1) REGEXP '^[0-9]+$'
+                        THEN SUBSTRING_INDEX(file_number, '_', -1)
+                    ELSE
+                        REVERSE(
+                            SUBSTRING(
+                                REVERSE(file_number),
+                                1,
+                                LENGTH(REVERSE(file_number)) - LENGTH(TRIM(LEADING '0123456789' FROM REVERSE(file_number)))
+                            )
+                        )
+                END AS UNSIGNED
+            ) AS trailing_number
         from m_archive_tree_contract matc left join u_archives_auto uaa on matc.id = uaa.node_id left join
         u_archive_file uaf on uaa.id = uaf.archive_id
         where uaa.is_deleted = 0  and matc.is_deleted = 0 and uaa.is_archive = 1
@@ -697,12 +739,12 @@
                 ORDER BY
                 matc.tree_sort,
                 CASE WHEN uaa.file_number IS NULL THEN 1 ELSE 0 END,
-                CAST(SUBSTRING_INDEX(uaa.file_number, '_', -1) AS SIGNED)
+                trailing_number
             </when>
             <when test="vo.sortRuleType != null and vo.sortRuleType == 2">
                 ORDER BY
                 CASE WHEN uaa.file_number IS NULL THEN 1 ELSE 0 END,
-                CAST(SUBSTRING_INDEX(uaa.file_number, '_', -1) AS SIGNED)
+                trailing_number
             </when>
             <otherwise>
                 order by uaa.tree_sort,uaa.auto_file_sort,uaa.file_number asc
@@ -711,7 +753,27 @@
     </select>
 
     <select id="pageByArchivesAuto11" resultMap="archivesAutoResultMap">
-        select uaa.*
+        select uaa.*,
+            CAST(
+                CASE
+                    WHEN SUBSTRING_INDEX(file_number, '-', -1) REGEXP '^[0-9]+$'
+                        THEN SUBSTRING_INDEX(file_number, '-', -1)
+                    WHEN SUBSTRING_INDEX(file_number, '•', -1) REGEXP '^[0-9]+$'
+                        THEN SUBSTRING_INDEX(file_number, '•', -1)
+                    WHEN SUBSTRING_INDEX(file_number, '·', -1) REGEXP '^[0-9]+$'
+                        THEN SUBSTRING_INDEX(file_number, '·', -1)
+                    WHEN SUBSTRING_INDEX(file_number, '_', -1) REGEXP '^[0-9]+$'
+                        THEN SUBSTRING_INDEX(file_number, '_', -1)
+                    ELSE
+                        REVERSE(
+                            SUBSTRING(
+                                REVERSE(file_number),
+                                1,
+                                LENGTH(REVERSE(file_number)) - LENGTH(TRIM(LEADING '0123456789' FROM REVERSE(file_number)))
+                            )
+                        )
+                END AS UNSIGNED
+            ) AS trailing_number
         from m_archive_tree_contract matc left join u_archives_auto uaa on matc.id = uaa.node_id
         where uaa.is_deleted = 0 and matc.is_deleted = 0 and uaa.is_archive = 1
         <if test="vo.queryValue != null and vo.queryValue != ''">
@@ -771,12 +833,12 @@
                 ORDER BY
                 matc.tree_sort,
                 CASE WHEN uaa.file_number IS NULL THEN 1 ELSE 0 END,
-                CAST(SUBSTRING_INDEX(uaa.file_number, '_', -1) AS SIGNED)
+                trailing_number
             </when>
             <when test="vo.sortRuleType != null and vo.sortRuleType == 2">
                 ORDER BY
                 CASE WHEN uaa.file_number IS NULL THEN 1 ELSE 0 END,
-                CAST(SUBSTRING_INDEX(uaa.file_number, '_', -1) AS SIGNED)
+                trailing_number
             </when>
             <otherwise>
                 order by uaa.tree_sort,uaa.auto_file_sort,uaa.file_number asc

+ 151 - 30
blade-service/blade-business/src/main/java/org/springblade/business/controller/InformationWriteQueryController.java

@@ -1967,13 +1967,20 @@ public R<Boolean> copyContractTreeNode(@RequestBody CopyContractTreeNodeVO vo) {
             }
 
             //TODO 20250414-lhb-新增 添加祖级字段 ancestorsPId
-            List<WbsTreeContract> contractWbsTreeByContractId = wbsTreeContractClient.getContractWbsTreeByContractId(Long.valueOf(needCopyNode.getContractId()));
-            contractWbsTreeByContractId.addAll(saveList);
-            Map<Long, WbsTreeContract> collect = contractWbsTreeByContractId.stream().collect(Collectors.toMap(WbsTreeContract::getPKeyId, Function.identity()));
-            saveList.forEach(node -> {
-                String correctAncestors = createAncestorsPId(node,collect);;
-                node.setAncestorsPId(correctAncestors);
-            });
+            //因为复制选中节点,所以要查询出选中节点的父节点信息 来组装祖级节点
+            if(needCopyNode != null){
+                Long parentPKeyId = null;
+                String ancestorsPId = null;
+                if(needCopyNode.getPId() == 0L){
+                    ancestorsPId = "0";
+                    parentPKeyId = 0L;
+                }else{
+                    WbsTreeContract parentNode = this.wbsTreeContractClient.getContractNodeByPrimaryKeyId(String.valueOf(needCopyNode.getPId()));
+                    ancestorsPId = parentNode.getAncestorsPId();
+                    parentPKeyId = parentNode.getPKeyId();
+                }
+                attachNodesToTarget(saveList,parentPKeyId,ancestorsPId);
+            }
         }
         needCopyNode.setNodeName(vo.getNeedCopyNodeName());
 
@@ -2141,6 +2148,26 @@ public R<Boolean> copyContractTreeNode(@RequestBody CopyContractTreeNodeVO vo) {
                                     this.addCopyTabData(needCopyNode, toCopyNode, tabOwner, resultTablesData, addTabList, vo.getIsCopyData(), addNewFileTabs);
                                 }
                             }
+
+
+                            /*重构祖级id*/
+                            List<WbsTreeContract> resultAll = new ArrayList<>();
+                            resultAll.addAll(addNodeList);
+                            resultAll.addAll(addTabList);
+                            //因为复制选中节点,所以要查询出选中节点的父节点信息 来组装祖级节点
+                            if(needCopyNode != null && CollectionUtil.isNotEmpty(resultAll)){
+                                Long parentPKeyId = null;
+                                String ancestorsPId = null;
+                                if(needCopyNode.getPId() == 0L){
+                                    ancestorsPId = "0";
+                                    parentPKeyId = 0L;
+                                }else{
+                                    WbsTreeContract parentNode = this.wbsTreeContractClient.getContractNodeByPrimaryKeyId(String.valueOf(toCopyVO.getPrimaryKeyId()));
+                                    ancestorsPId = parentNode.getAncestorsPId();
+                                    parentPKeyId = parentNode.getPKeyId();
+                                }
+                                attachNodesToTarget(resultAll,parentPKeyId,ancestorsPId);
+                            }
                         }
                     }
                 }
@@ -2150,14 +2177,6 @@ public R<Boolean> copyContractTreeNode(@RequestBody CopyContractTreeNodeVO vo) {
                 resultAll.addAll(addNodeList);
                 resultAll.addAll(addTabList);
 
-                //TODO 20250414-lhb-新增
-                List<WbsTreeContract> contractWbsTreeByContractId = wbsTreeContractClient.getContractWbsTreeByContractId(Long.valueOf(contractId));
-                contractWbsTreeByContractId.addAll(resultAll);
-                Map<Long, WbsTreeContract> collect = contractWbsTreeByContractId.stream().collect(Collectors.toMap(WbsTreeContract::getPKeyId, Function.identity()));
-                resultAll.forEach(node -> {
-                    String correctAncestors = createAncestorsPId(node,collect);;
-                    node.setAncestorsPId(correctAncestors);
-                });
 
                 List<WbsTreeContract> allData = this.reBuildAncestors(resultAll);
                 List<WbsTreeContract> nodes = allData.stream().filter(f -> f.getType().equals(1)).collect(Collectors.toList());
@@ -3966,24 +3985,20 @@ public R<Boolean> saveContractTreeNode(@RequestBody AddContractTreeNodeVO vo) {
             saveList.addAll(customResult);
         }
         //找到最顶级节点设置parentId
-        WbsTreeContract topLevelNode = findTopLevelNode(saveList);
-        if (ObjectUtils.isNotEmpty(topLevelNode)) {
+        List<WbsTreeContract> topLevelNode = findTopLevelNode(saveList);
+        if (CollectionUtil.isNotEmpty(topLevelNode)) {
             for (WbsTreeContract wbsTreeContract : saveList) {
-                if (topLevelNode.getPKeyId().equals(wbsTreeContract.getPKeyId())) {
-                    wbsTreeContract.setParentId(treeContract.getId());
-                    //TODO 20250414-lhb-新增
-                    wbsTreeContract.setPId(treeContract.getPKeyId());
+                for (WbsTreeContract contract : topLevelNode) {
+                    if (contract.getPKeyId().equals(wbsTreeContract.getPKeyId())) {
+                        wbsTreeContract.setParentId(treeContract.getId());
+                        //TODO 20250414-lhb-新增
+                        wbsTreeContract.setPId(treeContract.getPKeyId());
+                    }
                 }
             }
         }
         //TODO 20250414-lhb-新增 添加ancestorsPId字段
-        List<WbsTreeContract> contractWbsTreeByContractId = wbsTreeContractClient.getContractWbsTreeByContractId(Long.valueOf(treeContract.getContractId()));
-        contractWbsTreeByContractId.addAll(saveList);
-        Map<Long, WbsTreeContract> collect = contractWbsTreeByContractId.stream().collect(Collectors.toMap(WbsTreeContract::getPKeyId, Function.identity()));
-        saveList.forEach(node -> {
-            String correctAncestors = createAncestorsPId(node,collect);;
-            node.setAncestorsPId(correctAncestors);
-        });
+        attachNodesToTarget(saveList,treeContract.getPKeyId(),treeContract.getAncestorsPId());
 
         R<Boolean> booleanR = this.saveOrCopyNodeTree(saveList, saveLedger, 2, treeContract);
 
@@ -4009,16 +4024,20 @@ public R<String> getDICengNodeName(@RequestParam Long pKeyId,@RequestParam Long
     return R.data("");
 }
 
-public static WbsTreeContract findTopLevelNode(List<WbsTreeContract> saveList) {
+public static List<WbsTreeContract> findTopLevelNode(List<WbsTreeContract> saveList) {
     Set<Long> nodeIds = new HashSet<>();
     for (WbsTreeContract node : saveList) {
         nodeIds.add(node.getId());
     }
+    List<WbsTreeContract> parentNodes = new ArrayList<>();
     for (WbsTreeContract node : saveList) {
         if (!nodeIds.contains(node.getParentId())) {
-            return node;
+            parentNodes.add(node);
         }
     }
+    if(CollectionUtil.isNotEmpty(parentNodes)){
+        return parentNodes;
+    }
     return null;
 }
 
@@ -4893,4 +4912,106 @@ public R<Object> customAddContractNode(@RequestBody CustomAddContractNodeDTO dto
         }
     }
 
+    public void attachNodesToTarget(List<WbsTreeContract> newNodes, Long targetId, String targetAncestors) {
+        // 1. 找到新数据中的顶层节点(新树的根节点)
+        List<WbsTreeContract> newRoot = findRootNode(newNodes);
+
+        // 2. 将新树的根节点绑定到目标节点
+        newRoot.forEach(f -> {
+            f.setPId(targetId);
+            f.setAncestorsPId(calculateAncestors(targetAncestors, targetId));
+
+
+            // 3. 构建映射关系
+            Map<Long, WbsTreeContract> nodeMap = new HashMap<>();
+            Map<Long, List<WbsTreeContract>> childrenMap = new HashMap<>();
+
+            for (WbsTreeContract node : newNodes) {
+                nodeMap.put(node.getPKeyId(), node);
+                childrenMap.computeIfAbsent(node.getPId(), k -> new ArrayList<>()).add(node);
+            }
+
+            // 4. 安全层序遍历(带循环检测)
+            List<WbsTreeContract> list = childrenMap.get(f.getPKeyId());
+            if(CollectionUtil.isNotEmpty(list)){
+                //如果是多个根节点
+                safeBfsTraversal(f, childrenMap, newNodes.size());
+            }
+        });
+
+
+
+    }
+
+    private void safeBfsTraversal(WbsTreeContract root,
+                                  Map<Long, List<WbsTreeContract>> childrenMap,
+                                  int totalNodes) {
+        Queue<WbsTreeContract> queue = new LinkedList<>();
+        Set<Long> visited = new HashSet<>();  // 已访问节点集合
+        queue.add(root);
+        visited.add(root.getPKeyId());
+
+        int processedCount = 0;  // 已处理节点计数器
+        final int MAX_DEPTH = 100;  // 最大深度保护
+
+        while (!queue.isEmpty()) {
+            WbsTreeContract parent = queue.poll();
+            processedCount++;
+
+            // 安全检测1:防止循环引用导致无限循环
+            if (processedCount > totalNodes * 2) {
+                throw new ServiceException("处理节点数超过预期,可能存在循环引用。已处理: "
+                        + processedCount + ",总节点: " + totalNodes);
+            }
+
+            // 安全检测2:防止路径过长
+            if (parent.getAncestorsPId().split(",").length > MAX_DEPTH) {
+                throw new ServiceException("祖级路径超过最大深度限制: " + MAX_DEPTH);
+            }
+
+            List<WbsTreeContract> children = childrenMap.get(parent.getPKeyId());
+            if (children == null) continue;
+
+            for (WbsTreeContract child : children) {
+                // 安全检测3:检查循环引用
+                if (visited.contains(child.getPKeyId())) {
+                    throw new ServiceException("检测到循环引用: 节点" + child.getPKeyId()
+                            + " -> 节点" + parent.getPKeyId());
+                }
+
+                // 更新祖级路径 = 父路径 + 父ID
+                child.setAncestorsPId(calculateAncestors(parent.getAncestorsPId(), parent.getPKeyId()));
+
+                queue.add(child);
+                visited.add(child.getPKeyId());
+            }
+        }
+
+    }
+
+    private String calculateAncestors(String parentAncestors, Long parentId) {
+        if (parentAncestors == null || parentAncestors.isEmpty()) {
+            return parentId.toString();
+        }
+        return parentAncestors + "," + parentId;
+    }
+
+    private List<WbsTreeContract> findRootNode(List<WbsTreeContract> nodes) {
+        Set<Long> nodeIds = new HashSet<>();
+        for (WbsTreeContract node : nodes) {
+            nodeIds.add(node.getPKeyId());
+        }
+        List<WbsTreeContract> parentNodes = new ArrayList<>();
+        for (WbsTreeContract node : nodes) {
+            Long parentId = node.getPId();
+            // 父节点为空 或 父节点不在当前新数据列表中 → 视为根节点
+            if (parentId == null || !nodeIds.contains(parentId)) {
+                parentNodes.add(node);
+            }
+        }
+        if (CollectionUtil.isNotEmpty(parentNodes)) {
+            return parentNodes;
+        }
+        throw new IllegalArgumentException("新数据中未找到根节点");
+    }
 }

+ 2 - 2
blade-service/blade-business/src/main/java/org/springblade/business/controller/NeiYeController.java

@@ -350,7 +350,7 @@ public class NeiYeController {
                    vo1.setUnitName(unitName);
                    vo1.setUnitCount(1);
                }else {
-                   return R.data(300,null,"该节点暂未设置单元工程名称");
+                   return R.fail("该节点暂未设置单元工程名称");
                }
                //查询合格,优良,优良率
                 //查出当前节点下的单元工程施工质量验收评定表 后面需要改一下pid
@@ -462,7 +462,7 @@ public class NeiYeController {
                 }
             }
         }
-        return R.data(300,null,"未查询到数据");
+        return R.fail("未查询到数据");
     }
 
     @SneakyThrows

+ 2 - 2
blade-service/blade-business/src/main/java/org/springblade/business/controller/TaskController.java

@@ -2065,7 +2065,7 @@ public class TaskController extends BladeController {
     public R<Object>reSigningEntrust(@RequestBody List<ReSigningEntrustDto> dtos, HttpServletRequest request){
         for (ReSigningEntrustDto dto : dtos) {
             if(dto.getStatus()!=null&&dto.getStatus()!=1){
-                String sql="SELECT t.id FROM u_task t WHERE t.form_data_id=(Select id from u_information_query WHERE wbs_id="+dto.getEntrustId()+")";
+                String sql="SELECT t.id FROM u_task t WHERE t.form_data_id=(Select id from u_information_query WHERE wbs_id="+dto.getEntrustId()+" and status in (1,2))";
                 dto.setTaskId(jdbcTemplate.queryForObject(sql, String.class));
             }
         }
@@ -2126,7 +2126,7 @@ public class TaskController extends BladeController {
     /**
      * 任务超时提示信息
      */
-    @Scheduled(cron = "0 0 3 * * ?")
+//    @Scheduled(cron = "0 0 3 * * ?")
     public void TaskTimeoutTips() {
         String key = "task.time.out";
         String value = ParamCache.getValue(key);

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

@@ -87,7 +87,7 @@ public class TrialDeviceInfoServiceImpl extends BaseServiceImpl<TrialDeviceInfoM
      * 修改校验状态
      * cron = "0 0 1 * * ?" 每天1点执行
      */
-    @Scheduled(cron = "0 0 1 * * ?")
+//    @Scheduled(cron = "0 0 1 * * ?")
     public void syncUpdateIsCalibration() {
         //获取所有数据
         List<TrialDeviceInfo> trialDeviceInfos = baseMapper.selectList(Wrappers.<TrialDeviceInfo>lambdaQuery());

+ 3 - 3
blade-service/blade-business/src/main/java/org/springblade/business/service/impl/WeatherInfoServiceImpl.java

@@ -120,7 +120,7 @@ public class WeatherInfoServiceImpl extends ServiceImpl<WeatherInfoMapper, Weath
     /**
      * 获取当前系统所有项目下所有合同段的当天天气
      */
-    @Scheduled(cron = "0 18 10 * * ?")
+//    @Scheduled(cron = "0 18 10 * * ?")
     public void syncWeatherInfo() {
         if (!SystemUtils.isLinux()) {
             return;
@@ -178,7 +178,7 @@ public class WeatherInfoServiceImpl extends ServiceImpl<WeatherInfoMapper, Weath
     /**
      * 同步历史天气
      */
-    @Scheduled(cron = "0 0 8 * * ?")
+//    @Scheduled(cron = "0 0 8 * * ?")
     public void syncHistoryWeatherInfo() {
         if (!SystemUtils.isLinux()) {
             return;
@@ -295,7 +295,7 @@ public class WeatherInfoServiceImpl extends ServiceImpl<WeatherInfoMapper, Weath
     }
 
     //去除重复天气,并填充每个合同段缺失的天气
-    @Scheduled(cron = "0 0 9 * * ?")
+//    @Scheduled(cron = "0 0 9 * * ?")
     public void scanMissWeather(){
         if (!SystemUtils.isLinux()) {
             return;

+ 1 - 1
blade-service/blade-control/src/main/java/org/springblade/control/service/impl/PublicScheduledTaskServiceImpl.java

@@ -28,7 +28,7 @@ public class PublicScheduledTaskServiceImpl {
      * 定时删除费用管理的草稿数据信息
      * cron = 每天早上3点执行
      */
-    @Scheduled(cron = "0 0 3 * * ?")
+//    @Scheduled(cron = "0 0 3 * * ?")
     void delDraftDataInfo() {
         LocalDate currentDate = LocalDate.now();
         LocalTime midnight = LocalTime.MIDNIGHT;

+ 2 - 2
blade-service/blade-e-visa/src/main/java/org/springblade/evisa/controller/ArchiveController.java

@@ -63,7 +63,7 @@ public class ArchiveController {
     @Resource(name = "taskExecutor1")
     private ThreadPoolExecutor executor;
 
-   @Scheduled(cron = "0 0/1 * * * ?")
+//   @Scheduled(cron = "0 0/1 * * * ?")
     public void SignInfo() {
         //执行代码
 
@@ -160,7 +160,7 @@ public class ArchiveController {
         }
     }
 
-    @Scheduled(cron = "0/30 * * * * ?")
+//    @Scheduled(cron = "0/30 * * * * ?")
     public void SplitPdfInfo() {
         //执行代码
 

+ 1 - 1
blade-service/blade-e-visa/src/main/java/org/springblade/evisa/controller/EVController.java

@@ -58,7 +58,7 @@ public class EVController {
     @Resource(name = "taskExecutor1")
     private ThreadPoolExecutor executor;
 
-    @Scheduled(cron = "0/10 * * * * ?")
+//    @Scheduled(cron = "0/10 * * * * ?")
     public void SignInfo() {
         //执行代码
 

+ 3 - 1
blade-service/blade-manager/src/main/java/org/springblade/manager/controller/ExcelTabController.java

@@ -2025,7 +2025,6 @@ public class ExcelTabController extends BladeController {
             throw new RuntimeException(e);
         }
 
-
         //公式填充
         executionTime.info("----公式填充执行----");
         this.excelTabService.formulaFillData(tableInfoList, Long.parseLong(nodeId), ExecuteType.INSPECTION);
@@ -2035,6 +2034,8 @@ public class ExcelTabController extends BladeController {
             R.success("数据未发生变化");
         }
         executionTime.info("----公式填充执行完毕----");
+
+
         //保存数据到数据库
         R<Object> result = this.excelTabService.saveOrUpdateInfo(tableInfoList,singnType);
         RandomNumberHolder.RandomTemplateTypeclear();
@@ -4658,6 +4659,7 @@ public class ExcelTabController extends BladeController {
                 }
                 js2.put("orderList", array);
                 js.put("dataInfo", js2);
+                js.put("signType", "1");
                 /*if(infoB!=null && (infoB.getStatus()==1 || infoB.getStatus()==2)){
                     js.put("signType", "1");
                 }*/

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

@@ -113,7 +113,9 @@ public class TextdictInfoController extends BladeController {
     @ApiOperationSupport(order = 3)
     @ApiOperation(value = "分页", notes = "传入textdictInfo")
     public R<IPage<TextdictInfoVO>> page(TextdictInfoVO textdictInfo, Query query) {
-
+        if(textdictInfo.getType() == 4){
+            return R.data(textdictInfoService.analysisHtmlDefault(textdictInfo.getTabId()));
+        }
         IPage<TextdictInfoVO> pages = textdictInfoService.selectTextdictInfoPage(Condition.getPage(query), textdictInfo);
         return R.data(pages);
     }
@@ -155,7 +157,15 @@ public class TextdictInfoController extends BladeController {
     @PostMapping("/remove")
     @ApiOperationSupport(order = 7)
     @ApiOperation(value = "逻辑删除", notes = "传入ids")
-    public R remove(@ApiParam(value = "主键集合", required = true) @RequestParam String ids,@ApiParam(value = "wbs p_key_id", required = true) @RequestParam String tabId) throws FileNotFoundException {
+    public R remove(@ApiParam(value = "主键集合", required = true) @RequestParam String ids,
+                    @ApiParam(value = "wbs p_key_id", required = true) @RequestParam String tabId,
+                    String colKey,
+                    Integer type) throws FileNotFoundException {
+        if(type != null && type == 4){
+            textdictInfoService.removeHtmlDefault(tabId,colKey);
+            return R.success("删除成功");
+        }
+
         //获取节点信息
 
         WbsTreePrivate wbsTreePrivate = wbsTreePrivateMapper.getByPKeyId(Long.parseLong(tabId));
@@ -562,6 +572,11 @@ public class TextdictInfoController extends BladeController {
     @ApiOperationSupport(order = 7)
     @ApiOperation(value = "保存默认值", notes = "保存默认值")
     public R<String> saveDefaulVal(@Valid @RequestBody TextdictBy345VO textdictInfo) throws Exception {
+        if(textdictInfo.getType() == 4){
+            textdictInfoService.saveHtmlDefault(textdictInfo);
+            return R.success("操作成功");
+        }
+
 
         //当前清表信息
         WbsTreePrivate wbsTreePrivate = wbsTreePrivateMapper.getByPKeyId(textdictInfo.getTableId());

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

@@ -536,7 +536,7 @@ public class WbsParamController {
     }
 
      /*每天固定时间刷新treeCode*/
-    @Scheduled(cron = " 0 0 3,13 * * ?")
+//    @Scheduled(cron = " 0 0 3,13 * * ?")
     public  void job(){
         System.out.println("treeCode刷新任务开始"+ LocalDateTime.now());
         if(Optional.ofNullable(System.getProperty("os.name")).orElse(StringPool.EMPTY).equals("Linux")){
@@ -544,7 +544,7 @@ public class WbsParamController {
         }
     }
 
-    @Scheduled(initialDelay = 100000,fixedDelay = 30000)
+//    @Scheduled(initialDelay = 100000,fixedDelay = 30000)
     public  void monitor(){
         /*System.out.println("treeCode刷新检测"+ LocalDateTime.now());*/
         try {

+ 19 - 2
blade-service/blade-manager/src/main/java/org/springblade/manager/feign/ExcelTabClientImpl.java

@@ -888,13 +888,28 @@ public class ExcelTabClientImpl implements ExcelTabClient {
         JSONArray json2 = new JSONArray();
         for (int i = 0; i < jsonArray.size(); i++) {
             JSONObject jsonObject = jsonArray.getJSONObject(i);
+            json2.add(jsonObject);
             String pkeyId = jsonObject.getString("pkeyId");
             WbsTreePrivate wbsTreePrivate = this.wbsTreePrivateService.getOne(Wrappers.<WbsTreePrivate>lambdaQuery().eq(WbsTreePrivate::getPKeyId, pkeyId));
+            if(wbsTreePrivate == null || StringUtil.isBlank(wbsTreePrivate.getHtmlUrl())) {
+                continue;
+            }
+            if (!StringUtil.hasText(wbsTreePrivate.getInitTableId()) && !StringUtil.hasText(wbsTreePrivate.getInitTableName())) {
+                continue;
+            }
+            List<WbsFormElement> wbsFormElements;
+            if (StringUtil.hasText(wbsTreePrivate.getInitTableId())) {
+                wbsFormElements =  jdbcTemplate.query("SELECT e_key from m_wbs_form_element WHERE is_deleted = 0 and e_type = 6 and f_id = " + wbsTreePrivate.getInitTableId(), new BeanPropertyRowMapper<>(WbsFormElement.class) );
+            } else {
+                wbsFormElements =  jdbcTemplate.query("SELECT e_key from m_wbs_form_element WHERE e_type = 6 and f_id = (SELECT id from m_table_info WHERE tab_en_name = ' " + wbsTreePrivate.getInitTableName()
+                        + "' and is_deleted = 0 limit 1) and is_deleted = 0" + wbsTreePrivate.getInitTableName(), new BeanPropertyRowMapper<>(WbsFormElement.class) );
+            }
+            Map<String, String> map = wbsFormElements.stream().collect(Collectors.toMap(WbsFormElement::getEKey, WbsFormElement::getEKey));
             String htmlString = null;
             try {
                 htmlString = IoUtil.readToString(FileUtils.getInputStreamByUrl(wbsTreePrivate.getHtmlUrl()));
             } catch (Exception e) {
-                throw new RuntimeException(e);
+                e.printStackTrace();
             }
             Document doc = Jsoup.parse(htmlString);
             for (Element element : doc.getElementsByAttributeValueStarting("id", "key_")) {
@@ -902,12 +917,14 @@ public class ExcelTabClientImpl implements ExcelTabClient {
                 if(id == null || id.startsWith("key__")) {
                     continue;
                 }
+                if (map.containsKey(id.split("__")[0])) {
+                    continue;
+                }
                 String text = jsonObject.getString(id);
                 if (text == null || text.trim().isEmpty()) {
                     jsonObject.put(id, "/");
                 }
             }
-            json2.add(jsonObject);
         }
         return json2;
     }

+ 1 - 1
blade-service/blade-manager/src/main/java/org/springblade/manager/job/SystemMsgJob.java

@@ -42,7 +42,7 @@ public class SystemMsgJob {
     /**
      *  定时推送公告-取消公告-修改公告状态,不想污染日志,使用jdbc
      */
-    @Scheduled(cron = "0/10 * * * * ?")
+//    @Scheduled(cron = "0/10 * * * * ?")
     public void autoUpdateMsgStatus(){
         // 本地环境跳过执行(可添加日志输出)
         if (!schedulerEnabled) return;

+ 7 - 0
blade-service/blade-manager/src/main/java/org/springblade/manager/mapper/WbsFormElementMapper.java

@@ -77,4 +77,11 @@ public interface WbsFormElementMapper extends BaseMapper<WbsFormElement> {
      * @return
      */
     Integer selectFiledDataMaxLength(@Param("tableName") String initTableName,@Param("key") String eKey);
+
+    /**
+     * 统计当前表所有字段长度
+     * @param initTableName
+     * @return
+     */
+    int selectSumColumnLength(@Param("database") String database,@Param("tableName") String initTableName);
 }

+ 10 - 0
blade-service/blade-manager/src/main/java/org/springblade/manager/mapper/WbsFormElementMapper.xml

@@ -172,5 +172,15 @@
     <select id="selectFiledDataMaxLength" resultType="java.lang.Integer">
         select MAX(LENGTH(${key})) from ${tableName}
     </select>
+    <select id="selectSumColumnLength" resultType="java.lang.Integer">
+        SELECT
+            SUM( CHARACTER_MAXIMUM_LENGTH )
+        FROM
+            information_schema.COLUMNS
+        WHERE
+            TABLE_SCHEMA = #{database}
+            AND TABLE_NAME = #{tableName}
+            AND DATA_TYPE = 'varchar'
+    </select>
 
 </mapper>

+ 7 - 0
blade-service/blade-manager/src/main/java/org/springblade/manager/service/ITextdictInfoService.java

@@ -20,6 +20,7 @@ import com.baomidou.mybatisplus.extension.service.IService;
 import org.springblade.core.tool.api.R;
 import org.springblade.manager.dto.RangeInfo;
 import org.springblade.manager.entity.TextdictInfo;
+import org.springblade.manager.vo.TextdictBy345VO;
 import org.springblade.manager.vo.TextdictDataInfoVO;
 import org.springblade.manager.vo.TextdictInfoVO;
 import org.springblade.core.mp.base.BaseService;
@@ -47,4 +48,10 @@ public interface ITextdictInfoService extends IService<TextdictInfo> {
     void deleDataInfoById(String id);
 
     TextdictInfo selectTextdictInfoOne(String id,String sigRoleId,String projectId);
+
+    IPage<TextdictInfoVO> analysisHtmlDefault(String tabId);
+
+    void removeHtmlDefault(String tabId, String colKey);
+
+    void saveHtmlDefault(TextdictBy345VO textdictInfo);
 }

+ 65 - 1
blade-service/blade-manager/src/main/java/org/springblade/manager/service/impl/ExcelTabServiceImpl.java

@@ -1233,6 +1233,9 @@ public class ExcelTabServiceImpl extends BaseServiceImpl<ExcelTabMapper, ExcelTa
                     String delSql = "delete from " + tabName + " where p_key_id=" + tableInfo.getPkeyId();
                     String sqlInfo = "";
                     LinkedHashMap<String, String> dataMap2 = tableInfo.getDataMap();
+                    if (!updateFieldLength(tabName, dataMap2)) {
+                        throw new ServiceException("字段长度超出限制, 系统无法进行自增,请前往后台管理系统手动设置");
+                    }
                     /*检查发现有p_key_id缺失的情况,导致表单数据丢失,所以强制覆盖*/
                     dataMap2.put("p_key_id", tableInfo.getPkeyId());
                     //统计保存的字段
@@ -1343,6 +1346,63 @@ public class ExcelTabServiceImpl extends BaseServiceImpl<ExcelTabMapper, ExcelTa
        // return R.success(fileName1);
     }
 
+    public boolean updateFieldLength(String tableName, Map<String, String> fieldNameAndLengthMap) {
+        if (fieldNameAndLengthMap == null || fieldNameAndLengthMap.isEmpty()) {
+            return true;
+        }
+        fieldNameAndLengthMap.remove("id");
+        fieldNameAndLengthMap.remove("p_key_id");
+        fieldNameAndLengthMap.remove("group_id");
+        if (fieldNameAndLengthMap.isEmpty()) {
+            return true;
+        }
+        String fields = fieldNameAndLengthMap.keySet().stream().map(key -> "'" + key + "'").collect(Collectors.joining(","));
+        List<Map<String, Object>> fieldMap = jdbcTemplate.queryForList("select distinct COLUMN_NAME as fieldName, CHARACTER_MAXIMUM_LENGTH as fieldLength from information_schema.COLUMNS where  TABLE_NAME = '" + tableName +
+                "' and COLUMN_NAME in (" + fields + ")");
+        Map<String, Integer> map = fieldMap.stream().collect(toMap(k -> k.get("fieldName") + "", v -> {
+            try {
+                return Integer.parseInt(v.get("fieldLength") + "");
+            } catch (Exception e) {
+                return 0;
+            }
+        }, Math::max));
+
+        List<WbsFormElement> elementList = jdbcTemplate.query("SELECT id,e_key,e_length from m_wbs_form_element WHERE f_id = (SELECT id from m_table_info WHERE tab_en_name = '" + tableName
+                        +"' and is_deleted = 0  limit 1) and is_deleted = 0 and e_key in ( " +  fields + ")", new BeanPropertyRowMapper<>(WbsFormElement.class));
+        StringBuilder sql = new StringBuilder();
+        sql.append("alter table ").append(tableName);
+        elementList.forEach(element -> {
+            String data = fieldNameAndLengthMap.get(element.getEKey());
+            Integer fieldLength = map.get(element.getEKey());
+            if (data != null && element.getELength() != null && data.length() > fieldLength) {
+                int length = data.length();
+                // 取整
+                length = (length / 10 + 1) * 10;
+                if (length < element.getELength()) {
+                    length = element.getELength();
+                    element.setELength(null);
+                } else {
+                    element.setELength(length);
+                }
+                sql.append(" modify column ").append(element.getEKey()).append(" ").append("varchar").append("(").append(length).append("),");
+            }
+        });
+        if (sql.indexOf("modify") > 0) {
+            sql.deleteCharAt(sql.length() - 1);
+            TransactionStatus transactionStatus = this.beginTransaction(transactionManager1);
+            try {
+                jdbcTemplate.batchUpdate("update m_wbs_form_element set e_length = ? where id = ?", elementList.stream().filter(element -> element.getELength() != null).map(element -> new Object[]{element.getELength(), element.getId()}).collect(Collectors.toList()));
+                jdbcTemplate.execute(sql.toString());
+                transactionManager1.commit(transactionStatus);
+            } catch (Exception e) {
+                transactionManager1.rollback(transactionStatus);
+                log.error("更新字段长度失败, error: " + e.getMessage());
+                return false;
+            }
+        }
+        return true;
+    }
+
     public String reason(String log) {
         /*保存的时候错误提示例如:字段过短提示 yangyj*/
         StringBuilder sb = new StringBuilder();
@@ -3012,6 +3072,10 @@ public class ExcelTabServiceImpl extends BaseServiceImpl<ExcelTabMapper, ExcelTa
                                 for (String data : mysql) {
                                     String[] tabData = data.split("_\\^_");
                                     if (StringUtils.isNotEmpty(tabData[0])) {
+                                        Object o = reData.get(key + "__" + tabData[1]);
+                                        if (o != null && tabData[0].equals("/")) {
+                                            continue;
+                                        }
                                         reData.put(key + "__" + tabData[1], tabData[0]);
                                     }
                                 }
@@ -3358,7 +3422,7 @@ public class ExcelTabServiceImpl extends BaseServiceImpl<ExcelTabMapper, ExcelTa
                                 } else {
                                     nextCellValue = nextCell.getStringCellValue();
                                 }
-                                if (nextCellValue == null || nextCellValue.isEmpty()) {
+                                if (nextCellValue == null || nextCellValue.isEmpty() || nextCellValue.equals("/")) {
                                     nextCell.setCellValue(newContext.replace(oldContext, ""));
                                     CellStyle cellStyle = cell.getCellStyle();
                                     // 设置自动换行

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

@@ -56,7 +56,7 @@ public class TableInfoServiceImpl extends BaseServiceImpl<TableInfoMapper, Table
      * 十分钟执行一次
      * 替换动态表中的阿里云地址
      */
-    @Scheduled(cron = "0 */10 * * * ?")
+//    @Scheduled(cron = "0 */10 * * * ?")
 //    @Scheduled(fixedDelay = 60000)
     public void aliyunUrlReplace() {
         System.out.println("执行阿里云地址替换-----------------------------开始");

+ 129 - 0
blade-service/blade-manager/src/main/java/org/springblade/manager/service/impl/TextdictInfoServiceImpl.java

@@ -17,13 +17,18 @@
 package org.springblade.manager.service.impl;
 
 import com.baomidou.mybatisplus.core.metadata.IPage;
+import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
 import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
 import org.jsoup.Jsoup;
 import org.jsoup.nodes.Document;
 import org.jsoup.nodes.Element;
 import org.jsoup.select.Elements;
+import org.springblade.common.constant.CommonConstant;
+import org.springblade.common.utils.CommonUtil;
+import org.springblade.core.tool.utils.FileUtil;
 import org.springblade.core.tool.utils.Func;
 import org.springblade.core.tool.utils.IoUtil;
+import org.springblade.core.tool.utils.ResourceUtil;
 import org.springblade.manager.entity.TextdictInfo;
 import org.springblade.manager.entity.WbsTreePrivate;
 import org.springblade.manager.mapper.TextdictInfoMapper;
@@ -31,12 +36,17 @@ import org.springblade.manager.mapper.WbsTreePrivateMapper;
 import org.springblade.manager.service.ISignConfigService;
 import org.springblade.manager.service.ITextdictInfoService;
 import org.springblade.manager.utils.FileUtils;
+import org.springblade.manager.vo.TextdictBy345VO;
 import org.springblade.manager.vo.TextdictInfoVO;
+import org.springblade.system.cache.ParamCache;
 import org.springframework.context.annotation.Lazy;
 import org.springframework.stereotype.Service;
 import org.springframework.transaction.annotation.Transactional;
 
 import javax.annotation.Resource;
+import java.io.File;
+import java.io.FileInputStream;
+import java.io.FileNotFoundException;
 import java.io.InputStream;
 import java.util.*;
 import java.util.stream.Collectors;
@@ -178,4 +188,123 @@ public class TextdictInfoServiceImpl extends ServiceImpl<TextdictInfoMapper, Tex
         return true;
     }
 
+    @Override
+    public void saveHtmlDefault(TextdictBy345VO textdictInfo) {
+        String file_path = ParamCache.getValue(CommonConstant.SYS_LOCAL_URL);
+        String sys_file_net_url = ParamCache.getValue(CommonConstant.SYS_FILE_NET_URL);
+        WbsTreePrivate wbsTreePrivate = wbsTreePrivateMapper.getByPKeyId(textdictInfo.getTableId());
+        try {
+            File file1 = ResourceUtil.getFile(wbsTreePrivate.getHtmlUrl());
+            InputStream fileInputStream;
+            if (file1.exists()) {
+                fileInputStream = new FileInputStream(file1);
+            } else {
+                String path = sys_file_net_url + wbsTreePrivate.getHtmlUrl().replaceAll("//", "/").replaceAll(file_path, "");
+                fileInputStream = CommonUtil.getOSSInputStream(path);
+            }
+            String htmlString = IoUtil.readToString(fileInputStream);
+            //样式集合
+            Document doc = Jsoup.parse(htmlString);
+            //解析
+            Element table = doc.select("table").first();
+
+            Elements trs = table.select("tr");
+            Element element = trs.get(textdictInfo.getTrIndex()).select("td").get(textdictInfo.getTdIndex());
+
+            if (element.html().indexOf("el-input") >= 0 ) {
+                element.children().removeAttr("defText");
+                element.children().attr("defText", textdictInfo.getTextId());
+            } else {
+                element.children().removeAttr("defText");
+                element.attr("defText", textdictInfo.getTextId());
+            }
+            File writeFile = new File(wbsTreePrivate.getHtmlUrl());
+            FileUtil.writeToFile(writeFile, doc.html(), Boolean.parseBoolean("UTF-8"));
+
+        } catch (FileNotFoundException e) {
+            throw new RuntimeException(e);
+        }
+
+
+
+    }
+
+    @Override
+    public IPage<TextdictInfoVO> analysisHtmlDefault(String tabId) {
+        String file_path = ParamCache.getValue(CommonConstant.SYS_LOCAL_URL);
+        String sys_file_net_url = ParamCache.getValue(CommonConstant.SYS_FILE_NET_URL);
+
+        WbsTreePrivate wbsTreePrivate = wbsTreePrivateMapper.getByPKeyId(Long.parseLong(tabId));
+        IPage<TextdictInfoVO> textdictInfoPage = new Page<TextdictInfoVO>();
+        try {
+            File file1 = ResourceUtil.getFile(wbsTreePrivate.getHtmlUrl());
+            InputStream fileInputStream;
+            if (file1.exists()) {
+                fileInputStream = new FileInputStream(file1);
+            } else {
+                String path = sys_file_net_url + wbsTreePrivate.getHtmlUrl().replaceAll("//", "/").replaceAll(file_path, "");
+                fileInputStream = CommonUtil.getOSSInputStream(path);
+            }
+            String htmlString = IoUtil.readToString(fileInputStream);
+            //样式集合
+            Document doc = Jsoup.parse(htmlString);
+            //解析
+            Element table = doc.select("table").first();
+            Elements elements = table.select("[defText]");
+
+            ArrayList<TextdictInfoVO> textdictInfos = new ArrayList<>();
+            for (Element element : elements) {
+                TextdictInfoVO textdictInfo = new TextdictInfoVO();
+                String keyname = element.attr("keyname");
+                String placeholder = element.attr("placeholder");
+                String defText = element.attr("defText");
+                textdictInfo.setColKey(keyname);
+                textdictInfo.setColName(placeholder);
+                textdictInfo.setSigRoleName(defText);
+                textdictInfo.setType(4);
+                textdictInfo.setId(-1L);
+                textdictInfos.add(textdictInfo);
+            }
+            textdictInfoPage.setRecords(textdictInfos);
+            return textdictInfoPage;
+        } catch (FileNotFoundException e) {
+            throw new RuntimeException(e);
+        }
+    }
+
+    @Override
+    public void removeHtmlDefault(String tabId, String colKey) {
+        String file_path = ParamCache.getValue(CommonConstant.SYS_LOCAL_URL);
+        String sys_file_net_url = ParamCache.getValue(CommonConstant.SYS_FILE_NET_URL);
+
+        WbsTreePrivate wbsTreePrivate = wbsTreePrivateMapper.getByPKeyId(Long.parseLong(tabId));
+        try {
+            File file1 = ResourceUtil.getFile(wbsTreePrivate.getHtmlUrl());
+            InputStream fileInputStream;
+            if (file1.exists()) {
+                fileInputStream = new FileInputStream(file1);
+            } else {
+                String path = sys_file_net_url + wbsTreePrivate.getHtmlUrl().replaceAll("//", "/").replaceAll(file_path, "");
+                fileInputStream = CommonUtil.getOSSInputStream(path);
+            }
+            String htmlString = IoUtil.readToString(fileInputStream);
+            //样式集合
+            Document doc = Jsoup.parse(htmlString);
+            //解析
+            Element table = doc.select("table").first();
+            Elements elements = table.select("[defText]");
+            for (Element element : elements) {
+                String keyname = element.attr("keyname");
+                if(Objects.equals(colKey,keyname)){
+                    element.removeAttr("defText");
+                }
+            }
+
+            //重写html
+            File writeFile = new File(wbsTreePrivate.getHtmlUrl());
+            FileUtil.writeToFile(writeFile, doc.html(), Boolean.parseBoolean("UTF-8"));
+        } catch (FileNotFoundException e) {
+            throw new RuntimeException(e);
+        }
+    }
 }

+ 128 - 56
blade-service/blade-manager/src/main/java/org/springblade/manager/service/impl/WbsFormElementServiceImpl.java

@@ -62,6 +62,8 @@ public class WbsFormElementServiceImpl extends BaseServiceImpl<WbsFormElementMap
     public static final Integer DEFAULT_ELEMENT_LENGTH_DATE = 100;
     //实体表字段默认长度
     private static final String ELEMENT_LENGTH_ENTITY = "200";
+    //数据库动态表总字段最大长度
+    private static final Integer MYSQL_MAX_COLUMN_LENGTH = 16328;
 
     @Override
     public IPage<WbsFormElementVO> selectWbsFormElementPage(IPage<WbsFormElementVO> page, WbsFormElementVO wbsFormElement) {
@@ -141,23 +143,30 @@ public class WbsFormElementServiceImpl extends BaseServiceImpl<WbsFormElementMap
 
     @Override
     public WbsFormElement saveAndSyn(WbsFormElement wbsFormElement, String tableName) {
-        try {
 
-            String isExitSql = "select * from information_schema.TABLES where TABLE_NAME='" + tableName + "'";
-            List<Map<String, Object>> tabList = jdbcTemplate.queryForList(isExitSql);
-            if (tabList.size() <= 0) {
-                throw new ServiceException("未获取到对应的实体表名称initTableName");
-            }
+        String isExitSql = "select * from information_schema.TABLES where TABLE_NAME='" + tableName + "'";
+        List<Map<String, Object>> tabList = jdbcTemplate.queryForList(isExitSql);
+        if (tabList.size() <= 0) {
+            throw new ServiceException("未获取到对应的实体表名称initTableName");
+        }
 
 
-            //获取实体表主库信息
-            TableInfo tableInfo = tableInfoMapper.selectById(wbsFormElement.getFId());
-            if (tableInfo == null) {
-                throw new ServiceException("没有找到主库信息,确认fid是否正确");
-            } else {
-                tableName = tableInfo.getTabEnName();
-            }
+        //获取实体表主库信息
+        TableInfo tableInfo = tableInfoMapper.selectById(wbsFormElement.getFId());
+        if (tableInfo == null) {
+            throw new ServiceException("没有找到主库信息,确认fid是否正确");
+        } else {
+            tableName = tableInfo.getTabEnName();
+        }
+
 
+        //当前表总字段长度
+        int sumLength = baseMapper.selectSumColumnLength(jdbcTemplate.queryForObject("SELECT DATABASE()", String.class), tableName);
+        if (sumLength + wbsFormElement.getELength() > MYSQL_MAX_COLUMN_LENGTH) {
+            updateTableFieldLength(tableName);
+            throw new ServiceException("无法添加字段,可用长度:" + (MYSQL_MAX_COLUMN_LENGTH - sumLength) + ",已自动调整其他字段长度,请重新添加");
+        }
+        try {
             // 删除 元素和实体表不匹配的字段
             //baseMapper.deleteElementByfId2();
 
@@ -193,6 +202,7 @@ public class WbsFormElementServiceImpl extends BaseServiceImpl<WbsFormElementMap
                     throw new ServiceException("请输入正确的长度,范围为10-1000");
                 } else {
                     //新增
+                    wbsFormElement.setELength(DEFAULT_ELEMENT_LENGTH_VARCHAR);
                     baseMapper.insert(wbsFormElement);
 
                     //同步
@@ -209,6 +219,7 @@ public class WbsFormElementServiceImpl extends BaseServiceImpl<WbsFormElementMap
                     throw new ServiceException("请输入正确的长度,范围为10-255");
                 } else {
                     //新增
+                    wbsFormElement.setELength(DEFAULT_ELEMENT_LENGTH_VARCHAR);
                     baseMapper.insert(wbsFormElement);
 
                     //同步
@@ -240,6 +251,7 @@ public class WbsFormElementServiceImpl extends BaseServiceImpl<WbsFormElementMap
                     throw new ServiceException("请输入正确的长度,范围为0-100");
                 } else {
                     //新增
+                    wbsFormElement.setELength(DEFAULT_ELEMENT_LENGTH_VARCHAR);
                     baseMapper.insert(wbsFormElement);
 
                     //同步
@@ -305,19 +317,21 @@ public class WbsFormElementServiceImpl extends BaseServiceImpl<WbsFormElementMap
         wbsFormElementList.forEach(obj -> obj.setStatus(1));
         boolean b = this.updateBatchById(wbsFormElementList);
 
-        //字段级字段长度缓存
-        Map<String, Integer> lengthMap = new HashMap<>();
 
-        //查询当前表的所有字段级字段长度
-        List<Map<String, Object>> filedLengths = baseMapper.selectFiledLength(initTableName);
-        for (Map<String, Object> filedLength : filedLengths) {
-            BigInteger length = (BigInteger) filedLength.get("length");
-            if (length == null) {
-                continue;
-            }
-            lengthMap.put(filedLength.get("key").toString(), length.intValue());
+        //当前设置的字段总长度
+        Integer nowTotalLength = 0;
+        for (WbsFormElement wbsFormElement : wbsFormElementList) {
+            // + 10 预留字段长度,用来保存在excel中的位置信息,比如:xx_^_12_12, 不适合一个字段存储多个位置
+            nowTotalLength += wbsFormElement.getELength() + 10;
+        }
+        //当前表总字段长度
+        int sumLength = baseMapper.selectSumColumnLength(jdbcTemplate.queryForObject("SELECT DATABASE()", String.class), initTableName);
+        if (nowTotalLength > MYSQL_MAX_COLUMN_LENGTH) {
+            //修改元素字段长度
+            throw new ServiceException("无法添加字段,可用长度:" + (MYSQL_MAX_COLUMN_LENGTH - sumLength));
         }
 
+
         //修改实体表信息
         if (b) {
             String fId = "";
@@ -361,40 +375,14 @@ public class WbsFormElementServiceImpl extends BaseServiceImpl<WbsFormElementMap
                 int row1 = wbsTreeMapper.isThereAField(initTableName, eKey);
                 if (row1 > 0) {
                     try {
-                        //1、查询当前表当前字段
-
-                        //字段配置的长度
-                        Integer filedLength = lengthMap.get(eKey);
-                        if(filedLength == null){
-                            throw new RuntimeException("字段不存在");
-                        }
-                        //获取当前字段数据的最长数据长度
-                        Integer maxLength = baseMapper.selectFiledDataMaxLength(initTableName, eKey);
-                        //初始长度
-                        int initLength = 250;
-                        //当前字段数据长度为null
-                        if (maxLength == null) {
-                            //设置初始长度
-                            baseMapper.updateFiledType(initTableName, eKey, "varchar", initLength);
-                            wbsFormElement.setELength(initLength);
-                            baseMapper.updateById(wbsFormElement);
-                        } else {
-                            //动态扩容 每次根据最大数据长度扩容100
-                            int newLength = maxLength + 100;
-                            //如果字段的长度与扩容后的值一致则不去修改字段
-                            if (filedLength == newLength) {
-                                continue;
-                            }
-                            //如果数据的最大长度 +100 都大于字段配置的长度  则重新设置字段的长度
-                            if (filedLength >= newLength) {
-                                baseMapper.updateFiledType(initTableName, eKey, "varchar", newLength);
-                                wbsFormElement.setELength(newLength);
-                                baseMapper.updateById(wbsFormElement);
-                                continue;
-                            }
-                            baseMapper.updateFiledType(initTableName, eKey, "varchar", eLength);
-                        }
+                        // + 10 预留字段长度,用来保存在excel中的位置信息,比如:xx_^_12_12, 不适合一个字段存储多个位置
+                        baseMapper.updateFiledType(initTableName, eKey, "varchar", eLength + 10);
                     } catch (Exception e) {
+                        // 数据库字段长度大于修改长度,则忽略
+                        if (e.getMessage().contains("Data truncated for column '" + eKey + "' at row 1")) {
+                            continue;
+                        }
+                        e.printStackTrace();
                         this.updateBatchById(beforeUpdateWbsFormElements);
                         throw new RuntimeException("字段长度范围超出总最大限制,请尝试缩小当前字段长度或其他字段长度");
                     }
@@ -965,4 +953,88 @@ public class WbsFormElementServiceImpl extends BaseServiceImpl<WbsFormElementMap
         }
     }
 
+
+    /**
+     * 修改当前表所有字段的长度 (只用于字段缩减)
+     * 1、字段数量超过80 表数据超过500条 把数据长度为0的旧字段长度改为50
+     * 超过:新字段的默认长度改为150,并且
+     */
+    public void updateTableFieldLength(String tableName) {
+        TableInfo tableInfo = tableInfoMapper.selectOne(Wrappers.<TableInfo>lambdaQuery()
+                .eq(TableInfo::getTabEnName, tableName)
+                .last("limit 1"));
+
+        List<WbsFormElement> wbsFormElements = baseMapper.selectList(Wrappers.<WbsFormElement>lambdaQuery()
+                .eq(WbsFormElement::getFId, tableInfo.getId()));
+        //元素是否存在
+        if (CollectionUtil.isEmpty(wbsFormElements)) {
+            return;
+        }
+        //字段级字段长度缓存
+        Map<String, Integer> lengthMap = new HashMap<>();
+        //查询当前表的所有字段级字段长度
+        List<Map<String, Object>> filedLengths = baseMapper.selectFiledLength(tableName);
+        //表是否存在
+        if (CollectionUtil.isEmpty(filedLengths)) {
+            return;
+        }
+        for (Map<String, Object> filedLength : filedLengths) {
+            BigInteger length = (BigInteger) filedLength.get("length");
+            if (length == null) {
+                continue;
+            }
+            //记录字段与字段长度
+            lengthMap.put(filedLength.get("key").toString(), length.intValue());
+        }
+
+        //这张表是否拥有数据超过500条
+        Integer count = jdbcTemplate.queryForObject("select count(0) from " + tableName, Integer.class);
+
+
+        for (WbsFormElement wbsFormElement : wbsFormElements) {
+
+            String eKey = wbsFormElement.getEKey();
+            //字段不存在
+            if (lengthMap.get(eKey) == null) {
+                continue;
+            }
+            Integer dataLength = baseMapper.selectFiledDataMaxLength(tableName, eKey);
+
+            if (wbsFormElements.size() > 80 && count > 500) {
+                //数据长度
+                dataLength = dataLength == 0 ? 50 : lengthMap.get(eKey) + 100;
+                //如果当前需要设置的长度大于当前字段长度,则跳过
+                if (dataLength > wbsFormElement.getELength()) {
+                    continue;
+                }
+            } else if (wbsFormElements.size() > 80 && count < 500) {
+                //数据长度
+                dataLength = dataLength == 0 ? 100 : lengthMap.get(eKey) + 100;
+                //如果当前需要设置的长度大于当前字段长度,则跳过
+                if (dataLength > wbsFormElement.getELength()) {
+                    continue;
+                }
+            } else if (wbsFormElements.size() < 80 && count > 500) {
+                //数据长度
+                dataLength = dataLength == 0 ? 200 : lengthMap.get(eKey) + 100;
+                //如果当前需要设置的长度大于当前字段长度,则跳过
+                if (dataLength > wbsFormElement.getELength()) {
+                    continue;
+                }
+            } else {
+                //数据长度
+                dataLength = dataLength == 0 ? 200 : lengthMap.get(eKey) + 100;
+                //如果当前需要设置的长度大于当前字段长度,则跳过
+                if (dataLength > wbsFormElement.getELength()) {
+                    continue;
+                }
+                if (dataLength < 200) {
+                    dataLength = 200;
+                }
+            }
+            baseMapper.updateFiledType(tableName, eKey, "varchar", dataLength);
+            wbsFormElement.setELength(dataLength);
+            baseMapper.updateById(wbsFormElement);
+        }
+    }
 }

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

@@ -82,6 +82,8 @@ import java.io.IOException;
 import java.io.InputStream;
 import java.math.BigDecimal;
 import java.math.BigInteger;
+import java.math.MathContext;
+import java.math.RoundingMode;
 import java.util.*;
 import java.util.concurrent.ConcurrentHashMap;
 import java.util.function.Function;
@@ -110,6 +112,8 @@ public class WbsTreeContractServiceImpl extends BaseServiceImpl<WbsTreeContractM
     private final InformationQueryClient informationQueryClient;
     private final ContractClient contractClient;
     private final ITableFileService tableFileService;
+    private final TableInfoMapper  tableInfoMapper;
+    private final WbsFormElementMapper wbsFormElementMapper;
 
 
     @Autowired
@@ -1657,17 +1661,87 @@ public class WbsTreeContractServiceImpl extends BaseServiceImpl<WbsTreeContractM
                     sgTabMaps.put(s + "---" + wbsTreeContract.getPKeyId(), wbsTreeContract.getInitTableName());
                 }
             }
+            //获取 CL08水准测量记录表(监理)的 实际标高、高程偏差 对应字段 m_20220928134702_1574999102784012288
+            String leveling = "CL08水准测量记录表(监理)";
+            String levelingTableName = "m_20220928134702_1574999102784012288";
+
+            String designedElevation = "设计标高";
+            //负值+0/1 正值-0/1
+            String heightDeviation = "高程偏差";
+            //设置标高 + (高度偏差 / 100)
+            String actualElevation = "实际标高";
+
+            //m_20220928134725_1574999197613031424
+            String planePosition = "CL10平面位置检测记录表(监理)";
+            String planePositionTableName = "m_20220928134725_1574999197613031424";
+
+            //负值+0/1 正值-0/1
+            String difference = "差值";
+            //差值X + 差值Y 的开平方
+            String deviation = "偏位";
+            //指定表单和指定字段
+            Map<String, Map<String, String>> dataMaps = new HashMap<>();
+
             for (WbsTreeContract wbsTreeContract : jlTabSort) {
                 //监理表
                 String s = extractAlphameric(wbsTreeContract.getNodeName());
                 if (StringUtils.isNotEmpty(s)) {
                     jlTabMaps.put(s + "---" + wbsTreeContract.getPKeyId(), wbsTreeContract.getInitTableName());
                 }
+
+
+                /**
+                 * 如果是
+                 *  CL08水准测量记录表(监理)
+                 *      1、“实际标高”不获取数据,改为计算得来,计算规则为:实际标高 = 设计标高 + (高程偏差 / 100)。其中高程偏差需带符号进行计算,特别是负号;
+                 *      2、获取的【高程偏差】需要做随机加减(规则为:如果是负数则+0/1,如果是正数则-0/1)
+                 *  CL10平面位置检测记录表(监理)
+                 *      1、“差值”的两列和“偏位”数据不获取
+                 *      2、获取的【差值】两列 需要做随机加减(规则为:如果是负数则+0/1,如果是正数则-0/1)
+                 *      3、“偏差”不获取数据,改为计算得来,计算规则为:(差值x的平方 + 差值y的平方)的和开平方,四舍五入保留整数。
+                 */
+                HashMap<String, String> map = new HashMap<>();
+
+                //判断当前表单是否是CL08、CL10
+                if (levelingTableName.equals(wbsTreeContract.getInitTableName()) || planePositionTableName.equals(wbsTreeContract.getInitTableName())) {
+                    TableInfo tableInfo = tableInfoMapper.selectOne(Wrappers.<TableInfo>lambdaQuery()
+                            .eq(TableInfo::getTabEnName, wbsTreeContract.getInitTableName()));
+                    List<WbsFormElement> wbsFormElements = wbsFormElementMapper.selectList(Wrappers.<WbsFormElement>lambdaQuery()
+                            .eq(WbsFormElement::getFId, tableInfo.getId()));
+                    for (WbsFormElement wbsFormElement : wbsFormElements) {
+                        String eName = wbsFormElement.getEName();
+                        if(eName.contains(designedElevation)){
+                            //设置标高
+                            map.put(designedElevation, wbsFormElement.getEKey());
+                        }else if(eName.contains(heightDeviation)){
+                            //高度偏差
+                            map.put(heightDeviation, wbsFormElement.getEKey());
+                        }else if(eName.contains(actualElevation)){
+                            //实际标高
+                            map.put(actualElevation, wbsFormElement.getEKey());
+                        }else if(eName.contains(difference)){
+                            //差值
+                            if(eName.contains("X")){
+                                map.put(difference + "X", wbsFormElement.getEKey());
+                            }else if (eName.contains("Y")){
+                                map.put(difference + "Y", wbsFormElement.getEKey());
+                            }
+                        }else if(eName.contains(deviation)){
+                            //偏差
+                            map.put(deviation, wbsFormElement.getEKey());
+                        }
+                    }
+
+                    //存储
+                    dataMaps.put(wbsTreeContract.getInitTableName(),map);
+                }
             }
 
             //构造表数据
             List<InsertDataVO> resultData = new LinkedList<>();
-            this.syncTabDataImpl(sgTabMaps, jlTabMaps, resultData);
+            //坐标
+            Map<String,Set<String>> coordinateMap = new HashMap<>();
+            this.syncTabDataImpl(sgTabMaps, jlTabMaps, resultData,coordinateMap);
 
             //入库处理
             if (resultData.size() > 0) {
@@ -1753,6 +1827,209 @@ public class WbsTreeContractServiceImpl extends BaseServiceImpl<WbsTreeContractM
                                 filedNames.add(vo.getName());
                             }*/
                         }
+
+                        Map<String, String> stringStringMap = dataMaps.get(initTabName);
+
+                        //CL08水准测量记录表(监理)
+                        if(levelingTableName.equals(initTabName)){
+                            //设计标高
+                            String designedElevationNew = stringStringMap.get(designedElevation);
+                            HashMap<Integer, BigDecimal> designedElevationNewMap = new HashMap<>();
+                            //偏差
+                            String heightDeviationNew = stringStringMap.get(heightDeviation);
+                            HashMap<Integer, BigDecimal> heightDeviationNewMap = new HashMap<>();
+                            //实际标高
+                            String actualElevationNew = stringStringMap.get(actualElevation);
+
+                            //记录数量
+                            Integer rowMin = null;
+                            Integer rowMax = null;
+
+                            for (int i = 0; i < keys.size(); i++) {
+                                if(!Objects.equals(keys.get(i),designedElevationNew) && !Objects.equals(keys.get(i),heightDeviationNew)){
+                                    continue;
+                                }
+
+
+                                String value = values.get(i);
+                                //拆分数据
+                                String[] split1 = value.split("☆");
+
+                                List<String> heightDeviationList = new ArrayList<>();
+                                for (String s : split1) {
+                                    String[] split2 = s.split("_\\^_");
+                                    int rowNum = Integer.parseInt(split2[1].split("_")[0]);
+                                    //获取最大行数
+                                    if(rowMax == null){
+                                        rowMax = rowNum;
+                                    }else if(rowMax < rowNum){
+                                        rowMax = rowNum;
+                                    }
+                                    //获取最小行数
+                                    if(rowMin == null){
+                                        rowMin = rowNum;
+                                    }else if(rowMin > rowNum){
+                                        rowMin = rowNum;
+                                    }
+
+                                    if (keys.get(i).equals(designedElevationNew)) {
+                                        //设计标高
+                                        designedElevationNewMap.put(rowNum, new BigDecimal(split2[0]));
+                                    } else if (keys.get(i).equals(heightDeviationNew)){
+                                        if(StringUtils.isNotEmpty(split2[0])){
+                                            double v = Double.parseDouble(split2[0]);
+                                            //随机+ - 0/1
+                                            Random random = new Random();
+                                            int adjustment = random.nextInt(2);
+                                            if(v > 0){
+                                                v = v - adjustment;
+                                            }else{
+                                                v = v + adjustment;
+                                            }
+
+                                            //高度偏差
+                                            heightDeviationNewMap.put(rowNum, BigDecimal.valueOf(v));
+
+                                            heightDeviationList.add(new BigDecimal(v).setScale(0,RoundingMode.HALF_UP).intValue() + "_^_"+ split2[1]);
+                                        }
+                                    }
+                                }
+                                //设置偏高的值
+                                if(CollectionUtil.isNotEmpty(heightDeviationList)){
+                                    values.set(i, String.join("☆",heightDeviationList));
+                                }
+                            }
+                            if(rowMin==null){
+                                continue;
+                            }
+                            List<String> list = new ArrayList<>();
+
+                            //获取当前key对应的坐标
+                            Set<String> strings = coordinateMap.get(initTabName);
+                            String index = null;
+                            for (String string : strings) {
+                                String[] split = string.split("__");
+                                if(Objects.equals(split[0],actualElevationNew)){
+                                    index = split[1];
+                                }
+                            }
+                            //按照最小行数来计算
+                            for (int i = rowMin; i <= rowMax; i++) {
+                                BigDecimal designed = designedElevationNewMap.get(i);
+                                BigDecimal height = heightDeviationNewMap.get(i);
+
+                                if(designed == null || height == null){
+                                    continue;
+                                }
+                                BigDecimal v = designed.add(height.divide(new BigDecimal(1000)));
+                                //第5列,索引为4
+                                list.add(v.doubleValue() + "_^_"+ i + "_" + index);
+                            }
+                            //未获取到当前key的坐标就不设置值
+                            if(index == null){
+                                continue;
+                            }
+                            //设置实际标高的值
+                            values.set(keys.indexOf(actualElevationNew), String.join("☆",list));
+                        }else if(planePositionTableName.equals(initTabName)){
+                            //CL10平面位置检测记录表(监理)
+                            //差值
+                            String differenceNewX = stringStringMap.get(difference + "X");
+                            HashMap<Integer, BigDecimal> differenceNewXMap = new HashMap<>();
+
+                            String differenceNewY = stringStringMap.get(difference + "Y");
+                            HashMap<Integer, BigDecimal> differenceNewYMap = new HashMap<>();
+
+
+                            String deviationNew = stringStringMap.get(deviation);
+                            //记录数量
+                            Integer rowMin = null;
+                            Integer rowMax = null;
+                            for (int i = 0; i < keys.size(); i++) {
+                                if(!Objects.equals(keys.get(i),differenceNewX) && !Objects.equals(keys.get(i),differenceNewY)){
+                                    continue;
+                                }
+
+                                String value = values.get(i);
+                                //拆分数据
+                                String[] split1 = value.split("☆");
+
+                                List<String> list = new ArrayList<>();
+
+                                for (String s : split1) {
+                                    String[] split2 = s.split("_\\^_");
+                                    int rowNum = Integer.parseInt(split2[1].split("_")[0]);
+                                    //获取最大行数
+                                    if(rowMax == null){
+                                        rowMax = rowNum;
+                                    }else if(rowMax < rowNum){
+                                        rowMax = rowNum;
+                                    }
+                                    //获取最小行数
+                                    if(rowMin == null){
+                                        rowMin = rowNum;
+                                    }else if(rowMin > rowNum){
+                                        rowMin = rowNum;
+                                    }
+                                    if(StringUtils.isNotEmpty(split2[0])){
+                                        Integer v = Integer.parseInt(split2[0]);
+                                        //随机+ - 0/1
+                                        Random random = new Random();
+                                        int adjustment = random.nextInt(2);
+                                        if(v > 0){
+                                            v = v - adjustment;
+                                        }else{
+                                            v = v + adjustment;
+                                        }
+                                        if (keys.get(i).equals(differenceNewX)) {
+                                            //偏差X
+                                            differenceNewXMap.put(rowNum, new BigDecimal(split2[0]));
+                                        } else if (keys.get(i).equals(differenceNewY)){
+                                            //偏差Y
+                                            differenceNewYMap.put(rowNum, BigDecimal.valueOf(v));
+                                        }
+                                        list.add(v + "_^_"+ split2[1]);
+                                    }
+                                }
+                                values.set(i, String.join("☆",list));
+                            }
+                            if(rowMin==null){
+                                continue;
+                            }
+                            List<String> list = new ArrayList<>();
+                            //获取当前key对应的坐标
+                            Set<String> strings = coordinateMap.get(initTabName);
+                            String index = null;
+                            for (String string : strings) {
+                                String[] split = string.split("__");
+                                if(Objects.equals(split[0],deviationNew)){
+                                    index = split[1];
+                                }
+                            }
+                            //按照最小行数来计算
+                            for (int i = rowMin; i <= rowMax; i++) {
+                                BigDecimal x = differenceNewXMap.get(i);
+                                BigDecimal y = differenceNewYMap.get(i);
+
+                                if(x == null || y == null){
+                                    continue;
+                                }
+                                BigDecimal sqrt = sqrt(x.multiply(x).add(y.multiply(y)), 0);
+
+                                //第9列,索引为8
+                                list.add(sqrt.intValue() + "_^_"+ i + "_" + index);
+                            }
+                            //未获取到当前key的坐标就不设置值
+                            if(index == null){
+                                continue;
+                            }
+                            //设置实际标高的值
+                            values.set(keys.indexOf(deviationNew), String.join("☆",list));
+                        }
+
+
+
+
                         if (keys.size() > 0 && values.size() > 0 && keys.size() == values.size()) {
                             //alter SQL(扩容字段长度)
                             StringBuilder exStrBuilder = new StringBuilder();
@@ -1857,6 +2134,32 @@ public class WbsTreeContractServiceImpl extends BaseServiceImpl<WbsTreeContractM
         }
     }
 
+    // 牛顿迭代法实现开平方
+    public  BigDecimal sqrt(BigDecimal value, int precision) {
+        // 检查负数输入
+        if (value.compareTo(BigDecimal.ZERO) < 0) {
+            throw new ArithmeticException("不能对负数开平方");
+        }
+
+        // 精度设置(保留小数位 + 额外2位保证精度)
+        MathContext mc = new MathContext(precision + 2, RoundingMode.HALF_EVEN);
+
+        // 初始值 = value / 2
+        BigDecimal guess = value.divide(BigDecimal.valueOf(2), mc);
+        BigDecimal lastGuess;
+
+        // 牛顿迭代公式:xₙ₊₁ = (xₙ + value/xₙ)/2
+        do {
+            lastGuess = guess;
+            guess = value.divide(guess, mc).add(guess)
+                    .divide(BigDecimal.valueOf(2), mc);
+        } while (guess.subtract(lastGuess).abs().compareTo(
+                BigDecimal.valueOf(1, precision + 1)) > 0); // 精度控制
+
+        // 返回最终结果(精确到指定小数位)
+        return guess.setScale(precision, RoundingMode.HALF_UP);
+    }
+
     /**
      * 构造数据
      *
@@ -1866,7 +2169,7 @@ public class WbsTreeContractServiceImpl extends BaseServiceImpl<WbsTreeContractM
      * @throws Exception
      */
     private void syncTabDataImpl
-    (Map<String, String> sgData, Map<String, String> jlData, List<InsertDataVO> resultData) throws
+    (Map<String, String> sgData, Map<String, String> jlData, List<InsertDataVO> resultData, Map<String,Set<String>> coordinateMap) throws
             Exception {
         for (Map.Entry<String, String> sgTab : sgData.entrySet()) { //质检表
             String[] split = sgTab.getKey().split("---");
@@ -1885,6 +2188,22 @@ public class WbsTreeContractServiceImpl extends BaseServiceImpl<WbsTreeContractM
                 //表的代码名称相同,就复制数据,例如:G10=G10
                 if (nodeNameRe.equals(nodeNameReJL)) {
                     String htmlStringJL = this.getHtmlString(pKeyIdJL);
+
+                    //解析html坐标,生成key与keyName的映射关系
+                    if (StringUtils.isNotEmpty(htmlStringJL)) {
+                        Document doc = Jsoup.parse(htmlStringJL);
+                        Elements select = doc.select("[id]");
+                        HashSet<String> strings = new HashSet<>();
+                        for (Element element : select) {
+                            String id = element.id();
+                            String[] split1 = id.split("__");
+                            String s = split1[1].split("_")[1];
+
+                            strings.add(split1[0] + "__" + s);
+                        }
+                        coordinateMap.put(initTabNameJL, strings);
+                    }
+
                     //获取质检实体表对应数据
                     List<Map<String, Object>> mapsList = jdbcTemplate.queryForList("select * from " + initTabName + " where p_key_id = " + pKeyId);
                     if (mapsList.size() > 0) {

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

@@ -3058,7 +3058,7 @@ public class WbsTreePrivateServiceImpl extends BaseServiceImpl<WbsTreePrivateMap
     /**
      * 修改initTableId
      */
-    @Scheduled(cron = "0 0 3 * * ?")
+//    @Scheduled(cron = "0 0 3 * * ?")
     public void updateInitTableId() {
         List<WbsTreePrivate> wbsTreePrivates = baseMapper.selectList(Wrappers.<WbsTreePrivate>lambdaQuery().isNull(WbsTreePrivate::getInitTableId).isNotNull(WbsTreePrivate::getInitTableName).ne(WbsTreePrivate::getType, 1));
         List<TableInfo> list = baseMapper.selectTabInfoAll();

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

@@ -234,7 +234,7 @@ public class WbsTreeSynchronousRecordServiceImpl extends ServiceImpl<WbsTreeSync
      * 同步节点表单
      * 定时检查同步任务,状态为1的数据如果最后更新时间与当前时间超过10分钟,则修改状态为1
      */
-    @Scheduled(fixedDelay = 10000)
+//    @Scheduled(fixedDelay = 10000)
     public void syncInit() {
         // 本地环境跳过执行(可添加日志输出)
         if (!schedulerEnabled) return;

+ 7 - 7
blade-service/blade-repair/src/main/java/org/springblade/repair/controller/CheckAndRepairController.java

@@ -53,7 +53,7 @@ public class CheckAndRepairController {
      */
     @RequestMapping("/checkAndRepairExcelHtml")
     @ApiOperation("定时检测修复ExcelHtml")
-    @Scheduled(cron = "00 00 00 * * ?")
+//    @Scheduled(cron = "00 00 00 * * ?")
     public void checkAndRepairExcelHtml() {
         StringBuilder result=new StringBuilder("");
         String sql = "Select * from m_excel_tab where  is_deleted=0 and file_url is  not null";
@@ -144,7 +144,7 @@ public class CheckAndRepairController {
     /**
      * 定时更新private和contract的html,通过is_private_type_id;保证一样
      */
-    @Scheduled(cron = "0 0  3 * * ?")
+//    @Scheduled(cron = "0 0  3 * * ?")
     public void checkAndRepairPrivateAndContractHtml() {
         System.out.println("开始扫描private和contract的html");
         StringBuilder result=new StringBuilder("");
@@ -169,7 +169,7 @@ public class CheckAndRepairController {
      * 定时更新private initTable或者excelID,保证一样
      */
     @GetMapping("/checkAndRepairPrivateInitTableAndExcelId")
-    @Scheduled(cron = "0 30  1 * * ?")
+//    @Scheduled(cron = "0 30  1 * * ?")
     public void checkAndRepairPrivateInitTableAndExcelId() {
         System.out.println("开始扫描private initTable和ExcelId");
         String privateSql="select p_key_id,init_table_name,excel_id,html_url from m_wbs_tree_private where type=2 AND is_deleted=0 AND (excel_id IS NULL OR init_table_name IS NULL OR html_url IS NULL)";
@@ -223,7 +223,7 @@ public class CheckAndRepairController {
      * 定时更新contract initTable或者excelID,保证一样
      */
     @GetMapping("/checkAndRepairContractInitTableAndExcelId")
-    @Scheduled(cron = "0  00  2 * * ?")
+//    @Scheduled(cron = "0  00  2 * * ?")
     public void checkAndRepairContractInitTableAndExcelId() {
         System.out.println("定时更新contract initTable和ExcelId");
         String contractSql="select p_key_id,init_table_name,excel_id,html_url from m_wbs_tree_contract where type=2 AND is_deleted=0 AND (excel_id IS NULL OR init_table_name IS NULL OR html_url IS NULL)";
@@ -289,7 +289,7 @@ public class CheckAndRepairController {
      * 定时检测excel文件后缀名
      */
     @GetMapping("/checkExcelExtension")
-    @Scheduled(cron = "0 00  12 * * ?")
+//    @Scheduled(cron = "0 00  12 * * ?")
     public void checkExcelExtension(){
         String sql="select id,name,extension from m_excel_tab where is_deleted=0";
         List<ExcelTab> list = jdbcTemplate.query(sql, new BeanPropertyRowMapper<>(ExcelTab.class));
@@ -316,7 +316,7 @@ public class CheckAndRepairController {
      * 定时检测private html是否包含privateUrlCopy 但是不包括独立表单
      */
     @GetMapping("/checkPrivateHtmlIsCopy")
-    @Scheduled(cron = "0 30 23 * * ?")
+//    @Scheduled(cron = "0 30 23 * * ?")
     public void checkPrivateHtmlIsCopy(){
         String sql="select p_key_id,project_id,html_url from m_wbs_tree_private where is_deleted=0 and html_url  NOT LIKE '%privateUrlCopy%' AND type=2";
         List<WbsTreePrivate> list = jdbcTemplate.query(sql, new BeanPropertyRowMapper<>(WbsTreePrivate.class));
@@ -368,7 +368,7 @@ public class CheckAndRepairController {
      * 检查private html文件是否存在
      */
     @GetMapping("/checkPrivateHtmlIsExist")
-    @Scheduled(cron = "0  0  3 * * ?")
+//    @Scheduled(cron = "0  0  3 * * ?")
     public void checkPrivateHtmlIsExist() throws Exception {
         String sql="select p_key_id, excel_id,html_url from m_wbs_tree_private where html_url IS NOT NULL  and is_deleted=0";
         List<WbsTreePrivate> list = jdbcTemplate.query(sql, new BeanPropertyRowMapper<>(WbsTreePrivate.class));

+ 1 - 1
blade-service/blade-user/src/main/java/org/springblade/system/user/service/impl/UserServiceImpl.java

@@ -1088,7 +1088,7 @@ public class UserServiceImpl extends BaseServiceImpl<UserMapper, User> implement
     /**
      * 定时清理本地缓存信息,不在批量电签时删除,批量电签是多线程,会一直删除,导致缓存基本不生效(已废除Redis缓存,走本地缓存不需要Redis)
      */
-    @Scheduled(fixedRate = 180000) //每3分钟执行一次
+//    @Scheduled(fixedRate = 180000) //每3分钟执行一次
     public void clearContractLocalCacheAndRedisCache() {
         //获取锁
         ReentrantLock lock = new ReentrantLock();