Pārlūkot izejas kodu

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

huangtf 1 gadu atpakaļ
vecāks
revīzija
eea30adfb6
25 mainītis faili ar 1001 papildinājumiem un 132 dzēšanām
  1. 25 0
      blade-service-api/blade-archive-api/src/main/java/org/springblade/archive/dto/ArchiveWarningDTO.java
  2. 3 0
      blade-service-api/blade-archive-api/src/main/java/org/springblade/archive/entity/ExpertInspection.java
  3. 33 0
      blade-service-api/blade-archive-api/src/main/java/org/springblade/archive/vo/ArchiveWarningVO.java
  4. 14 0
      blade-service-api/blade-manager-api/src/main/java/org/springblade/manager/vo/InterimPaymentCertificate.java
  5. 30 0
      blade-service-api/blade-manager-api/src/main/java/org/springblade/manager/vo/InventoryForm.java
  6. 2 0
      blade-service-api/blade-manager-api/src/main/java/org/springblade/manager/vo/MeterPeriodInfo.java
  7. 32 0
      blade-service-api/blade-manager-api/src/main/java/org/springblade/manager/vo/Payment.java
  8. 1 0
      blade-service/blade-archive/src/main/java/org/springblade/archive/controller/ArchiveExpertConclusionController.java
  9. 6 0
      blade-service/blade-archive/src/main/java/org/springblade/archive/controller/ArchiveExpertScoreController.java
  10. 20 1
      blade-service/blade-archive/src/main/java/org/springblade/archive/controller/ArchivesAutoController.java
  11. 4 0
      blade-service/blade-archive/src/main/java/org/springblade/archive/service/IArchiveExpertScoreService.java
  12. 3 0
      blade-service/blade-archive/src/main/java/org/springblade/archive/service/IArchivesAutoService.java
  13. 17 4
      blade-service/blade-archive/src/main/java/org/springblade/archive/service/impl/ArchiveExpertConclusionServiceImpl.java
  14. 184 0
      blade-service/blade-archive/src/main/java/org/springblade/archive/service/impl/ArchiveExpertScoreServiceImpl.java
  15. 18 0
      blade-service/blade-archive/src/main/java/org/springblade/archive/service/impl/ArchivesAutoServiceImpl.java
  16. 100 0
      blade-service/blade-business/src/main/java/org/springblade/business/controller/EVisaTaskCheckController.java
  17. 8 0
      blade-service/blade-manager/src/main/java/com/mixsmart/utils/CustomFunction.java
  18. 23 0
      blade-service/blade-manager/src/main/java/com/mixsmart/utils/FormulaUtils.java
  19. 1 1
      blade-service/blade-manager/src/main/java/org/springblade/manager/controller/ArchiveTreeContractController.java
  20. 4 4
      blade-service/blade-manager/src/main/java/org/springblade/manager/formula/impl/ExecutorInit.java
  21. 94 23
      blade-service/blade-manager/src/main/java/org/springblade/manager/formula/impl/ExecutorSpecial.java
  22. 15 7
      blade-service/blade-manager/src/main/java/org/springblade/manager/service/IFormulaDao.java
  23. 37 6
      blade-service/blade-manager/src/main/java/org/springblade/manager/service/impl/FormulaDaoImpl.java
  24. 5 3
      blade-service/blade-manager/src/main/java/org/springblade/manager/service/impl/FormulaServiceImpl.java
  25. 322 83
      blade-service/blade-meter/src/main/java/org/springblade/meter/service/impl/MeterTreeContractServiceImpl.java

+ 25 - 0
blade-service-api/blade-archive-api/src/main/java/org/springblade/archive/dto/ArchiveWarningDTO.java

@@ -0,0 +1,25 @@
+package org.springblade.archive.dto;
+
+import io.swagger.annotations.ApiModelProperty;
+import lombok.Data;
+
+/**
+ * @Param    档案预警DTO
+ * @Author wangwl
+ * @Date 2024/1/12 10:41
+ **/
+@Data
+public class ArchiveWarningDTO {
+
+    @ApiModelProperty(value = "节点id")
+    private Long nodeId;
+
+    @ApiModelProperty(value = "项目id")
+    private Long projectId;
+
+    @ApiModelProperty(value = "合同id")
+    private Long contractId;
+
+    @ApiModelProperty(value = "1待整改2已整改")
+    private Integer rectification;
+}

+ 3 - 0
blade-service-api/blade-archive-api/src/main/java/org/springblade/archive/entity/ExpertInspection.java

@@ -19,6 +19,9 @@ public class ExpertInspection extends BaseEntity {
     @ApiModelProperty("项目id")
     private Long projectId;
 
+    @ApiModelProperty("对应节点id")
+    private Long nodeId;
+
     @ApiModelProperty("结论id")
     private Long conclusionId;
 

+ 33 - 0
blade-service-api/blade-archive-api/src/main/java/org/springblade/archive/vo/ArchiveWarningVO.java

@@ -0,0 +1,33 @@
+package org.springblade.archive.vo;
+
+import io.swagger.annotations.ApiModelProperty;
+import lombok.Data;
+
+/**
+ * @Param    档案预警VO
+ * @Author wangwl
+ * @Date 2024/1/12 10:41
+ **/
+@Data
+public class ArchiveWarningVO {
+
+    @ApiModelProperty(value = "节点id")
+    private Long archiveId;
+
+    @ApiModelProperty(value = "项目id")
+    private Long archiveName;
+
+    @ApiModelProperty(value = "合同id")
+    private Long allOpinion;
+
+    @ApiModelProperty(value = "文件名称")
+    private String fileName;
+
+    @ApiModelProperty(value = "文件地址")
+    private String fileUrl;
+
+    @ApiModelProperty(value = "来源0巡检1验收")
+    private Integer sourceType;
+
+
+}

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

@@ -3,6 +3,9 @@ package org.springblade.manager.vo;
 import com.alibaba.fastjson.annotation.JSONField;
 import lombok.Data;
 
+import java.math.BigDecimal;
+import java.math.RoundingMode;
+
 /**
  * @author yangyj
  * @Date 2024/1/8 15:46
@@ -37,4 +40,15 @@ public class InterimPaymentCertificate {
     /**备注*/
     @JSONField(name = "key_8",label="备注",ordinal = 8)
     private String remark;
+    /**本次实际支付金额合计*/
+    @JSONField(name = "key_9",label="本次实际支付金额合计",ordinal = 9)
+    private String total;
+    public void calculate(){
+        BigDecimal previousPeriodEndPayBd = new BigDecimal(previousPeriodEndPay);
+        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();
+    }
 }

+ 30 - 0
blade-service-api/blade-manager-api/src/main/java/org/springblade/manager/vo/InventoryForm.java

@@ -0,0 +1,30 @@
+package org.springblade.manager.vo;
+
+import lombok.Data;
+
+/**
+ * @author yangyj
+ * @Date 2024/1/12 10:20
+ * @description 合同计量清单映射
+ */
+@Data
+public class InventoryForm {
+    private Long id;
+    /*父节点id*/
+    private Long parentId;
+    /*清单名称*/
+    private String formName;
+    /*清单编号*/
+    private String formNumber;
+    /*章节*/
+    private  String chapter;
+    /*中标价格*/
+    private  String bidPrice;
+    /*合同数量*/
+    private Integer contractTotal;
+    /*合同金额*/
+    private String contractMoney;
+    /*变更后的金额*/
+    private String changeMoney;
+
+}

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

@@ -35,5 +35,7 @@ public class MeterPeriodInfo {
     /**请款理由*/
     @JSONField(name = "key_5",label="请款理由",ordinal = 5)
     private String  cause;
+    /**排序号*/
+    private Integer sort;
 
 }

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

@@ -0,0 +1,32 @@
+package org.springblade.manager.vo;
+
+import lombok.Data;
+
+import java.math.BigDecimal;
+
+/**
+ * @author yangyj
+ * @Date 2024/1/11 14:33
+ * @description 支付数据的映射
+ */
+@Data
+public class Payment {
+    /*清单编号*/
+    private String number;
+    private String name;
+    private String money;
+    private String chapter;
+    private String contractMoney;
+    private Integer sort;
+    private Long periodId;
+
+    public BigDecimal getMoneyAsBigDecimal() {
+        try {
+            return new BigDecimal(getMoney());
+        } catch (NumberFormatException e) {
+            return BigDecimal.ZERO;
+        }
+    }
+
+
+}

+ 1 - 0
blade-service/blade-archive/src/main/java/org/springblade/archive/controller/ArchiveExpertConclusionController.java

@@ -167,6 +167,7 @@ public class ArchiveExpertConclusionController extends BladeController {
             @ApiImplicitParam(name = "projectId", value = "项目id", required = true)
     })
     public R submitTable(@RequestBody ArchiveExpertConclusion conclusion) {
+        conclusionService.updateById(conclusion);
         conclusionService.submitTable(conclusion);
         return R.data("提交成功");
     }

+ 6 - 0
blade-service/blade-archive/src/main/java/org/springblade/archive/controller/ArchiveExpertScoreController.java

@@ -51,4 +51,10 @@ public class ArchiveExpertScoreController extends BladeController {
         return R.data("修改成功");
     }
 
+    @GetMapping("/test")
+    public R test( Long projectId,Long conclusionId) throws Exception {
+        scoreService.buildScorePdf(projectId,conclusionId);
+        return R.data("修改成功");
+    }
+
 }

+ 20 - 1
blade-service/blade-archive/src/main/java/org/springblade/archive/controller/ArchivesAutoController.java

@@ -33,6 +33,7 @@ import lombok.SneakyThrows;
 import lombok.extern.slf4j.Slf4j;
 import org.apache.commons.lang.StringUtils;
 import org.apache.http.message.BasicNameValuePair;
+import org.springblade.archive.dto.ArchiveWarningDTO;
 import org.springblade.archive.dto.SaveApplyDTO;
 import org.springblade.archive.entity.ArchiveConclusion;
 import org.springblade.archive.entity.ExpertInspection;
@@ -925,8 +926,26 @@ public class ArchivesAutoController extends BladeController {
 		return archivesAutoService.callbackSave(callback);
 	}
 
+	/**
+	 * 档案预警-分页查询
+	 */
+	@GetMapping("/warningPage")
+	@ApiOperationSupport(order = 36)
+	@ApiOperation(value = "在线验收-编写报告", notes = "传入项目id,节点和整改状态,返回分页信息")
+	@ApiImplicitParams(value = {
+			@ApiImplicitParam(name = "rectification", value = "1待整改2已整改", required = true),
+			@ApiImplicitParam(name = "nodeId", value = "节点id", required = true),
+			@ApiImplicitParam(name = "projectId", value = "项目id", required = true),
+			@ApiImplicitParam(name = "contractId", value = "合同id", required = true)
+	})
+	public R<IPage<ArchiveWarningVO>> warningPage(Query query, ArchiveWarningDTO dto) {
+		IPage<ArchiveWarningVO> iPage = archivesAutoService.warningPage(query, dto);
+		return R.data(iPage);
+	}
+
 
 
 
 
-}
+
+	}

+ 4 - 0
blade-service/blade-archive/src/main/java/org/springblade/archive/service/IArchiveExpertScoreService.java

@@ -4,6 +4,7 @@ import org.springblade.archive.entity.ArchiveExpertScore;
 import org.springblade.archive.entity.ExpertInspection;
 import org.springblade.core.mp.base.BaseService;
 
+import java.io.FileNotFoundException;
 import java.util.List;
 
 
@@ -13,4 +14,7 @@ public interface IArchiveExpertScoreService extends BaseService<ArchiveExpertSco
     void saveBaseScoreInfo(Long projectId,Long conclusionId);
 
     List<ArchiveExpertScore> getItemByUnit(Long projectId, Integer unitType);
+
+    //传入结论id,生成结论pdf
+    String buildScorePdf(Long projectId,Long conclusionId) throws Exception;
 }

+ 3 - 0
blade-service/blade-archive/src/main/java/org/springblade/archive/service/IArchivesAutoService.java

@@ -16,6 +16,7 @@
  */
 package org.springblade.archive.service;
 
+import org.springblade.archive.dto.ArchiveWarningDTO;
 import org.springblade.archive.dto.SaveApplyDTO;
 import org.springblade.archive.entity.ArchiveConclusion;
 import org.springblade.archive.entity.ArchivesAuto;
@@ -146,4 +147,6 @@ public interface IArchivesAutoService extends BaseService<ArchivesAuto> {
     ArchiveConclusion getArchiveConclusion(Long projectId);
 
 	ExcelEditCallback callbackSave(ExcelEditCallback callback);
+
+    IPage<ArchiveWarningVO> warningPage(Query query, ArchiveWarningDTO dto);
 }

+ 17 - 4
blade-service/blade-archive/src/main/java/org/springblade/archive/service/impl/ArchiveExpertConclusionServiceImpl.java

@@ -191,11 +191,24 @@ public class ArchiveExpertConclusionServiceImpl extends BaseServiceImpl<ArchiveE
     @Override
     @Transactional
     public void submitTable(ArchiveExpertConclusion conclusion) {
-        //保存数据
-        //查询出数据
+        //生成结论pdf
         //判断是否追加
-        //调用生成
-
+        if (conclusion.getIsBuildScore() == 1) {
+            String scoreUrl;
+            //调用生成
+            try {
+                 scoreUrl = scoreService.buildScorePdf(conclusion.getProjectId(), conclusion.getId());
+            }catch (Exception e){
+                throw new ServiceException("创建专家评分表PDF失败");
+            }
+            if (StringUtils.isNotBlank(scoreUrl)){
+                //合并PDF
+            }
+        }
+        //PDF电签
+        //修改状态,插入结论PDF
+        conclusion.setStatus(2);
+        this.updateById(conclusion);
     }
 
     @Override

+ 184 - 0
blade-service/blade-archive/src/main/java/org/springblade/archive/service/impl/ArchiveExpertScoreServiceImpl.java

@@ -2,6 +2,13 @@ package org.springblade.archive.service.impl;
 
 
 import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
+import com.itextpdf.text.*;
+import com.itextpdf.text.pdf.BaseFont;
+import com.itextpdf.text.pdf.PdfPCell;
+import com.itextpdf.text.pdf.PdfPTable;
+import com.itextpdf.text.pdf.PdfWriter;
+import lombok.AllArgsConstructor;
+import org.apache.commons.lang.StringUtils;
 import org.springblade.archive.entity.ArchiveExpertConclusion;
 import org.springblade.archive.entity.ArchiveExpertScore;
 import org.springblade.archive.entity.ExpertInspection;
@@ -9,15 +16,31 @@ import org.springblade.archive.mapper.ArchiveExpertScoreMapper;
 import org.springblade.archive.mapper.ExpertInspectionMapper;
 import org.springblade.archive.service.IArchiveExpertScoreService;
 import org.springblade.archive.service.IExpertInspectionService;
+import org.springblade.core.log.exception.ServiceException;
 import org.springblade.core.mp.base.BaseServiceImpl;
+import org.springblade.core.oss.model.BladeFile;
+import org.springblade.resource.feign.NewIOSSClient;
 import org.springframework.stereotype.Service;
 
+import java.io.FileNotFoundException;
+import java.io.FileOutputStream;
+import java.io.IOException;
 import java.util.ArrayList;
 import java.util.List;
+import java.util.Map;
+import java.util.stream.Collectors;
 
 @Service
+@AllArgsConstructor
 public class ArchiveExpertScoreServiceImpl extends BaseServiceImpl<ArchiveExpertScoreMapper, ArchiveExpertScore> implements IArchiveExpertScoreService {
 
+    private final NewIOSSClient newIOSSClient;
+
+    //表格高度
+    private static int high = 20;
+    //表格宽度
+    private static int widthPercentage = 100;
+
 
     @Override
     public void saveBaseScoreInfo(Long projectId,Long conclusionId) {
@@ -45,5 +68,166 @@ public class ArchiveExpertScoreServiceImpl extends BaseServiceImpl<ArchiveExpert
                 .eq(ArchiveExpertScore::getConclusionId,conclusion.getId()));
         return list;
     }
+
+    /**
+     *
+     * @return
+     */
+    @Override
+    public String buildScorePdf(Long projectId,Long conclusionId) throws Exception {
+        //获取数据
+        List<ArchiveExpertScore> list = this.list(new LambdaQueryWrapper<ArchiveExpertScore>()
+                .eq(ArchiveExpertScore::getProjectId, projectId)
+                .eq(ArchiveExpertScore::getConclusionId, conclusionId));
+        if (list.size() == 0){
+            return null;
+        }
+        Map<Integer, List<ArchiveExpertScore>> map = list.stream().collect(Collectors.groupingBy(ArchiveExpertScore::getUnitType));
+        String fileUrl = "C:\\Users\\泓创研发01\\Desktop\\conclusionPDF.pdf";
+        //新建一个pdf文档对象,前一个参数是纸张大小,后四个为边距
+        Document document = new Document(PageSize.A4, 5, 5, 30, 30);
+        //建立一个书写器
+        PdfWriter writer = PdfWriter.getInstance(document, new FileOutputStream(fileUrl));
+        document.open();
+        //创建字体
+        BaseFont baseFont = BaseFont.createFont("STSong-Light", "UniGB-UCS2-H", BaseFont.NOT_EMBEDDED);
+        //字体对象,这里可以创建一个方法
+        Font size10font = new Font(baseFont, 10, Font.NORMAL); //大小为10的正常字体
+        Font size10font2 = new Font(baseFont, 10, Font.BOLD); //大小为10的粗字体
+        Font size17font = new Font(baseFont, 17, Font.NORMAL);  //大小为17的正常字体
+        //该数组是每个表格的宽度
+        float[] floats = new float[6];
+        floats[0] = 0.5f;
+        floats[1] = 0.1f;
+        floats[2] = 0.1f;
+        floats[3] = 0.1f;
+        floats[4] = 0.1f;
+        floats[5] = 0.1f;
+        float[] floats2 = new float[5];
+        floats2[0] = 0.5f;
+        floats2[1] = 0.1f;
+        floats2[2] = 0.1f;
+        floats2[3] = 0.1f;
+        floats2[4] = 0.1f;
+        tableHeader(document,size17font);
+        tableUnit(document,size10font2,"建设单位");
+        //表头文字
+        String[] name = new String[]{"项目", "完整性", "扣分", "规范性","扣分","总得分"};
+        //创建第二行,并设置第二行中的表格数
+        PdfPTable twoTable = new PdfPTable(name.length);
+        twoTable.setWidthPercentage(widthPercentage);
+        //循环将表头数据添加到第二行表格中
+        for (int i = 0; i < name.length; i++) {
+            PdfPCell pdfPCell = pdfTableStyle(name[i], size10font,high, true, true);
+            pdfPCell.setBackgroundColor(new BaseColor(231,230,230));
+            twoTable.addCell(pdfPCell);
+        }
+        //设置表格的宽度
+        twoTable.setTotalWidth(floats);
+
+        document.add(twoTable);
+        //将数据放入表格中
+        int total = 0;
+        for (int i = 1; i <= 3; i++) {
+            if (i == 2){
+                tableUnit(document,size10font2,"监理单位");
+            }
+            if (i == 3){
+                tableUnit(document,size10font2,"施工单位");
+            }
+            List<ArchiveExpertScore> scores = map.get(i);
+            PdfPTable dataTable = new PdfPTable(5);
+            dataTable.setWidths(floats2);
+            dataTable.setWidthPercentage(100);
+            for (int j = 0; j < scores.size(); j++) {
+                ArchiveExpertScore score = scores.get(j);
+
+                dataTable.addCell(pdfTableStyle(score.getScoreItem(), size10font,high, true, true));
+                dataTable.addCell(pdfTableStyle(score.getIntegrality()+"", size10font, high, true, true));
+                dataTable.addCell(pdfTableStyle(score.getIntegralityDeduction()+"", size10font, high, true, true));
+                dataTable.addCell(pdfTableStyle(score.getNormative()+"", size10font, high, true, true));
+                dataTable.addCell(pdfTableStyle(score.getNormativeDeduction()+"", size10font, high, true, true));
+            }
+            PdfPTable mergeTable = new PdfPTable(2);
+            float[] columnWidths3 = {9f, 1f};
+            mergeTable.setWidths(columnWidths3);
+            mergeTable.setWidthPercentage(100);
+            PdfPCell leftCell = new PdfPCell(dataTable);
+            mergeTable.addCell(leftCell);
+            PdfPCell rightCell = pdfTableStyle("66", size10font,scores.size() * high,true,true);
+            mergeTable.addCell(rightCell);
+            document.add(mergeTable);
+
+        }
+        document.close();
+        writer.close();
+        BladeFile bladeFile = newIOSSClient.uploadFile("ArchiveApp.pdf", fileUrl);
+        if (bladeFile == null || StringUtils.isBlank(bladeFile.getLink())) {
+            throw new ServiceException("上传PDF失败");
+        }
+        return bladeFile.getLink();
+    }
+
+    static void tableHeader(Document document,Font size17font) throws DocumentException {
+        //添加标题
+        //创建第一行表格
+        PdfPTable tableName = new PdfPTable(1);
+        tableName.setWidthPercentage(widthPercentage);  //设置标题长度占纸张比例
+        PdfPCell cell = pdfTableStyle("项目档案验收评分表", size17font,50, true, true);
+        //给表格赋值
+        tableName.addCell(cell);
+        //将表格添加到文档对象中
+        document.add(tableName);
+    }
+
+    static void tableUnit(Document document,Font size10font2,String unitName) throws Exception {
+        //单位名称
+        PdfPTable two = new PdfPTable(1);
+        two.setWidthPercentage(widthPercentage);
+        PdfPCell cell2 = pdfTableStyle2(unitName, size10font2,20, false, true);
+        cell2.setBackgroundColor(new BaseColor(231,230,230));
+        two.addCell(cell2);
+        document.add(two);
+    }
+
+    static PdfPCell pdfTableStyle(String content, Font font, int high, boolean isAlignCenter, boolean isAlignMidle) {
+        Paragraph phrase = new Paragraph(content, font);
+        phrase.setAlignment(Paragraph.ALIGN_LEFT);
+        PdfPCell pdfPCell = new PdfPCell(phrase);
+        pdfPCell.setMinimumHeight(high);
+        pdfPCell.setUseAscender(true); // 设置可以居中
+        if (isAlignCenter) {
+            pdfPCell.setHorizontalAlignment(PdfPCell.ALIGN_CENTER); // 设置水平居中
+        }else {
+            pdfPCell.setHorizontalAlignment(PdfPCell.ALIGN_LEFT); // 设置水平居中
+        }
+        if (isAlignMidle) {
+            pdfPCell.setVerticalAlignment(PdfPCell.ALIGN_MIDDLE); // 设置垂直居中
+        }else {
+            pdfPCell.setVerticalAlignment(PdfPCell.ALIGN_LEFT); // 设置垂直居中
+        }
+
+        return pdfPCell;
+    }
+
+    static PdfPCell pdfTableStyle2(String content, Font size10font2,int high, boolean isAlignCenter, boolean isAlignMiddle) throws Exception {
+        Paragraph phrase = new Paragraph(content, size10font2);
+        phrase.setAlignment(Paragraph.ALIGN_LEFT);
+        PdfPCell pdfPCell = new PdfPCell(phrase);
+        pdfPCell.setMinimumHeight(high);
+        pdfPCell.setUseAscender(true); // 设置可以居中
+        if (isAlignCenter) {
+            pdfPCell.setHorizontalAlignment(PdfPCell.ALIGN_CENTER); // 设置水平居中
+        }else {
+            pdfPCell.setHorizontalAlignment(PdfPCell.ALIGN_LEFT); // 设置水平居中
+        }
+        if (isAlignMiddle) {
+            pdfPCell.setVerticalAlignment(PdfPCell.ALIGN_MIDDLE); // 设置垂直居中
+        }else {
+            pdfPCell.setVerticalAlignment(PdfPCell.ALIGN_LEFT); // 设置垂直居中
+        }
+
+        return pdfPCell;
+    }
 }
 

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

@@ -36,6 +36,7 @@ import com.itextpdf.text.pdf.PdfWriter;
 import lombok.AllArgsConstructor;
 import lombok.extern.slf4j.Slf4j;
 import org.apache.commons.lang.StringUtils;
+import org.springblade.archive.dto.ArchiveWarningDTO;
 import org.springblade.archive.dto.SaveApplyDTO;
 import org.springblade.archive.entity.*;
 import org.springblade.archive.mapper.ArchiveConclusionMapper;
@@ -3160,6 +3161,9 @@ public class ArchivesAutoServiceImpl extends BaseServiceImpl<ArchivesAutoMapper,
 			String userName = AuthUtil.getNickName();
 			//获取档案信息,如果状态未未查阅则修改
 			ArchivesAuto archive = this.getById(archiveId);
+			if (archive == null || archive.getNodeId() == null){
+				throw new ServiceException("获取档案信息失败");
+			}
 			//查询当前案卷节点的合同段类型
 			Integer unitType;
 			if (archive.getContractId() == null || archive.getContractId() == -1){
@@ -3177,6 +3181,7 @@ public class ArchivesAutoServiceImpl extends BaseServiceImpl<ArchivesAutoMapper,
 			inspection.setArchiveId(archiveId);
 			inspection.setArchiveName(archive.getName());
 			inspection.setConclusionId(conclusionId);
+			inspection.setNodeId(archive.getNodeId());
 			inspectionService.save(inspection);
 		}
 
@@ -3197,6 +3202,9 @@ public class ArchivesAutoServiceImpl extends BaseServiceImpl<ArchivesAutoMapper,
 		String userName = AuthUtil.getNickName();
 		//获取档案信息,如果状态未未查阅则修改
 		ArchivesAuto archive = this.getById(inspection.getArchiveId());
+		if (archive == null || archive.getNodeId() == null){
+			throw new ServiceException("获取档案信息失败");
+		}
 		archive.setIsInspect(1);
 		//查询当前案卷节点的合同段类型
 		Integer unitType;
@@ -3218,6 +3226,7 @@ public class ArchivesAutoServiceImpl extends BaseServiceImpl<ArchivesAutoMapper,
 		inspection.setExpertName(userName);
 		inspection.setIsPass(isPass);
 		inspection.setUnitType(unitType);
+		inspection.setNodeId(archive.getNodeId());
 		//合格,专家对案卷没有意见
 		if (isPass == 1){
 			//判断当前档案是否存在合格意见,存在则直接跳过,不存在就重新保存
@@ -3507,6 +3516,15 @@ public class ArchivesAutoServiceImpl extends BaseServiceImpl<ArchivesAutoMapper,
 		return editCallback;
 	}
 
+	/**
+	 * 档案预警-分页查询
+	 */
+	@Override
+	public IPage<ArchiveWarningVO> warningPage(Query query, ArchiveWarningDTO dto) {
+
+		return null;
+	}
+
 
 	public void deleteFile(String defaultDir,Long id){
 		String dir = defaultDir+"/"+id;

+ 100 - 0
blade-service/blade-business/src/main/java/org/springblade/business/controller/EVisaTaskCheckController.java

@@ -13,8 +13,10 @@ import io.swagger.annotations.ApiImplicitParams;
 import io.swagger.annotations.ApiOperation;
 import lombok.AllArgsConstructor;
 import org.apache.commons.lang.StringUtils;
+import org.springblade.business.entity.ContractLog;
 import org.springblade.business.entity.FixedFlowLink;
 import org.springblade.business.entity.InformationQuery;
+import org.springblade.business.service.IContractLogService;
 import org.springblade.business.service.IFixedFlowLinkService;
 import org.springblade.business.service.IFixedFlowService;
 import org.springblade.business.service.IInformationQueryService;
@@ -66,6 +68,8 @@ public class EVisaTaskCheckController {
 
     private final ProjectClient projectClient;
 
+    private final IContractLogService logService;
+
 
     /**
      * 检查所选的流程环节处理人是否具有审批权限(三大填报页、日志列表的批量上报、首件列表的批量上报)
@@ -421,6 +425,102 @@ public class EVisaTaskCheckController {
         return R.data(flowPage);
     }
 
+        /**
+     * 获取符合条件的预设流程(三大填报页、日志列表的批量上报、首件列表的批量上报)
+     */
+    @PostMapping("/queryFixedFlow3")
+    @ApiOperationSupport(order = 5)
+    @ApiOperation(value = "获取符合条件的预设流程(三大填报页、日志列表的批量上报、首件列表的批量上报)")
+    @ApiImplicitParams({
+            @ApiImplicitParam(name = "contractId", value = "合同段ID", required = true),
+            @ApiImplicitParam(name = "nodeId", value = "当前节点PkeyId", required = true),
+            @ApiImplicitParam(name = "privatePKeyId", value = "表单列表中的isTypePrivatePid字段,集合形式"),
+            @ApiImplicitParam(name = "theLogPrimaryKeyId", value = "日志左侧所选的填报类型ID"),
+            @ApiImplicitParam(name = "firstId", value = "首件记录ID,列表批量上报时传任意一个即可")
+    })
+    public R<IPage<FixedFlowVO>> queryFixedFlow3(@RequestBody JSONObject json) {
+        //获取所有流程
+        FixedFlowVO vo = new FixedFlowVO();
+        vo.setCurrent(1);
+        vo.setSize(100);
+        vo.setContractId(json.getLong("contractId"));
+        vo.setProjectId(json.getLong("projectId"));
+
+        IPage<FixedFlowVO> flowPage = this.fixedFlowService.selectFixedFlowPage(vo);
+        List<FixedFlowVO> flowList = flowPage.getRecords();
+
+        //获取对应表格的所有电签配置
+        String logIds = json.getString("nodeId");
+        List<Long> longs = Func.toLongList(logIds);
+        ContractLog log = logService.getById(longs.get(0));
+        if (log == null || StringUtils.isBlank(log.getPdfUrl())) {
+            return R.fail(300, "当前节点还未生成PDF,不能上报");
+        }
+        List<JSONObject> jsonList = this.queryTableEVisaConfig(json, log.getPdfUrl());
+
+        if (jsonList == null || jsonList.size() == 0) {
+            return R.fail(300, "未找到符合电签配置的相关流程,请重新保存再上报");
+        }
+
+
+        //汇总电签配置的审批角色
+        List<String> eVisaRoleList = jsonList.stream().map(jsonObject -> jsonObject.getString("sigRoleId")).distinct().collect(Collectors.toList());
+
+        //校验这些预设流程哪些是符合条件的
+        for (FixedFlowVO next : flowList) {
+            //先将流程设置为可选
+            next.setDisabled(false);
+
+            //首先找到对应流程下的审批人组
+            List<FixedFlowLink> flowLink = this.fixedFlowLinkService.selectFixedFlowLink(next.getId().toString());
+            List<Long> ids = flowLink.stream().map(l -> l.getFixedFlowLinkUser()).collect(Collectors.toList());
+
+            //获取这些人资料合同段下的权限
+            List<JSONObject> userRoleList = this.saveUserInfoByProjectClient.queryUserContractRole(flowLink.stream().map(FixedFlowLink::getFixedFlowLinkUser).distinct().collect(Collectors.toList()), log.getContractId() + "");
+            if (userRoleList == null || userRoleList.size() <= 0) {
+                //查看当前项目下是否有监理合同段关联此合同段
+                String sql = "SELECT id from m_contract_info mci WHERE contract_type = 2 and id in (SELECT contract_id_jlyz  FROM m_contract_relation_jlyz WHERE contract_id_sg = " + log.getContractId() + ")";
+                ContractInfo contractInfo = jdbcTemplate.query(sql, new BeanPropertyRowMapper<>(ContractInfo.class)).stream().findAny().orElse(null);
+                if (contractInfo != null) {
+                    userRoleList = this.saveUserInfoByProjectClient.queryUserContractRole(ids, contractInfo.getId() + "");
+                }
+            }
+            if (userRoleList == null) {
+                next.setDisabled(true);
+            } else {
+                //校验流程
+                if (eVisaRoleList.size() >= userRoleList.size()) {
+                    //循环审批人的角色集合,并判断电签配置中是否含有这个角色
+                    for (JSONObject userRole : userRoleList) {
+                        if (!eVisaRoleList.contains(userRole.getString("roleId"))) {
+                            //但凡有个不符合条件,禁选
+                            next.setDisabled(true);
+                            //设置提示信息
+                            String name = jdbcTemplate.queryForObject(" select name from blade_user WHERE id = " + userRole.get("userId"), String.class);
+                            next.setTips(name + "没有电签权限,请检查电签配置或查看表单是否隐藏");
+                            break;
+                        }
+                    }
+                } else {
+                    //小于,反向判断
+                    List<String> userRoleIds = userRoleList.stream().map(jsonObject -> jsonObject.getString("roleId")).distinct().collect(Collectors.toList());
+                    for (String eVisaRole : eVisaRoleList) {
+                        if (!userRoleIds.contains(eVisaRole)) {
+                            //但凡有个不符合条件,禁选
+                            next.setDisabled(true);
+                            break;
+                        }
+                    }
+                }
+            }
+        }
+
+        //设置流程
+        flowPage.setRecords(flowList);
+
+        return R.data(flowPage);
+    }
+
     /**
      * 检查当前审批人是否存在证书
      */

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

@@ -2782,6 +2782,14 @@ public class CustomFunction {
         ( (List<Object>)stepSum(list)).forEach(System.out::println);
     }
 */
+     /*字符模版*/
+      public static Object strTemplate(String template,List<Object>data){
+          if(BaseUtils.isNotEmpty(template)) {
+              return data.stream().map(s -> template.replaceAll("\\{\\s*}", BaseUtils.handleNull(s))).collect(Collectors.toList());
+          }
+          return data;
+      }
+
 
 
 

+ 23 - 0
blade-service/blade-manager/src/main/java/com/mixsmart/utils/FormulaUtils.java

@@ -54,6 +54,7 @@ import org.springblade.manager.formula.impl.CompositeDataAccess;
 import org.springblade.manager.formula.impl.TableElementConverter;
 import org.springblade.manager.utils.FileUtils;
 import org.springblade.manager.vo.BaseInfo;
+import org.springblade.manager.vo.InterimPaymentCertificate;
 import org.springblade.manager.vo.WbsFormElementVO;
 import reactor.core.publisher.Mono;
 
@@ -389,6 +390,28 @@ public class FormulaUtils {
         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()
+                .filter(fd -> functionMap.containsKey(fd.getCode()))
+                .forEach(fd -> {
+                    List<Object> raw = functionMap.get(fd.getCode()).apply(dataList);
+                    raw.stream().map(ElementData::new).forEach(fd.getValues()::add);
+                });
+    }
+
+
+    /*根据数据模型对象,生成数据集合按字段获取数据的函数*/
+    public static <T> Map<String, Function<List<T>, List<Object>>> fieldDataFcMap(Class<T> clazz) {
+        Map<String, Function<T, Object>> fieldMap = functionMapBuilder(clazz);
+        Map<String, Function<List<T>, List<Object>>> functionMap = new HashMap<>();
+        for (Map.Entry<String, Function<T, Object>> functionEntry : fieldMap.entrySet()) {
+            Function<List<T>, List<Object>> mapper = list -> list.stream().map(functionEntry.getValue()).collect(Collectors.toList());
+            functionMap.put(functionEntry.getKey(), mapper);
+        }
+        return functionMap;
+    }
+
 
     /*数据模型按字段生成内容获取函数*/
     public static <T> Map<String,Function<T,Object>> functionMapBuilder(Class<T> clazz){

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

@@ -498,7 +498,7 @@ public class ArchiveTreeContractController extends BladeController {
      */
     @GetMapping("/startInspect")
     @ApiOperationSupport(order = 22)
-    @ApiOperation(value = "档案在线验收-开始抽检", notes = "返回true跳转初始化验收,返回false跳转档案初检")
+    @ApiOperation(value = "档案在线验收-开始抽检", notes = "返回true跳转分配验收,返回false跳转档案抽检")
     @ApiImplicitParams(value = {
             @ApiImplicitParam(name = "projectId", value = "项目id")
     })

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

@@ -22,19 +22,19 @@ public class ExecutorInit extends FormulaExecutor {
     public ExecutorInit(TableElementConverter tec) {
         super(tec);
     }
-    private  Function<Long, BaseInfo> getBaseInfo;
-    private  Function<Long, MeterPeriodInfo>  getMeterPeriod;
+    private  Function<Long, BaseInfo> baseInfoFc;
+    private  Function<Long, MeterPeriodInfo>  meterPeriodFc;
 
 
     public void handle() {
 
         /*加载合同数据*/
-        BaseInfo baseInfo = this.getBaseInfo.apply(tec.getContractId());
+        BaseInfo baseInfo = baseInfoFc.apply(tec.getContractId());
         tec.getConstantMap().put(BaseInfo.TBN,baseInfo);
         tec.formDataMap.putAll(FormulaUtils.toFormDataMap(baseInfo));
         if(MeterType.MATERIAL.equals(tec.getMeterType())||MeterType.START.equals(tec.getMeterType())){
             /*加载计量期信息*/
-            MeterPeriodInfo meterPeriod=getMeterPeriod.apply(tec.getPeriodId());
+            MeterPeriodInfo meterPeriod=meterPeriodFc.apply(tec.getPeriodId());
             tec.formDataMap.putAll(FormulaUtils.toFormDataMap(meterPeriod));
             tec.getConstantMap().put(MeterPeriodInfo.TBN,meterPeriod);
         }else if(MeterType.INTERIM.equals(tec.getMeterType())){

+ 94 - 23
blade-service/blade-manager/src/main/java/org/springblade/manager/formula/impl/ExecutorSpecial.java

@@ -1,24 +1,18 @@
 package org.springblade.manager.formula.impl;
 
-import com.alibaba.fastjson.annotation.JSONField;
 import com.mixsmart.utils.FormulaUtils;
 import com.mixsmart.utils.StringUtils;
-import io.swagger.models.auth.In;
 import lombok.Data;
 import lombok.EqualsAndHashCode;
+import org.springblade.common.utils.BaseUtils;
 import org.springblade.core.tool.utils.Func;
-import org.springblade.core.tool.utils.ReflectUtil;
 import org.springblade.core.tool.utils.StringPool;
 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 org.springblade.manager.vo.BaseInfo;
-import org.springblade.manager.vo.InterimPaymentCertificate;
-import org.springblade.manager.vo.Material;
-import org.springblade.manager.vo.MeterType;
+import org.springblade.manager.vo.*;
 
-import java.lang.reflect.Field;
+import java.math.BigDecimal;
 import java.util.*;
 import java.util.function.Function;
 import java.util.stream.Collectors;
@@ -32,7 +26,10 @@ import java.util.stream.IntStream;
 @EqualsAndHashCode(callSuper = true)
 @Data
 public class ExecutorSpecial extends FormulaExecutor {
-    private Function<Long, List<Material>> materialListFc;
+    private Function<Long, List<Material>> materialFormFc;
+    private Function<Long, MeterPeriodInfo> interimMeterPeriodFc;
+    private Function<Long, List<Payment>> paymentListFc;
+    private Function<Long, List<InventoryForm>> inventoryFormFc;
     public ExecutorSpecial(TableElementConverter tec) {
         super(tec);
     }
@@ -145,7 +142,7 @@ public class ExecutorSpecial extends FormulaExecutor {
             /*加载合同材料、材料清单*/
             /* b.material_name name,b.unit,b.price,a.meter_amount amount,a.material_source source
             ,material_conform  materialConform,a.storage_place storagePlace,a.storage_status storageStatus,a.storage_conform storageConform,a.remark*/
-            List<Material> materials = materialListFc.apply(tec.getPeriodId());
+            List<Material> materials = materialFormFc.apply(tec.getPeriodId());
             if(Func.isNotEmpty(materials)){
                 BaseInfo baseInfo= (BaseInfo) tec.getConstantMap().get(BaseInfo.TBN);
                 int n=1;
@@ -190,6 +187,7 @@ public class ExecutorSpecial extends FormulaExecutor {
 
     @Data
     public  class InterimPayCert implements Special{
+        private List<InventoryForm> chapters = new ArrayList<>();
 
         @Override
         public boolean ready() {
@@ -197,27 +195,100 @@ public class ExecutorSpecial extends FormulaExecutor {
         }
 
 
+
+        private Function<List<InventoryForm>, Map<String, BigDecimal[]>> contractMoneySum = data -> data.stream()
+                .collect(Collectors.groupingBy(
+                        form -> getPrefix(form.getFormNumber()),
+                        Collectors.reducing(
+                                new BigDecimal[]{BigDecimal.ZERO, BigDecimal.ZERO},
+                                form -> new BigDecimal[]{
+                                        form.getContractMoney() != null ? new BigDecimal(form.getContractMoney()) : BigDecimal.ZERO,
+                                        form.getChangeMoney() != null ? new BigDecimal(form.getChangeMoney()) : BigDecimal.ZERO
+                                },
+                                (total1, total2) -> new BigDecimal[]{total1[0].add(total2[0]), total1[1].add(total2[1])}
+                        )
+                ));
+
+       private  Function<List<Payment>, Map<String, BigDecimal>> moneySum= data-> data.stream()
+                .collect(Collectors.groupingBy(
+                        payment -> getPrefix(payment.getNumber()),
+                        LinkedHashMap::new,
+                        Collectors.reducing(BigDecimal.ZERO, Payment::getMoneyAsBigDecimal, BigDecimal::add)
+                ));
+
+
+
+        public String getPrefix(String fn){
+            for(InventoryForm itf:this.chapters){
+                String prefix=itf.getChapter();
+                if(fn.startsWith(prefix)){
+                    return prefix;
+                }
+            }
+            return fn;
+        }
+
         @Override
         public void parse() {
             LinkedHashMap<String,FormData> fdm = FormulaUtils.toFormDataMap(new InterimPaymentCertificate());
-            Map<String,Function<InterimPaymentCertificate,Object>> functionMap = FormulaUtils.functionMapBuilder(InterimPaymentCertificate.class);
             tec.getFormDataMap().putAll(fdm);
+
+            Map<String,Function<List<InterimPaymentCertificate>,List<Object>>> functionMap =FormulaUtils.fieldDataFcMap(InterimPaymentCertificate.class);
+
             List<InterimPaymentCertificate> dataList = new ArrayList<>();
             /*数据获取start*/
-            dataList.add(new InterimPaymentCertificate()) ;//测试,按照业务写,实际会复杂许多
-            //TODO
-            /*数据获取end*/
-            fdm.values().forEach(fd->{
-                List<Object> raw = dataList.stream().map(functionMap.get(fd.getCode())).filter(Func::isNotEmpty).collect(Collectors.toList());
-                if(raw.size()>0){
-                    List<ElementData> eds = fd.getValues();
-                    for(Object value:raw){
-                        eds.add(new ElementData(value));
-                    }
+              /*支付数据*/
+             List<Payment> paymentList=paymentListFc.apply(tec.getContractId());
+             /*计量期*/
+             MeterPeriodInfo periodInfo=interimMeterPeriodFc.apply(tec.getPeriodId());
+             /*合同计量清单*/
+             List<InventoryForm> inventoryForms = inventoryFormFc.apply(tec.getContractId());
+             InventoryForm root = null;
+             for(InventoryForm itf:inventoryForms){
+                 if(itf.getParentId()==0){
+                     root = itf;
+                     break;
+                 }
+             }
+            for(InventoryForm itf:inventoryForms){
+                assert root != null;
+                if(itf.getParentId().equals(root.getParentId())){
+                    chapters.add(itf);
                 }
-            });
+            }
+
+             if(Func.isNotEmpty(paymentList)){
+                 /*之前的计量期数据*/
+                 List<Payment>previous = paymentList.stream().filter(e->e.getSort()<periodInfo.getSort()).collect(Collectors.toList());
+                 /*当前计量期数据*/
+                 List<Payment>current = paymentList.stream().filter(e-> e.getSort().equals(periodInfo.getSort())).collect(Collectors.toList());
+                 /*往期每章节的实际花费*/
+                 Map<String,BigDecimal> previousMoney= this.moneySum.apply(previous);
+                 /*当前计量期每章节的实际花费*/
+                 Map<String,BigDecimal> currentMoney= this.moneySum.apply(current);
+                /*合同金额*/
+                 Map<String,BigDecimal[]> contractMoney = this.contractMoneySum.apply(inventoryForms);
+                 for(Map.Entry<String,BigDecimal[]> cm:contractMoney.entrySet()){
+                      InterimPaymentCertificate ipc = new InterimPaymentCertificate();
+                      BigDecimal[]  bmMoney =cm.getValue();
+                      ipc.setContractAmount(bmMoney[0].toString());
+                      ipc.setRevisedAmount(bmMoney[1].toString());
+                      ipc.setPreviousPeriodEndPay(previousMoney.getOrDefault(cm.getKey(),BigDecimal.ZERO).toString());
+                      ipc.setCurrentPeriodPay(currentMoney.getOrDefault(cm.getKey(),BigDecimal.ZERO).toString());
+                      /*由已知求未知*/
+                      ipc.calculate();
+                      dataList.add(ipc);
+                 }
+             }
+            /*数据获取end*/
+            /*本期实际支付合计计算*/
+            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);
 
         }
+
+
     }
 
 

+ 15 - 7
blade-service/blade-manager/src/main/java/org/springblade/manager/service/IFormulaDao.java

@@ -1,8 +1,8 @@
 package org.springblade.manager.service;
 
-import org.springblade.manager.vo.BaseInfo;
-import org.springblade.manager.vo.Material;
-import org.springblade.manager.vo.MeterPeriodInfo;
+import lombok.Data;
+import org.springblade.manager.vo.*;
+import org.springframework.beans.BeanUtils;
 
 import java.util.List;
 import java.util.Map;
@@ -10,9 +10,17 @@ import java.util.function.Function;
 
 public interface IFormulaDao {
     /**获取项目合同基础信息*/
-    Function<Long, BaseInfo> getBaseInfo();
-    /**获取计量段信息*/
-    Function<Long, MeterPeriodInfo> getMeterPeriod();
+    Function<Long, BaseInfo> getBaseInfoFc();
+    /**获取开工材料计量期*/
+    Function<Long, MeterPeriodInfo> getMeterPeriodFc();
     /**获取清单信息*/
-    Function<Long, List<Material>> getMaterialForm();
+    Function<Long, List<Material>> getMaterialFormFc();
+
+    /**获取中间计量期*/
+    Function<Long, MeterPeriodInfo> getInterimMeterPeriodFc();
+    /**获取支付数据*/
+    Function<Long, List<Payment>> getPaymentListFc();
+    /*获取合同计量清单*/
+    Function<Long,List<InventoryForm>> getInventoryFormFc();
+
 }

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

@@ -6,12 +6,11 @@ import org.springblade.core.tool.utils.BeanUtil;
 import org.springblade.core.tool.utils.Func;
 import org.springblade.manager.entity.ContractInfo;
 import org.springblade.manager.entity.ProjectInfo;
+import org.springblade.manager.entity.TrialSelfDataRecord;
 import org.springblade.manager.service.IContractInfoService;
 import org.springblade.manager.service.IFormulaDao;
 import org.springblade.manager.service.IProjectInfoService;
-import org.springblade.manager.vo.BaseInfo;
-import org.springblade.manager.vo.Material;
-import org.springblade.manager.vo.MeterPeriodInfo;
+import org.springblade.manager.vo.*;
 import org.springframework.beans.BeanUtils;
 import org.springframework.jdbc.core.BeanPropertyRowMapper;
 import org.springframework.jdbc.core.JdbcTemplate;
@@ -36,7 +35,7 @@ public class FormulaDaoImpl implements IFormulaDao {
     private final IProjectInfoService projectInfoService;
     private final JdbcTemplate jdbcTemplate;
     @Override
-    public Function<Long, BaseInfo> getBaseInfo() {
+    public Function<Long, BaseInfo> getBaseInfoFc() {
         return contractId->{
             ContractInfo info=  this.contractInfoService.getById(contractId);
             ProjectInfo projectInfo= projectInfoService.getById(info.getPId());
@@ -48,7 +47,7 @@ public class FormulaDaoImpl implements IFormulaDao {
     }
 
     @Override
-    public Function<Long,MeterPeriodInfo> getMeterPeriod(){
+    public Function<Long,MeterPeriodInfo> getMeterPeriodFc(){
         return id-> {
            List<MeterPeriodInfo> beans = this.jdbcTemplate.query("select b.period_number periodNumber,b.period_name periodName,a.print_date formPrintDate ,a.repayment_cause cause from s_material_start_statement a join  s_meter_period b on a.meter_period_id=b.id where a.id="+id, new BeanPropertyRowMapper<>(MeterPeriodInfo.class));
             if(beans.size()>0){
@@ -67,7 +66,7 @@ public class FormulaDaoImpl implements IFormulaDao {
     }
 
     @Override
-    public Function<Long, List<Material>> getMaterialForm() {
+    public Function<Long, List<Material>> getMaterialFormFc() {
         return id->{
             List<Map<String,Object>> mapList = this.jdbcTemplate.queryForList("select  b.material_name name,b.unit,b.price,a.meter_amount amount,meter_money sum,a.material_source source,material_conform  materialConform,a.storage_place storagePlace,a.storage_status storageStatus,a.storage_conform storageConform,a.remark from s_material_meter_form a left join s_contract_material b on a.contract_material_id = b.id where a.meter_period_id="+id+"  and a.is_deleted=0");
             if(Func.isNotEmpty(mapList)){
@@ -76,4 +75,36 @@ public class FormulaDaoImpl implements IFormulaDao {
             return Collections.emptyList();
         };
     }
+
+
+
+    @Override
+    public Function<Long, MeterPeriodInfo> getInterimMeterPeriodFc() {
+        return  id->{
+            String sql="SELECT period_number name,sort from s_contract_meter_period where id ="+id;
+            return this.jdbcTemplate.queryForObject(sql,new BeanPropertyRowMapper<>(MeterPeriodInfo.class));
+        };
+    }
+
+    @Override
+    public Function<Long, List<Payment>> getPaymentListFc() {
+        return contractId->{
+            String paySql="select a.form_number number,a.form_name name ,current_meter_money money,b.chapter_number chapter,b.contract_money contractMoney,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));
+        };
+    }
+
+    @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;
+           return getEntityList(sql,InventoryForm.class);
+        };
+    }
+
+    public <T> List<T> getEntityList(String sql, Class<T> entityClass) {
+        return  jdbcTemplate.query(sql, new BeanPropertyRowMapper<>(entityClass));
+    }
+
+
 }

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

@@ -2555,14 +2555,16 @@ public class FormulaServiceImpl extends BaseServiceImpl<FormulaMapper, Formula>
         List<FormulaHandleChain> formulaHandleChains = new ArrayList<>();
         /*初始化*/
         ExecutorInit init= new ExecutorInit(tec);
-        init.setGetBaseInfo(this.formulaDao.getBaseInfo());
-        init.setGetMeterPeriod(this.formulaDao.getMeterPeriod());
+        init.setBaseInfoFc(this.formulaDao.getBaseInfoFc());
+        init.setMeterPeriodFc(this.formulaDao.getMeterPeriodFc());
         formulaHandleChains.add(init);
         formulaHandleChains.add(new ExecutorSort(tec));
         formulaHandleChains.add(new ExecutorPre(tec));
         /*特殊公式*/
         ExecutorSpecial special = new ExecutorSpecial(tec);
-        special.setMaterialListFc(this.formulaDao.getMaterialForm());
+        special.setMaterialFormFc(this.formulaDao.getMaterialFormFc());
+        special.setInterimMeterPeriodFc(this.formulaDao.getInterimMeterPeriodFc());
+        special.setPaymentListFc(this.formulaDao.getPaymentListFc());
         formulaHandleChains.add(special);
         /*通用计算*/
         formulaHandleChains.add(new ExecutorCalc(tec));

+ 322 - 83
blade-service/blade-meter/src/main/java/org/springblade/meter/service/impl/MeterTreeContractServiceImpl.java

@@ -14,15 +14,14 @@ import org.springblade.core.tool.utils.BeanUtil;
 import org.springblade.core.tool.utils.ObjectUtil;
 import org.springblade.meter.dto.MeterTreeContractSaveBatchDTO;
 import org.springblade.meter.dto.MeterTreeContractSaveDTO;
-import org.springblade.meter.entity.ContractInventoryForm;
-import org.springblade.meter.entity.InventoryFormMeter;
-import org.springblade.meter.entity.MeterTreeContract;
-import org.springblade.meter.entity.MeterTreeProject;
+import org.springblade.meter.entity.*;
+import org.springblade.meter.mapper.ContractInventoryFormMapper;
 import org.springblade.meter.mapper.InventoryFormMeterMapper;
 import org.springblade.meter.mapper.MeterTreeContractMapper;
 import org.springblade.meter.mapper.MeterTreeProjectMapper;
 import org.springblade.meter.service.MeterTreeContractService;
 import org.springblade.meter.vo.ChangeNodeVO;
+import org.springblade.meter.vo.ContractFromVO;
 import org.springblade.meter.vo.MeterTreeContractVO;
 import org.springblade.system.entity.Dict;
 import org.springframework.jdbc.core.BeanPropertyRowMapper;
@@ -46,6 +45,7 @@ public class MeterTreeContractServiceImpl extends BaseServiceImpl<MeterTreeContr
     private final JdbcTemplate jdbcTemplate;
     private final MeterTreeProjectMapper meterTreeProjectMapper;
     private final InventoryFormMeterMapper inventoryFormMeterMapper;
+    private final ContractInventoryFormMapper contractInventoryFormMapper;
 
     @Override
     public Integer selectMaxSort(Long parentId) {
@@ -583,29 +583,101 @@ public class MeterTreeContractServiceImpl extends BaseServiceImpl<MeterTreeContr
             rootNodesImport.add(meterTreeContract);
         }
 
-        List<MeterTreeContract> resultNodeList = new ArrayList<>();
-        List<InventoryFormMeter> resultFormList = new ArrayList<>();
+        /*解析excel*/
         List<Map<String, String>> parseExcelFileToList = this.parseExcelFile(file);
+
+        /*节点新增*/
+        List<MeterTreeContract> resultNodeListAdd = new LinkedList<>();
+        /*节点金额修改Ids*/
+        Set<Long> updateNodeSet = new HashSet<>();
+        /*清单中间新增*/
+        List<InventoryFormMeter> resultFormListAdd = new LinkedList<>();
+        /*清单中间数量修改*/
+        List<InventoryFormMeter> resultFormListUpdate = new LinkedList<>();
+
+        /*导入节点的子级信息*/
+        List<Long> rootNodeIds = rootNodesImport.stream().map(MeterTreeContract::getId).collect(Collectors.toList());
+        List<MeterTreeContract> rootNodeChild = baseMapper.selectList(Wrappers.<MeterTreeContract>lambdaQuery().in(MeterTreeContract::getParentId, rootNodeIds).isNotNull(MeterTreeContract::getNodeCode));
+        Map<String, MeterTreeContract> rootNodeChildMap = rootNodeChild.stream().collect(Collectors.toMap(MeterTreeContract::getNodeCode, Function.identity()));
+        List<Long> rootNodeChildIds = rootNodeChild.stream().map(MeterTreeContract::getId).collect(Collectors.toList());
+        Map<Long, List<InventoryFormMeter>> inventoryFormMeterMapsGroupByContractMeterId = new HashMap<>();
+        Map<String, InventoryFormMeter> inventoryFormMeterMapsByFormIdAndMeterId = new HashMap<>();
+        Map<String, ChangeTokenInventory> changeTokenInventoryMapsByFormIdAndMeterId = new HashMap<>();
+        Map<String, InventoryFormApply> inventoryFormApplyMapsByFormIdAndMeterId = new HashMap<>();
+        if (rootNodeChildIds.size() > 0) {
+            /*子级的中间表关联的清单信息*/
+            List<InventoryFormMeter> query = jdbcTemplate.query("SELECT * FROM s_inventory_form_meter WHERE is_deleted = 0" +
+                            " AND contract_id = " + meterTreeContract.getContractId() +
+                            " AND contract_meter_id IN(" + StringUtils.join(rootNodeChildIds, ",") + ")",
+                    new BeanPropertyRowMapper<>(InventoryFormMeter.class));
+            inventoryFormMeterMapsGroupByContractMeterId = query.stream().collect(Collectors.groupingBy(InventoryFormMeter::getContractMeterId));
+            inventoryFormMeterMapsByFormIdAndMeterId =
+                    query.stream()
+                            .collect(Collectors.toMap(
+                                    meter -> meter.getContractFormId() + ":" + meter.getContractMeterId(),
+                                    Function.identity()
+                            ));
+
+            /*变更令引用*/
+            List<ChangeTokenInventory> query1 = jdbcTemplate.query("SELECT contract_meter_id,contract_form_id FROM s_change_token_inventory WHERE is_deleted = 0" +
+                            " AND contract_id = " + meterTreeContract.getContractId() +
+                            " AND contract_meter_id IN(" + StringUtils.join(rootNodeChildIds, ",") + ")",
+                    new BeanPropertyRowMapper<>(ChangeTokenInventory.class));
+            changeTokenInventoryMapsByFormIdAndMeterId =
+                    query1.stream()
+                            .collect(Collectors.toMap(
+                                    change -> change.getContractFormId() + ":" + change.getContractMeterId(),
+                                    Function.identity()
+                            ));
+
+            /*中间计量引用*/
+            List<InventoryFormApply> query2 = jdbcTemplate.query("SELECT contract_meter_id,contract_form_id FROM s_inventory_form_apply WHERE is_deleted = 0" +
+                            " AND contract_id = " + meterTreeContract.getContractId() +
+                            " AND contract_meter_id IN(" + StringUtils.join(rootNodeChildIds, ",") + ")",
+                    new BeanPropertyRowMapper<>(InventoryFormApply.class));
+            inventoryFormApplyMapsByFormIdAndMeterId =
+                    query2.stream()
+                            .collect(Collectors.toMap(
+                                    inventoryFormApply -> inventoryFormApply.getContractFormId() + ":" + inventoryFormApply.getContractMeterId(),
+                                    Function.identity()
+                            ));
+        }
+
+        /*桩号类型*/
         Map<String, String> meterStakeTypeMaps = jdbcTemplate.query("SELECT dict_key,dict_value FROM blade_dict WHERE is_deleted = 0 AND code = 'meter_stake_type'", new BeanPropertyRowMapper<>(Dict.class)).stream().collect(Collectors.toMap(Dict::getDictValue, Dict::getDictKey));
-        Map<String, ContractInventoryForm> contractInventoryFormMaps = jdbcTemplate.query("SELECT id,change_price,form_number FROM s_contract_inventory_form WHERE is_deleted = 0 AND contract_id = " + meterTreeContract.getContractId(), new BeanPropertyRowMapper<>(ContractInventoryForm.class)).stream().collect(Collectors.toMap(ContractInventoryForm::getFormNumber, Function.identity()));
+
+        /*清单信息*/
+        List<ContractInventoryForm> query = jdbcTemplate.query("SELECT id,change_price,form_number FROM s_contract_inventory_form WHERE is_deleted = 0 AND contract_id = " + meterTreeContract.getContractId(), new BeanPropertyRowMapper<>(ContractInventoryForm.class));
+        Map<String, ContractInventoryForm> contractInventoryFormMapsByFormNumber = query.stream().collect(Collectors.toMap(ContractInventoryForm::getFormNumber, Function.identity()));
+        Map<Long, ContractInventoryForm> contractInventoryFormMapsById = query.stream().collect(Collectors.toMap(ContractInventoryForm::getId, Function.identity()));
+
         Map<String, List<Map<String, String>>> rootCodeMaps = parseExcelFileToList.stream()
                 .collect(Collectors.groupingBy(
                         map -> map.get("工程编号"),
                         LinkedHashMap::new,
-                        Collectors.toList()
-                ));
+                        Collectors.toList()));
+
         for (MeterTreeContract treeContract : rootNodesImport) {
+
+            /*工程编号匹配*/
             List<Map<String, String>> projectCodeGroup = rootCodeMaps.getOrDefault(treeContract.getNodeCode(), null);
+
             if (ObjectUtil.isNotEmpty(projectCodeGroup)) {
+
                 Map<String, List<Map<String, String>>> nodeCodeGroup = projectCodeGroup.stream()
                         .collect(Collectors.groupingBy(
                                 map -> map.get("节点编号"),
                                 LinkedHashMap::new,
-                                Collectors.toList()
-                        ));
+                                Collectors.toList()));
+                nodeCodeGroup.values().forEach(list -> list.forEach(map -> map.entrySet().removeIf(entry -> entry.getKey().isEmpty())));
+
                 int sort = 1;
+
+                /*节点编号匹配*/
                 for (Map.Entry<String, List<Map<String, String>>> listEntry : nodeCodeGroup.entrySet()) {
+
                     String nodeCode = listEntry.getKey();
+
                     List<Map<String, String>> rows = listEntry.getValue().stream()
                             .sorted(Comparator.comparing(map -> {
                                 String formCode = map.get("清单编号");
@@ -614,108 +686,275 @@ public class MeterTreeContractServiceImpl extends BaseServiceImpl<MeterTreeContr
                     long nullFormCodeCount = rows.stream()
                             .filter(map -> ObjectUtil.isEmpty(map.get("清单编号")))
                             .count();
+                    if (nullFormCodeCount == 0) {
+                        throw new RuntimeException("节点编号【" + nodeCode + "】没有清单编号为空的数据,请确认至少有一条");
+                    }
                     if (nullFormCodeCount > 1) {
                         throw new RuntimeException("节点编号【" + nodeCode + "】存在多条清单编号为空的数据,请确认是否只有一条");
                     }
 
-                    MeterTreeContract obj = new MeterTreeContract();
-                    Long nodeId = SnowFlakeUtil.getId();
-                    BigDecimal money = BigDecimal.ZERO;
-                    BigDecimal moneyChange = BigDecimal.ZERO;
+                    MeterTreeContract orDefault = rootNodeChildMap.getOrDefault(nodeCode, null);
 
-                    for (Map<String, String> map : rows) {
-                        String currCode = map.get("节点编号");
-                        if (currCode.equals(nodeCode)) {
-                            String formCode = map.get("清单编号");
-                            String nodeName = map.get("工程名称");
-                            String buildPictureTotal = map.get("施工图数量");
-                            String stakeType = map.get("桩号类型");
-                            String startStake = map.get("起始桩号");
-                            String endStake = map.get("结束桩号");
-                            String contractPicture = map.get("合同图号");
-                            String remarks = map.get("备注");
-
-                            //节点
-                            if (ObjectUtil.isEmpty(formCode)) {
-                                obj.setId(nodeId);
-                                obj.setParentId(treeContract.getId());
-                                obj.setAncestor(treeContract.getAncestor() + "," + obj.getParentId());
-                                obj.setNodeName(nodeName);
-                                obj.setNodeCode(currCode);
-                                obj.setUpdateStatus(0);
-                                obj.setSort(sort);
-                                if (ObjectUtil.isNotEmpty(stakeType)) {
-                                    String upperCase = stakeType.toUpperCase();
-                                    String key = meterStakeTypeMaps.getOrDefault(upperCase, null);
-                                    if (key != null) {
-                                        obj.setStakeType(Integer.parseInt(key));
+                    /*不存在节点编号,新增节点、清单*/
+                    if (orDefault == null) {
+                        MeterTreeContract obj = new MeterTreeContract();
+                        Long nodeId = SnowFlakeUtil.getId();
+                        BigDecimal money = BigDecimal.ZERO;
+                        BigDecimal moneyChange = BigDecimal.ZERO;
+
+                        for (Map<String, String> map : rows) {
+                            String currCode = map.get("节点编号");
+                            if (currCode.equals(nodeCode)) {
+                                String formCode = map.get("清单编号");
+                                String nodeName = map.get("工程名称");
+                                String buildPictureTotal = map.get("施工图数量");
+                                String stakeType = map.get("桩号类型");
+                                String startStake = map.get("起始桩号");
+                                String endStake = map.get("结束桩号");
+                                String contractPicture = map.get("合同图号");
+                                String remarks = map.get("备注");
+
+                                //节点
+                                if (ObjectUtil.isEmpty(formCode)) {
+                                    obj.setId(nodeId);
+                                    obj.setParentId(treeContract.getId());
+                                    obj.setAncestor(treeContract.getAncestor() + "," + obj.getParentId());
+                                    obj.setNodeName(nodeName);
+                                    obj.setNodeCode(currCode);
+                                    obj.setUpdateStatus(0);
+                                    obj.setSort(sort);
+
+                                    /*获取父节点下一级类型,如果父节点是最大类型6,那么默认最大6*/
+                                    if (ObjectUtil.isNotEmpty(treeContract.getNodeType())) {
+                                        obj.setNodeType(treeContract.getNodeType().equals(6) ? 6 : treeContract.getNodeType() + 1);
+                                    }
+
+                                    if (ObjectUtil.isNotEmpty(stakeType)) {
+                                        String upperCase = stakeType.toUpperCase();
+                                        String key = meterStakeTypeMaps.getOrDefault(upperCase, null);
+                                        if (key != null) {
+                                            obj.setStakeType(Integer.parseInt(key));
+                                        }
+                                    }
+                                    obj.setStartStake(startStake);
+                                    obj.setEndStake(endStake);
+                                    obj.setContractPicture(contractPicture);
+                                    obj.setRemarks(remarks);
+
+                                    obj.setTemplateId(treeContract.getTemplateId());
+                                    obj.setProjectId(treeContract.getProjectId());
+                                    obj.setContractId(treeContract.getContractId());
+
+                                    obj.setDataSourceType(4); //导入
+
+                                } else {
+                                    //清单
+                                    ContractInventoryForm contractInventoryForm = contractInventoryFormMapsByFormNumber.getOrDefault(formCode, null);
+                                    if (contractInventoryForm != null) {
+                                        InventoryFormMeter objForm = new InventoryFormMeter();
+                                        objForm.setId(SnowFlakeUtil.getId());
+                                        objForm.setProjectId(treeContract.getProjectId());
+                                        objForm.setContractId(treeContract.getContractId());
+
+                                        if (ObjectUtil.isNotEmpty(SecureUtil.getUser())) {
+                                            objForm.setCreateUser(SecureUtil.getUserId());
+                                            objForm.setUpdateUser(SecureUtil.getUserId());
+                                            if (SecureUtil.getDeptId().contains(",")) {
+                                                objForm.setCreateDept(Long.parseLong(SecureUtil.getDeptId().split(",")[0]));
+                                            } else {
+                                                objForm.setCreateDept(Long.parseLong(SecureUtil.getDeptId()));
+                                            }
+                                        }
+
+                                        objForm.setContractMeterId(nodeId);
+                                        objForm.setContractFormId(contractInventoryForm.getId());
+
+                                        objForm.setBuildPictureTotal(this.parseString(buildPictureTotal));
+                                        objForm.setChangeBuildPictureTotal(objForm.getBuildPictureTotal());
+                                        objForm.setBuildPictureMoney(objForm.getBuildPictureTotal().multiply(contractInventoryForm.getChangePrice())); //数量*变更后单价
+                                        objForm.setChangeBuildPictureMoney(objForm.getBuildPictureMoney());
+
+                                        /*计量单元节点金额相关累加*/
+                                        money = money.add(objForm.getBuildPictureMoney());
+                                        moneyChange = moneyChange.add(objForm.getChangeBuildPictureMoney());
+
+                                        resultFormListAdd.add(objForm);
                                     }
                                 }
-                                obj.setStartStake(startStake);
-                                obj.setEndStake(endStake);
-                                obj.setContractPicture(contractPicture);
-                                obj.setRemarks(remarks);
+                            }
+                        }
+
+                        obj.setBuildPictureMoney(money);
+                        obj.setChangeMoney(moneyChange);
+                        resultNodeListAdd.add(obj);
+                        sort++;
+
+                    } else {
+                        /*存在节点编号,只同步累加或者新增清单*/
+                        /*获取该节点的原始的清单中间信息*/
+                        List<InventoryFormMeter> inventoryFormMeters = inventoryFormMeterMapsGroupByContractMeterId.get(orDefault.getId());
+                        Map<String, ContractInventoryForm> ysContractInventoryFormMapsByFormNumber = new HashMap<>();
+                        for (InventoryFormMeter objForm : inventoryFormMeters) {
+                            /*获取原始清单详细详细*/
+                            ContractInventoryForm contractInventoryForm = contractInventoryFormMapsById.getOrDefault(objForm.getContractFormId(), null);
+                            if (contractInventoryForm != null) {
+                                ysContractInventoryFormMapsByFormNumber.put(contractInventoryForm.getFormNumber(), contractInventoryForm);
+                            }
+                        }
+
+                        for (Map<String, String> map : rows) {
+                            String formCode = map.get("清单编号");
+                            if (formCode.isEmpty()) {
+                                continue;
+                            }
+                            String buildPictureTotal = map.get("施工图数量");
+
+                            /*获取原始清单详细详细*/
+                            ContractInventoryForm contractInventoryForm = ysContractInventoryFormMapsByFormNumber.getOrDefault(formCode, null);
+                            if (contractInventoryForm != null) {
+                                //相同清单编号,则同步累加
+                                if (contractInventoryForm.getFormNumber().equals(formCode)) {
+                                    /*获取到对应的中间关联清单信息*/
+                                    String key = contractInventoryForm.getId() + ":" + orDefault.getId();
+                                    InventoryFormMeter formUpdate = inventoryFormMeterMapsByFormIdAndMeterId.getOrDefault(key, null);
+                                    if (formUpdate != null) {
+
+                                        /*判断是否被引用、变更*/
+                                        ChangeTokenInventory orDefault1 = changeTokenInventoryMapsByFormIdAndMeterId.getOrDefault(key, null);
+                                        InventoryFormApply orDefault2 = inventoryFormApplyMapsByFormIdAndMeterId.getOrDefault(key, null);
+                                        if (orDefault1 != null || orDefault2 != null) {
+                                            continue;
+                                        }
 
-                                obj.setTemplateId(treeContract.getTemplateId());
-                                obj.setProjectId(treeContract.getProjectId());
-                                obj.setContractId(treeContract.getContractId());
+                                        //累加
+                                        BigDecimal bigDecimal = this.parseString(buildPictureTotal);
+                                        formUpdate.setBuildPictureTotal(formUpdate.getBuildPictureTotal().add(bigDecimal));
 
-                                obj.setDataSourceType(4); //导入
+                                        formUpdate.setChangeBuildPictureTotal(formUpdate.getBuildPictureTotal());
+
+                                        formUpdate.setBuildPictureMoney(formUpdate.getBuildPictureTotal().multiply(contractInventoryForm.getChangePrice())); //数量*变更后单价
+
+                                        formUpdate.setChangeBuildPictureMoney(formUpdate.getBuildPictureMoney());
+
+                                        /*更改数量*/
+                                        resultFormListUpdate.add(formUpdate);
+
+                                        /*更新节点金额*/
+                                        updateNodeSet.add(orDefault.getId());
+
+                                    }
+                                }
 
                             } else {
-                                //清单
-                                ContractInventoryForm contractInventoryForm = contractInventoryFormMaps.getOrDefault(formCode, null);
-                                if (contractInventoryForm != null) {
-                                    InventoryFormMeter objForm = new InventoryFormMeter();
-                                    objForm.setId(SnowFlakeUtil.getId());
-                                    objForm.setProjectId(treeContract.getProjectId());
-                                    objForm.setContractId(treeContract.getContractId());
+
+                                //没有获取到,那么证明是不相同清单编号,则获取对应的清单数据,进行新增清单
+                                ContractInventoryForm contractInventoryFormAdd = contractInventoryFormMapsByFormNumber.getOrDefault(formCode, null);
+                                if (contractInventoryFormAdd != null) {
+                                    InventoryFormMeter formAdd = new InventoryFormMeter();
+                                    formAdd.setId(SnowFlakeUtil.getId());
+                                    formAdd.setProjectId(orDefault.getProjectId());
+                                    formAdd.setContractId(orDefault.getContractId());
 
                                     if (ObjectUtil.isNotEmpty(SecureUtil.getUser())) {
-                                        objForm.setCreateUser(SecureUtil.getUserId());
-                                        objForm.setUpdateUser(SecureUtil.getUserId());
+                                        formAdd.setCreateUser(SecureUtil.getUserId());
+                                        formAdd.setUpdateUser(SecureUtil.getUserId());
                                         if (SecureUtil.getDeptId().contains(",")) {
-                                            objForm.setCreateDept(Long.parseLong(SecureUtil.getDeptId().split(",")[0]));
+                                            formAdd.setCreateDept(Long.parseLong(SecureUtil.getDeptId().split(",")[0]));
                                         } else {
-                                            objForm.setCreateDept(Long.parseLong(SecureUtil.getDeptId()));
+                                            formAdd.setCreateDept(Long.parseLong(SecureUtil.getDeptId()));
                                         }
                                     }
 
-                                    objForm.setContractMeterId(nodeId);
-                                    objForm.setContractFormId(contractInventoryForm.getId());
+                                    formAdd.setContractMeterId(orDefault.getId());
+                                    formAdd.setContractFormId(contractInventoryFormAdd.getId());
+
+                                    formAdd.setBuildPictureTotal(this.parseString(buildPictureTotal));
+                                    formAdd.setChangeBuildPictureTotal(formAdd.getBuildPictureTotal());
+                                    formAdd.setBuildPictureMoney(formAdd.getBuildPictureTotal().multiply(contractInventoryFormAdd.getChangePrice())); //数量*变更后单价
+                                    formAdd.setChangeBuildPictureMoney(formAdd.getBuildPictureMoney());
 
-                                    objForm.setBuildPictureTotal(this.parseString(buildPictureTotal));
-                                    objForm.setChangeBuildPictureTotal(objForm.getBuildPictureTotal());
-                                    objForm.setBuildPictureMoney(objForm.getBuildPictureTotal().multiply(contractInventoryForm.getChangePrice())); //数量*变更后单价
-                                    objForm.setChangeBuildPictureMoney(objForm.getBuildPictureMoney());
+                                    /*新增清单*/
+                                    resultFormListAdd.add(formAdd);
 
-                                    /*计量单元节点金额相关累加*/
-                                    money = money.add(objForm.getBuildPictureMoney());
-                                    moneyChange = moneyChange.add(objForm.getChangeBuildPictureMoney());
+                                    /*更新节点金额*/
+                                    updateNodeSet.add(orDefault.getId());
 
-                                    resultFormList.add(objForm);
                                 }
                             }
                         }
                     }
-                    obj.setBuildPictureMoney(money);
-                    obj.setChangeMoney(moneyChange);
-                    resultNodeList.add(obj);
-                    sort++;
                 }
             }
         }
-        if (resultNodeList.size() > 0) {
-            this.saveBatch(resultNodeList, 1000);
-            if (resultFormList.size() > 0) {
-                inventoryFormMeterMapper.batchInsert(resultFormList);
-                /*for (InventoryFormMeter inventoryFormMeter : resultFormList) {
-                    inventoryFormMeterMapper.insert(inventoryFormMeter);
-                }*/
+
+        boolean var = false;
+
+        /*节点*/
+        if (resultNodeListAdd.size() > 0) {
+            this.saveBatch(resultNodeListAdd, 1000);
+            var = true;
+        }
+
+        /*清单中间新增*/
+        if (resultFormListAdd.size() > 0) {
+            inventoryFormMeterMapper.batchInsert(resultFormListAdd);
+            /*for (InventoryFormMeter inventoryFormMeter : resultFormListAdd) {
+                inventoryFormMeterMapper.insert(inventoryFormMeter);
+            }*/
+            var = true;
+        }
+
+        /*清单中间数量修改*/
+        if (resultFormListUpdate.size() > 0) {
+            for (InventoryFormMeter inventoryFormMeter : resultFormListUpdate) {
+                String sql = "UPDATE s_inventory_form_meter " +
+                        "SET build_picture_total = ? ," +
+                        "change_build_picture_total = ? ," +
+                        "build_picture_money = ? ," +
+                        "change_build_picture_money = ? WHERE id = ?";
+                jdbcTemplate.update(sql,
+                        inventoryFormMeter.getBuildPictureTotal(),
+                        inventoryFormMeter.getChangeBuildPictureTotal(),
+                        inventoryFormMeter.getBuildPictureMoney(),
+                        inventoryFormMeter.getChangeBuildPictureMoney(),
+                        inventoryFormMeter.getId());
             }
-            return true;
+            var = true;
         }
-        return false;
+
+        /*节点金额修改*/
+        if (updateNodeSet.size() > 0) {
+            for (Long treeContractId : updateNodeSet) {
+                /*重新计算节点下的清单数量金额等*/
+                List<ContractFromVO> decompositionList = contractInventoryFormMapper.getNodeResolveForm(meterTreeContract.getContractId(), treeContractId);
+                if (ObjectUtil.isNotEmpty(decompositionList) && decompositionList.size() > 0) {
+                    BigDecimal moneyAll = BigDecimal.ZERO;
+                    BigDecimal moneyChangeAll = BigDecimal.ZERO;
+
+                    for (ContractFromVO contractFromVO : decompositionList) {
+                        BigDecimal buildPictureTotal = contractFromVO.getBuildPictureTotal(); //变更前数量
+                        BigDecimal changeBuildPictureTotal = contractFromVO.getChangeBuildPictureTotal(); //变更后数量
+                        BigDecimal currentPrice = contractFromVO.getCurrentPrice(); //单价
+
+                        BigDecimal buildPictureMoney = buildPictureTotal.multiply(currentPrice); //变更前金额
+                        BigDecimal changeBuildPictureMoney = changeBuildPictureTotal.multiply(currentPrice); //变更后金额
+
+                        moneyAll = moneyAll.add(buildPictureMoney);
+                        moneyChangeAll = moneyChangeAll.add(changeBuildPictureMoney);
+                    }
+
+                    String sql = "UPDATE s_meter_tree_contract " +
+                            "SET build_picture_money = ?, " +
+                            "change_money = ? WHERE id = ?";
+                    jdbcTemplate.update(sql,
+                            moneyAll,
+                            moneyChangeAll,
+                            treeContractId);
+                }
+                var = true;
+            }
+        }
+        return var;
     }
 
     /**