Procházet zdrojové kódy

Merge branch 'master' of http://121.41.40.202:3000/zhuwei/bladex

huangtf před 1 rokem
rodič
revize
eb2f1a5f10
23 změnil soubory, kde provedl 627 přidání a 181 odebrání
  1. 9 0
      blade-common/src/main/java/org/springblade/common/utils/BaseUtils.java
  2. 5 0
      blade-service-api/blade-archive-api/src/main/java/org/springblade/archive/vo/ArchivesAutoVO.java
  3. 2 0
      blade-service-api/blade-manager-api/src/main/java/org/springblade/manager/vo/CurrentNode.java
  4. 2 2
      blade-service/blade-archive/src/main/java/org/springblade/archive/controller/ArchiveFileTaskController.java
  5. 5 3
      blade-service/blade-archive/src/main/java/org/springblade/archive/controller/ArchivesAutoController.java
  6. 14 0
      blade-service/blade-archive/src/main/java/org/springblade/archive/mapper/ArchivesAutoMapper.xml
  7. 26 26
      blade-service/blade-archive/src/main/java/org/springblade/archive/service/impl/ArchiveOfflineVersionInfoServiceImpl.java
  8. 35 3
      blade-service/blade-archive/src/main/java/org/springblade/archive/service/impl/ArchivesAutoServiceImpl.java
  9. 6 3
      blade-service/blade-business/src/main/java/org/springblade/business/controller/TaskController.java
  10. 55 5
      blade-service/blade-business/src/main/java/org/springblade/business/service/impl/InformationQueryServiceImpl.java
  11. 124 60
      blade-service/blade-business/src/main/java/org/springblade/business/service/impl/TaskServiceImpl.java
  12. 12 3
      blade-service/blade-manager/src/main/java/com/mixsmart/utils/FormulaUtils.java
  13. 63 35
      blade-service/blade-manager/src/main/java/org/springblade/manager/controller/ExcelTabController.java
  14. 54 7
      blade-service/blade-manager/src/main/java/org/springblade/manager/formula/ITurnPointCalculator.java
  15. 21 3
      blade-service/blade-manager/src/main/java/org/springblade/manager/formula/LevelInfo.java
  16. 39 5
      blade-service/blade-manager/src/main/java/org/springblade/manager/formula/TurnPoint.java
  17. 19 0
      blade-service/blade-manager/src/main/java/org/springblade/manager/formula/impl/FormulaTurnPoint.java
  18. 3 1
      blade-service/blade-manager/src/main/java/org/springblade/manager/service/IFormulaService.java
  19. 29 3
      blade-service/blade-manager/src/main/java/org/springblade/manager/service/impl/ContractInfoServiceImpl.java
  20. 22 17
      blade-service/blade-manager/src/main/java/org/springblade/manager/service/impl/ExcelTabServiceImpl.java
  21. 12 1
      blade-service/blade-manager/src/main/java/org/springblade/manager/service/impl/FormulaServiceImpl.java
  22. 1 0
      blade-service/blade-manager/src/main/java/org/springblade/manager/service/impl/WbsParamServiceImpl.java
  23. 69 4
      blade-service/blade-manager/src/main/java/org/springblade/manager/service/impl/WbsTreeContractServiceImpl.java

+ 9 - 0
blade-common/src/main/java/org/springblade/common/utils/BaseUtils.java

@@ -37,6 +37,15 @@ public class BaseUtils {
         return -1;
     }
 
+    public static  Double milestone(String s){
+        Pattern pattern=Pattern.compile("(?i)K(\\d+)\\+([\\d.]+)");
+        Matcher matcher = pattern.matcher(s);
+        if(matcher.find()){
+            return   Double.parseDouble(matcher.group(1))*1000+ Double.parseDouble(matcher.group(2));
+        }
+        return null;
+    }
+
 
     /**
      * @return java.util.Map<java.lang.String, java.lang.String>

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

@@ -75,6 +75,11 @@ public class ArchivesAutoVO extends ArchivesAuto {
 	@ApiModelProperty("输入框查询条件")
 	private String queryValue;
 
+	/**
+	 * 输入框查询条件集合
+	 */
+	private List<String> queryList;
+
 	/**
 	 * 节点查询条件
 	 */

+ 2 - 0
blade-service-api/blade-manager-api/src/main/java/org/springblade/manager/vo/CurrentNode.java

@@ -35,6 +35,8 @@ public class CurrentNode {
     private Long wtpPkeyId;
     /**wbs_tree的流水号 需要溯源*/
     private Long wbsNodeId;
+    /**treeCode*/
+    private List<String> treeCode =new ArrayList<>();
     /**
      * 当前节点父级下所有子孙节点里所有的node_type in(6,4)节点的pkeyId
      * */

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

@@ -311,8 +311,8 @@ public class ArchiveFileTaskController extends BladeController {
                     vo.setTaskReportUserName(nameMap.get(Long.parseLong(task.getReportUser())));
                     List<TaskParallel> taskParallelList = finalTaskParallelGroupMap.get(task.getProcessInstanceId());
                     if (taskParallelList != null && taskParallelList.size() > 0) {
-                        //如果是垂直签,判断是否是当前用户审批轮次,不是当前用户审批轮次就不显示该任务
-                        if (projectInfo != null && projectInfo.getApprovalType() == 1) {
+                        //如果是垂直签,且是待办页面,判断是否是当前用户审批轮次,不是当前用户审批轮次就不显示该任务
+                        if (projectInfo != null && projectInfo.getApprovalType() == 1 && dto.getSelectedType() == 1) {
                             boolean shouldDisplayTask = false; //标记是否显示当前任务
                             for (TaskParallel taskParallel : taskParallelList) {
                                 if (SecureUtil.getUserId().equals(Long.parseLong(taskParallel.getTaskUser()))) {

+ 5 - 3
blade-service/blade-archive/src/main/java/org/springblade/archive/controller/ArchivesAutoController.java

@@ -24,6 +24,7 @@ import io.swagger.annotations.*;
 import com.github.xiaoymin.knife4j.annotations.ApiOperationSupport;
 import lombok.AllArgsConstructor;
 
+import javax.servlet.ServletOutputStream;
 import javax.servlet.http.HttpServletResponse;
 import javax.validation.Valid;
 
@@ -64,6 +65,7 @@ import org.springblade.core.boot.ctrl.BladeController;
 import org.springframework.web.multipart.MultipartFile;
 
 import java.io.File;
+import java.io.IOException;
 import java.util.ArrayList;
 import java.util.Arrays;
 import java.util.List;
@@ -653,11 +655,11 @@ public class ArchivesAutoController extends BladeController {
 	/**
 	 * 批量下载档案
 	 */
-	@PostMapping(value = "/batchDownloadFileToZip", produces = {
-		MediaType.APPLICATION_OCTET_STREAM_VALUE, MediaType.APPLICATION_JSON_VALUE})
+	@GetMapping(value = "/batchDownloadFileToZip")
 	@ApiOperationSupport(order = 19)
 	@ApiOperation(value = "批量下载档案")
-	public void batchDownloadFileToZip(String ids, HttpServletResponse response) {
+	public void batchDownloadFileToZip(String ids, HttpServletResponse response) throws IOException {
+		ServletOutputStream outputStream = response.getOutputStream();
 		archivesAutoService.batchDownloadFileToZip(ids,response);
 	}
 }

+ 14 - 0
blade-service/blade-archive/src/main/java/org/springblade/archive/mapper/ArchivesAutoMapper.xml

@@ -467,6 +467,13 @@
         <if test="vo.queryValue != null and vo.queryValue != ''">
             and (uaa.name like concat('%',#{vo.queryValue},'%') or uaa.file_number like concat('%',#{vo.queryValue},'%'))
         </if>
+        <if test="vo.searchType == 1 and vo.queryList != null and vo.queryList.size > 0">
+            and (
+            <foreach collection="vo.queryList" item="query" separator="or" >
+                uaa.name like concat('%',#{query},'%')
+            </foreach>
+            )
+        </if>
         <if test="vo.projectId != null and vo.projectId != ''">
             and matc.project_id = #{vo.projectId}
         </if>
@@ -523,6 +530,13 @@
         <if test="vo.searchType == 1 and vo.queryValue != null and vo.queryValue != ''">
             and uaa.name like concat('%',#{vo.queryValue},'%')
         </if>
+        <if test="vo.searchType == 1 and vo.queryList != null and vo.queryList.size > 0">
+            and (
+            <foreach collection="vo.queryList" item="query" separator="or" >
+                uaa.name like concat('%',#{query},'%')
+            </foreach>
+            )
+        </if>
         <if test="vo.searchType == 2 and vo.queryValue != null and vo.queryValue != ''">
             and uaf.file_name like concat('%',#{vo.queryValue},'%')
         </if>

+ 26 - 26
blade-service/blade-archive/src/main/java/org/springblade/archive/service/impl/ArchiveOfflineVersionInfoServiceImpl.java

@@ -290,15 +290,15 @@ public class ArchiveOfflineVersionInfoServiceImpl extends BaseServiceImpl<Archiv
         if (list != null && list.size() > 0) {
             String localUrl = "/www/wwwroot/Users/hongchuangyanfa/Desktop/localArchive/localClient/local_archives/alilib/";
             for (ArchiveFile file : list) {
-                if (StringUtil.isNotBlank(file.getFileUrl())) {
-                    String fileUrl = file.getFileUrl();
-                    String fileName = fileUrl.substring(fileUrl.lastIndexOf('/') + 1);
-                    InputStream file_out = CommonUtil.getOSSInputStream(fileUrl);
-                    if (file_out != null) {
-                        CommonUtil.inputStreamToFile(file_out, new File(localUrl + fileName));
-                        file.setFileUrl(fileName);
-                    }
-                }
+//                if (StringUtil.isNotBlank(file.getFileUrl())) {
+//                    String fileUrl = file.getFileUrl();
+//                    String fileName = fileUrl.substring(fileUrl.lastIndexOf('/') + 1);
+//                    InputStream file_out = CommonUtil.getOSSInputStream(fileUrl);
+//                    if (file_out != null) {
+//                        CommonUtil.inputStreamToFile(file_out, new File(localUrl + fileName));
+//                        file.setFileUrl(fileName);
+//                    }
+//                }
                 if (StringUtil.isNotBlank(file.getPdfFileUrl())) {
                     String pdfFileUrl = file.getPdfFileUrl();
                     String fileName = pdfFileUrl.substring(pdfFileUrl.lastIndexOf('/') + 1);
@@ -402,23 +402,23 @@ public class ArchiveOfflineVersionInfoServiceImpl extends BaseServiceImpl<Archiv
         if (list != null && list.size() > 0) {
             String localUrl = "/www/wwwroot/Users/hongchuangyanfa/Desktop/localArchive/localClient/local_archives/alilib/";
             //拼接档案里文件的pdf设置allPdf
-            for (ArchivesAutoDTO dto : list) {
-                List<ArchiveFile> files = fileClient.getArchiveFileByArchivesId(dto.getId() + "", "");
-                if (files != null && files.size() > 0) {
-                    List<String> urlList = new ArrayList<>();
-                    for (ArchiveFile file : files) {
-                        if (StringUtil.isNotBlank(file.getPdfFileUrl())) {
-                            urlList.add(file.getPdfFileUrl());
-                        }
-                    }
-                    if (urlList.size() > 0) {
-                        Long id = SnowFlakeUtil.getId();
-                        FileUtils.mergePdfPublicMethods(urlList, localUrl + id + ".pdf");
-                        dto.setAllFilePdf(id + ".pdf");
-                    }
-                }
-
-            }
+//            for (ArchivesAutoDTO dto : list) {
+//                List<ArchiveFile> files = fileClient.getArchiveFileByArchivesId(dto.getId() + "", "");
+//                if (files != null && files.size() > 0) {
+//                    List<String> urlList = new ArrayList<>();
+//                    for (ArchiveFile file : files) {
+//                        if (StringUtil.isNotBlank(file.getPdfFileUrl())) {
+//                            urlList.add(file.getPdfFileUrl());
+//                        }
+//                    }
+//                    if (urlList.size() > 0) {
+//                        Long id = SnowFlakeUtil.getId();
+//                        FileUtils.mergePdfPublicMethods(urlList, localUrl + id + ".pdf");
+//                        dto.setAllFilePdf(id + ".pdf");
+//                    }
+//                }
+//
+//            }
             try {
                 Connection conn = data.dataSource().getConnection();
                 //清空数据

+ 35 - 3
blade-service/blade-archive/src/main/java/org/springblade/archive/service/impl/ArchivesAutoServiceImpl.java

@@ -155,6 +155,19 @@ public class ArchivesAutoServiceImpl extends BaseServiceImpl<ArchivesAutoMapper,
 		if (StringUtils.isNotBlank(vo.getCarrierType())) {
 			vo.setCarrierTypes(Arrays.asList(vo.getCarrierType().split(",")));
 		}
+		//判断是否多字段查询
+		if (StringUtils.isNotBlank(vo.getQueryValue())){
+			String queryValue = vo.getQueryValue();
+			if (queryValue.contains(",") || queryValue.contains(",")){
+				if (queryValue.contains(",")){
+					vo.setQueryList(Func.toStrList(",",queryValue));
+				}else if (queryValue.contains(",")){
+					vo.setQueryList(Func.toStrList(",",queryValue));
+				}
+				vo.setQueryValue(null);
+			}
+		}
+		//新增
 		List<ArchivesAutoVO> archivesAutos = null;
 		//获取合同段类型
 		ContractInfo contractInfo = contractClient.getContractById(vo.getContractId());
@@ -2409,19 +2422,38 @@ public class ArchivesAutoServiceImpl extends BaseServiceImpl<ArchivesAutoMapper,
 				this.packageZip2(defaultDir,projectDir,projectInfo.getId());
 				String zipFile = defaultDir + "/"+projectInfo.getId()+".zip";
 				Path path = Paths.get(zipFile);
-				response.setContentType("application/octet-stream");
-				response.setHeader("Content-Disposition", "attachment;filename="+projectInfo.getProjectName());
+				response.setContentType("application/zip");
+				response.setHeader("Content-Disposition", "attachment;filename="+projectInfo.getId()+"2.zip");
 				// 获取文件内容流并写入响应
 				Files.copy(path, response.getOutputStream());
 
 			}catch (Exception e){
 				throw new ServiceException(e.getMessage());
+			}finally {
+				//删除文件与zip文件
+				this.deleteFile(defaultDir,projectInfo.getId());
 			}
 		}
 	}
 
+	public void deleteFile(String defaultDir,Long id){
+		String dir = defaultDir+"/"+id;
+		String file = defaultDir+"/"+id+".zip";
+		// 多条命令执行
+		String[] cmds = {"/bin/sh", "-c", "cd "+defaultDir+" && rm -rf "+file +" "+ dir};
+		System.out.println("开始执行命令:" + Arrays.toString(cmds));
+		//主要在这步写入后调用命令
+		try {
+			Process process = Runtime.getRuntime().exec(cmds);
+			process.waitFor();
+		}catch (Exception e){
+			throw new ServiceException("删除时出现异常");
+		}
+	}
+
+
 	/**
-	 * 压缩指定路径下的文件夹-直接执行linux命令,多线程,速度快几十倍
+	 * 压缩指定路径下的文件夹
 	 *
 	 * @param
 	 * @throws Exception

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

@@ -1342,8 +1342,8 @@ public class TaskController extends BladeController {
                     vo.setProcessInstanceId(task.getProcessInstanceId());
                     List<TaskParallel> taskParallelList = finalTaskParallelGroupMap.get(task.getProcessInstanceId());
                     if (taskParallelList != null && taskParallelList.size() > 0) {
-                        //如果是垂直签,判断是否是当前用户审批轮次,不是当前用户审批轮次就不显示该任务
-                        if (projectInfo != null && projectInfo.getApprovalType() == 1) {
+                        //如果是垂直签,且是待办页面,判断是否是当前用户审批轮次,不是当前用户审批轮次就不显示该任务
+                        if (projectInfo != null && projectInfo.getApprovalType() == 1 && dto.getSelectedType() == 1) {
                             boolean shouldDisplayTask = false; //标记是否显示当前任务
                             for (TaskParallel taskParallel : taskParallelList) {
                                 if (SecureUtil.getUserId().equals(Long.parseLong(taskParallel.getTaskUser()))) {
@@ -1602,8 +1602,11 @@ public class TaskController extends BladeController {
     @ApiOperationSupport(order = 3)
     @ApiOperation(value = "任务管理-一键重签", notes = "传入taskIds、下拉框的contractId、projectId")
     public R<Object> reSigningEVisa(@RequestParam String taskIds, @RequestParam String contractId, @RequestParam String projectId, HttpServletRequest request) {
+        if (ObjectUtil.isEmpty(taskIds)) {
+            return R.fail("请选择一条记录");
+        }
         String header = request.getHeader("Blade-Auth");
-        taskService.reSigningEVisa(taskIds,contractId,projectId,header );
+        taskService.reSigningEVisa(taskIds, contractId, projectId, header);
         return R.success("任务已经成功提交重签,请耐心等待!");
     }
 

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

@@ -513,14 +513,46 @@ public class InformationQueryServiceImpl extends BaseServiceImpl<InformationQuer
 
         //转换VO
         if (result != null && result.size() != 0) {
+
+            //属于待审批和已审批状态,查询待办信息
+            Map<Long, Task> taskMaps = new HashMap<>();
+            Map<String, List<TaskParallel>> taskParallelMaps = new HashMap<>();
+            List<Long> informationIds = result.stream().filter(f -> f.getStatus().equals(1) || f.getStatus().equals(2)).map(InformationQuery::getId).collect(Collectors.toList());
+            String informationIdsStr = informationIds.stream().map(String::valueOf).collect(Collectors.joining(","));
+            if (StringUtils.isNotEmpty(informationIdsStr)) {
+                List<Task> query = jdbcTemplate.query("SELECT id,form_data_id,process_instance_id,approval_type,status,batch,project_id,contract_id FROM u_task WHERE form_data_id IN(" + informationIdsStr + ") AND status IN (1, 2, 3) AND is_deleted = 0", new BeanPropertyRowMapper<>(Task.class));
+                taskMaps = query.stream().collect(Collectors.toMap(Task::getId, Function.identity()));
+
+                Set<String> processInstanceIds = query.stream().map(Task::getProcessInstanceId).map(id -> "'" + id + "'").collect(Collectors.toSet());
+                if (processInstanceIds.size() > 0) {
+                    List<TaskParallel> taskParallels = jdbcTemplate.query("select task_user, task_user_name, e_visa_status, status, process_instance_id from u_task_parallel where is_deleted = 0 and process_instance_id in(" + StringUtils.join(processInstanceIds, ",") + ")", new BeanPropertyRowMapper<>(TaskParallel.class));
+                    taskParallelMaps = taskParallels.stream().collect(Collectors.groupingBy(TaskParallel::getProcessInstanceId));
+                }
+            }
+
+            //校验关联的工序节点是否全都已审批
+            List<String> sjRecordIds = result.stream().map(InformationQuery::getSjRecordIds).filter(Objects::nonNull).collect(Collectors.toList());
+            Set<Long> ids = new HashSet<>();
+            for (String sjRecordId : sjRecordIds) {
+                List<Long> longs = Func.toLongList(sjRecordId);
+                ids.addAll(longs);
+            }
+            List<InformationQuery> informationQueries = new ArrayList<>();
+            if (ids.size() > 0) {
+                informationQueries = baseMapper.selectBatchIds(ids);
+            }
+
             List<InformationQueryVO> voResult = JSONArray.parseArray(JSONObject.toJSONString(result), InformationQueryVO.class);
             //处理流程状态
+            List<InformationQuery> finalInformationQueries = informationQueries;
+            Map<Long, Task> finalTaskMaps = taskMaps;
+            Map<String, List<TaskParallel>> finalTaskParallelMaps = taskParallelMaps;
             voResult.forEach(vor -> {
                 if (ObjectUtil.isNotEmpty(vor.getCreateTime())) {
                     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()) ? "已审批" : "未上报");
+                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();
@@ -540,7 +572,7 @@ public class InformationQueryServiceImpl extends BaseServiceImpl<InformationQuer
 
                 if (Arrays.asList("1,2".split(",")).contains(vor.getStatus().toString())) {
                     //说明属于待审批和已审批状态,查询待办信息
-                    List<Task> tasks = this.taskClient.queryTaskListByFormDataId(String.valueOf(vor.getId()));
+                    /*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());
@@ -550,18 +582,37 @@ public class InformationQueryServiceImpl extends BaseServiceImpl<InformationQuer
                         }
                         //设置上报批次
                         vor.setReportNumber(String.valueOf(tasks.get(0).getBatch()));
+                    }*/
+                    Task task = finalTaskMaps.getOrDefault(vor.getId(), null);
+                    if (task != null) {
+                        //查询当前任务的所有待办人
+                        List<TaskParallel> linkTasks = finalTaskParallelMaps.getOrDefault(task.getProcessInstanceId(), null);
+                        if (linkTasks != null && linkTasks.size() > 0) {
+                            //处理审批状态
+                            this.integrationMethod(vor, linkTasks);
+                        }
+                        //设置上报批次
+                        vor.setReportNumber(String.valueOf(task.getBatch()));
                     }
                 }
 
                 //校验关联的工序节点是否全都已审批
                 if (StringUtils.isNotEmpty(vor.getSjRecordIds())) {
-                    List<InformationQuery> informationQueryList = this.baseMapper.selectBatchIds(Func.toLongList(vor.getSjRecordIds()));
+                    /*List<InformationQuery> informationQueryList = this.baseMapper.selectBatchIds(Func.toLongList(vor.getSjRecordIds()));
                     List<InformationQuery> collect = informationQueryList.stream().filter(f -> f.getStatus().equals(2)).collect(Collectors.toList());
                     if (collect.size() == informationQueryList.size()) {
                         vor.setIsApprove(true);
                     } else {
                         vor.setIsApprove(false);
-                    }
+                    }*/
+
+                    List<String> recordIdList = Func.toStrList(vor.getSjRecordIds());
+                    List<InformationQuery> informationQueryList = finalInformationQueries.stream()
+                            .filter(f -> recordIdList.contains(f.getId().toString()))
+                            .collect(Collectors.toList());
+                    boolean isApprove = informationQueryList.stream()
+                            .allMatch(f -> f.getStatus().equals(2));
+                    vor.setIsApprove(isApprove);
                 }
 
                 //试验关联文件pdf
@@ -570,7 +621,6 @@ public class InformationQueryServiceImpl extends BaseServiceImpl<InformationQuer
                 } catch (FileNotFoundException e) {
                     e.printStackTrace();
                 }
-
             });
 
             if (ObjectUtil.isEmpty(voResult)) {

+ 124 - 60
blade-service/blade-business/src/main/java/org/springblade/business/service/impl/TaskServiceImpl.java

@@ -1299,76 +1299,140 @@ public class TaskServiceImpl extends BaseServiceImpl<TaskMapper, Task> implement
         }
     }
 
+//    @Override
+//    public void reSigningEVisa(String taskIds, String contractId, String projectId,String header) {
+//        List<Task> taskList = jdbcTemplate.query("select * from u_task where id in(" + taskIds + ")", new BeanPropertyRowMapper<>(Task.class));
+//        if (taskList.size() > 0) {
+//            List<String> dataIdList = taskList.stream().map(Task::getFormDataId).filter(ObjectUtil::isNotEmpty).collect(Collectors.toList());
+//            List<InformationQuery> informationQueryList = jdbcTemplate.query("select * from u_information_query where id in(" + StringUtils.join(dataIdList, ",") + ")", new BeanPropertyRowMapper<>(InformationQuery.class));
+//            if (informationQueryList.size() > 0) {
+//                List<Long> nodePKeyIdList = informationQueryList.stream().map(InformationQuery::getWbsId).filter(ObjectUtil::isNotEmpty).collect(Collectors.toList());
+//                if (nodePKeyIdList.size() > 0) {
+//                    try {
+//                        //重新保存
+//                        long startTime_1 = System.currentTimeMillis();
+//                        R result = this.saveNodePdf(StringUtils.join(nodePKeyIdList, ","), contractId, projectId,header);
+//                        long endTime_1 = System.currentTimeMillis();
+//                        long executionTime_1 = endTime_1 - startTime_1;
+//                        log.info("saveNodePdf执行时间:" + executionTime_1 + " 毫秒");
+//
+//                        //重新电签
+//                        if (result != null && "成功".equals(result.getData())) {
+//
+//                            List<TaskApprovalVO> taskApprovalVOS = new ArrayList<>();
+//                            //获取任务详情信息Map
+//                            Set<String> processInstanceIds = taskList.stream().map(Task::getProcessInstanceId).collect(Collectors.toSet());
+//                            Map<String, List<TaskParallel>> taskParallelGroupMap = new HashMap<>();
+//                            if (processInstanceIds.size() > 0) {
+//                                String resultIds = processInstanceIds.stream()
+//                                        .map(id -> "'" + id + "'")
+//                                        .collect(Collectors.joining(","));
+//                                taskParallelGroupMap = jdbcTemplate.query("select parallel_process_instance_id,process_instance_id,e_visa_status,task_user,task_user_name,status from u_task_parallel where process_instance_id in(" + resultIds + ") order by id", new BeanPropertyRowMapper<>(TaskParallel.class)).stream().collect(Collectors.groupingBy(TaskParallel::getProcessInstanceId));
+//                            }
+//                            Map<String, List<TaskParallel>> finalTaskParallelGroupMap = taskParallelGroupMap;
+//
+//                            for (Task task : taskList) {
+//                                List<TaskParallel> taskParallelList = finalTaskParallelGroupMap.get(task.getProcessInstanceId());
+//                                for (TaskParallel taskParallel : taskParallelList) {
+//                                    //待审批的不进行重签, 存在待审批,但是电签状态是失败的
+//                                    if (!(new Integer(1)).equals(taskParallel.getStatus()) || (taskParallel.getEVisaStatus() != null && taskParallel.getEVisaStatus() == 99)) {
+//                                        TaskApprovalVO approvalVO = new TaskApprovalVO();
+//                                        approvalVO.setTaskId(task.getId().toString());
+//                                        approvalVO.setFlag("OK");
+//                                        approvalVO.setComment("重新发起电签");
+//                                        approvalVO.setApprovalType(1);
+//                                        approvalVO.setFormDataId(task.getFormDataId());
+//                                        approvalVO.setParallelProcessInstanceId(taskParallel.getParallelProcessInstanceId());
+//                                        approvalVO.setYsNickName(taskParallel.getTaskUserName());
+//                                        approvalVO.setUserId(Long.parseLong(taskParallel.getTaskUser()));
+//                                        taskApprovalVOS.add(approvalVO);
+//                                    }
+//                                }
+//                            }
+//                            long startTime_2 = System.currentTimeMillis();
+//                            this.batchCompleteApprovalTask(taskApprovalVOS);
+//                            long endTime_2 = System.currentTimeMillis();
+//                            long executionTime_2 = endTime_2 - startTime_2;
+//                            log.info("batchCompleteApprovalTask执行时间:" + executionTime_2 + " 毫秒");
+//                        } else {
+//                            throw new ServiceException("重新保存PDF信息失败");
+//                        }
+//
+//                    } catch (Exception e) {
+//                        e.printStackTrace();
+//                        throw new ServiceException("重新保存PDF信息失败,原因:" + e.getMessage());
+//                    }
+//                }
+//            }
+//        }
+//        throw new ServiceException("未获取到任务信息,操作失败!");
+//    }
+
     @Override
     public void reSigningEVisa(String taskIds, String contractId, String projectId,String header) {
-        if (ObjectUtil.isEmpty(taskIds)) {
-            throw new ServiceException("请选择至少一条任务进行重签");
-        }
+        //查询任务信息
         List<Task> taskList = jdbcTemplate.query("select * from u_task where id in(" + taskIds + ")", new BeanPropertyRowMapper<>(Task.class));
         if (taskList.size() > 0) {
+            //获取任务详情信息Map
+            Set<String> processInstanceIds = taskList.stream().map(Task::getProcessInstanceId).collect(Collectors.toSet());
+            Map<String, List<TaskParallel>> taskParallelGroupMap = new HashMap<>();
+            if (processInstanceIds.size() > 0) {
+                String resultIds = processInstanceIds.stream()
+                        .map(id -> "'" + id + "'")
+                        .collect(Collectors.joining(","));
+                taskParallelGroupMap = jdbcTemplate.query("select parallel_process_instance_id,process_instance_id,e_visa_status,task_user,task_user_name,status from u_task_parallel where process_instance_id in(" + resultIds + ") order by id", new BeanPropertyRowMapper<>(TaskParallel.class)).stream().collect(Collectors.groupingBy(TaskParallel::getProcessInstanceId));
+            }
+            Map<String, List<TaskParallel>> finalTaskParallelGroupMap = taskParallelGroupMap;
+            //获取每条任务对应的节点信息
             List<String> dataIdList = taskList.stream().map(Task::getFormDataId).filter(ObjectUtil::isNotEmpty).collect(Collectors.toList());
-            List<InformationQuery> informationQueryList = jdbcTemplate.query("select * from u_information_query where id in(" + StringUtils.join(dataIdList, ",") + ")", new BeanPropertyRowMapper<>(InformationQuery.class));
-            if (informationQueryList.size() > 0) {
-                List<Long> nodePKeyIdList = informationQueryList.stream().map(InformationQuery::getWbsId).filter(ObjectUtil::isNotEmpty).collect(Collectors.toList());
-                if (nodePKeyIdList.size() > 0) {
-                    try {
-                        //重新保存
-                        long startTime_1 = System.currentTimeMillis();
-                        R result = this.saveNodePdf(StringUtils.join(nodePKeyIdList, ","), contractId, projectId,header);
-                        long endTime_1 = System.currentTimeMillis();
-                        long executionTime_1 = endTime_1 - startTime_1;
-                        log.info("saveNodePdf执行时间:" + executionTime_1 + " 毫秒");
-
-                        //重新电签
-                        if (result != null && "成功".equals(result.getData())) {
-
-                            List<TaskApprovalVO> taskApprovalVOS = new ArrayList<>();
-                            //获取任务详情信息Map
-                            Set<String> processInstanceIds = taskList.stream().map(Task::getProcessInstanceId).collect(Collectors.toSet());
-                            Map<String, List<TaskParallel>> taskParallelGroupMap = new HashMap<>();
-                            if (processInstanceIds.size() > 0) {
-                                String resultIds = processInstanceIds.stream()
-                                        .map(id -> "'" + id + "'")
-                                        .collect(Collectors.joining(","));
-                                taskParallelGroupMap = jdbcTemplate.query("select parallel_process_instance_id,process_instance_id,e_visa_status,task_user,task_user_name,status from u_task_parallel where process_instance_id in(" + resultIds + ") order by id", new BeanPropertyRowMapper<>(TaskParallel.class)).stream().collect(Collectors.groupingBy(TaskParallel::getProcessInstanceId));
-                            }
-                            Map<String, List<TaskParallel>> finalTaskParallelGroupMap = taskParallelGroupMap;
-
-                            for (Task task : taskList) {
-                                List<TaskParallel> taskParallelList = finalTaskParallelGroupMap.get(task.getProcessInstanceId());
-                                for (TaskParallel taskParallel : taskParallelList) {
-                                    //待审批的不进行重签, 存在待审批,但是电签状态是失败的
-                                    if (!(new Integer(1)).equals(taskParallel.getStatus()) || (taskParallel.getEVisaStatus() != null && taskParallel.getEVisaStatus() == 99)) {
-                                        TaskApprovalVO approvalVO = new TaskApprovalVO();
-                                        approvalVO.setTaskId(task.getId().toString());
-                                        approvalVO.setFlag("OK");
-                                        approvalVO.setComment("重新发起电签");
-                                        approvalVO.setApprovalType(1);
-                                        approvalVO.setFormDataId(task.getFormDataId());
-                                        approvalVO.setParallelProcessInstanceId(taskParallel.getParallelProcessInstanceId());
-                                        approvalVO.setYsNickName(taskParallel.getTaskUserName());
-                                        approvalVO.setUserId(Long.parseLong(taskParallel.getTaskUser()));
-                                        taskApprovalVOS.add(approvalVO);
-                                    }
-                                }
+            Map<String, String> queryMap = jdbcTemplate.query("select * from u_information_query where id in(" + StringUtils.join(dataIdList, ",") + ")", new BeanPropertyRowMapper<>(InformationQuery.class)).stream().collect(Collectors.toMap(l -> l.getId()+"", l -> l.getWbsId()+""));
+            try {
+                for (Task task : taskList) {
+                    //重新保存
+                    long startTime_1 = System.currentTimeMillis();
+                    R result = this.saveNodePdf(queryMap.get(task.getFormDataId()), contractId, projectId, header);
+                    long endTime_1 = System.currentTimeMillis();
+                    long executionTime_1 = endTime_1 - startTime_1;
+                    log.info("saveNodePdf执行时间:" + executionTime_1 + " 毫秒");
+
+                    //重新电签
+                    if (result != null && "成功".equals(result.getData())) {
+                        List<TaskApprovalVO> taskApprovalVOS = new ArrayList<>();
+                        List<TaskParallel> taskParallelList = finalTaskParallelGroupMap.get(task.getProcessInstanceId());
+                        for (TaskParallel taskParallel : taskParallelList) {
+                            //待审批的不进行重签, 存在待审批,但是电签状态是失败的
+                            if (!(new Integer(1)).equals(taskParallel.getStatus()) || (taskParallel.getEVisaStatus() != null && taskParallel.getEVisaStatus() == 99)) {
+                                TaskApprovalVO approvalVO = new TaskApprovalVO();
+                                approvalVO.setTaskId(task.getId().toString());
+                                approvalVO.setFlag("OK");
+                                approvalVO.setComment("重新发起电签");
+                                approvalVO.setApprovalType(1);
+                                approvalVO.setFormDataId(task.getFormDataId());
+                                approvalVO.setParallelProcessInstanceId(taskParallel.getParallelProcessInstanceId());
+                                approvalVO.setYsNickName(taskParallel.getTaskUserName());
+                                approvalVO.setUserId(Long.parseLong(taskParallel.getTaskUser()));
+                                taskApprovalVOS.add(approvalVO);
                             }
-                            long startTime_2 = System.currentTimeMillis();
-                            this.batchCompleteApprovalTask(taskApprovalVOS);
-                            long endTime_2 = System.currentTimeMillis();
-                            long executionTime_2 = endTime_2 - startTime_2;
-                            log.info("batchCompleteApprovalTask执行时间:" + executionTime_2 + " 毫秒");
-
-                            throw new ServiceException("任务已经成功提交重签,请耐心等待!");
-                        } else {
-                            throw new ServiceException("重新保存PDF信息失败");
                         }
-
-                    } catch (Exception e) {
-                        e.printStackTrace();
-                        throw new ServiceException("重新保存PDF信息失败,原因:" + e.getMessage());
+                        long startTime_2 = System.currentTimeMillis();
+                        this.batchCompleteApprovalTask(taskApprovalVOS);
+                        long endTime_2 = System.currentTimeMillis();
+                        long executionTime_2 = endTime_2 - startTime_2;
+                        log.info("batchCompleteApprovalTask执行时间:" + executionTime_2 + " 毫秒");
+                    } else {
+                        //修改重签状态为保存PDF失败
+                        this.taskParallelService.update(Wrappers.<TaskParallel>lambdaUpdate()
+                                .set(TaskParallel::getEVisaContent, "重新保存PDF失败")
+                                .eq(TaskParallel::getProcessInstanceId, task.getProcessInstanceId())
+                                .eq(TaskParallel::getEVisaStatus,"99"));
                     }
                 }
+
+            } catch (Exception e) {
+                e.printStackTrace();
+                throw new ServiceException("重新保存PDF信息失败,原因:" + e.getMessage());
             }
+
         }
         throw new ServiceException("未获取到任务信息,操作失败!");
     }

+ 12 - 3
blade-service/blade-manager/src/main/java/com/mixsmart/utils/FormulaUtils.java

@@ -848,10 +848,19 @@ public static Map<String,List<Long>> relatedPages(List<FormData> curFormDatas ,L
   }
 
 /*    public static void main(String[] args) {
-        *//*String s="003000004001000003";*//*
-        String s="00300";
-        treeCodeSplit(s).forEach(System.out::println);
+
+        System.out.println(milestone("k8+120.23"));
+
     }*/
 
+    public static  Double milestone(String s){
+        Pattern pattern=Pattern.compile("(?i)K(\\d+)\\+([\\d.]+)");
+        Matcher matcher = pattern.matcher(s);
+        if(matcher.find()){
+           return   Double.parseDouble(matcher.group(1))*1000+ Double.parseDouble(matcher.group(2));
+        }
+        return null;
+    }
+
 
 }

+ 63 - 35
blade-service/blade-manager/src/main/java/org/springblade/manager/controller/ExcelTabController.java

@@ -24,6 +24,7 @@ import org.apache.poi.ss.usermodel.WorkbookFactory;
 import org.jsoup.Jsoup;
 import org.jsoup.nodes.Document;
 import org.jsoup.nodes.Element;
+import org.jsoup.nodes.Node;
 import org.jsoup.select.Elements;
 import org.springblade.business.entity.ContractLog;
 import org.springblade.business.entity.InformationQuery;
@@ -2408,11 +2409,35 @@ public class ExcelTabController extends BladeController {
                                                 pic.setHeight(Height);
                                                 sheet.getCellRange(y1, x1).getStyle().setShrinkToFit(true);
 
-                                            } else if (myData.equals("1") && data.html().indexOf("hc-form-checkbox-group") >= 0) {
-                                                CellRange cell = sheet.getCellRange(y1, x1);
-                                                String exceVal = cell.getText().replaceAll(" ", "");
-                                                cell.getCellStyle().getExcelFont().setFontName("EUDC");
-                                                cell.setText(exceVal.replace("□", "\u2611"));
+                                            } else if (data.html().indexOf("hc-form-checkbox-group") >= 0) {
+                                                 CellRange cellRange = sheet.getCellRange(y1, x1);
+                                                 String exceVal = cellRange.getValue().replaceAll(" ", "");
+                                                //如果有□ 代表 自动生成  如果没有 代表后期添加 需要显示html 中的值
+                                                if (exceVal.indexOf("□") >= 0) {
+                                                    if (myData.equals("1")) {
+                                                        cellRange.setValue(exceVal.replace("□", "\u2611"));
+                                                    }
+                                                } else {
+                                                    List<Node> nodes = data.childNodes();
+                                                    Node node = nodes.get(nodes.size() -1);
+                                                    String dataJson = node.attr(":objs");
+                                                    if (StringUtils.isNotEmpty(dataJson)) {
+                                                        JSONArray jsonArray = JSONArray.parseArray(dataJson);
+                                                        List<Integer> idList = Func.toIntList(myData);
+                                                        int indexx = 0;
+                                                        if (idList.get(0) >= 1) {
+                                                            indexx = idList.get(0) - 1;
+                                                        }
+
+                                                        String dataInfo = jsonArray.getJSONObject(indexx).getString("name");
+                                                        for (int inx = 1; inx < idList.size(); inx++) {
+                                                            int valIndex = idList.get(inx) - 1;
+                                                            dataInfo = dataInfo + "," + jsonArray.getJSONObject(valIndex).getString("name");
+                                                        }
+                                                        cellRange.setValue(dataInfo);
+                                                    }
+
+                                                }
                                             } else {
                                                 final CellRange cellRange = sheet.getCellRange(y1, x1);
                                                 cellRange.setText(myData);
@@ -3884,7 +3909,7 @@ public class ExcelTabController extends BladeController {
             @ApiImplicitParam(name = "classify", value = "classify", required = true),
             @ApiImplicitParam(name = "projectId", value = "projectId", required = true)
     })
-    public R synPDFInfo(String contractId,String nodeIds, String classify, String projectId) throws Exception {
+    public R synPDFInfo(String contractId,String nodeIds, String classify, String projectId) {
 
         if( contractId==null && StringUtils.isEmpty(contractId)){
             return R.data("contractId不能为空");
@@ -3903,38 +3928,41 @@ public class ExcelTabController extends BladeController {
         }
 
         String nodeId[] = Func.toStrArray(nodeIds);
-
-        for(String noId : nodeId){
-            JSONObject js = new JSONObject();
-            JSONObject js2 = new JSONObject();
-            List<AppWbsTreeContractVO> tableAll = wbsTreeContractService.searchNodeAllTable(noId, classify, contractId, projectId);
-            JSONArray array = new JSONArray();
-            if(tableAll!=null && tableAll.size()>=1){
-                for(AppWbsTreeContractVO tab:tableAll){
-                    try {
-                        R bussDataInfo = excelTabService.getBussDataInfo(tab.getPKeyId(), 0);
-                        Map<String, Object> jo = (Map<String, Object>) bussDataInfo.getData();
-                        String s = new Gson().toJson(jo);
-                        //字符串转jsonobject
-                        JSONObject obj = JSON.parseObject(s);
-                        obj.put("classify",classify);
-                        obj.put("nodeId",noId);
-                        obj.put("contractId",contractId);
-                        obj.put("pkeyId",tab.getPKeyId());
-                        obj.put("projectId",projectId);
-                        obj.put("isCollapseLoad",true);
-                        obj.put("isRenderForm",true);
-                        array.add(obj);
-                    }catch (Exception e){
-                        e.printStackTrace();
-                    }finally {
-                        continue;
+        try {
+            for (String noId : nodeId) {
+                JSONObject js = new JSONObject();
+                JSONObject js2 = new JSONObject();
+                List<AppWbsTreeContractVO> tableAll = wbsTreeContractService.searchNodeAllTable(noId, classify, contractId, projectId);
+                JSONArray array = new JSONArray();
+                if (tableAll != null && tableAll.size() >= 1) {
+                    for (AppWbsTreeContractVO tab : tableAll) {
+                        try {
+                            R bussDataInfo = excelTabService.getBussDataInfo(tab.getPKeyId(), 0);
+                            Map<String, Object> jo = (Map<String, Object>) bussDataInfo.getData();
+                            String s = new Gson().toJson(jo);
+                            //字符串转jsonobject
+                            JSONObject obj = JSON.parseObject(s);
+                            obj.put("classify", classify);
+                            obj.put("nodeId", noId);
+                            obj.put("contractId", contractId);
+                            obj.put("pkeyId", tab.getPKeyId());
+                            obj.put("projectId", projectId);
+                            obj.put("isCollapseLoad", true);
+                            obj.put("isRenderForm", true);
+                            array.add(obj);
+                        } catch (Exception e) {
+                            e.printStackTrace();
+                        } finally {
+                            continue;
+                        }
                     }
                 }
+                js2.put("orderList", array);
+                js.put("dataInfo", js2);
+                this.saveBussData2(js);
             }
-            js2.put("orderList",array);
-            js.put("dataInfo",js2);
-            this.saveBussData2(js);
+        }catch (Exception e){
+            return null;
         }
         return R.data("成功");
     }

+ 54 - 7
blade-service/blade-manager/src/main/java/org/springblade/manager/formula/ITurnPointCalculator.java

@@ -27,8 +27,6 @@ public interface ITurnPointCalculator {
         if (Func.isNotEmpty(data) && configMap != null) {
             /*重置*/
             levelInfo.reset();
-         /*   LevelInfo levelInfo = new LevelInfo();
-            levelInfo.setDx(g8pcfw);*/
             List<TurnPoint> tmp = new ArrayList<>();
             /*是否尝试初步补充数据*/
             boolean checked=true;
@@ -72,7 +70,6 @@ public interface ITurnPointCalculator {
         return Collections.emptyList();
     }
 
-
     /**判断是否保留原来的转点*/
     static boolean persist(List<TurnPoint> list){
         /*在补充计算之前进行完整性校验,如果成功则不会再生成任何新转点*/
@@ -254,6 +251,13 @@ public interface ITurnPointCalculator {
                     } else if (tp.getType().equals(TurnPoint.BMD)) {
                         /*水准点处理*/
                         tpHandlerBmd(tp);
+                         Double  milestone= info.getBmMap().get(tp.getName().trim());
+                         if(milestone!=null) {
+                             /*如果水准点包含里程信息就会启动距离计算转点 200米一个点,配合高差按多的那个算*/
+                             info.setDistance(true);
+                             /*设置初始里程*/
+                             info.setMilestone(milestone);
+                         }
                     }
                     /*把数据放到输出缓存*/
                     putCache(tp);
@@ -271,7 +275,6 @@ public interface ITurnPointCalculator {
         return Collections.emptyList();
     }
 
-
     static void tpHandlerBmd(TurnPoint tp){
         TurnPoint st = new TurnPoint(tp.getLevelInfo(), new HashMap<>());
         st.setBmd(tp.getBmd());
@@ -352,13 +355,57 @@ public interface ITurnPointCalculator {
             if (!tp.isVisible(negative)) {
                 result.addAll(tp.limit(negative));
             }
+            double x=tp.tooFar();
+            if(x>0){
+               /*距离超过两百米需要转点*/
+                List<TurnPoint>   closeZd=  info.getCloseZd();
+                TurnPoint last = closeZd.get(closeZd.size()-1);
+                 int n = (int)Math.ceil(x/200);
+                List<TurnPoint> list = new ArrayList<>();
+                for(int i=0;i<n;i++){
+                     TurnPoint zd = new TurnPoint(info, new HashMap<>());
+                     zd.setName("ZD"+closeZd.size());
+                     double dx = Math.random() * 0.07 * (RD.nextBoolean() ? -1 : 1);
+                     zd.setBmd(StringUtils.number2StringZero(Double.parseDouble(last.getBmd()) + dx, 3));
+                    double ddx = info.getSightHeight() - zd.getBmd0L();
+                    double xx = Math.abs(ddx);
+                    double small = BigDecimal.valueOf(r.nextDouble() * (info.getStep() - info.getMin() - xx) + info.getMin()).setScale(info.getScale(), ROUND_HALF_UP).doubleValue();
+                    double big = small + xx;
+                    if (ddx < 0) {
+                        /*后大前小,取高*/
+                        zd.setQ(small);
+                        zd.setH(big);
+                    } else {
+                        /*前大后小,趋低*/
+                        zd.setQ(big);
+                        zd.setH(small);
+                    }
+                    info.setSightHeight(zd.getBmd0L());
+                    zd.getDataMap().put(CD, zd.getName());
+                    zd.getDataMap().put(YG, zd.getBmd());
+                    zd.getDataMap().put(QS, zd.getQ());
+                    zd.getDataMap().put(HS, zd.getH());
+                    if(i==n-1) {
+                        /*最后一个重新计算前视,因为是微调所以不再判断高差是否在范围*/
+                        tp.setQ(info.getSightHeight() - tp.getSc0L());
+                    }
+                    closeZd.add(zd.clone());
+                    /*设置当前里程*/
+                    if(info.isDistance()) {
+                        /*没转一次点相当于往前推进两百米*/
+                        info.setMilestone(info.getMilestone()+200);
+                    }
+                    list.add(zd);
+                }
+                if(list.size()>0){
+                    result.addAll(list);
+                }
+            }
+
         }
 
     }
 
-
-
-
     /**验证当前测点数据的合理性*/
     static boolean finalizeCe(TurnPoint tp){
         if(Func.isNotBlank(tp.getSc())&&Func.isNotBlank(tp.getSj())&&Func.isNotBlank(tp.getQ())&&Func.isNotBlank(tp.getDx())){

+ 21 - 3
blade-service/blade-manager/src/main/java/org/springblade/manager/formula/LevelInfo.java

@@ -1,8 +1,6 @@
 package org.springblade.manager.formula;
 
-import java.util.ArrayList;
-import java.util.Arrays;
-import java.util.List;
+import java.util.*;
 
 /**
  * @author yangyj
@@ -58,6 +56,10 @@ public class LevelInfo implements  Cloneable {
     private boolean persist=false;
     /**是否开启距离转点模式,宝北项目隧道一个仪高点只能测量两百米范围的测点,超过就必须进行转点,所有需要配合桩号距离判断*/
     private boolean distance=false;
+    /**当前里程*/
+    private Double milestone;
+    /**测站点信息*/
+    private Map<String,Double> BmMap =new HashMap<>();
 
     public Double getBmdSj() {
         return bmdSj;
@@ -187,4 +189,20 @@ public class LevelInfo implements  Cloneable {
     public void setDistance(boolean distance) {
         this.distance = distance;
     }
+
+    public Map<String, Double> getBmMap() {
+        return BmMap;
+    }
+
+    public void setBmMap(Map<String, Double> bmMap) {
+        BmMap = bmMap;
+    }
+
+    public Double getMilestone() {
+        return milestone;
+    }
+
+    public void setMilestone(Double milestone) {
+        this.milestone = milestone;
+    }
 }

+ 39 - 5
blade-service/blade-manager/src/main/java/org/springblade/manager/formula/TurnPoint.java

@@ -85,6 +85,8 @@ public class TurnPoint {
 
     /**是否有效*/
     private int isDeleted=0;
+    /**转点和闭合转点是点对点成对的*/
+    private TurnPoint peer;
 
 
     public TurnPoint(LevelInfo levelInfo, Map<String, Object> dataMap) {
@@ -241,7 +243,15 @@ public class TurnPoint {
         if(negative){
             d=  Math.abs(d);
         }
-        return d >= levelInfo.getMin() && d <= levelInfo.getStep()&&levelInfo.getSightHeight()-getQ0L()==getSc0L();
+        if(d >= levelInfo.getMin() && d <= levelInfo.getStep()){
+            if(levelInfo.getSightHeight()-getQ0L()!=getSc0L()){
+                /*微调修复前视*/
+                setQ(levelInfo.getSightHeight()-getSc0L());
+            }
+            return true;
+        }
+        return false;
+
     }
     /**判断转点前后视是否在范围*/
     public boolean isWithinRangeValueZd(String any){
@@ -287,9 +297,7 @@ public class TurnPoint {
     /**转点的核心处理算法,当测点不在测量范围会触发*/
     public List<TurnPoint> limit(Boolean negative) {
         List<TurnPoint> result = new ArrayList<>();
-        /*double step = levelInfo.getStep();*/
         /*负前视必须是表单传入,而非自动生成*/
-        /*boolean fake=(!negative&&getQ0L()<0);*/
         boolean overRange=(!negative&&getQ0L()<levelInfo.getMin()) || getQ0L() > levelInfo.getStep();
         if(StringUtils.isEmpty(getQ())||overRange){
             double q = (double) (r.nextInt(3000) + 500) / 1000;
@@ -311,6 +319,11 @@ public class TurnPoint {
             }
             result.add(tmp);
             levelInfo.getCloseZd().add(tmp.clone());
+            /*设置当前里程*/
+            if(levelInfo.isDistance()) {
+                /*没转一次点相当于往前推进两百米*/
+                levelInfo.setMilestone(levelInfo.getMilestone()+200);
+            }
             loop++;
         } while (hd > 0 && loop < 20);
         return result;
@@ -367,12 +380,13 @@ public class TurnPoint {
         }
     }
 
-    @Override
-    public TurnPoint clone() {
+    public TurnPoint clone()   {
         TurnPoint t = new TurnPoint();
         t.setName("ZD" + (this.levelInfo.getCloseZd().size() + 1));
         BeanUtils.copyProperties(this, t);
         t.setDataMap(new HashMap<>(20));
+        this.peer=t;
+        t.setPeer(this);
         return t;
     }
 
@@ -430,4 +444,24 @@ public class TurnPoint {
     public void setIsDeleted(int isDeleted) {
         this.isDeleted = isDeleted;
     }
+    public double tooFar(){
+        if(this.levelInfo.isDistance()){
+            Double x= BaseUtils.milestone(this.name);
+            if(x!=null) {
+                double a=  x-this.levelInfo.getMilestone();
+                if(a>=200){
+                   return a;
+                }
+            }
+        }
+        return 0;
+    }
+
+    public TurnPoint getPeer() {
+        return peer;
+    }
+
+    public void setPeer(TurnPoint peer) {
+        this.peer = peer;
+    }
 }

+ 19 - 0
blade-service/blade-manager/src/main/java/org/springblade/manager/formula/impl/FormulaTurnPoint.java

@@ -13,8 +13,10 @@ import org.springblade.manager.dto.ElementData;
 import org.springblade.manager.dto.FormData;
 import org.springblade.manager.entity.Formula;
 import org.springblade.manager.formula.*;
+import org.springframework.beans.factory.annotation.Autowired;
 import org.springframework.context.annotation.Scope;
 import org.springframework.context.annotation.ScopedProxyMode;
+import org.springframework.jdbc.core.JdbcTemplate;
 import org.springframework.stereotype.Component;
 import org.springframework.web.context.WebApplicationContext;
 
@@ -38,6 +40,8 @@ public class FormulaTurnPoint implements FormulaStrategy {
     /**从节点参数获取G8偏差范围的公式脚本*/
     static final String F_DEV="WP['g8pcfw']";
 
+    private final JdbcTemplate jdbcTemplate;
+
     static {
         KEYS = new ArrayList<>(Arrays.asList(CD, YG, HS, QS, SC, SJ, GC, "备注"));
     }
@@ -83,6 +87,8 @@ public class FormulaTurnPoint implements FormulaStrategy {
                 info.setStep(4.6D);
                 info.setMin(0.4D);
             }
+            /*获取水准点里程*/
+            milestone(tec.getContractId(),info);
            /* 分组计算*/
             List<List<TurnPoint>> result = total.stream().map(e->ITurnPointCalculator.create(e,configMap,info)).collect(Collectors.toList());
             /*附加属性如:顶面和底面高程判断*/
@@ -95,6 +101,18 @@ public class FormulaTurnPoint implements FormulaStrategy {
         }
     }
 
+    public void milestone(Long contractId,LevelInfo info){
+        List<Map<String,Object>> listMaps= this.jdbcTemplate.queryForList("select name,milestone from t_om_datum_point where contract_id ="+contractId);
+        if(listMaps.size()>0){
+            Map<String,Double> bmMap = info.getBmMap();
+            listMaps.stream().filter(e->StringUtils.isNotEmpty(e.get("milestone"))).forEach(e->{
+                Double x=FormulaUtils.milestone(e.get("milestone").toString());
+                if(x!=null) {
+                    bmMap.put(e.get("name").toString().trim(),x);
+                }
+            });
+        }
+    }
 
     public List<Object> paginate( FormData cur,List<List<TurnPoint>> result,LinkedHashMap<String, String> configMap){
         int rowSize= cur.getCoordsList().size();
@@ -282,4 +300,5 @@ public class FormulaTurnPoint implements FormulaStrategy {
     }
 
 
+
 }

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

@@ -2,6 +2,7 @@ package org.springblade.manager.service;
 
 import org.jsoup.nodes.Document;
 import org.springblade.core.mp.base.BaseService;
+import org.springblade.core.tool.api.R;
 import org.springblade.manager.dto.FormData;
 import org.springblade.manager.entity.Formula;
 import org.springblade.manager.entity.WbsInfo;
@@ -110,5 +111,6 @@ public interface IFormulaService extends BaseService<Formula> {
     /**表单数据加载的时候执行节点参数*/
     void paramFormula(WbsTreeContract wbsTreeContract, Map<String, Object> result, Document document);
 
-
+    /**表单数据加载的时候执行节点参数*/
+    R<Object> pd(Long pkeyId);
 }

+ 29 - 3
blade-service/blade-manager/src/main/java/org/springblade/manager/service/impl/ContractInfoServiceImpl.java

@@ -353,8 +353,21 @@ public class ContractInfoServiceImpl extends BaseServiceImpl<ContractInfoMapper,
                         if (data != null) {
                             nodesAllTemp = JSON.parseArray(data.toString(), WbsTreeContractLazyVO.class);
                         } else {
-                            nodesAllTemp = jdbcTemplate.query("select a.p_key_id,a.id,a.parent_id,(SELECT CASE WHEN count(1) > 0 THEN 1 ELSE 0 END FROM m_wbs_tree_contract b WHERE b.parent_id = a.id AND type = 1 AND b.contract_id = " + contractId + " AND b.is_deleted = 0 ) AS hasChildren from m_wbs_tree_contract a where type = 1 and status = 1 and is_deleted = 0 and contract_id = " + contractId, new BeanPropertyRowMapper<>(WbsTreeContractLazyVO.class));
+                            nodesAllTemp = jdbcTemplate.query("select a.p_key_id,a.id,a.parent_id from m_wbs_tree_contract a where a.type = 1 and a.status = 1 and a.is_deleted = 0 and a.contract_id = " + contractId, new BeanPropertyRowMapper<>(WbsTreeContractLazyVO.class));
                             if (nodesAllTemp.size() > 0) {
+                                //判断是否有子级,赋值
+                                Map<Long, List<WbsTreeContractLazyVO>> groupedByParentId = nodesAllTemp.stream().collect(Collectors.groupingBy(WbsTreeContractLazyVO::getParentId));
+                                for (WbsTreeContractLazyVO vo : nodesAllTemp) {
+                                    if (vo.getParentId() == 0) {
+                                        vo.setHasChildren(1);
+                                    }
+                                    List<WbsTreeContractLazyVO> childNodes = groupedByParentId.getOrDefault(vo.getId(), null);
+                                    if (childNodes != null && childNodes.size() > 0) {
+                                        vo.setHasChildren(1);
+                                    } else {
+                                        vo.setHasChildren(0);
+                                    }
+                                }
                                 JSONArray array = JSONArray.parseArray(JSON.toJSONString(nodesAllTemp));
                                 redisTemplate.opsForValue().set("blade-manager::contract:wbstree:" + contractId, JSON.toJSON(array).toString());
                             }
@@ -490,10 +503,23 @@ public class ContractInfoServiceImpl extends BaseServiceImpl<ContractInfoMapper,
                             if (data != null) {
                                 nodesAllTemp = JSON.parseArray(data.toString(), WbsTreeContractLazyVO.class);
                             } else {
-                                nodesAllTemp = jdbcTemplate.query("select a.p_key_id,a.id,a.parent_id,(SELECT CASE WHEN count(1) > 0 THEN 1 ELSE 0 END FROM m_wbs_tree_contract b WHERE b.parent_id = a.id AND type = 1 AND b.contract_id = " + contractRelationJlyz.getContractIdSg() + " AND b.is_deleted = 0 ) AS hasChildren from m_wbs_tree_contract a where type = 1 and status = 1 and is_deleted = 0 and contract_id = " + contractRelationJlyz.getContractIdSg(), new BeanPropertyRowMapper<>(WbsTreeContractLazyVO.class));
+                                nodesAllTemp = jdbcTemplate.query("select a.p_key_id,a.id,a.parent_id from m_wbs_tree_contract a where a.type = 1 and a.status = 1 and a.is_deleted = 0 and a.contract_id = " + contractRelationJlyz.getContractIdSg(), new BeanPropertyRowMapper<>(WbsTreeContractLazyVO.class));
                                 if (nodesAllTemp.size() > 0) {
+                                    //判断是否有子级,赋值
+                                    Map<Long, List<WbsTreeContractLazyVO>> groupedByParentId = nodesAllTemp.stream().collect(Collectors.groupingBy(WbsTreeContractLazyVO::getParentId));
+                                    for (WbsTreeContractLazyVO vo : nodesAllTemp) {
+                                        if (vo.getParentId() == 0) {
+                                            vo.setHasChildren(1);
+                                        }
+                                        List<WbsTreeContractLazyVO> childNodes = groupedByParentId.getOrDefault(vo.getId(), null);
+                                        if (childNodes != null && childNodes.size() > 0) {
+                                            vo.setHasChildren(1);
+                                        } else {
+                                            vo.setHasChildren(0);
+                                        }
+                                    }
                                     JSONArray array = JSONArray.parseArray(JSON.toJSONString(nodesAllTemp));
-                                    redisTemplate.opsForValue().set("blade-manager::contract:wbstree:" + contractId, JSON.toJSON(array).toString());
+                                    redisTemplate.opsForValue().set("blade-manager::contract:wbstree:" + contractRelationJlyz.getContractIdSg(), JSON.toJSON(array).toString());
                                 }
                             }
 

+ 22 - 17
blade-service/blade-manager/src/main/java/org/springblade/manager/service/impl/ExcelTabServiceImpl.java

@@ -542,6 +542,9 @@ public class ExcelTabServiceImpl extends BaseServiceImpl<ExcelTabMapper, ExcelTa
                 currentNode.setWbsId(Long.parseLong(publicWtp.getWbsId()));
                 currentNode.setWtpPkeyId(wtp.getPKeyId());
                 currentNode.setWbsNodeId(publicWtp.getId());
+                if(Func.isNotBlank(wtc.getTreeCode())){
+                    currentNode.getTreeCode().addAll(FormulaUtils.treeCodeSplit(wtc.getTreeCode()));
+                }
                 return currentNode;
             }
         }
@@ -1695,23 +1698,25 @@ public class ExcelTabServiceImpl extends BaseServiceImpl<ExcelTabMapper, ExcelTa
                             if ((myData.indexOf("https") >= 0 || myData.indexOf("http") >= 0) && myData.indexOf("aliyuncs") >= 0) {
 
                                 InputStream imageIn = CommonUtil.getOSSInputStream(myData);
-                                byte[] byteNew = IOUtils.toByteArray(imageIn);
-                                byte[] bytes = CommonUtil.compressImage(byteNew);
-                                // 这里根据实际需求选择图片类型
-                                int pictureIdx = workbook.addPicture(bytes, 6);
-                                CreationHelper helper = workbook.getCreationHelper();
-                                ClientAnchor anchor = helper.createClientAnchor();
-                                anchor.setCol1(x1); // param1是列号
-                                anchor.setCol2(x2);
-                                anchor.setRow1(y1); // param2是行号
-                                anchor.setRow2(y2); // param2是行号
-                                //
-                                Drawing drawing = sheet.createDrawingPatriarch();
-                                anchor.setAnchorType(ClientAnchor.AnchorType.MOVE_AND_RESIZE);
-                                // 插入图片
-                                Picture pict = drawing.createPicture(anchor, pictureIdx); // 调整图片占单元格百分比的大小,1.0就是100%
-                                pict.resize(1, 1);
-                                FileUtils.imageOrientation(sheet, anchor, new DataVO(x1 - 1, y1 - 1));
+                                if(imageIn!=null) {
+                                    byte[] byteNew = IOUtils.toByteArray(imageIn);
+                                    byte[] bytes = CommonUtil.compressImage(byteNew);
+                                    // 这里根据实际需求选择图片类型
+                                    int pictureIdx = workbook.addPicture(bytes, 6);
+                                    CreationHelper helper = workbook.getCreationHelper();
+                                    ClientAnchor anchor = helper.createClientAnchor();
+                                    anchor.setCol1(x1); // param1是列号
+                                    anchor.setCol2(x2);
+                                    anchor.setRow1(y1); // param2是行号
+                                    anchor.setRow2(y2); // param2是行号
+                                    //
+                                    Drawing drawing = sheet.createDrawingPatriarch();
+                                    anchor.setAnchorType(ClientAnchor.AnchorType.MOVE_AND_RESIZE);
+                                    // 插入图片
+                                    Picture pict = drawing.createPicture(anchor, pictureIdx); // 调整图片占单元格百分比的大小,1.0就是100%
+                                    pict.resize(1, 1);
+                                    FileUtils.imageOrientation(sheet, anchor, new DataVO(x1 - 1, y1 - 1));
+                                }
 
                             } else if (data.tagName().equals("hc-form-checkbox-group")) {
                                 Row row = sheet.getRow(y1 - 1);

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

@@ -2357,7 +2357,18 @@ public class FormulaServiceImpl extends BaseServiceImpl<FormulaMapper, Formula>
         }
     }
 
-
+    @Override
+    public R<Object> pd(Long pkeyId) {
+        if(StringUtils.isNumber(pkeyId)) {
+            WbsTreeContract wtc= this.getSqlOne("select tree_code treeCode,contract_id from m_wbs_tree_contract where p_key_id =" + pkeyId,WbsTreeContract.class);
+            LinkedList<String> treeCode = new LinkedList<>(FormulaUtils.treeCodeSplit(wtc.getTreeCode()));
+            List<FormulaDataBlock> formulaDataBlocks = this.getSqlList("select a.* from m_formula_data_block a join (select parent_id from m_wbs_tree_contract where tree_code like '"+treeCode.getLast()+"%' and contract_id ="+wtc.getContractId()+" and major_data_type=2 and is_deleted=0 ORDER BY tree_code)b on a.sw_id=b.parent_id ",FormulaDataBlock.class);
+            if(formulaDataBlocks.size()>0){
+                return R.data(formulaDataBlocks);
+            }
+        }
+        return R.fail("无数据");
+    }
 
 }
 

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

@@ -98,6 +98,7 @@ public class WbsParamServiceImpl extends BaseServiceImpl<WbsParamMapper, WbsPara
                         parentId=t.getParentId();
                     }
                 }
+                Collections.reverse(list);
                 list.add(one);
             }else {
                 list.add(one);

+ 69 - 4
blade-service/blade-manager/src/main/java/org/springblade/manager/service/impl/WbsTreeContractServiceImpl.java

@@ -690,8 +690,21 @@ public class WbsTreeContractServiceImpl extends BaseServiceImpl<WbsTreeContractM
                     if (data != null) {
                         nodesAll = JSON.parseArray(data.toString(), WbsTreeContractLazyVO.class);
                     } else {
-                        nodesAll = jdbcTemplate.query("select a.p_key_id,a.id,a.parent_id,(SELECT CASE WHEN count(1) > 0 THEN 1 ELSE 0 END FROM m_wbs_tree_contract b WHERE b.parent_id = a.id AND type = 1 AND b.contract_id = " + contractId + " AND b.is_deleted = 0 ) AS hasChildren from m_wbs_tree_contract a where type = 1 and status = 1 and is_deleted = 0 and contract_id = " + contractId, new BeanPropertyRowMapper<>(WbsTreeContractLazyVO.class));
+                        nodesAll = jdbcTemplate.query("select a.p_key_id,a.id,a.parent_id from m_wbs_tree_contract a where a.type = 1 and a.status = 1 and a.is_deleted = 0 and a.contract_id = " + contractId, new BeanPropertyRowMapper<>(WbsTreeContractLazyVO.class));
                         if (nodesAll.size() > 0) {
+                            //判断是否有子级,赋值
+                            Map<Long, List<WbsTreeContractLazyVO>> groupedByParentId = nodesAll.stream().collect(Collectors.groupingBy(WbsTreeContractLazyVO::getParentId));
+                            for (WbsTreeContractLazyVO vo : nodesAll) {
+                                if (vo.getParentId() == 0) {
+                                    vo.setHasChildren(1);
+                                }
+                                List<WbsTreeContractLazyVO> childNodes = groupedByParentId.getOrDefault(vo.getId(), null);
+                                if (childNodes != null && childNodes.size() > 0) {
+                                    vo.setHasChildren(1);
+                                } else {
+                                    vo.setHasChildren(0);
+                                }
+                            }
                             JSONArray array = JSONArray.parseArray(JSON.toJSONString(nodesAll));
                             redisTemplate.opsForValue().set("blade-manager::contract:wbstree:" + contractId, JSON.toJSON(array).toString());
                         }
@@ -817,7 +830,7 @@ public class WbsTreeContractServiceImpl extends BaseServiceImpl<WbsTreeContractM
                     for (String sgContractId : contractIds) {
                         ContractInfo sgContractInfo = jdbcTemplate.query("select contract_name from m_contract_info where id = " + sgContractId, new BeanPropertyRowMapper<>(ContractInfo.class)).stream().findAny().orElse(null);
                         if (sgContractInfo != null) {
-                            //获取当前合同段所有缓存节点信息
+                            /*//获取当前合同段所有缓存节点信息
                             List<WbsTreeContractLazyVO> nodesAll;
                             Object data = redisTemplate.opsForValue().get("blade-manager::contract:wbstree:" + sgContractId);
                             if (data != null) {
@@ -828,6 +841,32 @@ public class WbsTreeContractServiceImpl extends BaseServiceImpl<WbsTreeContractM
                                     JSONArray array = JSONArray.parseArray(JSON.toJSONString(nodesAll));
                                     redisTemplate.opsForValue().set("blade-manager::contract:wbstree:" + sgContractId, JSON.toJSON(array).toString());
                                 }
+                            }*/
+
+                            //获取当前合同段所有缓存节点信息
+                            List<WbsTreeContractLazyVO> nodesAll;
+                            Object data = redisTemplate.opsForValue().get("blade-manager::contract:wbstree:" + sgContractId);
+                            if (data != null) {
+                                nodesAll = JSON.parseArray(data.toString(), WbsTreeContractLazyVO.class);
+                            } else {
+                                nodesAll = jdbcTemplate.query("select a.p_key_id,a.id,a.parent_id from m_wbs_tree_contract a where a.type = 1 and a.status = 1 and a.is_deleted = 0 and a.contract_id = " + sgContractId, new BeanPropertyRowMapper<>(WbsTreeContractLazyVO.class));
+                                if (nodesAll.size() > 0) {
+                                    //判断是否有子级,赋值
+                                    Map<Long, List<WbsTreeContractLazyVO>> groupedByParentId = nodesAll.stream().collect(Collectors.groupingBy(WbsTreeContractLazyVO::getParentId));
+                                    for (WbsTreeContractLazyVO vo : nodesAll) {
+                                        if (vo.getParentId() == 0) {
+                                            vo.setHasChildren(1);
+                                        }
+                                        List<WbsTreeContractLazyVO> childNodes = groupedByParentId.getOrDefault(vo.getId(), null);
+                                        if (childNodes != null && childNodes.size() > 0) {
+                                            vo.setHasChildren(1);
+                                        } else {
+                                            vo.setHasChildren(0);
+                                        }
+                                    }
+                                    JSONArray array = JSONArray.parseArray(JSON.toJSONString(nodesAll));
+                                    redisTemplate.opsForValue().set("blade-manager::contract:wbstree:" + sgContractId, JSON.toJSON(array).toString());
+                                }
                             }
 
                             //获取当前层懒加载节点
@@ -956,8 +995,21 @@ public class WbsTreeContractServiceImpl extends BaseServiceImpl<WbsTreeContractM
                     if (data != null) {
                         nodesAll = JSON.parseArray(data.toString(), WbsTreeContractLazyVO.class);
                     } else {
-                        nodesAll = jdbcTemplate.query("select a.p_key_id,a.id,a.parent_id,(SELECT CASE WHEN count(1) > 0 THEN 1 ELSE 0 END FROM m_wbs_tree_contract b WHERE b.parent_id = a.id AND type = 1 AND b.contract_id = " + contractId + " AND b.is_deleted = 0 ) AS hasChildren from m_wbs_tree_contract a where type = 1 and status = 1 and is_deleted = 0 and contract_id = " + contractId, new BeanPropertyRowMapper<>(WbsTreeContractLazyVO.class));
+                        nodesAll = jdbcTemplate.query("select a.p_key_id,a.id,a.parent_id from m_wbs_tree_contract a where a.type = 1 and a.status = 1 and a.is_deleted = 0 and a.contract_id = " + contractId, new BeanPropertyRowMapper<>(WbsTreeContractLazyVO.class));
                         if (nodesAll.size() > 0) {
+                            //判断是否有子级,赋值
+                            Map<Long, List<WbsTreeContractLazyVO>> groupedByParentId = nodesAll.stream().collect(Collectors.groupingBy(WbsTreeContractLazyVO::getParentId));
+                            for (WbsTreeContractLazyVO vo : nodesAll) {
+                                if (vo.getParentId() == 0) {
+                                    vo.setHasChildren(1);
+                                }
+                                List<WbsTreeContractLazyVO> childNodes = groupedByParentId.getOrDefault(vo.getId(), null);
+                                if (childNodes != null && childNodes.size() > 0) {
+                                    vo.setHasChildren(1);
+                                } else {
+                                    vo.setHasChildren(0);
+                                }
+                            }
                             JSONArray array = JSONArray.parseArray(JSON.toJSONString(nodesAll));
                             redisTemplate.opsForValue().set("blade-manager::contract:wbstree:" + contractId, JSON.toJSON(array).toString());
                         }
@@ -1058,8 +1110,21 @@ public class WbsTreeContractServiceImpl extends BaseServiceImpl<WbsTreeContractM
                             if (data != null) {
                                 nodesAll = JSON.parseArray(data.toString(), WbsTreeContractLazyVO.class);
                             } else {
-                                nodesAll = jdbcTemplate.query("select a.p_key_id,a.id,a.parent_id,(SELECT CASE WHEN count(1) > 0 THEN 1 ELSE 0 END FROM m_wbs_tree_contract b WHERE b.parent_id = a.id AND type = 1 AND b.contract_id = " + sgContractId + " AND b.is_deleted = 0 ) AS hasChildren from m_wbs_tree_contract a where type = 1 and status = 1 and is_deleted = 0 and contract_id = " + sgContractId, new BeanPropertyRowMapper<>(WbsTreeContractLazyVO.class));
+                                nodesAll = jdbcTemplate.query("select a.p_key_id,a.id,a.parent_id from m_wbs_tree_contract a where a.type = 1 and a.status = 1 and a.is_deleted = 0 and a.contract_id = " + sgContractId, new BeanPropertyRowMapper<>(WbsTreeContractLazyVO.class));
                                 if (nodesAll.size() > 0) {
+                                    //判断是否有子级,赋值
+                                    Map<Long, List<WbsTreeContractLazyVO>> groupedByParentId = nodesAll.stream().collect(Collectors.groupingBy(WbsTreeContractLazyVO::getParentId));
+                                    for (WbsTreeContractLazyVO vo : nodesAll) {
+                                        if (vo.getParentId() == 0) {
+                                            vo.setHasChildren(1);
+                                        }
+                                        List<WbsTreeContractLazyVO> childNodes = groupedByParentId.getOrDefault(vo.getId(), null);
+                                        if (childNodes != null && childNodes.size() > 0) {
+                                            vo.setHasChildren(1);
+                                        } else {
+                                            vo.setHasChildren(0);
+                                        }
+                                    }
                                     JSONArray array = JSONArray.parseArray(JSON.toJSONString(nodesAll));
                                     redisTemplate.opsForValue().set("blade-manager::contract:wbstree:" + sgContractId, JSON.toJSON(array).toString());
                                 }