瀏覽代碼

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

huangtf 1 年之前
父節點
當前提交
b574c63f0f
共有 16 個文件被更改,包括 391 次插入39 次删除
  1. 2 1
      blade-common/src/main/java/org/springblade/common/constant/CommonConstant.java
  2. 3 0
      blade-service-api/blade-meter-api/src/main/java/org/springblade/meter/vo/InventoryFormMeterVO.java
  3. 0 2
      blade-service/blade-manager/src/main/java/org/springblade/manager/controller/ExcelTabController.java
  4. 1 0
      blade-service/blade-manager/src/main/java/org/springblade/manager/formula/impl/ExecutorInit.java
  5. 44 11
      blade-service/blade-manager/src/main/java/org/springblade/manager/formula/impl/ExecutorMeter.java
  6. 4 0
      blade-service/blade-manager/src/main/java/org/springblade/manager/formula/impl/MeterElementWriter.java
  7. 4 3
      blade-service/blade-manager/src/main/java/org/springblade/manager/service/impl/ExcelTabServiceImpl.java
  8. 1 1
      blade-service/blade-manager/src/main/java/org/springblade/manager/service/impl/FormulaServiceImpl.java
  9. 9 3
      blade-service/blade-manager/src/main/java/org/springblade/manager/service/impl/WbsFormElementServiceImpl.java
  10. 0 1
      blade-service/blade-meter/src/main/java/org/springblade/meter/controller/MeterTreeController.java
  11. 29 9
      blade-service/blade-meter/src/main/java/org/springblade/meter/controller/TaskController.java
  12. 5 2
      blade-service/blade-meter/src/main/java/org/springblade/meter/mapper/InventoryFormMeterMapper.java
  13. 8 0
      blade-service/blade-meter/src/main/java/org/springblade/meter/mapper/InventoryFormMeterMapper.xml
  14. 4 1
      blade-service/blade-meter/src/main/java/org/springblade/meter/mapper/MeterTreeContractMapper.java
  15. 4 0
      blade-service/blade-meter/src/main/java/org/springblade/meter/mapper/MeterTreeContractMapper.xml
  16. 273 5
      blade-service/blade-meter/src/main/java/org/springblade/meter/service/impl/MeterTreeContractServiceImpl.java

+ 2 - 1
blade-common/src/main/java/org/springblade/common/constant/CommonConstant.java

@@ -59,9 +59,10 @@ public interface CommonConstant {
     String DEFAULT_PARAM_PASSWORD = "account.initPassword";
 
     String SYS_LOCAL_URL = "sys.local.url";
+    //计量wbs 主键Id值
+    String SYS_MEASURE_IDS = "sys.measure.ids";
 
     String SYS_FILE_NET_URL = "sys.file.net.url";
-
     String SYS_USER_TASK_BATCH = "sys.user.task.batch";
 
     String JL_THE_LOG = "JL.theLog";

+ 3 - 0
blade-service-api/blade-meter-api/src/main/java/org/springblade/meter/vo/InventoryFormMeterVO.java

@@ -37,4 +37,7 @@ public class InventoryFormMeterVO extends InventoryFormMeter {
 	@ApiModelProperty(value = "当前部位当前清单当前计量总和")
 	private BigDecimal allMeterMoney;
 
+	@ApiModelProperty(value = "清单编号")
+	private String formNumber;
+
 }

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

@@ -537,9 +537,7 @@ public class ExcelTabController extends BladeController {
         WbsTreePrivate wbsTree = new WbsTreePrivate();
         wbsTree.setPKeyId(tabId);
         WbsTreePrivate aPrivate = wbsTreePrivateService.getOne(Condition.getQueryWrapper(wbsTree));
-
         aPrivate.setExcelId(exceTabId);
-
         // 获取excel 基本信息
         ExcelTab excelTab = excelTabService.getById(exceTabId);
 

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

@@ -45,6 +45,7 @@ public class ExecutorInit extends FormulaExecutor {
         }else if(MeterType.INTERIM.equals(tec.getMeterType())){
             /*计量期*/
             tec.periodInfo=interimMeterPeriodFc.apply(tec.getReportId());
+            tec.periodInfo.setPeriodName(tec.periodInfo.getPeriodNumber());
             /*计量单元树*/
             tec.setMeterTreeMap(getMeterTreeMapAsync(tec.getContractId()));
         }

+ 44 - 11
blade-service/blade-manager/src/main/java/org/springblade/manager/formula/impl/ExecutorMeter.java

@@ -39,7 +39,7 @@ public class ExecutorMeter extends FormulaExecutor {
     private Function<Long, List<MeterApply>> meterApplyFc;
     private Function<Long, List<StartPayForm>> stayPayFormFc;
     private ElementWriter elementWriter;
-    /*执行链*/
+    /**执行链*/
     private List<Special> specialList = new ArrayList<>();
     /**支付章节*/
     private List<InventoryForm> chapters = new ArrayList<>();
@@ -47,6 +47,8 @@ public class ExecutorMeter extends FormulaExecutor {
     private List<Payment>  previous =new ArrayList<>();
     /**本期支付信息*/
     private List<Payment>   current =new ArrayList<>();
+    /**累计到本期末支付信息*/
+    private List<Payment>   paymentsPeriodEnd =new ArrayList<>();
 
     private List<InterimPaymentCertificate> interimPaymentCertificates =new ArrayList<>();
     /*求百分比*/
@@ -239,8 +241,10 @@ public class ExecutorMeter extends FormulaExecutor {
                        List<Object> dl= groupData.get(i);
                        FormData fd= fds.get(i);
                        /*计算完结*/
-                       fd.setFinished(true);
-                       elementWriter.write(fd,dl);
+                       if(fd!=null){ //由于计算为null 导致设置报错
+                           fd.setFinished(true);
+                           elementWriter.write(fd,dl);
+                       }
                    }
                 }
                 Integer sort = materials.get(0).getSort();
@@ -262,11 +266,8 @@ public class ExecutorMeter extends FormulaExecutor {
                         elementWriter.write(fdm.get(MaterialAdvancePayment.TBN+":key_3"),StringUtils.number2String(total,2));
                     }
                 }
-
-
             }
         }
-
     }
 
 
@@ -330,6 +331,8 @@ public class ExecutorMeter extends FormulaExecutor {
                  previous = paymentList.stream().filter(e->e.getSort()<tec.periodInfo.getSort()).collect(Collectors.toList());
                  /*当前计量期数据*/
                  current = paymentList.stream().filter(e-> e.getSort().equals(tec.periodInfo.getSort())).collect(Collectors.toList());
+                 /*累计到本期末*/
+                 paymentsPeriodEnd=paymentList.stream().filter(e->e.getSort()<=tec.periodInfo.getSort()).collect(Collectors.toList());
                  /*往期每章节的实际花费*/
                  Map<String,BigDecimal> previousMoney= this.moneySum.apply(previous);
                  /*当前计量期每章节的实际花费*/
@@ -521,7 +524,38 @@ public class ExecutorMeter extends FormulaExecutor {
             LinkedHashMap<String,Summary> currentSummary = toSummary(current);
             LinkedHashMap<String,Summary> preSummary = toSummary(previous);
             List<SubprojectInterimPaymentSummary> totalList = new ArrayList<>();
-            for(Map.Entry<String,Summary> form:currentSummary.entrySet()){
+            List<String> numbers=  paymentsPeriodEnd.stream().map(Payment::getNumber).distinct().collect(Collectors.toList());
+            numbers.forEach(number->{
+                Summary pre =preSummary.get(number);
+                Summary cur = currentSummary.get(number);
+                SubprojectInterimPaymentSummary sis = new SubprojectInterimPaymentSummary();
+                Summary main =cur;
+                if(main==null)main=pre;
+                sis.setFormNumber(main.getFormNumber());
+                sis.setItemName(main.getItemName());
+                sis.setUnit(main.getUnit());
+                sis.setContractTotal(main.getContractTotal().toString());
+                sis.setChangeTotal(main.getChangeTotal().toString());
+                sis.setContractMoney(main.getContractMoney().toString());
+                sis.setChangeMoney(main.getChangeMoney().toString());
+                if(cur!=null){
+                    sis.setCurrentPeriodCompleted(cur.getCompleted().toString());
+                    sis.setCurrentPeriodPay(cur.getCurrentPeriodPay().toString());
+                }
+                if(pre!=null){
+                    sis.setPreviousPeriodPay(pre.getMoney().toString());
+                    sis.setPreviousPeriodCompleted(pre.getCompleted().toString());
+                }
+                if(cur!=null&&pre!=null){
+                    main.merge(pre);
+                }
+                sis.setCompleted(main.getCompleted().toString());
+                sis.setCurrentPeriodPay(main.getCurrentPeriodPay().toString());
+                sis.setCurrentPeriodEndPay(main.getCurrentPeriodEndPay().toString());
+                sis.setPayRatio(ratioFc.apply(sis.getCurrentPeriodEndPay(),sis.getChangeMoney()));
+                totalList.add(sis);
+            });
+           /*for(Map.Entry<String,Summary> form:currentSummary.entrySet()){
                 SubprojectInterimPaymentSummary sis = new SubprojectInterimPaymentSummary();
                 Summary pre =preSummary.get(form.getKey());
                 Summary summary = form.getValue();
@@ -532,9 +566,10 @@ public class ExecutorMeter extends FormulaExecutor {
                 sis.setChangeTotal(summary.getChangeTotal().toString());
                 sis.setContractMoney(summary.getContractMoney().toString());
                 sis.setChangeMoney(summary.getChangeMoney().toString());
+
                 sis.setCurrentPeriodCompleted(summary.getCompleted().toString());
                 sis.setCurrentPeriodPay(summary.getCurrentPeriodPay().toString());
-                /*当前期和往期统计*/
+                *//*当前期和往期统计*//*
                 summary.merge(pre);
                 if(pre!=null){
                     sis.setPreviousPeriodPay(pre.getMoney().toString());
@@ -545,9 +580,7 @@ public class ExecutorMeter extends FormulaExecutor {
                 sis.setCurrentPeriodEndPay(summary.getCurrentPeriodEndPay().toString());
                 sis.setPayRatio(ratioFc.apply(sis.getCurrentPeriodEndPay(),sis.getChangeMoney()));
                 totalList.add(sis);
-            }
-
-
+            }*/
             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)->{

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

@@ -32,6 +32,10 @@ public class MeterElementWriter implements ElementWriter {
             List<Object> values = toList(data,containsNull);
             /*计量写入数据无效考虑是否存在表页实体,也就不存在超页的概念,只管按需自动增页写人,任何元素初始化都是一页*/
             int capacity=fd.getCoordsList().size();
+            if(capacity==0){
+                System.out.println(fd.getTableName()+fd.getEName()+"绑定单元格异常");
+                return;
+            }
             List<ElementData> eds=  IntStream.range(0,values.size()).boxed().map(i->{
                 Coords coords = fd.getCoordsList().get(i%capacity);
                 return new ElementData(i/capacity,values.get(i),coords.getX(),coords.getY());

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

@@ -886,7 +886,10 @@ public class ExcelTabServiceImpl extends BaseServiceImpl<ExcelTabMapper, ExcelTa
             }
         }
         //获取未匹配的字段
-        List<WbsFormElement> list = baseMapper.getUnMatchField(tabId, set);
+        List<WbsFormElement> list = new ArrayList<>();
+        if(set!=null && set.size()>0){
+             list = baseMapper.getUnMatchField(tabId, set);
+        }
         return list;
     }
 
@@ -1218,8 +1221,6 @@ public class ExcelTabServiceImpl extends BaseServiceImpl<ExcelTabMapper, ExcelTa
         }
         File file1 = ResourceUtil.getFile(wbsTreeContract.getHtmlUrl());
         if (file1.exists()) {
-
-
             FileInputStream fileInputStream = new FileInputStream(file1);
             String htmlString = IoUtil.readToString(fileInputStream);
             Document doc = Jsoup.parse(htmlString);

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

@@ -2716,7 +2716,7 @@ public class FormulaServiceImpl extends BaseServiceImpl<FormulaMapper, Formula>
     }
 
     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"));
+      return this.getSqlList("select a.p_key_id as pkeyId, a.node_name as nodeName, a.init_table_name as initTableName, a.html_url as htmlUrl, a.excel_id as excelId from m_wbs_tree_private a join m_wbs_tree_private b on(a.parent_id=b.id and a.project_id=b.project_id) where a.ancestors like ? and LENGTH(a.html_url) > 0 and a.is_deleted = 0 and a.project_id = ? and a.wbs_id = ?  ORDER BY b.sort",NodeTable.class,parent.get("path")+"%",parent.get("projectId"),parent.get("wbsId"));
     }
 
 

+ 9 - 3
blade-service/blade-manager/src/main/java/org/springblade/manager/service/impl/WbsFormElementServiceImpl.java

@@ -6,6 +6,7 @@ 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.springblade.common.constant.CommonConstant;
 import org.springblade.common.utils.SnowFlakeUtil;
 import org.springblade.core.log.exception.ServiceException;
 import org.springblade.core.mp.base.BaseServiceImpl;
@@ -29,6 +30,7 @@ import org.springblade.manager.vo.TableInfoVO;
 import org.springblade.manager.vo.WbsFormElementVO;
 import org.springblade.manager.vo.WbsFormElementVO2;
 import org.springblade.manager.vo.WbsNodeTableVO;
+import org.springblade.system.cache.ParamCache;
 import org.springframework.scheduling.annotation.Scheduled;
 import org.springframework.stereotype.Service;
 import org.springframework.transaction.annotation.Transactional;
@@ -84,8 +86,12 @@ public class WbsFormElementServiceImpl extends BaseServiceImpl<WbsFormElementMap
     @Override
     public Boolean initTable(List<WbsFormElement> elementList, String tableName) {
         String sql = createSQL(elementList);
-
-        return wbsFormElementMapper.createTable(sql, tableName) >= 0;
+        try {
+            boolean b = wbsFormElementMapper.createTable(sql, tableName) >= 0;
+            return b;
+        }catch (Exception e){
+            return true;
+        }
     }
 
     private String createSQL(List<WbsFormElement> elementList) {
@@ -704,7 +710,7 @@ public class WbsFormElementServiceImpl extends BaseServiceImpl<WbsFormElementMap
                         throw new ServiceException("操作失败,请完整填写元素名称与类型参数");
                     }
                 }
-
+                String sysId = ParamCache.getValue(CommonConstant.SYS_MEASURE_IDS);
                 //实体信息表验证,如果实体表的名称和数据表名称相同,则用同一张表否则新建
                 //初始化
                 String newTableName = "m_" + DateUtil.time() + "_" + SnowFlakeUtil.getId();

+ 0 - 1
blade-service/blade-meter/src/main/java/org/springblade/meter/controller/MeterTreeController.java

@@ -877,7 +877,6 @@ public class MeterTreeController extends BladeController {
                return meterTreeContractService.contractTreeNodeImport1(id, file);
             }else if (type == 2) {
                return meterTreeContractService.contractTreeNodeImport2(id, file);
-
             }
         }
         return R.fail("操作失败");

+ 29 - 9
blade-service/blade-meter/src/main/java/org/springblade/meter/controller/TaskController.java

@@ -24,6 +24,7 @@ import org.apache.poi.ss.usermodel.*;
 import org.apache.poi.util.IOUtils;
 import org.apache.poi.xssf.usermodel.XSSFWorkbook;
 import org.jsoup.Jsoup;
+import org.jsoup.nodes.Element;
 import org.jsoup.select.Elements;
 import org.springblade.business.entity.FixedFlow;
 import org.springblade.business.entity.FixedFlowLink;
@@ -2234,10 +2235,18 @@ public class TaskController extends BladeController {
                         reportId = materialS.getId()+"";
                     }
                 } else if (task.getMeterTaskType() == 1) { // 1中间
+                    // 获取总金额
+                    MiddleMeterApply middleMeterApply = new MiddleMeterApply();
+                    middleMeterApply.setContractId(Func.toLong(task.getContractId()) );
+                    middleMeterApply.setContractPeriodId(Func.toLong(task.getFormDataId()));
+                    BigDecimal currentMeterMoney = middleMeterApplyService.getCurrentMeterMoney(middleMeterApply);
+
                     InterimPayCertificate inData = interimPayCertificateService.getBaseMapper().selectOne(Wrappers.<InterimPayCertificate>lambdaQuery().eq(InterimPayCertificate::getContractId, task.getContractId()).eq(InterimPayCertificate::getContractPeriodId, task.getFormDataId()));
                     if (inData == null || Func.isNull(inData)) {
                         InterimPayCertificate inData2 = new InterimPayCertificate();
                         ContractMeterPeriod me = contractMeterPeriodService.getById(task.getFormDataId());
+                        inData2.setStartDate(me.getStartDate());
+                        inData2.setEndDate(me.getEndDate());
                         inData2.setProjectId(me.getProjectId());
                         inData2.setContractId(me.getContractId());
                         inData2.setContractPeriodId(Func.toLong(task.getFormDataId()));
@@ -2245,10 +2254,12 @@ public class TaskController extends BladeController {
                         inData2.setPeriodNumber(me.getPeriodNumber());
                         inData2.setPrintDate(me.getFormPrintDate());
                         inData2.setProjectId(me.getProjectId());
+                        inData2.setPayMoney(currentMeterMoney);
                         interimPayCertificateService.save(inData2);
                         reportId = inData2.getId()+"";
+                    }else{
+                        reportId = inData.getId()+"";
                     }
-                    reportId = inData.getId()+"";
                 }
                 /**计量公式执行 0中间,1材料,2开工*/
                 /*复制业务数据状态>主任务状态>替换数据*/
@@ -2769,7 +2780,7 @@ public class TaskController extends BladeController {
                                 /*设置表头*/
                                 setTitle(sheet, tile);
                                 /*添加电签*/
-                                setDQInfo(sheet,rs.getUrl());
+                                setDQInfo(sheet,rs.getUrl(),tile);
                                 //去掉表格虚线
                                 sheet.setPrintGridlines(false);
                                 //设置 整个工作表为一页
@@ -2839,8 +2850,8 @@ public class TaskController extends BladeController {
     }
 
     // 添加电签信息数据
-    public void setDQInfo(Sheet sheet, String htmlUrl) {
-        String file_path = CollectionUtils.getSysLocalFileUrl();
+    public void setDQInfo(Sheet sheet, String htmlUrl,String title) {
+        String file_path = "/www/wwwroot/Users/hongchuangyanfa/Desktop/";//CollectionUtils.getSysLocalFileUrl();
         // 添加电签关键字Id
         String sys_file_net_url = ParamCache.getValue(CommonConstant.SYS_FILE_NET_URL);
         File file = null;
@@ -2858,16 +2869,26 @@ public class TaskController extends BladeController {
             Elements dqlist = htmldoc.getElementsByAttribute("dqid");
             if(dqlist!=null && !dqlist.isEmpty()){
                 dqlist.forEach(element -> {
-                    int y1 = Func.toInt(element.attr("y1"));
-                    int x1 = Func.toInt(element.attr("x1"));
+                    System.out.println(element.hasAttr("y1"));
+                    int y1=0;
+                    int x1=0;
+                    if(!element.hasAttr("y1") && !element.hasAttr("x1")){
+                        Element element2 = element.children().get(0);
+                        y1 = Func.toInt(element2.attr("y1"));
+                        x1 = Func.toInt(element2.attr("x1"));
+                    }else{
+                         y1 = Func.toInt(element.attr("y1"));
+                         x1 = Func.toInt(element.attr("x1"));
+                    }
 
                     Row row = sheet.getRow(y1 - 1);
                     if (row != null) {
                         Cell cell = row.getCell(x1 - 1);
                         if (cell != null) {
-
+                            /*if(title.equals("重庆试验项目-中期支付汇总表")){
+                                System.out.println(title+"------坐标------"+y1+"__"+x1+"===="+element.attr("dqid"));
+                            }*/
                             cell.setCellValue(element.attr("dqid"));
-
                             Workbook workbook = cell.getSheet().getWorkbook();
                             CellStyle cellStyle = workbook.createCellStyle();
                             cellStyle.cloneStyleFrom(cell.getCellStyle());
@@ -2876,7 +2897,6 @@ public class TaskController extends BladeController {
                             newFont.setColor(IndexedColors.WHITE.getIndex());
                             newFont.setFontHeightInPoints((short) 2);
                             cellStyle.setFont(newFont);
-
                             cell.setCellStyle(cellStyle);
                         }
                     }

+ 5 - 2
blade-service/blade-meter/src/main/java/org/springblade/meter/mapper/InventoryFormMeterMapper.java

@@ -16,10 +16,12 @@
  */
 package org.springblade.meter.mapper;
 
-import feign.Param;
+
+import org.apache.ibatis.annotations.Param;
 import org.springblade.meter.entity.ContractInventoryForm;
 import org.springblade.meter.entity.InventoryFormMeter;
 import com.baomidou.mybatisplus.core.mapper.BaseMapper;
+import org.springblade.meter.vo.InventoryFormMeterVO;
 
 import java.util.List;
 
@@ -31,10 +33,11 @@ import java.util.List;
  */
 public interface InventoryFormMeterMapper extends BaseMapper<InventoryFormMeter> {
 
-
     List<Long> getNodeAllForm(@Param("nodeId") Long nodeId);
+
     ContractInventoryForm dadainfo(@Param("forid") long forid);
 
     void batchInsert(List<InventoryFormMeter> inventoryFormMeters);
 
+    List<InventoryFormMeterVO> getFormByNodeIds(@Param("contractId") Long contractId,@Param("ids") List<Long> nodeIds);
 }

+ 8 - 0
blade-service/blade-meter/src/main/java/org/springblade/meter/mapper/InventoryFormMeterMapper.xml

@@ -43,5 +43,13 @@
         from s_contract_inventory_form
         where id = #{forid};
     </select>
+    <select id="getFormByNodeIds" resultType="org.springblade.meter.vo.InventoryFormMeterVO">
+        select *,(select form_number from s_contract_inventory_form where id = ifm.contract_form_id) as formNumber
+        from s_inventory_form_meter ifm
+        where contract_id = #{contractId} and is_deleted = 0 and contract_meter_id in
+        <foreach collection="ids" item="id" open="(" separator="," close=")">
+            #{id}
+        </foreach>
+    </select>
 
 </mapper>

+ 4 - 1
blade-service/blade-meter/src/main/java/org/springblade/meter/mapper/MeterTreeContractMapper.java

@@ -1,11 +1,12 @@
 package org.springblade.meter.mapper;
 
 import com.baomidou.mybatisplus.core.mapper.BaseMapper;
-import jdk.internal.org.objectweb.asm.tree.analysis.Value;
 import org.apache.ibatis.annotations.Param;
 import org.apache.ibatis.annotations.Select;
+import org.springblade.meter.entity.InventoryFormApply;
 import org.springblade.meter.entity.InventoryFormMeter;
 import org.springblade.meter.entity.MeterTreeContract;
+import org.springblade.meter.entity.MiddleMeterApply;
 
 import java.math.BigDecimal;
 import java.util.List;
@@ -26,4 +27,6 @@ public interface MeterTreeContractMapper extends BaseMapper<MeterTreeContract> {
     List<String> getAllEqualsNumber(@Param("contractId") Long contractId,@Param("numbers") List<String> collect);
 
     void batchUpdateFormByNumber(@Param("contractId") Long contractId,@Param("map") Map<String, BigDecimal> map);
+
+    List<InventoryFormApply> getMeterInfo(@Param("meterId") Long aLong, @Param("formId") Long id);
 }

+ 4 - 0
blade-service/blade-meter/src/main/java/org/springblade/meter/mapper/MeterTreeContractMapper.xml

@@ -42,4 +42,8 @@
             #{number}
         </foreach>
     </select>
+    <select id="getMeterInfo" resultType="org.springblade.meter.entity.InventoryFormApply">
+        select * from s_inventory_form_apply where contract_meter_id = #{meterId} and contract_form_id = #{formId} and is_deleted = 0
+    </select>
+
 </mapper>

+ 273 - 5
blade-service/blade-meter/src/main/java/org/springblade/meter/service/impl/MeterTreeContractServiceImpl.java

@@ -10,6 +10,7 @@ import org.apache.poi.xssf.usermodel.XSSFWorkbook;
 import org.springblade.common.utils.SnowFlakeUtil;
 import org.springblade.core.log.exception.ServiceException;
 import org.springblade.core.mp.base.BaseServiceImpl;
+import org.springblade.core.secure.utils.AuthUtil;
 import org.springblade.core.secure.utils.SecureUtil;
 import org.springblade.core.tool.api.R;
 import org.springblade.core.tool.utils.BeanUtil;
@@ -24,6 +25,7 @@ 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.InventoryFormMeterVO;
 import org.springblade.meter.vo.MeterTreeContractVO;
 import org.springblade.system.entity.Dict;
 import org.springframework.jdbc.core.BeanPropertyRowMapper;
@@ -39,6 +41,7 @@ import java.math.BigDecimal;
 import java.util.*;
 import java.util.function.Function;
 import java.util.stream.Collectors;
+import java.util.stream.Stream;
 
 @Service
 @AllArgsConstructor
@@ -1511,10 +1514,12 @@ public class MeterTreeContractServiceImpl extends BaseServiceImpl<MeterTreeContr
             }
         }
         //修改合同工程清单的变更后数量
-        Map<String, BigDecimal> map = InventoryFormListUpdate.stream()
-                .collect(Collectors.groupingBy(l -> l.getFormNumber(),
-                        Collectors.mapping(ContractInventoryForm::getChangeTotal, Collectors.reducing(BigDecimal.ZERO, BigDecimal::add))));
-        baseMapper.batchUpdateFormByNumber(meterTreeContract.getContractId(),map);
+        if (InventoryFormListUpdate.size() > 0) {
+            Map<String, BigDecimal> map = InventoryFormListUpdate.stream()
+                    .collect(Collectors.groupingBy(l -> l.getFormNumber(),
+                            Collectors.mapping(ContractInventoryForm::getChangeTotal, Collectors.reducing(BigDecimal.ZERO, BigDecimal::add))));
+            baseMapper.batchUpdateFormByNumber(meterTreeContract.getContractId(), map);
+        }
         return R.success("成功导入:节点("+addNode+")个,"+"新增清单("+addForm+")条,"+"修改清单("+updateForm+")条.");
     }
 
@@ -1525,10 +1530,273 @@ public class MeterTreeContractServiceImpl extends BaseServiceImpl<MeterTreeContr
      * @return
      */
     @Override
+    @Transactional
     public R<String> contractTreeNodeImport1(String id, MultipartFile file) {
-        return null;
+        //获取当前节点
+        MeterTreeContract meterTreeContract = baseMapper.selectById(id);
+        if (meterTreeContract == null){
+            throw new ServiceException("未找到当前导入节点信息");
+        }
+        //查看当前节点是否挂载表单,如果存在表单,则提示
+        List<InventoryFormMeter> meterList = inventoryFormMeterMapper.selectList(new LambdaQueryWrapper<InventoryFormMeter>()
+                .eq(InventoryFormMeter::getContractId, meterTreeContract.getContractId())
+                .eq(InventoryFormMeter::getContractMeterId, id));
+        if (meterList.size() > 0){
+            throw new ServiceException("当前节点已经挂载清单,不能导入");
+        }
+        /*解析excel*/
+        List<Map<String, String>> parseExcelFileToList;
+        try {
+            parseExcelFileToList = this.parseExcelFile(file);
+        }catch (Exception e){
+            throw new ServiceException("excel解析失败,请检查格式:"+e.getMessage());
+        }
+        if (parseExcelFileToList.size() == 0){
+            throw new ServiceException("excel中未发现数据,请检查后再导入");
+        }
+        //过滤掉桩号支付编号为空的
+        parseExcelFileToList = parseExcelFileToList.stream().filter(l->StringUtils.isNotBlank(l.get("桩号支付编号")) && !l.get("桩号支付编号").contains("清单编号需手动填写")).collect(Collectors.toList());
+        /*节点新增*/
+        List<MeterTreeContract> resultNodeListAdd = new LinkedList<>();
+        /*节点金额修改Ids*/
+        Set<Long> updateNodeSet = new HashSet<>();
+        /*清单中间新增*/
+        List<InventoryFormMeter> resultFormListAdd = new LinkedList<>();
+        /*清单中间数量修改*/
+        List<InventoryFormMeter> resultFormListUpdate = new LinkedList<>();
+        /*合同清单变更后数量修改*/
+        List<ContractInventoryForm> InventoryFormListUpdate = new LinkedList<>();
+        /*末尾校验是否被计量过*/
+        Map<Long,Long> checkMeter = new HashMap<>();
+        //是否有子节点
+        Boolean hasChild = false;
+        //是否子节点有表单
+        Boolean hasForm = false;
+        //1 获取当前节点下一层的所有节点
+        List<MeterTreeContract> childNode = this.list(new LambdaQueryWrapper<MeterTreeContract>()
+                .eq(MeterTreeContract::getParentId, meterTreeContract.getId())
+                .eq(MeterTreeContract::getContractId, meterTreeContract.getContractId()));
+        if (childNode.size() > 0){
+            hasChild = true;
+        }
+        //key节点名称,value节点id
+        Map<String, Long> nameMap = childNode.stream().collect(Collectors.toMap(l -> l.getNodeName(), l -> l.getId()));
+        Map<Long, List<InventoryFormMeterVO>> formMap = new HashMap<>();
+        if (hasChild) {
+            List<Long> nodeIds = childNode.stream().map(l -> l.getId()).collect(Collectors.toList());
+            //2 获取节点下所有挂载表单,按照节点id分组
+            List<InventoryFormMeterVO> formMeters = inventoryFormMeterMapper.getFormByNodeIds(meterTreeContract.getContractId(),nodeIds);
+            if (formMeters.size() > 0) {
+                hasForm = true;
+                formMap = formMeters.stream().collect(Collectors.groupingBy(InventoryFormMeterVO::getContractMeterId));
+            }
+        }
+        //获取合同段所有的清单
+        List<ContractInventoryForm> formList = contractInventoryFormMapper.selectList(new LambdaQueryWrapper<ContractInventoryForm>()
+                .eq(ContractInventoryForm::getContractId, meterTreeContract.getContractId())
+                .eq(ContractInventoryForm::getIsFormNode, 1));
+        if (formList.size() == 0){
+            throw new ServiceException("导入失败,当前合同段没有合同工程清单");
+        }
+        List<String> numberList = formList.stream().map(l -> l.getFormNumber()).collect(Collectors.toList());
+        Map<String, ContractInventoryForm> formNumberMap = formList.stream().collect(Collectors.toMap(l -> l.getFormNumber(), l -> l));
+        //3 循环导入数据,查询当前节点下是否存在
+        for (Map<String, String> stringMap : parseExcelFileToList) {
+            String name = stringMap.get("桩号支付编号");
+            //获取所有清单,过滤掉不是清单的数据,过滤掉清单编号不存在的数据,过滤掉没有数量的数据,只留下清单存在,并且有数量的
+            List<String> allForm = stringMap.entrySet().stream()
+                    .filter(l->l.getKey().contains("-") && numberList.indexOf(l.getKey()) != -1 && StringUtils.isNotBlank(l.getValue()))
+                    .map(l->l.getKey()).collect(Collectors.toList());
+            // 查询当前节点下是否存在
+            if (hasChild && nameMap.get(name) != null){
+                updateNodeSet.add(nameMap.get(name));
+                // 循环需要挂载的清单
+                for (String fo : allForm) {
+                    //获取清单信息
+                    ContractInventoryForm form = formNumberMap.get(fo);
+                    //根据节点名称获取节点下的表单
+                    if (hasForm && formMap.get(nameMap.get(name)) != null){
+                        //存在挂载的表单,重新计算中间表
+                        List<InventoryFormMeterVO> list = formMap.get(nameMap.get(name));
+                        Map<String, InventoryFormMeterVO> map = list.stream().collect(Collectors.toMap(l -> l.getFormNumber(), l -> l));
+                        InventoryFormMeterVO vo = map.get(fo);
+                        if (vo == null){
+                            //没挂载过,组装中间表
+                            InventoryFormMeter middleAdd = this.buildInventoryFormMeter(form, nameMap.get(name), stringMap.get(fo));
+                            resultFormListAdd.add(middleAdd);
+                        }else {
+                            //存在节点,并且挂载过,则添加到校验集合
+                            //checkMeter.put(nameMap.get(name),vo.getId());
+                            //变更过直接跳过
+                            if (vo.getBuildPictureTotal().compareTo(vo.getChangeBuildPictureTotal()) != 0){
+                                continue;
+                            }
+                            //目前直接查询,以后优化
+                            List<InventoryFormApply> apply = baseMapper.getMeterInfo(nameMap.get(name),vo.getContractFormId());
+                            if (apply.size() > 0){
+                                continue;
+                            }
+
+                            //挂载过,重新计算中间表
+                            InventoryFormMeter middleUpdate = this.updateInventoryFormMeter(vo, form, stringMap.get(fo));
+                            resultFormListUpdate.add(middleUpdate);
+                        }
+                    }else {
+                        //不存在挂载的表单,组装中间表
+                        InventoryFormMeter middleAdd = this.buildInventoryFormMeter(form, nameMap.get(name), stringMap.get(fo));
+                        resultFormListAdd.add(middleAdd);
+                    }
+                    //设置清单增量
+                    ContractInventoryForm form2 = new ContractInventoryForm();
+                    form2.setFormNumber(form.getFormNumber());
+                    form2.setChangeTotal(this.parseString(stringMap.get(fo)));
+                    InventoryFormListUpdate.add(form2);
+                }
+            }else {
+                //节点不存在,则先新增节点,再直接新增清单
+                MeterTreeContract obj = new MeterTreeContract();
+                Long aLong = SnowFlakeUtil.getId();
+                obj.setId(aLong);
+                obj.setProjectId(meterTreeContract.getProjectId());
+                obj.setContractId(meterTreeContract.getContractId());
+                obj.setParentId(meterTreeContract.getId());
+                obj.setAncestor(meterTreeContract.getAncestor()+","+meterTreeContract.getId());
+                obj.setNodeName(name);
+                obj.setNodeType(6);
+                obj.setDataSourceType(4);
+                obj.setUpdateStatus(0);
+                obj.setRemarks(stringMap.get("备注"));
+                obj.setTenantId(AuthUtil.getTenantId());
+                obj.setIsSupplement(0);
+                obj.setIsResolveForm(1);
+                obj.setIsLock(0);
+                resultNodeListAdd.add(obj);
+                updateNodeSet.add(aLong);
+                for (String fo : allForm) {
+                    //获取清单信息
+                    ContractInventoryForm form = formNumberMap.get(fo);
+                    //设置清单增量
+                    ContractInventoryForm form2 = new ContractInventoryForm();
+                    form2.setFormNumber(form.getFormNumber());
+                    form2.setChangeTotal(this.parseString(stringMap.get(fo)));
+                    InventoryFormListUpdate.add(form2);
+                    //组装中间表
+                    InventoryFormMeter middleAdd = this.buildInventoryFormMeter(form, aLong, stringMap.get(fo));
+                    resultFormListAdd.add(middleAdd);
+                }
+            }
+        }
+
+        int addNode = 0;
+        int addForm = 0;
+        int updateForm = 0;
+        /*节点*/
+        if (resultNodeListAdd.size() > 0) {
+            this.saveBatch(resultNodeListAdd, 1000);
+            addNode = resultNodeListAdd.size();
+        }
+
+        /*清单中间新增*/
+        if (resultFormListAdd.size() > 0) {
+            inventoryFormMeterMapper.batchInsert(resultFormListAdd);
+            addForm = resultFormListAdd.size();
+        }
+
+        /*清单中间数量修改*/
+        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());
+            }
+            updateForm = resultFormListUpdate.size();
+        }
+
+        /*节点金额修改*/
+        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);
+                }
+            }
+        }
+        //修改合同工程清单的变更后数量
+        if (InventoryFormListUpdate.size() > 0) {
+            Map<String, BigDecimal> map = InventoryFormListUpdate.stream()
+                    .collect(Collectors.groupingBy(l -> l.getFormNumber(),
+                            Collectors.mapping(ContractInventoryForm::getChangeTotal, Collectors.reducing(BigDecimal.ZERO, BigDecimal::add))));
+            baseMapper.batchUpdateFormByNumber(meterTreeContract.getContractId(), map);
+        }
+        return R.success("成功导入:节点("+addNode+")个,"+"新增清单("+addForm+")条,"+"修改清单("+updateForm+")条.");
     }
 
+    /**
+     *  通过清单信息和合同计量单元节点,施工图数量,返回组装好的中间表对象
+     */
+    private InventoryFormMeter buildInventoryFormMeter(ContractInventoryForm form, Long nodeId, String buildTotal){
+        InventoryFormMeter meter = new InventoryFormMeter();
+        meter.setProjectId(form.getProjectId());
+        meter.setContractId(form.getContractId());
+        meter.setContractMeterId(nodeId);
+        meter.setContractFormId(form.getId());
+        try {
+            meter.setBuildPictureTotal(new BigDecimal(buildTotal));
+        }catch (Exception e){
+            throw new ServiceException("导入失败,施工图数量只能包含数字:清单编号:"+form.getFormNumber());
+        }
+        meter.setChangeBuildPictureTotal(new BigDecimal(buildTotal));
+        meter.setBuildPictureMoney(form.getBidPrice().multiply(meter.getBuildPictureTotal()));
+        meter.setChangeBuildPictureMoney(meter.getBuildPictureMoney());
+        return meter;
+    }
+
+    /**
+     *  更新中间表信息
+     */
+    private InventoryFormMeter updateInventoryFormMeter(InventoryFormMeter meter,ContractInventoryForm form,String buildTotal){
+        try {
+            meter.setBuildPictureTotal(meter.getBuildPictureTotal().add(new BigDecimal(buildTotal)));
+        }catch (Exception e){
+            throw new ServiceException("导入失败,施工图数量只能包含数字:清单编号:"+form.getFormNumber());
+        }
+        meter.setChangeBuildPictureTotal(meter.getChangeBuildPictureTotal().add(new BigDecimal(buildTotal)));
+        meter.setBuildPictureMoney(meter.getBuildPictureTotal().multiply(form.getBidPrice()));
+        meter.setChangeBuildPictureMoney(meter.getChangeBuildPictureTotal().multiply(form.getBidPrice()));
+        return meter;
+    }
+
+
     /**
      * 获取对应的父级的ancestor字段
      *