From e561f1eb03010e4039ccbd2d2343fbaa9c13eafe Mon Sep 17 00:00:00 2001 From: linfso Date: Mon, 29 Apr 2024 13:38:35 +0800 Subject: [PATCH] md --- ...__com_googlecode_aviator_aviator_5_2_4.xml | 13 + emis-biz-web/emis-biz-web.iml | 1 + .../erp/web/emis/EmisWaybillController.java | 42 +++ emis-biz/emis-biz.iml | 1 + emis-biz/pom.xml | 7 + .../erp/emis/service/EmisBaseService.java | 17 +- .../erp/emis/service/IEmisWaybillService.java | 4 +- .../impl/EmisQuotePriceServiceImpl.java | 11 +- .../service/impl/EmisWaybillServiceImpl.java | 127 ++++++++- .../com/xdadan/erp/emis/utils/Calculator.java | 249 ++++++++++++++++++ .../erp/emis/utils/DecimalAcquisition.java | 129 +++++++++ .../xdadan/erp/emis/utils/WaybillHelper.java | 10 + 12 files changed, 580 insertions(+), 31 deletions(-) create mode 100644 .idea/libraries/Maven__com_googlecode_aviator_aviator_5_2_4.xml create mode 100644 emis-biz/src/main/java/com/xdadan/erp/emis/utils/Calculator.java create mode 100644 emis-biz/src/main/java/com/xdadan/erp/emis/utils/DecimalAcquisition.java diff --git a/.idea/libraries/Maven__com_googlecode_aviator_aviator_5_2_4.xml b/.idea/libraries/Maven__com_googlecode_aviator_aviator_5_2_4.xml new file mode 100644 index 000000000..299938eb3 --- /dev/null +++ b/.idea/libraries/Maven__com_googlecode_aviator_aviator_5_2_4.xml @@ -0,0 +1,13 @@ + + + + + + + + + + + + + \ No newline at end of file diff --git a/emis-biz-web/emis-biz-web.iml b/emis-biz-web/emis-biz-web.iml index a15f9c34e..16f3d2b87 100644 --- a/emis-biz-web/emis-biz-web.iml +++ b/emis-biz-web/emis-biz-web.iml @@ -243,5 +243,6 @@ + \ No newline at end of file diff --git a/emis-biz-web/src/main/java/com/xdadan/erp/web/emis/EmisWaybillController.java b/emis-biz-web/src/main/java/com/xdadan/erp/web/emis/EmisWaybillController.java index 7808f8009..6d16ffefe 100644 --- a/emis-biz-web/src/main/java/com/xdadan/erp/web/emis/EmisWaybillController.java +++ b/emis-biz-web/src/main/java/com/xdadan/erp/web/emis/EmisWaybillController.java @@ -113,6 +113,48 @@ public class EmisWaybillController extends BaseController } } + @Log(title = "计算运费", businessType = BusinessType.OTHER) + @PostMapping(value = "/calcWaybillFee") + public AjaxResult calcWaybillFee(@RequestBody WaybillOrder waybillOrder) + { + try { + EmisWaybill emisWaybillSave = waybillOrder.toDb(); + + emisWaybillService.calcWaybillFee(emisWaybillSave); + + JSONObject jObjFee = new JSONObject(); + jObjFee.put("totalFee", emisWaybillSave.getFreight()); + + FeeItem feeItem = new FeeItem(); + jObjFee.put("feeList",feeItem.cvtToVoList(emisWaybillSave.getFeeitemList())); + + return AjaxResult.success("计算成功", jObjFee); + }catch (Exception ex){ + ex.printStackTrace(); + return AjaxResult.error("服务器异常,联系客服"); + } + } + + @Log(title = "计算计算重量", businessType = BusinessType.OTHER) + @PostMapping(value = "/calcSettledWeight") + public AjaxResult calcSettledWeight(@RequestBody WaybillOrder waybillOrder) + { + try { + EmisWaybill emisWaybillSave = waybillOrder.toDb(); + + emisWaybillService.calcSettledWeight(emisWaybillSave); + + JSONObject jObjRst = new JSONObject(); + jObjRst.put("settlementWeight", emisWaybillSave.getSettlementWeight()); + + return AjaxResult.success("计算成功", jObjRst); + }catch (Exception ex){ + ex.printStackTrace(); + return AjaxResult.error("服务器异常,联系客服"); + } + + } + /** * 查询运单列表列表 */ diff --git a/emis-biz/emis-biz.iml b/emis-biz/emis-biz.iml index 2404324c0..d2900522d 100644 --- a/emis-biz/emis-biz.iml +++ b/emis-biz/emis-biz.iml @@ -201,5 +201,6 @@ + \ No newline at end of file diff --git a/emis-biz/pom.xml b/emis-biz/pom.xml index 4829edba4..2c0ef935d 100644 --- a/emis-biz/pom.xml +++ b/emis-biz/pom.xml @@ -26,6 +26,13 @@ mysql-connector-java + + com.googlecode.aviator + aviator + 5.2.4 + + + \ No newline at end of file diff --git a/emis-biz/src/main/java/com/xdadan/erp/emis/service/EmisBaseService.java b/emis-biz/src/main/java/com/xdadan/erp/emis/service/EmisBaseService.java index fa6620f03..9d07efc05 100644 --- a/emis-biz/src/main/java/com/xdadan/erp/emis/service/EmisBaseService.java +++ b/emis-biz/src/main/java/com/xdadan/erp/emis/service/EmisBaseService.java @@ -93,23 +93,26 @@ public class EmisBaseService { return emisTransProductMapper.selectOne(queryWrapper); } - /** - * 获取产品报价 - * @param code + * 获取有效产品报价 + * @param prodCode + * @param sendSiteCode + * @param destSiteCode * @return */ - public List getQuotePriceList(String prodCode) { + public List getValidQuotePriceList(String prodCode,String sendSiteCode,String destSiteCode,String billType) { EmisQuotePrice queryEmisQuotePrice = new EmisQuotePrice(); queryEmisQuotePrice.setProdCode(prodCode); queryEmisQuotePrice.setStatus(1); - queryEmisQuotePrice.setStartDate(new Date()); // 有效报价 queryEmisQuotePrice.getParams().put("quoteStatus",4); + queryEmisQuotePrice.setBillType(billType); - emisQuotePriceMapper.selectEmisQuotePriceList(queryEmisQuotePrice); + queryEmisQuotePrice.setSendAreaSiteCode(sendSiteCode); + queryEmisQuotePrice.setDispAreaSiteCode(destSiteCode); + + return emisQuotePriceMapper.selectEmisQuotePriceList(queryEmisQuotePrice); - return null; } diff --git a/emis-biz/src/main/java/com/xdadan/erp/emis/service/IEmisWaybillService.java b/emis-biz/src/main/java/com/xdadan/erp/emis/service/IEmisWaybillService.java index 769a00005..eb8c6b680 100644 --- a/emis-biz/src/main/java/com/xdadan/erp/emis/service/IEmisWaybillService.java +++ b/emis-biz/src/main/java/com/xdadan/erp/emis/service/IEmisWaybillService.java @@ -105,11 +105,11 @@ public interface IEmisWaybillService //计算运单费用 - public int calcWaybillFee(EmisWaybill emisWaybill) throws Exception; + public void calcWaybillFee(EmisWaybill emisWaybill) throws Exception; // 计算结算重量 - public int calcSettledWeight(EmisWaybill emisWaybill) throws Exception; + public void calcSettledWeight(EmisWaybill emisWaybill) throws Exception; } diff --git a/emis-biz/src/main/java/com/xdadan/erp/emis/service/impl/EmisQuotePriceServiceImpl.java b/emis-biz/src/main/java/com/xdadan/erp/emis/service/impl/EmisQuotePriceServiceImpl.java index 5e6db885e..498e97ae2 100644 --- a/emis-biz/src/main/java/com/xdadan/erp/emis/service/impl/EmisQuotePriceServiceImpl.java +++ b/emis-biz/src/main/java/com/xdadan/erp/emis/service/impl/EmisQuotePriceServiceImpl.java @@ -48,13 +48,6 @@ public class EmisQuotePriceServiceImpl implements IEmisQuotePriceService public EmisQuotePrice selectEmisQuotePriceByQuoteId(Long quoteId) { EmisQuotePrice emisQuotePrice = emisQuotePriceMapper.selectEmisQuotePriceByQuoteId(quoteId); - if(emisQuotePrice !=null){ - // 查询表达式 - EmisQuoteExpression emisQuoteExpression = new EmisQuoteExpression(); - emisQuoteExpression.setQuoteId(emisQuotePrice.getQuoteId()); - List quoteExpressionList =emisQuoteExpressionMapper.selectEmisQuoteExpressionList(emisQuoteExpression); - emisQuotePrice.setQuoteExpressions(quoteExpressionList); - } return emisQuotePrice; } @@ -84,8 +77,8 @@ public class EmisQuotePriceServiceImpl implements IEmisQuotePriceService emisQuotePriceMapper.insertEmisQuotePrice(emisQuotePrice); // 插入子表达式 - if(CollectionUtil.isNotEmpty(emisQuotePrice.getQuoteExpressions()) ){ - for (EmisQuoteExpression emisQuoteExpression:emisQuotePrice.getQuoteExpressions()){ + if(CollectionUtil.isNotEmpty(emisQuotePrice.getExprList()) ){ + for (EmisQuoteExpression emisQuoteExpression:emisQuotePrice.getExprList()){ emisQuoteExpression.setId(null); emisQuoteExpression.setQuoteId(emisQuotePrice.getQuoteId()); emisQuoteExpressionMapper.insertEmisQuoteExpression(emisQuoteExpression); diff --git a/emis-biz/src/main/java/com/xdadan/erp/emis/service/impl/EmisWaybillServiceImpl.java b/emis-biz/src/main/java/com/xdadan/erp/emis/service/impl/EmisWaybillServiceImpl.java index 50dd366d8..da057fe8f 100644 --- a/emis-biz/src/main/java/com/xdadan/erp/emis/service/impl/EmisWaybillServiceImpl.java +++ b/emis-biz/src/main/java/com/xdadan/erp/emis/service/impl/EmisWaybillServiceImpl.java @@ -10,6 +10,7 @@ package com.xdadan.erp.emis.service.impl; +import java.math.BigDecimal; import java.util.ArrayList; import java.util.Date; import java.util.List; @@ -20,7 +21,9 @@ import cn.hutool.core.collection.CollectionUtil; import cn.hutool.core.lang.Singleton; import cn.hutool.core.lang.Snowflake; import cn.hutool.core.util.IdUtil; +import com.alibaba.fastjson.JSONObject; import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper; +import com.googlecode.aviator.AviatorEvaluator; import com.xdadan.erp.common.utils.DBUtil; import com.xdadan.erp.common.utils.DateUtils; import com.xdadan.erp.common.utils.SecurityUtils; @@ -351,32 +354,130 @@ public class EmisWaybillServiceImpl extends EmisBaseService implements IEmisWayb * @return */ @Override - public int calcWaybillFee(EmisWaybill emisWaybill) throws Exception { + public void calcWaybillFee(EmisWaybill emisWaybill) throws Exception { - // 获取资费列表 - // 获取结算重量 -// emisWaybill.getSettlementWeight().floatValue(); + /** + * 计算逻辑,获取表达式进行计算 + */ -// 111 + if(StringUtils.isAnyEmpty(emisWaybill.getProductType(), + emisWaybill.getSendSiteCode(), + emisWaybill.getDispatchSiteCode(), + emisWaybill.getCalcFeeType() + ) + ){ + throw new Exception("参数不整取不能计算"); + } + + List emisQuotePriceList=getValidQuotePriceList(emisWaybill.getProductType(), + emisWaybill.getSendSiteCode(),emisWaybill.getDispatchSiteCode(), + emisWaybill.getCalcFeeType()); + + + if(CollectionUtils.isEmpty(emisQuotePriceList)){ + throw new Exception("计算失败,无有效资费"); + } + + // 根据表达式计算费用 + String calcFeeType = emisWaybill.getCalcFeeType(); + + double totalFee = 0.0D; + List feeList = new ArrayList<>(); + + for (EmisQuotePrice quoteItem: emisQuotePriceList) { + + List exprList = quoteItem.getExprList(); + if(CollectionUtils.isEmpty(exprList)){ + continue; + } + +// emisWaybill.getTotalVolume(), +// emisWaybill.getSettlementWeight() + + EmisWaybillFeeitem feeItem = new EmisWaybillFeeitem(); + // 重量计费 + if("1".equals(calcFeeType)){ + for (EmisQuoteExpression exprItem: exprList) { + if( exprItem.getStartWeight().doubleValue() >= emisWaybill.getSettlementWeight().doubleValue() + && exprItem.getEndWeight().doubleValue() <= emisWaybill.getSettlementWeight().doubleValue() + ){ + feeItem.setFeeCode(quoteItem.getFeeType()); + feeItem.setQuoteId(quoteItem.getQuoteId()); + feeItem.setExprId(exprItem.getId()); + + String exprStr = exprItem.getCalculateExpression(); + + String calcExprStr=exprStr.replaceAll("w",emisWaybill.getSettlementWeight().toString()); + log.info("计算公式:"+calcExprStr+",重量:"+emisWaybill.getSettlementWeight()); + double fee = Double.valueOf(AviatorEvaluator.execute(calcExprStr).toString()); + feeItem.setFee(BigDecimal.valueOf(fee)); + log.info("计算后费用:"+feeItem.getFee()); + totalFee=totalFee+fee; + feeItem.setRemark(JSONObject.toJSONString(exprItem)); + + feeList.add(feeItem); + } + + } + } + // 体积计费 + else if("2".equals(calcFeeType)){ + + for (EmisQuoteExpression exprItem: exprList) { + if( exprItem.getStartWeight().doubleValue() >= emisWaybill.getTotalVolume().doubleValue() + && exprItem.getEndWeight().doubleValue() <= emisWaybill.getTotalVolume().doubleValue() + ){ + feeItem.setFeeCode(quoteItem.getFeeType()); + feeItem.setQuoteId(quoteItem.getQuoteId()); + feeItem.setExprId(exprItem.getId()); + String exprStr = exprItem.getCalculateExpression(); + String calcExprStr=exprStr.replaceAll("w",emisWaybill.getTotalVolume().toString()); + log.info("计算公式:"+calcExprStr+",体积:"+emisWaybill.getTotalVolume()); + double fee = Double.valueOf(AviatorEvaluator.execute(calcExprStr).toString()); + feeItem.setFee(BigDecimal.valueOf(fee)); + log.info("计算后费用:"+feeItem.getFee()); + totalFee=totalFee+fee; + feeItem.setRemark(JSONObject.toJSONString(exprItem)); + feeList.add(feeItem); + } + } + } + } + + // 设置费用明细 + emisWaybill.setFeeitemList(feeList); + emisWaybill.setFreight(BigDecimal.valueOf(totalFee)); - return 1; } @Override - public int calcSettledWeight(EmisWaybill emisWaybill) throws Exception { + public void calcSettledWeight(EmisWaybill emisWaybill) throws Exception { - // 获取资费列表 - // 获取结算重量 -// emisWaybill.getSettlementWeight().floatValue(); + double billWeight=emisWaybill.getBillWeight().doubleValue(); + double totalVolume=emisWaybill.getTotalVolume().doubleValue(); + // 获取泡重比,计算体积重量 + EmisTransLine emisTransLine= getTransLineByCode(emisWaybill.getTransLineType()); + + double volumeWeight=0.0D; + if(!StringUtils.isEmpty(emisTransLine.getMeterRate())) { + volumeWeight=totalVolume * (1000000 / Double.valueOf(emisTransLine.getMeterRate())); + } + + // 两则取大 + double maxWeight = Math.max(billWeight,volumeWeight); + + // 取重方式 + EmisTransProduct emisTransProduct = getTransProductByCode(emisWaybill.getProductType()); + String carryType=emisTransProduct.getCarryType(); + + double setteldWeight = WaybillHelper.calcSettledWeight(maxWeight); + emisWaybill.setSettlementWeight(setteldWeight); - return 1; } - - public static void main(String[] args) { Snowflake snowflake = IdUtil.getSnowflake(0, 0); diff --git a/emis-biz/src/main/java/com/xdadan/erp/emis/utils/Calculator.java b/emis-biz/src/main/java/com/xdadan/erp/emis/utils/Calculator.java new file mode 100644 index 000000000..7fa251df3 --- /dev/null +++ b/emis-biz/src/main/java/com/xdadan/erp/emis/utils/Calculator.java @@ -0,0 +1,249 @@ +package com.xdadan.erp.emis.utils; + + + +import com.googlecode.aviator.AviatorEvaluator; + +import java.math.BigDecimal; +import java.util.HashMap; +import java.util.Map; +import java.util.Stack; +import java.util.regex.Matcher; +import java.util.regex.Pattern; + +/** + * @author Anzepeng + * @title: Calculator + * @projectName demo + * @description: TODO + * @date 2020/6/10 0010下午 15:02 + */ +public class Calculator { + + // 表达式字符合法性校验正则模式,静态常量化可以降低每次使用都要编译地消耗 + private static final Pattern EXPRESSION_PATTERN = Pattern.compile("[0-9\\.+-/*()= ]+"); + + // 运算符优先级map + private static final Map OPT_PRIORITY_MAP = new HashMap() { + private static final long serialVersionUID = 6968472606692771458L; + + { + put("(", 0); + put("+", 2); + put("-", 2); + put("*", 3); + put("/", 3); + put(")", 7); + put("=", 20); + } + }; + + + /** + ** 输入加减乘除表达式字符串,返回计算结果 + ** @param expression 表达式字符串 + ** @return 返回计算结果 + * + */ + public static double executeExpression(String expression) { + // 非空校验 + if (null == expression || "".equals(expression.trim())) { + throw new IllegalArgumentException("表达式不能为空!"); + } + + // 表达式字符合法性校验 + Matcher matcher = EXPRESSION_PATTERN.matcher(expression); + if (!matcher.matches()) { + throw new IllegalArgumentException("表达式含有非法字符!"); + } + + Stack optStack = new Stack<>(); // 运算符栈 + Stack numStack = new Stack<>(); // 数值栈,数值以BigDecimal存储计算,避免精度计算问题 + StringBuilder curNumBuilder = new StringBuilder(16); // 当前正在读取中的数值字符追加器 + + // 逐个读取字符,并根据运算符判断参与何种计算 + for (int i = 0; i < expression.length(); i++) { + char c = expression.charAt(i); + if (c != ' ') { // 空白字符直接丢弃掉 + if ((c >= '0' && c <= '9') || c == '.') { + curNumBuilder.append(c); // 持续读取一个数值的各个字符 + } else { + if (curNumBuilder.length() > 0) { + // 如果追加器有值,说明之前读取的字符是数值,而且此时已经完整读取完一个数值 + numStack.push(new BigDecimal(curNumBuilder.toString())); + curNumBuilder.delete(0, curNumBuilder.length()); + } + + String curOpt = String.valueOf(c); + if (optStack.empty()) { + // 运算符栈栈顶为空则直接入栈 + optStack.push(curOpt); + } else { + if (curOpt.equals("(")) { + // 当前运算符为左括号,直接入运算符栈 + optStack.push(curOpt); + } else if (curOpt.equals(")")) { + // 当前运算符为右括号,触发括号内的字表达式进行计算 + directCalc(optStack, numStack, true); + } else if (curOpt.equals("=")) { + // 当前运算符为等号,触发整个表达式剩余计算,并返回总的计算结果 + directCalc(optStack, numStack, false); + return numStack.pop().doubleValue(); + } else { + // 当前运算符为加减乘除之一,要与栈顶运算符比较,判断是否要进行一次二元计算 + compareAndCalc(optStack, numStack, curOpt); + } + } + } + } + } + + // 表达式不是以等号结尾的场景 + if (curNumBuilder.length() > 0) { + // 如果追加器有值,说明之前读取的字符是数值,而且此时已经完整读取完一个数值 + numStack.push(new BigDecimal(curNumBuilder.toString())); + } + directCalc(optStack, numStack, false); + return numStack.pop().doubleValue(); + } + + /** + ** 拿当前运算符和栈顶运算符对比,如果栈顶运算符优先级高于或同级于当前运算符, + ** 则执行一次二元运算(递归比较并计算),否则当前运算符入栈 + ** @param optStack 运算符栈 + ** @param numStack 数值栈 + ** @param curOpt 当前运算符 + * + */ + public static void compareAndCalc(Stack optStack, Stack numStack, + String curOpt) { + // 比较当前运算符和栈顶运算符的优先级 + String peekOpt = optStack.peek(); + int priority = getPriority(peekOpt, curOpt); + if (priority == -1 || priority == 0) { + // 栈顶运算符优先级大或同级,触发一次二元运算 + String opt = optStack.pop(); // 当前参与计算运算符 + BigDecimal num2 = numStack.pop(); // 当前参与计算数值2 + BigDecimal num1 = numStack.pop(); // 当前参与计算数值1 + BigDecimal bigDecimal = floatingPointCalc(opt, num1, num2); + + // 计算结果当做操作数入栈 + numStack.push(bigDecimal); + + // 运算完栈顶还有运算符,则还需要再次触发一次比较判断是否需要再次二元计算 + if (optStack.empty()) { + optStack.push(curOpt); + } else { + compareAndCalc(optStack, numStack, curOpt); + } + } else { + // 当前运算符优先级高,则直接入栈 + optStack.push(curOpt); + } + } + + /** + ** 遇到右括号和等号执行的连续计算操作(递归计算) + ** @param optStack 运算符栈 + ** @param numStack 数值栈 + ** @param isBracket true表示为括号类型计算 + * + */ + public static void directCalc(Stack optStack, Stack numStack, + boolean isBracket) { + String opt = optStack.pop(); // 当前参与计算运算符 + BigDecimal num2 = numStack.pop(); // 当前参与计算数值2 + BigDecimal num1 = numStack.pop(); // 当前参与计算数值1 + BigDecimal bigDecimal = floatingPointCalc(opt, num1, num2); + + // 计算结果当做操作数入栈 + numStack.push(bigDecimal); + + if (isBracket) { + if ("(".equals(optStack.peek())) { + // 括号类型则遇左括号停止计算,同时将左括号从栈中移除 + optStack.pop(); + } else { + directCalc(optStack, numStack, isBracket); + } + } else { + if (!optStack.empty()) { + // 等号类型只要栈中还有运算符就继续计算 + directCalc(optStack, numStack, isBracket); + } + } + } + + /** + ** 不丢失精度的二元运算,支持高精度计算 + ** @param opt + ** @param bigDecimal1 + ** @param bigDecimal2 + ** @return + * + */ + public static BigDecimal floatingPointCalc(String opt, BigDecimal bigDecimal1, + BigDecimal bigDecimal2) { + BigDecimal resultBigDecimal = new BigDecimal(0); + switch (opt) { + case "+": + resultBigDecimal = bigDecimal1.add(bigDecimal2); + break; + case "-": + resultBigDecimal = bigDecimal1.subtract(bigDecimal2); + break; + case "*": + resultBigDecimal = bigDecimal1.multiply(bigDecimal2); + break; + case "/": + resultBigDecimal = bigDecimal1.divide(bigDecimal2, 10, BigDecimal.ROUND_HALF_DOWN); // 注意此处用法 + break; + default: + break; + } + return resultBigDecimal; + } + + /** + ** priority = 0 表示两个运算符同级别 + ** priority = 1 第二个运算符级别高,负数则相反 + ** @param opt1 + ** @param opt2 + ** @return + * + */ + public static int getPriority(String opt1, String opt2) { + int priority = OPT_PRIORITY_MAP.get(opt2) - OPT_PRIORITY_MAP.get(opt1); + return priority; + } + + /** + ** 浮点数相等比较函数 + ** @param value1 + ** @param value2 + ** @return + * + */ + private static boolean isDoubleEquals(double value1, double value2) { + System.out.println("正确结果=" + value1 + ", 实际计算结果=" + value2); + return Math.abs(value1 - value2) <= 0.0001; + } + + public static void main(String[] args) { + // 几个测试数据 +// System.out.println(isDoubleEquals(-39.5, executeExpression(" 2 + 3/2 * 3 - 4 *(2 + 5 -2*4/2+9) + 3 + (2*1)-3= "))); +// System.out.println(isDoubleEquals(60.3666, executeExpression("9*2+1/3*2-4+(3*2/5+3+3*6)+3*5-1+3+(4+5*1/2)="))); +// System.out.println(isDoubleEquals(372.8, executeExpression(" 9.2 *(20-1)-1+199 = "))); +// System.out.println(isDoubleEquals(372.8, executeExpression(" 9.2 *(20-1)-1+199" ))); +// System.out.println(isDoubleEquals(372.8, executeExpression(" 9.2 *(20-1)-1+199"))); +// System.out.println(isDoubleEquals(-29, executeExpression(" 9 *(20-1)-(1+199) "))); +// System.out.println(isDoubleEquals(1.0E24, executeExpression("1000000000000*1000000000000 = "))); +// System.out.println(executeExpression("100")); + +// String exprStr= "(w-1)*35+100"; + String exprStr= "w*35"; + String calcExprStr=exprStr.replaceAll("w","7.2"); + double fee = Double.valueOf(AviatorEvaluator.execute(calcExprStr).toString()); + System.out.println(fee); + } +} \ No newline at end of file diff --git a/emis-biz/src/main/java/com/xdadan/erp/emis/utils/DecimalAcquisition.java b/emis-biz/src/main/java/com/xdadan/erp/emis/utils/DecimalAcquisition.java new file mode 100644 index 000000000..e1fa3a0b1 --- /dev/null +++ b/emis-biz/src/main/java/com/xdadan/erp/emis/utils/DecimalAcquisition.java @@ -0,0 +1,129 @@ +package com.xdadan.erp.emis.utils; + +import java.math.RoundingMode; +import java.text.DecimalFormat; + +/** + * 小数位获取 + */ +public class DecimalAcquisition { + + public static void main(String[] args) { + + /** 常量:测试取精度 */ + double pai = 3.141592657589; + + /** 常量:测试四舍五入 */ + double num = 3.555555555555; + + /** + * 第一种方案 + * 保留两位小数,四舍五入 + */ + DecimalFormat b = new DecimalFormat("#.00"); + + // 两位精度处理测试 + String s = b.format(pai); + System.out.println(s); // 3.14 + + // 是否四舍五入测试 + String s1 = b.format(num); + System.out.println(s1); // 3.56 + + + /** + * 第二种方案(全面,可配置) + * 保留两位小数,四舍五入 + * 通过setMaximumFractionDigits设置具体的几进位。 + * 通过setRoundingMode设置进位机制{ + * RoundingMode.HALF_UP 四舍五入,负数先取绝对值再四舍五入再负数 + * RoundingMode.CEILINGZ 取右边最近的整数 + * RoundingMode.DOWN 去掉小数部分取整,也就是正数取左边,负数取右边,相当于向原点靠近的方向取整 + * RoundingMode.FLOOR 取左边最近的正数 + * RoundingMode.HALF_DOWN 五舍六入,负数先取绝对值再五舍六入再负数 + * RoundingMode.HALF_EVEN 整数位若是奇数则四舍五入,若是偶数则五舍六入 + * } + */ + DecimalFormat decimalFormat = new DecimalFormat(); + decimalFormat.setMaximumFractionDigits(2); // 保留两位小数 + decimalFormat.setRoundingMode(RoundingMode.HALF_UP); // 设置具体的进位机制 + Double aDouble = Double.valueOf(decimalFormat.format(pai)); + Double aDouble1 = Double.valueOf(decimalFormat.format(num)); + System.out.println(aDouble); // 3.14 + System.out.println(aDouble1); // 3.56 + + } + + public static void main1(String[] args) { + + /** + * 说明: + * 1. HALF_UP在处理小数位保留时不会出现精度缺失,但是会四舍五入。 + * 2. FLOOR在处理小数位保留时不会四舍五入,但是会存在精度缺失的问题。 + */ + + /** 方案一 */ + DecimalFormat doubleFormatter = new DecimalFormat(); + doubleFormatter.setMaximumFractionDigits(6); + doubleFormatter.setGroupingSize(0); + doubleFormatter.setRoundingMode(RoundingMode.FLOOR); + + Double value = Double.valueOf(doubleFormatter.format(1.654321 + 0.001)); + System.out.println(value); //1.65532 + + doubleFormatter.setRoundingMode(RoundingMode.HALF_UP); + Double valueB = Double.valueOf(doubleFormatter.format(1.654321 + 0.001)); + System.out.println(valueB); //1.655321 + System.out.println("-------------------------------------------"); + + /** 方案二 */ + DecimalFormat doubleFormatterB = new DecimalFormat(); + doubleFormatterB.setMaximumFractionDigits(6); + doubleFormatterB.setGroupingSize(0); + doubleFormatterB.setRoundingMode(RoundingMode.FLOOR); + + Double valueC = Double.valueOf(doubleFormatterB.format(1.555555 + 0.0000005)); + System.out.println(valueC); //1.555555 + + doubleFormatterB.setRoundingMode(RoundingMode.HALF_UP); + Double valueD = Double.valueOf(doubleFormatterB.format(1.555555 + 0.0000005)); + System.out.println(valueD); //1.555556 + + } + + public static void main2(String[] args) { + + /** + * 说明: + * 1. HALF_UP在处理小数位保留时不会出现精度缺失,但是会四舍五入。 + * 2. FLOOR在处理小数位保留时不会四舍五入,但是会存在精度缺失的问题。 + */ + + /** 方案一 */ + DecimalFormat doubleFormatter = new DecimalFormat("#.000000"); + doubleFormatter.setRoundingMode(RoundingMode.FLOOR); + + Double value = Double.valueOf(doubleFormatter.format(1.654321 + 0.001)); + System.out.println(value); //1.65532 + + doubleFormatter.setRoundingMode(RoundingMode.HALF_UP); + Double valueB = Double.valueOf(doubleFormatter.format(1.654321 + 0.001)); + System.out.println(valueB); //1.655321 + System.out.println("-------------------------------------------"); + + /** 方案二 */ + DecimalFormat doubleFormatterB = new DecimalFormat("#.000000"); + doubleFormatterB.setRoundingMode(RoundingMode.FLOOR); + + Double valueC = Double.valueOf(doubleFormatterB.format(1.555555 + 0.0000005)); + System.out.println(valueC); //1.555555 + + doubleFormatterB.setRoundingMode(RoundingMode.HALF_UP); + Double valueD = Double.valueOf(doubleFormatterB.format(1.555555 + 0.0000005)); + System.out.println(valueD); //1.555556 + + } + + + +} \ No newline at end of file diff --git a/emis-biz/src/main/java/com/xdadan/erp/emis/utils/WaybillHelper.java b/emis-biz/src/main/java/com/xdadan/erp/emis/utils/WaybillHelper.java index ca8d2cf04..0f7911fd4 100644 --- a/emis-biz/src/main/java/com/xdadan/erp/emis/utils/WaybillHelper.java +++ b/emis-biz/src/main/java/com/xdadan/erp/emis/utils/WaybillHelper.java @@ -10,4 +10,14 @@ public class WaybillHelper { Long orderId = snowflake.nextId(); return "TAO" + orderId.toString(); } + + // 进位计算 + public static double calcSettledWeight(double weight,String carryType){ + // 0.1进位 + if("1".equals(carryType)){ +// setteldWeight=maxWeight + } + + return weight; + } }