Browse Source

基于计算程序模板的用户自定义公式解析、越界处理等。

Chenshilong 7 years ago
parent
commit
bde19243f7
2 changed files with 50 additions and 35 deletions
  1. 28 14
      public/calc_util.js
  2. 22 21
      test/calculation/test_analyzer.js

+ 28 - 14
public/calc_util.js

@@ -41,6 +41,7 @@ let executeObj = {
 
 let analyzer = {
     calcTemplate: null,
+    success: true,
 
     standard: function(expr){
         let str = expr;
@@ -72,7 +73,7 @@ let analyzer = {
             return base;
         };
         function calcBaseToIDExpr(base){
-            // for test.
+            /*// for test. 公路模式,基数到ID
             let id = -1;
             if (base == '[人工费]'){
                 id = 111;
@@ -85,7 +86,9 @@ let analyzer = {
             }
             else id = "错误";
 
-            return "@('" + id + "')";
+            return "@('" + id + "')";*/
+            let baseValue = base.slice(1, -1);
+            return "base('" + baseValue + "')";
         };
 
         while (expr.indexOf('[') > 0) {
@@ -94,7 +97,7 @@ let analyzer = {
             let baseValue = base.slice(1, -1);   // []会给下面的正则带来干扰,这里去掉
             var pattBase =new RegExp(baseValue, "g");
             expr = expr.replace(pattBase, id);
-            expr = expr.replace(/\[@\('/g, "@('");      // [@('
+            expr = expr.replace(/\[base\('/g, "base('");      // [@('       [base('
             expr = expr.replace(/'\)\]/g, "')");        // ')]
         };
 
@@ -102,12 +105,20 @@ let analyzer = {
     },
 
     analyzeLineRef: function(expr){
+        let me = this;
         function isOperator(char){
             var operator = "+-*/()";
             return operator.indexOf(char) > -1;
         };
-        function codeToID(code){
-            return eval(parseFloat(code)+1);
+        function lineNumToID(lineNum){
+            if (lineNum > me.calcTemplate.calcItems.length){
+                me.success = false;
+                return '越界';
+            }
+            else{
+                let id = me.calcTemplate.calcItems[lineNum - 1].ID;
+                return id;
+            }
         };
         // 前提:必须无空格、无特殊符号、标准大写F
         function getSection(expr){
@@ -133,12 +144,13 @@ let analyzer = {
         };
         function sectionToIDExpr(section){
             if (section){
-                let code = section.slice(1);
-                if (isNaN(code)){
-                    return '错误'      // 这里的返回提示不能加上section,因为会无限循环
+                let lineNum = section.slice(1);
+                if (isNaN(lineNum)){
+                    me.success = false;
+                    return '错误';      // 这里的返回提示不能加上section,因为会无限循环
                 }
                 else
-                    return "@('" + codeToID(code) + "')";
+                    return "@('" + lineNumToID(lineNum) + "')";
             }
             else return '';
         };
@@ -153,16 +165,18 @@ let analyzer = {
     },
 
     analyzeUserExpr: function(calcTemplate, calcItem){
-        this.calcTemplate = calcTemplate;
+        let me = this;
+        me.calcTemplate = calcTemplate;
         let expr = calcItem.dispExpr;
         // 标准化:处理特殊字符、中文符号、大小写
-        expr = this.standard(expr);
+        expr = me.standard(expr);
         calcItem.dispExpr = expr;
         // 先换掉计算基数
-        expr = this.analyzeCalcBase(expr);
+        expr = me.analyzeCalcBase(expr);
         // 再换掉行引用
-        expr = this.analyzeLineRef(expr);
+        expr = me.analyzeLineRef(expr);
         calcItem.expression = expr;
+        return me.success;
     }
 };
 
@@ -363,4 +377,4 @@ class Calculation {
     }
 };
 
-//export default analyzer;
+export default analyzer;

+ 22 - 21
test/calculation/test_analyzer.js

@@ -10,7 +10,7 @@ test('解析测试', function(t){
         name: "建筑工程",
         calcItems: [
             {
-                ID: "1",
+                ID: "101",
                 code: "1",
                 name: "基价直接工程费",
                 fieldName: "baseDirect",
@@ -20,7 +20,7 @@ test('解析测试', function(t){
                 statement: "基价人工费+基价材料费+基价机械费+未计价材料费"
             },
             {
-                ID: "2",
+                ID: "102",
                 code: "1.1",
                 name: "基价人工费",
                 fieldName: "baseLabour",
@@ -30,7 +30,7 @@ test('解析测试', function(t){
                 statement: "定额基价人工费+定额人工单价(基价)调整"
             },
             {
-                ID: "3",
+                ID: "103",
                 code: "1.1.1",
                 name: "定额基价人工费",
                 fieldName: "rationBaseLabour",
@@ -40,7 +40,7 @@ test('解析测试', function(t){
                 statement: "定额基价人工费"
             },
             {
-                ID: "4",
+                ID: "104",
                 code: "1.1.2",
                 name: "定额人工单价(基价)调整",
                 fieldName: "rationLabourFixed",
@@ -52,7 +52,7 @@ test('解析测试', function(t){
                 memo: "渝建发(2013)51"
             },
             {
-                ID: "5",
+                ID: "105",
                 code: "1.2",
                 name: "基价材料费",
                 fieldName: "baseMaterial",
@@ -62,7 +62,7 @@ test('解析测试', function(t){
                 statement: "定额基价材料费"
             },
             {
-                ID: "6",
+                ID: "106",
                 code: "1.3",
                 name: "基价机械费",
                 fieldName: "baseMachine",
@@ -72,7 +72,7 @@ test('解析测试', function(t){
                 statement: "定额基价机械费+定额机上人工单价(基价)调整"
             },
             {
-                ID: "7",
+                ID: "107",
                 code: "1.3.1",
                 name: "定额基价机械费",
                 fieldName: "rationBaseMachine",
@@ -82,7 +82,7 @@ test('解析测试', function(t){
                 statement: "定额基价机械费"
             },
             {
-                ID: "8",
+                ID: "108",
                 code: "1.3.1.1",
                 name: "其中:定额基价机上人工费",
                 fieldName: "rationBaseMachineLabour",
@@ -92,7 +92,7 @@ test('解析测试', function(t){
                 statement: "定额基价机上人工费"
             },
             {
-                ID: "9",
+                ID: "109",
                 code: "1.3.2",
                 name: "定额机上人工单价(基价)调整",
                 fieldName: "rationBaseMachineLabourFixed",
@@ -103,7 +103,7 @@ test('解析测试', function(t){
                 statement: "定额基价机上人工费*[定额机上人工单价(基价)调整系数-1]"
             },
             {
-                ID: "10",
+                ID: "110",
                 code: "1.4",
                 name: "未计价材料费",
                 fieldName: "unPriceMaterial",
@@ -113,7 +113,7 @@ test('解析测试', function(t){
                 statement: "主材费+设备费"
             },
             {
-                ID: "11",
+                ID: "111",
                 code: "2",
                 name: "企业管理费",
                 fieldName: "manageFee",
@@ -125,7 +125,7 @@ test('解析测试', function(t){
                 memo: "渝建发[2014]27号"
             },
             {
-                ID: "12",
+                ID: "112",
                 code: "3",
                 name: "利润",
                 fieldName: "profit",
@@ -136,7 +136,7 @@ test('解析测试', function(t){
                 statement: "定额基价人工费"
             },
             {
-                ID: "13",
+                ID: "113",
                 code: "4",
                 name: "风险因素",
                 fieldName: "risk",
@@ -148,7 +148,7 @@ test('解析测试', function(t){
                 memo: "同定额包干费"
             },
             {
-                ID: "14",
+                ID: "114",
                 code: "5",
                 name: "人材机价差",
                 fieldName: "lmmDiff",
@@ -158,7 +158,7 @@ test('解析测试', function(t){
                 statement: "人工费价差+材料费价差+机械费价差"
             },
             {
-                ID: "15",
+                ID: "115",
                 code: "5.1",
                 name: "人工费价差",
                 fieldName: "labourDiff",
@@ -168,7 +168,7 @@ test('解析测试', function(t){
                 statement: "市场价格人工费-调整后的定额人工费(基价)"
             },
             {
-                ID: "16",
+                ID: "116",
                 code: "5.2",
                 name: "材料费价差",
                 fieldName: "materialDiff",
@@ -178,7 +178,7 @@ test('解析测试', function(t){
                 statement: "市场价格材料费-定额基价材料费"
             },
             {
-                ID: "17",
+                ID: "117",
                 code: "5.3",
                 name: "机械费价差",
                 fieldName: "machineDiff",
@@ -188,7 +188,7 @@ test('解析测试', function(t){
                 statement: "市场价格机械费-调整后的定额基价机械费(基价)"
             },
             {
-                ID: "18",
+                ID: "118",
                 code: "6",
                 name: "综合单价",
                 fieldName: "common",
@@ -199,9 +199,10 @@ test('解析测试', function(t){
             }
         ]
     };
-    let calcItem = {dispExpr: "12 +[人工费]*1.2+f4+ (F6+ f10) +F23+[人工费] + f6+[材料费]"};
-    let target = "12+@('111')*1.2+@('5')+(@('7')+@('11'))+@('24')+@('111')+@('7')+@('222')";
-    analyzer.analyzeUserExpr(calcTemplate, calcItem);
+    let calcItem = {dispExpr: "12 +[人工费]*1.2+f13+ (F6+ f10) +F16+[人工费] + f6+[材料费]"};
+    let target = "12+base('人工费')*1.2+@('113')+(@('106')+@('110'))+@('116')+base('人工费')+@('106')+base('材料费')";
+    let rst = analyzer.analyzeUserExpr(calcTemplate, calcItem);
+    console.log('用户表达式是否正确:' + rst);
     console.log(calcItem.dispExpr);
     console.log(calcItem.expression);
     t.equal(calcItem.expression, target);