|
@@ -21,6 +21,7 @@ import org.springblade.manager.formula.FormulaStrategyFactory;
|
|
|
import org.springblade.manager.formula.impl.TableElementConverter;
|
|
|
import org.springblade.manager.mapper.FormulaMapper;
|
|
|
import org.springblade.manager.service.IFormulaService;
|
|
|
+import org.springblade.manager.service.IWbsParamService;
|
|
|
import org.springblade.manager.service.IWbsTreeContractService;
|
|
|
import org.springframework.stereotype.Service;
|
|
|
|
|
@@ -39,7 +40,7 @@ import java.util.stream.Collectors;
|
|
|
@AllArgsConstructor
|
|
|
public class FormulaServiceImpl extends BaseServiceImpl<FormulaMapper, Formula> implements IFormulaService {
|
|
|
|
|
|
- private final WbsParamServiceImpl wpService;
|
|
|
+ private final IWbsParamService wpService;
|
|
|
private final MileageClient mileageClient;
|
|
|
private final IWbsTreeContractService treeContractService;
|
|
|
private final FormulaStrategyFactory formulaStrategyFactory;
|
|
@@ -52,168 +53,147 @@ public class FormulaServiceImpl extends BaseServiceImpl<FormulaMapper, Formula>
|
|
|
public static final String POLY_REG= "(avg|min|max|sum)\\(([^)]+)\\)";
|
|
|
public static final Pattern POLY = Pattern.compile(POLY_REG);
|
|
|
public static final Pattern MILE_P = Pattern.compile("(?<=MILE<)([^,]+),([^,]+)(?=,)");
|
|
|
+ private Map<String,Object> constantMap;
|
|
|
+ private List<FormData> formDataList;
|
|
|
+
|
|
|
|
|
|
|
|
|
/**
|
|
|
- * @Description
|
|
|
* @Param [list: 源数据, contractId: 合同段id, primaryKeyId: wbs节点id]
|
|
|
- * @return void
|
|
|
* @Author yangyj
|
|
|
* @Date 2022.08.03 14:03
|
|
|
**/
|
|
|
@Override
|
|
|
public void execute(List<FormData> list ,Long contractId,Long primaryKeyId){
|
|
|
+ /*初始化变量>>依赖排序>>预处理>>特殊公式>>通用公式执行*/
|
|
|
+// this.init(list,contractId,primaryKeyId).sort().pre().special().calculate();
|
|
|
+ }
|
|
|
|
|
|
-/* contractId=888888L;*/
|
|
|
- /*变量准备*/
|
|
|
- /*依赖排序*/
|
|
|
- /*公式预处理*/
|
|
|
- /*公式运算*/
|
|
|
- Map<Boolean,List<FormData>> map = list.stream().collect(Collectors.partitioningBy(e->e!=null&&e.getFormula().getFormula().contains("E[")));
|
|
|
- List<FormData>total = new ArrayList<>();
|
|
|
- /*用来保存所有变量*/
|
|
|
- Map<String,Object> constantMap = new HashMap<>(20);
|
|
|
- constantMap.put("contractId",contractId);
|
|
|
- /*预设变量start*/
|
|
|
- List<WbsTreeContract> trees = new ArrayList<>();
|
|
|
- List<WbsTreeContract> nodes = treeContractService.searchParentAllNode(primaryKeyId,contractId);
|
|
|
- if(CollectionUtil.isEmpty(nodes)){
|
|
|
- for(int i=0;i<6;i++){
|
|
|
- WbsTreeContract t= new WbsTreeContract();
|
|
|
- t.setDeptName("第"+i+"层");
|
|
|
- trees.add(t);
|
|
|
- }
|
|
|
- }else{
|
|
|
- trees=nodes;
|
|
|
- }
|
|
|
- List<WbsParam> wps = this.wpService.list(Wrappers.<WbsParam>lambdaQuery().eq(WbsParam::getWbsId,123456));
|
|
|
- Map<String,Object> wpMap= new HashMap<>();
|
|
|
- if(CollectionUtil.isNotEmpty(wps)){
|
|
|
- for(WbsParam p:wps){
|
|
|
- wpMap.put(p.getK(),p.getV());
|
|
|
- }
|
|
|
+ @Override
|
|
|
+ public void execute(TableElementConverter tec) {
|
|
|
+ WbsTreeContract one = this.treeContractService.getById(tec.getTableInfoList().get(0).getPkeyId());
|
|
|
+ this.execute(tec.getFds(),tec.getContractId(),Func.isNotEmpty(one.getOldId())?Long.parseLong(one.getOldId()):one.getParentId());
|
|
|
+ }
|
|
|
+
|
|
|
+ @Override
|
|
|
+ public void init(List<FormData> list,Long contractId,Long primaryKeyId) {
|
|
|
+ this.constantMap=new HashMap<>(100);
|
|
|
+ this.formDataList=list;
|
|
|
+ this.constantMap.put("contractId",contractId);
|
|
|
+ List<WbsTreeContract> nodes = treeContractService.searchParentAllNode(primaryKeyId,contractId);
|
|
|
+ this.constantMap.put(CHAIN,nodes.stream().map(WbsTreeContract::getFullName).collect(Collectors.toList()));
|
|
|
+ List<WbsParam> wps = this.wpService.list(Wrappers.<WbsParam>lambdaQuery().eq(WbsParam::getWbsId,primaryKeyId));
|
|
|
+ Map<String,Object> wpMap= new HashMap<>(wps.size()*2);
|
|
|
+ if(CollectionUtil.isNotEmpty(wps)){
|
|
|
+ for(WbsParam p:wps){
|
|
|
+ wpMap.put(p.getK(),p.getV());
|
|
|
}
|
|
|
- /*预设变量end*/
|
|
|
-
|
|
|
- /*没有依赖的*/
|
|
|
- List<FormData> simple=map.get(false);
|
|
|
- if(CollectionUtil.isNotEmpty(simple)){
|
|
|
- total.addAll(simple);
|
|
|
- }
|
|
|
- /*有依赖的*/
|
|
|
- List<FormData> rely= map.get(true);
|
|
|
- if(CollectionUtil.isNotEmpty(rely)){
|
|
|
- sort(rely,((rely.size()+1)/2)*rely.size());
|
|
|
- total.addAll(rely);
|
|
|
- }
|
|
|
- if(CollectionUtil.isNotEmpty(total)){
|
|
|
- /*变量环境加载*/
|
|
|
- constantMap.put(WP,wpMap);
|
|
|
- constantMap.put(CHAIN,trees.stream().map(WbsTreeContract::getDeptName).collect(Collectors.toList()));
|
|
|
- for(FormData fd:total){
|
|
|
- /*预处理公式脚本*/
|
|
|
- String tmp =fd.getFormula().getFormula();
|
|
|
- tmp = tmp.replace(FC, CustomFunction.CLASS_CALL);
|
|
|
-
|
|
|
- if(tmp.contains("WP[")){
|
|
|
- Matcher m = PP.matcher(tmp);
|
|
|
- while (m.find()){
|
|
|
- tmp= tmp.replace("WP"+m.group()+"]","WP['"+m.group()+"']");
|
|
|
- }
|
|
|
- }
|
|
|
-
|
|
|
- if(tmp.contains(CustomFunction.CLASS_CALL+"ifelse")){
|
|
|
- Matcher im =IF.matcher(tmp);
|
|
|
- while (im.find()){
|
|
|
- String rep =im.group();
|
|
|
- Matcher fm=P.matcher(rep);
|
|
|
- while (fm.find()){
|
|
|
- rep=rep.replace(fm.group(),"'+"+fm.group()+"+'");
|
|
|
- rep="'"+rep+"'";
|
|
|
- }
|
|
|
- tmp=tmp.replace(im.group(),rep);
|
|
|
+ }
|
|
|
+ this.constantMap.put(WP,wpMap);
|
|
|
+// return this;
|
|
|
+ }
|
|
|
+
|
|
|
+ @Override
|
|
|
+ public void sort() {
|
|
|
+ Map<Boolean,List<FormData>> map = this.formDataList.stream().collect(Collectors.partitioningBy(e->e!=null&&e.getFormula().getFormula().contains("E[")));
|
|
|
+ this.formDataList.clear();
|
|
|
+ /*没有依赖的*/
|
|
|
+ List<FormData> simple=map.get(false);
|
|
|
+ if(CollectionUtil.isNotEmpty(simple)){
|
|
|
+ this.formDataList.addAll(simple);
|
|
|
+ }
|
|
|
+ /*有依赖的*/
|
|
|
+ List<FormData> rely= map.get(true);
|
|
|
+ if(CollectionUtil.isNotEmpty(rely)){
|
|
|
+ sort(rely,((rely.size()+1)/2)*rely.size());
|
|
|
+ this.formDataList.addAll(rely);
|
|
|
+ }
|
|
|
+// return this;
|
|
|
+ }
|
|
|
+
|
|
|
+ @Override
|
|
|
+ public void pre() {
|
|
|
+ if(CollectionUtil.isNotEmpty(this.formDataList)){
|
|
|
+ for(FormData fd:this.formDataList){
|
|
|
+ /*预处理公式脚本*/
|
|
|
+ String tmp =fd.getFormula().getFormula();
|
|
|
+ tmp = tmp.replace(FC, CustomFunction.CLASS_CALL);
|
|
|
+ if(tmp.contains(CustomFunction.CLASS_CALL+"ifelse")){
|
|
|
+ Matcher im =IF.matcher(tmp);
|
|
|
+ while (im.find()){
|
|
|
+ String rep =im.group();
|
|
|
+ Matcher fm=P.matcher(rep);
|
|
|
+ while (fm.find()){
|
|
|
+ rep=rep.replace(fm.group(),"'+"+fm.group()+"+'");
|
|
|
}
|
|
|
+ tmp=tmp.replace(im.group(),rep);
|
|
|
}
|
|
|
-
|
|
|
- if(tmp.contains("E[")){
|
|
|
- Matcher m2 = P.matcher(tmp);
|
|
|
- while (m2.find()){
|
|
|
- tmp= tmp.replace("E["+m2.group()+"]","E['"+m2.group()+"']");
|
|
|
- }
|
|
|
- }
|
|
|
- fd.getFormula().setFormula(tmp);
|
|
|
}
|
|
|
|
|
|
- /*公式执行*/
|
|
|
- for(FormData fd:total){
|
|
|
- Formula formula= fd.getFormula();
|
|
|
- formulaStrategyFactory.get(fd).forEach(e->e.execute(list,constantMap));
|
|
|
- if(formula!=null){
|
|
|
- String f=formula.getFormula();
|
|
|
- if(Func.isNotBlank(f)){
|
|
|
-
|
|
|
- Map<String, Object> currentMap = new HashMap<>(constantMap);
|
|
|
- Map<String,Object> E = getMap(currentMap,"E");
|
|
|
- List<String> relyList = fd.getFormula().getRelyList();
|
|
|
-
|
|
|
- if(CollectionUtil.isNotEmpty(relyList)){
|
|
|
-
|
|
|
- List<FormData> ele = total.stream().filter(e->relyList.contains(e.getCode())).collect(Collectors.toList());
|
|
|
-
|
|
|
- if(f.contains(CustomFunction.CLASS_CALL+"avg(")||f.contains(CustomFunction.CLASS_CALL+"min(")||f.contains(CustomFunction.CLASS_CALL+"max(")||f.contains(CustomFunction.CLASS_CALL+"sum(")){
|
|
|
- /*聚合*/
|
|
|
- Matcher m = POLY.matcher(f);
|
|
|
- while (m.find()){
|
|
|
- List<String> elementCodes=CustomFunction.parseElementCode(m.group(2));
|
|
|
- List<FormData> tmp = ele.stream().filter(e->elementCodes.contains(e.getCode())).collect(Collectors.toList());
|
|
|
- ele.removeAll(tmp);
|
|
|
+ if(tmp.contains("E[")||tmp.contains("WP[")){
|
|
|
+ Matcher am = AP.matcher(tmp);
|
|
|
+ while (am.find()){
|
|
|
+ tmp = tmp.replace(am.group(),am.group(1)+"['"+am.group(2)+"']");
|
|
|
+ }
|
|
|
+ }
|
|
|
+ fd.getFormula().setFormula(tmp);
|
|
|
+ }
|
|
|
+ }
|
|
|
+// return this;
|
|
|
+ }
|
|
|
|
|
|
- tmp.forEach(e-> E.put(e.getCode(),e.getValues().stream().map(ElementData::getValue).collect(Collectors.toList())));
|
|
|
- Object data = Expression.parse(CustomFunction.CLASS_CALL+m.group()).calculate(currentMap);
|
|
|
+ @Override
|
|
|
+ public void special() {
|
|
|
+ for(FormData fd:this.formDataList) {
|
|
|
+ formulaStrategyFactory.get(fd).forEach(e->e.execute(this.formDataList,constantMap));
|
|
|
+ }
|
|
|
+// return this;
|
|
|
+ }
|
|
|
|
|
|
- f = f.replace(CustomFunction.CLASS_CALL+m.group(),data.toString());
|
|
|
- fd.getFormula().setFormula(f);
|
|
|
- }
|
|
|
+ @Override
|
|
|
+ public void calculate() {
|
|
|
+ /*公式执行*/
|
|
|
+ /*先处理聚合类的方法*/
|
|
|
+ /*每次执行都会构造一个只有依赖的的集合*/
|
|
|
+ for(FormData fd:this.formDataList){
|
|
|
+ Formula formula= fd.getFormula();
|
|
|
+ if(formula!=null){
|
|
|
+ String f=formula.getFormula();
|
|
|
+ if(Func.isNotBlank(f)){
|
|
|
+ Map<String, Object> currentMap = new HashMap<>(this.constantMap);
|
|
|
+ List<String> relyList = fd.getFormula().getRelyList();
|
|
|
+ if(CollectionUtil.isNotEmpty(relyList)){
|
|
|
+ List<FormData> ele = this.formDataList.stream().filter(e->relyList.contains(e.getCode())).collect(Collectors.toList());
|
|
|
+ if(CollectionUtil.isNotEmpty(ele)){
|
|
|
+ /*每一组依赖的数据*/
|
|
|
+ Map<Integer,Map<String,List<Object>>> dataSource = new HashMap<>(20);
|
|
|
+ for(FormData e:ele){
|
|
|
+ /*分组*/
|
|
|
+ Map<Integer,List<ElementData>> m = e.getValues().stream().collect(Collectors.groupingBy(ElementData::getGroupId));
|
|
|
+ for(Map.Entry<Integer,List<ElementData>> entry:m.entrySet()){
|
|
|
+ /*拿到每一组数据*/
|
|
|
+ Map<String,List<Object>> t = dataSource.computeIfAbsent(entry.getKey(), k -> new HashMap<String,List<Object>>(20));
|
|
|
+ t.put(e.getCode(),entry.getValue().stream().map(ElementData::getValue).flatMap(o->Collections.nCopies(e.getStep(),o).stream()).collect(Collectors.toList()));
|
|
|
}
|
|
|
- if(CollectionUtil.isNotEmpty(ele)){
|
|
|
- Map<Integer,Map<String,List<Object>>> dataSource = new HashMap<>();
|
|
|
-
|
|
|
- for(FormData e:ele){
|
|
|
- Map<Integer,List<ElementData>> m = e.getValues().stream().collect(Collectors.groupingBy(ElementData::getGroupId));
|
|
|
-
|
|
|
- for(Map.Entry<Integer,List<ElementData>> entry:m.entrySet()){
|
|
|
- Map<String,List<Object>> t = dataSource.computeIfAbsent(entry.getKey(), k -> new HashMap());
|
|
|
- t.put(e.getCode(),entry.getValue().stream().map(ElementData::getValue).collect(Collectors.toList()));
|
|
|
- }
|
|
|
-
|
|
|
- }
|
|
|
-
|
|
|
- if(dataSource.size()>0){
|
|
|
- for(Map.Entry<Integer,Map<String,List<Object>>> entry:dataSource.entrySet()){
|
|
|
- if(entry.getValue().keySet().size()>=ele.size()){
|
|
|
- List<ElementData> eds = slice(entry.getValue(),constantMap,f,entry.getKey());
|
|
|
- fd.setValues(eds);
|
|
|
- }
|
|
|
- }
|
|
|
+ }
|
|
|
+ if(dataSource.size()>0){
|
|
|
+ for(Map.Entry<Integer,Map<String,List<Object>>> entry:dataSource.entrySet()){
|
|
|
+ if(entry.getValue().keySet().size()>=ele.size()){
|
|
|
+ List<ElementData> eds = slice(entry.getValue(),this.constantMap,f,entry.getKey());
|
|
|
+ fd.setValues(eds);
|
|
|
}
|
|
|
-
|
|
|
- }else{
|
|
|
- fd.getValues().add(new ElementData(0,0,Expression.parse(formula.getFormula()).calculate(currentMap)));
|
|
|
}
|
|
|
- }else{
|
|
|
- fd.getValues().add(new ElementData(0,0,Expression.parse(formula.getFormula()).calculate(currentMap)));
|
|
|
}
|
|
|
+
|
|
|
+ }else{
|
|
|
+ fd.getValues().add(new ElementData(0,0,Expression.parse(formula.getFormula()).calculate(currentMap)));
|
|
|
}
|
|
|
+ }else{
|
|
|
+ fd.getValues().add(new ElementData(0,0,Expression.parse(formula.getFormula()).calculate(currentMap)));
|
|
|
}
|
|
|
}
|
|
|
}
|
|
|
- total.stream().filter(e->Func.isNotBlank(e.getFormula().getFormula())).map(FormData::getValues).forEach(e->e.stream().map(JSON::toJSONString).forEach(System.out::println));
|
|
|
- }
|
|
|
-
|
|
|
- @Override
|
|
|
- public void execute(TableElementConverter tec) {
|
|
|
- WbsTreeContract one = this.treeContractService.getById(tec.getTableInfoList().get(0).getPkeyId());
|
|
|
- this.execute(tec.getFds(),tec.getContractId(),Func.isNotEmpty(one.getOldId())?Long.parseLong(one.getOldId()):one.getParentId());
|
|
|
+ }
|
|
|
}
|
|
|
|
|
|
public Map<String,Object> getMap(Map<String,Object> main,String key){
|
|
@@ -226,7 +206,6 @@ public class FormulaServiceImpl extends BaseServiceImpl<FormulaMapper, Formula>
|
|
|
}
|
|
|
|
|
|
public List<ElementData> slice(Map<String,List<Object>> elementMap,Map<String,Object> constantMap,String formula,Integer groupId){
|
|
|
-
|
|
|
int min =0;
|
|
|
List<ElementData> result = new ArrayList<>();
|
|
|
|
|
@@ -264,8 +243,10 @@ public class FormulaServiceImpl extends BaseServiceImpl<FormulaMapper, Formula>
|
|
|
public static final String WP_REG= "(?<=P\\[)[^]]+(?=\\])";
|
|
|
public static final Pattern PP = Pattern.compile(WP_REG);
|
|
|
|
|
|
+ public static final Pattern AP=Pattern.compile("(E|WP)\\[([^]]+)]");
|
|
|
+
|
|
|
public static final String IF_REG= "(?<=T\\(com.mixsmart.utils.CustomFunction\\).ifelse\\()[^,]+(?=,)";
|
|
|
- public static final Pattern IF = Pattern.compile(WP_REG);
|
|
|
+ public static final Pattern IF = Pattern.compile(IF_REG);
|
|
|
/**
|
|
|
* 依赖排序
|
|
|
*/
|
|
@@ -320,23 +301,29 @@ public class FormulaServiceImpl extends BaseServiceImpl<FormulaMapper, Formula>
|
|
|
}
|
|
|
}
|
|
|
|
|
|
-/* public static void main(String[] args) {
|
|
|
- Set<Class<?>> classList = ReflectionUtil.getClassSetBySuper(IFcHandler.class);
|
|
|
- List<IFcHandler> receiptHandlerList = new ArrayList<>();
|
|
|
- if (classList.size() > 0) {
|
|
|
- for (Class<?> clazz : classList) {
|
|
|
- try {
|
|
|
- receiptHandlerList.add((IFcHandler)clazz.newInstance());
|
|
|
- } catch ( Exception e) {
|
|
|
- e.printStackTrace();
|
|
|
- }
|
|
|
- }
|
|
|
- }
|
|
|
- System.out.println();
|
|
|
- }*/
|
|
|
|
|
|
|
|
|
|
|
|
+public void polymerization(){
|
|
|
+// if(f.contains(CustomFunction.CLASS_CALL+"avg(")||f.contains(CustomFunction.CLASS_CALL+"min(")||f.contains(CustomFunction.CLASS_CALL+"max(")||f.contains(CustomFunction.CLASS_CALL+"sum(")){
|
|
|
+// /*聚合*/
|
|
|
+// Matcher m = POLY.matcher(f);
|
|
|
+// while (m.find()){
|
|
|
+// /**/
|
|
|
+// List<String> elementCodes=CustomFunction.parseElementCode(m.group(2));
|
|
|
+// List<FormData> tmp = ele.stream().filter(e->elementCodes.contains(e.getCode())).collect(Collectors.toList());
|
|
|
+// ele.removeAll(tmp);
|
|
|
+//
|
|
|
+// tmp.forEach(e-> E.put(e.getCode(),e.getValues().stream().map(ElementData::getValue).collect(Collectors.toList())));
|
|
|
+// Object data = Expression.parse(CustomFunction.CLASS_CALL+m.group()).calculate(currentMap);
|
|
|
+//
|
|
|
+// f = f.replace(CustomFunction.CLASS_CALL+m.group(),data.toString());
|
|
|
+// fd.getFormula().setFormula(f);
|
|
|
+// }
|
|
|
+// }
|
|
|
+}
|
|
|
+
|
|
|
+
|
|
|
}
|
|
|
|
|
|
|