瀏覽代碼

工程变更台账表,相关功能调整

MaiXinRong 4 年之前
父節點
當前提交
a0c8dc4834

+ 23 - 0
app/extend/helper.js

@@ -18,6 +18,7 @@ const Decimal = require('decimal.js');
 Decimal.set({ precision: 50, defaults: true });
 const SMS = require('../lib/sms');
 const WX = require('../lib/wechat');
+const timesLen = 100;
 
 module.exports = {
     _,
@@ -1254,4 +1255,26 @@ module.exports = {
         const counts = (arr, value) => arr.reduce((a, v) => { return value.indexOf(v) !== -1 ? a + 1 : a + 0; }, 0);
         return counts(array, val);
     },
+
+    filterLastestData(data, keyFields) {
+        const dataIndex = {};
+        for (const d of data) {
+            let key = 'd';
+            for (const kf of keyFields) {
+                key = key + '.' + (d[kf] || '');
+            }
+
+            const di = dataIndex[key];
+            if (di) {
+                if ((di.times * timesLen + di.order) < (d.times * timesLen + d.order)) dataIndex[key] = d;
+            } else {
+                dataIndex[key] = d;
+            }
+        }
+        const result = [];
+        for (const prop in dataIndex) {
+            result.push(dataIndex[prop]);
+        }
+        return result;
+    },
 };

+ 23 - 17
app/lib/rpt_data_analysis.js

@@ -1613,6 +1613,7 @@ const getChangeLedger = {
             if (b.b_code) continue;
 
             const l = {
+                id: b.id,
                 code: b.code, name: b.name, unit: b.unit,
                 ledger_id: b.ledger_id, ledger_pid: b.ledger_pid, level: b.level, full_path: b.full_path,
                 total_price: b.total_price, deal_tp: b.deal_tp,
@@ -1620,12 +1621,15 @@ const getChangeLedger = {
                 end_contract_tp: b.end_contract_tp, end_qc_tp: b.end_qc_tp, end_gather_tp: b.end_gather_tp,
             };
             result.push(l);
-            const gcl = bills.filter(x => { return x.full_path.indexOf(l.full_path + '-') === 1 && x.b_code; });
+            const childGcl = bills.filter(x => { return x.ledger_pid === b.ledger_id && x.b_code});
+            if (!childGcl || childGcl.length === 0) continue;
+
+            const gcl = bills.filter(x => { return x.full_path.indexOf(l.full_path + '-') === 0 && x.b_code; });
             if (gcl.length === 0) continue;
 
             const gclIds = gcl.map(x => { return x.id; });
             const changes = changeList.filter(x => { return gclIds.indexOf(x.lid) >= 0; });
-            if (!changes) return;
+            if (!changes || changes.length === 0) continue;
 
             l.changes = [];
             for (const c of changes) {
@@ -1645,15 +1649,14 @@ const getChangeLedger = {
         }
         return result;
     },
-    _filterChangeLedger(ctx, data, options) {
+    _filterChangeLedger(ctx, changeLedger, options) {
         const result = [];
-        for (const f of data) {
-            const calc = data.filter(x => { return x.full_path.indexOf(f.full_path + '-') === 1 && x.changes && x.changes.length > 0; });
-            if (!calc) continue;
+        for (const f of changeLedger) {
+            const calc = changeLedger.filter(x => { return x.full_path.indexOf(f.full_path) === 0 && x.changes && x.changes.length > 0; });
+            if (!calc || calc.length === 0) continue;
 
-            if (options.level === '2-leaf') {
-                if (f.level !== 2 || !f.changes || f.changes.length === 0) continue;
-            }
+            if (options.level === '2-leaf')
+                if (f.level !== 2 && (!f.changes || f.changes.length === 0)) continue;
 
             result.push({
                 code: f.code, name: f.name, unit: f.unit,
@@ -1663,13 +1666,15 @@ const getChangeLedger = {
                 end_contract_tp: f.end_contract_tp, end_qc_tp: f.end_qc_tp, end_gather_tp: f.end_gather_tp,
             });
             if (f.changes && f.changes.length > 0) {
-                const c = {
-                    c_code: c.c_code, c_name: c.c_name,
-                    c_new_code: c.c_new_code, c_new_name: c.c_new_name,
-                    c_content: c.c_content, c_basis: c.c_basis, c_cin_time: c.c_cin_time,
-                };
-                if (options.mergeName) c.name = c.c_name;
-                result.push(c);
+                for (const c of f.changes) {
+                    const fc = {
+                        c_code: c.c_code, c_name: c.c_name,
+                        c_new_code: c.c_new_code, c_new_name: c.c_new_name,
+                        c_content: c.c_content, c_basis: c.c_basis, c_cin_time: c.c_cin_time,
+                    };
+                    if (options.mergeName) fc.name = fc.c_name;
+                    result.push(fc);
+                }
             }
         }
         return result;
@@ -1679,7 +1684,7 @@ const getChangeLedger = {
         if (!data.mem_stage_bills) return;
         if (!data.mem_stage_change_bills) return;
 
-        const changeLedger = this._getSource(ctx, data.mem_stage_bills, data.mem_stage_chagne_bills);
+        const changeLedger = this._getSource(ctx, data.mem_stage_bills, data.mem_stage_change_bills);
         data.mem_stage_change_ledger = this._filterChangeLedger(ctx, changeLedger, options);
     },
 };
@@ -1744,6 +1749,7 @@ const analysisObj = {
     unionPos,
     splitXmjCode,
     loadCooperationData,
+    getChangeLedger,
     treeFilter,
 };
 const analysisDefine = (function(obj) {

+ 2 - 4
app/service/report.js

@@ -47,7 +47,7 @@ module.exports = app => {
                             runnableKey.push(filter);
                             break;
                         case 'advance_pay':
-                            runnableRst.push(service.advance.getAllDataByCondition({ where: {tid: params.tender_id}}));
+                            runnableRst.push(service.advance.getAllDataByCondition({ where: { tid: params.tender_id } }));
                             runnableKey.push(filter);
                             break;
                         case 'deal_bills' :
@@ -176,7 +176,7 @@ module.exports = app => {
                             runnableKey.push(filter);
                             break;
                         case 'mem_stage_change_bills':
-                            runnableRst.push(service.reportMemory.getSignSelect(params.tender_id, params.stage_id, customSelect));
+                            runnableRst.push(service.stageChangeFinal.getFinalData(params.tender_id));
                             runnableKey.push(filter);
                             break;
                         default:
@@ -188,8 +188,6 @@ module.exports = app => {
             for (let idx = 0; idx < runnableKey.length; idx++) {
                 rst[runnableKey[idx]] = queryRst[idx];
             }
-            this.ctx.helper.saveBufferFile(JSON.stringify(queryRst, '', '\t'), this.ctx.app.baseDir + '/reportDataOrg.json');
-            this.ctx.helper.saveBufferFile(JSON.stringify(rst, '', '\t'), this.ctx.app.baseDir + '/reportData.json');
             for (const filter of filters) {
                 switch (filter) {
                     case 'mem_stage_im_tz':

+ 2 - 0
app/service/stage_audit.js

@@ -449,6 +449,7 @@ module.exports = app => {
                     // 生成截止本期数据 final数据
                     await this.ctx.service.stageBillsFinal.generateFinalData(transaction, this.ctx.tender, this.ctx.stage);
                     await this.ctx.service.stagePosFinal.generateFinalData(transaction, this.ctx.tender, this.ctx.stage);
+                    await this.ctx.service.stageChangeFinal.generateFinalData(transaction, this.ctx.tender, this.ctx.stage);
                     // 同步 期信息
                     await transaction.update(this.ctx.service.stage.tableName, {
                         id: stageId,
@@ -885,6 +886,7 @@ module.exports = app => {
                 // 生成截止本期数据 final数据
                 await this.ctx.service.stageBillsFinal.delGenerateFinalData(transaction, this.ctx.tender, this.ctx.stage);
                 await this.ctx.service.stagePosFinal.delGenerateFinalData(transaction, this.ctx.tender, this.ctx.stage);
+                await this.ctx.service.stageChangeFinal.delGenerateFinalData(transaction, this.ctx.tender, this.ctx.stage);
                 // 同步 期信息
                 await transaction.update(this.ctx.service.stage.tableName, {
                     id: stageId,

+ 36 - 71
app/service/stage_change.js

@@ -33,7 +33,7 @@ module.exports = app => {
          * @param {Number} sid - 期id
          * @param {Number} lid - 台账节点id
          * @param {Number} pid - 部位明细id
-         * @returns {Promise<*>}
+         * @return {Promise<*>}
          */
         async getLastestStageData(tid, sid, lid, pid) {
             const sql = 'SELECT c.*,' +
@@ -62,7 +62,7 @@ module.exports = app => {
          * @param {Number} order - 第几人
          * @param {Number} lid - 台账节点id
          * @param {Number} pid - 部位明细id
-         * @returns {Promise<*>}
+         * @return {Promise<*>}
          */
         async getAuditorStageData(tid, sid, times, order, lid, pid) {
             const sql = 'SELECT c.*,' +
@@ -71,7 +71,7 @@ module.exports = app => {
                 '  INNER JOIN ( ' +
                 '    SELECT MAX(`stimes` * ' + timesLen + ' + `sorder`) As `progress`, `lid`, `pid`, `sid`, `cid`, `cbid` From ' + this.tableName +
                 '      WHERE tid = ? And sid = ? And (`stimes` < ? OR (`stimes` = ? AND `sorder` <= ?)) And lid = ? And pid = ?' +
-                '      GROUP By `lid`, `pid`' +
+                '      GROUP By `lid`, `pid`, cid, cbid' +
                 '  ) As m ' +
                 '  ON (c.stimes * ' + timesLen + ' + c.sorder) = m.progress And c.lid = m.lid And c.pid = m.pid And c.`sid` = m.`sid` And c.`cid` = m.`cid` And c.`cbid` = m.`cbid`' +
                 '  LEFT JOIN ' + this.ctx.service.change.tableName + ' As oc' +
@@ -90,11 +90,11 @@ module.exports = app => {
                 '  INNER JOIN ( ' +
                 '    SELECT MAX(`stimes` * ' + timesLen + ' + `sorder`) As `progress`, `lid`, `pid`, `sid`, `cid`, `cbid` From ' + this.tableName +
                 '      WHERE tid = ? And sid = ?' +
-                '      GROUP By `lid`, `pid`' +
+                '      GROUP By `lid`, `pid`, cid, cbid' +
                 '  ) As m ' +
                 '  ON (c.stimes * ' + timesLen + ' + c.sorder) = m.progress And c.lid = m.lid And c.pid = m.pid And c.`sid` = m.`sid` And c.`cid` = m.`cid` And c.`cbid` = m.`cbid`' +
                 '  LEFT JOIN ' + this.ctx.service.change.tableName + ' As oc' +
-                '  ON c.cid = oc.cid'+
+                '  ON c.cid = oc.cid' +
                 '  LEFT JOIN ' + this.ctx.service.changeAuditList.tableName + ' As ocb' +
                 '  ON c.cbid = ocb.id' +
                 '  WHERE not ISNULL(ocb.id)';
@@ -109,11 +109,11 @@ module.exports = app => {
                 '  INNER JOIN ( ' +
                 '    SELECT MAX(`stimes` * ' + timesLen + ' + `sorder`) As `progress`, `lid`, `pid`, `sid`, `cid`, `cbid` From ' + this.tableName +
                 '      WHERE tid = ? And sid = ? And (`stimes` < ? OR (`stimes` = ? AND `sorder` <= ?))' +
-                '      GROUP By `lid`, `pid`' +
+                '      GROUP By `lid`, `pid`, cid, cbid' +
                 '  ) As m ' +
                 '  ON (c.stimes * ' + timesLen + ' + c.sorder) = m.progress And c.lid = m.lid And c.pid = m.pid And c.`sid` = m.`sid` And c.`cid` = m.`cid` And c.`cbid` = m.`cbid`' +
                 '  LEFT JOIN ' + this.ctx.service.change.tableName + ' As oc' +
-                '  ON c.cid = oc.cid'+
+                '  ON c.cid = oc.cid' +
                 '  LEFT JOIN ' + this.ctx.service.changeAuditList.tableName + ' As ocb' +
                 '  ON c.cbid = ocb.id' +
                 '  WHERE not ISNULL(ocb.id)';
@@ -126,7 +126,7 @@ module.exports = app => {
          *
          * @param {Object} bills - 台账节点数据
          * @param {Array} changes - 调用的变更令
-         * @returns {Promise<void>}
+         * @return {Promise<void>}
          */
         async billsChange(bills, changes) {
             const self = this;
@@ -136,12 +136,12 @@ module.exports = app => {
                     sid: self.ctx.stage.id,
                     lid: bills.id,
                     pid: -1,
-                    cid: cid,
-                    cbid: cbid,
+                    cid,
+                    cbid,
                     stimes: times,
                     sorder: order,
-                    qty: qty
-                }
+                    qty,
+                };
             }
             const ledgerBills = await this.ctx.service.ledger.getDataById(bills.id);
             if (!ledgerBills || ledgerBills.tender_id !== this.ctx.tender.id) {
@@ -151,10 +151,11 @@ module.exports = app => {
             // 获取原变更令
             const oldChanges = await this.getLastestStageData(this.ctx.tender.id, this.ctx.stage.id, bills.id, -1);
             // 获取更新数据
-            const updateChanges = [], newChanges = [];
+            const updateChanges = [],
+                newChanges = [];
             let billsQty = 0;
             for (const oc of oldChanges) {
-                const nc = this._.find(changes, {cid: oc.cid, cbid: oc.cbid});
+                const nc = this._.find(changes, { cid: oc.cid, cbid: oc.cbid });
                 if (!nc || nc.qty !== oc.qty) {
                     const qty = nc ? this.round(nc.qty, precision.value) : null;
                     const change = getNewChange(oc.cid, oc.cbid, this.ctx.stage.curTimes, this.ctx.stage.curOrder, qty);
@@ -170,7 +171,7 @@ module.exports = app => {
                 }
             }
             for (const c of changes) {
-                const nc = this._.find(oldChanges, {cid: c.cid, cbid: c.cbid});
+                const nc = this._.find(oldChanges, { cid: c.cid, cbid: c.cbid });
                 if (!nc) {
                     const change = getNewChange(c.cid, c.cbid, this.ctx.stage.curTimes, this.ctx.stage.curOrder, this.round(c.qty, precision.value));
                     billsQty = this.ctx.helper.add(billsQty, change.qty);
@@ -194,7 +195,7 @@ module.exports = app => {
                 throw err;
             }
             const result = await this.ctx.service.stageBills.getLastestStageData(this.ctx.tender.id, this.ctx.stage.id, [bills.id]);
-            return { bills: {curStageData: result} };
+            return { bills: { curStageData: result } };
         }
 
         /**
@@ -202,7 +203,7 @@ module.exports = app => {
          *
          * @param {Object} pos - 部位明细数据
          * @param {Array} changes - 调用的变更令
-         * @returns {Promise<{}>}
+         * @return {Promise<{}>}
          */
         async posChange(pos, changes) {
             const self = this;
@@ -212,12 +213,12 @@ module.exports = app => {
                     sid: self.ctx.stage.id,
                     lid: pos.lid,
                     pid: pos.id,
-                    cid: cid,
-                    cbid: cbid,
+                    cid,
+                    cbid,
                     stimes: times,
                     sorder: order,
-                    qty: qty
-                }
+                    qty,
+                };
             }
             const ledgerBills = await this.ctx.service.ledger.getDataById(pos.lid);
             if (!ledgerBills || ledgerBills.tender_id !== this.ctx.tender.id) {
@@ -226,10 +227,11 @@ module.exports = app => {
             const precision = this.ctx.helper.findPrecision(this.ctx.tender.info.precision, ledgerBills.unit);
             // 获取原变更令
             const oldChanges = await this.getLastestStageData(this.ctx.tender.id, this.ctx.stage.id, pos.lid, pos.id);
-            const updateChanges = [], newChanges = [];
+            const updateChanges = [],
+                newChanges = [];
             let posQty = 0;
             for (const oc of oldChanges) {
-                const nc = this._.find(changes, {cid: oc.cid, cbid: oc.cbid});
+                const nc = this._.find(changes, { cid: oc.cid, cbid: oc.cbid });
                 if (!nc || nc.qty !== oc.qty) {
                     const qty = nc ? this.round(nc.qty, precision.value) : null;
                     const change = getNewChange(oc.cid, oc.cbid, this.ctx.stage.curTimes, this.ctx.stage.curOrder, qty);
@@ -245,7 +247,7 @@ module.exports = app => {
                 }
             }
             for (const c of changes) {
-                const nc = this._.find(oldChanges, {cid: c.cid, cbid: c.cbid});
+                const nc = this._.find(oldChanges, { cid: c.cid, cbid: c.cbid });
                 if (!nc) {
                     const change = getNewChange(c.cid, c.cbid, this.ctx.stage.curTimes, this.ctx.stage.curOrder, this.round(c.qty, precision.value));
                     posQty = this.ctx.helper.add(posQty, change.qty);
@@ -272,9 +274,9 @@ module.exports = app => {
             try {
                 const data = { bills: {}, pos: {} };
                 data.bills.curStageData = await this.ctx.service.stageBills.getLastestStageData(this.ctx.tender.id, this.ctx.stage.id, [pos.lid]);
-                data.pos.curStageData = await this.ctx.service.stagePos.getLastestStageData2(this.ctx.tender.id, this.ctx.stage.id, {pid: pos.id});
+                data.pos.curStageData = await this.ctx.service.stagePos.getLastestStageData2(this.ctx.tender.id, this.ctx.stage.id, { pid: pos.id });
                 return data;
-            } catch(err) {
+            } catch (err) {
                 throw '获取数据错误,请刷新页面';
             }
         }
@@ -283,7 +285,7 @@ module.exports = app => {
          * 获取 变更令 - 变更清单 使用情况
          * @param {Number} sid - 查询期id
          * @param {uuid} cid - 变更令id
-         * @returns {Promise<void>}
+         * @return {Promise<void>}
          */
         async getUsedData(tid, cid) {
             const lastStage = await this.ctx.service.stage.getLastestStage(tid, true);
@@ -298,7 +300,7 @@ module.exports = app => {
                     filter = '';
                 } else if (lastStage.status === audit.stage.status.checkNo) {
                     filter = this.db.format(' And (s.`order` < ? || (s.`order` = ? And sChange.`stimes` <= ?))',
-                        [lastStage.order, lastStage.order, lastStage.times])
+                        [lastStage.order, lastStage.order, lastStage.times]);
                 } else {
                     const curAuditor = await this.ctx.service.stageAudit.getCurAuditor(lastStage.id, lastStage.times);
                     filter = this.db.format(' And (s.`order` < ? || (s.`order` = ? And sChange.`stimes` <= ? And sChange.`sorder` <= ?))',
@@ -347,7 +349,7 @@ module.exports = app => {
          * 获取 变更令 - 变更清单 当期使用情况
          * @param {Number} sid - 查询期id
          * @param {uuid} cid - 变更令id
-         * @returns {Promise<*>}
+         * @return {Promise<*>}
          */
         async getStageUsedData(sid, cid) {
             const sql = 'SELECT c.*, ' +
@@ -371,7 +373,7 @@ module.exports = app => {
         /**
          * 获取 本期 使用的变更令
          * @param sid
-         * @returns {Promise<void>}
+         * @return {Promise<void>}
          */
         async getStageUsedChangeId(sid) {
             const sql = 'SELECT c.`cid`, sum(qty) As qty FROM ' + this.tableName + ' As c' +
@@ -387,49 +389,12 @@ module.exports = app => {
             return this._.map(this._.filter(result, 'qty'), 'cid');
         }
 
-        async getReportLastestAllStageData(tid, sid) {
-            const sql = 'SELECT c.*,' +
-                '    oc.p_code As c_code, oc.name As c_name, oc.new_code As c_new_code, oc.new_name As c_new_name, ' +
-                '    oc.content As c_content, oc.basis As c_basis, oc.cin_time As c_cin_time, ' +
-                '    ocb.code As b_code, ocb.name As b_name, ocb.unit As b_unit, ocb.unit_price As b_unit_price, ' +
-                '  FROM ' + this.tableName + ' As c ' +
-                '  INNER JOIN ( ' +
-                '    SELECT MAX(`stimes` * ' + timesLen + ' + `sorder`) As `progress`, `lid`, `pid`, `sid`, `cid`, `cbid` From ' + this.tableName +
-                '      WHERE tid = ? And sid = ?' +
-                '      GROUP By `lid`, `pid`' +
-                '  ) As m ' +
-                '  ON (c.stimes * ' + timesLen + ' + c.sorder) = m.progress And c.lid = m.lid And c.pid = m.pid And c.`sid` = m.`sid` And c.`cid` = m.`cid` And c.`cbid` = m.`cbid`' +
-                '  LEFT JOIN ' + this.ctx.service.change.tableName + ' As oc' +
-                '  ON c.cid = oc.cid'+
-                '  LEFT JOIN ' + this.ctx.service.changeAuditList.tableName + ' As ocb' +
-                '  ON c.cbid = ocb.id' +
-                '  WHERE not ISNULL(ocb.id)';
-            const sqlParam = [tid, sid];
-            return await this.db.query(sql, sqlParam);
-        }
-
-        async getReportAuditorAllStageData(tid, sid, times, order) {
-            const sql = 'SELECT c.*, ' +
-                '    oc.p_code As c_code, oc.name As c_name, oc.new_code As c_new_code, oc.new_name As c_new_name, ' +
-                '    oc.content As c_content, oc.basis As c_basis, oc.cin_time As c_cin_time, ' +
-                '    ocb.code As b_code, ocb.name As b_name, ocb.unit As b_unit, ocb.unit_price As b_unit_price, ' +
-                '  FROM ' + this.tableName + ' As c ' +
-                '  INNER JOIN ( ' +
-                '    SELECT MAX(`stimes` * ' + timesLen + ' + `sorder`) As `progress`, `lid`, `pid`, `sid`, `cid`, `cbid` From ' + this.tableName +
-                '      WHERE tid = ? And sid = ? And (`stimes` < ? OR (`stimes` = ? AND `sorder` <= ?))' +
-                '      GROUP By `lid`, `pid`' +
-                '  ) As m ' +
-                '  ON (c.stimes * ' + timesLen + ' + c.sorder) = m.progress And c.lid = m.lid And c.pid = m.pid And c.`sid` = m.`sid` And c.`cid` = m.`cid` And c.`cbid` = m.`cbid`' +
-                '  LEFT JOIN ' + this.ctx.service.change.tableName + ' As oc' +
-                '  ON c.cid = oc.cid'+
-                '  LEFT JOIN ' + this.ctx.service.changeAuditList.tableName + ' As ocb' +
-                '  ON c.cbid = ocb.id' +
-                '  WHERE not ISNULL(ocb.id)';
-            const sqlParam = [tid, sid, times, times, order];
-            return await this.db.query(sql, sqlParam);
+        async getFinalStageData(tid, sid) {
+            const data = await this.getAllDataByCondition({ where: { tid, sid } });
+            return this.ctx.helper.filterLastestData(data, ['lid', 'pid', 'cid', 'cbid']);
         }
     }
 
     return StageChange;
 
-};
+};

+ 84 - 0
app/service/stage_change_final.js

@@ -0,0 +1,84 @@
+'use strict';
+
+/**
+ * stage_change_final 期-变更令使用-最终数据
+ *
+ * @author Mai
+ * @date
+ * @version
+ */
+
+const timesLen = require('../const/audit').stage.timesLen;
+
+module.exports = app => {
+
+    class StageChangeFinal extends app.BaseService {
+        /**
+         * 构造函数
+         *
+         * @param {Object} ctx - egg全局变量
+         * @return {void}
+         */
+        constructor(ctx) {
+            super(ctx);
+            this.tableName = 'stage_change_final';
+        }
+
+        /**
+         * 获取截止本期数据
+         * @param {Object} tender - 标段
+         * @param {Object} stage - 本期
+         * @return {Promise<void>}
+         */
+        async getFinalData(tid) {
+            const sql = 'Select cf.*, c.code As c_code, c.name As c_name, c.new_code As c_new_code, c.new_name As c_new_name, c.content As c_content, c.basis As c_basis, c.cin_time As c_cin_time' +
+                '  FROM ' + this.tableName + ' cf Left Join ' + this.ctx.service.change.tableName + ' c' +
+                '  ON cf.cid = c.cid' +
+                '  Where cf.tid = ?';
+            return await this.db.query(sql, [tid]);
+            //return await this.getAllDataByCondition({ where: { tid: tid } });
+        }
+
+        /**
+         * 生成本期最终数据
+         * @param transaction - 所属事务
+         * @param {Number} tender - 标段
+         * @param {Number}stage - 本期
+         * @return {Promise<void>}
+         */
+        async generateFinalData(transaction, tender, stage) {
+            if (!transaction || !tender || !stage) {
+                throw '数据错误';
+            }
+
+            const cur = await this.ctx.service.stageChange.getFinalStageData(tender.id, stage.id);
+            const data = [];
+            for (const c of cur) {
+                if (!c.qty) continue;
+
+                data.push({
+                    tid: c.tid, sid: c.sid,
+                    lid: c.lid, pid: c.pid, cid: c.cid, cbid: c.cbid,
+                    qty: c.qty,
+                });
+            }
+            await transaction.insert(this.tableName, data);
+        }
+
+        /**
+         * 删除生成本期最终数据
+         * @param transaction - 所属事务
+         * @param {Object} tender - 标段
+         * @param {Object} stage - 本期
+         * @return {Promise<void>}
+         */
+        async delGenerateFinalData(transaction, tender, stage) {
+            if (!transaction || !tender || !stage) {
+                throw '数据错误';
+            }
+            await transaction.delete(this.tableName, { tid: tender.id, sid: stage.id });
+        }
+    }
+
+    return StageChangeFinal;
+};

+ 92 - 0
db_script/stage-change-final.js

@@ -0,0 +1,92 @@
+'use strict';
+
+/**
+ *
+ *
+ * @author Mai
+ * @date
+ * @version
+ */
+const audit = require('../app/const/audit');
+
+const mysql = require('mysql');
+
+const pool = mysql.createPool({
+    // host
+    host: '192.168.1.76',
+    // 端口号
+    port: '3306',
+    // 用户名
+    user: 'zh_dev',
+    // 密码
+    password: 'zongheng2019',
+    // 数据库名
+    database: 'calculation',
+    // database: 'calc_copy_pro',
+});
+
+const querySql = async function (sql, sqlParam) {
+    return new Promise(function (resolve, reject) {
+        pool.getConnection(function (err, conn) {
+            if (err) {
+                reject(err);
+            } else {
+                conn.query(sql, sqlParam, function (err, rows, fields) {
+                    //释放连接
+                    conn.release();
+                    //传递Promise回调对象
+                    resolve({"err": err, "rows": rows, "fields": fields});
+                });
+            }
+        });
+    });
+};
+
+const timesLen = 100;
+const filterLastestData = function(data, keyFields) {
+    const dataIndex = {};
+    for (const d of data) {
+        let key = 'd';
+        for (const kf of keyFields) {
+            key = key + '.' + (d[kf] || '');
+        }
+
+        const di = dataIndex[key];
+        if (di) {
+            if ((di.times * timesLen + di.order) < (d.times * timesLen + d.order)) dataIndex[key] = d;
+        } else {
+            dataIndex[key] = d;
+        }
+    }
+    const result = [];
+    for (const prop in dataIndex) {
+        result.push(dataIndex[prop]);
+    }
+    return result;
+};
+
+const doComplete = async function () {
+    const tenders = await querySql('Select * From zh_tender where ledger_status = ?', [audit.ledger.status.checked]);
+    for (const t of tenders.rows) {
+        const stages = await querySql('Select * From zh_stage where tid = ? and status = ?', [t.id, audit.stage.status.checked]);
+        for (const s of stages.rows) {
+            const stageChange = await querySql('Select * From zh_stage_change where sid = ?', [s.id]);
+            const validStageChange = filterLastestData(stageChange.rows, ['lid', 'pid', 'cid', 'cbid']);
+
+            const stageChangeFinal = [];
+            for (const vsc of validStageChange) {
+                if (!vsc.qty) continue;
+
+                stageChangeFinal.push([
+                    vsc.tid, vsc.sid,
+                    vsc.lid, vsc.pid, vsc.cid, vsc.cbid,
+                    vsc.qty,
+                ]);
+            }
+            const result = await querySql('Insert Into zh_stage_change_final(tid, sid, lid, pid, cid, cbid, qty) Values ?', [stageChangeFinal]);
+        }
+    }
+    pool.end();
+};
+
+doComplete();

+ 25 - 25
package-lock.json

@@ -631,7 +631,7 @@
         },
         "isarray": {
           "version": "1.0.0",
-          "resolved": "https://registry.npm.taobao.org/isarray/download/isarray-1.0.0.tgz?cache=0&sync_timestamp=1562592096220&other_urls=https%3A%2F%2Fregistry.npm.taobao.org%2Fisarray%2Fdownload%2Fisarray-1.0.0.tgz",
+          "resolved": "https://registry.npmjs.org/isarray/-/isarray-1.0.0.tgz",
           "integrity": "sha1-u5NdSFgsuhaMBoNJV6VKPgcSTxE="
         },
         "normalize-path": {
@@ -2330,7 +2330,7 @@
     },
     "buffer-crc32": {
       "version": "0.2.13",
-      "resolved": "https://registry.npm.taobao.org/buffer-crc32/download/buffer-crc32-0.2.13.tgz",
+      "resolved": "https://registry.npmjs.org/buffer-crc32/-/buffer-crc32-0.2.13.tgz",
       "integrity": "sha1-DTM+PwDqxQqhRUq9MO+MKl2ackI="
     },
     "buffer-equal": {
@@ -6764,7 +6764,7 @@
           "bundled": true,
           "optional": true,
           "requires": {
-            "number-is-nan": "1.0.1"
+            "number-is-nan": "^1.0.0"
           }
         },
         "isarray": {
@@ -6847,8 +6847,8 @@
           "bundled": true,
           "optional": true,
           "requires": {
-            "abbrev": "1.1.1",
-            "osenv": "0.1.5"
+            "abbrev": "1",
+            "osenv": "^0.1.4"
           }
         },
         "npm-bundled": {
@@ -6861,8 +6861,8 @@
           "bundled": true,
           "optional": true,
           "requires": {
-            "ignore-walk": "3.0.1",
-            "npm-bundled": "1.0.5"
+            "ignore-walk": "^3.0.1",
+            "npm-bundled": "^1.0.1"
           }
         },
         "npmlog": {
@@ -6909,8 +6909,8 @@
           "bundled": true,
           "optional": true,
           "requires": {
-            "os-homedir": "1.0.2",
-            "os-tmpdir": "1.0.2"
+            "os-homedir": "^1.0.0",
+            "os-tmpdir": "^1.0.0"
           }
         },
         "path-is-absolute": {
@@ -9288,27 +9288,27 @@
     },
     "lodash.defaults": {
       "version": "4.2.0",
-      "resolved": "https://registry.npm.taobao.org/lodash.defaults/download/lodash.defaults-4.2.0.tgz",
+      "resolved": "https://registry.npmjs.org/lodash.defaults/-/lodash.defaults-4.2.0.tgz",
       "integrity": "sha1-0JF4cW/+pN3p5ft7N/bwgCJ0WAw="
     },
     "lodash.difference": {
       "version": "4.5.0",
-      "resolved": "https://registry.npm.taobao.org/lodash.difference/download/lodash.difference-4.5.0.tgz",
+      "resolved": "https://registry.npmjs.org/lodash.difference/-/lodash.difference-4.5.0.tgz",
       "integrity": "sha1-nMtOUF1Ia5FlE0V3KIWi3yf9AXw="
     },
     "lodash.flatten": {
       "version": "4.4.0",
-      "resolved": "https://registry.npm.taobao.org/lodash.flatten/download/lodash.flatten-4.4.0.tgz",
+      "resolved": "https://registry.npmjs.org/lodash.flatten/-/lodash.flatten-4.4.0.tgz",
       "integrity": "sha1-8xwiIlqWMtK7+OSt2+8kCqdlph8="
     },
     "lodash.isplainobject": {
       "version": "4.0.6",
-      "resolved": "https://registry.npm.taobao.org/lodash.isplainobject/download/lodash.isplainobject-4.0.6.tgz",
+      "resolved": "https://registry.npmjs.org/lodash.isplainobject/-/lodash.isplainobject-4.0.6.tgz",
       "integrity": "sha1-fFJqUtibRcRcxpC4gWO+BJf1UMs="
     },
     "lodash.union": {
       "version": "4.6.0",
-      "resolved": "https://registry.npm.taobao.org/lodash.union/download/lodash.union-4.6.0.tgz",
+      "resolved": "https://registry.npmjs.org/lodash.union/-/lodash.union-4.6.0.tgz",
       "integrity": "sha1-SLtQiECfFvGCFmZkHETdGqrjzYg="
     },
     "long": {
@@ -9929,20 +9929,20 @@
       "dev": true
     },
     "mysql": {
-      "version": "2.17.1",
-      "resolved": "https://registry.npmjs.org/mysql/-/mysql-2.17.1.tgz",
-      "integrity": "sha512-7vMqHQ673SAk5C8fOzTG2LpPcf3bNt0oL3sFpxPEEFp1mdlDcrLK0On7z8ZYKaaHrHwNcQ/MTUz7/oobZ2OyyA==",
+      "version": "2.18.1",
+      "resolved": "https://registry.npmjs.org/mysql/-/mysql-2.18.1.tgz",
+      "integrity": "sha512-Bca+gk2YWmqp2Uf6k5NFEurwY/0td0cpebAucFpY/3jhrwrVGuxU2uQFCHjU19SJfje0yQvi+rVWdq78hR5lig==",
       "requires": {
-        "bignumber.js": "7.2.1",
-        "readable-stream": "2.3.6",
+        "bignumber.js": "9.0.0",
+        "readable-stream": "2.3.7",
         "safe-buffer": "5.1.2",
         "sqlstring": "2.3.1"
       },
       "dependencies": {
         "bignumber.js": {
-          "version": "7.2.1",
-          "resolved": "https://registry.npmjs.org/bignumber.js/-/bignumber.js-7.2.1.tgz",
-          "integrity": "sha512-S4XzBk5sMB+Rcb/LNcpzXr57VRTxgAvaAEDAl1AwRx27j00hT84O6OkteE7u8UB3NuaaygCRrEpqox4uDOrbdQ=="
+          "version": "9.0.0",
+          "resolved": "https://registry.npmjs.org/bignumber.js/-/bignumber.js-9.0.0.tgz",
+          "integrity": "sha512-t/OYhhJ2SD+YGBQcjY8GzzDHEk9f3nerxjtfa6tlMXfe7frs/WozhvCNoGvpM0P3bNf3Gq5ZRMlGr5f3r4/N8A=="
         },
         "isarray": {
           "version": "1.0.0",
@@ -9955,9 +9955,9 @@
           "integrity": "sha512-3ouUOpQhtgrbOa17J7+uxOTpITYWaGP7/AhoR3+A+/1e9skrzelGi/dXzEYyvbxubEF6Wn2ypscTKiKJFFn1ag=="
         },
         "readable-stream": {
-          "version": "2.3.6",
-          "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-2.3.6.tgz",
-          "integrity": "sha512-tQtKA9WIAhBF3+VLAseyMqZeBjW0AHJoxOtYqSUZNJxauErmLbVm2FW1y+J/YA9dUrAC39ITejlZWhVIwawkKw==",
+          "version": "2.3.7",
+          "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-2.3.7.tgz",
+          "integrity": "sha512-Ebho8K4jIbHAxnuxi7o42OrZgF/ZTNcsZj6nRKyUmkhLFq8CHItp/fy6hQZuZmP/n3yZ9VBUbp4zz/mX8hmYPw==",
           "requires": {
             "core-util-is": "~1.0.0",
             "inherits": "~2.0.3",

+ 1 - 0
package.json

@@ -31,6 +31,7 @@
         "lz-string": "^1.4.4",
         "mathjs": "^5.9.0",
         "moment": "^2.20.1",
+        "mysql": "^2.18.1",
         "node-schedule": "^1.3.2",
         "node-uuid": "^1.4.8",
         "node-xlsx": "^0.12.0",