|
@@ -1,119 +1,508 @@
|
|
|
package org.springblade.manager.formula.impl;
|
|
|
|
|
|
+import cn.hutool.core.util.HashUtil;
|
|
|
import com.jfireel.expression.Expression;
|
|
|
+import com.mixsmart.utils.CustomFunction;
|
|
|
import com.mixsmart.utils.FormulaUtils;
|
|
|
+import com.mixsmart.utils.RegexUtils;
|
|
|
import com.mixsmart.utils.StringUtils;
|
|
|
import lombok.Data;
|
|
|
import lombok.EqualsAndHashCode;
|
|
|
+import org.apache.poi.ss.usermodel.*;
|
|
|
+import org.springblade.common.utils.BaseUtils;
|
|
|
+import org.springblade.common.utils.CommonUtil;
|
|
|
import org.springblade.core.tool.utils.CollectionUtil;
|
|
|
import org.springblade.core.tool.utils.Func;
|
|
|
+import org.springblade.core.tool.utils.StringPool;
|
|
|
+import org.springblade.manager.dto.Coords;
|
|
|
+import org.springblade.manager.dto.ElementData;
|
|
|
import org.springblade.manager.dto.FormData;
|
|
|
import org.springblade.manager.dto.LocalVariable;
|
|
|
import org.springblade.manager.entity.Formula;
|
|
|
+import org.springblade.manager.formula.ElementWriter;
|
|
|
import org.springblade.manager.formula.FormulaLog;
|
|
|
+import org.springblade.manager.formula.KeyMapper;
|
|
|
import org.springblade.manager.formula.NodeTable;
|
|
|
|
|
|
import java.util.*;
|
|
|
+import java.util.function.Consumer;
|
|
|
+import java.util.function.Function;
|
|
|
+import java.util.function.Predicate;
|
|
|
+import java.util.regex.Matcher;
|
|
|
+import java.util.stream.Collectors;
|
|
|
+import java.util.stream.IntStream;
|
|
|
|
|
|
/**
|
|
|
* @author yangyj
|
|
|
* @Date 2023/12/18 14:01
|
|
|
- * @description TODO
|
|
|
+ * @description 通用计算
|
|
|
*/
|
|
|
@EqualsAndHashCode(callSuper = true)
|
|
|
@Data
|
|
|
public class ExecutorCalc extends FormulaExecutor {
|
|
|
+ public Function<List<String>, List<Map<String,Object>>> tableExcelInfoFc;
|
|
|
+ public ElementWriter elementWriter;
|
|
|
+ private String checkTable= StringPool.EMPTY;
|
|
|
+ public static final String SIMPLE="simple";
|
|
|
+ public static final String BATCH="batch";
|
|
|
public ExecutorCalc(TableElementConverter tec) {
|
|
|
super(tec);
|
|
|
}
|
|
|
|
|
|
- @Override
|
|
|
- public void handle() {
|
|
|
- /*通用计算*/
|
|
|
- generalCalc(tec);
|
|
|
+ /*判断是否需要批量计算*/
|
|
|
+ private Function<FormData,String> fcDict= fd->{
|
|
|
+ if(fd.getCoordsList().size()>1&&fd.getFormula().getFormula().split("[/+\\-*]").length>1){
|
|
|
+ /*批量计算*/
|
|
|
+ return BATCH;
|
|
|
+ }else{
|
|
|
+ /*默认返回普通计算*/
|
|
|
+ return SIMPLE;
|
|
|
+ }
|
|
|
+ };
|
|
|
+
|
|
|
+ public ExecuteFlow createExecuteFlow(){
|
|
|
+ Optional<NodeTable> op=tec.getTableAll().stream().filter(e->StringUtils.isEquals(1,e.getTableType())).findAny();
|
|
|
+ op.ifPresent(nodeTable -> this.checkTable = nodeTable.getInitTableName());
|
|
|
+ this.elementWriter=new MeterElementWriter();
|
|
|
+ return new ExecuteFlow();
|
|
|
}
|
|
|
|
|
|
- public void generalCalc(TableElementConverter tec){
|
|
|
- /*关键内容,常量变量集合,计算时变量集合,依赖元素,公式,输出元素,是否批量运算*/
|
|
|
+ @Override
|
|
|
+ public void handle() {
|
|
|
+ /*关键内容:常量变量集合,计算时变量集合,依赖元素,公式,输出元素,是否批量运算*/
|
|
|
+ /*执行条件:有没有依赖,是否批量执行*/
|
|
|
+ /*写入情况:一对多,一对一,多对一,多对多*/
|
|
|
+ /*并发说明:有依赖关系,需要按顺序执行,否则有可能取不到内容*/
|
|
|
+ ExecuteFlow executeFlow=createExecuteFlow();
|
|
|
for(FormData fd:tec.formDataList){
|
|
|
if(fd.verify()){
|
|
|
- Formula formula =fd.getFormula();
|
|
|
- String f=formula.getFormula();
|
|
|
- if(Func.isNotBlank(f)){
|
|
|
- try{
|
|
|
- Map<String, Object> currentMap = new HashMap<>(tec.constantMap);
|
|
|
- List<String> relyList = fd.getFormula().getRelyList();
|
|
|
- if(CollectionUtil.isNotEmpty(relyList)){
|
|
|
- /*存在依赖*/
|
|
|
- List<FormData> ele = new ArrayList<>();
|
|
|
- relyList.forEach(rely->{
|
|
|
- FormData formData= tec.getFormDataMap().get(rely);
|
|
|
- if(formData!=null&&!formData.empty()){
|
|
|
- ele.add(formData);
|
|
|
- }
|
|
|
- });
|
|
|
- /*并不是所有依赖都用FormData表示*/
|
|
|
- if(ele.size()<relyList.size()){
|
|
|
- tec.getLog().put(FormulaLog.RELY,fd.getCode()+"@"+fd.getEName()+"@"+fd.getFormula().getFormula().replaceAll("'", ""));
|
|
|
- continue;
|
|
|
- }
|
|
|
- FormulaUtils.putEle(f,ele,currentMap,fd);
|
|
|
- Object data = Expression.parse(formula.getFormula()).calculate(currentMap);
|
|
|
- FormulaUtils.write(fd,data);
|
|
|
- }else{
|
|
|
- Object data =Expression.parse(formula.getFormula()).calculate(currentMap);
|
|
|
- FormulaUtils.write(fd,data);
|
|
|
- }
|
|
|
- }catch (Exception e){
|
|
|
- e.printStackTrace();
|
|
|
- tec.getLog().put(FormulaLog.CALC,fd.getEName()+"("+formula+")");
|
|
|
- }
|
|
|
-
|
|
|
+ try {
|
|
|
+ /*自定义脚本预处理*/
|
|
|
+ preCalc(fd);
|
|
|
+ /*解析器通用脚本*/
|
|
|
+ executeFlow.start(fd).depend(dependenceHandler).calculate();
|
|
|
+ }catch (Exception e){
|
|
|
+ e.printStackTrace();
|
|
|
+ tec.getLog().put(FormulaLog.CALC,fd.getEName()+"("+fd.getFormula().getFormula()+")");
|
|
|
}
|
|
|
- fd.setUpdate(1);
|
|
|
}
|
|
|
}
|
|
|
+ }
|
|
|
+
|
|
|
+ @Data
|
|
|
+ class ExecuteFlow{
|
|
|
+ Map<String,Calculation> calculationMap = new HashMap<>();
|
|
|
+ private Function<FormData,String> pickCalculation;
|
|
|
+ Function<FormData,List<FormData>> dependenceHandler;
|
|
|
+ private FormData formData;
|
|
|
+ private Calculation calculation;
|
|
|
+
|
|
|
+ public ExecuteFlow() {
|
|
|
+ calculationMap.put(SIMPLE,new SimpleCalculation());
|
|
|
+ calculationMap.put(BATCH,new BatchCalculation());
|
|
|
+ pickCalculation=fcDict;
|
|
|
+ }
|
|
|
+
|
|
|
+ public ExecuteFlow start(FormData fd){
|
|
|
+ this.formData=fd;
|
|
|
+ this.calculation= calculationMap.get(pickCalculation.apply(fd));
|
|
|
+ return this;
|
|
|
+ }
|
|
|
+
|
|
|
+ public ExecuteFlow depend(Function<FormData,List<FormData>> depend){
|
|
|
+ this.dependenceHandler=depend;
|
|
|
+ return this;
|
|
|
+ }
|
|
|
+
|
|
|
+ public void calculate(){
|
|
|
+ this.calculation.calculate(this.formData,dependenceHandler);
|
|
|
+ }
|
|
|
+
|
|
|
+
|
|
|
|
|
|
}
|
|
|
|
|
|
+ /**元素数据写入类*/
|
|
|
+ static class MeterElementWriter implements ElementWriter {
|
|
|
+ public void write(FormData fd, Object data){
|
|
|
+ write(fd,data,false);
|
|
|
+ }
|
|
|
+ public void write(FormData fd, Object data,Boolean containsNull){
|
|
|
+ if(checkEmpty(fd)){
|
|
|
+ /*无定位信息不写入*/
|
|
|
+ return;
|
|
|
+ }
|
|
|
+ try {
|
|
|
+ /*写入前清空内容*/
|
|
|
+ clear(fd);
|
|
|
+ List<Object> values = toList(data,containsNull);
|
|
|
+ /*计量写入数据无效考虑是否存在表页实体,也就不存在超页的概念,只管按需自动增页写人,任何元素初始化都是一页*/
|
|
|
+ int capacity=fd.getCoordsList().size();
|
|
|
+ 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());
|
|
|
+ }).collect(Collectors.toList());
|
|
|
+ fd.setValues(eds);
|
|
|
+ fd.setUpdate(1);
|
|
|
+ }catch (Exception e){
|
|
|
+ e.printStackTrace();
|
|
|
+ }
|
|
|
+ }
|
|
|
+ /*检查写入目标地址是否未空*/
|
|
|
+ public boolean checkEmpty(FormData fd){
|
|
|
+ return Func.isEmpty(fd.getCoordsList());
|
|
|
+ }
|
|
|
+ /*写入前需要清空原内容*/
|
|
|
+ public void clear(FormData fd){
|
|
|
+ fd.getValues().forEach(t->t.setValue(null));
|
|
|
+ }
|
|
|
+
|
|
|
+ /*原素数据一律用List集合表示*/
|
|
|
+ public List<Object> toList(Object raw,boolean containsNull){
|
|
|
+ List<Object> values= Optional.ofNullable(raw)
|
|
|
+ .filter(List.class::isInstance)
|
|
|
+ .map(list -> (List<Object>) list)
|
|
|
+ .orElseGet(() -> Collections.singletonList(raw));
|
|
|
+ if(containsNull){
|
|
|
+ return values.stream().filter(StringUtils::isNotEmpty).collect(Collectors.toList());
|
|
|
+ }
|
|
|
+ return values;
|
|
|
+
|
|
|
+ }
|
|
|
|
|
|
- interface Calculation {
|
|
|
- void calculate(Formula formula, List<FormData> ele, TableElementConverter tec);
|
|
|
}
|
|
|
|
|
|
- static class SimpleCalculation implements Calculation{
|
|
|
+ interface Calculation {
|
|
|
+ void calculate(FormData fd, Function<FormData,List<FormData>> dependenceHandler );
|
|
|
+ }
|
|
|
|
|
|
+ @Data
|
|
|
+ class SimpleCalculation implements Calculation{
|
|
|
@Override
|
|
|
- public void calculate(Formula formula, List<FormData> ele, TableElementConverter tec) {
|
|
|
-
|
|
|
+ public void calculate(FormData fd , Function<FormData,List<FormData>> dependenceHandler ) {
|
|
|
+ List<FormData> relyElements= dependenceHandler.apply(fd);
|
|
|
+ if(relyElements==null){
|
|
|
+ /*null说明存在依赖却没有匹配成功,可能是内容为空或者找不到*/
|
|
|
+ return;
|
|
|
+ }
|
|
|
+ String formulaStr=fd.getFormula().getFormula();
|
|
|
+ Map<String, Object> currentMap = new HashMap<>(tec.constantMap);
|
|
|
+ if(relyElements.size()>0) {
|
|
|
+ FormulaUtils.putEle(formulaStr,relyElements,currentMap,fd);
|
|
|
+ }
|
|
|
+ Object data = Expression.parse(formulaStr).calculate(currentMap);
|
|
|
+ elementWriter.write(fd, data);
|
|
|
}
|
|
|
+
|
|
|
+
|
|
|
}
|
|
|
|
|
|
- static class BatchCalculation implements Calculation{
|
|
|
|
|
|
+ @Data
|
|
|
+ class BatchCalculation implements Calculation{
|
|
|
@Override
|
|
|
- public void calculate(Formula formula, List<FormData> ele, TableElementConverter tec) {
|
|
|
+ public void calculate(FormData fd, Function<FormData,List<FormData>> dependenceHandler ) {
|
|
|
+ List<FormData> relyElements= dependenceHandler.apply(fd);
|
|
|
+ if(relyElements==null){
|
|
|
+ /*null说明存在依赖却没有匹配成功,可能是内容为空或者找不到*/
|
|
|
+ return;
|
|
|
+ }
|
|
|
+ String formulaStr=fd.getFormula().getFormula();
|
|
|
+ LinkedHashMap<String,FormData> fdMap=FormulaUtils.step(relyElements);
|
|
|
+ List<LocalVariable> local= FormulaUtils.slice2Local(formulaStr,fdMap,tec);
|
|
|
+ if(local.size()>0){
|
|
|
+ List<Object> values = FormulaUtils.slice(local,formulaStr);
|
|
|
+ elementWriter.write(fd,values ,!fd.getTableName().equals(checkTable));
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
+ }
|
|
|
+
|
|
|
+
|
|
|
+
|
|
|
+
|
|
|
+
|
|
|
+ Function<FormData,List<FormData>> dependenceHandler = fd->{
|
|
|
+ List<String> relyList = fd.getFormula().getRelyList();
|
|
|
+ List<FormData> ele = new ArrayList<>();
|
|
|
+ if(CollectionUtil.isNotEmpty(relyList)) {
|
|
|
+ /*存在依赖*/
|
|
|
+ relyList.forEach(rely -> {
|
|
|
+ FormData formData = tec.getFormDataMap().get(rely);
|
|
|
+ if (formData != null && !formData.empty()) {
|
|
|
+ ele.add(formData);
|
|
|
+ }
|
|
|
+ });
|
|
|
+ /*并不是所有依赖都用FormData表示*/
|
|
|
+ if (ele.size() < relyList.size()) {
|
|
|
+ tec.getLog().put(FormulaLog.RELY, fd.getCode() + "@" + fd.getEName() + "@" + fd.getFormula().getFormula().replaceAll("'", ""));
|
|
|
+ return null;
|
|
|
+ }
|
|
|
+ }
|
|
|
+ return ele;
|
|
|
+ };
|
|
|
+
|
|
|
+
|
|
|
+ /**
|
|
|
+ * 先把公式脚本需要聚合部分预处理
|
|
|
+ * */
|
|
|
+ public void preCalc(FormData fd){
|
|
|
+ try{
|
|
|
+ Formula formula=fd.getFormula();
|
|
|
+ String f=formula.getFormula();
|
|
|
+ if (f.contains("converge")){
|
|
|
+ Matcher m = RegexUtils.matcher(FC_REG+"(converge)\\(([^)]+)\\)",f);
|
|
|
+ while (m.find()){
|
|
|
+ List<FormData> target = getFormDataByCode(m.group(2));
|
|
|
+ Object data =target.stream().flatMap(e->e.getValues().stream()).map(ElementData::getValue).filter(StringUtils::isNotEmpty).collect(Collectors.toList());
|
|
|
+ f=f.replace(m.group(),tec.putDataWithKey(data));
|
|
|
+ }
|
|
|
+ }
|
|
|
+ if(f.contains("compound")){
|
|
|
+ Matcher m = RegexUtils.matcher(FC_REG+"(compound)\\(([^)]+)\\)",f);
|
|
|
+ while (m.find()){
|
|
|
+ List<FormData> target = getFormDataByCode(m.group(2));
|
|
|
+ List<List<Object>> values=target.stream().map(e->e.getValues().stream().map(ElementData::getValue).collect(Collectors.toList())).collect(Collectors.toList());
|
|
|
+ List<String> eNames=target.stream().map(FormData::getEName).collect(Collectors.toList());
|
|
|
+ Map<String,List<Object>> data = new LinkedHashMap<>();
|
|
|
+ for(int i=0;i<eNames.size();i++){
|
|
|
+ data.put(eNames.get(i),values.get(i));
|
|
|
+ }
|
|
|
+ f=f.replace(m.group(),tec.putDataWithKey(data));
|
|
|
+ }
|
|
|
+ }
|
|
|
+ if(f.contains(".option")){
|
|
|
+ /*FC.optionC?是无法嵌套的函数*/
|
|
|
+ Matcher m = RegexUtils.matcher(FC_REG+"optionC?\\(([^)(]+),",f);
|
|
|
+ while (m.find()){
|
|
|
+ /* String[] args= m.group(2).split(",");*/
|
|
|
+ String flag=m.group(1);
|
|
|
+ /*radio控件,结果只有两个0,1 ,结果作为标识位,且为1才会执第二个参数的回调方法*/
|
|
|
+ if("OPTION".equals(flag)){
|
|
|
+ Optional<KeyMapper> kOp=tec.getKeyMappers().stream().filter(e->StringUtils.isEquals(e.getCode(),fd.getCode())).findFirst();
|
|
|
+ if(kOp.isPresent()){
|
|
|
+ /*表名+合同段+父节点*/
|
|
|
+ String findStr="OP['"+fd.getTableName()+"']['"+fd.getKey()+"']['TF']";
|
|
|
+ flag=StringUtils.handleNull(Expression.parse(findStr).calculate(tec.constantMap));
|
|
|
+ }
|
|
|
+ }else if(flag.contains("E[")){
|
|
|
+ List<FormData> target = getFormDataByCode(flag);
|
|
|
+ if(target.size()>0){
|
|
|
+ flag= target.get(0).getValues().stream().map(ElementData::stringValue).filter(StringUtils::isNotEmpty).findFirst().orElse("0");
|
|
|
+ }
|
|
|
+ }
|
|
|
+ if(Func.isBlank(flag)||"OPTION".equals(flag)){
|
|
|
+ /*默认0*/
|
|
|
+ flag="0";
|
|
|
+ }
|
|
|
+ if(StringUtils.isEquals(flag,1)){
|
|
|
+ f=f.replace(m.group(),"").replaceAll("\\)$","");
|
|
|
+ }else{
|
|
|
+ fd.setFinished(Boolean.TRUE);
|
|
|
+ f="''";
|
|
|
+ }
|
|
|
+ }
|
|
|
+ }
|
|
|
+ if(f.contains(".ifelse")){
|
|
|
+ int max=0;
|
|
|
+ do{
|
|
|
+ Matcher m = RegexUtils.matcher(FC_REG+"(ifelse)\\(([^)]+)\\)",f);
|
|
|
+ while (m.find()){
|
|
|
+ String el=m.group();
|
|
|
+ String pstr=el.replaceAll("^"+FC_REG+"ifelse\\(","").replaceAll("\\)$","");
|
|
|
+ String[] pa =pstr.split(",");
|
|
|
+ if(pa.length==3){
|
|
|
+ Object data = Expression.parse(pa[0]+"?"+pa[1]+":"+pa[2]).calculate(createCurrentMap(el));
|
|
|
+ f=f.replace(el,tec.putDataWithKey(data));
|
|
|
+ }else{
|
|
|
+ f=f.replace(el,"参数格式错误");
|
|
|
+ }
|
|
|
|
|
|
+ }
|
|
|
+ max++;
|
|
|
+ }while (f.contains("ifelse")&&max<20);
|
|
|
+ }
|
|
|
+ if(f.contains("avg4segment")){
|
|
|
+ Matcher m = RegexUtils.matcher(FC_REG+"(avg4segment)\\(([^)]+)\\)",f);
|
|
|
+ while (m.find()){
|
|
|
+ String[] args=m.group(2).split(",");
|
|
|
+ List<FormData> target = getFormDataByCode(args[0]);
|
|
|
+ if(!target.isEmpty()){
|
|
|
+ FormData a=target.get(0);
|
|
|
+ int n=Math.max(1,a.coordsList.size()/fd.getCoordsList().size());
|
|
|
+ List<Object> data= CustomFunction.avg4segment(a.getValues().stream().map(ElementData::getValue).collect(Collectors.toList()),n);
|
|
|
+ f=f.replace(m.group(),tec.putDataWithKey(data));
|
|
|
+ }
|
|
|
+ }
|
|
|
+ }
|
|
|
+ if(f.contains("skip")){
|
|
|
+ Matcher m = RegexUtils.matcher(FC_REG+"(skip)\\(([^)]+)\\)",f);
|
|
|
+ while (m.find()){
|
|
|
+ String[] args=m.group(2).split(",");
|
|
|
+ List<FormData> target = getFormDataByCode(args[0]);
|
|
|
+ if(!target.isEmpty()){
|
|
|
+ FormData a=target.get(0);
|
|
|
+ a.setOffset(StringUtils.handleObj2Integer(args[1]));
|
|
|
+ f=f.replace(m.group(),args[0]);
|
|
|
+ }
|
|
|
+ }
|
|
|
+ }
|
|
|
+ formula.setFormula(f);
|
|
|
+ if(f.contains("quantity")){
|
|
|
+ quantity(formula,fd,f);
|
|
|
+ }
|
|
|
+ }catch (Exception e){
|
|
|
+ tec.getLog().put(FormulaLog.OTHER,e.getMessage());
|
|
|
+ e.printStackTrace();
|
|
|
+ }
|
|
|
+ }
|
|
|
+ /*合格率预处理*/
|
|
|
+ public void quantity( Formula formula,FormData fd,String f){
|
|
|
+ /*聚合*/
|
|
|
+ Matcher m = RegexUtils.matcher(FC_REG+"(quantity)\\(([^)]+)\\)",f);
|
|
|
+ while (m.find()) {
|
|
|
+ Object data=null;
|
|
|
+ List<String> codeList = FormulaUtils.getCodeList(m.group(2));
|
|
|
+ {
|
|
|
+ FormData dataFd=tec.formDataMap.get(codeList.get(0));
|
|
|
+ String designStr=codeList.get(1);
|
|
|
+ FormData designFd=tec.formDataMap.get(designStr);
|
|
|
+ String devStr=StringUtils.isNotEmpty(formula.getDev())?formula.getDev():fd.getEAllowDeviation();
|
|
|
+ if(StringUtils.isEmpty(devStr)){
|
|
|
+ /*数据库找不到的情况就读取Excel*/
|
|
|
+ if(tec.wkbMap.isEmpty()){
|
|
|
+ /*初始化*/
|
|
|
+ List<String> tableNames4Excel= tec.getFormDataList().stream().filter(FormData::executable).filter(e->e.info().contains("quantity")).map(FormData::getTableName).distinct().collect(Collectors.toList());
|
|
|
+ if(!tableNames4Excel.isEmpty()){
|
|
|
+ List<String> ids =tec.getTableAll().stream().filter(e->tableNames4Excel.contains(e.getInitTableName())).map(NodeTable::getPKeyId).map(String::valueOf).collect(Collectors.toList());
|
|
|
+ //List<Map<String,Object>> listMaps= this.jdbcTemplate.queryForList("select a.p_key_id pkeyId,a.init_table_name tableName,b.file_url url from m_wbs_tree_contract a join m_excel_tab b on a.excel_id=b.id where a.p_key_id in("+String.join(",",ids)+")");
|
|
|
+ List<Map<String,Object>> listMaps =tableExcelInfoFc.apply(ids);
|
|
|
+ listMaps.forEach(mp->{
|
|
|
+ try {
|
|
|
+ Workbook wb = WorkbookFactory.create(Objects.requireNonNull(CommonUtil.getOSSInputStream(StringUtils.handleNull(mp.get("url")))));
|
|
|
+ tec.wkbMap.put(mp.get("pkeyId").toString(),wb);
|
|
|
+ } catch (Exception e) {
|
|
|
+ e.printStackTrace();
|
|
|
+ }
|
|
|
+ });
|
|
|
+ }
|
|
|
+ }
|
|
|
+ Optional<NodeTable> nodeTableOp =tec.getTableAll().stream().filter(e->e.getInitTableName().equals(fd.getTableName())).findFirst();
|
|
|
+ if(nodeTableOp.isPresent()){
|
|
|
+ Workbook wb = tec.wkbMap.get(nodeTableOp.get().getPKeyId().toString());
|
|
|
+ if(wb!=null){
|
|
|
+ Cell deCell=null;
|
|
|
+ Sheet sheet = wb.getSheetAt(0);
|
|
|
+ outerLoop: for(int y=3;y<35;y++){
|
|
|
+ for(int x=0;x<35;x++){
|
|
|
+ Row row = sheet.getRow(y);
|
|
|
+ Cell cell= row.getCell(x);
|
|
|
+ String sv=StringUtils.handleNull(FormulaUtils.getValue(cell)).replaceAll("[^\u4e00-\u9fa5]+","");
|
|
|
+ if(sv.contains("规定")&&sv.contains("偏差")){
|
|
|
+ deCell=cell;
|
|
|
+ break outerLoop;
|
|
|
+ }
|
|
|
+ }
|
|
|
+ }
|
|
|
+ if(deCell!=null) {
|
|
|
+ int min = 0;
|
|
|
+ Optional<Integer> op = fd.getCoordsList().stream().map(Coords::getY).distinct().min(Comparator.comparingInt(e -> e));
|
|
|
+ if (op.isPresent()) {
|
|
|
+ min = op.get();
|
|
|
+ }
|
|
|
+ Row row = sheet.getRow(min);
|
|
|
+ Cell cell = row.getCell(deCell.getColumnIndex());
|
|
|
+ devStr = FormulaUtils.getValue(cell).toString();
|
|
|
+ }
|
|
|
+ }
|
|
|
+ }
|
|
|
+ }
|
|
|
+ if(CustomFunction.containsZH(devStr)||StringUtils.isEmpty(devStr)||StringUtils.handleNull(devStr).contains("/")){
|
|
|
+ devStr="±100000";
|
|
|
+ }
|
|
|
+ if(devStr.contains("E[")){
|
|
|
+ List<String> codes= getCodeByEl(devStr);
|
|
|
+ Map<String,Object> map = new HashMap<>();
|
|
|
+ boolean isNull=false;
|
|
|
+ for (String c:codes){
|
|
|
+ FormData ffd= tec.getFormDataMap().get(c);
|
|
|
+ if(ffd.empty()){
|
|
|
+ isNull=true;
|
|
|
+ break;
|
|
|
+ } else{
|
|
|
+ map.put("E["+c+"]",ffd.getRawValue().stream().filter(StringUtils::isNotEmpty).findFirst().orElse(null)) ;
|
|
|
+ }
|
|
|
+ }
|
|
|
+ if(isNull){
|
|
|
+ devStr="±100000";
|
|
|
+ }
|
|
|
+ devStr= Arrays.stream(devStr.replaceAll("^\\[|\\]$","").split(",")).map(s->map.getOrDefault(s,s)).map(StringUtils::handleNull).collect(Collectors.joining(","));
|
|
|
+ }
|
|
|
+ /*设计值可以是数值类型,或空(等效0)*/
|
|
|
+ if(dataFd!=null){
|
|
|
+ List<Object> values= dataFd.getRawValue();
|
|
|
+ boolean nonNumeric=values.stream().filter(StringUtils::isNotEmpty).anyMatch(e->!StringUtils.isNumber(e));
|
|
|
+ if(nonNumeric){
|
|
|
+ data=values.stream().filter(StringUtils::isNotEmpty).count();
|
|
|
+ }else if(designFd!=null){
|
|
|
+ if(dataFd.getValues().stream().map(ElementData::getValue).anyMatch(StringUtils::isNotEmpty)&&(designFd.getValues().size()>1||designFd.getValues().stream().map(ElementData::getValue).anyMatch(StringUtils::isEmpty))){
|
|
|
+ /*多少个设计值暂时默认全部合格,满足绝大部分结果*/
|
|
|
+ data=dataFd.getValues().stream().map(ElementData::getValue).filter(StringUtils::isNotEmpty).count();
|
|
|
+ }else{
|
|
|
+ List<Object> result = CustomFunction.b445check(dataFd.getValues().stream().map(ElementData::getValue).collect(Collectors.toList()),designFd.getValues().stream().map(ElementData::getValue).collect(Collectors.toList()),devStr,1 );
|
|
|
+ data=result.get(1);
|
|
|
+ }
|
|
|
+ }else if(BaseUtils.isNumber(designStr)) {
|
|
|
+ List<Object> result = CustomFunction.b445check(dataFd.getValues().stream().map(ElementData::getValue).collect(Collectors.toList()), 0, devStr, 1);
|
|
|
+ data = result.get(1);
|
|
|
+ }
|
|
|
+ }
|
|
|
+ }
|
|
|
+ f = f.replace(m.group(),tec.putDataWithKey(BaseUtils.isNumber(data)?Double.parseDouble(data.toString()):data));
|
|
|
}
|
|
|
+ fd.getFormula().setFormula(f);
|
|
|
+ formula.setScale(1);
|
|
|
}
|
|
|
|
|
|
- interface DependenceHandler {
|
|
|
- boolean handle(String rely, TableElementConverter tec);
|
|
|
+ public List<String> getCodeByEl(String el){
|
|
|
+ List<String> l = new ArrayList<>();
|
|
|
+ if(Func.isNotBlank(el)){
|
|
|
+ Matcher m = FormulaUtils.P.matcher(el);
|
|
|
+ while (m.find()){
|
|
|
+ String tmp =m.group().replaceAll("'","");
|
|
|
+ l.add(tmp);
|
|
|
+ }
|
|
|
+ }
|
|
|
+ return l;
|
|
|
}
|
|
|
|
|
|
- static class FormDataDependenceHandler implements DependenceHandler {
|
|
|
- @Override
|
|
|
- public boolean handle(String rely, TableElementConverter tec) {
|
|
|
- return false;
|
|
|
+
|
|
|
+ /*根据参数获取所有的元素*/
|
|
|
+ public List<FormData> getFormDataByCode(String codes){
|
|
|
+ List<FormData> target = new ArrayList<>();
|
|
|
+ String[] tfa=codes.split(",");
|
|
|
+ for(String code:tfa){
|
|
|
+ code=code.replace("E['","").replace("']","");
|
|
|
+ FormData fdt=tec.formDataMap.get(code);
|
|
|
+ if(fdt!=null){
|
|
|
+ target.add(fdt);
|
|
|
+ }
|
|
|
}
|
|
|
+ return target;
|
|
|
}
|
|
|
|
|
|
- static class OtherDependenceHandler implements DependenceHandler {
|
|
|
- @Override
|
|
|
- public boolean handle(String rely, TableElementConverter tec) {
|
|
|
- return false;
|
|
|
+ public Map<String,Object> createCurrentMap(String el){
|
|
|
+ Map<String,Object> currentMap= new HashMap<>(tec.constantMap);
|
|
|
+ List<FormData> fds= getFormDataByCode(String.join(",", getCodeByEl(el)));
|
|
|
+ if(Func.isNotEmpty(fds)){
|
|
|
+ Map<String,Object> Em= (Map<String, Object>) currentMap.computeIfAbsent(E, k->new HashMap<String,Object>());
|
|
|
+ fds.forEach(e->{
|
|
|
+ Em.put(e.getCode(),e.getValues().stream().map(ElementData::getValue).collect(Collectors.toList()));
|
|
|
+ });
|
|
|
}
|
|
|
+ return currentMap;
|
|
|
}
|
|
|
+
|
|
|
public void generalCalcOld(TableElementConverter tec){
|
|
|
String checkTable ="";
|
|
|
Optional<NodeTable> op=tec.getTableAll().stream().filter(e->StringUtils.isEquals(1,e.getTableType())).findAny();
|