浏览代码

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

“zhifk” 2 年之前
父节点
当前提交
65b77108d1
共有 45 个文件被更改,包括 1166 次插入352 次删除
  1. 3 0
      blade-service-api/blade-manager-api/src/main/java/org/springblade/manager/dto/FormulaBean.java
  2. 10 2
      blade-service-api/blade-manager-api/src/main/java/org/springblade/manager/dto/FormulaOption.java
  3. 0 1
      blade-service-api/blade-manager-api/src/main/java/org/springblade/manager/dto/WbsTreeContractDTO.java
  4. 38 1
      blade-service-api/blade-manager-api/src/main/java/org/springblade/manager/entity/ArchiveTree.java
  5. 8 1
      blade-service-api/blade-manager-api/src/main/java/org/springblade/manager/entity/ArchiveTreeContract.java
  6. 2 1
      blade-service-api/blade-manager-api/src/main/java/org/springblade/manager/feign/ArchiveTreeClient.java
  7. 7 0
      blade-service-api/blade-manager-api/src/main/java/org/springblade/manager/vo/ArchiveTreeVO2.java
  8. 11 0
      blade-service-api/blade-manager-api/src/main/java/org/springblade/manager/vo/WbsTreeVO2.java
  9. 5 4
      blade-service/blade-business/src/main/java/org/springblade/business/controller/ArchiveFileController.java
  10. 9 7
      blade-service/blade-business/src/main/java/org/springblade/business/controller/ImageClassificationFileController.java
  11. 27 12
      blade-service/blade-business/src/main/java/org/springblade/business/controller/InformationWriteQueryController.java
  12. 2 1
      blade-service/blade-business/src/main/java/org/springblade/business/controller/TaskController.java
  13. 4 0
      blade-service/blade-business/src/main/java/org/springblade/business/mapper/InformationQueryMapper.java
  14. 41 0
      blade-service/blade-business/src/main/java/org/springblade/business/mapper/InformationQueryMapper.xml
  15. 1 1
      blade-service/blade-business/src/main/java/org/springblade/business/service/impl/InformationQueryServiceImpl.java
  16. 0 1
      blade-service/blade-business/src/main/java/org/springblade/business/socket/WebSocket.java
  17. 1 2
      blade-service/blade-business/src/main/java/org/springblade/business/socket/WebSocketManager.java
  18. 26 0
      blade-service/blade-manager/src/main/java/com/mixsmart/utils/CustomFunction.java
  19. 2 1
      blade-service/blade-manager/src/main/java/org/springblade/manager/controller/ArchiveTreeContractController.java
  20. 26 11
      blade-service/blade-manager/src/main/java/org/springblade/manager/controller/ArchiveTreeController.java
  21. 74 32
      blade-service/blade-manager/src/main/java/org/springblade/manager/controller/FormulaController.java
  22. 38 22
      blade-service/blade-manager/src/main/java/org/springblade/manager/controller/TextdictInfoController.java
  23. 7 0
      blade-service/blade-manager/src/main/java/org/springblade/manager/controller/WbsFormElementController.java
  24. 22 2
      blade-service/blade-manager/src/main/java/org/springblade/manager/controller/WbsTreePrivateController.java
  25. 3 2
      blade-service/blade-manager/src/main/java/org/springblade/manager/feign/ArchiveTreeClientImpl.java
  26. 2 1
      blade-service/blade-manager/src/main/java/org/springblade/manager/feign/WbsTreeContractClientImpl.java
  27. 11 3
      blade-service/blade-manager/src/main/java/org/springblade/manager/mapper/ArchiveTreeContractMapper.java
  28. 6 0
      blade-service/blade-manager/src/main/java/org/springblade/manager/mapper/ArchiveTreeContractMapper.xml
  29. 4 2
      blade-service/blade-manager/src/main/java/org/springblade/manager/mapper/ArchiveTreeMapper.java
  30. 11 3
      blade-service/blade-manager/src/main/java/org/springblade/manager/mapper/ArchiveTreeMapper.xml
  31. 2 0
      blade-service/blade-manager/src/main/java/org/springblade/manager/mapper/WbsTreeMapper.xml
  32. 2 1
      blade-service/blade-manager/src/main/java/org/springblade/manager/mapper/WbsTreePrivateMapper.java
  33. 35 0
      blade-service/blade-manager/src/main/java/org/springblade/manager/mapper/WbsTreePrivateMapper.xml
  34. 2 3
      blade-service/blade-manager/src/main/java/org/springblade/manager/service/IArchiveTreeContractService.java
  35. 7 5
      blade-service/blade-manager/src/main/java/org/springblade/manager/service/IArchiveTreeService.java
  36. 6 0
      blade-service/blade-manager/src/main/java/org/springblade/manager/service/IWbsTreePrivateService.java
  37. 16 38
      blade-service/blade-manager/src/main/java/org/springblade/manager/service/impl/ArTreeContractInitServiceImpl.java
  38. 28 93
      blade-service/blade-manager/src/main/java/org/springblade/manager/service/impl/ArchiveTreeContractServiceImpl.java
  39. 238 28
      blade-service/blade-manager/src/main/java/org/springblade/manager/service/impl/ArchiveTreeServiceImpl.java
  40. 11 6
      blade-service/blade-manager/src/main/java/org/springblade/manager/service/impl/FormulaServiceImpl.java
  41. 169 3
      blade-service/blade-manager/src/main/java/org/springblade/manager/service/impl/WbsTreePrivateServiceImpl.java
  42. 11 61
      blade-service/blade-manager/src/main/java/org/springblade/manager/service/impl/WbsTreeServiceImpl.java
  43. 46 0
      blade-service/blade-manager/src/main/java/org/springblade/manager/utils/AsyncConfigurer.java
  44. 1 1
      blade-service/blade-manager/src/main/java/org/springblade/manager/utils/ForestNodeMerger.java
  45. 191 0
      blade-service/blade-manager/src/main/java/org/springblade/manager/utils/ThreadPoolMonitor.java

+ 3 - 0
blade-service-api/blade-manager-api/src/main/java/org/springblade/manager/dto/FormulaBean.java

@@ -4,6 +4,8 @@ import lombok.Data;
 import org.springblade.manager.entity.Formula;
 import org.springframework.beans.BeanUtils;
 
+import java.util.Map;
+
 /**
  * @author yangyj
  * @Date 2022/6/14 16:27
@@ -37,6 +39,7 @@ public class FormulaBean {
     private Long projectId;
     private String dev;
     private Integer ver;
+    private Map<String,Object> dict;
     public Formula toFormula(){
         Formula f= new Formula();
         BeanUtils.copyProperties(this,f);

+ 10 - 2
blade-service-api/blade-manager-api/src/main/java/org/springblade/manager/dto/FormulaOption.java

@@ -9,7 +9,15 @@ import lombok.Data;
  */
 @Data
 public class FormulaOption {
+    private Long id;
+    private Long parentId;
+    private String ekey;
+    private Long contractId;
+    private String value;
     private Long pKeyId;
-    private Integer value;
-    private String key;
+    private Integer scope;
+
+    public String toSql(){
+        return ","+parentId+",'"+ekey+"',"+contractId+",'"+value+"',"+pKeyId+","+scope;
+    }
 }

+ 0 - 1
blade-service-api/blade-manager-api/src/main/java/org/springblade/manager/dto/WbsTreeContractDTO.java

@@ -1,6 +1,5 @@
 package org.springblade.manager.dto;
 
-import com.baomidou.mybatisplus.annotation.TableName;
 import com.fasterxml.jackson.annotation.JsonProperty;
 import io.swagger.annotations.ApiModelProperty;
 import lombok.AllArgsConstructor;

+ 38 - 1
blade-service-api/blade-manager-api/src/main/java/org/springblade/manager/entity/ArchiveTree.java

@@ -5,6 +5,9 @@ import io.swagger.annotations.ApiModelProperty;
 import lombok.Data;
 import lombok.EqualsAndHashCode;
 import org.springblade.core.mp.base.BaseEntity;
+import org.springblade.manager.vo.ArchiveTreeVO2;
+import org.springframework.beans.BeanUtils;
+import org.springframework.beans.BeansException;
 
 @Data
 @TableName("m_archive_tree")
@@ -19,6 +22,9 @@ public class ArchiveTree extends BaseEntity {
     @ApiModelProperty(value = "租户id")
     private String tenantId;
 
+    @ApiModelProperty(value = "项目id,0为系统")
+    private Long projectId;
+
     /**
      * 父主键
      */
@@ -156,11 +162,42 @@ public class ArchiveTree extends BaseEntity {
     @ApiModelProperty(value = "是否为设置的节点")
     private Integer archiveAutoGroupSelect;
 
+    private Long fromId;
+
     /**
      * 试验资料类型
      */
     @ApiModelProperty(value = "试验资料类型,‘使用逗号拼接’")
     private String expDataType;
 
-
+    public ArchiveTree() {
+    }
+
+    public ArchiveTree(ArchiveTreeVO2 archiveTree) {
+        if (archiveTree == null) {
+            return;
+        }
+
+        try {
+            BeanUtils.copyProperties(archiveTree,this);
+            this.nodeName = archiveTree.getTitle();
+            this.isUploadFileDisplayConfigurationTree = archiveTree.getIsDisplayTree();
+            this.fromId = archiveTree.getId();
+        } catch (BeansException e) {
+            e.printStackTrace();
+        }
+    }
+
+    public ArchiveTree(ArchiveTree archiveTree) {
+        if (archiveTree == null) {
+            return;
+        }
+
+        try {
+            BeanUtils.copyProperties(archiveTree,this);
+            this.fromId = archiveTree.getId();
+        } catch (BeansException e) {
+            e.printStackTrace();
+        }
+    }
 }

+ 8 - 1
blade-service-api/blade-manager-api/src/main/java/org/springblade/manager/entity/ArchiveTreeContract.java

@@ -155,8 +155,11 @@ public class ArchiveTreeContract extends BaseEntity {
 	 */
 	private Integer archiveAutoGroupSelect;
 
+//
+//	//系统级模板Id
+//	private Long originId;
 	/**
-	 * 来源id,用于后续同步更新
+	 * 来源id,项目级,用于后续同步更新
 	 */
 	private Long fromId;
 	/**
@@ -169,6 +172,10 @@ public class ArchiveTreeContract extends BaseEntity {
 	 */
 	private String expDataType;
 
+	//权限编码
+	private String treeCode;
+
+
 
 	public ArchiveTreeContract() {
 	}

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

@@ -3,6 +3,7 @@ package org.springblade.manager.feign;
 import org.springblade.core.tool.api.R;
 import org.springblade.manager.entity.ArchiveTree;
 import org.springblade.manager.vo.ArchiveTreeVO;
+import org.springblade.manager.vo.ArchiveTreeVO2;
 import org.springframework.cloud.openfeign.FeignClient;
 import org.springframework.web.bind.annotation.GetMapping;
 import org.springframework.web.bind.annotation.PostMapping;
@@ -30,6 +31,6 @@ public interface ArchiveTreeClient {
      * 获取归档树映射
      */
     @GetMapping(API_PREFIX + "/tree")
-    R<List<ArchiveTreeVO>> tree(@RequestParam Integer disPlayTree, @RequestParam Integer nodeType);
+    R<List<ArchiveTreeVO2>> tree(@RequestParam Long projectId, @RequestParam Integer disPlayTree, @RequestParam Integer nodeType);
 
 }

+ 7 - 0
blade-service-api/blade-manager-api/src/main/java/org/springblade/manager/vo/ArchiveTreeVO2.java

@@ -22,6 +22,13 @@ public class ArchiveTreeVO2 implements INode<ArchiveTreeVO2> {
     @ApiModelProperty(value = "主键id")
     private Long id;
 
+    /**
+     * 父节点ID
+     */
+    @JsonSerialize(using = ToStringSerializer.class)
+    @ApiModelProperty(value = "项目id,0为系统级")
+    private Long projectId;
+
     /**
      * 父节点ID
      */

+ 11 - 0
blade-service-api/blade-manager-api/src/main/java/org/springblade/manager/vo/WbsTreeVO2.java

@@ -43,8 +43,11 @@ public class WbsTreeVO2 implements INode<WbsTreeVO2> {
 
     private Integer isExistForm;
 
+    private Integer majorDataType;
+
     private String ancestors;
 
+
     @JsonInclude(JsonInclude.Include.NON_EMPTY)
     private Boolean hasChildren;
 
@@ -136,6 +139,14 @@ public class WbsTreeVO2 implements INode<WbsTreeVO2> {
         this.value = value;
     }
 
+    public Integer getMajorDataType() {
+        return majorDataType;
+    }
+
+    public void setMajorDataType(Integer majorDataType) {
+        this.majorDataType = majorDataType;
+    }
+
 
     public String toString() {
         return "TreeNode(nodeType=" + this.getNodeType()

+ 5 - 4
blade-service/blade-business/src/main/java/org/springblade/business/controller/ArchiveFileController.java

@@ -38,6 +38,7 @@ import org.springblade.manager.feign.ArchiveTreeClient;
 import org.springblade.manager.feign.ContractClient;
 import org.springblade.manager.feign.ProjectClient;
 import org.springblade.manager.vo.ArchiveTreeVO;
+import org.springblade.manager.vo.ArchiveTreeVO2;
 import org.springblade.system.entity.Role;
 import org.springblade.system.feign.ISysClient;
 import org.springframework.beans.BeanUtils;
@@ -363,7 +364,7 @@ public class ArchiveFileController extends BladeController {
 	@PostMapping("/tree")
 	@ApiOperationSupport(order = 2)
 	@ApiOperation(value = "获取归档划分树")
-	public R<List<ArchiveTreeVO>> tree(@RequestParam String contractId){
+	public R<List<ArchiveTreeVO2>> tree(@RequestParam String contractId){
 		//查询合同段信息
 		ContractInfo contractInfo = this.contractClient.getContractById(Long.parseLong(contractId));
 		String roleName;
@@ -379,16 +380,16 @@ public class ArchiveFileController extends BladeController {
 				break;
 		}
 		//获取归档树
-		List<ArchiveTreeVO> result = this.archiveTreeClient.tree(1,2).getData();
+		List<ArchiveTreeVO2> result = this.archiveTreeClient.tree(Long.parseLong(contractInfo.getPId()), 1,2).getData();
 
 		String finalRoleName = roleName;
 		result.forEach(archiveTreeVO -> {
 			if("0".equals(archiveTreeVO.getParentId().toString())){
 				//根节点,获取子级判断合同段权限
 				if(archiveTreeVO.getChildren() != null && archiveTreeVO.getChildren().size() > 0){
-					Iterator<ArchiveTreeVO> iterator = archiveTreeVO.getChildren().iterator();
+					Iterator<ArchiveTreeVO2> iterator = archiveTreeVO.getChildren().iterator();
 					while (iterator.hasNext()){
-						ArchiveTreeVO next = iterator.next();
+						ArchiveTreeVO2 next = iterator.next();
 						if(StringUtils.isNotEmpty(next.getPostType())){
 							Role role = this.sysClient.getRole(Long.parseLong(next.getPostType())).getData();
 							if(role != null){

+ 9 - 7
blade-service/blade-business/src/main/java/org/springblade/business/controller/ImageClassificationFileController.java

@@ -163,8 +163,8 @@ public class ImageClassificationFileController extends BladeController {
                     //需要删除的本地文件集合
                     List<String> removeList = new ArrayList<>();
 
-                    // 压缩到小于指定文件大小200kb
-                    double targetSize = 200 * 1024;
+                    // 压缩到小于指定文件大小500kb
+                    double targetSize = 500 * 1024;
 
                     for (ImageClassificationFile file : fileResult) {
                         //获取图片文件流
@@ -204,14 +204,16 @@ public class ImageClassificationFileController extends BladeController {
 
                                             //获取文件流
                                             byte[] bytes = CommonUtil.InputStreamToBytes(CommonUtil.getOSSInputStream(urls.get(i)));
+                                            byte[] a = new byte[(int) targetSize];
                                             //压缩文件大小
                                             while (bytes.length > targetSize) {
                                                 float reduceMultiple = 0.5f;
                                                 bytes = FileUtils.resizeImage(bytes, reduceMultiple);
+                                                a = bytes;
                                             }
 
                                             //创建图片
-                                            drawing.createPicture(anchor, workbook.addPicture(bytes, Workbook.PICTURE_TYPE_JPEG));
+                                            drawing.createPicture(anchor, workbook.addPicture(a, Workbook.PICTURE_TYPE_JPEG));
                                             //图片定位
                                             FileUtils.imageOrientation(sheet, anchor, i == 1 ? new DataVO(1, 28) : new DataVO(0, 0));
 
@@ -689,18 +691,18 @@ public class ImageClassificationFileController extends BladeController {
     }
 
     /**
-     *
      * @param urlStr
-     * @return  返回Url资源大小
+     * @return 返回Url资源大小
      * @throws IOException
      */
     public long getResourceLength(String urlStr) throws IOException {
-        URL url=new URL(urlStr);
-        URLConnection urlConnection=url.openConnection();
+        URL url = new URL(urlStr);
+        URLConnection urlConnection = url.openConnection();
         urlConnection.connect();
         //返回响应报文头字段Content-Length的值
         return urlConnection.getContentLength();
     }
+
     /**
      * 根据字节返回文件大小
      */

+ 27 - 12
blade-service/blade-business/src/main/java/org/springblade/business/controller/InformationWriteQueryController.java

@@ -541,7 +541,7 @@ public class InformationWriteQueryController extends BladeController {
     @PostMapping("/abolishOne-sj")
     @ApiOperationSupport(order = 24)
     @ApiOperation(value = "单个废除-首件")
-    public R<Boolean> abolishOneSJ(@RequestParam String primaryKeyId,@RequestParam String id) {
+    public R<Boolean> abolishOneSJ(@RequestParam String primaryKeyId, @RequestParam String id) {
         //查询填报状态
         InformationQuery businessData = this.informationQueryService.getOne(Wrappers.<InformationQuery>lambdaQuery()
                 .eq(InformationQuery::getId, id));
@@ -682,13 +682,13 @@ public class InformationWriteQueryController extends BladeController {
     @PostMapping("/queryNodeStatus-sj")
     @ApiOperationSupport(order = 23)
     @ApiOperation(value = "/查询节点状态-首件")
-    @ApiModelProperty(value = "id",notes = "当前该条首件的记录id")
-    public R<String> queryNodeStatusSj(@RequestParam String primaryKeyId, @RequestParam String classify,String id) {
+    @ApiModelProperty(value = "id", notes = "当前该条首件的记录id")
+    public R<String> queryNodeStatusSj(@RequestParam String primaryKeyId, @RequestParam String classify, String id) {
         //记录状态
         String status = "1";
         //查询填报状态,type=3首件
         InformationQuery businessData = this.informationQueryService.getOne(Wrappers.<InformationQuery>lambdaQuery()
-                .eq(InformationQuery::getId,id)
+                .eq(InformationQuery::getId, id)
                 .eq(InformationQuery::getType, 3)
         );
         if (businessData != null) {
@@ -1309,8 +1309,13 @@ public class InformationWriteQueryController extends BladeController {
                     //获取当前所有复制的节点的最大sort
                     String sql = "select sort from m_wbs_tree_contract where contract_id = '" + node.getContractId() + "' and (id = '" + node.getId() + "' or old_id = '" + node.getId() + "')";
                     List<WbsTreeContract> query = jdbcTemplate.query(sql, new BeanPropertyRowMapper<>(WbsTreeContract.class));
-                    List<Integer> collect = query.stream().map(WbsTreeContract::getSort).collect(Collectors.toList());
-                    Integer max = collect.stream().reduce(collect.get(0), Integer::max);
+                    List<Integer> collect = query.stream().filter(f -> ObjectUtils.isNotEmpty(f.getSort())).collect(Collectors.toList()).stream().map(WbsTreeContract::getSort).collect(Collectors.toList());
+                    Integer max=1;
+                    if (collect.size() > 0) {
+                        max = collect.stream().reduce(collect.get(0), Integer::max);
+                    } else {
+                        max = 1;
+                    }
                     //设置sort
                     newData.setSort(max);
 
@@ -1385,8 +1390,13 @@ public class InformationWriteQueryController extends BladeController {
                         //获取当前所有复制的节点的最大sort
                         String sql = "select sort from m_wbs_tree_contract where contract_id = '" + node.getContractId() + "' and (id = '" + node.getId() + "' or old_id = '" + node.getId() + "')";
                         List<WbsTreeContract> query = jdbcTemplate.query(sql, new BeanPropertyRowMapper<>(WbsTreeContract.class));
-                        List<Integer> collect = query.stream().map(WbsTreeContract::getSort).collect(Collectors.toList());
-                        Integer max = collect.stream().reduce(collect.get(0), Integer::max);
+                        List<Integer> collect = query.stream().filter(f -> ObjectUtils.isNotEmpty(f.getSort())).collect(Collectors.toList()).stream().map(WbsTreeContract::getSort).collect(Collectors.toList());
+                        Integer max=1;
+                        if (collect.size() > 0) {
+                            max = collect.stream().reduce(collect.get(0), Integer::max);
+                        } else {
+                            max = 1;
+                        }
                         //设置sort
                         newData.setSort(max);
 
@@ -1822,8 +1832,13 @@ public class InformationWriteQueryController extends BladeController {
                 //获取当前所有复制的节点的最大sort
                 String sql = "select sort from m_wbs_tree_contract where contract_id = '" + treeContract.getContractId() + "' and (id = '" + half.getId() + "' or old_id = '" + half.getId() + "')";
                 List<WbsTreeContract> query = jdbcTemplate.query(sql, new BeanPropertyRowMapper<>(WbsTreeContract.class));
-                List<Integer> collect = query.stream().map(WbsTreeContract::getSort).collect(Collectors.toList());
-                Integer max = collect.stream().reduce(collect.get(0), Integer::max);
+                List<Integer> collect = query.stream().filter(f -> ObjectUtils.isNotEmpty(f.getSort())).collect(Collectors.toList()).stream().map(WbsTreeContract::getSort).collect(Collectors.toList());
+                Integer max =1 ;
+                if (collect.size() > 0) {
+                    max = collect.stream().reduce(collect.get(0), Integer::max);
+                } else {
+                    max = 1;
+                }
                 //设置sort
                 newData.setSort(max);
 
@@ -2137,8 +2152,8 @@ public class InformationWriteQueryController extends BladeController {
                     List<String> treeIds = queryDataResult.stream().map(QueryProcessDataVO::getPrimaryKeyId).distinct().collect(Collectors.toList());
                     //通过合同段主键在首件关联表中查询出所有数据
                     List<TreeContractFirst> firstList = treeContractFirstService.list(new LambdaQueryWrapper<TreeContractFirst>().in(TreeContractFirst::getWbsNodeId, treeIds));
-                    List<String> list = firstList.stream().map(fl -> (fl.getWbsNodeId()+"")).collect(Collectors.toList());
-                    queryDataResult = queryDataResult.stream().filter(qdr->list.contains(qdr.getPrimaryKeyId())).collect(Collectors.toList());
+                    List<String> list = firstList.stream().map(fl -> (fl.getWbsNodeId() + "")).collect(Collectors.toList());
+                    queryDataResult = queryDataResult.stream().filter(qdr -> list.contains(qdr.getPrimaryKeyId())).collect(Collectors.toList());
 //                    for (QueryProcessDataVO queryProcessDataVO : queryDataResult) {
 //                        TreeContractFirst first = treeContractFirstService.getOne(new LambdaQueryWrapper<TreeContractFirst>()
 //                                .eq(TreeContractFirst::getWbsNodeId, queryProcessDataVO.getPrimaryKeyId()));

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

@@ -427,7 +427,8 @@ public class TaskController extends BladeController {
 	 */
 	private void integrationMethod(TaskQueryVO queryVO, Map<String,Task> masterTaskMap, Map<String,TaskParallel> parallelMap, List<String> parallelProcessInstanceIds, String status){
 		//先查询符合条件的流程
-		LambdaQueryWrapper<Task> wrapper = Wrappers.<Task>lambdaQuery().eq(Task::getIsDeleted, 0).eq(Task::getProjectId, queryVO.getProjectId());
+		LambdaQueryWrapper<Task> wrapper = Wrappers.<Task>lambdaQuery().eq(Task::getIsDeleted, 0)
+				.eq(Task::getProjectId, queryVO.getProjectId()).eq(StringUtils.isNotBlank(queryVO.getBatch()),Task::getBatch,queryVO.getBatch());
 		this.integrationMethod(wrapper, queryVO);
 
 		//符合条件的集合

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

@@ -77,6 +77,10 @@ public interface InformationQueryMapper extends BaseMapper<InformationQuery> {
 	 * 统计
 	 */
 	Integer countInformationQuery(@Param("query") InformationQueryVO informationQuery);
+	/**
+	 * 统计
+	 */
+	Integer countInformationQueryTwo(@Param("query") InformationQueryVO informationQuery);
 
 	/**
 	 * 自定义分页

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

@@ -384,6 +384,47 @@
         ) AS query
     </select>
 
+    <select id="countInformationQueryTwo" resultType="java.lang.Integer">
+        select
+        count( distinct query.id)
+        from
+        (
+            select
+            query.id
+            from
+            (
+                select
+                iq.id,
+                (case iq.STATUS when 0 THEN null else t.batch end) as report_number,
+                date_format(iq.create_time,'%Y-%m-%d') as createTimes
+                from u_information_query iq left join (select  * from u_task k where k.status!=3 and k.contract_id = #{query.contractId}) t on iq.id = t.form_data_id  and t.is_deleted = 0
+                where
+                iq.is_deleted = 0
+                and iq.classify = #{query.classify}
+                and iq.contract_id = #{query.contractId}
+                <if test="query.taskStatus != null and query.taskStatus != ''"> and iq.status = #{query.taskStatus} </if>
+                <if test="query.sourceType != null and query.sourceType != ''"> and iq.source_type = #{query.sourceType} </if>
+                <if test="query.reportNumber != null and query.reportNumber != ''"> and t.batch = #{query.reportNumber} </if>
+                <if test="query.fileUserIdAndName != null and query.fileUserIdAndName != ''"> and iq.file_user_id_and_name like concat('%',#{query.fileUserIdAndName},'%') </if>
+                <if test="query.queryValue != null and query.queryValue != ''"> and (iq.name like concat('%',#{query.queryValue},'%') OR iq.number like concat('%',#{query.queryValue},'%')) </if>
+                <if test="query.firstTitle != null and query.firstTitle != ''"> and iq.type = 3 </if>
+                <if test="query.firstTitle == null or query.firstTitle == ''"> and iq.type != 3 </if>
+                <if test="query.wbsIds != null">
+                and iq.wbs_id in
+                <foreach collection="query.wbsIds" item="wbsIdc" open="(" separator="," close=")">
+                    #{wbsIdc}
+                </foreach>
+                </if>
+            ) AS query
+        where
+        1 = 1
+        <if test="query.reportNumber != null and query.reportNumber != ''"> and report_number = #{query.reportNumber} </if>
+        <if test="query.startTime != null and query.startTime != '' and query.endTime != null and query.endTime != ''">
+            and query.createTimes between #{query.startTime} and #{query.endTime}
+        </if>
+        ) AS query
+    </select>
+
     <select id="selectInformationQueryPage" resultMap="informationQueryResultMap">
         select
             query.wbs_id,

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

@@ -460,7 +460,7 @@ public class InformationQueryServiceImpl extends BaseServiceImpl<InformationQuer
         }
 
         //获取总量
-        Integer count = this.baseMapper.countInformationQuery(vo);
+        Integer count = this.baseMapper.countInformationQueryTwo(vo);
 
         //获取数据
         List<InformationQuery> result = this.baseMapper.selectInformationQueryPageTwo(current, page.getSize(), vo);

+ 0 - 1
blade-service/blade-business/src/main/java/org/springblade/business/socket/WebSocket.java

@@ -167,7 +167,6 @@ public class WebSocket {
     @Scheduled(cron = "0 0/5 * * * ?")
     public void reSendMessage() throws IOException {
         if (webSocketMap.isEmpty() || webSocketMessageMap.isEmpty()) {
-            logger.error("定时重发消息WebSocket,reSendMessage()方法未执行,原因:客户端未建立WebSocket链接");
             return;
         }
 

+ 1 - 2
blade-service/blade-business/src/main/java/org/springblade/business/socket/WebSocketManager.java

@@ -163,10 +163,9 @@ public class WebSocketManager {
     /***
      * 定时重发任务消息WebSocket - 后管
      */
-    @Scheduled(cron = "0 0/6 * * * ?")
+    @Scheduled(cron = "0 0/5 * * * ?")
     public void reSendMessageManager() throws IOException {
         if (webSocketMap2.isEmpty() || webSocketMessageMap2.isEmpty()) {
-            logger.error("定时重发消息WebSocket,reSendMessageManager()方法未执行,原因:客户端未建立WebSocket链接");
             return;
         }
 

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

@@ -7,6 +7,7 @@ import cn.hutool.core.util.HashUtil;
 import cn.hutool.core.util.NumberUtil;
 import cn.hutool.core.util.RadixUtil;
 import cn.hutool.dfa.SensitiveUtil;
+import com.alibaba.fastjson.JSON;
 import com.jfireel.expression.Expression;
 import com.jfireel.expression.node.CalculateNode;
 import com.jfireel.expression.node.impl.CompileObjectMethodNode;
@@ -1801,6 +1802,12 @@ public class CustomFunction {
 	public static Object gfn(Object ob1,Object ob2){
 		return _gfn(ob1,ob2);
 	}
+	public static Object gfn(List<Object> list){
+		if(ListUtils.isNotEmpty(list)){
+			return _gfn(list.toArray());
+		}
+		return "";
+	}
 	/**
 	 * @Description  返回第一个不为空的对象
 	 * @Param
@@ -1830,6 +1837,23 @@ public class CustomFunction {
 	}
 
 
+	public Object checkItemName(List<Object> data,List<Object> names){
+		if(ListUtils.isNotEmpty(data)&&ListUtils.isNotEmpty(names)&&data.size()!=names.size()){
+			StringBuilder sb = new StringBuilder();
+			for(int i=0;i< data.size();i++){
+				List<Object> datas= obj2ListNe(data.get(i));
+				if(datas.stream().anyMatch(e->StringUtils.isNotEmpty(e)&&StringUtils.isNotEquals("/",e))){
+					sb.append(names.get(i)).append(",");
+				}
+			}
+			if(sb.length()>1){
+				sb.deleteCharAt(sb.length()-1);
+			}
+			return sb.toString();
+		}
+		return "";
+	}
+
 	/**
 	 * @Description 三元运算 bool?o1:o2 ,默认返回空字符串
 	 * @Param [bool, o1, o2]
@@ -2595,6 +2619,8 @@ public class CustomFunction {
 
 
 
+
+
 	/**
 	 * @Description String 转List
 	 * @Param [o, separator]

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

@@ -203,6 +203,7 @@ public class ArchiveTreeContractController extends BladeController {
 	})
 	public R<List<ArchiveTreeContractVO2>> tree(Integer disPlayTree, Integer nodeType,Long projectId){
 
+
 		List<ArchiveTreeContractVO2> tree = archiveTreeContractService.tree2(AuthUtil.getTenantId(), disPlayTree, nodeType,projectId);
 		if (tree != null && tree.size() > 0) {
 			return R.data(tree);
@@ -221,7 +222,7 @@ public class ArchiveTreeContractController extends BladeController {
 	@GetMapping("/test")
 	public R test(){
 		Long projectId = 1578599210897772545L;
-		List<ArchiveTree> trees = archiveTreeService.treeList(AuthUtil.getTenantId(), null, null);
+		List<ArchiveTree> trees = archiveTreeService.treeList(AuthUtil.getTenantId(), projectId,null, null);
 
 		archiveTreeContractService.initTree2(AuthUtil.getTenantId(),projectId);
 

+ 26 - 11
blade-service/blade-manager/src/main/java/org/springblade/manager/controller/ArchiveTreeController.java

@@ -56,6 +56,7 @@ public class ArchiveTreeController extends BladeController {
     @ApiOperationSupport(order = 2)
     @ApiOperation(value = "详情", notes = "传入archiveTree")
     public R<ArchiveTree> detail(ArchiveTree archiveTree) {
+
         ArchiveTree detail = archiveTreeService.getOne(Condition.getQueryWrapper(archiveTree));
         return R.data(detail);
     }
@@ -111,10 +112,12 @@ public class ArchiveTreeController extends BladeController {
     @ApiOperationSupport(order = 6)
     @ApiOperation(value = "懒加载树形结构", notes = "传入父级id")
     @ApiImplicitParams(value = {
+            @ApiImplicitParam(name = "projectId", value = "项目id,0是系统级"),
             @ApiImplicitParam(name = "parentId", value = "父级id", required = true)
     })
-    public R<List<ArchiveTreeVO2>> lazyTree(Long parentId,Long extId,Long level) {
-        List<ArchiveTreeVO2> tree = archiveTreeService.lazyTree2(AuthUtil.getTenantId(), parentId,extId,level);
+    public R<List<ArchiveTreeVO2>> lazyTree(Long projectId,Long parentId,Long extId,Long level) {
+
+        List<ArchiveTreeVO2> tree = archiveTreeService.lazyTree2(AuthUtil.getTenantId(),projectId, parentId,extId,level);
         if (tree != null && tree.size() > 0) {
             return R.data(tree);
         }
@@ -128,11 +131,14 @@ public class ArchiveTreeController extends BladeController {
     @ApiOperationSupport(order = 7)
     @ApiOperation(value = "全加载树形结构/显示树", notes = "disPlayTree、nodeType")
     @ApiImplicitParams(value = {
+            @ApiImplicitParam(name = "projectId", value = "项目id,0是系统级"),
             @ApiImplicitParam(name = "disPlayTree", value = "是否加载显示树 'null'=不加载 '1'=加载"),
-            @ApiImplicitParam(name = "nodeType", value = "'null'=全加载 '1'=关联电子原生文件类型树 '2'=文件上传类型树")
+            @ApiImplicitParam(name = "nodeType", value = "'null'=全加载 '1'=关联电子原生文件类型树 '2'=文件上传类型树"),
+            @ApiImplicitParam(name = "wbsId", value = "对应的wbs树,用于展示关联质检节点下的"),
     })
-    public R<List<ArchiveTreeVO2>> tree(Integer disPlayTree, Integer nodeType) {
-        List<ArchiveTreeVO2> tree = archiveTreeService.tree2(AuthUtil.getTenantId(), disPlayTree, nodeType);
+    public R<List<ArchiveTreeVO2>> tree(Long projectId,Integer disPlayTree, Integer nodeType,String wbsId) {
+
+        List<ArchiveTreeVO2> tree = archiveTreeService.tree2(AuthUtil.getTenantId(),projectId, disPlayTree, nodeType,wbsId);
         if (tree != null && tree.size() > 0) {
             return R.data(tree);
         }
@@ -172,12 +178,21 @@ public class ArchiveTreeController extends BladeController {
         return R.status(archiveTreeService.submitArchiveTreeSort(listSort));
     }
 
-    @GetMapping("/test")
-    public R test(){
-
-
-        return R.fail(200, "初始化成功");
+    /**
+     * 初始化归档树根节点
+     */
+    @PostMapping("/initProjectTree")
+    @ApiOperationSupport(order = 11)
+    @ApiOperation(value = "初始化项目级归档树根节点", notes = "传入token")
+    @ApiImplicitParams(value = {
+            @ApiImplicitParam(name = "projectId", value = "项目id")
+    })
+    public R<ArchiveTree> initProjectTree(Long projectId) {
+        boolean b = archiveTreeService.initArchiveProjectTree(projectId);
+        if (b) {
+            return R.success("初始化创建成功");
+        }
+        return R.fail(200, "初始化创建失败");
     }
 
-
 }

+ 74 - 32
blade-service/blade-manager/src/main/java/org/springblade/manager/controller/FormulaController.java

@@ -21,15 +21,9 @@ import org.springblade.core.tool.utils.Func;
 import org.springblade.core.tool.utils.RegexUtil;
 import org.springblade.core.tool.utils.StringPool;
 import org.springblade.manager.dto.*;
-import org.springblade.manager.entity.ElementFormulaMapping;
-import org.springblade.manager.entity.Formula;
-import org.springblade.manager.entity.TextdictInfo;
-import org.springblade.manager.entity.WbsTreeContract;
+import org.springblade.manager.entity.*;
 import org.springblade.manager.formula.KeyMapper;
-import org.springblade.manager.service.IElementFormulaMappingService;
-import org.springblade.manager.service.IExcelTabService;
-import org.springblade.manager.service.ITextdictInfoService;
-import org.springblade.manager.service.IWbsTreeContractService;
+import org.springblade.manager.service.*;
 import org.springblade.manager.service.impl.FormulaServiceImpl;
 import org.springblade.manager.wrapper.FormulaWrapper;
 import org.springframework.dao.EmptyResultDataAccessException;
@@ -56,6 +50,7 @@ public class FormulaController {
     private final IExcelTabService tabService;
     private final IElementFormulaMappingService elementFormulaMappingService;
     private final JdbcTemplate jdbcTemplate;
+    private final IContractInfoService contractInfoService;
     private final ITextdictInfoService textdictInfoService;
     /**
      * 新增或修改
@@ -174,7 +169,19 @@ public class FormulaController {
             }
             List<Map<String,Object>> listMap = this.jdbcTemplate.queryForList(sb.toString());
             if(Func.isNotEmpty(listMap)){
-                return R.data(BeanUtil.toBean(listMap.get(0),FormulaBean.class));
+                Map<String,Object> map =listMap.get(0);
+                String rely = StringUtils.handleNull(map.get("rely"));
+                FormulaBean fb=BeanUtil.toBean(map,FormulaBean.class);
+                if(StringUtils.isNotEmpty(rely)){
+                    String[] relyArr = rely.split(StringPool.COMMA);
+                   List<Map<String,Object>> mapList =this.jdbcTemplate.queryForList("select CONCAT(a.tab_en_name,':',b.e_key) ekey,a.tab_ch_name tableName,b.e_name ename  ,b.e_length elength,c.dict_value type from m_table_info a JOIN m_wbs_form_element b on a.id=b.f_id  LEFT JOIN (select dict_key, dict_value from blade_dict where code ='data_type' and parent_id > 0 and is_sealed = 0 and is_deleted = 0 )c on b.e_type=c.dict_key" +
+                            " where  a.tab_en_name in( "+ Arrays.stream(relyArr).map(e->e.split(StringPool.COLON)[0]).distinct().collect(Collectors.joining(StringPool.COMMA,"'","'"))+")");
+                   if(ListUtils.isNotEmpty(mapList)){
+                       fb.setDict(mapList.stream().filter(e-> Arrays.stream(relyArr).anyMatch(c->StringUtils.isEquals(e.get("ekey"),c))).collect(Collectors.toMap(e->StringUtils.handleNull(e.get("ekey")), e->e)));
+                   }
+
+                }
+                return R.data(fb);
             }
 
         }
@@ -312,31 +319,67 @@ public class FormulaController {
         return R.fail("无数据");
     }
 
+
+    public static String TEMPLATE="{\n" +
+            "'type': 'radio',\n" +
+            "'info': {\n" +
+            "'label': '是否引用公式数据',\n" +
+            "'value': [\n" +
+            "{\n" +
+            "'label': '是',\n" +
+            "'value': 1\n" +
+            "},\n" +
+            "{\n" +
+            "'label': '否',\n" +
+            "'value': 0\n" +
+            "}\n" +
+            "]\n" +
+            "}\n" +
+            "}";
+
     @GetMapping("/panel")
     @ApiOperationSupport(order = 10)
     @ApiOperation(value = "公式交互面板", notes = "公式交互面板")
-    public R<Object> panel(Long pkeyId ,String key,String projectId)  {
+    public R<Object> panel(FormulaOption fo)  {
              Map<String,Object> result = new LinkedHashMap<>();
-              key=key.replaceAll("__[\\d_]+","");
-              List<KeyMapper> kms =  this.service.getKeyMapperList(Collections.singletonList(pkeyId),projectId);
-              if(Func.isNotEmpty(kms)&&Func.isNotEmpty(kms.get(0).getFormulaId())){
-                   Formula formula = this.service.getById(kms.get(0).getFormulaId());
+             String  key=fo.getEkey().replaceAll("__[\\d_]+","");;
+              ContractInfo contract = this.contractInfoService.getById(fo.getContractId());
+              List<KeyMapper> kms =  this.service.getKeyMapperList(Collections.singletonList(fo.getPKeyId()),contract.getPId());
+              KeyMapper keyMapper=null;
+              if(Func.isNotEmpty(kms)){
+                Optional<KeyMapper> optionalKeyMapper=  kms.stream().filter(e->StringUtils.isEquals(e.getField(),key)).findFirst();
+                if(optionalKeyMapper.isPresent()){
+                    keyMapper=optionalKeyMapper.get();
+                }
+              }
+              if(keyMapper!=null&&Func.isNotEmpty(keyMapper.getFormulaId())){
+                   Formula formula = this.service.getById(keyMapper.getFormulaId());
+                   /*临时处理,等确定数据结构在优化*/
                    if(formula.getFormula().contains(".option")){
-                       result.put("type","radio");
-                       Map<String,Object> info = new LinkedHashMap<>();
-                       result.put("info",info);
+                       JSONObject jo =JSON.parseObject(TEMPLATE);
+                       jo.put("scope",0);
+                       JSONObject info =jo.getJSONObject("info");
                        info.put("label","是否引用公式数据");
-                        List<Map<String,Object>> value = new ArrayList<>();
-                        info.put("value",value);
-                        Map<String,Object> y=new LinkedHashMap<>();
-                        Map<String,Object> n=new LinkedHashMap<>();
-                        value.add(y);
-                        value.add(n);
-                        y.put("label","是");
-                        y.put("value",1);
-                        n.put("label","是");
-                        n.put("value",1);
-                   }
+                       /*针对元素级别*/
+                       List<Map<String,Object>> mapList=this.jdbcTemplate.queryForList("select id,parent_id parentId,table_id pKeyId,val value,e_key ekey,contract_id contractId,scope from m_formula_option where scope=0 and parent_id ="+fo.getParentId()+" and e_key='"+key+"' and contract_id="+fo.getContractId());
+                       if(Func.isNotEmpty(mapList)){
+                           info.put("data",mapList.get(0));
+                       }
+                     return    R.data(jo);
+                   }else if (StringUtils.isEquals("MILE",formula.getNumber())){
+                      if(StringUtils.isEquals(key,formula.getRelyList().get(0).split(StringPool.COLON)[1])){
+                          JSONObject jo =JSON.parseObject(TEMPLATE);
+                          jo.put("scope",1);
+                          JSONObject info =jo.getJSONObject("info");
+                          info.put("label","竖直方向");
+                          List<Map<String,Object>> mapList=this.jdbcTemplate.queryForList("select id,parent_id parentId,table_id pKeyId,val value,e_key ekey,contract_id contractId,scope from m_formula_option where scope=1 and table_id="+fo.getPKeyId()+" and parent_id ="+fo.getParentId()+" and e_key='"+key+"' and contract_id="+fo.getContractId());
+                          if(Func.isNotEmpty(mapList)){
+                              result.put("data",mapList.get(0));
+                          }
+                      }
+                  }
+              }else{
+                  R.success("暂无公式控件");
               }
              return R.data(result);
     }
@@ -345,11 +388,10 @@ public class FormulaController {
     @ApiOperationSupport(order = 10)
     @ApiOperation(value = "公式交互面板参数保存", notes = "公式交互面板参数保存")
     public R<Object> panelSave( @RequestBody FormulaOption fo){
-            List<Map<String,Object>> mapList = this.jdbcTemplate.queryForList("select parent_id pid,contract_id cid from m_wbs_tree_contract where p_key_id="+fo.getPKeyId());
-            if(Func.isNotEmpty(mapList)){
-                  Map<String,Object> map = mapList.get(0);
-                   this.jdbcTemplate.execute("");
+            if(Func.isNotEmpty(fo.getId())){
+                this.jdbcTemplate.execute("delete from m_formula_option where id="+fo.getId());
             }
+            this.jdbcTemplate.execute("insert into m_formula_option values ("+SnowFlakeUtil.getId()+fo.toSql()+")");
            return    R.success("保存成功");
     }
 

+ 38 - 22
blade-service/blade-manager/src/main/java/org/springblade/manager/controller/TextdictInfoController.java

@@ -35,9 +35,12 @@ import org.jsoup.nodes.Element;
 import org.jsoup.select.Elements;
 import org.springblade.common.utils.CommonUtil;
 import org.springblade.common.utils.SnowFlakeUtil;
+import org.springblade.core.log.exception.ServiceException;
 import org.springblade.core.mp.support.Condition;
 import org.springblade.core.mp.support.Query;
+import org.springblade.core.redis.cache.BladeRedis;
 import org.springblade.core.secure.BladeUser;
+import org.springblade.core.secure.utils.SecureUtil;
 import org.springblade.core.tool.api.R;
 import org.springblade.core.tool.utils.*;
 import org.springblade.manager.entity.*;
@@ -84,7 +87,7 @@ public class TextdictInfoController extends BladeController {
     private final WbsTreePrivateMapper wbsTreePrivateMapper;
     private final WbsTreePrivateServiceImpl wbsTreePrivateService;
     private final WbsTreeContractServiceImpl wbsTreeContractService;
-
+    private final BladeRedis bladeRedis;
     private final JdbcTemplate jdbcTemplate;
 
     /**
@@ -212,7 +215,7 @@ public class TextdictInfoController extends BladeController {
         delIds.add(ids);
         textdictInfoService.getBaseMapper().deleteBatchIds(delIds);
 
-        return R.success("成功");
+        return R.success("删除成功");
     }
 
 
@@ -339,6 +342,10 @@ public class TextdictInfoController extends BladeController {
     @ApiOperationSupport(order = 7)
     @ApiOperation(value = "保存电签", notes = "保存电签")
     public R<String> saveSigInfo(@Valid @RequestBody JSONObject dataInfo) throws IOException {
+        String redisValue = bladeRedis.get("save-eVis-lock:" + SecureUtil.getUserId());
+        if (StringUtils.isNotEmpty(redisValue) && redisValue.equals("1")) {
+            throw new ServiceException("请勿重复提交,请3秒后再尝试");
+        }
         JSONArray jsonArray = dataInfo.getJSONArray("dataInfo");
         Long tableId = dataInfo.getLong("tabId");
 
@@ -352,10 +359,11 @@ public class TextdictInfoController extends BladeController {
                 .eq(WbsTreePrivate::getStatus, 1));
         List<Long> pKeyIds = wbsTreePrivatesEqual.stream().map(WbsTreePrivate::getPKeyId).collect(Collectors.toList());
         String ids = StringUtils.join(pKeyIds, ",");
-
-        //删除引用当前模板所有电签信息
-        String delSql = "delete from m_textdict_info where tab_id in(" + ids + ") and type in(2,6)";
-        jdbcTemplate.execute(delSql);
+        if (StringUtils.isNotEmpty(ids)) {
+            //删除引用当前模板所有电签信息
+            String delSql = "delete from m_textdict_info where tab_id in(" + ids + ") and type in(2,6)";
+            jdbcTemplate.execute(delSql);
+        }
 
         // 读取html页面信息
         File file1 = ResourceUtil.getFile(wbsTreePrivate.getHtmlUrl());
@@ -428,12 +436,12 @@ public class TextdictInfoController extends BladeController {
         FileUtil.writeToFile(writeFile, doc.html(), Boolean.parseBoolean("UTF-8"));
 
         String str1 = wbsTreePrivate.getHtmlUrl().replace("Desktop//privateUrl", "Desktop/privateUrl");
-
         String replace = str1.replace("\\", "\\\\");
-
-        //修改所有节点的htmlUrl
-        String updateSqlP = "update m_wbs_tree_private set html_url = '" + replace + "' where p_key_id in (" + ids + ")";
-        jdbcTemplate.execute(updateSqlP);
+        if (StringUtils.isNotEmpty(ids)){
+            //修改所有节点的htmlUrl
+            String updateSqlP = "update m_wbs_tree_private set html_url = '" + replace + "' where p_key_id in (" + ids + ")";
+            jdbcTemplate.execute(updateSqlP);
+        }
 
         //修改对应合同段的htmlUrl,当前项目下对应合同段的节点
         List<Long> cIdsList = wbsTreePrivatesEqual.stream().map(WbsTreePrivate::getId).distinct().collect(Collectors.toList());
@@ -441,12 +449,15 @@ public class TextdictInfoController extends BladeController {
                 .eq(WbsTreeContract::getProjectId, wbsTreePrivate.getProjectId())
                 .eq(WbsTreeContract::getExcelId, wbsTreePrivate.getExcelId())
                 .eq(WbsTreeContract::getStatus, 1)
-                .in(WbsTreeContract::getId, cIdsList)
-        ).stream().map(WbsTreeContract::getPKeyId).collect(Collectors.toList());
-
+                .in(WbsTreeContract::getId, cIdsList)).stream().map(WbsTreeContract::getPKeyId).collect(Collectors.toList());
         String cPkeyIdsStr = StringUtils.join(cPkeyIds, ",");
-        String updateSqlC = "update m_wbs_tree_contract set html_url = '" + replace + "' where p_key_id in (" + cPkeyIdsStr + ")";
-        jdbcTemplate.execute(updateSqlC);
+        if (StringUtils.isNotEmpty(cPkeyIdsStr)) {
+            String updateSqlC = "update m_wbs_tree_contract set html_url = '" + replace + "' where p_key_id in (" + cPkeyIdsStr + ")";
+            jdbcTemplate.execute(updateSqlC);
+        }
+
+        bladeRedis.set("save-eVis-lock:" + SecureUtil.getUserId(), "1");
+        bladeRedis.expire("save-eVis-lock:" + SecureUtil.getUserId(), 3);
 
         return R.success("操作成功");
     }
@@ -458,6 +469,7 @@ public class TextdictInfoController extends BladeController {
     @ApiOperationSupport(order = 7)
     @ApiOperation(value = "保存默认值", notes = "保存默认值")
     public R<String> saveDefaulVal(@Valid @RequestBody TextdictBy345VO textdictInfo) throws IOException, ClassNotFoundException {
+
         //当前清表信息
         WbsTreePrivate wbsTreePrivate = wbsTreePrivateMapper.getByPKeyId(textdictInfo.getTableId());
 
@@ -549,10 +561,11 @@ public class TextdictInfoController extends BladeController {
 
         String str1 = wbsTreePrivate.getHtmlUrl().replace("Desktop//privateUrl", "Desktop/privateUrl");
         String replace = str1.replace("\\", "\\\\");
-
-        //修改所有节点的htmlUrl
-        String updateSqlP = "update m_wbs_tree_private set html_url = '" + replace + "' where p_key_id in (" + ids + ")";
-        jdbcTemplate.execute(updateSqlP);
+        if (StringUtils.isNotEmpty(ids)) {
+            //修改所有节点的htmlUrl
+            String updateSqlP = "update m_wbs_tree_private set html_url = '" + replace + "' where p_key_id in (" + ids + ")";
+            jdbcTemplate.execute(updateSqlP);
+        }
 
         //修改对应合同段的htmlUrl,当前项目下对应合同段的节点
         List<Long> cIdsList = wbsTreePrivatesEqual.stream().map(WbsTreePrivate::getId).distinct().collect(Collectors.toList());
@@ -564,8 +577,11 @@ public class TextdictInfoController extends BladeController {
         ).stream().map(WbsTreeContract::getPKeyId).collect(Collectors.toList());
 
         String cPkeyIdsStr = StringUtils.join(cPkeyIds, ",");
-        String updateSqlC = "update m_wbs_tree_contract set html_url = '" + replace + "' where p_key_id in (" + cPkeyIdsStr + ")";
-        jdbcTemplate.execute(updateSqlC);
+        if (StringUtils.isNotEmpty(cPkeyIdsStr)) {
+            String updateSqlC = "update m_wbs_tree_contract set html_url = '" + replace + "' where p_key_id in (" + cPkeyIdsStr + ")";
+            jdbcTemplate.execute(updateSqlC);
+        }
+
 
         return R.success("操作成功");
     }

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

@@ -220,6 +220,13 @@ public class WbsFormElementController extends BladeController {
     public R<List<WbsNodeTableVO>> searchNodeTables(String nodeId, String excelTabId) {
         List<WbsNodeTableVO> list = wbsFormElementService.searchNodeTables(nodeId, excelTabId);
         if (list.size() > 0) {
+            list.forEach(l->{
+                if (l.getInitTableName() != null){
+                    if (!l.getInitTableName().contains("m_")) {
+                        l.setIsLinkTable(2);
+                    }
+                }
+            });
             return R.data(list, "查询成功");
         }
         return R.fail(200, "操作失败");

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

@@ -317,9 +317,9 @@ public class WbsTreePrivateController extends BladeController {
         List<WbsNodeTableVO> rs = wbsTreePrivateService.selectByNodeTable(parentId, wbsId, projectId);
         if (rs.size() > 0) {
             for (WbsNodeTableVO r : rs) {
-                if (StringUtil.isBlank(r.getInitTableId())){
+                if (StringUtil.isBlank(r.getInitTableId())) {
                     WbsTree wbsTree = wbsTreeService.getById(r.getId());
-                    if (wbsTree != null){
+                    if (wbsTree != null) {
                         r.setInitTableId(wbsTree.getInitTableId().toString());
                         r.setElementTotal(Math.toIntExact(wbsFormElementService.count(
                                 new LambdaQueryWrapper<WbsFormElement>().eq(WbsFormElement::getFId, r.getInitTableId()))));
@@ -482,6 +482,16 @@ public class WbsTreePrivateController extends BladeController {
         return R.status(wbsTreePrivateService.syncNodeParam(projectId));
     }
 
+    /**
+     * 同步项目下所有节点的电签默认信息
+     */
+    @ApiOperationSupport(order = 14)
+    @ApiOperation(value = "同步项目下所有节点的电签默认信息", notes = "传入项目projectId")
+    @RequestMapping(value = "/sync-project-eVisa", method = RequestMethod.POST)
+    public R syncProjectEVisa(@RequestParam String projectId) {
+        return R.status(wbsTreePrivateService.syncProjectEVisa(projectId));
+    }
+
     /**
      * 同步项目下节点的元素表
      */
@@ -599,5 +609,15 @@ public class WbsTreePrivateController extends BladeController {
         return wbsTreePrivateService.getExcelHtml(primaryKeyId);
     }
 
+    /**
+     * 解決项目电签信息重复问题接口
+     * @param pid 当前项目id
+     * @return
+     */
+    @PostMapping("/eVisInfoRepeatDel")
+    public R eVisInfoRepeatDel(String pid) {
+        wbsTreePrivateService.eVisInfoRepeatDel(pid);
+        return R.status(true);
+    }
 
 }

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

@@ -7,6 +7,7 @@ import org.springblade.core.tool.api.R;
 import org.springblade.manager.entity.ArchiveTree;
 import org.springblade.manager.service.IArchiveTreeService;
 import org.springblade.manager.vo.ArchiveTreeVO;
+import org.springblade.manager.vo.ArchiveTreeVO2;
 import org.springframework.web.bind.annotation.RestController;
 
 import java.util.ArrayList;
@@ -39,7 +40,7 @@ public class ArchiveTreeClientImpl implements ArchiveTreeClient {
     }
 
     @Override
-    public R<List<ArchiveTreeVO>> tree(Integer disPlayTree, Integer nodeType) {
-        return R.data(this.archiveTreeService.tree(AuthUtil.getTenantId(), disPlayTree, nodeType));
+    public R<List<ArchiveTreeVO2>> tree(Long projectId,Integer disPlayTree, Integer nodeType) {
+        return R.data(this.archiveTreeService.tree2(AuthUtil.getTenantId(),projectId, disPlayTree, nodeType,null));
     }
 }

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

@@ -99,7 +99,8 @@ public class WbsTreeContractClientImpl implements WbsTreeContractClient {
             //查询表格
             return this.wbsTreeContractService.list(wrapper);
         } else {
-            return this.wbsTreeContractService.list(Wrappers.<WbsTreeContract>lambdaQuery().eq(WbsTreeContract::getParentId, treeNode.getId()).eq(WbsTreeContract::getContractId, treeNode.getContractId()).eq(WbsTreeContract::getType, "1"));
+            //.eq(WbsTreeContract::getType, "1")
+            return this.wbsTreeContractService.list(Wrappers.<WbsTreeContract>lambdaQuery().eq(WbsTreeContract::getParentId, treeNode.getId()).eq(WbsTreeContract::getContractId, treeNode.getContractId()));
         }
     }
 

+ 11 - 3
blade-service/blade-manager/src/main/java/org/springblade/manager/mapper/ArchiveTreeContractMapper.java

@@ -44,13 +44,21 @@ public interface ArchiveTreeContractMapper extends BaseMapper<ArchiveTreeContrac
 	 * @return
 	 */
 	List<ArchiveTreeContractVO> selectArchiveTreeContractPage(IPage page, ArchiveTreeContractVO archiveTreeContract);
+	List<ArchiveTreeContractVO> tree(@Param("tenantId") String tenantId, @Param("disPlayTree") Integer disPlayTree, @Param("nodeType") Integer nodeType, @Param("projectId") Long projectId);
+
 	List<ArchiveTreeContractVO> lazyTree(@Param("tenantId") String tenantId, @Param("parentId") Long parentId, @Param("projectId") Long projectId);
 
-	List<ArchiveTreeContractVO> tree(@Param("tenantId") String tenantId, @Param("disPlayTree") Integer disPlayTree, @Param("nodeType") Integer nodeType, @Param("projectId") Long projectId);
 
-	List<ArchiveTreeContractVO2> lazyTree2(@Param("tenantId") String tenantId, @Param("parentId") Long parentId, @Param("projectId") Long projectId);
 
-	List<ArchiveTreeContractVO2> tree2(@Param("tenantId") String tenantId, @Param("disPlayTree") Integer disPlayTree, @Param("nodeType") Integer nodeType, @Param("projectId") Long projectId);
+	List<ArchiveTreeContractVO2> lazyTree2(@Param("tenantId") String tenantId, @Param("parentId") Long parentId, @Param("projectId") Long projectId
+			, @Param("code") String code, @Param("contractId") String contractId);
+
+	List<ArchiveTreeContractVO2> tree2(@Param("tenantId") String tenantId, @Param("disPlayTree") Integer disPlayTree, @Param("nodeType") Integer nodeType, @Param("projectId") Long projectId
+			, @Param("code") String code, @Param("contractId") String contractId);
+
+	List<ArchiveTreeContractVO2> lazyTree3(@Param("tenantId") String tenantId, @Param("parentId") Long parentId, @Param("projectId") Long projectId, @Param("treeCode") Long treeCode);
+
+	List<ArchiveTreeContractVO2> tree3(@Param("tenantId") String tenantId, @Param("disPlayTree") Integer disPlayTree, @Param("nodeType") Integer nodeType, @Param("projectId") Long projectId, @Param("treeCode") Long treeCode);
 	/**
 	 * 自动组卷规则设置节点下所有子节点
 	 * @param treeContract

+ 6 - 0
blade-service/blade-manager/src/main/java/org/springblade/manager/mapper/ArchiveTreeContractMapper.xml

@@ -195,6 +195,9 @@
         <if test="tenantId!=null and tenantId!=''">
             AND d.tenant_id = #{tenantId}
         </if>
+        <if test="code!=null and code!=''">
+            AND (d.tree_code = #{code} or d.tree_code = #{contractId} or d.parent_id = 0)
+        </if>
         ORDER BY d.sort
     </select>
 
@@ -231,6 +234,9 @@
             /*根节点=0 关联电子原生文件=1 数字化上传文件=2*/
             AND node_type in (0,#{nodeType})
         </if>
+        <if test="code!=null and code!=''">
+            AND (d.tree_code = #{code} or d.tree_code = #{contractId} or d.parent_id = 0)
+        </if>
         OR ( parent_id = 0 AND project_id = #{projectId} )
         ORDER BY sort
     </select>

+ 4 - 2
blade-service/blade-manager/src/main/java/org/springblade/manager/mapper/ArchiveTreeMapper.java

@@ -12,9 +12,11 @@ import java.util.List;
 public interface ArchiveTreeMapper extends BaseMapper<ArchiveTree> {
 
     List<ArchiveTreeVO> lazyTree(@Param("tenantId") String tenantId, @Param("parentId") Long parentId);
-    List<ArchiveTreeVO2> lazyTree2(@Param("tenantId") String tenantId, @Param("parentId") Long parentId);
+
     List<ArchiveTreeVO> tree(@Param("tenantId") String tenantId, @Param("disPlayTree") Integer disPlayTree, @Param("nodeType") Integer nodeType);
-    List<ArchiveTreeVO2> tree2(@Param("tenantId") String tenantId, @Param("disPlayTree") Integer disPlayTree, @Param("nodeType") Integer nodeType);
+
+    List<ArchiveTreeVO2> lazyTree2(@Param("tenantId") String tenantId, @Param("projectId") Long projectId,@Param("parentId") Long parentId);
+    List<ArchiveTreeVO2> tree2(@Param("tenantId") String tenantId, @Param("projectId") Long projectId,@Param("disPlayTree") Integer disPlayTree, @Param("nodeType") Integer nodeType);
     int updateBatch(@Param("diffRent") List<String> diffRent);
 
     int updateBatch2(@Param("diffRent") List<String> diffRent);

+ 11 - 3
blade-service/blade-manager/src/main/java/org/springblade/manager/mapper/ArchiveTreeMapper.xml

@@ -13,6 +13,7 @@
         <result column="status" property="status"/>
         <result column="is_deleted" property="isDeleted"/>
         <result column="parent_id" property="parentId"/>
+        <result column="project_id" property="projectId"/>
         <result column="ancestors" property="ancestors"/>
         <result column="node_name" property="nodeName"/>
         <result column="full_name" property="fullName"/>
@@ -32,6 +33,7 @@
         <result column="ext_type" property="extType"/>
         <result column="ext_id" property="extId"/>
         <result column="exp_data_type" property="expDataType"/>
+        <result column="from_id" property="fromId"/>
         <result column="archive_auto_type" property="archiveAutoType"/>
         <result column="archive_auto_node_id" property="archiveAutoNodeId"/>
         <result column="archive_auto_group_select" property="archiveAutoGroupSelect"/>
@@ -42,6 +44,7 @@
     <resultMap id="ArchiveTreeVOResultMap" type="org.springblade.manager.vo.ArchiveTreeVO2">
         <id column="id" property="id"/>
         <result column="parent_id" property="parentId"/>
+        <result column="project_id" property="projectId"/>
         <result column="title" property="title"/>
         <result column="value" property="value"/>
         <result column="key" property="key"/>
@@ -59,6 +62,7 @@
         <result column="storage_type" property="storageType"/>
         <result column="ext_type" property="extType"/>
         <result column="ext_id" property="extId"/>
+        <result column="from_id" property="fromId"/>
         <result column="archive_auto_type" property="archiveAutoType"/>
         <result column="archive_auto_node_id" property="archiveAutoNodeId"/>
         <result column="archive_auto_group_id" property="archiveAutoGroupId"/>
@@ -187,6 +191,7 @@
     <select id="lazyTree2" resultMap="ArchiveTreeVOResultMap">
         SELECT
         d.id,
+        d.project_id,
         d.parent_id,
         d.node_name AS title,
         d.id AS "value",
@@ -198,6 +203,7 @@
         d.node_type AS nodeType,
         d.project_type,
         d.storage_type,
+        d.association_type,
         d.ext_type,
         d.ext_id,
         d.exp_data_type,
@@ -213,7 +219,7 @@
         FROM
         m_archive_tree d
         WHERE
-        d.parent_id = #{parentId} AND d.is_deleted = 0
+        d.parent_id = #{parentId} AND d.is_deleted = 0 AND project_id = #{projectId}
         <if test="tenantId!=null and tenantId!=''">
             AND d.tenant_id = #{tenantId}
         </if>
@@ -223,6 +229,7 @@
     <select id="tree2" resultMap="ArchiveTreeVOResultMap">
         SELECT
         id,
+        project_id,
         parent_id,
         node_name AS title,
         id AS "value",
@@ -236,6 +243,7 @@
         node_type AS nodeType,
         project_type,
         storage_type,
+        association_type,
         ext_type,
         ext_id,
         exp_data_type,
@@ -247,7 +255,7 @@
         interface_type,
         sort
         FROM m_archive_tree
-        WHERE is_deleted = 0
+        WHERE is_deleted = 0 AND project_id = #{projectId}
         <if test=" tenantId!=null and tenantId!='' ">
             AND tenant_id = #{tenantId}
         </if>
@@ -258,7 +266,7 @@
             /*根节点=0 关联电子原生文件=1 数字化上传文件=2*/
             AND node_type in (0,#{nodeType})
         </if>
-        OR parent_id = 0
+        OR (parent_id = 0 and is_deleted = 0 AND project_id = #{projectId})
         ORDER BY sort
     </select>
 

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

@@ -57,6 +57,7 @@
         <result column="value" property="value"/>
         <result column="key" property="key"/>
         <result column="has_children" property="hasChildren"/>
+        <result column="major_data_type" property="majorDataType"/>
         <result column="type" property="type"/>
         <result column="nodeType" property="nodeType"/>
         <result column="wbsType" property="wbsType"/>
@@ -266,6 +267,7 @@
             d.type AS "type",
             d.id AS "value",
             d.id AS "key",
+            d.major_data_type,
             d.node_type AS "nodeType",
             d.is_exist_form AS "isExistForm",
             a.wbs_type AS "wbsType"

+ 2 - 1
blade-service/blade-manager/src/main/java/org/springblade/manager/mapper/WbsTreePrivateMapper.java

@@ -11,6 +11,7 @@ import org.springblade.manager.injector.EasyBaseMapper;
 import org.springblade.manager.vo.TreeNodeVOByTabType;
 import org.springblade.manager.vo.WbsNodeTableVO;
 import org.springblade.manager.vo.WbsTreePrivateVO;
+import org.springblade.manager.vo.WbsTreeVO2;
 
 import java.util.List;
 
@@ -18,7 +19,7 @@ public interface WbsTreePrivateMapper extends EasyBaseMapper<WbsTreePrivate> {
     List<WbsTreePrivate> selectAll(Integer wbsType);
 
     List<WbsTreePrivateVO> tree(@Param("wbsId") String wbsId, @Param("projectId") String projectId, @Param("wbsType") Integer wbsType);
-
+    List<WbsTreeVO2> tree2(@Param("wbsId") String wbsId, @Param("projectId") String projectId, @Param("wbsType") Integer wbsType);
     List<WbsTreePrivate> selectByCondition(@Param("id") String id, @Param("wbsId") String wbsId, @Param("projectId") String projectId);
 
     void deleteByCondition(String id, String wbsId, String projectId);

+ 35 - 0
blade-service/blade-manager/src/main/java/org/springblade/manager/mapper/WbsTreePrivateMapper.xml

@@ -46,6 +46,22 @@
         <result column="project_name" property="projectName"/>
     </resultMap>
 
+    <resultMap id="WbsTreeResultMap2" type="org.springblade.manager.vo.WbsTreeVO2">
+        <id column="id" property="id"/>
+        <result column="parent_id" property="parentId"/>
+        <result column="title" property="title"/>
+        <result column="value" property="value"/>
+        <result column="key" property="key"/>
+        <result column="has_children" property="hasChildren"/>
+        <result column="major_data_type" property="majorDataType"/>
+        <result column="type" property="type"/>
+        <result column="nodeType" property="nodeType"/>
+        <result column="wbsType" property="wbsType"/>
+        <result column="isExistForm" property="isExistForm"/>
+        <result column="ancestors" property="ancestors"/>
+        <result column="tenantId" property="tenantId"/>
+    </resultMap>
+
     <resultMap id="treeNodeResultMap" type="org.springblade.manager.vo.TreeNodeVO">
         <id column="id" property="id"/>
         <result column="parent_id" property="parentId"/>
@@ -376,6 +392,25 @@
         ORDER BY sort
     </select>
 
+    <select id="tree2" resultMap="WbsTreeResultMap2">
+        select
+        id, parent_id , node_name as title,type as "type", id as "value", id as "key" ,
+        node_type AS "nodeType", is_exist_form AS "isExistForm",major_data_type,
+        wbs_type as "wbsType"
+        from m_wbs_tree_private
+        where
+        is_deleted = 0
+        and status = 1
+        and `type` = 1
+        and project_id = #{projectId}
+        and wbs_id = #{wbsId}
+        and parent_id is not null
+        <if test="wbsType != null and wbsType != ''">
+            and wbs_type = #{wbsType}
+        </if>
+        ORDER BY sort
+    </select>
+
     <select id="selectByCondition" resultType="org.springblade.manager.entity.WbsTreePrivate">
         SELECT *
         FROM m_wbs_tree_private

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

@@ -55,9 +55,8 @@ public interface IArchiveTreeContractService extends BaseService<ArchiveTreeCont
 	 * 初始化项目级归档树
 	 * @param tenantId
 	 * @param projectId
-	 * @return
-	 */
-	boolean initTree(String tenantId, Long projectId, List<ArchiveTree> trees);
+	 * @return*/
+
 
 	boolean initTree2(String tenantId, Long projectId);
 

+ 7 - 5
blade-service/blade-manager/src/main/java/org/springblade/manager/service/IArchiveTreeService.java

@@ -16,11 +16,11 @@ public interface IArchiveTreeService extends BaseService<ArchiveTree> {
 
 	boolean submit(ArchiveTreeDTO archiveTreeDTO);
 
-	List<ArchiveTreeVO> lazyTree(String tenantId, Long parentId);
-	List<ArchiveTreeVO2> lazyTree2(String tenantId, Long parentId, Long extId,Long level);
+//	List<ArchiveTreeVO> lazyTree(String tenantId, Long parentId);
+//	List<ArchiveTreeVO> tree(String tenantI, Integer disPlayTree, Integer nodeType);
 
-	List<ArchiveTreeVO> tree(String tenantI, Integer disPlayTree, Integer nodeType);
-	List<ArchiveTreeVO2> tree2(String tenantI, Integer disPlayTree, Integer nodeType);
+	List<ArchiveTreeVO2> lazyTree2(String tenantId, Long projectId, Long parentId, Long extId,Long level);
+	List<ArchiveTreeVO2> tree2(String tenantI, Long projectId, Integer disPlayTree, Integer nodeType,String wbsId);
 
 	List<ArchiveTree> selectByParentIdOrId(String id);
 
@@ -30,9 +30,11 @@ public interface IArchiveTreeService extends BaseService<ArchiveTree> {
 
 	boolean submitArchiveTreeSort(List<ArchiveTreeSortDTO> listSort);
 
-	List<ArchiveTree> treeList(String tenantI,Integer disPlayTree,Integer nodeType);
+	List<ArchiveTree> treeList(String tenantId,Long projectId, Integer disPlayTree,Integer nodeType);
 	
 
 
 	boolean saveAechiveAutoRule(Integer archiveAutoType,String nodeIds);
+
+	boolean initArchiveProjectTree(Long projectId);
 }

+ 6 - 0
blade-service/blade-manager/src/main/java/org/springblade/manager/service/IWbsTreePrivateService.java

@@ -15,6 +15,7 @@ import java.util.List;
 public interface IWbsTreePrivateService extends BaseService<WbsTreePrivate> {
 
     List<WbsTreePrivateVO> tree(String wbsId, String projectId);
+    List<WbsTreeVO2> tree2(String wbsId, String projectId);
 
     boolean submit(WbsTreePrivate wbsTreePrivate);
 
@@ -72,4 +73,9 @@ public interface IWbsTreePrivateService extends BaseService<WbsTreePrivate> {
     List<WbsTreePrivate> searchNodeAllTable(String primaryKeyId, String type, String tableType, String contractId, String projectId, Integer isAdd, Long id);
 
     Object getExcelHtml(String primaryKeyId) throws IOException;
+
+    boolean syncProjectEVisa(String projectId);
+
+    void eVisInfoRepeatDel(String pid);
+
 }

+ 16 - 38
blade-service/blade-manager/src/main/java/org/springblade/manager/service/impl/ArTreeContractInitServiceImpl.java

@@ -22,48 +22,12 @@ import java.util.*;
 @Service
 @AllArgsConstructor
 public class ArTreeContractInitServiceImpl {
-    private final IWbsTreeService wbsTreeService;
+
 
     private final IContractInfoService contractInfoService;
 
     private final ProjectClient projectClient;
 
-    /**
-     * 按照层次获取公共归档树
-     * @param parentId
-     * @param wbsId
-     * @param tenantId
-     * @param type
-     * @param level 层次,1,单位工程,2
-     * @return
-     */
-    public List<ArchiveTree> getWbsArchiveTree(Long parentId, String wbsId, String tenantId, String type,Long level)
-    {
-        List<ArchiveTree> archiveTreeList = new ArrayList<>();
-
-        List<WbsTreeVO2> wbsTreeVO2s = wbsTreeService.tree(wbsId, tenantId, type);
-
-        //遍历构建
-        for (WbsTreeVO2 wbsTreeVO2:wbsTreeVO2s) {
-            //只展示指定层级之上的
-            if (wbsTreeVO2.getNodeType() > level){
-                continue;
-            }
-
-            ArchiveTree archiveTree = new ArchiveTree();
-            archiveTree.setId(SnowFlakeUtil.getId());
-            archiveTree.setParentId(parentId);
-            archiveTree.setNodeName(wbsTreeVO2.getTitle());
-            archiveTree.setExtId(wbsTreeVO2.getId());
-            archiveTree.setDisplayHierarchy(level.toString());
-            archiveTreeList.add(archiveTree);
-        }
-
-        //设置pid
-
-        return archiveTreeList;
-    }
-
     /**
      *
      * @param tenantId
@@ -104,7 +68,17 @@ public class ArTreeContractInitServiceImpl {
         //拷贝第一层
         copyChild(tenantId,projectId,null,archiveTreeContract.getId(),tree.getChildren(),archiveTreeContracts,oldNewMap);
 
-        //拷贝
+        //遍历打
+        for (ArchiveTreeContract ar:archiveTreeContracts) {
+            if (ar.getNodeName().indexOf("施工") >= 0) {
+                ar.setTreeCode("C");
+            }else if (ar.getNodeName().indexOf("监理") >= 0) {
+                ar.setTreeCode("S");
+            }
+        }
+
+
+        //拷贝建设,施工,监理下的树
         for (ArchiveTreeVO2 child: tree.getChildren()) {
             if (child.getTitle().indexOf("施工") >= 0 && bHasCon) {
                 for (ContractInfo contractInfo:contracts) {
@@ -125,6 +99,7 @@ public class ArTreeContractInitServiceImpl {
             }
         }
 
+
         //设置祖先id
         InitAncestors(archiveTreeContracts);
 
@@ -155,6 +130,8 @@ public class ArTreeContractInitServiceImpl {
         contractNode.setParentId(newRootId);
         contractNode.setProjectId(projectId);
         contractNode.setContractId(contractInfo.getId());
+        //设置权限编码
+        contractNode.setTreeCode(contractInfo.getId().toString());
         contractNode.setIsDeleted(0);
         archiveTreeContracts.add(contractNode);
 
@@ -234,6 +211,7 @@ public class ArTreeContractInitServiceImpl {
 
             if (contractId != null ) {
                 archiveTreeContract.setContractId(contractId);
+                archiveTreeContract.setTreeCode(contractId.toString());
             }
 
             archiveTreeContracts.add(archiveTreeContract);

+ 28 - 93
blade-service/blade-manager/src/main/java/org/springblade/manager/service/impl/ArchiveTreeContractServiceImpl.java

@@ -23,6 +23,7 @@ import com.mixsmart.utils.StringUtils;
 import lombok.AllArgsConstructor;
 import org.springblade.common.utils.SnowFlakeUtil;
 import org.springblade.core.log.exception.ServiceException;
+import org.springblade.core.secure.BladeUser;
 import org.springblade.core.secure.utils.AuthUtil;
 import org.springblade.core.tool.constant.BladeConstant;
 import org.springblade.core.tool.node.ForestNodeMerger;
@@ -76,95 +77,11 @@ public class ArchiveTreeContractServiceImpl extends BaseServiceImpl<ArchiveTreeC
 	public IPage<ArchiveTreeContractVO> selectArchiveTreeContractPage(IPage<ArchiveTreeContractVO> page, ArchiveTreeContractVO archiveTreeContract) {
 		return page.setRecords(baseMapper.selectArchiveTreeContractPage(page, archiveTreeContract));
 	}
-	@Override
-	public boolean initTree(String tenantId, Long projectId, List<ArchiveTree> trees){
-		boolean bCreate = false;
-		QueryWrapper<ArchiveTreeContract> queryWrapper = new QueryWrapper<>();
-		queryWrapper.eq("parent_id", 0);
-		queryWrapper.eq("ancestors", 0);
-		queryWrapper.eq("tenant_id", tenantId);
-		queryWrapper.eq("project_id", projectId);
-
-		queryWrapper.eq("status", 1);
-		queryWrapper.eq("is_deleted", 0);
-		ArchiveTreeContract archiveTreeContract = archiveTreeContractMapper.selectOne(queryWrapper);
-		if (archiveTreeContract == null) {
-			bCreate = true;
-		}
-
-
-		//todo 同步新增节点
-
-
-
-		//系统模板的
-		List<ArchiveTreeContract> archiveTreeContracts = new ArrayList<>();
-		Map<Long,Long> oldNewMap = new LinkedHashMap<>();
-
-		Map<Long,ArchiveTree> archiveMap = new LinkedHashMap<>();
-
-		for (ArchiveTree archiveTreeVO :trees) {
-			oldNewMap.put(archiveTreeVO.getId(), SnowFlakeUtil.getId());
-			archiveMap.put(archiveTreeVO.getId(), archiveTreeVO);
-		}
-		oldNewMap.put(0L,0L);
-
-		for (ArchiveTree archiveTreeVO :trees) {
-
-			ArchiveTreeContract archiveTree = new ArchiveTreeContract(archiveTreeVO);
-			archiveTree.setId(oldNewMap.get(archiveTreeVO.getId()));
-			archiveTree.setParentId(oldNewMap.get(archiveTreeVO.getParentId()));
-			archiveTree.setCreateUser(AuthUtil.getUserId());
-			archiveTree.setProjectId(projectId);
-
-			String anCenstors = archiveTreeVO.getAncestors();
-			if (StringUtils.isNotEmpty(anCenstors)) {
-				String newAnCenstors = "";
-				String arrAnCenstor[] = anCenstors.split(",");
-				if (arrAnCenstor.length > 0) {
-
-					for (String anCenstor: arrAnCenstor) {
-						Long anCenstorId = Long.parseLong(anCenstor);
-						Long newAnCenstorId = oldNewMap.get(anCenstorId);
-						if (newAnCenstorId!= null) {
-							if (newAnCenstors.length() == 0) {
-								newAnCenstors += newAnCenstorId;
-							}else {
-								newAnCenstors += (","+ newAnCenstorId);
-							}
-						}
-					}
-				}
-				archiveTree.setAncestors(newAnCenstors);
-			}
-
-			archiveTreeContracts.add(archiveTree);
-		}
-
-		//todo 同步合同划分
-
-		//todo 生成动态节点
-		List<ArchiveTreeContractVO2> archiveTreeContractVO2List = this.tree2(tenantId,1,null,projectId);
-
-		//todo 遍历找到关联质检资料的节点,取出合同段
-
-		//todo 处理文件提名
-
-		//todo 立卷规则
-
-		//todo 同步划分树节点到案卷列表
-
-
-
-		this.saveBatch(archiveTreeContracts);
-		return true;
-	}
-
 
 	@Override
 	public boolean initTree2(String tenantId, Long projectId){
 
-		List<ArchiveTreeVO2> tree = archiveTreeService.tree2(AuthUtil.getTenantId(), null, null);
+		List<ArchiveTreeVO2> tree = archiveTreeService.tree2(AuthUtil.getTenantId(), projectId,null, null,null);
 		if (tree == null || tree.size() == 0) {
 			return false;
 		}
@@ -178,13 +95,9 @@ public class ArchiveTreeContractServiceImpl extends BaseServiceImpl<ArchiveTreeC
 
 		arTreeContractInitService.copyTree(tenantId,projectId,projectInfo.getProjectName(),tree.get(0),archiveTreeContracts,contractInfoVOS);
 
-	    //todo 同步动态节点
-
-		//todo 遍历找到关联质检资料的节点,取出合同段
-
-		//todo 处理文件提名
+	    //todo 同步质检资料动态节点,处理文件提名
 
-		//todo 立卷规则
+		//todo 同步立卷规则
 
 		//todo 同步划分树节点到案卷列表
 
@@ -211,12 +124,13 @@ public class ArchiveTreeContractServiceImpl extends BaseServiceImpl<ArchiveTreeC
 		if (AuthUtil.isAdministrator()) {
 			tenantId = StringPool.EMPTY;
 		}
-		return ForestNodeMerger.merge(baseMapper.lazyTree2(tenantId, parentId,projectId));
+		return ForestNodeMerger.merge(baseMapper.lazyTree2(tenantId, parentId,projectId,getAuthCode(),getAuthContractId()));
 	}
 
 	@Override
 	public List<ArchiveTreeContractVO2> tree2(String tenantId, Integer disPlayTree, Integer nodeType, Long projectId) {
-		return ForestNodeMerger.merge(baseMapper.tree2(tenantId, disPlayTree, nodeType,projectId));
+
+		return ForestNodeMerger.merge(baseMapper.tree2(tenantId, disPlayTree, nodeType,projectId,getAuthCode(),getAuthContractId()));
 	}
 
 	/**
@@ -509,4 +423,25 @@ public class ArchiveTreeContractServiceImpl extends BaseServiceImpl<ArchiveTreeC
 		}
 	}
 
+	/**
+	 * 返回所属的合同段,没有则范围“”
+	 * @return
+	 */
+	public String getAuthContractId() {
+		String contractId ="";
+		BladeUser bladeUser = AuthUtil.getUser();
+
+		return contractId;
+	}
+
+	/**
+	 * 施工则返回“C”,监理则返回“S”,其他返回“”
+	 * @return
+	 */
+	public String getAuthCode() {
+		String code ="";
+		BladeUser bladeUser = AuthUtil.getUser();
+		return code;
+	}
+
 }

+ 238 - 28
blade-service/blade-manager/src/main/java/org/springblade/manager/service/impl/ArchiveTreeServiceImpl.java

@@ -5,20 +5,29 @@ import com.baomidou.mybatisplus.core.toolkit.StringPool;
 import com.baomidou.mybatisplus.core.toolkit.StringUtils;
 import com.baomidou.mybatisplus.core.toolkit.Wrappers;
 import lombok.AllArgsConstructor;
+import org.springblade.common.utils.SnowFlakeUtil;
 import org.springblade.core.log.exception.ServiceException;
 import org.springblade.core.secure.utils.AuthUtil;
 import org.springblade.core.tool.constant.BladeConstant;
-import org.springblade.core.tool.node.ForestNodeMerger;
+
 import org.springblade.core.tool.utils.Func;
 import org.springblade.manager.dto.ArchiveTreeDTO;
 import org.springblade.manager.dto.ArchiveTreeSortDTO;
 import org.springblade.manager.entity.ArchiveTree;
+import org.springblade.manager.entity.ArchiveTreeContract;
+import org.springblade.manager.entity.ProjectInfo;
+import org.springblade.manager.service.IProjectInfoService;
+import org.springblade.manager.service.IWbsTreePrivateService;
+import org.springblade.manager.service.IWbsTreeService;
 import org.springblade.manager.utils.DiffListUtil;
+import org.springblade.manager.utils.ForestNodeMerger;
+import org.springblade.manager.vo.ArchiveTreeContractVO2;
 import org.springblade.manager.vo.ArchiveTreeVO;
 import org.springblade.manager.mapper.ArchiveTreeMapper;
 import org.springblade.manager.service.IArchiveTreeService;
 import org.springblade.core.mp.base.BaseServiceImpl;
 import org.springblade.manager.vo.ArchiveTreeVO2;
+import org.springblade.manager.vo.WbsTreeVO2;
 import org.springframework.stereotype.Service;
 
 import java.util.*;
@@ -30,11 +39,15 @@ public class ArchiveTreeServiceImpl extends BaseServiceImpl<ArchiveTreeMapper, A
 
     private final ArchiveTreeMapper archiveTreeMapper;
     private final ArTreeContractInitServiceImpl archiveTreeContractInitService;
+    private final IWbsTreeService wbsTreeService;
+    private final IWbsTreePrivateService wbsTreePrivateService;
+    private final IProjectInfoService projectInfoService;
 
     @Override
     public boolean initArchiveTree() {
         QueryWrapper<ArchiveTree> queryWrapper = new QueryWrapper<>();
         queryWrapper.eq("parent_id", 0);
+        queryWrapper.eq("project_id", 0);
         queryWrapper.eq("ancestors", 0);
         queryWrapper.eq("status", 1);
         ArchiveTree archiveTree1 = archiveTreeMapper.selectOne(queryWrapper);
@@ -53,17 +66,131 @@ public class ArchiveTreeServiceImpl extends BaseServiceImpl<ArchiveTreeMapper, A
         return this.save(archiveTree);
     }
 
-
     @Override
-    public List<ArchiveTreeVO> lazyTree(String tenantId, Long parentId) {
-        if (AuthUtil.isAdministrator()) {
-            tenantId = StringPool.EMPTY;
+    public boolean initArchiveProjectTree(Long projectId) {
+
+        if (projectId == null || projectId == 0) {
+            return false;
         }
-        return ForestNodeMerger.merge(baseMapper.lazyTree(tenantId, parentId));
+        QueryWrapper<ArchiveTree> queryWrapper = new QueryWrapper<>();
+        queryWrapper.eq("parent_id", 0);
+        queryWrapper.eq("project_id", projectId);
+        queryWrapper.eq("status", 1);
+        queryWrapper.eq("is_deleted", 0);
+        ArchiveTree archiveTree1 = archiveTreeMapper.selectOne(queryWrapper);
+        if (archiveTree1 != null) {
+            throw new ServiceException("根节点已存在,请先删除后再进行初始化");
+        }
+
+        List<ArchiveTree> sysTrees = this.treeList(AuthUtil.getTenantId(), 0L,null, null);
+        if (sysTrees == null || sysTrees.size() == 0) {
+            return false;
+        }
+
+        List<ArchiveTree> archiveTrees = new ArrayList<>();
+        Map<Long,Long> oldNewMap = new LinkedHashMap<>();
+
+        Map<Long,ArchiveTree> archiveMap = new LinkedHashMap<>();
+
+        for (ArchiveTree archiveTree :sysTrees) {
+            oldNewMap.put(archiveTree.getId(), SnowFlakeUtil.getId());
+            archiveMap.put(archiveTree.getId(), archiveTree);
+        }
+        oldNewMap.put(0L,0L);
+
+        for (ArchiveTree node :sysTrees) {
+
+            ArchiveTree archiveTree = new ArchiveTree(node);
+            archiveTree.setId(oldNewMap.get(node.getId()));
+            archiveTree.setParentId(oldNewMap.get(node.getParentId()));
+            archiveTree.setCreateUser(AuthUtil.getUserId());
+            archiveTree.setProjectId(projectId);
+
+
+            String anCenstors = archiveTree.getAncestors();
+            if (com.mixsmart.utils.StringUtils.isNotEmpty(anCenstors)) {
+                String newAnCenstors = "";
+                String arrAnCenstor[] = anCenstors.split(",");
+                if (arrAnCenstor.length > 0) {
+
+                    for (String anCenstor: arrAnCenstor) {
+                        Long anCenstorId = Long.parseLong(anCenstor);
+                        Long newAnCenstorId = oldNewMap.get(anCenstorId);
+                        if (newAnCenstorId!= null) {
+                            if (newAnCenstors.length() == 0) {
+                                newAnCenstors += newAnCenstorId;
+                            }else {
+                                newAnCenstors += (","+ newAnCenstorId);
+                            }
+                        }
+                    }
+                }
+                archiveTree.setAncestors(newAnCenstors);
+            }
+
+            archiveTrees.add(archiveTree);
+        }
+
+        this.saveBatch(archiveTrees);
+
+        return true;
     }
 
+    public boolean initArchiveProjectTree1(Long projectId) {
+        QueryWrapper<ArchiveTree> queryWrapper = new QueryWrapper<>();
+        queryWrapper.eq("parent_id", 0);
+        queryWrapper.eq("project_id", 0);
+        queryWrapper.eq("status", 1);
+        queryWrapper.eq("is_deleted", 0);
+        ArchiveTree archiveTree1 = archiveTreeMapper.selectOne(queryWrapper);
+        if (archiveTree1 != null) {
+            throw new ServiceException("根节点已存在,请先删除后再进行初始化");
+        }
+
+        List<ArchiveTreeVO2> sysTrees = this.tree2(AuthUtil.getTenantId(), projectId,null, null,null);
+        if (sysTrees == null || sysTrees.size() == 0) {
+            return false;
+        }
+
+        List<ArchiveTreeVO2> trees = new ArrayList<>();
+        ForestNodeMerger.getTreeList(sysTrees.get(0),trees);
+
+        List<ArchiveTree> archiveTrees = new ArrayList<>();
+        Map<Long,Long> oldNewMap = new LinkedHashMap<>();
+
+        Map<Long,ArchiveTreeVO2> archiveMap = new LinkedHashMap<>();
+
+        for (ArchiveTreeVO2 archiveTreeVO :trees) {
+            oldNewMap.put(archiveTreeVO.getId(), SnowFlakeUtil.getId());
+            archiveMap.put(archiveTreeVO.getId(), archiveTreeVO);
+        }
+        oldNewMap.put(0L,0L);
+
+        for (ArchiveTreeVO2 archiveTreeVO :trees) {
+
+            ArchiveTree archiveTree = new ArchiveTree(archiveTreeVO);
+            archiveTree.setId(oldNewMap.get(archiveTreeVO.getId()));
+            archiveTree.setParentId(oldNewMap.get(archiveTreeVO.getParentId()));
+            archiveTree.setCreateUser(AuthUtil.getUserId());
+            archiveTree.setProjectId(projectId);
+            archiveTrees.add(archiveTree);
+        }
+
+
+        return true;
+    }
+
+
+//    @Override
+//    public List<ArchiveTreeVO> lazyTree(String tenantId, Long parentId) {
+//        if (AuthUtil.isAdministrator()) {
+//            tenantId = StringPool.EMPTY;
+//        }
+//        return ForestNodeMerger.merge(baseMapper.lazyTree(tenantId, parentId));
+//    }
+
     @Override
-    public List<ArchiveTreeVO2> lazyTree2(String tenantId, Long parentId, Long extId,Long level) {
+    public List<ArchiveTreeVO2> lazyTree2(String tenantId, Long projectId, Long parentId, Long extId,Long level) {
         if (AuthUtil.isAdministrator()) {
             tenantId = StringPool.EMPTY;
         }
@@ -71,14 +198,19 @@ public class ArchiveTreeServiceImpl extends BaseServiceImpl<ArchiveTreeMapper, A
         //获取父节点的信息
         List<ArchiveTreeVO2> archiveTreeVO2List = null;
         //带关联节点则从
-        if (extId != null && level != null) {
-            //从wbs树获取
-            String wbsId = extId.toString();
-            archiveTreeContractInitService.getWbsArchiveTree(parentId,wbsId,tenantId,"1",level);
+        if (extId != null && level != null && projectId != null) {
+            //从系统级wbs树获取
+//            if (projectId == 0) {
+//                String wbsId = extId.toString();
+//                this.getWbsArchiveTree(tenantId,null,parentId,wbsId,"1",level);
+//            }else {
+//
+//            }
+
 
         }//征程流程
         else {
-            archiveTreeVO2List = baseMapper.lazyTree2(tenantId, parentId);
+            archiveTreeVO2List = baseMapper.lazyTree2(tenantId, projectId,parentId);
             //质检资料关联节点设置成有子树
             for (ArchiveTreeVO2 archiveTreeVO2:archiveTreeVO2List) {
                 if (archiveTreeVO2.getAssociationType() != null && archiveTreeVO2.getAssociationType() == 1) {
@@ -90,22 +222,45 @@ public class ArchiveTreeServiceImpl extends BaseServiceImpl<ArchiveTreeMapper, A
         return ForestNodeMerger.merge(archiveTreeVO2List);
     }
 
-    @Override
-    public List<ArchiveTreeVO> tree(String tenantId, Integer disPlayTree, Integer nodeType) {
-        List<ArchiveTreeVO> archiveTreeVOList = baseMapper.tree(tenantId, disPlayTree, nodeType);
-//        for (ArchiveTreeVO vo:archiveTreeVOList) {
-//            System.out.println();
-//        }
-        return ForestNodeMerger.merge(archiveTreeVOList);
-    }
+//    @Override
+//    public List<ArchiveTreeVO> tree(String tenantId, Integer disPlayTree, Integer nodeType) {
+//        List<ArchiveTreeVO> archiveTreeVOList = baseMapper.tree(tenantId, disPlayTree, nodeType);
+//
+//        return ForestNodeMerger.merge(archiveTreeVOList);
+//    }
 
     @Override
-    public List<ArchiveTreeVO2> tree2(String tenantId, Integer disPlayTree, Integer nodeType) {
-        List<ArchiveTreeVO2> archiveTreeVOList = baseMapper.tree2(tenantId, disPlayTree, nodeType);
-//        for (ArchiveTreeVO2 vo2:archiveTreeVOList) {
-//            System.out.println();
-//        }
-        return ForestNodeMerger.merge(archiveTreeVOList);
+    public List<ArchiveTreeVO2> tree2(String tenantId,Long projectId, Integer disPlayTree, Integer nodeType,String wbsId) {
+        List<ArchiveTreeVO2> archiveTreeVOList = baseMapper.tree2(tenantId, projectId,disPlayTree, nodeType);
+        List<ArchiveTreeVO2> treeVO2s = ForestNodeMerger.merge(archiveTreeVOList);
+        //todo 遍历树,找到质检节点,调用getWbsArchiveTree,根据关联层级,拼接上去
+        //待传入wbsId,把child 加入ar的childred
+        if (StringUtils.isEmpty(wbsId) && projectId != 0) {
+            ProjectInfo projectInfo = projectInfoService.getOne(projectId);
+            if (projectInfo!= null) {
+                Long lWbsId = projectInfo.getReferenceWbsTemplateId();
+                if (lWbsId != null) {
+                    wbsId = projectInfo.getReferenceWbsTemplateId().toString();
+                }
+            }
+        }
+
+        if (StringUtils.isNotEmpty(wbsId)) {
+            for (ArchiveTreeVO2 ar : archiveTreeVOList) {
+                //关联质检资料
+                if (ar.getAssociationType()!= null
+                        &&  ar.getAssociationType() == 1
+                        && ar.getDisplayHierarchy() != null ) {
+                    ArchiveTreeVO2 child = getWbsArchiveTree(tenantId,projectId,ar.getId(),
+                            wbsId,"1",Long.parseLong(ar.getDisplayHierarchy()));
+
+                    if (child!= null) {
+                        ar.getChildren().add(child);
+                    }
+                }
+            }
+        }
+        return treeVO2s;
     }
 
     @Override
@@ -210,9 +365,64 @@ public class ArchiveTreeServiceImpl extends BaseServiceImpl<ArchiveTreeMapper, A
     }
 
     @Override
-    public List<ArchiveTree> treeList(String tenantId, Integer disPlayTree, Integer nodeType) {
+    public List<ArchiveTree> treeList(String tenantId, Long projectId, Integer disPlayTree, Integer nodeType) {
         return          baseMapper.selectList(Wrappers.<ArchiveTree>query().lambda()
-                .eq(ArchiveTree::getTenantId, tenantId).eq(ArchiveTree::getIsDeleted,0).orderByAsc(ArchiveTree::getSort));
+                .eq(ArchiveTree::getTenantId, tenantId).eq(ArchiveTree::getIsDeleted,0)
+                .eq(ArchiveTree::getProjectId,projectId).orderByAsc(ArchiveTree::getSort));
+    }
+
+    /**
+     * 按照层次获取归档树链表
+     * @param parentId
+     * @param wbsId
+     * @param tenantId
+     * @param type
+     * @param level 层次,1,单位工程,2
+     * @return
+     */
+    public ArchiveTreeVO2 getWbsArchiveTree(String tenantId, Long projectId,Long parentId, String wbsId, String type,Long level)
+    {
+        List<ArchiveTreeVO2> archiveTreeList = new ArrayList<>();
+
+        List<WbsTreeVO2> wbsTreeVO2s = null;
+
+        if (projectId == 0) {
+            wbsTreeVO2s = wbsTreeService.tree(wbsId, tenantId, type);
+        }else {
+            wbsTreeVO2s = wbsTreePrivateService.tree2(wbsId, projectId.toString());
+        }
+
+        List<WbsTreeVO2> wbsTreeVO2List = new ArrayList<>();
+        ForestNodeMerger.getTreeList(wbsTreeVO2s.get(0),wbsTreeVO2List);
+
+        //遍历构建
+        for (WbsTreeVO2 wbsTreeVO2:wbsTreeVO2List) {
+            //只展示指定层级之上的
+            if (wbsTreeVO2.getMajorDataType() != null ) {
+                if (wbsTreeVO2.getMajorDataType() == 1
+                    || wbsTreeVO2.getMajorDataType() == 2
+                    || wbsTreeVO2.getMajorDataType() == 3){
+                    continue;
+                }
+            }
+            if (wbsTreeVO2.getNodeType() > level){
+                continue;
+            }
+            ArchiveTreeVO2 archiveTree = new ArchiveTreeVO2();
+            archiveTree.setId(wbsTreeVO2.getId());
+            archiveTree.setParentId(wbsTreeVO2.getParentId());
+            archiveTree.setTitle(wbsTreeVO2.getTitle());
+            archiveTree.setExtId(wbsTreeVO2.getId());
+            archiveTree.setDisplayHierarchy(level.toString());
+            archiveTreeList.add(archiveTree);
+        }
+
+        //设置pid
+        List<ArchiveTreeVO2> archiveTreeVO2s = ForestNodeMerger.merge(archiveTreeList);
+        if (archiveTreeVO2s != null && archiveTreeVO2s.size() > 0 ) {
+            return archiveTreeVO2s.get(0);
+        }
+        return null;
     }
 
 

+ 11 - 6
blade-service/blade-manager/src/main/java/org/springblade/manager/service/impl/FormulaServiceImpl.java

@@ -248,9 +248,6 @@ public class FormulaServiceImpl extends BaseServiceImpl<FormulaMapper, Formula>
 
     public Map<String, String> getTableCols(AppWbsTreeContractVO wbsTreeContract) throws FileNotFoundException {
         Map<String, String> dataMap = new HashMap<>();
-        if (Func.isEmpty(wbsTreeContract.getHtmlUrl())) {
-            return dataMap;
-        }
         File file1 = ResourceUtil.getFile(wbsTreeContract.getHtmlUrl());
         FileInputStream fileInputStream = new FileInputStream(file1);
         String htmlString = IoUtil.readToString(fileInputStream);
@@ -741,7 +738,7 @@ public class FormulaServiceImpl extends BaseServiceImpl<FormulaMapper, Formula>
                  Formula formula=fd.getFormula();
                  String f=formula.getFormula();
                  if (f.contains("converge")){
-                     Matcher m = RegexUtils.matcher("T\\(com.mixsmart.utils.CustomFunction\\)\\.(\\w+)\\(([^]]+)\\)",f);
+                     Matcher m = RegexUtils.matcher("T\\(com.mixsmart.utils.CustomFunction\\)\\.(converge)\\(([^)]+)\\)",f);
                      while (m.find()){
                          List<FormData> target = getFormDataByCode(m.group(2));
                          Object data =target.stream().flatMap(e->e.getValues().stream()).map(ElementData::getValue).collect(Collectors.toList());
@@ -749,7 +746,7 @@ public class FormulaServiceImpl extends BaseServiceImpl<FormulaMapper, Formula>
                      }
                  }
                  if(f.contains("compound")){
-                     Matcher m = RegexUtils.matcher("T\\(com.mixsmart.utils.CustomFunction\\)\\.(compound)\\(([^]]+)\\)",f);
+                     Matcher m = RegexUtils.matcher("T\\(com.mixsmart.utils.CustomFunction\\)\\.(compound)\\(([^)]+)\\)",f);
                      while (m.find()){
                          List<FormData> target = getFormDataByCode(m.group(2));
                          List<List<Object>> values=target.stream().map(e->e.getValues().stream().map(ElementData::getValue).collect(Collectors.toList())).collect(Collectors.toList());
@@ -759,10 +756,13 @@ public class FormulaServiceImpl extends BaseServiceImpl<FormulaMapper, Formula>
                              data.put(eNames.get(i),values.get(i));
                          }
                          f=f.replace(m.group(),putDataWithKey(data));
+                         if(f.contains("ENAME")){
+                             f=f.replace("ENAME",putDataWithKey(target.stream().map(FormData::getEName).collect(Collectors.toList())));
+                         }
                      }
                  }
                  if(f.contains(".option")){
-                     Matcher m = RegexUtils.matcher("T\\(com.mixsmart.utils.CustomFunction\\)\\.(option)\\(([^]]+)\\)",f);
+                     Matcher m = RegexUtils.matcher("T\\(com.mixsmart.utils.CustomFunction\\)\\.(optionC?)\\(([^)]+)\\)",f);
                      while (m.find()){
                        String[] args= m.group(2).split(",");
                        String flag=args[0];
@@ -774,6 +774,11 @@ public class FormulaServiceImpl extends BaseServiceImpl<FormulaMapper, Formula>
                                Map<String,Object> dictMap = (Map<String, Object>) this.constantMap.computeIfAbsent("OPTION",k->new HashMap<>());
                                flag=StringUtils.handleNull(dictMap.get(findStr));
                            }
+                       }else if(flag.contains("E[")){
+                           List<FormData> target = getFormDataByCode(flag);
+                           if(target.size()>1){
+                              flag= target.get(0).getValues().stream().map(ElementData::stringValue).filter(StringUtils::isNotEmpty).findFirst().orElse("0");
+                           }
                        }
                        if(Func.isBlank(flag)){
                            /*默认0*/

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

@@ -6,6 +6,7 @@ import com.baomidou.mybatisplus.core.metadata.IPage;
 import com.baomidou.mybatisplus.core.toolkit.ObjectUtils;
 import com.baomidou.mybatisplus.core.toolkit.StringUtils;
 import com.baomidou.mybatisplus.core.toolkit.Wrappers;
+import com.google.common.collect.Lists;
 import lombok.AllArgsConstructor;
 import org.jsoup.Jsoup;
 import org.jsoup.nodes.Document;
@@ -20,7 +21,6 @@ import org.springblade.core.tool.api.R;
 import org.springblade.core.tool.constant.BladeConstant;
 import org.springblade.core.tool.node.ForestNodeMerger;
 import org.springblade.core.tool.utils.*;
-import org.springblade.manager.dto.WbsTreeContractDTO;
 import org.springblade.manager.dto.WbsTreePrivateDTO2;
 import org.springblade.manager.dto.WbsTreePrivateDTO3;
 import org.springblade.manager.entity.*;
@@ -34,10 +34,16 @@ import org.springframework.scheduling.annotation.Scheduled;
 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.IOException;
 import java.util.*;
+import java.util.concurrent.Callable;
+import java.util.concurrent.CompletableFuture;
+import java.util.concurrent.Future;
+import java.util.concurrent.ThreadPoolExecutor;
+import java.util.function.Function;
 import java.util.stream.Collectors;
 
 @Service
@@ -46,8 +52,6 @@ public class WbsTreePrivateServiceImpl extends BaseServiceImpl<WbsTreePrivateMap
 
     private final WbsTreeContractMapper wbsTreeContractMapper;
     private final WbsTreeContractServiceImpl wbsTreeContractService;
-
-    // 表单主表信息
     private final ITableInfoService tableInfoService;
     private final WbsTreeMapper wbsTreeMapper;
     private final ContractInfoMapper contractInfoMapper;
@@ -57,6 +61,10 @@ public class WbsTreePrivateServiceImpl extends BaseServiceImpl<WbsTreePrivateMap
     private final ProjectInfoMapper projectInfoMapper;
     private final WbsTreePrivateMapper wbsTreePrivateMapper;
     private final JdbcTemplate jdbcTemplate;
+    private final TextdictInfoServiceImpl textDictInfoService;
+
+    @Resource(name = "taskExecutor1")
+    private ThreadPoolExecutor executor;
 
     @Override
     public List<WbsTreePrivateVO> tree(String wbsId, String projectId) {
@@ -74,6 +82,22 @@ public class WbsTreePrivateServiceImpl extends BaseServiceImpl<WbsTreePrivateMap
         return null;
     }
 
+    @Override
+    public List<WbsTreeVO2> tree2(String wbsId, String projectId) {
+        WbsInfo wbsInfo = wbsInfoMapper.selectOne(Wrappers.<WbsInfo>query().lambda().eq(WbsInfo::getId, wbsId));
+        if (wbsInfo != null) {
+            //公有引用
+            return ForestNodeMerger.merge(baseMapper.tree2(wbsId, projectId, wbsInfo.getWbsType()));
+        } else {
+            //私有引用
+            WbsTreePrivate nodeRoot = wbsTreePrivateMapper.selectOne(Wrappers.<WbsTreePrivate>query().lambda().eq(WbsTreePrivate::getWbsId, wbsId).eq(WbsTreePrivate::getProjectId, projectId).eq(WbsTreePrivate::getParentId, 0L));
+            if (nodeRoot != null) {
+                return ForestNodeMerger.merge(baseMapper.tree2(wbsId, projectId, Integer.valueOf(nodeRoot.getWbsType())));
+            }
+        }
+        return null;
+    }
+
     @Override
     @Transactional(rollbackFor = Exception.class)
     public boolean submit(WbsTreePrivate wbsTreePrivate) {
@@ -1601,6 +1625,148 @@ public class WbsTreePrivateServiceImpl extends BaseServiceImpl<WbsTreePrivateMap
         return R.data(table + "");
     }
 
+    @Override
+    public boolean syncProjectEVisa(String projectId) {
+        if (StringUtils.isNotEmpty(projectId)) {
+            ProjectInfo projectInfo = projectInfoMapper.selectById(projectId);
+            if (projectInfo != null && ("private").equals(projectInfo.getReferenceWbsTemplateType()) && ObjectUtils.isNotEmpty(projectInfo.getReferenceWbsTemplateId())) {
+                //构造参数集合
+                List<TextdictInfo> insertData = new ArrayList<>();
+                Map<String, List<TextdictInfo>> textDictInfoData = new HashMap<>();
+
+                //获取当前引用的项目节点树的根节点信息
+                WbsTreePrivate oneRecordRoot = this.getOne(Wrappers.<WbsTreePrivate>lambdaQuery().eq(WbsTreePrivate::getPKeyId, projectInfo.getReferenceWbsTemplateId()));
+
+                //获取当前项目下节点树所有节点、表、独立表
+                String sqlNodeTreeAllNow = "SELECT p_key_id,id,type,parent_id,html_url FROM m_wbs_tree_private WHERE project_id = " + projectId + " AND STATUS = 1 AND is_deleted = 0 AND (((type = 1 OR type = 2) AND wbs_type = 1) OR (type= 10 AND parent_id = -10 ))";
+                List<WbsTreePrivate> wbsTreePrivatesNodeAndTabNow = jdbcTemplate.query(sqlNodeTreeAllNow, new BeanPropertyRowMapper<>(WbsTreePrivate.class));
+                List<WbsTreePrivate> wbsTreePrivatesTableDL = wbsTreePrivatesNodeAndTabNow.stream().filter(f -> f.getType().equals(10) && f.getParentId().equals(-10L)).collect(Collectors.toList());
+
+                //获取当前项目节点树
+                Map<Long, WbsTreePrivate> nowNodeTreeAll = wbsTreePrivatesNodeAndTabNow.stream().filter(f -> f.getType().equals(1)).collect(Collectors.toList()).stream()
+                        .collect(Collectors.toMap(WbsTreePrivate::getId, Function.identity()));
+
+                //获取当前引用的节点树下所有节点、表、独立表
+                String sqlNodeTreeAllOld = "SELECT p_key_id,id,type,parent_id FROM m_wbs_tree_private WHERE project_id = " + oneRecordRoot.getProjectId() + " AND STATUS = 1 AND is_deleted = 0 AND (((type = 1 OR type = 2) AND wbs_id = " + oneRecordRoot.getWbsId() + ") OR ((type= 10 OR parent_id = -10 ) AND wbs_id IS NULL))";
+                List<WbsTreePrivate> wbsTreePrivatesNodeAndTab = jdbcTemplate.query(sqlNodeTreeAllOld, new BeanPropertyRowMapper<>(WbsTreePrivate.class));
+
+                //获取当前对应电签位置配置信息
+                List<WbsTreePrivate> collect1 = wbsTreePrivatesNodeAndTab.stream().filter(f -> f.getType().equals(10) || f.getType().equals(2)).collect(Collectors.toList());
+                List<Long> pKeyIds = collect1.stream().map(WbsTreePrivate::getPKeyId).collect(Collectors.toList());
+
+                //分组查询
+                List<TextdictInfo> textDictInfosAll = new ArrayList<>();
+                List<List<Long>> partition = Lists.partition(pKeyIds, 1000);
+                for (List<Long> ids : partition) {
+                    String sql = "select id,name,type,tab_id,col_key,sig_role_id,is_deleted,sig_role_name,col_name,pyzbx,pyzby from m_textdict_info where tab_id in(" + org.apache.commons.lang.StringUtils.join(ids, ",") + ")";
+                    List<TextdictInfo> textDictInfos = jdbcTemplate.query(sql, new BeanPropertyRowMapper<>(TextdictInfo.class));
+                    textDictInfosAll.addAll(textDictInfos);
+                }
+
+                Map<String, List<TextdictInfo>> collect3 = textDictInfosAll.stream().collect(Collectors.groupingBy(TextdictInfo::getTabId));
+
+                //构造原始电签信息
+                for (WbsTreePrivate wbsTreePrivate : collect1) {
+                    if (wbsTreePrivate.getType() == 2) {
+                        WbsTreePrivate obj = nowNodeTreeAll.get(wbsTreePrivate.getParentId());
+                        assert obj != null;
+                        List<TextdictInfo> textDictInfos = collect3.get(String.valueOf(wbsTreePrivate.getPKeyId()));
+                        if (textDictInfos != null && textDictInfos.size() > 0) {
+                            textDictInfoData.put(wbsTreePrivate.getPKeyId() + "," + wbsTreePrivate.getId(), textDictInfos);
+                        }
+                    }
+
+                    if (wbsTreePrivate.getType() == 10 && wbsTreePrivate.getParentId() == -10) { //type=10,parentId=-10 独立库
+                        //判断是否存在独立表单,存在则不新增
+                        List<WbsTreePrivate> collect = wbsTreePrivatesTableDL.stream().filter(f -> f.getId().equals(wbsTreePrivate.getId())).collect(Collectors.toList());
+                        if (collect.size() == 0) {
+                            //根据元素表pKeyId,获取电签位置匹配信息、编辑默认信息
+                            List<TextdictInfo> textDictInfos = collect3.get(String.valueOf(wbsTreePrivate.getPKeyId()));
+                            if (textDictInfos != null && textDictInfos.size() > 0) {
+                                textDictInfoData.put(wbsTreePrivate.getPKeyId() + "," + wbsTreePrivate.getId(), textDictInfos);
+                            }
+                        }
+                    }
+                }
+
+                //只同步独立库中有关联过清表的元素表type=10,以及原始方式的元素表type=2
+                List<WbsTreePrivate> collect = wbsTreePrivatesNodeAndTabNow.stream().filter(f -> f.getType().equals(2) || (f.getHtmlUrl() != null && f.getType().equals(10))).collect(Collectors.toList());
+
+                collect.forEach(tree -> {
+                    textDictInfoData.forEach((k, v) -> {
+                        String nodeId = k.split(",")[1];
+                        if (tree.getId().equals(Long.parseLong(nodeId))) {
+                            for (TextdictInfo textdictInfo : v) {
+                                TextdictInfo obj = BeanUtil.copyProperties(textdictInfo, TextdictInfo.class);
+                                assert obj != null;
+                                obj.setTabId(String.valueOf(tree.getPKeyId())); //重新赋值绑定到对应的表上
+                                obj.setId(SnowFlakeUtil.getId());
+                                insertData.add(obj);
+                            }
+                        }
+                    });
+                });
+
+                //去重,删除当前表的电签信息
+                List<String> collect2 = insertData.stream().map(TextdictInfo::getTabId).collect(Collectors.toList());
+                List<List<String>> partitionDel = Lists.partition(collect2, 1000);
+                for (List<String> ids : partitionDel) {
+                    String delSql = "delete from m_textdict_info where tab_id in (" + org.apache.commons.lang.StringUtils.join(ids, ",") + ")";
+                    jdbcTemplate.execute(delSql);
+                }
+
+                //新增
+                textDictInfoService.insertBatch(insertData, 1000);
+
+                return true;
+            } else {
+                throw new ServiceException("当前项目关联的wbs树不是私有关联");
+            }
+        }
+        return false;
+    }
+
+    @Override
+    public void eVisInfoRepeatDel(String pid) {
+        //获取当前项目下节点树所有节点、表、独立表
+        String sqlNodeTreeAllNow = "SELECT p_key_id,id,type,parent_id,html_url FROM m_wbs_tree_private WHERE project_id = " + pid + " AND STATUS = 1 AND is_deleted = 0 AND (((type = 1 OR type = 2) AND wbs_type = 1) OR (type= 10 AND parent_id = -10 ))";
+        List<WbsTreePrivate> wbsTreePrivatesNodeAndTabNow = jdbcTemplate.query(sqlNodeTreeAllNow, new BeanPropertyRowMapper<>(WbsTreePrivate.class));
+
+        //获取当前对应电签位置配置信息
+        List<WbsTreePrivate> collect1 = wbsTreePrivatesNodeAndTabNow.stream().filter(f -> f.getType().equals(10) || f.getType().equals(2)).collect(Collectors.toList());
+        List<Long> pKeyIds = collect1.stream().map(WbsTreePrivate::getPKeyId).collect(Collectors.toList());
+
+        //分组查询电签信息
+        List<TextdictInfo> textDictInfosAll = new ArrayList<>();
+        List<List<Long>> partition = Lists.partition(pKeyIds, 1000);
+        for (List<Long> ids : partition) {
+            String sql = "select id,tab_id,col_key,col_name,sig_role_id,sig_role_name from m_textdict_info where tab_id in(" + org.apache.commons.lang.StringUtils.join(ids, ",") + ")";
+            List<TextdictInfo> textDictInfos = jdbcTemplate.query(sql, new BeanPropertyRowMapper<>(TextdictInfo.class));
+            textDictInfosAll.addAll(textDictInfos);
+        }
+
+        //去重,解决之前由于删除接口重复保存,导致数据重复问题
+        List<TextdictInfo> list = textDictInfosAll.stream().collect(
+                Collectors.collectingAndThen(
+                        Collectors.toCollection(() -> new TreeSet<>(
+                                Comparator.comparing(o -> o.getTabId() + ";" + o.getSigRoleId() + ";" + o.getColKey() + ";" + o.getSigRoleName() + ";" + o.getColName()
+                                )
+                        )), ArrayList::new));
+
+        List<Long> idsAll = textDictInfosAll.stream().map(TextdictInfo::getId).collect(Collectors.toList());
+
+        List<Long> saveIds = list.stream().map(TextdictInfo::getId).collect(Collectors.toList());
+
+        List<Long> delIds = idsAll.stream().filter(f -> !saveIds.contains(f)).collect(Collectors.toList());
+
+        List<List<Long>> partition1 = Lists.partition(delIds, 1000);
+        for (List<Long> ids : partition1) {
+            String delSql = "delete from m_textdict_info where id in (" + org.apache.commons.lang.StringUtils.join(ids, ",") + ")";
+            jdbcTemplate.execute(delSql);
+        }
+
+    }
+
     @Transactional(rollbackFor = Exception.class)
     public boolean insertBatch(Collection<WbsTreePrivate> entityList, int batchSize) {
         try {

+ 11 - 61
blade-service/blade-manager/src/main/java/org/springblade/manager/service/impl/WbsTreeServiceImpl.java

@@ -550,12 +550,12 @@ public class WbsTreeServiceImpl extends BaseServiceImpl<WbsTreeMapper, WbsTree>
             List<String> idList2 = new ArrayList<>();
 
             if (pawDTO.getReferenceType().equals("public")) {
-                //当前公有引用ids
+                //当前公有引用
                 List<WbsTreePrivate> wbsTreePrivates = wbsTreePrivateMapper.selectList(Wrappers.<WbsTreePrivate>query().lambda().eq(WbsTreePrivate::getWbsId, pawDTO.getWbsId()).eq(WbsTreePrivate::getProjectId, pawDTO.getProjectId()).eq(WbsTreePrivate::getType, 1));
                 List<String> collect = wbsTreePrivates.stream().map(WbsTreePrivate::getId).collect(Collectors.toList()).stream().map(String::valueOf).collect(Collectors.toList());
                 idList2.addAll(collect);
             } else if (pawDTO.getReferenceType().equals("private")) {
-                //当前私有引用ids
+                //当前私有引用
                 List<WbsTreePrivate> wbsTreePrivates2 = wbsTreePrivateMapper.selectList(Wrappers.<WbsTreePrivate>query().lambda().eq(WbsTreePrivate::getWbsId, pawDTO.getPrimaryKeyId()).eq(WbsTreePrivate::getProjectId, pawDTO.getProjectId()).eq(WbsTreePrivate::getType, 1));
                 List<String> collect = wbsTreePrivates2.stream().map(WbsTreePrivate::getId).collect(Collectors.toList()).stream().map(String::valueOf).collect(Collectors.toList());
                 idList2.addAll(collect);
@@ -564,14 +564,13 @@ public class WbsTreeServiceImpl extends BaseServiceImpl<WbsTreeMapper, WbsTree>
             List<String> saveIds = idList1.stream().filter(f -> !idList2.contains(f)).collect(Collectors.toList());
             List<String> delIds = idList2.stream().filter(f -> !idList1.contains(f)).collect(Collectors.toList());
 
-            //1.同步私有电签默认信息
+            //TODO -------同步私有电签默认信息--------
             if (saveIds.size() == 0 && delIds.size() == 0) {
                 if (pawDTO.getReferenceType().equals("private")) {
-
-                    //新增独立表单库数据
+                    //新增独立表单
                     this.insertDLTabAsync(pawDTO);
 
-                    //获取私有引用项目的wbs树的所有节点、元素表、独立表(type=10)
+                    /*//获取私有引用项目的wbs树的所有节点、元素表、独立表(type=10)
                     WbsTreePrivate wbsTreePrivate = wbsTreePrivateMapper.selectOne(Wrappers.<WbsTreePrivate>query().lambda().eq(WbsTreePrivate::getPKeyId, pawDTO.getPrimaryKeyId()));
                     List<WbsTreePrivate> wbsTreePrivateAllOld = wbsTreePrivateMapper.selectList(Wrappers.<WbsTreePrivate>query().lambda()
                             .eq(WbsTreePrivate::getProjectId, Long.parseLong(wbsTreePrivate.getProjectId()))
@@ -588,11 +587,11 @@ public class WbsTreeServiceImpl extends BaseServiceImpl<WbsTreeMapper, WbsTree>
                     List<WbsTreePrivate> wbsTreePrivateNowTables = wbsTreePrivatesAllNow.stream().filter(f -> f.getType() == 2 || f.getType() == 10).collect(Collectors.toList());
 
                     //同步私有-电签匹配数据、默认信息数据
-                    this.insertTextDictInfoAsync(WbsTreePrivateTables, wbsTreePrivateNowTables);
+                    this.insertTextDictInfoAsync(WbsTreePrivateTables, wbsTreePrivateNowTables);*/
                 }
 
             } else {
-                //2.删除
+                //TODO ------------删除------------
                 if (delIds.size() > 0) {
                     if (pawDTO.getReferenceType().equals("public")) {
                         List<Long> ids1 = delIds.stream().map(Long::parseLong).collect(Collectors.toList());
@@ -652,26 +651,22 @@ public class WbsTreeServiceImpl extends BaseServiceImpl<WbsTreeMapper, WbsTree>
                     }
                 }
 
-                //3.新增
+                //TODO ------------新增------------
                 if (saveIds.size() > 0) {
                     if (saveIds.size() >= 1000) {
-                        //加锁
                         String redisValue = bladeRedis.get("submit-wbs-project:" + pawDTO.getProjectId());
                         if (StringUtils.isNotEmpty(redisValue) && redisValue.equals("1")) {
                             throw new ServiceException("请勿重复提交,请60秒后再尝试");
                         }
                     }
 
-                    //公有-数据初始化节点
+                    //构造入参集合
                     List<WbsTreePrivate> insertData1 = new ArrayList<>();
-                    //私有-数据初始化节点
                     List<WbsTreePrivate> insertData2 = new ArrayList<>();
-                    //私有-电签匹配数据、默认信息数据
-                    List<TextdictInfo> insertData3 = new ArrayList<>();
 
                     if (pawDTO.getReferenceType().equals("public")) {
                         List<WbsTree> addListData = new ArrayList<>();
-                        //获取当前wbs树下所有节点、表信息
+                        //获取当前树下所有节点、表信息
                         List<WbsTree> treesAll = baseMapper.selectList(Wrappers.<WbsTree>lambdaQuery().eq(WbsTree::getWbsId, pawDTO.getWbsId()).eq(WbsTree::getStatus, 1));
                         for (WbsTree wbsTree : treesAll) {
                             for (String id : saveIds) {
@@ -698,29 +693,19 @@ public class WbsTreeServiceImpl extends BaseServiceImpl<WbsTreeMapper, WbsTree>
                     } else if (pawDTO.getReferenceType().equals("private")) {
                         List<WbsTreePrivate> addListData = new ArrayList<>();
 
-                        //私有引用-电签匹配数据、默认信息数据
-                        Map<Long, List<TextdictInfo>> textDictInfoData = new HashMap<>();
-
-                        //查询出当前wbs树下所有节点、表信息(type=10独立表)
+                        //获取当前树下所有节点、表信息(type=10独立表)
                         List<WbsTreePrivate> wbsTreePrivatesNodeAndTab = wbsTreePrivateMapper.selectList(Wrappers.<WbsTreePrivate>lambdaQuery()
                                 .eq(WbsTreePrivate::getStatus, 1)
                                 .eq(WbsTreePrivate::getProjectId, pawDTO.getReferencePrivateWbsProjectId())
                                 .eq(WbsTreePrivate::getWbsId, pawDTO.getWbsId())
                                 .and(obj -> obj.eq(WbsTreePrivate::getType, 1).or().eq(WbsTreePrivate::getType,2))
                         );
-
                         List<WbsTreePrivate> wbsTreePrivatesTableDLOld = wbsTreePrivateMapper.selectList(Wrappers.<WbsTreePrivate>lambdaQuery().eq(WbsTreePrivate::getProjectId, pawDTO.getReferencePrivateWbsProjectId()).eq(WbsTreePrivate::getType, 10).eq(WbsTreePrivate::getStatus, 1).eq(WbsTreePrivate::getParentId, -10).isNull(WbsTreePrivate::getWbsId));
                         wbsTreePrivatesNodeAndTab.addAll(wbsTreePrivatesTableDLOld);
 
                         //获取当前项目下的所有独立表
                         List<WbsTreePrivate> wbsTreePrivatesTableDL = wbsTreePrivateMapper.selectList(Wrappers.<WbsTreePrivate>lambdaQuery().eq(WbsTreePrivate::getProjectId, pawDTO.getProjectId()).eq(WbsTreePrivate::getType, 10).eq(WbsTreePrivate::getParentId, -10).eq(WbsTreePrivate::getStatus, 1));
 
-                        //查询对应电签位置配置信息的pKeyIds
-                        List<Long> pIdsDL = wbsTreePrivatesNodeAndTab.stream().filter(f -> f.getType().equals(10) || f.getType().equals(2)).collect(Collectors.toList()).stream().map(WbsTreePrivate::getPKeyId).collect(Collectors.toList());
-                        String pKeyIds = StringUtils.join(pIdsDL, ",");
-                        String sql = "select `id`,`name`,`type`,tab_id,col_key,sig_role_id,is_deleted,sig_role_name,col_name,pyzbx,pyzby from m_textdict_info where tab_id in (" + pKeyIds + ") and is_deleted = 0";
-                        List<TextdictInfo> textDictInfosAll = jdbcTemplate.query(sql, new BeanPropertyRowMapper<>(TextdictInfo.class));
-
                         for (WbsTreePrivate wbsTreePrivate : wbsTreePrivatesNodeAndTab) {
                             if (wbsTreePrivate.getType() == 1 || wbsTreePrivate.getType() == 2) {
                                 for (String id : saveIds) {
@@ -729,13 +714,6 @@ public class WbsTreeServiceImpl extends BaseServiceImpl<WbsTreeMapper, WbsTree>
 
                                     } else if (Long.parseLong(id) == (wbsTreePrivate.getParentId()) && wbsTreePrivate.getType() == 2) {
                                         addListData.add(wbsTreePrivate);
-
-                                        //根据元素表pKeyId,获取电签位置匹配信息、编辑默认信息
-                                        List<TextdictInfo> textDictInfos = textDictInfosAll.stream().filter(f -> ObjectUtils.isNotEmpty(f.getTabId())
-                                                && f.getTabId().equals(String.valueOf(wbsTreePrivate.getPKeyId()))).collect(Collectors.toList());
-                                        if (textDictInfos.size() > 0) {
-                                            textDictInfoData.put(wbsTreePrivate.getPKeyId(), textDictInfos);
-                                        }
                                     }
                                 }
                             }
@@ -745,13 +723,6 @@ public class WbsTreeServiceImpl extends BaseServiceImpl<WbsTreeMapper, WbsTree>
                                 List<WbsTreePrivate> collect = wbsTreePrivatesTableDL.stream().filter(f -> f.getId().equals(wbsTreePrivate.getId())).collect(Collectors.toList());
                                 if (collect.size() == 0) {
                                     addListData.add(wbsTreePrivate);
-
-                                    //根据元素表pKeyId,获取电签位置匹配信息、编辑默认信息
-                                    List<TextdictInfo> textDictInfos = textDictInfosAll.stream().filter(f -> ObjectUtils.isNotEmpty(f.getTabId())
-                                            && f.getTabId().equals(String.valueOf(wbsTreePrivate.getPKeyId()))).collect(Collectors.toList());
-                                    if (textDictInfos.size() > 0) {
-                                        textDictInfoData.put(wbsTreePrivate.getPKeyId(), textDictInfos);
-                                    }
                                 }
                             }
                         }
@@ -777,23 +748,6 @@ public class WbsTreeServiceImpl extends BaseServiceImpl<WbsTreeMapper, WbsTree>
                                     wbsTreePrivate.setWbsType(String.valueOf(pawDTO.getWbsType()));
                                 }
                                 insertData2.add(wbsTreePrivate);
-
-                                //电签
-                                if (wbsTreePrivate.getType() == 2 || (wbsTreePrivate.getType() == 10 && wbsTreePrivate.getParentId() == -10)) { //type=10,parentId=-10 独立库引用元素库
-                                    if (textDictInfoData.size() > 0) {
-                                        textDictInfoData.forEach((k, v) -> {
-                                            if (tree.getPKeyId().equals(k)) {
-                                                for (TextdictInfo textdictInfo : v) {
-                                                    TextdictInfo obj = BeanUtil.copyProperties(textdictInfo, TextdictInfo.class);
-                                                    assert obj != null;
-                                                    obj.setTabId(String.valueOf(wbsTreePrivate.getPKeyId()));
-                                                    obj.setId(SnowFlakeUtil.getId());
-                                                    insertData3.add(obj);
-                                                }
-                                            }
-                                        });
-                                    }
-                                }
                             }
                         });
                     }
@@ -813,9 +767,6 @@ public class WbsTreeServiceImpl extends BaseServiceImpl<WbsTreeMapper, WbsTree>
 
                         this.insertBatch(insertData2, 1000);
 
-                        //电签
-                        textDictInfoService.insertBatch(insertData3, 1000);
-
                         if (pawDTO.getWbsType() == 1) {
                             projectInfoMapper.updateTemplateInfoQuality(pawDTO.getProjectId(), pawDTO.getPrimaryKeyId(), "private");
                         }
@@ -824,7 +775,6 @@ public class WbsTreeServiceImpl extends BaseServiceImpl<WbsTreeMapper, WbsTree>
                         }
                     }
                     if (saveIds.size() >= 1000) {
-                        //解锁
                         bladeRedis.set("submit-wbs-project:" + pawDTO.getProjectId(), "1");
                         bladeRedis.expire("submit-wbs-project:" + pawDTO.getProjectId(), 60);
                     }

+ 46 - 0
blade-service/blade-manager/src/main/java/org/springblade/manager/utils/AsyncConfigurer.java

@@ -0,0 +1,46 @@
+package org.springblade.manager.utils;
+
+import lombok.extern.slf4j.Slf4j;
+import org.springframework.context.annotation.Bean;
+import org.springframework.context.annotation.Configuration;
+import org.springframework.scheduling.annotation.EnableAsync;
+
+import java.util.concurrent.*;
+
+@Slf4j
+@Configuration
+@EnableAsync
+public class AsyncConfigurer {
+
+    /**
+     * cpu 核心数量
+     */
+    public static final int cpuNum = Runtime.getRuntime().availableProcessors();
+
+    /**
+     * 线程池配置
+     *
+     * @return
+     */
+    @Bean("taskExecutor1")
+    public ThreadPoolExecutor getAsyncExecutor() {
+        return new ThreadPoolMonitor(cpuNum
+                , cpuNum * 2
+                , 60
+                , TimeUnit.SECONDS
+                , new LinkedBlockingQueue<>(2000)
+                , new ThreadPoolExecutor.DiscardOldestPolicy(), "manager-thread-pool");
+    }
+
+    /**
+     * 线程池配置
+     *
+     * @return
+     */
+    @Bean("singleExecutor")
+    public ExecutorService getSingleExecutor() {
+        log.info("线程池初始化......");
+        return Executors.newSingleThreadExecutor();
+    }
+
+}

+ 1 - 1
blade-service/blade-manager/src/main/java/org/springblade/manager/utils/ForestNodeMerger.java

@@ -9,7 +9,7 @@ public class ForestNodeMerger {
     public static <T extends INode<T>> List<T> merge(List<T> items) {
         ForestNodeManager<T> forestNodeManager = new ForestNodeManager(items);
         items.forEach((forestNode) -> {
-            if (forestNode.getParentId() != 0L) {
+            if (forestNode.getParentId()!= null && forestNode.getParentId() != 0L) {
                 INode<T> node = forestNodeManager.getTreeNodeAt(forestNode.getParentId());
                 if (node != null) {
                     node.getChildren().add(forestNode);

+ 191 - 0
blade-service/blade-manager/src/main/java/org/springblade/manager/utils/ThreadPoolMonitor.java

@@ -0,0 +1,191 @@
+package org.springblade.manager.utils;
+
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+import java.util.List;
+import java.util.Objects;
+import java.util.concurrent.*;
+import java.util.concurrent.atomic.AtomicInteger;
+import java.util.concurrent.atomic.AtomicLong;
+
+public class ThreadPoolMonitor extends ThreadPoolExecutor {
+    private final Logger logger = LoggerFactory.getLogger(getClass());
+
+    /**
+     * ActiveCount
+     */
+    int ac = 0;
+
+    /**
+     * 当前所有线程消耗的时间
+     */
+    private AtomicLong totalCostTime = new AtomicLong();
+
+    /**
+     * 当前执行的线程总数
+     */
+    private AtomicLong totalTasks = new AtomicLong();
+
+    /**
+     * 线程池名称
+     */
+    private String poolName;
+
+    /**
+     * 最短 执行时间
+     */
+    private long minCostTime;
+
+    /**
+     * 最长执行时间
+     */
+    private long maxCostTime;
+
+
+    /**
+     * 保存任务开始执行的时间
+     */
+    private ThreadLocal<Long> startTime = new ThreadLocal<>();
+
+    public ThreadPoolMonitor(int corePoolSize, int maximumPoolSize, long keepAliveTime,
+                             TimeUnit unit, BlockingQueue<Runnable> workQueue, String poolName) {
+        this(corePoolSize, maximumPoolSize, keepAliveTime, unit, workQueue,
+                Executors.defaultThreadFactory(), poolName);
+    }
+
+    public ThreadPoolMonitor(int corePoolSize, int maximumPoolSize, long keepAliveTime,
+                             TimeUnit unit, BlockingQueue<Runnable> workQueue,
+                             ThreadFactory threadFactory, String poolName) {
+        super(corePoolSize, maximumPoolSize, keepAliveTime, unit, workQueue, threadFactory);
+        this.poolName = poolName;
+    }
+
+    public ThreadPoolMonitor(int corePoolSize, int maximumPoolSize, long keepAliveTime, TimeUnit unit, BlockingQueue<Runnable> workQueue, RejectedExecutionHandler handler, String poolName) {
+        super(corePoolSize, maximumPoolSize, keepAliveTime, unit, workQueue, handler);
+        this.poolName = poolName;
+    }
+
+    /**
+     * 线程池延迟关闭时(等待线程池里的任务都执行完毕),统计线程池情况
+     */
+    @Override
+    public void shutdown() {
+        // 统计已执行任务、正在执行任务、未执行任务数量
+        logger.info("{} Going to shutdown. Executed tasks: {}, Running tasks: {}, Pending tasks: {}",
+                this.poolName, this.getCompletedTaskCount(), this.getActiveCount(), this.getQueue().size());
+        super.shutdown();
+    }
+
+    @Override
+    public List<Runnable> shutdownNow() {
+        // 统计已执行任务、正在执行任务、未执行任务数量
+        logger.info("{} Going to immediately shutdown. Executed tasks: {}, Running tasks: {}, Pending tasks: {}",
+                this.poolName, this.getCompletedTaskCount(), this.getActiveCount(), this.getQueue().size());
+        return super.shutdownNow();
+    }
+
+    /**
+     * 任务执行之前,记录任务开始时间
+     */
+    @Override
+    protected void beforeExecute(Thread t, Runnable r) {
+        logger.info("{}-before: " +
+                        " PoolSize: {}, CorePoolSize: {}, ActiveCount: {}, " +
+                        "Completed: {}, Task: {}, Queue: {}, LargestPoolSize: {}, " +
+                        "MaximumPoolSize: {},  KeepAliveTime: {}, isShutdown: {}, isTerminated: {}",
+                this.poolName,
+                this.getPoolSize(), this.getCorePoolSize(), super.getActiveCount(),
+                this.getCompletedTaskCount(), this.getTaskCount(), this.getQueue().size(), this.getLargestPoolSize(),
+                this.getMaximumPoolSize(), this.getKeepAliveTime(TimeUnit.MILLISECONDS), this.isShutdown(), this.isTerminated());
+        startTime.set(System.currentTimeMillis());
+    }
+
+    /**
+     * 任务执行之后,计算任务结束时间
+     */
+    @Override
+    protected void afterExecute(Runnable r, Throwable t) {
+        long costTime = System.currentTimeMillis() - startTime.get();
+        startTime.remove();  //删除,避免占用太多内存
+        //设置最大最小执行时间
+        maxCostTime = maxCostTime > costTime ? maxCostTime : costTime;
+        if (totalTasks.get() == 0) {
+            minCostTime = costTime;
+        }
+        minCostTime = minCostTime < costTime ? minCostTime : costTime;
+        totalCostTime.addAndGet(costTime);
+        totalTasks.incrementAndGet();
+        ac = this.getActiveCount();  //获取ActiveCount的值
+
+        logger.info("{}-after: " +
+                        "Duration: {} ms, PoolSize: {}, CorePoolSize: {}, ActiveCount: {}, " +
+                        "Completed: {}, Task: {}, Queue: {}, LargestPoolSize: {}, " +
+                        "MaximumPoolSize: {},  KeepAliveTime: {}, isShutdown: {}, isTerminated: {}",
+                this.poolName,
+                costTime, this.getPoolSize(), this.getCorePoolSize(), super.getActiveCount(),
+                this.getCompletedTaskCount(), this.getTaskCount(), this.getQueue().size(), this.getLargestPoolSize(),
+                this.getMaximumPoolSize(), this.getKeepAliveTime(TimeUnit.MILLISECONDS), this.isShutdown(), this.isTerminated());
+    }
+
+    public int getAc() {
+        return ac;
+    }
+
+    /**
+     * 线程平均耗时
+     *
+     * @return
+     */
+    public float getAverageCostTime() {
+        return totalCostTime.get() / totalTasks.get();
+    }
+
+    /**
+     * 线程最大耗时
+     */
+    public long getMaxCostTime() {
+        return maxCostTime;
+    }
+
+    /**
+     * 线程最小耗时
+     */
+    public long getMinCostTime() {
+        return minCostTime;
+    }
+
+    /**
+     * 生成线程池所用的线程,改写了线程池默认的线程工厂
+     */
+    static class EventThreadFactory implements ThreadFactory {
+        private static final AtomicInteger poolNumber = new AtomicInteger(1);
+        private final ThreadGroup group;
+        private final AtomicInteger threadNumber = new AtomicInteger(1);
+        private final String namePrefix;
+
+        /**
+         * 初始化线程工厂
+         *
+         * @param poolName 线程池名称
+         */
+        EventThreadFactory(String poolName) {
+            SecurityManager s = System.getSecurityManager();
+            group = Objects.nonNull(s) ? s.getThreadGroup() : Thread.currentThread().getThreadGroup();
+            namePrefix = poolName + "-pool-" + poolNumber.getAndIncrement() + "-thread-";
+        }
+
+        @Override
+        public Thread newThread(Runnable r) {
+            Thread t = new Thread(group, r, namePrefix + threadNumber.getAndIncrement(), 0);
+
+            if (t.isDaemon()) {
+                t.setDaemon(false);
+            }
+            if (t.getPriority() != Thread.NORM_PRIORITY) {
+                t.setPriority(Thread.NORM_PRIORITY);
+            }
+            return t;
+        }
+    }
+}