Browse Source

需求变更:调整模板Excel,调整默认参数,调整页面显示

MaiXinRong 7 years atrás
parent
commit
df82a5b05f

+ 27 - 5
app/const/template_param.js

@@ -11,10 +11,11 @@
 // 参数绑定类别
 const matchType = {
     fixed_id: 1,
-    node_default: 2,
-    properties: 3,
-    code: 4,
-    non_match: 5,
+    properties: 2,
+    node_default: 11,
+    parent_default: 12,
+    code: 21,
+    non_match: -1,
 }
 const matchTypeStr = [];
 matchTypeStr[matchType.fixed_id] = '全局匹配参数';
@@ -218,7 +219,28 @@ const defaultNodeParams = [
         name: '本项清单数量',
         match_type: matchType.node_default,
         match_num: matchNum.quantity,
-    }
+    }, {
+        template_id: 1,
+        param_id: 1,
+        code: 'e',
+        name: '父项合价',
+        match_type: matchType.parent_default,
+        match_num: matchNum.total_price,
+    }, {
+        template_id: 1,
+        param_id: 2,
+        code: 'f',
+        name: '父项数量1',
+        match_type: matchType.parent_default,
+        match_num: matchNum.dgn_quantity1,
+    }, {
+        template_id: 1,
+        param_id: 3,
+        code: 'g',
+        name: '父项数量2',
+        match_type: matchType.parent_default,
+        match_num: matchNum.dgn_quantity2,
+    },
 ];
 
 module.exports = {

+ 27 - 3
app/extend/helper.js

@@ -210,10 +210,20 @@ module.exports = {
         return json;
     },
 
+    /**
+     * 判断value是否是四则运算符
+     * @param {String} value - 判断字符串
+     * @return {Boolean}
+     */
     isOperator(value) {
         const operatorString = "+-*/()";
-        return operatorString.indexOf(value) > -1
+        return operatorString.indexOf(value) > -1;
     },
+    /**
+     * Rpn解析栈
+     * @param exp
+     * @returns {Array}
+     */
     parse2Rpn(exp) {
         const getPriority = function (value){
             switch(value){
@@ -287,6 +297,11 @@ module.exports = {
         }
         return outputQueue;
     },
+    /**
+     * 计算Rpn解析栈
+     * @param rpnQueue
+     * @returns {*}
+     */
     evalRpn(rpnQueue) {
         const getResult = function (num1, num2, opera) {
             switch (opera) {
@@ -325,7 +340,6 @@ module.exports = {
             return outputStack[0];
         }
     },
-
     /**
      * 解析四则运算字符串并计算
      * @param {String} expr
@@ -345,7 +359,12 @@ module.exports = {
         }
     },
 
-    splitByOperator(expr) {
+    /**
+     * 使用四则运算符分隔
+     * @param expr
+     * @returns {Array}
+     */
+    splitByOperator (expr) {
         const exprStack = [];
         const result = [];
         for(let i = 0, len = expr.length; i < len; i++){
@@ -376,6 +395,11 @@ module.exports = {
         return result;
     },
 
+    /**
+     * 解析 数学计算式(字符串) 并计算
+     * @param expr
+     * @returns {null}
+     */
     calcExprStr(expr) {
         try {
             const result = mathjs.eval(expr);

+ 118 - 14
app/public/js/template.js

@@ -9,6 +9,15 @@
  */
 
 $(document).ready(function () {
+    /**
+     * 判断是否是 加减乘除 符号
+     * @param value
+     * @returns {boolean}
+     */
+    const isOperate1 = function (value) {
+        const operatorString = "+-*/";
+        return operatorString.indexOf(value) > -1;
+    };
     // 删除规则计算参数按钮是否显示
     const refreshDelParamVisible = function () {
         if ($('#rule').children().length > 1) {
@@ -19,6 +28,7 @@ $(document).ready(function () {
     };
     // 合成新增参数的html
     const addParamHtml = function (html, param) {
+        if (!param || param.length === 0) { return; }
         html.push('<span class="badge badge-light" title="' + param.text() + '"');
         html.push(' name="' + param.text() + '"');
         html.push(' code="' + param.attr('value') + '">');
@@ -27,17 +37,52 @@ $(document).ready(function () {
     };
     // 弹窗设置指标计算规则
     $('a[name=setRule]').click(function () {
+        const isOperator = function (value) {
+            const operatorString = "+-*/()";
+            return operatorString.indexOf(value) > -1;
+        };
+        const splitByOperator = function (expr) {
+            const exprStack = [];
+            const result = [];
+            for(let i = 0, len = expr.length; i < len; i++){
+                const cur = expr[i];
+                if(cur !== ' ' ){
+                    exprStack.push(cur);
+                }
+            }
+            let param = '', isParamBefore = false;
+            while(exprStack.length > 0){
+                const cur = exprStack.shift();
+                if (isOperator(cur)) {
+                    if (isParamBefore) {
+                        result.push(param);
+                        param = '';
+                    }
+                    result.push(cur);
+                    isParamBefore = false;
+                } else {
+                    param = param + cur;
+                    isParamBefore = true;
+                    if (exprStack.length === 0) {
+                        result.push(param);
+                        param = '';
+                    }
+                }
+            }
+            return result;
+        };
         const rule = $(this).attr('value');
         const index = this.parentNode.parentNode;
         $('#rule').attr('curIndex', index.attributes['index_id'].nodeValue);
         $('span', $('#rule')).remove();
         const html = [];
-        const params = rule.split('/');
+        const params = splitByOperator(rule);
         for (let i = 0, iLen = params.length; i < iLen; i++) {
-            const p = $('option[value='+ params[i] +']');
-            addParamHtml(html, p);
-            if (i < iLen - 1) {
-                html.push('<span class="badge badge-light" title="/" code="/" name="/">/ </span>');
+            if (isOperator(params[i])) {
+                html.push('<span class="badge badge-light" title="' + params[i] + '" code="' + params[i] + '" name="' + params[i] + '">' + params[i] + '</span>');
+            } else {
+                const p = $('option[value='+ params[i] +']:first');
+                addParamHtml(html, p);
             }
         }
         $('#delParam').before(html.join(''));
@@ -66,17 +111,73 @@ $(document).ready(function () {
             } else {
                 $('#paramAlert').text('无选定参数').show();
             }
-        }
-        if (lastParam) {
-            if (lastParam.attr('code') !== '/' && paramType.selectedIndex !== 2) {
-                $('#paramAlert').text('2个参数之间需要一个计算式').show();
-            } else if (lastParam.attr('code') === '/' && paramType.selectedIndex === 2 ) {
-                $('#paramAlert').text('计算式后只可添加参数').show();
+        };
+        if (lastParam && lastParam.length > 0) {
+            const calcSelect = $('select', $('#calcParams'))[0];
+            if (isOperate1(lastParam.attr('code'))) {
+                if (paramType.selectedIndex === 2) {
+                    if (calcSelect.selectedIndex !== 4) {
+                        $('#paramAlert').text('计算式后请输入参数').show();
+                    } else {
+                        addParam();
+                    }
+                } else {
+                    addParam();
+                }
+            } else if (lastParam.attr('code') === '(') {
+                if (paramType.selectedIndex === 2) {
+                    $('#paramAlert').text('左括号后请输入参数').show();
+                } else {
+                    addParam();
+                }
+            } else if (lastParam.attr('code') === ')') {
+                if (paramType.selectedIndex === 2) {
+                    if (calcSelect.selectedIndex < 4) {
+                        addParam();
+                    } else {
+                        $('#paramAlert').text('右括号后请输入计算式').show();
+                    }
+                } else {
+                    $('#paramAlert').text('右括号后请输入计算式').show();
+                }
             } else {
-                addParam();
+                if (paramType.selectedIndex === 2) {
+                    if (calcSelect.selectedIndex === 4) {
+                        $('#paramAlert').text('2个参数之间需要一个计算式').show();
+                    } else {
+                        addParam();
+                    }
+                } else {
+                    $('#paramAlert').text('2个参数之间需要一个计算式').show();
+                }
             }
+            // if (!isOperate1(lastParam.attr('code')) && paramType.selectedIndex !== 2) {
+            //     $('#paramAlert').text('2个参数之间需要一个计算式').show();
+            // } else if (isOperate1(lastParam.attr('code')) && paramType.selectedIndex === 2 ) {
+            //     const paramSelect = $('select', $('#calcParams'));
+            //     if (paramSelect.selectedIndex === 4) {
+            //         addParam();
+            //     } else if (paramSelect.selectedIndex === 5) {
+            //         const leftBracket = $('span[code=(]');
+            //         const rightBracket = $('span[code=)]');
+            //         if (leftBracket.length > rightBracket.length) {
+            //             addParam();
+            //         } else {
+            //             $('#paramAlert').text('添加")"前请先添加"("').show();
+            //         }
+            //     } else {
+            //         $('#paramAlert').text('计算式后只可添加参数').show();
+            //     }
+            // } else {
+            //     addParam();
+            // }
         } else if (paramType.selectedIndex === 2) {
-            $('#paramAlert').text('计算式前需含有参数').show();
+            const paramSelect = $('select', $('#calcParams'));
+            if (paramSelect.selectedIndex === 4) {
+                addParam()
+            } else {
+                $('#paramAlert').text('计算式前需含有参数').show();
+            }
         } else {
             addParam();
         }
@@ -89,10 +190,13 @@ $(document).ready(function () {
     // 设置指标计算规则
     $('#ruleOk').click(function () {
         const lastParam = $('#delParam').prev();
+        const leftBracket = $("span[code='(']").length, rightBracket = $("span[code=')']").length;
         if (!lastParam) {
             $('#paramAlert').text('未设置计算规则').show();
-        } else if (lastParam.attr('code') === lastParam.attr('name')) {
+        } else if (isOperate1(lastParam.attr('code'))) {
             $('#paramAlert').text('计算式后应添加参数').show();
+        } else if (lastParam.attr('code') === '(' || leftBracket !== rightBracket) {
+            $('#paramAlert').text('计算式错误,请检查').show();
         } else {
             const indexRow = $('tr[index_id=' + $('#rule').attr('curIndex') + ']');
             const params = $('span', $('#rule'));

+ 20 - 5
app/service/match.js

@@ -93,11 +93,16 @@ module.exports = app => {
          * @private
          */
         _getNodeBillsValue(param, bills) {
-            switch (param.match_num) {
-                case paramConst.matchNum.quantity: return bills.quantity;
-                case paramConst.matchNum.total_price: return bills.total_price;
-                case paramConst.matchNum.dgn_quantity1: return bills.dgn_quantity1;
-                case paramConst.matchNum.dgn_quantity2: return bills.dgn_quantity2;
+            if (bills) {
+                switch (param.match_num) {
+                    case paramConst.matchNum.quantity: return bills.quantity;
+                    case paramConst.matchNum.total_price: return bills.total_price;
+                    case paramConst.matchNum.dgn_quantity1: return bills.dgn_quantity1;
+                    case paramConst.matchNum.dgn_quantity2: return bills.dgn_quantity2;
+                    default: return undefined;
+                }
+            } else {
+                return undefined;
             }
         }
 
@@ -133,6 +138,15 @@ module.exports = app => {
         }
 
         /**
+         * 获取父项
+         * @param {Object} node - 分项清单节点
+         * @private
+         */
+        _getParentBills(node) {
+            return node ? this.ctx.helper.findObj(this.bills, 'n_id', node.n_pid) : null;
+        }
+
+        /**
          * 获取指标参数取值
          * @param {Object} param - 指标参数
          * @param {Object} nodeBills - 指标参数 所属 指标节点,绑定的 清单
@@ -143,6 +157,7 @@ module.exports = app => {
             switch (param.match_type) {
                 case paramConst.matchType.fixed_id: return this._getFixedIdParamValue(param);
                 case paramConst.matchType.node_default: return this._getNodeBillsValue(param, nodeBills);
+                case paramConst.matchType.parent_default: return this._getNodeBillsValue(param, this._getParentBills(nodeBills));
                 case paramConst.matchType.code: return this._getCodeParamValue(param);
                 // to do 匹配属性
                 default: return undefined;

+ 2 - 0
app/service/template_node.js

@@ -164,6 +164,8 @@ module.exports = app => {
                             node_pid: this._findParentId(row[0], nodes) || -1,
                             code: row[0],
                             name: row[1],
+                            match_type: row[11] && row[11] !== '' ? nodeConst.matchType.code : nodeConst.matchType.name,
+                            match_key: row[11] && row[11] !== '' ? row[11] : row[1],
                         };
                         nodes.push(node);
                     }

+ 1 - 1
app/view/template/index.ejs

@@ -63,7 +63,7 @@
                                         <tr>
                                             <td code="<%= n.code %>"><%= n.name %></td>
                                             <td>
-                                                <% if (n.match_type !== paramConst.matchType.node_default) { %>
+                                                <% if (paramConst.validMatchType.indexOf(n.match_type) > -1) { %>
                                                 <div class="input-group input-group-sm">
                                                     <div class="input-group-prepend">
                                                         <button class="btn btn-outline-secondary dropdown-toggle" type="button" data-toggle="dropdown" aria-haspopup="true" aria-expanded="false" value="<%= n.match_num %>">

+ 14 - 5
app/view/template/modal.ejs

@@ -40,7 +40,12 @@
                 <!--计算式-->
                 <div class="form-group" id="calcParams" name="param" style="display: none;">
                     <select class="form-control">
-                        <option>/</option>
+                        <option value="+">+</option>
+                        <option value="-">-</option>
+                        <option value="*">*</option>
+                        <option value="/">/</option>
+                        <option value="(">(</option>
+                        <option value=")">)</option>
                     </select>
                 </div>
                 <button id="addParam" class="btn btn-outline-primary">添加</button>
@@ -81,9 +86,13 @@
 <script>
     const globalParams = <%- JSON.stringify(globalParams) %>;
     const nodeParams = <%- JSON.stringify(nodeParams) %>;
-    const calcParams = [{
-        code: '/',
-        name: '/'
-    }];
+    const calcParams = [
+        { code: '+', name: '+'},
+        { code: '-', name: '-'},
+        { code: '*', name: '*'},
+        { code: '/', name: '/'},
+        { code: '(', name: '('},
+        { code: ')', name: ')'}
+    ];
 </script>
 <script src="/public/js/template.js"></script>