瀏覽代碼

上报自检速度优化

MaiXinRong 4 年之前
父節點
當前提交
34c590ad21
共有 5 個文件被更改,包括 168 次插入234 次删除
  1. 7 15
      app/controller/ledger_controller.js
  2. 8 18
      app/controller/revise_controller.js
  3. 6 15
      app/controller/stage_controller.js
  4. 0 165
      app/extend/helper.js
  5. 147 21
      app/lib/ledger.js

+ 7 - 15
app/controller/ledger_controller.js

@@ -472,26 +472,18 @@ module.exports = app => {
                     ? await ctx.service.pos.getPosData({ tid: ctx.tender.id }) : [];
 
                 const checkDataModel = require('../lib/ledger').checkData;
-                const checkData = new checkDataModel(ctx);
+                const checkData = new checkDataModel(ctx, measureType);
                 checkData.loadData(ledgerData, posData);
-                const sameCodeError = ctx.tender.info.ledger_check.same_code ? checkData.checkSameCode() : [];
-                const siblingError = ctx.tender.info.ledger_check.sibling ? checkData.checkSibling() : [];
 
-                const qtyData = ctx.helper.checkBillsWithPos(ledgerData, posData,
-                    ['sgfh_qty', 'qtcl_qty', 'sjcl_qty', 'quantity']);
-                qtyData.error.forEach(x => { x.errorType = 'qty'; });
-                const tpData = ctx.helper.checkBillsTp(ledgerData, [
+                ctx.tender.info.ledger_check.same_code && checkData.checkSameCode();
+                ctx.tender.info.ledger_check.sibling && checkData.checkSibling();
+
+                checkData.checkBillsQty(['sgfh_qty', 'qtcl_qty', 'sjcl_qty', 'quantity']);
+                checkData.checkBillsTp([
                     {qty: 'sgfh_qty', tp: 'sgfh_tp'}, {qty: 'qtcl_qty', tp: 'qtcl_tp'},
                     {qty: 'sjcl_qty', tp: 'sjcl_tp'}, {qty: 'quantity', tp: 'total_price'}
                 ], this.ctx.tender.info.decimal);
-                tpData.error.forEach(x => { x.errorType = 'tp'; });
-                ctx.body = { err: 0, msg: '', data: {
-                    error: [...qtyData.error, ...tpData.error, ...sameCodeError, ...siblingError],
-                    source: {
-                        bills: [...qtyData.source.bills, ...tpData.source.bills],
-                        pos: [...qtyData.source.pos, ...tpData.source.pos],
-                    },
-                }};
+                ctx.body = { err: 0, msg: '', data: checkData.checkResult };
             } catch (err) {
                 this.log(err);
                 ctx.body = this.ajaxErrorBody(err, '检查数据错误');

+ 8 - 18
app/controller/revise_controller.js

@@ -460,27 +460,17 @@ module.exports = app => {
                 const revisePos = await ctx.service.revisePos.getData(ctx.tender.id);
 
                 const checkDataModel = require('../lib/ledger').checkData;
-                const checkData = new checkDataModel(ctx);
-                checkData.loadData(reviseBills, revisePos);
-                const sameCodeError = ctx.tender.info.ledger_check.same_code ? checkData.checkSameCode() : [];
-                const siblingError = ctx.tender.info.ledger_check.sibling ? checkData.checkSibling() : [];
-
-                const qtyData = ctx.helper.checkBillsWithPos(reviseBills, revisePos,
-                    ['sgfh_qty', 'qtcl_qty', 'sjcl_qty', 'quantity']);
-                qtyData.error.forEach(x => { x.errorType = 'qty'; });
-                const tpData = ctx.helper.checkBillsTp(reviseBills, [
+                const reviseCheck = new checkDataModel(ctx, measureType);
+                reviseCheck.loadData(reviseBills, revisePos);
+                ctx.tender.info.ledger_check.same_code && reviseCheck.checkSameCode();
+                ctx.tender.info.ledger_check.sibling && reviseCheck.checkSibling();
+
+                reviseCheck.checkBillsQty(['sgfh_qty', 'qtcl_qty', 'sjcl_qty', 'quantity']);
+                reviseCheck.checkBillsTp([
                     {qty: 'sgfh_qty', tp: 'sgfh_tp'}, {qty: 'qtcl_qty', tp: 'qtcl_tp'},
                     {qty: 'sjcl_qty', tp: 'sjcl_tp'}, {qty: 'quantity', tp: 'total_price'}
                 ], this.ctx.tender.info.decimal);
-                tpData.error.forEach(x => { x.errorType = 'tp'; });
-                ctx.body = { err: 0, msg: '', data: {
-                        error: [...qtyData.error, ...tpData.error, ...sameCodeError, ...siblingError],
-                        source: {
-                            bills: [...qtyData.source.bills, ...tpData.source.bills],
-                            pos: [...qtyData.source.pos, ...tpData.source.pos],
-                        },
-                    }
-                };
+                ctx.body = { err: 0, msg: '', data: reviseCheck.checkResult };
             } catch (err) {
                 this.log(err);
                 ctx.body = this.ajaxErrorBody(err, '检查数据错误');

+ 6 - 15
app/controller/stage_controller.js

@@ -363,26 +363,17 @@ module.exports = app => {
                 const posData = await this._getStagePosData(ctx);
 
                 const checkDataModel = require('../lib/ledger').checkData;
-                const checkData = new checkDataModel(ctx);
+                const checkData = new checkDataModel(ctx, measureType);
                 checkData.loadData(ledgerData, posData);
                 await this.ctx.service.s2bProj.refreshSessionS2b();
-                const check3fResult = checkData.check3fLimit(ctx.tender.data);
+                checkData.check3fLimit(ctx.tender.data);
+                checkData.checkBillsQty(['sgfh_qty', 'qtcl_qty', 'sjcl_qty', 'quantity']);
 
-                const [qtyData, overData] = ctx.helper.checkBillsWithPos2(ledgerData, posData,
-                    ['contract_qty', 'qc_qty'], projRela.banOver, this.ctx.tender.data.measure_type === measureType.tz.value);
-                qtyData.error.forEach(x => { x.errorType = 'qty'; });
-                overData.error.forEach(x => {x.errorType = 'over'});
-                const tpData = ctx.helper.checkBillsTp(ledgerData.filter(x => {return !x.is_tp}), [
+                projRela.banOver && checkData.checkOverRange(['contract_qty', 'qc_qty']);
+                checkData.checkBillsTp([
                     { qty: 'contract_qty', tp: 'contract_tp' }, { qty: 'qc_qty', tp: 'qc_tp' },
                 ], this.ctx.tender.info.decimal);
-                tpData.error.forEach(x => { x.errorType = 'tp'; });
-                ctx.body = { err: 0, msg: '', data: {
-                    error: [...qtyData.error, ...tpData.error, ...overData.error, ...check3fResult.error],
-                    source: {
-                        bills: ctx.helper._.uniqBy([...qtyData.source.bills, ...tpData.source.bills, ...overData.source.bills, ...check3fResult.source.bills], 'id'),
-                        pos: ctx.helper._.uniqBy([...qtyData.source.pos, ...tpData.source.pos, ...overData.source.pos, ...check3fResult.source.pos], 'id'),
-                    },
-                } };
+                ctx.body = { err: 0, msg: '', data: checkData.checkResult };
             } catch (err) {
                 this.log(err);
                 ctx.body = this.ajaxErrorBody(err, '检查数据错误');

+ 0 - 165
app/extend/helper.js

@@ -1156,171 +1156,6 @@ module.exports = {
         return request.url.indexOf('/wap/') !== -1;
     },
 
-    getDefaultCheckResult() {
-        return {
-            error: [],
-            source: {
-                bills: [],
-                pos: [],
-            },
-        };
-    },
-
-    checkBillsWithPos(bills, pos, fields) {
-        const result = this.getDefaultCheckResult();
-        for (const b of bills) {
-            const pr = _.remove(pos, { lid: b.id });
-            const checkData = {},
-                calcData = {};
-            if (pr && pr.length > 0) {
-                for (const field of fields) {
-                    checkData[field] = b[field] ? b[field] : 0;
-                }
-                for (const p of pr) {
-                    for (const field of fields) {
-                        calcData[field] = this.add(calcData[field], p[field]);
-                    }
-                }
-                if (!_.isMatch(checkData, calcData)) {
-                    result.error.push({
-                        ledger_id: b.ledger_id,
-                        b_code: b.b_code,
-                        name: b.name,
-                        error: { checkData, calcData },
-                    });
-                    result.source.bills.push(b);
-                    for (const p of pr) {
-                        result.source.pos.push(p);
-                    }
-                }
-            }
-        }
-        return result;
-    },
-
-    checkBillsOverRange(bills, posRange, isTz) {
-        // if (isTz && posRange.length > 0) {
-        //     for (const p of posRange) {
-        //         const end_contract_qty = this.add(p.pre_contract_qty, p.contract_qty);
-        //         if (end_contract_qty > p.quantity) return true;
-        //     }
-        //     return false;
-        // } else {
-        //     const end_qc_qty = this.add(bills.qc_qty, bills.pre_qc_qty);
-        //     const end_qc_tp = this.add(bills.qc_tp, bills.pre_qc_tp);
-        //     const end_gather_qty = this.sum([bills.contract_qty, bills.pre_contract_qty, end_qc_qty]);
-        //     const end_gather_tp = this.sum([bills.contract_tp, bills.pre_contract_tp, end_qc_tp]);
-        //     if (isTz) {
-        //         if (end_gather_qty) {
-        //             return !bills.quantity || Math.abs(end_gather_qty) > Math.abs(this.add(bills.quantity, end_qc_qty));
-        //         } else if (end_gather_tp) {
-        //             return !bills.total_price || Math.abs(end_gather_tp) > Math.abs(this.add(bills.total_price, end_qc_tp));
-        //         }
-        //     } else {
-        //         if (end_gather_qty) {
-        //             return !bills.deal_qty || Math.abs(end_gather_qty) > Math.abs(this.add(bills.deal_qty, end_qc_qty));
-        //         } else if (end_gather_tp) {
-        //             return !bills.deal_tp || Math.abs(end_gather_tp) > Math.abs(this.add(bills.deal_tp, end_qc_tp));
-        //         }
-        //     }
-        // }
-        if (isTz && posRange.length > 0) {
-            if (posRange.length > 0) {
-                for (const p of posRange) {
-                    const end_contract_qty = this.add(p.pre_contract_qty, p.contract_qty);
-                    if (!p.quantity) return !!end_contract_qty;
-                    return p.quantity > 0
-                        ? end_contract_qty > p.quantity
-                        : end_contract_qty < p.quantity || end_contract_qty > 0;
-                }
-                return false;
-            }
-        } else {
-            const end_contract_qty = this.add(bills.contract_qty, bills.pre_contract_qty);
-            const end_contract_tp = this.add(bills.contract_tp, bills.pre_contract_tp);
-            if (bills.is_tp) {
-                const compare_tp = isTz ? bills.total_price : bills.deal_tp;
-                if (!compare_tp) return !!end_contract_tp;
-                return compare_tp >= 0 ? end_contract_tp > compare_tp : end_contract_tp < compare_tp || end_contract_tp > 0;
-            } else {
-                const compare_qty = isTz ? bills.quantity : bills.deal_qty;
-                if (!compare_qty) return !!end_contract_qty;
-                return compare_qty >= 0 ? end_contract_qty > compare_qty : end_contract_qty < compare_qty || end_contract_qty > 0;
-            }
-        }
-
-    },
-
-    checkBillsWithPos2(bills, pos, fields, checkOver, isTz) {
-        const result = this.getDefaultCheckResult(), overResult = this.getDefaultCheckResult();
-        for (const b of bills) {
-            let hasSource = false;
-            const pr = _.remove(pos, { lid: b.id });
-            const checkData = {},
-                calcData = {};
-            if (pr && pr.length > 0) {
-                for (const field of fields) {
-                    checkData[field] = b[field] ? b[field] : 0;
-                }
-                for (const p of pr) {
-                    for (const field of fields) {
-                        calcData[field] = this.add(calcData[field], p[field]);
-                    }
-                }
-                if (!_.isMatch(checkData, calcData)) {
-                    hasSource = true;
-                    result.error.push({
-                        ledger_id: b.ledger_id,
-                        b_code: b.b_code,
-                        name: b.name,
-                        error: { checkData, calcData },
-                    });
-                    result.source.bills.push(b);
-                    for (const p of pr) {
-                        result.source.pos.push(p);
-                    }
-                }
-            }
-            if (checkOver && this.checkBillsOverRange(b, pr, isTz)) {
-                overResult.error.push({
-                    ledger_id: b.ledger_id,
-                    b_code: b.b_code,
-                    name: b.name,
-                });
-                if (!hasSource) {
-                    overResult.source.bills.push(b);
-                    for (const p of pr) {
-                        overResult.source.pos.push(p);
-                    }
-                }
-            }
-        }
-        return [result, overResult];
-    },
-
-    checkBillsTp(bills, field, decimal) {
-        const result = this.getDefaultCheckResult();
-        for (const b of bills) {
-            if (!b.check_calc) continue;
-
-            const checkData = {}, calcData = {};
-            for (const f of field) {
-                checkData[f.tp] = b[f.tp] || 0;
-                calcData[f.tp] = this.mul(b.unit_price, b[f.qty], decimal.tp) || 0;
-            }
-            if (!this._.isMatch(checkData, calcData)) {
-                result.error.push({
-                    ledger_id: b.ledger_id,
-                    b_code: b.b_code,
-                    name: b.name,
-                    error: { checkData, calcData },
-                });
-                result.source.bills.push(b);
-            }
-        }
-        return result;
-    },
-
     check18MainCode(code) {
         return /^([0-9]([0-9][0-9])*)?(GD[0-9]{3}([0-9][0-9])*)?$/.test(code);
     },

+ 147 - 21
app/lib/ledger.js

@@ -573,10 +573,18 @@ class pos {
 }
 
 class checkData {
-    constructor(ctx) {
+    constructor(ctx, measureType) {
         this.ctx = ctx;
         this.checkBills = new billsTree(ctx, { id: 'ledger_id', pid: 'ledger_pid', order: 'order', level: 'level', rootId: -1 });
         this.checkPos = new pos({ id: 'id', ledgerId: 'lid' });
+        this.checkResult = {
+            error: [],
+            source: {
+                bills: [],
+                pos: [],
+            },
+        };
+        this.measureType = measureType;
     }
 
     _check3f(data, limit, ratio) {
@@ -666,7 +674,7 @@ class checkData {
         }
         if (over.length + lost.length > 0) {
             for (const o of over) {
-                result.error.push({
+                this.checkResult.error.push({
                     ledger_id: bills.ledger_id,
                     b_code: bills.b_code,
                     name: bills.name,
@@ -674,18 +682,20 @@ class checkData {
                 });
             }
             for (const l of lost) {
-                result.error.push({
+                this.checkResult.error.push({
                     ledger_id: bills.ledger_id,
                     b_code: bills.b_code,
                     name: bills.name,
                     errorType: 's2b_lost_' + l,
                 });
             }
-            result.source.bills.push(bills);
-            if (posRange && posRange.length > 0) result.source.pos.push(...posRange);
+            if (!this.checkResult.source.bills.find(x => {return x.ledger_id === b.ledger_id})) {
+                this.checkResult.source.bills.push(bills);
+                if (posRange && posRange.length > 0) this.checkResult.source.pos.push(...posRange);
+            }
         }
     }
-    _recursiveCheckBills3fLimit(checkType, bills, result, parentCheckInfo) {
+    _recursiveCheckBills3fLimit(checkType, bills, parentCheckInfo) {
         const checkInfo = this.ctx.helper._.assign({}, parentCheckInfo);
         for (const ct of checkType) {
             if (bills[ct + '_limit'] > 0) {
@@ -694,10 +704,10 @@ class checkData {
         }
         if (bills.children && bills.children.length > 0) {
             for (const c of bills.children) {
-                this._recursiveCheckBills3fLimit(checkType, c, result, checkInfo);
+                this._recursiveCheckBills3fLimit(checkType, c, checkInfo);
             }
         } else {
-            this._checkLeafBills3fLimit(checkType, bills, result, checkInfo);
+            this._checkLeafBills3fLimit(checkType, bills, checkInfo);
         }
     }
 
@@ -707,7 +717,6 @@ class checkData {
     }
 
     checkSibling() {
-        const error = [];
         for (const node of this.checkBills.nodes) {
             if (!node.children || node.children.length === 0) continue;
             let hasXmj, hasGcl;
@@ -715,25 +724,23 @@ class checkData {
                 if (child.b_code) hasXmj = true;
                 if (!child.b_code) hasGcl = true;
             }
-            if (hasXmj && hasGcl) error.push({
+            if (hasXmj && hasGcl) this.checkResult.error.push({
                 ledger_id: node.ledger_id,
                 b_code: node.b_code,
                 name: node.name,
                 errorType: 'sibling',
             });
         }
-        return error;
     }
 
     checkSameCode() {
-        const error = [];
         let xmj = this.checkBills.nodes.filter(x => { return /^((GD*)|G)?[0-9]+/.test(x.code); });
         let check = null;
         while (xmj.length > 0) {
             [check, xmj] = this.ctx.helper._.partition(xmj, x => { return x.code === xmj[0].code; });
             if (check.length > 1) {
                 for (const c of check) {
-                    error.push({
+                    this.checkResult.error.push({
                         ledger_id: c.ledger_id,
                         b_code: c.b_code,
                         name: c.name,
@@ -742,24 +749,143 @@ class checkData {
                 }
             }
         }
-        return error;
     }
 
     check3fLimit(tender) {
-        const result = {
-            error: [],
-            source: {bills: [], pos: []},
-        };
-
         const check = [];
         if (tender.s2b_gxby_limit) check.push('gxby');
         if (tender.s2b_dagl_limit) check.push('dagl');
         if (check.length === 0) return result;
 
         for (const b of this.checkBills.children) {
-            this._recursiveCheckBills3fLimit(check, b, result, {});
+            this._recursiveCheckBills3fLimit(check, b, {});
+        }
+    }
+    checkBillsQty(fields) {
+        for (const b of this.checkBills.nodes) {
+            if (b.children && b.children.length > 0) continue;
+            const pr = this.checkPos.getLedgerPos(b.id);
+            if (!pr || pr.length === 0) continue;
+            const checkData = {},
+                calcData = {};
+            for (const field of fields) {
+                checkData[field] = b[field] ? b[field] : 0;
+            }
+            for (const p of pr) {
+                for (const field of fields) {
+                    calcData[field] = this.ctx.helper.add(calcData[field], p[field]);
+                }
+            }
+            if (!this.ctx.helper._.isMatch(checkData, calcData)) {
+                this.checkResult.error.push({
+                    ledger_id: b.ledger_id,
+                    b_code: b.b_code,
+                    name: b.name,
+                    errorType: 'qty',
+                    error: { checkData, calcData },
+                });
+                if (!this.checkResult.source.bills.find(x => {return x.ledger_id === b.ledger_id})) {
+                    this.checkResult.source.bills.push(b);
+                    for (const p of pr) {
+                        this.checkResult.source.pos.push(p);
+                    }
+                }
+            }
+        }
+    }
+    checkBillsTp(field, decimal) {
+        for (const b of this.checkBills.nodes) {
+            if ((b.children && b.children.length > 0) || !b.check_calc) continue;
+
+            const checkData = {}, calcData = {};
+            for (const f of field) {
+                checkData[f.tp] = b[f.tp] || 0;
+                calcData[f.tp] = this.ctx.helper.mul(b.unit_price, b[f.qty], decimal.tp) || 0;
+            }
+            if (!this.ctx.helper._.isMatch(checkData, calcData)) {
+                this.checkResult.error.push({
+                    ledger_id: b.ledger_id,
+                    b_code: b.b_code,
+                    name: b.name,
+                    errorType: 'tp',
+                    error: { checkData, calcData },
+                });
+                if (!this.checkResult.source.bills.find(x => {return x.ledger_id === b.ledger_id})) {
+                    this.checkResult.source.bills.push(b);
+                }
+            }
+        }
+    }
+    _checkBillsOverRange(bills, posRange, isTz) {
+        // if (isTz && posRange.length > 0) {
+        //     for (const p of posRange) {
+        //         const end_contract_qty = this.add(p.pre_contract_qty, p.contract_qty);
+        //         if (end_contract_qty > p.quantity) return true;
+        //     }
+        //     return false;
+        // } else {
+        //     const end_qc_qty = this.add(bills.qc_qty, bills.pre_qc_qty);
+        //     const end_qc_tp = this.add(bills.qc_tp, bills.pre_qc_tp);
+        //     const end_gather_qty = this.sum([bills.contract_qty, bills.pre_contract_qty, end_qc_qty]);
+        //     const end_gather_tp = this.sum([bills.contract_tp, bills.pre_contract_tp, end_qc_tp]);
+        //     if (isTz) {
+        //         if (end_gather_qty) {
+        //             return !bills.quantity || Math.abs(end_gather_qty) > Math.abs(this.add(bills.quantity, end_qc_qty));
+        //         } else if (end_gather_tp) {
+        //             return !bills.total_price || Math.abs(end_gather_tp) > Math.abs(this.add(bills.total_price, end_qc_tp));
+        //         }
+        //     } else {
+        //         if (end_gather_qty) {
+        //             return !bills.deal_qty || Math.abs(end_gather_qty) > Math.abs(this.add(bills.deal_qty, end_qc_qty));
+        //         } else if (end_gather_tp) {
+        //             return !bills.deal_tp || Math.abs(end_gather_tp) > Math.abs(this.add(bills.deal_tp, end_qc_tp));
+        //         }
+        //     }
+        // }
+        if (isTz && posRange.length > 0) {
+            if (posRange.length > 0) {
+                for (const p of posRange) {
+                    const end_contract_qty = this.add(p.pre_contract_qty, p.contract_qty);
+                    if (!p.quantity) return !!end_contract_qty;
+                    return p.quantity > 0
+                        ? end_contract_qty > p.quantity
+                        : end_contract_qty < p.quantity || end_contract_qty > 0;
+                }
+                return false;
+            }
+        } else {
+            const end_contract_qty = this.add(bills.contract_qty, bills.pre_contract_qty);
+            const end_contract_tp = this.add(bills.contract_tp, bills.pre_contract_tp);
+            if (bills.is_tp) {
+                const compare_tp = isTz ? bills.total_price : bills.deal_tp;
+                if (!compare_tp) return !!end_contract_tp;
+                return compare_tp >= 0 ? end_contract_tp > compare_tp : end_contract_tp < compare_tp || end_contract_tp > 0;
+            } else {
+                const compare_qty = isTz ? bills.quantity : bills.deal_qty;
+                if (!compare_qty) return !!end_contract_qty;
+                return compare_qty >= 0 ? end_contract_qty > compare_qty : end_contract_qty < compare_qty || end_contract_qty > 0;
+            }
+        }
+    }
+    checkOverRange() {
+        const isTz = this.ctx.tender.data.measure_type === this.measureType.tz.value;
+        for (const b of this.checkBills.nodes) {
+            if (b.children && b.children.length > 0) continue;
+            const pr = this.checkPos.getLedgerPos(b.id);
+
+            if (this._checkBillsOverRange(b, pr, isTz)) {
+                this.checkResult.error.push({
+                    ledger_id: b.ledger_id,
+                    b_code: b.b_code,
+                    name: b.name,
+                    errorType: 'over',
+                });
+                if (!this.checkResult.source.bills.find(x => {return x.ledger_id === b.ledger_id})) {
+                    this.checkResult.source.bills.push(b);
+                    if (pr && pr.length > 0) this.checkResult.source.pos.push(...pr);
+                }
+            }
         }
-        return result;
     }
 }