浏览代码

Merge branch 'lvy' of http://219.151.181.73:3000/zhuwei/bladex into test-merge-02

# Conflicts:
#	blade-service-api/blade-manager-api/src/main/java/org/springblade/manager/feign/WbsParamClient.java
#	blade-service/blade-manager/src/main/java/org/springblade/manager/feign/WbsParamClientImpl.java
#	blade-service/blade-manager/src/main/java/org/springblade/manager/service/impl/TextdictInfoServiceImpl.java
LHB 3 月之前
父节点
当前提交
ad49697232
共有 18 个文件被更改,包括 582 次插入108 次删除
  1. 1 1
      blade-service-api/blade-archive-api/src/main/java/org/springblade/archive/vo/ArchivesAutoVO.java
  2. 2 2
      blade-service-api/blade-business-api/src/main/java/org/springblade/business/vo/MessageWarningVO.java
  3. 2 2
      blade-service-api/blade-manager-api/src/main/java/org/springblade/manager/feign/TableFileClient.java
  4. 4 0
      blade-service-api/blade-manager-api/src/main/java/org/springblade/manager/feign/WbsParamClient.java
  5. 9 2
      blade-service/blade-archive/src/main/java/org/springblade/archive/controller/ArchiveFileController.java
  6. 9 2
      blade-service/blade-archive/src/main/java/org/springblade/archive/controller/ArchiveInspectionInfoController.java
  7. 84 0
      blade-service/blade-archive/src/main/java/org/springblade/archive/service/impl/ArchivesAutoServiceImpl.java
  8. 95 59
      blade-service/blade-business/src/main/java/org/springblade/business/controller/InformationWriteQueryController.java
  9. 10 6
      blade-service/blade-business/src/main/java/org/springblade/business/controller/MessageWarningController.java
  10. 1 1
      blade-service/blade-business/src/main/java/org/springblade/business/mapper/InformationQueryMapper.xml
  11. 4 0
      blade-service/blade-business/src/main/java/org/springblade/business/service/impl/TrialMaterialMobilizationServiceImpl.java
  12. 18 1
      blade-service/blade-manager/src/main/java/org/springblade/manager/controller/ExcelTabController.java
  13. 2 2
      blade-service/blade-manager/src/main/java/org/springblade/manager/feign/TableFileClientImpl.java
  14. 7 0
      blade-service/blade-manager/src/main/java/org/springblade/manager/feign/WbsParamClientImpl.java
  15. 15 0
      blade-service/blade-manager/src/main/java/org/springblade/manager/service/impl/TextdictInfoServiceImpl.java
  16. 3 21
      blade-service/blade-manager/src/main/java/org/springblade/manager/utils/PdfAddContextUtils.java
  17. 268 6
      blade-service/blade-repair/src/main/java/org/springblade/repair/controller/CheckAndRepairController.java
  18. 48 3
      blade-service/blade-user/src/main/java/org/springblade/system/user/service/impl/UserServiceImpl.java

+ 1 - 1
blade-service-api/blade-archive-api/src/main/java/org/springblade/archive/vo/ArchivesAutoVO.java

@@ -234,7 +234,7 @@ public class ArchivesAutoVO extends ArchivesAuto {
 
 		private  String archiveId;
 
-		private Long id;
+		private String id;
 		private Long fileSize;
 		private Integer isElement;
 	}

+ 2 - 2
blade-service-api/blade-business-api/src/main/java/org/springblade/business/vo/MessageWarningVO.java

@@ -45,8 +45,8 @@ public class MessageWarningVO extends MessageWarning {
     @ApiModelProperty("结束时间")
     private String endTime;
 
-    @ApiModelProperty("类型")
-    private String typeValue;
+    @ApiModelProperty("1废除, 2驳回")
+    private String repealType;
 
     @ApiModelProperty("任务催办未读数量")
     private Long typeOneNumber;

+ 2 - 2
blade-service-api/blade-manager-api/src/main/java/org/springblade/manager/feign/TableFileClient.java

@@ -29,7 +29,7 @@ public interface TableFileClient {
     @PostMapping(API_PREFIX + "/saveBatch")
     boolean saveBatch(@RequestBody List<TableFile> newFiles);
 
-    @GetMapping(API_PREFIX + "/getTabFilesByTabIds")
-    List<TableFile> getTabFilesByTabIds(@RequestParam String tabFileIds);
+    @PostMapping(API_PREFIX + "/getTabFilesByTabIds")
+    List<TableFile> getTabFilesByTabIds(@RequestBody List<String> tabFileIds);
 
 }

+ 4 - 0
blade-service-api/blade-manager-api/src/main/java/org/springblade/manager/feign/WbsParamClient.java

@@ -9,6 +9,8 @@ import org.springframework.web.bind.annotation.PostMapping;
 import org.springframework.web.bind.annotation.RequestBody;
 import org.springframework.web.bind.annotation.RequestParam;
 
+import java.util.List;
+
 import static org.springblade.core.launch.constant.AppConstant.APPLICATION_NAME_PREFIX;
 
 @FeignClient(value = APPLICATION_NAME_PREFIX + "manager")
@@ -24,6 +26,8 @@ public interface WbsParamClient {
     @GetMapping(API_PREFIX + "/getWbsParam")
     WbsParam getWbsParam(@RequestParam Long nodeId);
 
+    @PostMapping(API_PREFIX + "/saveWbsParams")
+    void saveWbsParams(@RequestBody List<WbsParam> wbsParamList);
     @PostMapping(API_PREFIX + "/createFileTitle")
     String createFileTitle(@RequestBody WbsTreeContract contract);
 }

+ 9 - 2
blade-service/blade-archive/src/main/java/org/springblade/archive/controller/ArchiveFileController.java

@@ -416,8 +416,15 @@ public class ArchiveFileController extends BladeController {
     @GetMapping("/getMetadataFile")
     @ApiOperationSupport(order = 16)
     @ApiOperation(value = "文件收集-上传文件责任者")
-    public R getMetadataFile(Long fileId) {
-        return R.data(metadataClassificationClient.getMetadataFile(fileId));
+    public R getMetadataFile(String fileId) {
+        long id;
+        try  {
+            fileId = fileId.split("_")[0];
+            id = Long.parseLong(fileId);
+        } catch (Exception e) {
+            return R.data(null);
+        }
+        return R.data(metadataClassificationClient.getMetadataFile(id));
     }
 
     /**

+ 9 - 2
blade-service/blade-archive/src/main/java/org/springblade/archive/controller/ArchiveInspectionInfoController.java

@@ -97,9 +97,16 @@ public class ArchiveInspectionInfoController {
     @GetMapping("/opinion")
     @ApiOperationSupport(order = 6)
     @ApiOperation(value = "获取抽检意见", notes = "传入fileId")
-    public R<ArchiveInspectionDTO> getOpinion(@RequestParam Long fileId) {
+    public R<ArchiveInspectionDTO> getOpinion(@RequestParam String fileId) {
         Long userId = AuthUtil.getUserId();
-        ArchiveInspectionDTO archiveInspectionDTO = archiveInspectionService.getbyFileId(fileId, userId);
+        long id;
+        try  {
+            fileId = fileId.split("_")[0];
+            id = Long.parseLong(fileId);
+        } catch (Exception e) {
+            return R.data(null);
+        }
+        ArchiveInspectionDTO archiveInspectionDTO = archiveInspectionService.getbyFileId(id, userId);
         return R.data(archiveInspectionDTO);
     }
 

+ 84 - 0
blade-service/blade-archive/src/main/java/org/springblade/archive/service/impl/ArchivesAutoServiceImpl.java

@@ -376,6 +376,90 @@ public class ArchivesAutoServiceImpl extends BaseServiceImpl<ArchivesAutoMapper,
 		} else {
 			vo.setPageNumber(0);
 		}
+		String outUrl = vo.getOutUrl();
+		if (StringUtils.isNotBlank(outUrl)) {
+			// 根据 factorType 字符串生成档案号码字符串链表
+			ArchiveProjectConfig config = archiveProjectConfigService.getByProjectIdOrNew(vo.getProjectId());
+			String[] frontUrls = outUrl.split(",");
+			ArchivesAutoVO.ApprovalFile front = new ArchivesAutoVO.ApprovalFile();
+			ArchivesAutoVO.ApprovalFile cataLog = new ArchivesAutoVO.ApprovalFile();
+			ArchivesAutoVO.ApprovalFile spare = new ArchivesAutoVO.ApprovalFile();
+			ArchivesAutoVO.ApprovalFile back = new ArchivesAutoVO.ApprovalFile();
+			for (String frontUrl : frontUrls) {
+				// 封面(原r_Archives_front)增加中文"封面"匹配
+				if ((frontUrl.contains(ArchiveAutoPdfServiceImpl.ARCHIVE_NUMBER[0])
+						|| frontUrl.contains("封面"))
+						&& config.getFactorType().contains("1")) {
+					front.setFileName("封面");
+					if(frontUrl.contains("@@@")){
+						front.setFileUrl(frontUrl.substring(0,frontUrl.indexOf("@@@")));
+					}else {
+						front.setFileUrl(frontUrl);
+					}
+				}
+				// 卷内目录(原r_Archives_catalog)增加中文匹配
+				else if ((frontUrl.contains(ArchiveAutoPdfServiceImpl.ARCHIVE_NUMBER[1])
+						|| frontUrl.contains("卷内目录"))
+						&& config.getFactorType().contains("2")) {
+					cataLog.setFileName("卷内目录");
+					if(frontUrl.contains("@@@")){
+						cataLog.setFileUrl(frontUrl.substring(0,frontUrl.indexOf("@@@")));
+					}else {
+						cataLog.setFileUrl(frontUrl);
+					}
+				}
+				// 备考表(原r_Archives_spare)增加中文匹配
+				else if ((frontUrl.contains(ArchiveAutoPdfServiceImpl.ARCHIVE_NUMBER[2])
+						|| frontUrl.contains("备考表"))
+						&& config.getFactorType().contains("3")) {
+					spare.setFileName("备考表");
+					if(frontUrl.contains("@@@")){
+						spare.setFileUrl(frontUrl.substring(0,frontUrl.indexOf("@@@")));
+					}else {
+						spare.setFileUrl(frontUrl);
+					}
+				}
+				// 背脊(原r_Archives_back)增加中文匹配
+				else if ((frontUrl.contains(ArchiveAutoPdfServiceImpl.ARCHIVE_NUMBER[3])
+						|| frontUrl.contains("背脊"))
+						&& config.getFactorType().contains("4")) {
+					back.setFileName("背脊");
+					if(frontUrl.contains("@@@")){
+						back.setFileUrl(frontUrl.substring(0,frontUrl.indexOf("@@@")));
+					}else {
+						back.setFileUrl(frontUrl);
+					}
+				}
+			}
+			List<ArchivesAutoVO.ApprovalFile> files = vo.getApprovalFileList();
+			if (files != null && !files.isEmpty()) {
+				ArchivesAutoVO.ApprovalFile temp = files.get(0);
+				if (front.getFileUrl() != null) {
+					front.setId(temp.getId() + "_1");
+					front.setPdfFileUrl(front.getFileUrl());
+					files.add(0,front);
+				}
+				if (cataLog.getFileUrl() != null) {
+					cataLog.setId(temp.getId()  + "_2");
+					cataLog.setPdfFileUrl(cataLog.getFileUrl());
+					if (front.getFileUrl() != null) {
+						files.add(1,cataLog);
+					} else {
+						files.add(0,cataLog);
+					}
+				}
+				if (spare.getFileUrl() != null) {
+					spare.setId(temp.getId()  + "_3");
+					spare.setPdfFileUrl(spare.getFileUrl());
+					files.add(spare);
+				}
+				if (back.getFileUrl() != null) {
+					back.setId(temp.getId()  + "_4");
+					back.setPdfFileUrl(back.getFileUrl());
+					files.add(back);
+				}
+			}
+		}
 		return vo;
 	}
 

+ 95 - 59
blade-service/blade-business/src/main/java/org/springblade/business/controller/InformationWriteQueryController.java

@@ -1787,6 +1787,7 @@ public R<Boolean> copyContractTreeNode(@RequestBody CopyContractTreeNodeVO vo) {
 
             /*获取元素表数据*/
             Map<Long, Map<String, Object>> colMaps = new HashMap<>();
+            Map<Long, String> colMap = new HashMap<>();
             //是否需要复制数据
             if (vo.getIsCopyData() == 1) {
                 //表名集合
@@ -1797,7 +1798,7 @@ public R<Boolean> copyContractTreeNode(@RequestBody CopyContractTreeNodeVO vo) {
                         .collect(Collectors.toList());
                 //表名集合转逗号拼接的字符串
                 String inClausePlaceholders = String.join(",", Collections.nCopies(tabNames.size(), "?"));
-                String sql = "SELECT table_name AS queryType, GROUP_CONCAT(COLUMN_name) AS ancestors " +
+                String sql = "SELECT table_name AS queryType, GROUP_CONCAT(distinct COLUMN_name) AS ancestors " +
                         "FROM information_schema.COLUMNS WHERE table_name IN (" + inClausePlaceholders + ") " +
                         "GROUP BY table_name";
                 Object[] params = tabNames.toArray();
@@ -1826,21 +1827,23 @@ public R<Boolean> copyContractTreeNode(@RequestBody CopyContractTreeNodeVO vo) {
                     List<WbsTreeContract> tabs = tabsGroup.get(tabName);
                     for (WbsTreeContract tab : tabs) {
                         //根据字段
-                        String dataSql = "SELECT " + keys + " FROM " + tabName + " WHERE p_key_id = " + tab.getPKeyId() + " LIMIT 1;";
-                        try {
-                            //查询指定表指定表节点的数据
-                            Map<String, Object> resultMap = jdbcTemplate.queryForMap(dataSql);
-                            //删除空值
-                            resultMap.values().removeIf(value -> value == null || (value instanceof String && ObjectUtil.isEmpty(value)));
-                            colMaps.put(tab.getPKeyId(), resultMap);
-                        } catch (EmptyResultDataAccessException e) {
-                            continuePkeyIds.add(tab.getPKeyId());
-                        }
+//                        String dataSql = "SELECT " + keys + " FROM " + tabName + " WHERE p_key_id = " + tab.getPKeyId() + " LIMIT 1;";
+//                        try {
+//                            //查询指定表指定表节点的数据
+//                            Map<String, Object> resultMap = jdbcTemplate.queryForMap(dataSql);
+//                            //删除空值
+//                            resultMap.values().removeIf(value -> value == null || (value instanceof String && ObjectUtil.isEmpty(value)));
+//                            colMaps.put(tab.getPKeyId(), resultMap);
+//                        } catch (EmptyResultDataAccessException e) {
+//                            continuePkeyIds.add(tab.getPKeyId());
+//                        }
+                        colMap.put(tab.getPKeyId(), keys);
                     }
                 }
                 logger.info("以下元素表没有获取到对应实体表数据,已跳过 ===> 表pKeyId:[{}]", StringUtils.join(continuePkeyIds, ","));
             }
             // 节点+表节点
+            List<WbsTreeContract> wbsParamAndLedgerList = new ArrayList<>();
             for (WbsTreeContract nodeOld : nodeChildAll) {
                 //新节点
                 WbsTreeContract newData = new WbsTreeContract();
@@ -1851,15 +1854,18 @@ public R<Boolean> copyContractTreeNode(@RequestBody CopyContractTreeNodeVO vo) {
                 if (nodeOld.getNodeType() != null && nodeOld.getNodeType() == 6) {
                     //新旧节点关联关系
                     peerMap.put(newData.getPKeyId(), nodeOld.getPKeyId());
-                    //复制节点命名配置
-                    //查询节点绑定的公共配置 文件提名信息
-                    WbsParam wbsParam = wbsParamClient.getWbsParam(Long.parseLong(vo.getNeedCopyPrimaryKeyId()));
-                    if(wbsParam!=null){
-                        wbsParam.setId(SnowFlakeUtil.getId());
-                        wbsParam.setNodeId(newData.getPKeyId());
-                        //给复制的节点绑定的公共配置
-                        wbsParamClient.saveWbsParam(wbsParam);
-                    }
+//                    //复制节点命名配置
+//                    //查询节点绑定的公共配置 文件提名信息
+//                    WbsParam wbsParam = wbsParamClient.getWbsParam(Long.parseLong(vo.getNeedCopyPrimaryKeyId()));
+//                    if(wbsParam!=null){
+//                        wbsParam.setId(SnowFlakeUtil.getId());
+//                        wbsParam.setNodeId(newData.getPKeyId());
+//                        //给复制的节点绑定的公共配置
+//                        wbsParamClient.saveWbsParam(wbsParam);
+//                    }
+//                    /*生成工序节点施工日志*/
+//                    this.createLedger(newData, saveLedger, nodeMap, null);
+                    wbsParamAndLedgerList.add(newData);
                 }
                 //源节点是否为复制节点 如果是则设置源节点的源节点 如何不是设置源节点id
                 if (StringUtils.isNotEmpty(nodeOld.getOldId())) {
@@ -1904,9 +1910,9 @@ public R<Boolean> copyContractTreeNode(@RequestBody CopyContractTreeNodeVO vo) {
                 saveList.add(newData);
 
                 /*生成工序节点施工日志*/
-                if (new Integer("6").equals(nodeOld.getNodeType())) {
-                    this.createLedger(newData, saveLedger, nodeMap, null);
-                }
+//                if (new Integer("6").equals(nodeOld.getNodeType())) {
+//                    this.createLedger(newData, saveLedger, nodeMap, null);
+//                }
 
                 /*处理复制表数据*/
                 if (nodeOld.getType() == 2 && vo.getIsCopyData() == 1
@@ -1914,54 +1920,84 @@ public R<Boolean> copyContractTreeNode(@RequestBody CopyContractTreeNodeVO vo) {
                         && tabOwner.contains(nodeOld.getTableOwner())) {
 
                     /*获取表对应的实体数据*/
-                    Map<String, Object> resultMap = colMaps.getOrDefault(nodeOld.getPKeyId(), null);
-                    if (resultMap == null) {
+//                    Map<String, Object> resultMap = colMaps.getOrDefault(nodeOld.getPKeyId(), null);
+//                    if (resultMap == null) {
+//                        continue;
+//                    }
+                    String keys = colMap.getOrDefault(nodeOld.getPKeyId(), null);
+                    if (keys == null || keys.isEmpty()) {
                         continue;
                     }
-
                     /*重置*/
-                    Map<String, String> eMap = reviseValue(nodeOld, null, ekvMap);
+//                    Map<String, String> eMap = reviseValue(nodeOld, null, ekvMap);
 
                     /*构造复制表数据*/
-                    StringBuilder newString = new StringBuilder();
-                    List<String> keySet = new LinkedList<>();
-                    for (Map.Entry<String, Object> entry : resultMap.entrySet()) {
-                        keySet.add(entry.getKey());
-                        Object value = reviseValue(eMap, entry.getKey(), entry.getValue());
-                        if (value != null) {
-                            if (value.toString().contains("\n")) {
-                                value = value.toString().replace("\n", "\\n");
-                            }
-                            newString.append("'").append(value).append("',");
-                        }
-                    }
-                    if (newString.length() > 0) {
-                        newString.insert(0, ',');
-                        if (newString.charAt(newString.length() - 1) == ',') {
-                            newString.deleteCharAt(newString.length() - 1);
-                        }
-                    }
-                    String keysHaveValue = StringUtils.join(keySet, ",");
-                    if (keysHaveValue.length() > 0) {
-                        keysHaveValue = "," + keysHaveValue;
-                    }
+//                    StringBuilder newString = new StringBuilder();
+//                    List<String> keySet = new LinkedList<>();
+//                    for (Map.Entry<String, Object> entry : resultMap.entrySet()) {
+//                        keySet.add(entry.getKey());
+//                        Object value = reviseValue(eMap, entry.getKey(), entry.getValue());
+//                        if (value != null) {
+//                            if (value.toString().contains("\n")) {
+//                                value = value.toString().replace("\n", "\\n");
+//                            }
+//                            newString.append("'").append(value).append("',");
+//                        }
+//                    }
+//                    if (newString.length() > 0) {
+//                        newString.insert(0, ',');
+//                        if (newString.charAt(newString.length() - 1) == ',') {
+//                            newString.deleteCharAt(newString.length() - 1);
+//                        }
+//                    }
+//                    String keysHaveValue = StringUtils.join(keySet, ",");
+//                    if (keysHaveValue.length() > 0) {
+//                        keysHaveValue = "," + keysHaveValue;
+//                    }
                     //delete SQL (先删除旧数据,再新增)
                     String delSql = "DELETE FROM " + newData.getInitTableName() + " WHERE p_key_id = " + newData.getPKeyId() + " ; ";
                     //insert SQL
+//                    copySql.append(delSql)
+//                            .append("INSERT INTO ")
+//                            .append(newData.getInitTableName())
+//                            .append(" (id,p_key_id,group_id")
+//                            .append(keysHaveValue)
+//                            .append(") VALUES (")
+//                            .append(SnowFlakeUtil.getId()).append(",")
+//                            .append(newData.getPKeyId()).append(",null")
+//                            .append(newString)
+//                            .append(");");
                     copySql.append(delSql)
                             .append("INSERT INTO ")
                             .append(newData.getInitTableName())
-                            .append(" (id,p_key_id,group_id")
-                            .append(keysHaveValue)
-                            .append(") VALUES (")
+                            .append(" (id,p_key_id,group_id,")
+                            .append(keys).append(") select ")
                             .append(SnowFlakeUtil.getId()).append(",")
-                            .append(newData.getPKeyId()).append(",null")
-                            .append(newString)
-                            .append(");");
+                            .append(newData.getPKeyId()).append(",null, ")
+                            .append(keys).append(" from ").append(newData.getInitTableName()).append(" where p_key_id =").append(nodeOld.getPKeyId()).append(" LIMIT 1;");
                 }
 
 
 
+            }
+            if (!wbsParamAndLedgerList.isEmpty()) {
+                //复制节点命名配置
+                //查询节点绑定的公共配置 文件提名信息
+                WbsParam wbsParam = wbsParamClient.getWbsParam(Long.parseLong(vo.getNeedCopyPrimaryKeyId()));
+                List<WbsParam> wbsParamList = new ArrayList<>();
+                wbsParamAndLedgerList.forEach(newData -> {
+                    if(wbsParam!=null){
+                        WbsParam wbsParam1 = new WbsParam();
+                        BeanUtil.copy(wbsParam, wbsParam1);
+                        wbsParam1.setId(SnowFlakeUtil.getId());
+                        wbsParam1.setNodeId(newData.getPKeyId());
+                        //给复制的节点绑定的公共配置
+                        wbsParamList.add(wbsParam1);
+                    }
+                    /*生成工序节点施工日志*/
+                    this.createLedger(newData, saveLedger, nodeMap, null);
+                });
+                wbsParamClient.saveWbsParams(wbsParamList);
             }
 
             //TODO 20250414-lhb-新增 添加祖级字段 ancestorsPId
@@ -2309,7 +2345,7 @@ private Map<String, String> reviseValue(WbsTreeContract wtc, WbsTreeContract par
             if (!ekvMap.containsKey(tableName)) {
                 Map<String, String> map = ekvMap.computeIfAbsent(wtc.getInitTableName(), K -> new HashMap<>());
                 if (parent == null) {
-                    parent = this.wbsTreeContractClient.getContractWbsTreeByContractIdAndId(wtc.getParentId(), Long.parseLong(wtc.getContractId()));
+                    parent = this.wbsTreeContractClient.getContractWbsTreeByPrimaryKeyId(wtc.getPId());
                 }
                 /*凡是关联了节点参数公式的元素都不复制数据*/
                 List<Map<String, Object>> paramKey = this.jdbcTemplate.queryForList("select DISTINCT b.e_key ek from m_table_info a  join m_wbs_form_element b on a.id=b.f_id  join m_element_formula_mapping c on b.id = c.element_id where a.tab_en_name='" + tableName + "' and b.is_deleted=0 and c.scope=35 and c.is_deleted=0");
@@ -2467,8 +2503,8 @@ private List<WbsTreeContract> reBuildAncestors(List<WbsTreeContract> list) {
 public void addCopyTabFile(Set<WbsTreeContract> addChildNodesTables,
                            Set<WbsTreeContract> addChildNodesTablesOld) {
     //获取所有数据源附件文件
-    List<Long> tabFileIds = addChildNodesTablesOld.stream().distinct().map(WbsTreeContract::getPKeyId).collect(Collectors.toList());
-    Map<String, List<TableFile>> tableFileOldMap = tableFileClient.getTabFilesByTabIds(StringUtils.join(tabFileIds, ",")).stream().collect(Collectors.groupingBy(TableFile::getTabId));
+    List<String> tabFileIds = addChildNodesTablesOld.stream().distinct().map(item -> item.getPKeyId() + "").collect(Collectors.toList());
+    Map<String, List<TableFile>> tableFileOldMap = tableFileClient.getTabFilesByTabIds(tabFileIds).stream().collect(Collectors.groupingBy(TableFile::getTabId));
     if (tableFileOldMap != null && tableFileOldMap.size() > 0) {
         List<TableFile> resultFileData = new ArrayList<>();
         Set<Long> updatePKeyIds = new HashSet<>();
@@ -2760,7 +2796,7 @@ private void addCopyNodesAndTabsBuildData(List<WbsTreeContract> addNodeList, Lis
         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()));
+        Map<String, QueryProcessDataVO> tabColsAllByTabNameMaps = jdbcTemplate.query("SELECT table_name as queryType, GROUP_CONCAT(DISTINCT 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();
             //新节点

+ 10 - 6
blade-service/blade-business/src/main/java/org/springblade/business/controller/MessageWarningController.java

@@ -155,7 +155,8 @@ public class MessageWarningController extends BladeController {
     @ApiOperationSupport(order = 4)
     @ApiOperation(value = "分页", notes = "传入operationWarning")
     public R<IPage<MessageWarningVO>> list(MessageWarningVO vo, Query query) {
-
+        String content = vo.getContent();
+        vo.setContent(null);
         QueryWrapper<MessageWarning> wrapper = Condition.getQueryWrapper(vo);
         //获取当前人的数据
         wrapper.lambda().eq(MessageWarning::getPushUser, AuthUtil.getUserId().toString());
@@ -166,13 +167,16 @@ public class MessageWarningController extends BladeController {
         if (vo.getSmsType() != null && vo.getSmsType() > -1) {
             wrapper.lambda().eq(MessageWarning::getIsRead, new Integer("2").equals(vo.getSmsType()) ? 0 : 1);
         }
-        if (vo.getTypeValue() != null && !vo.getTypeValue().isEmpty()) {
-            if (vo.getTypeValue().equals("1")) {
+        if (vo.getRepealType() != null && !vo.getRepealType().isEmpty()) {
+            if (vo.getRepealType().equals("1")) {
                 wrapper.lambda().like(MessageWarning::getContent, "废除了");
             } else {
                 wrapper.lambda().like(MessageWarning::getContent, "驳回了");
             }
         }
+        if (content != null && !content.isEmpty()) {
+            wrapper.lambda().like(MessageWarning::getContent, content);
+        }
         //设置合同段ID
         wrapper.lambda().eq(MessageWarning::getProjectId, vo.getProjectId()).eq(MessageWarning::getContractId, vo.getContractId());
 
@@ -188,16 +192,16 @@ public class MessageWarningController extends BladeController {
             iPage.getRecords().forEach(reVO -> {
                 if (reVO.getType() != null && reVO.getType() == 3) {
                     if (reVO.getContent() != null && reVO.getContent().contains("驳回了")) {
-                        reVO.setTypeValue("驳回通知");
+                        reVO.setRepealType("驳回通知");
                     } else if (reVO.getContent() != null && reVO.getContent().contains("废除了")) {
-                        reVO.setTypeValue("废除通知");
+                        reVO.setRepealType("废除通知");
                     }
                     return;
                 }
                 if (dictBizs != null && dictBizs.size() > 0) {
                     for (DictBiz biz : dictBizs) {
                         if (biz.getDictKey().equals(reVO.getType().toString())) {
-                            reVO.setTypeValue(biz.getDictValue());
+                            reVO.setRepealType(biz.getDictValue());
                             break;
                         }
                     }

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

@@ -923,7 +923,7 @@
 
     <!--获取当前节点下,所有表单的字段数据-->
     <select id="getNodeChildTabColsAllByTabName" resultMap="queryProcessDataMap">
-        SELECT table_name as queryType, GROUP_CONCAT(COLUMN_name) as ancestors
+        SELECT table_name as queryType, GROUP_CONCAT(distinct COLUMN_name) as ancestors
         from information_schema.COLUMNS
         where table_name
                   in (#{tabName})

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

@@ -11,6 +11,10 @@ import com.lowagie.text.pdf.BaseFont;
 import com.lowagie.text.pdf.PdfPTable;
 import com.lowagie.text.pdf.PdfWriter;
 import lombok.AllArgsConstructor;
+import org.apache.commons.fileupload.disk.DiskFileItem;
+import org.apache.commons.fileupload.disk.DiskFileItemFactory;
+import org.apache.commons.io.FileUtils;
+import org.apache.commons.io.IOUtils;
 import org.apache.commons.lang.StringUtils;
 import org.apache.commons.lang.time.DateUtils;
 import org.springblade.business.dto.TrialMaterialMobilizationDTO;

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

@@ -792,6 +792,23 @@ public class ExcelTabController extends BladeController {
                 this.excelTabService.gsColor(pkeyId, process.getPKeyId().toString(), wbsTreeContract.getProjectId(), doc);
             }
             doc.select("Col").remove();
+            org.springblade.manager.entity.TableInfo tableInfo = this.tableInfoService.getOne(Wrappers.<org.springblade.manager.entity.TableInfo>lambdaQuery().select(org.springblade.manager.entity.TableInfo::getId)
+                    .eq(org.springblade.manager.entity.TableInfo::getTabEnName, wbsTreeContract.getInitTableName()).eq(org.springblade.manager.entity.TableInfo::getIsDeleted, 0).last("limit 1"));
+            if (tableInfo != null ) {
+                List<WbsFormElement> list = this.wbsFormElementService.list(Wrappers.<WbsFormElement>lambdaQuery().select(WbsFormElement::getEKey, WbsFormElement::getELength)
+                        .eq(WbsFormElement::getFId, tableInfo.getId()).eq(WbsFormElement::getIsDeleted, 0));
+                if (list != null && !list.isEmpty()) {
+                    Map<String, Integer> keyNameMap = list.stream().collect(Collectors.toMap(WbsFormElement::getEKey, WbsFormElement::getELength));
+                    Elements keyNames = table.getElementsByAttribute("keyname");
+                    keyNames.forEach(element -> {
+                        String key = element.attr("keyname");
+                        Integer length = keyNameMap.get(key.split("__")[0]);
+                        if (length != null) {
+                            element.attr("maxlength", length.toString());
+                        }
+                    });
+                }
+            }
             fileInputStream.close();
             return R.data(table + "");
         } catch (Exception e) {
@@ -1672,7 +1689,7 @@ public class ExcelTabController extends BladeController {
         String tabName = wbsTreeContract.getInitTableName();
         // 字段查询 并去掉公式字段
 
-        String colkeys = "SELECT GROUP_CONCAT(COLUMN_NAME) as colkeys from information_schema.COLUMNS c where c.table_name='" + tabName + "' and COLUMN_NAME not in('id','p_key_id')";
+        String colkeys = "SELECT GROUP_CONCAT(distinct COLUMN_NAME) as colkeys from information_schema.COLUMNS c where c.table_name='" + tabName + "' and COLUMN_NAME not in('id','p_key_id')";
         Map<String, Object> stringObjectMap = jdbcTemplate.queryForMap(colkeys);
         colkeys = stringObjectMap.get("colkeys") + "";
         // 复制表数据

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

@@ -36,9 +36,9 @@ public class TableFileClientImpl implements TableFileClient {
     }
 
     @Override
-    public List<TableFile> getTabFilesByTabIds(String tabFileIds) {
+    public List<TableFile> getTabFilesByTabIds(List<String> tabFileIds) {
         return tableFileService.getBaseMapper().selectList(Wrappers.<TableFile>lambdaQuery()
-                .in(TableFile::getTabId, Func.toLongList(tabFileIds))
+                .in(TableFile::getTabId, tabFileIds)
                 .ne(TableFile::getType, 1) //排除源文件
                 .isNotNull(TableFile::getTabId)
         );

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

@@ -7,6 +7,8 @@ import org.springblade.manager.entity.WbsTreeContract;
 import org.springblade.manager.service.IWbsParamService;
 import org.springframework.web.bind.annotation.RestController;
 
+import java.util.List;
+
 @RestController
 @AllArgsConstructor
 public class WbsParamClientImpl implements WbsParamClient{
@@ -27,4 +29,9 @@ public class WbsParamClientImpl implements WbsParamClient{
     public String createFileTitle(WbsTreeContract contract) {
         return iWbsParamService.createFileTitle(contract);
     }
+
+    @Override
+    public void saveWbsParams(List<WbsParam> wbsParamList) {
+        iWbsParamService.saveBatch(wbsParamList);
+    }
 }

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

@@ -119,6 +119,21 @@ public class TextdictInfoServiceImpl extends ServiceImpl<TextdictInfoMapper, Tex
                             textdict.addAll(collect);
                         }
                     }
+                    List<TextdictInfoVO> textdictList= baseMapper.selectTextdictInfoByExcelId(page, textdictInfo);
+                    if (textdict == null || textdict.isEmpty()) {
+                        textdict = textdictList;
+                    } else if (textdictList != null && !textdictList.isEmpty()) {
+                        Map<String, Map<String, TextdictInfoVO>> map = textdict.stream().collect(Collectors.groupingBy(TextdictInfoVO::getColKey, Collectors.toMap(TextdictInfoVO::getSigRoleId, v -> v, (v1, v2) -> v1)));
+                        List<TextdictInfoVO> collect = textdictList.stream().filter(textdictInfoVO -> {
+                            Map<String, TextdictInfoVO> voMap = map.get(textdictInfoVO.getColKey());
+                            textdictInfoVO.setIsSystem(1);
+                            if (voMap != null && !voMap.isEmpty() ) {
+                                return voMap.get(textdictInfoVO.getSigRoleId()) == null;
+                            }
+                            return true;
+                        }).collect(Collectors.toList());
+                        textdict.addAll(collect);
+                    }
                 }else{
                     textdict = baseMapper.selectTextdictInfoByExcelId(page, textdictInfo);
                 }

+ 3 - 21
blade-service/blade-manager/src/main/java/org/springblade/manager/utils/PdfAddContextUtils.java

@@ -13,11 +13,11 @@ import com.itextpdf.text.pdf.parser.PdfReaderContentParser;
 import com.itextpdf.text.pdf.parser.RenderListener;
 import com.itextpdf.text.pdf.parser.TextRenderInfo;
 import org.apache.poi.ss.usermodel.Cell;
+import org.apache.poi.ss.usermodel.CellType;
 import org.apache.poi.ss.usermodel.Row;
 import  org.apache.poi.ss.usermodel.Sheet;
 
-import java.io.File;
-import java.io.FileInputStream;
+
 import java.io.FileOutputStream;
 import java.io.IOException;
 import java.util.ArrayList;
@@ -27,23 +27,6 @@ public class PdfAddContextUtils {
 
     public static void addContextByTitle(String src, String dest, String title, String context,  int fontSize) throws IOException, DocumentException {
 
-        File pdfFile = new File(src);
-        byte[] pdfData = new byte[(int) pdfFile.length()];
-        FileInputStream inputStream = null;
-        try {
-            inputStream = new FileInputStream(pdfFile);
-            inputStream.read(pdfData);
-        } catch (IOException e) {
-            throw e;
-        } finally {
-            if (inputStream != null) {
-                try {
-                    inputStream.close();
-                } catch (IOException e) {
-                    inputStream.close();
-                }
-            }
-        }
         // 读取PDF文件
         PdfReader reader = new PdfReader(src);
         PdfStamper stamper = new PdfStamper(reader, new FileOutputStream(dest));
@@ -66,14 +49,13 @@ public class PdfAddContextUtils {
     public static String getExcelFullTitle(org.apache.poi.ss.usermodel.Workbook workbook, String title) {
         Sheet sheet = workbook.getSheetAt(0);
         sheet.setForceFormulaRecalculation(true);
-        int rowNum = sheet.getLastRowNum();
         for (int i = 0; i < 6; i++) {
             Row row = sheet.getRow(i);
             if (row != null) {
                 short cellNum = row.getLastCellNum();
                 for (int j = 0; j < cellNum; j++) {
                     Cell cell = row.getCell(j);
-                    if (cell != null) {
+                    if (cell != null && cell.getCellTypeEnum() == CellType.STRING) {
                         String cellValue = cell.getStringCellValue();
                         if (cellValue != null && !cellValue.isEmpty()) {
                             if (containsAllCharactersInOrder(cellValue, title)) {

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

@@ -6,14 +6,19 @@ import io.swagger.annotations.Api;
 import io.swagger.annotations.ApiOperation;
 import lombok.AllArgsConstructor;
 import org.apache.commons.lang.SystemUtils;
+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.common.utils.SnowFlakeUtil;
 import org.springblade.core.oss.model.BladeFile;
+import org.springblade.core.tool.utils.FileUtil;
+import org.springblade.core.tool.utils.IoUtil;
 import org.springblade.core.tool.utils.ObjectUtil;
-import org.springblade.manager.entity.ExcelTab;
-import org.springblade.manager.entity.WbsTreeContract;
-import org.springblade.manager.entity.WbsTreePrivate;
+import org.springblade.core.tool.utils.StringUtil;
+import org.springblade.manager.entity.*;
 import org.springblade.repair.util.ExcelInfoUtils;
 import org.springblade.repair.util.FileUtils;
 import org.springblade.resource.feign.NewIOSSClient;
@@ -21,19 +26,19 @@ import org.springblade.system.cache.ParamCache;
 import org.springframework.jdbc.core.BeanPropertyRowMapper;
 import org.springframework.jdbc.core.JdbcTemplate;
 import org.springframework.scheduling.annotation.Scheduled;
+import org.springframework.transaction.support.TransactionTemplate;
 import org.springframework.web.bind.annotation.GetMapping;
 import org.springframework.web.bind.annotation.RequestMapping;
 import org.springframework.web.bind.annotation.RestController;
 import org.springblade.manager.feign.ExcelTabClient;
 
+import javax.validation.constraints.NotNull;
 import java.io.*;
 import java.nio.file.Files;
 import java.nio.file.Path;
 import java.nio.file.Paths;
 import java.nio.file.StandardCopyOption;
-import java.util.List;
-import java.util.Map;
-import java.util.Set;
+import java.util.*;
 import java.util.stream.Collectors;
 
 
@@ -418,4 +423,261 @@ public class CheckAndRepairController {
         }
         System.out.println("检查完毕,更新了"+i+"条记录");
     }
+
+
+    private final TransactionTemplate transactionTemplate;
+    @RequestMapping("/checkAndRepairExcelHtmlDefaultValue")
+    @ApiOperation("定时检测修复ExcelHtml")
+    @Scheduled(cron = "00 00 01 * * ?")
+    public void checkAndRepairExcelHtmlDefaultValue() {
+//        String projectSql = "SELECT * from m_project_info WHERE is_deleted = 0 and id != 1904814720589430785";
+        String projectSql = "SELECT * from m_project_info WHERE is_deleted = 0 and id = 1630011899725201410";
+        List<ProjectInfo> projectInfos = jdbcTemplate.query(projectSql, new BeanPropertyRowMapper<>(ProjectInfo.class));
+        projectInfos.forEach(projectInfo -> {
+            String sql = "SELECT html_url from m_wbs_tree_private WHERE html_url is not null and html_url != '' and is_deleted = 0 and project_id = ? group by html_url LIMIT ? offset ?;";
+            long pageSize = 2000L;
+            long offset = 0L;
+            boolean flag = true;
+            while (flag) {
+                List<String> htmlUrls = jdbcTemplate.queryForList(sql, String.class,projectInfo.getId(), pageSize, offset);
+                if (!htmlUrls.isEmpty()) {
+                    for (String htmlUrl : htmlUrls) {
+                        try  {
+                            List<TextdictInfo> textDictInfoDefaultByHtml = new ArrayList<>();
+                            List<TextdictInfo> textDictInfoTipsByHtml = new ArrayList<>();
+                            // 获取html中的 默认值信息和提示信息
+                            getTextDictInfos(htmlUrl, textDictInfoTipsByHtml, textDictInfoDefaultByHtml);
+                            List<WbsTreePrivate> wbsTreePrivates = jdbcTemplate.query("SELECT * from m_wbs_tree_private WHERE is_deleted = 0 and project_id = ? and html_url = ?", new BeanPropertyRowMapper<>(WbsTreePrivate.class),
+                                    projectInfo.getId(), htmlUrl);
+                            // 获取表元素信息
+                            Map<String, Map<String, String>> tableElementInfo = getTableElementInfo(wbsTreePrivates);
+                            for (WbsTreePrivate wbsTreePrivate : wbsTreePrivates) {
+                                List<TextdictInfo> textDictInfoList = jdbcTemplate.query("SELECT * from m_textdict_info WHERE type in (4,5) and is_deleted = 0 and tab_id = " + wbsTreePrivate.getPKeyId() + " and project_id = " + wbsTreePrivate.getProjectId(),
+                                        new BeanPropertyRowMapper<>(TextdictInfo.class));
+                                Map<String, String> map = tableElementInfo.get(wbsTreePrivate.getInitTableName());
+                                Map<String, TextdictInfo> insertTextDictInfoMaps = new HashMap<>();
+                                List<TextdictInfo> updateHtmlTextDictInfos = new ArrayList<>();
+                                if (textDictInfoList.isEmpty()) {
+                                    createTextDictInfos(wbsTreePrivate, textDictInfoTipsByHtml, map, insertTextDictInfoMaps, 5, "提示信息");
+                                    createTextDictInfos(wbsTreePrivate, textDictInfoDefaultByHtml, map, insertTextDictInfoMaps, 4, "默认值");
+                                } else {
+                                    // 去重并保留id最大的
+                                    Map<String, TextdictInfo> tempMap = new HashMap<>();
+                                    textDictInfoList.forEach(info -> {
+                                        if (info.getColKey() == null || info.getColKey().isEmpty()) {
+                                            return;
+                                        }
+                                        TextdictInfo temp = tempMap.get(info.getColKey() + "_" + info.getType());
+                                        if (temp == null || info.getId() > temp.getId()) {
+                                            tempMap.put(info.getColKey() + "_" + info.getType(), info);
+                                        }
+                                    });
+                                    // 与html中的进行对比, 保留数据库中的值
+                                    textDictInfoDefaultByHtml.forEach(info -> {
+                                        TextdictInfo temp = tempMap.get(info.getColKey() + "_" + info.getType());
+                                        if (temp != null) {
+                                            if (!temp.getSigRoleName().equals(info.getSigRoleName())) {
+                                                // 更新html中的值
+                                                temp.setColName(info.getColName());
+                                                info.setSigRoleName(temp.getSigRoleName());
+                                                updateHtmlTextDictInfos.add(temp);
+                                            }
+                                            tempMap.remove(info.getColKey() + "_" + info.getType());
+                                        }
+                                        TextdictInfo textdictInfo = createTextDictInfo(wbsTreePrivate, map, 4, "默认值", info);
+                                        insertTextDictInfoMaps.put(textdictInfo.getColKey() + "_" + textdictInfo.getType(), textdictInfo);
+                                    });
+                                    textDictInfoTipsByHtml.forEach(info -> {
+                                        TextdictInfo temp = tempMap.get(info.getColKey() + "_" + info.getType());
+                                        if (temp != null) {
+                                            if (!temp.getSigRoleName().equals(info.getSigRoleName())) {
+                                                // 更新html中的值
+                                                temp.setColName(info.getColName());
+                                                info.setSigRoleName(temp.getSigRoleName());
+                                                updateHtmlTextDictInfos.add(temp);
+                                            }
+                                            tempMap.remove(info.getColKey() + "_" + info.getType());
+                                        }
+                                        TextdictInfo textdictInfo = createTextDictInfo(wbsTreePrivate, map, 5, "提示信息", info);
+                                        insertTextDictInfoMaps.put(textdictInfo.getColKey() + "_" + textdictInfo.getType(), textdictInfo);
+                                    });
+                                    if (!tempMap.isEmpty()) {
+                                        tempMap.forEach((key, value) -> {
+                                            if (value.getType() == 4) {
+                                                TextdictInfo textdictInfo = createTextDictInfo(wbsTreePrivate, map, 4, "默认值", value);
+                                                insertTextDictInfoMaps.put(textdictInfo.getColKey() + "_" + textdictInfo.getType(), textdictInfo);
+                                            } else if (value.getType() == 5) {
+                                                TextdictInfo textdictInfo = createTextDictInfo(wbsTreePrivate, map, 5, "提示信息", value);
+                                                insertTextDictInfoMaps.put(textdictInfo.getColKey() + "_" + textdictInfo.getType(), textdictInfo);
+                                            }
+                                            updateHtmlTextDictInfos.add(value);
+                                        });
+                                    }
+                                }
+                                String replace;
+                                if (!updateHtmlTextDictInfos.isEmpty()) {
+                                    InputStream fileInputStream = FileUtils.getInputStreamByUrl(wbsTreePrivate.getHtmlUrl());
+                                    String htmlString = IoUtil.readToString(fileInputStream);
+                                    Document doc = Jsoup.parse(htmlString);
+                                    updateHtmlTextDictInfos.forEach(textdictInfo -> {
+                                        Element element = doc.getElementById(textdictInfo.getColKey());
+                                        if (element != null) {
+                                            element.attr("placeholder", textdictInfo.getColName());
+                                            if (textdictInfo.getType() == 4) {
+                                                element.attr("defText", textdictInfo.getSigRoleName());
+                                            } else if (textdictInfo.getType() == 5) {
+                                                Element parent = element.parent();
+                                                // 判断 parent 是否是el-tooltip
+                                                if (parent.tagName().equals("el-tooltip")) {
+                                                    parent.attr("content", textdictInfo.getSigRoleName());
+                                                } else {
+                                                    String lastHtml = " <el-tooltip content='" + textdictInfo.getSigRoleName() + "' placement='top' effect='customized'>" + parent.html() + "</el-tooltip>";
+                                                    parent.empty().append(lastHtml);
+                                                }
+                                            }
+                                        }
+                                    });
+                                    String url = wbsTreePrivate.getHtmlUrl();
+                                    File writeFile = new File(url);
+                                    FileUtil.writeToFile(writeFile, doc.html(), Boolean.parseBoolean("UTF-8"));
+                                    String str1 = url.replace("Desktop//privateUrl", "Desktop/privateUrl");
+                                    replace = str1.replace("\\", "\\\\");
+                                } else {
+                                    replace = null;
+                                }
+                                transactionTemplate.execute( status -> {
+                                    if (!insertTextDictInfoMaps.isEmpty()) {
+                                        // 使用jdbcTemplate批量插入
+                                        jdbcTemplate.batchUpdate("insert into m_textdict_info_copy3 (id,name,type,tab_id,col_key,col_name,sig_role_id,sig_role_name,pyzbx,pyzby,excel_id,project_id,is_deleted,time_col_key,time_name,time_state) values (?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?)",
+                                                insertTextDictInfoMaps.values(),
+                                                insertTextDictInfoMaps.values().size(), (ps, textdictInfo) -> {
+                                                    ps.setLong(1, textdictInfo.getId());
+                                                    ps.setString(2, textdictInfo.getName());
+                                                    ps.setInt(3, textdictInfo.getType());
+                                                    ps.setString(4, textdictInfo.getTabId());
+                                                    ps.setString(5, textdictInfo.getColKey());
+                                                    ps.setString(6, textdictInfo.getColName());
+                                                    ps.setString(7, textdictInfo.getSigRoleId());
+                                                    ps.setString(8, textdictInfo.getSigRoleName());
+                                                    ps.setDouble(9, 0);
+                                                    ps.setDouble(10, 0);
+                                                    ps.setString(11, textdictInfo.getExcelId());
+                                                    ps.setString(12, textdictInfo.getProjectId());
+                                                    ps.setInt(13, 0);
+                                                    ps.setString(14, textdictInfo.getTimeColKey());
+                                                    ps.setString(15, textdictInfo.getTimeName());
+                                                    ps.setInt(16, 0);
+                                                }
+                                        );
+                                    }
+                                    if (replace != null) {
+                                        String updateSqlP = "update m_wbs_tree_private_copy6 set html_url = '" + replace + "' where p_key_id = " + wbsTreePrivate.getPKeyId() + " and project_id = " + wbsTreePrivate.getProjectId();
+                                        jdbcTemplate.execute(updateSqlP);
+                                    }
+                                    if (!textDictInfoList.isEmpty()) {
+                                        List<Long> ids = textDictInfoList.stream().map(TextdictInfo::getId).collect(Collectors.toList());
+                                        jdbcTemplate.execute("update  m_textdict_info_copy3 set is_deleted = 2 where  id in (" + StringUtil.join(ids, ",") + ")");
+                                    }
+                                    return true;
+                                });
+                            }
+                        } catch (Exception e) {
+                            e.printStackTrace();
+                        }
+                    }
+                } else {
+                    flag = false;
+                }
+                offset  += pageSize;
+            }
+        });
+    }
+    private static void createTextDictInfos(WbsTreePrivate wbsTreePrivate, List<TextdictInfo> textDictInfos, Map<String, String> map, Map<String, TextdictInfo> insertTextDictInfoMaps, int type, String name) {
+        if (!textDictInfos.isEmpty()) {
+            for (TextdictInfo textdictInfo : textDictInfos) {
+                TextdictInfo saveTextdictInfo = createTextDictInfo(wbsTreePrivate, map, type, name, textdictInfo);
+                insertTextDictInfoMaps.put(saveTextdictInfo.getColKey() + "_" + saveTextdictInfo.getType(), saveTextdictInfo);
+            }
+        }
+    }
+    @NotNull
+    private static TextdictInfo createTextDictInfo(WbsTreePrivate wbsTreePrivate, Map<String, String> map, int type, String name, TextdictInfo textdictInfo) {
+        TextdictInfo saveTextdictInfo = new TextdictInfo();
+        saveTextdictInfo.setColKey(textdictInfo.getColKey());
+        saveTextdictInfo.setColName(textdictInfo.getColName());
+        saveTextdictInfo.setSigRoleName(textdictInfo.getSigRoleName());
+        saveTextdictInfo.setId(SnowFlakeUtil.getId());
+        saveTextdictInfo.setTabId(wbsTreePrivate.getPKeyId() + "");
+        saveTextdictInfo.setType(type);
+        saveTextdictInfo.setName(name);
+        saveTextdictInfo.setExcelId(wbsTreePrivate.getExcelId() + "");
+        saveTextdictInfo.setProjectId(wbsTreePrivate.getProjectId());
+        if (map != null) {
+            String s = map.get(saveTextdictInfo.getColKey().split("__")[0]);
+            if (s != null && !s.trim().isEmpty()) {
+                saveTextdictInfo.setColName(s);
+            }
+        }
+        return saveTextdictInfo;
+    }
+    private Map<String, Map<String, String>> getTableElementInfo(List<WbsTreePrivate> wbsTreePrivates) {
+        String inSql = wbsTreePrivates.stream().map(e -> "'" + e.getInitTableName() + "'").distinct().collect(Collectors.joining(","));
+        List<TableInfo> tableInfos = jdbcTemplate.query("SELECT id, tab_en_name from m_table_info  where tab_en_name in (" + inSql + ")", new BeanPropertyRowMapper<>(TableInfo.class));
+        if (tableInfos.isEmpty()) {
+            return new HashMap<>();
+        }
+        Map<String, String> map = tableInfos.stream().collect(Collectors.toMap(tableInfo -> tableInfo.getId() + "", TableInfo::getTabEnName));
+        List<WbsFormElement> wbsFormElementList = jdbcTemplate.query("SELECT f_id,e_key,e_name from m_wbs_form_element WHERE f_id in (" + StringUtil.join(map.keySet(), ",") + ")", new BeanPropertyRowMapper<>(WbsFormElement.class));
+        // 将 initTableNames 与 wbsFormElementList 关联
+        return wbsFormElementList.stream().peek(item -> item.setFId(map.get(item.getFId())))
+                .collect(Collectors.groupingBy(WbsFormElement::getFId, Collectors.toMap(WbsFormElement::getEKey, WbsFormElement::getEName, (v1, v2) -> v1)));
+    }
+    private static void getTextDictInfos(String htmlUrl, List<TextdictInfo> textDictInfoTips, List<TextdictInfo> textDictInfoDefault) throws Exception {
+        InputStream fileInputStream = FileUtils.getInputStreamByUrl(htmlUrl);
+        String htmlString = IoUtil.readToString(fileInputStream);
+        Document doc = Jsoup.parse(htmlString);
+        Element table = doc.select("table").first();
+        Elements trs = table.select("tr");
+        trs.forEach(tr -> {
+            Elements td = tr.select("td");
+            for (Element element : td) {
+                Elements tooltips = element.select("el-tooltip");
+                getTextDictInfo(tooltips, "content", textDictInfoTips);
+                Elements inputs = element.select("el-input");
+                getTextDictInfo(inputs, "deftext", textDictInfoDefault);
+            }
+        });
+    }
+    private static void getTextDictInfo(Elements elements, String attrName, List<TextdictInfo> textDictInfos) {
+        if (!elements.isEmpty()) {
+            elements.forEach(element -> {
+                String content = element.attr(attrName);
+                if (content != null && !content.trim().isEmpty()) {
+                    String keyname = element.children().attr("keyname");
+                    String placeholder = element.children().attr("placeholder");
+                    if (keyname == null || !keyname.trim().isEmpty()) {
+                        String html = element.html();
+                        keyname = getHtmlAttrValue(html, "keyname");
+                        placeholder = getHtmlAttrValue(html, "placeholder");
+                    }
+                    if (keyname != null) {
+                        TextdictInfo info = new TextdictInfo();
+                        info.setColKey(keyname);
+                        info.setColName(placeholder);
+                        info.setSigRoleName(content);
+                        textDictInfos.add(info);
+                    }
+                }
+            });
+        }
+    }
+    private static String getHtmlAttrValue(String html, String attr) {
+        int index = html.indexOf(attr);
+        if (index > 0) {
+            int start = attr.length() + index + 1;
+            char c = html.charAt(start);
+            return html.substring(start + 1, html.indexOf(c, start + 1));
+        }
+        return null;
+    }
 }

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

@@ -792,7 +792,7 @@ public class UserServiceImpl extends BaseServiceImpl<UserMapper, User> implement
                         long startTime = System.currentTimeMillis();
 //                        List<NodeVO> nodeVOList = distinctNodesAll.stream().map(this::convertToNodeVO).collect(Collectors.toList());
 //                        Map<Long, NodeVO> nodeVOMap = nodeVOList.stream().collect(Collectors.toMap(NodeVO::getId, vo -> vo, (existing, replacement) -> existing));
-                        List<NodeVO> treeNodeVOList = this.buildNodeTreeByStream(distinctNodesAll, lowestNodesMap);
+                        List<NodeVO> treeNodeVOList = this.buildNodeTreeByStream1(distinctNodesAll, lowestNodesMap);
 //                        NodeVO.calculateStatusToDFS(treeNodeVOList, nodeVOMap);
                         Map<Long, Integer> nodeColorStatusMap = new HashMap<>();
                         NodeVO.calculateStatusToDFS1(treeNodeVOList, nodeColorStatusMap);
@@ -935,7 +935,7 @@ public class UserServiceImpl extends BaseServiceImpl<UserMapper, User> implement
 
 //                                List<NodeVO> nodeVOList = distinctNodesAll.stream().map(this::convertToNodeVO).collect(Collectors.toList());
 //                                Map<Long, NodeVO> nodeVOMap = nodeVOList.stream().collect(Collectors.toMap(NodeVO::getId, vo -> vo, (existing, replacement) -> existing));
-                                List<NodeVO> treeNodeVOList = this.buildNodeTreeByStream(distinctNodesAll, lowestNodesMap);
+                                List<NodeVO> treeNodeVOList = this.buildNodeTreeByStream1(distinctNodesAll, lowestNodesMap);
 //                                NodeVO.calculateStatusToDFS(treeNodeVOList, nodeVOMap);
 //                                List<NodeVO> nodeVOS = this.flattenTree(treeNodeVOList);
 //                                Map<Long, Integer> nodeColorStatusMap = nodeVOS.stream().collect(Collectors.toMap(NodeVO::getPKeyId, NodeVO::getStatus, (existing, replacement) -> existing));
@@ -1512,7 +1512,7 @@ public class UserServiceImpl extends BaseServiceImpl<UserMapper, User> implement
                 })
                 .collect(Collectors.toList());
         List<Long> collect = collectedNodes.stream()
-                .map(WbsTreeContractLazyVO::getParentId).filter(Objects::nonNull).distinct()
+                .map(WbsTreeContractLazyVO::getParentId).filter(Objects::nonNull)
                 .collect(Collectors.toList());
         if (!collect.isEmpty()) {
             result.addAll(collectedNodes);
@@ -1575,6 +1575,51 @@ public class UserServiceImpl extends BaseServiceImpl<UserMapper, User> implement
         return result;
     }
 
+    /**
+     * 构造树形结构数据 (解决节点颜色问题)
+     *
+     * @param distinctNodesAll 去重后所有节点数据
+     * @return
+     */
+    public List<NodeVO> buildNodeTreeByStream1(List<WbsTreeContractLazyVO> distinctNodesAll,
+                                              Map<Long, WbsTreeContractLazyVO> lowestNodesMap) {
+        List<WbsTreeContractLazyVO> list = distinctNodesAll.stream().filter(f->f.getParentId()!=null).filter(f -> f.getParentId().equals(0L)).collect(Collectors.toList());
+        Map<Long, List<WbsTreeContractLazyVO>> map = distinctNodesAll.stream().filter(f->f.getParentId()!=null).collect(Collectors.groupingBy(WbsTreeContractLazyVO::getParentId));
+        Map<Long, NodeVO> nodeVOMap = new HashMap<>();
+        return recursionFnNodeTree(list, map, lowestNodesMap,nodeVOMap);
+    }
+
+    public List<NodeVO> recursionFnNodeTree
+            (List<WbsTreeContractLazyVO> list, Map<Long, List<WbsTreeContractLazyVO>> map,
+             Map<Long, WbsTreeContractLazyVO> lowestNodesMap, Map<Long, NodeVO> nodeVOMap) {
+        List<NodeVO> result = new ArrayList<>();
+        for (WbsTreeContractLazyVO vo : list) {
+            if (vo.getHasChildren().equals(0)) {
+                WbsTreeContractLazyVO lowestNodeVO = lowestNodesMap.getOrDefault(vo.getPKeyId(), null);
+                if (lowestNodeVO != null && lowestNodeVO.getColorStatus() != null) {
+                    //最底层颜色初始化
+                    vo.setColorStatus(lowestNodeVO.getColorStatus());
+                }
+            } else {
+                //非最底层节点,颜色默认=1黑色
+                vo.setColorStatus(1);
+            }
+            //转换为NodeVO
+            NodeVO nodeVO = convertToNodeVO(vo);
+            nodeVOMap.put(nodeVO.getPKeyId(), nodeVO);
+            List<WbsTreeContractLazyVO> childrenList = map.get(vo.getId());
+            if (childrenList != null && !childrenList.isEmpty()) {
+                List<WbsTreeContractLazyVO> collect = childrenList.stream().filter(child -> !nodeVOMap.containsKey(child.getPKeyId()))
+                        .collect(Collectors.toList());
+                if (!collect.isEmpty()) {
+                    nodeVO.setChildren(recursionFnNodeTree(collect, map, lowestNodesMap, nodeVOMap));
+                }
+            }
+            result.add(nodeVO);
+        }
+        return result;
+    }
+
     /**
      * 树形层级结构转为普通List
      *