浏览代码

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

laibulaizheli 2 天之前
父节点
当前提交
b1b1c8bfb5
共有 81 个文件被更改,包括 3189 次插入426 次删除
  1. 1 0
      blade-gateway/src/main/java/org/springblade/gateway/provider/AuthProvider.java
  2. 2 2
      blade-ops/blade-resource/src/main/java/org/springblade/resource/builder/oss/OssBuilder.java
  3. 34 0
      blade-service-api/blade-business-api/src/main/java/org/springblade/business/dto/TaskProgressDTO.java
  4. 67 0
      blade-service-api/blade-business-api/src/main/java/org/springblade/business/entity/TaskProgress.java
  5. 19 0
      blade-service-api/blade-business-api/src/main/java/org/springblade/business/feign/TaskProgressClient.java
  6. 34 0
      blade-service-api/blade-business-api/src/main/java/org/springblade/business/vo/TaskProgressVO.java
  7. 19 0
      blade-service-api/blade-business-api/src/main/java/org/springblade/business/vo/TaskProgressVO1.java
  8. 37 0
      blade-service-api/blade-manager-api/src/main/java/org/springblade/manager/dto/FormulaReferenceDTO.java
  9. 1 0
      blade-service-api/blade-manager-api/src/main/java/org/springblade/manager/dto/NameRuleDto.java
  10. 22 0
      blade-service-api/blade-manager-api/src/main/java/org/springblade/manager/dto/ProfilerOffsetDTO.java
  11. 22 0
      blade-service-api/blade-manager-api/src/main/java/org/springblade/manager/dto/ProfilerOffsetResultDTO.java
  12. 3 0
      blade-service-api/blade-manager-api/src/main/java/org/springblade/manager/dto/TrialSummaryReflectionSaveDTO.java
  13. 1 0
      blade-service-api/blade-manager-api/src/main/java/org/springblade/manager/entity/ElementFormulaMapping.java
  14. 89 0
      blade-service-api/blade-manager-api/src/main/java/org/springblade/manager/entity/ProfilerData.java
  15. 158 0
      blade-service-api/blade-manager-api/src/main/java/org/springblade/manager/entity/ProfilerOffset.java
  16. 102 0
      blade-service-api/blade-manager-api/src/main/java/org/springblade/manager/entity/ProfilerStandardSectionBean.java
  17. 3 3
      blade-service-api/blade-manager-api/src/main/java/org/springblade/manager/entity/TextdictInfo.java
  18. 5 0
      blade-service-api/blade-manager-api/src/main/java/org/springblade/manager/entity/WbsTreeContractExtend.java
  19. 59 0
      blade-service-api/blade-manager-api/src/main/java/org/springblade/manager/entity/profiler/ProfilerDataPush.java
  20. 66 0
      blade-service-api/blade-manager-api/src/main/java/org/springblade/manager/entity/profiler/ProfilerOffsetPush.java
  21. 43 0
      blade-service-api/blade-manager-api/src/main/java/org/springblade/manager/entity/profiler/ProfilerResult.java
  22. 22 0
      blade-service-api/blade-manager-api/src/main/java/org/springblade/manager/entity/profiler/ProfilerSaveDTO.java
  23. 52 0
      blade-service-api/blade-manager-api/src/main/java/org/springblade/manager/entity/profiler/ProfilerSectionPush.java
  24. 2 0
      blade-service-api/blade-manager-api/src/main/java/org/springblade/manager/vo/NameRuleVo.java
  25. 3 0
      blade-service-api/blade-manager-api/src/main/java/org/springblade/manager/vo/TextdictInfoVO.java
  26. 10 0
      blade-service-api/blade-manager-api/src/main/java/org/springblade/manager/vo/TrialTableDataInfo.java
  27. 23 11
      blade-service/blade-archive/src/main/java/org/springblade/archive/service/impl/ArchivesAutoServiceImpl.java
  28. 11 0
      blade-service/blade-business/src/main/java/org/springblade/business/controller/InformationWriteQueryController.java
  29. 137 0
      blade-service/blade-business/src/main/java/org/springblade/business/controller/TaskProgressController.java
  30. 23 0
      blade-service/blade-business/src/main/java/org/springblade/business/feignClient/TaskProgressClientImpl.java
  31. 2 2
      blade-service/blade-business/src/main/java/org/springblade/business/mapper/ArchiveFileMapper.xml
  32. 53 0
      blade-service/blade-business/src/main/java/org/springblade/business/mapper/TaskProgressMapper.java
  33. 58 0
      blade-service/blade-business/src/main/java/org/springblade/business/mapper/TaskProgressMapper.xml
  34. 6 0
      blade-service/blade-business/src/main/java/org/springblade/business/mapper/WbsTreeContractStatisticsMapper.xml
  35. 49 0
      blade-service/blade-business/src/main/java/org/springblade/business/service/ITaskProgressService.java
  36. 1 1
      blade-service/blade-business/src/main/java/org/springblade/business/service/ITaskService.java
  37. 2 1
      blade-service/blade-business/src/main/java/org/springblade/business/service/impl/InformationQueryServiceImpl.java
  38. 159 0
      blade-service/blade-business/src/main/java/org/springblade/business/service/impl/TaskProgressServiceImpl.java
  39. 10 7
      blade-service/blade-business/src/main/java/org/springblade/business/service/impl/TaskServiceImpl.java
  40. 7 0
      blade-service/blade-business/src/main/java/org/springblade/business/service/impl/TrialSelfInspectionRecordServiceImpl.java
  41. 4 11
      blade-service/blade-business/src/main/java/org/springblade/business/sync/TaskSync.java
  42. 3 0
      blade-service/blade-e-visa/src/main/java/org/springblade/evisa/service/impl/EVDataServiceImpl.java
  43. 2 1
      blade-service/blade-e-visa/src/main/java/org/springblade/evisa/service/impl/ScrDataServiceImpl.java
  44. 25 0
      blade-service/blade-manager/src/main/java/com/mixsmart/utils/CustomFunction.java
  45. 2 0
      blade-service/blade-manager/src/main/java/org/springblade/manager/bean/TableInfo.java
  46. 115 3
      blade-service/blade-manager/src/main/java/org/springblade/manager/controller/ExcelTabController.java
  47. 1 1
      blade-service/blade-manager/src/main/java/org/springblade/manager/controller/FormulaController.java
  48. 109 0
      blade-service/blade-manager/src/main/java/org/springblade/manager/controller/ProfilerController.java
  49. 105 55
      blade-service/blade-manager/src/main/java/org/springblade/manager/controller/TextdictInfoController.java
  50. 163 44
      blade-service/blade-manager/src/main/java/org/springblade/manager/controller/TrialSummaryClassificationConfigurationController.java
  51. 37 24
      blade-service/blade-manager/src/main/java/org/springblade/manager/controller/WbsTreeContractController.java
  52. 5 3
      blade-service/blade-manager/src/main/java/org/springblade/manager/controller/WbsTreePrivateController.java
  53. 1 45
      blade-service/blade-manager/src/main/java/org/springblade/manager/feign/ExcelTabClientImpl.java
  54. 1 1
      blade-service/blade-manager/src/main/java/org/springblade/manager/formula/impl/SubTable.java
  55. 2 0
      blade-service/blade-manager/src/main/java/org/springblade/manager/formula/impl/TableElementConverter.java
  56. 20 0
      blade-service/blade-manager/src/main/java/org/springblade/manager/mapper/ProfilerDataMapper.java
  57. 25 0
      blade-service/blade-manager/src/main/java/org/springblade/manager/mapper/ProfilerDataMapper.xml
  58. 23 0
      blade-service/blade-manager/src/main/java/org/springblade/manager/mapper/ProfilerOffsetMapper.java
  59. 36 0
      blade-service/blade-manager/src/main/java/org/springblade/manager/mapper/ProfilerOffsetMapper.xml
  60. 20 0
      blade-service/blade-manager/src/main/java/org/springblade/manager/mapper/ProfilerStandardSectionBeanMapper.java
  61. 28 0
      blade-service/blade-manager/src/main/java/org/springblade/manager/mapper/ProfilerStandardSectionBeanMapper.xml
  62. 8 0
      blade-service/blade-manager/src/main/java/org/springblade/manager/mapper/TextdictInfoMapper.java
  63. 1 1
      blade-service/blade-manager/src/main/java/org/springblade/manager/mapper/TextdictInfoMapper.xml
  64. 2 1
      blade-service/blade-manager/src/main/java/org/springblade/manager/mapper/WbsParamMapper.xml
  65. 1 1
      blade-service/blade-manager/src/main/java/org/springblade/manager/service/IFormulaService.java
  66. 3 4
      blade-service/blade-manager/src/main/java/org/springblade/manager/service/IWbsTreeContractService.java
  67. 1 1
      blade-service/blade-manager/src/main/java/org/springblade/manager/service/IWbsTreePrivateService.java
  68. 13 0
      blade-service/blade-manager/src/main/java/org/springblade/manager/service/ProfilerDataService.java
  69. 34 0
      blade-service/blade-manager/src/main/java/org/springblade/manager/service/ProfilerOffsetService.java
  70. 13 0
      blade-service/blade-manager/src/main/java/org/springblade/manager/service/ProfilerStandardSectionBeanService.java
  71. 51 7
      blade-service/blade-manager/src/main/java/org/springblade/manager/service/impl/ExcelTabServiceImpl.java
  72. 95 34
      blade-service/blade-manager/src/main/java/org/springblade/manager/service/impl/FormulaServiceImpl.java
  73. 22 0
      blade-service/blade-manager/src/main/java/org/springblade/manager/service/impl/ProfilerDataServiceImpl.java
  74. 339 0
      blade-service/blade-manager/src/main/java/org/springblade/manager/service/impl/ProfilerOffsetServiceImpl.java
  75. 22 0
      blade-service/blade-manager/src/main/java/org/springblade/manager/service/impl/ProfilerStandardSectionBeanServiceImpl.java
  76. 48 37
      blade-service/blade-manager/src/main/java/org/springblade/manager/service/impl/TextdictInfoServiceImpl.java
  77. 149 9
      blade-service/blade-manager/src/main/java/org/springblade/manager/service/impl/WbsParamServiceImpl.java
  78. 89 5
      blade-service/blade-manager/src/main/java/org/springblade/manager/service/impl/WbsTreeContractServiceImpl.java
  79. 44 13
      blade-service/blade-manager/src/main/java/org/springblade/manager/service/impl/WbsTreePrivateServiceImpl.java
  80. 14 2
      blade-service/blade-meter/src/main/java/org/springblade/meter/controller/TaskController.java
  81. 96 96
      blade-service/blade-user/src/main/java/org/springblade/system/user/service/impl/UserServiceImpl.java

+ 1 - 0
blade-gateway/src/main/java/org/springblade/gateway/provider/AuthProvider.java

@@ -69,6 +69,7 @@ public class AuthProvider {
         DEFAULT_SKIP_URL.add("/getArchiveToken"); //成渝第三方登录获取档案系统tokne
         DEFAULT_SKIP_URL.add("/meeting/**");//DingDing会议接口
         DEFAULT_SKIP_URL.add("/hczc/api/meter/**");//重庆高速计量获取分部分项划分
+        DEFAULT_SKIP_URL.add("/profiler/save");//成渝断面仪新增接口开放
 
     }
 

+ 2 - 2
blade-ops/blade-resource/src/main/java/org/springblade/resource/builder/oss/OssBuilder.java

@@ -91,13 +91,13 @@ public class OssBuilder {
 		String tenantId = AuthUtil.getTenantId();
 		Oss oss = getOss(tenantId, code);
         String sys_isonline = ParamCache.getValue(CommonConstant.SYS_ISONLINE);
-       /* if(SystemUtils.isMacOs()||SystemUtils.isWindows()){
+       if(SystemUtils.isMacOs()||SystemUtils.isWindows()){
             if("20".equals(sys_isonline)){
                 oss.setEndpoint("http://183.247.216.148:9000/");
             }else {
                 oss.setEndpoint("https://xinan1.zos.ctyun.cn");
             }
-        }*/
+        }
 		//oss.setEndpoint("https://xinan1.zos.ctyun.cn");
 		System.out.println("oss111="+oss.getEndpoint());
 		Oss ossCached = ossPool.get(tenantId);

+ 34 - 0
blade-service-api/blade-business-api/src/main/java/org/springblade/business/dto/TaskProgressDTO.java

@@ -0,0 +1,34 @@
+/*
+ *      Copyright (c) 2018-2028, Chill Zhuang All rights reserved.
+ *
+ *  Redistribution and use in source and binary forms, with or without
+ *  modification, are permitted provided that the following conditions are met:
+ *
+ *  Redistributions of source code must retain the above copyright notice,
+ *  this list of conditions and the following disclaimer.
+ *  Redistributions in binary form must reproduce the above copyright
+ *  notice, this list of conditions and the following disclaimer in the
+ *  documentation and/or other materials provided with the distribution.
+ *  Neither the name of the dreamlu.net developer nor the names of its
+ *  contributors may be used to endorse or promote products derived from
+ *  this software without specific prior written permission.
+ *  Author: Chill 庄骞 (smallchill@163.com)
+ */
+package org.springblade.business.dto;
+
+import lombok.Data;
+import lombok.EqualsAndHashCode;
+import org.springblade.business.entity.TaskProgress;
+
+/**
+ * 任务进度表数据传输对象实体类
+ *
+ * @author BladeX
+ * @since 2025-10-15
+ */
+@Data
+@EqualsAndHashCode(callSuper = true)
+public class TaskProgressDTO extends TaskProgress {
+	private static final long serialVersionUID = 1L;
+
+}

+ 67 - 0
blade-service-api/blade-business-api/src/main/java/org/springblade/business/entity/TaskProgress.java

@@ -0,0 +1,67 @@
+/*
+ *      Copyright (c) 2018-2028, Chill Zhuang All rights reserved.
+ *
+ *  Redistribution and use in source and binary forms, with or without
+ *  modification, are permitted provided that the following conditions are met:
+ *
+ *  Redistributions of source code must retain the above copyright notice,
+ *  this list of conditions and the following disclaimer.
+ *  Redistributions in binary form must reproduce the above copyright
+ *  notice, this list of conditions and the following disclaimer in the
+ *  documentation and/or other materials provided with the distribution.
+ *  Neither the name of the dreamlu.net developer nor the names of its
+ *  contributors may be used to endorse or promote products derived from
+ *  this software without specific prior written permission.
+ *  Author: Chill 庄骞 (smallchill@163.com)
+ */
+package org.springblade.business.entity;
+
+import com.baomidou.mybatisplus.annotation.TableName;
+import java.io.Serializable;
+
+import lombok.AllArgsConstructor;
+import lombok.NoArgsConstructor;
+import org.springblade.core.mp.base.BaseEntity;
+import lombok.Data;
+import lombok.EqualsAndHashCode;
+
+/**
+ * 任务进度表实体类
+ *
+ * @author BladeX
+ * @since 2025-10-15
+ */
+@Data
+@TableName("m_task_progress")
+@EqualsAndHashCode(callSuper = true)
+@NoArgsConstructor
+@AllArgsConstructor
+public class TaskProgress extends BaseEntity {
+
+	private static final long serialVersionUID = 1L;
+
+	private Long projectId;
+	private Long contractId;
+	/**
+	* 1.sava_again 2.re_sign 3.电签检测 4.一键电签
+	*/
+		private Integer type;
+	/**
+	* 任务总数
+	*/
+		private Integer taskTotal;
+	/**
+	* 已完成数
+	*/
+		private Integer finishTatol;
+	/**
+	* 是否已完成 0否 1是
+	*/
+		private Integer isFinish;
+	/**
+	 * 任务ID
+ 	 */
+		private String dataId;
+
+
+}

+ 19 - 0
blade-service-api/blade-business-api/src/main/java/org/springblade/business/feign/TaskProgressClient.java

@@ -0,0 +1,19 @@
+package org.springblade.business.feign;
+
+import org.springframework.cloud.openfeign.FeignClient;
+import org.springframework.web.bind.annotation.GetMapping;
+import org.springframework.web.bind.annotation.RequestParam;
+
+import static org.springblade.core.launch.constant.AppConstant.APPLICATION_NAME_PREFIX;
+
+@FeignClient(value = APPLICATION_NAME_PREFIX + "business")
+public interface TaskProgressClient {
+    /**
+     * 接口前缀
+     */
+    String API_PREFIX = "/api/business/taskProgress";
+
+
+    @GetMapping(API_PREFIX + "/updateTaskProgress")
+    Boolean updateTaskProgress(@RequestParam("projectId") Long projectId,@RequestParam("contractId") Long contractId,@RequestParam("type") Integer type,@RequestParam("finishTotal") Integer finishTotal,@RequestParam("dataId") String dataId);
+}

+ 34 - 0
blade-service-api/blade-business-api/src/main/java/org/springblade/business/vo/TaskProgressVO.java

@@ -0,0 +1,34 @@
+/*
+ *      Copyright (c) 2018-2028, Chill Zhuang All rights reserved.
+ *
+ *  Redistribution and use in source and binary forms, with or without
+ *  modification, are permitted provided that the following conditions are met:
+ *
+ *  Redistributions of source code must retain the above copyright notice,
+ *  this list of conditions and the following disclaimer.
+ *  Redistributions in binary form must reproduce the above copyright
+ *  notice, this list of conditions and the following disclaimer in the
+ *  documentation and/or other materials provided with the distribution.
+ *  Neither the name of the dreamlu.net developer nor the names of its
+ *  contributors may be used to endorse or promote products derived from
+ *  this software without specific prior written permission.
+ *  Author: Chill 庄骞 (smallchill@163.com)
+ */
+package org.springblade.business.vo;
+
+import lombok.Data;
+import lombok.EqualsAndHashCode;
+import org.springblade.business.entity.TaskProgress;
+
+/**
+ * 任务进度表视图实体类
+ *
+ * @author BladeX
+ * @since 2025-10-15
+ */
+@Data
+@EqualsAndHashCode(callSuper = true)
+public class TaskProgressVO extends TaskProgress {
+	private static final long serialVersionUID = 1L;
+
+}

+ 19 - 0
blade-service-api/blade-business-api/src/main/java/org/springblade/business/vo/TaskProgressVO1.java

@@ -0,0 +1,19 @@
+package org.springblade.business.vo;
+
+import lombok.AllArgsConstructor;
+import lombok.Data;
+import lombok.NoArgsConstructor;
+
+import java.math.BigDecimal;
+
+@Data
+@NoArgsConstructor
+@AllArgsConstructor
+public class TaskProgressVO1 {
+
+    private Integer finishCount;
+
+    private Integer totalCount;
+
+    private BigDecimal pace;
+}

+ 37 - 0
blade-service-api/blade-manager-api/src/main/java/org/springblade/manager/dto/FormulaReferenceDTO.java

@@ -0,0 +1,37 @@
+package org.springblade.manager.dto;
+
+import io.swagger.annotations.ApiModelProperty;
+import lombok.Data;
+
+import javax.validation.constraints.NotBlank;
+import javax.validation.constraints.NotNull;
+
+/**
+ * 公式应用设置
+ * @author LHB
+ */
+@Data
+public class FormulaReferenceDTO {
+    @ApiModelProperty("表单pKeyId")
+    private Long pKeyId;
+
+    @ApiModelProperty(value = "节点pKeyId",required = true)
+    @NotNull(message = "节点pKeyId不能为空")
+    private Long pId;
+
+    @ApiModelProperty(value = "选择表格的元素key",required = true)
+    @NotBlank(message = "选择表格的元素key不能为空")
+    private String key;
+
+    @ApiModelProperty(value = "表单元素表名称",required = true)
+    @NotBlank(message = "表单元素表名称不能为空")
+    private String initTableName;
+
+    @ApiModelProperty(value = "状态 0禁用 1启用",required = true)
+    @NotNull(message = "状态不能为空")
+    private Integer status;
+
+        @ApiModelProperty(value = "类型 1-质检 2-试验",required = true)
+    @NotNull(message = "类型")
+    private Integer type;
+}

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

@@ -13,5 +13,6 @@ public class NameRuleDto {
     private String nodeId;
     private Long projectId;
     private Integer type;
+    private String remark;
 
 }

+ 22 - 0
blade-service-api/blade-manager-api/src/main/java/org/springblade/manager/dto/ProfilerOffsetDTO.java

@@ -0,0 +1,22 @@
+package org.springblade.manager.dto;
+
+import io.swagger.annotations.ApiModelProperty;
+import lombok.Data;
+import lombok.EqualsAndHashCode;
+import org.springblade.manager.entity.ProfilerOffset;
+
+/**
+ * @author LHB
+ */
+@EqualsAndHashCode(callSuper = true)
+@Data
+public class ProfilerOffsetDTO extends ProfilerOffset {
+    @ApiModelProperty(value = "当前页")
+    private Integer current;
+    @ApiModelProperty(value = "每页显示数量")
+    private Integer size;
+    @ApiModelProperty(value = "开始时间")
+    private String startTime;
+    @ApiModelProperty(value = "结束时间")
+    private String endTime;
+}

+ 22 - 0
blade-service-api/blade-manager-api/src/main/java/org/springblade/manager/dto/ProfilerOffsetResultDTO.java

@@ -0,0 +1,22 @@
+package org.springblade.manager.dto;
+
+import io.swagger.annotations.ApiModelProperty;
+import lombok.Data;
+import lombok.EqualsAndHashCode;
+import org.springblade.manager.entity.ProfilerData;
+import org.springblade.manager.entity.ProfilerOffset;
+import org.springblade.manager.entity.ProfilerStandardSectionBean;
+
+import java.util.List;
+
+/**
+ * @author LHB
+ */
+@EqualsAndHashCode(callSuper = true)
+@Data
+public class ProfilerOffsetResultDTO extends ProfilerOffset {
+    @ApiModelProperty(value = "标准断面")
+    private List<ProfilerStandardSectionBean> sectionBeans;
+    @ApiModelProperty(value = "测量点数组")
+    private List<ProfilerData> data;
+}

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

@@ -18,6 +18,9 @@ public class TrialSummaryReflectionSaveDTO implements Serializable {
 
     @Data
     public static class ReflectionBean implements Serializable {
+        @ApiModelProperty(value = "试验表的p_key_id")
+        private Long id;
+
         @ApiModelProperty(value = "试验表的p_key_id")
         private Long trialTabId;
 

+ 1 - 0
blade-service-api/blade-manager-api/src/main/java/org/springblade/manager/entity/ElementFormulaMapping.java

@@ -25,6 +25,7 @@ public class ElementFormulaMapping extends BaseEntity {
     @Size(max = 20)
     private Long wbsId;
     private Long projectId;
+    // 公式级别 0=元素库级别  1=WBS级别 2=WBS 节点级别 10=项目级别 20=项目节点级别 35=节点参数级别
     private Integer scope;
     private Long paramId;
 

+ 89 - 0
blade-service-api/blade-manager-api/src/main/java/org/springblade/manager/entity/ProfilerData.java

@@ -0,0 +1,89 @@
+package org.springblade.manager.entity;
+
+import com.baomidou.mybatisplus.annotation.IdType;
+import com.baomidou.mybatisplus.annotation.TableId;
+import com.baomidou.mybatisplus.annotation.TableName;
+
+import java.time.LocalDateTime;
+
+import com.fasterxml.jackson.annotation.JsonFormat;
+import io.swagger.annotations.ApiModelProperty;
+import lombok.Data;
+import org.springframework.format.annotation.DateTimeFormat;
+
+/**
+ * 断面仪-测量点数组
+ * @author LHB
+ * @TableName q_profiler_data
+ */
+@TableName(value ="q_profiler_data")
+@Data
+public class ProfilerData {
+    /**
+     * 
+     */
+    @TableId(type = IdType.INPUT)
+    @ApiModelProperty("id")
+    private Long id;
+
+    /**
+     * 基础信息id
+     */
+    @ApiModelProperty("基础信息id")
+    private Long offsetId;
+
+    /**
+     * 测点角度
+     */
+    @ApiModelProperty("测点角度")
+    private String angle;
+
+    /**
+     * 超/欠挖值
+     */
+    @ApiModelProperty("超/欠挖值")
+    private String backBreak;
+
+    /**
+     * 距离
+     */
+    @ApiModelProperty("距离")
+    private String dist;
+
+    /**
+     * x坐标
+     */
+    @ApiModelProperty("x坐标")
+    private String x;
+
+    /**
+     * z坐标
+     */
+    @ApiModelProperty("z坐标")
+    private String z;
+
+    /**
+     *  创建时间
+     */
+    @JsonFormat(pattern = "yyyy-MM-dd HH:mm:ss", timezone = "GMT+8")
+    @DateTimeFormat(pattern = "yyyy-MM-dd HH:mm:ss")
+    private LocalDateTime createTime;
+
+    /**
+     *  创建人
+     */
+    private Long createUser;
+
+    /**
+     *  修改时间
+     */
+    @JsonFormat(pattern = "yyyy-MM-dd HH:mm:ss", timezone = "GMT+8")
+    @DateTimeFormat(pattern = "yyyy-MM-dd HH:mm:ss")
+    private LocalDateTime updateTime;
+
+    /**
+     *  修改人
+     */
+    private Long updateUser;
+
+}

+ 158 - 0
blade-service-api/blade-manager-api/src/main/java/org/springblade/manager/entity/ProfilerOffset.java

@@ -0,0 +1,158 @@
+package org.springblade.manager.entity;
+
+import com.baomidou.mybatisplus.annotation.IdType;
+import com.baomidou.mybatisplus.annotation.TableField;
+import com.baomidou.mybatisplus.annotation.TableId;
+import com.baomidou.mybatisplus.annotation.TableName;
+
+import java.time.LocalDateTime;
+
+import com.fasterxml.jackson.annotation.JsonFormat;
+import io.swagger.annotations.ApiModelProperty;
+import lombok.Data;
+import org.springframework.format.annotation.DateTimeFormat;
+
+/**
+ * 断面仪-基础信息+测量者信息
+ * @author LHB
+ * @TableName q_profiler_offset
+ */
+@TableName(value ="q_profiler_offset")
+@Data
+public class ProfilerOffset {
+    /**
+     * 
+     */
+    @TableId(type = IdType.INPUT)
+    @ApiModelProperty("id")
+    private Long id;
+
+    /**
+     * 断面仪测量设备编码或名称
+     */
+    @ApiModelProperty("断面仪测量设备编码或名称")
+    private String deviceCode;
+
+    /**
+     * 仪器高度(米)
+     */
+    @ApiModelProperty("仪器高度(米)")
+    private String deviceHeight;
+
+    /**
+     * 椭圆半径
+     */
+    @ApiModelProperty("椭圆半径")
+    private String ellipseRadius;
+
+    /**
+     * 斜坡
+     */
+    @ApiModelProperty("斜坡")
+    private String slope;
+
+    /**
+     * x方向偏移量(米)
+     */
+    @ApiModelProperty("x方向偏移量(米)")
+    @TableField(value = "x")
+    private String x0;
+
+    /**
+     * z方向偏移量(米)
+     */
+    @ApiModelProperty("z方向偏移量(米)")
+    @TableField(value = "z")
+    private String z0;
+
+    /**
+     * 隧道名称
+     */
+    @ApiModelProperty("隧道名称")
+    @TableField(value = "info_channel_name")
+    private String channelName;
+
+    /**
+     * 施工单位
+     */
+    @ApiModelProperty("施工单位")
+    @TableField(value = "info_construction_unit")
+    private String constructionUnit;
+
+    /**
+     * 测量时间
+     */
+    @ApiModelProperty("测量时间")
+    @TableField(value = "info_date")
+    private String date;
+
+    /**
+     * 工程名称
+     */
+    @ApiModelProperty("工程名称")
+    @TableField(value = "info_name_of_project")
+    private String nameOfProject;
+
+    /**
+     * 测量者
+     */
+    @ApiModelProperty("测量者")
+    @TableField(value = "info_user_name")
+    private String userName;
+
+    /**
+     * 里程号
+     */
+    @ApiModelProperty("里程号")
+    @TableField(value = "info_mileage_number")
+    private String mileageNumber;
+    /**
+     * 是否超欠挖 (我们这边自己判断的状态)
+     */
+    @ApiModelProperty("是否超欠挖")
+    @TableField(value = "back_break")
+    private String backBreak;
+
+    /**
+     * 文件地址
+     */
+    @ApiModelProperty("文件地址")
+    private String fileUrl;
+
+    /**
+     * 是否推送(0-未推送,1-已推送,2-推送失败)
+     */
+    @ApiModelProperty("是否推送(0-未推送,1-已推送,2-推送失败)")
+    private Integer push;
+
+    /**
+     * 推送时间
+     */
+    @ApiModelProperty("推送时间")
+    private LocalDateTime pushTime;
+
+    /**
+     *  创建时间
+     */
+    @JsonFormat(pattern = "yyyy-MM-dd HH:mm:ss", timezone = "GMT+8")
+    @DateTimeFormat(pattern = "yyyy-MM-dd HH:mm:ss")
+    private LocalDateTime createTime;
+
+    /**
+     *  创建人
+     */
+    private Long createUser;
+
+    /**
+     *  修改时间
+     */
+    @JsonFormat(pattern = "yyyy-MM-dd HH:mm:ss", timezone = "GMT+8")
+    @DateTimeFormat(pattern = "yyyy-MM-dd HH:mm:ss")
+    private LocalDateTime updateTime;
+
+    /**
+     *  修改人
+     */
+    private Long updateUser;
+
+}

+ 102 - 0
blade-service-api/blade-manager-api/src/main/java/org/springblade/manager/entity/ProfilerStandardSectionBean.java

@@ -0,0 +1,102 @@
+package org.springblade.manager.entity;
+
+import com.baomidou.mybatisplus.annotation.IdType;
+import com.baomidou.mybatisplus.annotation.TableField;
+import com.baomidou.mybatisplus.annotation.TableId;
+import com.baomidou.mybatisplus.annotation.TableName;
+
+import java.time.LocalDateTime;
+
+import com.fasterxml.jackson.annotation.JsonFormat;
+import io.swagger.annotations.ApiModelProperty;
+import lombok.Data;
+import org.springframework.format.annotation.DateTimeFormat;
+
+/**
+ * 断面仪-标准断面
+ * @author LHB
+ * @TableName q_profiler_standard_section_bean
+ */
+@TableName(value ="q_profiler_standard_section_bean")
+@Data
+public class ProfilerStandardSectionBean {
+    /**
+     * 
+     */
+    @TableId(type = IdType.INPUT)
+    @ApiModelProperty("id")
+    private Long id;
+
+    /**
+     * 基础信息id
+     */
+    @ApiModelProperty("基础信息id")
+    private Long offsetId;
+
+    /**
+     * 方向,true为顺时针,false为逆时针 
+     */
+    @ApiModelProperty("方向,true为顺时针,false为逆时针 ")
+    private String direction;
+
+    /**
+     * 终角
+     */
+    @ApiModelProperty("终角")
+    private String endAngle;
+
+    /**
+     * 半径
+     */
+    @ApiModelProperty("半径")
+    private String radius;
+
+    /**
+     * 查询
+     */
+    @ApiModelProperty("查询")
+    @TableField("`select`")
+    private String select;
+
+    /**
+     * 起角(米)
+     */
+    @ApiModelProperty("起角(米)")
+    private String startAngle;
+
+    /**
+     * 圆心x(米)
+     */
+    @ApiModelProperty("圆心x(米)")
+    private String x;
+
+    /**
+     * 圆心z(米)
+     */
+    @ApiModelProperty("圆心z(米)")
+    private String y;
+
+    /**
+     *  创建时间
+     */
+    @JsonFormat(pattern = "yyyy-MM-dd HH:mm:ss", timezone = "GMT+8")
+    @DateTimeFormat(pattern = "yyyy-MM-dd HH:mm:ss")
+    private LocalDateTime createTime;
+
+    /**
+     *  创建人
+     */
+    private Long createUser;
+
+    /**
+     *  修改时间
+     */
+    @JsonFormat(pattern = "yyyy-MM-dd HH:mm:ss", timezone = "GMT+8")
+    @DateTimeFormat(pattern = "yyyy-MM-dd HH:mm:ss")
+    private LocalDateTime updateTime;
+
+    /**
+     *  修改人
+     */
+    private Long updateUser;
+}

+ 3 - 3
blade-service-api/blade-manager-api/src/main/java/org/springblade/manager/entity/TextdictInfo.java

@@ -85,12 +85,12 @@ public class TextdictInfo implements Serializable {
     /**
      * 偏移坐标X
      */
-    private double pyzbx;
+    private Double pyzbx;
 
     /**
      * 偏移坐标Y
      */
-    private double pyzby;
+    private Double pyzby;
 
     /**
      * excelId
@@ -120,5 +120,5 @@ public class TextdictInfo implements Serializable {
     /**
      * 是否需要时间 1需要 0不需要
      */
-    private int timeState;
+    private Integer timeState;
 }

+ 5 - 0
blade-service-api/blade-manager-api/src/main/java/org/springblade/manager/entity/WbsTreeContractExtend.java

@@ -64,4 +64,9 @@ public class WbsTreeContractExtend {
      *  修改人
      */
     private Long updateUser;
+
+    /**
+     * 哪些元素执行公式
+     */
+    private String formulaConfig;
 }

+ 59 - 0
blade-service-api/blade-manager-api/src/main/java/org/springblade/manager/entity/profiler/ProfilerDataPush.java

@@ -0,0 +1,59 @@
+package org.springblade.manager.entity.profiler;
+
+import com.alibaba.druid.util.StringUtils;
+import lombok.Data;
+import org.springblade.core.tool.utils.StringUtil;
+import org.springblade.manager.entity.ProfilerData;
+
+import java.util.List;
+import java.util.stream.Collectors;
+
+/**
+ * @author LHB
+ * 断面仪 测量数据推送对象
+ */
+@Data
+public class ProfilerDataPush {
+    /**
+     * 测点
+     */
+    private String measurement_point;
+    /**
+     * 距离
+     */
+    private String distance;
+    /**
+     * x坐标
+     */
+    private String x_coordinate;
+    /**
+     * z坐标
+     */
+    private String z_coordinate;
+    /**
+     * 超挖值(米)
+     */
+    private String overbreak_value;
+    /**
+     * 欠挖值(米)
+     */
+    private String underbreak_value;
+    public static List<ProfilerDataPush> parameterMapping(List<ProfilerData> data) {
+        return data.stream().map(f -> {
+            ProfilerDataPush sectionPush = new ProfilerDataPush();
+            sectionPush.setMeasurement_point(f.getAngle());
+            sectionPush.setDistance(f.getDist());
+            sectionPush.setX_coordinate(f.getX());
+            sectionPush.setZ_coordinate(f.getZ());
+            if(StringUtil.isNotBlank(f.getBackBreak()) && StringUtils.isNumber(f.getBackBreak())){
+                if(Double.parseDouble(f.getBackBreak()) >= 0){
+                    sectionPush.setOverbreak_value(f.getBackBreak());
+
+                }else{
+                    sectionPush.setUnderbreak_value(f.getBackBreak());
+                }
+            }
+            return sectionPush;
+        }).collect(Collectors.toList());
+    }
+}

+ 66 - 0
blade-service-api/blade-manager-api/src/main/java/org/springblade/manager/entity/profiler/ProfilerOffsetPush.java

@@ -0,0 +1,66 @@
+package org.springblade.manager.entity.profiler;
+
+import cn.hutool.core.date.DateTime;
+import cn.hutool.core.date.DateUtil;
+import lombok.Data;
+import org.springblade.manager.entity.ProfilerOffset;
+
+import java.util.List;
+
+/**
+ * @author LHB
+ * 断面仪 基础信息推送对象
+ */
+@Data
+public class ProfilerOffsetPush {
+    /**
+     * 上传时间 yyyy-MM-dd
+     */
+    private String report_date;
+    /**
+     * 测量时间 yyyy-MM-dd HH:mm:ss
+     */
+    private String measurement_time;
+    /**
+     * 测量人
+     */
+    private String measurement_person;
+    /**
+     * 桩号
+     */
+    private String pile_number;
+    /**
+     * x方向偏移量(米)
+     */
+    private String x_offset;
+    /**
+     * y方向偏移量(米)
+     */
+    private String y_offset;
+    /**
+     * 仪器高度(米)
+     */
+    private String instrument_height;
+    /**
+     * 测量断面
+     */
+    private List<ProfilerSectionPush> measurement_section;
+    /**
+     * 测量数据
+     */
+    private List<ProfilerDataPush> receipt_data;
+
+
+
+    public static ProfilerOffsetPush parameterMapping(ProfilerOffset push) {
+        ProfilerOffsetPush profilerOffsetPush = new ProfilerOffsetPush();
+        profilerOffsetPush.setReport_date(DateUtil.format(DateTime.now(),"yyyy-MM-dd"));
+        profilerOffsetPush.setMeasurement_time(push.getDate());
+        profilerOffsetPush.setMeasurement_person(push.getUserName());
+        profilerOffsetPush.setPile_number(null);
+        profilerOffsetPush.setX_offset(push.getX0());
+        profilerOffsetPush.setY_offset(push.getZ0());
+        profilerOffsetPush.setInstrument_height(push.getDeviceHeight());
+        return profilerOffsetPush;
+    }
+}

+ 43 - 0
blade-service-api/blade-manager-api/src/main/java/org/springblade/manager/entity/profiler/ProfilerResult.java

@@ -0,0 +1,43 @@
+package org.springblade.manager.entity.profiler;
+
+import lombok.Data;
+
+/**
+ * @author LHB
+ */
+@Data
+public class ProfilerResult {
+    private String success;
+    private ProfilerError error;
+    private Object result;
+
+    @Data
+    static class ProfilerError{
+        private String code;
+        private String message;
+        private String details;
+
+        public ProfilerError(String code, String message, String details) {
+            this.code = code;
+            this.message = message;
+            this.details = details;
+        }
+    }
+
+
+    public static ProfilerResult success() {
+        ProfilerResult r = new ProfilerResult();
+        r.setSuccess("true");
+        r.setResult(null);
+        return r;
+    }
+
+
+    public static ProfilerResult error(String code, String message, String details) {
+        ProfilerResult r = new ProfilerResult();
+        r.setSuccess("false");
+        r.setError(new ProfilerError(code, message, details));
+        return r;
+    }
+
+}

+ 22 - 0
blade-service-api/blade-manager-api/src/main/java/org/springblade/manager/entity/profiler/ProfilerSaveDTO.java

@@ -0,0 +1,22 @@
+package org.springblade.manager.entity.profiler;
+
+import io.swagger.annotations.ApiModelProperty;
+import lombok.Data;
+
+/**
+ * @author LHB
+ * 第三方推送数据结构
+ */
+@Data
+public class ProfilerSaveDTO {
+    @ApiModelProperty(value = "appKey")
+    private String appKey;
+    @ApiModelProperty(value = "当前时间戳(秒)")
+    private Long timestamp;
+    @ApiModelProperty(value = "签名")
+    private String sign;
+    @ApiModelProperty(value = "编码")
+    private String deviceCode;
+    @ApiModelProperty(value = "JSON数据")
+    private String data;
+}

+ 52 - 0
blade-service-api/blade-manager-api/src/main/java/org/springblade/manager/entity/profiler/ProfilerSectionPush.java

@@ -0,0 +1,52 @@
+package org.springblade.manager.entity.profiler;
+
+import lombok.Data;
+import org.springblade.manager.entity.ProfilerStandardSectionBean;
+
+import java.util.List;
+import java.util.stream.Collectors;
+
+/**
+ * @author LHB
+ * 断面仪 测量断面推送对象
+ */
+@Data
+public class ProfilerSectionPush {
+    /**
+     * 方向
+     */
+    private String direction;
+    /**
+     * 终角
+     */
+    private String final_angle;
+    /**
+     * 起角
+     */
+    private String start_angle;
+    /**
+     * 半径
+     */
+    private String radius;
+    /**
+     * 圆心X
+     */
+    private String center_x;
+    /**
+     * 圆心Y
+     */
+    private String center_y;
+
+    public static List<ProfilerSectionPush> parameterMapping(List<ProfilerStandardSectionBean> sectionBeans) {
+        return sectionBeans.stream().map(f -> {
+            ProfilerSectionPush sectionPush = new ProfilerSectionPush();
+            sectionPush.setDirection(f.getDirection());
+            sectionPush.setFinal_angle(f.getEndAngle());
+            sectionPush.setStart_angle(f.getStartAngle());
+            sectionPush.setRadius(f.getRadius());
+            sectionPush.setCenter_x(f.getX());
+            sectionPush.setCenter_y(f.getY());
+            return sectionPush;
+        }).collect(Collectors.toList());
+    }
+}

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

@@ -15,6 +15,8 @@ public class NameRuleVo {
     private String nameVaule;
     // 1全部节点 2部分节点
     private Integer type;
+    //资料类型
+    private String remark;
     //文件题名范围
     private List<NameRuleVo1> list=new ArrayList<>();
 

+ 3 - 0
blade-service-api/blade-manager-api/src/main/java/org/springblade/manager/vo/TextdictInfoVO.java

@@ -38,4 +38,7 @@ public class TextdictInfoVO extends TextdictInfo {
 
     @ApiModelProperty("是否引用系统级电签配置,1 系统级,0 项目级")
     private Integer isSystem = 0;
+
+    @ApiModelProperty("元素是否匹配, 1:匹配, 0:不匹配")
+    private Integer isMatch = 1;
 }

+ 10 - 0
blade-service-api/blade-manager-api/src/main/java/org/springblade/manager/vo/TrialTableDataInfo.java

@@ -46,6 +46,16 @@ public class TrialTableDataInfo implements java.io.Serializable {
         return UNKNOWN;
     }
 
+    public static Long getElementId(String key) {
+        TrialTableElementEnum[] values = TrialTableElementEnum.values();
+        for (TrialTableElementEnum value : values) {
+            if (value.key.equals(key)) {
+                return value.id;
+            }
+        }
+        return 0L;
+    }
+
     @Getter
     public static enum TrialTableElementEnum {
         RECORD_NO(203700000001001L, "key_301","recordNo", "记录编号"),

+ 23 - 11
blade-service/blade-archive/src/main/java/org/springblade/archive/service/impl/ArchivesAutoServiceImpl.java

@@ -5369,9 +5369,6 @@ public class ArchivesAutoServiceImpl extends BaseServiceImpl<ArchivesAutoMapper,
 		//List<Long> idsList=Func.toLongList(ids);
 		List<ArchivesAuto> archivesAutoList = this.list(new LambdaQueryWrapper<ArchivesAuto>().in(ArchivesAuto::getId, idsList));
 		for (ArchivesAuto auto : archivesAutoList) {
-			if(auto.getOutUrl()==null||auto.getOutUrl().isEmpty()){
-				continue;
-			}
 			String sql=" select * from u_archive_file where is_deleted = 0 and archive_id="+auto.getId();
 			List<ArchiveFile> archiveFiles = jdbcTemplate.query(sql, new BeanPropertyRowMapper<>(ArchiveFile.class));
 			if(archiveFiles.isEmpty()){
@@ -5393,14 +5390,15 @@ public class ArchivesAutoServiceImpl extends BaseServiceImpl<ArchivesAutoMapper,
 					if(!list.isEmpty()){
 						StringBuilder fileName=new StringBuilder();
 						for (String result : list) {
+							result=result.replaceAll("\\s+", "");
 							if(result.contains("档号")){
 								String fileNum=result.replace("档号","").replace(":","").replace(":","");
 								auto.setFileNumber(fileNum);
 							}else if(result.contains("立卷单位")){
-								String unit=result.replace("立卷单位","").replace(":","").replace(":","");
+								String unit=result.replace("立卷单位","").replace(":","").replace(":","").replaceAll("_","");
 								auto.setUnit(unit);
-							} else if (result.contains("起止日期")) {
-								String time=result.replace("起止日期","").replace(":","").replace(":","");
+							}else if (result.contains("起止日期")) {
+								String time=result.replace("起止日期","").replace(":","").replace(":","").replaceAll("_","");
 								if(result.contains("~")){
 									LocalDateTime[] localDateTimes = convertDateRange(time, "~");
 									auto.setStartDate(localDateTimes[0]);
@@ -5411,16 +5409,30 @@ public class ArchivesAutoServiceImpl extends BaseServiceImpl<ArchivesAutoMapper,
 									auto.setEndDate(localDateTimes[1]);
 								}
 							} else if (result.contains("保管期限")||result.contains("保管限期")) {
-								String storageTime=result.replace("保管期限","").replace("保管限期","").replace(":","").replace(":","");
-								auto.setStorageTime(storageTime);
+								String storageTime=result.replace("保管期限","").replace("保管限期","").replace(":","").replace(":","").replaceAll("_","");
+								if(StringUtils.isNotEmpty(storageTime)){
+									if("10年".equals(storageTime)){
+										auto.setStorageTime("1");
+									} else if("30年".equals(storageTime)){
+										auto.setStorageTime("2");
+									} else{
+										auto.setStorageTime("3");
+									}
+								}
 							} else if (result.contains("密1")||result.contains("密级")) {
-								String secretLevel=result.replace("密1","").replace("密级","");
+								String secretLevel=result.replace("密1","").replace("密级","").replaceAll("_","");
 								auto.setSecretLevel(secretLevel);
 							} else {
-								fileName.append(result);
+								if(StringUtils.isNotEmpty(result)){
+									fileName.append(result);
+									System.out.println("文件题名识别结果:"+result);
+									System.out.println(fileName);
+								}
 							}
 						}
-						auto.setName(fileName.toString());
+						if(StringUtils.isNotEmpty(fileName.toString())){
+							auto.setName(fileName.toString().replace("密级",""));
+						}
 					}
 				}
 			}catch (Exception e){

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

@@ -2003,6 +2003,17 @@ public R<Boolean> diySort(@RequestBody DiySortVO vo) {
         if (needCopyNode != null && ObjectUtil.isNotEmpty(needCopyNode.getContractId())) {
             informationQueryService.delAsyncWbsTree(needCopyNode.getContractId());
         }
+        try {
+            JSONObject json = new JSONObject();
+            json.put("operationObjIds", sortLists);
+            json.put("operationObjName", "节点排序");
+            json.put("projectId", needCopyNode == null ? null : needCopyNode.getProjectId());
+            json.put("contractId", needCopyNode == null ? null : needCopyNode.getContractId());
+            json.put("saveData", vo);
+            operationLogClient.saveUserOperationLog(3, "资料管理", "工序资料", json);
+        } catch (Exception e) {
+            e.printStackTrace();
+        }
     }
     return R.status(b);
 }

+ 137 - 0
blade-service/blade-business/src/main/java/org/springblade/business/controller/TaskProgressController.java

@@ -0,0 +1,137 @@
+/*
+ *      Copyright (c) 2018-2028, Chill Zhuang All rights reserved.
+ *
+ *  Redistribution and use in source and binary forms, with or without
+ *  modification, are permitted provided that the following conditions are met:
+ *
+ *  Redistributions of source code must retain the above copyright notice,
+ *  this list of conditions and the following disclaimer.
+ *  Redistributions in binary form must reproduce the above copyright
+ *  notice, this list of conditions and the following disclaimer in the
+ *  documentation and/or other materials provided with the distribution.
+ *  Neither the name of the dreamlu.net developer nor the names of its
+ *  contributors may be used to endorse or promote products derived from
+ *  this software without specific prior written permission.
+ *  Author: Chill 庄骞 (smallchill@163.com)
+ */
+package org.springblade.business.controller;
+
+import io.swagger.annotations.Api;
+import io.swagger.annotations.ApiOperation;
+import io.swagger.annotations.ApiParam;
+import com.github.xiaoymin.knife4j.annotations.ApiOperationSupport;
+import lombok.AllArgsConstructor;
+import javax.validation.Valid;
+
+import org.springblade.business.entity.TaskProgress;
+import org.springblade.core.mp.support.Condition;
+import org.springblade.core.mp.support.Query;
+import org.springblade.core.tool.api.R;
+import org.springblade.core.tool.utils.Func;
+import org.springblade.business.vo.TaskProgressVO1;
+import org.springframework.web.bind.annotation.*;
+import org.springframework.web.bind.annotation.RequestParam;
+import com.baomidou.mybatisplus.core.metadata.IPage;
+import org.springblade.business.vo.TaskProgressVO;
+import org.springblade.business.service.ITaskProgressService;
+import org.springblade.core.boot.ctrl.BladeController;
+
+import java.util.Map;
+
+/**
+ * 任务进度表 控制器
+ *
+ * @author BladeX
+ * @since 2025-10-15
+ */
+@RestController
+@AllArgsConstructor
+@RequestMapping("/taskProgress")
+@Api(value = "任务进度表", tags = "任务进度表接口")
+public class TaskProgressController extends BladeController {
+
+	private final ITaskProgressService taskProgressService;
+
+	/**
+	 * 详情
+	 */
+	@GetMapping("/detail")
+	@ApiOperationSupport(order = 1)
+	@ApiOperation(value = "详情", notes = "传入taskProgress")
+	public R<TaskProgress> detail(TaskProgress taskProgress) {
+		TaskProgress detail = taskProgressService.getOne(Condition.getQueryWrapper(taskProgress));
+		return R.data(detail);
+	}
+
+	@GetMapping("/getTaskProgress")
+	@ApiOperationSupport(order = 1)
+	@ApiOperation(value = "获取进度", notes = "传入taskProgress")
+	public R<Map<String, TaskProgressVO1>> getTaskProgress(Long projectId, Long contractId){
+		return R.data(taskProgressService.selectNewTaskProgress(projectId,contractId));
+	}
+
+	/**
+	 * 分页 任务进度表
+	 */
+	@GetMapping("/list")
+	@ApiOperationSupport(order = 2)
+	@ApiOperation(value = "分页", notes = "传入taskProgress")
+	public R<IPage<TaskProgress>> list(TaskProgress taskProgress, Query query) {
+		IPage<TaskProgress> pages = taskProgressService.page(Condition.getPage(query), Condition.getQueryWrapper(taskProgress));
+		return R.data(pages);
+	}
+
+	/**
+	 * 自定义分页 任务进度表
+	 */
+	@GetMapping("/page")
+	@ApiOperationSupport(order = 3)
+	@ApiOperation(value = "分页", notes = "传入taskProgress")
+	public R<IPage<TaskProgressVO>> page(TaskProgressVO taskProgress, Query query) {
+		IPage<TaskProgressVO> pages = taskProgressService.selectTaskProgressPage(Condition.getPage(query), taskProgress);
+		return R.data(pages);
+	}
+
+	/**
+	 * 新增 任务进度表
+	 */
+	@PostMapping("/save")
+	@ApiOperationSupport(order = 4)
+	@ApiOperation(value = "新增", notes = "传入taskProgress")
+	public R save(@Valid @RequestBody TaskProgress taskProgress) {
+		return R.status(taskProgressService.save(taskProgress));
+	}
+
+	/**
+	 * 修改 任务进度表
+	 */
+	@PostMapping("/update")
+	@ApiOperationSupport(order = 5)
+	@ApiOperation(value = "修改", notes = "传入taskProgress")
+	public R update(@Valid @RequestBody TaskProgress taskProgress) {
+		return R.status(taskProgressService.updateById(taskProgress));
+	}
+
+	/**
+	 * 新增或修改 任务进度表
+	 */
+	@PostMapping("/submit")
+	@ApiOperationSupport(order = 6)
+	@ApiOperation(value = "新增或修改", notes = "传入taskProgress")
+	public R submit(@Valid @RequestBody TaskProgress taskProgress) {
+		return R.status(taskProgressService.saveOrUpdate(taskProgress));
+	}
+
+	
+	/**
+	 * 删除 任务进度表
+	 */
+	@PostMapping("/remove")
+	@ApiOperationSupport(order = 7)
+	@ApiOperation(value = "逻辑删除", notes = "传入ids")
+	public R remove(@ApiParam(value = "主键集合", required = true) @RequestParam String ids) {
+		return R.status(taskProgressService.deleteLogic(Func.toLongList(ids)));
+	}
+
+	
+}

+ 23 - 0
blade-service/blade-business/src/main/java/org/springblade/business/feignClient/TaskProgressClientImpl.java

@@ -0,0 +1,23 @@
+package org.springblade.business.feignClient;
+
+import lombok.AllArgsConstructor;
+
+import org.springblade.business.feign.TaskProgressClient;
+import org.springblade.business.service.ITaskProgressService;
+import org.springframework.web.bind.annotation.RestController;
+
+@RestController
+@AllArgsConstructor
+public class TaskProgressClientImpl implements TaskProgressClient {
+
+
+    private final ITaskProgressService taskProgressService;
+
+
+
+
+    @Override
+    public Boolean updateTaskProgress(Long projectId, Long contractId, Integer type, Integer finishTotal,String dataId) {
+        return taskProgressService.updateTaskProgress(projectId, contractId, type, finishTotal,dataId);
+    }
+}

+ 2 - 2
blade-service/blade-business/src/main/java/org/springblade/business/mapper/ArchiveFileMapper.xml

@@ -97,7 +97,7 @@
         <if test="vo.sourceType != null and vo.sourceType != ''">
             and u.source_type = #{vo.sourceType}
         </if>
-        <if test="vo.isArchive != null and vo.isArchive != ''">
+        <if test="vo.isArchive != null">
             <choose>
                 <when test="vo.isArchive == 0">
                     AND (u.is_archive = #{vo.isArchive} OR u.is_archive IS NULL)
@@ -183,7 +183,7 @@
         <if test="vo.sourceType != null and vo.sourceType != ''">
             and u.source_type = #{vo.sourceType}
         </if>
-        <if test="vo.isArchive != null and vo.isArchive != ''">
+        <if test="vo.isArchive != null">
             <choose>
                 <when test="vo.isArchive == 0">
                     AND (u.is_archive = #{vo.isArchive} OR u.is_archive IS NULL)

+ 53 - 0
blade-service/blade-business/src/main/java/org/springblade/business/mapper/TaskProgressMapper.java

@@ -0,0 +1,53 @@
+/*
+ *      Copyright (c) 2018-2028, Chill Zhuang All rights reserved.
+ *
+ *  Redistribution and use in source and binary forms, with or without
+ *  modification, are permitted provided that the following conditions are met:
+ *
+ *  Redistributions of source code must retain the above copyright notice,
+ *  this list of conditions and the following disclaimer.
+ *  Redistributions in binary form must reproduce the above copyright
+ *  notice, this list of conditions and the following disclaimer in the
+ *  documentation and/or other materials provided with the distribution.
+ *  Neither the name of the dreamlu.net developer nor the names of its
+ *  contributors may be used to endorse or promote products derived from
+ *  this software without specific prior written permission.
+ *  Author: Chill 庄骞 (smallchill@163.com)
+ */
+package org.springblade.business.mapper;
+
+import org.apache.ibatis.annotations.Param;
+import org.springblade.business.entity.TaskProgress;
+import org.springblade.business.vo.TaskProgressVO;
+import com.baomidou.mybatisplus.core.mapper.BaseMapper;
+import com.baomidou.mybatisplus.core.metadata.IPage;
+
+import java.util.List;
+
+/**
+ * 任务进度表 Mapper 接口
+ *
+ * @author BladeX
+ * @since 2025-10-15
+ */
+public interface TaskProgressMapper extends BaseMapper<TaskProgress> {
+
+	/**
+	 * 自定义分页
+	 *
+	 * @param page
+	 * @param taskProgress
+	 * @return
+	 */
+	List<TaskProgressVO> selectTaskProgressPage(IPage page, TaskProgressVO taskProgress);
+
+	TaskProgressVO selectNewTaskProgress(@Param("projectId") Long projectId, @Param("contractId") Long contractId,@Param("type") Integer type);
+
+	void addFinishTotalById(@Param("id") Long id, @Param("finishTotal") Integer finishTotal);
+
+	void checkAndUpdateIsFinish(@Param("id") Long id);
+
+	TaskProgressVO selectNewTaskProgress1(@Param("projectId") Long projectId, @Param("contractId") Long contractId, @Param("type") Integer type);
+
+	Integer selectTaskBatchSize(@Param("dataIds") List<Long> dataIds);
+}

+ 58 - 0
blade-service/blade-business/src/main/java/org/springblade/business/mapper/TaskProgressMapper.xml

@@ -0,0 +1,58 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!DOCTYPE mapper PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN" "http://mybatis.org/dtd/mybatis-3-mapper.dtd">
+<mapper namespace="org.springblade.business.mapper.TaskProgressMapper">
+
+    <!-- 通用查询映射结果 -->
+    <resultMap id="taskProgressResultMap" type="org.springblade.business.entity.TaskProgress">
+        <result column="id" property="id"/>
+        <result column="create_user" property="createUser"/>
+        <result column="create_dept" property="createDept"/>
+        <result column="create_time" property="createTime"/>
+        <result column="update_user" property="updateUser"/>
+        <result column="update_time" property="updateTime"/>
+        <result column="status" property="status"/>
+        <result column="is_deleted" property="isDeleted"/>
+        <result column="project_id" property="projectId"/>
+        <result column="contract_id" property="contractId"/>
+        <result column="type" property="type"/>
+        <result column="task_total" property="taskTotal"/>
+        <result column="finish_tatol" property="finishTatol"/>
+        <result column="is_finish" property="isFinish"/>
+    </resultMap>
+    <update id="addFinishTotalById">
+        update m_task_progress set finish_tatol = finish_tatol + #{finishTotal} where id = #{id}
+    </update>
+    <update id="checkAndUpdateIsFinish">
+        update m_task_progress set is_finish = 1 where id = #{id} and finish_tatol >= task_total
+    </update>
+
+
+    <select id="selectTaskProgressPage" resultMap="taskProgressResultMap">
+        select * from m_task_progress where is_deleted = 0
+    </select>
+    <select id="selectNewTaskProgress" resultType="org.springblade.business.vo.TaskProgressVO">
+        select * from m_task_progress where is_deleted = 0 and project_id = #{projectId} and contract_id = #{contractId} and type = #{type} and is_finish=0 order by create_time desc limit 1
+    </select>
+    <select id="selectNewTaskProgress1" resultType="org.springblade.business.vo.TaskProgressVO">
+        select * from m_task_progress where is_deleted = 0 and project_id = #{projectId} and contract_id = #{contractId} and type = #{type}  order by create_time desc limit 1
+    </select>
+    <select id="selectTaskBatchSize" resultType="java.lang.Integer">
+        SELECT COUNT(*)
+        FROM (
+        SELECT DISTINCT JSON_UNQUOTE(JSON_EXTRACT(utb.json_data, '$.taskId')) as taskId
+        FROM u_task_batch utb
+        INNER JOIN m_task_progress mtp
+        ON FIND_IN_SET(
+        JSON_UNQUOTE(JSON_EXTRACT(utb.json_data, '$.formDataId')),
+        mtp.data_id
+        ) > 0
+        <if test="dataIds != null and dataIds.size() > 0">
+            WHERE JSON_UNQUOTE(JSON_EXTRACT(utb.json_data, '$.formDataId')) IN
+            <foreach collection="dataIds" item="id" open="(" close=")" separator=",">
+                #{id}
+            </foreach>
+        </if>
+        ) distinct_tasks
+    </select>
+
+</mapper>

+ 6 - 0
blade-service/blade-business/src/main/java/org/springblade/business/mapper/WbsTreeContractStatisticsMapper.xml

@@ -38,6 +38,12 @@
         SET a.leaf_num = ifnull(t.leaf_num, a.leaf_num), a.fill_num = ifnull(t.fill_num, a.fill_num),a.approve_num = ifnull(t.approve_num, a.approve_num),
             a.complete_num = ifnull(t.complete_num, a.complete_num), a.jl_fill_num = ifnull(t.jl_fill_num, a.jl_fill_num), a.jl_approve_num = ifnull(t.jl_approve_num, a.jl_approve_num),
             a.jl_complete_num = ifnull(t.jl_complete_num, a.jl_complete_num), a.is_leaf = if(t.leaf_num > 0, 0, 1);
+        update m_wbs_tree_contract_statistics a set fill_num = 0, approve_num = 0, complete_num = 0, jl_fill_num= 0, jl_approve_num = 0, jl_complete_num = 0
+                                                where (is_leaf = 1 or leaf_num = 0) and is_deleted = 0 and id in (
+        <foreach collection="ids" item="item" separator=",">
+            #{item}
+        </foreach>
+        ) and not exists (SELECT 1 from m_wbs_tree_contract where p_id = a.id and is_deleted = 0);
     </update>
     <select id="getByIdOnLock" resultMap="ResultMap">
         select <include refid="includeSql"/> from m_wbs_tree_contract_statistics where id = #{id} for update

+ 49 - 0
blade-service/blade-business/src/main/java/org/springblade/business/service/ITaskProgressService.java

@@ -0,0 +1,49 @@
+/*
+ *      Copyright (c) 2018-2028, Chill Zhuang All rights reserved.
+ *
+ *  Redistribution and use in source and binary forms, with or without
+ *  modification, are permitted provided that the following conditions are met:
+ *
+ *  Redistributions of source code must retain the above copyright notice,
+ *  this list of conditions and the following disclaimer.
+ *  Redistributions in binary form must reproduce the above copyright
+ *  notice, this list of conditions and the following disclaimer in the
+ *  documentation and/or other materials provided with the distribution.
+ *  Neither the name of the dreamlu.net developer nor the names of its
+ *  contributors may be used to endorse or promote products derived from
+ *  this software without specific prior written permission.
+ *  Author: Chill 庄骞 (smallchill@163.com)
+ */
+package org.springblade.business.service;
+
+import org.springblade.business.entity.TaskProgress;
+import org.springblade.business.vo.TaskProgressVO;
+import org.springblade.core.mp.base.BaseService;
+import com.baomidou.mybatisplus.core.metadata.IPage;
+import org.springblade.business.vo.TaskProgressVO1;
+
+import java.util.Map;
+
+/**
+ * 任务进度表 服务类
+ *
+ * @author BladeX
+ * @since 2025-10-15
+ */
+public interface ITaskProgressService extends BaseService<TaskProgress> {
+
+	/**
+	 * 自定义分页
+	 *
+	 * @param page
+	 * @param taskProgress
+	 * @return
+	 */
+	IPage<TaskProgressVO> selectTaskProgressPage(IPage<TaskProgressVO> page, TaskProgressVO taskProgress);
+
+	Map<String, TaskProgressVO1> selectNewTaskProgress(Long projectId, Long contractId);
+
+	Boolean updateTaskProgress(Long projectId,Long contractId,Integer type,Integer finishTotal,String dataId);
+
+	Boolean addTaskProgress(Long projectId,Long contractId,Integer type,Integer taskTotal,String dataIds);
+}

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

@@ -137,6 +137,6 @@ public interface ITaskService extends BaseService<Task> {
 
     void logSaveAgain(LogSaveAgainDto dto) throws Exception;
 
-    //
+    //一键重签
     R reSigningEVisaByUserIds(String ids, String userIds);
 }

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

@@ -35,6 +35,7 @@ import org.springblade.manager.entity.TabBusstimeInfo;
 import org.springblade.manager.entity.WbsTreeContract;
 import org.springblade.manager.feign.ContractClient;
 import org.springblade.manager.feign.WbsTreeContractClient;
+import org.springblade.business.service.ITaskProgressService;
 import org.springblade.manager.vo.WbsTreeContractTreeVOS;
 import org.springblade.resource.feign.NewIOSSClient;
 import org.springblade.system.cache.ParamCache;
@@ -44,7 +45,6 @@ import org.springframework.beans.factory.annotation.Autowired;
 import org.springframework.data.redis.core.StringRedisTemplate;
 import org.springframework.jdbc.core.BeanPropertyRowMapper;
 import org.springframework.jdbc.core.JdbcTemplate;
-import org.springframework.scheduling.annotation.Async;
 import org.springframework.stereotype.Service;
 
 import java.io.File;
@@ -83,6 +83,7 @@ public class InformationQueryServiceImpl extends BaseServiceImpl<InformationQuer
 
     private final JdbcTemplate jdbcTemplate;
     private final IOperationLogService operationLogService;
+    private final ITaskProgressService taskProgressService;
 
     @Autowired
     StringRedisTemplate RedisTemplate;

+ 159 - 0
blade-service/blade-business/src/main/java/org/springblade/business/service/impl/TaskProgressServiceImpl.java

@@ -0,0 +1,159 @@
+/*
+ *      Copyright (c) 2018-2028, Chill Zhuang All rights reserved.
+ *
+ *  Redistribution and use in source and binary forms, with or without
+ *  modification, are permitted provided that the following conditions are met:
+ *
+ *  Redistributions of source code must retain the above copyright notice,
+ *  this list of conditions and the following disclaimer.
+ *  Redistributions in binary form must reproduce the above copyright
+ *  notice, this list of conditions and the following disclaimer in the
+ *  documentation and/or other materials provided with the distribution.
+ *  Neither the name of the dreamlu.net developer nor the names of its
+ *  contributors may be used to endorse or promote products derived from
+ *  this software without specific prior written permission.
+ *  Author: Chill 庄骞 (smallchill@163.com)
+ */
+package org.springblade.business.service.impl;
+
+import org.apache.commons.lang.StringUtils;
+import org.springblade.common.utils.SnowFlakeUtil;
+import org.springblade.business.entity.TaskProgress;
+import org.springblade.business.vo.TaskProgressVO;
+import org.springblade.business.mapper.TaskProgressMapper;
+import org.springblade.business.service.ITaskProgressService;
+import org.springblade.core.mp.base.BaseServiceImpl;
+import org.springblade.business.vo.TaskProgressVO1;
+import org.springblade.core.tool.utils.Func;
+import org.springframework.stereotype.Service;
+import com.baomidou.mybatisplus.core.metadata.IPage;
+
+import java.math.BigDecimal;
+import java.math.RoundingMode;
+import java.util.Collections;
+import java.util.HashMap;
+import java.util.Map;
+
+/**
+ * 任务进度表 服务实现类
+ *
+ * @author BladeX
+ * @since 2025-10-15
+ */
+@Service
+public class TaskProgressServiceImpl extends BaseServiceImpl<TaskProgressMapper, TaskProgress> implements ITaskProgressService {
+
+	@Override
+	public IPage<TaskProgressVO> selectTaskProgressPage(IPage<TaskProgressVO> page, TaskProgressVO taskProgress) {
+		return page.setRecords(baseMapper.selectTaskProgressPage(page, taskProgress));
+	}
+
+	@Override
+	public Map<String, TaskProgressVO1> selectNewTaskProgress(Long projectId, Long contractId) {
+		Map<String, TaskProgressVO1> map = new HashMap<>();
+		TaskProgressVO vo1 = baseMapper.selectNewTaskProgress1(projectId, contractId,1);
+		if(vo1!=null){
+			BigDecimal result = (vo1.getTaskTotal() != null && vo1.getTaskTotal() > 0 && vo1.getFinishTatol() != null) ?
+					new BigDecimal(vo1.getFinishTatol())
+							.divide(new BigDecimal(vo1.getTaskTotal()), 2, RoundingMode.HALF_UP)
+							.multiply(new BigDecimal(100)) :
+					BigDecimal.ZERO;
+			map.put("save-again", new TaskProgressVO1(vo1.getFinishTatol(),vo1.getTaskTotal(),result));
+		}
+		TaskProgressVO vo2 = baseMapper.selectNewTaskProgress1(projectId, contractId,2);
+		if(vo2!=null){
+			Integer size=0;
+			if(StringUtils.isNotEmpty(vo2.getDataId())){
+				size=baseMapper.selectTaskBatchSize(Func.toLongList(vo2.getDataId()));
+			}
+			Integer finishTatol=vo2.getTaskTotal()-size;
+			// 使用 BigDecimal 进行精确计算并保留两位小数
+			BigDecimal result = vo2.getTaskTotal() > 0 ?
+					new BigDecimal(finishTatol).divide(new BigDecimal(vo2.getTaskTotal()), 2, RoundingMode.HALF_UP).multiply(new BigDecimal(100)) :
+					BigDecimal.ZERO;
+			result = result.setScale(2, RoundingMode.HALF_UP);
+			map.put("re-sign", new TaskProgressVO1(finishTatol,vo2.getTaskTotal(),result));
+			if(size==0){
+				vo2.setIsDeleted(0);
+				baseMapper.updateById(vo2);
+			}
+		}
+		TaskProgressVO vo3 = baseMapper.selectNewTaskProgress1(projectId, contractId,4);
+		if(vo3!=null){
+			Integer size=0;
+			if(StringUtils.isNotEmpty(vo3.getDataId())){
+				size=baseMapper.selectTaskBatchSize(Func.toLongList(vo3.getDataId()));
+			}
+			Integer finishTatol=vo3.getTaskTotal()-size;
+			// 使用 BigDecimal 进行精确计算并保留两位小数
+			BigDecimal result = vo3.getTaskTotal() > 0 ?
+					new BigDecimal(finishTatol).divide(new BigDecimal(vo3.getTaskTotal()), 2, RoundingMode.HALF_UP).multiply(new BigDecimal(100)) :
+					BigDecimal.ZERO;
+			result = result.setScale(2, RoundingMode.HALF_UP);
+			map.put("electronic-sign", new TaskProgressVO1(finishTatol,vo3.getTaskTotal(),result));
+			if(size==0){
+				vo3.setIsDeleted(0);
+				baseMapper.updateById(vo3);
+			}
+		}
+		return map;
+	}
+
+	/**
+	 * 完成任务后更新进度
+	 * @param projectId
+	 * @param contractId
+	 * @param type 1.sava_again 2.re_sign 3.电签检测 4.一键电签
+	 * @param finishTotal
+	 * @return
+	 */
+	public Boolean updateTaskProgress(Long projectId,Long contractId,Integer type,Integer finishTotal,String dataId) {
+		TaskProgressVO vo = baseMapper.selectNewTaskProgress(projectId, contractId,type);
+		if (vo==null) {
+			return false;
+		} else if (StringUtils.isNotEmpty(dataId)&&StringUtils.isNotEmpty(vo.getDataId())) {
+			if(!vo.getDataId().contains(dataId)){
+				return false;
+			}
+		}
+		if(vo.getIsFinish()!=1){
+			baseMapper.addFinishTotalById(vo.getId(),finishTotal);
+			baseMapper.checkAndUpdateIsFinish(vo.getId());
+		}
+		return true;
+	}
+
+	/**
+	 * 添加任务进度
+	 * @param projectId
+	 * @param contractId
+	 * @param type
+	 * @param taskTotal
+	 * @param dataIds
+	 * @return
+	 */
+	public Boolean addTaskProgress(Long projectId,Long contractId,Integer type,Integer taskTotal,String dataIds) {
+		TaskProgressVO vo = baseMapper.selectNewTaskProgress(projectId, contractId,type);
+		if(vo==null){
+			TaskProgress progress = new TaskProgress();
+			progress.setId(SnowFlakeUtil.getId());
+			progress.setProjectId(projectId);
+			progress.setContractId(contractId);
+			progress.setType(type);
+			progress.setTaskTotal(taskTotal);
+			progress.setFinishTatol(0);
+			progress.setIsFinish(0);
+			if(StringUtils.isNotEmpty(dataIds)){
+				progress.setDataId(dataIds);
+			}
+			baseMapper.insert(progress);
+		}else {
+			vo.setTaskTotal(vo.getTaskTotal()+taskTotal);
+			if(StringUtils.isNotEmpty(dataIds)){
+				vo.setDataId(vo.getDataId()+","+dataIds);
+			}
+			baseMapper.updateById(vo);
+		}
+		return true;
+	}
+}

+ 10 - 7
blade-service/blade-business/src/main/java/org/springblade/business/service/impl/TaskServiceImpl.java

@@ -43,10 +43,7 @@ import org.springblade.flow.core.feign.IFlowClient;
 import org.springblade.flow.core.feign.NewFlowClient;
 import org.springblade.flow.core.utils.FlowUtil;
 
-import org.springblade.manager.entity.ContractInfo;
-import org.springblade.manager.entity.ProjectInfo;
-import org.springblade.manager.entity.TabBusstimeInfo;
-import org.springblade.manager.entity.WbsTreeContract;
+import org.springblade.manager.entity.*;
 import org.springblade.manager.feign.*;
 import org.springblade.manager.vo.AppWbsTreeContractVO;
 import org.springblade.manager.vo.WbsTreePrivateVO4;
@@ -142,6 +139,8 @@ public class TaskServiceImpl extends BaseServiceImpl<TaskMapper, Task> implement
 
     private final ITrialSelfInspectionRecordService iTrialSelfInspectionRecordService;
 
+    private final ITaskProgressService taskProgressService;
+
 
     @Override
     public List<TaskParallel> queryApprovalUser(String formDataIds) {
@@ -1972,6 +1971,7 @@ public class TaskServiceImpl extends BaseServiceImpl<TaskMapper, Task> implement
                     .in(InformationQuery::getId, newIds));
             List<InformationQuery> list = informationQueryService.list(new LambdaQueryWrapper<>(InformationQuery.class).in(InformationQuery::getId, newIds));
             recordResignLog("save-again", StringUtils.join(newIds, ","), list, dtos, dtos.get(0).getProjectId()+"", dtos.get(0).getContractId()+"", null);
+            taskProgressService.addTaskProgress(dtos.get(0).getProjectId(), dtos.get(0).getContractId(), 1,dtos.size(),StringUtils.join(newIds, ","));
         }
         return R.success("操作成功");
     }
@@ -2008,8 +2008,10 @@ public class TaskServiceImpl extends BaseServiceImpl<TaskMapper, Task> implement
             Map<String, List<TaskParallel>> finalTaskParallelGroupMap = taskParallelGroupMap;
             //获取每条任务对应的节点信息
             List<String> dataIdList = taskList.stream().map(Task::getFormDataId).filter(ObjectUtil::isNotEmpty).collect(Collectors.toList());
+            //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() + ""));
             List<InformationQuery> list = informationQueryService.list(Wrappers.<InformationQuery>lambdaQuery().in(InformationQuery::getId, dataIdList));
-            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() + ""));
+            taskProgressService.addTaskProgress(Long.parseLong(projectId), Long.parseLong(contractId), 2,taskList.size(),StringUtils.join(dataIdList, ","));
+            Map<String, String> queryMap=list.stream().collect(Collectors.toMap(l -> l.getId() + "", l -> l.getWbsId() + ""));
             Map<String, String> typeMap = 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.getClassify() + ""));
 
             try {
@@ -2340,10 +2342,10 @@ public class TaskServiceImpl extends BaseServiceImpl<TaskMapper, Task> implement
             }
             ids2 = ids2.substring(0, ids2.length() - 1);
         }
-        List<InformationQuery> queryList = jdbcTemplate.query("select id, e_visa_pdf_url, status from u_information_query where id in( " + ids + ") and is_deleted=0 and status in (1,2)", new BeanPropertyRowMapper<>(InformationQuery.class));
+        List<InformationQuery> queryList = jdbcTemplate.query("select id, e_visa_pdf_url, status ,project_id,contract_id from u_information_query where id in( " + ids + ") and is_deleted=0 and status in (1,2)", new BeanPropertyRowMapper<>(InformationQuery.class));
         String sqlqu = "update u_information_query set status=2,e_visa_pdf_url='' where id in( " + ids + ") and is_deleted=0 and status in (1,2)";
         String sqlForTask = "update u_task set status=2 where form_data_id in( " + ids2 + ") and status in(1,2) and is_deleted=0 ";
-        String sqlForTaskPall = "update u_task_parallel a INNER JOIN u_task b on a.process_instance_id = b.process_instance_id set a.is_resign = 1, a.`status`=2 , a.e_visa_status=1 ,a.e_visa_content='电签成功' where b.form_data_id in( " + ids2 + ") and b.status in(0,1,2) and b.is_deleted = 0 and a.`status` in(0,1)";
+        String sqlForTaskPall = "update u_task_parallel a INNER JOIN u_task b on a.process_instance_id = b.process_instance_id set a.is_resign = 1, a.`status`=2 , a.e_visa_status=1 ,a.e_visa_content='电签成功' where b.form_data_id in( " + ids2 + ") and b.status in(0,1,2) and b.is_deleted = 0 and a.`status` in(0,1,3)";
 
         String taskBtech = "insert into u_task_batch(id,task_parallel_id,json_data,create_user,create_dept,create_time,update_user,update_time,status,is_deleted,nick_name,sign_format,sign_type)  " +
                 " SELECT a.id,a.process_instance_id,json_object('approvalFileList',json_array(),'approvalType',b.approval_type,'comment','','flag','OK','formDataId',b.form_data_id,'parallelProcessInstanceId',a.parallel_process_instance_id,'pass',true,'taskId',b.id) as  json_data,a.task_user,a.create_dept,a.create_time,a.update_user,SYSDATE(),1 as status,0 as is_deleted,a.task_user_name as nick_name ,1 as sign_format,1 as sign_type from u_task_parallel a,u_task b where b.`status` in(1,2) and a.`status` in(2)  and   a.process_instance_id=b.process_instance_id " +
@@ -2368,6 +2370,7 @@ public class TaskServiceImpl extends BaseServiceImpl<TaskMapper, Task> implement
             requestMap.put("userIds", userIds);
             recordResignLog("一键重签", ids, queryList, requestMap, null, null, null);
         }
+        taskProgressService.addTaskProgress(queryList.get(0).getProjectId(), queryList.get(0).getContractId(), 4,queryList.size(),ids);
         return R.success("操作成功");
     }
 

+ 7 - 0
blade-service/blade-business/src/main/java/org/springblade/business/service/impl/TrialSelfInspectionRecordServiceImpl.java

@@ -1156,6 +1156,10 @@ public class TrialSelfInspectionRecordServiceImpl extends BaseServiceImpl<TrialS
         if (ObjectUtil.isNotEmpty(dto.getId())) {
             dto.setTableIds(null);
         }
+
+        //获取之前关联的委托单id
+        TrialSelfInspectionRecord oldData = baseMapper.selectById(dto.getId());
+        
         this.saveOrUpdate(dto);
         dto.setTableIds(tableIds);
         if (ObjectUtil.isNotEmpty(dto.getId())) {
@@ -1187,6 +1191,9 @@ public class TrialSelfInspectionRecordServiceImpl extends BaseServiceImpl<TrialS
             //修改项目节点基础信息
             jdbcTemplate.update("update u_entrust_info set sample_status=4 where id ='" + dto.getEntrustId() + "'");
         }
+        if(oldData != null && oldData.getEntrustId() != null && dto.getEntrustId() == null){
+            entrustInfoService.update(Wrappers.<EntrustInfo>lambdaUpdate().eq(EntrustInfo::getId, oldData.getEntrustId()).set(EntrustInfo::getExpCount, 0));
+        }
         String[] strings = dto.getTableType().split(",");
         if (StringUtils.isNotEmpty(dto.getRecordAutoNumber()) || StringUtils.isNotEmpty(dto.getReportAutoNumber())) {
             if (dto.getOldRecordNumber() != null && dto.getOldRecordNumber().equals(dto.getRecordNo()) || dto.getOldReportNumber() != null && dto.getOldReportNumber().equals(dto.getReportNo())) {

+ 4 - 11
blade-service/blade-business/src/main/java/org/springblade/business/sync/TaskSync.java

@@ -1,26 +1,18 @@
 package org.springblade.business.sync;
 
 import cn.hutool.core.date.DateTime;
-import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
 import com.baomidou.mybatisplus.core.conditions.update.LambdaUpdateWrapper;
 import com.baomidou.mybatisplus.core.toolkit.CollectionUtils;
 import com.baomidou.mybatisplus.core.toolkit.Wrappers;
-import com.google.common.collect.Lists;
 import lombok.AllArgsConstructor;
 import lombok.extern.slf4j.Slf4j;
-import org.springblade.business.dto.reSigningEVisaStatus;
 import org.springblade.business.entity.InformationQuery;
-import org.springblade.business.service.IInformationQueryFileService;
 import org.springblade.business.service.IInformationQueryService;
 import org.springblade.common.utils.SystemUtils;
-import org.springblade.core.log.exception.ServiceException;
-import org.springblade.core.redis.cache.BladeRedis;
 import org.springblade.core.tool.api.R;
-import org.springblade.manager.entity.WbsTreeSynchronousRecord;
 import org.springblade.manager.feign.ExcelTabClient;
+import org.springblade.business.feign.TaskProgressClient;
 import org.springblade.system.user.feign.IUserClient;
-import org.springframework.beans.factory.annotation.Autowired;
-import org.springframework.scheduling.annotation.Async;
 import org.springframework.scheduling.annotation.Scheduled;
 import org.springframework.stereotype.Component;
 
@@ -29,7 +21,6 @@ import java.util.ArrayList;
 import java.util.List;
 import java.util.concurrent.CompletableFuture;
 import java.util.concurrent.ThreadPoolExecutor;
-import java.util.stream.Collectors;
 
 /**
  * @author LHB
@@ -49,6 +40,8 @@ public class TaskSync {
     @Resource
     private IUserClient userClient;
 
+    private final TaskProgressClient taskProgressClient;
+
 
     public void reSigningEVisaStatusSync(InformationQuery dto, String header) {
         log.info("数据正在重刷,线程名称:{}", Thread.currentThread().getName());
@@ -75,7 +68,7 @@ public class TaskSync {
         }
         lambda.set(InformationQuery::getUpdateTime, DateTime.now());
         lambda.eq(InformationQuery::getId, dto.getId());
-
+        taskProgressClient.updateTaskProgress(dto.getProjectId(), dto.getContractId(), 1, 1,dto.getId()+"");
         informationQueryService.update(lambda);
         log.info("数据重刷完毕,线程名称:{}", Thread.currentThread().getName());
     }

+ 3 - 0
blade-service/blade-e-visa/src/main/java/org/springblade/evisa/service/impl/EVDataServiceImpl.java

@@ -15,6 +15,7 @@ import org.springblade.business.entity.InformationQuery;
 import org.springblade.business.entity.TrialSelfInspectionRecord;
 import org.springblade.business.feign.MessageWarningClient;
 import org.springblade.business.feign.TaskClient;
+import org.springblade.business.feign.TaskProgressClient;
 import org.springblade.business.vo.TaskSignInfoVO;
 import org.springblade.business.vo.TrialRawMaterialSelfRecord;
 import org.springblade.common.constant.CommonConstant;
@@ -69,6 +70,8 @@ public class EVDataServiceImpl implements EVDataService {
     @Autowired
      private final MessageWarningClient messageWarningClient;
 
+    private final TaskProgressClient taskProgressClient;
+
     /**
      * 电签主要流程
      *

+ 2 - 1
blade-service/blade-e-visa/src/main/java/org/springblade/evisa/service/impl/ScrDataServiceImpl.java

@@ -10,10 +10,10 @@ import org.springblade.business.vo.ScrSignInfoVO;
 import org.springblade.common.utils.CommonUtil;
 import org.springblade.core.tool.utils.CollectionUtil;
 import org.springblade.core.tool.utils.Func;
-import org.springblade.core.tool.utils.StringUtil;
 import org.springblade.evisa.service.ScrDataService;
 import org.springblade.evisa.utils.PdfAddimgUtil;
 import org.springblade.evisa.vo.SignKeyVO;
+import org.springblade.business.feign.TaskProgressClient;
 import org.springblade.manager.vo.PDFIndexInfo;
 import org.springframework.data.redis.core.StringRedisTemplate;
 import org.springframework.jdbc.core.JdbcTemplate;
@@ -29,6 +29,7 @@ public class ScrDataServiceImpl implements ScrDataService {
 
     private final JdbcTemplate jdbcTemplate;
     private final StringRedisTemplate RedisTemplate;
+
     // 主流程
     @Override
     public void sctTaskBatch(ScrSignInfoVO taskApp) throws Exception {

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

@@ -478,6 +478,15 @@ public class CustomFunction {
            return "";
     }
 
+    //天气 - 气温
+    public static Object weathertem( Object dateObj,Map<String,Object> map){
+        if(dateObj!=null&&map!=null){
+            List<Object> date=obj2ListObj(dateObj);
+            return  date.stream().map(StringUtils::handleNull).filter(StringUtils::isNotEmpty).map(e->map.get(new DateTime(FormulaUtils.range2end(e)).toString(DatePattern.NORM_DATE_PATTERN))).collect(Collectors.toList());
+        }
+        return "";
+    }
+
     // 获取最大温度
     public static Object maxtembydate( Object dateObj,Map<String,Object> map){
         if(dateObj!=null&&map!=null){
@@ -496,7 +505,23 @@ public class CustomFunction {
         return "";
     }
 
+    // 获取星期几
+    public static Object weekbydate( Object dateObj,Map<String,Object> map){
+        if(dateObj!=null&&map!=null){
+            List<Object> date=obj2ListObj(dateObj);
+            return  date.stream().map(StringUtils::handleNull).filter(StringUtils::isNotEmpty).map(e->map.get(new DateTime(FormulaUtils.range2end(e)).toString(DatePattern.NORM_DATE_PATTERN))).collect(Collectors.toList());
+        }
+        return "";
+    }
 
+    // 获取最大温度
+    public static Object maxminbydate( Object dateObj,Map<String,Object> map){
+        if(dateObj!=null&&map!=null){
+            List<Object> date=obj2ListObj(dateObj);
+            return  date.stream().map(StringUtils::handleNull).filter(StringUtils::isNotEmpty).map(e->map.get(new DateTime(FormulaUtils.range2end(e)).toString(DatePattern.NORM_DATE_PATTERN))).collect(Collectors.toList());
+        }
+        return "";
+    }
 
     public static List<Object> obj2ListObj(Object input) {
         if (input == null) {

+ 2 - 0
blade-service/blade-manager/src/main/java/org/springblade/manager/bean/TableInfo.java

@@ -27,6 +27,8 @@ public class TableInfo {
     private String groupId = "0";
     // 用于实验
     private String testGroupId = "0";
+    //清楚字段数据时 是否删除附表 0否 1是
+    private String isRemoveForSubTab;
 
 
     /**

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

@@ -11,6 +11,7 @@ import com.baomidou.mybatisplus.core.conditions.update.LambdaUpdateWrapper;
 import com.baomidou.mybatisplus.core.conditions.update.UpdateWrapper;
 import com.baomidou.mybatisplus.core.metadata.IPage;
 import com.baomidou.mybatisplus.core.toolkit.Wrappers;
+import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
 import com.github.xiaoymin.knife4j.annotations.ApiOperationSupport;
 import com.google.gson.Gson;
 import com.spire.xls.*;
@@ -669,7 +670,7 @@ public class ExcelTabController extends BladeController {
                 }
             }
         }
-
+        saveOldHtmlConfig(aPrivate, doc);
         File writefile = new File(thmlUrl);
         FileUtil.writeToFile(writefile, doc.html(), Boolean.parseBoolean("UTF-8"));
 
@@ -715,6 +716,114 @@ public class ExcelTabController extends BladeController {
         return R.success("关联成功");
     }
 
+    public void saveOldHtmlConfig(WbsTreePrivate wbsTreePrivate, Document doc){
+        // 获取原默认值配置
+        List<TextdictInfoVO> defaultConfigs = new ArrayList<>();
+        {
+            IPage<TextdictInfoVO> result = textdictInfoService.analysisHtmlDefault(wbsTreePrivate.getPKeyId() + "");
+            if (result != null && result.getRecords() != null && !result.getRecords().isEmpty()) {
+                defaultConfigs.addAll(result.getRecords());
+            }
+        }
+        // 将原配置信息写入到新的html中,先通过colKey匹配,再通过colName匹配。如果匹配不上,则保存到数据库。后续手动配置、修改
+        defaultConfigs.removeIf(config -> {
+            String colKey = config.getColKey();
+            Element element = null;
+            String colName = config.getColName();
+            if (colKey != null && !colKey.isEmpty()) {
+                element = doc.select("[keyname='" + config.getColKey() + "']").first();
+                if (element != null && colName != null) {
+                    String placeholder = element.attr("placeholder");
+                    if (!StringCNUtils.compareStringIgnoreSpaceAndSymbols(placeholder, colName)) {
+                        element = null;
+                    }
+                }
+            }
+            if (element != null) {
+                element.removeAttr("defText");
+                element.attr("defText", config.getSigRoleName());
+                return true;
+            }
+            return config.getId() != null && config.getId() > 0;
+        });
+        if (!defaultConfigs.isEmpty()) {
+            List<TextdictInfo> saves = new ArrayList<>();
+            defaultConfigs.forEach(config -> {
+                TextdictInfo info = new TextdictInfo();
+                info.setId(SnowFlakeUtil.getId());
+                info.setTabId(wbsTreePrivate.getPKeyId() + "");
+                info.setExcelId(wbsTreePrivate.getExcelId() == null ? null : wbsTreePrivate.getExcelId() + "");
+                info.setType(config.getType());
+                info.setColKey(config.getColKey());
+                info.setColName(config.getColName());
+                info.setSigRoleName(config.getSigRoleName());
+                info.setProjectId(wbsTreePrivate.getProjectId());
+                info.setName("编辑默认值");
+                saves.add( info);
+            });
+            textdictInfoService.saveOrUpdateBatch(saves);
+        }
+        // 获取原电签配置
+        TextdictInfoVO textdictInfo = new TextdictInfoVO();
+        textdictInfo.setProjectId(wbsTreePrivate.getProjectId());
+        textdictInfo.setTabId(wbsTreePrivate.getPKeyId() + "");
+        textdictInfo.setShowType(1);
+        textdictInfo.setType(2);
+        IPage<TextdictInfoVO> signConfigs = textdictInfoService.selectTextdictInfoPage(new Page<>(1, 1000), textdictInfo);
+        if (signConfigs != null && signConfigs.getRecords() != null && !signConfigs.getRecords().isEmpty()) {
+            List<TextdictInfoVO> signConfigList = signConfigs.getRecords();
+            signConfigList.removeIf(config -> {
+                String colKey = config.getColKey();
+                Element element = null;
+                if (colKey != null && !colKey.isEmpty()) {
+                    element = doc.select("[keyname='" + config.getColKey() + "']").first();
+                    if (element == null && colKey.contains("__")) {
+                        element = doc.select("[keyname*='" + colKey.split("__")[0] + "']").first();
+                        String point = colKey.split("__")[1];
+                        if (element == null && point.contains("_")) {
+                            String[] split = point.split("_");
+                            element = doc.select("[trindex='" + split[0] + "'],[tdindex='" + split[1] + "']").first();
+                        }
+                    }
+                }
+                if (element == null) {
+                    element = doc.select("[placeholder='" + config.getColName() + "']").first();
+                }
+                if (element != null) {
+                    int i = 5;
+                    Element parent = element.parent();
+                    while (i > 0 && parent != null) {
+                        if (parent.hasAttr("title") || parent.hasAttr("dqid")) {
+                            String dqid = element.attr("dqid");
+                            if (dqid != null && !dqid.isEmpty()) {
+                                element.attr("dqid", dqid + "||" + config.getId());
+                            } else {
+                                element.attr("dqid", config.getId() + "");
+                            }
+                            return true;
+                        }
+                        parent = parent.parent();
+                        i--;
+                    }
+                }
+                return false;
+            });
+            if (!signConfigList.isEmpty()) {
+                String ids = signConfigList.stream().map(config -> config.getId() + "").collect(Collectors.joining("||"));
+                Element table = doc.select("table").first();
+                if (table != null) {
+                    Element tr = table.select("tr").last();
+                    if (tr != null) {
+                        Element td = tr.select("td").last();
+                        if (td != null) {
+                            td.attr("dqid", ids);
+                        }
+                    }
+                }
+            }
+        }
+    }
+
 
     /**
      * 质检 获取html接口
@@ -4172,9 +4281,12 @@ public class ExcelTabController extends BladeController {
     @PostMapping("/add-buss-imginfo")
     @ApiOperationSupport(order = 32)
     @ApiOperation(value = "表单填写图片上传", notes = "表单填写图片上传")
-    public R addBussFile(@RequestParam MultipartFile file) {
-
+    public R addBussFile(@RequestParam MultipartFile file,String oldUrl) {
         BladeFile bladeFile = this.newIOSSClient.uploadFileByInputStream(file);
+        if(bladeFile!=null&&StringUtils.isNotEmpty(oldUrl)){
+            String fileName=oldUrl.substring(oldUrl.lastIndexOf("/")+1);
+            newIOSSClient.removeFile("upload/"+fileName);
+        }
         return R.data(bladeFile);
     }
 

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

@@ -424,7 +424,7 @@ public class FormulaController {
             ContractInfo contract = this.contractInfoService.getById(fo.getContractId());
             WbsTreeContract parent = this.wbsTreeContractService.getOne(Wrappers.<WbsTreeContract>lambdaQuery().eq(WbsTreeContract::getId,fo.getParentId()).eq(WbsTreeContract::getContractId,fo.getContractId()).last("limit 1"));
 
-            List<KeyMapper> kms = this.service.getKeyMapperList(Collections.singletonList(fo.getPkeyId()), contract.getPId(), parent.getPKeyId().toString(), ExecuteType.INSPECTION);
+            List<KeyMapper> kms = this.service.getKeyMapperList(Collections.singletonList(fo.getPkeyId()), contract.getPId(), parent.getPKeyId().toString(), ExecuteType.INSPECTION, null);
             KeyMapper keyMapper = null;
             if (Func.isNotEmpty(kms)) {
                 Optional<KeyMapper> optionalKeyMapper = kms.stream().filter(e -> StringUtils.isEquals(e.getField(), key)).findFirst();

+ 109 - 0
blade-service/blade-manager/src/main/java/org/springblade/manager/controller/ProfilerController.java

@@ -0,0 +1,109 @@
+package org.springblade.manager.controller;
+
+import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
+import com.github.xiaoymin.knife4j.annotations.ApiOperationSupport;
+import io.swagger.annotations.Api;
+import io.swagger.annotations.ApiOperation;
+import lombok.AllArgsConstructor;
+import org.springblade.core.tool.api.R;
+import org.springblade.core.tool.utils.StringUtil;
+import org.springblade.manager.dto.ProfilerOffsetDTO;
+import org.springblade.manager.dto.ProfilerOffsetResultDTO;
+import org.springblade.manager.entity.ProfilerOffset;
+import org.springblade.manager.entity.profiler.ProfilerResult;
+import org.springblade.manager.entity.profiler.ProfilerSaveDTO;
+import org.springblade.manager.service.ProfilerOffsetService;
+import org.springframework.web.bind.annotation.*;
+import org.springframework.web.multipart.MultipartFile;
+
+import javax.servlet.http.HttpServletRequest;
+import java.util.List;
+
+/**
+ * @author LHB
+ */
+@RestController
+@AllArgsConstructor
+@RequestMapping("/profiler")
+@Api(value = "质检-综合管理-断面仪", tags = "质检-综合管理-断面仪")
+public class ProfilerController {
+
+    private final ProfilerOffsetService offsetService;
+
+    /**
+     * 新增接口
+     * 第三方推送数据过来
+     */
+    @PostMapping("/save")
+    @ApiOperationSupport(order = 1)
+    @ApiOperation(value = "新增断面仪数据", notes = "")
+    public ProfilerResult add(ProfilerSaveDTO save,
+                              @RequestParam(value = "file", required = false) MultipartFile file) {
+        if (StringUtil.isBlank(save.getAppKey())) {
+            return ProfilerResult.error("1001", "appKey不能为空", "");
+        }
+        if (save.getTimestamp() == null) {
+            return ProfilerResult.error("1002", "timestamp不能为空", "");
+        }
+        if (StringUtil.isBlank(save.getSign())) {
+            return ProfilerResult.error("1003", "sign不能为空", "");
+        }
+        if (StringUtil.isBlank(save.getDeviceCode())) {
+            return ProfilerResult.error("1004", "deviceCode不能为空", "");
+        }
+        if (StringUtil.isBlank(save.getData())) {
+            return ProfilerResult.error("1005", "data不能为空", "");
+        }
+        return offsetService.save(save, file);
+    }
+
+
+    /**
+     * 查询接口
+     */
+    @ApiOperationSupport(order = 2)
+    @ApiOperation(value = "查询接口", notes = "")
+    @PostMapping("/page")
+    public R<Page<ProfilerOffset>> page(ProfilerOffsetDTO offset) {
+        return R.data(offsetService.getPage(offset));
+    }
+
+    /**
+     * 查询详情接口
+     */
+    @ApiOperationSupport(order = 3)
+    @ApiOperation(value = "查询详情接口", notes = "")
+    @GetMapping("/getOne")
+    public R<ProfilerOffsetResultDTO> getOne(Long id) {
+        return R.data(offsetService.getOne(id));
+    }
+
+    /**
+     * 编辑接口
+     */
+    @ApiOperationSupport(order = 4)
+    @ApiOperation(value = "修改接口", notes = "")
+    @PostMapping("/edit")
+    public R<Boolean> edit(@RequestBody ProfilerOffsetResultDTO offset) {
+        return R.status(offsetService.edit(offset));
+    }
+
+    /**
+     * 查询测量人
+     */
+    @ApiOperationSupport(order = 5)
+    @ApiOperation(value = "查询测量人", notes = "")
+    @GetMapping("/getListUserName")
+    public R<List<String>> getListUserName(){
+        return R.data(offsetService.getListUserName());
+    }
+
+    /**
+     * 推送接口
+     */
+    @GetMapping("/push")
+    public R push(){
+        offsetService.push();
+        return R.success("正在推送中");
+    }
+}

+ 105 - 55
blade-service/blade-manager/src/main/java/org/springblade/manager/controller/TextdictInfoController.java

@@ -21,6 +21,7 @@ import com.alibaba.fastjson.JSONArray;
 import com.alibaba.fastjson.JSONObject;
 import com.baomidou.mybatisplus.core.metadata.IPage;
 import com.baomidou.mybatisplus.core.toolkit.Wrappers;
+import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
 import com.github.xiaoymin.knife4j.annotations.ApiOperationSupport;
 import io.swagger.annotations.*;
 import lombok.AllArgsConstructor;
@@ -165,6 +166,21 @@ public class TextdictInfoController extends BladeController {
                     String colKey,
                     Integer type) throws FileNotFoundException {
         if(type != null && type == 4){
+            if (ids != null && !ids.isEmpty()) {
+                String[] split = ids.split(",");
+                List<Long> removeIds = new ArrayList<>();
+                for (String id : split) {
+                    if (StringUtil.isNumeric(id)) {
+                        long lid = Long.parseLong(id);
+                        if (lid > 0) {
+                            removeIds.add(lid);
+                        }
+                    }
+                }
+                if (!removeIds.isEmpty()) {
+                    textdictInfoService.remove(Wrappers.<TextdictInfo>lambdaQuery().in(TextdictInfo::getId, removeIds).eq(TextdictInfo::getTabId, tabId).eq(TextdictInfo::getType, 4));
+                }
+            }
             textdictInfoService.removeHtmlDefault(tabId,colKey);
             return R.success("删除成功");
         }
@@ -247,8 +263,10 @@ public class TextdictInfoController extends BladeController {
             param.put("ids", ids);
             param.put("tabId", tabId);
             dqOperationLogService.save(new DqOperationLog(wbsTreePrivate, AuthUtil.getUser(), String.join( ",", delIds), 2,param.toJSONString(), JSON.toJSONString(query), ""));
+            textdictInfoService.update(Wrappers.<TextdictInfo>lambdaUpdate().in(TextdictInfo::getId, delIds).eq(TextdictInfo::getProjectId, wbsTreePrivate.getProjectId()).set(TextdictInfo::getIsDeleted, 1));
+        } else {
+            textdictInfoService.getBaseMapper().deleteBatchIds(delIds);
         }
-        textdictInfoService.getBaseMapper().deleteBatchIds(delIds);
 
         return R.success("删除成功");
     }
@@ -436,6 +454,9 @@ public class TextdictInfoController extends BladeController {
             throw new ServiceException("请勿重复提交,请3秒后再尝试");
         }
         JSONArray jsonArray = dataInfo.getJSONArray("dataInfo");
+        if (jsonArray == null || jsonArray.isEmpty()) {
+            return R.success("操作成功");
+        }
 
         // -------- 移除所有html 的dqid -----
         Long tableId = dataInfo.getLong("tabId"); //节点pkid
@@ -446,101 +467,104 @@ public class TextdictInfoController extends BladeController {
         // 样式集合
         Document doc = Jsoup.parse(htmlString);
         //解析
-        Element table = doc.select("table").first();
-        Elements trs = table.select("tr");
-        //解析
         Elements onlyInfo = doc.select("[:readonly]");
-        if (onlyInfo != null && onlyInfo.size() >= 1) {
+        if (onlyInfo != null && !onlyInfo.isEmpty()) {
             for (Element element : onlyInfo) {
                 element.removeAttr(":readonly");
             }
         }
         Elements tryInfo = doc.select("td[dqid]");
-        if (tryInfo != null && tryInfo.size() >= 1) {
+        if (tryInfo != null && !tryInfo.isEmpty()) {
             for (Element element : tryInfo) {
                 element.removeAttr("dqid");
             }
         }
-        if (jsonArray == null || jsonArray.size() == 0) {
-            return R.success("操作成功");
-        }
-
-        List<WbsTreePrivate> wbsTreePrivatesEqual = wbsTreePrivateMapper.selectList(Wrappers.<WbsTreePrivate>lambdaQuery()
-                .eq(WbsTreePrivate::getProjectId, wbsTreePrivate.getProjectId())
-                .eq(WbsTreePrivate::getIsDeleted, 0)
-                .eq(WbsTreePrivate::getExcelId, wbsTreePrivate.getExcelId()));
-        List<Long> pKeyIds = wbsTreePrivatesEqual.stream().map(WbsTreePrivate::getPKeyId).collect(Collectors.toList());
-        String ids = StringUtils.join(pKeyIds, ",");
-
-        //删除历史数据
-        String querySql = "select * from m_textdict_info where (tab_id in(SELECT p_key_id from m_wbs_tree_private where project_id='"+wbsTreePrivate.getProjectId()+"' and excel_id='"+wbsTreePrivate.getExcelId()+"' and type=2 and is_deleted=0) or (excel_id="+wbsTreePrivate.getExcelId()+" AND project_id='"+wbsTreePrivate.getProjectId()+"')) and project_id="+wbsTreePrivate.getProjectId()+" and type in(2,6) ";
-        List<TextdictInfo> oldTextdictInfos = jdbcTemplate.query(querySql, new BeanPropertyRowMapper<>(TextdictInfo.class));
-        String delSql = "delete from m_textdict_info where (tab_id in(SELECT p_key_id from m_wbs_tree_private where project_id='"+wbsTreePrivate.getProjectId()+"' and excel_id='"+wbsTreePrivate.getExcelId()+"' and type=2 and is_deleted=0) or (excel_id="+wbsTreePrivate.getExcelId()+" AND project_id='"+wbsTreePrivate.getProjectId()+"')) and project_id="+wbsTreePrivate.getProjectId()+" and type in(2,6) ";
-        jdbcTemplate.execute(delSql);
 
+        // 查询历史数据
+        Map<String, TextdictInfo> oldTextDictInfoMap = new HashMap<>();
+        List<TextdictInfoVO> oldTextDictInfos = new ArrayList<>();
+        TextdictInfoVO param = new TextdictInfoVO();
+        param.setProjectId(wbsTreePrivate.getProjectId());
+        param.setTabId(wbsTreePrivate.getPKeyId() + "");
+        param.setShowType(1);
+        param.setType(2);
+        IPage<TextdictInfoVO> signConfigs = textdictInfoService.selectTextdictInfoPage(new Page<>(1, 1000), param);
+        if (signConfigs != null && signConfigs.getRecords() != null && !signConfigs.getRecords().isEmpty()) {
+            oldTextDictInfos = signConfigs.getRecords();
+            oldTextDictInfoMap = oldTextDictInfos.stream().collect(Collectors.toMap(item -> item.getProjectId() + item.getId(), textdictInfo -> textdictInfo));
+        }
         // 由于要实现电签 一对多(1个key 对应多个电签Id)
         Map<String,String> keyMap = new HashMap<>();
+        //解析
+        Element table = doc.select("table").first();
+        Elements trs = table.select("tr");
 
         // ------- 查询数据库是否存在 该该电签信息 ---------
         StringBuilder dqIds = new StringBuilder();
         List<TextdictInfo> newTextDictInfos = new ArrayList<>();
+        List<TextdictInfo> updateList = new ArrayList<>();
+        List<TextdictInfo> addList = new ArrayList<>();
         for (int i = 0; i < jsonArray.size(); i++) {
             JSONObject jsonObject = jsonArray.getJSONObject(i);
-            TextdictInfo textdictInfo = new TextdictInfo();
-            String keky = jsonObject.getString("colKey");
-
-            String[] trtd = keky.split("__")[1].split("_");
-            Element element = trs.get(Integer.parseInt(trtd[0])).select("td").get(Integer.parseInt(trtd[1]));
+            String key = jsonObject.getString("colKey");
+            String sigRoleId = jsonObject.getString("sigRoleId");
 
-            String id = element.children().get(0).attr("keyname");
-            if (jsonObject.containsKey("id")) {
-                textdictInfo.setId(jsonObject.getLong("id"));
+            TextdictInfo textdictInfo = new TextdictInfo();
+            Long id = jsonObject.getLong("id");
+            if (id != null && id > 0) {
+                textdictInfo.setId(id);
             } else {
                 textdictInfo.setId(SnowFlakeUtil.getId());
                 textdictInfo.setIsDeleted(0);
             }
             textdictInfo.setName("电签位置配置");
             textdictInfo.setType(jsonObject.getInteger("type"));
-            textdictInfo.setColKey(id);
-            textdictInfo.setSigRoleId(jsonObject.getString("sigRoleId"));
-
+            textdictInfo.setSigRoleId(sigRoleId);
             textdictInfo.setTabId(tableId.toString());
             textdictInfo.setExcelId(wbsTreePrivate.getExcelId() + "");
-
             textdictInfo.setColName(jsonObject.getString("colName"));
             textdictInfo.setSigRoleName(jsonObject.getString("sigRoleName"));
             textdictInfo.setPyzbx(jsonObject.getDouble("pyzbx"));
             textdictInfo.setPyzby(jsonObject.getDouble("pyzby"));
             Integer timeState = jsonObject.getInteger("timeState");
             textdictInfo.setTimeState(timeState);
-            if(timeState!=null && timeState==1){
+            if(timeState == 1){
                 textdictInfo.setTimeColKey(jsonObject.getString("timeColKey"));
                 textdictInfo.setTimeName(jsonObject.getString("timeName"));
             }else{
                 textdictInfo.setTimeColKey("");
                 textdictInfo.setTimeName("");
             }
-
             textdictInfo.setProjectId(wbsTreePrivate.getProjectId());
 
-            //由于使用联合主键
-            TextdictInfo one = textdictInfoService.selectTextdictInfoOne(textdictInfo.getId()+"",textdictInfo.getSigRoleId(),textdictInfo.getProjectId());
-            if(ObjectUtil.isNotEmpty(one)){
-                textdictInfoService.saveOrUpdate(textdictInfo);
-            }else{
-                textdictInfoService.save(textdictInfo);
+            String[] trtd = key.split("__")[1].split("_");
+            Element element;
+            String colKey;
+            try {
+                element = trs.get(Integer.parseInt(trtd[0])).select("td").get(Integer.parseInt(trtd[1]));
+                colKey = element.children().get(0).attr("keyname");
+            } catch (Exception e) {
+                throw new ServiceException(String.format("【%s】元素位置与表单不匹配,请重新编辑后保存", textdictInfo.getColName()));
+            }
+            textdictInfo.setColKey(colKey);
+
+            TextdictInfo info = oldTextDictInfoMap.get(wbsTreePrivate.getProjectId() + id);
+            if (info != null) {
+                updateList.add(textdictInfo);
+            } else {
+                addList.add(textdictInfo);
             }
             newTextDictInfos.add(textdictInfo);
             dqIds.append(textdictInfo.getId()).append( ",");
             String dqId = "";
-            if(keyMap.containsKey(keky)){
-                dqId = keyMap.get(keky)+"||"+textdictInfo.getId();
+            if(keyMap.containsKey(key)){
+                dqId = keyMap.get(key)+"||"+textdictInfo.getId();
             }else{
                 dqId=textdictInfo.getId()+"";
             }
-            keyMap.put(keky,dqId);
+            keyMap.put(key,dqId);
             element.removeAttr("dqId");
-            element.attr("dqId", keyMap.get(keky));
+            element.attr("dqId", keyMap.get(key));
             if (jsonObject.getInteger("type") == 2) { //个人签字 不能用户输入
                 if (element.html().indexOf("el-tooltip") >= 0) {
                     element.children().get(0).children().get(0).attr(":readonly", "true");
@@ -550,25 +574,54 @@ public class TextdictInfoController extends BladeController {
             }
         }
         File writeFile = new File(wbsTreePrivate.getHtmlUrl());
-//        File writeFile = new File("D:\\file\\downfile\\1792757075013533696.html");
         FileUtil.writeToFile(writeFile, doc.html(), Boolean.parseBoolean("UTF-8"));
-
         String str1 = wbsTreePrivate.getHtmlUrl().replace("Desktop//privateUrl", "Desktop/privateUrl");
         String replace = str1.replace("\\", "\\\\");
+        if (!oldTextDictInfos.isEmpty()) {
+            Set<Long> set = oldTextDictInfos.stream().map(TextdictInfoVO::getId).collect(Collectors.toSet());
+            // 先逻辑删除然后修改
+            this.textdictInfoService.update(Wrappers.<TextdictInfo>lambdaUpdate().eq(TextdictInfo::getProjectId, wbsTreePrivate.getProjectId())
+                    .eq(TextdictInfo::getExcelId, wbsTreePrivate.getExcelId()).in(TextdictInfo::getType, 2, 6).in(TextdictInfo::getId, set).set(TextdictInfo::getIsDeleted, 1));
+        }
+        if (!updateList.isEmpty()) {
+            for (TextdictInfo info : updateList) {
+                this.textdictInfoService.update(Wrappers.<TextdictInfo>lambdaUpdate().eq(TextdictInfo::getId, info.getId()).eq(TextdictInfo::getProjectId, info.getProjectId())
+                        .set(info.getExcelId() != null ,TextdictInfo::getExcelId, info.getExcelId()).set(info.getSigRoleId() != null ,TextdictInfo::getSigRoleId, info.getSigRoleId())
+                        .set(info.getName() != null ,TextdictInfo::getName, info.getName())
+                        .set(info.getType() != null ,TextdictInfo::getType, info.getType())
+                        .set(info.getColName() != null, TextdictInfo::getColName, info.getColName())
+                        .set(info.getSigRoleName() != null, TextdictInfo::getSigRoleName, info.getSigRoleName())
+                        .set(info.getPyzbx() != null, TextdictInfo::getPyzbx, info.getPyzbx())
+                        .set(info.getPyzby() != null, TextdictInfo::getPyzby, info.getPyzby())
+                        .set(info.getTimeColKey() != null, TextdictInfo::getTimeColKey, info.getTimeColKey())
+                        .set(info.getTimeName() != null, TextdictInfo::getTimeName, info.getTimeName())
+                        .set(info.getColKey() != null, TextdictInfo::getColKey, info.getColKey())
+                        .set(info.getTabId() != null,TextdictInfo::getTabId, info.getTabId())
+                        .set(info.getTimeState() != null ,TextdictInfo::getTimeState, info.getTimeState()).set(TextdictInfo::getIsDeleted, 0));
+            }
+        }
+        if (!addList.isEmpty()) {
+            this.textdictInfoService.saveBatch(addList);
+        }
 
         //修改同几点的数据
+        List<WbsTreePrivate> wbsTreePrivatesEqual = wbsTreePrivateMapper.selectList(Wrappers.<WbsTreePrivate>lambdaQuery()
+                .eq(WbsTreePrivate::getProjectId, wbsTreePrivate.getProjectId())
+                .eq(WbsTreePrivate::getIsDeleted, 0)
+                .eq(WbsTreePrivate::getExcelId, wbsTreePrivate.getExcelId()).eq(WbsTreePrivate::getHtmlUrl, wbsTreePrivate.getHtmlUrl()));
+        List<Long> pKeyIds = wbsTreePrivatesEqual.stream().map(WbsTreePrivate::getPKeyId).collect(Collectors.toList());
+        String ids = StringUtils.join(pKeyIds, ",");
         if(StringUtils.isNotBlank(ids)){
             String updateSqlP = "update m_wbs_tree_private set html_url = '" + replace + "' where p_key_id in ("+ids+") and project_id="+wbsTreePrivate.getProjectId()+"";
             jdbcTemplate.execute(updateSqlP);
         }
 
         //修改对应合同段的htmlUrl,当前项目下对应合同段的节点
-        List<Long> cIdsList = wbsTreePrivatesEqual.stream().map(WbsTreePrivate::getId).distinct().collect(Collectors.toList());
-
+        List<Long> cIdsList = wbsTreePrivatesEqual.stream().map(WbsTreePrivate::getPKeyId).distinct().collect(Collectors.toList());
         List<Long> cPkeyIds = wbsTreeContractService.getBaseMapper().selectList(Wrappers.<WbsTreeContract>lambdaQuery()
                 .eq(WbsTreeContract::getProjectId, wbsTreePrivate.getProjectId())
                 .eq(WbsTreeContract::getExcelId, wbsTreePrivate.getExcelId())
-                .in(WbsTreeContract::getId, cIdsList)).stream().map(WbsTreeContract::getPKeyId).collect(Collectors.toList());
+                .in(WbsTreeContract::getIsTypePrivatePid, cIdsList)).stream().map(WbsTreeContract::getPKeyId).collect(Collectors.toList());
         String cPkeyIdsStr = StringUtils.join(cPkeyIds, ",");
 
         if (StringUtils.isNotEmpty(cPkeyIdsStr)) {
@@ -576,18 +629,15 @@ public class TextdictInfoController extends BladeController {
             jdbcTemplate.execute(updateSqlC);
         }
         BladeUser user = AuthUtil.getUser();
-        DqOperationLog log = new DqOperationLog(wbsTreePrivate, user, "", 1, dataInfo.toJSONString(), JSON.toJSONString(oldTextdictInfos), JSON.toJSONString(newTextDictInfos));
+        DqOperationLog log = new DqOperationLog(wbsTreePrivate, user, "", 1, dataInfo.toJSONString(), JSON.toJSONString(oldTextDictInfos), JSON.toJSONString(newTextDictInfos));
         if (dqIds.length() > 1) {
             log.setBusinessId(dqIds.deleteCharAt(dqIds.length() - 1).toString());
         }
         dqOperationLogService.save(log);
         bladeRedis.set("save-eVis-lock:" + SecureUtil.getUserId(), "1");
         bladeRedis.expire("save-eVis-lock:" + SecureUtil.getUserId(), 3);
-
         return R.success("操作成功");
     }
-
-
     /**
      * 保存默认值
      */

+ 163 - 44
blade-service/blade-manager/src/main/java/org/springblade/manager/controller/TrialSummaryClassificationConfigurationController.java

@@ -10,6 +10,7 @@ import org.apache.commons.lang.StringUtils;
 import org.jsoup.Jsoup;
 import org.jsoup.nodes.Document;
 import org.jsoup.nodes.Element;
+import org.jsoup.select.Elements;
 import org.springblade.common.constant.CommonConstant;
 import org.springblade.common.utils.CommonUtil;
 import org.springblade.common.utils.SnowFlakeUtil;
@@ -39,9 +40,11 @@ import org.springframework.web.bind.annotation.*;
 
 import javax.validation.Valid;
 import java.io.*;
+import java.nio.charset.StandardCharsets;
 import java.util.*;
 import java.util.function.Function;
 import java.util.stream.Collectors;
+import java.util.stream.Stream;
 
 
 @RestController
@@ -147,6 +150,8 @@ public class TrialSummaryClassificationConfigurationController extends BladeCont
                 fileInputStream = CommonUtil.getOSSInputStream(path);
             }
             String htmlString = IoUtil.readToString(fileInputStream);
+            htmlString= htmlString.replaceAll("title","trial");
+            htmlString= htmlString.replaceAll("trialsummaryreflection", "title");
             Document doc = Jsoup.parse(htmlString);
             Element table = doc.select("table").first();
             doc.select("Col").remove();
@@ -211,35 +216,43 @@ public class TrialSummaryClassificationConfigurationController extends BladeCont
     @RequestMapping(value = "/input/detail", method = RequestMethod.GET)
     public R<Object> inputDetail(@RequestParam String classId, @RequestParam String keyName) {
         TrialSummaryClassificationConfiguration classificationConfiguration = iTrialSummaryClassificationConfigurationService.getById(classId);
+        List<Map<String, String>> r=new ArrayList<>();
         if (classificationConfiguration != null && ObjectUtil.isNotEmpty(classificationConfiguration.getExcelId())) {
             String sql = "SELECT * FROM m_trial_summary_excel_tab_reflection WHERE excel_id = ? AND html_key_name = ?";
-            TrialSummaryExcelTabReflection obj = jdbcTemplate.query(sql, new Object[]{classificationConfiguration.getExcelId(), keyName}, new BeanPropertyRowMapper<>(TrialSummaryExcelTabReflection.class)).stream().findAny().orElse(null);
-            if (obj != null) {
-                if (TrialTableDataInfo.LONG_ID.equals(obj.getTrialTabId())) {
-                    Map<String, String> map = new HashMap<>();
-                    map.put("id", obj.getId().toString());
-                    map.put("tabName", TrialTableDataInfo.TBN_CH);
-                    map.put("elementName", TrialTableDataInfo.getElementName(obj.getElementKey()));
-                    return R.data(map);
-                }
-                WbsTreePrivate trialTab = wbsTreePrivateServiceImpl.getBaseMapper().getByPKeyId(obj.getTrialTabId());
-                WbsFormElement element = wbsFormElementService.getById(obj.getElementId());
-                if (trialTab != null && element != null) {
-                    Map<String, String> map = new HashMap<>();
-                    map.put("id", obj.getId().toString());
-                    map.put("tabName", ObjectUtil.isNotEmpty(trialTab.getFullName()) ? trialTab.getFullName() : trialTab.getNodeName());
-                    map.put("elementName", element.getEName());
-                    return R.data(map);
+            List<TrialSummaryExcelTabReflection> list = jdbcTemplate.query(sql, new Object[]{classificationConfiguration.getExcelId(), keyName}, new BeanPropertyRowMapper<>(TrialSummaryExcelTabReflection.class));
+            if (list != null) {
+                for (TrialSummaryExcelTabReflection obj : list) {
+                    if (TrialTableDataInfo.LONG_ID.equals(obj.getTrialTabId())) {
+                        Map<String, String> map = new HashMap<>();
+                        map.put("id", obj.getId().toString());
+                        map.put("tabName", TrialTableDataInfo.TBN_CH);
+                        map.put("elementName", TrialTableDataInfo.getElementName(obj.getElementKey()));
+                        map.put("trialTabId",TrialTableDataInfo.LONG_ID+"");
+                        map.put("elementId",TrialTableDataInfo.getElementId(obj.getElementKey())+"");
+                        r.add( map);
+                    }else {
+                        WbsTreePrivate trialTab = wbsTreePrivateServiceImpl.getBaseMapper().getByPKeyId(obj.getTrialTabId());
+                        WbsFormElement element = wbsFormElementService.getById(obj.getElementId());
+                        if (trialTab != null && element != null) {
+                            Map<String, String> map = new HashMap<>();
+                            map.put("id", obj.getId().toString());
+                            map.put("tabName", ObjectUtil.isNotEmpty(trialTab.getFullName()) ? trialTab.getFullName() : trialTab.getNodeName());
+                            map.put("elementName", element.getEName());
+                            map.put("trialTabId",obj.getTrialTabId()+"");
+                            map.put("elementId",obj.getElementId()+"");
+                            r.add(map);
+                        }
+                    }
                 }
             }
         }
-        return R.data(null);
+        return R.data(r);
     }
 
     @ApiOperationSupport(order = 13)
     @ApiOperation(value = "映射数据保存", notes = "传入TrialSummaryReflectionSaveDTO")
     @RequestMapping(value = "/reflection/save", method = RequestMethod.POST)
-    public R<Object> reflectionSave(@RequestBody TrialSummaryReflectionSaveDTO dto) {
+    public R<Object> reflectionSave(@RequestBody TrialSummaryReflectionSaveDTO dto) throws IOException {
         if (ObjectUtil.isNotEmpty(dto.getClassId())) {
             if (ObjectUtil.isEmpty(dto.getReflectionBeanList().size()) || dto.getReflectionBeanList().size() == 0) {
                 return R.success("操作成功");
@@ -248,37 +261,89 @@ public class TrialSummaryClassificationConfigurationController extends BladeCont
                 if (classificationConfiguration != null && ObjectUtil.isNotEmpty(classificationConfiguration.getExcelId())) {
                     List<TrialSummaryReflectionSaveDTO.ReflectionBean> reflectionBeanList = dto.getReflectionBeanList();
                     Set<TrialSummaryReflectionSaveDTO.ReflectionBean> collect = new HashSet<>(reflectionBeanList);
+                    Set<TrialSummaryReflectionSaveDTO.ReflectionBean> updateList = collect.stream().filter(bean -> ObjectUtil.isNotEmpty(bean.getId())).collect(Collectors.toSet());
+                    Set<TrialSummaryReflectionSaveDTO.ReflectionBean> insertList = collect.stream().filter(bean -> ObjectUtil.isEmpty(bean.getId())).collect(Collectors.toSet());
+
                     List<String> keyNameList = collect.stream()
                             .map(bean -> "'" + bean.getHtmlKeyName() + "'")
                             .collect(Collectors.toList());
                     if (keyNameList.size() <= 0) {
                         throw new ServiceException("入参异常,未获取到htmlKeyName");
                     }
-
-                    String sqlDel = "DELETE FROM m_trial_summary_excel_tab_reflection WHERE excel_id = ? AND class_id = ? AND html_key_name IN (" +
-                            StringUtils.join(keyNameList, ",") + ")";
-                    List<Object> paramsDel = new ArrayList<>();
-                    paramsDel.add(classificationConfiguration.getExcelId());
-                    paramsDel.add(classificationConfiguration.getId());
-                    jdbcTemplate.update(sqlDel, paramsDel.toArray());
-
-                    String sqlInsert = "INSERT INTO m_trial_summary_excel_tab_reflection(id,class_id,excel_id,trial_tab_id,element_id,html_key_name,trial_tab_name,element_key) VALUES (?,?,?,?,?,?,?,?)";
-                    List<Object[]> batchArgs = new ArrayList<>();
-                    for (TrialSummaryReflectionSaveDTO.ReflectionBean reflectionBean : collect) {
-                        Object[] paramsInsert = {
-                                SnowFlakeUtil.getId(),
-                                classificationConfiguration.getId(),
-                                classificationConfiguration.getExcelId(),
-                                reflectionBean.getTrialTabId(),
-                                reflectionBean.getElementId(),
-                                reflectionBean.getHtmlKeyName(),
-                                reflectionBean.getTrialTabName(),
-                                reflectionBean.getElementKey()
-                        };
-                        batchArgs.add(paramsInsert);
+                    // 批量更新已有记录
+                    if (!updateList.isEmpty()) {
+                        String sqlUpdate = "UPDATE m_trial_summary_excel_tab_reflection SET trial_tab_id = ?, element_id = ? WHERE id = ?";
+                        List<Object[]> updateBatchArgs = new ArrayList<>();
+                        for (TrialSummaryReflectionSaveDTO.ReflectionBean reflectionBean : updateList) {
+                            Object[] paramsUpdate = {
+                                    reflectionBean.getTrialTabId(),
+                                    reflectionBean.getElementId(),
+                                    reflectionBean.getId()
+                            };
+                            updateBatchArgs.add(paramsUpdate);
+                        }
+                        jdbcTemplate.batchUpdate(sqlUpdate, updateBatchArgs);
+                    }
+                    if (!insertList.isEmpty()){
+                        String sqlInsert = "INSERT INTO m_trial_summary_excel_tab_reflection(id,class_id,excel_id,trial_tab_id,element_id,html_key_name,trial_tab_name,element_key) VALUES (?,?,?,?,?,?,?,?)";
+                        List<Object[]> batchArgs = new ArrayList<>();
+                        for (TrialSummaryReflectionSaveDTO.ReflectionBean reflectionBean : insertList) {
+                            Object[] paramsInsert = {
+                                    SnowFlakeUtil.getId(),
+                                    classificationConfiguration.getId(),
+                                    classificationConfiguration.getExcelId(),
+                                    reflectionBean.getTrialTabId(),
+                                    reflectionBean.getElementId(),
+                                    reflectionBean.getHtmlKeyName(),
+                                    reflectionBean.getTrialTabName(),
+                                    reflectionBean.getElementKey()
+                            };
+                            batchArgs.add(paramsInsert);
+                        }
+                        jdbcTemplate.batchUpdate(sqlInsert, batchArgs);
+                    }
+                    //设置html上的属性,添加一个属性,trialSummaryReflection
+                    String file_path = ParamCache.getValue(CommonConstant.SYS_LOCAL_URL);
+                    String sys_file_net_url = ParamCache.getValue(CommonConstant.SYS_FILE_NET_URL);
+                    String fileUrl = classificationConfiguration.getHtmlUrl();
+                    File file1 = ResourceUtil.getFile(fileUrl);
+                    InputStream fileInputStream;
+                    if (file1.exists()) {
+                        fileInputStream = new FileInputStream(file1);
+                    } else {
+                        String path = sys_file_net_url + fileUrl.replaceAll("//", "/").replaceAll(file_path, "").replaceAll("/www/wwwroot/Users/hongchuangyanfa/Desktop/", "");
+                        fileInputStream = CommonUtil.getOSSInputStream(path);
+                    }
+                    String htmlString = IoUtil.readToString(fileInputStream);
+                    Document doc = Jsoup.parse(htmlString);
+                    List<Map<String, Object>> htmlData1 = reflectionHtmlData1(dto.getClassId() + "");
+                    // 按htmlKeyName分组,合并相同位置的elementValue
+                    Map<String, String> keyValueMap = new HashMap<>();
+                    for (Map<String, Object> item : htmlData1) {
+                        String htmlKeyName = (String) item.get("htmlKeyName");
+                        String elementValue = (String) item.get("elementValue");
+                        if (keyValueMap.containsKey(htmlKeyName)) {
+                            // 如果已存在该key,则用/分隔追加
+                            keyValueMap.put(htmlKeyName, keyValueMap.get(htmlKeyName) + "/" + elementValue);
+                        } else {
+                            keyValueMap.put(htmlKeyName, elementValue);
+                        }
+                    }
+                    // 在HTML中设置trialSummaryReflection属性
+                    for (Map.Entry<String, String> entry : keyValueMap.entrySet()) {
+                        String keyName = entry.getKey();
+                        String elementValue = entry.getValue();
+                        // 查找具有指定keyname属性的元素
+                        Elements element = doc.select("[keyname='" + keyName + "']");
+                        if (element != null) {
+                            // 设置trialSummaryReflection属性
+                            element.attr("trialsummaryreflection", elementValue);
+                        }
+                    }
+                    // 修改HTML文档后,保存回原文件
+                    try (FileOutputStream outputStream = new FileOutputStream(file1)) {
+                        outputStream.write(doc.html().getBytes(StandardCharsets.UTF_8));
                     }
-                    jdbcTemplate.batchUpdate(sqlInsert, batchArgs);
-
                     return R.success("操作成功");
                 }
             }
@@ -310,6 +375,10 @@ public class TrialSummaryClassificationConfigurationController extends BladeCont
                 if (query.size() > 0) {
                     Set<Long> eleIds = query.stream().map(TrialSummaryExcelTabReflection::getElementId).collect(Collectors.toSet());
                     Map<Long, WbsFormElement> eleMap = wbsFormElementService.getBaseMapper().selectBatchIds(eleIds).stream().collect(Collectors.toMap(WbsFormElement::getId, Function.identity()));
+
+                    // 用于按htmlKeyName分组
+                    Map<String, List<Map<String, Object>>> groupedMaps = new HashMap<>();
+
                     for (TrialSummaryExcelTabReflection obj : query) {
                         Map<String, Object> map = new HashMap<>();
                         map.put("id", obj.getId());
@@ -322,7 +391,28 @@ public class TrialSummaryClassificationConfigurationController extends BladeCont
                             map.put("elementValue", ObjectUtil.isNotEmpty(orDefault) ? orDefault.getEName() : null);
                         }
                         map.put("htmlKeyName", obj.getHtmlKeyName());
-                        maps.add(map);
+
+                        // 按htmlKeyName分组
+                        groupedMaps.computeIfAbsent(obj.getHtmlKeyName(), k -> new ArrayList<>()).add(map);
+                    }
+
+                    // 合并相同htmlKeyName的条目
+                    for (Map.Entry<String, List<Map<String, Object>>> entry : groupedMaps.entrySet()) {
+                        List<Map<String, Object>> group = entry.getValue();
+                        if (group.size() > 1) {
+                            // 如果有多个相同的htmlKeyName,合并为一个
+                            Map<String, Object> mergedMap = new HashMap<>();
+                            mergedMap.put("htmlKeyName", entry.getKey());
+                            mergedMap.put("elementValue", "多元素");
+                            // 保留第一个条目的其他属性
+                            mergedMap.put("id", group.get(0).get("id"));
+                            mergedMap.put("trialTabId", group.get(0).get("trialTabId"));
+                            mergedMap.put("elementId", group.get(0).get("elementId"));
+                            maps.add(mergedMap);
+                        } else {
+                            // 只有一个条目,直接添加
+                            maps.add(group.get(0));
+                        }
                     }
                 }
             }
@@ -330,4 +420,33 @@ public class TrialSummaryClassificationConfigurationController extends BladeCont
         return R.data(maps);
     }
 
+    public List<Map<String, Object>> reflectionHtmlData1(@RequestParam String id) {
+        List<Map<String, Object>> maps = new LinkedList<>();
+        if (ObjectUtil.isNotEmpty(id)) {
+            TrialSummaryClassificationConfiguration clazz = iTrialSummaryClassificationConfigurationService.getById(id);
+            if (clazz != null) {
+                List<TrialSummaryExcelTabReflection> query = jdbcTemplate.query("SELECT * FROM m_trial_summary_excel_tab_reflection WHERE class_id = ?", new Object[]{id}, new BeanPropertyRowMapper<>(TrialSummaryExcelTabReflection.class));
+                if (query.size() > 0) {
+                    Set<Long> eleIds = query.stream().map(TrialSummaryExcelTabReflection::getElementId).collect(Collectors.toSet());
+                    Map<Long, WbsFormElement> eleMap = wbsFormElementService.getBaseMapper().selectBatchIds(eleIds).stream().collect(Collectors.toMap(WbsFormElement::getId, Function.identity()));
+                    for (TrialSummaryExcelTabReflection obj : query) {
+                        Map<String, Object> map = new HashMap<>();
+                        map.put("id", obj.getId());
+                        map.put("trialTabId", obj.getTrialTabId());
+                        map.put("elementId", obj.getElementId());
+                        if (TrialTableDataInfo.LONG_ID.equals(obj.getTrialTabId())) {
+                            map.put("elementValue", TrialTableDataInfo.getElementName(obj.getElementKey()));
+                        } else {
+                            WbsFormElement orDefault = eleMap.getOrDefault(obj.getElementId(), null);
+                            map.put("elementValue", ObjectUtil.isNotEmpty(orDefault) ? orDefault.getEName() : null);
+                        }
+                        map.put("htmlKeyName", obj.getHtmlKeyName());
+                        maps.add(map);
+                    }
+                }
+            }
+        }
+        return maps;
+    }
+
 }

+ 37 - 24
blade-service/blade-manager/src/main/java/org/springblade/manager/controller/WbsTreeContractController.java

@@ -41,6 +41,7 @@ import org.springblade.core.tool.utils.CollectionUtil;
 import org.springblade.core.tool.utils.IoUtil;
 import org.springblade.core.tool.utils.ObjectUtil;
 import org.springblade.core.tool.utils.ResourceUtil;
+import org.springblade.manager.dto.FormulaReferenceDTO;
 import org.springblade.manager.dto.MoveNodeDTO;
 import org.springblade.manager.dto.TableSortDTO;
 import org.springblade.manager.dto.WbsTreeContractDTO2;
@@ -50,6 +51,7 @@ import org.springblade.manager.service.INodeBaseInfoService;
 import org.springblade.manager.service.IWbsParamService;
 import org.springblade.manager.service.IWbsTreeContractService;
 import org.springblade.manager.service.IWbsTreePrivateService;
+import org.springblade.manager.service.impl.ExcelTabServiceImpl;
 import org.springblade.manager.service.impl.NodeBaseInfoServiceImpl;
 import org.springblade.manager.service.impl.WbsTreeContractServiceImpl;
 import org.springblade.manager.utils.FileUtils;
@@ -100,6 +102,7 @@ public class WbsTreeContractController extends BladeController {
 
 
     private final ExcelTabController excelTabController;
+    private final ExcelTabServiceImpl excelTabServiceImpl;
 
 
     @GetMapping("/diGuiWbs")
@@ -877,18 +880,33 @@ public class WbsTreeContractController extends BladeController {
                 }
                 String sql = null;
                 if (initId != null) {
-                    sql = "update " + byId.getInitTableName() + " set ";
                     //导入的数据
                     Set<Map.Entry<String, String>> entries = stringStringMap.entrySet();
                     if(entries.isEmpty()){
                         continue;
                     }
-                    StringBuilder sb = new StringBuilder();
-                    Map<String, Object> finalInitId = initId;
+                    Map<String, String> finalInitId = new HashMap<>();
+                    for (Map.Entry<String, Object> entry : initId.entrySet()) {
+                        if (entry.getValue() != null) {
+                            finalInitId.put(entry.getKey(), entry.getValue().toString());
+                        }
+                    }
                     entries.forEach(f -> {
                         //原先是否存在值 是否为☆拼接的多数据
-                        String oldValue = (String) finalInitId.get(f.getKey());
-                        if (StringUtils.isNotEmpty(oldValue)) {
+                        String oldValue = finalInitId.get(f.getKey());
+                        //key_201是否存在值
+                        String key201 = finalInitId.get("key_201");
+                        if (StringUtils.isNotEmpty(oldValue) || (StringUtils.isNotEmpty(key201) && key201.contains(f.getKey()))) {
+                            if(StringUtils.isEmpty(oldValue)){
+                                String[] split = key201.split("\\$\\$");
+                                for (String s : split) {
+                                    if(s.contains(f.getKey())){
+                                        oldValue = s.split(":")[1];
+                                        break;
+                                    }
+                                }
+                            }
+
                             //当前keu坐标与数据的对应关系
                             HashMap<String, String> newCoordinate = new HashMap<>();
                             //旧数据中需要保留的数据
@@ -916,29 +934,18 @@ public class WbsTreeContractController extends BladeController {
                                 f.setValue(f.getValue() + "☆" + StringUtils.join(oldRetainData, "☆"));
                             }
                         }
-                        if (StringUtils.isNotEmpty(sb.toString())) {
-                            sb.append(",");
-                        }
-                        sb.append(f.getKey()).append("=").append("'").append(f.getValue()).append("'");
+                        finalInitId.put(f.getKey(), f.getValue());
                     });
-                    sql = sql + sb + "where id = " + initId.get("id");
+                    StringBuilder stringBuilder = excelTabServiceImpl.buildMTableInsertSql(byId.getInitTableName(), finalInitId, null, null, null);
+                    sql = stringBuilder.toString();
                 } else {
-                    Set<String> strings = stringStringMap.keySet();
-                    if(strings.isEmpty()){
-                        continue;
-                    }
-                    Collection<String> values = stringStringMap.values();
-                    //转换成sql能够使用的字符串
-                    ArrayList<String> strings1 = new ArrayList<>();
-                    values.forEach(f -> {
-                        f = "'" + f + "'";
-                        strings1.add(f);
-                    });
                     long newPkId = SnowFlakeUtil.getId();
-                    sql = "insert into " + byId.getInitTableName() + " (id,p_key_id," + StringUtils.join(strings, ",") + ") VALUES (" + newPkId + ", " + wbsTreeContract.getPKeyId() + ", " + StringUtils.join(strings1, ",") + ")";
+                    StringBuilder stringBuilder = excelTabServiceImpl.buildMTableInsertSql(byId.getInitTableName(), stringStringMap, newPkId, null, wbsTreeContract.getPKeyId());
+                    sql = stringBuilder.toString();
                 }
 
-
+                //先删除再添加
+                jdbcTemplate.execute("delete from " + byId.getInitTableName() + " where p_key_id = " + wbsTreeContract.getPKeyId());
                 jdbcTemplate.execute(sql);
             }
 
@@ -1217,5 +1224,11 @@ public class WbsTreeContractController extends BladeController {
     }
 
 
-
+    @PostMapping("/setFormulaReference")
+    @ApiOperation(value = "公式引用")
+    @ApiOperationSupport(order = 33)
+    public R setFormulaReference(@RequestBody FormulaReferenceDTO dto) {
+        iWbsTreeContractService.setFormulaReference(dto);
+        return R.success("成功");
+    }
 }

+ 5 - 3
blade-service/blade-manager/src/main/java/org/springblade/manager/controller/WbsTreePrivateController.java

@@ -849,9 +849,9 @@ public class WbsTreePrivateController extends BladeController {
      */
     @GetMapping("/get-excel-html")
     @ApiOperationSupport(order = 23)
-    @ApiOperation(value = "试验-客户端获取表的HTML", notes = "传入节点primaryKeyId")
-    public Object getExcelHtml(@RequestParam String primaryKeyId) throws Exception {
-        return wbsTreePrivateService.getExcelHtml(primaryKeyId);
+    @ApiOperation(value = "试验-客户端获取表的HTML", notes = "传入节点primaryKeyId和试验id")
+    public Object getExcelHtml(@RequestParam String primaryKeyId, String id) throws Exception {
+        return wbsTreePrivateService.getExcelHtml(primaryKeyId, id);
     }
 
     /**
@@ -964,6 +964,7 @@ public class WbsTreePrivateController extends BladeController {
                 vo.setNameVaule(entry.getValue().get(0).getV());
                 vo.setNameRule(getNameRuleV1(entry.getValue().get(0).getV()));
                 vo.setType(entry.getValue().get(0).getNameType());
+                vo.setRemark(entry.getValue().get(0).getRemark());
                 List<NameRuleVo1>vo1s=new ArrayList<>();
                 for (WbsParamVo2 param : entry.getValue()) {
                     vo1s.add(new NameRuleVo1(param.getNodeId(),param.getNodeName()));
@@ -1034,6 +1035,7 @@ public class WbsTreePrivateController extends BladeController {
                 param.setProjectId(dto.getProjectId());
                 param.setNameId(SnowFlakeUtil.getId());
                 param.setNameType(dto.getType());
+                param.setRemark(dto.getRemark());
                 //如果nameID不为空,先删除在保存
                 if(dto.getNameId()!=null){
                     iWbsParamService.getBaseMapper().delete(new QueryWrapper<WbsParam>().eq("name_id",dto.getNameId()));

+ 1 - 45
blade-service/blade-manager/src/main/java/org/springblade/manager/feign/ExcelTabClientImpl.java

@@ -88,7 +88,6 @@ public class ExcelTabClientImpl implements ExcelTabClient {
 
         //应用抽取的数据
         dataArray = excelTabService.addLoadDataInfo(dataArray);
-        dataArray = putIfAbsent(dataArray);
         List<TableInfo> tableInfoList = this.excelTabService.getTableInfoListTrial(dataArray, tabIds);
         for (TableInfo tableInfo : tableInfoList) {
             tableInfo.setTestGroupId(dto.getId()+"");
@@ -886,50 +885,7 @@ public class ExcelTabClientImpl implements ExcelTabClient {
         return R.data(resultMapList);
     }
 
-    private JSONArray putIfAbsent(JSONArray jsonArray) {
-        JSONArray json2 = new JSONArray();
-        for (int i = 0; i < jsonArray.size(); i++) {
-            JSONObject jsonObject = jsonArray.getJSONObject(i);
-            json2.add(jsonObject);
-            String pkeyId = jsonObject.getString("pkeyId");
-            WbsTreePrivate wbsTreePrivate = this.wbsTreePrivateService.getOne(Wrappers.<WbsTreePrivate>lambdaQuery().eq(WbsTreePrivate::getPKeyId, pkeyId));
-            if(wbsTreePrivate == null || StringUtil.isBlank(wbsTreePrivate.getHtmlUrl())) {
-                continue;
-            }
-            if (!StringUtil.hasText(wbsTreePrivate.getInitTableId()) && !StringUtil.hasText(wbsTreePrivate.getInitTableName())) {
-                continue;
-            }
-            List<WbsFormElement> wbsFormElements;
-            if (StringUtil.hasText(wbsTreePrivate.getInitTableId())) {
-                wbsFormElements =  jdbcTemplate.query("SELECT e_key from m_wbs_form_element WHERE is_deleted = 0 and e_type = 6 and f_id = " + wbsTreePrivate.getInitTableId(), new BeanPropertyRowMapper<>(WbsFormElement.class) );
-            } else {
-                wbsFormElements =  jdbcTemplate.query("SELECT e_key from m_wbs_form_element WHERE e_type = 6 and f_id = (SELECT id from m_table_info WHERE tab_en_name = ' " + wbsTreePrivate.getInitTableName()
-                        + "' and is_deleted = 0 limit 1) and is_deleted = 0" + wbsTreePrivate.getInitTableName(), new BeanPropertyRowMapper<>(WbsFormElement.class) );
-            }
-            Map<String, String> map = wbsFormElements.stream().collect(Collectors.toMap(WbsFormElement::getEKey, WbsFormElement::getEKey));
-            String htmlString = null;
-            try {
-                htmlString = IoUtil.readToString(FileUtils.getInputStreamByUrl(wbsTreePrivate.getHtmlUrl()));
-            } catch (Exception e) {
-                e.printStackTrace();
-            }
-            Document doc = Jsoup.parse(htmlString);
-            for (Element element : doc.getElementsByAttributeValueStarting("id", "key_")) {
-                String id = element.attr("id");
-                if(id == null || id.startsWith("key__")) {
-                    continue;
-                }
-                if (map.containsKey(id.split("__")[0])) {
-                    continue;
-                }
-                String text = jsonObject.getString(id);
-                if (text == null || text.trim().isEmpty()) {
-                    jsonObject.put(id, "/");
-                }
-            }
-        }
-        return json2;
-    }
+
     @Override
     public R synPdfKeyInfo(String contractId, String nodeIds, String classify, String projectId, String authorization) throws Exception {
 

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

@@ -180,7 +180,7 @@ public class SubTable {
     /*获取最终输出的项目信息*/
     public List<Item> getPutOutList(){
         /*初始化group,保留原先内容,只做同KEY覆盖*/
-        initOriginal();
+        //initOriginal();
         List<Item> itemList = new ArrayList<>(group.values());
         if(this.mainList!=null){
             List<String> itemNameIndex = this.mainList.stream().map(e->FormulaUtils.parseItemName(e.getEName()).trim()).collect(Collectors.toList());

+ 2 - 0
blade-service/blade-manager/src/main/java/org/springblade/manager/formula/impl/TableElementConverter.java

@@ -134,6 +134,8 @@ public class TableElementConverter implements ITableElementConverter {
     /**取小数*/
     public Integer scale = 0;
     public Integer payRadicScale = 2;
+    //清楚字段数据时 是否删除附表 0否 1是
+    private String isRemoveForSubTab;
     /*计量属性*/
     /**根据表名获取对应表页对象*/
     public LinkedList<NodeTable> getTableByName(String initTableName){

+ 20 - 0
blade-service/blade-manager/src/main/java/org/springblade/manager/mapper/ProfilerDataMapper.java

@@ -0,0 +1,20 @@
+package org.springblade.manager.mapper;
+
+import org.apache.ibatis.annotations.Mapper;
+import org.springblade.manager.entity.ProfilerData;
+import com.baomidou.mybatisplus.core.mapper.BaseMapper;
+
+/**
+* @author LHB
+* @description 针对表【q_profiler_data(断面仪-测量点数组)】的数据库操作Mapper
+* @createDate 2025-10-27 15:58:56
+* @Entity org.springblade.manager.entity.QProfilerData
+*/
+@Mapper
+public interface ProfilerDataMapper extends BaseMapper<ProfilerData> {
+
+}
+
+
+
+

+ 25 - 0
blade-service/blade-manager/src/main/java/org/springblade/manager/mapper/ProfilerDataMapper.xml

@@ -0,0 +1,25 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!DOCTYPE mapper
+        PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
+        "http://mybatis.org/dtd/mybatis-3-mapper.dtd">
+<mapper namespace="org.springblade.manager.mapper.ProfilerDataMapper">
+
+    <resultMap id="BaseResultMap" type="org.springblade.manager.entity.ProfilerData">
+            <id property="id" column="id" />
+            <result property="offsetId" column="offset_id" />
+            <result property="angle" column="angle" />
+            <result property="backBreak" column="back_break" />
+            <result property="dist" column="dist" />
+            <result property="x" column="x" />
+            <result property="z" column="z" />
+            <result property="createTime" column="create_time" />
+            <result property="createUser" column="create_user" />
+            <result property="updateTime" column="update_time" />
+            <result property="updateUser" column="update_user" />
+    </resultMap>
+
+    <sql id="Base_Column_List">
+        id,offset_id,angle,back_break,dist,x,
+        z,create_time,create_user,update_time,update_user
+    </sql>
+</mapper>

+ 23 - 0
blade-service/blade-manager/src/main/java/org/springblade/manager/mapper/ProfilerOffsetMapper.java

@@ -0,0 +1,23 @@
+package org.springblade.manager.mapper;
+
+import org.apache.ibatis.annotations.Mapper;
+import org.springblade.manager.entity.ProfilerOffset;
+import com.baomidou.mybatisplus.core.mapper.BaseMapper;
+
+import java.util.List;
+
+/**
+* @author LHB
+* @description 针对表【q_profiler_offset(断面仪-基础信息+测量者信息)】的数据库操作Mapper
+* @createDate 2025-10-27 15:58:56
+* @Entity org.springblade.manager.entity.QProfilerOffset
+*/
+@Mapper
+public interface ProfilerOffsetMapper extends BaseMapper<ProfilerOffset> {
+
+    List<String> getListUserName();
+}
+
+
+
+

+ 36 - 0
blade-service/blade-manager/src/main/java/org/springblade/manager/mapper/ProfilerOffsetMapper.xml

@@ -0,0 +1,36 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!DOCTYPE mapper
+        PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
+        "http://mybatis.org/dtd/mybatis-3-mapper.dtd">
+<mapper namespace="org.springblade.manager.mapper.ProfilerOffsetMapper">
+
+    <resultMap id="BaseResultMap" type="org.springblade.manager.entity.ProfilerOffset">
+            <id property="id" column="id" />
+            <result property="deviceCode" column="device_code" />
+            <result property="deviceHeight" column="device_height" />
+            <result property="ellipseRadius" column="ellipse_radius" />
+            <result property="slope" column="slope" />
+            <result property="x" column="x" />
+            <result property="z" column="z" />
+            <result property="infoChannelName" column="info_channel_name" />
+            <result property="infoConstructionUnit" column="info_construction_unit" />
+            <result property="infoDate" column="info_date" />
+            <result property="infoNameOfProject" column="info_name_of_project" />
+            <result property="infoUserName" column="info_user_name" />
+            <result property="infoMileageNumber" column="info_mileage_number" />
+            <result property="fileUrl" column="file_url" />
+            <result property="createTime" column="create_time" />
+            <result property="createUser" column="create_user" />
+            <result property="updateTime" column="update_time" />
+            <result property="updateUser" column="update_user" />
+    </resultMap>
+
+    <sql id="Base_Column_List">
+        id,device_code,device_height,ellipse_radius,slope,x,z,
+        info_channel_name,info_construction_unit,info_date,info_name_of_project,info_user_name,
+        info_mileage_number,file_url,create_time,create_user,update_time,update_user
+    </sql>
+    <select id="getListUserName" resultType="java.lang.String">
+        select info_user_name from q_profiler_offset group by info_user_name
+    </select>
+</mapper>

+ 20 - 0
blade-service/blade-manager/src/main/java/org/springblade/manager/mapper/ProfilerStandardSectionBeanMapper.java

@@ -0,0 +1,20 @@
+package org.springblade.manager.mapper;
+
+import org.apache.ibatis.annotations.Mapper;
+import org.springblade.manager.entity.ProfilerStandardSectionBean;
+import com.baomidou.mybatisplus.core.mapper.BaseMapper;
+
+/**
+* @author LHB
+* @description 针对表【q_profiler_standard_section_bean(断面仪-标准断面)】的数据库操作Mapper
+* @createDate 2025-10-27 15:58:56
+* @Entity org.springblade.manager.entity.QProfilerStandardSectionBean
+*/
+@Mapper
+public interface ProfilerStandardSectionBeanMapper extends BaseMapper<ProfilerStandardSectionBean> {
+
+}
+
+
+
+

+ 28 - 0
blade-service/blade-manager/src/main/java/org/springblade/manager/mapper/ProfilerStandardSectionBeanMapper.xml

@@ -0,0 +1,28 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!DOCTYPE mapper
+        PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
+        "http://mybatis.org/dtd/mybatis-3-mapper.dtd">
+<mapper namespace="org.springblade.manager.mapper.ProfilerStandardSectionBeanMapper">
+
+    <resultMap id="BaseResultMap" type="org.springblade.manager.entity.ProfilerStandardSectionBean">
+            <id property="id" column="id" />
+            <result property="offsetId" column="offset_id" />
+            <result property="direction" column="direction" />
+            <result property="endAngle" column="end_angle" />
+            <result property="radius" column="radius" />
+            <result property="select" column="select" />
+            <result property="startAngle" column="start_angle" />
+            <result property="x" column="x" />
+            <result property="y" column="y" />
+            <result property="createTime" column="create_time" />
+            <result property="createUser" column="create_user" />
+            <result property="updateTime" column="update_time" />
+            <result property="updateUser" column="update_user" />
+    </resultMap>
+
+    <sql id="Base_Column_List">
+        id,offset_id,direction,end_angle,radius,select,
+        start_angle,x,y,create_time,create_user,
+        update_time,update_user
+    </sql>
+</mapper>

+ 8 - 0
blade-service/blade-manager/src/main/java/org/springblade/manager/mapper/TextdictInfoMapper.java

@@ -16,13 +16,16 @@
  */
 package org.springblade.manager.mapper;
 
+import org.apache.ibatis.annotations.Select;
 import org.springblade.manager.entity.TextdictInfo;
+import org.springblade.manager.entity.WbsTreePrivate;
 import org.springblade.manager.injector.EasyBaseMapper;
 import org.springblade.manager.vo.TextdictInfoVO;
 import com.baomidou.mybatisplus.core.mapper.BaseMapper;
 import com.baomidou.mybatisplus.core.metadata.IPage;
 import org.springframework.data.repository.query.Param;
 
+import java.util.Collection;
 import java.util.List;
 
 /**
@@ -54,4 +57,9 @@ public interface TextdictInfoMapper extends EasyBaseMapper<TextdictInfo> {
     //通过表单Id 获取电签信息
     List<TextdictInfoVO> getTextdictListInfoByPkeyId(@Param("tabId") String tabId,@Param("projectId") String projectId);
 
+    @Select("select * from m_textdict_info where project_id = #{treePrivate.projectId} and tab_id = #{treePrivate.pKeyId} and type in (2,6) and is_deleted = 0")
+    List<TextdictInfoVO> selectTextDictInfoByProjectIdAndTabId(IPage<TextdictInfoVO> page, @Param("treePrivate") WbsTreePrivate treePrivate);
+
+    @Select("SELECT * from m_textdict_info WHERE project_id = #{treePrivate.projectId} and excel_id = #{treePrivate.excelId} and type in (2,6) and is_deleted = 0 and (SELECT 1 from m_wbs_tree_private WHERE p_key_id = tab_id and html_url = #{treePrivate.htmlUrl}) = 1")
+    List<TextdictInfoVO> selectTextdictInfoByExcelIdAndProjectIdAndHtmlUrl(IPage<TextdictInfoVO> page,@Param("treePrivate") WbsTreePrivate treePrivate);
 }

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

@@ -52,7 +52,7 @@
 
     <select id="selectTextdictBYIds" resultMap="textdictInfoVoResultMap">
         SELECT a.* from m_textdict_info a
-        where project_id=#{projectId} and  id in
+        where is_deleted = 0 and project_id=#{projectId} and  id in
         <foreach collection="ids" item="id" open="(" close=")" separator=",">
             #{id}
         </foreach>

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

@@ -24,7 +24,8 @@
             a.node_id,
             a.name_id,
             a.name_type,
-            (SELECT node_name FROM m_wbs_tree_private WHERE id = a.node_id LIMIT 1) AS nodeName
+            (SELECT node_name FROM m_wbs_tree_private WHERE id = a.node_id LIMIT 1) AS nodeName,
+            a.remark
         FROM m_wbs_param a
         WHERE a.project_id = #{projectId}
           AND a.is_deleted = 0

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

@@ -63,7 +63,7 @@ public interface IFormulaService extends BaseService<Formula> {
     /**
      * ids 表流水号 projectId项目 nodeId工序节点的pkeyId ExecuteType执行模式 质检或者试验 首件
      */
-    List<KeyMapper> getKeyMapperList(List<Long> ids, String projectId, String nodeId, ExecuteType executeType);
+    List<KeyMapper> getKeyMapperList(List<Long> ids, String projectId, String nodeId, ExecuteType executeType, String testGroupId);
 
    void formulaInto(List<FormData> curFormDatas, String projectId, String nodeId, ExecuteType executeType);
 

+ 3 - 4
blade-service/blade-manager/src/main/java/org/springblade/manager/service/IWbsTreeContractService.java

@@ -4,10 +4,7 @@ import org.apache.poi.openxml4j.exceptions.InvalidFormatException;
 import org.springblade.business.dto.EKeyDto;
 import org.springblade.core.mp.base.BaseService;
 import org.springblade.core.tool.api.R;
-import org.springblade.manager.dto.MoveNodeDTO;
-import org.springblade.manager.dto.RangeInfo;
-import org.springblade.manager.dto.WbsTreeContractDTO;
-import org.springblade.manager.dto.WbsTreeContractDTO2;
+import org.springblade.manager.dto.*;
 import org.springblade.manager.entity.ContractRelationJlyz;
 import org.springblade.manager.entity.WbsTreeContract;
 import org.springblade.manager.entity.WbsTreePrivate;
@@ -118,4 +115,6 @@ public interface IWbsTreeContractService extends BaseService<WbsTreeContract> {
     Object getWbsContractSubdivisionMeasurable(String projectId, String sectionId, String pid, Boolean judgment);
 
     List<QualityData> qualityDataAcquisition(String projectId, String sectionId, String codesId);
+
+    void setFormulaReference(FormulaReferenceDTO dto);
 }

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

@@ -84,7 +84,7 @@ public interface IWbsTreePrivateService extends BaseService<WbsTreePrivate> {
 
     List<WbsTreePrivateVO4> searchNodeAllTable(String primaryKeyId, String type, String tableType, String contractId, String projectId, Integer isAdd, Long id);
 
-    Object getExcelHtml(String primaryKeyId) throws Exception;
+    Object getExcelHtml(String primaryKeyId, String id) throws Exception;
 
     Object getExcelHtmlEntrust(String nodeId,String contractId) throws Exception;
 

+ 13 - 0
blade-service/blade-manager/src/main/java/org/springblade/manager/service/ProfilerDataService.java

@@ -0,0 +1,13 @@
+package org.springblade.manager.service;
+
+import org.springblade.manager.entity.ProfilerData;
+import com.baomidou.mybatisplus.extension.service.IService;
+
+/**
+* @author LHB
+* @description 针对表【q_profiler_data(断面仪-测量点数组)】的数据库操作Service
+* @createDate 2025-10-27 15:58:56
+*/
+public interface ProfilerDataService extends IService<ProfilerData> {
+
+}

+ 34 - 0
blade-service/blade-manager/src/main/java/org/springblade/manager/service/ProfilerOffsetService.java

@@ -0,0 +1,34 @@
+package org.springblade.manager.service;
+
+import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
+import org.springblade.manager.dto.ProfilerOffsetDTO;
+import org.springblade.manager.dto.ProfilerOffsetResultDTO;
+import org.springblade.manager.entity.ProfilerOffset;
+import com.baomidou.mybatisplus.extension.service.IService;
+import org.springblade.manager.entity.profiler.ProfilerResult;
+import org.springblade.manager.entity.profiler.ProfilerSaveDTO;
+import org.springframework.scheduling.annotation.Async;
+import org.springframework.web.multipart.MultipartFile;
+
+import java.util.List;
+
+/**
+* @author LHB
+* @description 针对表【q_profiler_offset(断面仪-基础信息+测量者信息)】的数据库操作Service
+* @createDate 2025-10-27 15:58:56
+*/
+public interface ProfilerOffsetService extends IService<ProfilerOffset> {
+
+    ProfilerResult save(ProfilerSaveDTO save, MultipartFile file);
+
+    ProfilerOffsetResultDTO getOne(Long id);
+
+    boolean edit(ProfilerOffsetResultDTO offset);
+
+    Page<ProfilerOffset> getPage(ProfilerOffsetDTO offset);
+
+    List<String> getListUserName();
+
+    @Async
+    void push();
+}

+ 13 - 0
blade-service/blade-manager/src/main/java/org/springblade/manager/service/ProfilerStandardSectionBeanService.java

@@ -0,0 +1,13 @@
+package org.springblade.manager.service;
+
+import org.springblade.manager.entity.ProfilerStandardSectionBean;
+import com.baomidou.mybatisplus.extension.service.IService;
+
+/**
+* @author LHB
+* @description 针对表【q_profiler_standard_section_bean(断面仪-标准断面)】的数据库操作Service
+* @createDate 2025-10-27 15:58:56
+*/
+public interface ProfilerStandardSectionBeanService extends IService<ProfilerStandardSectionBean> {
+
+}

+ 51 - 7
blade-service/blade-manager/src/main/java/org/springblade/manager/service/impl/ExcelTabServiceImpl.java

@@ -116,6 +116,7 @@ public class ExcelTabServiceImpl extends BaseServiceImpl<ExcelTabMapper, ExcelTa
 
     private final InformationQueryClient informationQueryClient;
     private final IWbsTreeContractService wbsTreeContractService;
+    private final WbsTreeContractExtendService wbsTreeContractExtendService;
     private final IFormulaService formulaService;
     @Autowired
     private JdbcTemplate jdbcTemplate;
@@ -362,7 +363,7 @@ public class ExcelTabServiceImpl extends BaseServiceImpl<ExcelTabMapper, ExcelTa
                 tableInfo.setProjectId(dataInfo2.getString("projectId"));
                 //huangjn 填报的类型,施工或监理
                 tableInfo.setClassify(dataInfo2.getString("classify"));
-
+                tableInfo.setIsRemoveForSubTab(dataInfo2.getString("isRemoveForSubTab"));
                 //设置首件信息
                 this.setFirstData(dataInfo2, tableInfo);
                 //设置日志信息
@@ -466,11 +467,11 @@ public class ExcelTabServiceImpl extends BaseServiceImpl<ExcelTabMapper, ExcelTa
                 }else{
                    tableAll = createNodeTables(nodeId, tableInfoList.get(0).getContractId(), tableInfoList.get(0).getProjectId(), type,tableInfoList.get(0).getClassify(), tableInfoList.get(0).getTestGroupId());
                 }
-
+                String isRemoveForSubTab = "0";
 
                 if (tableAll.size() > tableInfoList.size()) {
                     TableInfo example = tableInfoList.get(0);
-
+                    isRemoveForSubTab=example.getIsRemoveForSubTab();
                     /*补充缺失的数据*/
                     List<Long> cp = tableInfoList.stream().map(TableInfo::getPkeyId).map(Long::parseLong).collect(Collectors.toList());
                     List<Long> load = tableAll.stream().map(NodeTable::getPKeyId).filter(pk -> !cp.contains(pk)).collect(Collectors.toList());
@@ -503,6 +504,7 @@ public class ExcelTabServiceImpl extends BaseServiceImpl<ExcelTabMapper, ExcelTa
                                 e.setClassify(example.getClassify());
                                 e.setProjectId(example.getProjectId());
                                 e.setGroupId(example.getGroupId());
+                                e.setTestGroupId(example.getTestGroupId());
                                 map.forEach((key, value) -> {
                                     if (key.startsWith("key_")) {
                                         e.getDataMap().put(key, Func.toStr(value));
@@ -516,7 +518,7 @@ public class ExcelTabServiceImpl extends BaseServiceImpl<ExcelTabMapper, ExcelTa
                     tableInfoList.sort(Comparator.comparingInt(a -> tableAllIds.indexOf(Long.parseLong(a.getPkeyId()))));
                 }
                 StopWatch stopWatch = new StopWatch();
-                List<KeyMapper> keyMappers = this.formulaService.getKeyMapperList(tableAll.stream().map(NodeTable::getPKeyId).filter(Func::isNotEmpty).collect(Collectors.toList()), tableInfoList.get(0).getProjectId(), String.valueOf(nodeId), type);
+                List<KeyMapper> keyMappers = this.formulaService.getKeyMapperList(tableAll.stream().map(NodeTable::getPKeyId).filter(Func::isNotEmpty).collect(Collectors.toList()), tableInfoList.get(0).getProjectId(), String.valueOf(nodeId), type, tableInfoList.get(0).getTestGroupId());
                 if (Func.isNotEmpty(keyMappers) && Func.isNotEmpty(tableAll)) {
                     Map<String, Map<String, String>> coordinateMap = createCoordinateMap(keyMappers, type);
                     stopWatch.start("公式处理");
@@ -549,6 +551,7 @@ public class ExcelTabServiceImpl extends BaseServiceImpl<ExcelTabMapper, ExcelTa
                         tec.setExecuteType(type);
                         tec.setContractId(contractId);
                         tec.setProjectId(projectId);
+                        tec.setIsRemoveForSubTab(isRemoveForSubTab);
                         if (tec.isPresent()) {
                             tec.before();
                             this.formulaService.execute(tec);
@@ -1088,13 +1091,35 @@ public class ExcelTabServiceImpl extends BaseServiceImpl<ExcelTabMapper, ExcelTa
     @Override
     public void gsColor(Long pKeyId, String nodeId, String projectId, Document doc) {
         try {
-            List<KeyMapper> keyMappers = this.formulaService.getKeyMapperList(Collections.singletonList(pKeyId), projectId, nodeId, ExecuteType.INSPECTION);
+            List<KeyMapper> keyMappers = this.formulaService.getKeyMapperList(Collections.singletonList(pKeyId), projectId, nodeId, ExecuteType.INSPECTION, "1");
+            //扩展----根据父节点查询不允许执行的公式
+            WbsTreeContractExtend byId = wbsTreeContractExtendService.getById(nodeId);
+            List<String> list;
+
+            if(byId != null){
+                String formulaConfig = byId.getFormulaConfig();
+                if(StringUtils.isNotEmpty(formulaConfig)){
+                    list = Arrays.asList(formulaConfig.split(","));
+                } else {
+                    list = new ArrayList<>();
+                }
+            } else {
+                list = new ArrayList<>();
+            }
+
             if (!keyMappers.isEmpty()) {
                 keyMappers.stream()
                         .filter(e -> e.getFormulaId() != null)
                         .forEach(e -> {
                             String key = e.getField() + "__";
-                            processElements(doc.select("table").first().select("[keyname^=" + key + "]"));
+                            Elements select = doc.select("table").first().select("[keyname^=" + key + "]");
+                            if(list.contains(e.getTableName() + ":" + e.getField())){
+                                //当前元素不执行公式
+                                select.stream().filter(Objects::nonNull).forEach(element -> element.attr("clearFormula", "1"));
+                            }else{
+                                select.stream().filter(Objects::nonNull).forEach(element -> element.attr("clearFormula", "0"));
+                                processElements(select);
+                            }
                         });
             }
         } catch (Exception e) {
@@ -1375,7 +1400,7 @@ public class ExcelTabServiceImpl extends BaseServiceImpl<ExcelTabMapper, ExcelTa
 //                    sqlInfo = sqlInfo + keyStr + ") VALUES (" + valStr + ")";
 
                     WbsTreeContract wbsTreeContractByP = wbsTreeContractService.getBaseMapper().selectOne(Wrappers.<WbsTreeContract>query().lambda()
-                            .eq(WbsTreeContract::getId, wbsTreeContract.getParentId()).eq(WbsTreeContract::getContractId, tableInfo.getContractId()));
+                            .eq(WbsTreeContract::getPKeyId, wbsTreeContract.getPId()).eq(WbsTreeContract::getContractId, wbsTreeContract.getContractId()));
                     if (wbsTreeContractByP != null) {
                         //处理文件提名
                         String fileName = this.wbsParamService.createFileTitle(wbsTreeContractByP);
@@ -1833,6 +1858,15 @@ public class ExcelTabServiceImpl extends BaseServiceImpl<ExcelTabMapper, ExcelTa
                     }
                 }
             }
+            //取消公式执行 的单元格不自动获取html上的数据到表格中
+            WbsTreeContractExtend byId = wbsTreeContractExtendService.getById(nodeId);
+            if(byId != null && StringUtils.isNotEmpty(byId.getFormulaConfig())){
+                List<String> notFormula = Arrays.asList(byId.getFormulaConfig().split(","));
+                reData.keySet().removeIf(key -> {
+                    String[] keyParts = key.split("__");
+                    return keyParts.length > 1 && notFormula.contains(wbsTreeContract.getInitTableName() + ":" + keyParts[0]);
+                });
+            }
 
             //电签默认值
             if (defText.size() >= 1) {
@@ -3228,6 +3262,16 @@ public class ExcelTabServiceImpl extends BaseServiceImpl<ExcelTabMapper, ExcelTa
                         break;
                     }
                 }
+                //取消公式执行 过滤html数据
+                WbsTreeContractExtend byId = wbsTreeContractExtendService.getById(record.getId());
+                if(byId != null && StringUtils.isNotEmpty(byId.getFormulaConfig())){
+                    List<String> notFormula = Arrays.asList(byId.getFormulaConfig().split(","));
+                    reData.keySet().removeIf(key -> {
+                        String[] keyParts = key.split("__");
+                        return keyParts.length > 1 && notFormula.contains(wbsTreePrivate.getInitTableName() + ":" + keyParts[0]);
+                    });
+
+                }
 
                 ProjectInfo projectInfo = jdbcTemplate.query("select project_name from m_project_info where id = " + wbsTreePrivate.getProjectId(), new BeanPropertyRowMapper<>(ProjectInfo.class)).stream().findAny().orElse(null);
                 if (projectInfo != null) {

+ 95 - 34
blade-service/blade-manager/src/main/java/org/springblade/manager/service/impl/FormulaServiceImpl.java

@@ -78,6 +78,7 @@ import java.io.*;
 import java.lang.reflect.Field;
 import java.math.BigDecimal;
 import java.math.RoundingMode;
+import java.text.SimpleDateFormat;
 import java.time.LocalDate;
 import java.time.format.DateTimeFormatter;
 import java.util.*;
@@ -130,6 +131,7 @@ public class FormulaServiceImpl extends BaseServiceImpl<FormulaMapper, Formula>
     private final IWbsParamService wpService;
     private final FormulaStrategyFactory formulaStrategyFactory;
     private final IWbsTreeContractService wbsTreeContractService;
+    private final WbsTreeContractExtendService wbsTreeContractExtendService;
     private final WbsTreePrivateMapper wbsTreePrivateMapper;
     private final IElementFormulaMappingService elementFormulaMappingService;
     private final JdbcTemplate jdbcTemplate;
@@ -1237,8 +1239,21 @@ public class FormulaServiceImpl extends BaseServiceImpl<FormulaMapper, Formula>
         try {
             List<String> dateList = new ArrayList<>();
             tec.formDataList.forEach(e -> {
-                if (e.executable() && (e.getFormula().getFormula().contains(".weather(") || e.getFormula().getFormula().contains(".maxtembydate("))) {
-                    String code = RegexUtil.findResult("(?<=\\(E\\[')[^']+(?='\\],WEATHER\\))", e.getFormula().getFormula());
+                if (e.executable() && (e.getFormula().getFormula().contains(".weather(") //天气
+                        || e.getFormula().getFormula().contains(".maxtembydate(") // 最大气温
+                        || e.getFormula().getFormula().contains(".mintembydate(")  // 最小气温
+                        || e.getFormula().getFormula().contains(".maxminbydate(")  //最大最小气温
+                        || e.getFormula().getFormula().contains(".weathertem(")    // 气温/天气
+                        || e.getFormula().getFormula().contains(".weekbydate(")  // 日期计算周几
+                )) {
+                    String tyepData[] = new String[]{"WEATHER","MAXTEMBYDATE","MINTEMBYDATE","MAXMINBYDATE","WEATHERTEM","WEEKBYDATE"};
+                    String code ="";
+                    for (int i=0;i<tyepData.length;i++){
+                        code = RegexUtil.findResult("(?<=\\(E\\[')[^']+(?='\\],"+tyepData[i]+"\\))", e.getFormula().getFormula());
+                        if (code != null) {
+                            break;
+                        }
+                    }
                     if (code != null) {
                         FormData formData = tec.getFormDataMap().get(code);
                         if (formData != null && !formData.empty()) {
@@ -1249,38 +1264,51 @@ public class FormulaServiceImpl extends BaseServiceImpl<FormulaMapper, Formula>
                 }
             });
             if (dateList.size() > 0) {
-                List<Map<String, Object>> listMap = this.jdbcTemplate.queryForList(" select DATE(b.record_time) ds,b.weather,temp_high as maxtembydate,temp_low as mintembydate from m_project_contract_area a join u_weather_info b on a.id=contract_area_id where a.contract_id=" + tec.getContractId() + " and DATE(b.record_time) in('" + dateList.stream().distinct().collect(Collectors.joining("','")) + "')");
+                List<Map<String, Object>> listMap = this.jdbcTemplate.queryForList(" select DATE(b.record_time) ds,b.weather,temp_high as maxtembydate,temp_low as mintembydate,CONCAT_WS('~',temp_low,temp_high) as maxminbydate,CONCAT(b.weather,'、',temp_low,'℃~',temp_high,'℃') as weathertem from m_project_contract_area a join u_weather_info b on a.id=contract_area_id where a.contract_id=" + tec.getContractId() + " and DATE(b.record_time) in('" + dateList.stream().distinct().collect(Collectors.joining("','")) + "')");
+
                 // 天气
                 Map<String, String> map = new HashMap<>();
+                //最高气温
+                Map<String, String> map2 = new HashMap<>();
+                //最低气温
+                Map<String, String> map3 = new HashMap<>();
                 //星期几
                 Map<String, String> map4 = new HashMap<>();
+                //最高最低气温
+                Map<String, String> map5 = new HashMap<>();
+                //气温 天气
+                Map<String, String> map6 = new HashMap<>();
                 listMap.forEach(m -> {
                     String ds = Func.toStr(m.get("ds"));
                     map.put(ds, Func.toStr(m.get("weather")));
                     //将时间转化星期几
+                    if (StringUtils.isNotEmpty(ds)) {
+                        Date datetime = null;
+                        SimpleDateFormat dateFormat = new SimpleDateFormat("yyyy-MM-dd");
+                        try {
+                            datetime = dateFormat.parse(ds);
+                        }catch (Exception e){
 
-
-
+                        }
+                        String[] weekDays = {"日", "一", "二", "三", "四", "五", "六"};
+                        Calendar calendar = Calendar.getInstance();
+                        calendar.setTime(datetime);
+                        String week = weekDays[calendar.get(Calendar.DAY_OF_WEEK) - 1];
+                        map4.put(ds, week);
+                    }else {
+                        map4.put(ds, "");
+                    }
+                    map2.put(ds, Func.toStr(m.get("maxtembydate")));
+                    map3.put(ds, Func.toStr(m.get("mintembydate")));
+                    map5.put(ds, Func.toStr(m.get("maxminbydate")));
+                    map6.put(ds, Func.toStr(m.get("weathertem")));
                 });
                 tec.constantMap.put("WEATHER", map);
-
-                // 最高气温
-                Map<String, String> map2 = new HashMap<>();
-                listMap.forEach(m -> {
-                    map2.put(Func.toStr(m.get("ds")), Func.toStr(m.get("maxtembydate")));
-                });
                 tec.constantMap.put("MAXTEMBYDATE", map2);
-
-                // 最低气温
-                Map<String, String> map3 = new HashMap<>();
-                listMap.forEach(m -> {
-                    map3.put(Func.toStr(m.get("ds")), Func.toStr(m.get("mintembydate")));
-                });
                 tec.constantMap.put("MINTEMBYDATE", map3);
-
-                //星期几
-                tec.constantMap.put("MINTEMBYDATE", map4 );
-
+                tec.constantMap.put("WEEKBYDATE", map4);
+                tec.constantMap.put("MAXMINBYDATE", map5);
+                tec.constantMap.put("WEATHERTEM", map6);
             }
         } catch (Exception e) {
             e.printStackTrace();
@@ -1326,6 +1354,12 @@ public class FormulaServiceImpl extends BaseServiceImpl<FormulaMapper, Formula>
                             });
                             if (ele.size() < relyList.size()) {
                                 tec.getLog().put(FormulaLog.RELY, fd.getCode() + "@" + fd.getEName() + "@" + fd.getFormula().getFormula().replaceAll("'", ""));
+                                fd.getValues().forEach(e->e.setValue(null));
+                                FormData formData = tec.getFormDataMap().get(fd.getCode());
+                                if(formData!=null){
+                                    formData.getValues().forEach(e->e.setValue(null));
+                                    formData.setUpdate(1);
+                                }
                                 continue;
                             }
                             if (fd.getCoordsList().size() > 1 && f.split("[/+\\-*]").length > 1) {
@@ -1663,14 +1697,16 @@ public class FormulaServiceImpl extends BaseServiceImpl<FormulaMapper, Formula>
                 headerFooterSub(subTableFds, tec);
                 /*如果识别到手填内容需要在附表写入数据后,更新评定关联数据*/
             }else {
-                List<NodeTable> subTabList = tec.getTableAll().stream().filter(e -> e.getNodeName().contains("附表") && (e.getTableType() == 1 || e.getTableType() == 5)).collect(Collectors.toList());
-                if(!subTabList.isEmpty()){
-                    String queryIds = subTabList.stream().map(e -> e.getPKeyId() + "").collect(Collectors.joining(","));
-                    // 如果不是系统自动生成的附表,则不删除。
-                    List<Long> ids = jdbcTemplate.query("SELECT a.p_key_id from m_wbs_tree_contract a LEFT JOIN m_wbs_tree_private b on b.p_key_id = a.is_type_private_pid " +
-                            "where a.is_deleted = 0 and (b.p_key_id is null or (b.is_deleted = 0 and b.is_link_table = 2 and b.type = 10 )) and a.p_key_id in ( " + queryIds +")", new SingleColumnRowMapper<>(Long.class));
-                    if (!ids.isEmpty()) {
-                        this.wbsTreeContractMapper.deleteLogicByIds(ids);
+                if(StringUtils.isNotEmpty(tec.getIsRemoveForSubTab())&&"1".equals(tec.getIsRemoveForSubTab())){
+                    List<NodeTable> subTabList = tec.getTableAll().stream().filter(e -> e.getNodeName().contains("附表") && (e.getTableType() == 1 || e.getTableType() == 5)).collect(Collectors.toList());
+                    if(!subTabList.isEmpty()){
+                        String queryIds = subTabList.stream().map(e -> e.getPKeyId() + "").collect(Collectors.joining(","));
+                        // 如果不是系统自动生成的附表,则不删除。
+                        List<Long> ids = jdbcTemplate.query("SELECT a.p_key_id from m_wbs_tree_contract a LEFT JOIN m_wbs_tree_private b on b.p_key_id = a.is_type_private_pid " +
+                                "where a.is_deleted = 0 and (b.p_key_id is null or (b.is_deleted = 0 and b.is_link_table = 2 and b.type = 10 )) and a.p_key_id in ( " + queryIds +")", new SingleColumnRowMapper<>(Long.class));
+                        if (!ids.isEmpty()) {
+                            this.wbsTreeContractMapper.deleteLogicByIds(ids);
+                        }
                     }
                 }
             }
@@ -2249,12 +2285,12 @@ public class FormulaServiceImpl extends BaseServiceImpl<FormulaMapper, Formula>
     }
 
     @Override
-    public List<KeyMapper> getKeyMapperList(List<Long> ids, String projectId, String nodeId, ExecuteType executeType) {
+    public List<KeyMapper> getKeyMapperList(List<Long> ids, String projectId, String nodeId, ExecuteType executeType, String testGroupId) {
         /*ids 表流水号 projectId项目 nodeId工序节点的pkeyId ExecuteType执行模式 质检或者试验 首件*/
         if (executeType.equals(ExecuteType.INSPECTION)) {
-            return listForContract(ids, projectId, nodeId);
+            return listForContract(ids, projectId, nodeId, testGroupId);
         } else if (executeType.equals(ExecuteType.TESTING) ) {
-            return listForPrivate(ids, projectId, nodeId);
+            return listForPrivate(ids, projectId, nodeId, testGroupId);
         } else if (executeType.equals(ExecuteType.LOGINFO) ) {
             return listForPrivateByLog(ids, projectId, nodeId);
         }
@@ -4927,8 +4963,18 @@ public class FormulaServiceImpl extends BaseServiceImpl<FormulaMapper, Formula>
     }
 
     /*表id,项目id,节点Id*/
-    public List<KeyMapper> listForContract(List<Long> ids, String projectId, String nodeId) {
+    public List<KeyMapper> listForContract(List<Long> ids, String projectId, String nodeId, String testGroupId) {
         List<Map<String, Object>> listMap = listMap(ids, ExecuteType.INSPECTION);
+        //质检这个参数为0,表示过滤公式,为1,表示html渲染表格
+        if(!"1".equals(testGroupId)){
+            //根据节点id查询 合同段扩展表
+            WbsTreeContractExtend byId = wbsTreeContractExtendService.getById(nodeId);
+            if (byId != null && StringUtils.isNotEmpty(byId.getFormulaConfig())) {
+                List<String> list = Arrays.asList(byId.getFormulaConfig().split(","));
+                listMap = listMap.stream().filter(m -> !list.contains(m.get("tableName").toString() + ":" + m.get("field").toString())).collect(Collectors.toList());
+            }
+        }
+
         WbsTreePrivate wtp = wtpId(Long.parseLong(nodeId));
         if (Func.isNotEmpty(listMap)) {
             /*当前节点的某个元素存在多种作用域的公式,作用域范围越小优先级越高*/
@@ -5013,9 +5059,17 @@ public class FormulaServiceImpl extends BaseServiceImpl<FormulaMapper, Formula>
 
     }
 
-    private List<KeyMapper> listForPrivate(List<Long> ids, String projectId, String nodeId) {
+    private List<KeyMapper> listForPrivate(List<Long> ids, String projectId, String nodeId, String testGroupId) {
         /**/
         List<Map<String, Object>> listMap = listMap(ids, ExecuteType.TESTING);
+        if(StringUtil.isNotBlank(testGroupId)){
+            //根据节点id查询 合同段扩展表
+            WbsTreeContractExtend byId = wbsTreeContractExtendService.getById(testGroupId);
+            if (byId != null && StringUtils.isNotEmpty(byId.getFormulaConfig())) {
+                List<String> list = Arrays.asList(byId.getFormulaConfig().split(","));
+                listMap = listMap.stream().filter(m -> !list.contains(m.get("tableName").toString() + ":" + m.get("field").toString())).collect(Collectors.toList());
+            }
+        }
         List<KeyMapper> list = listMap.stream().map(m -> BeanUtil.toBean(m, KeyMapper.class)).collect(Collectors.toList());
         if (Func.isNotEmpty(listMap)) {
             WbsTreePrivate wtp = this.wbsTreePrivateMapper.selectOne(Wrappers.<WbsTreePrivate>lambdaQuery().eq(WbsTreePrivate::getPKeyId, nodeId));
@@ -6173,6 +6227,13 @@ public class FormulaServiceImpl extends BaseServiceImpl<FormulaMapper, Formula>
                 });
             }*/
             fds.removeIf(f -> f.getFormula() == null);
+            //取消公式执行
+            WbsTreeContractExtend byId = wbsTreeContractExtendService.getById(wtc.getPId());
+            if(byId != null && org.apache.commons.lang.StringUtils.isNotEmpty(byId.getFormulaConfig())){
+                List<String> list = Arrays.asList(byId.getFormulaConfig().split(","));
+                fds = fds.stream().filter(f -> !list.contains(f.getCode())).collect(Collectors.toList());
+            }
+
             if (fds.size() > 0) {
                 /*执行结果放回数据集合*/
                 Map<String, Object> currentMap = new HashMap<>(30);

+ 22 - 0
blade-service/blade-manager/src/main/java/org/springblade/manager/service/impl/ProfilerDataServiceImpl.java

@@ -0,0 +1,22 @@
+package org.springblade.manager.service.impl;
+
+import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
+import org.springblade.manager.entity.ProfilerData;
+import org.springblade.manager.service.ProfilerDataService;
+import org.springblade.manager.mapper.ProfilerDataMapper;
+import org.springframework.stereotype.Service;
+
+/**
+* @author LHB
+* @description 针对表【q_profiler_data(断面仪-测量点数组)】的数据库操作Service实现
+* @createDate 2025-10-27 15:58:56
+*/
+@Service
+public class ProfilerDataServiceImpl extends ServiceImpl<ProfilerDataMapper, ProfilerData>
+    implements ProfilerDataService {
+
+}
+
+
+
+

+ 339 - 0
blade-service/blade-manager/src/main/java/org/springblade/manager/service/impl/ProfilerOffsetServiceImpl.java

@@ -0,0 +1,339 @@
+package org.springblade.manager.service.impl;
+
+import cn.hutool.core.date.DateTime;
+import cn.hutool.core.util.URLUtil;
+import cn.hutool.http.HttpException;
+import cn.hutool.http.HttpRequest;
+import cn.hutool.http.HttpUtil;
+import cn.hutool.json.JSONConfig;
+import cn.hutool.json.JSONObject;
+import cn.hutool.json.JSONUtil;
+import com.alibaba.nacos.common.utils.MD5Utils;
+import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
+import com.baomidou.mybatisplus.core.toolkit.Wrappers;
+import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
+import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
+import lombok.extern.slf4j.Slf4j;
+import org.apache.commons.codec.digest.HmacAlgorithms;
+import org.apache.commons.codec.digest.HmacUtils;
+import org.apache.commons.lang.RandomStringUtils;
+import org.springblade.common.utils.SnowFlakeUtil;
+import org.springblade.core.oss.model.BladeFile;
+import org.springblade.core.tool.utils.BeanUtil;
+import org.springblade.core.tool.utils.CollectionUtil;
+import org.springblade.core.tool.utils.StringUtil;
+import org.springblade.manager.dto.ProfilerOffsetDTO;
+import org.springblade.manager.dto.ProfilerOffsetResultDTO;
+import org.springblade.manager.entity.ProfilerData;
+import org.springblade.manager.entity.ProfilerOffset;
+import org.springblade.manager.entity.ProfilerStandardSectionBean;
+import org.springblade.manager.entity.profiler.*;
+import org.springblade.manager.service.ProfilerDataService;
+import org.springblade.manager.service.ProfilerOffsetService;
+import org.springblade.manager.mapper.ProfilerOffsetMapper;
+import org.springblade.manager.service.ProfilerStandardSectionBeanService;
+import org.springblade.resource.feign.NewIOSSClient;
+import org.springframework.dao.DataAccessException;
+import org.springframework.jdbc.core.JdbcTemplate;
+import org.springframework.scheduling.annotation.Scheduled;
+import org.springframework.stereotype.Service;
+import org.springframework.transaction.annotation.Transactional;
+import org.springframework.web.multipart.MultipartFile;
+
+import javax.annotation.Resource;
+import javax.servlet.http.HttpServletRequest;
+import java.time.Instant;
+import java.util.*;
+
+/**
+ * @author LHB
+ * @description 针对表【q_profiler_offset(断面仪-基础信息+测量者信息)】的数据库操作Service实现
+ * @createDate 2025-10-27 15:58:56
+ */
+@Service
+@Slf4j
+public class ProfilerOffsetServiceImpl extends ServiceImpl<ProfilerOffsetMapper, ProfilerOffset>
+        implements ProfilerOffsetService {
+
+    //第三方的appKey 固定值
+    private final static String APP_KEY = "QDM123";
+    //第三方密钥
+    private final static String APP_SECRET = "MDc1YWI4OTMtY2M0NC00NDViLTlkZmUtYzAzZTVmZTUxMmE1";
+    // 时间戳有效期(秒),防止重放攻击 // 30分钟
+    private static final long TIMESTAMP_EXPIRE = 1800;
+    @Resource
+    private NewIOSSClient newIOSSClient;
+    @Resource
+    private ProfilerDataService dataService;
+    @Resource
+    private ProfilerStandardSectionBeanService beanService;
+    @Resource
+    private JdbcTemplate jdbcTemplate;
+    @Override
+    @Transactional(rollbackFor = Exception.class)
+    public ProfilerResult save(ProfilerSaveDTO save, MultipartFile file) {
+        if (!save.getAppKey().equals(APP_KEY)) {
+            return ProfilerResult.error("10006", "appKey错误", "");
+        }
+        String s = MD5Utils.md5Hex(APP_KEY + APP_SECRET + save.getTimestamp(), "UTF-8");
+        if (!s.equals(save.getSign())) {
+            return ProfilerResult.error("10007", "sign错误", "");
+        }
+        if (!isValidTimestamp(save.getTimestamp())) {
+            return ProfilerResult.error("10008", "签名验证失败:timeTicks的时间和当前时间必须小于30分钟", "");
+        }
+
+        //主键id
+        Long id = SnowFlakeUtil.getId();
+        //断面仪测量设备编码或名称
+        String deviceCode = save.getDeviceCode();
+        //字符串转json
+        JSONObject jsonObject = null;
+        try {
+            jsonObject = JSONUtil.parseObj(save.getData());
+        } catch (Exception e) {
+            return ProfilerResult.error("10009", "data参数格式错误", "");
+        }
+        //获取基础信息 + 测量者信息
+        ProfilerOffset offset = jsonObject.getBean("offset", ProfilerOffset.class);
+        if (offset == null) {
+            offset = new ProfilerOffset();
+        }
+        offset.setId(id);
+        offset.setDeviceCode(deviceCode);
+        ProfilerOffset info = jsonObject.getBean("info", ProfilerOffset.class);
+        //把测量者信息赋值给基础信息对象
+        if (info != null) {
+            offset.setChannelName(info.getChannelName());
+            offset.setConstructionUnit(info.getConstructionUnit());
+            offset.setDate(info.getDate());
+            offset.setNameOfProject(info.getNameOfProject());
+            offset.setUserName(info.getUserName());
+            offset.setMileageNumber(info.getMileageNumber());
+        }
+        //获取标准断面数据
+        JSONObject mStandardSectionDataBeanList = jsonObject.getJSONObject("standardSectionBean");
+        List<ProfilerStandardSectionBean> standardSectionBean = null;
+        if (mStandardSectionDataBeanList != null) {
+            standardSectionBean = mStandardSectionDataBeanList.getBeanList("mStandardSectionDataBeanList", ProfilerStandardSectionBean.class);
+            if (standardSectionBean != null) {
+                standardSectionBean.forEach(f -> {
+                    f.setId(SnowFlakeUtil.getId());
+                    f.setOffsetId(id);
+                });
+            }
+        }
+        //获取测量数据
+        List<ProfilerData> data = jsonObject.getBeanList("data", ProfilerData.class);
+        if (data != null) {
+            data.forEach(f -> {
+                f.setId(SnowFlakeUtil.getId());
+                f.setOffsetId(id);
+            });
+        }
+        //上传文件
+        if (file != null && !file.isEmpty() && file.getSize() > 0) {
+            //获取文件名称后缀
+            BladeFile bladeFile = this.newIOSSClient.uploadFileByInputStream(file);
+            offset.setFileUrl(bladeFile.getLink());
+        }
+        //保存数据
+        baseMapper.insert(offset);
+        if (CollectionUtil.isNotEmpty(standardSectionBean)) {
+            beanService.saveBatch(standardSectionBean);
+        }
+        if (CollectionUtil.isNotEmpty(data)) {
+            dataService.saveBatch(data);
+        }
+        return ProfilerResult.success();
+    }
+
+    /**
+     * 验证时间戳有效性
+     *
+     * @param timestamp 时间戳字符串
+     * @return 是否有效
+     */
+    private static boolean isValidTimestamp(Long timestamp) {
+        try {
+            long currentTs = Instant.now().getEpochSecond();
+            // 检查时间戳是否在有效期内(前后5分钟)
+            return Math.abs(currentTs - timestamp) <= TIMESTAMP_EXPIRE;
+        } catch (NumberFormatException e) {
+            return false;
+        }
+    }
+
+    @Override
+    public ProfilerOffsetResultDTO getOne(Long id) {
+        ProfilerOffset byId = this.getById(id);
+        if (byId != null) {
+            ProfilerOffsetResultDTO resultDTO = BeanUtil.copyProperties(byId, ProfilerOffsetResultDTO.class);
+            if (resultDTO != null) {
+                List<ProfilerStandardSectionBean> list = beanService.list(Wrappers.<ProfilerStandardSectionBean>lambdaQuery().eq(ProfilerStandardSectionBean::getOffsetId, id));
+                List<ProfilerData> list1 = dataService.list(Wrappers.<ProfilerData>lambdaQuery().eq(ProfilerData::getOffsetId, id));
+                resultDTO.setSectionBeans(list);
+                resultDTO.setData(list1);
+            }
+            return resultDTO;
+        }
+        return null;
+    }
+
+    @Override
+    @Transactional(rollbackFor = Exception.class)
+    public boolean edit(ProfilerOffsetResultDTO offset) {
+        ProfilerOffset qProfilerOffset = BeanUtil.copyProperties(offset, ProfilerOffset.class);
+        boolean update = this.updateById(qProfilerOffset);
+
+        List<ProfilerStandardSectionBean> sectionBeans = offset.getSectionBeans();
+        if (CollectionUtil.isNotEmpty(sectionBeans)) {
+            beanService.updateBatchById(sectionBeans);
+        }
+        List<ProfilerData> data = offset.getData();
+        if (CollectionUtil.isNotEmpty(data)) {
+            dataService.updateBatchById(data);
+        }
+        return update;
+    }
+
+    @Override
+    public Page<ProfilerOffset> getPage(ProfilerOffsetDTO offset) {
+        QueryWrapper<ProfilerOffset> qProfilerOffsetQueryWrapper = new QueryWrapper<>();
+        qProfilerOffsetQueryWrapper.lambda()
+                .eq(StringUtil.isNotBlank(offset.getUserName()), ProfilerOffset::getUserName, offset.getUserName())
+                .eq(StringUtil.isNotBlank(offset.getBackBreak()), ProfilerOffset::getBackBreak, offset.getBackBreak())
+                .ge(StringUtil.isNotBlank(offset.getStartTime()), ProfilerOffset::getDate, offset.getStartTime())
+                .le(StringUtil.isNotBlank(offset.getEndTime()), ProfilerOffset::getDate, offset.getEndTime());
+        return baseMapper.selectPage(new Page<>(offset.getCurrent(), offset.getSize()), qProfilerOffsetQueryWrapper);
+    }
+
+    @Override
+    public List<String> getListUserName() {
+        return baseMapper.getListUserName();
+    }
+
+    @Override
+    @Transactional(rollbackFor = Exception.class)
+    @Scheduled(cron = "0 0 23 ? * FRI")
+    public void push() {
+        String url = "/data/openapi/v1/push";
+
+
+        //从系统参数中获取配置信息
+        String sql = "select param_value from blade_param where param_key = 'profiler.isPush' and is_deleted = 0";
+        Integer isPush = jdbcTemplate.queryForObject(sql, Integer.class);
+        //判断是否上传数据
+        if(isPush != null && isPush == 0){
+            return;
+        }
+
+        //从系统参数中获取配置信息
+        String baseUrl = null;
+        try {
+            sql = "select param_value from blade_param where param_key = 'profiler.baseUrl' and is_deleted = 0";
+            baseUrl = jdbcTemplate.queryForObject(sql, String.class);
+        } catch (DataAccessException e) {
+            log.error("系统参数未找到 profiler.baseUrl");
+        }
+
+        String clientKey = null;
+        try {
+            sql = "select param_value from blade_param where param_key = 'profiler.clientKey' and is_deleted = 0";
+            //第三方提供的key
+            clientKey = jdbcTemplate.queryForObject(sql, String.class);
+        } catch (DataAccessException e) {
+            log.error("系统参数未找到 profiler.clientKey");
+            return;
+        }
+
+        String secret = null;
+        try {
+            sql = "select param_value from blade_param where param_key = 'profiler.secret' and is_deleted = 0";
+            //第三方提供的key
+            secret = jdbcTemplate.queryForObject(sql, String.class);
+        } catch (DataAccessException e) {
+            log.error("系统参数未找到 profiler.secret");
+            return;
+        }
+
+        String protocolApiId = null;
+        try {
+            sql = "select param_value from blade_param where param_key = 'profiler.protocolApiId' and is_deleted = 0";
+            //第三方提供的key
+            protocolApiId = jdbcTemplate.queryForObject(sql, String.class);
+        } catch (DataAccessException e) {
+            log.error("系统参数未找到 profiler.protocolApiId");
+            return;
+        }
+        if(StringUtil.isBlank(baseUrl) || StringUtil.isBlank(clientKey) || StringUtil.isBlank(secret) || StringUtil.isBlank(protocolApiId)){
+            log.error("系统参数未找到配置项");
+            return;
+        }
+
+        //当前时间戳
+        String secTimestamp = String.valueOf(System.currentTimeMillis());
+
+        //获取数据
+        List<ProfilerOffset> list = this.list(Wrappers.<ProfilerOffset>lambdaQuery().eq(ProfilerOffset::getPush, 0));
+        log.info("开始推送断面仪数据------{}", DateTime.now());
+        for (ProfilerOffset f : list) {
+            //随机字符串 每次推送都是唯一的
+            String secNonce = UUID.randomUUID().toString();
+            //获取测量断面
+            List<ProfilerStandardSectionBean> sectionBeans = beanService.list(Wrappers.<ProfilerStandardSectionBean>lambdaQuery().eq(ProfilerStandardSectionBean::getOffsetId, f.getId()));
+            List<ProfilerSectionPush> sectionPushes = ProfilerSectionPush.parameterMapping(sectionBeans);
+            //获取测量数据
+            List<ProfilerData> data = dataService.list(Wrappers.<ProfilerData>lambdaQuery().eq(ProfilerData::getOffsetId, f.getId()));
+            List<ProfilerDataPush> dataPushes = ProfilerDataPush.parameterMapping(data);
+
+            //赋值
+            ProfilerOffsetPush profilerOffsetPush = ProfilerOffsetPush.parameterMapping(f);
+            profilerOffsetPush.setMeasurement_section(sectionPushes);
+            profilerOffsetPush.setReceipt_data(dataPushes);
+            //设置不忽略空值
+            JSONConfig config = JSONConfig.create().setIgnoreNullValue(false);
+            JSONObject jsonObject = new JSONObject(config);
+            jsonObject.set("protocolApiId", protocolApiId);
+            jsonObject.set("data", profilerOffsetPush);
+
+            //数据json字符串
+            String catLog = jsonObject.toString();
+            //http对象
+            HttpRequest post = HttpUtil.createPost(baseUrl + url);
+            //获取签名字符串
+            String sign = "POST_" + url + "_" + secTimestamp + "_" + secNonce;
+            //请求头
+            HashMap<String, String> catLogHeaders = new HashMap<>();
+            catLogHeaders.put("Content-Type", "application/json");
+            //应用ID
+            catLogHeaders.put("Sec-API-Key", clientKey);
+            //当前时间 毫秒值
+            catLogHeaders.put("Sec-Timestamp", secTimestamp);
+            //请求发起时的随机字符串,需要保证唯一性
+            catLogHeaders.put("Sec-Nonce", secNonce);
+            //签名
+            catLogHeaders.put("Sec-Signature", new HmacUtils(HmacAlgorithms.HMAC_SHA_256, secret).hmacHex(sign));
+
+            try {
+                String catLogBody = post.addHeaders(catLogHeaders).body(catLog).contentType("application/json").execute().body();
+                //响应结果
+                JSONObject result = JSONUtil.parseObj(catLogBody);
+                log.info("推送结果:{}",result);
+                if ("200".equals(result.getStr("code"))) {
+                    f.setPush(1);
+                } else {
+                    f.setPush(2);
+                }
+            } catch (HttpException e) {
+                f.setPush(2);
+            }
+        }
+        log.info("推送完成------{}", DateTime.now());
+        this.updateBatchById(list);
+    }
+}
+
+
+
+

+ 22 - 0
blade-service/blade-manager/src/main/java/org/springblade/manager/service/impl/ProfilerStandardSectionBeanServiceImpl.java

@@ -0,0 +1,22 @@
+package org.springblade.manager.service.impl;
+
+import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
+import org.springblade.manager.entity.ProfilerStandardSectionBean;
+import org.springblade.manager.service.ProfilerStandardSectionBeanService;
+import org.springblade.manager.mapper.ProfilerStandardSectionBeanMapper;
+import org.springframework.stereotype.Service;
+
+/**
+* @author LHB
+* @description 针对表【q_profiler_standard_section_bean(断面仪-标准断面)】的数据库操作Service实现
+* @createDate 2025-10-27 15:58:56
+*/
+@Service
+public class ProfilerStandardSectionBeanServiceImpl extends ServiceImpl<ProfilerStandardSectionBeanMapper, ProfilerStandardSectionBean>
+    implements ProfilerStandardSectionBeanService {
+
+}
+
+
+
+

+ 48 - 37
blade-service/blade-manager/src/main/java/org/springblade/manager/service/impl/TextdictInfoServiceImpl.java

@@ -16,20 +16,32 @@
  */
 package org.springblade.manager.service.impl;
 
+import com.baomidou.mybatisplus.core.mapper.BaseMapper;
 import com.baomidou.mybatisplus.core.metadata.IPage;
+import com.baomidou.mybatisplus.core.toolkit.Wrappers;
+import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
 import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
 import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
+import org.apache.commons.lang.StringUtils;
+import org.jetbrains.annotations.NotNull;
+import org.jetbrains.annotations.Nullable;
 import org.jsoup.Jsoup;
 import org.jsoup.nodes.Document;
 import org.jsoup.nodes.Element;
 import org.jsoup.select.Elements;
 import org.springblade.common.constant.CommonConstant;
 import org.springblade.common.utils.CommonUtil;
+import org.springblade.common.utils.SnowFlakeUtil;
+import org.springblade.common.utils.SystemUtils;
+import org.springblade.core.tool.utils.*;
+import org.springblade.common.constant.CommonConstant;
+import org.springblade.common.utils.CommonUtil;
 import org.springblade.core.tool.utils.FileUtil;
 import org.springblade.core.tool.utils.Func;
 import org.springblade.core.tool.utils.IoUtil;
 import org.springblade.core.tool.utils.ResourceUtil;
 import org.springblade.manager.entity.TextdictInfo;
+import org.springblade.manager.entity.WbsTreeContract;
 import org.springblade.manager.entity.WbsTreePrivate;
 import org.springblade.manager.mapper.TextdictInfoMapper;
 import org.springblade.manager.mapper.WbsTreePrivateMapper;
@@ -48,7 +60,9 @@ import java.io.File;
 import java.io.FileInputStream;
 import java.io.FileNotFoundException;
 import java.io.InputStream;
+import java.io.*;
 import java.util.*;
+import java.util.concurrent.atomic.AtomicBoolean;
 import java.util.stream.Collectors;
 
 /**
@@ -61,9 +75,6 @@ import java.util.stream.Collectors;
 public class TextdictInfoServiceImpl extends ServiceImpl<TextdictInfoMapper, TextdictInfo> implements ITextdictInfoService {
     @Resource
     private WbsTreePrivateMapper wbsTreePrivateMapper;
-
-    @Resource
-    private ISignConfigService iSignConfigService;
     @Override
     public IPage<TextdictInfoVO> selectTextdictInfoPage(IPage<TextdictInfoVO> page, TextdictInfoVO textdictInfo) {
         List<TextdictInfoVO> textdict = new ArrayList<>();
@@ -76,48 +87,36 @@ public class TextdictInfoServiceImpl extends ServiceImpl<TextdictInfoMapper, Tex
                 Document doc = Jsoup.parse(htmlString);
                 Elements table = doc.getElementsByAttribute("dqid");
                 List<String> dqid = new ArrayList<>();
-                List<String> keys = new ArrayList<>();
                 for(Element ek:table){
                     dqid.addAll(Func.toStrList("\\|\\|",ek.attr("dqid")));
-                    Elements keyNames = ek.getElementsByAttribute("keyname");
-                    if(Func.isNotEmpty(keyNames)){
-                        for(Element keyName:keyNames){
-                            keys.addAll(Func.toStrList("\\|\\|",keyName.attr("keyname")));
-                        }
-                    }
                 }
                 if(Func.isNotEmpty(textdictInfo.getShowType()) && textdictInfo.getShowType() == 1){
-                    if(Func.isNotEmpty(dqid) && dqid.size() > 0){
+                    if (!dqid.isEmpty()) {
                         textdict = baseMapper.selectTextdictBYIds(dqid,privateInfo.getProjectId());
-                    }else {
-                        textdict = new ArrayList<>();
                     }
-                    if (!keys.isEmpty()) {
-                        // 查询系统级电签配置
-                        TextdictInfoVO temp = null;
-                        if (textdict != null && !textdict.isEmpty()) {
-                            temp = textdict.get(0);
-                        }
-                        if (temp == null) {
-                            temp = new TextdictInfoVO();
-                            temp.setProjectId(privateInfo.getProjectId());
-                            temp.setExcelId(privateInfo.getExcelId() + "");
-                            temp.setTabId(privateInfo.getPKeyId() + "");
-                            temp.setType(2);
-                        }
-                        List<TextdictInfoVO> textdictList = iSignConfigService.hasSignConfig(privateInfo.getInitTableName(), keys, temp);
+                    if (textdict == null || textdict.isEmpty()) {
+                        textdict = baseMapper.selectTextDictInfoByProjectIdAndTabId(page, privateInfo);
                         if (textdict == null || textdict.isEmpty()) {
-                            textdict = textdictList;
-                        } else {
-                            Map<String, Map<String, TextdictInfoVO>> map = textdict.stream().collect(Collectors.groupingBy(TextdictInfoVO::getColKey, Collectors.toMap(TextdictInfoVO::getSigRoleId, v -> v, (v1, v2) -> v1)));
-                            List<TextdictInfoVO> collect = textdictList.stream().filter(textdictInfoVO -> {
-                                Map<String, TextdictInfoVO> voMap = map.get(textdictInfoVO.getColKey());
-                                if (voMap != null && !voMap.isEmpty() ) {
-                                    return voMap.get(textdictInfoVO.getSigRoleId()) == null;
+                            textdict = baseMapper.selectTextdictInfoByExcelIdAndProjectIdAndHtmlUrl(page, privateInfo);
+                        }
+                    }
+                    if (textdict != null && !textdict.isEmpty()) {
+                        Map<String, TextdictInfoVO> map = textdict.stream().collect(Collectors.toMap(item -> item.getProjectId() + item.getTabId() + item.getColKey() + item.getColName(), item -> item, (v1, v2) -> dqid.contains(v2.getId() + "") ? v2 : v1));
+                        textdict = new ArrayList<>(map.values());
+                        for (TextdictInfoVO vo : textdict) {
+                            Elements keyName = doc.getElementsByAttributeValue("keyname", vo.getColKey());
+                            if (keyName ==  null || keyName.isEmpty()) {
+                                vo.setIsMatch(0);
+                            } else {
+                                for (Element ek : keyName) {
+                                    Elements placeholder = ek.getElementsByAttributeValue("placeholder", vo.getColName());
+                                    if (placeholder != null && !placeholder.isEmpty()) {
+                                        vo.setIsMatch(1);
+                                        break;
+                                    }
+                                    vo.setIsMatch(0);
                                 }
-                                return true;
-                            }).collect(Collectors.toList());
-                            textdict.addAll(collect);
+                            }
                         }
                     }
                 }else{
@@ -271,6 +270,18 @@ public class TextdictInfoServiceImpl extends ServiceImpl<TextdictInfoMapper, Tex
                 textdictInfo.setId(-1L);
                 textdictInfos.add(textdictInfo);
             }
+            List<TextdictInfo> list = this.list(Wrappers.<TextdictInfo>lambdaQuery().eq(TextdictInfo::getTabId, tabId).eq(TextdictInfo::getType, 4));
+            Map<String, TextdictInfoVO> map = textdictInfos.stream().collect(Collectors.toMap(vo -> vo.getColKey() + vo.getColName() + vo.getSigRoleName(), vo -> vo, (vo1, vo2) -> vo1));
+            list.forEach(textdictInfo -> {
+                if (!map.containsKey(textdictInfo.getColKey() + textdictInfo.getColName() + textdictInfo.getSigRoleName())) {
+                    TextdictInfoVO vo = new TextdictInfoVO();
+                    BeanUtil.copyProperties(textdictInfo, vo);
+                    map.put(textdictInfo.getColKey() + textdictInfo.getColName() + textdictInfo.getSigRoleName(), vo);
+                    textdictInfos.add(vo);
+                } else {
+                    baseMapper.delete(Wrappers.<TextdictInfo>lambdaQuery().eq(TextdictInfo::getId, textdictInfo.getId()).eq(TextdictInfo::getProjectId, textdictInfo.getProjectId()).eq(TextdictInfo::getType, 4));
+                }
+            });
             textdictInfoPage.setRecords(textdictInfos);
             return textdictInfoPage;
         } catch (FileNotFoundException e) {

+ 149 - 9
blade-service/blade-manager/src/main/java/org/springblade/manager/service/impl/WbsParamServiceImpl.java

@@ -79,13 +79,16 @@ public class WbsParamServiceImpl extends BaseServiceImpl<WbsParamMapper, WbsPara
                     RandomNumberHolder.setRandomTemplateType(1);
                     WbsTreePrivate wtp = this.wtpId(wtc.getPKeyId());
                     if(wtp!=null){
-                        /*优先取私有*/
-                        WbsParam wp = this.getOne(Wrappers.<WbsParam>lambdaQuery().eq(WbsParam::getNodeId, wtp.getPKeyId()).eq(WbsParam::getK, FILE_TITLE).last(" limit 1"));
+                        //优先使用文件题名全局配置里面的规则
+                        WbsParam wp=this.getPrivateNameRuleByPkeyId(wtc);
                         if (wp == null) {
-                            WbsTreePrivate publicWtp = this.getOriginWtp(wtp.getPKeyId());
-                            wp = this.getOne(Wrappers.<WbsParam>lambdaQuery().eq(WbsParam::getNodeId, publicWtp.getId()).eq(WbsParam::getK, FILE_TITLE).last(" limit 1 "));
+                            wp = this.getOne(Wrappers.<WbsParam>lambdaQuery().eq(WbsParam::getNodeId, wtp.getPKeyId()).eq(WbsParam::getK, FILE_TITLE).last(" limit 1"));
                             if(wp==null){
-                                wp = this.getOne(Wrappers.<WbsParam>lambdaQuery().eq(WbsParam::getNodeId, publicWtp.getTreePId()).eq(WbsParam::getK, FILE_TITLE).last(" limit 1 "));
+                                WbsTreePrivate publicWtp = this.getOriginWtp(wtp.getPKeyId());
+                                wp = this.getOne(Wrappers.<WbsParam>lambdaQuery().eq(WbsParam::getNodeId, publicWtp.getId()).eq(WbsParam::getK, FILE_TITLE).last(" limit 1 "));
+                                if(wp==null){
+                                    wp = this.getOne(Wrappers.<WbsParam>lambdaQuery().eq(WbsParam::getNodeId, publicWtp.getTreePId()).eq(WbsParam::getK, FILE_TITLE).last(" limit 1 "));
+                                }
                             }
                         }
                         if (Func.isNotEmpty(wp)) {
@@ -106,6 +109,9 @@ public class WbsParamServiceImpl extends BaseServiceImpl<WbsParamMapper, WbsPara
         }
         return "找不到节点";
     }
+
+
+
     //根据选择的文件题名规则,返回文件题名;
     @Override
     public String createFileTitle1(WbsTreeContract wtc,String wp) {
@@ -254,14 +260,58 @@ public class WbsParamServiceImpl extends BaseServiceImpl<WbsParamMapper, WbsPara
                     //如果有部分节点优先部分
                     List<WbsParam> collect1 = result.stream().filter(o -> o.getNameType() == 2).collect(Collectors.toList());
                     if(collect1.size()>0){
-                        WbsParam param = collect1.get(0);
-                        return R.data(Arrays.asList(param.getV().split("-")));
+                        //如果节点的资料类型不为null
+                        if(contract.getMajorDataType()!=null){
+                            //如果与配置的文件题名资料类型一致
+                            List<WbsParam> data = collect1.stream().filter(o -> StringUtils.isNotEmpty(o.getRemark()) && o.getRemark().contains(contract.getMajorDataType() + "")).collect(Collectors.toList());
+                            if(data.size()>0){
+                                WbsParam param = data.get(0);
+                                return R.data(Arrays.asList(param.getV().split("-")));
+                            }else {
+                                //与配置的文件题名类型不一致,就使用全部类型的文件题名规则
+                                List<WbsParam> data1 = collect1.stream().filter(o -> o.getRemark() != null && o.getRemark().equals("0")).collect(Collectors.toList());
+                                if(data1.size()>0){
+                                    WbsParam param = data1.get(0);
+                                    return R.data(Arrays.asList(param.getV().split("-")));
+                                }
+                            }
+                        }else {
+                            //如果节点的资料类型为null
+                            List<WbsParam> data1 = collect1.stream().filter(o -> o.getRemark() != null && o.getRemark().equals("0")).collect(Collectors.toList());
+                            //使用全部类型的文件题名规则
+                            if(data1.size()>0){
+                                WbsParam param = data1.get(0);
+                                return R.data(Arrays.asList(param.getV().split("-")));
+                            }
+                        }
                     }
                     //没有部分节点用所有节点
                     List<WbsParam> collect2 = result.stream().filter(o -> o.getNameType() == 1).collect(Collectors.toList());
                     if(collect2.size()>0){
-                        WbsParam param = collect2.get(0);
-                        return R.data(Arrays.asList(param.getV().split("-")));
+                        //如果节点的资料类型不为null
+                        if(contract.getMajorDataType()!=null){
+                            //如果与配置的文件题名资料类型一致
+                            List<WbsParam> data = collect2.stream().filter(o -> StringUtils.isNotEmpty(o.getRemark()) && o.getRemark().contains(contract.getMajorDataType() + "")).collect(Collectors.toList());
+                            if(data.size()>0){
+                                WbsParam param = data.get(0);
+                                return R.data(Arrays.asList(param.getV().split("-")));
+                            }else {
+                                //与配置的文件题名类型不一致,就使用全部类型的文件题名规则
+                                List<WbsParam> data1 = collect2.stream().filter(o -> o.getRemark() != null && o.getRemark().equals("0")).collect(Collectors.toList());
+                                if(data1.size()>0){
+                                    WbsParam param = data1.get(0);
+                                    return R.data(Arrays.asList(param.getV().split("-")));
+                                }
+                            }
+                        }else {
+                            //如果节点的资料类型为null
+                            List<WbsParam> data1 = collect2.stream().filter(o -> o.getRemark() != null && o.getRemark().equals("0")).collect(Collectors.toList());
+                            //使用全部类型的文件题名规则
+                            if(data1.size()>0){
+                                WbsParam param = data1.get(0);
+                                return R.data(Arrays.asList(param.getV().split("-")));
+                            }
+                        }
                     }
                 }
             }
@@ -270,6 +320,96 @@ public class WbsParamServiceImpl extends BaseServiceImpl<WbsParamMapper, WbsPara
         return R.success("暂无数据");
     }
 
+    private WbsParam getPrivateNameRuleByPkeyId(WbsTreeContract wtc) {
+        WbsParam wp=null;
+        List<WbsParam> wbsParams = baseMapper.selectList(Wrappers.<WbsParam>lambdaQuery().eq(WbsParam::getProjectId, wtc.getProjectId()).eq(WbsParam::getK, FILE_TITLE));
+        String sql1="select * from m_wbs_tree_private where p_key_id="+wtc.getIsTypePrivatePid();
+        WbsTreePrivate wbsTreePrivate = jdbcTemplate.queryForObject(sql1,new BeanPropertyRowMapper<>(WbsTreePrivate.class));
+        if(wbsTreePrivate==null){
+            return null;
+        }
+        //拿到引用项目级节点的祖级节点
+        String ancestor=wbsTreePrivate.getAncestorsPId()+","+wbsTreePrivate.getPKeyId();
+        String[] ancestors = ancestor.split(",");
+        List<Long> list2 = Arrays.stream(ancestors)
+                .map(Long::parseLong)
+                .collect(Collectors.toList());
+        String join = String.join(",", list2.stream().map(String::valueOf).collect(Collectors.toList()));
+        String sql11 = "SELECT * FROM m_wbs_tree_private WHERE node_type=1  AND project_id="+wtc.getProjectId()+"  AND parent_id!=0 AND p_key_id IN (" + join + ")";
+        List<WbsTreePrivate> nodeList = jdbcTemplate.query(sql11, new BeanPropertyRowMapper<>(WbsTreePrivate.class));
+        //祖级节点的Id
+        List<Long> list3 = nodeList.stream().map(o -> o.getId()).collect(Collectors.toList());
+        List<WbsParam> result=new ArrayList<>();
+        if(list3.size()<0){
+            return null;
+        }
+        if(!wbsParams.isEmpty()){
+            for (WbsParam param : wbsParams) {
+                //祖级节点里有文件题名配置就加进去
+                if(list3.contains(param.getNodeId())){
+                    result.add(param);
+                }
+                //如果是所有的也加进去
+                if(param.getNameType()!=null&&param.getNameType()==1){
+                    result.add(param);
+                }
+            }
+            if(result.size()>0){
+                //如果有部分节点优先部分
+                List<WbsParam> collect1 = result.stream().filter(o -> o.getNameType() == 2).collect(Collectors.toList());
+                if(collect1.size()>0){
+                    //如果节点的资料类型不为null
+                    if(wtc.getMajorDataType()!=null){
+                        //如果与配置的文件题名资料类型一致
+                        List<WbsParam> data = collect1.stream().filter(o -> StringUtils.isNotEmpty(o.getRemark()) && o.getRemark().contains(wtc.getMajorDataType() + "")).collect(Collectors.toList());
+                        if(data.size()>0){
+                            return data.get(0);
+                        }else {
+                            //与配置的文件题名类型不一致,就使用全部类型的文件题名规则
+                            List<WbsParam> data1 = collect1.stream().filter(o -> o.getRemark() != null && o.getRemark().equals("0")).collect(Collectors.toList());
+                            if(data1.size()>0){
+                                return data1.get(0);
+                            }
+                        }
+                    }else {
+                        //如果节点的资料类型为null
+                        List<WbsParam> data1 = collect1.stream().filter(o -> o.getRemark() != null && o.getRemark().equals("0")).collect(Collectors.toList());
+                        //使用全部类型的文件题名规则
+                        if(data1.size()>0){
+                            return data1.get(0);
+                        }
+                    }
+                }
+                //没有部分节点用所有节点
+                List<WbsParam> collect2 = result.stream().filter(o -> o.getNameType() == 1).collect(Collectors.toList());
+                if(collect2.size()>0){
+                    //如果节点的资料类型不为null
+                    if(wtc.getMajorDataType()!=null){
+                        //如果与配置的文件题名资料类型一致
+                        List<WbsParam> data = collect2.stream().filter(o -> StringUtils.isNotEmpty(o.getRemark()) && o.getRemark().contains(wtc.getMajorDataType() + "")).collect(Collectors.toList());
+                        if(data.size()>0){
+                            return data.get(0);
+                        }else {
+                            //与配置的文件题名类型不一致,就使用全部类型的文件题名规则
+                            List<WbsParam> data1 = collect2.stream().filter(o -> o.getRemark() != null && o.getRemark().equals("0")).collect(Collectors.toList());
+                            if(data1.size()>0){
+                                return data1.get(0);
+                            }
+                        }
+                    }else {
+                        //如果节点的资料类型为null
+                        List<WbsParam> data1 = collect2.stream().filter(o -> o.getRemark() != null && o.getRemark().equals("0")).collect(Collectors.toList());
+                        //使用全部类型的文件题名规则
+                        if(data1.size()>0){
+                            return data1.get(0);
+                        }
+                    }
+                }
+            }
+        }
+        return wp;
+    }
+
 
     @Override
     public List<WbsTreeContract> tracing(@NotNull Long pkeyId){

+ 89 - 5
blade-service/blade-manager/src/main/java/org/springblade/manager/service/impl/WbsTreeContractServiceImpl.java

@@ -20,6 +20,7 @@ import org.apache.ibatis.session.SqlSessionFactory;
 import org.apache.poi.openxml4j.exceptions.InvalidFormatException;
 import org.apache.poi.ss.usermodel.*;
 import org.apache.poi.ss.usermodel.Cell;
+import org.apache.poi.ss.usermodel.DateUtil;
 import org.apache.poi.ss.usermodel.Row;
 import org.apache.poi.ss.usermodel.Sheet;
 import org.apache.poi.ss.util.CellRangeAddress;
@@ -38,10 +39,7 @@ import org.springblade.business.dto.EKeyDto;
 import org.springblade.business.dto.ImportTreeDto;
 import org.springblade.business.entity.ConstructionLedger;
 import org.springblade.business.entity.InformationQuery;
-import org.springblade.business.feign.ConstructionLedgerFeignClient;
-import org.springblade.business.feign.InformationQueryClient;
-import org.springblade.business.feign.TrialCyAccessoriesClient;
-import org.springblade.business.feign.WbsTreeContractStatisticsClient;
+import org.springblade.business.feign.*;
 import org.springblade.business.vo.QueryProcessDataVO;
 import org.springblade.common.constant.CommonConstant;
 import org.springblade.common.utils.Colour;
@@ -69,6 +67,7 @@ import org.springblade.manager.mapper.*;
 import org.springblade.manager.service.INodeBaseInfoService;
 import org.springblade.manager.service.ITableFileService;
 import org.springblade.manager.service.IWbsTreeContractService;
+import org.springblade.manager.service.WbsTreeContractExtendService;
 import org.springblade.manager.util.DataStructureFormatUtils;
 import org.springblade.manager.utils.CompositeKey;
 import org.springblade.manager.vo.*;
@@ -139,6 +138,8 @@ public class WbsTreeContractServiceImpl extends BaseServiceImpl<WbsTreeContractM
     private final TrialCyAccessoriesClient trialCyAccessoriesClient;
     private final WbsTreeContractStatisticsClient wbsTreeContractStatisticsClient;
     private final FormulaDataBlockMapper formulaDataBlockMapper;
+    private final WbsTreeContractExtendService wbsTreeContractExtendService;
+    private final OperationLogClient operationLogClient;
 
 
 
@@ -3498,7 +3499,23 @@ public class WbsTreeContractServiceImpl extends BaseServiceImpl<WbsTreeContractM
      */
     private static Object getCellValue1(Cell cell) {
         if (cell == null) return null;
-        return cell.getStringCellValue();
+
+        switch (cell.getCellTypeEnum()) {
+            case STRING:
+                return cell.getStringCellValue();
+            case NUMERIC:
+                if (DateUtil.isCellDateFormatted(cell)) {
+                    return cell.getDateCellValue();
+                } else {
+                    return cell.getNumericCellValue();
+                }
+            case BOOLEAN:
+                return cell.getBooleanCellValue();
+            case FORMULA:
+                return cell.getCellFormula();
+            default:
+                return null;
+        }
     }
 
     /**
@@ -4293,6 +4310,17 @@ public class WbsTreeContractServiceImpl extends BaseServiceImpl<WbsTreeContractM
             this.update(new LambdaUpdateWrapper<WbsTreeContract>()
                     .eq(WbsTreeContract::getPKeyId, dto.getNodeIds())
                     .set(WbsTreeContract::getIsUseSort, 1));
+            try{
+                JSONObject json = new JSONObject();
+                json.put("operationObjIds", Collections.singletonList(dto.getNodeIds()));
+                json.put("operationObjName", "表单排序");
+                json.put("projectId", dto.getProjectId());
+                json.put("contractId", dto.getContractId());
+                json.put("saveData", dto);
+                operationLogClient.saveUserOperationLog(3, "资料管理", "工序资料", json);
+            } catch (Exception e) {
+                e.printStackTrace();
+            }
         } else {
             throw new ServiceException("请传入ids");
         }
@@ -6084,4 +6112,60 @@ public class WbsTreeContractServiceImpl extends BaseServiceImpl<WbsTreeContractM
         // 如果共同部分都相同,长度短的排在前面(父级在子级前面)
         return Integer.compare(arr1.length, arr2.length);
     }
+
+    @Override
+    public void setFormulaReference(FormulaReferenceDTO dto) {
+        try {
+            dto.setKey(dto.getKey().split("__")[0]);
+            WbsTreeContract parentNode = null;
+            if(dto.getType() == 1){
+                //查询父节点
+                parentNode = wbsTreeContractMapper.selectById(dto.getPId());
+            }
+
+            //查询父节点的扩展信息
+            WbsTreeContractExtend byId = wbsTreeContractExtendService.getById(dto.getPId());
+
+            if(byId != null){
+                String formulaConfig = byId.getFormulaConfig();
+                if(StringUtils.isNotEmpty(formulaConfig)){
+                    List<String> list = Arrays.asList(formulaConfig.split(","));
+                    HashSet<String> strings = new HashSet<>(list);
+                    if(dto.getStatus() == 1){
+                        strings.remove(dto.getInitTableName() + ":" + dto.getKey());
+                    }else{
+                        strings.add(dto.getInitTableName() + ":" + dto.getKey());
+                    }
+                    byId.setFormulaConfig(StringUtils.join(strings, ","));
+                }else{
+                    if(dto.getStatus() == 0){
+                        byId.setFormulaConfig(dto.getInitTableName() + ":" + dto.getKey());
+                    }
+                }
+                wbsTreeContractExtendService.updateById(byId);
+            }else{
+                if(dto.getStatus() == 0){
+                    WbsTreeContractExtend wbsTreeContractExtend = new WbsTreeContractExtend();
+                    if(dto.getType() == 1){
+                        if(parentNode == null){
+                            throw new ServiceException("父节点不存在");
+                        }
+                        wbsTreeContractExtend.setPKeyId(parentNode.getPKeyId());
+                        wbsTreeContractExtend.setContractId(Long.valueOf(parentNode.getContractId()));
+                        wbsTreeContractExtend.setAncestors(parentNode.getAncestorsPId());
+                    }
+                    if(dto.getType() == 2){
+                        wbsTreeContractExtend.setPKeyId(dto.getPId());
+                    }
+                    wbsTreeContractExtend.setType(null);
+                    wbsTreeContractExtend.setIsSync(0);
+                    wbsTreeContractExtend.setFormulaConfig(dto.getInitTableName() + ":" + dto.getKey());
+                    wbsTreeContractExtendService.save(wbsTreeContractExtend);
+                }
+            }
+        } catch (NumberFormatException e) {
+            e.printStackTrace();
+            throw new RuntimeException("失败");
+        }
+    }
 }

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

@@ -39,10 +39,7 @@ import org.springblade.manager.dto.WbsTreePrivateDTO2;
 import org.springblade.manager.dto.WbsTreePrivateDTO3;
 import org.springblade.manager.entity.*;
 import org.springblade.manager.mapper.*;
-import org.springblade.manager.service.IElementFormulaMappingService;
-import org.springblade.manager.service.IFormulaService;
-import org.springblade.manager.service.ITableInfoService;
-import org.springblade.manager.service.IWbsTreePrivateService;
+import org.springblade.manager.service.*;
 import org.springblade.manager.utils.CompositeKey1;
 import org.springblade.manager.utils.FileUtils;
 import org.springblade.manager.vo.*;
@@ -76,6 +73,7 @@ public class WbsTreePrivateServiceImpl extends BaseServiceImpl<WbsTreePrivateMap
 
     private final WbsTreeContractMapper wbsTreeContractMapper;
     private final WbsTreeContractServiceImpl wbsTreeContractService;
+    private final WbsTreeContractExtendService wbsTreeContractExtendService;
     private final ITableInfoService tableInfoService;
     private final WbsTreeMapper wbsTreeMapper;
     private final ContractInfoMapper contractInfoMapper;
@@ -2901,7 +2899,7 @@ public class WbsTreePrivateServiceImpl extends BaseServiceImpl<WbsTreePrivateMap
     }
 
     @Override
-    public Object getExcelHtml(String primaryKeyId) throws Exception {
+    public Object getExcelHtml(String primaryKeyId, String id) throws Exception {
 
         WbsTreePrivate wbsTreePrivate = baseMapper.selectOne(Wrappers.<WbsTreePrivate>query().lambda()
                 .eq(WbsTreePrivate::getPKeyId, primaryKeyId));
@@ -2957,18 +2955,51 @@ public class WbsTreePrivateServiceImpl extends BaseServiceImpl<WbsTreePrivateMap
         //字段查询、获取公式字段
         String colKeys = "SELECT e_key from m_table_info a ,m_wbs_form_element b WHERE a.tab_en_name = '" + tabName + "' and a.id=b.f_id and b.id  in(SELECT element_id from m_element_formula_mapping c where c.is_deleted=0) ";
         List<Map<String, Object>> maps = jdbcTemplate.queryForList(colKeys);
+        //扩展----根据父节点查询不允许执行的公式
+        List<String>  list = new ArrayList<>();;
+        if(StringUtil.isNotBlank(id)){
+            WbsTreeContractExtend byId = wbsTreeContractExtendService.getById(id);
+            if(byId != null){
+                String formulaConfig = byId.getFormulaConfig();
+                if(StringUtils.isNotEmpty(formulaConfig)){
+                    list = Arrays.asList(formulaConfig.split(","));
+                }
+            }
+        }
+
         if (maps.size() > 0) {
             for (Map<String, Object> keys : maps) {
                 String key = keys.get("e_key") + "__";
-                Elements gsColor = doc.select("el-input[keyname~=^" + key + "]");
-                for (Element element : gsColor) {
-                    element.parent().attr("gscolor", "11");
+                //采用质检html渲染方式获取表单数据
+                Elements select = doc.select("table").first().select("[keyname^=" + key + "]");
+                if(list.contains(tabName + ":" + keys.get("e_key"))){
+                    //当前元素不执行公式
+                    select.stream().filter(Objects::nonNull).forEach(element -> element.attr("clearFormula", "1"));
+                }else{
+                    //当前元素不执行公式
+                    select.stream().filter(Objects::nonNull).forEach(element -> element.attr("clearFormula", "0"));
+                    for (Element element : select) {
+                        element.parent().attr("gscolor", "11");
+                    }
                 }
 
-                Elements dateColor = doc.select("el-date-picker[keyname~=^" + key + "]");
-                for (Element element : dateColor) {
-                    element.parent().attr("gscolor", "11");
-                }
+//                Elements gsColor = doc.select("el-input[keyname~=^" + key + "]");
+//                if(list.contains(tabName + ":" + keys.get("e_key"))){
+//                    gsColor.stream().filter(Objects::nonNull).forEach(element -> element.attr("clearFormula", "1"));
+//                }else{
+//                    for (Element element : gsColor) {
+//                        element.parent().attr("gscolor", "11");
+//                    }
+//                }
+//                Elements dateColor = doc.select("el-date-picker[keyname~=^" + key + "]");
+//                if(list.contains(tabName + ":" + keys.get("e_key"))){
+//                    dateColor.stream().filter(Objects::nonNull).forEach(element -> element.attr("clearFormula", "1"));
+//                }else{
+//                    for (Element element : dateColor) {
+//                        element.parent().attr("gscolor", "11");
+//                    }
+//                }
+
             }
         }
         doc.select("Col").remove();
@@ -3003,7 +3034,7 @@ public class WbsTreePrivateServiceImpl extends BaseServiceImpl<WbsTreePrivateMap
         } else {
             return R.fail("该合同段没有委托单权限业务");
         }
-        Object excelHtml = getExcelHtml(pkeyId);
+        Object excelHtml = getExcelHtml(pkeyId, null);
         return excelHtml;
     }
 

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

@@ -3007,8 +3007,11 @@ public class TaskController extends BladeController {
             }
 
             /*副任务状态*/
-            updateTaskParallelStatus(task);
-
+            if(task.getApprovalType()==11){ //变更令  走流程不需要电签
+                updateTaskParallelStatusByBGL(task);
+            }else {
+                updateTaskParallelStatus(task);
+            }
             Set<String> aopParamsSet = new HashSet<>();
             for (TaskParallel taskParallel : taskParallels) {
                 String param = taskParallel.getTaskUser() + "," + task.getProjectId() + "," + task.getContractId();
@@ -3866,6 +3869,15 @@ public class TaskController extends BladeController {
         return this;
     }
 
+    private void updateTaskParallelStatusByBGL(Task task) {
+        TaskParallel taskParallelOne = jdbcTemplate.query("SELECT * FROM u_task_parallel WHERE status=1 and process_instance_id = '" + task.getProcessInstanceId() + "' AND task_user = " + SecureUtil.getUserId(), new BeanPropertyRowMapper<>(TaskParallel.class)).stream().findAny().orElse(null);
+        if (taskParallelOne != null && taskParallelOne.getStatus().equals(1)) {
+            String sql = "UPDATE u_task_parallel SET status = ? ,update_time = ? ,e_visa_status=1,e_visa_content='电签成功',initiative=2, create_time = SYSDATE()  WHERE id = ?";
+            Object[] param = {2, new Date(), taskParallelOne.getId()};
+            jdbcTemplate.update(sql, param);
+        }
+    }
+
     private void updateTaskParallelStatus(Task task) {
         TaskParallel taskParallelOne = jdbcTemplate.query("SELECT * FROM u_task_parallel WHERE status=1 and process_instance_id = '" + task.getProcessInstanceId() + "' AND task_user = " + SecureUtil.getUserId(), new BeanPropertyRowMapper<>(TaskParallel.class)).stream().findAny().orElse(null);
         if (taskParallelOne != null && taskParallelOne.getStatus().equals(1)) {

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

@@ -1959,7 +1959,7 @@ public class UserServiceImpl extends BaseServiceImpl<UserMapper, User> implement
 
         long startTime = System.currentTimeMillis();
         List<InformationQuery> result = new ArrayList<>();
-        List<List<String>> partition = Lists.partition(vo.getWbsIds(), 500);
+        List<List<String>> partition = Lists.partition(vo.getWbsIds(), 5000);
         for (List<String> wbsIds : partition) {
             vo.setWbsIds(wbsIds);
             List<InformationQuery> queries = baseMapper.selectInformationQueryPageTwo(vo);
@@ -1970,10 +1970,77 @@ public class UserServiceImpl extends BaseServiceImpl<UserMapper, User> implement
         _logger.info("合同段 " + node.getContractId() + " 获取当前资料 执行时间:" + executionTime + " ms");
 
         if (result.size() != 0) {
+            List<InformationQueryVO> voResult = JSONArray.parseArray(JSONObject.toJSONString(result), InformationQueryVO.class);
+            if (ObjectUtil.isEmpty(voResult)) {
+                page.setRecords(null);
+            } else if (voResult.size() == 1) {
+                page.setRecords(voResult);
+                page.setTotal(voResult.size());
+            } else if (voResult.size() > 1) {
+                if (org.apache.commons.lang.StringUtils.isNotEmpty(vo.getIsFirst())) {
+                    long current = (page.getCurrent() - 1) * page.getSize();
+                    if (current < 0) {
+                        throw new IllegalArgumentException("当前页码不能小于0");
+                    }
+                    int currentNow = (int) (current / page.getSize() + 1);
+                    int pageSize = (int) page.getSize();
+                    int fromIndex = (currentNow - 1) * pageSize;
+                    int toIndex = Math.min(currentNow * pageSize, voResult.size());
+                    List<InformationQueryVO> subList = voResult.subList(fromIndex, toIndex);
+                    page.setRecords(subList);
+                    page.setTotal(voResult.size());
+                } else {
+                    childNodesPkeyIds.add(0, node.getPKeyId());
+                    if (childNodesPkeyIds.size() > 1) {
+                        LinkedList<InformationQueryVO> resultData = new LinkedList<>();
+                        LinkedHashMap<Long, InformationQueryVO> dataMaps = voResult.stream()
+                                .collect(Collectors.toMap(InformationQueryVO::getWbsId, Function.identity(),
+                                        (oldValue, newValue) -> oldValue, LinkedHashMap::new));
+                        for (Long pKeyId : childNodesPkeyIds) {
+                            InformationQueryVO queryVO = dataMaps.get(pKeyId);
+                            if (queryVO != null) {
+                                resultData.add(queryVO);
+                            }
+                        }
+                        if (resultData.size() > 0) {
+                            long current = (page.getCurrent() - 1) * page.getSize();
+                            if (current < 0) {
+                                throw new IllegalArgumentException("当前页码不能小于0");
+                            }
+                            int currentNow = (int) (current / page.getSize() + 1);
+                            int pageSize = (int) page.getSize();
+                            int fromIndex = (currentNow - 1) * pageSize;
+                            int toIndex = Math.min(currentNow * pageSize, resultData.size());
+                            List<InformationQueryVO> subList = resultData.subList(fromIndex, toIndex);
+                            page.setRecords(subList);
+                            page.setTotal(resultData.size());
+                        } else {
+                            page.setRecords(null);
+                        }
+                    } else {
+                        long current = (page.getCurrent() - 1) * page.getSize();
+                        if (current < 0) {
+                            throw new IllegalArgumentException("当前页码不能小于0");
+                        }
+                        int currentNow = (int) (current / page.getSize() + 1);
+                        int pageSize = (int) page.getSize();
+                        int fromIndex = (currentNow - 1) * pageSize;
+                        int toIndex = Math.min(currentNow * pageSize, voResult.size());
+                        List<InformationQueryVO> subList = voResult.subList(fromIndex, toIndex);
+                        page.setRecords(subList);
+                        page.setTotal(voResult.size());
+                    }
+                }
+            }
+            List<InformationQueryVO> records = page.getRecords();
+            if (records == null || records.isEmpty()) {
+                return page;
+            }
             Map<String, List<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(","));
+
+            List<Long> informationIds = records.stream().filter(f -> f.getStatus().equals(1) || f.getStatus().equals(2)).map(InformationQueryVO::getId).collect(Collectors.toList());
+            String informationIdsStr = informationIds.stream().map(id -> "'" + id + "'").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,create_time FROM u_task WHERE form_data_id IN(" + informationIdsStr + ") AND status IN (1, 2) AND is_deleted = 0", new BeanPropertyRowMapper<>(Task.class));
                 taskMaps = query.stream().collect(Collectors.groupingBy(Task::getFormDataId));
@@ -1984,7 +2051,7 @@ public class UserServiceImpl extends BaseServiceImpl<UserMapper, User> implement
                 }
             }
 
-            List<String> sjRecordIds = result.stream().map(InformationQuery::getSjRecordIds).filter(Objects::nonNull).collect(Collectors.toList());
+            List<String> sjRecordIds = records.stream().map(InformationQueryVO::getSjRecordIds).filter(Objects::nonNull).collect(Collectors.toList());
             Set<Long> ids = new HashSet<>();
             for (String sjRecordId : sjRecordIds) {
                 List<Long> longs = Func.toLongList(sjRecordId);
@@ -1994,12 +2061,10 @@ public class UserServiceImpl extends BaseServiceImpl<UserMapper, User> implement
             if (ids.size() > 0) {
                 informationQueries = jdbcTemplate.query("SELECT id FROM u_information_query WHERE id IN(" + StringUtils.join(ids, ",") + ")", new BeanPropertyRowMapper<>(InformationQuery.class));
             }
-
-            List<InformationQueryVO> voResult = JSONArray.parseArray(JSONObject.toJSONString(result), InformationQueryVO.class);
             List<InformationQuery> finalInformationQueries = informationQueries;
             Map<String, List<Task>> finalTaskMaps = taskMaps;
             Map<String, List<TaskParallel>> finalTaskParallelMaps = taskParallelMaps;
-            voResult.forEach(vor -> {
+            records.forEach(vor -> {
                 if(vor.getId()==1838134135841955842L){
                     System.out.println("111");
                 }
@@ -2061,99 +2126,34 @@ public class UserServiceImpl extends BaseServiceImpl<UserMapper, User> implement
                     e.printStackTrace();
                 }
             });
-            if(!ObjectUtil.isEmpty(voResult)){
+            if(!ObjectUtil.isEmpty(records)){
                 //过滤审批人状态
                 if (vo.getWaitingUserStatus() != null) {
-                    voResult = voResult.stream()
-                        .filter(vo1 -> {
-                            List<InformationQueryVO.WaitingUser> waitingUsers = vo1.getWaitingUserList();
-                            if(waitingUsers!=null){
-                                //签字正常状态
-                                if (vo.getWaitingUserStatus() == 2) {
-                                    // 当 waitingUserStatus == 2 时,所有元素的 status 都必须等于 waitingUserStatus
-                                    return waitingUsers.stream().allMatch(waitingUser ->waitingUser!=null&&waitingUser.getStatus()!=null&& waitingUser.getStatus().equals(vo.getWaitingUserStatus()));
-                                } else {
-                                    // 当 waitingUserStatus != 2 时,只要有一个元素的 status 等于 waitingUserStatus 就满足
-                                    return waitingUsers.stream().anyMatch(waitingUser ->waitingUser!=null&&waitingUser.getStatus()!=null&& waitingUser.getStatus().equals(vo.getWaitingUserStatus()));
+                    records = records.stream()
+                            .filter(vo1 -> {
+                                List<InformationQueryVO.WaitingUser> waitingUsers = vo1.getWaitingUserList();
+                                if(waitingUsers!=null){
+                                    //签字正常状态
+                                    if (vo.getWaitingUserStatus() == 2) {
+                                        // 当 waitingUserStatus == 2 时,所有元素的 status 都必须等于 waitingUserStatus
+                                        return waitingUsers.stream().allMatch(waitingUser ->waitingUser!=null&&waitingUser.getStatus()!=null&& waitingUser.getStatus().equals(vo.getWaitingUserStatus()));
+                                    } else {
+                                        // 当 waitingUserStatus != 2 时,只要有一个元素的 status 等于 waitingUserStatus 就满足
+                                        return waitingUsers.stream().anyMatch(waitingUser ->waitingUser!=null&&waitingUser.getStatus()!=null&& waitingUser.getStatus().equals(vo.getWaitingUserStatus()));
+                                    }
                                 }
-                            }
-                            return false;
-                        })
-                        .collect(Collectors.toList());
-                }
-            }
-            StringBuilder sb = new StringBuilder();
-            for (InformationQueryVO queryVO : voResult) {
-                sb=sb.append(queryVO.getId()+",");
-            }
-            System.out.println(sb);
-            if (ObjectUtil.isEmpty(voResult)) {
-                return page.setRecords(null);
-            }
-            else if (voResult.size() == 1) {
-                page.setRecords(voResult);
-                page.setTotal(voResult.size());
-                return page;
-
-            } else if (voResult.size() > 1) {
-                if (org.apache.commons.lang.StringUtils.isNotEmpty(vo.getIsFirst())) {
-                    long current = (page.getCurrent() - 1) * page.getSize();
-                    if (current < 0) {
-                        throw new IllegalArgumentException("当前页码不能小于0");
-                    }
-                    int currentNow = (int) (current / page.getSize() + 1);
-                    int pageSize = (int) page.getSize();
-                    int fromIndex = (currentNow - 1) * pageSize;
-                    int toIndex = Math.min(currentNow * pageSize, voResult.size());
-                    List<InformationQueryVO> subList = voResult.subList(fromIndex, toIndex);
-                    page.setRecords(subList);
-                    page.setTotal(voResult.size());
-                    return page;
-                } else {
-                    childNodesPkeyIds.add(0, node.getPKeyId());
-                    if (childNodesPkeyIds.size() > 1) {
-                        LinkedList<InformationQueryVO> resultData = new LinkedList<>();
-                        LinkedHashMap<Long, InformationQueryVO> dataMaps = voResult.stream()
-                                .collect(Collectors.toMap(InformationQueryVO::getWbsId, Function.identity(),
-                                        (oldValue, newValue) -> oldValue, LinkedHashMap::new));
-                        for (Long pKeyId : childNodesPkeyIds) {
-                            InformationQueryVO queryVO = dataMaps.get(pKeyId);
-                            if (queryVO != null) {
-                                resultData.add(queryVO);
-                            }
-                        }
-                        if (resultData.size() > 0) {
-                            long current = (page.getCurrent() - 1) * page.getSize();
-                            if (current < 0) {
-                                throw new IllegalArgumentException("当前页码不能小于0");
-                            }
-                            int currentNow = (int) (current / page.getSize() + 1);
-                            int pageSize = (int) page.getSize();
-                            int fromIndex = (currentNow - 1) * pageSize;
-                            int toIndex = Math.min(currentNow * pageSize, resultData.size());
-                            List<InformationQueryVO> subList = resultData.subList(fromIndex, toIndex);
-                            page.setRecords(subList);
-                            page.setTotal(resultData.size());
-                            return page;
-                        } else {
-                            return page.setRecords(null);
-                        }
-                    } else {
-                        long current = (page.getCurrent() - 1) * page.getSize();
-                        if (current < 0) {
-                            throw new IllegalArgumentException("当前页码不能小于0");
-                        }
-                        int currentNow = (int) (current / page.getSize() + 1);
-                        int pageSize = (int) page.getSize();
-                        int fromIndex = (currentNow - 1) * pageSize;
-                        int toIndex = Math.min(currentNow * pageSize, voResult.size());
-                        List<InformationQueryVO> subList = voResult.subList(fromIndex, toIndex);
-                        page.setRecords(subList);
-                        page.setTotal(voResult.size());
-                        return page;
-                    }
+                                return false;
+                            })
+                            .collect(Collectors.toList());
                 }
-            }
+                page.setRecords(records);
+            }
+            return page;
+//            StringBuilder sb = new StringBuilder();
+//            for (InformationQueryVO queryVO : voResult) {
+//                sb=sb.append(queryVO.getId()+",");
+//            }
+//            System.out.println(sb);
         }
         return page.setRecords(null);
     }