Browse Source

1. 合同支付,检查本期金额计算式是否合法
2. 合同支付,检查起扣金额,扣款限额计算式是否合法

MaiXinRong 5 years ago
parent
commit
2de2c711a9
1 changed files with 143 additions and 5 deletions
  1. 143 5
      app/public/js/stage_pay.js

+ 143 - 5
app/public/js/stage_pay.js

@@ -272,10 +272,129 @@ $(document).ready(() => {
     SpreadJsObj.loadSheetData(paySpread.getActiveSheet(), SpreadJsObj.DataType.Data, dealPay);
 
     const paySpreadObj = {
+        _checkExprValid(expr, invalidParam) {
+            if (!expr) return [true, null];
+            const param = [];
+            let num = '', base = '';
+            for (let i = 0, iLen = expr.length; i < iLen; i++) {
+                if (/^[\d\.%]+/.test(expr[i])) {
+                    if (base !== '') {
+                        param.push({type: 'base', value: base});
+                        base = '';
+                    }
+                    num = num + expr[i];
+                } else if (/^[a-z]/.test(expr[i])) {
+                    if (num !== '') {
+                        param.push({type: 'num', value: num});
+                        base = '';
+                    }
+                    base = base + expr[i];
+                } else if (expr[i] === '(') {
+                    if (num !== '') {
+                        param.push({type: 'num', value: num});
+                        base = '';
+                    }
+                    if (base !== '') {
+                        param.push({type: 'base', value: base});
+                        base = '';
+                    }
+                    param.push({type: 'left', value: '('});
+                } else if (expr[i] === ')') {
+                    if (num !== '') {
+                        param.push({type: 'num', value: num});
+                        base = '';
+                    }
+                    if (base !== '') {
+                        param.push({type: 'base', value: base});
+                        base = '';
+                    }
+                    param.push({type: 'right', value: ')'});
+                } else if (/^[\+\-*\/]/.test(expr[i])) {
+                    if (num !== '') {
+                        param.push({type: 'num', value: num});
+                        base = '';
+                    }
+                    if (base !== '') {
+                        param.push({type: 'base', value: base});
+                        base = '';
+                    }
+                    param.push({type: 'calc', value: expr[i]});
+                } else {
+                    return [false, '输入的表达式含有非法字符: ' + expr[i]];
+                }
+            }
+            if (num !== '') {
+                param.push({type: 'num', value: num});
+                base = '';
+            }
+            if (base !== '') {
+                param.push({type: 'base', value: base});
+                base = '';
+            }
+            if (param.length === 0) return true;
+            if (param.length > 1) {
+                if (param[0].value === '-') {
+                    param[1].value = '-' + param[1];
+                }
+                param.unshift();
+            }
+            const iLen = param.length;
+            let iLeftCount = 0, iRightCount = 0;
+            for (const [i, p] of param.entries()) {
+                if (p.type === 'calc') {
+                    if (i === 0 || i === iLen - 1)
+                        return [false, '输入的表达式非法:计算符号' + p.value + '前后应有数字或计算基数'];
+                }
+                if (p.type === 'num') {
+                    num = p.value.replace('%', '');
+                    if (p.value.length - num.length > 1)
+                        return [false, '输入的表达式非法:' + p.value + '不是一个有效的数字'];
+                    num = _.toNumber(num);
+                    if (num === undefined || num === null || _.isNaN(num))
+                        return [false, '输入的表达式非法:' + p.value + '不是一个有效的数字'];
+                    if (i > 0) {
+                        if (param[i - 1].type !== 'calc') {
+                            return [false, '输入的表达式非法:' + p.value + '前应有运算符'];
+                        } else if (param[i - 1].value === '/' && num === 0) {
+                            return [false, '输入的表达式非法:请勿除0'];
+                        }
+                    }
+                }
+                if (p.type === 'base') {
+                    const baseParam = _.find(calcBase, {code: p.value});
+                    if (!baseParam)
+                        return [false, '输入的表达式非法:不存在计算基数' + p.value];
+                    if (invalidParam && invalidParam.indexOf(p.value) >= 0)
+                        return [false, '不可使用计算基数' + p.value];
+                    if (i > 0 && param[i - 1].type === 'calc')
+                        return [false, '输入的表达式非法:' + p.value + '前应有运算符'];
+                }
+                if (p.type === 'left') {
+                    iLeftCount += 1;
+                    if (i !== 0 && param[i-1].type !== 'calc')
+                        return [false, '输入的表达式非法:(前应有运算符'];
+                }
+                if (p.type === 'right') {
+                    iRightCount += 1;
+                    if (i !== iLen - 1 && param[i+1].type !== 'calc')
+                        return [false, '输入的表达式非法:)后应有运算符'];
+                    if (iRightCount > iLeftCount)
+                        return [false, '输入的表达式非法:")"前无对应的"("'];
+                }
+            }
+            if (iLeftCount > iRightCount)
+                return [false, '输入的表达式非法:"("后无对应的")"'];
+            return [true, ''];
+        },
         _checkSExpr: function (payNode, text, data) {
             if (!payNode) return [false, '数据错误'];
+
             const num = text ? _.toNumber(text) : null;
-            const expr = text ? (num ? null : text) : null;
+            let expr = text ? (num ? null : text) : null;
+            expr = expr ? expr.replace('=', '').toLowerCase(): null;
+            const [valid, msg] = this._checkExprValid(expr, ['bqwc', 'ybbqwc']);
+            if (!valid) return [valid, msg];
+
             if (payBase.isStarted(payNode)) {
                 return [false, '已经开始计量,请勿修改起扣金额'];
             } else {
@@ -295,8 +414,13 @@ $(document).ready(() => {
         },
         _checkRExpr: function (payNode, text, data) {
             if (!payNode) return [false, '数据错误'];
+
             const num = text ? _.toNumber(text) : null;
-            const expr = text ? (num ? null : text) : null;
+            let expr = text ? (num ? null : text) : null;
+            expr = expr.replace('=', '').toLowerCase();
+            const [valid, msg] = this._checkExprValid(expr, ['bqwc', 'ybbqwc']);
+            if (!valid) return [valid, msg];
+
             if (payBase.isStarted(payNode)) {
                 if (payNode.pre_finish) return [false, '已达扣款限额,请勿修改'];
                 const value = expr ? payCalc.calculateExpr(expr) : num;
@@ -317,13 +441,17 @@ $(document).ready(() => {
                     data.tp = num;
                     data.expr = null;
                 } else {
-                    data.expr = text.replace('=', '');
+                    const expr = text.replace('=', '').toLowerCase();
+                    const [valid, msg] = this._checkExprValid(expr);
+                    if (!valid) return [valid, msg];
+                    data.expr = expr;
                     data.tp = null;
                 }
             } else {
                 data.tp = null;
                 data.expr = null;
             }
+            return [true, ''];
         },
         refreshActn: function () {
             const setObjEnable = function (obj, enable) {
@@ -467,7 +595,12 @@ $(document).ready(() => {
                 // 获取更新数据
                 if (col.field === 'tp') {
                     data.updateData.pid = select.pid;
-                    paySpreadObj._checkExpr(validText, data.updateData);
+                    const [valid, msg] = paySpreadObj._checkExpr(validText, data.updateData);
+                    if (!valid) {
+                        toastr.warning(msg);
+                        SpreadJsObj.reLoadRowData(info.sheet, info.row);
+                        return;
+                    }
                 } else if (col.field === 'name') {
                     data.updateData.pid = select.pid;
                     data.updateData.name = validText;
@@ -623,7 +756,12 @@ $(document).ready(() => {
                         const updateData = {};
                         if (col.field === 'tp') {
                             updateData.pid = node.pid;
-                            paySpreadObj._checkExpr(validText, updateData);
+                            const [valid, msg] = paySpreadObj._checkExpr(validText, updateData);
+                            if (!valid) {
+                                toastr.warning(msg);
+                                SpreadJsObj.reLoadSheetData(paySpread.getActiveSheet());
+                                return;
+                            }
                         } else {
                             updateData.id = node.pid;
                             if (validText) {