Browse Source

计量公式/分项评定实测值支持中文描述

yangyj 1 year ago
parent
commit
6018edba60

+ 2 - 1
blade-service-api/blade-manager-api/src/main/java/org/springblade/manager/dto/TreeNode.java

@@ -7,7 +7,7 @@ import java.util.List;
 /**
  * @author yangyj
  * @Date 2023/10/9 14:21
- * @description 工具类,用来刷treeCode
+ * @description 工具类,树结构遍历读改<T>
  */
 @Data
 public class TreeNode<T> {
@@ -17,6 +17,7 @@ public class TreeNode<T> {
        private TreeNode<T> parent;
        private String name;
        private int sort;
+       private boolean checked=false;
        private List<TreeNode<T>> children=new ArrayList<>();
        public boolean hasChildren(){
           return !children.isEmpty();

+ 5 - 3
blade-service-api/blade-manager-api/src/main/java/org/springblade/manager/vo/ItemBlock.java

@@ -4,6 +4,7 @@ import com.alibaba.fastjson.annotation.JSONField;
 import lombok.Data;
 import org.springblade.core.tool.utils.Func;
 
+import java.util.ArrayList;
 import java.util.Arrays;
 import java.util.List;
 import java.util.stream.Collectors;
@@ -25,10 +26,10 @@ public class ItemBlock {
     @JSONField(name = "p")
     private Long pkeyId;
     /**
-     * 实测值
+     * 实测值:按设计值分组
      */
     @JSONField(name = "d")
-    private List<List<Double>> data;
+    private List<List<Object>> data;
     /**
      * 设计值
      */
@@ -52,7 +53,8 @@ public class ItemBlock {
 
     public void setD(String d) {
         if (Func.isNotEmpty(d)) {
-            this.data = Arrays.stream(d.split("/")).map(e -> Arrays.stream(e.split(",")).map(Double::parseDouble).collect(Collectors.toList())).collect(Collectors.toList());
+            this.data = Arrays.stream(d.split("/")).map(e-> Arrays.stream(e.split(",")) .map(s -> (Object) s).collect(Collectors.toList())
+            ).collect(Collectors.toList());
         }
     }
 

+ 10 - 1
blade-service-api/blade-manager-api/src/main/java/org/springblade/manager/vo/MeterTree.java

@@ -18,10 +18,19 @@ public class MeterTree {
 
     @ApiModelProperty(value = "节点编码")
     private String nodeCode;
-
+    @ApiModelProperty(value = "祖级id")
+    private String ancestor;
     @ApiModelProperty(value = "父级id")
     private Long parentId;
     @ApiModelProperty(value = "排序")
     private Integer sort;
 
+    public String chapterPrefix(){
+        if(this.ancestor.length()>=41){
+            return this.ancestor.substring(0,42);
+        }
+        return this.ancestor;
+    }
+    public SubInterimMeterPaySummary  peer;
+
 }

+ 6 - 4
blade-service-api/blade-manager-api/src/main/java/org/springblade/manager/vo/SubInterimMeterPaySummary.java

@@ -3,6 +3,8 @@ package org.springblade.manager.vo;
 import com.alibaba.fastjson.annotation.JSONField;
 import lombok.Data;
 
+import java.math.BigDecimal;
+
 /**
  * @author yangyj
  * @Date 2024/1/16 16:58
@@ -27,13 +29,13 @@ public class SubInterimMeterPaySummary {
     private String contractTotal;
     /**变更数量*/
     @JSONField(name = "key_4",label="变更数量",ordinal = 4)
-    private String revisedTotal;
+    private Integer revisedTotal;
     /**本次完成数量*/
     @JSONField(name = "key_5",label="本次完成数量",ordinal = 5)
-    private String currentPeriodComplete;
+    private Integer currentPeriodCompleted;
     /**累计完成数量*/
     @JSONField(name = "key_6",label="累计完成数量",ordinal = 6)
-    private String complete;
+    private Integer completed;
     /**合同金额*/
     @JSONField(name = "key_7",label="合同金额",ordinal = 7)
     private String contractAmount;
@@ -45,7 +47,7 @@ public class SubInterimMeterPaySummary {
     private String currentPeriodPay;
     /**累计支付B金额*/
     @JSONField(name = "key_10",label="累计支付金额",ordinal = 10)
-    private String currentPeriodEndPay;
+    private BigDecimal currentPeriodEndPay;
     /**比例*/
     @JSONField(name = "key_11",label="变更令号",ordinal = 11)
     private String changeTokenId;

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

@@ -400,7 +400,7 @@ public class FormulaUtils {
 
 
     /*根据数据模型对象,生成数据集合按字段获取数据的函数*/
-    public static <T> Map<String, Function<List<T>, List<Object>>> fieldDataFcMap(Class<T> clazz) {
+    public static <T> Map<String, Function<List<T>, List<Object>>> fieldDataFcMap(Class<?> 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()) {
@@ -412,7 +412,7 @@ public class FormulaUtils {
 
 
     /*数据模型按字段生成内容获取函数*/
-    public static <T> Map<String,Function<T,Object>> functionMapBuilder(Class<T> clazz){
+    public static <T> Map<String,Function<T,Object>> functionMapBuilder(Class<?> clazz){
         Map<String, Function<T, Object>> functionMap = new HashMap<>();
         for (Field field : clazz.getDeclaredFields()) {
             JSONField jf = field.getAnnotation(JSONField.class);
@@ -426,7 +426,7 @@ public class FormulaUtils {
         return functionMap;
     }
 
-    private static <T> Function<T, Object> getFunction(Class<T> clazz, String fieldName) {
+    private static <T> Function<T, Object> getFunction(Class<?> clazz, String fieldName) {
         return certificate -> {
             try {
                 Field field = clazz.getDeclaredField(fieldName);
@@ -473,6 +473,20 @@ public class FormulaUtils {
           }
     }
 
+    /*回溯标记*/
+    public static <T> void treeNodeChecked( TreeNode<T> tmp){
+        int loop = 10;
+        do{
+            if(tmp.isChecked()) {
+                /*已经检出则停止循环*/
+                loop=0;
+            }else{
+                tmp.setChecked(true);
+                tmp=tmp.getParent();
+            }
+        }while (tmp!=null&&loop-->0);
+    }
+
     /*获取层级链*/
     public static <T> List<T> treeNodeChains( TreeNode<T> tmp){
         List<T> result = new ArrayList<>();

+ 91 - 25
blade-service/blade-manager/src/main/java/org/springblade/manager/formula/impl/ExecutorSpecial.java

@@ -73,7 +73,14 @@ public class ExecutorSpecial extends FormulaExecutor {
         return fn;
     }
 
-   public Function<String,String> preFixFc= this::getPrefix;
+    public Function<String,String> preFixFc= this::getPrefix;
+
+    public <T> LinkedHashMap<String,FormData>   builderFormDatas(T bean){
+        LinkedHashMap<String,FormData> fdm = FormulaUtils.toFormDataMap(bean);
+        Map<String,Function<List<T>,List<Object>>> functionMap =FormulaUtils.fieldDataFcMap(bean.getClass());
+        tec.getFormDataMap().putAll(fdm);
+        return fdm;
+    }
 
     @Override
     public void handle() {
@@ -325,8 +332,7 @@ public class ExecutorSpecial extends FormulaExecutor {
         }
 
         /*合计字段*/
-        BiFunction<List<InterimPaymentSummary>,Function<InterimPaymentSummary,String>,String>
-                bfc= (list,fc) -> StringUtils.number2String(list.stream().map(fc).mapToDouble(Double::parseDouble).sum(),1);
+        BiFunction<List<InterimPaymentSummary>,Function<InterimPaymentSummary,String>,String> bfc= (list,fc) -> StringUtils.number2String(list.stream().map(fc).mapToDouble(Double::parseDouble).sum(),1);
 
 
         @Override
@@ -359,9 +365,6 @@ public class ExecutorSpecial extends FormulaExecutor {
         }
     }
 
-
-
-
     @Data
     public  class SubIPaySum implements Special{
          private Integer capacity=10;
@@ -535,43 +538,56 @@ public class ExecutorSpecial extends FormulaExecutor {
             return current.size()>0;
         }
 
+        public BiFunction<Payment,Payment,SubInterimMeterPaySummary> payment2Smps=(payment,prePayment)->{
+            SubInterimMeterPaySummary smps= new SubInterimMeterPaySummary();
+            smps.setItemName(payment.getName());
+            smps.setFormNumber(payment.getNumber());
+            smps.setUnit(payment.getUnit());
+            smps.setRevisedTotal(payment.getChangeTotal());
+            smps.setCurrentPeriodCompleted(payment.getCompleted());
+            smps.setCompleted(payment.getCompleted()+prePayment.getCompleted());
+            smps.setRevisedAmount(payment.getChangeMoney());
+            smps.setCurrentPeriodPay(payment.getMoney());
+            smps.setCurrentPeriodEndPay(new BigDecimal(payment.getMoney()).add(new BigDecimal(prePayment.getMoney())));
+            return smps;
+        };
+
         @Override
         public void parse() {
             /*按照计量单元和单元内的清单顺序排序显示计量清单,并且把计量单元的层级一并显示*/
             /*根据每一期的s_middle_meter_apply,s_inventory_form_apply 获取对应的计量清单,然后根据清单Id配合s_inventory_form_meter查找计量单元信息*/
             /*s_change_token_inventory每个清单关联的变更令,s_change_token_meter每个计量单元关联的变更令*/
+            LinkedHashMap<String,FormData> fdm = FormulaUtils.toFormDataMap(new SubInterimMeterPaySummary());
+            Map<String,Function<List<SubInterimMeterPaySummary>,List<Object>>> functionMap =FormulaUtils.fieldDataFcMap(SubInterimMeterPaySummary.class);
+            tec.getFormDataMap().putAll(fdm);
             try {
                 Map<Long, TreeNode<MeterTree>> treeNodeMap = tec.getMeterTreeMap().get();
                 Optional<TreeNode<MeterTree>> optionalTreeNode=  treeNodeMap.values().stream().filter(TreeNode::isTop).findAny();
                 if(optionalTreeNode.isPresent()) {
                     /*计量单元根节点*/
                     TreeNode<MeterTree> top= optionalTreeNode.get();
-                    List<TreeNode<MeterTree>> treeNodeList = new ArrayList<>();
                     Map<Long, List<Payment>> paymentGroup = current.stream().collect(Collectors.groupingBy(Payment::getMeterId));
                     Map<String,Payment> preMeterPaymentGroup = previous.stream().collect(Collectors.toMap(Payment::meterFormKey,p->p,(p1,p2)->p2));
                     FormulaUtils.treeNodeSort(0,top);
                     current.forEach(e -> {
                         TreeNode<MeterTree> meterTreeNode=treeNodeMap.get(e.getMeterId());
                         if(meterTreeNode!=null){
-                            treeNodeList.add(meterTreeNode);
+                            MeterTree meterUnit = meterTreeNode.getValue();
+                            List<Payment> paymentList = paymentGroup.get(meterUnit.getId());
+                            for(Payment payment:paymentList){
+                                Payment prePayment = preMeterPaymentGroup.get(meterUnit.getId().toString()+payment.getFormId());
+                                this.treeNodeCheckedCount(meterTreeNode,payment,prePayment);
+                            }
                         }
                     });
-                    if(treeNodeList.size()>0){
-                        treeNodeList.sort(Comparator.comparingInt(TreeNode::getSort));
-                        for(TreeNode<MeterTree> node:treeNodeList){
-                             MeterTree meterUnit = node.getValue();
-                             List<MeterTree> chains = FormulaUtils.treeNodeChains(node);
-                             List<Payment> paymentList = paymentGroup.get(meterUnit.getId());
-                             for(Payment payment:paymentList){
-                                 Payment prePayment = preMeterPaymentGroup.get(meterUnit.getId().toString()+payment.getFormId());
-                                 SubInterimMeterPaySummary smps= new SubInterimMeterPaySummary();
-                                 smps.setItemName(payment.getName());
-                                 smps.setFormNumber(payment.getNumber());
-                                 smps.setUnit(payment.getUnit());
-                             }
-                        }
-                    }
-
+                    List<List<SubInterimMeterPaySummary>> pageData =traversal(top);
+                    List<SubInterimMeterPaySummary> dataList=  pageData.stream().flatMap(list->{
+                        List<SubInterimMeterPaySummary> tmp =new ArrayList<>(list);
+                        tmp.add(new SubInterimMeterPaySummary());
+                       return tmp.stream();
+                    }).collect(Collectors.toList());
+                    /*内容输出*/
+                    FormulaUtils.put2FormData(fdm,functionMap,dataList);
                 }
             }catch (Exception e){
                 e.printStackTrace();
@@ -579,9 +595,59 @@ public class ExecutorSpecial extends FormulaExecutor {
 
         }
 
+        /*溯源并计算累计支付*/
+        public  void treeNodeCheckedCount(TreeNode<MeterTree> tmp,Payment payment, Payment prePayment ){
+            tmp.setChecked(true);
+            MeterTree meterTree = tmp.getValue();
+            if(meterTree.peer==null){
+                meterTree.peer= payment2Smps.apply(payment,prePayment);
+            }
+            int loop = 10;
+            TreeNode<MeterTree> node=tmp.getParent();
+            SubInterimMeterPaySummary sp= meterTree.peer;
+            while (node!=null&&loop-->0){
+                node.setChecked(true);
+                MeterTree tmpTree= node.getValue();
+                SubInterimMeterPaySummary ss=tmpTree.peer;
+                if(ss==null){
+                    /*不存在则新增*/
+                    ss = new SubInterimMeterPaySummary();
+                    ss.setItemName(meterTree.getNodeName());
+                    ss.setCurrentPeriodEndPay(sp.getCurrentPeriodEndPay());
+                    tmpTree.peer=ss;
+                }else{
+                    /*已存在则相加*/
+                    ss.setCurrentPeriodEndPay(ss.getCurrentPeriodEndPay().add(sp.getCurrentPeriodEndPay()));
+                }
+                node=node.getParent();
+            }
+        }
 
-        public void traversal(TreeNode<MeterTree> top){
+        /*遍历树获取smps*/
+        public  List<List<SubInterimMeterPaySummary>> traversal(TreeNode<MeterTree> top){
+            List<List<SubInterimMeterPaySummary>> total = new ArrayList<>();
+            if(top.hasChildren()) {
+                List<TreeNode<MeterTree>> parts = top.getChildren();
+                for(TreeNode<MeterTree> node :parts){
+                    List<SubInterimMeterPaySummary> list = new ArrayList<>();
+                    toSmps(node,list);
+                    if(list.size()>0){
+                        total.add(list);
+                    }
+                }
+            }
+            return total;
+        }
 
+        public void toSmps(TreeNode<MeterTree> node,List<SubInterimMeterPaySummary> list){
+            if(node.isChecked()){
+                list.add(node.getValue().getPeer());
+                if(node.hasChildren()){
+                      for(TreeNode<MeterTree> child:node.getChildren()){
+                          toSmps(child,list);
+                      }
+                }
+            }
         }
 
     }

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

@@ -324,9 +324,21 @@ public class FormulaServiceImpl extends BaseServiceImpl<FormulaMapper, Formula>
                                         FormulaUtils.write(t.getJudge(), "合格", false);
                                     }
 //                                    itemBlockList.sort(Comparator.comparingInt(a -> ids.indexOf(a.getPkeyId())));
-                                    List<String> values = itemBlockList.stream().map(ItemBlock::getData).flatMap(v -> v.stream().flatMap(Collection::stream)).map(Object::toString).collect(Collectors.toList());
+                                    List<String> values;
+                                    Predicate<String> predicate=s->Pattern.matches("^[,]*$",s);
+                                    if(itemBlockList.stream().map(ItemBlock::getData).flatMap(v -> v.stream().flatMap(Collection::stream)).map(Func::toStr).anyMatch(CustomFunction::containsZH)) {
+                                        values=itemBlockList.stream().map(ItemBlock::getData).flatMap(v->v.stream().map(l->l.stream().map(Func::toStr).collect(Collectors.joining(","))).filter(predicate.negate()).distinct().flatMap(s-> Arrays.stream(s.split(",")))).collect(Collectors.toList());
+                                    }else{
+                                        values=  itemBlockList.stream().map(ItemBlock::getData).flatMap(v -> v.stream().flatMap(Collection::stream)).map(Func::toStr).collect(Collectors.toList());
+                                    }
+
                                     int scale = StringUtils.getScale(values);
-                                    FormulaUtils.write(t.getValue(), values.stream().map(u -> StringUtils.number2String(u, scale)).collect(Collectors.toList()), true);
+                                    FormulaUtils.write(t.getValue(), values.stream().filter(StringUtils::isNotEmpty).map(u -> {
+                                              if(StringUtils.isNumber(u)){
+                                                  return  StringUtils.number2String(u, scale);
+                                              }  return u;
+                                            }
+                                    ).collect(Collectors.toList()), true);
 //                                   if(t.getValue().getEName().contains("±")){
 //                                       /*存在偏差范围则获取的是偏差值:实测-设计*/
 //                                       FormulaUtils.write(t.getValue(),itemBlockList.stream().flatMap(b->{
@@ -1385,9 +1397,10 @@ public class FormulaServiceImpl extends BaseServiceImpl<FormulaMapper, Formula>
                             AtomicInteger index = new AtomicInteger();
                             if (targetItem.getDesigns()!=null&&targetItem.getDesigns().size()>0) {
                                 int len = targetItem.getDesigns().size();
-                                targetItem.setData(new ArrayList<>(list.stream().map(StringUtils::obj2Double).collect(Collectors.groupingBy(k -> index.getAndIncrement() / len, LinkedHashMap::new, Collectors.toList())).values()));
+                                targetItem.setData(new ArrayList<>(list.stream().collect(Collectors.groupingBy(k -> index.getAndIncrement() / len, LinkedHashMap::new, Collectors.toList())).values()));
                             } else {
-                                targetItem.setData(Collections.singletonList(list.stream().map(StringUtils::obj2Double).collect(Collectors.toList())));
+                                /*targetItem.setData(Collections.singletonList(list.stream().map(StringUtils::obj2Double).collect(Collectors.toList())));*/
+                                targetItem.setData(Collections.singletonList(list));
                             }
                             if (pass != null && !pass.empty()) {
                                 targetItem.setSubPass((int) Math.round(list.size() * StringUtils.obj2Double(pass.getValues().get(0).getValue()) / 100));