浏览代码

Merge branch 'dev' of http://192.168.1.41:3000/maixinrong/Calculation into dev

Tony Kang 2 年之前
父节点
当前提交
411e82aa91
共有 45 个文件被更改,包括 1026 次插入471 次删除
  1. 7 1
      app/controller/profile_controller.js
  2. 7 1
      app/controller/report_controller.js
  3. 11 1
      app/controller/tender_controller.js
  4. 6 0
      app/lib/rm/material.js
  5. 1 1
      app/lib/rpt_data_analysis.js
  6. 2 2
      app/lib/sum_load.js
  7. 1 1
      app/lib/tender_info.js
  8. 45 59
      app/middleware/stage_check.js
  9. 0 1
      app/middleware/tender_check.js
  10. 4 0
      app/public/js/change_information.js
  11. 1 1
      app/public/js/ledger_gather.js
  12. 2 3
      app/public/js/material_checklist.js
  13. 2 6
      app/public/js/revise_price.js
  14. 1 0
      app/public/js/se_bonus.js
  15. 209 0
      app/public/js/shares/batch_import.js
  16. 62 22
      app/public/js/shares/export_excel.js
  17. 27 0
      app/public/js/stage.js
  18. 1 5
      app/public/js/stage_audit.js
  19. 13 0
      app/public/report/js/jpc_output.js
  20. 2 0
      app/public/report/js/rpt_main.js
  21. 3 1
      app/service/change_ledger.js
  22. 2 2
      app/service/material_list.js
  23. 39 49
      app/service/stage.js
  24. 48 27
      app/service/stage_audit.js
  25. 6 1
      app/service/stage_audit_ass.js
  26. 21 0
      app/service/stage_bills.js
  27. 23 3
      app/service/stage_bonus.js
  28. 20 0
      app/service/stage_detail.js
  29. 30 3
      app/service/stage_jgcl.js
  30. 26 3
      app/service/stage_other.js
  31. 3 3
      app/service/stage_pay.js
  32. 21 0
      app/service/stage_pos.js
  33. 34 4
      app/service/stage_safe_prod.js
  34. 26 4
      app/service/stage_temp_land.js
  35. 11 0
      app/service/sum_load_history.js
  36. 63 61
      app/view/change/information.ejs
  37. 1 1
      app/view/report/rpt_all_popup.ejs
  38. 32 0
      app/view/shares/batch_import_modal.ejs
  39. 7 3
      app/view/stage/audit_modal.ejs
  40. 1 1
      app/view/stage/index.ejs
  41. 2 1
      app/view/stage/modal.ejs
  42. 1 0
      config/web.js
  43. 14 12
      publish.md
  44. 0 188
      sql/update.sql
  45. 188 0
      sql/update20230212.sql

+ 7 - 1
app/controller/profile_controller.js

@@ -482,7 +482,8 @@ module.exports = app => {
                 const parts = ctx.multipart({ autoFields: true });
                 const paths = [];
                 let index = 0;
-                while ((stream = await parts()) !== undefined) {
+                stream = await parts();
+                while (stream !== undefined) {
                     // 判断用户是否选择上传文件
                     if (!stream.filename) {
                         throw '请选择上传的文件!';
@@ -497,6 +498,11 @@ module.exports = app => {
                     }
                     paths.push(filepath);
                     ++index;
+                    if (Array.isArray(parts.field.size) && index < parts.field.size.length) {
+                        stream = await parts();
+                    } else {
+                        stream = undefined;
+                    }
                 }
                 // 获取账号数据
                 const accountData = await ctx.service.projectAccount.getDataByCondition({ id: ctx.session.sessionUser.accountId });

+ 7 - 1
app/controller/report_controller.js

@@ -501,7 +501,13 @@ module.exports = app => {
             // 原则说明:把所有报表模板集中获取,统一filter,只读一次数据!
             const params = JSON.parse(ctx.request.body.params);
             const pageShow = ctx.session.sessionProject.page_show;
-            if (pageShow !== null && pageShow !== undefined && parseInt(pageShow.closeExportPdf) === 1) {
+            if (pageShow !== null
+                && pageShow !== undefined
+                && params.outputType
+                && ((params.outputType === 'PDF' && parseInt(pageShow.closeExportPdf) === 1)
+                    || (params.outputType === 'Excel' && parseInt(pageShow.closeExportExcel) === 1)
+                )
+            ) {
                 ctx.body = { data: [], signatureRelInfo: [], stageAudit: [] };
                 ctx.status = 201;
                 return;

+ 11 - 1
app/controller/tender_controller.js

@@ -1206,7 +1206,8 @@ module.exports = app => {
         async listLoad(ctx) {
             try {
                 const data = JSON.parse(ctx.request.body.data);
-                if (!data.tid || !data.lid || !data.type) throw '数据错误';
+                if (!data.type || !data.tid) throw '数据错误';
+                if (data.type !== 'stageBatch' && !data.lid) throw '数据错误';
                 const responseData = {
                     err: 0,
                     msg: '',
@@ -1244,6 +1245,11 @@ module.exports = app => {
                             if (history) responseData.data.history = { tenders: history.tenders, load_time: history.load_time, type: 'ledger' };
                         }
                     }
+                } else if (data.type === 'stageBatch') {
+                    responseData.data.tenders = tenderList.filter(x => {
+                        return x.ledger_status === auditConst.ledger.status.checked && !!x.lastStage;
+                    });
+                    responseData.data.history = await this.ctx.service.sumLoadHistory.getBatchHistory(data.tid);
                 } else if (data.type === 'revise') {
                     responseData.data.tenders = tenderList.filter(x => {
                         return x.ledger_status === auditConst.ledger.status.checked;
@@ -1297,6 +1303,10 @@ module.exports = app => {
                     responseData.data.tenders = tenderList.filter(x => {
                         return x.ledger_status === auditConst.ledger.status.checked && !!x.lastCheckedStage;
                     });
+                } else if (data.type === 'stageBatch') {
+                    responseData.data.tenders = tenderList.filter(x => {
+                        return x.ledger_status === auditConst.ledger.status.checked && !!x.lastStage;
+                    });
                 }
                 ctx.body = responseData;
             } catch(err) {

+ 6 - 0
app/lib/rm/material.js

@@ -231,6 +231,8 @@ class ReportMemoryMaterial {
 
     async getMaterialBills(tender_id, material_order, fields) {
         const material = await this.ctx.service.material.getDataByCondition({tid: tender_id, order: material_order});
+        if (!material) return [];
+
         try {
             const billsData = await this.ctx.service.ledger.getData(tender_id);
             if (this._checkFieldsExist(fields, billsFields.stage)) {
@@ -262,6 +264,8 @@ class ReportMemoryMaterial {
 
     async getMaterialPos(tender_id, material_order, fields) {
         const material = await this.ctx.service.material.getDataByCondition({tid: tender_id, order: material_order});
+        if (!material) return [];
+
         try {
             const posData = await this.ctx.service.pos.getAllDataByCondition({ where: {tid: tender_id }});
             if (this._checkFieldsExist(fields, posFields.stage)) {
@@ -385,6 +389,8 @@ class ReportMemoryMaterial {
 
     async getMaterialStage(tender_id, material_order, fields) {
         const material = await this.ctx.service.material.getDataByCondition({tid: tender_id, order: material_order});
+        if (!material) return [];
+
         if (material.is_stage_self) {
             return await this.ctx.service.materialStage.getAllDataByCondition({ where: { mid: material.id } });
         } else {

+ 1 - 1
app/lib/rpt_data_analysis.js

@@ -1577,7 +1577,7 @@ const loadCooperationData = {
         if (!stageAuditAss || stageAuditAss.length === 0) return null;
         if (relaId.length > 0) {
             for (const id of relaId) {
-                const c = stageAuditAss.find(x => { return x.ass_ledger_id.indexOf(id) >= 0; });
+                const c = stageAuditAss.find(x => { return x.ass_ledger_id.indexOf(id + '') >= 0; });
                 if (c) return c;
             }
             return null;

+ 2 - 2
app/lib/sum_load.js

@@ -397,13 +397,13 @@ class gatherStageGclTree extends loadGclBaseTree {
     getUpdateData() {
         const result = { update: [], errors: [], qc_detail: [] };
         for (const bn of this.baseNodes) {
-            if (!this.cover && !bn.is_import && !bn.contract_qty && !bn.qc_qty && !bn.contract_tp) continue;
+            if (!this.cover && !bn.is_import && !bn.contract_qty && !bn.qc_qty && !bn.contract_tp && !bn.qc_minus_qty) continue;
 
             if (!bn.is_import && bn.org_qc_qty !== 0 && bn.qc_qty !== 0) {
                 result.errors.push({ b_code: bn.b_code, name: bn.name, unit: bn.unit, qc_qty: bn.qc_qty, qc_minus_qty: bn.qc_minus_qty, ledger_id: bn.ledger_id, type: 'qc-conflict'});
                 continue;
             }
-            if (bn.is_import || this.cover || bn.contract_qty !== bn.org_contract_qty || bn.contract_tp !== bn.org_contract_tp || bn.qc_qty !== bn.org_qc_qty || bn.qc_minus_qty != bn.org_qc_minus_qty) {
+            if (bn.is_import || this.cover || bn.contract_qty !== bn.org_contract_qty || bn.contract_tp !== bn.org_contract_tp || bn.qc_qty !== bn.org_qc_qty || bn.qc_minus_qty !== bn.org_qc_minus_qty) {
                 let data = { lid: bn.id, contract_qty: bn.contract_qty, contract_tp: bn.contract_tp };
                 if (!bn.is_import && bn.org_qc_qty) {
                     data.qc_qty = bn.org_qc_qty;

+ 1 - 1
app/lib/tender_info.js

@@ -35,7 +35,7 @@ class TenderInfo {
         if (this.stage) return;
         this.stages = await this._getValidStages(this.tender.id);
         this.stage = this.stages[0];
-        if (this.stage) await this.ctx.service.stage.doCheckStage(this.stage);
+        if (this.stage) await this.ctx.service.stage.doCheckStage(this.stage, this.ctx.session.sessionUser.is_admin);
     }
 
     async _getStageBillsData () {

+ 45 - 59
app/middleware/stage_check.js

@@ -68,6 +68,7 @@ module.exports = options => {
             const accountId = this.session.sessionUser.accountId,
                 auditorIds = _.map(stage.auditors, 'aid');
             let auditAssists = yield this.service.stageAuditAss.getData(stage);
+            // 过滤无效的协审人
             auditAssists = auditAssists.filter(x => {
                 return x.user_id === stage.user_id || auditorIds.indexOf(x.user_id) >= 0;
             });
@@ -78,20 +79,61 @@ module.exports = options => {
                 shareIds = [];
             stage.users = stage.status === status.uncheck ? [stage.user_id, ...userAssistIds] : [stage.user_id, ...userAssistIds, ...auditorIds, ...auditAssistIds];
             stage.relaAssists = auditAssists.filter(x => { return x.user_id === accountId });
-            if (stage.status === status.uncheck || stage.status === status.checkNo) {
+            if (stage.status === status.uncheck) {
                 stage.readOnly = accountId !== stage.user_id && userAssistIds.indexOf(accountId) < 0;
-                if (!stage.readOnly) stage.assist = stage.userAssists.find(x => { return x.ass_user_id === accountId; });
+                if (!stage.readOnly) {
+                    stage.assist = stage.userAssists.find(x => { return x.ass_user_id === accountId; });
+                }
+                stage.curTimes = stage.times;
+                stage.curOrder = 0;
+            } else if (stage.status === status.checkNo) {
+                stage.readOnly = accountId !== stage.user_id && userAssistIds.indexOf(accountId) < 0;
+                const checkNoAudit = yield this.service.stageAudit.getDataByCondition({
+                    sid: stage.id, times: stage.times - 1, status: status.checkNo,
+                });
+                if (!stage.readOnly) {
+                    stage.assist = stage.userAssists.find(x => { return x.ass_user_id === accountId; });
+                    stage.curTimes = stage.times;
+                    stage.curOrder = 0;
+                } else {
+                    stage.curTimes = stage.times - 1;
+                    stage.curOrder = checkNoAudit.order;
+                }
             } else if (stage.status === status.checked) {
                 stage.readOnly = true;
+                stage.curTimes = stage.times;
+                stage.curOrder = _.max(_.map(stage.auditors, 'order'));
             } else {
                 const ass = stage.auditAssists.find(x => { return x.user_id === stage.curAuditor.aid && x.ass_user_id === accountId; });
                 stage.readOnly = stage.curAuditor.aid !== accountId && !ass;
-                if (!stage.readOnly) stage.assist = ass;
+                stage.curTimes = stage.times;
+                if (!stage.readOnly) {
+                    stage.assist = ass;
+                    stage.curOrder = stage.curAuditor.order;
+                } else {
+                    stage.curOrder = stage.curAuditor.order - 1;
+                }
             }
             if (stage.readOnly) {
                 stage.assist = accountId === stage.user_id || auditorIds.indexOf(accountId) >= 0 ? null : auditAssists.find(x => { return x.ass_user_id === accountId});
             }
 
+            const permission = this.session.sessionUser.permission;
+            if (stage.users.indexOf(accountId) >= 0) {
+                stage.filePermission = true;
+            } else {
+                if (shareIds.indexOf(accountId) !== -1 || (permission !== null && permission.tender !== undefined && permission.tender.indexOf('2') !== -1)) {// 分享人
+                    if (stage.status === status.uncheck) {
+                        throw '您无权查看该数据';
+                    }
+                    stage.filePermission = false;
+                } else if (this.tender.isTourist || this.session.sessionUser.is_admin) {
+                    stage.filePermission = this.tender.touristPermission.file || auditorIds.indexOf(accountId) !== -1;
+                } else {
+                    throw '您无权查看该数据';
+                }
+            }
+
             // 获取当前审批人的上一个审批人,判断是否是当前登录人,并赋予撤回功能,(当审批人存在有审批过时,上一人不允许再撤回)
             stage.cancancel = 0;
             if (stage.status !== status.checked && stage.status !== status.uncheck) {
@@ -123,62 +165,6 @@ module.exports = options => {
                 }
             }
 
-            const permission = this.session.sessionUser.permission;
-            if (accountId === stage.user_id || userAssistIds.indexOf(accountId) >= 0) { // 原报
-                stage.curTimes = stage.times;
-                if (stage.status === status.uncheck || stage.status === status.checkNo) {
-                    stage.curOrder = 0;
-                } else if (stage.status === status.checked) {
-                    stage.curOrder = _.max(_.map(stage.auditors, 'order'));
-                } else {
-                    stage.curOrder = stage.curAuditor.aid === accountId ? stage.curAuditor.order : stage.curAuditor.order - 1;
-                }
-                stage.filePermission = true;
-            } else if (auditorIds.indexOf(accountId) !== -1 || auditAssistIds.indexOf(accountId) >= 0) { // 审批人/协审
-                if (stage.status === status.uncheck) {
-                    throw '您无权查看该数据';
-                }
-                stage.curTimes = stage.status === status.checkNo ? stage.times - 1 : stage.times;
-                if (stage.status === status.checked) {
-                    stage.curOrder = _.max(_.map(stage.auditors, 'order'));
-                } else if (stage.status === status.checkNo) {
-                    const audit = yield this.service.stageAudit.getDataByCondition({
-                        sid: stage.id, times: stage.times - 1, status: status.checkNo,
-                    });
-                    stage.curOrder = audit.order;
-                } else {
-                    stage.curOrder = accountId === stage.curAuditor.aid ? stage.curAuditor.order : stage.curAuditor.order - 1;
-                }
-                stage.filePermission = true;
-            } else if (shareIds.indexOf(accountId) !== -1 || (permission !== null && permission.tender !== undefined && permission.tender.indexOf('2') !== -1)) { // 分享人
-                if (stage.status === status.uncheck) {
-                    throw '您无权查看该数据';
-                }
-                stage.readOnly = true;
-                stage.curTimes = stage.status === status.checkNo ? stage.times - 1 : stage.times;
-                if (stage.status === status.checkNo) {
-                    const audit = yield this.service.stageAudit.getDataByCondition({
-                        sid: stage.id, times: stage.times - 1, status: status.checkNo,
-                    });
-                    stage.curOrder = audit.order;
-                } else {
-                    stage.curOrder = stage.status === status.checked ? _.max(_.map(stage.auditors, 'order')) : stage.curAuditor.order - 1;
-                }
-                stage.filePermission = false;
-            } else if (this.tender.isTourist || this.session.sessionUser.is_admin) {
-                stage.curTimes = stage.times;
-                if (stage.status === status.uncheck || stage.status === status.checkNo) {
-                    stage.curOrder = 0;
-                } else if (stage.status === status.checked) {
-                    stage.curOrder = _.max(_.map(stage.auditors, 'order'));
-                } else {
-                    stage.curOrder = stage.curAuditor.order;
-                }
-                stage.filePermission = this.tender.touristPermission.file || auditorIds.indexOf(accountId) !== -1;
-            } else { // 其他不可见
-                throw '您无权查看该数据';
-            }
-
             const lastRevise = yield this.service.ledgerRevise.getLastestRevise(this.tender.id);
             stage.revising = (lastRevise && lastRevise.status !== reviseStatus.checked) || false;
             this.stage = stage;

+ 0 - 1
app/middleware/tender_check.js

@@ -117,7 +117,6 @@ module.exports = options => {
             tender.schedule_permission = schedule_permission;
             yield next;
         } catch (err) {
-            console.log(err);
             // 输出错误到日志
             if (err.stack) {
                 this.logger.error(err);

+ 4 - 0
app/public/js/change_information.js

@@ -486,6 +486,7 @@ $(document).ready(() => {
             xmjSpread.refresh();
             const width = (($('#right-view').width()/$('#right-view').parent('div').width())*100).toFixed();
             setLocalCache('change_information_width', width);
+            $('#left-header').css('min-width', (100 - parseFloat(getLocalCache('change_information_width'))) + '%');
         }
     });
 
@@ -493,8 +494,11 @@ $(document).ready(() => {
     if (getLocalCache('change_information_width')) {
         $('#left-view').css('width', (100 - parseFloat(getLocalCache('change_information_width'))) + '%');
         $('#right-view').css('width', getLocalCache('change_information_width') + '%');
+        $('#left-header').css('min-width', (100 - parseFloat(getLocalCache('change_information_width'))) + '%');
         changeSpread.refresh();
         xmjSpread.refresh();
+    } else {
+        $('#left-header').css('min-width', '33.33%');
     }
 });
 

+ 1 - 1
app/public/js/ledger_gather.js

@@ -238,7 +238,7 @@ $(document).ready(() => {
         const tab = $(this), tabPanel = $(tab.attr('content'));
         if (!tab.hasClass('active')) {
             $('a', '#side-menu').removeClass('active');
-            $('.tab-content .tab-pane.active').removeClass('active');
+            $('#right-view .tab-content .tab-pane.active').removeClass('active');
             tab.addClass('active');
             tabPanel.addClass('active');
             showTools(tab.hasClass('active'));

+ 2 - 3
app/public/js/material_checklist.js

@@ -1147,6 +1147,7 @@ $(document).ready(() => {
                 const needPushTree = [];
                 // 分析materialCheckList和tree,找出相同的清单并插入对应不存在的工料
                 for (const t of tree) {
+                    if(t.children.length === 0) continue;
                     const order = _.findIndex(gclGatherData, { b_code: t.b_code, name: t.name, unit: t.unit, unit_price: t.unit_price ? parseFloat(t.unit_price) : null });
                     const mlOrder = _.findIndex(materialChecklistData, { b_code: t.b_code, name: t.name, unit: t.unit, unit_price: t.unit_price ? parseFloat(t.unit_price) : null });
                     if (mlOrder === -1 && order !== -1 && _.findIndex(pushChecklist, { b_code: t.b_code, name: t.name, unit: t.unit, unit_price: t.unit_price ? parseFloat(t.unit_price) : null}) === -1) {
@@ -1175,7 +1176,6 @@ $(document).ready(() => {
                     //     }
                     // }
                 }
-                console.log(pushChecklist, pushBillsData);
                 if (needPushTree.length === 0) {
                     throw '不存在需要导入的工料清单含量';
                 }
@@ -1276,7 +1276,6 @@ $(document).ready(() => {
     }
 
     async function pushListData(tree = []) {
-        console.log(tree);
         if (tree.length > 0) {
             for (const [i,t] of tree.entries()) {
                 $('#list-detail').find('b').text(t.b_code);
@@ -1294,7 +1293,7 @@ $(document).ready(() => {
                             // toastr.warning('已保留6位小数');
                             mb.quantity = ZhCalc.round(num, 6);
                         }
-                        mbList.push({ id: mbInfo.id, quantity: mb.quantity });
+                        mbList.push({ id: mbInfo.id, quantity: mb.quantity ? mb.quantity : 0 });
                     }
                 }
                 if (mbList.length === 0) {

+ 2 - 6
app/public/js/revise_price.js

@@ -80,12 +80,8 @@ $(document).ready(() => {
         font: '12px 微软雅黑',
         readOnly,
         getColor: function (sheet, data, row, col, defaultColor) {
-            if (!data || (data.rela_lid && data.rela_cid)) return '#f5deb3';
-
-            const samePrice = sheet.zh_data.find(x => {
-                return x.b_code === data.b_code && x.name === data.name && x.unit === data.unit && x.org_price === data.org_price;
-            });
-            return samePrice ? defaultColor : '#f5deb3';
+            if (!data) return defaultColor;
+            if (data.rela_lid && data.rela_cid) return '#f5deb3';
         }
     };
     const priceBwSpreadSetting = {

+ 1 - 0
app/public/js/se_bonus.js

@@ -267,6 +267,7 @@ $(document).ready(() => {
                 });
             }
             this.resortData();
+            this.refreshDisplay();
         }
         getCurStageNewOrder() {
             const cur = this.data.filter(function (x) {

+ 209 - 0
app/public/js/shares/batch_import.js

@@ -0,0 +1,209 @@
+const BatchImportStageGcl = function (setting) {
+    const biObj = {
+        setting,
+        spread: null,
+        sheet: null,
+        tenderSourceTree: null,
+        history: [],
+        batchTree: null,
+        rebuildStageSelect: function () {
+            const getItems = function (data) {
+                const items = [];
+                if (data) {
+                    for (let i = 1; i <= data.stageCount; i++) {
+                        items.push({value: i, text: `第${i}期`});
+                    }
+                }
+                return items;
+            };
+            for (let i = 0; i < biObj.sheet.getRowCount(); i++) {
+                const data = biObj.batchTree.nodes[i];
+                if (!data.tid) continue;
+
+                const items = getItems(data);
+                const cellType = new spreadNS.CellTypes.ComboBox().itemHeight(10).editorValueType(spreadNS.CellTypes.EditorValueType.value).items(items);
+                biObj.sheet.getCell(i, 2).cellType(cellType);
+            }
+        },
+        trEditEnded: function (e, info) {
+            const data = SpreadJsObj.getSelectObject(info.sheet);
+            const col = info.sheet.zh_setting.cols[info.col];
+            data[col.field] = info.sheet.getValue(info.row, info.col);
+        },
+        reloadBatchTree() {
+            this.batchTree.clearDatas();
+            for (const h of this.history) {
+                if (!h.ledger_node) continue;
+
+                const ledgerData = { lid: h.lid, ledger_id: h.ledger_node.ledger_id, code: h.ledger_node.code, name: h.ledger_node.name, ledger_node: h.ledger_node };
+                const batchNode = this.batchTree.addNode(ledgerData, null);
+                for (const t of h.tenders) {
+                    const tenderData = JSON.parse(JSON.stringify(t));
+                    const tender = this.tenderSourceTree.nodes.find(y => { return y.tid === t.tid });
+                    tenderData.stageCount = tender.stageCount;
+                    this.batchTree.addNode(tenderData, batchNode);
+                }
+            }
+            this.batchTree.sortTreeNode(true);
+        },
+        loadHistory: function () {
+            if (biObj.batching) return;
+
+            biObj.tender_id = biObj.setting.stageTree.nodes[0].tender_id;
+            postData('/list/load', {type: 'stageBatch', tid: biObj.tender_id}, data => {
+                biObj.history = data.history || [];
+                // 屏蔽自己
+                const curIndex = data.tenders.findIndex(x => { return x.id === biObj.tender_id });
+                if (curIndex >= 0) data.tenders.splice(curIndex, 1);
+                biObj.tenderSourceTree = Tender2Tree.convert(data.category, data.tenders, data.ledgerAuditConst, data.stageAuditConst);
+                for (const h of biObj.history) {
+                    h.ledger_order = biObj.setting.stageTree.nodes.findIndex(x => { return x.id === h.lid; });
+                    h.ledger_node = h.ledger_order >= 0 ? biObj.setting.stageTree.nodes[h.ledger_order] : null;
+                    if (h.tenders) h.tenders = h.tenders.filter(x => { return biObj.tenderSourceTree.nodes.find(y => { return x.tid === y.tid; })});
+                }
+                biObj.history.sort((x, y) => { return x.ledger_order - y.ledger_order; });
+                biObj.reloadBatchTree();
+                SpreadJsObj.loadSheetData(biObj.sheet, SpreadJsObj.DataType.Tree, biObj.batchTree);
+                biObj.rebuildStageSelect();
+            });
+        },
+        initBatchImport: function () {
+            if (this.spread) return;
+
+            this.spread = SpreadJsObj.createNewSpread($('#bi-spread')[0]);
+            this.sheet = this.spread.getActiveSheet();
+            SpreadJsObj.initSheet(this.sheet, {
+                cols: [
+                    // {title: '选择', field: 'selected', hAlign: 1, width: 40, formatter: '@', cellType: 'checkbox'},
+                    {title: '编号', field: 'code', hAlign: 0, width: 180, formatter: '@', cellType: 'tree'},
+                    {title: '名称/引用标段', field: 'name', hAlign: 0, width: 180, formatter: '@'},
+                    {title: '可选期', field: 'stage', hAlign: 1, width: 60, formatter: '@'},
+                    // {title: '覆盖数据', field: 'is_cover', hAlign: 1, width: 60, cellType: 'checkbox'},
+                    {title: '状态', field: 'status', hAlign: 1, width: 60, formatter: '@'},
+                    {title: '错误信息', field: 'error', hAlign: 1, width: 60, formatter: '@'},
+                ],
+                emptyRows: 0,
+                headRows: 1,
+                headRowHeight: [32],
+                defaultRowHeight: 21,
+                headerFont: '12px 微软雅黑',
+                font: '12px 微软雅黑',
+                selectedBackColor: '#fffacd',
+            });
+            this.spread.bind(spreadNS.Events.EditEnded, biObj.trEditEnded);
+
+            this.batchTree = createNewPathTree('gather', {
+                id: 'id',
+                pid: 'pid',
+                order: 'order',
+                level: 'level',
+                rootId: -1,
+                fullPath: 'full_path',
+            });
+        },
+        checkErrors: function () {
+            const hasError = this.batchTree.children.findIndex(x => { return x.error > 0; }) >= 0;
+            if (hasError) {
+                $('#bi-download-error').show();
+            } else {
+                $('#bi-download-error').hide();
+            }
+        },
+        importStageGcl: async function (node, cover) {
+            const updateData = { lid: node.lid, type: 'stage', cover, tenders: [] };
+            for (const tender of node.children) {
+                updateData.tenders.push({ tid: tender.tid, name: tender.name, stageCount: tender.stageCount, stage: tender.stage });
+            }
+
+            const result = await postDataAsync(window.location.pathname + '/sumLoad', updateData);
+            biObj.setting.afterLoad(result, node.ledger_node);
+            node.errors = result.sumLoadHis.errors;
+            node.error = node.errors ? node.errors.length : 0;
+        },
+        batchImport: async function () {
+            $('#bi-start')[0].disabled = true;
+            biObj.batching = true;
+            const cover = $('#bi-cover')[0].checked;
+            for (const node of this.batchTree.children) {
+                if (!node.children || node.children.length === 0) continue;
+                const row = this.batchTree.getNodeIndex(node);
+                try {
+                    node.status = '开始导入';
+                    SpreadJsObj.reLoadRowData(biObj.sheet, row);
+                    await biObj.importStageGcl(node, cover);
+                    node.status = '导入完成';
+                    SpreadJsObj.reLoadRowData(biObj.sheet, row);
+                } catch(err) {
+                    console.log(err);
+                    node.status = '导入失败';
+                    SpreadJsObj.reLoadRowData(biObj.sheet, row);
+                }
+            }
+            biObj.batching = false;
+            $('#bi-start')[0].disabled = false;
+            biObj.checkErrors();
+        },
+        downloadErrors: function () {
+            const errorType = {
+                less: '数量变少',
+                miss: '找不到清单',
+                'qc-conflict': '变更冲突(已调用变更令)'
+            };
+            // const setting = {
+            //     header: ['清单编号', '清单名称','单位', '合同数量', '变更数量', '错误类型'],
+            //     width: [80, 200, 60, 80, 80, 180],
+            //     hAlign: ['left', 'left', 'center', 'right', 'right', 'left'],
+            // };
+            // const sheets = [];
+            // for (const node of this.batchTree.children) {
+            //     if (node.error > 0) {
+            //         sheets.push({ name: node.code, setting, data: node.errors.map(x => {
+            //             return [x.b_code, x.name, x.unit, x.qty, x.qc_qty, errorType[x.type]]; })
+            //         });
+            //     }
+            // }
+            // XLSXObj.exportXlsxSheets(sheets, '批量导入错误.xlsx');
+            const setting = {
+                cols: [
+                    {title: '清单编号', field: 'b_code', hAlign: 0, width: 80, formatter: '@'},
+                    {title: '清单名称', field: 'name', hAlign: 0, width: 180, formatter: '@'},
+                    {title: '单位', field: 'unit', hAlign: 1, width: 60, formatter: '@'},
+                    {title: '合同数量', field: 'qty', hAlign: 2, width: 80, formatter: '@'},
+                    {title: '变更数量', field: 'qc_qty', hAlign: 2, width: 80, formatter: '@'},
+                    {title: '错误类型', field: 'type', hAlign: 0, width: 150, formatter: '@', getValue(data) { return errorType[data.type]; }},
+                ],
+                emptyRows: 0,
+                headRows: 1,
+                headRowHeight: [32],
+                defaultRowHeight: 21,
+                headerFont: '12px 微软雅黑',
+                font: '12px 微软雅黑',
+            };
+            const sheets = [];
+            for (const node of this.batchTree.children) {
+                if (node.error > 0) {
+                    sheets.push({ name: node.code, setting, data: node.errors });
+                }
+            }
+            SpreadExcelObj.exportSimpleXlsxSheets(sheets, '批量导入错误.xlsx');
+        }
+    };
+
+    $('#batch-import').on('shown.bs.modal', () => {
+        biObj.initBatchImport();
+        biObj.loadHistory();
+    });
+
+    $('#bi-start').click(function () {
+        biObj.batchImport();
+    });
+    $('#bi-download-error').click(function () {
+        biObj.downloadErrors();
+    });
+
+    const show = function () {
+        $('#batch-import').modal('show');
+    };
+
+    return { show }
+};

+ 62 - 22
app/public/js/shares/export_excel.js

@@ -22,22 +22,7 @@ const SpreadExcelObj = (function() {
         document.body.removeChild(div);
     };
 
-    const exportSpread2XlsxWithHeader = function (spread, file) {
-        spread.getActiveSheet().options.isProtected = false;
-        const excelIo = new GC.Spread.Excel.IO();
-        const sJson = JSON.stringify(spread.toJSON({columnHeadersAsFrozenRows: true, rowHeadersAsFrozenColumns: true}));
-        excelIo.save(sJson, function(blob) {
-            saveAs(blob, file);
-        });
-        spread.getActiveSheet().options.isProtected = true;
-    };
-
-    const exportSimpleXlsxSheet = function (setting, data, file) {
-        const div = _createHideSpread();
-
-        const spread = SpreadJsObj.createNewSpread(div, true);
-        const sheet = spread.getActiveSheet();
-
+    const exportSimpleXlsxSheetData = function (sheet, setting, data) {
         SpreadJsObj.beginMassOperation(sheet);
         sheet.options.isProtected = false;
         sheet.setColumnCount(setting.cols.length);
@@ -71,7 +56,7 @@ const SpreadExcelObj = (function() {
                 const cell = sheet.getCell(curRow, iCol);
                 const col = setting.cols[iCol];
                 if (col.field !== '' && d[col.field]) {
-                    cell.value(d[col.field]);
+                    cell.value(col.getValue ? col.getValue(d) : d[col.field]);
                     if (typeof d[col.field] === 'string') {
                         cell.formatter('@');
                     }
@@ -85,6 +70,35 @@ const SpreadExcelObj = (function() {
             }
         }
         SpreadJsObj.endMassOperation(sheet);
+    };
+
+    const exportSimpleXlsxSheet = function (setting, data, file) {
+        const div = _createHideSpread();
+
+        const spread = SpreadJsObj.createNewSpread(div, true);
+        const sheet = spread.getActiveSheet();
+        exportSimpleXlsxSheetData(sheet, setting, data);
+
+        const excelIo = new GC.Spread.Excel.IO();
+        const sJson = JSON.stringify(spread.toJSON());
+        excelIo.save(sJson, function(blob) {
+            saveAs(blob, file);
+            _removeHideSpread(div);
+        });
+    };
+
+    const exportSimpleXlsxSheets = function (sheets, file) {
+        if (!sheets || sheets.length === 0) return;
+
+        const div = _createHideSpread();
+        const spread = new spreadNS.Workbook(div, {sheetCount: sheets.length});
+
+        for (const [i, sheetData] of sheets.entries()) {
+            const sheet = spread.getSheet(i);
+            sheet.name(sheetData.name);
+            exportSimpleXlsxSheetData(sheet, sheetData.setting, sheetData.data);
+
+        }
 
         const excelIo = new GC.Spread.Excel.IO();
         const sJson = JSON.stringify(spread.toJSON());
@@ -94,14 +108,24 @@ const SpreadExcelObj = (function() {
         });
     };
 
-    return {exportSimpleXlsxSheet, exportSpread2XlsxWithHeader}
+    const exportSpread2XlsxWithHeader = function (spread, file) {
+        spread.getActiveSheet().options.isProtected = false;
+        const excelIo = new GC.Spread.Excel.IO();
+        const sJson = JSON.stringify(spread.toJSON({columnHeadersAsFrozenRows: true, rowHeadersAsFrozenColumns: true}));
+        excelIo.save(sJson, function(blob) {
+            saveAs(blob, file);
+        });
+        spread.getActiveSheet().options.isProtected = true;
+    };
+
+    return {exportSimpleXlsxSheet, exportSpread2XlsxWithHeader, exportSimpleXlsxSheets}
 })();
 
 const XLSXObj = (function () {
-    const exportXlsxSheet = function (setting, data, file) {
+    const transportSheetData = function (setting, data) {
         const headerStyle = {
             font: { sz: 10, bold: true },
-            alignment: {horizontal: 'center'},
+            alignment: { horizontal: 'center' },
         };
         const sHeader = setting.header
             .map((v, i) => Object.assign({}, {v: v, s: headerStyle, position: String.fromCharCode(65+i) + 1 }))
@@ -118,6 +142,11 @@ const XLSXObj = (function () {
         const result = Object.assign({}, output,
             {'!ref': outputPos[0] + ':' + outputPos[outputPos.length - 1]},
             {'!cols': setting.width.map((w) => Object.assign({}, {wpx: w}))});
+        return result;
+    };
+
+    const exportXlsxSheet = function (setting, data, file) {
+        const result = transportSheetData(setting, data);
         const xlsxData = {
             SheetNames: ['Sheet1'],
             Sheets: {
@@ -128,5 +157,16 @@ const XLSXObj = (function () {
         saveAs(blob, file);
     };
 
-    return {exportXlsxSheet}
-});
+    const exportXlsxSheets = function (sheets, file) {
+        const xlsxData = { SheetNames: [], Sheets: {} };
+        for (const sheet of sheets) {
+            const xlsxSheet = transportSheetData(sheet.setting, sheet.data);
+            xlsxData.SheetNames.push(sheet.name);
+            xlsxData.Sheets[sheet.name] = xlsxSheet;
+        }
+        const blob = xlsxUtils.format2Blob(xlsxData);
+        saveAs(blob, file);
+    };
+
+    return { exportXlsxSheet, exportXlsxSheets }
+})();

+ 27 - 0
app/public/js/stage.js

@@ -1479,6 +1479,23 @@ $(document).ready(() => {
             if (checkedChanges) checkedChanges.reloadChangeData();
         }
     });
+    const batchImport = BatchImportStageGcl({
+        stageTree,
+        afterLoad: function (result, select) {
+            const nodes = stageTree.loadPostStageData(result);
+            const posterity = stageTree.getPosterity(select);
+            for (const p of posterity) {
+                p.is_import = !!result.import_change.data.find(x => { return x.lid === p.id });
+            }
+            stageTreeSpreadObj.refreshTreeNodes(slSpread.getActiveSheet(), nodes);
+            if (detail) {
+                detail.loadStageLedgerUpdateData(result, nodes);
+            } else {
+                stageIm.loadUpdateLedgerData(result, nodes);
+            }
+            if (checkedChanges) checkedChanges.reloadChangeData();
+        }
+    });
     $.contextMenu({
         selector: '#stage-ledger',
         build: function ($trigger, e) {
@@ -1578,6 +1595,16 @@ $(document).ready(() => {
                     tenderSelect.showSelect(SpreadJsObj.getSelectObject(slSpread.getActiveSheet()));
                 }
             },
+            batchImportStageGcl: {
+                name: '批量导入(其他标段)工程量清单计量数据',
+                icon: 'fa-link',
+                disable: function (key, opt) {
+                    return readOnly;
+                },
+                callback: function (key, opt){
+                    batchImport.show();
+                }
+            },
             shoufangdanSpr: '---',
             shoufangdan: {
                 name: '生成收方单',

+ 1 - 5
app/public/js/stage_audit.js

@@ -380,11 +380,8 @@ $(document).ready(function () {
 
     // 比uid大的序号进行调整
     function updateOrder(aid, num = 1) {
-        console.log('hello');
         const index = _.findIndex(auditorList, { aid });
-        console.log(index, auditorList.length);
         for (let i = index;i < auditorList.length; i++) {
-            console.log(i,i+num, auditorList.length);
             $('#admin-edit-shenpi tbody').children('tr').eq(i).find('.shenpi-order').text(i+num);
         }
     }
@@ -404,7 +401,7 @@ $(document).ready(function () {
                 auditorshtml.push('<span class="pull-right">'+ transFormToChinese(index) +'审</span>');
             }
             auditorshtml.push('</li>');
-            if (data.status === auditConst.status.uncheck) {
+            if (data.status === sam_auditConst.status.uncheck) {
                 lastAuditorHtml += '<li class="timeline-list-item pb-2 is_uncheck">\n' +
                     '                                            <div class="timeline-item-date">\n' +
                     '                                                \n' +
@@ -427,7 +424,6 @@ $(document).ready(function () {
                     '                                        </li>';
             }
         }
-        console.log(lastAuditorHtml);
         $('.last-auditor-list .is_uncheck').remove();
         $('.last-auditor-list').append(lastAuditorHtml);
         $('.auditors-list').html(auditorshtml.join(''));

+ 13 - 0
app/public/report/js/jpc_output.js

@@ -471,6 +471,19 @@ let JpcCanvasOutput = {
                 };
                 img.onerror = function() {
                     console.log('cell.path error: ' + cell.path);
+                    const noCroimg = new Image();
+                    if (cell.path.indexOf(OSS_PATH) < 0 && cell.path[0] !== '/') {
+                        noCroimg.src = OSS_PATH + cell.path;
+                    } else {
+                        noCroimg.src = cell.path;
+                    }
+                    noCroimg.onload = function() {
+                        if (cell.signature_name.indexOf(JV.SIGNATURE_NAME_DUMMY) >= 0) {
+                            private_drawImage(cell, control, noCroimg,moveSignatureTool, (!!cell.isStamp), [1, 1, 1, 1]);
+                        } else {
+                            private_drawImage(cell, control, noCroimg,moveSignatureTool);
+                        }
+                    };
                 }
             }
         }

+ 2 - 0
app/public/report/js/rpt_main.js

@@ -879,6 +879,7 @@ let rptControlObj = {
                 } else {
                     params.needWaterMark = false;
                 }
+                params.outputType = 'Excel';
                 CommonAjax.postXsrfEx("/tender/report_api/getMultiReports", params, WAIT_TIME_EXPORT, true, getCookie('csrfToken_j'),
                     function(result){
                         $.bootstrapLoading.end();
@@ -1038,6 +1039,7 @@ let rptControlObj = {
                 } else {
                     params.needWaterMark = false;
                 }
+                params.outputType = 'PDF';
                 CommonAjax.postXsrfEx("/tender/report_api/getMultiReports", params, WAIT_TIME_EXPORT, true, getCookie('csrfToken_j'),
                     async function(result){
                         // closeWaitingView();

+ 3 - 1
app/service/change_ledger.js

@@ -51,7 +51,7 @@ module.exports = app => {
                 level: 'level',
                 isLeaf: 'is_leaf',
                 fullPath: 'full_path',
-                keyPre: 'change_ledger_maxLid:',
+                keyPre: 'change_ledger_maxLid2:', // 换个名称,防止缓存导致旧数据出问题
                 uuid: true,
             };
             super(ctx, setting, 'pos');
@@ -153,6 +153,8 @@ module.exports = app => {
                         maxId = queryResult2.max_id || 0;
                     }
                 }
+                const oldCacheKey = 'change_ledger_maxLid:' + mid;
+                this.cache.del(oldCacheKey);
                 this.cache.set(cacheKey, maxId, 'EX', this.ctx.app.config.cacheTime);
             }
             return maxId;

+ 2 - 2
app/service/material_list.js

@@ -397,7 +397,7 @@ module.exports = app => {
         }
 
         async getMaterialStageData(tid, mid) {
-            const sql = 'SELECT ml.`id`, mb.`code`, mb.`name`, mb.`unit`, ml.`order`, ml.`quantity`, ml.`expr`, ml.`mb_id`, ml.`gcl_id`, ml.`xmj_id`, ml.`mx_id`, ml.`ms_id`, ml.`tid`, ml.`mid`, msb.m_spread, ml.ms_id, ms.sid, ms.order as s_order' +
+            const sql = 'SELECT ml.`id`, mb.`code`, mb.`name`, mb.`unit`, ml.`order`, ml.`quantity`, ml.`expr`, msb.id AS mb_id, ml.`gcl_id`, ml.`xmj_id`, ml.`mx_id`, ml.`ms_id`, ml.`tid`, ml.`mid`, msb.m_spread, ml.ms_id, ms.sid, ms.order as s_order' +
                 ' FROM ' + this.tableName + ' as ml' +
                 ' LEFT JOIN ' + this.ctx.service.materialBills.tableName + ' as mb ON ml.`mb_id` = mb.`id`' +
                 ' LEFT JOIN ' + this.ctx.service.materialStageBills.tableName + ' as msb ON ml.mb_id = msb.mb_id AND ml.ms_id = msb.ms_id' +
@@ -408,7 +408,7 @@ module.exports = app => {
         }
 
         async getPreMaterialStageData(tid, mid) {
-            const sql = 'SELECT ml.`id`, mb.`code`, mb.`name`, mb.`unit`, ml.`order`, ml.`quantity`, ml.`expr`, ml.`mb_id`, ml.`gcl_id`, ml.`xmj_id`, ml.`mx_id`, ml.`ms_id`, ml.`tid`, ml.`mid`, msb.m_spread, ml.ms_id, ms.sid, ms.order as s_order' +
+            const sql = 'SELECT ml.`id`, mb.`code`, mb.`name`, mb.`unit`, ml.`order`, ml.`quantity`, ml.`expr`, msb.id AS mb_id, ml.`gcl_id`, ml.`xmj_id`, ml.`mx_id`, ml.`ms_id`, ml.`tid`, ml.`mid`, msb.m_spread, ml.ms_id, ms.sid, ms.order as s_order' +
                 ' FROM ' + this.tableName + ' as ml' +
                 ' LEFT JOIN ' + this.ctx.service.materialBills.tableName + ' as mb ON ml.`mb_id` = mb.`id`' +
                 ' LEFT JOIN ' + this.ctx.service.materialStageBills.tableName + ' as msb ON ml.`mb_id` = msb.mb_id AND ml.ms_id = msb.ms_id And ml.mid = msb.mid' +

+ 39 - 49
app/service/stage.js

@@ -93,71 +93,61 @@ module.exports = app => {
             await this.loadStageUser(stage);
 
             const accountId = this.ctx.session.sessionUser.accountId, shareIds = [];
-            if (stage.status === status.uncheck || stage.status === status.checkNo) {
+            const isTenderTourist = await this.service.tenderTourist.getDataByCondition({ tid: stage.tid, user_id: accountId });
+            const permission = this.ctx.session.sessionUser.permission;
+            if (stage.status === status.uncheck) {
+                stage.readOnly = accountId !== stage.user_id && stage.userAssistIds.indexOf(accountId) < 0;
+                if (!stage.readOnly) {
+                    stage.assist = stage.userAssists.find(x => { return x.ass_user_id === accountId; });
+                }
+                stage.curTimes = stage.times;
+                stage.curOrder = 0;
+            } else if (stage.status === status.checkNo) {
                 stage.readOnly = accountId !== stage.user_id && stage.userAssistIds.indexOf(accountId) < 0;
-                if (!stage.readOnly) stage.assist = stage.userAssists.find(x => { return x.ass_user_id === accountId; });
+                const checkNoAudit = await this.service.stageAudit.getDataByCondition({
+                    sid: stage.id, times: stage.times - 1, status: status.checkNo,
+                });
+                if (!stage.readOnly) {
+                    stage.assist = stage.userAssists.find(x => { return x.ass_user_id === accountId; });
+                    stage.curTimes = stage.times;
+                    stage.curOrder = 0;
+                } else {
+                    stage.curTimes = stage.times - 1;
+                    stage.curOrder = checkNoAudit.order;
+                }
             } else if (stage.status === status.checked) {
                 stage.readOnly = true;
+                stage.curTimes = stage.times;
+                stage.curOrder = _.max(_.map(stage.auditors, 'order'));
             } else {
                 const ass = stage.auditAssists.find(x => { return x.user_id === stage.curAuditor.aid && x.ass_user_id === accountId; });
                 stage.readOnly = stage.curAuditor.aid !== accountId && !ass;
-                if (!stage.readOnly) stage.assist = ass;
+                stage.curTimes = stage.times;
+                if (!stage.readOnly) {
+                    stage.assist = ass;
+                    stage.curOrder = stage.curAuditor.order;
+                } else {
+                    stage.curOrder = stage.curAuditor.order - 1;
+                }
             }
             if (stage.readOnly) {
                 stage.assist = accountId === stage.user_id || stage.auditorIds.indexOf(accountId) >= 0
                     ? null
                     : stage.assists.find(x => { return x.ass_user_id === accountId});
             }
-            const isTenderTourist = await this.service.tenderTourist.getDataByCondition({ tid: stage.tid, user_id: accountId });
-            const permission = this.ctx.session.sessionUser.permission;
-            if (accountId === stage.user_id || stage.userAssistIds.indexOf(accountId) >= 0) { // 原报
-                stage.curTimes = stage.times;
-                if (stage.status === status.uncheck || stage.status === status.checkNo) {
-                    stage.curOrder = 0;
-                } else if (stage.status === status.checked) {
-                    stage.curOrder = this._.max(this._.map(stage.auditors, 'order'));
-                } else {
-                    stage.curOrder = stage.curAuditor.aid === accountId ? stage.curAuditor.order : stage.curAuditor.order - 1;
-                }
+            if (stage.users.indexOf(accountId) >= 0) {
                 stage.filePermission = true;
-            } else if (!!isTenderTourist || force) { // 游客
-                stage.readOnly = true;
-                stage.curTimes = stage.times;
-                if (stage.status === status.uncheck || stage.status === status.checkNo) {
-                    stage.curOrder = 0;
-                } else if (stage.status === status.checked) {
-                    stage.curOrder = this._.max(this._.map(stage.auditors, 'order'));
-                } else {
-                    stage.curOrder = stage.curAuditor.order;
-                }
-            } else if (stage.auditorIds.indexOf(accountId) >= 0 || stage.auditAssistIds.indexOf(accountId) >= 0) { // 审批人
-                if (stage.status === status.uncheck) throw '您无权查看该数据';
-                stage.curTimes = stage.status === status.checkNo ? stage.times - 1 : stage.times;
-                if (stage.status === status.checked) {
-                    stage.curOrder = this._.max(this._.map(stage.auditors, 'order'));
-                } else if (stage.status === status.checkNo) {
-                    const audit = await this.service.stageAudit.getDataByCondition({
-                        sid: stage.id, times: stage.times - 1, status: status.checkNo,
-                    });
-                    stage.curOrder = audit.order;
+            } else if (!!isTenderTourist || force) {
+                stage.filePermission = this.tender && this.tender.touristPermission ? this.tender.touristPermission.file : false;
+            } else {
+                if (shareIds.indexOf(accountId) !== -1 || (permission !== null && permission.tender !== undefined && permission.tender.indexOf('2') !== -1)) {// 分享人
+                    if (stage.status === status.uncheck) {
+                        throw '您无权查看该数据';
+                    }
+                    stage.filePermission = false;
                 } else {
-                    stage.curOrder = accountId === stage.curAuditor.aid ? stage.curAuditor.order : stage.curAuditor.order - 1;
-                }
-                stage.filePermission = true;
-            } else if (shareIds.indexOf(accountId) !== -1 || (permission !== null && permission.tender !== undefined && permission.tender.indexOf('2') !== -1)) { // 分享人
-                if (stage.status === status.uncheck) {
                     throw '您无权查看该数据';
                 }
-                stage.readOnly = true;
-                stage.curTimes = stage.status === status.checkNo ? stage.times - 1 : stage.times;
-                if (stage.status === status.checkNo) {
-                    const audit = await this.service.stageAudit.getDataByCondition({
-                        sid: stage.id, times: stage.times - 1, status: status.checkNo,
-                    });
-                    stage.curOrder = audit.order;
-                } else {
-                    stage.curOrder = stage.status === status.checked ? this._.max(this._.map(stage.auditors, 'order')) : stage.curAuditor.order - 1;
-                }
             }
 
             let time = stage.readOnly ? stage.cache_time_r : stage.cache_time_l;

+ 48 - 27
app/service/stage_audit.js

@@ -984,7 +984,7 @@ module.exports = app => {
          * @return {Promise<void>}
          */
         async checkCancel(stageId, times = 1) {
-            // 分3种情况,根据ctx.cancancel值判断:
+            // 分4种情况,根据ctx.cancancel值判断:
             // 1.原报发起撤回,当前流程删除,并回到待上报
             // 2.审批人撤回审批通过,增加流程,并回到它审批中
             // 3.审批人撤回审批退回上一人,并删除退回人,增加流程,并回到它审批中,并更新计量期状态为审批中
@@ -992,6 +992,8 @@ module.exports = app => {
             const transaction = await this.db.beginTransaction();
             const time = new Date();
             try {
+                await this._updateTender(transaction);
+                let newTimes, newOrder, newSaid, oldTimes, oldOrder, oldSaid = '';
                 if (this.ctx.stage.cancancel === 1) {
                     // 原报撤回,判断是否为多次,多次则为退回状态
                     // 整理当前流程审核人状态更新
@@ -1032,12 +1034,16 @@ module.exports = app => {
                     // 计算该审批人最终数据
                     await this.ctx.service.stagePay.calcAllStagePays(this.ctx.stage, transaction);
                     // 复制一份最新数据给下一人
+                    // 保留审批人数据,覆盖到原报中并删除该审批人合同支付数据
+                    await this.ctx.service.stagePay.deleteAuditStagePays(this.ctx.stage, this.ctx.stage.times, 0, transaction);
+                    await this.ctx.service.stagePay.copyAuditStagePays(this.ctx.stage, this.ctx.stage.times, 0, transaction, this.ctx.stage.times, 1);
                     await this.ctx.service.stagePay.deleteAuditStagePays(this.ctx.stage, this.ctx.stage.times, 1, transaction);
-                    await this.ctx.service.stageJgcl.updateHistory(this.ctx.stage, transaction);
-                    await this.ctx.service.stageBonus.updateHistory(this.ctx.stage, transaction);
-                    await this.ctx.service.stageOther.updateHistory(this.ctx.stage, transaction);
-                    await this.ctx.service.stageSafeProd.updateHistory(this.ctx.stage, transaction);
-                    await this.ctx.service.stageTempLand.updateHistory(this.ctx.stage, transaction);
+                    newTimes = this.ctx.stage.times;
+                    newOrder = 0;
+                    newSaid = this.ctx.stage.user_id;
+                    oldTimes = this.ctx.stage.times;
+                    oldOrder = 1;
+                    oldSaid = curAudit.aid;
                 } else if (this.ctx.stage.cancancel === 2) {
                     const tpData = await this.ctx.service.stageBills.getSumTotalPrice(this.ctx.stage);
                     // 整理当前流程审核人状态更新
@@ -1107,13 +1113,13 @@ module.exports = app => {
                     // 计算该审批人最终数据
                     await this.ctx.service.stagePay.calcAllStagePays(this.ctx.stage, transaction);
                     // 复制一份最新数据给下一人
-                    await this.ctx.service.stagePay.copyAuditStagePays(this.ctx.stage, this.ctx.stage.times, curAudit.order + 1, transaction);
-                    await this.ctx.service.stageJgcl.updateHistory(this.ctx.stage, transaction);
-                    await this.ctx.service.stageBonus.updateHistory(this.ctx.stage, transaction);
-                    await this.ctx.service.stageOther.updateHistory(this.ctx.stage, transaction);
-                    await this.ctx.service.stageSafeProd.updateHistory(this.ctx.stage, transaction);
-                    await this.ctx.service.stageTempLand.updateHistory(this.ctx.stage, transaction);
-
+                    await this.ctx.service.stagePay.copyAuditStagePays(this.ctx.stage, this.ctx.stage.times, curAudit.order + 1, transaction, this.ctx.stage.times, this.ctx.stage.curOrder + 1);
+                    newTimes = this.ctx.stage.times;
+                    newOrder = curAudit.order + 1;
+                    newSaid = preAudit.aid;
+                    oldTimes = this.ctx.stage.times;
+                    oldOrder = curAudit.order;
+                    oldSaid = curAudit.aid;
                     // 锁定本人数据,保留锁定数据相关确认状态
                     // await this.ctx.service.stageAuditAss.lockConfirm4CheckNoPre(this.ctx.stage, curAudit.aid, preAudit.aid, transaction);
                 } else if (this.ctx.stage.cancancel === 3) {
@@ -1186,12 +1192,14 @@ module.exports = app => {
                     // 计算该审批人最终数据
                     await this.ctx.service.stagePay.calcAllStagePays(this.ctx.stage, transaction);
                     // 复制一份最新数据给下一人
-                    await this.ctx.service.stagePay.copyAuditStagePays(this.ctx.stage, this.ctx.stage.times, curAudit.order + 1, transaction);
-                    await this.ctx.service.stageJgcl.updateHistory(this.ctx.stage, transaction);
-                    await this.ctx.service.stageBonus.updateHistory(this.ctx.stage, transaction);
-                    await this.ctx.service.stageOther.updateHistory(this.ctx.stage, transaction);
-                    await this.ctx.service.stageSafeProd.updateHistory(this.ctx.stage, transaction);
-                    await this.ctx.service.stageTempLand.updateHistory(this.ctx.stage, transaction);
+                    await this.ctx.service.stagePay.copyAuditStagePays(this.ctx.stage, this.ctx.stage.times, curAudit.order + 1, transaction, this.ctx.stage.times, this.ctx.stage.curOrder + 1);
+
+                    newTimes = this.ctx.stage.times;
+                    newOrder = curAudit.order + 1;
+                    newSaid = preAudit.aid;
+                    oldTimes = this.ctx.stage.times;
+                    oldOrder = curAudit.order;
+                    oldSaid = curAudit.aid;
 
                     // 锁定本人数据,保留锁定数据相关确认状态
                     // await this.ctx.service.stageAuditAss.lockConfirm4CheckNoPre(this.ctx.stage, curAudit.aid, preAudit.aid, transaction);
@@ -1235,7 +1243,7 @@ module.exports = app => {
                     // 计算并合同支付最终数据
                     const [yfPay, sfPay] = await this.ctx.service.stagePay.calcAllStagePays(this.ctx.stage, transaction);
                     this.ctx.stage.tp_history.push({
-                        times,
+                        times: times - 1,
                         order: curAudit.order,
                         contract_tp: tpData.contract_tp,
                         qc_tp: tpData.qc_tp,
@@ -1260,15 +1268,28 @@ module.exports = app => {
                     // 计算该审批人最终数据
                     await this.ctx.service.stagePay.calcAllStagePays(this.ctx.stage, transaction);
                     // 复制一份最新数据给下一人
+                    await this.ctx.service.stagePay.copyAuditStagePays(this.ctx.stage, this.ctx.stage.times - 1, curAudit.order + 1, transaction, this.ctx.stage.times, 0);
+                    await this.ctx.service.stagePay.copyAuditStagePays(this.ctx.stage, this.ctx.stage.times - 1, curAudit.order + 2, transaction, this.ctx.stage.times, 0);
                     await this.ctx.service.stagePay.deleteAuditStagePays(this.ctx.stage, this.ctx.stage.times, 0, transaction);
-                    await this.ctx.service.stagePay.copyAuditStagePays(this.ctx.stage, this.ctx.stage.times - 1, curAudit.order + 1, transaction);
-                    await this.ctx.service.stagePay.copyAuditStagePays(this.ctx.stage, this.ctx.stage.times - 1, curAudit.order + 2, transaction);
-                    await this.ctx.service.stageJgcl.updateHistory(this.ctx.stage, transaction);
-                    await this.ctx.service.stageBonus.updateHistory(this.ctx.stage, transaction);
-                    await this.ctx.service.stageOther.updateHistory(this.ctx.stage, transaction);
-                    await this.ctx.service.stageSafeProd.updateHistory(this.ctx.stage, transaction);
-                    await this.ctx.service.stageTempLand.updateHistory(this.ctx.stage, transaction);
+
+                    newTimes = this.ctx.stage.times - 1;
+                    newOrder = curAudit.order + 2;
+                    newSaid = curAudit.aid;
+                    oldTimes = this.ctx.stage.times;
+                    oldOrder = 0;
+                    oldSaid = this.ctx.stage.user_id;
                 }
+                // 先覆盖再删除
+                await this.ctx.service.stageBills.updateStageBills4CheckCancel(stageId, newSaid, newTimes, newOrder, oldSaid, oldTimes, oldOrder, transaction);
+                await this.ctx.service.stagePos.updateStagePos4CheckCancel(stageId, newSaid, newTimes, newOrder, oldSaid, oldTimes, oldOrder, transaction);
+                await this.ctx.service.stageDetail.updateStageDetail4CheckCancel(stageId, newTimes, newOrder, oldTimes, oldOrder, transaction);
+
+                await this.ctx.service.stageJgcl.updateHistory4CheckCancel(this.ctx.stage, newTimes, newOrder, transaction);
+                await this.ctx.service.stageBonus.updateHistory4CheckCancel(this.ctx.stage, newTimes, newOrder, transaction);
+                await this.ctx.service.stageOther.updateHistory4CheckCancel(this.ctx.stage, newTimes, newOrder, transaction);
+                await this.ctx.service.stageSafeProd.updateHistory4CheckCancel(this.ctx.stage, newTimes, newOrder, transaction);
+                await this.ctx.service.stageTempLand.updateHistory4CheckCancel(this.ctx.stage, newTimes, newOrder, transaction);
+
                 // 上报/审批 - 检查三方特殊推送
                 await this.ctx.service.specMsg.addStageMsg(transaction, this.ctx.session.sessionProject.id, this.ctx.stage, pushOperate.stage.flow);
                 await transaction.commit();

+ 6 - 1
app/service/stage_audit_ass.js

@@ -98,6 +98,9 @@ module.exports = app => {
             });
             // 审批人数据锁定
             const locking = await this.getAllDataByCondition({ where: { sid: stage.id, times: stage.curTimes, user_id: uid, confirm: 1 } });
+            locking.forEach(x => {
+                x.locked_ledger_id = x.ass_ledger_id.split(',');
+            });
             if (locking.length > 0) {
                 const updateLock = locking.map(x => { return { id: x.id, locked: 1 }; });
                 await transaction.updateRows(this.tableName, updateLock);
@@ -174,7 +177,9 @@ module.exports = app => {
             const sql = 'SELECT saa.tid, saa.sid, saa.times, saa.user_id, saa.ass_ledger_id, saa.ass_user_id, saa.name, saa.company, saa.role, pa.sign_path, pa.stamp_path' +
                 `   FROM ${this.tableName} saa LEFT JOIN ${this.ctx.service.projectAccount.tableName} pa ON saa.ass_user_id = pa.id` +
                 `   WHERE saa.sid = ? AND saa.times = ?`;
-            return this.db.query(sql, [sid, stimes]);
+            const result = await this.db.query(sql, [sid, stimes]);
+            result.forEach(x => { x.ass_ledger_id = x.ass_ledger_id ? x.ass_ledger_id.split(',') : []});
+            return result;
         }
     }
 

+ 21 - 0
app/service/stage_bills.js

@@ -126,6 +126,27 @@ module.exports = app => {
             return stageBills[0];
         }
 
+        async updateStageBills4CheckCancel(sid, newSaid, newTimes, newOrder, oldSaid, oldTimes, oldOrder, transaction) {
+            const oldSBLists = await this.getAllDataByCondition({ where: { sid, times: oldTimes, order: oldOrder } });
+            const newSBLists = await this.getAllDataByCondition({ where: { sid, times: newTimes, order: newOrder } });
+            const delidList = [];
+            for (const o of oldSBLists) {
+                const newSBInfo = this._.find(newSBLists, { lid: o.lid });
+                if (newSBInfo) {
+                    // 删除
+                    delidList.push(newSBInfo.id);
+                }
+            }
+            if (delidList.length > 0) await transaction.delete(this.tableName, { id: delidList });
+            if (oldSBLists.length > 0) {
+                await transaction.update(this.tableName, {
+                    said: newSaid,
+                    times: newTimes,
+                    order: newOrder,
+                }, { where: { id: this._.map(oldSBLists, 'id') } });
+            }
+        }
+
         async getStageUsedBills(tid, sid) {
             const sql = 'SELECT Bills.lid, ((not IsNull(Bills.contract_qty) and Bills.contract_qty <> 0) or (not IsNull(Bills.contract_tp) and Bills.contract_tp <> 0) or (not IsNull(Bills.qc_qty) and Bills.qc_qty <> 0) or (not IsNull(Bills.qc_tp) and Bills.qc_tp <> 0)) As used' +
                 '  FROM ' + this.tableName + ' As Bills ' +

+ 23 - 3
app/service/stage_bonus.js

@@ -34,9 +34,9 @@ module.exports = app => {
             }
         }
 
-        async getStageData(sid) {
+        async getStageData(sid, cancel = false) {
             const data = await this.getAllDataByCondition({where: { sid: sid }});
-            if (this.ctx.stage && this.ctx.stage.readOnly && !this.ctx.tender.isTourist && this.ctx.stage.status !== auditConst.status.checked) {
+            if (!cancel && this.ctx.stage && this.ctx.stage.readOnly && !this.ctx.tender.isTourist && this.ctx.stage.status !== auditConst.status.checked) {
                 for (const d of data) {
                     const his = d.shistory ? JSON.parse(d.shistory) : [];
                     const h = this.ctx.helper._.find(his, {
@@ -178,7 +178,7 @@ module.exports = app => {
                 const history = d.shistory && d.shistory !== '' ? JSON.parse(d.shistory) : [];
                 const his = history.find(function (x) {
                     return x.stimes && x.stimes === times
-                        && x.sorder && x.sorder === order;
+                        && x.sorder !== undefined && x.sorder !== null && x.sorder === order;
                 });
                 if (his) {
                     his.tp = d.tp;
@@ -190,6 +190,26 @@ module.exports = app => {
             await transaction.updateRows(this.tableName, updateDatas);
         }
 
+        async updateHistory4CheckCancel(stage, newTimes, newOrder, transaction) {
+            const datas = await this.getStageData(stage.id, true);
+            if (datas.length === 0) return;
+
+            const updateDatas = [];
+            for (const d of datas) {
+                const history = d.shistory && d.shistory !== '' ? JSON.parse(d.shistory) : [];
+                const his = history.find(function (x) {
+                    return x.stimes === newTimes && x.sorder === newOrder;
+                });
+                if (his) {
+                    his.tp = d.tp;
+                } else {
+                    history.push({ stimes: newTimes, sorder: newOrder, tp: d.tp });
+                }
+                updateDatas.push({ id: d.id, shistory: JSON.stringify(history) });
+            }
+            await transaction.updateRows(this.tableName, updateDatas);
+        }
+
         async updateHistory4CheckAgain(stage, transaction) {
             const datas = await this.getStageData(stage.id);
             if (datas.length === 0) return;

+ 20 - 0
app/service/stage_detail.js

@@ -82,6 +82,26 @@ module.exports = app => {
             }
         }
 
+        async updateStageDetail4CheckCancel(sid, newTimes, newOrder, oldTimes, oldOrder, transaction) {
+            const oldSBLists = await this.getAllDataByCondition({ where: { sid, times: oldTimes, order: oldOrder } });
+            const newSBLists = await this.getAllDataByCondition({ where: { sid, times: newTimes, order: newOrder } });
+            const delidList = [];
+            for (const o of oldSBLists) {
+                const newSBInfo = this._.find(newSBLists, { lid: o.lid });
+                if (newSBInfo) {
+                    // 删除
+                    delidList.push(newSBInfo.id);
+                }
+            }
+            if (delidList.length > 0) await transaction.delete(this.tableName, { id: delidList });
+            if (oldSBLists.length > 0) {
+                await transaction.update(this.tableName, {
+                    times: newTimes,
+                    order: newOrder,
+                }, { where: { id: this._.map(oldSBLists, 'id') } });
+            }
+        }
+
         /**
          * 获取 中间计量 用户最新输入数据
          * @param {Number} tid - 标段id

+ 30 - 3
app/service/stage_jgcl.js

@@ -22,9 +22,9 @@ module.exports = app => {
             this.tableName = 'stage_jgcl';
         }
 
-        async getStageData(stage) {
+        async getStageData(stage, cancel = false) {
             const data = await this.getAllDataByCondition({where: { sid: stage.id }});
-            if (stage && stage.readOnly && !this.ctx.tender.isTourist && stage.status !== auditConst.status.checked) {
+            if (!cancel && stage && stage.readOnly && !this.ctx.tender.isTourist && stage.status !== auditConst.status.checked) {
                 for (const d of data) {
                     const his = d.shistory ? JSON.parse(d.shistory) : [];
                     const h = this.ctx.helper._.find(his, {
@@ -204,7 +204,7 @@ module.exports = app => {
                 const history = d.shistory && d.shistory !== '' ? JSON.parse(d.shistory) : [];
                 const his = history.find(function (x) {
                     return x.stimes && x.stimes === times
-                        && x.sorder && x.sorder === order;
+                        && x.sorder !== undefined && x.sorder !== null && x.sorder === order;
                 });
                 if (his) {
                     his.arrive_qty = d.arrive_qty;
@@ -223,6 +223,33 @@ module.exports = app => {
             await transaction.updateRows(this.tableName, updateDatas);
         }
 
+        async updateHistory4CheckCancel(stage, newTimes, newOrder, transaction) {
+            const datas = await this.getStageData(stage, true);
+            if (datas.length === 0) return;
+
+            const updateDatas = [];
+            for (const d of datas) {
+                const history = d.shistory && d.shistory !== '' ? JSON.parse(d.shistory) : [];
+                const his = history.find(function (x) {
+                    return x.stimes === newTimes && x.sorder === newOrder;
+                });
+                if (his) {
+                    his.arrive_qty = d.arrive_qty;
+                    his.arrive_tp = d.arrive_tp;
+                    his.deduct_qty = d.deduct_qty;
+                    his.deduct_tp = d.deduct_tp;
+                } else {
+                    history.push({
+                        stimes: newTimes, sorder: newOrder,
+                        arrive_qty: d.arrive_qty, arrive_tp: d.arrive_tp,
+                        deduct_qty: d.deduct_qty, deduct_tp: d.deduct_tp
+                    });
+                }
+                updateDatas.push({ id: d.id, shistory: JSON.stringify(history) });
+            }
+            await transaction.updateRows(this.tableName, updateDatas);
+        }
+
         async updateHistory4CheckAgain(stage, transaction) {
             const datas = await this.getStageData(stage);
             if (datas.length === 0) return;

+ 26 - 3
app/service/stage_other.js

@@ -22,9 +22,9 @@ module.exports = app => {
             this.tableName = 'stage_other';
         }
 
-        async getStageData(stage) {
+        async getStageData(stage, cancel = false) {
             const data = await this.getAllDataByCondition({where: { sid: stage.id }});
-            if (stage && stage.readOnly && !this.ctx.tender.isTourist && stage.status !== auditConst.status.checked) {
+            if (!cancel && stage && stage.readOnly && !this.ctx.tender.isTourist && stage.status !== auditConst.status.checked) {
                 for (const d of data) {
                     const his = d.shistory ? JSON.parse(d.shistory) : [];
                     const h = this.ctx.helper._.find(his, {
@@ -174,7 +174,7 @@ module.exports = app => {
                 const history = d.shistory && d.shistory !== '' ? JSON.parse(d.shistory) : [];
                 const his = history.find(function (x) {
                     return x.stimes && x.stimes === times
-                        && x.sorder && x.sorder === order;
+                        && x.sorder !== undefined && x.sorder !== null && x.sorder === order;
                 });
                 if (his) {
                     his.tp = d.tp;
@@ -189,6 +189,29 @@ module.exports = app => {
             await transaction.updateRows(this.tableName, updateDatas);
         }
 
+        async updateHistory4CheckCancel(stage, newTimes, newOrder, transaction) {
+            const datas = await this.getStageData(stage, true);
+            if (datas.length === 0) return;
+
+            const updateDatas = [];
+            for (const d of datas) {
+                const history = d.shistory && d.shistory !== '' ? JSON.parse(d.shistory) : [];
+                const his = history.find(function (x) {
+                    return x.stimes === newTimes && x.sorder === newOrder;
+                });
+                if (his) {
+                    his.tp = d.tp;
+                    if (d.sid === d.add_sid) his.total_price = d.total_price;
+                } else {
+                    const nHis = { stimes: newTimes, sorder: newOrder, tp: d.tp };
+                    if (d.sid === d.add_sid) nHis.total_price = d.total_price;
+                    history.push(nHis);
+                }
+                updateDatas.push({ id: d.id, shistory: JSON.stringify(history) });
+            }
+            await transaction.updateRows(this.tableName, updateDatas);
+        }
+
         async updateHistory4CheckAgain(stage, transaction) {
             const datas = await this.getStageData(stage);
             if (datas.length === 0) return;

+ 3 - 3
app/service/stage_pay.js

@@ -214,7 +214,7 @@ module.exports = app => {
                 const updateData = {id: stagePay.id};
                 if (data.name !== undefined) { updateData.name = data.name }
                 if (data.expr !== undefined) { updateData.expr = data.expr }
-                if (data.tp !== undefined) { updateData.tp = data.tp }
+                if (data.tp !== undefined) { updateData.tp = data.tp; updateData.end_tp = this.ctx.helper.add(data.tp, data.pre_tp); }
                 if (data.pause !== undefined) { updateData.pause = data.pause }
                 if (data.postil !== undefined) updateData.postil = data.postil;
                 updateDatas.push(updateData);
@@ -293,7 +293,7 @@ module.exports = app => {
          * @param transaction - 事务
          * @returns {Promise<*>}
          */
-        async copyAuditStagePays(stage, times, order, transaction) {
+        async copyAuditStagePays(stage, times, order, transaction, curTimes = stage.curTimes, curOrder = stage.curOrder) {
             if (!stage || !transaction || !times || order === undefined) {
                 throw '数据错误';
             }
@@ -303,7 +303,7 @@ module.exports = app => {
                         '     SP.`pre_tp`, SP.`end_tp`, SP.`pre_used`, SP.`pre_finish`, SP.`start_stage_order`, SP.`postil` ' +
                         '  FROM ?? As SP' +
                         '  WHERE SP.`sid` = ? AND SP.`stimes` = ? AND SP.`sorder` = ?';
-            const sqlParam = [this.tableName, times, order, this.tableName, stage.id, stage.curTimes, stage.curOrder];
+            const sqlParam = [this.tableName, times, order, this.tableName, stage.id, curTimes, curOrder];
             return await transaction.query(sql, sqlParam);
         }
 

+ 21 - 0
app/service/stage_pos.js

@@ -125,6 +125,27 @@ module.exports = app => {
             return this._filterLastestData(stagePos);
         }
 
+        async updateStagePos4CheckCancel(sid, newSaid, newTimes, newOrder, oldSaid, oldTimes, oldOrder, transaction) {
+            const oldSBLists = await this.getAllDataByCondition({ where: { sid, times: oldTimes, order: oldOrder } });
+            const newSBLists = await this.getAllDataByCondition({ where: { sid, times: newTimes, order: newOrder } });
+            const delidList = [];
+            for (const o of oldSBLists) {
+                const newSBInfo = this._.find(newSBLists, { lid: o.lid, pid: o.pid });
+                if (newSBInfo) {
+                    // 删除
+                    delidList.push(newSBInfo.id);
+                }
+            }
+            if (delidList.length > 0) await transaction.delete(this.tableName, { id: delidList });
+            if (oldSBLists.length > 0) {
+                await transaction.update(this.tableName, {
+                    times: newTimes,
+                    order: newOrder,
+                    said: newSaid,
+                }, { where: { id: this._.map(oldSBLists, 'id') } });
+            }
+        }
+
         async getStageUsedPos(tid, sid, where) {
             const self = this;
             const stagePos = await this.getLastestStageData2(tid, sid, where);

+ 34 - 4
app/service/stage_safe_prod.js

@@ -23,9 +23,9 @@ module.exports = app => {
             this.tableName = 'stage_safe_prod';
         }
 
-        async getStageData(stage) {
+        async getStageData(stage, cancel) {
             const data = await this.getAllDataByCondition({where: { sid: stage.id }});
-            if (stage && stage.readOnly && !this.ctx.tender.isTourist && stage.status !== auditConst.status.checked) {
+            if (!cancel && stage && stage.readOnly && !this.ctx.tender.isTourist && stage.status !== auditConst.status.checked) {
                 for (const d of data) {
                     const his = d.shistory ? JSON.parse(d.shistory) : [];
                     const h = this.ctx.helper._.find(his, {
@@ -186,7 +186,7 @@ module.exports = app => {
                 const history = d.shistory && d.shistory !== '' ? JSON.parse(d.shistory) : [];
                 const his = history.find(function (x) {
                     return x.stimes && x.stimes === times
-                        && x.sorder && x.sorder === order;
+                        && x.sorder !== undefined && x.sorder !== null && x.sorder === order;
                 });
                 if (his) {
                     his.qty = d.qty;
@@ -208,6 +208,36 @@ module.exports = app => {
             await transaction.updateRows(this.tableName, updateDatas);
         }
 
+        async updateHistory4CheckCancel(stage, newTimes, newOrder, transaction) {
+            const datas = await this.getStageData(stage, true);
+            if (datas.length === 0) return;
+
+            const updateDatas = [];
+            for (const d of datas) {
+                const history = d.shistory && d.shistory !== '' ? JSON.parse(d.shistory) : [];
+                const his = history.find(function (x) {
+                    return x.stimes === newTimes && x.sorder === newOrder;
+                });
+                if (his) {
+                    his.qty = d.qty;
+                    his.tp = d.tp;
+                    if (d.sid === d.add_sid) {
+                        his.quantity = d.quantity;
+                        his.total_price = d.total_price;
+                    }
+                } else {
+                    const nHis = { stimes: newTimes, sorder: newOrder, qty: d.qty, tp: d.tp };
+                    if (d.sid === d.add_sid) {
+                        nHis.quantity = d.quantity;
+                        nHis.total_price = d.total_price;
+                    }
+                    history.push(nHis);
+                }
+                updateDatas.push({ id: d.id, shistory: JSON.stringify(history) });
+            }
+            await transaction.updateRows(this.tableName, updateDatas);
+        }
+
         async updateHistory4CheckAgain(stage, transaction) {
             const datas = await this.getStageData(stage);
             if (datas.length === 0) return;
@@ -288,4 +318,4 @@ module.exports = app => {
     }
 
     return StageSafeProd;
-};
+};

+ 26 - 4
app/service/stage_temp_land.js

@@ -23,9 +23,9 @@ module.exports = app => {
             this.tableName = 'stage_temp_land';
         }
 
-        async getStageData(stage) {
+        async getStageData(stage, cancel = false) {
             const data = await this.getAllDataByCondition({where: { sid: stage.id }});
-            if (stage && stage.readOnly && !this.ctx.tender.isTourist && stage.status !== auditConst.status.checked) {
+            if (!cancel && stage && stage.readOnly && !this.ctx.tender.isTourist && stage.status !== auditConst.status.checked) {
                 for (const d of data) {
                     const his = d.shistory ? JSON.parse(d.shistory) : [];
                     const h = this.ctx.helper._.find(his, {
@@ -177,7 +177,7 @@ module.exports = app => {
                 const history = d.shistory && d.shistory !== '' ? JSON.parse(d.shistory) : [];
                 const his = history.find(function (x) {
                     return x.stimes && x.stimes === times
-                        && x.sorder && x.sorder === order;
+                        && x.sorder !== undefined && x.sorder !== null && x.sorder === order;
                 });
                 if (his) {
                     his.qty = d.qty;
@@ -191,6 +191,28 @@ module.exports = app => {
             await transaction.updateRows(this.tableName, updateDatas);
         }
 
+        async updateHistory4CheckCancel(stage, newTimes, newOrder, transaction) {
+            const datas = await this.getStageData(stage, true);
+            if (datas.length === 0) return;
+
+            const updateDatas = [];
+            for (const d of datas) {
+                const history = d.shistory && d.shistory !== '' ? JSON.parse(d.shistory) : [];
+                const his = history.find(function (x) {
+                    return x.stimes === newTimes && x.sorder === newOrder;
+                });
+                if (his) {
+                    his.qty = d.qty;
+                    his.tp = d.tp;
+                } else {
+                    const nHis = { stimes: newTimes, sorder: newOrder, qty: d.qty, tp: d.tp };
+                    history.push(nHis);
+                }
+                updateDatas.push({ id: d.id, shistory: JSON.stringify(history) });
+            }
+            await transaction.updateRows(this.tableName, updateDatas);
+        }
+
         async updateHistory4CheckAgain(stage, transaction) {
             const datas = await this.getStageData(stage);
             if (datas.length === 0) return;
@@ -263,4 +285,4 @@ module.exports = app => {
     }
 
     return StageTempLand;
-};
+};

+ 11 - 0
app/service/sum_load_history.js

@@ -48,6 +48,17 @@ module.exports = app => {
             return await this.getHistroy(tid, lid, 'stage');
         }
 
+        async getBatchHistory(tid) {
+            const sql = `SELECT * FROM ${this.tableName} WHERE id IN (SELECT MAX(id) FROM ${this.tableName} WHERE tid = ? GROUP by lid);`;
+            const result = await this.db.query(sql, [tid]);
+            result.forEach(x => {
+                if (x && x.tenders) x.tenders = JSON.parse(x.tenders);
+                delete x.errors;
+            });
+            return result;
+        }
+
+
         async saveLedgerHistory(tid, lid, tenders, errors) {
             const data = {
                 tid, lid, type: 'ledger',

+ 63 - 61
app/view/change/information.ejs

@@ -1,16 +1,32 @@
 <% include ../tender/tender_sub_menu.ejs %>
 <div class="panel-content">
-    <div class="panel-title"><!--收起详解目录添加类名 fluid -->
+    <div class="panel-title" style="padding-right: 0px"><!--收起详解目录添加类名 fluid -->
         <div class="title-main d-flex"><!--工具-->
             <% include ../tender/tender_sub_mini_menu.ejs %>
-            <div>
-                <% if(auditStatus === auditConst.status.uncheck || auditStatus === auditConst.status.back || auditStatus === auditConst.status.revise) { %>
-                    <div class="d-inline-block">
+            <div style="width: 100%">
+                <div id="left-header" class="d-inline-block" style="min-width: 203px;">
+                <% if(auditStatus === 1 || auditStatus === 2 || auditStatus === 9) { %>
+                    <div class="d-inline-block mr-3">
                         <a class="btn btn-sm btn-primary" href="#add-bj" data-toggle="modal" data-target="#add-bj">拷贝其他变更令数据</a>
                     </div>
                 <% } %>
+                <div class="d-inline-block">
+                    <div class="custom-control custom-checkbox" style="line-height: normal;">
+                        <input type="checkbox" class="custom-control-input change-detail-checkbox" id="customCheck1">
+                        <label class="custom-control-label" for="customCheck1">变更详情</label>
+                    </div>
+                </div>
+                <% if (auditStatus === 3 || auditStatus === 4 || auditStatus === 5 || auditStatus === 7 || auditStatus === 8) { %>
+                    <div class="d-inline-block ml-3">
+                        <div class="custom-control custom-checkbox" style="line-height: normal;">
+                            <input type="checkbox" class="custom-control-input" id="show-table-detail">
+                            <label class="custom-control-label" for="show-table-detail">审批过程</label>
+                        </div>
+                    </div>
+                <% } %>
+                </div>
                 <% if (auditStatus === 1 || auditStatus === 2 || auditStatus === 9) { %>
-                    <div class="d-inline-block">
+                    <div class="d-inline-block ml-3">
                         <a href="#addlist" data-toggle="modal" class="btn btn-sm btn-light text-primary" id="open-list-modal" data-toggle="tooltip" data-placement="bottom" title="" data-original-title="添加清单"><i class="fa fa-plus" aria-hidden="true"></i> <span class="order_text"><% if (change.order_by === 0) { %>添加<% } else { %>插入<% } %></span>台账清单</a>
                     </div>
                     <div class="d-inline-block mr-1">
@@ -35,75 +51,61 @@
                             </ul>
                         </div>
                     </div>
-                    <div class="d-inline-block mr-3" id="upAndMoveBtn" <% if (change.order_by === 0) { %>style="display: none!important;" <% } %>>
+                    <div class="d-inline-block mr-2" id="upAndMoveBtn" <% if (change.order_by === 0) { %>style="display: none!important;" <% } %>>
                         <a href="javascript:void(0)" id="up-move" class="btn btn-sm btn-light text-primary" data-toggle="tooltip" data-placement="bottom" title="" data-original-title="上移"><i class="fa fa-arrow-up" aria-hidden="true"></i></a>
                         <a href="javascript:void(0)" id="down-move" class="btn btn-sm btn-light text-primary" data-toggle="tooltip" data-placement="bottom" title="" data-original-title="下移"><i class="fa fa-arrow-down" aria-hidden="true"></i></a>
                     </div>
                 <% } %>
-                <div class="d-inline-block">
-                    <div class="custom-control custom-checkbox" style="line-height: normal;">
-                        <input type="checkbox" class="custom-control-input change-detail-checkbox" id="customCheck1">
-                        <label class="custom-control-label" for="customCheck1">变更详情</label>
-                    </div>
-                </div>
-                <% if (auditStatus === 3 || auditStatus === 4 || auditStatus === 5 || auditStatus === 7 || auditStatus === 8) { %>
-                    <div class="d-inline-block ml-3">
-                        <div class="custom-control custom-checkbox" style="line-height: normal;">
-                            <input type="checkbox" class="custom-control-input" id="show-table-detail">
-                            <label class="custom-control-label" for="show-table-detail">审批过程</label>
-                        </div>
-                    </div>
-                <% } %>
                 <% if (showPlanBtn) { %>
                 <div class="d-inline-block ml-3">
                     <a class="btn btn-sm btn-primary" href="#bgfadb" data-toggle="modal" data-target="#bgfadb">差值对比</a>
                 </div>
                 <% } %>
-            </div>
-            <div class="ml-auto" id="sp-btn">
-                <!--info状态区分-->
-                <% if (auditStatus === 1) { %>
-                    <a href="#sub-ap" data-category="up_change" data-toggle="modal" data-target="#sub-ap" class="btn btn-primary btn-sm">上报审批</a>
-                <% } else if (auditStatus === 2 || auditStatus === 9) { %>
-                    <a href="#sub-sp2" data-category="up_change" data-toggle="modal" data-target="#sub-sp2" class="btn btn-primary btn-sm">重新上报</a>
-                <% } else if (auditStatus === 3) { %>
-                    <a href="#sp-list" data-toggle="modal" data-target="#sp-list" class="btn btn-outline-warning btn-sm text-muted">审批退回</a>
-                <% } else if (auditStatus === 4) { %>
-                    <a href="#sp-list" data-toggle="modal" data-target="#sp-list" class="btn btn-outline-success btn-sm">审批完成</a>
-                <% } else if (auditStatus === 5) { %>
-                    <a href="#sp-list" data-toggle="modal" data-target="#sp-list" class="btn btn-outline-danger btn-sm">审批终止</a>
-                <% } else if (auditStatus === 6) { %>
-                    <a href="#sp-done" data-toggle="modal" data-target="#sp-done" class="btn btn-success btn-sm">审批通过</a>
-                    <a href="#sp-back" data-toggle="modal" data-target="#sp-back" class="btn btn-warning btn-sm">审批退回</a>
-                <% } else if (auditStatus === 7) { %>
-                    <a href="#sp-list" data-toggle="modal" data-target="#sp-list" class="btn btn-outline-secondary btn-sm">审批中</a>
-                <% } else if (auditStatus === 8) { %>
-                    <% if (change.status === auditConst.status.uncheck) { %>
-                    <a href="#sp-list" data-toggle="modal" data-target="#sp-list" class="btn btn-outline-secondary btn-sm">上报中</a>
-                    <% } else if (change.status === auditConst.status.checking) { %>
-                    <a href="#sp-list" data-toggle="modal" data-target="#sp-list" class="btn btn-outline-secondary btn-sm">审批中</a>
+                <div class="pull-right mr-3" id="sp-btn">
+                    <!--info状态区分-->
+                    <% if (auditStatus === 1) { %>
+                        <a href="#sub-ap" data-category="up_change" data-toggle="modal" data-target="#sub-ap" class="btn btn-primary btn-sm">上报审批</a>
+                    <% } else if (auditStatus === 2 || auditStatus === 9) { %>
+                        <a href="#sub-sp2" data-category="up_change" data-toggle="modal" data-target="#sub-sp2" class="btn btn-primary btn-sm">重新上报</a>
+                    <% } else if (auditStatus === 3) { %>
+                        <a href="#sp-list" data-toggle="modal" data-target="#sp-list" class="btn btn-outline-warning btn-sm text-muted">审批退回</a>
+                    <% } else if (auditStatus === 4) { %>
+                        <a href="#sp-list" data-toggle="modal" data-target="#sp-list" class="btn btn-outline-success btn-sm">审批完成</a>
+                    <% } else if (auditStatus === 5) { %>
+                        <a href="#sp-list" data-toggle="modal" data-target="#sp-list" class="btn btn-outline-danger btn-sm">审批终止</a>
+                    <% } else if (auditStatus === 6) { %>
+                        <a href="#sp-done" data-toggle="modal" data-target="#sp-done" class="btn btn-success btn-sm">审批通过</a>
+                        <a href="#sp-back" data-toggle="modal" data-target="#sp-back" class="btn btn-warning btn-sm">审批退回</a>
+                    <% } else if (auditStatus === 7) { %>
+                        <a href="#sp-list" data-toggle="modal" data-target="#sp-list" class="btn btn-outline-secondary btn-sm">审批中</a>
+                    <% } else if (auditStatus === 8) { %>
+                        <% if (change.status === auditConst.status.uncheck) { %>
+                        <a href="#sp-list" data-toggle="modal" data-target="#sp-list" class="btn btn-outline-secondary btn-sm">上报中</a>
+                        <% } else if (change.status === auditConst.status.checking) { %>
+                        <a href="#sp-list" data-toggle="modal" data-target="#sp-list" class="btn btn-outline-secondary btn-sm">审批中</a>
+                        <% } %>
                     <% } %>
-                <% } %>
-                <% if (auditStatus === 4 && ctx.session.sessionUser.accountId === auditList[auditList.length-1].uid) { %>
-                    <% if (stageChangeNum === 0) { %>
-                        <!--重新审批-->
-                        <!--<a href="javascript: void(0);" data-toggle="modal" data-target="#sp-down-back" class="btn btn-warning btn-sm">重新审批</a>-->
-                    <% } else { %>
-                        <!--<button class="btn btn-outline-secondary btn-sm" data-toggle="tooltip" data-placement="bottom" title="已被调用">重新审批</button>-->
+                    <% if (auditStatus === 4 && ctx.session.sessionUser.accountId === auditList[auditList.length-1].uid) { %>
+                        <% if (stageChangeNum === 0) { %>
+                            <!--重新审批-->
+                            <!--<a href="javascript: void(0);" data-toggle="modal" data-target="#sp-down-back" class="btn btn-warning btn-sm">重新审批</a>-->
+                        <% } else { %>
+                            <!--<button class="btn btn-outline-secondary btn-sm" data-toggle="tooltip" data-placement="bottom" title="已被调用">重新审批</button>-->
+                        <% } %>
                     <% } %>
-                <% } %>
-                <% if (auditStatus === 4 && ctx.session.sessionUser.accountId === change.uid) { %>
-                    <a href="javascript: void(0);" data-toggle="modal" data-target="#sp-down-revise" class="btn btn-warning btn-sm">修订变更</a>
+                    <% if (auditStatus === 4 && ctx.session.sessionUser.accountId === change.uid) { %>
+                        <a href="javascript: void(0);" data-toggle="modal" data-target="#sp-down-revise" class="btn btn-warning btn-sm">修订变更</a>
+                    <% } %>
+                </div>
+                <!--info状态区分-->
+                <% if (auditStatus === 1 || auditStatus === 2 || auditStatus === 9) { %>
+                    <div class="pull-right px-3" id="show-save-btn" style="display: none">
+                        <span>您修改了变更信息,记得保存修改。</span>
+                        <button class="btn btn-sm btn-primary save_change_btn" id="save_change"><i class="fa fa-save"></i> 保存修改</button>
+                        <button class="btn btn-sm btn-light" id="cancel_change">取消</button>
+                    </div>
                 <% } %>
             </div>
-            <!--info状态区分-->
-            <% if (auditStatus === 1 || auditStatus === 2 || auditStatus === 9) { %>
-                <div class="ml-auto px-4" id="show-save-btn" style="display: none">
-                    <span>您修改了变更信息,记得保存修改。</span>
-                    <button class="btn btn-sm btn-primary save_change_btn" id="save_change"><i class="fa fa-save"></i> 保存修改</button>
-                    <button class="btn btn-sm btn-light" id="cancel_change">取消</button>
-                </div>
-            <% } %>
         </div>
     </div>
     <div class="content-wrap">

+ 1 - 1
app/view/report/rpt_all_popup.ejs

@@ -319,7 +319,7 @@
     <div class="modal-dialog modal-lg" role="document">
         <div class="modal-content">
             <div class="modal-header">
-                <h5 class="modal-title" id="audit-select-title">选择个人章</h5>
+                <h5 class="modal-title" id="select-personal-signature-title">选择个人章</h5>
                 <button type="button" class="close" data-dismiss="modal" aria-label="Close">
                     <span aria-hidden="true">&times;</span>
                 </button>

+ 32 - 0
app/view/shares/batch_import_modal.ejs

@@ -0,0 +1,32 @@
+<div class="modal fade" id="batch-import" data-backdrop="static">
+    <div class="modal-dialog modal-lg" role="document">
+        <div class="modal-content">
+            <div class="modal-header">
+                <h5 class="modal-title" id="batch-import-title">批量导入(其他标段)工程量清单计量数据</h5>
+                <button type="button" class="close" data-dismiss="modal" aria-label="Close">
+                    <span aria-hidden="true">&times;</span>
+                </button>
+            </div>
+            <div class="modal-body">
+                <div class="form-group mb-2">
+                    <div class="d-flex">
+                        <div class="d-inline-block">
+                            <div class="form-check form-check-inline">
+                                <input class="form-check-input" type="checkbox" id="bi-cover">
+                                <label class="form-check-label" for="bi-cover">覆盖数据</label>
+                            </div>
+                        </div>
+                        <div class="ml-auto">
+                            <button class="btn btn-sm btn-primary" id="bi-start">导入</button>
+                            <button class="btn btn-sm btn-primary" id="bi-download-error" style="display: none">下载错误信息</button>
+                        </div>
+                    </div>
+                </div>
+                <div class="form-group">
+                    <div class="modal-height-300" id="bi-spread">
+                    </div>
+                </div>
+            </div>
+        </div>
+    </div>
+</div>

+ 7 - 3
app/view/stage/audit_modal.ejs

@@ -81,9 +81,12 @@
                 <div class="modal-body">
                     <div class="row">
                         <div class="col-4">
-                            <% if(ctx.stage.status !== auditConst.status.checked && ctx.session.sessionUser.is_admin) { %>
-                            <a class="sp-list-item" href="#sub-sp2" data-toggle="modal" data-target="#sub-sp2"
+                            <% if(ctx.stage.status === auditConst.status.checkNo && ctx.session.sessionUser.accountId === ctx.stage.user_id) { %>
+                            <a class="sp-list-item" href="#sub-sp" data-toggle="modal" data-target="#sub-sp"
                                 id="hideSp">修改审批流程</a>
+                            <% } else if(ctx.stage.status !== auditConst.status.checked && ctx.session.sessionUser.is_admin) { %>
+                            <a class="sp-list-item" href="#sub-sp2" data-toggle="modal" data-target="#sub-sp2"
+                               id="hideSp">修改审批流程</a>
                             <% } %>
                             <div class="card mt-3">
                                 <ul class="list-group list-group-flush auditors-list" id="auditors-list">
@@ -817,7 +820,7 @@
                 <h5 class="modal-title">撤回</h5>
             </div>
             <div class="modal-body">
-                <h5>撤回后将回退到你的操作状态,并删除下一个流程中发生变化的数据,确定撤回?</h5>
+                <h5>撤回后将回退到你的操作状态,但保留下一个流程中发生变化的数据,确定撤回?</h5>
             </div>
             <div class="modal-footer">
                 <button type="button" class="btn btn-secondary btn-sm" data-dismiss="modal">取消</button>
@@ -969,6 +972,7 @@
 <script type="text/javascript">
     const csrf = '<%= ctx.csrf %>';
     const authMobile = '<%= authMobile %>';
+    const sam_auditConst = JSON.parse('<%- JSON.stringify(auditConst) %>');
 </script>
 <% if (ctx.stage && (ctx.session.sessionUser.accountId === ctx.stage.user_id && (ctx.stage.status === auditConst.status.uncheck || ctx.stage.status === auditConst.status.checkNo))) { %>
 <script>

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

@@ -527,7 +527,7 @@
         regExp = new RegExp(FindText, 'g');
         return this.replace(regExp, RepText);
     }
-    const readOnly = <%- stage.readOnly || stage.revising || (!stage.assist || !!stage.assist.confirm) %>;
+    const readOnly = <%- stage.readOnly || stage.revising || (stage.assist ? !!stage.assist.confirm : false) %>;
     const ledgerSpreadSetting = JSON.parse('<%- JSON.stringify(ledgerSpread) %>');
     ledgerSpreadSetting.localCache = {
         key: 'stage-bills',

+ 2 - 1
app/view/stage/modal.ejs

@@ -652,4 +652,5 @@
 <% include ../shares/tender_select_modal.ejs %>
 <% include ../shares/import_excel_modal.ejs%>
 <% include ../shares/stage_stash_modal.ejs%>
-<% include ../shares/delete_hint_modal.ejs%>
+<% include ../shares/delete_hint_modal.ejs%>
+<% include ../shares/batch_import_modal.ejs%>

+ 1 - 0
config/web.js

@@ -355,6 +355,7 @@ const JsFiles = {
                     '/public/js/stage_im.js',
                     '/public/js/shares/tenders2tree.js',
                     '/public/js/shares/tender_select.js',
+                    '/public/js/shares/batch_import.js',
                     // '/public/js/shares/stage_excel.js',
                     '/public/js/ledger_check.js',
                     '/public/js/stage.js',

+ 14 - 12
publish.md

@@ -10,21 +10,24 @@
 ##特殊操作
 如果没有特殊说明,则在第默认操作的第3步前,执行相关脚本,如果有特殊要求,需特别说明
 
-### V3.9
-2022-1024 ~ ...(uat) ~ ... prod
+### V3.5.28.0227
+2022-1024 ~ 2023-02-07(uat) ~ 2023-02-12 prod
 3.1 pay:
     - 重算所有合同支付项order
-### uat
+#### uat
 ```bash
 $ node pay_order uat
 ```
-### prod
+#### prod
 ```bash
 $ node pay_order default
 ```
 
-### V3.6
-2022-08-03 ~ ...(uat) ~ ...(prod)
+### V3.5.26.1024
+2022-10-10 ~ 2022-10-24(uat) ~ 2022-10-24(prod)
+
+### V3.5.25.1010
+2022-08-03 ~ 2022-08-04(uat) ~ 2022-10-10(prod)
 3.1 change:
     - 变更令正负变更金额,positive_tp, negative_tp
     - 期计量,计量单元,正负变更数量,positive_qc_qty, negative_qc_qty
@@ -34,28 +37,27 @@ $ node pay_order default
     - 期计量,本期补差,无旧数据,不需兼容:positive_qc_pc_tp, negative_qc_pc_tp
     - 期计量,本期正负变更金额,截止本期正负变更金额,positive_qc_tp, negative_qc_tp, pre_positive_qc_tp, pre_negative_pc_tp(补差无旧数据不兼容:positive_qc_pc_tp, negative_qc_pc_tp)
 
-### uat
+#### uat
 ```bash
 $ node change uat
 ```
-### prod
+#### prod
 ```bash
 $ node change default
 ```
 
-
 ### V3.5.24.0822
-2022-05-31 ~ 2022-08-02(uat) ~ 2022-08-03(prod)
+2022-05-31 ~ 2022-08-02(uat) ~ 2022-08-04(prod)
 3.1. ledger_his_count: 更新ledger_history表中新增的bills_count和pos_count两个字段数据
 3.2. minus_no_value: 更新project.fun_rela.minusNoValue=false和tender_info.fun_rela.stage_change.minusNoValue=false
 
-### uat
+#### uat
 ```bash
 $ node ledger_his_count uat
 $ node minus_no_value uat
 ```
 
-### prod
+#### prod
 ```bash
 $ node ledger_his_count default
 $ node minus_no_value default

+ 0 - 188
sql/update.sql

@@ -1,188 +0,0 @@
-ALTER TABLE `zh_project_account` CHANGE `stamp_path` `stamp_path` VARCHAR(5000) CHARACTER SET utf8 COLLATE utf8_general_ci NULL DEFAULT NULL COMMENT '用户签章oss地址';
-
-ALTER TABLE `zh_revise_price`
-ADD COLUMN `rela_lid`  varchar(1000) NOT NULL DEFAULT '' COMMENT '关联台账id(zh_ledger.ledger_id)' AFTER `use_stage_order`;
-ALTER TABLE `zh_revise_price`
-ADD COLUMN `rela_cid`  varchar(5000) NOT NULL DEFAULT '' COMMENT '关联变更令id(zh_change.cid)' AFTER `rela_lid`;
-ALTER TABLE `zh_revise_price`
-ADD COLUMN `his_rela_cid`  varchar(5000) NOT NULL DEFAULT '' COMMENT '审批通过后,关联变更令id(zh_change.cid)' AFTER `rela_cid`;
-
-CREATE TABLE `zh_audit_ass` (
-  `id` bigint(20) NOT NULL AUTO_INCREMENT,
-  `pid` int(11) unsigned NOT NULL COMMENT '项目id',
-  `tid` int(11) unsigned NOT NULL COMMENT '标段id',
-  `user_id` int(11) unsigned NOT NULL COMMENT '主账号id',
-  `ass_user_id` int(11) unsigned NOT NULL COMMENT '协审账号id',
-  `name` varchar(50) COLLATE utf8_unicode_ci NOT NULL DEFAULT '' COMMENT '用户名',
-  `company` varchar(255) COLLATE utf8_unicode_ci NOT NULL DEFAULT '' COMMENT '单位',
-  `role` varchar(255) COLLATE utf8_unicode_ci NOT NULL DEFAULT '' COMMENT '角色',
-  `ass_ledger_id` varchar(1000) COLLATE utf8_unicode_ci NOT NULL DEFAULT '' COMMENT '协审台账id(zh_ledger.ledger_id)',
-  PRIMARY KEY (`id`),
-  KEY `idx_tid` (`tid`) USING BTREE,
-  KEY `idx_tid_user` (`tid`,`user_id`) USING BTREE
-) ENGINE=InnoDB DEFAULT CHARSET=utf8 COLLATE=utf8_unicode_ci;
-
-CREATE TABLE `zh_stage_audit_ass` (
-  `id` bigint(20) unsigned NOT NULL AUTO_INCREMENT,
-  `pid` int(11) unsigned NOT NULL COMMENT '项目id',
-  `tid` int(11) unsigned NOT NULL COMMENT '标段id',
-  `sid` int(11) unsigned NOT NULL COMMENT '期id',
-  `times` int(11) unsigned NOT NULL DEFAULT '1' COMMENT '审批次',
-  `user_id` int(11) unsigned NOT NULL COMMENT '主账号id',
-  `ass_user_id` int(11) unsigned NOT NULL COMMENT '协审人账号id',
-  `ass_ledger_id` varchar(5000) COLLATE utf8_unicode_ci NOT NULL DEFAULT '' COMMENT '协审台账id(zh_ledger.ledger_id)',
-  `name` varchar(50) COLLATE utf8_unicode_ci NOT NULL DEFAULT '' COMMENT '名称',
-  `company` varchar(255) COLLATE utf8_unicode_ci NOT NULL DEFAULT '' COMMENT '单位',
-  `role` varchar(255) COLLATE utf8_unicode_ci NOT NULL DEFAULT '' COMMENT '角色',
-  `create_time` timestamp NOT NULL DEFAULT CURRENT_TIMESTAMP COMMENT '创建时间',
-  `update_time` timestamp NOT NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP COMMENT '更新时间',
-  `confirm` tinyint(4) unsigned NOT NULL DEFAULT '1',
-  `locked` tinyint(4) unsigned NOT NULL DEFAULT '0' COMMENT '锁定',
-  PRIMARY KEY (`id`),
-  KEY `idx_sid_times` (`sid`,`times`) USING BTREE,
-  KEY `idx_sid_times_user` (`sid`,`times`,`user_id`) USING BTREE
-) ENGINE=InnoDB DEFAULT CHARSET=utf8 COLLATE=utf8_unicode_ci;
-
-ALTER TABLE `zh_budget_final`
-ADD COLUMN `deal_dgn_qty1`  decimal(24,8) NOT NULL DEFAULT 0 COMMENT '决算-合同-数量1' AFTER `dgn_qty`,
-ADD COLUMN `deal_dgn_qty2`  decimal(24,8) NOT NULL DEFAULT 0 COMMENT '决算-合同-数量2' AFTER `deal_dgn_qty1`,
-ADD COLUMN `c_dgn_qty1`  decimal(24,8) NOT NULL DEFAULT 0 COMMENT '决算-变更-数量1' AFTER `deal_dgn_qty2`,
-ADD COLUMN `c_dgn_qty2`  decimal(24,8) NOT NULL DEFAULT 0 COMMENT '决算-变更-数量2' AFTER `c_dgn_qty1`,
-ADD COLUMN `final_contract_tp`  decimal(24,8) NOT NULL DEFAULT 0 COMMENT '决算-合同金额' AFTER `final_dgn_qty2`,
-ADD COLUMN `final_qc_tp`  decimal(24,8) NOT NULL DEFAULT 0 COMMENT '决算-变更金额' AFTER `final_cotnract_tp`;
-
-ALTER TABLE `zh_tender`
-ADD COLUMN `rpt_show_level`  varchar(50) NOT NULL DEFAULT 'last' AFTER `c_plan_list_rule`;
-
-ALTER TABLE `zh_ledger_0`
-ADD COLUMN `ccid`  varchar(36) NULL DEFAULT '' COMMENT 'create_change_id(uuid)' AFTER `crid`;
-ALTER TABLE `zh_ledger_1`
-ADD COLUMN `ccid`  varchar(36) NULL DEFAULT '' COMMENT 'create_change_id(uuid)' AFTER `crid`;
-ALTER TABLE `zh_ledger_2`
-ADD COLUMN `ccid`  varchar(36) NULL DEFAULT '' COMMENT 'create_change_id(uuid)' AFTER `crid`;
-ALTER TABLE `zh_ledger_3`
-ADD COLUMN `ccid`  varchar(36) NULL DEFAULT '' COMMENT 'create_change_id(uuid)' AFTER `crid`;
-ALTER TABLE `zh_ledger_4`
-ADD COLUMN `ccid`  varchar(36) NULL DEFAULT '' COMMENT 'create_change_id(uuid)' AFTER `crid`;
-ALTER TABLE `zh_ledger_5`
-ADD COLUMN `ccid`  varchar(36) NULL DEFAULT '' COMMENT 'create_change_id(uuid)' AFTER `crid`;
-ALTER TABLE `zh_ledger_6`
-ADD COLUMN `ccid`  varchar(36) NULL DEFAULT '' COMMENT 'create_change_id(uuid)' AFTER `crid`;
-ALTER TABLE `zh_ledger_7`
-ADD COLUMN `ccid`  varchar(36) NULL DEFAULT '' COMMENT 'create_change_id(uuid)' AFTER `crid`;
-ALTER TABLE `zh_ledger_8`
-ADD COLUMN `ccid`  varchar(36) NULL DEFAULT '' COMMENT 'create_change_id(uuid)' AFTER `crid`;
-ALTER TABLE `zh_ledger_9`
-ADD COLUMN `ccid`  varchar(36) NULL DEFAULT '' COMMENT 'create_change_id(uuid)' AFTER `crid`;
-
-ALTER TABLE `zh_pos_0`
-ADD COLUMN `ccid`  varchar(36) NULL DEFAULT '' COMMENT 'create_change_id(uuid)' AFTER `crid`;
-ALTER TABLE `zh_pos_1`
-ADD COLUMN `ccid`  varchar(36) NULL DEFAULT '' COMMENT 'create_change_id(uuid)' AFTER `crid`;
-ALTER TABLE `zh_pos_2`
-ADD COLUMN `ccid`  varchar(36) NULL DEFAULT '' COMMENT 'create_change_id(uuid)' AFTER `crid`;
-ALTER TABLE `zh_pos_3`
-ADD COLUMN `ccid`  varchar(36) NULL DEFAULT '' COMMENT 'create_change_id(uuid)' AFTER `crid`;
-ALTER TABLE `zh_pos_4`
-ADD COLUMN `ccid`  varchar(36) NULL DEFAULT '' COMMENT 'create_change_id(uuid)' AFTER `crid`;
-ALTER TABLE `zh_pos_5`
-ADD COLUMN `ccid`  varchar(36) NULL DEFAULT '' COMMENT 'create_change_id(uuid)' AFTER `crid`;
-ALTER TABLE `zh_pos_6`
-ADD COLUMN `ccid`  varchar(36) NULL DEFAULT '' COMMENT 'create_change_id(uuid)' AFTER `crid`;
-ALTER TABLE `zh_pos_7`
-ADD COLUMN `ccid`  varchar(36) NULL DEFAULT '' COMMENT 'create_change_id(uuid)' AFTER `crid`;
-ALTER TABLE `zh_pos_8`
-ADD COLUMN `ccid`  varchar(36) NULL DEFAULT '' COMMENT 'create_change_id(uuid)' AFTER `crid`;
-ALTER TABLE `zh_pos_9`
-ADD COLUMN `ccid`  varchar(36) NULL DEFAULT '' COMMENT 'create_change_id(uuid)' AFTER `crid`;
-ALTER TABLE `zh_pos_10`
-ADD COLUMN `ccid`  varchar(36) NULL DEFAULT '' COMMENT 'create_change_id(uuid)' AFTER `crid`;
-ALTER TABLE `zh_pos_11`
-ADD COLUMN `ccid`  varchar(36) NULL DEFAULT '' COMMENT 'create_change_id(uuid)' AFTER `crid`;
-ALTER TABLE `zh_pos_12`
-ADD COLUMN `ccid`  varchar(36) NULL DEFAULT '' COMMENT 'create_change_id(uuid)' AFTER `crid`;
-ALTER TABLE `zh_pos_13`
-ADD COLUMN `ccid`  varchar(36) NULL DEFAULT '' COMMENT 'create_change_id(uuid)' AFTER `crid`;
-ALTER TABLE `zh_pos_14`
-ADD COLUMN `ccid`  varchar(36) NULL DEFAULT '' COMMENT 'create_change_id(uuid)' AFTER `crid`;
-ALTER TABLE `zh_pos_15`
-ADD COLUMN `ccid`  varchar(36) NULL DEFAULT '' COMMENT 'create_change_id(uuid)' AFTER `crid`;
-ALTER TABLE `zh_pos_16`
-ADD COLUMN `ccid`  varchar(36) NULL DEFAULT '' COMMENT 'create_change_id(uuid)' AFTER `crid`;
-ALTER TABLE `zh_pos_17`
-ADD COLUMN `ccid`  varchar(36) NULL DEFAULT '' COMMENT 'create_change_id(uuid)' AFTER `crid`;
-ALTER TABLE `zh_pos_18`
-ADD COLUMN `ccid`  varchar(36) NULL DEFAULT '' COMMENT 'create_change_id(uuid)' AFTER `crid`;
-ALTER TABLE `zh_pos_19`
-ADD COLUMN `ccid`  varchar(36) NULL DEFAULT '' COMMENT 'create_change_id(uuid)' AFTER `crid`;
-
-ALTER TABLE `zh_revise_bills_0`
-ADD COLUMN `ccid`  varchar(36) NULL DEFAULT '' COMMENT 'create_change_id(uuid)' AFTER `crid`;
-ALTER TABLE `zh_revise_bills_1`
-ADD COLUMN `ccid`  varchar(36) NULL DEFAULT '' COMMENT 'create_change_id(uuid)' AFTER `crid`;
-ALTER TABLE `zh_revise_bills_2`
-ADD COLUMN `ccid`  varchar(36) NULL DEFAULT '' COMMENT 'create_change_id(uuid)' AFTER `crid`;
-ALTER TABLE `zh_revise_bills_3`
-ADD COLUMN `ccid`  varchar(36) NULL DEFAULT '' COMMENT 'create_change_id(uuid)' AFTER `crid`;
-ALTER TABLE `zh_revise_bills_4`
-ADD COLUMN `ccid`  varchar(36) NULL DEFAULT '' COMMENT 'create_change_id(uuid)' AFTER `crid`;
-ALTER TABLE `zh_revise_bills_5`
-ADD COLUMN `ccid`  varchar(36) NULL DEFAULT '' COMMENT 'create_change_id(uuid)' AFTER `crid`;
-ALTER TABLE `zh_revise_bills_6`
-ADD COLUMN `ccid`  varchar(36) NULL DEFAULT '' COMMENT 'create_change_id(uuid)' AFTER `crid`;
-ALTER TABLE `zh_revise_bills_7`
-ADD COLUMN `ccid`  varchar(36) NULL DEFAULT '' COMMENT 'create_change_id(uuid)' AFTER `crid`;
-ALTER TABLE `zh_revise_bills_8`
-ADD COLUMN `ccid`  varchar(36) NULL DEFAULT '' COMMENT 'create_change_id(uuid)' AFTER `crid`;
-ALTER TABLE `zh_revise_bills_9`
-ADD COLUMN `ccid`  varchar(36) NULL DEFAULT '' COMMENT 'create_change_id(uuid)' AFTER `crid`;
-
-ALTER TABLE `zh_revise_pos_0`
-ADD COLUMN `ccid`  varchar(36) NULL DEFAULT '' COMMENT 'create_change_id(uuid)' AFTER `crid`;
-ALTER TABLE `zh_revise_pos_1`
-ADD COLUMN `ccid`  varchar(36) NULL DEFAULT '' COMMENT 'create_change_id(uuid)' AFTER `crid`;
-ALTER TABLE `zh_revise_pos_2`
-ADD COLUMN `ccid`  varchar(36) NULL DEFAULT '' COMMENT 'create_change_id(uuid)' AFTER `crid`;
-ALTER TABLE `zh_revise_pos_3`
-ADD COLUMN `ccid`  varchar(36) NULL DEFAULT '' COMMENT 'create_change_id(uuid)' AFTER `crid`;
-ALTER TABLE `zh_revise_pos_4`
-ADD COLUMN `ccid`  varchar(36) NULL DEFAULT '' COMMENT 'create_change_id(uuid)' AFTER `crid`;
-ALTER TABLE `zh_revise_pos_5`
-ADD COLUMN `ccid`  varchar(36) NULL DEFAULT '' COMMENT 'create_change_id(uuid)' AFTER `crid`;
-ALTER TABLE `zh_revise_pos_6`
-ADD COLUMN `ccid`  varchar(36) NULL DEFAULT '' COMMENT 'create_change_id(uuid)' AFTER `crid`;
-ALTER TABLE `zh_revise_pos_7`
-ADD COLUMN `ccid`  varchar(36) NULL DEFAULT '' COMMENT 'create_change_id(uuid)' AFTER `crid`;
-ALTER TABLE `zh_revise_pos_8`
-ADD COLUMN `ccid`  varchar(36) NULL DEFAULT '' COMMENT 'create_change_id(uuid)' AFTER `crid`;
-ALTER TABLE `zh_revise_pos_9`
-ADD COLUMN `ccid`  varchar(36) NULL DEFAULT '' COMMENT 'create_change_id(uuid)' AFTER `crid`;
-ALTER TABLE `zh_revise_pos_10`
-ADD COLUMN `ccid`  varchar(36) NULL DEFAULT '' COMMENT 'create_change_id(uuid)' AFTER `crid`;
-ALTER TABLE `zh_revise_pos_11`
-ADD COLUMN `ccid`  varchar(36) NULL DEFAULT '' COMMENT 'create_change_id(uuid)' AFTER `crid`;
-ALTER TABLE `zh_revise_pos_12`
-ADD COLUMN `ccid`  varchar(36) NULL DEFAULT '' COMMENT 'create_change_id(uuid)' AFTER `crid`;
-ALTER TABLE `zh_revise_pos_13`
-ADD COLUMN `ccid`  varchar(36) NULL DEFAULT '' COMMENT 'create_change_id(uuid)' AFTER `crid`;
-ALTER TABLE `zh_revise_pos_14`
-ADD COLUMN `ccid`  varchar(36) NULL DEFAULT '' COMMENT 'create_change_id(uuid)' AFTER `crid`;
-ALTER TABLE `zh_revise_pos_15`
-ADD COLUMN `ccid`  varchar(36) NULL DEFAULT '' COMMENT 'create_change_id(uuid)' AFTER `crid`;
-ALTER TABLE `zh_revise_pos_16`
-ADD COLUMN `ccid`  varchar(36) NULL DEFAULT '' COMMENT 'create_change_id(uuid)' AFTER `crid`;
-ALTER TABLE `zh_revise_pos_17`
-ADD COLUMN `ccid`  varchar(36) NULL DEFAULT '' COMMENT 'create_change_id(uuid)' AFTER `crid`;
-ALTER TABLE `zh_revise_pos_18`
-ADD COLUMN `ccid`  varchar(36) NULL DEFAULT '' COMMENT 'create_change_id(uuid)' AFTER `crid`;
-ALTER TABLE `zh_revise_pos_19`
-ADD COLUMN `ccid`  varchar(36) NULL DEFAULT '' COMMENT 'create_change_id(uuid)' AFTER `crid`;
-
-ALTER TABLE `zh_stage_pay`
-ADD COLUMN `porder` tinyint(4) NOT NULL DEFAULT '0' COMMENT '排序' AFTER `sorder`;
-UPDATE zh_stage_pay sp LEFT JOIN zh_pay p ON sp.pid = p.id SET sp.porder = p.`order`;
-
-ALTER TABLE `zh_change_ledger` ADD `formc` TINYINT(1) NOT NULL DEFAULT '1' COMMENT '是否为变更新增(用于区分台账)' AFTER `ccid`;
-ALTER TABLE `zh_change_pos` ADD `formc` TINYINT(1) NOT NULL DEFAULT '1' COMMENT '是否为变更新增(用于区分台账)' AFTER `ccid`;
-
-ALTER TABLE `zh_stage_audit` ADD `is_old` TINYINT(1) NOT NULL DEFAULT '0' COMMENT '是否为旧流程(用于管理员修改流程时旧数据保留但不影响新流程)' AFTER `lock_lid`;

+ 188 - 0
sql/update20230212.sql

@@ -0,0 +1,188 @@
+ALTER TABLE `zh_project_account` CHANGE `stamp_path` `stamp_path` VARCHAR(5000) CHARACTER SET utf8 COLLATE utf8_general_ci NULL DEFAULT NULL COMMENT '用户签章oss地址';
+
+ALTER TABLE `zh_revise_price`
+ADD COLUMN `rela_lid`  varchar(1000) NOT NULL DEFAULT '' COMMENT '关联台账id(zh_ledger.ledger_id)' AFTER `use_stage_order`;
+ALTER TABLE `zh_revise_price`
+ADD COLUMN `rela_cid`  varchar(5000) NOT NULL DEFAULT '' COMMENT '关联变更令id(zh_change.cid)' AFTER `rela_lid`;
+ALTER TABLE `zh_revise_price`
+ADD COLUMN `his_rela_cid`  varchar(5000) NOT NULL DEFAULT '' COMMENT '审批通过后,关联变更令id(zh_change.cid)' AFTER `rela_cid`;
+
+CREATE TABLE `zh_audit_ass` (
+  `id` bigint(20) NOT NULL AUTO_INCREMENT,
+  `pid` int(11) unsigned NOT NULL COMMENT '项目id',
+  `tid` int(11) unsigned NOT NULL COMMENT '标段id',
+  `user_id` int(11) unsigned NOT NULL COMMENT '主账号id',
+  `ass_user_id` int(11) unsigned NOT NULL COMMENT '协审账号id',
+  `name` varchar(50) COLLATE utf8_unicode_ci NOT NULL DEFAULT '' COMMENT '用户名',
+  `company` varchar(255) COLLATE utf8_unicode_ci NOT NULL DEFAULT '' COMMENT '单位',
+  `role` varchar(255) COLLATE utf8_unicode_ci NOT NULL DEFAULT '' COMMENT '角色',
+  `ass_ledger_id` varchar(1000) COLLATE utf8_unicode_ci NOT NULL DEFAULT '' COMMENT '协审台账id(zh_ledger.ledger_id)',
+  PRIMARY KEY (`id`),
+  KEY `idx_tid` (`tid`) USING BTREE,
+  KEY `idx_tid_user` (`tid`,`user_id`) USING BTREE
+) ENGINE=InnoDB DEFAULT CHARSET=utf8 COLLATE=utf8_unicode_ci;
+
+CREATE TABLE `zh_stage_audit_ass` (
+  `id` bigint(20) unsigned NOT NULL AUTO_INCREMENT,
+  `pid` int(11) unsigned NOT NULL COMMENT '项目id',
+  `tid` int(11) unsigned NOT NULL COMMENT '标段id',
+  `sid` int(11) unsigned NOT NULL COMMENT '期id',
+  `times` int(11) unsigned NOT NULL DEFAULT '1' COMMENT '审批次',
+  `user_id` int(11) unsigned NOT NULL COMMENT '主账号id',
+  `ass_user_id` int(11) unsigned NOT NULL COMMENT '协审人账号id',
+  `ass_ledger_id` varchar(5000) COLLATE utf8_unicode_ci NOT NULL DEFAULT '' COMMENT '协审台账id(zh_ledger.ledger_id)',
+  `name` varchar(50) COLLATE utf8_unicode_ci NOT NULL DEFAULT '' COMMENT '名称',
+  `company` varchar(255) COLLATE utf8_unicode_ci NOT NULL DEFAULT '' COMMENT '单位',
+  `role` varchar(255) COLLATE utf8_unicode_ci NOT NULL DEFAULT '' COMMENT '角色',
+  `create_time` timestamp NOT NULL DEFAULT CURRENT_TIMESTAMP COMMENT '创建时间',
+  `update_time` timestamp NOT NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP COMMENT '更新时间',
+  `confirm` tinyint(4) unsigned NOT NULL DEFAULT '1',
+  `locked` tinyint(4) unsigned NOT NULL DEFAULT '0' COMMENT '锁定',
+  PRIMARY KEY (`id`),
+  KEY `idx_sid_times` (`sid`,`times`) USING BTREE,
+  KEY `idx_sid_times_user` (`sid`,`times`,`user_id`) USING BTREE
+) ENGINE=InnoDB DEFAULT CHARSET=utf8 COLLATE=utf8_unicode_ci;
+
+ALTER TABLE `zh_budget_final`
+ADD COLUMN `deal_dgn_qty1`  decimal(24,8) NOT NULL DEFAULT 0 COMMENT '决算-合同-数量1' AFTER `dgn_qty`,
+ADD COLUMN `deal_dgn_qty2`  decimal(24,8) NOT NULL DEFAULT 0 COMMENT '决算-合同-数量2' AFTER `deal_dgn_qty1`,
+ADD COLUMN `c_dgn_qty1`  decimal(24,8) NOT NULL DEFAULT 0 COMMENT '决算-变更-数量1' AFTER `deal_dgn_qty2`,
+ADD COLUMN `c_dgn_qty2`  decimal(24,8) NOT NULL DEFAULT 0 COMMENT '决算-变更-数量2' AFTER `c_dgn_qty1`,
+ADD COLUMN `final_contract_tp`  decimal(24,8) NOT NULL DEFAULT 0 COMMENT '决算-合同金额' AFTER `final_dgn_qty2`,
+ADD COLUMN `final_qc_tp`  decimal(24,8) NOT NULL DEFAULT 0 COMMENT '决算-变更金额' AFTER `final_contract_tp`;
+
+ALTER TABLE `zh_tender`
+ADD COLUMN `rpt_show_level`  varchar(50) NOT NULL DEFAULT 'last' AFTER `c_plan_list_rule`;
+
+ALTER TABLE `zh_ledger_0`
+ADD COLUMN `ccid`  varchar(36) NULL DEFAULT '' COMMENT 'create_change_id(uuid)' AFTER `crid`;
+ALTER TABLE `zh_ledger_1`
+ADD COLUMN `ccid`  varchar(36) NULL DEFAULT '' COMMENT 'create_change_id(uuid)' AFTER `crid`;
+ALTER TABLE `zh_ledger_2`
+ADD COLUMN `ccid`  varchar(36) NULL DEFAULT '' COMMENT 'create_change_id(uuid)' AFTER `crid`;
+ALTER TABLE `zh_ledger_3`
+ADD COLUMN `ccid`  varchar(36) NULL DEFAULT '' COMMENT 'create_change_id(uuid)' AFTER `crid`;
+ALTER TABLE `zh_ledger_4`
+ADD COLUMN `ccid`  varchar(36) NULL DEFAULT '' COMMENT 'create_change_id(uuid)' AFTER `crid`;
+ALTER TABLE `zh_ledger_5`
+ADD COLUMN `ccid`  varchar(36) NULL DEFAULT '' COMMENT 'create_change_id(uuid)' AFTER `crid`;
+ALTER TABLE `zh_ledger_6`
+ADD COLUMN `ccid`  varchar(36) NULL DEFAULT '' COMMENT 'create_change_id(uuid)' AFTER `crid`;
+ALTER TABLE `zh_ledger_7`
+ADD COLUMN `ccid`  varchar(36) NULL DEFAULT '' COMMENT 'create_change_id(uuid)' AFTER `crid`;
+ALTER TABLE `zh_ledger_8`
+ADD COLUMN `ccid`  varchar(36) NULL DEFAULT '' COMMENT 'create_change_id(uuid)' AFTER `crid`;
+ALTER TABLE `zh_ledger_9`
+ADD COLUMN `ccid`  varchar(36) NULL DEFAULT '' COMMENT 'create_change_id(uuid)' AFTER `crid`;
+
+ALTER TABLE `zh_pos_0`
+ADD COLUMN `ccid`  varchar(36) NULL DEFAULT '' COMMENT 'create_change_id(uuid)' AFTER `crid`;
+ALTER TABLE `zh_pos_1`
+ADD COLUMN `ccid`  varchar(36) NULL DEFAULT '' COMMENT 'create_change_id(uuid)' AFTER `crid`;
+ALTER TABLE `zh_pos_2`
+ADD COLUMN `ccid`  varchar(36) NULL DEFAULT '' COMMENT 'create_change_id(uuid)' AFTER `crid`;
+ALTER TABLE `zh_pos_3`
+ADD COLUMN `ccid`  varchar(36) NULL DEFAULT '' COMMENT 'create_change_id(uuid)' AFTER `crid`;
+ALTER TABLE `zh_pos_4`
+ADD COLUMN `ccid`  varchar(36) NULL DEFAULT '' COMMENT 'create_change_id(uuid)' AFTER `crid`;
+ALTER TABLE `zh_pos_5`
+ADD COLUMN `ccid`  varchar(36) NULL DEFAULT '' COMMENT 'create_change_id(uuid)' AFTER `crid`;
+ALTER TABLE `zh_pos_6`
+ADD COLUMN `ccid`  varchar(36) NULL DEFAULT '' COMMENT 'create_change_id(uuid)' AFTER `crid`;
+ALTER TABLE `zh_pos_7`
+ADD COLUMN `ccid`  varchar(36) NULL DEFAULT '' COMMENT 'create_change_id(uuid)' AFTER `crid`;
+ALTER TABLE `zh_pos_8`
+ADD COLUMN `ccid`  varchar(36) NULL DEFAULT '' COMMENT 'create_change_id(uuid)' AFTER `crid`;
+ALTER TABLE `zh_pos_9`
+ADD COLUMN `ccid`  varchar(36) NULL DEFAULT '' COMMENT 'create_change_id(uuid)' AFTER `crid`;
+ALTER TABLE `zh_pos_10`
+ADD COLUMN `ccid`  varchar(36) NULL DEFAULT '' COMMENT 'create_change_id(uuid)' AFTER `crid`;
+ALTER TABLE `zh_pos_11`
+ADD COLUMN `ccid`  varchar(36) NULL DEFAULT '' COMMENT 'create_change_id(uuid)' AFTER `crid`;
+ALTER TABLE `zh_pos_12`
+ADD COLUMN `ccid`  varchar(36) NULL DEFAULT '' COMMENT 'create_change_id(uuid)' AFTER `crid`;
+ALTER TABLE `zh_pos_13`
+ADD COLUMN `ccid`  varchar(36) NULL DEFAULT '' COMMENT 'create_change_id(uuid)' AFTER `crid`;
+ALTER TABLE `zh_pos_14`
+ADD COLUMN `ccid`  varchar(36) NULL DEFAULT '' COMMENT 'create_change_id(uuid)' AFTER `crid`;
+ALTER TABLE `zh_pos_15`
+ADD COLUMN `ccid`  varchar(36) NULL DEFAULT '' COMMENT 'create_change_id(uuid)' AFTER `crid`;
+ALTER TABLE `zh_pos_16`
+ADD COLUMN `ccid`  varchar(36) NULL DEFAULT '' COMMENT 'create_change_id(uuid)' AFTER `crid`;
+ALTER TABLE `zh_pos_17`
+ADD COLUMN `ccid`  varchar(36) NULL DEFAULT '' COMMENT 'create_change_id(uuid)' AFTER `crid`;
+ALTER TABLE `zh_pos_18`
+ADD COLUMN `ccid`  varchar(36) NULL DEFAULT '' COMMENT 'create_change_id(uuid)' AFTER `crid`;
+ALTER TABLE `zh_pos_19`
+ADD COLUMN `ccid`  varchar(36) NULL DEFAULT '' COMMENT 'create_change_id(uuid)' AFTER `crid`;
+
+ALTER TABLE `zh_revise_bills_0`
+ADD COLUMN `ccid`  varchar(36) NULL DEFAULT '' COMMENT 'create_change_id(uuid)' AFTER `crid`;
+ALTER TABLE `zh_revise_bills_1`
+ADD COLUMN `ccid`  varchar(36) NULL DEFAULT '' COMMENT 'create_change_id(uuid)' AFTER `crid`;
+ALTER TABLE `zh_revise_bills_2`
+ADD COLUMN `ccid`  varchar(36) NULL DEFAULT '' COMMENT 'create_change_id(uuid)' AFTER `crid`;
+ALTER TABLE `zh_revise_bills_3`
+ADD COLUMN `ccid`  varchar(36) NULL DEFAULT '' COMMENT 'create_change_id(uuid)' AFTER `crid`;
+ALTER TABLE `zh_revise_bills_4`
+ADD COLUMN `ccid`  varchar(36) NULL DEFAULT '' COMMENT 'create_change_id(uuid)' AFTER `crid`;
+ALTER TABLE `zh_revise_bills_5`
+ADD COLUMN `ccid`  varchar(36) NULL DEFAULT '' COMMENT 'create_change_id(uuid)' AFTER `crid`;
+ALTER TABLE `zh_revise_bills_6`
+ADD COLUMN `ccid`  varchar(36) NULL DEFAULT '' COMMENT 'create_change_id(uuid)' AFTER `crid`;
+ALTER TABLE `zh_revise_bills_7`
+ADD COLUMN `ccid`  varchar(36) NULL DEFAULT '' COMMENT 'create_change_id(uuid)' AFTER `crid`;
+ALTER TABLE `zh_revise_bills_8`
+ADD COLUMN `ccid`  varchar(36) NULL DEFAULT '' COMMENT 'create_change_id(uuid)' AFTER `crid`;
+ALTER TABLE `zh_revise_bills_9`
+ADD COLUMN `ccid`  varchar(36) NULL DEFAULT '' COMMENT 'create_change_id(uuid)' AFTER `crid`;
+
+ALTER TABLE `zh_revise_pos_0`
+ADD COLUMN `ccid`  varchar(36) NULL DEFAULT '' COMMENT 'create_change_id(uuid)' AFTER `crid`;
+ALTER TABLE `zh_revise_pos_1`
+ADD COLUMN `ccid`  varchar(36) NULL DEFAULT '' COMMENT 'create_change_id(uuid)' AFTER `crid`;
+ALTER TABLE `zh_revise_pos_2`
+ADD COLUMN `ccid`  varchar(36) NULL DEFAULT '' COMMENT 'create_change_id(uuid)' AFTER `crid`;
+ALTER TABLE `zh_revise_pos_3`
+ADD COLUMN `ccid`  varchar(36) NULL DEFAULT '' COMMENT 'create_change_id(uuid)' AFTER `crid`;
+ALTER TABLE `zh_revise_pos_4`
+ADD COLUMN `ccid`  varchar(36) NULL DEFAULT '' COMMENT 'create_change_id(uuid)' AFTER `crid`;
+ALTER TABLE `zh_revise_pos_5`
+ADD COLUMN `ccid`  varchar(36) NULL DEFAULT '' COMMENT 'create_change_id(uuid)' AFTER `crid`;
+ALTER TABLE `zh_revise_pos_6`
+ADD COLUMN `ccid`  varchar(36) NULL DEFAULT '' COMMENT 'create_change_id(uuid)' AFTER `crid`;
+ALTER TABLE `zh_revise_pos_7`
+ADD COLUMN `ccid`  varchar(36) NULL DEFAULT '' COMMENT 'create_change_id(uuid)' AFTER `crid`;
+ALTER TABLE `zh_revise_pos_8`
+ADD COLUMN `ccid`  varchar(36) NULL DEFAULT '' COMMENT 'create_change_id(uuid)' AFTER `crid`;
+ALTER TABLE `zh_revise_pos_9`
+ADD COLUMN `ccid`  varchar(36) NULL DEFAULT '' COMMENT 'create_change_id(uuid)' AFTER `crid`;
+ALTER TABLE `zh_revise_pos_10`
+ADD COLUMN `ccid`  varchar(36) NULL DEFAULT '' COMMENT 'create_change_id(uuid)' AFTER `crid`;
+ALTER TABLE `zh_revise_pos_11`
+ADD COLUMN `ccid`  varchar(36) NULL DEFAULT '' COMMENT 'create_change_id(uuid)' AFTER `crid`;
+ALTER TABLE `zh_revise_pos_12`
+ADD COLUMN `ccid`  varchar(36) NULL DEFAULT '' COMMENT 'create_change_id(uuid)' AFTER `crid`;
+ALTER TABLE `zh_revise_pos_13`
+ADD COLUMN `ccid`  varchar(36) NULL DEFAULT '' COMMENT 'create_change_id(uuid)' AFTER `crid`;
+ALTER TABLE `zh_revise_pos_14`
+ADD COLUMN `ccid`  varchar(36) NULL DEFAULT '' COMMENT 'create_change_id(uuid)' AFTER `crid`;
+ALTER TABLE `zh_revise_pos_15`
+ADD COLUMN `ccid`  varchar(36) NULL DEFAULT '' COMMENT 'create_change_id(uuid)' AFTER `crid`;
+ALTER TABLE `zh_revise_pos_16`
+ADD COLUMN `ccid`  varchar(36) NULL DEFAULT '' COMMENT 'create_change_id(uuid)' AFTER `crid`;
+ALTER TABLE `zh_revise_pos_17`
+ADD COLUMN `ccid`  varchar(36) NULL DEFAULT '' COMMENT 'create_change_id(uuid)' AFTER `crid`;
+ALTER TABLE `zh_revise_pos_18`
+ADD COLUMN `ccid`  varchar(36) NULL DEFAULT '' COMMENT 'create_change_id(uuid)' AFTER `crid`;
+ALTER TABLE `zh_revise_pos_19`
+ADD COLUMN `ccid`  varchar(36) NULL DEFAULT '' COMMENT 'create_change_id(uuid)' AFTER `crid`;
+
+ALTER TABLE `zh_stage_pay`
+ADD COLUMN `porder` tinyint(4) NOT NULL DEFAULT '0' COMMENT '排序' AFTER `sorder`;
+UPDATE zh_stage_pay sp LEFT JOIN zh_pay p ON sp.pid = p.id SET sp.porder = IF(ISNull(p.`order`), 0, p.`order`);
+
+ALTER TABLE `zh_change_ledger` ADD `formc` TINYINT(1) NOT NULL DEFAULT '1' COMMENT '是否为变更新增(用于区分台账)' AFTER `ccid`;
+ALTER TABLE `zh_change_pos` ADD `formc` TINYINT(1) NOT NULL DEFAULT '1' COMMENT '是否为变更新增(用于区分台账)' AFTER `ccid`;
+
+ALTER TABLE `zh_stage_audit` ADD `is_old` TINYINT(1) NOT NULL DEFAULT '0' COMMENT '是否为旧流程(用于管理员修改流程时旧数据保留但不影响新流程)' AFTER `opinion`;