Browse Source

feat(wise-cost-util): 材料关键字计算方法

zhangweicheng 4 years ago
parent
commit
a700509957
3 changed files with 63 additions and 2 deletions
  1. 3 2
      wise-cost-util/package.json
  2. 1 0
      wise-cost-util/src/index.ts
  3. 59 0
      wise-cost-util/src/material.ts

+ 3 - 2
wise-cost-util/package.json

@@ -1,6 +1,6 @@
 {
 {
   "name": "@sc/wise-cost-util",
   "name": "@sc/wise-cost-util",
-  "version": "1.0.3",
+  "version": "1.0.4",
   "description": "wise-cost项目前后端业务通用工具包",
   "description": "wise-cost项目前后端业务通用工具包",
   "main": "./dist/index.cjs.js",
   "main": "./dist/index.cjs.js",
   "module": "./dist/index.esm.js",
   "module": "./dist/index.esm.js",
@@ -49,6 +49,7 @@
   },
   },
   "dependencies": {
   "dependencies": {
     "@sc/util": "^1.0.7",
     "@sc/util": "^1.0.7",
-    "lodash": "^4.17.21"
+    "lodash": "^4.17.21",
+    "evaluator.js": "^3.2.3"
   }
   }
 }
 }

+ 1 - 0
wise-cost-util/src/index.ts

@@ -2,3 +2,4 @@ export * from './bill';
 export * from './rationAss';
 export * from './rationAss';
 export * from './glj';
 export * from './glj';
 export * from './cptLib';
 export * from './cptLib';
+export * from './material';

+ 59 - 0
wise-cost-util/src/material.ts

@@ -0,0 +1,59 @@
+import { roundForObj } from '@sc/util';
+import evaluate from 'evaluator.js';
+
+// 关键字组
+export interface IKeywordItem {
+  optionCode: string; // 选项号
+  coe: string;
+}
+
+export interface IInfoPriceMain {
+  classCode: string; // 别名编码 0749B01D01
+  expString: string; // 表达式 :X*(1+(A-1)+(B-1)+(C-1))
+  basePrice: string; // 基价
+}
+
+/* eslint-disable import/prefer-default-export */
+const replaceAll = (FindText: RegExp | string, RepText: string, str: string): string => {
+  const regExp = new RegExp(FindText, 'g');
+  return str.replace(regExp, RepText);
+};
+
+/**
+ * 计算材料价
+ * infoPrice:主表的数据
+ * keywordItems : 关键字列表
+ */
+export const calcMaterialExp = (infoPrice: IInfoPriceMain, keywordItems: IKeywordItem[]) => {
+  const preCodeLength = 4; // 别名编码位数,可能要改成5位或6位
+  const decimal = 2; // 小数位数
+  const groupStr = infoPrice.classCode.substr(preCodeLength);
+  let { expString } = infoPrice; // 计算式
+  try {
+    if (groupStr.length > 0) {
+      let startIndex = 0;
+      while (groupStr.length > startIndex) {
+        const option = groupStr.substr(startIndex, 3); // 获取A01这样的编号
+        const group = keywordItems.find(item => item.optionCode === option);
+        if (group) {
+          // 运距=15km  这种类型的要特殊处理 暂时没有办法处理~ 没法从编号中获取具体要加减多少
+          const operator = group.coe.charAt(0); // 加 减 乘的操作
+          let coeNumber = parseFloat(group.coe.substr(1)); // 要代入计算的系数
+          if (operator === '*') coeNumber -= 1;
+          expString = replaceAll(option.charAt(0), `${coeNumber}`, expString);
+        }
+        startIndex += 3;
+      }
+      // 替换基价
+      expString = replaceAll('X', infoPrice.basePrice, expString);
+
+      // 没找到的按0处理
+      expString = replaceAll(/[a-zA-Z]/, '0', expString);
+      return roundForObj(evaluate(expString), decimal);
+    }
+  } catch (error) {
+    throw new Error('计算失败,表达式有误');
+  }
+
+  return roundForObj(infoPrice.basePrice, decimal);
+};