Procházet zdrojové kódy

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

huangtf před 1 rokem
rodič
revize
7888094fad
48 změnil soubory, kde provedl 1312 přidání a 797 odebrání
  1. 0 3
      blade-service-api/blade-manager-api/src/main/java/org/springblade/manager/dto/TrialSummaryClassificationConfigurationMatchDTO.java
  2. 2 5
      blade-service-api/blade-manager-api/src/main/java/org/springblade/manager/dto/TrialSummaryClassificationConfigurationRelevancyDTO.java
  3. 31 0
      blade-service-api/blade-manager-api/src/main/java/org/springblade/manager/dto/TrialSummaryReflectionSaveDTO.java
  4. 8 0
      blade-service-api/blade-manager-api/src/main/java/org/springblade/manager/entity/TrialSummaryClassificationConfiguration.java
  5. 25 0
      blade-service-api/blade-manager-api/src/main/java/org/springblade/manager/entity/TrialSummaryExcelTabReflection.java
  6. 6 0
      blade-service-api/blade-manager-api/src/main/java/org/springblade/manager/feign/FormulaClient.java
  7. 14 0
      blade-service-api/blade-manager-api/src/main/java/org/springblade/manager/vo/ExcelTabTreeVO.java
  8. 4 2
      blade-service-api/blade-manager-api/src/main/java/org/springblade/manager/vo/InterimPaymentCertificate.java
  9. 1 0
      blade-service-api/blade-manager-api/src/main/java/org/springblade/manager/vo/Payment.java
  10. 20 0
      blade-service-api/blade-manager-api/src/main/java/org/springblade/manager/vo/SelectedTabVO.java
  11. 2 2
      blade-service-api/blade-manager-api/src/main/java/org/springblade/manager/vo/TrialTreeVO.java
  12. 2 0
      blade-service/blade-archive/src/main/java/org/springblade/archive/mapper/ArchiveExpertConclusionMapper.java
  13. 7 0
      blade-service/blade-archive/src/main/java/org/springblade/archive/mapper/ArchiveExpertConclusionMapper.xml
  14. 5 0
      blade-service/blade-archive/src/main/java/org/springblade/archive/mapper/ArchivesAutoMapper.xml
  15. 5 3
      blade-service/blade-archive/src/main/java/org/springblade/archive/service/impl/ArchiveExpertConclusionServiceImpl.java
  16. 36 38
      blade-service/blade-archive/src/main/java/org/springblade/archive/service/impl/ArchiveExpertScoreServiceImpl.java
  17. 19 0
      blade-service/blade-archive/src/main/java/org/springblade/archive/service/impl/ArchivesAutoServiceImpl.java
  18. 9 473
      blade-service/blade-business/src/main/java/org/springblade/business/controller/TrialSummaryController.java
  19. 498 0
      blade-service/blade-business/src/main/java/org/springblade/business/controller/TrialSummaryMonthlyController.java
  20. 3 1
      blade-service/blade-business/src/main/java/org/springblade/business/service/impl/TaskServiceImpl.java
  21. 3 4
      blade-service/blade-e-visa/src/main/java/org/springblade/evisa/controller/EVisaController.java
  22. 6 18
      blade-service/blade-manager/src/main/java/com/jfireel/expression/Expression.java
  23. 35 0
      blade-service/blade-manager/src/main/java/com/jfireel/expression/parse/impl/ChineseParser.java
  24. 1 1
      blade-service/blade-manager/src/main/java/com/jfireel/expression/parse/impl/IdentifierParser.java
  25. 3 7
      blade-service/blade-manager/src/main/java/com/jfireel/expression/parse/impl/NumberParser.java
  26. 3 3
      blade-service/blade-manager/src/main/java/com/jfireel/expression/token/DefaultKeyWord.java
  27. 19 0
      blade-service/blade-manager/src/main/java/com/jfireel/expression/util/CharType.java
  28. 1 1
      blade-service/blade-manager/src/main/java/com/mixsmart/utils/CustomFunction.java
  29. 21 1
      blade-service/blade-manager/src/main/java/com/mixsmart/utils/FormulaUtils.java
  30. 12 2
      blade-service/blade-manager/src/main/java/org/springblade/manager/controller/ExcelTabController.java
  31. 196 5
      blade-service/blade-manager/src/main/java/org/springblade/manager/controller/TrialSummaryClassificationConfigurationController.java
  32. 7 0
      blade-service/blade-manager/src/main/java/org/springblade/manager/feign/FormulaClientImpl.java
  33. 0 17
      blade-service/blade-manager/src/main/java/org/springblade/manager/formula/impl/CompositeDataAccessGroup.java
  34. 0 6
      blade-service/blade-manager/src/main/java/org/springblade/manager/formula/impl/ExecutorCalc.java
  35. 0 10
      blade-service/blade-manager/src/main/java/org/springblade/manager/formula/impl/ExecutorFormat.java
  36. 10 11
      blade-service/blade-manager/src/main/java/org/springblade/manager/formula/impl/ExecutorInit.java
  37. 92 84
      blade-service/blade-manager/src/main/java/org/springblade/manager/formula/impl/ExecutorMeter.java
  38. 0 1
      blade-service/blade-manager/src/main/java/org/springblade/manager/formula/impl/ExecutorPre.java
  39. 0 4
      blade-service/blade-manager/src/main/java/org/springblade/manager/formula/impl/ExecutorSort.java
  40. 4 4
      blade-service/blade-manager/src/main/java/org/springblade/manager/formula/impl/FormulaExecutor.java
  41. 3 5
      blade-service/blade-manager/src/main/java/org/springblade/manager/formula/impl/TableElementConverter.java
  42. 5 2
      blade-service/blade-manager/src/main/java/org/springblade/manager/service/ITrialSummaryClassificationConfigurationService.java
  43. 8 6
      blade-service/blade-manager/src/main/java/org/springblade/manager/service/impl/ArchiveTreeContractServiceImpl.java
  44. 4 4
      blade-service/blade-manager/src/main/java/org/springblade/manager/service/impl/FormulaDaoImpl.java
  45. 9 11
      blade-service/blade-manager/src/main/java/org/springblade/manager/service/impl/FormulaServiceImpl.java
  46. 143 49
      blade-service/blade-manager/src/main/java/org/springblade/manager/service/impl/TrialSummaryClassificationConfigurationServiceImpl.java
  47. 20 12
      blade-service/blade-meter/src/main/java/org/springblade/meter/controller/TaskController.java
  48. 10 2
      blade-service/blade-user/src/main/java/org/springblade/system/user/controller/UserController.java

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

@@ -8,9 +8,6 @@ import java.io.Serializable;
 @Data
 public class TrialSummaryClassificationConfigurationMatchDTO implements Serializable {
 
-    @ApiModelProperty(value = "项目id")
-    private String projectId;
-
     @ApiModelProperty(value = "分类id(page接口的id)")
     private String classId;
 

+ 2 - 5
blade-service-api/blade-manager-api/src/main/java/org/springblade/manager/dto/TrialSummaryClassificationConfigurationRelevancyDTO.java

@@ -8,13 +8,10 @@ import java.io.Serializable;
 @Data
 public class TrialSummaryClassificationConfigurationRelevancyDTO implements Serializable {
 
-    @ApiModelProperty(value = "项目id")
-    private String projectId;
-
     @ApiModelProperty(value = "分类id(page接口的id)")
     private String classId;
 
-    @ApiModelProperty(value = "选择节点的pKeyId英文逗号拼接成ids")
-    private String ids;
+    @ApiModelProperty(value = "选择的清表id")
+    private String excelId;
 
 }

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

@@ -0,0 +1,31 @@
+package org.springblade.manager.dto;
+
+
+import io.swagger.annotations.ApiModelProperty;
+import lombok.Data;
+
+import java.io.Serializable;
+import java.util.List;
+
+@Data
+public class TrialSummaryReflectionSaveDTO implements Serializable {
+
+    @ApiModelProperty(value = "分类id")
+    private Long classId;
+
+    @ApiModelProperty(value = "映射数组信息")
+    private List<ReflectionBean> reflectionBeanList;
+
+    @Data
+    public class ReflectionBean implements Serializable {
+        @ApiModelProperty(value = "试验表的p_key_id")
+        private Long trialTabId;
+
+        @ApiModelProperty(value = "试验表下的元素id")
+        private Long elementId;
+
+        @ApiModelProperty(value = "对应html的坐标信息")
+        private String htmlKeyName;
+    }
+
+}

+ 8 - 0
blade-service-api/blade-manager-api/src/main/java/org/springblade/manager/entity/TrialSummaryClassificationConfiguration.java

@@ -1,6 +1,7 @@
 package org.springblade.manager.entity;
 
 import com.baomidou.mybatisplus.annotation.TableName;
+import io.swagger.annotations.ApiModelProperty;
 import lombok.Data;
 import lombok.EqualsAndHashCode;
 import org.springblade.core.mp.base.BaseEntity;
@@ -16,12 +17,19 @@ public class TrialSummaryClassificationConfiguration extends BaseEntity {
 
     private static final long serialVersionUID = 1L;
 
+    @ApiModelProperty(value = "分类名称")
     private String className;
 
+    @ApiModelProperty(value = "关联的试验树id,英文逗号字符串拼接")
     private String trialTreeIds;
 
+    @ApiModelProperty(value = "关联的清表id")
     private Long excelId;
 
+    @ApiModelProperty(value = "清表对应的html路径")
+    private String htmlUrl;
+
+    @ApiModelProperty(value = "排序")
     private Integer sort;
 
 }

+ 25 - 0
blade-service-api/blade-manager-api/src/main/java/org/springblade/manager/entity/TrialSummaryExcelTabReflection.java

@@ -0,0 +1,25 @@
+package org.springblade.manager.entity;
+
+import io.swagger.annotations.ApiModelProperty;
+import lombok.Data;
+
+import java.io.Serializable;
+
+@Data
+public class TrialSummaryExcelTabReflection implements Serializable {
+
+    private Long id;
+
+    @ApiModelProperty(value = "关联的清表id")
+    private Long excelId;
+
+    @ApiModelProperty(value = "试验表的p_key_id")
+    private Long trialTabId;
+
+    @ApiModelProperty(value = "试验表下的元素id")
+    private Long elementId;
+
+    @ApiModelProperty(value = "对应html的坐标信息")
+    private String htmlKeyName;
+
+}

+ 6 - 0
blade-service-api/blade-manager-api/src/main/java/org/springblade/manager/feign/FormulaClient.java

@@ -1,6 +1,7 @@
 package org.springblade.manager.feign;
 
 import org.springblade.manager.entity.FormulaOption;
+import org.springblade.manager.vo.ReportResult;
 import org.springframework.cloud.openfeign.FeignClient;
 import org.springframework.web.bind.annotation.GetMapping;
 import org.springframework.web.bind.annotation.PostMapping;
@@ -8,6 +9,7 @@ import org.springframework.web.bind.annotation.RequestParam;
 
 import javax.validation.constraints.NotNull;
 import java.io.FileNotFoundException;
+import java.util.List;
 
 import static org.springblade.core.launch.constant.AppConstant.APPLICATION_NAME_PREFIX;
 
@@ -30,4 +32,8 @@ public interface FormulaClient {
     @GetMapping(API_PREFIX + "option")
     FormulaOption option(@RequestParam @NotNull Long pkeyId);
 
+    //计量公式执行体
+    @PostMapping(API_PREFIX + "execute3")
+    List<ReportResult> formulaExecute3(@RequestParam Long contractId, @RequestParam Long periodId,@RequestParam Integer type);
+
 }

+ 14 - 0
blade-service-api/blade-manager-api/src/main/java/org/springblade/manager/vo/ExcelTabTreeVO.java

@@ -0,0 +1,14 @@
+package org.springblade.manager.vo;
+
+import io.swagger.annotations.ApiModelProperty;
+import lombok.Data;
+import org.springblade.manager.entity.ExcelTab;
+
+
+@Data
+public class ExcelTabTreeVO extends ExcelTab {
+
+    @ApiModelProperty(value = "回显状态 1=勾选")
+    private Integer recordStatus;
+
+}

+ 4 - 2
blade-service-api/blade-manager-api/src/main/java/org/springblade/manager/vo/InterimPaymentCertificate.java

@@ -51,7 +51,9 @@ public class InterimPaymentCertificate {
         BigDecimal currentPeriodPayBd = new BigDecimal(currentPeriodPay);
         BigDecimal currentPeriodEndPayBd = previousPeriodEndPayBd.add(currentPeriodPayBd);
         this.currentPeriodEndPay = currentPeriodEndPayBd.toString();
-        BigDecimal payRatioBd = currentPeriodPayBd.multiply(new BigDecimal(100)).divide(currentPeriodEndPayBd, 2, RoundingMode.HALF_UP);
-        this.payRatio = payRatioBd.toString();
+        if(BigDecimal.ZERO.compareTo(currentPeriodEndPayBd)<0) {
+            BigDecimal payRatioBd = currentPeriodPayBd.multiply(new BigDecimal(100)).divide(currentPeriodEndPayBd, 2, RoundingMode.HALF_UP);
+            this.payRatio = payRatioBd.toString();
+        }
     }
 }

+ 1 - 0
blade-service-api/blade-manager-api/src/main/java/org/springblade/manager/vo/Payment.java

@@ -11,6 +11,7 @@ import java.math.BigDecimal;
  */
 @Data
 public class Payment {
+    private Long id;
     /**计量清单id*/
     private Long  formId;
     /**计量单元id*/

+ 20 - 0
blade-service-api/blade-manager-api/src/main/java/org/springblade/manager/vo/SelectedTabVO.java

@@ -0,0 +1,20 @@
+package org.springblade.manager.vo;
+
+import io.swagger.annotations.ApiModelProperty;
+import lombok.Data;
+
+import java.io.Serializable;
+
+@Data
+public class SelectedTabVO implements Serializable {
+
+    @ApiModelProperty(value = "主键id")
+    private Long pKeyId;
+
+    @ApiModelProperty(value = "id")
+    private Long id;
+
+    @ApiModelProperty(value = "表单名称")
+    private String tabName;
+
+}

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

@@ -28,7 +28,7 @@ public class TrialTreeVO implements Serializable {
     @ApiModelProperty(value = "是否存在子节点 true=存在子级 false=不存在子级")
     private boolean hasChild;
 
-    @ApiModelProperty(value = "回显状态 0=未勾选 1=勾选")
-    private Integer status;
+    @ApiModelProperty(value = "回显状态 1=勾选")
+    private Integer recordStatus;
 
 }

+ 2 - 0
blade-service/blade-archive/src/main/java/org/springblade/archive/mapper/ArchiveExpertConclusionMapper.java

@@ -24,4 +24,6 @@ public interface ArchiveExpertConclusionMapper extends BaseMapper<ArchiveExpertC
     void updateAllArchiveByProject(@Param("projectId") Long projectId);
 
     void updateAllNodeByProject(@Param("projectId") Long projectId);
+
+    List<ArchiveExpertScore> getAllScore(@Param("projectId") Long projectId,@Param("id") Long id);
 }

+ 7 - 0
blade-service/blade-archive/src/main/java/org/springblade/archive/mapper/ArchiveExpertConclusionMapper.xml

@@ -18,4 +18,11 @@
             #{id}
         </foreach>
     </select>
+
+    <select id="getAllScore" resultType="org.springblade.archive.entity.ArchiveExpertScore">
+        SELECT id,score_item ,unit_type,IFNULL(integrality,0) as integrality,IFNULL(integrality_deduction,0) as integrality_deduction,
+               IFNULL(normative,0) as normative ,IFNULL(normative_deduction,0) as normative_deduction
+        FROM u_archive_expert_score
+        WHERE project_id = #{projectId} and conclusion_id = #{id} and is_deleted = 0
+    </select>
 </mapper>

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

@@ -1134,6 +1134,11 @@
         <foreach collection="ids" item="id" open="(" separator="," close=")">
             #{id}
         </foreach>
+        order by FIELD(uaa.id,
+        <foreach collection="ids" item="id" separator="," >
+            #{id}
+        </foreach>
+        )
     </select>
     <select id="getRoutingInspection" resultType="org.springblade.archive.vo.ArchiveWarningVO">
         select uaf.file_name ,uaf.file_url,0 as sourceType,uaf.node_id,

+ 5 - 3
blade-service/blade-archive/src/main/java/org/springblade/archive/service/impl/ArchiveExpertConclusionServiceImpl.java

@@ -296,9 +296,11 @@ public class ArchiveExpertConclusionServiceImpl extends BaseServiceImpl<ArchiveE
 
     private String buildPdf(ArchiveExpertConclusion conclusion,List<User> users) throws Exception {
         //获取评分基础数据
-        List<ArchiveExpertScore> list1 = scoreService.list(new LambdaQueryWrapper<ArchiveExpertScore>()
-                .eq(ArchiveExpertScore::getProjectId, conclusion.getProjectId())
-                .eq(ArchiveExpertScore::getConclusionId, conclusion.getId()));
+//        List<ArchiveExpertScore> list1 = scoreService.list(new LambdaQueryWrapper<ArchiveExpertScore>()
+//                .eq(ArchiveExpertScore::getProjectId, conclusion.getProjectId())
+//                .eq(ArchiveExpertScore::getConclusionId, conclusion.getId()));
+        //手动获取评分数据,为null补零
+        List<ArchiveExpertScore> list1 = baseMapper.getAllScore(conclusion.getProjectId(),conclusion.getId());
         Map<Integer, List<ArchiveExpertScore>> map = list1.stream().collect(Collectors.groupingBy(ArchiveExpertScore::getUnitType));
         //获取专家组长
         User us = null;

+ 36 - 38
blade-service/blade-archive/src/main/java/org/springblade/archive/service/impl/ArchiveExpertScoreServiceImpl.java

@@ -46,46 +46,44 @@ public class ArchiveExpertScoreServiceImpl extends BaseServiceImpl<ArchiveExpert
     public void saveBaseScoreInfo(Long projectId,Long conclusionId) {
         List<ArchiveExpertScore> list = new ArrayList<>();
         //业主
-        list.add(new ArchiveExpertScore(projectId,conclusionId,1,"施工准备文件",10,0,10,0));
-        list.add(new ArchiveExpertScore(projectId,conclusionId,1,"工地试验室资质证书、延期文件、仪器标定证书",10,0,10,0));
-        list.add(new ArchiveExpertScore(projectId,conclusionId,1,"会议纪要、往来文件",10,0,10,0));
-        list.add(new ArchiveExpertScore(projectId,conclusionId,1,"桥隧工程风险评估报告",10,0,10,0));
-        list.add(new ArchiveExpertScore(projectId,conclusionId,1,"质评资料",10,0,10,0));
-        list.add(new ArchiveExpertScore(projectId,conclusionId,1,"进度进化控制文件",10,0,10,0));
-        list.add(new ArchiveExpertScore(projectId,conclusionId,1,"计量支付文件",10,0,10,0));
-        list.add(new ArchiveExpertScore(projectId,conclusionId,1,"工程变更令",10,0,10,0));
-        list.add(new ArchiveExpertScore(projectId,conclusionId,1,"总结",10,0,10,0));
-        list.add(new ArchiveExpertScore(projectId,conclusionId,1,"照片",10,0,10,0));
+        list.add(new ArchiveExpertScore(projectId,conclusionId,1,"立项审批",10,null,10,null));
+        list.add(new ArchiveExpertScore(projectId,conclusionId,1,"设计审批文件",7,null,7,null));
+        list.add(new ArchiveExpertScore(projectId,conclusionId,1,"招投标文件",7,null,null,null));
+        list.add(new ArchiveExpertScore(projectId,conclusionId,1,"工程准备文件",5,null,null,null));
+        list.add(new ArchiveExpertScore(projectId,conclusionId,1,"施工文件",4,null,null,null));
+        list.add(new ArchiveExpertScore(projectId,conclusionId,1,"交、竣工文件",8,null,null,null));
+        list.add(new ArchiveExpertScore(projectId,conclusionId,1,"资金管理文件",5,null,null,null));
+        list.add(new ArchiveExpertScore(projectId,conclusionId,1,"照片",4,null,null,null));
         //监理
-        list.add(new ArchiveExpertScore(projectId,conclusionId,2,"监理机构、制度",10,0,10,0));
-        list.add(new ArchiveExpertScore(projectId,conclusionId,2,"会议纪要、往来文件、监理费用、支付报表、监理日志、总结",10,0,10,0));
-        list.add(new ArchiveExpertScore(projectId,conclusionId,2,"工地试验室资质证书、延期文件、仪器标定证书",10,0,10,0));
-        list.add(new ArchiveExpertScore(projectId,conclusionId,2,"试验资料",10,0,10,0));
-        list.add(new ArchiveExpertScore(projectId,conclusionId,2,"质检资料",10,0,10,0));
-        list.add(new ArchiveExpertScore(projectId,conclusionId,2,"质评资料",10,0,10,0));
-        list.add(new ArchiveExpertScore(projectId,conclusionId,2,"安全资料",10,0,10,0));
-        list.add(new ArchiveExpertScore(projectId,conclusionId,2,"监理指令及回复、旁站记录、巡视记录",10,0,10,0));
-        list.add(new ArchiveExpertScore(projectId,conclusionId,2,"照片",10,0,10,0));
+        list.add(new ArchiveExpertScore(projectId,conclusionId,2,"监理机构、制度",3,null,10,null));
+        list.add(new ArchiveExpertScore(projectId,conclusionId,2,"会议纪要、往来文件、监理费用、支付报表、监理日志、总结",10,null,null,null));
+        list.add(new ArchiveExpertScore(projectId,conclusionId,2,"工地试验室资质证书、延期文件、仪器标定证书",3,null,null,null));
+        list.add(new ArchiveExpertScore(projectId,conclusionId,2,"试验资料",6,null,null,null));
+        list.add(new ArchiveExpertScore(projectId,conclusionId,2,"质检资料",6,null,null,null));
+        list.add(new ArchiveExpertScore(projectId,conclusionId,2,"质评资料",6,null,null,null));
+        list.add(new ArchiveExpertScore(projectId,conclusionId,2,"安全资料",3,null,null,null));
+        list.add(new ArchiveExpertScore(projectId,conclusionId,2,"监理指令及回复、旁站记录、巡视记录",9,null,null,null));
+        list.add(new ArchiveExpertScore(projectId,conclusionId,2,"照片",4,null,null,null));
         //施工
-        list.add(new ArchiveExpertScore(projectId,conclusionId,3,"设计变更及竣工图",10,0,10,0));
-        list.add(new ArchiveExpertScore(projectId,conclusionId,3,"施工准备文件",10,0,10,0));
-        list.add(new ArchiveExpertScore(projectId,conclusionId,3,"试验资料(含工地试验室资质证书、仪器标定证书等)",10,0,10,0));
-        list.add(new ArchiveExpertScore(projectId,conclusionId,3,"质检资料",10,0,10,0));
-        list.add(new ArchiveExpertScore(projectId,conclusionId,3,"路基工程质检资料",10,0,10,0));
-        list.add(new ArchiveExpertScore(projectId,conclusionId,3,"路面工程质检资料",10,0,10,0));
-        list.add(new ArchiveExpertScore(projectId,conclusionId,3,"隧道工程质检资料",10,0,10,0));
-        list.add(new ArchiveExpertScore(projectId,conclusionId,3,"绿化工程质检资料",10,0,10,0));
-        list.add(new ArchiveExpertScore(projectId,conclusionId,3,"交通与安全工程质检资料",10,0,10,0));
-        list.add(new ArchiveExpertScore(projectId,conclusionId,3,"机电工程质检资料",10,0,10,0));
-        list.add(new ArchiveExpertScore(projectId,conclusionId,3,"房建工程质检资料",10,0,10,0));
-        list.add(new ArchiveExpertScore(projectId,conclusionId,3,"质评资料",10,0,10,0));
-        list.add(new ArchiveExpertScore(projectId,conclusionId,3,"进度进化控制文件",10,0,10,0));
-        list.add(new ArchiveExpertScore(projectId,conclusionId,3,"安全生产、文明施工资料",10,0,10,0));
-        list.add(new ArchiveExpertScore(projectId,conclusionId,3,"施工日志、大事记",10,0,10,0));
-        list.add(new ArchiveExpertScore(projectId,conclusionId,3,"计量支付文件",10,0,10,0));
-        list.add(new ArchiveExpertScore(projectId,conclusionId,3,"会议纪要、往来文件",10,0,10,0));
-        list.add(new ArchiveExpertScore(projectId,conclusionId,3,"照片",10,0,10,0));
-        list.add(new ArchiveExpertScore(projectId,conclusionId,3,"总结",10,0,10,0));
+        list.add(new ArchiveExpertScore(projectId,conclusionId,3,"设计变更及竣工图",9,null,null,null));
+        list.add(new ArchiveExpertScore(projectId,conclusionId,3,"施工准备文件",5,null,null,null));
+        list.add(new ArchiveExpertScore(projectId,conclusionId,3,"试验资料(含工地试验室资质证书、仪器标定证书等)",9,null,10,null));
+        list.add(new ArchiveExpertScore(projectId,conclusionId,3,"质检资料",10,null,null,null));
+        list.add(new ArchiveExpertScore(projectId,conclusionId,3,"路基工程质检资料",null,null,null,null));
+        list.add(new ArchiveExpertScore(projectId,conclusionId,3,"路面工程质检资料",null,null,null,null));
+        list.add(new ArchiveExpertScore(projectId,conclusionId,3,"隧道工程质检资料",null,null,null,null));
+        list.add(new ArchiveExpertScore(projectId,conclusionId,3,"绿化工程质检资料",null,null,null,null));
+        list.add(new ArchiveExpertScore(projectId,conclusionId,3,"交通与安全工程质检资料",null,null,null,null));
+        list.add(new ArchiveExpertScore(projectId,conclusionId,3,"机电工程质检资料",null,null,null,null));
+        list.add(new ArchiveExpertScore(projectId,conclusionId,3,"房建工程质检资料",null,null,null,null));
+        list.add(new ArchiveExpertScore(projectId,conclusionId,3,"质评资料",5,null,null,null));
+        list.add(new ArchiveExpertScore(projectId,conclusionId,3,"进度进化控制文件",3,null,null,null));
+        list.add(new ArchiveExpertScore(projectId,conclusionId,3,"安全生产、文明施工资料",2,null,null,null));
+        list.add(new ArchiveExpertScore(projectId,conclusionId,3,"施工日志、大事记",3,null,null,null));
+        list.add(new ArchiveExpertScore(projectId,conclusionId,3,"计量支付文件",5,null,null,null));
+        list.add(new ArchiveExpertScore(projectId,conclusionId,3,"会议纪要、往来文件",3,null,null,null));
+        list.add(new ArchiveExpertScore(projectId,conclusionId,3,"照片",3,null,null,null));
+        list.add(new ArchiveExpertScore(projectId,conclusionId,3,"总结",3,null,null,null));
         this.saveBatch(list);
     }
 

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

@@ -3120,6 +3120,11 @@ public class ArchivesAutoServiceImpl extends BaseServiceImpl<ArchivesAutoMapper,
 	@Override
 	@Transactional
 	public void updateInspectStatus(Long archiveId,Long projectId,Long conclusionId) {
+		try {
+			Thread.sleep(100);
+		} catch (InterruptedException e) {
+			e.printStackTrace();
+		}
 		//查看当前档案是否存在有意见的数据,存在则什么都不修改,不存在则修改已抽检,合格
 		long count2 = inspectionService.count(new LambdaQueryWrapper<ExpertInspection>()
 				.eq(ExpertInspection::getIsPass, 0)
@@ -3181,6 +3186,19 @@ public class ArchivesAutoServiceImpl extends BaseServiceImpl<ArchivesAutoMapper,
 		//专家基本信息
 		Long userId = AuthUtil.getUserId();
 		String userName = AuthUtil.getNickName();
+		//判断是否存在id,存在则代表是记录里面直接修改
+		if (inspection.getId() != null && inspection.getId() != -1){
+			//获取当前意见
+			ExpertInspection inspect = inspectionService.getById(inspection.getId());
+			if (inspect == null){
+				throw new ServiceException("未获取到当前意见");
+			}
+			//判断意见专家和当前用户是否为同一人
+			if (!userId.equals(inspect.getExpertId())){
+				userId = inspect.getExpertId();
+				userName = inspect.getExpertName();
+			}
+		}
 		//获取档案信息,如果状态未未查阅则修改
 		ArchivesAuto archive = this.getById(inspection.getArchiveId());
 		if (archive == null || archive.getNodeId() == null){
@@ -3251,6 +3269,7 @@ public class ArchivesAutoServiceImpl extends BaseServiceImpl<ArchivesAutoMapper,
 					.eq(ExpertInspection::getConclusionId, inspection.getConclusionId()));
 			//如果不存在数据,然后保存
 			if (one == null) {
+				inspection.setId(null);
 				inspectionService.save(inspection);
 			} else {
 				//如果存在数据,则判断是否存在意见,然后修改

+ 9 - 473
blade-service/blade-business/src/main/java/org/springblade/business/controller/TrialSummaryController.java

@@ -1,498 +1,34 @@
 package org.springblade.business.controller;
 
-import com.aspose.cells.PageSetup;
-import com.aspose.cells.PaperSizeType;
-import com.aspose.cells.PdfSaveOptions;
-import com.baomidou.mybatisplus.core.metadata.IPage;
-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.apache.commons.lang.StringUtils;
-import org.apache.poi.ss.usermodel.*;
-import org.apache.poi.ss.util.CellRangeAddress;
-import org.apache.poi.xssf.usermodel.*;
-import org.springblade.business.dto.TrialSummaryMonthlyEditDTO;
-import org.springblade.business.dto.TrialSummaryMonthlyPageDTO;
-import org.springblade.business.entity.TrialSelfInspectionRecord;
-import org.springblade.business.entity.TrialSummaryMonthlyRemarks;
-import org.springblade.common.utils.SnowFlakeUtil;
-import org.springblade.core.log.exception.ServiceException;
-import org.springblade.core.oss.model.BladeFile;
 import org.springblade.core.tool.api.R;
-import org.springblade.core.tool.utils.ObjectUtil;
+import org.springblade.manager.entity.TrialSummaryClassificationConfiguration;
 import org.springblade.resource.feign.NewIOSSClient;
-import org.springframework.core.io.ByteArrayResource;
 import org.springframework.jdbc.core.BeanPropertyRowMapper;
 import org.springframework.jdbc.core.JdbcTemplate;
-import org.springframework.mock.web.MockMultipartFile;
-import org.springframework.web.bind.annotation.*;
-import org.springframework.web.multipart.MultipartFile;
+import org.springframework.web.bind.annotation.PostMapping;
+import org.springframework.web.bind.annotation.RequestMapping;
+import org.springframework.web.bind.annotation.RestController;
 
-import javax.servlet.ServletOutputStream;
-import javax.servlet.http.HttpServletResponse;
-import java.io.*;
-import java.net.URLDecoder;
-import java.util.*;
 import java.util.List;
-import java.util.function.Function;
-import java.util.stream.Collectors;
 
 @RestController
 @AllArgsConstructor
 @RequestMapping("/trial/summary")
-@Api(value = "试验、月报汇总", tags = "试验、月报汇总接口")
+@Api(value = "试验汇总", tags = "试验汇总接口")
 public class TrialSummaryController {
 
     private final JdbcTemplate jdbcTemplate;
     private final NewIOSSClient newIOSSClient;
 
-    @PostMapping("/monthly/page")
+    @PostMapping("/list")
     @ApiOperationSupport(order = 1)
-    @ApiOperation(value = "月报汇总分页查询", notes = "传入TrialSummaryMonthlyPageDTO")
-    public R<IPage<Map<String, Object>>> monthlyPage(@RequestBody TrialSummaryMonthlyPageDTO dto) {
-        if (ObjectUtil.isEmpty(dto.getContractId()) || ObjectUtil.isEmpty(dto.getType()) || ObjectUtil.isEmpty(dto.getIds()) || StringUtils.isBlank(dto.getStartTime()) || StringUtils.isBlank(dto.getEndTime())) {
-            throw new ServiceException("入参异常");
-        }
-        List<Object> params = new ArrayList<>();
-        StringBuilder sqlString = new StringBuilder("SELECT * FROM u_trial_self_inspection_record WHERE 1=1 AND is_deleted = 0");
-        if (ObjectUtil.isNotEmpty(dto.getContractId())) {
-            sqlString.append(" AND contract_id = ?");
-            params.add(dto.getContractId());
-        }
-        if (ObjectUtil.isNotEmpty(dto.getType())) {
-            sqlString.append(" AND detection_category = ?");
-            params.add(dto.getType());
-        } else {
-            sqlString.append(" AND detection_category = 1");
-        }
-        if (StringUtils.isNotBlank(dto.getStartTime()) && StringUtils.isNotBlank(dto.getEndTime())) {
-            sqlString.append(" AND report_date BETWEEN ? AND ?");
-            params.add(dto.getStartTime());
-            params.add(dto.getEndTime());
-        }
-        if (StringUtils.isNotEmpty(dto.getIds())) {
-            sqlString.append(" AND node_id in(?)");
-            params.add(dto.getIds());
-        }
-
-        String sqlPage = sqlString.append(" ORDER BY create_time;").toString();
-        List<TrialSelfInspectionRecord> resultList = jdbcTemplate.query(
-                sqlPage,
-                new BeanPropertyRowMapper<>(TrialSelfInspectionRecord.class),
-                params.toArray()
-        );
-
-        Map<String, List<TrialSelfInspectionRecord>> groupTOTrialProjectName = resultList.stream()
-                .collect(Collectors.groupingBy(TrialSelfInspectionRecord::getTrialProjectName, LinkedHashMap::new, Collectors.toList()));
-
-        int current = dto.getCurrent();
-        int size = dto.getSize();
-        int start = (current - 1) * size;
-        Map<String, List<TrialSelfInspectionRecord>> paginatedMap = groupTOTrialProjectName.entrySet()
-                .stream()
-                .skip(start)
-                .limit(size)
-                .collect(Collectors.toMap(Map.Entry::getKey, Map.Entry::getValue, (e1, e2) -> e1, LinkedHashMap::new));
-
-        if (paginatedMap.size() <= 0) {
-            return R.data(null);
-        }
-
-        Set<String> names = paginatedMap.keySet();
-        String commaSeparatedQuotedNames = names.stream()
-                .map(name -> "'" + name + "'")
-                .collect(Collectors.joining(","));
-        String sql = "SELECT * FROM u_trial_self_inspection_record WHERE is_deleted = 0 AND contract_id = " + dto.getContractId() + " AND trial_project_name IN (" + commaSeparatedQuotedNames + ")";
-        List<TrialSelfInspectionRecord> query = jdbcTemplate.query(sql, new BeanPropertyRowMapper<>(TrialSelfInspectionRecord.class));
-        Map<String, List<TrialSelfInspectionRecord>> groupAllTOTrialProjectName = query.stream().collect(Collectors.groupingBy(TrialSelfInspectionRecord::getTrialProjectName));
-
-        String sqlRemarks = "SELECT record_id,remarks FROM m_trial_summary_monthly_remarks WHERE contract_id = ?";
-        List<TrialSummaryMonthlyRemarks> trialSummaryMonthlyRemarks = jdbcTemplate.query(sqlRemarks, new Object[]{dto.getContractId()}, new BeanPropertyRowMapper<>(TrialSummaryMonthlyRemarks.class));
-        Map<Long, TrialSummaryMonthlyRemarks> trialSummaryMonthlyRemarksMaps = trialSummaryMonthlyRemarks.stream().collect(Collectors.toMap(TrialSummaryMonthlyRemarks::getRecordId, Function.identity()));
-
-        IPage<Map<String, Object>> page = new Page<>();
-        List<Map<String, Object>> result = new LinkedList<>();
-
-        for (Map.Entry<String, List<TrialSelfInspectionRecord>> stringListEntry : paginatedMap.entrySet()) {
-            String key = stringListEntry.getKey();
-            if (ObjectUtil.isEmpty(key)) {
-                continue;
-            }
-
-            Map<String, Object> map = new LinkedHashMap<>();
-            map.put("trialProjectName", key);
-
-            List<TrialSelfInspectionRecord> currentMonthValue = stringListEntry.getValue();
-            Map<String, Object> currentMonthValueMap = new HashMap<>();
-            Optional<TrialSelfInspectionRecord> minIdRecord = currentMonthValue.stream()
-                    .min(Comparator.comparingLong(TrialSelfInspectionRecord::getId));
-            TrialSelfInspectionRecord minIdRecordOrNull = minIdRecord.orElse(null);
-            if (minIdRecordOrNull != null) {
-                long recordId = minIdRecordOrNull.getId() + 1; //防止与累加id重复,+1
-                currentMonthValueMap.put("recordId", recordId);
-                TrialSummaryMonthlyRemarks orDefault = trialSummaryMonthlyRemarksMaps.getOrDefault(recordId, null);
-                currentMonthValueMap.put("remarks", ObjectUtil.isNotEmpty(orDefault) ? ObjectUtil.isNotEmpty(orDefault.getRemarks()) ? orDefault.getRemarks() : "" : "");
-            }
-            currentMonthValueMap.put("qualifiedTotal", currentMonthValue.stream().filter(f -> f.getDetectionResult() == 1).count());
-            currentMonthValueMap.put("unQualifiedTotal", currentMonthValue.stream().filter(f -> f.getDetectionResult() == 0).count());
-            map.put("currentMonth", currentMonthValueMap);
-
-            List<TrialSelfInspectionRecord> totalMonthValue = groupAllTOTrialProjectName.getOrDefault(key, null);
-            Map<String, Object> totalMonthValueMap = new HashMap<>();
-            Optional<TrialSelfInspectionRecord> minIdRecordAll = totalMonthValue.stream()
-                    .min(Comparator.comparingLong(TrialSelfInspectionRecord::getId));
-            TrialSelfInspectionRecord minIdRecordOrNullAll = minIdRecordAll.orElse(null);
-            if (minIdRecordOrNullAll != null) {
-                long recordId = minIdRecordOrNullAll.getId() + 2; //防止与本月id重复,+2
-                totalMonthValueMap.put("recordId", recordId);
-                TrialSummaryMonthlyRemarks orDefault = trialSummaryMonthlyRemarksMaps.getOrDefault(recordId, null);
-                totalMonthValueMap.put("remarks", ObjectUtil.isNotEmpty(orDefault) ? ObjectUtil.isNotEmpty(orDefault.getRemarks()) ? orDefault.getRemarks() : "" : "");
-            }
-            totalMonthValueMap.put("qualifiedTotal", totalMonthValue.stream().filter(f -> f.getDetectionResult() == 1).count());
-            totalMonthValueMap.put("unQualifiedTotal", totalMonthValue.stream().filter(f -> f.getDetectionResult() == 0).count());
-            map.put("totalMonth", totalMonthValueMap);
-
-            result.add(map);
-        }
-
-        page.setRecords(result);
-        page.setSize(size);
-        page.setCurrent(current);
-        page.setTotal(groupTOTrialProjectName.size());
-        page.setPages((page.getTotal() + size - 1) / size);
-        return R.data(page);
+    @ApiOperation(value = "汇总分类列表", notes = "")
+    public R<List<TrialSummaryClassificationConfiguration>> list() {
+        return R.data(jdbcTemplate.query("SELECT * FROM m_trial_summary_classification_configuration WHERE is_deleted = 0 AND status = 1 ORDER BY sort,create_time", new BeanPropertyRowMapper<>(TrialSummaryClassificationConfiguration.class)));
     }
 
-    @PostMapping("/monthly/edit")
-    @ApiOperationSupport(order = 2)
-    @ApiOperation(value = "月报汇总编辑备注", notes = "传入TrialSummaryMonthlyEditDTO")
-    public R<Object> monthlyEdit(@RequestBody TrialSummaryMonthlyEditDTO dto) {
-        if (ObjectUtil.isEmpty(dto.getRecordId()) || ObjectUtil.isEmpty(dto.getContractId())) {
-            throw new ServiceException("入参异常");
-        }
-        if (ObjectUtil.isNotEmpty(dto.getRemarks()) && dto.getRemarks().length() > 2000) {
-            throw new ServiceException("备注信息最长2000个字符,请重新输入");
-        }
-        try {
-            String sql = "SELECT COUNT(*) FROM m_trial_summary_monthly_remarks WHERE record_id = ? AND contract_id = ?";
-            Integer count = jdbcTemplate.queryForObject(sql, Integer.class, dto.getRecordId(), dto.getContractId());
-            int rowCount = (count != null) ? count : 0;
-            if (rowCount == 0) {
-                String insertSql = "INSERT INTO m_trial_summary_monthly_remarks(id, contract_id, record_id, remarks) VALUES (?, ?, ?, ?)";
-                Object[] insertParams = {
-                        SnowFlakeUtil.getId(),
-                        dto.getContractId(),
-                        dto.getRecordId(),
-                        ObjectUtil.isNotEmpty(dto.getRemarks()) ? dto.getRemarks() : null
-                };
-                jdbcTemplate.update(insertSql, insertParams);
-            } else {
-                String updateSql = "UPDATE m_trial_summary_monthly_remarks SET remarks = ? WHERE record_id = ? AND contract_id = ?";
-                Object[] updateParams = {
-                        ObjectUtil.isNotEmpty(dto.getRemarks()) ? dto.getRemarks() : null,
-                        dto.getRecordId(),
-                        dto.getContractId()
-                };
-                jdbcTemplate.update(updateSql, updateParams);
-            }
-
-            return R.data(200, null, "操作成功");
-        } catch (Exception e) {
-            return R.fail("操作失败" + e.getMessage());
-        }
-    }
-
-    @PostMapping("/monthly/download")
-    @ApiOperationSupport(order = 3)
-    @ApiOperation(value = "月报汇总下载", notes = "传入TrialSummaryMonthlyPageDTO")
-    public void monthlyDownload(@RequestBody TrialSummaryMonthlyPageDTO dto, HttpServletResponse response) {
-        List<Map<String, Object>> records = monthlyPage(dto).getData().getRecords();
-        try (Workbook workbook = new XSSFWorkbook()) {
-            Sheet sheet = workbook.createSheet("Sheet1");
-            Row titleRow_1 = sheet.createRow(0);
-            sheet.addMergedRegion(new CellRangeAddress(0, 1, 0, 1));
-            titleRow_1.setHeight((short) 500);
-            setCellValueWithNullCheck(titleRow_1.createCell(0), "", "");
-
-            CreationHelper helper = workbook.getCreationHelper();
-            XSSFDrawing xssfDrawing = (XSSFDrawing) sheet.createDrawingPatriarch();
-            ClientAnchor anchor = helper.createClientAnchor();
-            anchor.setCol1(0);
-            anchor.setCol2(2);
-            anchor.setRow1(0);
-            anchor.setRow2(2);
-            XSSFSimpleShape simpleShape = xssfDrawing.createSimpleShape((XSSFClientAnchor) anchor);
-            simpleShape.setShapeType(ShapeTypes.LINE);
-            simpleShape.setLineWidth(0.5);
-            simpleShape.setLineStyle(0);
-            simpleShape.setLineStyleColor(0, 0, 0);
-
-            int leftBottomX = anchor.getDx1();
-            int leftBottomY = anchor.getDy1();
-            int rightTopX = anchor.getDx2();
-            int rightTopY = anchor.getDy2();
-            XSSFDrawing xssfDrawingText1 = (XSSFDrawing) sheet.createDrawingPatriarch();
-            XSSFClientAnchor textBoxAnchor1 = new XSSFClientAnchor(leftBottomX, leftBottomY, leftBottomX, leftBottomY, 1, 0, 2, 1);
-            XSSFTextBox textBox1 = xssfDrawingText1.createTextbox(textBoxAnchor1);
-            textBox1.setText("试验组数");
-            XSSFDrawing xssfDrawingText2 = (XSSFDrawing) sheet.createDrawingPatriarch();
-            XSSFClientAnchor textBoxAnchor2 = new XSSFClientAnchor(rightTopX, rightTopY, rightTopX, rightTopY, 0, 1, 1, 2);
-            XSSFTextBox textBox2 = xssfDrawingText2.createTextbox(textBoxAnchor2);
-            textBox2.setText("试验项目");
-
-            sheet.addMergedRegion(new CellRangeAddress(0, 0, 2, 4));
-            setCellValueWithNullCheck(titleRow_1.createCell(2), "承包人", "");
-            Row titleRow_2 = sheet.createRow(1);
-            titleRow_2.setHeight((short) 500);
-            setCellValueWithNullCheck(titleRow_2.createCell(2), "合格数", "");
-            setCellValueWithNullCheck(titleRow_2.createCell(3), "不合格数", "");
-            setCellValueWithNullCheck(titleRow_2.createCell(4), "备注", "");
-
-            int rowNum = 2;
-            for (Map<String, Object> record : records) {
-                Row currentMonthRow = sheet.createRow(rowNum);
-                sheet.addMergedRegion(new CellRangeAddress(rowNum, rowNum + 1, 0, 0));
-                setCellValueWithNullCheck(currentMonthRow.createCell(0), "", record.get("trialProjectName"));
-
-                Map<String, Object> currentMonth = (Map<String, Object>) record.get("currentMonth");
-                setCellValueWithNullCheck(currentMonthRow.createCell(1), "本月", "");
-                setCellValueWithNullCheck(currentMonthRow.createCell(2), "", currentMonth.get("qualifiedTotal"));
-                setCellValueWithNullCheck(currentMonthRow.createCell(3), "", currentMonth.get("unQualifiedTotal"));
-                setCellValueWithNullCheck(currentMonthRow.createCell(4), "", currentMonth.get("remarks"));
-
-                Map<String, Object> totalMonth = (Map<String, Object>) record.get("totalMonth");
-                Row totalMonthRow = sheet.createRow(++rowNum);
-                setCellValueWithNullCheck(totalMonthRow.createCell(1), "累计", "");
-                setCellValueWithNullCheck(totalMonthRow.createCell(2), "", totalMonth.get("qualifiedTotal"));
-                setCellValueWithNullCheck(totalMonthRow.createCell(3), "", totalMonth.get("unQualifiedTotal"));
-                setCellValueWithNullCheck(totalMonthRow.createCell(4), "", totalMonth.get("remarks"));
-
-                rowNum++;
-            }
-
-            sheet.setColumnWidth(0, 5000);
-            sheet.setColumnWidth(1, 5000);
-            sheet.setColumnWidth(2, 5000);
-            sheet.setColumnWidth(3, 5000);
-            sheet.setColumnWidth(4, 5000);
-
-            try (ServletOutputStream outputStream = response.getOutputStream();
-                 ByteArrayOutputStream byteArrayOutputStreamResult = new ByteArrayOutputStream()) {
-                String fileName = dto.getStartTime() + "~" + dto.getEndTime() + ".xlsx";
-                String decodedFileName = URLDecoder.decode(fileName, "UTF-8");
-                response.setHeader("Content-Disposition", "attachment; filename=\"" + decodedFileName + "\"");
-                response.setContentType("application/vnd.openxmlformats-officedocument.spreadsheetml.sheet");
-                workbook.write(byteArrayOutputStreamResult);
-                byte[] excelBytesResult = byteArrayOutputStreamResult.toByteArray();
-                outputStream.write(excelBytesResult);
-
-            } catch (IOException e) {
-                e.printStackTrace();
-            } finally {
-                workbook.close();
-            }
-        } catch (IOException e) {
-            e.printStackTrace();
-        }
-    }
-
-    private void setCellValueWithNullCheck(Cell cell, String defaultValue, Object value) {
-        if (ObjectUtil.isNotEmpty(value)) {
-            cell.setCellValue(String.valueOf(value));
-        } else {
-            cell.setCellValue(defaultValue);
-        }
-    }
-
-    @PostMapping("/monthly/print")
-    @ApiOperationSupport(order = 4)
-    @ApiOperation(value = "月报汇总打印", notes = "传入TrialSummaryMonthlyPageDTO")
-    public R<Object> monthlyPrint(@RequestBody TrialSummaryMonthlyPageDTO dto) {
-        List<Map<String, Object>> records = monthlyPage(dto).getData().getRecords();
-        try (Workbook workbook = new XSSFWorkbook()) {
-            Sheet sheet = workbook.createSheet("Sheet1");
-            Row titleRow_1 = sheet.createRow(0);
-            sheet.addMergedRegion(new CellRangeAddress(0, 1, 0, 1));
-            titleRow_1.setHeight((short) 500);
-            setCellValueWithNullCheck(titleRow_1.createCell(0), "", "");
-
-            CreationHelper helper = workbook.getCreationHelper();
-            XSSFDrawing xssfDrawing = (XSSFDrawing) sheet.createDrawingPatriarch();
-            ClientAnchor anchor = helper.createClientAnchor();
-            anchor.setCol1(0);
-            anchor.setCol2(2);
-            anchor.setRow1(0);
-            anchor.setRow2(2);
-            XSSFSimpleShape simpleShape = xssfDrawing.createSimpleShape((XSSFClientAnchor) anchor);
-            simpleShape.setShapeType(ShapeTypes.LINE);
-            simpleShape.setLineWidth(0.5);
-            simpleShape.setLineStyle(0);
-            simpleShape.setLineStyleColor(0, 0, 0);
-
-            int leftBottomX = anchor.getDx1();
-            int leftBottomY = anchor.getDy1();
-            int rightTopX = anchor.getDx2();
-            int rightTopY = anchor.getDy2();
-            XSSFDrawing xssfDrawingText1 = (XSSFDrawing) sheet.createDrawingPatriarch();
-            XSSFClientAnchor textBoxAnchor1 = new XSSFClientAnchor(leftBottomX, leftBottomY, leftBottomX, leftBottomY, 1, 0, 2, 1);
-            XSSFTextBox textBox1 = xssfDrawingText1.createTextbox(textBoxAnchor1);
-            textBox1.setText("试验组数");
-            XSSFDrawing xssfDrawingText2 = (XSSFDrawing) sheet.createDrawingPatriarch();
-            XSSFClientAnchor textBoxAnchor2 = new XSSFClientAnchor(rightTopX, rightTopY, rightTopX, rightTopY, 0, 1, 1, 2);
-            XSSFTextBox textBox2 = xssfDrawingText2.createTextbox(textBoxAnchor2);
-            textBox2.setText("试验项目");
-
-            sheet.addMergedRegion(new CellRangeAddress(0, 0, 2, 4));
-            setCellValueWithNullCheck(titleRow_1.createCell(2), "承包人", "");
-            Row titleRow_2 = sheet.createRow(1);
-            titleRow_2.setHeight((short) 500);
-            setCellValueWithNullCheck(titleRow_2.createCell(2), "合格数", "");
-            setCellValueWithNullCheck(titleRow_2.createCell(3), "不合格数", "");
-            setCellValueWithNullCheck(titleRow_2.createCell(4), "备注", "");
-
-            int rowNum = 2;
-            for (Map<String, Object> record : records) {
-                Row currentMonthRow = sheet.createRow(rowNum);
-                sheet.addMergedRegion(new CellRangeAddress(rowNum, rowNum + 1, 0, 0));
-                setCellValueWithNullCheck(currentMonthRow.createCell(0), "", record.get("trialProjectName"));
-
-                Map<String, Object> currentMonth = (Map<String, Object>) record.get("currentMonth");
-                setCellValueWithNullCheck(currentMonthRow.createCell(1), "本月", "");
-                setCellValueWithNullCheck(currentMonthRow.createCell(2), "", currentMonth.get("qualifiedTotal"));
-                setCellValueWithNullCheck(currentMonthRow.createCell(3), "", currentMonth.get("unQualifiedTotal"));
-                setCellValueWithNullCheck(currentMonthRow.createCell(4), "", currentMonth.get("remarks"));
-
-                Map<String, Object> totalMonth = (Map<String, Object>) record.get("totalMonth");
-                Row totalMonthRow = sheet.createRow(++rowNum);
-                setCellValueWithNullCheck(totalMonthRow.createCell(1), "累计", "");
-                setCellValueWithNullCheck(totalMonthRow.createCell(2), "", totalMonth.get("qualifiedTotal"));
-                setCellValueWithNullCheck(totalMonthRow.createCell(3), "", totalMonth.get("unQualifiedTotal"));
-                setCellValueWithNullCheck(totalMonthRow.createCell(4), "", totalMonth.get("remarks"));
-
-                rowNum++;
-            }
-
-            sheet.setColumnWidth(0, 5000);
-            sheet.setColumnWidth(1, 5000);
-            sheet.setColumnWidth(2, 5000);
-            sheet.setColumnWidth(3, 5000);
-            sheet.setColumnWidth(4, 5000);
-
-            try (ByteArrayOutputStream byteArrayOutputStreamResult = new ByteArrayOutputStream()) {
-                workbook.write(byteArrayOutputStreamResult);
-                byte[] excelBytesResult = byteArrayOutputStreamResult.toByteArray();
-                MultipartFile multipartFile = convertExcelToPdf(excelBytesResult);
-                if (multipartFile != null) {
-                    BladeFile bladeFile = newIOSSClient.uploadFileByInputStream(multipartFile);
-                    if (bladeFile != null) {
-                        return R.data(bladeFile.getLink());
-                    }
-                }
-            } catch (IOException e) {
-                e.printStackTrace();
-            } finally {
-                workbook.close();
-            }
-        } catch (IOException e) {
-            e.printStackTrace();
-        }
-        return R.fail("操作失败");
-    }
-
-    private MultipartFile convertExcelToPdf(byte[] excelBytes) {
-        ByteArrayInputStream byteArrayInputStream = null;
-        ByteArrayOutputStream outReport = null;
-        try {
-            byteArrayInputStream = new ByteArrayInputStream(excelBytes);
-            Workbook ss = WorkbookFactory.create(byteArrayInputStream);
-            Sheet sheet = ss.getSheetAt(0);
-            for (int r = 0; r <= sheet.getLastRowNum(); r++) {
-                Row row = sheet.getRow(r);
-                if (row != null) {
-                    for (int c = 0; c < row.getLastCellNum(); c++) {
-                        Cell cell = row.getCell(c);
-                        if (cell != null) {
-                            CellStyle cellStyle = ss.createCellStyle();
-                            cellStyle.cloneStyleFrom(cell.getCellStyle());
-                            cellStyle.setBorderBottom(BorderStyle.THIN);
-                            cellStyle.setBorderTop(BorderStyle.THIN);
-                            cellStyle.setBorderRight(BorderStyle.THIN);
-                            cellStyle.setBorderLeft(BorderStyle.THIN);
-                            cell.setCellStyle(cellStyle);
-                            CellRangeAddress mergedRegion = getMergedRegion(sheet, r, c);
-                            if (mergedRegion != null) {
-                                setMergedRegionBorders(sheet, mergedRegion, cellStyle);
-                            }
-                        }
-                    }
-                }
-                sheet.setPrintGridlines(false);
-                sheet.setFitToPage(true);
-            }
-
-            outReport = new ByteArrayOutputStream();
-            ss.write(outReport);
-
-            PdfSaveOptions pdfSaveOptions = new PdfSaveOptions();
-            pdfSaveOptions.setOnePagePerSheet(true);
-
-            com.aspose.cells.Workbook wb = new com.aspose.cells.Workbook(new ByteArrayInputStream(outReport.toByteArray()));
-            PageSetup pageSetup = wb.getWorksheets().get(0).getPageSetup();
-            pageSetup.setPaperSize(PaperSizeType.PAPER_A_4);
-
-            ByteArrayOutputStream pdfByteArrayOutputStream = new ByteArrayOutputStream();
-            wb.save(pdfByteArrayOutputStream, pdfSaveOptions);
-
-            ByteArrayResource resource = new ByteArrayResource(pdfByteArrayOutputStream.toByteArray());
-
-            return new MockMultipartFile("file", SnowFlakeUtil.getId() + ".pdf", "application/pdf", resource.getInputStream());
-
-        } catch (Exception e) {
-            e.printStackTrace();
-            return null;
-        } finally {
-            if (outReport != null) {
-                try {
-                    outReport.close();
-                } catch (Exception e) {
-                    e.printStackTrace();
-                }
-            }
-            if (byteArrayInputStream != null) {
-                try {
-                    byteArrayInputStream.close();
-                } catch (Exception e) {
-                    e.printStackTrace();
-                }
-            }
-        }
-    }
-
-    private void setMergedRegionBorders(Sheet sheet, CellRangeAddress region, CellStyle style) {
-        for (int row = region.getFirstRow(); row <= region.getLastRow(); row++) {
-            Row currentRow = sheet.getRow(row);
-            if (currentRow == null) {
-                currentRow = sheet.createRow(row);
-            }
-            for (int col = region.getFirstColumn(); col <= region.getLastColumn(); col++) {
-                Cell currentCell = currentRow.getCell(col);
-                if (currentCell == null) {
-                    currentCell = currentRow.createCell(col);
-                }
-                currentCell.setCellStyle(style);
-            }
-        }
-    }
-
-    private CellRangeAddress getMergedRegion(Sheet sheet, int row, int col) {
-        for (int i = 0; i < sheet.getNumMergedRegions(); i++) {
-            CellRangeAddress mergedRegion = sheet.getMergedRegion(i);
-            if (mergedRegion.isInRange(row, col)) {
-                return mergedRegion;
-            }
-        }
-        return null;
-    }
 }

+ 498 - 0
blade-service/blade-business/src/main/java/org/springblade/business/controller/TrialSummaryMonthlyController.java

@@ -0,0 +1,498 @@
+package org.springblade.business.controller;
+
+import com.aspose.cells.PageSetup;
+import com.aspose.cells.PaperSizeType;
+import com.aspose.cells.PdfSaveOptions;
+import com.baomidou.mybatisplus.core.metadata.IPage;
+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.apache.commons.lang.StringUtils;
+import org.apache.poi.ss.usermodel.*;
+import org.apache.poi.ss.util.CellRangeAddress;
+import org.apache.poi.xssf.usermodel.*;
+import org.springblade.business.dto.TrialSummaryMonthlyEditDTO;
+import org.springblade.business.dto.TrialSummaryMonthlyPageDTO;
+import org.springblade.business.entity.TrialSelfInspectionRecord;
+import org.springblade.business.entity.TrialSummaryMonthlyRemarks;
+import org.springblade.common.utils.SnowFlakeUtil;
+import org.springblade.core.log.exception.ServiceException;
+import org.springblade.core.oss.model.BladeFile;
+import org.springblade.core.tool.api.R;
+import org.springblade.core.tool.utils.ObjectUtil;
+import org.springblade.resource.feign.NewIOSSClient;
+import org.springframework.core.io.ByteArrayResource;
+import org.springframework.jdbc.core.BeanPropertyRowMapper;
+import org.springframework.jdbc.core.JdbcTemplate;
+import org.springframework.mock.web.MockMultipartFile;
+import org.springframework.web.bind.annotation.*;
+import org.springframework.web.multipart.MultipartFile;
+
+import javax.servlet.ServletOutputStream;
+import javax.servlet.http.HttpServletResponse;
+import java.io.*;
+import java.net.URLDecoder;
+import java.util.*;
+import java.util.List;
+import java.util.function.Function;
+import java.util.stream.Collectors;
+
+@RestController
+@AllArgsConstructor
+@RequestMapping("/trial/summary")
+@Api(value = "月报汇总", tags = "月报汇总接口")
+public class TrialSummaryMonthlyController {
+
+    private final JdbcTemplate jdbcTemplate;
+    private final NewIOSSClient newIOSSClient;
+
+    @PostMapping("/monthly/page")
+    @ApiOperationSupport(order = 1)
+    @ApiOperation(value = "月报汇总分页查询", notes = "传入TrialSummaryMonthlyPageDTO")
+    public R<IPage<Map<String, Object>>> monthlyPage(@RequestBody TrialSummaryMonthlyPageDTO dto) {
+        if (ObjectUtil.isEmpty(dto.getContractId()) || ObjectUtil.isEmpty(dto.getType()) || ObjectUtil.isEmpty(dto.getIds()) || StringUtils.isBlank(dto.getStartTime()) || StringUtils.isBlank(dto.getEndTime())) {
+            throw new ServiceException("入参异常");
+        }
+        List<Object> params = new ArrayList<>();
+        StringBuilder sqlString = new StringBuilder("SELECT * FROM u_trial_self_inspection_record WHERE 1=1 AND is_deleted = 0");
+        if (ObjectUtil.isNotEmpty(dto.getContractId())) {
+            sqlString.append(" AND contract_id = ?");
+            params.add(dto.getContractId());
+        }
+        if (ObjectUtil.isNotEmpty(dto.getType())) {
+            sqlString.append(" AND detection_category = ?");
+            params.add(dto.getType());
+        } else {
+            sqlString.append(" AND detection_category = 1");
+        }
+        if (StringUtils.isNotBlank(dto.getStartTime()) && StringUtils.isNotBlank(dto.getEndTime())) {
+            sqlString.append(" AND report_date BETWEEN ? AND ?");
+            params.add(dto.getStartTime());
+            params.add(dto.getEndTime());
+        }
+        if (StringUtils.isNotEmpty(dto.getIds())) {
+            sqlString.append(" AND node_id in(?)");
+            params.add(dto.getIds());
+        }
+
+        String sqlPage = sqlString.append(" ORDER BY create_time;").toString();
+        List<TrialSelfInspectionRecord> resultList = jdbcTemplate.query(
+                sqlPage,
+                new BeanPropertyRowMapper<>(TrialSelfInspectionRecord.class),
+                params.toArray()
+        );
+
+        Map<String, List<TrialSelfInspectionRecord>> groupTOTrialProjectName = resultList.stream()
+                .collect(Collectors.groupingBy(TrialSelfInspectionRecord::getTrialProjectName, LinkedHashMap::new, Collectors.toList()));
+
+        int current = dto.getCurrent();
+        int size = dto.getSize();
+        int start = (current - 1) * size;
+        Map<String, List<TrialSelfInspectionRecord>> paginatedMap = groupTOTrialProjectName.entrySet()
+                .stream()
+                .skip(start)
+                .limit(size)
+                .collect(Collectors.toMap(Map.Entry::getKey, Map.Entry::getValue, (e1, e2) -> e1, LinkedHashMap::new));
+
+        if (paginatedMap.size() <= 0) {
+            return R.data(null);
+        }
+
+        Set<String> names = paginatedMap.keySet();
+        String commaSeparatedQuotedNames = names.stream()
+                .map(name -> "'" + name + "'")
+                .collect(Collectors.joining(","));
+        String sql = "SELECT * FROM u_trial_self_inspection_record WHERE is_deleted = 0 AND contract_id = " + dto.getContractId() + " AND trial_project_name IN (" + commaSeparatedQuotedNames + ")";
+        List<TrialSelfInspectionRecord> query = jdbcTemplate.query(sql, new BeanPropertyRowMapper<>(TrialSelfInspectionRecord.class));
+        Map<String, List<TrialSelfInspectionRecord>> groupAllTOTrialProjectName = query.stream().collect(Collectors.groupingBy(TrialSelfInspectionRecord::getTrialProjectName));
+
+        String sqlRemarks = "SELECT record_id,remarks FROM m_trial_summary_monthly_remarks WHERE contract_id = ?";
+        List<TrialSummaryMonthlyRemarks> trialSummaryMonthlyRemarks = jdbcTemplate.query(sqlRemarks, new Object[]{dto.getContractId()}, new BeanPropertyRowMapper<>(TrialSummaryMonthlyRemarks.class));
+        Map<Long, TrialSummaryMonthlyRemarks> trialSummaryMonthlyRemarksMaps = trialSummaryMonthlyRemarks.stream().collect(Collectors.toMap(TrialSummaryMonthlyRemarks::getRecordId, Function.identity()));
+
+        IPage<Map<String, Object>> page = new Page<>();
+        List<Map<String, Object>> result = new LinkedList<>();
+
+        for (Map.Entry<String, List<TrialSelfInspectionRecord>> stringListEntry : paginatedMap.entrySet()) {
+            String key = stringListEntry.getKey();
+            if (ObjectUtil.isEmpty(key)) {
+                continue;
+            }
+
+            Map<String, Object> map = new LinkedHashMap<>();
+            map.put("trialProjectName", key);
+
+            List<TrialSelfInspectionRecord> currentMonthValue = stringListEntry.getValue();
+            Map<String, Object> currentMonthValueMap = new HashMap<>();
+            Optional<TrialSelfInspectionRecord> minIdRecord = currentMonthValue.stream()
+                    .min(Comparator.comparingLong(TrialSelfInspectionRecord::getId));
+            TrialSelfInspectionRecord minIdRecordOrNull = minIdRecord.orElse(null);
+            if (minIdRecordOrNull != null) {
+                long recordId = minIdRecordOrNull.getId() + 1; //防止与累加id重复,+1
+                currentMonthValueMap.put("recordId", recordId);
+                TrialSummaryMonthlyRemarks orDefault = trialSummaryMonthlyRemarksMaps.getOrDefault(recordId, null);
+                currentMonthValueMap.put("remarks", ObjectUtil.isNotEmpty(orDefault) ? ObjectUtil.isNotEmpty(orDefault.getRemarks()) ? orDefault.getRemarks() : "" : "");
+            }
+            currentMonthValueMap.put("qualifiedTotal", currentMonthValue.stream().filter(f -> f.getDetectionResult() == 1).count());
+            currentMonthValueMap.put("unQualifiedTotal", currentMonthValue.stream().filter(f -> f.getDetectionResult() == 0).count());
+            map.put("currentMonth", currentMonthValueMap);
+
+            List<TrialSelfInspectionRecord> totalMonthValue = groupAllTOTrialProjectName.getOrDefault(key, null);
+            Map<String, Object> totalMonthValueMap = new HashMap<>();
+            Optional<TrialSelfInspectionRecord> minIdRecordAll = totalMonthValue.stream()
+                    .min(Comparator.comparingLong(TrialSelfInspectionRecord::getId));
+            TrialSelfInspectionRecord minIdRecordOrNullAll = minIdRecordAll.orElse(null);
+            if (minIdRecordOrNullAll != null) {
+                long recordId = minIdRecordOrNullAll.getId() + 2; //防止与本月id重复,+2
+                totalMonthValueMap.put("recordId", recordId);
+                TrialSummaryMonthlyRemarks orDefault = trialSummaryMonthlyRemarksMaps.getOrDefault(recordId, null);
+                totalMonthValueMap.put("remarks", ObjectUtil.isNotEmpty(orDefault) ? ObjectUtil.isNotEmpty(orDefault.getRemarks()) ? orDefault.getRemarks() : "" : "");
+            }
+            totalMonthValueMap.put("qualifiedTotal", totalMonthValue.stream().filter(f -> f.getDetectionResult() == 1).count());
+            totalMonthValueMap.put("unQualifiedTotal", totalMonthValue.stream().filter(f -> f.getDetectionResult() == 0).count());
+            map.put("totalMonth", totalMonthValueMap);
+
+            result.add(map);
+        }
+
+        page.setRecords(result);
+        page.setSize(size);
+        page.setCurrent(current);
+        page.setTotal(groupTOTrialProjectName.size());
+        page.setPages((page.getTotal() + size - 1) / size);
+        return R.data(page);
+    }
+
+    @PostMapping("/monthly/edit")
+    @ApiOperationSupport(order = 2)
+    @ApiOperation(value = "月报汇总编辑备注", notes = "传入TrialSummaryMonthlyEditDTO")
+    public R<Object> monthlyEdit(@RequestBody TrialSummaryMonthlyEditDTO dto) {
+        if (ObjectUtil.isEmpty(dto.getRecordId()) || ObjectUtil.isEmpty(dto.getContractId())) {
+            throw new ServiceException("入参异常");
+        }
+        if (ObjectUtil.isNotEmpty(dto.getRemarks()) && dto.getRemarks().length() > 2000) {
+            throw new ServiceException("备注信息最长2000个字符,请重新输入");
+        }
+        try {
+            String sql = "SELECT COUNT(*) FROM m_trial_summary_monthly_remarks WHERE record_id = ? AND contract_id = ?";
+            Integer count = jdbcTemplate.queryForObject(sql, Integer.class, dto.getRecordId(), dto.getContractId());
+            int rowCount = (count != null) ? count : 0;
+            if (rowCount == 0) {
+                String insertSql = "INSERT INTO m_trial_summary_monthly_remarks(id, contract_id, record_id, remarks) VALUES (?, ?, ?, ?)";
+                Object[] insertParams = {
+                        SnowFlakeUtil.getId(),
+                        dto.getContractId(),
+                        dto.getRecordId(),
+                        ObjectUtil.isNotEmpty(dto.getRemarks()) ? dto.getRemarks() : null
+                };
+                jdbcTemplate.update(insertSql, insertParams);
+            } else {
+                String updateSql = "UPDATE m_trial_summary_monthly_remarks SET remarks = ? WHERE record_id = ? AND contract_id = ?";
+                Object[] updateParams = {
+                        ObjectUtil.isNotEmpty(dto.getRemarks()) ? dto.getRemarks() : null,
+                        dto.getRecordId(),
+                        dto.getContractId()
+                };
+                jdbcTemplate.update(updateSql, updateParams);
+            }
+
+            return R.data(200, null, "操作成功");
+        } catch (Exception e) {
+            return R.fail("操作失败" + e.getMessage());
+        }
+    }
+
+    @PostMapping("/monthly/download")
+    @ApiOperationSupport(order = 3)
+    @ApiOperation(value = "月报汇总下载", notes = "传入TrialSummaryMonthlyPageDTO")
+    public void monthlyDownload(@RequestBody TrialSummaryMonthlyPageDTO dto, HttpServletResponse response) {
+        List<Map<String, Object>> records = monthlyPage(dto).getData().getRecords();
+        try (Workbook workbook = new XSSFWorkbook()) {
+            Sheet sheet = workbook.createSheet("Sheet1");
+            Row titleRow_1 = sheet.createRow(0);
+            sheet.addMergedRegion(new CellRangeAddress(0, 1, 0, 1));
+            titleRow_1.setHeight((short) 500);
+            setCellValueWithNullCheck(titleRow_1.createCell(0), "", "");
+
+            CreationHelper helper = workbook.getCreationHelper();
+            XSSFDrawing xssfDrawing = (XSSFDrawing) sheet.createDrawingPatriarch();
+            ClientAnchor anchor = helper.createClientAnchor();
+            anchor.setCol1(0);
+            anchor.setCol2(2);
+            anchor.setRow1(0);
+            anchor.setRow2(2);
+            XSSFSimpleShape simpleShape = xssfDrawing.createSimpleShape((XSSFClientAnchor) anchor);
+            simpleShape.setShapeType(ShapeTypes.LINE);
+            simpleShape.setLineWidth(0.5);
+            simpleShape.setLineStyle(0);
+            simpleShape.setLineStyleColor(0, 0, 0);
+
+            int leftBottomX = anchor.getDx1();
+            int leftBottomY = anchor.getDy1();
+            int rightTopX = anchor.getDx2();
+            int rightTopY = anchor.getDy2();
+            XSSFDrawing xssfDrawingText1 = (XSSFDrawing) sheet.createDrawingPatriarch();
+            XSSFClientAnchor textBoxAnchor1 = new XSSFClientAnchor(leftBottomX, leftBottomY, leftBottomX, leftBottomY, 1, 0, 2, 1);
+            XSSFTextBox textBox1 = xssfDrawingText1.createTextbox(textBoxAnchor1);
+            textBox1.setText("试验组数");
+            XSSFDrawing xssfDrawingText2 = (XSSFDrawing) sheet.createDrawingPatriarch();
+            XSSFClientAnchor textBoxAnchor2 = new XSSFClientAnchor(rightTopX, rightTopY, rightTopX, rightTopY, 0, 1, 1, 2);
+            XSSFTextBox textBox2 = xssfDrawingText2.createTextbox(textBoxAnchor2);
+            textBox2.setText("试验项目");
+
+            sheet.addMergedRegion(new CellRangeAddress(0, 0, 2, 4));
+            setCellValueWithNullCheck(titleRow_1.createCell(2), "承包人", "");
+            Row titleRow_2 = sheet.createRow(1);
+            titleRow_2.setHeight((short) 500);
+            setCellValueWithNullCheck(titleRow_2.createCell(2), "合格数", "");
+            setCellValueWithNullCheck(titleRow_2.createCell(3), "不合格数", "");
+            setCellValueWithNullCheck(titleRow_2.createCell(4), "备注", "");
+
+            int rowNum = 2;
+            for (Map<String, Object> record : records) {
+                Row currentMonthRow = sheet.createRow(rowNum);
+                sheet.addMergedRegion(new CellRangeAddress(rowNum, rowNum + 1, 0, 0));
+                setCellValueWithNullCheck(currentMonthRow.createCell(0), "", record.get("trialProjectName"));
+
+                Map<String, Object> currentMonth = (Map<String, Object>) record.get("currentMonth");
+                setCellValueWithNullCheck(currentMonthRow.createCell(1), "本月", "");
+                setCellValueWithNullCheck(currentMonthRow.createCell(2), "", currentMonth.get("qualifiedTotal"));
+                setCellValueWithNullCheck(currentMonthRow.createCell(3), "", currentMonth.get("unQualifiedTotal"));
+                setCellValueWithNullCheck(currentMonthRow.createCell(4), "", currentMonth.get("remarks"));
+
+                Map<String, Object> totalMonth = (Map<String, Object>) record.get("totalMonth");
+                Row totalMonthRow = sheet.createRow(++rowNum);
+                setCellValueWithNullCheck(totalMonthRow.createCell(1), "累计", "");
+                setCellValueWithNullCheck(totalMonthRow.createCell(2), "", totalMonth.get("qualifiedTotal"));
+                setCellValueWithNullCheck(totalMonthRow.createCell(3), "", totalMonth.get("unQualifiedTotal"));
+                setCellValueWithNullCheck(totalMonthRow.createCell(4), "", totalMonth.get("remarks"));
+
+                rowNum++;
+            }
+
+            sheet.setColumnWidth(0, 5000);
+            sheet.setColumnWidth(1, 5000);
+            sheet.setColumnWidth(2, 5000);
+            sheet.setColumnWidth(3, 5000);
+            sheet.setColumnWidth(4, 5000);
+
+            try (ServletOutputStream outputStream = response.getOutputStream();
+                 ByteArrayOutputStream byteArrayOutputStreamResult = new ByteArrayOutputStream()) {
+                String fileName = dto.getStartTime() + "~" + dto.getEndTime() + ".xlsx";
+                String decodedFileName = URLDecoder.decode(fileName, "UTF-8");
+                response.setHeader("Content-Disposition", "attachment; filename=\"" + decodedFileName + "\"");
+                response.setContentType("application/vnd.openxmlformats-officedocument.spreadsheetml.sheet");
+                workbook.write(byteArrayOutputStreamResult);
+                byte[] excelBytesResult = byteArrayOutputStreamResult.toByteArray();
+                outputStream.write(excelBytesResult);
+
+            } catch (IOException e) {
+                e.printStackTrace();
+            } finally {
+                workbook.close();
+            }
+        } catch (IOException e) {
+            e.printStackTrace();
+        }
+    }
+
+    private void setCellValueWithNullCheck(Cell cell, String defaultValue, Object value) {
+        if (ObjectUtil.isNotEmpty(value)) {
+            cell.setCellValue(String.valueOf(value));
+        } else {
+            cell.setCellValue(defaultValue);
+        }
+    }
+
+    @PostMapping("/monthly/print")
+    @ApiOperationSupport(order = 4)
+    @ApiOperation(value = "月报汇总打印", notes = "传入TrialSummaryMonthlyPageDTO")
+    public R<Object> monthlyPrint(@RequestBody TrialSummaryMonthlyPageDTO dto) {
+        List<Map<String, Object>> records = monthlyPage(dto).getData().getRecords();
+        try (Workbook workbook = new XSSFWorkbook()) {
+            Sheet sheet = workbook.createSheet("Sheet1");
+            Row titleRow_1 = sheet.createRow(0);
+            sheet.addMergedRegion(new CellRangeAddress(0, 1, 0, 1));
+            titleRow_1.setHeight((short) 500);
+            setCellValueWithNullCheck(titleRow_1.createCell(0), "", "");
+
+            CreationHelper helper = workbook.getCreationHelper();
+            XSSFDrawing xssfDrawing = (XSSFDrawing) sheet.createDrawingPatriarch();
+            ClientAnchor anchor = helper.createClientAnchor();
+            anchor.setCol1(0);
+            anchor.setCol2(2);
+            anchor.setRow1(0);
+            anchor.setRow2(2);
+            XSSFSimpleShape simpleShape = xssfDrawing.createSimpleShape((XSSFClientAnchor) anchor);
+            simpleShape.setShapeType(ShapeTypes.LINE);
+            simpleShape.setLineWidth(0.5);
+            simpleShape.setLineStyle(0);
+            simpleShape.setLineStyleColor(0, 0, 0);
+
+            int leftBottomX = anchor.getDx1();
+            int leftBottomY = anchor.getDy1();
+            int rightTopX = anchor.getDx2();
+            int rightTopY = anchor.getDy2();
+            XSSFDrawing xssfDrawingText1 = (XSSFDrawing) sheet.createDrawingPatriarch();
+            XSSFClientAnchor textBoxAnchor1 = new XSSFClientAnchor(leftBottomX, leftBottomY, leftBottomX, leftBottomY, 1, 0, 2, 1);
+            XSSFTextBox textBox1 = xssfDrawingText1.createTextbox(textBoxAnchor1);
+            textBox1.setText("试验组数");
+            XSSFDrawing xssfDrawingText2 = (XSSFDrawing) sheet.createDrawingPatriarch();
+            XSSFClientAnchor textBoxAnchor2 = new XSSFClientAnchor(rightTopX, rightTopY, rightTopX, rightTopY, 0, 1, 1, 2);
+            XSSFTextBox textBox2 = xssfDrawingText2.createTextbox(textBoxAnchor2);
+            textBox2.setText("试验项目");
+
+            sheet.addMergedRegion(new CellRangeAddress(0, 0, 2, 4));
+            setCellValueWithNullCheck(titleRow_1.createCell(2), "承包人", "");
+            Row titleRow_2 = sheet.createRow(1);
+            titleRow_2.setHeight((short) 500);
+            setCellValueWithNullCheck(titleRow_2.createCell(2), "合格数", "");
+            setCellValueWithNullCheck(titleRow_2.createCell(3), "不合格数", "");
+            setCellValueWithNullCheck(titleRow_2.createCell(4), "备注", "");
+
+            int rowNum = 2;
+            for (Map<String, Object> record : records) {
+                Row currentMonthRow = sheet.createRow(rowNum);
+                sheet.addMergedRegion(new CellRangeAddress(rowNum, rowNum + 1, 0, 0));
+                setCellValueWithNullCheck(currentMonthRow.createCell(0), "", record.get("trialProjectName"));
+
+                Map<String, Object> currentMonth = (Map<String, Object>) record.get("currentMonth");
+                setCellValueWithNullCheck(currentMonthRow.createCell(1), "本月", "");
+                setCellValueWithNullCheck(currentMonthRow.createCell(2), "", currentMonth.get("qualifiedTotal"));
+                setCellValueWithNullCheck(currentMonthRow.createCell(3), "", currentMonth.get("unQualifiedTotal"));
+                setCellValueWithNullCheck(currentMonthRow.createCell(4), "", currentMonth.get("remarks"));
+
+                Map<String, Object> totalMonth = (Map<String, Object>) record.get("totalMonth");
+                Row totalMonthRow = sheet.createRow(++rowNum);
+                setCellValueWithNullCheck(totalMonthRow.createCell(1), "累计", "");
+                setCellValueWithNullCheck(totalMonthRow.createCell(2), "", totalMonth.get("qualifiedTotal"));
+                setCellValueWithNullCheck(totalMonthRow.createCell(3), "", totalMonth.get("unQualifiedTotal"));
+                setCellValueWithNullCheck(totalMonthRow.createCell(4), "", totalMonth.get("remarks"));
+
+                rowNum++;
+            }
+
+            sheet.setColumnWidth(0, 5000);
+            sheet.setColumnWidth(1, 5000);
+            sheet.setColumnWidth(2, 5000);
+            sheet.setColumnWidth(3, 5000);
+            sheet.setColumnWidth(4, 5000);
+
+            try (ByteArrayOutputStream byteArrayOutputStreamResult = new ByteArrayOutputStream()) {
+                workbook.write(byteArrayOutputStreamResult);
+                byte[] excelBytesResult = byteArrayOutputStreamResult.toByteArray();
+                MultipartFile multipartFile = convertExcelToPdf(excelBytesResult);
+                if (multipartFile != null) {
+                    BladeFile bladeFile = newIOSSClient.uploadFileByInputStream(multipartFile);
+                    if (bladeFile != null) {
+                        return R.data(bladeFile.getLink());
+                    }
+                }
+            } catch (IOException e) {
+                e.printStackTrace();
+            } finally {
+                workbook.close();
+            }
+        } catch (IOException e) {
+            e.printStackTrace();
+        }
+        return R.fail("操作失败");
+    }
+
+    private MultipartFile convertExcelToPdf(byte[] excelBytes) {
+        ByteArrayInputStream byteArrayInputStream = null;
+        ByteArrayOutputStream outReport = null;
+        try {
+            byteArrayInputStream = new ByteArrayInputStream(excelBytes);
+            Workbook ss = WorkbookFactory.create(byteArrayInputStream);
+            Sheet sheet = ss.getSheetAt(0);
+            for (int r = 0; r <= sheet.getLastRowNum(); r++) {
+                Row row = sheet.getRow(r);
+                if (row != null) {
+                    for (int c = 0; c < row.getLastCellNum(); c++) {
+                        Cell cell = row.getCell(c);
+                        if (cell != null) {
+                            CellStyle cellStyle = ss.createCellStyle();
+                            cellStyle.cloneStyleFrom(cell.getCellStyle());
+                            cellStyle.setBorderBottom(BorderStyle.THIN);
+                            cellStyle.setBorderTop(BorderStyle.THIN);
+                            cellStyle.setBorderRight(BorderStyle.THIN);
+                            cellStyle.setBorderLeft(BorderStyle.THIN);
+                            cell.setCellStyle(cellStyle);
+                            CellRangeAddress mergedRegion = getMergedRegion(sheet, r, c);
+                            if (mergedRegion != null) {
+                                setMergedRegionBorders(sheet, mergedRegion, cellStyle);
+                            }
+                        }
+                    }
+                }
+                sheet.setPrintGridlines(false);
+                sheet.setFitToPage(true);
+            }
+
+            outReport = new ByteArrayOutputStream();
+            ss.write(outReport);
+
+            PdfSaveOptions pdfSaveOptions = new PdfSaveOptions();
+            pdfSaveOptions.setOnePagePerSheet(true);
+
+            com.aspose.cells.Workbook wb = new com.aspose.cells.Workbook(new ByteArrayInputStream(outReport.toByteArray()));
+            PageSetup pageSetup = wb.getWorksheets().get(0).getPageSetup();
+            pageSetup.setPaperSize(PaperSizeType.PAPER_A_4);
+
+            ByteArrayOutputStream pdfByteArrayOutputStream = new ByteArrayOutputStream();
+            wb.save(pdfByteArrayOutputStream, pdfSaveOptions);
+
+            ByteArrayResource resource = new ByteArrayResource(pdfByteArrayOutputStream.toByteArray());
+
+            return new MockMultipartFile("file", SnowFlakeUtil.getId() + ".pdf", "application/pdf", resource.getInputStream());
+
+        } catch (Exception e) {
+            e.printStackTrace();
+            return null;
+        } finally {
+            if (outReport != null) {
+                try {
+                    outReport.close();
+                } catch (Exception e) {
+                    e.printStackTrace();
+                }
+            }
+            if (byteArrayInputStream != null) {
+                try {
+                    byteArrayInputStream.close();
+                } catch (Exception e) {
+                    e.printStackTrace();
+                }
+            }
+        }
+    }
+
+    private void setMergedRegionBorders(Sheet sheet, CellRangeAddress region, CellStyle style) {
+        for (int row = region.getFirstRow(); row <= region.getLastRow(); row++) {
+            Row currentRow = sheet.getRow(row);
+            if (currentRow == null) {
+                currentRow = sheet.createRow(row);
+            }
+            for (int col = region.getFirstColumn(); col <= region.getLastColumn(); col++) {
+                Cell currentCell = currentRow.getCell(col);
+                if (currentCell == null) {
+                    currentCell = currentRow.createCell(col);
+                }
+                currentCell.setCellStyle(style);
+            }
+        }
+    }
+
+    private CellRangeAddress getMergedRegion(Sheet sheet, int row, int col) {
+        for (int i = 0; i < sheet.getNumMergedRegions(); i++) {
+            CellRangeAddress mergedRegion = sheet.getMergedRegion(i);
+            if (mergedRegion.isInRange(row, col)) {
+                return mergedRegion;
+            }
+        }
+        return null;
+    }
+}

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

@@ -1409,13 +1409,15 @@ public class TaskServiceImpl extends BaseServiceImpl<TaskMapper, Task> implement
             //获取每条任务对应的节点信息
             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() + ""));
+            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 {
                 for (Task task : taskList) {
                     R result = new R();
                     if (type == 1) {
                         //重新保存
                         long startTime_1 = System.currentTimeMillis();
-                        result = this.saveNodePdf(classify, queryMap.get(task.getFormDataId()), contractId, projectId, header);
+                        result = this.saveNodePdf(typeMap.get(task.getFormDataId()), queryMap.get(task.getFormDataId()), contractId, projectId, header);
                         long endTime_1 = System.currentTimeMillis();
                         long executionTime_1 = endTime_1 - startTime_1;
                         log.info("saveNodePdf执行时间:" + executionTime_1 + " 毫秒");

+ 3 - 4
blade-service/blade-e-visa/src/main/java/org/springblade/evisa/controller/EVisaController.java

@@ -109,7 +109,7 @@ public class EVisaController {
                 String up_task = "update u_task_batch set is_deleted=5 where id="+taskApprovalVO.getId();
                 jdbcTemplate.execute(up_task);
 
-                String up_task_par = "update u_task_parallel set status=99,e_visa_content='pdf关键字与数据库中id不匹配' ,update_time=SYSDATE() where parallel_process_instance_id='"+taskApprovalVO.getParallelProcessInstanceId()+"'";
+                String up_task_par = "update u_task_parallel set e_visa_status=99,e_visa_content='pdf关键字与数据库中id不匹配' ,update_time=SYSDATE() where parallel_process_instance_id='"+taskApprovalVO.getParallelProcessInstanceId()+"'";
                 jdbcTemplate.execute(up_task_par);
 
             } else if ("success".equals(eVisaStatus) || eVisaStatus.contains("success")) { //成功操作
@@ -168,11 +168,10 @@ public class EVisaController {
         }else{ //废除
 
             // 修改 主 任务 u_task 表 状态改为3
-
             String up_task_par = "update u_task_parallel set status=3 where parallel_process_instance_id="+taskApprovalVO.getParallelProcessInstanceId();
-
             String up_task = "update u_task set status=3 where id="+taskApprovalVO.getTaskId();
-
+            jdbcTemplate.execute(up_task_par);
+            jdbcTemplate.execute(up_task);
         }
     }
 }

+ 6 - 18
blade-service/blade-manager/src/main/java/com/jfireel/expression/Expression.java

@@ -13,8 +13,8 @@ public class Expression {
     private CalculateNode parseNode;
     private Deque<CalculateNode> nodes = new LinkedList<CalculateNode>();
     private String el;
-    private int function;
-    private Invoker head;
+    private final int function;
+    private final Invoker head;
     private static final Invoker DEFAULT_HEAD;
 
     static {
@@ -32,26 +32,14 @@ public class Expression {
                 new ConstantStringParser(), //
                 new NumberParser(), //
                 new IdentifierParser(), //
-                new OperatorParser()//
-        };
-        Invoker pred = new Invoker() {
-
-            @Override
-            public int parse(String el, int offset, Deque<CalculateNode> nodes, int function) {
-                return offset;
-            }
+                new OperatorParser(),//
+                new ChineseParser()
         };
+        Invoker pred = (el, offset, nodes, function) -> offset;
         for (int i = parsers.length - 1; i > -1; i--) {
             final NodeParser parser = parsers[i];
             final Invoker next = pred;
-            Invoker invoker = new Invoker() {
-
-                @Override
-                public int parse(String el, int offset, Deque<CalculateNode> nodes, int function) {
-                    return parser.parse(el, offset, nodes, function, next);
-                }
-            };
-            pred = invoker;
+            pred = (el1, offset, nodes1, function1) -> parser.parse(el1, offset, nodes1, function1, next);
         }
         DEFAULT_HEAD = pred;
     }

+ 35 - 0
blade-service/blade-manager/src/main/java/com/jfireel/expression/parse/impl/ChineseParser.java

@@ -0,0 +1,35 @@
+package com.jfireel.expression.parse.impl;
+
+import com.jfireel.expression.node.CalculateNode;
+import com.jfireel.expression.node.impl.StringNode;
+import com.jfireel.expression.parse.Invoker;
+import com.jfireel.expression.util.CharType;
+
+import java.util.Deque;
+
+/**
+ * @author yangyj
+ * @Date 2024/1/26 16:41
+ * @description 专门用来处理包含中文的变量
+ */
+public class ChineseParser extends NodeParser{
+    @Override
+    public int parse(String el, int offset, Deque<CalculateNode> nodes, int function, Invoker next) {
+        if (!CharType.isChineseChar(getChar(offset, el))) {
+            return next.parse(el, offset, nodes, function);
+        }
+        return parseChinese(el, offset, nodes);
+    }
+
+    private int parseChinese(String el, int offset, Deque<CalculateNode> nodes) {
+        int length = 0;
+        while (!CharType.isEnglishBracketOrComma(getChar(length + offset, el)) ) {
+            length++;
+        }
+        String literals = el.substring(offset, offset + length);
+        offset += length;
+        nodes.push(new StringNode(literals));
+        return offset;
+    }
+
+}

+ 1 - 1
blade-service/blade-manager/src/main/java/com/jfireel/expression/parse/impl/IdentifierParser.java

@@ -13,7 +13,7 @@ public class IdentifierParser extends NodeParser {
 
     @Override
     public int parse(String el, int offset, Deque<CalculateNode> nodes, int function, Invoker next) {
-        if (CharType.isAlphabet(getChar(offset, el)) == false) {
+        if (!CharType.isAlphabet(getChar(offset, el))) {
             return next.parse(el, offset, nodes, function);
         }
         return parseIdentifier(el, offset, nodes);

+ 3 - 7
blade-service/blade-manager/src/main/java/com/jfireel/expression/parse/impl/NumberParser.java

@@ -27,22 +27,18 @@ public class NumberParser extends NodeParser {
             if (nodes.peek() != null && nodes.peek().type() == Symbol.LEFT_PAREN) {
                 // 这种情况下,-代表是一个负数
                 return true;
-            } else if (nodes.peek() != null && nodes.peek().type() instanceof Operator == false) {
+            } else if (nodes.peek() != null && !(nodes.peek().type() instanceof Operator)) {
                 // 这种情况下,-是一个操作符
                 return false;
             } else {
                 throw new IllegalArgumentException("无法识别的-符号,不是负数也不是操作符,问题区间:" + el.substring(0, offset));
             }
-        } else if (CharType.isDigital(getChar(offset, el))) {
-            return true;
-        } else {
-            return false;
-        }
+        } else return CharType.isDigital(getChar(offset, el));
     }
 
     @Override
     public int parse(String el, int offset, Deque<CalculateNode> nodes, int function, Invoker next) {
-        if (match(el, offset, nodes, function) == false) {
+        if (!match(el, offset, nodes, function)) {
             return next.parse(el, offset, nodes, function);
         }
         int index = offset;

+ 3 - 3
blade-service/blade-manager/src/main/java/com/jfireel/expression/token/DefaultKeyWord.java

@@ -6,15 +6,15 @@ import java.util.Map;
 public enum DefaultKeyWord implements KeyWord {
     TRUE, FALSE, NULL;
 
-    private static Map<String, DefaultKeyWord> defaultKeeyWords = new HashMap<String, DefaultKeyWord>(128);
+    private static final Map<String, DefaultKeyWord> defaultKeyWords = new HashMap<>(128);
 
     static {
         for (DefaultKeyWord each : DefaultKeyWord.values()) {
-            defaultKeeyWords.put(each.name().toLowerCase(), each);
+            defaultKeyWords.put(each.name().toLowerCase(), each);
         }
     }
 
     public static DefaultKeyWord getDefaultKeyWord(String literals) {
-        return defaultKeeyWords.get(literals.toLowerCase());
+        return defaultKeyWords.get(literals.toLowerCase());
     }
 }

+ 19 - 0
blade-service/blade-manager/src/main/java/com/jfireel/expression/util/CharType.java

@@ -36,6 +36,25 @@ public class CharType {
         return ch >= 'A' && ch <= 'Z' || ch >= 'a' && ch <= 'z';
     }
 
+    /**
+     * 判断是否为中文
+     *
+     * @param ch 待判断的字符
+     * @return 是否为中文
+     */
+    public static boolean isChineseChar(final char ch) {
+        return ch >= 0x4E00 && ch <= 0x9FFF || ch >= 0x3400 && ch <= 0x4DBF;
+    }
+    /**
+     * 判断是右括号和顿号
+     *
+     * @param ch 待判断的字符
+     * @return 是否为右括号和顿号
+     */
+    public static boolean isEnglishBracketOrComma(final char ch) {
+        return ch == ')' || ch == ',';
+    }
+
     /**
      * 判断是否为数字.
      *

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

@@ -2783,7 +2783,7 @@ public class CustomFunction {
     }
 */
      /*字符模版*/
-      public static Object strTemplate(String template,List<Object>data){
+      public static Object strTemplate(List<Object>data,String template){
           if(BaseUtils.isNotEmpty(template)) {
               return data.stream().map(s -> template.replaceAll("\\{\\s*}", BaseUtils.handleNull(s))).collect(Collectors.toList());
           }

+ 21 - 1
blade-service/blade-manager/src/main/java/com/mixsmart/utils/FormulaUtils.java

@@ -361,6 +361,7 @@ public class FormulaUtils {
         return vos;
     }
 
+    /*根据数据模型实例生成带数据的元素,用于修改*/
     public static <T> LinkedHashMap<String,FormData> toFormDataMap(T bean){
         LinkedHashMap<String,FormData> result = new LinkedHashMap<>();
         if(bean!=null){
@@ -387,7 +388,26 @@ public class FormulaUtils {
         }
         return result;
     }
-
+    /*根据数据模型建立空元素,待写入数据*/
+    public static <T> LinkedHashMap<String,FormData> toFormDataMap(Class<T> clazz){
+        LinkedHashMap<String,FormData> result = new LinkedHashMap<>();
+            try {
+                String TBN = (String)  clazz.getField(TBN_FN).get(null);
+                for (Field field : clazz.getDeclaredFields()) {
+                    JSONField jf = field.getAnnotation(JSONField.class);
+                    if (jf != null) {
+                        FormData fd = new FormData();
+                        fd.setCode(TBN+ StringPool.COLON +jf.name());
+                        fd.setEName(jf.label());
+                        fd.getCoordsList().add(new Coords("0","0"));
+                        result.put(fd.getCode(),fd);
+                    }
+                }
+            }catch (Exception e){
+                e.printStackTrace();
+            }
+        return result;
+    }
     /*把结果数据回写到元素*/
     public static<T>void  put2FormData( LinkedHashMap<String,FormData> fdm,Map<String,Function<List<T>,List<Object>>> functionMap,List<T> dataList){
         fdm.values().stream()

+ 12 - 2
blade-service/blade-manager/src/main/java/org/springblade/manager/controller/ExcelTabController.java

@@ -3212,6 +3212,13 @@ public class ExcelTabController extends BladeController {
         }
         JSONObject tableInfo1 = dataArray.getJSONObject(0);
         String nodeid = tableInfo1.getString("nodeId");
+        String nodePrimaryKeyId = dataInfo.getString("nodePrimaryKeyId");
+
+        // 合同段id
+        String contractId = tableInfo1.getString("contractId");
+        String pkeyId = tableInfo1.getString("pkeyId");
+        String recordTime = tableInfo1.getString("recordTime");
+
         List<TableInfo> tableInfoList = this.excelTabService.getTableInfoList(dataArray);
         try {
             this.excelTabService.formulaFillData(tableInfoList, Long.parseLong(nodeid), ExecuteType.FAI);
@@ -3220,14 +3227,17 @@ public class ExcelTabController extends BladeController {
         }
 
         // 保存数据到数据库
+        String data= "";
         String isFirst = tableInfoList.get(0).getIsFirst();
         if (StringUtils.isNotEmpty(isFirst)) {
             //保存首件
-            return R.data(this.excelTabService.saveOrUpdateFirst(tableInfoList));
+            data=this.excelTabService.saveOrUpdateFirst(tableInfoList);
         } else {
             //保存日志
-            return R.data(this.excelTabService.saveOrUpdateTheLog(tableInfoList));
+            data = this.excelTabService.saveOrUpdateTheLog(tableInfoList);
         }
+        this.getTheLogPdInfo(pkeyId,nodePrimaryKeyId,recordTime,contractId);
+        return R.data(data);
     }
 
 

+ 196 - 5
blade-service/blade-manager/src/main/java/org/springblade/manager/controller/TrialSummaryClassificationConfigurationController.java

@@ -1,22 +1,49 @@
 package org.springblade.manager.controller;
 
 import com.baomidou.mybatisplus.core.metadata.IPage;
+import com.baomidou.mybatisplus.core.toolkit.Wrappers;
 import com.github.xiaoymin.knife4j.annotations.ApiOperationSupport;
 import io.swagger.annotations.Api;
 import io.swagger.annotations.ApiOperation;
 import lombok.AllArgsConstructor;
+import org.apache.commons.lang.StringUtils;
+import org.jsoup.Jsoup;
+import org.jsoup.nodes.Document;
+import org.jsoup.nodes.Element;
+import org.springblade.common.constant.CommonConstant;
+import org.springblade.common.utils.CommonUtil;
+import org.springblade.common.utils.SnowFlakeUtil;
 import org.springblade.core.boot.ctrl.BladeController;
 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.BeanUtil;
+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.TrialSummaryClassificationConfigurationMatchDTO;
 import org.springblade.manager.dto.TrialSummaryClassificationConfigurationRelevancyDTO;
-import org.springblade.manager.entity.TrialSummaryClassificationConfiguration;
+import org.springblade.manager.dto.TrialSummaryReflectionSaveDTO;
+import org.springblade.manager.entity.*;
+import org.springblade.manager.mapper.ExcelTabMapper;
 import org.springblade.manager.service.ITrialSummaryClassificationConfigurationService;
+import org.springblade.manager.service.IWbsFormElementService;
+import org.springblade.manager.service.impl.WbsTreePrivateServiceImpl;
+import org.springblade.manager.vo.ExcelTabTreeVO;
+import org.springblade.manager.vo.SelectedTabVO;
 import org.springblade.manager.vo.TrialTreeVO;
+import org.springblade.system.cache.ParamCache;
+import org.springframework.jdbc.core.BeanPropertyRowMapper;
+import org.springframework.jdbc.core.JdbcTemplate;
 import org.springframework.web.bind.annotation.*;
 
 import javax.validation.Valid;
+import java.io.*;
+import java.util.ArrayList;
+import java.util.HashMap;
+import java.util.List;
+import java.util.Map;
+import java.util.stream.Collectors;
 
 
 @RestController
@@ -26,6 +53,10 @@ import javax.validation.Valid;
 public class TrialSummaryClassificationConfigurationController extends BladeController {
 
     private final ITrialSummaryClassificationConfigurationService iTrialSummaryClassificationConfigurationService;
+    private final WbsTreePrivateServiceImpl wbsTreePrivateServiceImpl;
+    private final ExcelTabMapper excelTabMapper;
+    private final JdbcTemplate jdbcTemplate;
+    private final IWbsFormElementService wbsFormElementService;
 
     @ApiOperationSupport(order = 1)
     @ApiOperation(value = "详情", notes = "传入id")
@@ -66,15 +97,175 @@ public class TrialSummaryClassificationConfigurationController extends BladeCont
     @ApiOperationSupport(order = 6)
     @ApiOperation(value = "关联清表", notes = "传入TrialSummaryClassificationConfigurationRelevancyDTO")
     @RequestMapping(value = "/relevancy", method = RequestMethod.POST)
-    public R<Object> relevancy(@RequestBody TrialSummaryClassificationConfigurationRelevancyDTO dto) {
+    public R<Object> relevancy(@RequestBody TrialSummaryClassificationConfigurationRelevancyDTO dto) throws IOException {
         return R.data(iTrialSummaryClassificationConfigurationService.relevancy(dto));
     }
 
     @ApiOperationSupport(order = 7)
-    @ApiOperation(value = "试验树全加载", notes = "传入项目id、classId=page接口数据id、type=1匹配划分 =2关联清表")
+    @ApiOperation(value = "试验树全加载", notes = "传入项目id、classId=page接口数据id")
     @RequestMapping(value = "/tree", method = RequestMethod.GET)
-    public R<TrialTreeVO> tree(@RequestParam String projectId, @RequestParam String classId, @RequestParam String type) {
-        return R.data(iTrialSummaryClassificationConfigurationService.tree(projectId, classId, type));
+    public R<TrialTreeVO> tree(@RequestParam String projectId, @RequestParam String classId) {
+        return R.data(iTrialSummaryClassificationConfigurationService.tree(projectId, classId));
+    }
+
+    @ApiOperationSupport(order = 8)
+    @ApiOperation(value = "关联清表-清表懒加载", notes = "清表列表调/api/blade-manager/exceltab/page接口;传入父级id、modeId、分类classId")
+    @RequestMapping(value = "/lazy", method = RequestMethod.GET)
+    public R<List<ExcelTabTreeVO>> lazy(@RequestParam String parentId, @RequestParam String modeId, @RequestParam String classId) {
+        List<ExcelTab> excelTabs = excelTabMapper.selectList(Wrappers.<ExcelTab>lambdaQuery().eq(ExcelTab::getParentId, parentId).like(ExcelTab::getAlias, modeId));
+        List<ExcelTabTreeVO> excelTabTreeVOS = BeanUtil.copyProperties(excelTabs, ExcelTabTreeVO.class);
+        TrialSummaryClassificationConfiguration classificationConfiguration = iTrialSummaryClassificationConfigurationService.getById(classId);
+        if (classificationConfiguration != null) {
+            for (ExcelTabTreeVO excelTabTreeVO : excelTabTreeVOS) {
+                if (excelTabTreeVO.getId().equals(classificationConfiguration.getExcelId())) {
+                    excelTabTreeVO.setRecordStatus(1);
+                }
+            }
+        }
+        return R.data(excelTabTreeVOS);
+    }
+
+    @ApiOperationSupport(order = 9)
+    @ApiOperation(value = "获取关联清表html", notes = "传入外层page接口分类id")
+    @RequestMapping(value = "/tab/html", method = RequestMethod.GET)
+    public R<String> html(@RequestParam String classId) throws Exception {
+        TrialSummaryClassificationConfiguration classificationConfiguration = iTrialSummaryClassificationConfigurationService.getById(classId);
+        if (classificationConfiguration != null && ObjectUtil.isNotEmpty(classificationConfiguration.getExcelId()) && ObjectUtil.isNotEmpty(classificationConfiguration.getHtmlUrl())) {
+            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, "");
+                fileInputStream = CommonUtil.getOSSInputStream(path);
+            }
+            String htmlString = IoUtil.readToString(fileInputStream);
+            Document doc = Jsoup.parse(htmlString);
+            Element table = doc.select("table").first();
+            doc.select("Col").remove();
+            if (fileInputStream != null) {
+                fileInputStream.close();
+            }
+            return R.data(table.toString());
+        }
+        return R.fail("未关联清表信息");
+    }
+
+    @ApiOperationSupport(order = 10)
+    @ApiOperation(value = "选择表单列表", notes = "传入外层page接口分类id")
+    @RequestMapping(value = "/tab/list", method = RequestMethod.GET)
+    public R<List<SelectedTabVO>> tabList(@RequestParam String classId) {
+        TrialSummaryClassificationConfiguration trialSummaryClassificationConfiguration = iTrialSummaryClassificationConfigurationService.getById(classId);
+        if (trialSummaryClassificationConfiguration != null && ObjectUtil.isNotEmpty(trialSummaryClassificationConfiguration.getTrialTreeIds())) {
+            List<WbsTreePrivate> query = jdbcTemplate.query("SELECT id,project_id,wbs_id,wbs_type FROM m_wbs_tree_private WHERE p_key_id in (" + trialSummaryClassificationConfiguration.getTrialTreeIds() + ")", new BeanPropertyRowMapper<>(WbsTreePrivate.class));
+            List<Long> ids = query.stream().map(WbsTreePrivate::getId).collect(Collectors.toList());
+            String projectId = query.stream().map(WbsTreePrivate::getProjectId).findAny().orElse(null);
+            String wbsId = query.stream().map(WbsTreePrivate::getWbsId).findAny().orElse(null);
+            String wbsType = query.stream().map(WbsTreePrivate::getWbsType).findAny().orElse(null);
+            if (ids.size() > 0 && projectId != null && wbsId != null && wbsType != null) {
+                List<WbsTreePrivate> wbsTreePrivates = wbsTreePrivateServiceImpl.getBaseMapper().selectList(Wrappers.<WbsTreePrivate>lambdaQuery()
+                        .in(WbsTreePrivate::getId, ids).eq(WbsTreePrivate::getProjectId, projectId)
+                        .eq(WbsTreePrivate::getWbsType, wbsType)
+                        .eq(WbsTreePrivate::getWbsId, wbsId));
+                List<SelectedTabVO> list = new ArrayList<>();
+                for (WbsTreePrivate wbsTreePrivate : wbsTreePrivates) {
+                    SelectedTabVO vo = new SelectedTabVO();
+                    vo.setPKeyId(wbsTreePrivate.getPKeyId());
+                    vo.setId(wbsTreePrivate.getId());
+                    vo.setTabName(ObjectUtil.isNotEmpty(wbsTreePrivate.getFullName()) ? wbsTreePrivate.getFullName() : wbsTreePrivate.getNodeName());
+                    list.add(vo);
+                }
+                return R.data(list);
+            }
+        }
+        return null;
+    }
+
+    @ApiOperationSupport(order = 11)
+    @ApiOperation(value = "选择元素列表", notes = "传入/tab/list接口的id")
+    @RequestMapping(value = "/element/list", method = RequestMethod.GET)
+    public R<List<WbsFormElement>> elementList(@RequestParam String id) {
+        return R.data(wbsFormElementService.selectElementListByFid(id));
+    }
+
+    @ApiOperationSupport(order = 12)
+    @ApiOperation(value = "获取输入框映射数据来源", notes = "传入classId、html输入框的keyname值")
+    @RequestMapping(value = "/input/detail", method = RequestMethod.GET)
+    public R<Object> inputDetail(@RequestParam String classId, @RequestParam String keyName) {
+        TrialSummaryClassificationConfiguration classificationConfiguration = iTrialSummaryClassificationConfigurationService.getById(classId);
+        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) {
+                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);
+                }
+            }
+        }
+        return R.data(null);
+    }
+
+    @ApiOperationSupport(order = 13)
+    @ApiOperation(value = "映射数据保存", notes = "传入TrialSummaryReflectionSaveDTO")
+    @RequestMapping(value = "/reflection/save", method = RequestMethod.POST)
+    public R<Object> reflectionSave(@RequestBody TrialSummaryReflectionSaveDTO dto) {
+        if (ObjectUtil.isNotEmpty(dto.getClassId())) {
+            if (ObjectUtil.isEmpty(dto.getReflectionBeanList().size()) || dto.getReflectionBeanList().size() == 0) {
+                return R.success("操作成功");
+            } else {
+                TrialSummaryClassificationConfiguration classificationConfiguration = iTrialSummaryClassificationConfigurationService.getById(dto.getClassId());
+                if (classificationConfiguration != null && ObjectUtil.isNotEmpty(classificationConfiguration.getExcelId())) {
+                    List<TrialSummaryReflectionSaveDTO.ReflectionBean> reflectionBeanList = dto.getReflectionBeanList();
+                    List<String> keyNameList = reflectionBeanList.stream()
+                            .map(bean -> "'" + bean.getHtmlKeyName() + "'")
+                            .collect(Collectors.toList());
+                    String sqlDel = "DELETE FROM m_trial_summary_excel_tab_reflection WHERE excel_id = ? AND html_key_name IN (" +
+                            StringUtils.repeat("?", ",", keyNameList.size()) + ")";
+                    List<Object> paramsDel = new ArrayList<>();
+                    paramsDel.add(classificationConfiguration.getExcelId());
+                    paramsDel.addAll(keyNameList);
+                    jdbcTemplate.update(sqlDel, paramsDel.toArray());
+
+                    String sqlInsert = "INSERT INTO m_trial_summary_excel_tab_reflection(id,excel_id,trial_tab_id,element_id,html_key_name) VALUES (?,?,?,?,?)";
+                    List<Object[]> batchArgs = new ArrayList<>();
+                    for (TrialSummaryReflectionSaveDTO.ReflectionBean reflectionBean : reflectionBeanList) {
+                        Object[] paramsInsert = {
+                                SnowFlakeUtil.getId(),
+                                classificationConfiguration.getExcelId(),
+                                reflectionBean.getTrialTabId(),
+                                reflectionBean.getElementId(),
+                                reflectionBean.getHtmlKeyName(),
+                        };
+                        batchArgs.add(paramsInsert);
+                    }
+                    jdbcTemplate.batchUpdate(sqlInsert, batchArgs);
+
+                    return R.success("操作成功");
+                }
+            }
+        }
+        return R.fail("操作失败");
+    }
+
+    @ApiOperationSupport(order = 14)
+    @ApiOperation(value = "映射数据删除", notes = "传入/input/detail接口返回的id")
+    @RequestMapping(value = "/reflection/remove", method = RequestMethod.POST)
+    public R<Object> reflectionRemove(@RequestParam String id) {
+        if (ObjectUtil.isNotEmpty(id)) {
+            String sqlDel = "DELETE FROM m_trial_summary_excel_tab_reflection WHERE id = ?";
+            jdbcTemplate.update(sqlDel, id);
+            return R.success("操作成功");
+        }
+        return R.fail("操作失败");
     }
 
 }

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

@@ -14,11 +14,13 @@ import org.springblade.manager.service.IExcelTabService;
 import org.springblade.manager.service.IFormulaOptionService;
 import org.springblade.manager.service.IFormulaService;
 import org.springblade.manager.service.IWbsTreeContractService;
+import org.springblade.manager.vo.ReportResult;
 import org.springframework.jdbc.core.JdbcTemplate;
 import org.springframework.web.bind.annotation.RestController;
 
 import javax.validation.constraints.NotNull;
 import java.io.FileNotFoundException;
+import java.util.List;
 import java.util.Map;
 
 /**
@@ -64,5 +66,10 @@ public class FormulaClientImpl implements FormulaClient {
        return this.formulaOptionService.getById(pkeyId);
     }
 
+    @Override
+    public List<ReportResult> formulaExecute3(Long contractId, Long periodId, Integer type) {
+       return service.execute3(contractId,periodId,type);
+    }
+
 
 }

+ 0 - 17
blade-service/blade-manager/src/main/java/org/springblade/manager/formula/impl/CompositeDataAccessGroup.java

@@ -1,17 +0,0 @@
-package org.springblade.manager.formula.impl;
-
-import org.springblade.manager.dto.ElementData;
-
-import java.util.Hashtable;
-import java.util.List;
-import java.util.Map;
-
-/**
- * @author yangyj
- * @Date 2022/9/9 17:37
- * @description TODO
- */
-public class CompositeDataAccessGroup {
-    List<CompositeDataAccess> list;
-    Map<String, ElementData> dataMap;
-}

+ 0 - 6
blade-service/blade-manager/src/main/java/org/springblade/manager/formula/impl/ExecutorCalc.java

@@ -1,25 +1,19 @@
 package org.springblade.manager.formula.impl;
 
 import com.jfireel.expression.Expression;
-import com.mixsmart.utils.CustomFunction;
 import com.mixsmart.utils.FormulaUtils;
 import com.mixsmart.utils.StringUtils;
 import lombok.Data;
 import lombok.EqualsAndHashCode;
 import org.springblade.core.tool.utils.CollectionUtil;
 import org.springblade.core.tool.utils.Func;
-import org.springblade.core.tool.utils.RegexUtil;
-import org.springblade.manager.dto.ElementData;
 import org.springblade.manager.dto.FormData;
 import org.springblade.manager.dto.LocalVariable;
 import org.springblade.manager.entity.Formula;
-import org.springblade.manager.enums.ExecuteType;
-import org.springblade.manager.formula.FormulaExecutor;
 import org.springblade.manager.formula.FormulaLog;
 import org.springblade.manager.formula.NodeTable;
 
 import java.util.*;
-import java.util.stream.Collectors;
 
 /**
  * @author yangyj

+ 0 - 10
blade-service/blade-manager/src/main/java/org/springblade/manager/formula/impl/ExecutorFormat.java

@@ -1,22 +1,12 @@
 package org.springblade.manager.formula.impl;
 
-import com.baomidou.mybatisplus.core.toolkit.Wrappers;
 import com.mixsmart.utils.FormulaUtils;
 import com.mixsmart.utils.StringUtils;
 import lombok.Data;
 import lombok.EqualsAndHashCode;
-import org.springblade.common.utils.SnowFlakeUtil;
-import org.springblade.core.tool.utils.BeanUtil;
-import org.springblade.manager.bean.TableInfo;
 import org.springblade.manager.dto.ElementData;
 import org.springblade.manager.dto.FormData;
 import org.springblade.manager.entity.Formula;
-import org.springblade.manager.entity.WbsTreeContract;
-import org.springblade.manager.formula.FormulaExecutor;
-import org.springblade.manager.formula.NodeTable;
-
-import java.util.*;
-import java.util.stream.Collectors;
 
 /**
  * @author yangyj

+ 10 - 11
blade-service/blade-manager/src/main/java/org/springblade/manager/formula/impl/ExecutorInit.java

@@ -3,17 +3,12 @@ package org.springblade.manager.formula.impl;
 import com.mixsmart.utils.FormulaUtils;
 import lombok.Data;
 import lombok.EqualsAndHashCode;
-import org.springblade.core.tool.utils.Func;
 import org.springblade.manager.dto.TreeNode;
-import org.springblade.manager.formula.FormulaExecutor;
 import org.springblade.manager.vo.*;
-import org.springframework.scheduling.annotation.Async;
 
 import java.util.*;
 import java.util.concurrent.CompletableFuture;
 import java.util.function.Function;
-import java.util.logging.Handler;
-import java.util.stream.Collectors;
 
 /**
  * @author yangyj
@@ -29,6 +24,8 @@ public class ExecutorInit extends FormulaExecutor {
     private  Function<Long, BaseInfo> baseInfoFc;
     private  Function<Long, MeterPeriodInfo>  meterPeriodFc;
     private Function<Long, List<MeterTree>> meterTreeFc;
+    private Function<Long, MeterPeriodInfo> interimMeterPeriodFc;
+
 
 
     public void handle() {
@@ -39,14 +36,16 @@ public class ExecutorInit extends FormulaExecutor {
         tec.formDataMap.putAll(FormulaUtils.toFormDataMap(baseInfo));
         if(MeterType.MATERIAL.equals(tec.getMeterType())||MeterType.START.equals(tec.getMeterType())){
             /*加载计量期信息*/
-            MeterPeriodInfo meterPeriod=meterPeriodFc.apply(tec.getReportId());
-            tec.setPeriodId(meterPeriod.getId());
-            tec.formDataMap.putAll(FormulaUtils.toFormDataMap(meterPeriod));
-            tec.getConstantMap().put(MeterPeriodInfo.TBN,meterPeriod);
+            tec.periodInfo=meterPeriodFc.apply(tec.getReportId());
+            tec.setPeriodId(tec.periodInfo.getId());
         }else if(MeterType.INTERIM.equals(tec.getMeterType())){
-               /*计量单元树*/
-                tec.setMeterTreeMap(getMeterTreeMapAsync(tec.getContractId()));
+            /*计量期*/
+            tec.periodInfo=interimMeterPeriodFc.apply(tec.getReportId());
+            /*计量单元树*/
+            tec.setMeterTreeMap(getMeterTreeMapAsync(tec.getContractId()));
         }
+        tec.formDataMap.putAll(FormulaUtils.toFormDataMap(tec.periodInfo));
+
 
     }
 

+ 92 - 84
blade-service/blade-manager/src/main/java/org/springblade/manager/formula/impl/ExecutorSpecial.java → blade-service/blade-manager/src/main/java/org/springblade/manager/formula/impl/ExecutorMeter.java

@@ -10,7 +10,6 @@ import org.springblade.core.tool.utils.StringPool;
 import org.springblade.manager.dto.ElementData;
 import org.springblade.manager.dto.FormData;
 import org.springblade.manager.dto.TreeNode;
-import org.springblade.manager.formula.FormulaExecutor;
 import org.springblade.manager.vo.*;
 import org.springframework.beans.BeanUtils;
 
@@ -27,29 +26,27 @@ import java.util.stream.IntStream;
 /**
  * @author yangyj
  * @Date 2023/12/19 17:40
- * @description TODO
+ * @description 计量相关报表计算
  */
 @EqualsAndHashCode(callSuper = true)
 @Data
-public class ExecutorSpecial extends FormulaExecutor {
+public class ExecutorMeter extends FormulaExecutor {
     private Function<Long, List<Material>> materialFormFc;
-    private Function<Long, MeterPeriodInfo> interimMeterPeriodFc;
     private Function<Long, List<Payment>> paymentListFc;
     private Function<Long, List<InventoryForm>> inventoryFormFc;
     private Function<Long, List<MeterApply>> meterApplyFc;
-    public ExecutorSpecial(TableElementConverter tec) {
-        super(tec);
-    }
-    /**章节*/
-    private List<InventoryForm> chapters = new ArrayList<>();
+    /*执行链*/
     private List<Special> specialList = new ArrayList<>();
+    /**支付章节*/
+    private List<InventoryForm> chapters = new ArrayList<>();
+    /**上期累计支付信息*/
     private List<Payment>  previous =new ArrayList<>();
+    /**本期支付信息*/
     private List<Payment>   current =new ArrayList<>();
-    /**计量期*/
-    private  MeterPeriodInfo periodInfo;
+
     private List<InterimPaymentCertificate> interimPaymentCertificates =new ArrayList<>();
     /*求百分比*/
-    BinaryOperator<String> ratioFc = (a,b)->{
+    private BinaryOperator<String> ratioFc = (a,b)->{
         /*合同金额*/
         BigDecimal aBd =new BigDecimal(a);
         /*变更金额*/
@@ -60,6 +57,7 @@ public class ExecutorSpecial extends FormulaExecutor {
         return  aBd.multiply(new BigDecimal(100)).divide(bBd, 2, RoundingMode.HALF_UP).toString();
     };
 
+   /**根据清单编号获取支付项目章节编号*/
     public String getPrefix(String fn){
         for(InventoryForm itf:chapters){
             String prefix=itf.getChapter();
@@ -74,15 +72,10 @@ public class ExecutorSpecial extends FormulaExecutor {
         return fn;
     }
 
-    public Function<String,String> preFixFc= this::getPrefix;
+    Function<String,String> preFixFc= this::getPrefix;
 
-    public <T> LinkedHashMap<String,FormData>   builderFormDatas(T bean){
-        LinkedHashMap<String,FormData> fdm = FormulaUtils.toFormDataMap(bean);
-        Map<String,Function<List<T>,List<Object>>> functionMap =FormulaUtils.fieldDataFcMap(bean.getClass());
-        tec.getFormDataMap().putAll(fdm);
-        return fdm;
-    }
 
+    /*获取动态行最大行数,codeFind为相关元素码集合 */
     public Integer getLineSize(List<String> codeFind){
         int line=10;
         Optional<FormData> formDataOp=  tec.getFormDataList().stream().filter(e-> BaseUtils.inChain(codeFind,e.getCode())).findAny();
@@ -100,9 +93,16 @@ public class ExecutorSpecial extends FormulaExecutor {
         }else if(MeterType.INTERIM.equals(tec.getMeterType())){
             this.specialList.add(new InterimPayCert());
             this.specialList.add(new InterimSum());
+            this.specialList.add(new SubIPaySum());
+            this.specialList.add(new SubIMeterPay());
+            this.specialList.add(new IMeterPaySummary());
+            this.specialList.add(new IMeter());
         }
         this.specialList.stream().filter(Special::ready).forEach(Special::parse);
     }
+
+
+
     @Data
     public  class MaterialCalc implements Special{
         private FormData index;
@@ -244,8 +244,9 @@ public class ExecutorSpecial extends FormulaExecutor {
         }
     }
 
+    @EqualsAndHashCode(callSuper = true)
     @Data
-    public  class InterimPayCert implements Special{
+    public  class InterimPayCert extends   BaseSpecial<InterimPaymentCertificate> implements Special{
 
         @Override
         public boolean ready() {
@@ -276,16 +277,11 @@ public class ExecutorSpecial extends FormulaExecutor {
 
         @Override
         public void parse() {
-            LinkedHashMap<String,FormData> fdm = FormulaUtils.toFormDataMap(new InterimPaymentCertificate());
-            tec.getFormDataMap().putAll(fdm);
-            Map<String,Function<List<InterimPaymentCertificate>,List<Object>>> functionMap =FormulaUtils.fieldDataFcMap(InterimPaymentCertificate.class);
-
-            List<InterimPaymentCertificate> dataList = new ArrayList<>();
+            builderFormDatas(InterimPaymentCertificate.class);
             /*数据获取start*/
               /*支付数据*/
              List<Payment> paymentList=paymentListFc.apply(tec.getContractId());
-             /*计量期*/
-              periodInfo=interimMeterPeriodFc.apply(tec.getPeriodId());
+
              /*合同计量清单*/
              List<InventoryForm> inventoryForms = inventoryFormFc.apply(tec.getContractId());
              InventoryForm root = null;
@@ -304,9 +300,9 @@ public class ExecutorSpecial extends FormulaExecutor {
 
              if(Func.isNotEmpty(paymentList)){
                  /*之前的计量期数据*/
-                 previous = paymentList.stream().filter(e->e.getSort()<periodInfo.getSort()).collect(Collectors.toList());
+                 previous = paymentList.stream().filter(e->e.getSort()<tec.periodInfo.getSort()).collect(Collectors.toList());
                  /*当前计量期数据*/
-                 current = paymentList.stream().filter(e-> e.getSort().equals(periodInfo.getSort())).collect(Collectors.toList());
+                 current = paymentList.stream().filter(e-> e.getSort().equals(tec.periodInfo.getSort())).collect(Collectors.toList());
                  /*往期每章节的实际花费*/
                  Map<String,BigDecimal> previousMoney= this.moneySum.apply(previous);
                  /*当前计量期每章节的实际花费*/
@@ -314,6 +310,7 @@ public class ExecutorSpecial extends FormulaExecutor {
                 /*合同金额*/
                  Map<String,BigDecimal[]> contractMoney = this.contractMoneySum.apply(inventoryForms);
                  for(Map.Entry<String,BigDecimal[]> cm:contractMoney.entrySet()){
+                       if(Func.isEmpty(cm.getKey()))continue;
                       InterimPaymentCertificate ipc = new InterimPaymentCertificate();
                       BigDecimal[]  bmMoney =cm.getValue();
                       ipc.setContractAmount(bmMoney[0].toString());
@@ -329,14 +326,14 @@ public class ExecutorSpecial extends FormulaExecutor {
             /*本期实际支付合计计算*/
             functionMap.put(InterimPaymentCertificate.TBN+ StringPool.COLON+"key_9",(List<InterimPaymentCertificate> list)-> Collections.singletonList(list.stream().map(InterimPaymentCertificate::getCurrentPeriodPay).mapToDouble(Double::parseDouble).sum()));
             /*内容输出*/
-            FormulaUtils.put2FormData(fdm,functionMap,dataList);
-
+            putOut();
         }
 
 
     }
+    @EqualsAndHashCode(callSuper = true)
     @Data
-    public  class InterimSum implements Special{
+    public  class InterimSum extends   BaseSpecial<InterimPaymentSummary> implements Special{
         @Override
         public boolean ready() {
             return interimPaymentCertificates.size()>0;
@@ -348,10 +345,7 @@ public class ExecutorSpecial extends FormulaExecutor {
 
         @Override
         public void parse() {
-            LinkedHashMap<String,FormData> fdm = FormulaUtils.toFormDataMap(new InterimPaymentSummary());
-            Map<String,Function<List<InterimPaymentSummary>,List<Object>>> functionMap =FormulaUtils.fieldDataFcMap(InterimPaymentSummary.class);
-            tec.getFormDataMap().putAll(fdm);
-            List<InterimPaymentSummary> dataList=new ArrayList<>();
+            builderFormDatas(InterimPaymentSummary.class);
             for(InterimPaymentCertificate ipc:interimPaymentCertificates){
                 InterimPaymentSummary ips = new InterimPaymentSummary();
                 BeanUtils.copyProperties(ipc,ips);
@@ -371,14 +365,14 @@ public class ExecutorSpecial extends FormulaExecutor {
                 summary.setPayRatioA(ratioFc.apply(summary.getCurrentPeriodEndPay(),summary.getRevisedAmount()));
                 dataList.add(summary);
                 /*内容输出*/
-                FormulaUtils.put2FormData(fdm,functionMap,dataList);
+                putOut();
             }
         }
     }
 
+    @EqualsAndHashCode(callSuper = true)
     @Data
-    public  class SubIPaySum implements Special{
-         private Integer capacity=10;
+    public  class SubIPaySum extends   BaseSpecial<SubprojectInterimPaymentSummary> implements Special{
 
         @Override
         public boolean ready() {
@@ -436,7 +430,6 @@ public class ExecutorSpecial extends FormulaExecutor {
             }
         }
 
-
         /*按清单编号求和*/
         public  Map<String,Summary> toSummary(List<Payment> payments) {
             return payments.stream()
@@ -449,17 +442,12 @@ public class ExecutorSpecial extends FormulaExecutor {
         }
 
 
-
         @Override
         public void parse() {
-            LinkedHashMap<String,FormData> fdm = FormulaUtils.toFormDataMap(new SubprojectInterimPaymentSummary());
-            /*获取实际输出行数*/
-            this.capacity=getLineSize(new ArrayList<>(fdm.keySet()));
-            Map<String,Function<List<SubprojectInterimPaymentSummary>,List<Object>>> functionMap =FormulaUtils.fieldDataFcMap(SubprojectInterimPaymentSummary.class);
-            tec.getFormDataMap().putAll(fdm);
+            builderFormDatas(SubprojectInterimPaymentSummary.class);
             Map<String,Summary> currentSummary = toSummary(current);
             Map<String,Summary> preSummary = toSummary(previous);
-            List<SubprojectInterimPaymentSummary> dataList = new ArrayList<>();
+            List<SubprojectInterimPaymentSummary> totalList = new ArrayList<>();
             for(Map.Entry<String,Summary> form:currentSummary.entrySet()){
                 SubprojectInterimPaymentSummary sis = new SubprojectInterimPaymentSummary();
                 Summary pre =preSummary.get(form.getKey());
@@ -478,10 +466,9 @@ public class ExecutorSpecial extends FormulaExecutor {
                     sis.setCurrentPeriodEndPay(summary.getCurrentPeriodEndPay().toString());
                     sis.setPayRatio(ratioFc.apply(sis.getCurrentPeriodEndPay(),sis.getRevisedAmount()));
                 }
-                dataList.add(sis);
+                totalList.add(sis);
             }
-            List<SubprojectInterimPaymentSummary> outPutList= new ArrayList<>();
-            LinkedHashMap<String,List<SubprojectInterimPaymentSummary>> chapterGroup= dataList.stream().collect(Collectors.groupingBy(e->getPrefix(e.getFormNumber()),LinkedHashMap::new,Collectors.toList()));
+            LinkedHashMap<String,List<SubprojectInterimPaymentSummary>> chapterGroup= totalList.stream().collect(Collectors.groupingBy(e->getPrefix(e.getFormNumber()),LinkedHashMap::new,Collectors.toList()));
             AtomicInteger loop = new AtomicInteger(chapterGroup.size());
             chapterGroup.forEach((k,v)->{
                 int extra=loop.getAndDecrement()>0?1:2;
@@ -490,8 +477,6 @@ public class ExecutorSpecial extends FormulaExecutor {
                 /*每页小结是固定内容,需要每页保留一行*/
                 int dataAreaSize=capacity-1;
                 int pageSize=(int)Math.ceil(dataLength/(double)dataAreaSize);
-                /*总长度*/
-                int total = pageSize*capacity;
                 List<List<SubprojectInterimPaymentSummary>> ds = BaseUtils.splitList(v,capacity-1);
                 List<SubprojectInterimPaymentSummary> tmp = new ArrayList<>();
                 for(int n=0;n<pageSize;n++){
@@ -508,37 +493,35 @@ public class ExecutorSpecial extends FormulaExecutor {
                     if(placeholderSize>0){
                         tmp.addAll(Collections.nCopies(placeholderSize,new SubprojectInterimPaymentSummary()));
                     }
-                    SubprojectInterimPaymentSummary last = new SubprojectInterimPaymentSummary("本页小计");
-                    last.calculate(currentPageData);
-                    tmp.add(last);
+                    subtotal(new SubprojectInterimPaymentSummary("本页小计"),tmp,currentPageData);
                     if(m>1) {
                         /*本章小结*/
-                        SubprojectInterimPaymentSummary lastA = new SubprojectInterimPaymentSummary();
-                        lastA.calculate(v);
-                        tmp.add(lastA);
+                        subtotal(new SubprojectInterimPaymentSummary("章合计"),tmp,v);
                     }
                     if(m>2){
                         /*所有章合计*/
-                        SubprojectInterimPaymentSummary lastB = new SubprojectInterimPaymentSummary();
-                        lastB.calculate(dataList);
-                        tmp.add(lastB);
+                        subtotal(new SubprojectInterimPaymentSummary("所有章合计"),tmp,totalList);
                     }
-                    outPutList.addAll(tmp);
+                    dataList.addAll(tmp);
                     tmp.clear();
                 }
             });
             /*内容输出*/
-            FormulaUtils.put2FormData(fdm,functionMap,outPutList);
+             putOut();
         }
 
+        public void subtotal(SubprojectInterimPaymentSummary b,  List<SubprojectInterimPaymentSummary> result ,List<SubprojectInterimPaymentSummary> data){
+            b.calculate(data);
+            result.add(b);
+        }
 
 
-    }
 
+    }
 
+    @EqualsAndHashCode(callSuper = true)
     @Data
-    public class SubIMeterPay implements Special{
-        private Integer capacity=10;
+    public class SubIMeterPay extends  BaseSpecial<SubInterimMeterPaySummary> implements Special{
 
         @Override
         public boolean ready() {
@@ -561,14 +544,10 @@ public class ExecutorSpecial extends FormulaExecutor {
 
         @Override
         public void parse() {
+            builderFormDatas(SubInterimMeterPaySummary.class);
             /*按照计量单元和单元内的清单顺序排序显示计量清单,并且把计量单元的层级一并显示*/
             /*根据每一期的s_middle_meter_apply,s_inventory_form_apply 获取对应的计量清单,然后根据清单Id配合s_inventory_form_meter查找计量单元信息*/
             /*s_change_token_inventory每个清单关联的变更令,s_change_token_meter每个计量单元关联的变更令*/
-            LinkedHashMap<String,FormData> fdm = FormulaUtils.toFormDataMap(new SubInterimMeterPaySummary());
-            /*获取实际输出行数*/
-            this.capacity=getLineSize(new ArrayList<>(fdm.keySet()));
-            Map<String,Function<List<SubInterimMeterPaySummary>,List<Object>>> functionMap =FormulaUtils.fieldDataFcMap(SubInterimMeterPaySummary.class);
-            tec.getFormDataMap().putAll(fdm);
             try {
                 Map<Long, TreeNode<MeterTree>> treeNodeMap = tec.getMeterTreeMap().get();
                 Optional<TreeNode<MeterTree>> optionalTreeNode=  treeNodeMap.values().stream().filter(TreeNode::isTop).findAny();
@@ -591,7 +570,7 @@ public class ExecutorSpecial extends FormulaExecutor {
                     });
                     /*分组列表,每一组都是一个章节*/
                     List<List<SubInterimMeterPaySummary>> pageData =traversal(top);
-                    List<SubInterimMeterPaySummary> dataList=  pageData.stream().flatMap(list->{
+                    dataList=  pageData.stream().flatMap(list->{
                         List<SubInterimMeterPaySummary> tmp =new ArrayList<>(list);
                         int size = (int)Math.ceil(tmp.size()/(double)this.capacity);
                         /*每一章需要留一行做小计,其他要填充空白行*/
@@ -606,7 +585,7 @@ public class ExecutorSpecial extends FormulaExecutor {
                        return tmp.stream();
                     }).collect(Collectors.toList());
                     /*内容输出*/
-                    FormulaUtils.put2FormData(fdm,functionMap,dataList);
+                    putOut();
                 }
             }catch (Exception e){
                 e.printStackTrace();
@@ -671,9 +650,10 @@ public class ExecutorSpecial extends FormulaExecutor {
 
     }
 
+    @EqualsAndHashCode(callSuper = true)
     @Data
-    public class IMeterPaySummary implements Special{
-        private Integer capacity=20;
+    public class IMeterPaySummary extends BaseSpecial<InterimMeterPaySummary> implements Special{
+        /*private Integer capacity=20;*/
         @Override
         public boolean ready() {
             return current.size()>0;
@@ -681,12 +661,7 @@ public class ExecutorSpecial extends FormulaExecutor {
 
         @Override
         public void parse() {
-            LinkedHashMap<String,FormData> fdm = FormulaUtils.toFormDataMap(new InterimMeterPaySummary());
-            /*获取实际输出行数*/
-            this.capacity=getLineSize(new ArrayList<>(fdm.keySet()));
-            Map<String,Function<List<InterimMeterPaySummary>,List<Object>>> functionMap =FormulaUtils.fieldDataFcMap(InterimMeterPaySummary.class);
-            tec.getFormDataMap().putAll(fdm);
-            List<InterimMeterPaySummary> dataList = new ArrayList<>();
+            builderFormDatas(InterimMeterPaySummary.class);
             for(Payment payment:current){
                 InterimMeterPaySummary imps = new InterimMeterPaySummary();
                 BeanUtils.copyProperties(payment,imps);
@@ -700,7 +675,7 @@ public class ExecutorSpecial extends FormulaExecutor {
                 summary.setMoney(StringUtils.number2StringZero(sum,2));
                 dataList.add(summary);
             }
-            FormulaUtils.put2FormData(fdm,functionMap,dataList);
+            putOut();
         }
     }
 
@@ -751,11 +726,44 @@ public class ExecutorSpecial extends FormulaExecutor {
         }
     }
 
-
-    public interface  Special{
+    @Data
+    class BaseSpecial<T>{
+        /*数据模型包含的元素*/
+        public LinkedHashMap<String,FormData> fdm;
+        /*元素内容输出对应的映射函数*/
+        public Map<String,Function<List<T>,List<Object>>> functionMap;
+        /*获取实际输出行数*/
+        public Integer capacity;
+        /*输出值*/
+        List<T> dataList;
+        /*用实例去构建带有初始化数据的元素*/
+        public void  builderFormDatas(T bean){
+            fdm = FormulaUtils.toFormDataMap(bean);
+            functionMap =FormulaUtils.fieldDataFcMap(bean.getClass());
+            capacity=getLineSize(new ArrayList<>(fdm.keySet()));
+            tec.getFormDataMap().putAll(fdm);
+            dataList=new ArrayList<>();
+        }
+        /*用元类class 创建空元素*/
+        public void  builderFormDatas(Class<T> clazz){
+            fdm = FormulaUtils.toFormDataMap(clazz);
+            functionMap =FormulaUtils.fieldDataFcMap(clazz);
+            capacity=getLineSize(new ArrayList<>(fdm.keySet()));
+            tec.getFormDataMap().putAll(fdm);
+            dataList=new ArrayList<>();
+        }
+        /*写入对应的元素*/
+        public void putOut(){
+            FormulaUtils.put2FormData(fdm,functionMap,dataList);
+        };
+    }
+    interface  Special{
         /**是否满足执行条件*/
         boolean ready();
         /**解析数据*/
         void parse();
     }
+    public ExecutorMeter(TableElementConverter tec) {
+        super(tec);
+    }
 }

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

@@ -6,7 +6,6 @@ import lombok.Data;
 import lombok.EqualsAndHashCode;
 import org.springblade.core.tool.utils.CollectionUtil;
 import org.springblade.manager.dto.FormData;
-import org.springblade.manager.formula.FormulaExecutor;
 
 import java.util.regex.Matcher;
 

+ 0 - 4
blade-service/blade-manager/src/main/java/org/springblade/manager/formula/impl/ExecutorSort.java

@@ -1,17 +1,13 @@
 package org.springblade.manager.formula.impl;
 
 import com.mixsmart.utils.FormulaUtils;
-import com.mixsmart.utils.StringUtils;
 import lombok.Data;
 import lombok.EqualsAndHashCode;
 import org.springblade.core.tool.utils.CollectionUtil;
 import org.springblade.core.tool.utils.Func;
 import org.springblade.manager.dto.ElementData;
 import org.springblade.manager.dto.FormData;
-import org.springblade.manager.formula.FormulaExecutor;
-import org.springblade.manager.formula.NodeTable;
 
-import java.util.Comparator;
 import java.util.List;
 import java.util.Map;
 import java.util.Optional;

+ 4 - 4
blade-service/blade-manager/src/main/java/org/springblade/manager/formula/FormulaExecutor.java → blade-service/blade-manager/src/main/java/org/springblade/manager/formula/impl/FormulaExecutor.java

@@ -1,7 +1,7 @@
-package org.springblade.manager.formula;
+package org.springblade.manager.formula.impl;
 
 import lombok.Data;
-import org.springblade.manager.formula.impl.TableElementConverter;
+import org.springblade.manager.formula.FormulaHandleChain;
 import java.util.regex.Pattern;
 
 
@@ -11,8 +11,8 @@ import java.util.regex.Pattern;
  * @description 公式执行器
  */
 @Data
-public abstract  class   FormulaExecutor implements FormulaHandleChain{
-    public  TableElementConverter tec;
+public abstract  class   FormulaExecutor implements FormulaHandleChain {
+    TableElementConverter tec;
     public final static String WP="WP";
     public final static String CHAIN="trees";
     public final static String FC="FC.";

+ 3 - 5
blade-service/blade-manager/src/main/java/org/springblade/manager/formula/impl/TableElementConverter.java

@@ -20,11 +20,7 @@ import org.springblade.manager.formula.FormulaLog;
 import org.springblade.manager.formula.ITableElementConverter;
 import org.springblade.manager.formula.KeyMapper;
 import org.springblade.manager.formula.NodeTable;
-import org.springblade.manager.vo.CurrentNode;
-import org.springblade.manager.vo.MeterTree;
-import org.springblade.manager.vo.MeterType;
-import org.springblade.manager.vo.ReportResult;
-import org.springframework.jdbc.core.JdbcTemplate;
+import org.springblade.manager.vo.*;
 
 import java.util.*;
 import java.util.concurrent.CompletableFuture;
@@ -113,6 +109,8 @@ public class TableElementConverter implements ITableElementConverter {
     private  Long reportId;
     /**计量期Id*/
     private Long periodId;
+    /**计量期信息*/
+    public MeterPeriodInfo periodInfo;
     /**计量类型*/
     private MeterType meterType;
     /**计量单元树*/

+ 5 - 2
blade-service/blade-manager/src/main/java/org/springblade/manager/service/ITrialSummaryClassificationConfigurationService.java

@@ -7,6 +7,9 @@ import org.springblade.manager.dto.TrialSummaryClassificationConfigurationReleva
 import org.springblade.manager.entity.TrialSummaryClassificationConfiguration;
 import org.springblade.manager.vo.TrialTreeVO;
 
+import java.io.FileNotFoundException;
+import java.io.IOException;
+
 public interface ITrialSummaryClassificationConfigurationService extends BaseService<TrialSummaryClassificationConfiguration> {
 
     TrialSummaryClassificationConfiguration detail(Long id);
@@ -17,8 +20,8 @@ public interface ITrialSummaryClassificationConfigurationService extends BaseSer
 
     boolean matching(TrialSummaryClassificationConfigurationMatchDTO dto);
 
-    boolean relevancy(TrialSummaryClassificationConfigurationRelevancyDTO dto);
+    boolean relevancy(TrialSummaryClassificationConfigurationRelevancyDTO dto) throws IOException;
 
-    TrialTreeVO tree(String projectId, String classId, String type);
+    TrialTreeVO tree(String projectId, String classId);
 
 }

+ 8 - 6
blade-service/blade-manager/src/main/java/org/springblade/manager/service/impl/ArchiveTreeContractServiceImpl.java

@@ -1447,7 +1447,7 @@ public class ArchiveTreeContractServiceImpl extends BaseServiceImpl<ArchiveTreeC
 		String userId = AuthUtil.getUserId()+"";
 		String userName = AuthUtil.getNickName();
 		//取出所有选择的节点,只获取专家名称和专家id字段
-		List<Long> longs = Func.toLongList(ids);
+		List<Long> longs = Func.toLongList(ids).stream().distinct().collect(Collectors.toList());
 		List<ArchiveTreeContract> list = baseMapper.getSelectNodes(longs);
 		//循环判断是否已经存在专家,存在则追加
 		list.stream().forEach(l->{
@@ -1456,11 +1456,13 @@ public class ArchiveTreeContractServiceImpl extends BaseServiceImpl<ArchiveTreeC
 				l.setExpertId(userId);
 				l.setExpertName(userName);
 			}else {
-				//不为空
-				String expertId = l.getExpertId();
-				l.setExpertId(expertId+","+userId);
-				String expertName = l.getExpertName();
-				l.setExpertName(expertName+"/"+userName);
+				//不为空,并且不包含当前专家
+				if (!l.getExpertId().contains(userId)) {
+					String expertId = l.getExpertId();
+					l.setExpertId(expertId + "," + userId);
+					String expertName = l.getExpertName();
+					l.setExpertName(expertName + "/" + userName);
+				}
 			}
 		});
 		//保存所有节点

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

@@ -78,8 +78,8 @@ public class FormulaDaoImpl implements IFormulaDao {
 
     @Override
     public Function<Long, MeterPeriodInfo> getInterimMeterPeriodFc() {
-        return  id->{
-            String sql="SELECT period_number name,sort from s_contract_meter_period where id ="+id;
+        return certificateId->{
+            String sql="select a.period_number number,a.sort from  s_contract_meter_period a join s_interim_pay_certificate b on a.id=b.contract_period_id where a.is_deleted=0 and b.id="+certificateId;
             return this.jdbcTemplate.queryForObject(sql,new BeanPropertyRowMapper<>(MeterPeriodInfo.class));
         };
     }
@@ -87,7 +87,7 @@ public class FormulaDaoImpl implements IFormulaDao {
     @Override
     public Function<Long, List<Payment>> getPaymentListFc() {
         return contractId->{
-            String paySql="select a.form_number number,a.form_name name ,a.middle_meter_id,a.current_meter_total completed ,a.current_price price,current_meter_money money,meter_number meterNumber ,contract_meter_id meterId,b.id formId,b.chapter_number chapter, b.contract_money contractMoney,b.change_money,b.unit,contract_total ,change_total,c.sort,c.id periodId from s_inventory_form_apply a join s_contract_inventory_form b on a.contract_form_id=b.id join s_contract_meter_period c on a.contract_period_id=c.id where a.is_deleted=0 and a.approve_status=2 and a.contract_id="+contractId;
+            String paySql="select  a.id,a.form_number number,a.form_name name ,a.middle_meter_id,a.current_meter_total completed ,a.current_price price,current_meter_money money,meter_number meterNumber ,contract_meter_id meterId,b.id formId,b.chapter_number chapter, b.contract_money contractMoney,b.change_money,b.unit,contract_total ,change_total,c.sort,c.id periodId from s_inventory_form_apply a join s_contract_inventory_form b on a.contract_form_id=b.id join s_contract_meter_period c on a.contract_period_id=c.id where a.is_deleted=0 and a.approve_status=2 and a.contract_id="+contractId;
             return this.jdbcTemplate.query(paySql,new BeanPropertyRowMapper<>(Payment.class));
         };
     }
@@ -95,7 +95,7 @@ public class FormulaDaoImpl implements IFormulaDao {
     @Override
     public Function<Long, List<InventoryForm>> getInventoryFormFc() {
         return  contractId->{
-           String sql="select form_name,chapter_number,bid_price,contract_total,form_number,contract_money,change_money from  s_contract_inventory_form where   is_deleted=0  and contract_id="+contractId;
+           String sql="select id,form_name,parent_id,chapter_number chapter,bid_price,contract_total,form_number,contract_money,change_money from  s_contract_inventory_form where   is_deleted=0  and contract_id="+contractId;
            return getEntityList(sql,InventoryForm.class);
         };
     }

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

@@ -2612,6 +2612,7 @@ public class FormulaServiceImpl extends BaseServiceImpl<FormulaMapper, Formula>
         for(Map.Entry<String,Object> entry:map.entrySet()){
             result.put(entry.getKey(),StringUtils.handleNull(entry.getValue()));
         }
+        result.put("projectId",projectId);
         return result;
     }
 
@@ -2623,8 +2624,8 @@ public class FormulaServiceImpl extends BaseServiceImpl<FormulaMapper, Formula>
 
         /*元素创建*/
         Map<String,String> parent=  getWtpParent(meterType.getName(),contractInfo.getPId());
-        List<NodeTable> tableList=  this.getSqlList("select p_key_id pkeyId, node_name nodeName ,init_table_name initTableName,html_url htmlUrl ,excel_id excelId from  m_wbs_tree_private where ancestors like ? and LENGTH(html_url)>0 and is_deleted=0 and project_id=? and wbs_id=?",NodeTable.class,parent.get("path")+"%",contractInfo.getPId(),parent.get("wbsId"));
-        Map<String,Map<String,String>> coordinateMap=tableList.stream().collect(Collectors.toMap(NodeTable::getInitTableName,m->FormulaUtils.getElementCell(m.getHtmlUrl()),(v1,v2)->v2));
+        List<NodeTable> tableList=getTableListMeter(parent);
+        Map<String,Map<String,String>> coordinateMap=tableList.parallelStream().collect(Collectors.toMap(NodeTable::getInitTableName,m->FormulaUtils.getElementCell(m.getHtmlUrl()),(v1,v2)->v2));
         List<FormData> processFds = this.createFormDataByTableName(tableList.stream().map(NodeTable::getInitTableName).collect(Collectors.joining("','")));
         listForMeter(processFds,contractInfo.getPId(),parent.get("id"));
 
@@ -2641,18 +2642,13 @@ public class FormulaServiceImpl extends BaseServiceImpl<FormulaMapper, Formula>
         List<FormulaHandleChain> formulaHandleChains = new ArrayList<>();
         /*初始化*/
         ExecutorInit init= new ExecutorInit(tec);
-        init.setBaseInfoFc(this.formulaDao.getBaseInfoFc());
-        init.setMeterPeriodFc(this.formulaDao.getMeterPeriodFc());
-        init .setMeterTreeFc(this.formulaDao.getMeterTreeFc());
+        BeanUtils.copyProperties(this.formulaDao,init);
         formulaHandleChains.add(init);
         formulaHandleChains.add(new ExecutorSort(tec));
         formulaHandleChains.add(new ExecutorPre(tec));
         /*特殊公式*/
-        ExecutorSpecial special = new ExecutorSpecial(tec);
-        special.setMaterialFormFc(this.formulaDao.getMaterialFormFc());
-        special.setInterimMeterPeriodFc(this.formulaDao.getInterimMeterPeriodFc());
-        special.setPaymentListFc(this.formulaDao.getPaymentListFc());
-        special.setMeterApplyFc(this.formulaDao.getMeterApplyFc());
+        ExecutorMeter special = new ExecutorMeter(tec);
+        BeanUtils.copyProperties(this.formulaDao,special);
         formulaHandleChains.add(special);
         /*通用计算*/
         formulaHandleChains.add(new ExecutorCalc(tec));
@@ -2663,7 +2659,9 @@ public class FormulaServiceImpl extends BaseServiceImpl<FormulaMapper, Formula>
         return tec.getReportResults();
     }
 
-
+    public List<NodeTable> getTableListMeter(Map<String,String> parent){
+      return this.getSqlList("select p_key_id pkeyId, node_name nodeName ,init_table_name initTableName,html_url htmlUrl ,excel_id excelId from  m_wbs_tree_private where ancestors like ? and LENGTH(html_url)>0 and is_deleted=0 and project_id=? and wbs_id=?",NodeTable.class,parent.get("path")+"%",parent.get("projectId"),parent.get("wbsId"));
+    }
 
 
 

+ 143 - 49
blade-service/blade-manager/src/main/java/org/springblade/manager/service/impl/TrialSummaryClassificationConfigurationServiceImpl.java

@@ -1,23 +1,40 @@
 package org.springblade.manager.service.impl;
 
+import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
 import com.baomidou.mybatisplus.core.metadata.IPage;
 import com.baomidou.mybatisplus.core.toolkit.Wrappers;
 import lombok.AllArgsConstructor;
+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.utils.MathUtil;
 import org.springblade.common.utils.SnowFlakeUtil;
+import org.springblade.core.log.exception.ServiceException;
 import org.springblade.core.mp.base.BaseServiceImpl;
-import org.springblade.core.tool.utils.BeanUtil;
-import org.springblade.core.tool.utils.ObjectUtil;
+import org.springblade.core.tool.utils.*;
 import org.springblade.manager.dto.TrialSummaryClassificationConfigurationMatchDTO;
 import org.springblade.manager.dto.TrialSummaryClassificationConfigurationRelevancyDTO;
-import org.springblade.manager.entity.TrialSummaryClassificationConfiguration;
-import org.springblade.manager.entity.WbsTreePrivate;
+import org.springblade.manager.entity.*;
 import org.springblade.manager.mapper.TrialSummaryClassificationConfigurationMapper;
+import org.springblade.manager.service.IExcelTabService;
+import org.springblade.manager.service.ITableInfoService;
 import org.springblade.manager.service.ITrialSummaryClassificationConfigurationService;
+import org.springblade.manager.service.IWbsFormElementService;
+import org.springblade.manager.utils.FileUtils;
+import org.springblade.manager.utils.RegularExpressionUtil;
+import org.springblade.manager.utils.WbsElementUtil;
 import org.springblade.manager.vo.TrialTreeVO;
 import org.springframework.jdbc.core.BeanPropertyRowMapper;
 import org.springframework.jdbc.core.JdbcTemplate;
 import org.springframework.stereotype.Service;
 
+import java.io.File;
+import java.io.FileInputStream;
+import java.io.FileNotFoundException;
+import java.io.IOException;
+import java.util.ArrayList;
 import java.util.List;
 import java.util.Map;
 import java.util.function.Function;
@@ -31,6 +48,8 @@ public class TrialSummaryClassificationConfigurationServiceImpl
 
     private final JdbcTemplate jdbcTemplate;
     private final WbsTreePrivateServiceImpl wbsTreePrivateServiceImpl;
+    private final IExcelTabService excelTabService;
+    private final IWbsFormElementService wbsFormElementService;
 
     @Override
     public TrialSummaryClassificationConfiguration detail(Long id) {
@@ -50,52 +69,129 @@ public class TrialSummaryClassificationConfigurationServiceImpl
 
     @Override
     public boolean matching(TrialSummaryClassificationConfigurationMatchDTO dto) {
-        if (ObjectUtil.isNotEmpty(dto.getIds()) && ObjectUtil.isNotEmpty(dto.getClassId()) && ObjectUtil.isNotEmpty(dto.getProjectId())) {
-            String delSql = "DELETE FROM m_trial_summary_class_config_record WHERE type = ? AND class_id = ?";
-            Object[] delParams = {1, dto.getClassId(),};
+        if (ObjectUtil.isNotEmpty(dto.getIds()) && ObjectUtil.isNotEmpty(dto.getClassId())) {
+            String delSql = "UPDATE m_trial_summary_classification_configuration SET trial_tree_ids = ? WHERE id = ?";
+            Object[] delParams = {dto.getIds(), dto.getClassId(),};
             jdbcTemplate.update(delSql, delParams);
-
-            for (String pKeyId : dto.getIds().split(",")) {
-                String insertSql = "INSERT INTO m_trial_summary_class_config_record(id,type,project_id,class_id,p_key_id) VALUES (?,?,?,?,?)";
-                Object[] insertParams = {
-                        SnowFlakeUtil.getId(),
-                        1,
-                        dto.getProjectId(),
-                        dto.getClassId(),
-                        pKeyId
-                };
-                jdbcTemplate.update(insertSql, insertParams);
-            }
             return true;
         }
         return false;
     }
 
     @Override
-    public boolean relevancy(TrialSummaryClassificationConfigurationRelevancyDTO dto) {
-        if (ObjectUtil.isNotEmpty(dto.getIds()) && ObjectUtil.isNotEmpty(dto.getClassId()) && ObjectUtil.isNotEmpty(dto.getProjectId())) {
-            String delSql = "DELETE FROM m_trial_summary_class_config_record WHERE type = ? AND class_id = ?";
-            Object[] delParams = {2, dto.getClassId(),};
-            jdbcTemplate.update(delSql, delParams);
+    public boolean relevancy(TrialSummaryClassificationConfigurationRelevancyDTO dto) throws IOException {
+        if (ObjectUtil.isNotEmpty(dto.getExcelId()) && ObjectUtil.isNotEmpty(dto.getClassId())) {
+            /*关联清表,重新生成html,重构定位信息*/
+            String file_path = FileUtils.getSysLocalFileUrl();
+            ExcelTab excelTab = excelTabService.getById(dto.getExcelId());
+            if (ObjectUtil.isEmpty(excelTab)) {
+                throw new ServiceException("未获取到清表信息");
+            }
+            if (ObjectUtil.isEmpty(excelTab.getTabId())) {
+                throw new ServiceException("未获取到清表tabId信息");
+            }
+            List<WbsFormElement> elementList = wbsFormElementService.selectElementListByFid(excelTab.getTabId());
+            if (elementList.size() == 0) {
+                throw new ServiceException("未获取到清表对应元素信息");
+            }
+
+            //复制模版htmlURL
+            File file_in = ResourceUtil.getFile(excelTab.getHtmlUrl());
+            String fileCode = SnowFlakeUtil.getId() + "";
+            String htmlUrl = file_path + "/privateUrl/" + fileCode + ".html";
+            File file_out = ResourceUtil.getFile(htmlUrl);
+            FileUtil.copy(file_in, file_out);
+
+            //匹配关联
+            File file1 = ResourceUtil.getFile(htmlUrl);
+            String htmlString = IoUtil.readToString(new FileInputStream(file1));
+            Document doc = Jsoup.parse(htmlString);
+            //解析
+            Element table = doc.select("table").first();
+            Elements trs = table.select("tr");
+            for (int i = 0; i < trs.size(); i++) {
+                Element tr = trs.get(i);
+                Elements tds = tr.select("td");
+                for (int j = 0; j < tds.size(); j++) {
+                    Element element = tds.get(j);
+                    if (element.html().indexOf("el-input") >= 0 || element.html().indexOf("el-date-picker") >= 0) {
+
+                        boolean is_true = false;
+                        String titleName = element.attr("title");
+                        double maxScore = 0.48;
+                        String lastName = "警告";
+                        String attrInfo = "key" + "__" + i + "_" + j;
+                        String filedType = "";
+                        String filedLength = "";
+
+                        for (WbsFormElement elementInfo : elementList) {
+                            String ysName = elementInfo.getEName();
+                            if (titleName.equals(ysName)) {
+                                lastName = elementInfo.getEName();
+                                attrInfo = elementInfo.getEKey() + "__" + i + "_" + j;
+
+                                filedType = WbsElementUtil.getInitTableFiledType(elementInfo.getEType());
 
-            for (String pKeyId : dto.getIds().split(",")) {
-                String sql = "INSERT INTO m_trial_summary_class_config_record(id,type,project_id,class_id,p_key_id) VALUES (?,?,?,?,?)";
-                Object[] insertParams = {
-                        SnowFlakeUtil.getId(),
-                        2,
-                        dto.getProjectId(),
-                        dto.getClassId(),
-                        pKeyId
-                };
-                jdbcTemplate.update(sql, insertParams);
+                                filedLength = elementInfo.getELength().toString();
+
+                                maxScore = 100;
+                                is_true = true;
+                                break;
+                            } else {
+                                if (MathUtil.sim(titleName, ysName) > maxScore) {
+                                    attrInfo = elementInfo.getEKey() + "__" + i + "_" + j;
+
+                                    filedType = WbsElementUtil.getInitTableFiledType(elementInfo.getEType());
+
+                                    filedLength = elementInfo.getELength().toString();
+
+                                    lastName = ysName;
+                                    maxScore = MathUtil.sim(titleName, ysName);
+                                    is_true = true;
+                                }
+                            }
+                        }
+                        String oncklickText = "'" + lastName + "'," + i + "," + j;
+
+                        //字段正则表达式校验
+                        String regularExpression = "$event" + "," + "'" + RegularExpressionUtil.getRegularExpression(filedType) + "','" + (StringUtils.isNotEmpty(filedType) ? WbsElementUtil.getTypeTips(filedType) : null) + "'," + i + "," + j;
+
+                        if (is_true) {
+                            element.children().get(0).attr("placeholder", lastName)
+                                    .attr("weighing", maxScore + "").attr("id", attrInfo).attr("keyName", attrInfo)
+                                    .attr("@blur", "getRegularExpression(" + regularExpression + ",'" + filedLength + "')")
+                                    .attr("v-model", "formData." + attrInfo)
+                                    .attr("maxlength", filedLength);
+                            if (element.html().indexOf("el-input") >= 0) {
+                                String mousedown = "$event" + "," + "'" + attrInfo + "'";
+                                element.children().get(0).attr("@mouseup.left", "inputLeftClick(" + mousedown + ")");
+                            }
+                        } else {
+                            element.children().get(0)
+                                    //.attr("placeholder", lastName)
+                                    .attr("weighing", maxScore + "").attr("id", attrInfo).attr("keyName", attrInfo)
+                                    .attr("@blur", "getRegularExpression(" + regularExpression + ",'" + filedLength + "')")
+                                    .attr("maxlength", filedLength)
+                                    .attr("class", "warnstyle");
+                        }
+                        element.attr("@click", "getInformation(" + oncklickText + ")");
+                    }
+                }
             }
+
+            File writeFile = new File(htmlUrl);
+            FileUtil.writeToFile(writeFile, doc.html(), Boolean.parseBoolean("UTF-8"));
+
+            String delSql = "UPDATE m_trial_summary_classification_configuration SET excel_id = ?,html_url = ? WHERE id = ?";
+            Object[] delParams = {dto.getExcelId(), htmlUrl, dto.getClassId()};
+            jdbcTemplate.update(delSql, delParams);
             return true;
         }
         return false;
     }
 
     @Override
-    public TrialTreeVO tree(String projectId, String classId, String type) {
+    public TrialTreeVO tree(String projectId, String classId) {
         List<WbsTreePrivate> wbsTreePrivatesNodes = wbsTreePrivateServiceImpl.getBaseMapper().selectList(Wrappers.<WbsTreePrivate>lambdaQuery()
                 .select(WbsTreePrivate::getId, WbsTreePrivate::getPKeyId, WbsTreePrivate::getParentId, WbsTreePrivate::getNodeName)
                 .eq(WbsTreePrivate::getProjectId, projectId)
@@ -103,38 +199,36 @@ public class TrialSummaryClassificationConfigurationServiceImpl
                 .eq(WbsTreePrivate::getType, 1)
                 .eq(WbsTreePrivate::getStatus, 1)
         );
-        return buildTree(wbsTreePrivatesNodes, projectId, classId, type);
+        return buildTree(wbsTreePrivatesNodes, classId);
     }
 
-    private TrialTreeVO buildTree(List<WbsTreePrivate> wbsTreePrivatesNodes, String projectId, String classId, String type) {
+    private TrialTreeVO buildTree(List<WbsTreePrivate> wbsTreePrivatesNodes, String classId) {
         List<TrialTreeVO> trialTreeVOS = BeanUtil.copyProperties(wbsTreePrivatesNodes, TrialTreeVO.class);
         if (!trialTreeVOS.isEmpty()) {
-            String sql = "SELECT p_key_id FROM m_trial_summary_class_config_record WHERE class_id = ? AND project_id = ? AND type = ?";
-            Object[] params = {classId, projectId, type};
-            List<TrialTreeVO> query = jdbcTemplate.query(sql, params, new BeanPropertyRowMapper<>(TrialTreeVO.class));
-            Map<Long, TrialTreeVO> statusMap = query.stream().collect(Collectors.toMap(TrialTreeVO::getPKeyId, Function.identity()));
+            TrialSummaryClassificationConfiguration classificationConfiguration = baseMapper.selectById(classId);
+            List<String> trialTreeNodePKeyIds = new ArrayList<>();
+            if (classificationConfiguration != null) {
+                trialTreeNodePKeyIds = Func.toStrList(classificationConfiguration.getTrialTreeIds());
+            }
 
             Map<Long, List<TrialTreeVO>> map = trialTreeVOS.stream().collect(Collectors.groupingBy(TrialTreeVO::getParentId));
             List<TrialTreeVO> list = trialTreeVOS.stream().filter(f -> f.getParentId() == 0L).collect(Collectors.toList());
-            buildChildNodes(list, map, statusMap);
+            buildChildNodes(list, map, trialTreeNodePKeyIds);
             return trialTreeVOS.get(0);
         }
         return null;
     }
 
-    private void buildChildNodes(List<TrialTreeVO> list, Map<Long, List<TrialTreeVO>> map, Map<Long, TrialTreeVO> statusMap) {
+    private void buildChildNodes(List<TrialTreeVO> list, Map<Long, List<TrialTreeVO>> map, List<String> trialTreeNodePKeyIds) {
         for (TrialTreeVO trialTreeVO : list) {
-            TrialTreeVO orDefault = statusMap.getOrDefault(trialTreeVO.getPKeyId(), null);
-            if (orDefault != null) {
-                trialTreeVO.setStatus(1);
-            } else {
-                trialTreeVO.setStatus(0);
+            if (trialTreeNodePKeyIds.contains(trialTreeVO.getPKeyId().toString())) {
+                trialTreeVO.setRecordStatus(1);
             }
             List<TrialTreeVO> childrenList = map.getOrDefault(trialTreeVO.getId(), null);
             if (childrenList != null && childrenList.size() > 0) {
                 trialTreeVO.setChildNode(childrenList);
                 trialTreeVO.setHasChild(true);
-                buildChildNodes(childrenList, map, statusMap);
+                buildChildNodes(childrenList, map, trialTreeNodePKeyIds);
             }
         }
     }

+ 20 - 12
blade-service/blade-meter/src/main/java/org/springblade/meter/controller/TaskController.java

@@ -34,6 +34,9 @@ import org.springblade.core.tool.utils.ObjectUtil;
 import org.springblade.feign.ArchiveFileTaskClient;
 import org.springblade.manager.entity.ContractInfo;
 import org.springblade.manager.entity.ContractRelationJlyz;
+import org.springblade.manager.entity.WbsTreePrivate;
+import org.springblade.manager.feign.FormulaClient;
+import org.springblade.manager.vo.ReportResult;
 import org.springblade.meter.dto.*;
 import org.springblade.meter.entity.*;
 import org.springblade.meter.mapper.MiddleMeterApplyMapper;
@@ -89,6 +92,9 @@ public class TaskController extends BladeController {
     private final ChangeTokenInventoryServiceImpl changeTokenInventoryService;
     private final ChangeTokenInventoryServiceTaskImpl changeTokenInventoryServiceTask;
 
+    // 计量公式入口
+    private final FormulaClient formulaClient;
+
     @GetMapping("/name")
     @ApiOperationSupport(order = 1)
     @ApiOperation(value = "获取任务名称", notes = "传入合同段contractId、期数id(变更令传勾选的id字符串英文逗号拼接)、type=1(中间计量申请)、=2(材料计量单)、3=(开工预付款计量单)、=4(变更令)")
@@ -2021,9 +2027,8 @@ public class TaskController extends BladeController {
 
             /*最终审批轮次*/
             if (isCurrentUserLastApprove) {
-
                 //TODO 重新生成报表,执行电签(电签失败直接return或抛出异常,不修改下方状态)
-
+                meterPdfInfo(task);
                 /*复制业务数据状态>主任务状态>替换数据*/
                 updateCopyDataApproveStatus(task, dto).updateTaskStatus(task).displace(task, dto);
             }
@@ -2036,27 +2041,30 @@ public class TaskController extends BladeController {
                 String param = taskParallel.getTaskUser() + "," + task.getProjectId() + "," + task.getContractId();
                 aopParamsSet.add(param);
             }
-
-            // 判断是否为审批 最后一人 如果是 即生成 pdf 并开始电签
-            /*当前审批轮次*/
-            String sql_3 = "SELECT * FROM u_task_parallel WHERE status=1 and process_instance_id = ? ORDER BY sort";
-            List<TaskParallel> lastTaskParallels = jdbcTemplate.query(sql_3, new Object[]{task.getProcessInstanceId()}, new BeanPropertyRowMapper<>(TaskParallel.class));
-            if(lastTaskParallels == null || lastTaskParallels.size() == 0 ){
-                meterPdfInfo(task);
-            }
             return R.data(200, aopParamsSet, "操作成功");
         }
-
         return R.fail("操作失败");
     }
 
 
     // pdf 生成
-
     private boolean meterPdfInfo(Task task) {
+        // 材料生成pdf
+        if(task.getType()==2){
+            // 获取填报数据
+
+            // 调用公式
+            List<ReportResult> reportResults = formulaClient.formulaExecute3(Long.parseLong(task.getContractId()), Long.parseLong(task.getFormDataId()),1);
+            //生成pdf
+            String fen ="SELECT * from m_wbs_tree_private WHERE project_id='"+task.getProjectId()+"' and wbs_type=3 and parent_id=(SELECT id from m_wbs_tree_private where project_id='"+task.getProjectId()+"' and is_deleted=0 and type=1 and wbs_type=3 and node_type=31)" +
+                    "AND type = 2 AND status = 1 and is_deleted= 0 ORDER BY sort";
+            WbsTreePrivate wbsTreePrivate = jdbcTemplate.query(fen, new BeanPropertyRowMapper<>(WbsTreePrivate.class)).stream().findAny().orElse(null);;
 
 
 
+        }
+
+
 
         return true;
     }

+ 10 - 2
blade-service/blade-user/src/main/java/org/springblade/system/user/controller/UserController.java

@@ -508,9 +508,17 @@ public class UserController {
 
             HttpClient httpClient = HttpClientBuilder.create().build();
             HttpPost httpPost = new HttpPost("http://39.108.216.210:8090/blade-auth/oauth/token");
-            httpPost.setHeader("Authorization", "Basic YXJjaGl2ZXM6YXJjaGl2ZXNfc2VjcmV0");
+
+            if(userInfo.getSysId().equals("30")){
+                httpPost.setHeader("Authorization", "Basic YXJjaGl2ZXM6YXJjaGl2ZXNfc2VjcmV0");
+            }else if ("40".equals(userInfo.getSysId())) {
+                httpPost.setHeader("Authorization", "Basic bWVhc3VyZTptZWFzdXJlX3NlY3JldA==");
+            }else{
+                httpPost.setHeader("Authorization", "Basic YXJjaGl2ZXM6YXJjaGl2ZXNfc2VjcmV0");
+            }
+
             httpPost.setHeader("Content-Type", "application/x-www-form-urlencoded");
-            httpPost.setHeader("Tenant-Id", "000000");
+            httpPost.setHeader("Tenant-Id", userInfo.getTenantId());
             List<NameValuePair> params = new ArrayList<NameValuePair>();
             params.add(new BasicNameValuePair("grant_type", "password"));
             params.add(new BasicNameValuePair("username", account));