|
|
@@ -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);
|
|
|
+};
|