Browse Source

计算重构2

wangchangsheng 2 years ago
parent
commit
898cc49897

+ 8 - 0
ims-common/pom.xml

@@ -43,6 +43,14 @@
             <groupId>org.apache.poi</groupId>
             <artifactId>poi</artifactId>
         </dependency>
+        <dependency>
+            <groupId>org.apache.poi</groupId>
+            <artifactId>poi-ooxml</artifactId>
+        </dependency>
+        <dependency>
+            <groupId>org.apache.poi</groupId>
+            <artifactId>poi-ooxml</artifactId>
+        </dependency>
     </dependencies>
 
     <build>

+ 61 - 0
ims-common/src/main/java/com/ims/common/function/CalculateMortgage.java

@@ -0,0 +1,61 @@
+package com.ims.common.function;
+
+import org.apache.poi.ss.formula.OperationEvaluationContext;
+import org.apache.poi.ss.formula.eval.*;
+import org.apache.poi.ss.formula.functions.FreeRefFunction;
+
+public class CalculateMortgage  implements FreeRefFunction {
+
+	@Override
+	public ValueEval evaluate(ValueEval[] args, OperationEvaluationContext ec ) {
+		if (args.length != 3) {
+			return ErrorEval.VALUE_INVALID;
+		}
+		double principal, rate, years,  result;
+		try {
+			ValueEval v1 = OperandResolver.getSingleValue( args[0],
+				ec.getRowIndex(),
+				ec.getColumnIndex() ) ;
+			ValueEval v2 = OperandResolver.getSingleValue( args[1],
+				ec.getRowIndex(),
+				ec.getColumnIndex() ) ;
+			ValueEval v3 = OperandResolver.getSingleValue( args[2],
+				ec.getRowIndex(),
+				ec.getColumnIndex() ) ;
+			principal  = OperandResolver.coerceValueToDouble( v1 ) ;
+			rate  = OperandResolver.coerceValueToDouble( v2 ) ;
+			years = OperandResolver.coerceValueToDouble( v3 ) ;
+
+			result = calculateMortgagePayment( principal, rate, years ) ;
+
+			checkValue(result);
+
+		} catch (EvaluationException e) {
+			e.printStackTrace() ;
+			return e.getErrorEval();
+		}
+		return new NumberEval( result ) ;
+	}
+
+	public double calculateMortgagePayment( double p, double r, double y ) {
+		double i = r / 12 ;
+		double n = y * 12 ;
+
+		//M = P [ i(1 + i)n ] / [ (1 + i)n - 1]
+		double principalAndInterest =
+			p * (( i * Math.pow((1 + i),n ) ) / ( Math.pow((1 + i),n) - 1))  ;
+
+		return principalAndInterest ;
+	}
+
+	/**
+	 * Excel does not support infinities and NaNs, rather, it gives a #NUM! error in these cases
+	 *
+	 * @throws EvaluationException (#NUM!) if <tt>result</tt> is <tt>NaN</> or <tt>Infinity</tt>
+	 */
+	static final void checkValue(double result) throws EvaluationException {
+		if (Double.isNaN(result) || Double.isInfinite(result)) {
+			throw new EvaluationException(ErrorEval.NUM_ERROR);
+		}
+	}
+}

+ 34 - 0
ims-common/src/main/java/com/ims/common/function/IFSFunction.java

@@ -0,0 +1,34 @@
+package com.ims.common.function;
+
+import org.apache.poi.ss.formula.OperationEvaluationContext;
+import org.apache.poi.ss.formula.eval.BoolEval;
+import org.apache.poi.ss.formula.eval.ErrorEval;
+import org.apache.poi.ss.formula.eval.ValueEval;
+import org.apache.poi.ss.formula.functions.FreeRefFunction;
+
+public class IFSFunction implements FreeRefFunction {
+	/**
+	 * 函数名
+	 */
+	public static final String FUNCTION_NAME = "IFS";
+
+	@Override
+	public ValueEval evaluate(ValueEval[] valueEvals, OperationEvaluationContext operationEvaluationContext) {
+		if (valueEvals == null || valueEvals.length % 2 != 0) {
+			return ErrorEval.FUNCTION_NOT_IMPLEMENTED;
+		}
+		int length = valueEvals.length;
+		for (int i = 0; i < length; i++) {
+			if (i % 2 == 0) {
+				ValueEval valueEval = valueEvals[i];
+				if (valueEval instanceof BoolEval) {
+					BoolEval boolEval = (BoolEval) valueEval;
+					if (boolEval.getBooleanValue()) {
+						return valueEvals[i + 1];
+					}
+				}
+			}
+		}
+		return valueEvals[length - 1];
+	}
+}

+ 52 - 3
ims-common/src/main/java/com/ims/common/utils/FormulaUtils.java

@@ -1,10 +1,15 @@
 package com.ims.common.utils;
 
+import com.ims.common.function.IFSFunction;
 import org.apache.poi.hssf.usermodel.*;
 import org.apache.poi.ss.formula.FormulaParseException;
-import org.apache.poi.ss.usermodel.CellType;
-import org.apache.poi.ss.usermodel.FormulaEvaluator;
+import org.apache.poi.ss.formula.functions.FreeRefFunction;
+import org.apache.poi.ss.formula.udf.AggregatingUDFFinder;
+import org.apache.poi.ss.formula.udf.DefaultUDFFinder;
+import org.apache.poi.ss.formula.udf.UDFFinder;
+import org.apache.poi.ss.usermodel.*;
 
+import java.io.IOException;
 import java.math.BigDecimal;
 
 public class FormulaUtils {
@@ -25,12 +30,15 @@ public class FormulaUtils {
 	 * @param formula Excel 中的公式,例如:MAX(56-FLOOR(20/6,1),2)
 	 * @return
 	 */
-	public static double caculateFormula(String formula) {
+	public static double caculateFormula1(String formula) {
 		if(formula.startsWith("=")){
 			formula =formula.replace("=","");
 		}
 		HSSFWorkbook workbook = new HSSFWorkbook();
+		workbook.addToolPack(new AggregatingUDFFinder(new DefaultUDFFinder(new String[]{IFSFunction.FUNCTION_NAME}, new FreeRefFunction[]{new IFSFunction()})));
+
 		HSSFSheet sheet = workbook.createSheet();
+
 		row = sheet.createRow(0);
 		formulaEvaluator = new HSSFFormulaEvaluator(workbook);
 
@@ -46,4 +54,45 @@ public class FormulaUtils {
 			return 0;
 		}
 	}
+
+
+	public static double caculateFormula(String formula){
+		Workbook workbook = null;
+		try {
+			workbook = new HSSFWorkbook();
+
+			String[] functionNames = { IFSFunction.FUNCTION_NAME } ;
+			FreeRefFunction[] functionImpls = { new IFSFunction() } ;
+
+			UDFFinder udfs = new DefaultUDFFinder( functionNames, functionImpls ) ;
+			UDFFinder udfToolpack = new AggregatingUDFFinder( udfs ) ;
+
+			workbook.addToolPack(udfToolpack);
+
+			FormulaEvaluator evaluator = workbook.getCreationHelper().createFormulaEvaluator();
+
+			Sheet sheet = workbook.createSheet();
+			Row row = sheet.createRow(0);
+			Cell cell = row.createCell(0);
+			cell.setCellFormula(formula);
+			cell.setCellType(CellType.FORMULA);
+
+			double value = evaluator.evaluate(cell).getNumberValue() ;
+			return new BigDecimal(value).setScale(2, BigDecimal.ROUND_CEILING).doubleValue();
+		} catch (Exception e) {
+			e.printStackTrace();
+		}finally {
+			try {
+				if(null != workbook){
+					workbook.close();
+				}
+			} catch (IOException e) {
+				e.printStackTrace();
+			}
+
+		}
+
+		return 0.0;
+	}
+
 }

+ 6 - 1
ims-service/ims-eval/src/main/java/com/ims/eval/controller/CalculatorController.java

@@ -2,6 +2,7 @@ package com.ims.eval.controller;
 
 import com.ims.eval.entity.dto.result.R;
 import com.ims.eval.schedule.ScoreCalculationSchedule;
+import com.ims.eval.service.IOrganizationEvaluationInfoService;
 import org.springframework.beans.factory.annotation.Autowired;
 import org.springframework.web.bind.annotation.GetMapping;
 import org.springframework.web.bind.annotation.RequestMapping;
@@ -23,9 +24,13 @@ public class CalculatorController {
 	@Autowired
 	private ScoreCalculationSchedule scoreCalculationSchedule;
 
+	@Autowired
+	private IOrganizationEvaluationInfoService organizationEvaluationInfoService;
+
 	@GetMapping("/cron")
 	public R test(@RequestParam("id") String id){
-		boolean b = scoreCalculationSchedule.doTask(id);
+		boolean b = organizationEvaluationInfoService.calculationByEvaluationId("","",id,"");
+//		boolean b = scoreCalculationSchedule.doTask(id);
 		if (b){
 			return R.ok().data(b);
 		}else {

+ 1 - 0
ims-service/ims-eval/src/main/java/com/ims/eval/controller/OrganizationEvaluationInfoController.java

@@ -128,6 +128,7 @@ public class OrganizationEvaluationInfoController {
 				}
 				boolean b = organizationEvaluationInfoService.saveOrUpdateBatch(bindingList);
 				if (b) {
+					organizationEvaluationInfoService.calculationByEvaluationId("","",bindingList.get(0).getOrganizationEvaluationId(),"");
 					return R.ok().data(b);
 				} else {
 					return R.error().data("保存失败!");

+ 1 - 1
ims-service/ims-eval/src/main/java/com/ims/eval/entity/EvaluationScoreCount.java

@@ -15,7 +15,7 @@ import lombok.*;
 @Data
 @EqualsAndHashCode(callSuper = true)
 //@Builder
-public class EvaluationScoreCount extends Model {
+public class 	EvaluationScoreCount extends Model {
 
     private static final long serialVersionUID = 1L;
 

+ 4 - 1
ims-service/ims-eval/src/main/java/com/ims/eval/service/IEvaluationScoreCountService.java

@@ -1,7 +1,6 @@
 package com.ims.eval.service;
 
 import com.baomidou.mybatisplus.extension.service.IService;
-import com.ims.eval.entity.BinSection;
 import com.ims.eval.entity.EvaluationScoreCount;
 
 import java.util.List;
@@ -22,6 +21,10 @@ public interface IEvaluationScoreCountService extends IService<EvaluationScoreCo
 
 
 	Map<String, Object> evaluationList(String binSection, String binStage, String type, String condition, String date);
+
+
+	List<EvaluationScoreCount> getEvaluationScoreCountList(String organizationEvaluationId,String organizationEvaluationRuleId,String indicatorId);
+
 }
 
 

+ 23 - 7
ims-service/ims-eval/src/main/java/com/ims/eval/service/impl/EvaluatioinScoreCountServiceImpl.java

@@ -3,17 +3,11 @@ package com.ims.eval.service.impl;
 import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
 import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
 import com.ims.common.utils.DateUtils;
-import com.ims.eval.config.CustomException;
-import com.ims.eval.dao.BinSectionMapper;
+import com.ims.common.utils.StringUtils;
 import com.ims.eval.dao.EvaluationScoreCountMapper;
-import com.ims.eval.entity.BinSection;
 import com.ims.eval.entity.EvaluationScoreCount;
-import com.ims.eval.service.IBinSectionService;
 import com.ims.eval.service.IEvaluationScoreCountService;
 import org.springframework.stereotype.Service;
-import org.springframework.transaction.annotation.Transactional;
-
-import javax.annotation.Resource;
 import java.util.*;
 import java.util.stream.Collectors;
 
@@ -85,4 +79,26 @@ public class EvaluatioinScoreCountServiceImpl extends ServiceImpl<EvaluationScor
 		result.put("value", value);
 		return result;
 	}
+
+	@Override
+	public List<EvaluationScoreCount> getEvaluationScoreCountList(String organizationEvaluationId, String organizationEvaluationRuleId, String indicatorId) {
+
+
+		QueryWrapper<EvaluationScoreCount> qw = new QueryWrapper();
+
+
+		if (StringUtils.isNotEmpty(organizationEvaluationId)) {
+			qw.lambda().eq(EvaluationScoreCount::getOrganizationEvaluationId,organizationEvaluationId);
+		}
+
+		if (StringUtils.isNotEmpty(organizationEvaluationRuleId)) {
+			qw.lambda().eq(EvaluationScoreCount::getOrganizationEvaluationRuleId,organizationEvaluationRuleId);
+		}
+		if (StringUtils.isNotEmpty(indicatorId)) {
+			qw.lambda().eq(EvaluationScoreCount::getIndicatorId,indicatorId);
+		}
+
+		List<EvaluationScoreCount> list = baseMapper.selectList(qw);
+		return list;
+	}
 }

+ 10 - 1
ims-service/ims-eval/src/main/java/com/ims/eval/service/impl/OrganizationEvaluationInfoServiceImpl.java

@@ -298,11 +298,12 @@ public class OrganizationEvaluationInfoServiceImpl extends ServiceImpl<Organizat
 												}
 												dto.setFormula(dto.getFormula().replace("["+f.getOptionCode()+"]", f.getQuantifiedValue() + ""));
 											}
+											log.info("计算公式为:"+dto.getFormula());
 											double score = FormulaUtils.caculateFormula(dto.getFormula());
 											if(StringUtils.inStringIgnoreCase("DF",dto.getOptionCode())){
 												totalScore = totalScore+score;
 											}
-											log.info(dto.getOrganizationShortName()+"|"+dto.getIndicatorName()+"----------"+dto.getFormula()+"="+score);
+											log.info(dto.getOrganizationShortName()+"|"+dto.getIndicatorName()+"|"+dto.getOptionCode()+"----------"+dto.getFormula()+"="+score);
 											OrganizationEvaluationInfo info  = baseMapper.selectById(dto.getId());
 											//将计算结果保存
 											info.setQuantifiedValue(score);
@@ -312,9 +313,17 @@ public class OrganizationEvaluationInfoServiceImpl extends ServiceImpl<Organizat
 									}
 
 									log.info("综合得分:"+totalScore);
+									if(null==scoreCount.getOrganizationEvaluationId()|| null== scoreCount.getOrganizationEvaluationRuleId() || null == scoreCount.getIndicatorId()){
+											continue;
+									}
 									scoreCount.setScore(totalScore);
 									scoreCount.setObversionScore(totalScore);
 									scoreCount.setIsQuantified("1");
+									List<EvaluationScoreCount>  listcount = iEvaluatioinScoreCountService.getEvaluationScoreCountList(scoreCount.getOrganizationEvaluationId(),scoreCount.getOrganizationEvaluationRuleId(),scoreCount.getIndicatorId());
+									if(null  != listcount && listcount.size() >0){
+										List<String> ids = listcount.stream().map(EvaluationScoreCount::getId).collect(Collectors.toList());
+										boolean cod = iEvaluatioinScoreCountService.removeByIds(ids);
+									}
 									iEvaluatioinScoreCountService.save(scoreCount);
 								}
 							}