liuyc 2 жил өмнө
parent
commit
13c31f21dc
24 өөрчлөгдсөн 1711 нэмэгдсэн , 1190 устгасан
  1. 1 1
      blade-gateway/src/main/resources/bootstrap.yml
  2. 1 1
      blade-ops-api/blade-flow-api/src/main/java/org/springblade/flow/core/feign/NewFlowClient.java
  3. 0 1
      blade-service-api/blade-manager-api/src/main/java/org/springblade/manager/feign/WbsTreeContractClient.java
  4. 20 1
      blade-service/blade-business/pom.xml
  5. 24 6
      blade-service/blade-business/src/main/java/org/springblade/business/controller/ArchiveFileController.java
  6. 468 445
      blade-service/blade-business/src/main/java/org/springblade/business/controller/ContractLogController.java
  7. 27 11
      blade-service/blade-business/src/main/java/org/springblade/business/controller/InformationWriteQueryController.java
  8. 218 142
      blade-service/blade-business/src/main/java/org/springblade/business/controller/MessageWarningController.java
  9. 29 1
      blade-service/blade-business/src/main/java/org/springblade/business/controller/TaskController.java
  10. 29 0
      blade-service/blade-business/src/main/java/org/springblade/business/controller/TestDemoController.java
  11. 3 0
      blade-service/blade-business/src/main/java/org/springblade/business/mapper/InformationQueryMapper.java
  12. 7 4
      blade-service/blade-business/src/main/java/org/springblade/business/mapper/InformationQueryMapper.xml
  13. 2 6
      blade-service/blade-business/src/main/java/org/springblade/business/mapper/MessageWarningMapper.java
  14. 6 0
      blade-service/blade-business/src/main/java/org/springblade/business/service/ITaskService.java
  15. 455 437
      blade-service/blade-business/src/main/java/org/springblade/business/service/impl/InformationQueryServiceImpl.java
  16. 61 12
      blade-service/blade-business/src/main/java/org/springblade/business/service/impl/MessageWarningServiceImpl.java
  17. 154 118
      blade-service/blade-business/src/main/java/org/springblade/business/service/impl/TaskServiceImpl.java
  18. 159 0
      blade-service/blade-business/src/main/java/org/springblade/business/socket/WebSocket.java
  19. 35 0
      blade-service/blade-business/src/main/java/org/springblade/business/socket/WebSocketConfig.java
  20. 0 1
      blade-service/blade-manager/src/main/java/org/springblade/manager/feign/WbsTreeContractClientImpl.java
  21. 0 1
      blade-service/blade-manager/src/main/java/org/springblade/manager/mapper/WbsTreePrivateMapper.java
  22. 3 1
      blade-service/blade-manager/src/main/java/org/springblade/manager/mapper/WbsTreePrivateMapper.xml
  23. 8 1
      blade-service/blade-manager/src/main/java/org/springblade/manager/service/impl/WbsTreePrivateServiceImpl.java
  24. 1 0
      blade-service/blade-manager/src/main/java/org/springblade/manager/service/impl/WbsTreeServiceImpl.java

+ 1 - 1
blade-gateway/src/main/resources/bootstrap.yml

@@ -1,5 +1,5 @@
 server:
-  port: 80
+  port: 8090
 
 spring:
   cloud:

+ 1 - 1
blade-ops-api/blade-flow-api/src/main/java/org/springblade/flow/core/feign/NewFlowClient.java

@@ -7,7 +7,6 @@ import org.springblade.flow.core.vo.FlowProcessVO;
 import org.springframework.cloud.openfeign.FeignClient;
 import org.springframework.web.bind.annotation.GetMapping;
 import org.springframework.web.bind.annotation.PostMapping;
-import org.springframework.web.bind.annotation.RequestBody;
 import org.springframework.web.bind.annotation.RequestParam;
 
 import java.util.List;
@@ -21,6 +20,7 @@ public interface NewFlowClient {
 
     String START_FLOW = API_PREFIX + "/start-flow";
     String TO_DO_LIST = API_PREFIX + "/to-do-list";
+    String TO_DO_TOTAL = API_PREFIX + "/to-do-total";
     String COMPLETE_APPROVAL_TASK = API_PREFIX + "/complete-approval-task";
     String QUERY_TASK_ID = API_PREFIX + "/query-task-id";
     String DONE_LIST = API_PREFIX + "/done-list";

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

@@ -3,7 +3,6 @@ package org.springblade.manager.feign;
 import org.springblade.manager.entity.ContractRelationJlyz;
 import org.springblade.manager.entity.WbsTreeContract;
 import org.springblade.manager.vo.WbsTreeContractTreeVOS;
-import org.springblade.manager.vo.WbsTreeContractVO;
 import org.springframework.cloud.openfeign.FeignClient;
 import org.springframework.web.bind.annotation.GetMapping;
 import org.springframework.web.bind.annotation.PostMapping;

+ 20 - 1
blade-service/blade-business/pom.xml

@@ -107,7 +107,6 @@
             <groupId>junit</groupId>
             <artifactId>junit</artifactId>
         </dependency>
-
         <dependency>
             <groupId>e-iceblue</groupId>
             <artifactId>spire.office.free</artifactId>
@@ -120,6 +119,26 @@
             <scope>compile</scope>
         </dependency>
 
+        <!--webSocket-->
+        <dependency>
+            <groupId>org.springframework.boot</groupId>
+            <artifactId>spring-boot-starter-websocket</artifactId>
+        </dependency>
+        <dependency>
+            <groupId>org.springframework.boot</groupId>
+            <artifactId>spring-boot-starter-web</artifactId>
+            <exclusions>
+                <exclusion>
+                    <groupId>org.springframework.boot</groupId>
+                    <artifactId>spring-boot-starter-tomcat</artifactId>
+                </exclusion>
+            </exclusions>
+        </dependency>
+        <dependency>
+            <groupId>org.springframework.boot</groupId>
+            <artifactId>spring-boot-starter-undertow</artifactId>
+        </dependency>
+
     </dependencies>
 
     <build>

+ 24 - 6
blade-service/blade-business/src/main/java/org/springblade/business/controller/ArchiveFileController.java

@@ -1,6 +1,7 @@
 package org.springblade.business.controller;
 
 import com.alibaba.excel.util.DateUtils;
+import com.alibaba.fastjson.JSON;
 import com.alibaba.fastjson.JSONArray;
 import com.alibaba.fastjson.JSONObject;
 import com.baomidou.mybatisplus.core.conditions.update.LambdaUpdateWrapper;
@@ -18,6 +19,8 @@ import org.springblade.business.feign.MessageWarningClient;
 import org.springblade.business.feign.OperationLogClient;
 import org.springblade.business.feign.RecycleBinClient;
 import org.springblade.business.feign.TaskClient;
+import org.springblade.business.service.ITaskService;
+import org.springblade.business.socket.WebSocket;
 import org.springblade.business.utils.FileUtils;
 import org.springblade.business.vo.MessageWarningVO;
 import org.springblade.business.vo.StartTaskVO;
@@ -25,6 +28,7 @@ import org.springblade.business.vo.TaskVO;
 import org.springblade.core.secure.utils.AuthUtil;
 import org.springblade.core.tool.api.R;
 import org.springblade.core.tool.utils.Func;
+import org.springblade.core.tool.utils.ObjectUtil;
 import org.springblade.evisa.feign.EVisaClient;
 import org.springblade.manager.entity.ArchiveTree;
 import org.springblade.manager.entity.ContractInfo;
@@ -45,6 +49,7 @@ import org.springblade.business.service.IArchiveFileService;
 import org.springblade.core.boot.ctrl.BladeController;
 
 import javax.servlet.http.HttpServletResponse;
+import java.io.IOException;
 import java.util.*;
 import java.util.stream.Collectors;
 
@@ -80,6 +85,10 @@ public class ArchiveFileController extends BladeController {
 
 	private final MessageWarningClient messageWarningClient;
 
+	private final ITaskService iTaskService;
+
+	private final WebSocket webSocket;
+
 	/**
 	 * 批量认证(特殊签章 签个透明空白图片,主要目的是在验签的时候有验签信息 )
 	 */
@@ -153,7 +162,7 @@ public class ArchiveFileController extends BladeController {
 	@PostMapping("batchAbolish")
 	@ApiOperationSupport(order = 7)
 	@ApiOperation(value = "批量废除")
-	public R<Boolean> batchAbolish(@RequestParam String ids){
+	public R<Boolean> batchAbolish(@RequestParam String ids) throws IOException {
 		//获取所有相关任务记录
 		List<Task> taskList =  this.taskClient.queryTaskListByFormDataId(ids);
 		if(taskList != null && taskList.size() > 0){
@@ -214,17 +223,16 @@ public class ArchiveFileController extends BladeController {
 								));
 							}
 							if(messageList.size() > 0){
+								//内部通过WebSocket推送数量条数
 								this.messageWarningClient.savePushUserMessageWarning(messageList);
 							}
 						}
-
 					}catch (Exception e){
 						e.printStackTrace();
 					}
-
-
 				}
 			}
+
 			return R.data(true);
 		}
 
@@ -237,7 +245,7 @@ public class ArchiveFileController extends BladeController {
 	@PostMapping("/batchApproval")
 	@ApiOperationSupport(order = 6)
 	@ApiOperation(value = "批量上报")
-	public R<Boolean> batchApproval(@RequestBody StartTaskVO startTaskVO){
+	public R<Boolean> batchApproval(@RequestBody StartTaskVO startTaskVO) throws IOException {
 		String archiveTaskIds = startTaskVO.getIds();
 		if(StringUtils.isNotEmpty(archiveTaskIds)){
 			//生成流程实体
@@ -267,7 +275,17 @@ public class ArchiveFileController extends BladeController {
 			this.taskClient.startTask(taskVO);
 			//修改状态为待审批
 			String[] archiveTaskIdArray = archiveTaskIds.split(",");
-			return R.data(this.archiveFileService.update(Wrappers.<ArchiveFile>lambdaUpdate().set(ArchiveFile::getStatus, 1).in(ArchiveFile::getId, Arrays.asList(archiveTaskIdArray))));
+			boolean update = this.archiveFileService.update(Wrappers.<ArchiveFile>lambdaUpdate().set(ArchiveFile::getStatus, 1).in(ArchiveFile::getId, Arrays.asList(archiveTaskIdArray)));
+			if (update){
+				//通过WebSocket推送数量条数
+				if (ObjectUtil.isNotEmpty(startTaskVO.getUserTasks())) {
+					for (StartTaskVO.CustomUserTask userTask : startTaskVO.getUserTasks()) {
+						Map<String, String> stringMap = iTaskService.getTaskCount(startTaskVO.getProjectId(), startTaskVO.getContractId(), userTask.getUserId());
+						webSocket.sendMessageByUserId(userTask.getUserId(), JSON.toJSONString(stringMap));
+					}
+				}
+				return R.data(true);
+			}
 		}
 		return R.data(false);
 	}

+ 468 - 445
blade-service/blade-business/src/main/java/org/springblade/business/controller/ContractLogController.java

@@ -1,5 +1,6 @@
 package org.springblade.business.controller;
 
+import com.alibaba.fastjson.JSON;
 import com.alibaba.fastjson.JSONArray;
 import com.alibaba.fastjson.JSONObject;
 import com.baomidou.mybatisplus.core.conditions.update.LambdaUpdateWrapper;
@@ -20,6 +21,8 @@ import org.springblade.business.feign.MessageWarningClient;
 import org.springblade.business.feign.OperationLogClient;
 import org.springblade.business.feign.TaskClient;
 import org.springblade.business.service.IContractLogWbsService;
+import org.springblade.business.service.ITaskService;
+import org.springblade.business.socket.WebSocket;
 import org.springblade.business.utils.FileUtils;
 import org.springblade.business.utils.YearTreeUtils;
 import org.springblade.business.vo.*;
@@ -29,6 +32,7 @@ import org.springblade.core.oss.model.BladeFile;
 import org.springblade.core.secure.utils.AuthUtil;
 import org.springblade.core.tool.api.R;
 import org.springblade.core.tool.utils.Func;
+import org.springblade.core.tool.utils.ObjectUtil;
 import org.springblade.manager.entity.ContractInfo;
 import org.springblade.manager.entity.ProjectInfo;
 import org.springblade.manager.feign.ContractClient;
@@ -41,7 +45,9 @@ import org.springframework.beans.BeanUtils;
 import org.springframework.web.bind.annotation.*;
 import org.springblade.business.service.IContractLogService;
 import org.springblade.core.boot.ctrl.BladeController;
+import springfox.documentation.spring.web.json.Json;
 
+import java.io.IOException;
 import java.util.*;
 import java.util.stream.Collectors;
 
@@ -57,144 +63,148 @@ import java.util.stream.Collectors;
 @Api(value = "日志通用表", tags = "日志通用表接口")
 public class ContractLogController extends BladeController {
 
-	private final IContractLogService contractLogService;
-
-	private final IContractLogWbsService contractLogWbsService;
-
-	private final WbsTreeContractClient wbsTreeContractClient;
-
-	private final TaskClient taskClient;
-
-	private final OperationLogClient operationLogClient;
-
-	private final MessageWarningClient messageWarningClient;
-
-	private final NewIOSSClient newIOSSClient;
-
-	private final ContractClient contractClient;
-
-	private final ProjectClient projectClient;
-
-	/**
-	 * 获取填报记录
-	 */
-	@GetMapping("/queryLogList")
-	@ApiOperationSupport(order = 19)
-	@ApiOperation(value = "获取填报记录")
-	@ApiImplicitParams({
-			@ApiImplicitParam(name = "contractId", value = "合同段ID"),
-			@ApiImplicitParam(name = "nodePrimaryKeyId", value = "左侧填报日志节点primaryKeyId"),
-			@ApiImplicitParam(name = "time", value = "所选的时间,格式为yyyy-MM-dd、yyyy-MM、yyyy")
-	})
-	public R<List<ContractLog>> queryLogByContractIdAndNodePrimaryKeyId(@RequestParam String contractId, @RequestParam String nodePrimaryKeyId, @RequestParam String time){
-		return R.data(this.contractLogService.list(Wrappers.<ContractLog>lambdaQuery().eq(ContractLog::getContractId, contractId).eq(ContractLog::getWbsNodeId, nodePrimaryKeyId).like(ContractLog::getRecordTime, time)));
-	}
-
-	/**
-	 * 获取当前合同段下本日志节点的填报资料日期树
-	 */
-	@GetMapping("/queryReportLogTimeTree")
-	@ApiOperationSupport(order = 18)
-	@ApiOperation(value = "获取当前合同段下本日志节点的填报资料日期树")
-	@ApiImplicitParams({
-			@ApiImplicitParam(name = "contractId", value = "合同段ID"),
-			@ApiImplicitParam(name = "nodePrimaryKeyId", value = "左侧填报的日志节点primaryKeyId")
-	})
-	public R<List<TreeVo>> queryReportLogTimeTree(@RequestParam String contractId, @RequestParam String nodePrimaryKeyId){
-		//获取填报时间
-		List<String> recordTimeList = this.contractLogService.queryReportLogTimeTree(contractId, nodePrimaryKeyId);
-		//转成结构树
-		return R.data(YearTreeUtils.yearMonthDayTree(recordTimeList, "ASC"));
-	}
-
-	/**
-	 * 删除日志
-	 */
-	@PostMapping("/removeByIds")
-	@ApiOperationSupport(order = 12)
-	@ApiOperation(value = "删除日志")
-	@ApiImplicitParam(name = "ids", value = "删除的数据ID", required = true)
-	public R<Boolean> removeByIds(@RequestBody JSONObject json){
-		if(json.containsKey("ids")){
-			Object ids = json.get("ids");
-			List<Long> idList;
-			if(ids instanceof List){
-				//如果是集合,按集合处理
-				idList = JSONArray.parseArray(JSONObject.toJSONString(ids), Long.class);
-			} else {
-				//否则均按字符串处理
-				idList = Func.toLongList(ids.toString());
-			}
-
-			return R.status(this.contractLogService.deleteLogic(idList));
-		}
-		return R.data(300, false, "未找到具体数据");
-	}
-
-	/**
-	 * 单个废除(填报页)
-	 */
-	@GetMapping("/oneAbolish")
-	@ApiOperationSupport(order = 11)
-	@ApiOperation(value = " 单个废除(填报页)")
-	@ApiImplicitParams({
-			@ApiImplicitParam(name = "contractId", value = "合同段ID", required = true),
-			@ApiImplicitParam(name = "nodePrimaryKeyId", value = "当前操作的日志类型ID,即左侧列表的节点primaryKeyId", required = true),
-			@ApiImplicitParam(name = "recordTime", value = "当前选择的填写日期,即右侧日期控件所选日期,格式为 yyyy-MM-dd", required = true)
-	})
-	public R<Boolean> oneAbolish(@RequestParam String nodePrimaryKeyId, @RequestParam String recordTime, @RequestParam String contractId){
-		//查询数据
-		ContractLog log = this.contractLogService.getOne(Wrappers.<ContractLog>lambdaQuery().eq(ContractLog::getWbsNodeId, nodePrimaryKeyId)
-				.eq(ContractLog::getCreateUser, AuthUtil.getUserId())
-				.eq(ContractLog::getRecordTime, recordTime)
-				.eq(ContractLog::getContractId, contractId));
-		if(log != null){
-			//调用批量废除接口
-			return this.batchAbolish(log.getId().toString());
-		}
-		return R.data(300, false, "废除失败");
-	}
-
-	/**
-	 * 获取当前资料的任务状态
-	 */
-	@GetMapping("/checkTheLogTaskStatus")
-	@ApiOperationSupport(order = 10)
-	@ApiOperation(value = "获取当前资料的任务状态")
-	@ApiImplicitParams({
-			@ApiImplicitParam(name = "contractId", value = "合同段ID", required = true),
-			@ApiImplicitParam(name = "nodePrimaryKeyId", value = "当前操作的日志类型ID,即左侧列表的节点primaryKeyId", required = true),
-			@ApiImplicitParam(name = "recordTime", value = "当前选择的填写日期,即右侧日期控件所选日期,格式为 yyyy-MM-dd", required = true)
-	})
-	public R<Integer> checkTheLogTaskStatus(@RequestParam String nodePrimaryKeyId, @RequestParam String recordTime, @RequestParam String contractId){
-		ContractLog log = this.contractLogService.getOne(Wrappers.<ContractLog>lambdaQuery()
-				.eq(ContractLog::getWbsNodeId, nodePrimaryKeyId)
-				.eq(ContractLog::getContractId, contractId)
-				.eq(ContractLog::getRecordTime, recordTime)
-				.eq(ContractLog::getCreateUser, AuthUtil.getUserId()));
-		//默认未上报
-		int status = 1;
-
-		if(log != null){
-			switch (log.getStatus()){
-				case 0:
-				case 3:
-					//已填报未上报 或 已填报已废除
-					status = 2;
-					break;
-				case 1:
-					//待审批
-					status = 3;
-					break;
-				case 2:
-					//已审批
-					status = 4;
-					break;
-			}
-		}
-
-		return R.data(status);
-	}
+    private final IContractLogService contractLogService;
+
+    private final IContractLogWbsService contractLogWbsService;
+
+    private final WbsTreeContractClient wbsTreeContractClient;
+
+    private final TaskClient taskClient;
+
+    private final OperationLogClient operationLogClient;
+
+    private final MessageWarningClient messageWarningClient;
+
+    private final NewIOSSClient newIOSSClient;
+
+    private final ContractClient contractClient;
+
+    private final ProjectClient projectClient;
+
+    private final ITaskService iTaskService;
+
+    private final WebSocket webSocket;
+
+    /**
+     * 获取填报记录
+     */
+    @GetMapping("/queryLogList")
+    @ApiOperationSupport(order = 19)
+    @ApiOperation(value = "获取填报记录")
+    @ApiImplicitParams({
+            @ApiImplicitParam(name = "contractId", value = "合同段ID"),
+            @ApiImplicitParam(name = "nodePrimaryKeyId", value = "左侧填报日志节点primaryKeyId"),
+            @ApiImplicitParam(name = "time", value = "所选的时间,格式为yyyy-MM-dd、yyyy-MM、yyyy")
+    })
+    public R<List<ContractLog>> queryLogByContractIdAndNodePrimaryKeyId(@RequestParam String contractId, @RequestParam String nodePrimaryKeyId, @RequestParam String time) {
+        return R.data(this.contractLogService.list(Wrappers.<ContractLog>lambdaQuery().eq(ContractLog::getContractId, contractId).eq(ContractLog::getWbsNodeId, nodePrimaryKeyId).like(ContractLog::getRecordTime, time)));
+    }
+
+    /**
+     * 获取当前合同段下本日志节点的填报资料日期树
+     */
+    @GetMapping("/queryReportLogTimeTree")
+    @ApiOperationSupport(order = 18)
+    @ApiOperation(value = "获取当前合同段下本日志节点的填报资料日期树")
+    @ApiImplicitParams({
+            @ApiImplicitParam(name = "contractId", value = "合同段ID"),
+            @ApiImplicitParam(name = "nodePrimaryKeyId", value = "左侧填报的日志节点primaryKeyId")
+    })
+    public R<List<TreeVo>> queryReportLogTimeTree(@RequestParam String contractId, @RequestParam String nodePrimaryKeyId) {
+        //获取填报时间
+        List<String> recordTimeList = this.contractLogService.queryReportLogTimeTree(contractId, nodePrimaryKeyId);
+        //转成结构树
+        return R.data(YearTreeUtils.yearMonthDayTree(recordTimeList, "ASC"));
+    }
+
+    /**
+     * 删除日志
+     */
+    @PostMapping("/removeByIds")
+    @ApiOperationSupport(order = 12)
+    @ApiOperation(value = "删除日志")
+    @ApiImplicitParam(name = "ids", value = "删除的数据ID", required = true)
+    public R<Boolean> removeByIds(@RequestBody JSONObject json) {
+        if (json.containsKey("ids")) {
+            Object ids = json.get("ids");
+            List<Long> idList;
+            if (ids instanceof List) {
+                //如果是集合,按集合处理
+                idList = JSONArray.parseArray(JSONObject.toJSONString(ids), Long.class);
+            } else {
+                //否则均按字符串处理
+                idList = Func.toLongList(ids.toString());
+            }
+
+            return R.status(this.contractLogService.deleteLogic(idList));
+        }
+        return R.data(300, false, "未找到具体数据");
+    }
+
+    /**
+     * 单个废除(填报页)
+     */
+    @GetMapping("/oneAbolish")
+    @ApiOperationSupport(order = 11)
+    @ApiOperation(value = " 单个废除(填报页)")
+    @ApiImplicitParams({
+            @ApiImplicitParam(name = "contractId", value = "合同段ID", required = true),
+            @ApiImplicitParam(name = "nodePrimaryKeyId", value = "当前操作的日志类型ID,即左侧列表的节点primaryKeyId", required = true),
+            @ApiImplicitParam(name = "recordTime", value = "当前选择的填写日期,即右侧日期控件所选日期,格式为 yyyy-MM-dd", required = true)
+    })
+    public R<Boolean> oneAbolish(@RequestParam String nodePrimaryKeyId, @RequestParam String recordTime, @RequestParam String contractId) throws IOException {
+        //查询数据
+        ContractLog log = this.contractLogService.getOne(Wrappers.<ContractLog>lambdaQuery().eq(ContractLog::getWbsNodeId, nodePrimaryKeyId)
+                .eq(ContractLog::getCreateUser, AuthUtil.getUserId())
+                .eq(ContractLog::getRecordTime, recordTime)
+                .eq(ContractLog::getContractId, contractId));
+        if (log != null) {
+            //调用批量废除接口
+            return this.batchAbolish(log.getId().toString());
+        }
+        return R.data(300, false, "废除失败");
+    }
+
+    /**
+     * 获取当前资料的任务状态
+     */
+    @GetMapping("/checkTheLogTaskStatus")
+    @ApiOperationSupport(order = 10)
+    @ApiOperation(value = "获取当前资料的任务状态")
+    @ApiImplicitParams({
+            @ApiImplicitParam(name = "contractId", value = "合同段ID", required = true),
+            @ApiImplicitParam(name = "nodePrimaryKeyId", value = "当前操作的日志类型ID,即左侧列表的节点primaryKeyId", required = true),
+            @ApiImplicitParam(name = "recordTime", value = "当前选择的填写日期,即右侧日期控件所选日期,格式为 yyyy-MM-dd", required = true)
+    })
+    public R<Integer> checkTheLogTaskStatus(@RequestParam String nodePrimaryKeyId, @RequestParam String recordTime, @RequestParam String contractId) {
+        ContractLog log = this.contractLogService.getOne(Wrappers.<ContractLog>lambdaQuery()
+                .eq(ContractLog::getWbsNodeId, nodePrimaryKeyId)
+                .eq(ContractLog::getContractId, contractId)
+                .eq(ContractLog::getRecordTime, recordTime)
+                .eq(ContractLog::getCreateUser, AuthUtil.getUserId()));
+        //默认未上报
+        int status = 1;
+
+        if (log != null) {
+            switch (log.getStatus()) {
+                case 0:
+                case 3:
+                    //已填报未上报 或 已填报已废除
+                    status = 2;
+                    break;
+                case 1:
+                    //待审批
+                    status = 3;
+                    break;
+                case 2:
+                    //已审批
+                    status = 4;
+                    break;
+            }
+        }
+
+        return R.data(status);
+    }
 
     /**
      * 日志上报(填报页)
@@ -202,253 +212,255 @@ public class ContractLogController extends BladeController {
     @PostMapping("/startTaskTheLog")
     @ApiOperationSupport(order = 9)
     @ApiOperation(value = "日志上报(填报页)")
-	@ApiImplicitParams({
-			@ApiImplicitParam(name = "startTaskVO", value = "流程参数", required = true),
-			@ApiImplicitParam(name = "nodePrimaryKeyId", value = "当前操作的日志类型ID,即左侧列表的节点primaryKeyId", required = true),
-			@ApiImplicitParam(name = "recordTime", value = "当前选择的填写日期,即右侧日期控件所选日期,格式为 yyyy-MM-dd", required = true)
-	})
-    public R<Boolean> startTaskTheLog(@RequestBody JSONObject json){
-
-		if(json != null){
-			StartTaskVO startTaskVO = JSONObject.parseObject(JSONObject.toJSONString(json), StartTaskVO.class);
-
-			String nodePrimaryKeyId = "", recordTime = "";
-			if(json.containsKey("nodePrimaryKeyId")){
-				nodePrimaryKeyId = json.getString("nodePrimaryKeyId");
-			}
-			if(json.containsKey("recordTime")){
-				recordTime = json.getString("recordTime");
-			}
-
-			if(StringUtils.isEmpty(startTaskVO.getIds())){
-				if(StringUtils.isEmpty(nodePrimaryKeyId) && StringUtils.isEmpty(recordTime)){
-					return R.fail("未找到业务数据");
-				}
-				//如果ids为空,说明是填报页上报,那么需要根据 nodePrimaryKeyId 和 recordTime 获取当前用户的填写记录
-				ContractLog log = this.contractLogService.getOne(Wrappers.<ContractLog>lambdaQuery().eq(ContractLog::getWbsNodeId, nodePrimaryKeyId)
-						.eq(ContractLog::getRecordTime, recordTime).eq(ContractLog::getContractId, startTaskVO.getContractId())
-						.eq(ContractLog::getCreateUser, AuthUtil.getUserId()));
-				if(log == null){
-					return R.fail("未找到业务数据");
-				}
-				startTaskVO.setIds(String.valueOf(log.getId()));
-			}
-			return this.batchTask(startTaskVO);
-
-		}
+    @ApiImplicitParams({
+            @ApiImplicitParam(name = "startTaskVO", value = "流程参数", required = true),
+            @ApiImplicitParam(name = "nodePrimaryKeyId", value = "当前操作的日志类型ID,即左侧列表的节点primaryKeyId", required = true),
+            @ApiImplicitParam(name = "recordTime", value = "当前选择的填写日期,即右侧日期控件所选日期,格式为 yyyy-MM-dd", required = true)
+    })
+    public R<Boolean> startTaskTheLog(@RequestBody JSONObject json) throws IOException {
+
+        if (json != null) {
+            StartTaskVO startTaskVO = JSONObject.parseObject(JSONObject.toJSONString(json), StartTaskVO.class);
+
+            String nodePrimaryKeyId = "", recordTime = "";
+            if (json.containsKey("nodePrimaryKeyId")) {
+                nodePrimaryKeyId = json.getString("nodePrimaryKeyId");
+            }
+            if (json.containsKey("recordTime")) {
+                recordTime = json.getString("recordTime");
+            }
+
+            if (StringUtils.isEmpty(startTaskVO.getIds())) {
+                if (StringUtils.isEmpty(nodePrimaryKeyId) && StringUtils.isEmpty(recordTime)) {
+                    return R.fail("未找到业务数据");
+                }
+                //如果ids为空,说明是填报页上报,那么需要根据 nodePrimaryKeyId 和 recordTime 获取当前用户的填写记录
+                ContractLog log = this.contractLogService.getOne(Wrappers.<ContractLog>lambdaQuery().eq(ContractLog::getWbsNodeId, nodePrimaryKeyId)
+                        .eq(ContractLog::getRecordTime, recordTime).eq(ContractLog::getContractId, startTaskVO.getContractId())
+                        .eq(ContractLog::getCreateUser, AuthUtil.getUserId()));
+                if (log == null) {
+                    return R.fail("未找到业务数据");
+                }
+                startTaskVO.setIds(String.valueOf(log.getId()));
+            }
+            return this.batchTask(startTaskVO);
+
+        }
 
         return R.data(300, false, "上报失败");
     }
 
-	/**
-	 * 预览、打印
-	 */
-	@PostMapping("/theLogPreviewAndPrint")
-	@ApiOperationSupport(order = 8)
-	@ApiOperation(value = "预览、打印")
-	@ApiImplicitParam(name = "json", value = "key为 ids数组,ids的数据为勾选的列表数据id集合")
-	public R<String> theLogPreviewAndPrint(@RequestBody JSONObject json){
-		//获取配置的路径
-		String file_path = ParamCache.getValue(CommonConstant.SYS_LOCAL_URL);
-
-		if(json.containsKey("ids")){
-			//id集合
-			List<String> ids = JSONArray.parseArray(JSONObject.toJSONString(json.getJSONArray("ids")), String.class);
-			//查询具体数据
-			List<ContractLog> logList = this.contractLogService.list(Wrappers.<ContractLog>lambdaQuery().in(ContractLog::getId, ids));
-			//获取pdf路径
-			List<String> pdfUrls = logList.stream().map(log -> StringUtils.isNotEmpty(log.getEVisaPdfUrl()) ? log.getEVisaPdfUrl() : log.getPdfUrl()).distinct().collect(Collectors.toList());
-
-			//删除空数据
-			pdfUrls.removeIf(StringUtils::isEmpty);
-
-			if(pdfUrls.size() > 0){
-				//合并的pdf路径
-				String fileName = SnowFlakeUtil.getId() + "-" + new Date().getTime() + ".pdf";
-				String mergePdfPath = file_path + "/pdf//" + fileName;
-				FileUtils.mergePdfPublicMethods(pdfUrls, mergePdfPath);
-
-				//上传
-				BladeFile file = this.newIOSSClient.uploadFile(fileName, mergePdfPath);
-				if(file != null){
-					return R.data(file.getLink());
-				}
-			}
-
-		}
-		return R.fail("未找到数据");
-	}
-
-	/**
-	 * 获取当前日志资料关联的工序节点信息
-	 */
-	@PostMapping("/queryCurrentLogSelectProcessList")
-	@ApiOperationSupport(order = 7)
-	@ApiOperation(value = "获取当前日志资料关联的工序节点信息")
+    /**
+     * 预览、打印
+     */
+    @PostMapping("/theLogPreviewAndPrint")
+    @ApiOperationSupport(order = 8)
+    @ApiOperation(value = "预览、打印")
+    @ApiImplicitParam(name = "json", value = "key为 ids数组,ids的数据为勾选的列表数据id集合")
+    public R<String> theLogPreviewAndPrint(@RequestBody JSONObject json) {
+        //获取配置的路径
+        String file_path = ParamCache.getValue(CommonConstant.SYS_LOCAL_URL);
+
+        if (json.containsKey("ids")) {
+            //id集合
+            List<String> ids = JSONArray.parseArray(JSONObject.toJSONString(json.getJSONArray("ids")), String.class);
+            //查询具体数据
+            List<ContractLog> logList = this.contractLogService.list(Wrappers.<ContractLog>lambdaQuery().in(ContractLog::getId, ids));
+            //获取pdf路径
+            List<String> pdfUrls = logList.stream().map(log -> StringUtils.isNotEmpty(log.getEVisaPdfUrl()) ? log.getEVisaPdfUrl() : log.getPdfUrl()).distinct().collect(Collectors.toList());
+
+            //删除空数据
+            pdfUrls.removeIf(StringUtils::isEmpty);
+
+            if (pdfUrls.size() > 0) {
+                //合并的pdf路径
+                String fileName = SnowFlakeUtil.getId() + "-" + new Date().getTime() + ".pdf";
+                String mergePdfPath = file_path + "/pdf//" + fileName;
+                FileUtils.mergePdfPublicMethods(pdfUrls, mergePdfPath);
+
+                //上传
+                BladeFile file = this.newIOSSClient.uploadFile(fileName, mergePdfPath);
+                if (file != null) {
+                    return R.data(file.getLink());
+                }
+            }
+
+        }
+        return R.fail("未找到数据");
+    }
+
+    /**
+     * 获取当前日志资料关联的工序节点信息
+     */
+    @PostMapping("/queryCurrentLogSelectProcessList")
+    @ApiOperationSupport(order = 7)
+    @ApiOperation(value = "获取当前日志资料关联的工序节点信息")
     @ApiImplicitParam(name = "businessId", value = "数据ID")
-	public R<List<JSONObject>> querySelectProcessList(String businessId){
-		List<JSONObject> jsonResult = new ArrayList<>();
-
-		if(StringUtils.isNotEmpty(businessId)){
-			List<ContractLogWbs> result = this.contractLogWbsService.list(Wrappers.<ContractLogWbs>lambdaQuery().eq(ContractLogWbs::getBusinessId, businessId));
-			if(result != null && result.size() > 0){
-				result.forEach(logWbs -> {
-					JSONObject json = new JSONObject();
-					json.put("primaryKeyId", logWbs.getTreePrimaryKeyId());
-					json.put("path", logWbs.getTitle());
-
-					jsonResult.add(json);
-				});
-			}
-		}
-
-		return R.data(jsonResult);
-	}
-
-	/**
-	 * 获取合同段当前日志节点下的填报日期记录
-	 */
-	@PostMapping("/getSubmitLogDateList")
-	@ApiOperationSupport(order = 6)
-	@ApiOperation(value = "获取合同段当前日志节点下的填报日期记录")
-	public R<List<String>> getSubmitLogDateList(@RequestParam String contractId, @RequestParam String primaryKeyId, @RequestParam String year){
-		return R.data(this.contractLogService.getSubmitLogDateList(contractId, primaryKeyId, year));
-	}
-
-	/**
-	 * 批量废除
-	 */
-	@PostMapping("/batchAbolish")
-	@ApiOperationSupport(order = 5)
-	@ApiOperation(value = "批量废除")
-	public R<Boolean> batchAbolish(@RequestParam String ids){
-		//获取所有相关任务记录
-		List<Task> taskList = this.taskClient.queryTaskListByFormDataId(ids);
-		if(taskList != null && taskList.size() > 0){
-			//执行废除
-			for(Task task : taskList){
-				if(new Integer("1").equals(task.getStatus())){
-					//正在审批,调用废除
-					this.taskClient.abolishTask(task);
-				} else if(new Integer("2").equals(task.getStatus())) {
-					//已审批的任务,修改业务数据的审批状态为未上报并撤签即可
-					this.contractLogService.update(Wrappers.<ContractLog>lambdaUpdate().set(ContractLog::getAuditUserIdAndName, null).set(ContractLog::getEVisaPdfUrl, null).set(ContractLog::getStatus, 3).in(ContractLog::getId, Arrays.asList(task.getFormDataId().split(","))));
-				}
-
-				List<ContractLog> contractLogs = this.contractLogService.getBaseMapper().selectBatchIds(Arrays.asList(task.getFormDataId().split(",")));
-				List<String> fileNameList = new ArrayList<>();
-				for(ContractLog contractLog : contractLogs){
-
-					if(!fileNameList.contains(contractLog.getFileName())){
-						fileNameList.add(contractLog.getFileName());
-					}
-
-					ProjectInfo projectInfo = this.projectClient.queryProjectList(Func.toStrList(contractLog.getProjectId().toString())).get(0);
-					ContractInfo contractInfo = this.contractClient.getContractById(contractLog.getContractId());
-
-					try{
-						//保存推送记录
-						this.messageWarningClient.savePushUserMessageWarning(new MessageWarningVO(
-								contractLog.getProjectId(),
-								contractLog.getContractId(),
-								//废除通知
-								3,
-								//内容
-								(StringUtils.isNotEmpty(projectInfo.getProjectAlias()) ? projectInfo.getProjectAlias() : projectInfo.getProjectName()) + contractInfo.getContractName() + "的用户" + AuthUtil.getNickName() + "废除了【" + contractLog.getFileName() + "】流程,请及时查看",
-								//推送的目标人
-								contractLog.getCreateUser(),
-								//默认未读
-								0
-						));
-
-						//保存操作记录
-						JSONObject json = new JSONObject();
-						json.put("operationObjIds", Func.toStrList(task.getFormDataId()));
-						json.put("operationObjName", contractLog.getFileName());
-
-						this.operationLogClient.saveUserOperationLog(9, "台账日志", "日志填报", json);
-
-
-					}catch (Exception e){
-						e.printStackTrace();
-					}
-
-				}
-				try{
-					//获取当前任务的环节审批人
-					List<TaskParallel> linkList = this.taskClient.queryApprovalUserByTaskId(task.getProcessInstanceId());
-					if(linkList != null && linkList.size() > 0){
-						ProjectInfo projectInfo = this.projectClient.queryProjectList(Func.toStrList(task.getProjectId())).get(0);
-						ContractInfo contractInfo = this.contractClient.getContractById(Long.parseLong(task.getContractId()));
-
-						List<MessageWarningVO> messageList = new ArrayList<>();
-						for(String fileName : fileNameList){
-							for(TaskParallel taskParallel : linkList){
-								messageList.add(new MessageWarningVO(
-										Long.parseLong(task.getProjectId()),
-										Long.parseLong(task.getContractId()),
-										//废除通知
-										3,
-										//内容
-										(StringUtils.isNotEmpty(projectInfo.getProjectAlias()) ? projectInfo.getProjectAlias() : projectInfo.getProjectName()) + contractInfo.getContractName() + "的用户" + AuthUtil.getNickName() + "废除了【" + fileName + "】流程,请及时查看",
-										//推送的目标人
-										Long.parseLong(taskParallel.getTaskUser()),
-										//默认未读
-										0
-								));
-							}
-						}
-						if(messageList.size() > 0){
-							this.messageWarningClient.savePushUserMessageWarning(messageList);
-						}
-					}
-				}catch (Exception e){
-					e.printStackTrace();
-				}
-			}
-		}
-		return R.data(true);
-	}
-
-	/**
-	 * 批量上报
-	 */
-	@PostMapping("/batchTask")
-	@ApiOperationSupport(order = 4)
-	@ApiOperation(value = "批量上报")
-	public R<Boolean> batchTask(@RequestBody StartTaskVO startTaskVO){
-		if(StringUtils.isNotEmpty(startTaskVO.getIds())){
-			//获取数据源id
-			String[] ids = startTaskVO.getIds().split(",");
-			if(ids.length > 0){
-				List<ContractLog> logList = this.contractLogService.list(Wrappers.<ContractLog>lambdaQuery().in(ContractLog::getId, Arrays.asList(ids)));
-				Map<String, String> logMap = new HashMap<>();
-				logList.forEach(log -> logMap.put(log.getId().toString(), log.getFileName()));
-
-				for(String id : ids){
-					//生成任务实体
-					TaskVO taskVO = new TaskVO();
-					BeanUtils.copyProperties(startTaskVO, taskVO);
-					if(taskVO.getUserTasks() != null && taskVO.getUserTasks().size() > 0){
-						//标记为自定义流程
-						taskVO.setFixedFlowId(Long.parseLong("0"));
-					}
-					//设置任务名称
-					if(StringUtils.isNotEmpty(logMap.get(id))){
-						taskVO.setTaskName(logMap.get(id));
-					}
-					//设置数据源指向
-					taskVO.setFormDataId(id);
-					//设置上报类型
-					taskVO.setApprovalType(3);
-					//上报
-					if(this.taskClient.startTask(taskVO).getData()){
+    public R<List<JSONObject>> querySelectProcessList(String businessId) {
+        List<JSONObject> jsonResult = new ArrayList<>();
+
+        if (StringUtils.isNotEmpty(businessId)) {
+            List<ContractLogWbs> result = this.contractLogWbsService.list(Wrappers.<ContractLogWbs>lambdaQuery().eq(ContractLogWbs::getBusinessId, businessId));
+            if (result != null && result.size() > 0) {
+                result.forEach(logWbs -> {
+                    JSONObject json = new JSONObject();
+                    json.put("primaryKeyId", logWbs.getTreePrimaryKeyId());
+                    json.put("path", logWbs.getTitle());
+
+                    jsonResult.add(json);
+                });
+            }
+        }
+
+        return R.data(jsonResult);
+    }
+
+    /**
+     * 获取合同段当前日志节点下的填报日期记录
+     */
+    @PostMapping("/getSubmitLogDateList")
+    @ApiOperationSupport(order = 6)
+    @ApiOperation(value = "获取合同段当前日志节点下的填报日期记录")
+    public R<List<String>> getSubmitLogDateList(@RequestParam String contractId, @RequestParam String primaryKeyId, @RequestParam String year) {
+        return R.data(this.contractLogService.getSubmitLogDateList(contractId, primaryKeyId, year));
+    }
+
+    /**
+     * 批量废除
+     */
+    @PostMapping("/batchAbolish")
+    @ApiOperationSupport(order = 5)
+    @ApiOperation(value = "批量废除")
+    public R<Boolean> batchAbolish(@RequestParam String ids) throws IOException {
+        //获取所有相关任务记录
+        List<Task> taskList = this.taskClient.queryTaskListByFormDataId(ids);
+        if (taskList != null && taskList.size() > 0) {
+            //执行废除
+            for (Task task : taskList) {
+                if (new Integer("1").equals(task.getStatus())) {
+                    //正在审批,调用废除
+                    this.taskClient.abolishTask(task);
+                } else if (new Integer("2").equals(task.getStatus())) {
+                    //已审批的任务,修改业务数据的审批状态为未上报并撤签即可
+                    this.contractLogService.update(Wrappers.<ContractLog>lambdaUpdate().set(ContractLog::getAuditUserIdAndName, null).set(ContractLog::getEVisaPdfUrl, null).set(ContractLog::getStatus, 3).in(ContractLog::getId, Arrays.asList(task.getFormDataId().split(","))));
+                }
+
+                List<ContractLog> contractLogs = this.contractLogService.getBaseMapper().selectBatchIds(Arrays.asList(task.getFormDataId().split(",")));
+                List<String> fileNameList = new ArrayList<>();
+                for (ContractLog contractLog : contractLogs) {
+
+                    if (!fileNameList.contains(contractLog.getFileName())) {
+                        fileNameList.add(contractLog.getFileName());
+                    }
+
+                    ProjectInfo projectInfo = this.projectClient.queryProjectList(Func.toStrList(contractLog.getProjectId().toString())).get(0);
+                    ContractInfo contractInfo = this.contractClient.getContractById(contractLog.getContractId());
+
+                    try {
+                        //保存推送记录
+                        this.messageWarningClient.savePushUserMessageWarning(new MessageWarningVO(
+                                contractLog.getProjectId(),
+                                contractLog.getContractId(),
+                                //废除通知
+                                3,
+                                //内容
+                                (StringUtils.isNotEmpty(projectInfo.getProjectAlias()) ? projectInfo.getProjectAlias() : projectInfo.getProjectName()) + contractInfo.getContractName() + "的用户" + AuthUtil.getNickName() + "废除了【" + contractLog.getFileName() + "】流程,请及时查看",
+                                //推送的目标人
+                                contractLog.getCreateUser(),
+                                //默认未读
+                                0
+                        ));
+
+                        //保存操作记录
+                        JSONObject json = new JSONObject();
+                        json.put("operationObjIds", Func.toStrList(task.getFormDataId()));
+                        json.put("operationObjName", contractLog.getFileName());
+
+                        this.operationLogClient.saveUserOperationLog(9, "台账日志", "日志填报", json);
+
+
+                    } catch (Exception e) {
+                        e.printStackTrace();
+                    }
+
+                }
+                try {
+                    //获取当前任务的环节审批人
+                    List<TaskParallel> linkList = this.taskClient.queryApprovalUserByTaskId(task.getProcessInstanceId());
+                    if (linkList != null && linkList.size() > 0) {
+                        ProjectInfo projectInfo = this.projectClient.queryProjectList(Func.toStrList(task.getProjectId())).get(0);
+                        ContractInfo contractInfo = this.contractClient.getContractById(Long.parseLong(task.getContractId()));
+
+                        List<MessageWarningVO> messageList = new ArrayList<>();
+                        for (String fileName : fileNameList) {
+                            for (TaskParallel taskParallel : linkList) {
+                                messageList.add(new MessageWarningVO(
+                                        Long.parseLong(task.getProjectId()),
+                                        Long.parseLong(task.getContractId()),
+                                        //废除通知
+                                        3,
+                                        //内容
+                                        (StringUtils.isNotEmpty(projectInfo.getProjectAlias()) ? projectInfo.getProjectAlias() : projectInfo.getProjectName()) + contractInfo.getContractName() + "的用户" + AuthUtil.getNickName() + "废除了【" + fileName + "】流程,请及时查看",
+                                        //推送的目标人
+                                        Long.parseLong(taskParallel.getTaskUser()),
+                                        //默认未读
+                                        0
+                                ));
+                            }
+                        }
+                        if (messageList.size() > 0) {
+                            //通过WebSocket推送数量条数
+                            this.messageWarningClient.savePushUserMessageWarning(messageList);
+                        }
+                    }
+                } catch (Exception e) {
+                    e.printStackTrace();
+                }
+            }
+        }
+
+        return R.data(true);
+    }
+
+    /**
+     * 批量上报
+     */
+    @PostMapping("/batchTask")
+    @ApiOperationSupport(order = 4)
+    @ApiOperation(value = "批量上报")
+    public R<Boolean> batchTask(@RequestBody StartTaskVO startTaskVO) throws IOException {
+        if (StringUtils.isNotEmpty(startTaskVO.getIds())) {
+            //获取数据源id
+            String[] ids = startTaskVO.getIds().split(",");
+            if (ids.length > 0) {
+                List<ContractLog> logList = this.contractLogService.list(Wrappers.<ContractLog>lambdaQuery().in(ContractLog::getId, Arrays.asList(ids)));
+                Map<String, String> logMap = new HashMap<>();
+                logList.forEach(log -> logMap.put(log.getId().toString(), log.getFileName()));
+
+                for (String id : ids) {
+                    //生成任务实体
+                    TaskVO taskVO = new TaskVO();
+                    BeanUtils.copyProperties(startTaskVO, taskVO);
+                    if (taskVO.getUserTasks() != null && taskVO.getUserTasks().size() > 0) {
+                        //标记为自定义流程
+                        taskVO.setFixedFlowId(Long.parseLong("0"));
+                    }
+                    //设置任务名称
+                    if (StringUtils.isNotEmpty(logMap.get(id))) {
+                        taskVO.setTaskName(logMap.get(id));
+                    }
+                    //设置数据源指向
+                    taskVO.setFormDataId(id);
+                    //设置上报类型
+                    taskVO.setApprovalType(3);
+                    //上报
+                    if (this.taskClient.startTask(taskVO).getData()) {
                         LambdaUpdateWrapper<ContractLog> wrappers = Wrappers.lambdaUpdate();
                         wrappers.set(ContractLog::getBatch, taskVO.getBatch()).set(ContractLog::getStatus, 1);
 
                         //查询审批人
                         List<TaskParallel> taskUsers = this.taskClient.queryApprovalUser(id);
-                        if(taskUsers.size() > 0){
+                        if (taskUsers.size() > 0) {
                             //生成审批人信息
                             StringBuilder stringBuilder = new StringBuilder();
                             taskUsers.forEach(users -> stringBuilder.append(",").append(users.getTaskUser()).append("-").append(users.getTaskUserName()));
@@ -457,75 +469,86 @@ public class ContractLogController extends BladeController {
                         }
                         wrappers.eq(ContractLog::getId, id);
 
-						//修改记录
-						this.contractLogService.update(wrappers);
-					}
-				}
-
-				List<ContractLog> contractLogs = this.contractLogService.getBaseMapper().selectBatchIds(Arrays.asList(startTaskVO.getIds().split(",")));
-				String title = "批量上报";
-				if(contractLogs != null && contractLogs.size() > 0){
-					title = contractLogs.stream().map(ContractLog::getFileName).distinct().collect(Collectors.joining());
-				}
-
-				try{
-					//保存操作记录
-					JSONObject json = new JSONObject();
-					json.put("operationObjIds", Func.toStrList(startTaskVO.getIds()));
-					json.put("operationObjName", title);
-
-					this.operationLogClient.saveUserOperationLog(8, "台账日志", "日志填报", json);
-				}catch (Exception e){
-					e.printStackTrace();
-				}
-
-				return R.data(true);
-			}
-		}
-		return R.data(false);
-	}
-
-	/**
-	 * 获取当前日志类型的填报人
-	 * @return 结果
-	 */
-	@GetMapping("/queryFillUser")
-	@ApiOperationSupport(order = 3)
-	@ApiOperation(value = "获取当前日志类型的填报人")
-	@ApiImplicitParams({
-			@ApiImplicitParam(name = "primaryKeyId", value = "分类列表的primaryKeyId", required = true),
-			@ApiImplicitParam(name = "contractId", value = "合同段ID", required = true)
-	})
-	public R<List<FileUserVO>> queryFillUser(@RequestParam Long primaryKeyId, @RequestParam Long contractId){
-		ContractLogVO logVo = new ContractLogVO();
-		logVo.setWbsNodeId(primaryKeyId);
-		logVo.setContractId(contractId);
-		return R.data(this.contractLogService.queryFillUser(logVo));
-	}
-
-	/**
-	 * 施工日志分页
-	 * @param logVo 查询条件
-	 * @return 结果
-	 */
-	@PostMapping("/constructionLogPage")
-	@ApiOperationSupport(order = 2)
-	@ApiOperation(value = "施工日志分页")
-	public R<IPage<ContractLogVO>> constructionLogPage(@RequestBody ContractLogVO logVo){
-		return R.data(this.contractLogService.constructionLogPage(logVo));
-	}
-
-	/**
-	 * 获取当前合同段下的日志类型
-	 * @param contractId 合同段ID
-	 * @return 结果
-	 */
-	@GetMapping("/queryCurrentContractLogList")
-	@ApiOperationSupport(order = 1)
-	@ApiOperation(value = "获取当前合同段下的日志类型")
-	@ApiImplicitParam(name = "contractId", value = "合同段ID", required = true)
-	public R<List<WbsTreeContractTreeVOS>> queryCurrentContractLogList(@RequestParam String contractId){
-		return R.data(this.wbsTreeContractClient.queryCurrentContractLogList(contractId));
-	}
+                        //修改记录
+                        this.contractLogService.update(wrappers);
+                    }
+                }
+
+                List<ContractLog> contractLogs = this.contractLogService.getBaseMapper().selectBatchIds(Arrays.asList(startTaskVO.getIds().split(",")));
+                String title = "批量上报";
+                if (contractLogs != null && contractLogs.size() > 0) {
+                    title = contractLogs.stream().map(ContractLog::getFileName).distinct().collect(Collectors.joining());
+                }
+
+                try {
+                    //保存操作记录
+                    JSONObject json = new JSONObject();
+                    json.put("operationObjIds", Func.toStrList(startTaskVO.getIds()));
+                    json.put("operationObjName", title);
+
+                    this.operationLogClient.saveUserOperationLog(8, "台账日志", "日志填报", json);
+                } catch (Exception e) {
+                    e.printStackTrace();
+                }
+
+                //通过WebSocket推送数量条数
+                if (ObjectUtil.isNotEmpty(startTaskVO.getUserTasks())) {
+                    for (StartTaskVO.CustomUserTask userTask : startTaskVO.getUserTasks()) {
+                        Map<String, String> stringMap = iTaskService.getTaskCount(startTaskVO.getProjectId(), startTaskVO.getContractId(), userTask.getUserId());
+                        webSocket.sendMessageByUserId(userTask.getUserId(), JSON.toJSONString(stringMap));
+                    }
+                }
+
+                return R.data(true);
+            }
+        }
+        return R.data(false);
+    }
+
+    /**
+     * 获取当前日志类型的填报人
+     *
+     * @return 结果
+     */
+    @GetMapping("/queryFillUser")
+    @ApiOperationSupport(order = 3)
+    @ApiOperation(value = "获取当前日志类型的填报人")
+    @ApiImplicitParams({
+            @ApiImplicitParam(name = "primaryKeyId", value = "分类列表的primaryKeyId", required = true),
+            @ApiImplicitParam(name = "contractId", value = "合同段ID", required = true)
+    })
+    public R<List<FileUserVO>> queryFillUser(@RequestParam Long primaryKeyId, @RequestParam Long contractId) {
+        ContractLogVO logVo = new ContractLogVO();
+        logVo.setWbsNodeId(primaryKeyId);
+        logVo.setContractId(contractId);
+        return R.data(this.contractLogService.queryFillUser(logVo));
+    }
+
+    /**
+     * 施工日志分页
+     *
+     * @param logVo 查询条件
+     * @return 结果
+     */
+    @PostMapping("/constructionLogPage")
+    @ApiOperationSupport(order = 2)
+    @ApiOperation(value = "施工日志分页")
+    public R<IPage<ContractLogVO>> constructionLogPage(@RequestBody ContractLogVO logVo) {
+        return R.data(this.contractLogService.constructionLogPage(logVo));
+    }
+
+    /**
+     * 获取当前合同段下的日志类型
+     *
+     * @param contractId 合同段ID
+     * @return 结果
+     */
+    @GetMapping("/queryCurrentContractLogList")
+    @ApiOperationSupport(order = 1)
+    @ApiOperation(value = "获取当前合同段下的日志类型")
+    @ApiImplicitParam(name = "contractId", value = "合同段ID", required = true)
+    public R<List<WbsTreeContractTreeVOS>> queryCurrentContractLogList(@RequestParam String contractId) {
+        return R.data(this.wbsTreeContractClient.queryCurrentContractLogList(contractId));
+    }
 
 }

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

@@ -1,5 +1,6 @@
 package org.springblade.business.controller;
 
+import com.alibaba.fastjson.JSON;
 import com.alibaba.fastjson.JSONArray;
 import com.alibaba.fastjson.JSONObject;
 import com.baomidou.mybatisplus.core.conditions.update.LambdaUpdateWrapper;
@@ -21,6 +22,8 @@ import org.springblade.business.feign.RecycleBinClient;
 import org.springblade.business.feign.TaskClient;
 import org.springblade.business.service.IConstructionLedgerService;
 import org.springblade.business.service.IInformationQueryFileService;
+import org.springblade.business.service.ITaskService;
+import org.springblade.business.socket.WebSocket;
 import org.springblade.business.utils.FileUtils;
 import org.springblade.business.vo.*;
 import org.springblade.common.constant.CommonConstant;
@@ -33,6 +36,7 @@ import org.springblade.core.secure.utils.AuthUtil;
 import org.springblade.core.tool.api.R;
 import org.springblade.core.tool.node.ForestNodeMerger;
 import org.springblade.core.tool.utils.Func;
+import org.springblade.core.tool.utils.ObjectUtil;
 import org.springblade.evisa.feign.EVisaClient;
 import org.springblade.evisa.vo.CertBeanVO;
 import org.springblade.manager.entity.*;
@@ -41,7 +45,6 @@ import org.springblade.manager.feign.ProjectClient;
 import org.springblade.manager.feign.WbsTreeContractClient;
 import org.springblade.manager.feign.WbsTreePrivateClient;
 import org.springblade.manager.vo.WbsTreeContractTreeVOS;
-import org.springblade.manager.vo.WbsTreeContractVO;
 import org.springblade.resource.feign.NewIOSSClient;
 import org.springblade.system.cache.ParamCache;
 import org.springblade.system.entity.DictBiz;
@@ -53,6 +56,7 @@ import org.springframework.web.bind.annotation.RequestParam;
 import org.springblade.business.service.IInformationQueryService;
 import org.springblade.core.boot.ctrl.BladeController;
 
+import java.io.IOException;
 import java.util.*;
 import java.util.stream.Collectors;
 
@@ -98,6 +102,10 @@ public class InformationWriteQueryController extends BladeController {
 
     private final ProjectClient projectClient;
 
+    private final ITaskService iTaskService;
+
+    private final WebSocket webSocket;
+
     /**
      * 获取文件题名
      */
@@ -214,8 +222,8 @@ public class InformationWriteQueryController extends BladeController {
 
                 for (ContractInfo contractInfo : contractInfos) {
                     for (WbsTreeContractTreeVOS wbsTreeContractTreeVOS : sgChildNodeList) {
-                        if (contractInfo.getId().equals(Long.parseLong(wbsTreeContractTreeVOS.getContractIdRelation()))){
-                            if (wbsTreeContractTreeVOS.getParentId().equals(0L)){
+                        if (contractInfo.getId().equals(Long.parseLong(wbsTreeContractTreeVOS.getContractIdRelation()))) {
+                            if (wbsTreeContractTreeVOS.getParentId().equals(0L)) {
                                 wbsTreeContractTreeVOS.setTitle(contractInfo.getContractName());
                                 wbsTreeContractTreeVOS.setNodeName(contractInfo.getContractName());
                                 wbsTreeContractTreeVOS.setFullName(contractInfo.getContractName());
@@ -283,11 +291,11 @@ public class InformationWriteQueryController extends BladeController {
                 //获取合同段名称,设置根节点名称
                 ContractInfo contractInfo = contractClient.getContractById(Long.valueOf(contractId));
                 for (WbsTreeContractTreeVOS wbsTreeContractTreeVOS : result) {
-                        if (wbsTreeContractTreeVOS.getParentId().equals(0L)){
-                            wbsTreeContractTreeVOS.setTitle(contractInfo.getContractName());
-                            wbsTreeContractTreeVOS.setNodeName(contractInfo.getContractName());
-                            wbsTreeContractTreeVOS.setFullName(contractInfo.getContractName());
-                        }
+                    if (wbsTreeContractTreeVOS.getParentId().equals(0L)) {
+                        wbsTreeContractTreeVOS.setTitle(contractInfo.getContractName());
+                        wbsTreeContractTreeVOS.setNodeName(contractInfo.getContractName());
+                        wbsTreeContractTreeVOS.setFullName(contractInfo.getContractName());
+                    }
                 }
 
                 return R.data(result);
@@ -602,7 +610,7 @@ public class InformationWriteQueryController extends BladeController {
     @PostMapping("/taskOne")
     @ApiOperationSupport(order = 22)
     @ApiOperation(value = "填报页单个上报")
-    public R<Boolean> taskOne(@RequestBody StartTaskVO startTaskVO) {
+    public R<Boolean> taskOne(@RequestBody StartTaskVO startTaskVO) throws IOException {
         //此时的ids是当前节点的primaryKeyId但并不是业务数据ID,需要根据ids和classify去查询具体的业务ID
         InformationQuery businessData = this.informationQueryService.getOne(Wrappers.<InformationQuery>lambdaQuery().eq(InformationQuery::getWbsId, startTaskVO.getIds().replaceAll(",", "")).eq(InformationQuery::getClassify, startTaskVO.getClassify().toString()));
 
@@ -612,6 +620,7 @@ public class InformationWriteQueryController extends BladeController {
             startTaskVO.setIds(businessData.getId().toString());
             return this.batchTask(startTaskVO);
         }
+
         return R.data(300, false, "上报失败");
     }
 
@@ -830,10 +839,10 @@ public class InformationWriteQueryController extends BladeController {
                                     ));
                                 }
                                 if (messageList.size() > 0) {
+                                    //内部通过WebSocket推送数量条数
                                     this.messageWarningClient.savePushUserMessageWarning(messageList);
                                 }
                             }
-
                         }
                     }
 
@@ -863,7 +872,7 @@ public class InformationWriteQueryController extends BladeController {
     @PostMapping("/batchTask")
     @ApiOperationSupport(order = 17)
     @ApiOperation(value = "批量上报")
-    public R<Boolean> batchTask(@RequestBody StartTaskVO startTaskVO) {
+    public R<Boolean> batchTask(@RequestBody StartTaskVO startTaskVO) throws IOException {
         if (StringUtils.isNotEmpty(startTaskVO.getIds())) {
             //获取数据源id
             String[] ids = startTaskVO.getIds().split(",");
@@ -929,6 +938,13 @@ public class InformationWriteQueryController extends BladeController {
                 } catch (Exception e) {
                     e.printStackTrace();
                 }
+
+                //通过WebSocket推送数量条数
+                for (StartTaskVO.CustomUserTask userTask : startTaskVO.getUserTasks()) {
+                    Map<String, String> stringMap = iTaskService.getTaskCount(startTaskVO.getProjectId(), startTaskVO.getContractId(), userTask.getUserId());
+                    webSocket.sendMessageByUserId(userTask.getUserId(), JSON.toJSONString(stringMap));
+                }
+
                 return R.data(true);
             }
         }

+ 218 - 142
blade-service/blade-business/src/main/java/org/springblade/business/controller/MessageWarningController.java

@@ -16,8 +16,10 @@
  */
 package org.springblade.business.controller;
 
+import com.alibaba.fastjson.JSON;
 import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
 import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
+import com.baomidou.mybatisplus.core.toolkit.ObjectUtils;
 import com.baomidou.mybatisplus.core.toolkit.Wrappers;
 import io.swagger.annotations.Api;
 import io.swagger.annotations.ApiOperation;
@@ -27,7 +29,11 @@ import lombok.AllArgsConstructor;
 
 import org.apache.commons.lang.StringUtils;
 import org.apache.commons.lang.time.DateUtils;
+import org.apache.logging.log4j.LogManager;
+import org.apache.logging.log4j.Logger;
 import org.springblade.business.entity.MessageWarning;
+import org.springblade.business.service.ITaskService;
+import org.springblade.business.socket.WebSocket;
 import org.springblade.business.vo.MessageWarningVO;
 import org.springblade.business.wrapper.MessageWarningWrapper;
 import org.springblade.core.mp.support.Condition;
@@ -36,19 +42,22 @@ import org.springblade.core.secure.utils.AuthUtil;
 import org.springblade.core.tool.api.R;
 import org.springblade.core.tool.utils.DateUtil;
 import org.springblade.core.tool.utils.Func;
+import org.springblade.core.tool.utils.ObjectUtil;
 import org.springblade.system.entity.DictBiz;
 import org.springblade.system.feign.IDictBizClient;
+import org.springframework.scheduling.annotation.Scheduled;
 import org.springframework.web.bind.annotation.*;
 import org.springframework.web.bind.annotation.RequestParam;
 import com.baomidou.mybatisplus.core.metadata.IPage;
 import org.springblade.business.service.IMessageWarningService;
 import org.springblade.core.boot.ctrl.BladeController;
 
-import java.util.Comparator;
-import java.util.List;
+import javax.websocket.Session;
+import java.io.IOException;
+import java.util.*;
 
 /**
- *  控制器
+ * 控制器
  *
  * @author BladeX
  * @since 2022-09-05
@@ -59,143 +68,210 @@ import java.util.List;
 @Api(value = "消息提醒", tags = "消息提醒接口")
 public class MessageWarningController extends BladeController {
 
-	private final IMessageWarningService messageWarningService;
-
-	private final IDictBizClient dictBizClient;
-
-	/**
-	 * 标记已读
-	 */
-	@PostMapping("/setMessageWarningRead")
-	@ApiOperationSupport(order = 5)
-	@ApiOperation(value = "标记已读")
-	public R<Boolean> setMessageWarningRead(MessageWarningVO vo){
-		if(vo.getIds() != null && vo.getIds().size() > 0){
-			try{
-				this.messageWarningService.update(Wrappers.<MessageWarning>lambdaUpdate().set(MessageWarning::getIsRead, 1).in(MessageWarning::getId, vo.getIds()));
-				return R.data(true);
-			}catch (Exception e){
-				e.printStackTrace();
-			}
-		}
-		return R.data(300, false, "标记失败");
-	}
-
-	/**
-	 * 获取当前用户的消息数量
-	 */
-	@GetMapping("/queryCurrentUserMessageCount")
-	@ApiOperationSupport(order = 4)
-	@ApiOperation(value = "获取当前用户的消息数量")
-	public R<MessageWarningVO> queryCurrentUserMessageCount(@RequestParam String projectId, @RequestParam String contractId){
-		MessageWarningVO vo = new MessageWarningVO();
-
-		for(int i = 1, l = 6; i < l; i ++){
-			LambdaQueryWrapper<MessageWarning> wrapper = Wrappers.lambdaQuery();
-			//当前用户
-			wrapper.eq(MessageWarning::getPushUser, AuthUtil.getUserId());
-			wrapper.eq(MessageWarning::getType, i);
-			wrapper.eq(MessageWarning::getIsRead, 0);
-			wrapper.eq(MessageWarning::getProjectId, projectId);
-			wrapper.eq(MessageWarning::getContractId, contractId);
-
-			//获取数量
-			Long typeNumber = this.messageWarningService.count(wrapper);
-
-			switch (i){
-				case 1:
-					vo.setTypeOneNumber(typeNumber);
-					break;
-				case 2:
-					vo.setTypeTowNumber(typeNumber);
-					break;
-				case 3:
-					vo.setTypeThreeNumber(typeNumber);
-					break;
-				case 4:
-					vo.setTypeFourNumber(typeNumber);
-					break;
-				case 5:
-					vo.setTypeFiveNumber(typeNumber);
-					break;
-				default:
-					break;
-			}
-
-		}
-
-		return R.data(vo);
-	}
-
-	/**
-	 * 获取消息类型(左侧菜单)
-	 */
-	@GetMapping("/queryMessageType")
-	@ApiOperationSupport(order = 3)
-	@ApiOperation(value = "获取消息类型(左侧菜单)")
-	public R<List<DictBiz>> queryMessageType() {
-		List<DictBiz> dictBizs = this.dictBizClient.getList("business_message_type", "notRoot").getData();
-		if(dictBizs != null && dictBizs.size() > 0){
-			dictBizs.sort(Comparator.comparing(DictBiz::getSort));
-		}
-		return R.data(dictBizs);
-	}
-
-	/**
-	 * 分页 
-	 */
-	@GetMapping("/list")
-	@ApiOperationSupport(order = 1)
-	@ApiOperation(value = "分页", notes = "传入operationWarning")
-	public R<IPage<MessageWarningVO>> list(MessageWarningVO vo, Query query) {
-
-		QueryWrapper<MessageWarning> wrapper = Condition.getQueryWrapper(vo);
-		//获取当前人的数据
-		wrapper.lambda().eq(MessageWarning::getPushUser, AuthUtil.getUserId().toString());
-		if(StringUtils.isNotEmpty(vo.getStartTime())){
-			wrapper.lambda().between(MessageWarning::getCreateTime, vo.getStartTime(), DateUtil.format(DateUtils.addDays(DateUtil.parse(vo.getEndTime(), "yyyy-MM-dd"), 1), "yyyy-MM-dd"));
-		}
-
-		if(vo.getSmsType() != null && vo.getSmsType() > -1){
-			wrapper.lambda().eq(MessageWarning::getIsRead, new Integer("2").equals(vo.getSmsType()) ? 0 : 1);
-		}
-		//设置合同段ID
-		wrapper.lambda().eq(MessageWarning::getProjectId, vo.getProjectId()).eq(MessageWarning::getContractId, vo.getContractId());
-
-		//时间倒序,状态正序(已读在后,未读在前)
-		wrapper.lambda().orderByAsc(MessageWarning::getIsRead).orderByDesc(MessageWarning::getCreateTime);
-
-		IPage<MessageWarningVO> iPage = MessageWarningWrapper.build().pageVO(this.messageWarningService.page(Condition.getPage(query), wrapper));
-
-		if(iPage.getRecords() != null && iPage.getRecords().size() > 0){
-			//获取类型
-			List<DictBiz> dictBizs = this.dictBizClient.getList("business_message_type", "notRoot").getData();
-
-			iPage.getRecords().forEach(reVO -> {
-				if(dictBizs != null && dictBizs.size() > 0){
-					for(DictBiz biz : dictBizs){
-						if(biz.getDictKey().equals(reVO.getType().toString())){
-							reVO.setTypeValue(biz.getDictValue());
-							break;
-						}
-					}
-				}
-			});
-		}
-
-		return R.data(iPage);
-	}
-
-	
-	/**
-	 * 删除 
-	 */
-	@PostMapping("/remove")
-	@ApiOperationSupport(order = 2)
-	@ApiOperation(value = "逻辑删除", notes = "传入ids")
-	public R remove(@ApiParam(value = "主键集合", required = true) @RequestParam String ids) {
-		return R.status(this.messageWarningService.deleteLogic(Func.toLongList(ids)));
-	}
-
-	
+    private final static Logger logger = LogManager.getLogger(MessageWarningController.class);
+
+    private final IMessageWarningService messageWarningService;
+
+    private final IDictBizClient dictBizClient;
+
+    private final ITaskService iTaskService;
+
+    private final WebSocket webSocket;
+
+    /**
+     * 标记已读
+     */
+    @PostMapping("/setMessageWarningRead")
+    @ApiOperationSupport(order = 5)
+    @ApiOperation(value = "标记已读")
+    public R<Boolean> setMessageWarningRead(MessageWarningVO vo) {
+        if (vo.getIds() != null && vo.getIds().size() > 0) {
+            try {
+                this.messageWarningService.update(Wrappers.<MessageWarning>lambdaUpdate().set(MessageWarning::getIsRead, 1).in(MessageWarning::getId, vo.getIds()));
+
+                //通过WebSocket推送数量条数
+                if (ObjectUtil.isNotEmpty(AuthUtil.getUserId())) {
+                    Map<String, String> webSocketMessageMap = WebSocket.getWebSocketMessageMap();
+                    Set<Map.Entry<String, String>> message = webSocketMessageMap.entrySet();
+                    for (Map.Entry<String, String> entry : message) {
+                        String userId = entry.getKey();
+                        if (userId.equals(AuthUtil.getUserId().toString())) { //只推送当前用户
+                            String projectAndContractId = entry.getValue();
+                            if (StringUtils.isNotEmpty(projectAndContractId) && StringUtils.isNotEmpty(userId)) {
+                                String projectId = projectAndContractId.split(",")[0];
+                                String contractId = projectAndContractId.split(",")[1];
+                                Map<String, String> stringMap = iTaskService.getTaskCount(projectId, contractId, userId);
+
+                                webSocket.sendMessageByUserId(AuthUtil.getUserId().toString(), JSON.toJSONString(stringMap));
+                            }
+                        }
+                    }
+                }
+
+                return R.data(true);
+            } catch (Exception e) {
+                e.printStackTrace();
+            }
+        }
+        return R.data(300, false, "标记失败");
+    }
+
+    /**
+     * 获取当前用户的消息数量
+     */
+    @GetMapping("/queryCurrentUserMessageCount")
+    @ApiOperationSupport(order = 4)
+    @ApiOperation(value = "获取当前用户的消息数量")
+    public R<MessageWarningVO> queryCurrentUserMessageCount(@RequestParam String projectId, @RequestParam String contractId) {
+        MessageWarningVO vo = new MessageWarningVO();
+
+        for (int i = 1, l = 6; i < l; i++) {
+            LambdaQueryWrapper<MessageWarning> wrapper = Wrappers.lambdaQuery();
+            //当前用户
+            wrapper.eq(MessageWarning::getPushUser, AuthUtil.getUserId());
+            wrapper.eq(MessageWarning::getType, i);
+            wrapper.eq(MessageWarning::getIsRead, 0);
+            wrapper.eq(MessageWarning::getProjectId, projectId);
+            wrapper.eq(MessageWarning::getContractId, contractId);
+
+            //获取数量
+            Long typeNumber = this.messageWarningService.count(wrapper);
+
+            switch (i) {
+                case 1:
+                    vo.setTypeOneNumber(typeNumber);
+                    break;
+                case 2:
+                    vo.setTypeTowNumber(typeNumber);
+                    break;
+                case 3:
+                    vo.setTypeThreeNumber(typeNumber);
+                    break;
+                case 4:
+                    vo.setTypeFourNumber(typeNumber);
+                    break;
+                case 5:
+                    vo.setTypeFiveNumber(typeNumber);
+                    break;
+                default:
+                    break;
+            }
+
+        }
+
+        return R.data(vo);
+    }
+
+    /**
+     * 获取消息类型(左侧菜单)
+     */
+    @GetMapping("/queryMessageType")
+    @ApiOperationSupport(order = 3)
+    @ApiOperation(value = "获取消息类型(左侧菜单)")
+    public R<List<DictBiz>> queryMessageType() {
+        List<DictBiz> dictBizs = this.dictBizClient.getList("business_message_type", "notRoot").getData();
+        if (dictBizs != null && dictBizs.size() > 0) {
+            dictBizs.sort(Comparator.comparing(DictBiz::getSort));
+        }
+        return R.data(dictBizs);
+    }
+
+    /**
+     * 分页
+     */
+    @GetMapping("/list")
+    @ApiOperationSupport(order = 1)
+    @ApiOperation(value = "分页", notes = "传入operationWarning")
+    public R<IPage<MessageWarningVO>> list(MessageWarningVO vo, Query query) {
+
+        QueryWrapper<MessageWarning> wrapper = Condition.getQueryWrapper(vo);
+        //获取当前人的数据
+        wrapper.lambda().eq(MessageWarning::getPushUser, AuthUtil.getUserId().toString());
+        if (StringUtils.isNotEmpty(vo.getStartTime())) {
+            wrapper.lambda().between(MessageWarning::getCreateTime, vo.getStartTime(), DateUtil.format(DateUtils.addDays(DateUtil.parse(vo.getEndTime(), "yyyy-MM-dd"), 1), "yyyy-MM-dd"));
+        }
+
+        if (vo.getSmsType() != null && vo.getSmsType() > -1) {
+            wrapper.lambda().eq(MessageWarning::getIsRead, new Integer("2").equals(vo.getSmsType()) ? 0 : 1);
+        }
+        //设置合同段ID
+        wrapper.lambda().eq(MessageWarning::getProjectId, vo.getProjectId()).eq(MessageWarning::getContractId, vo.getContractId());
+
+        //时间倒序,状态正序(已读在后,未读在前)
+        wrapper.lambda().orderByAsc(MessageWarning::getIsRead).orderByDesc(MessageWarning::getCreateTime);
+
+        IPage<MessageWarningVO> iPage = MessageWarningWrapper.build().pageVO(this.messageWarningService.page(Condition.getPage(query), wrapper));
+
+        if (iPage.getRecords() != null && iPage.getRecords().size() > 0) {
+            //获取类型
+            List<DictBiz> dictBizs = this.dictBizClient.getList("business_message_type", "notRoot").getData();
+
+            iPage.getRecords().forEach(reVO -> {
+                if (dictBizs != null && dictBizs.size() > 0) {
+                    for (DictBiz biz : dictBizs) {
+                        if (biz.getDictKey().equals(reVO.getType().toString())) {
+                            reVO.setTypeValue(biz.getDictValue());
+                            break;
+                        }
+                    }
+                }
+            });
+        }
+
+        return R.data(iPage);
+    }
+
+
+    /**
+     * 删除
+     */
+    @PostMapping("/remove")
+    @ApiOperationSupport(order = 2)
+    @ApiOperation(value = "逻辑删除", notes = "传入ids")
+    public R remove(@ApiParam(value = "主键集合", required = true) @RequestParam String ids) {
+        return R.status(this.messageWarningService.deleteLogic(Func.toLongList(ids)));
+    }
+
+
+    /***
+     * 定时重发任务消息WebSocket
+     */
+    @Scheduled(cron = "0 0/5 * * * ?")
+    public void reSendMessage() throws IOException {
+        Map<String, WebSocket> webSocketMap = WebSocket.getWebSocketMap();
+        Map<String, String> webSocketMessageMap = WebSocket.getWebSocketMessageMap();
+
+        if (webSocketMap.isEmpty() || webSocketMessageMap.isEmpty()) {
+            logger.error("定时重发消息WebSocket,reSendMessage()方法未执行,原因:客户端未建立WebSocket链接");
+            return;
+        }
+
+        logger.info("定时重发消息WebSocket,reSendMessage()方法执行成功,入参:webSocketMap->{},webSocketMessageMap->{}", webSocketMap, webSocketMessageMap);
+
+        Set<Map.Entry<String, String>> message = webSocketMessageMap.entrySet();
+
+        List<Map<String, String>> maps = new ArrayList<>();
+
+        for (Map.Entry<String, String> entry : message) {
+            String userId = entry.getKey();
+            String projectAndContractId = entry.getValue();
+
+            if (StringUtils.isNotEmpty(projectAndContractId) && StringUtils.isNotEmpty(userId)) {
+
+                String projectId = projectAndContractId.split(",")[0];
+                String contractId = projectAndContractId.split(",")[1];
+                Map<String, String> stringMap = iTaskService.getTaskCount(projectId, contractId, userId);
+                maps.add(stringMap);
+            }
+        }
+
+        for (Map<String, String> map : maps) {
+            String userId = map.get("userId");
+            webSocketMap.get(userId).sendMessage(JSON.toJSONString(map));
+            logger.info("给用户{}重发消息{}", userId, map);
+        }
+        logger.info("定时重发消息WebSocket,reSendMessage()方法执行结束");
+    }
+
+
 }

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

@@ -1,5 +1,6 @@
 package org.springblade.business.controller;
 
+import com.alibaba.fastjson.JSON;
 import com.alibaba.fastjson.JSONArray;
 import com.alibaba.fastjson.JSONObject;
 import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
@@ -19,6 +20,7 @@ import org.springblade.business.entity.TaskParallel;
 import org.springblade.business.service.IDefaultConfigService;
 import org.springblade.business.service.ITaskBatchService;
 import org.springblade.business.service.ITaskParallelService;
+import org.springblade.business.socket.WebSocket;
 import org.springblade.business.vo.BatchTaskVO;
 import org.springblade.business.vo.TaskApprovalVO;
 import org.springblade.business.vo.TaskQueryVO;
@@ -30,6 +32,7 @@ import org.springblade.core.sms.model.SmsResponse;
 import org.springblade.core.tool.api.R;
 import org.springblade.core.tool.jackson.JsonUtil;
 import org.springblade.core.tool.utils.DateUtil;
+import org.springblade.core.tool.utils.ObjectUtil;
 import org.springblade.flow.core.entity.BladeFlow;
 import org.springblade.flow.core.feign.NewFlowClient;
 import org.springblade.manager.feign.ContractClient;
@@ -45,6 +48,7 @@ import org.springblade.business.service.ITaskService;
 import org.springblade.core.boot.ctrl.BladeController;
 
 import java.io.FileNotFoundException;
+import java.io.IOException;
 import java.time.Duration;
 import java.util.*;
 import java.util.stream.Collectors;
@@ -75,6 +79,10 @@ public class TaskController extends BladeController {
 
 	private final ITaskBatchService taskBatchService;
 
+	private final ITaskService iTaskService;
+
+	private final WebSocket webSocket;
+
 	/**
 	 * 记录短信验证码超时时间
 	 */
@@ -257,7 +265,7 @@ public class TaskController extends BladeController {
 	@PostMapping("/batch-complete-approval-task")
 	@ApiOperationSupport(order = 8)
 	@ApiOperation(value = "批量审批")
-	public R<Boolean> batchCompleteApprovalTask(@RequestBody BatchTaskVO batchTaskVO) throws FileNotFoundException {
+	public R<Boolean> batchCompleteApprovalTask(@RequestBody BatchTaskVO batchTaskVO) throws IOException {
 		String taskIds = batchTaskVO.getTaskIds();
 		String parallelProcessInstanceIds = batchTaskVO.getParallelProcessInstanceIds();
 		if(StringUtils.isNotEmpty(taskIds)){
@@ -280,6 +288,26 @@ public class TaskController extends BladeController {
 				taskApprovalVOS.add(approvalVO);
 			}
 			this.taskService.batchCompleteApprovalTask(taskApprovalVOS);
+
+			//通过WebSocket推送数量条数
+			if (ObjectUtil.isNotEmpty(AuthUtil.getUserId())) {
+				Map<String, String> webSocketMessageMap = WebSocket.getWebSocketMessageMap();
+				Set<Map.Entry<String, String>> message = webSocketMessageMap.entrySet();
+				for (Map.Entry<String, String> entry : message) {
+					String userId = entry.getKey();
+					if (userId.equals(AuthUtil.getUserId().toString())) { //只推送当前用户
+						String projectAndContractId = entry.getValue();
+						if (StringUtils.isNotEmpty(projectAndContractId) && StringUtils.isNotEmpty(userId)) {
+							String projectId = projectAndContractId.split(",")[0];
+							String contractId = projectAndContractId.split(",")[1];
+							Map<String, String> stringMap = iTaskService.getTaskCount(projectId, contractId, userId);
+
+							webSocket.sendMessageByUserId(AuthUtil.getUserId().toString(), JSON.toJSONString(stringMap));
+						}
+					}
+				}
+			}
+
 			return R.data(true);
 		}
 		return R.data(false);

+ 29 - 0
blade-service/blade-business/src/main/java/org/springblade/business/controller/TestDemoController.java

@@ -0,0 +1,29 @@
+package org.springblade.business.controller;
+
+import lombok.AllArgsConstructor;
+import org.springblade.business.socket.WebSocket;
+import org.springblade.core.boot.ctrl.BladeController;
+import org.springframework.web.bind.annotation.PostMapping;
+import org.springframework.web.bind.annotation.RequestMapping;
+import org.springframework.web.bind.annotation.RestController;
+
+import java.io.IOException;
+
+@RestController
+@AllArgsConstructor
+@RequestMapping("/task")
+public class TestDemoController extends BladeController {
+
+    private WebSocket webSocket;
+
+    @PostMapping("/sentMessage")
+    public void sentMessage(String userId,String message){
+        try {
+            webSocket.sendMessageByUserId(userId,message);
+        } catch (IOException e) {
+            e.printStackTrace();
+        }
+    }
+
+
+}

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

@@ -23,6 +23,7 @@ import com.baomidou.mybatisplus.core.metadata.IPage;
 import java.util.List;
 import org.apache.ibatis.annotations.Param;
 import org.springblade.business.vo.QueryProcessDataVO;
+import org.springblade.manager.entity.WbsTreeContract;
 import org.springblade.manager.vo.WbsTreeContractTreeVOS;
 
 /**
@@ -78,4 +79,6 @@ public interface InformationQueryMapper extends BaseMapper<InformationQuery> {
 	 */
 	List<InformationQuery> selectInformationQueryPage(@Param("current") Long current, @Param("size") Long size, @Param("query") InformationQueryVO informationQuery);
 
+	List<WbsTreeContract> getContractNodeByPrimaryKeyIds(String ids);
+
 }

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

@@ -32,6 +32,7 @@
         <result column="e_visa_pdf_url" property="eVisaPdfUrl"/>
         <result column="table_id" property="tableId"/>
         <result column="link_merge_pdf_url" property="linkMergePdfUrl"/>
+        <result column="sort" property="sort"/>
     </resultMap>
 
     <resultMap id="queryProcessDataMap" type="org.springblade.business.vo.QueryProcessDataVO">
@@ -374,6 +375,7 @@
 
     <select id="selectInformationQueryPage" resultMap="informationQueryResultMap">
         select
+            query.wbs_id,
             query.id,
             query.name,
             query.number,
@@ -382,9 +384,7 @@
             query.report_number,
             query.file_user_id_and_name,
             query.pdf_url,
-            query.e_visa_pdf_url,
-            (select sort from m_wbs_tree_contract where p_key_id = query.wbs_id and is_deleted = 0) as sort,
-            (select parent_id from m_wbs_tree_contract where p_key_id = query.wbs_id and is_deleted = 0) as parentId
+            query.e_visa_pdf_url
         from
         (
             select
@@ -423,8 +423,11 @@
         <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>
-        order by parentId,sort
         limit #{current}, #{size}
     </select>
 
+    <select id="getContractNodeByPrimaryKeyIds" resultType="org.springblade.manager.entity.WbsTreeContract">
+        select * from m_wbs_tree_contract where p_key_id in (${ids}) and is_deleted = 0 order by ancestors,sort
+    </select>
+
 </mapper>

+ 2 - 6
blade-service/blade-business/src/main/java/org/springblade/business/mapper/MessageWarningMapper.java

@@ -18,16 +18,12 @@ package org.springblade.business.mapper;
 
 import com.baomidou.mybatisplus.core.mapper.BaseMapper;
 import org.springblade.business.entity.MessageWarning;
-import org.springblade.business.vo.MessageWarningVO;
-import com.baomidou.mybatisplus.core.metadata.IPage;
-import java.util.List;
 
 /**
- *  Mapper 接口
+ * Mapper 接口
  *
  * @author BladeX
  * @since 2022-09-05
  */
 public interface MessageWarningMapper extends BaseMapper<MessageWarning> {
-
-}
+}

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

@@ -24,6 +24,7 @@ import org.springblade.core.mp.base.BaseService;
 
 import java.io.FileNotFoundException;
 import java.util.List;
+import java.util.Map;
 
 /**
  * 任务审核主表 服务类
@@ -61,4 +62,9 @@ public interface ITaskService extends BaseService<Task> {
      */
     Boolean abolishTask(Task task);
 
+    /**
+     * 获取待办任务数量
+     */
+    Map<String,String> getTaskCount(String projectId, String contractId, String userId);
+
 }

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

@@ -36,7 +36,7 @@ import java.util.*;
 import java.util.stream.Collectors;
 
 /**
- *  服务实现类
+ * 服务实现类
  *
  * @author BladeX
  * @since 2022-06-08
@@ -45,444 +45,462 @@ import java.util.stream.Collectors;
 @AllArgsConstructor
 public class InformationQueryServiceImpl extends BaseServiceImpl<InformationQueryMapper, InformationQuery> implements IInformationQueryService {
 
-	private final WbsTreeContractClient wbsTreeContractClient;
+    private final WbsTreeContractClient wbsTreeContractClient;
 
-	private final IUserClient userClient;
+    private final IUserClient userClient;
 
-	private final TaskClient taskClient;
+    private final TaskClient taskClient;
 
-	private final ITaskParallelService taskParallelService;
-
-	private final IFirstInformationService firstInformationService;
-
-	private final NewIOSSClient newIOSSClient;
-
-	private final IInformationQueryFileService informationQueryFileService;
-
-	private final IContractLogService contractLogService;
-
-	@Override
-	public List<String> queryBusinessTableData(String formDataId) {
-		//获取具体业务数据
-		InformationQuery query = this.getById(formDataId);
-
-		//查询这个业务数据绑定的表格,需要区分监理和施工
-		if(query != null){
-			WbsTreeContract tree = this.wbsTreeContractClient.getContractWbsTreeByPrimaryKeyId(query.getWbsId());
-			List<WbsTreeContract> tableList = this.wbsTreeContractClient.queryChildByParentId(tree, "queryTable", String.valueOf(query.getClassify()));
-			if(tableList != null && tableList.size() > 0){
-				//删除掉无法溯源的数据
-				tableList.removeIf(node -> node.getIsTypePrivatePid() == null || node.getIsTypePrivatePid() <= 0 || StringUtils.isEmpty(node.getIsTypePrivatePid().toString()));
-
-				List<Long> privatePIdList = tableList.stream().map(WbsTreeContract::getIsTypePrivatePid).distinct().collect(Collectors.toList());
-
-				return JSONArray.parseArray(JSONObject.toJSONString(privatePIdList), String.class);
-			}
-		} else {
-			//那么就可能是日志,检查是不是日志
-			ContractLog log = this.contractLogService.getById(formDataId);
-			if(log != null){
-				//说明是日志,日志的绑定节点在wbs_tree_private表中,所以这个节点ID就是要找的ID
-				return Func.toStrList(String.valueOf(log.getTableId()));
-			}
-		}
-
-		return null;
-	}
-
-	@Override
-	public List<WbsTreeContractTreeVOS> queryContractTreeSupervision(List<String> contractIds, String parentId, Integer classify) {
-		return this.baseMapper.queryContractTreeSupervision(contractIds, parentId, classify);
-	}
-
-	@Override
-	public List<WbsTreeContractTreeVOS> queryContractTree(String contractId, String parentId, Integer classify) {
-		return this.baseMapper.queryContractTree(contractId, parentId, classify);
-	}
-
-	@Override
-	public List<QueryProcessDataVO> queryProcessDataByPrimaryKeyIdAndClassify(String primaryKeyId, Integer classify) {
-		return this.baseMapper.queryProcessDataByPrimaryKeyIdAndClassify(primaryKeyId, classify);
-	}
-
-	@Override
-	public List<QueryProcessDataVO> queryProcessDataByParentIdAndContractId(String parentId, Integer classify, String contractId) {
-		List<QueryProcessDataVO> result = this.baseMapper.queryProcessDataByParentIdAndContractId(parentId, classify, contractId);
-		if(result == null || result.size() <= 0){
-			result = this.baseMapper.queryProcessDataByParentIdAndContractId("", classify, contractId);
-		}
-		return result;
-	}
-
-	private List<FirstInformation> setFirstLinkData(List<JSONObject> linkDataList, String businessId){
-		List<FirstInformation> linkList = new ArrayList<>();
-
-		Date nowDate = new Date();
-		linkDataList.forEach(json -> {
-			FirstInformation linkData = new FirstInformation();
-			linkData.setFirstId(Long.parseLong(businessId));
-			linkData.setTitle(json.getString("name"));
-			linkData.setLinkId(json.getLong("id"));
-
-			linkData.setCreateUser(AuthUtil.getUserId());
-			linkData.setCreateTime(nowDate);
-
-			linkList.add(linkData);
-		});
-
-		return linkList;
-	}
-
-	private void updateLinkMergePdfUrl(List<JSONObject> linkDataList, InformationQuery data, String businessId){
-		//保存关联数据
-		if(linkDataList != null && linkDataList.size() > 0){
-			try{
-				//获取配置的路径
-				String file_path = ParamCache.getValue(CommonConstant.SYS_LOCAL_URL);
-
-				//获取关联的数据
-				List<String> linkIds = linkDataList.stream().map(json -> json.getString("id")).distinct().collect(Collectors.toList());
-				//查询数据
-				List<InformationQuery> linkList = this.listByIds(linkIds);
-				//获取pdfUrl
-				List<String> pdfUrls = linkList.stream().map(query -> StringUtils.isNotEmpty(query.getEVisaPdfUrl()) ? query.getEVisaPdfUrl() : query.getPdfUrl()).distinct().collect(Collectors.toList());
-
-
-				String mergeFileName = SnowFlakeUtil.getId() + ".pdf", margePdfPath = file_path + "/pdf//" + mergeFileName;
-				//合并
-				FileUtils.mergePdfPublicMethods(pdfUrls, margePdfPath);
-				//上传
-				BladeFile file = this.newIOSSClient.uploadFile(mergeFileName, margePdfPath);
-				if(file != null){
-					data.setLinkMergePdfUrl(file.getLink());
-				}
-
-				//保存关联
-				this.firstInformationService.saveBatch(this.setFirstLinkData(linkDataList, businessId));
-			}catch (Exception e){
-				e.printStackTrace();
-			}
-		}
-
-
-	}
-
-	private String saveOrUpdateFirstInformationQueryData(String primaryKeyId, String tableId,
-													   String businessId, String fileName,
-													   Integer classify, Integer sourceType,
-													   String sourceUrl,
-													   String pdfUrl, String firstFileName, List<JSONObject> linkDataList){
-
-		BladeUser user = AuthUtil.getUser();
-		//获取绑定的节点信息
-		WbsTreeContract contractTree = this.wbsTreeContractClient.getContractWbsTreeByPrimaryKeyId(Long.parseLong(primaryKeyId));
-
-		InformationQuery oldData = this.getById(businessId);
-		if(oldData != null){
-			//存在记录,修改
-			if(StringUtils.isNotEmpty(fileName)){
-				oldData.setName(fileName);
-			}
-
-			oldData.setUpdateTime(new Date());
-			oldData.setUpdateUser(user.getUserId());
-
-			//拼接填报人信息
-			String fileUser = user.getUserId() + "-" + user.getNickName();
-			if(StringUtils.isNotEmpty(oldData.getFileUserIdAndName())){
-				if(!oldData.getFileUserIdAndName().contains(user.getUserId().toString())){
-					//不包含,拼接
-					oldData.setFileUserIdAndName(oldData.getFileUserIdAndName() + "," + fileUser);
-				}
-			} else {
-				oldData.setFileUserIdAndName(fileUser);
-			}
-
-			//删除关联关系
-			this.firstInformationService.update(Wrappers.<FirstInformation>lambdaUpdate().set(FirstInformation::getIsDeleted, 1).eq(FirstInformation::getFirstId, businessId));
-			//重新添加并处理合并的pdf
-			this.updateLinkMergePdfUrl(linkDataList, oldData, businessId);
-
-			//找到关联附件
-			InformationQueryFile file = this.informationQueryFileService.getOne(Wrappers.<InformationQueryFile>lambdaQuery().eq(InformationQueryFile::getQueryId, businessId));
-			if(file != null){
-				file.setName(firstFileName);
-				file.setPdfUrl(pdfUrl);
-				file.setSourceUrl(sourceUrl);
-
-				file.setUpdateTime(new Date());
-				file.setUpdateUser(AuthUtil.getUserId());
-				//修改
-				this.informationQueryFileService.updateById(file);
-			} else {
-				file = new InformationQueryFile();
-				file.setQueryId(Long.parseLong(businessId));
-				file.setName(firstFileName);
-				file.setPdfUrl(pdfUrl);
-				file.setSourceUrl(sourceUrl);
-				file.setCreateUser(AuthUtil.getUserId());
-				file.setCreateTime(new Date());
-
-				this.informationQueryFileService.save(file);
-			}
-
-			//修改数据
-			this.baseMapper.updateById(oldData);
-
-		} else {
-			//新增
-			InformationQuery newData = new InformationQuery();
-			//处理关联数据及合并pdf
-			this.updateLinkMergePdfUrl(linkDataList, newData, businessId);
-
-			//数据ID
-			newData.setId(Long.parseLong(businessId));
-			//设置文件题名
-			newData.setName(fileName);
-			//设置文件类型
-			newData.setCategory(contractTree.getNodeType());
-			//项目ID
-			newData.setProjectId(Long.parseLong(contractTree.getProjectId()));
-			//合同段ID
-			newData.setContractId(Long.parseLong(contractTree.getContractId()));
-			//施工资料还是质检资料
-			newData.setClassify(classify);
-			//节点ID
-			newData.setWbsId(contractTree.getPKeyId());
-
-			//1资料填报,2试验,3首件
-			newData.setType(3);
-
-			//流程状态,默认未上报
-			newData.setStatus(0);
-			//填报人ID及姓名
-			newData.setFileUserIdAndName(user.getUserId() + "-" + user.getNickName());
-			//数据源类型
-			newData.setSourceType(sourceType);
-			newData.setCreateUser(user.getUserId());
-			newData.setCreateTime(new Date());
-
-			newData.setTableId(tableId);
-
-			//新增附件
-			InformationQueryFile file = new InformationQueryFile();
-			file.setQueryId(Long.parseLong(businessId));
-			file.setName(firstFileName);
-			file.setPdfUrl(pdfUrl);
-			file.setSourceUrl(sourceUrl);
-			file.setCreateUser(AuthUtil.getUserId());
-			file.setCreateTime(new Date());
-
-			this.informationQueryFileService.save(file);
-
-			//保存数据
-			this.baseMapper.insert(newData);
-		}
-
-		return businessId;
-	}
-
-	@Override
-	public String saveOrUpdateInformationQueryData(String primaryKeyId, String tableId,
-												 String businessId, String fileName,
-												 Integer classify, Integer sourceType,
-												 String isFirst, String sourceUrl,
-												 String pdfUrl, String firstFileName, List<JSONObject> linkDataList) {
-		BladeUser user = AuthUtil.getUser();
-
-		if(StringUtils.isNotEmpty(isFirst) && "true".equals(isFirst)){
-			return this.saveOrUpdateFirstInformationQueryData(primaryKeyId, tableId, businessId, fileName, classify, sourceType, sourceUrl, pdfUrl, firstFileName, linkDataList);
-		} else {
-			//首先根据wbsId获取合同段ID和项目ID
-			WbsTreeContract contractTree = this.wbsTreeContractClient.getContractWbsTreeByPrimaryKeyId(Long.parseLong(primaryKeyId));
-
-			//判断当前填报节点下是否已经存在相应数据
-			InformationQuery oldData = this.baseMapper.getInformationQueryByWbsId(contractTree.getPKeyId(), classify);
-
-			if(oldData != null){
-				//存在记录,修改
-				if(StringUtils.isNotEmpty(fileName)){
-					oldData.setName(fileName);
-				}
-
-				//拼接填报人信息
-				String fileUser = user.getUserId() + "-" + user.getNickName();
-				if(StringUtils.isNotEmpty(oldData.getFileUserIdAndName())){
-					if(!oldData.getFileUserIdAndName().contains(user.getUserId().toString())){
-						//不包含,拼接
-						oldData.setFileUserIdAndName(oldData.getFileUserIdAndName() + "," + fileUser);
-					}
-				} else {
-					oldData.setFileUserIdAndName(fileUser);
-				}
-
-				oldData.setUpdateTime(new Date());
-				oldData.setUpdateUser(user.getUserId());
-				//修改数据
-				this.baseMapper.updateById(oldData);
-			} else {
-				//新增基础数据
-				InformationQuery newData = new InformationQuery();
-				//设置文件题名
-				newData.setName(fileName);
-				//设置文件类型
-				newData.setCategory(contractTree.getNodeType());
-				//项目ID
-				newData.setProjectId(Long.parseLong(contractTree.getProjectId()));
-				//合同段ID
-				newData.setContractId(Long.parseLong(contractTree.getContractId()));
-				//施工资料还是质检资料
-				newData.setClassify(classify);
-				//节点ID
-				newData.setWbsId(contractTree.getPKeyId());
-
-				//1资料填报,2试验,3首件
-				newData.setType((contractTree.getIsExpernode() == null || contractTree.getIsExpernode() <= 0) ? 1 : 2);
-
-				//流程状态,默认未上报
-				newData.setStatus(0);
-				//填报人ID及姓名
-				newData.setFileUserIdAndName(user.getUserId() + "-" + user.getNickName());
-				//数据源类型
-				newData.setSourceType(sourceType);
-				newData.setCreateUser(user.getUserId());
-				newData.setCreateTime(new Date());
-				//保存数据
-				this.baseMapper.insert(newData);
-			}
-		}
-		return null;
-	}
-
-	@Override
-	public List<Integer> getReportNumberByContractId(Integer classify, String contractId) {
-		return this.baseMapper.getReportNumberByContractId(classify, contractId);
-	}
-
-	@Override
-	public List<FileUserVO> queryFileUserByContractId(Integer classify, String contractId) {
-		//获取当前合同段下有填报记录的填报人
-		List<InformationQuery> fileUserResult = this.baseMapper.queryFileUserByContractId(classify, contractId);
-
-		//获取填报人数据
-		//将原本拼接的字符串拆分为userId和userName
-		List<FileUserVO> result = new ArrayList<>();
-		if(fileUserResult != null && fileUserResult.size() > 0){
-			List<String> userList = new ArrayList<>();
-			fileUserResult.removeIf(Objects::isNull);
-			if(fileUserResult.size() > 0){
-				fileUserResult.forEach(user -> {
-					//一次去重
-					String[] array = user.getFileUserIdAndName().split(",");
-					for(String str : array){
-						if(!userList.contains(str)){
-							userList.add(str);
-						}
-					}
-				});
-				//二次去重
-				HashSet<String> hashSet = new HashSet<>(userList);
-				List<String> users = new ArrayList<>();
-				hashSet.forEach(user -> {
-					String[] array = user.split("-");
-					if(!users.contains(array[0])){
-						User bUser = this.userClient.userInfoById(Long.parseLong(array[0])).getData();
-						if(bUser != null){
-							result.add(new FileUserVO(array[0], bUser.getRealName()));
-						} else {
-							result.add(new FileUserVO(array[0], array[1]));
-						}
-						users.add(array[0]);
-					}
-				});
-			}
-		}
-
-		return result;
-	}
-
-	@Override
-	public IPage<InformationQueryVO> selectInformationQueryPage(IPage<InformationQueryVO> page, InformationQueryVO vo) {
-		long current = (page.getCurrent() - 1L) * page.getSize();
-
-		if(StringUtils.isNotEmpty(vo.getBetweenTime())){
-			String[] betweenTime;
-			if(vo.getBetweenTime().contains("~")){
-				String[] between = vo.getBetweenTime().split("~");
-				betweenTime = new String[]{between[0], between[1]};
-			} else {
-				betweenTime = new String[]{vo.getBetweenTime(), DateUtils.formatDate(new Date(), "yyyy-MM-dd")};
-			}
-			vo.setStartTime(betweenTime[0]);
-			vo.setEndTime(betweenTime[1]);
-		}
-
-		if(StringUtils.isNotEmpty(vo.getFileUserIdAndName())){
-			vo.setFileUserIdAndName(vo.getFileUserIdAndName().split("-")[0]);
-		}
-
-		if(vo.getStatus() != null){
-			vo.setTaskStatus(vo.getStatus().toString());
-		}
-
-		//获取总量
-		Integer count = this.baseMapper.countInformationQuery(vo);
-
-		//获取数据
-		List<InformationQuery> result = this.baseMapper.selectInformationQueryPage(current, page.getSize(), vo);
-		//转换VO
-		if(result != null && result.size() != 0){
-			List<InformationQueryVO> voResult = JSONArray.parseArray(JSONObject.toJSONString(result), InformationQueryVO.class);
-			//处理流程状态
-			voResult.forEach(vor -> {
-				vor.setStartTime(DateUtil.format(vor.getCreateTime(), "yyyy-MM-dd"));
-				vor.setTaskStatusStr(new Integer("0").equals(vor.getStatus()) ? "未上报" : new Integer("1").equals(vor.getStatus()) ? "待审批" : new Integer("2").equals(vor.getStatus()) ? "已审批" : "已废除");
-				try{
-					//填报人
-					String fileUserIdAndName = vor.getFileUserIdAndName();
-					String[] fileUserIdAndNames = fileUserIdAndName.split(",");
-					List<String> names = new ArrayList<>();
-					for(String str : fileUserIdAndNames){
-						String[] strs = str.split("-");
-						if(!names.contains(strs[1])){
-							names.add(strs[1]);
-						}
-					}
-					//只拼接名字
-					vor.setFileUserIdAndName(String.join(",", names));
-				}catch (Exception e){
-					e.printStackTrace();
-				}
-
-				if(Arrays.asList("1,2".split(",")).contains(vor.getStatus().toString())){
-					//说明属于待审批和已审批状态,查询待办信息
-					List<Task> tasks = this.taskClient.queryTaskListByFormDataId(String.valueOf(vor.getId()));
-					if(tasks != null && tasks.size() > 0){
-						//查询当前任务的所有待办人
-						List<TaskParallel> linkTasks = this.taskParallelService.queryApprovalUser(tasks.get(0).getProcessInstanceId());
-						if(linkTasks != null && linkTasks.size() > 0){
-							//处理审批状态
-							this.integrationMethod(vor, linkTasks);
-						}
-						//设置上报批次
-//						vor.setReportNumber(String.valueOf(tasks.get(0).getBatch()));
-					}
-				}
-			});
-			page.setRecords(voResult);
-			page.setTotal(count);
-
-			return page;
-		}
-
-		return page.setRecords(null);
-	}
-
-	/**
-	 * 统合方法
-	 */
-	private void integrationMethod(InformationQueryVO vo, List<TaskParallel> linkList) {
-		linkList.forEach(link -> vo.setWaitingUserList(link.getTaskUserName(), new Integer("999").equals(link.getEVisaStatus()) ? 999 : new Integer("2").equals(link.getStatus()) ? 2 : new Integer("3").equals(link.getStatus()) && new Integer("1").equals(link.getInitiative()) ? 3 : 1));
-	}
+    private final ITaskParallelService taskParallelService;
+
+    private final IFirstInformationService firstInformationService;
+
+    private final NewIOSSClient newIOSSClient;
+
+    private final IInformationQueryFileService informationQueryFileService;
+
+    private final IContractLogService contractLogService;
+
+    @Override
+    public List<String> queryBusinessTableData(String formDataId) {
+        //获取具体业务数据
+        InformationQuery query = this.getById(formDataId);
+
+        //查询这个业务数据绑定的表格,需要区分监理和施工
+        if (query != null) {
+            WbsTreeContract tree = this.wbsTreeContractClient.getContractWbsTreeByPrimaryKeyId(query.getWbsId());
+            List<WbsTreeContract> tableList = this.wbsTreeContractClient.queryChildByParentId(tree, "queryTable", String.valueOf(query.getClassify()));
+            if (tableList != null && tableList.size() > 0) {
+                //删除掉无法溯源的数据
+                tableList.removeIf(node -> node.getIsTypePrivatePid() == null || node.getIsTypePrivatePid() <= 0 || StringUtils.isEmpty(node.getIsTypePrivatePid().toString()));
+
+                List<Long> privatePIdList = tableList.stream().map(WbsTreeContract::getIsTypePrivatePid).distinct().collect(Collectors.toList());
+
+                return JSONArray.parseArray(JSONObject.toJSONString(privatePIdList), String.class);
+            }
+        } else {
+            //那么就可能是日志,检查是不是日志
+            ContractLog log = this.contractLogService.getById(formDataId);
+            if (log != null) {
+                //说明是日志,日志的绑定节点在wbs_tree_private表中,所以这个节点ID就是要找的ID
+                return Func.toStrList(String.valueOf(log.getTableId()));
+            }
+        }
+
+        return null;
+    }
+
+    @Override
+    public List<WbsTreeContractTreeVOS> queryContractTreeSupervision(List<String> contractIds, String parentId, Integer classify) {
+        return this.baseMapper.queryContractTreeSupervision(contractIds, parentId, classify);
+    }
+
+    @Override
+    public List<WbsTreeContractTreeVOS> queryContractTree(String contractId, String parentId, Integer classify) {
+        return this.baseMapper.queryContractTree(contractId, parentId, classify);
+    }
+
+    @Override
+    public List<QueryProcessDataVO> queryProcessDataByPrimaryKeyIdAndClassify(String primaryKeyId, Integer classify) {
+        return this.baseMapper.queryProcessDataByPrimaryKeyIdAndClassify(primaryKeyId, classify);
+    }
+
+    @Override
+    public List<QueryProcessDataVO> queryProcessDataByParentIdAndContractId(String parentId, Integer classify, String contractId) {
+        List<QueryProcessDataVO> result = this.baseMapper.queryProcessDataByParentIdAndContractId(parentId, classify, contractId);
+        if (result == null || result.size() <= 0) {
+            result = this.baseMapper.queryProcessDataByParentIdAndContractId("", classify, contractId);
+        }
+        return result;
+    }
+
+    private List<FirstInformation> setFirstLinkData(List<JSONObject> linkDataList, String businessId) {
+        List<FirstInformation> linkList = new ArrayList<>();
+
+        Date nowDate = new Date();
+        linkDataList.forEach(json -> {
+            FirstInformation linkData = new FirstInformation();
+            linkData.setFirstId(Long.parseLong(businessId));
+            linkData.setTitle(json.getString("name"));
+            linkData.setLinkId(json.getLong("id"));
+
+            linkData.setCreateUser(AuthUtil.getUserId());
+            linkData.setCreateTime(nowDate);
+
+            linkList.add(linkData);
+        });
+
+        return linkList;
+    }
+
+    private void updateLinkMergePdfUrl(List<JSONObject> linkDataList, InformationQuery data, String businessId) {
+        //保存关联数据
+        if (linkDataList != null && linkDataList.size() > 0) {
+            try {
+                //获取配置的路径
+                String file_path = ParamCache.getValue(CommonConstant.SYS_LOCAL_URL);
+
+                //获取关联的数据
+                List<String> linkIds = linkDataList.stream().map(json -> json.getString("id")).distinct().collect(Collectors.toList());
+                //查询数据
+                List<InformationQuery> linkList = this.listByIds(linkIds);
+                //获取pdfUrl
+                List<String> pdfUrls = linkList.stream().map(query -> StringUtils.isNotEmpty(query.getEVisaPdfUrl()) ? query.getEVisaPdfUrl() : query.getPdfUrl()).distinct().collect(Collectors.toList());
+
+
+                String mergeFileName = SnowFlakeUtil.getId() + ".pdf", margePdfPath = file_path + "/pdf//" + mergeFileName;
+                //合并
+                FileUtils.mergePdfPublicMethods(pdfUrls, margePdfPath);
+                //上传
+                BladeFile file = this.newIOSSClient.uploadFile(mergeFileName, margePdfPath);
+                if (file != null) {
+                    data.setLinkMergePdfUrl(file.getLink());
+                }
+
+                //保存关联
+                this.firstInformationService.saveBatch(this.setFirstLinkData(linkDataList, businessId));
+            } catch (Exception e) {
+                e.printStackTrace();
+            }
+        }
+
+
+    }
+
+    private String saveOrUpdateFirstInformationQueryData(String primaryKeyId, String tableId,
+                                                         String businessId, String fileName,
+                                                         Integer classify, Integer sourceType,
+                                                         String sourceUrl,
+                                                         String pdfUrl, String firstFileName, List<JSONObject> linkDataList) {
+
+        BladeUser user = AuthUtil.getUser();
+        //获取绑定的节点信息
+        WbsTreeContract contractTree = this.wbsTreeContractClient.getContractWbsTreeByPrimaryKeyId(Long.parseLong(primaryKeyId));
+
+        InformationQuery oldData = this.getById(businessId);
+        if (oldData != null) {
+            //存在记录,修改
+            if (StringUtils.isNotEmpty(fileName)) {
+                oldData.setName(fileName);
+            }
+
+            oldData.setUpdateTime(new Date());
+            oldData.setUpdateUser(user.getUserId());
+
+            //拼接填报人信息
+            String fileUser = user.getUserId() + "-" + user.getNickName();
+            if (StringUtils.isNotEmpty(oldData.getFileUserIdAndName())) {
+                if (!oldData.getFileUserIdAndName().contains(user.getUserId().toString())) {
+                    //不包含,拼接
+                    oldData.setFileUserIdAndName(oldData.getFileUserIdAndName() + "," + fileUser);
+                }
+            } else {
+                oldData.setFileUserIdAndName(fileUser);
+            }
+
+            //删除关联关系
+            this.firstInformationService.update(Wrappers.<FirstInformation>lambdaUpdate().set(FirstInformation::getIsDeleted, 1).eq(FirstInformation::getFirstId, businessId));
+            //重新添加并处理合并的pdf
+            this.updateLinkMergePdfUrl(linkDataList, oldData, businessId);
+
+            //找到关联附件
+            InformationQueryFile file = this.informationQueryFileService.getOne(Wrappers.<InformationQueryFile>lambdaQuery().eq(InformationQueryFile::getQueryId, businessId));
+            if (file != null) {
+                file.setName(firstFileName);
+                file.setPdfUrl(pdfUrl);
+                file.setSourceUrl(sourceUrl);
+
+                file.setUpdateTime(new Date());
+                file.setUpdateUser(AuthUtil.getUserId());
+                //修改
+                this.informationQueryFileService.updateById(file);
+            } else {
+                file = new InformationQueryFile();
+                file.setQueryId(Long.parseLong(businessId));
+                file.setName(firstFileName);
+                file.setPdfUrl(pdfUrl);
+                file.setSourceUrl(sourceUrl);
+                file.setCreateUser(AuthUtil.getUserId());
+                file.setCreateTime(new Date());
+
+                this.informationQueryFileService.save(file);
+            }
+
+            //修改数据
+            this.baseMapper.updateById(oldData);
+
+        } else {
+            //新增
+            InformationQuery newData = new InformationQuery();
+            //处理关联数据及合并pdf
+            this.updateLinkMergePdfUrl(linkDataList, newData, businessId);
+
+            //数据ID
+            newData.setId(Long.parseLong(businessId));
+            //设置文件题名
+            newData.setName(fileName);
+            //设置文件类型
+            newData.setCategory(contractTree.getNodeType());
+            //项目ID
+            newData.setProjectId(Long.parseLong(contractTree.getProjectId()));
+            //合同段ID
+            newData.setContractId(Long.parseLong(contractTree.getContractId()));
+            //施工资料还是质检资料
+            newData.setClassify(classify);
+            //节点ID
+            newData.setWbsId(contractTree.getPKeyId());
+
+            //1资料填报,2试验,3首件
+            newData.setType(3);
+
+            //流程状态,默认未上报
+            newData.setStatus(0);
+            //填报人ID及姓名
+            newData.setFileUserIdAndName(user.getUserId() + "-" + user.getNickName());
+            //数据源类型
+            newData.setSourceType(sourceType);
+            newData.setCreateUser(user.getUserId());
+            newData.setCreateTime(new Date());
+
+            newData.setTableId(tableId);
+
+            //新增附件
+            InformationQueryFile file = new InformationQueryFile();
+            file.setQueryId(Long.parseLong(businessId));
+            file.setName(firstFileName);
+            file.setPdfUrl(pdfUrl);
+            file.setSourceUrl(sourceUrl);
+            file.setCreateUser(AuthUtil.getUserId());
+            file.setCreateTime(new Date());
+
+            this.informationQueryFileService.save(file);
+
+            //保存数据
+            this.baseMapper.insert(newData);
+        }
+
+        return businessId;
+    }
+
+    @Override
+    public String saveOrUpdateInformationQueryData(String primaryKeyId, String tableId,
+                                                   String businessId, String fileName,
+                                                   Integer classify, Integer sourceType,
+                                                   String isFirst, String sourceUrl,
+                                                   String pdfUrl, String firstFileName, List<JSONObject> linkDataList) {
+        BladeUser user = AuthUtil.getUser();
+
+        if (StringUtils.isNotEmpty(isFirst) && "true".equals(isFirst)) {
+            return this.saveOrUpdateFirstInformationQueryData(primaryKeyId, tableId, businessId, fileName, classify, sourceType, sourceUrl, pdfUrl, firstFileName, linkDataList);
+        } else {
+            //首先根据wbsId获取合同段ID和项目ID
+            WbsTreeContract contractTree = this.wbsTreeContractClient.getContractWbsTreeByPrimaryKeyId(Long.parseLong(primaryKeyId));
+
+            //判断当前填报节点下是否已经存在相应数据
+            InformationQuery oldData = this.baseMapper.getInformationQueryByWbsId(contractTree.getPKeyId(), classify);
+
+            if (oldData != null) {
+                //存在记录,修改
+                if (StringUtils.isNotEmpty(fileName)) {
+                    oldData.setName(fileName);
+                }
+
+                //拼接填报人信息
+                String fileUser = user.getUserId() + "-" + user.getNickName();
+                if (StringUtils.isNotEmpty(oldData.getFileUserIdAndName())) {
+                    if (!oldData.getFileUserIdAndName().contains(user.getUserId().toString())) {
+                        //不包含,拼接
+                        oldData.setFileUserIdAndName(oldData.getFileUserIdAndName() + "," + fileUser);
+                    }
+                } else {
+                    oldData.setFileUserIdAndName(fileUser);
+                }
+
+                oldData.setUpdateTime(new Date());
+                oldData.setUpdateUser(user.getUserId());
+                //修改数据
+                this.baseMapper.updateById(oldData);
+            } else {
+                //新增基础数据
+                InformationQuery newData = new InformationQuery();
+                //设置文件题名
+                newData.setName(fileName);
+                //设置文件类型
+                newData.setCategory(contractTree.getNodeType());
+                //项目ID
+                newData.setProjectId(Long.parseLong(contractTree.getProjectId()));
+                //合同段ID
+                newData.setContractId(Long.parseLong(contractTree.getContractId()));
+                //施工资料还是质检资料
+                newData.setClassify(classify);
+                //节点ID
+                newData.setWbsId(contractTree.getPKeyId());
+
+                //1资料填报,2试验,3首件
+                newData.setType((contractTree.getIsExpernode() == null || contractTree.getIsExpernode() <= 0) ? 1 : 2);
+
+                //流程状态,默认未上报
+                newData.setStatus(0);
+                //填报人ID及姓名
+                newData.setFileUserIdAndName(user.getUserId() + "-" + user.getNickName());
+                //数据源类型
+                newData.setSourceType(sourceType);
+                newData.setCreateUser(user.getUserId());
+                newData.setCreateTime(new Date());
+                //保存数据
+                this.baseMapper.insert(newData);
+            }
+        }
+        return null;
+    }
+
+    @Override
+    public List<Integer> getReportNumberByContractId(Integer classify, String contractId) {
+        return this.baseMapper.getReportNumberByContractId(classify, contractId);
+    }
+
+    @Override
+    public List<FileUserVO> queryFileUserByContractId(Integer classify, String contractId) {
+        //获取当前合同段下有填报记录的填报人
+        List<InformationQuery> fileUserResult = this.baseMapper.queryFileUserByContractId(classify, contractId);
+
+        //获取填报人数据
+        //将原本拼接的字符串拆分为userId和userName
+        List<FileUserVO> result = new ArrayList<>();
+        if (fileUserResult != null && fileUserResult.size() > 0) {
+            List<String> userList = new ArrayList<>();
+            fileUserResult.removeIf(Objects::isNull);
+            if (fileUserResult.size() > 0) {
+                fileUserResult.forEach(user -> {
+                    //一次去重
+                    String[] array = user.getFileUserIdAndName().split(",");
+                    for (String str : array) {
+                        if (!userList.contains(str)) {
+                            userList.add(str);
+                        }
+                    }
+                });
+                //二次去重
+                HashSet<String> hashSet = new HashSet<>(userList);
+                List<String> users = new ArrayList<>();
+                hashSet.forEach(user -> {
+                    String[] array = user.split("-");
+                    if (!users.contains(array[0])) {
+                        User bUser = this.userClient.userInfoById(Long.parseLong(array[0])).getData();
+                        if (bUser != null) {
+                            result.add(new FileUserVO(array[0], bUser.getRealName()));
+                        } else {
+                            result.add(new FileUserVO(array[0], array[1]));
+                        }
+                        users.add(array[0]);
+                    }
+                });
+            }
+        }
+
+        return result;
+    }
+
+    @Override
+    public IPage<InformationQueryVO> selectInformationQueryPage(IPage<InformationQueryVO> page, InformationQueryVO vo) {
+        long current = (page.getCurrent() - 1L) * page.getSize();
+
+        if (StringUtils.isNotEmpty(vo.getBetweenTime())) {
+            String[] betweenTime;
+            if (vo.getBetweenTime().contains("~")) {
+                String[] between = vo.getBetweenTime().split("~");
+                betweenTime = new String[]{between[0], between[1]};
+            } else {
+                betweenTime = new String[]{vo.getBetweenTime(), DateUtils.formatDate(new Date(), "yyyy-MM-dd")};
+            }
+            vo.setStartTime(betweenTime[0]);
+            vo.setEndTime(betweenTime[1]);
+        }
+
+        if (StringUtils.isNotEmpty(vo.getFileUserIdAndName())) {
+            vo.setFileUserIdAndName(vo.getFileUserIdAndName().split("-")[0]);
+        }
+
+        if (vo.getStatus() != null) {
+            vo.setTaskStatus(vo.getStatus().toString());
+        }
+
+        //获取总量
+        Integer count = this.baseMapper.countInformationQuery(vo);
+
+        //获取数据
+        List<InformationQuery> result = this.baseMapper.selectInformationQueryPage(current, page.getSize(), vo);
+
+        //获取所有节点顺序,按照节点排序
+        List<String> wbsIds = result.stream().map(InformationQuery::getWbsId).collect(Collectors.toList()).stream().map(String::valueOf).collect(Collectors.toList());
+        List<InformationQuery> resultSort = new ArrayList<>();
+        if (wbsIds.size() > 0) {
+            List<WbsTreeContract> wbsTreeContracts = this.baseMapper.getContractNodeByPrimaryKeyIds(StringUtils.join(wbsIds, ","));
+            if (wbsTreeContracts != null && wbsTreeContracts.size() > 0) {
+                for (WbsTreeContract wbsTreeContract : wbsTreeContracts) {
+                    for (InformationQuery informationQuery : result) {
+                        if (wbsTreeContract.getPKeyId().equals(informationQuery.getWbsId())) {
+                            resultSort.add(informationQuery);
+                        }
+                    }
+                }
+            }
+        }
+
+        //转换VO
+        //if (result != null && result.size() != 0) {
+        if (resultSort.size() != 0) {
+            List<InformationQueryVO> voResult = JSONArray.parseArray(JSONObject.toJSONString(resultSort), InformationQueryVO.class);
+            //处理流程状态
+            voResult.forEach(vor -> {
+                vor.setStartTime(DateUtil.format(vor.getCreateTime(), "yyyy-MM-dd"));
+                vor.setTaskStatusStr(new Integer("0").equals(vor.getStatus()) ? "未上报" : new Integer("1").equals(vor.getStatus()) ? "待审批" : new Integer("2").equals(vor.getStatus()) ? "已审批" : "已废除");
+                try {
+                    //填报人
+                    String fileUserIdAndName = vor.getFileUserIdAndName();
+                    String[] fileUserIdAndNames = fileUserIdAndName.split(",");
+                    List<String> names = new ArrayList<>();
+                    for (String str : fileUserIdAndNames) {
+                        String[] strs = str.split("-");
+                        if (!names.contains(strs[1])) {
+                            names.add(strs[1]);
+                        }
+                    }
+                    //只拼接名字
+                    vor.setFileUserIdAndName(String.join(",", names));
+                } catch (Exception e) {
+                    e.printStackTrace();
+                }
+
+                if (Arrays.asList("1,2".split(",")).contains(vor.getStatus().toString())) {
+                    //说明属于待审批和已审批状态,查询待办信息
+                    List<Task> tasks = this.taskClient.queryTaskListByFormDataId(String.valueOf(vor.getId()));
+                    if (tasks != null && tasks.size() > 0) {
+                        //查询当前任务的所有待办人
+                        List<TaskParallel> linkTasks = this.taskParallelService.queryApprovalUser(tasks.get(0).getProcessInstanceId());
+                        if (linkTasks != null && linkTasks.size() > 0) {
+                            //处理审批状态
+                            this.integrationMethod(vor, linkTasks);
+                        }
+                        //设置上报批次
+                        //vor.setReportNumber(String.valueOf(tasks.get(0).getBatch()));
+                    }
+                }
+            });
+            page.setRecords(voResult);
+            page.setTotal(count);
+
+            return page;
+        }
+
+        return page.setRecords(null);
+    }
+
+    /**
+     * 统合方法
+     */
+    private void integrationMethod(InformationQueryVO vo, List<TaskParallel> linkList) {
+        linkList.forEach(link -> vo.setWaitingUserList(link.getTaskUserName(), new Integer("999").equals(link.getEVisaStatus()) ? 999 : new Integer("2").equals(link.getStatus()) ? 2 : new Integer("3").equals(link.getStatus()) && new Integer("1").equals(link.getInitiative()) ? 3 : 1));
+    }
 
 }

+ 61 - 12
blade-service/blade-business/src/main/java/org/springblade/business/service/impl/MessageWarningServiceImpl.java

@@ -16,20 +16,35 @@
  */
 package org.springblade.business.service.impl;
 
+import com.alibaba.fastjson.JSON;
 import com.alibaba.fastjson.JSONArray;
 import com.alibaba.fastjson.JSONObject;
+import com.baomidou.mybatisplus.core.toolkit.Wrappers;
+import lombok.AllArgsConstructor;
 import org.springblade.business.entity.MessageWarning;
+import org.springblade.business.entity.Task;
+import org.springblade.business.entity.TaskParallel;
 import org.springblade.business.mapper.MessageWarningMapper;
 import org.springblade.business.service.IMessageWarningService;
+import org.springblade.business.service.ITaskParallelService;
+import org.springblade.business.service.ITaskService;
+import org.springblade.business.socket.WebSocket;
 import org.springblade.business.vo.MessageWarningVO;
 import org.springblade.core.mp.base.BaseServiceImpl;
+import org.springblade.core.tool.utils.ObjectUtil;
 import org.springframework.beans.BeanUtils;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.context.annotation.Lazy;
 import org.springframework.stereotype.Service;
 
+import java.io.IOException;
+import java.util.HashMap;
 import java.util.List;
+import java.util.Map;
+import java.util.stream.Collectors;
 
 /**
- *  服务实现类
+ * 服务实现类
  *
  * @author BladeX
  * @since 2022-09-05
@@ -37,17 +52,51 @@ import java.util.List;
 @Service
 public class MessageWarningServiceImpl extends BaseServiceImpl<MessageWarningMapper, MessageWarning> implements IMessageWarningService {
 
-	@Override
-	public void savePushUserMessageWarning(List<MessageWarningVO> vos) {
-		List<MessageWarning> saveList = JSONArray.parseArray(JSONObject.toJSONString(vos), MessageWarning.class);
-		this.saveBatch(saveList);
-	}
+    //@Lazy解决循环注入问题
+    @Lazy
+    @Autowired
+    private ITaskService iTaskService;
+
+    @Lazy
+    @Autowired
+    private WebSocket webSocket;
+
+    @Override
+    public void savePushUserMessageWarning(List<MessageWarningVO> vos) {
+        List<MessageWarning> saveList = JSONArray.parseArray(JSONObject.toJSONString(vos), MessageWarning.class);
+
+        //通过WebSocket推送数量条数
+        for (MessageWarning messageWarning : saveList) {
+            if (ObjectUtil.isNotEmpty(messageWarning.getProjectId()) && ObjectUtil.isNotEmpty(messageWarning.getContractId()) && ObjectUtil.isNotEmpty(messageWarning.getPushUser())) {
+                Map<String, String> stringMap = iTaskService.getTaskCount(messageWarning.getProjectId().toString(), messageWarning.getContractId().toString(), messageWarning.getPushUser().toString());
+                try {
+                    webSocket.sendMessageByUserId(messageWarning.getPushUser().toString(), JSON.toJSONString(stringMap));
+                } catch (IOException e) {
+                    e.printStackTrace();
+                }
+            }
+        }
+
+        this.saveBatch(saveList);
+    }
+
+    @Override
+    public void savePushUserMessageWarning(MessageWarningVO vo) {
+        MessageWarning messageWarning = new MessageWarning();
+        BeanUtils.copyProperties(vo, messageWarning);
+
+        //通过WebSocket推送数量条数
+        if (ObjectUtil.isNotEmpty(messageWarning.getProjectId()) && ObjectUtil.isNotEmpty(messageWarning.getContractId()) && ObjectUtil.isNotEmpty(messageWarning.getPushUser())) {
+            Map<String, String> stringMap = iTaskService.getTaskCount(messageWarning.getProjectId().toString(), messageWarning.getContractId().toString(), messageWarning.getPushUser().toString());
+            try {
+                webSocket.sendMessageByUserId(messageWarning.getPushUser().toString(), JSON.toJSONString(stringMap));
+            } catch (IOException e) {
+                e.printStackTrace();
+            }
+        }
+
+        this.baseMapper.insert(messageWarning);
+    }
 
-	@Override
-	public void savePushUserMessageWarning(MessageWarningVO vo) {
-		MessageWarning messageWarning = new MessageWarning();
-		BeanUtils.copyProperties(vo, messageWarning);
 
-		this.baseMapper.insert(messageWarning);
-	}
 }

+ 154 - 118
blade-service/blade-business/src/main/java/org/springblade/business/service/impl/TaskServiceImpl.java

@@ -45,10 +45,7 @@ import org.springframework.stereotype.Service;
 import org.springframework.transaction.annotation.Transactional;
 
 import java.io.FileNotFoundException;
-import java.util.ArrayList;
-import java.util.Arrays;
-import java.util.Date;
-import java.util.List;
+import java.util.*;
 import java.util.concurrent.TimeUnit;
 import java.util.stream.Collectors;
 
@@ -93,6 +90,7 @@ public class TaskServiceImpl extends BaseServiceImpl<TaskMapper, Task> implement
 
     private final ITrialSelfInspectionRecordService iTrialSelfInspectionRecordService;
 
+
     @Override
     public List<TaskParallel> queryApprovalUser(String formDataIds) {
         //返回结果
@@ -100,12 +98,12 @@ public class TaskServiceImpl extends BaseServiceImpl<TaskMapper, Task> implement
 
         String[] formDataIdArray = formDataIds.split(",");
         List<Long> taskIds = new ArrayList<>();
-        for(String formDataId : formDataIdArray){
+        for (String formDataId : formDataIdArray) {
             Task task = this.baseMapper.queryTaskListByFormDataId(formDataId);
-            if(!taskIds.contains(task.getId())){
+            if (!taskIds.contains(task.getId())) {
                 //查询审批人
                 List<TaskParallel> parallels = this.taskParallelService.queryApprovalUser(task.getProcessInstanceId());
-                if(parallels != null && parallels.size() > 0){
+                if (parallels != null && parallels.size() > 0) {
                     result.addAll(parallels);
                 }
                 taskIds.add(task.getId());
@@ -114,54 +112,54 @@ public class TaskServiceImpl extends BaseServiceImpl<TaskMapper, Task> implement
         return result;
     }
 
-     /**
-      * 任务专用
-      */
-     @Override
-     public TaskApprovalVO queryBusinessDataTask(TaskApprovalVO taskApprovalVO) {
-         int foreachNumber = 0;
-         do {
-             //判断锁是否存在
-             if(!DistributedRedisLock.getLockStatus(taskApprovalVO.getFormDataId())){
-                 //如果不存在,直接获取并上锁,由于这个查询方法是任务方面使用,所以解锁需要在对应数据使用结束后
-                 DistributedRedisLock.acquire(taskApprovalVO.getFormDataId(), 20);
-                 switch (taskApprovalVO.getApprovalType()){
-                     case 1:
-                         //填报数据
-                         return this.queryProcessSubmitBusinessData(taskApprovalVO.getFormDataId(), true);
-                     case 2:
-                         //工程文件
-                         return this.queryArchiveFileBusinessData(taskApprovalVO.getFormDataId());
-                     case 3:
-                         //日志资料
-                         return this.queryTheLogFileBusinessData(taskApprovalVO.getFormDataId());
-                     default:
-                         //未找到数据,解锁
-                         DistributedRedisLock.release(taskApprovalVO.getFormDataId());
-                         return null;
-                 }
-             } else {
-                try{
-                    if(foreachNumber < 10){
+    /**
+     * 任务专用
+     */
+    @Override
+    public TaskApprovalVO queryBusinessDataTask(TaskApprovalVO taskApprovalVO) {
+        int foreachNumber = 0;
+        do {
+            //判断锁是否存在
+            if (!DistributedRedisLock.getLockStatus(taskApprovalVO.getFormDataId())) {
+                //如果不存在,直接获取并上锁,由于这个查询方法是任务方面使用,所以解锁需要在对应数据使用结束后
+                DistributedRedisLock.acquire(taskApprovalVO.getFormDataId(), 20);
+                switch (taskApprovalVO.getApprovalType()) {
+                    case 1:
+                        //填报数据
+                        return this.queryProcessSubmitBusinessData(taskApprovalVO.getFormDataId(), true);
+                    case 2:
+                        //工程文件
+                        return this.queryArchiveFileBusinessData(taskApprovalVO.getFormDataId());
+                    case 3:
+                        //日志资料
+                        return this.queryTheLogFileBusinessData(taskApprovalVO.getFormDataId());
+                    default:
+                        //未找到数据,解锁
+                        DistributedRedisLock.release(taskApprovalVO.getFormDataId());
+                        return null;
+                }
+            } else {
+                try {
+                    if (foreachNumber < 10) {
                         //如果存在锁,则等待解锁
                         TimeUnit.MILLISECONDS.sleep(5);
-                        foreachNumber ++;
+                        foreachNumber++;
                     } else {
                         break;
                     }
-                }catch (Exception e){
+                } catch (Exception e) {
                     e.printStackTrace();
                 }
-             }
-         } while (true);
-         //能走到这说明找不到文件或者超过锁定次数,解锁并返回
-         DistributedRedisLock.release(taskApprovalVO.getFormDataId());
-         return taskApprovalVO;
-     }
+            }
+        } while (true);
+        //能走到这说明找不到文件或者超过锁定次数,解锁并返回
+        DistributedRedisLock.release(taskApprovalVO.getFormDataId());
+        return taskApprovalVO;
+    }
 
     @Override
     public TaskApprovalVO queryBusinessData(TaskApprovalVO taskApprovalVO) {
-        switch (taskApprovalVO.getApprovalType()){
+        switch (taskApprovalVO.getApprovalType()) {
             case 1:
                 //填报数据
                 return this.queryProcessSubmitBusinessData(taskApprovalVO.getFormDataId(), false);
@@ -179,11 +177,11 @@ public class TaskServiceImpl extends BaseServiceImpl<TaskMapper, Task> implement
     /**
      * 日志资料
      */
-    private TaskApprovalVO queryTheLogFileBusinessData(String formDataId){
+    private TaskApprovalVO queryTheLogFileBusinessData(String formDataId) {
         //查询对应的数据
         TaskApprovalVO vo = new TaskApprovalVO();
         ContractLog log = this.contractLogService.getById(formDataId);
-        if(log != null && (StringUtils.isNotEmpty(log.getPdfUrl()) || StringUtils.isNotEmpty(log.getEVisaPdfUrl()))){
+        if (log != null && (StringUtils.isNotEmpty(log.getPdfUrl()) || StringUtils.isNotEmpty(log.getEVisaPdfUrl()))) {
             vo.setApprovalFileList(log.getFileName(), StringUtils.isNotEmpty(log.getEVisaPdfUrl()) ? log.getEVisaPdfUrl() : log.getPdfUrl());
         }
 
@@ -193,32 +191,32 @@ public class TaskServiceImpl extends BaseServiceImpl<TaskMapper, Task> implement
     /**
      * 查询填报数据
      */
-    private TaskApprovalVO queryProcessSubmitBusinessData(String formDataId, boolean isTask){
+    private TaskApprovalVO queryProcessSubmitBusinessData(String formDataId, boolean isTask) {
         //查询对应的数据
         TaskApprovalVO vo = new TaskApprovalVO();
 
         InformationQuery query = this.informationQueryService.getById(formDataId);
-        if(query != null){
-            if(new Integer("3").equals(query.getType())){
+        if (query != null) {
+            if (new Integer("3").equals(query.getType())) {
                 //首件,首件的资料由三个部分组成:封面、关联资料、总结报告
-                if(StringUtils.isNotEmpty(query.getEVisaPdfUrl()) || StringUtils.isNotEmpty(query.getPdfUrl())){
+                if (StringUtils.isNotEmpty(query.getEVisaPdfUrl()) || StringUtils.isNotEmpty(query.getPdfUrl())) {
                     //封面
                     vo.setApprovalFileList(query.getName(), StringUtils.isNotEmpty(query.getEVisaPdfUrl()) ? query.getEVisaPdfUrl() : query.getPdfUrl());
                 }
                 //不是签章时再查关联资料,因为关联资料都是审批好的pdf,存在关键字,不能再执行签 字/章
-                if(!isTask){
+                if (!isTask) {
                     //关联资料
-                    if(StringUtils.isNotEmpty(query.getLinkMergePdfUrl())){
+                    if (StringUtils.isNotEmpty(query.getLinkMergePdfUrl())) {
                         vo.setApprovalFileList("首件关联资料", query.getLinkMergePdfUrl());
                     }
                     InformationQueryFile queryFile = this.informationQueryFileService.getOne(Wrappers.<InformationQueryFile>lambdaQuery().eq(InformationQueryFile::getQueryId, query.getId()));
-                    if(queryFile != null){
+                    if (queryFile != null) {
                         vo.setApprovalFileList(queryFile.getName(), queryFile.getPdfUrl());
                     }
                 }
 
             } else {
-                if(StringUtils.isNotEmpty(query.getEVisaPdfUrl()) || StringUtils.isNotEmpty(query.getPdfUrl())){
+                if (StringUtils.isNotEmpty(query.getEVisaPdfUrl()) || StringUtils.isNotEmpty(query.getPdfUrl())) {
                     vo.setApprovalFileList(query.getName(), StringUtils.isNotEmpty(query.getEVisaPdfUrl()) ? query.getEVisaPdfUrl() : query.getPdfUrl());
                 }
             }
@@ -229,12 +227,12 @@ public class TaskServiceImpl extends BaseServiceImpl<TaskMapper, Task> implement
     /**
      * 查询工程文件
      */
-    private TaskApprovalVO queryArchiveFileBusinessData(String formDataId){
+    private TaskApprovalVO queryArchiveFileBusinessData(String formDataId) {
         List<ArchiveFile> archiveFileList = this.archiveFileService.list(Wrappers.<ArchiveFile>lambdaQuery().in(ArchiveFile::getId, Arrays.asList(formDataId.split(","))).eq(ArchiveFile::getIsDeleted, 0));
-        if(archiveFileList != null && archiveFileList.size() > 0){
+        if (archiveFileList != null && archiveFileList.size() > 0) {
             //转换数据
             TaskApprovalVO vo = new TaskApprovalVO();
-            for(ArchiveFile archiveFile : archiveFileList){
+            for (ArchiveFile archiveFile : archiveFileList) {
                 vo.setApprovalFileList(archiveFile.getFileName(), StringUtils.isEmpty(archiveFile.getPdfFileUrl()) ? archiveFile.getFileUrl() : archiveFile.getPdfFileUrl());
             }
             return vo;
@@ -248,9 +246,9 @@ public class TaskServiceImpl extends BaseServiceImpl<TaskMapper, Task> implement
         List<Long> record = new ArrayList<>();
 
         String[] formDataIdArray = formDataIds.split(",");
-        for(String formDataId : formDataIdArray){
+        for (String formDataId : formDataIdArray) {
             Task task = this.baseMapper.queryTaskListByFormDataId(formDataId);
-            if(task != null && !record.contains(task.getId())){
+            if (task != null && !record.contains(task.getId())) {
                 record.add(task.getId());
                 result.add(task);
             }
@@ -264,17 +262,17 @@ public class TaskServiceImpl extends BaseServiceImpl<TaskMapper, Task> implement
         List<TaskParallel> linkList = this.taskParallelService.list(Wrappers.<TaskParallel>lambdaQuery().eq(TaskParallel::getProcessInstanceId, task.getProcessInstanceId()));
 
         //将所有分支流程执行结束
-        for(TaskParallel taskParallel : linkList){
+        for (TaskParallel taskParallel : linkList) {
             //根据实例ID获取任务ID
             String linkTaskId = this.newFlowClient.queryTaskIdByProcessInstanceId(taskParallel.getParallelProcessInstanceId());
-            if(StringUtils.isNotEmpty(linkTaskId)){
+            if (StringUtils.isNotEmpty(linkTaskId)) {
                 //结束分支流程
                 this.newFlowClient.completeApprovalTask(linkTaskId, taskParallel.getParallelProcessInstanceId(), "上报人主动废除");
             }
         }
         //获取主流程的任务ID
         String masterTaskId = this.newFlowClient.queryTaskIdByProcessInstanceId(task.getProcessInstanceId());
-        if(StringUtils.isNotEmpty(masterTaskId)){
+        if (StringUtils.isNotEmpty(masterTaskId)) {
             //结束主流程
             this.newFlowClient.completeApprovalTask(masterTaskId, task.getProcessInstanceId(), "上报人主动废除");
         }
@@ -287,6 +285,44 @@ public class TaskServiceImpl extends BaseServiceImpl<TaskMapper, Task> implement
         return true;
     }
 
+    @Override
+    public Map<String, String> getTaskCount(String projectId, String contractId, String userId) {
+        List<Task> tasks = this.baseMapper.selectList(Wrappers.<Task>lambdaQuery()
+                .eq(Task::getProjectId, projectId)
+                .eq(Task::getContractId, contractId)
+                .eq(Task::getStatus, 1));
+
+        List<String> collect = tasks.stream().map(Task::getProcessInstanceId).collect(Collectors.toList());
+
+        long aLong = 0L;
+        if (collect.size() > 0) {
+            for (String id : collect) {
+                Long row = taskParallelService.getBaseMapper().selectCount(Wrappers.<TaskParallel>lambdaQuery()
+                        .eq(TaskParallel::getProcessInstanceId, id)
+                        .eq(TaskParallel::getStatus, 1)
+                        .eq(TaskParallel::getTaskUser, userId)
+                );
+                if (row == 1) {
+                    aLong++;
+                }
+            }
+        }
+
+        long aLong1 = messageWarningService.getBaseMapper().selectCount(Wrappers.<MessageWarning>lambdaQuery()
+                .eq(MessageWarning::getProjectId, projectId)
+                .eq(MessageWarning::getContractId, contractId)
+                .eq(MessageWarning::getPushUser, userId)
+                .eq(MessageWarning::getIsRead, 0)
+        );
+
+        Map<String, String> map = new HashMap<>();
+        map.put("taskCount", String.valueOf(aLong));
+        map.put("messageCount", String.valueOf(aLong1));
+        map.put("allCount", String.valueOf(aLong + aLong1));
+        map.put("userId", userId);
+        return map;
+    }
+
     @Override
     public List<Task> queryBatchList(String projectId, String contract) {
         return this.baseMapper.queryBatchList(projectId, contract);
@@ -298,7 +334,7 @@ public class TaskServiceImpl extends BaseServiceImpl<TaskMapper, Task> implement
         List<String> taskIds = taskApprovalVOS.stream().map(TaskApprovalVO::getParallelProcessInstanceId).distinct().collect(Collectors.toList());
 
         long batch = this.taskBatchService.count(Wrappers.<TaskBatch>lambdaQuery().eq(TaskBatch::getCreateUser, AuthUtil.getUserId()));
-        if(batch > 0){
+        if (batch > 0) {
             //修改电签状态
             this.taskParallelService.update(Wrappers.<TaskParallel>lambdaUpdate()
                     .set(TaskParallel::getEVisaContent, "当前等待电签的批次较多,请等待几分钟后刷新页面查看........")
@@ -329,20 +365,20 @@ public class TaskServiceImpl extends BaseServiceImpl<TaskMapper, Task> implement
 
     }
 
-    private void checkIsExsitTaskBatch(List<TaskApprovalVO> taskApprovalVOS, String batchId){
+    private void checkIsExsitTaskBatch(List<TaskApprovalVO> taskApprovalVOS, String batchId) {
         boolean isContinue = true;
-        while (isContinue){
+        while (isContinue) {
             logger.info("【任务审核】当前批次开始电签。批次ID:" + batchId);
             //执行电签
-            for(TaskApprovalVO taskApprovalVO : taskApprovalVOS){
+            for (TaskApprovalVO taskApprovalVO : taskApprovalVOS) {
                 this.completeApprovalTask(taskApprovalVO);
             }
             //删除掉对应批次
             this.taskBatchService.deletedById(batchId);
-            try{
+            try {
                 //查询是否还存在对应批次(时间升序)
                 List<TaskBatch> taskBatches = this.taskBatchService.list(Wrappers.<TaskBatch>lambdaQuery().eq(TaskBatch::getCreateUser, AuthUtil.getUserId()).orderByAsc(TaskBatch::getCreateTime));
-                if(taskBatches != null && taskBatches.size() > 0){
+                if (taskBatches != null && taskBatches.size() > 0) {
                     TaskBatch taskBatch = taskBatches.get(0);
                     //获取业务参数集合
                     taskApprovalVOS = JSONArray.parseArray(JSONObject.toJSONString(taskBatch.getJsonData()), TaskApprovalVO.class);
@@ -351,7 +387,7 @@ public class TaskServiceImpl extends BaseServiceImpl<TaskMapper, Task> implement
                     logger.info("【任务审核】已无等待电签批次!当前线程结束即将释放。");
                     isContinue = false;
                 }
-            }catch (Exception e){
+            } catch (Exception e) {
                 isContinue = false;
                 e.printStackTrace();
             }
@@ -365,18 +401,18 @@ public class TaskServiceImpl extends BaseServiceImpl<TaskMapper, Task> implement
         String parallelProcessInstanceId = taskApprovalVO.getParallelProcessInstanceId();
         //获取审批内容
         String comment = taskApprovalVO.getComment();
-        if(StringUtils.isEmpty(comment) && "OK".equals(taskApprovalVO.getFlag())){
+        if (StringUtils.isEmpty(comment) && "OK".equals(taskApprovalVO.getFlag())) {
             comment = "同意";
         }
         //获取当前分支信息
         TaskParallel currentLink = this.taskParallelService.getOne(Wrappers.<TaskParallel>lambdaQuery().eq(TaskParallel::getParallelProcessInstanceId, parallelProcessInstanceId).eq(TaskParallel::getIsDeleted, 0));
-        if(currentLink == null){
+        if (currentLink == null) {
             return;
         }
         //获取主流程
         Task masterTask = this.getOne(Wrappers.<Task>lambdaQuery().eq(Task::getIsDeleted, 0).eq(Task::getProcessInstanceId, currentLink.getProcessInstanceId()));
 
-        if("OK".equals(taskApprovalVO.getFlag())){
+        if ("OK".equals(taskApprovalVO.getFlag())) {
             //同意,执行签章
             //todo ============================ 执行电签区域 ============================
             //电签状态
@@ -384,7 +420,7 @@ public class TaskServiceImpl extends BaseServiceImpl<TaskMapper, Task> implement
             //todo ============================ 执行电签区域 ============================
 
             //电签状态分为success/notPfxOrFile/error,当状态为error时就需要重新提交请求
-            if("success".equals(eVisaStatus) || eVisaStatus.contains("success")){
+            if ("success".equals(eVisaStatus) || eVisaStatus.contains("success")) {
                 //审批通过会返回签章成功的文件,需要设置替换
                 //完成/审批当前分支流程
                 this.newFlowClient.completeApprovalTask(taskId, parallelProcessInstanceId, comment).getData();
@@ -402,24 +438,24 @@ public class TaskServiceImpl extends BaseServiceImpl<TaskMapper, Task> implement
                 //获取状态为1(待审批)的分支流程
                 List<TaskParallel> otherLink = this.taskParallelService.list(Wrappers.<TaskParallel>lambdaQuery().eq(TaskParallel::getProcessInstanceId, currentLink.getProcessInstanceId()).eq(TaskParallel::getIsDeleted, 0).eq(TaskParallel::getStatus, 1));
 
-                if(otherLink == null || otherLink.size() == 0){
+                if (otherLink == null || otherLink.size() == 0) {
                     //说明都审批完成,将主表状态更改为已完成
                     String finalPdfUrl = null;
-                    if(eVisaStatus.contains("@@@@")){
+                    if (eVisaStatus.contains("@@@@")) {
                         finalPdfUrl = eVisaStatus.split("@@@@")[1];
                     }
                     //todo ===================== 执行合同章
-                    try{
+                    try {
                         //执行合同章,返回的是盖有合同章的PDF路径
                         finalPdfUrl = this.eVisaClient.eVisaContractSeal(JSONObject.parseObject(JSONObject.toJSONString(taskApprovalVO), EVisaTaskApprovalVO.class), finalPdfUrl);
-                    }catch (Exception e){
+                    } catch (Exception e) {
                         e.printStackTrace();
                     }
                     //todo ===================== 执行合同章
 
                     //根据主表的业务ID(processInstanceId)获取主流程的taskId
                     String masterTaskId = this.newFlowClient.queryTaskIdByProcessInstanceId(masterTask.getProcessInstanceId());
-                    if(StringUtils.isNotEmpty(masterTaskId)){
+                    if (StringUtils.isNotEmpty(masterTaskId)) {
                         //完成流程
                         this.newFlowClient.completeApprovalTask(taskId, masterTask.getProcessInstanceId(), "审批完成");
                         //修改主流程状态为已完成
@@ -429,12 +465,12 @@ public class TaskServiceImpl extends BaseServiceImpl<TaskMapper, Task> implement
                     }
                 } else {
                     //只更新PDF路径
-                    this.updateBusinessDataByFormDataId(masterTask, 1,  eVisaStatus.contains("@@@@") ? eVisaStatus.split("@@@@")[1] : null);
+                    this.updateBusinessDataByFormDataId(masterTask, 1, eVisaStatus.contains("@@@@") ? eVisaStatus.split("@@@@")[1] : null);
                 }
-            } else if("eVisaError".equals(eVisaStatus) || eVisaStatus.contains("eVisaError")){
+            } else if ("eVisaError".equals(eVisaStatus) || eVisaStatus.contains("eVisaError")) {
                 //电签失败,将对应分支任务的电签状态修改为99并添加错误信息
                 String message = "电签失败";
-                if(eVisaStatus.contains("####")){
+                if (eVisaStatus.contains("####")) {
                     message = eVisaStatus.split("####")[1];
                 }
                 //修改
@@ -473,18 +509,18 @@ public class TaskServiceImpl extends BaseServiceImpl<TaskMapper, Task> implement
             //主流程实例ID
             String masterProcessInstanceId;
 
-            if(otherLink != null && otherLink.size() > 0){
+            if (otherLink != null && otherLink.size() > 0) {
                 masterProcessInstanceId = otherLink.get(0).getProcessInstanceId();
-                for(TaskParallel parallel : otherLink){
-                    if(!new Integer("2").equals(parallel.getStatus())){
+                for (TaskParallel parallel : otherLink) {
+                    if (!new Integer("2").equals(parallel.getStatus())) {
                         //修改所有状态为已废除
                         this.taskParallelService.update(Wrappers.<TaskParallel>lambdaUpdate().set(TaskParallel::getInitiative, 2).set(TaskParallel::getUpdateUser, AuthUtil.getUserId()).set(TaskParallel::getUpdateTime, new Date()).eq(TaskParallel::getId, parallel.getId()));
 
-                        if(new Integer("1").equals(parallel.getStatus())){
+                        if (new Integer("1").equals(parallel.getStatus())) {
                             //存在未审批的情况,自动执行其分支流程
                             //获取流程ID
                             String parallelTaskId = this.newFlowClient.queryTaskIdByProcessInstanceId(parallel.getParallelProcessInstanceId());
-                            if(StringUtils.isNotEmpty(parallelTaskId)){
+                            if (StringUtils.isNotEmpty(parallelTaskId)) {
                                 //执行流程
                                 this.newFlowClient.completeApprovalTask(parallelTaskId, parallel.getParallelProcessInstanceId(), "其它分支主动废除任务,当前任务被动完成");
                             }
@@ -499,7 +535,7 @@ public class TaskServiceImpl extends BaseServiceImpl<TaskMapper, Task> implement
             //处理完分支流程后,将主流程结束并设置状态为废除
             //获取主流程的taskId
             String masterTaskId = this.newFlowClient.queryTaskIdByProcessInstanceId(masterProcessInstanceId);
-            if(StringUtils.isNotEmpty(masterTaskId)){
+            if (StringUtils.isNotEmpty(masterTaskId)) {
                 //执行流程
                 this.newFlowClient.completeApprovalTask(masterTaskId, masterProcessInstanceId, "废除任务");
             }
@@ -516,22 +552,22 @@ public class TaskServiceImpl extends BaseServiceImpl<TaskMapper, Task> implement
     /**
      * 任务废除通知
      */
-    private void abolishMessage(Task masterTask, TaskParallel currentLink, String comment){
+    private void abolishMessage(Task masterTask, TaskParallel currentLink, String comment) {
         //查询合同段及项目名称
         ProjectInfo projectInfo = this.projectClient.queryProjectList(Func.toStrList(masterTask.getProjectId())).get(0);
         String projectName = StringUtils.isNotEmpty(projectInfo.getProjectAlias()) ? projectInfo.getProjectAlias() : projectInfo.getProjectName();
         ContractInfo contractInfo = this.contractClient.getContractById(Long.parseLong(masterTask.getContractId()));
         String contractName = contractInfo.getContractName();
 
-        try{
+        try {
             //记录已经通知的人
             List<Long> userIds = new ArrayList<>();
 
             //设置废除通知信息
             List<MessageWarningVO> messageWarningList = new ArrayList<>();
             List<TaskParallel> linkTaskList = this.taskParallelService.list(Wrappers.<TaskParallel>lambdaQuery().eq(TaskParallel::getProcessInstanceId, masterTask.getProcessInstanceId()));
-            for(TaskParallel parallel : linkTaskList){
-                if(!currentLink.getId().equals(parallel.getId()) && !userIds.contains(Long.parseLong(parallel.getTaskUser()))){
+            for (TaskParallel parallel : linkTaskList) {
+                if (!currentLink.getId().equals(parallel.getId()) && !userIds.contains(Long.parseLong(parallel.getTaskUser()))) {
                     messageWarningList.add(new MessageWarningVO(
                             Long.parseLong(masterTask.getProjectId()),
                             Long.parseLong(masterTask.getContractId()),
@@ -559,19 +595,19 @@ public class TaskServiceImpl extends BaseServiceImpl<TaskMapper, Task> implement
             //查询业务数据
             JSONObject businessJson = this.queryTaskBusinessObject(masterTask.getFormDataId());
             //通知填报人
-            if(businessJson.containsKey("isQuery") || businessJson.containsKey("isLog") || businessJson.containsKey("isArchive")){
+            if (businessJson.containsKey("isQuery") || businessJson.containsKey("isLog") || businessJson.containsKey("isArchive")) {
                 //获取集合
                 List<JSONObject> result = JSONArray.parseArray(JSONObject.toJSONString(businessJson.get("result")), JSONObject.class);
-                for(JSONObject json : result){
-                    if(businessJson.containsKey("isQuery")){
+                for (JSONObject json : result) {
+                    if (businessJson.containsKey("isQuery")) {
                         //填报资料,获取参与的填报人
                         String fileUserIdAndName = json.getString("fileUserIdAndName");
-                        if(StringUtils.isNotEmpty(fileUserIdAndName)){
+                        if (StringUtils.isNotEmpty(fileUserIdAndName)) {
                             String[] fileUserIdAndNames = fileUserIdAndName.split(",");
-                            for(String str : fileUserIdAndNames){
+                            for (String str : fileUserIdAndNames) {
                                 String[] strs = str.split("-");
                                 //可能上报人就是填报人,防止重复推送
-                                if(!userIds.contains(Long.parseLong(strs[0]))){
+                                if (!userIds.contains(Long.parseLong(strs[0]))) {
                                     //通知上报人
                                     messageWarningList.add(new MessageWarningVO(
                                             Long.parseLong(masterTask.getProjectId()),
@@ -586,10 +622,10 @@ public class TaskServiceImpl extends BaseServiceImpl<TaskMapper, Task> implement
                             }
                         }
 
-                    } else if(businessJson.containsKey("isLog") || businessJson.containsKey("isArchive")){
+                    } else if (businessJson.containsKey("isLog") || businessJson.containsKey("isArchive")) {
                         //获取填写人
                         String fillUser = json.getString("createUser");
-                        if(StringUtils.isNotEmpty(fillUser) && !userIds.contains(Long.parseLong(fillUser))){
+                        if (StringUtils.isNotEmpty(fillUser) && !userIds.contains(Long.parseLong(fillUser))) {
                             //通知上报人
                             messageWarningList.add(new MessageWarningVO(
                                     Long.parseLong(masterTask.getProjectId()),
@@ -607,7 +643,7 @@ public class TaskServiceImpl extends BaseServiceImpl<TaskMapper, Task> implement
 
             //生成废除通知
             this.messageWarningService.savePushUserMessageWarning(messageWarningList);
-        }catch (Exception e){
+        } catch (Exception e) {
             e.printStackTrace();
         }
     }
@@ -616,7 +652,7 @@ public class TaskServiceImpl extends BaseServiceImpl<TaskMapper, Task> implement
     public Boolean startApproval(TaskVO vo) {
         //获取业务表
         String businessTable = FlowUtil.getBusinessTable(ProcessConstant.EXAMINATION_AND_APPROVAL);
-        if(Func.isEmpty(vo.getId())){
+        if (Func.isEmpty(vo.getId())) {
             vo.setId(SnowFlakeUtil.getId());
             //设置开始/结束时间
             Date nowTime = new Date();
@@ -628,24 +664,24 @@ public class TaskServiceImpl extends BaseServiceImpl<TaskMapper, Task> implement
             query.setSize(999);
             //获取流程
             List<FlowProcessVO> modeProcessVOS = this.newFlowClient.startFlowList("", query, 1);
-            if(modeProcessVOS == null || modeProcessVOS.size() == 0){
+            if (modeProcessVOS == null || modeProcessVOS.size() == 0) {
                 return false;
             }
             //获取当中的审批流程
             String taskFlowId = null;
-            for(FlowProcessVO processVO : modeProcessVOS){
-                if("approval".equals(processVO.getKey())){
+            for (FlowProcessVO processVO : modeProcessVOS) {
+                if ("approval".equals(processVO.getKey())) {
                     taskFlowId = processVO.getId();
                     break;
                 }
             }
             //如果没有对应流程,直接返回
-            if(StringUtils.isEmpty(taskFlowId)){
+            if (StringUtils.isEmpty(taskFlowId)) {
                 return false;
             }
             //获取选择的固定流程
             List<FixedFlowLink> links;
-            if(Long.valueOf("0").equals(vo.getFixedFlowId())){
+            if (Long.valueOf("0").equals(vo.getFixedFlowId())) {
                 //自定义流程
                 links = new ArrayList<>();
                 //获取自定义流程
@@ -656,7 +692,7 @@ public class TaskServiceImpl extends BaseServiceImpl<TaskMapper, Task> implement
             } else {
                 //预设流程
                 links = this.fixedFlowLinkService.selectFixedFlowLink(vo.getFixedFlowId().toString());
-                if(links == null || links.size() == 0){
+                if (links == null || links.size() == 0) {
                     return false;
                 }
             }
@@ -674,7 +710,7 @@ public class TaskServiceImpl extends BaseServiceImpl<TaskMapper, Task> implement
 
             //根据所选择的固定流程所含有的环节发起审批任务
             List<TaskParallel> taskParallelArray = new ArrayList<>();
-            for(FixedFlowLink link : links){
+            for (FixedFlowLink link : links) {
                 //启动并行流程
                 Kv variables = Kv.create()
                         //下一步流程审批人
@@ -712,12 +748,12 @@ public class TaskServiceImpl extends BaseServiceImpl<TaskMapper, Task> implement
     /**
      * 获取业务数据
      */
-    private JSONObject queryTaskBusinessObject(String formDataId){
+    private JSONObject queryTaskBusinessObject(String formDataId) {
         JSONObject json = new JSONObject();
         List<JSONObject> jsonResult;
         //先检查是否是资料填报
         List<InformationQuery> querys = this.informationQueryService.list(Wrappers.<InformationQuery>lambdaQuery().in(InformationQuery::getId, Func.toStrList(formDataId)));
-        if(querys != null && querys.size() > 0){
+        if (querys != null && querys.size() > 0) {
             jsonResult = JSONArray.parseArray(JSONObject.toJSONString(querys), JSONObject.class);
             //设置标记
             json.put("isQuery", "true");
@@ -725,7 +761,7 @@ public class TaskServiceImpl extends BaseServiceImpl<TaskMapper, Task> implement
         } else {
             //再检查是否是日志
             List<ContractLog> logs = this.contractLogService.list(Wrappers.<ContractLog>lambdaQuery().in(ContractLog::getId, Func.toStrList(formDataId)));
-            if(logs != null && logs.size() > 0){
+            if (logs != null && logs.size() > 0) {
                 jsonResult = JSONArray.parseArray(JSONObject.toJSONString(logs), JSONObject.class);
                 //设置标记
                 json.put("isLog", "true");
@@ -733,7 +769,7 @@ public class TaskServiceImpl extends BaseServiceImpl<TaskMapper, Task> implement
             } else {
                 //工程文件
                 List<ArchiveFile> archiveList = this.archiveFileService.list(Wrappers.<ArchiveFile>lambdaQuery().eq(ArchiveFile::getId, Func.toStrList(formDataId)));
-                if(archiveList != null && archiveList.size() > 0){
+                if (archiveList != null && archiveList.size() > 0) {
                     jsonResult = JSONArray.parseArray(JSONObject.toJSONString(archiveList), JSONObject.class);
                     //设置标记
                     json.put("isArchive", "true");
@@ -747,8 +783,8 @@ public class TaskServiceImpl extends BaseServiceImpl<TaskMapper, Task> implement
     /**
      * 修改业务数据状态
      */
-    private void updateBusinessDataByFormDataId(Task task, Integer status, String newFileUrl){
-        switch (task.getApprovalType()){
+    private void updateBusinessDataByFormDataId(Task task, Integer status, String newFileUrl) {
+        switch (task.getApprovalType()) {
             case 1:
                 //资料填报
                 this.updateWriteBusinessDataStatus(task.getFormDataId(), status, newFileUrl);
@@ -770,7 +806,7 @@ public class TaskServiceImpl extends BaseServiceImpl<TaskMapper, Task> implement
      * 施工日志等
      */
     @Transactional
-    public void updateContractLogBusinessDataStatus(String formDataId, Integer status, String newFileUrl){
+    public void updateContractLogBusinessDataStatus(String formDataId, Integer status, String newFileUrl) {
         this.contractLogService.update(Wrappers.<ContractLog>lambdaUpdate().set(ContractLog::getStatus, status)
                 .set(ContractLog::getEVisaPdfUrl, newFileUrl)
                 .set(ContractLog::getAuditUserIdAndName, null)
@@ -784,7 +820,7 @@ public class TaskServiceImpl extends BaseServiceImpl<TaskMapper, Task> implement
      * 资料填报
      */
     @Transactional
-    public void updateWriteBusinessDataStatus(String formDataId, Integer status, String newFileUrl){
+    public void updateWriteBusinessDataStatus(String formDataId, Integer status, String newFileUrl) {
         this.informationQueryService.update(Wrappers.<InformationQuery>lambdaUpdate().set(InformationQuery::getStatus, status)
                 .set(InformationQuery::getEVisaPdfUrl, newFileUrl)
                 .set(InformationQuery::getReportNumber, null)
@@ -798,7 +834,7 @@ public class TaskServiceImpl extends BaseServiceImpl<TaskMapper, Task> implement
      * 工程文件
      */
     @Transactional
-    public void updateArchiveFileBusinessDataStatus(String formDataId, Integer status, String newFileUrl){
+    public void updateArchiveFileBusinessDataStatus(String formDataId, Integer status, String newFileUrl) {
         LambdaUpdateWrapper<ArchiveFile> wrapper = Wrappers.lambdaUpdate();
         //更改状态,更改电签文件信息
         wrapper.set(ArchiveFile::getStatus, status)

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

@@ -0,0 +1,159 @@
+package org.springblade.business.socket;
+
+import com.alibaba.fastjson.JSON;
+import org.apache.commons.lang.StringUtils;
+import org.apache.logging.log4j.LogManager;
+import org.apache.logging.log4j.Logger;
+import org.springblade.business.service.ITaskService;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.stereotype.Component;
+import cn.hutool.core.util.StrUtil;
+import org.springframework.web.bind.annotation.CrossOrigin;
+
+import javax.websocket.*;
+import javax.websocket.server.PathParam;
+import javax.websocket.server.ServerEndpoint;
+import java.io.IOException;
+import java.util.Map;
+import java.util.concurrent.ConcurrentHashMap;
+
+@Component
+@CrossOrigin
+@ServerEndpoint(value = "/websocket/{userId}")
+public class WebSocket {
+
+    private static ITaskService iTaskService;
+
+    private final static Logger logger = LogManager.getLogger(WebSocket.class);
+    private static int onlineCount = 0;
+    private static ConcurrentHashMap<String, WebSocket> webSocketMap = new ConcurrentHashMap<>();
+    private static ConcurrentHashMap<String, String> webSocketMessageMap = new ConcurrentHashMap<>();
+    private Session session;
+    private String userId;
+
+    /**
+     * 注入service
+     */
+    @Autowired
+    public void setApplicationContext(ITaskService iTaskService) {
+        WebSocket.iTaskService = iTaskService;
+    }
+
+    public static Map<String, WebSocket> getWebSocketMap() {
+        return webSocketMap;
+    }
+
+    public static Map<String, String> getWebSocketMessageMap() {
+        return webSocketMessageMap;
+    }
+
+    @OnOpen
+    public void onOpen(Session session, @PathParam("userId") String userId) {
+        this.session = session;
+        this.userId = userId;
+        //加入map
+        webSocketMap.put(userId, this);
+        addOnlineCount();           //在线数加1
+        logger.info("用户{}连接成功,当前在线人数为{}", userId, getOnlineCount());
+        try {
+            sendMessage(String.valueOf(this.session.getQueryString()));
+        } catch (IOException e) {
+            logger.error("IO异常");
+        }
+    }
+
+    @OnClose
+    public void onClose() {
+        //从map中删除
+        webSocketMap.remove(userId);
+        webSocketMessageMap.remove(userId);
+        subOnlineCount(); //在线数减1
+        logger.info("用户{}关闭连接!当前在线人数为{}", userId, getOnlineCount());
+    }
+
+    /**
+     * 收到客户端消息后调用的方法
+     *
+     * @param message 客户端发送过来的消息
+     */
+    @OnMessage
+    public void onMessage(String message, Session session) {
+        webSocketMessageMap.put(userId, message);
+        logger.info("来自客户端用户:{} 消息:{}", userId, message);
+
+        String projectId = message.split(",")[0];
+        String contractId = message.split(",")[1];
+
+        Map<String, String> stringMap = null;
+        if (StringUtils.isNotEmpty(projectId) && StringUtils.isNotEmpty(contractId) && StringUtils.isNotEmpty(userId)) {
+            stringMap = iTaskService.getTaskCount(projectId, contractId, userId);
+        }
+
+        //切换项目合同段,推送当前项目合同段的业务数量
+        try {
+            webSocketMap.get(userId).sendMessage(JSON.toJSONString(stringMap));
+        } catch (IOException e) {
+            e.printStackTrace();
+        }
+    }
+
+    /**
+     * 发生错误时调用
+     */
+    @OnError
+    public void onError(Session session, Throwable error) {
+        logger.error("用户错误:" + this.userId + ",原因:" + error.getMessage());
+        error.printStackTrace();
+    }
+
+    /**
+     * 向客户端发送消息
+     */
+    public void sendMessage(String message) throws IOException {
+        //同步
+        //this.session.getBasicRemote().sendText(message);
+
+        //异步
+        this.session.getAsyncRemote().sendText(message);
+    }
+
+    /**
+     * 通过userId向客户端发送消息
+     */
+    public void sendMessageByUserId(String userId, String message) throws IOException {
+        logger.info("服务端发送消息到{},消息:{}", userId, message);
+        if (StrUtil.isNotBlank(userId) && webSocketMap.containsKey(userId)) {
+            webSocketMap.get(userId).sendMessage(message);
+        } else {
+            logger.error("用户{}不在线", userId);
+        }
+    }
+
+    /**
+     * 群发自定义消息
+     */
+    public static void sendInfo(String message) throws IOException {
+        for (String item : webSocketMap.keySet()) {
+            try {
+                webSocketMap.get(item).sendMessage(message);
+            } catch (IOException e) {
+                continue;
+            }
+        }
+    }
+
+    public static synchronized int getOnlineCount() {
+        return onlineCount;
+    }
+
+    public static synchronized void addOnlineCount() {
+        WebSocket.onlineCount++;
+    }
+
+    public static synchronized void subOnlineCount() {
+        WebSocket.onlineCount--;
+    }
+
+}
+
+

+ 35 - 0
blade-service/blade-business/src/main/java/org/springblade/business/socket/WebSocketConfig.java

@@ -0,0 +1,35 @@
+package org.springblade.business.socket;
+
+import org.springframework.context.annotation.Bean;
+import org.springframework.context.annotation.Configuration;
+import org.springframework.messaging.simp.config.MessageBrokerRegistry;
+import org.springframework.web.socket.config.annotation.EnableWebSocketMessageBroker;
+import org.springframework.web.socket.config.annotation.StompEndpointRegistry;
+import org.springframework.web.socket.config.annotation.WebSocketMessageBrokerConfigurer;
+import org.springframework.web.socket.server.standard.ServerEndpointExporter;
+
+@Configuration
+@EnableWebSocketMessageBroker
+public class WebSocketConfig implements WebSocketMessageBrokerConfigurer {
+
+    @Bean
+    public ServerEndpointExporter serverEndpointExporter() {
+        return new ServerEndpointExporter();
+    }
+
+    @Override
+    public void registerStompEndpoints(StompEndpointRegistry registry){
+        registry.addEndpoint("/websocket")
+                .setAllowedOrigins("*") //跨域
+                .withSockJS();
+    }
+
+    @Override
+    public void configureMessageBroker(MessageBrokerRegistry registry){
+        registry.enableSimpleBroker("*");
+        registry.setApplicationDestinationPrefixes("*");
+        registry.setUserDestinationPrefix("*");
+    }
+
+}
+

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

@@ -17,7 +17,6 @@ import org.springblade.manager.service.IWbsTreeContractService;
 import org.springblade.manager.vo.WbsTreeContractTreeVO;
 import org.springblade.manager.vo.WbsTreeContractTreeVO3;
 import org.springblade.manager.vo.WbsTreeContractTreeVOS;
-import org.springblade.manager.vo.WbsTreeContractVO;
 import org.springblade.system.entity.DictBiz;
 import org.springblade.system.feign.IDictBizClient;
 import org.springblade.system.feign.ISysClient;

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

@@ -87,7 +87,6 @@ public interface WbsTreePrivateMapper extends EasyBaseMapper<WbsTreePrivate> {
 
     List<WbsTreePrivate> selectWbsTreeContractList(List<String> tableOwnerNumbers,String tableType, String projectId, String wbsId, Long parentId, List<String> tableOwnerList);
 
-
     //删除表单信息
     void delTableById(String pKeyId);
 

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

@@ -283,7 +283,9 @@
                 table_owner = #{item.tableOwner},
                 fill_rate = #{item.fillRate},
                 import_matching_info = #{item.importMatchingInfo},
-                mix_ratio_test_ids = #{item.mixRatioTestIds}
+                mix_ratio_test_ids = #{item.mixRatioTestIds},
+                init_table_name = #{item.initTableName},
+                init_table_id = #{item.initTableId}
             </set>
             WHERE id = #{item.id}
             AND project_id = #{item.projectId}

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

@@ -370,6 +370,8 @@ public class WbsTreePrivateServiceImpl extends BaseServiceImpl<WbsTreePrivateMap
                                 || (ObjectUtils.isNotEmpty(wbsTree.getTableOwner()) && !wbsTree.getTableOwner().equals(wbsTreePrivate.getTableOwner()))
                                 || (ObjectUtils.isNotEmpty(wbsTree.getImportMatchingInfo()) && !wbsTree.getImportMatchingInfo().equals(wbsTreePrivate.getImportMatchingInfo()))
                                 || (ObjectUtils.isNotEmpty(wbsTree.getMixRatioTestIds()) && !wbsTree.getMixRatioTestIds().equals(wbsTreePrivate.getMixRatioTestIds()))
+                                || (ObjectUtils.isNotEmpty(wbsTree.getInitTableId()) && !wbsTree.getInitTableId().toString().equals(wbsTreePrivate.getInitTableId()))
+                                || (ObjectUtils.isNotEmpty(wbsTree.getInitTableName()) && !wbsTree.getInitTableName().equals(wbsTreePrivate.getInitTableName()))
                         )) {
                     //修改项目wbs信息
                     WbsTreePrivate wbsPrivate = BeanUtil.copyProperties(wbsTree, WbsTreePrivate.class);
@@ -417,6 +419,8 @@ public class WbsTreePrivateServiceImpl extends BaseServiceImpl<WbsTreePrivateMap
                                 || (ObjectUtils.isNotEmpty(wbsTreePrivate.getTableOwner()) && !wbsTreePrivate.getTableOwner().equals(treePrivateNow.getTableOwner()))
                                 || (ObjectUtils.isNotEmpty(wbsTreePrivate.getImportMatchingInfo()) && !wbsTreePrivate.getImportMatchingInfo().equals(treePrivateNow.getImportMatchingInfo()))
                                 || (ObjectUtils.isNotEmpty(wbsTreePrivate.getMixRatioTestIds()) && !wbsTreePrivate.getMixRatioTestIds().equals(treePrivateNow.getMixRatioTestIds()))
+                                || (ObjectUtils.isNotEmpty(wbsTreePrivate.getInitTableId()) && !wbsTreePrivate.getInitTableId().equals(treePrivateNow.getInitTableId()))
+                                || (ObjectUtils.isNotEmpty(wbsTreePrivate.getInitTableName()) && !wbsTreePrivate.getInitTableName().equals(treePrivateNow.getInitTableName()))
                         )) {
                     //修改项目wbs信息
                     WbsTreePrivate wbsPrivate = BeanUtil.copyProperties(wbsTreePrivate, WbsTreePrivate.class);
@@ -1527,7 +1531,10 @@ public class WbsTreePrivateServiceImpl extends BaseServiceImpl<WbsTreePrivateMap
             for (WbsTreePrivate wbsTreePrivate : wbsTreePrivates) {
                 if (tableInfo.getTabEnName().equals(wbsTreePrivate.getInitTableName()) || tableInfo.getTabChName().equals(wbsTreePrivate.getInitTableName())) {
                     if (ObjectUtil.isEmpty(wbsTreePrivate.getInitTableId())) {
-                        this.update(Wrappers.<WbsTreePrivate>lambdaUpdate().set(WbsTreePrivate::getInitTableId, String.valueOf(tableInfo.getId())).eq(WbsTreePrivate::getPKeyId, wbsTreePrivate.getPKeyId()));
+                        this.update(Wrappers.<WbsTreePrivate>lambdaUpdate()
+                                .set(WbsTreePrivate::getInitTableId, String.valueOf(tableInfo.getId()))
+                                .set(WbsTreePrivate::getInitTableName, tableInfo.getTabEnName())
+                                .eq(WbsTreePrivate::getPKeyId, wbsTreePrivate.getPKeyId()));
                     }
                 }
             }

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

@@ -477,6 +477,7 @@ public class WbsTreeServiceImpl extends BaseServiceImpl<WbsTreeMapper, WbsTree>
 
                     //修改公有wbs节点信息、元素表基础信息到项目级wbs、合同段wbs
                     this.updateWbsInfoPrivateAsync(wbsTreeListAll, wbsTreePrivatesAll, pawDTO.getProjectId());
+
                 }
 
                 if (pawDTO.getReferenceType().equals("private")) {