Przeglądaj źródła

中间计量改版第一次提交

MaiXinRong 5 lat temu
rodzic
commit
8ff72af9a2

+ 1 - 0
app/const/tender.js

@@ -59,6 +59,7 @@ const measureType = {
 const imType = {
 const imType = {
     zl: { value: 0, name: '总量控制' },
     zl: { value: 0, name: '总量控制' },
     tz: { value: 1, name: '0号台账' },
     tz: { value: 1, name: '0号台账' },
+    bw: { value: 2, name: '清单部位' },
 };
 };
 
 
 const typeString = [];
 const typeString = [];

+ 105 - 24
app/controller/stage_controller.js

@@ -147,32 +147,33 @@ module.exports = app => {
                 const renderData = await this._getDefaultRenderData(ctx);
                 const renderData = await this._getDefaultRenderData(ctx);
                 [renderData.ledgerSpread, renderData.posSpread] = this._getSpreadSetting();
                 [renderData.ledgerSpread, renderData.posSpread] = this._getSpreadSetting();
                 renderData.changeConst = changeConst;
                 renderData.changeConst = changeConst;
-                renderData.ledgerData = await ctx.service.ledger.getData(ctx.tender.id);
-                const dgnData = await ctx.service.stageBillsDgn.getDgnData(ctx.tender.id);
-                for (const d of dgnData) {
-                    const l = ctx.app._.find(renderData.ledgerData, {id: d.id});
-                    ctx.app._.assignIn(l, d);
-                }
-                let curStageData, preStageData;
-                // 当前操作人查看最新数据,其他人查看历史数据
-                if (ctx.stage.readOnly) {
-                    curStageData = await ctx.service.stageBills.getAuditorStageData(ctx.tender.id, ctx.stage.id, ctx.stage.curTimes, ctx.stage.curOrder);
-                } else {
-                    curStageData = await ctx.service.stageBills.getLastestStageData(ctx.tender.id, ctx.stage.id);
-                }
-                // 查询截止上期数据
-                if (ctx.stage.order > 1) {
-                    preStageData = await ctx.service.stageBillsFinal.getFinalData(ctx.tender.data, ctx.stage.order - 1);
-                    //renderData.preStageData = await ctx.service.stageBills.getEndStageData(ctx.tender.id, ctx.stage.order - 1);
-                } else {
-                    preStageData = [];
-                }
-                this.ctx.helper.assignRelaData(renderData.ledgerData, [
-                    {data: curStageData, fields: ['contract_qty', 'contract_tp', 'qc_qty', 'qc_tp', 'postil'], prefix: '', relaId: 'lid',},
-                    {data: preStageData, fields: ['contract_qty', 'contract_tp', 'qc_qty', 'qc_tp'], prefix: 'pre_', relaId: 'lid',}
-                ]);
+                // renderData.ledgerData = await ctx.service.ledger.getData(ctx.tender.id);
+                // const dgnData = await ctx.service.stageBillsDgn.getDgnData(ctx.tender.id);
+                // for (const d of dgnData) {
+                //     const l = ctx.app._.find(renderData.ledgerData, {id: d.id});
+                //     ctx.app._.assignIn(l, d);
+                // }
+                // let curStageData, preStageData;
+                // // 当前操作人查看最新数据,其他人查看历史数据
+                // if (ctx.stage.readOnly) {
+                //     curStageData = await ctx.service.stageBills.getAuditorStageData(ctx.tender.id, ctx.stage.id, ctx.stage.curTimes, ctx.stage.curOrder);
+                // } else {
+                //     curStageData = await ctx.service.stageBills.getLastestStageData(ctx.tender.id, ctx.stage.id);
+                // }
+                // // 查询截止上期数据
+                // if (ctx.stage.order > 1) {
+                //     preStageData = await ctx.service.stageBillsFinal.getFinalData(ctx.tender.data, ctx.stage.order - 1);
+                //     //renderData.preStageData = await ctx.service.stageBills.getEndStageData(ctx.tender.id, ctx.stage.order - 1);
+                // } else {
+                //     preStageData = [];
+                // }
+                // this.ctx.helper.assignRelaData(renderData.ledgerData, [
+                //     {data: curStageData, fields: ['contract_qty', 'contract_tp', 'qc_qty', 'qc_tp', 'postil'], prefix: '', relaId: 'lid',},
+                //     {data: preStageData, fields: ['contract_qty', 'contract_tp', 'qc_qty', 'qc_tp'], prefix: 'pre_', relaId: 'lid',}
+                // ]);
                 renderData.jsFiles = this.app.jsFiles.common.concat(this.app.jsFiles.stage.index);
                 renderData.jsFiles = this.app.jsFiles.common.concat(this.app.jsFiles.stage.index);
                 renderData.whiteList = this.ctx.app.config.multipart.whitelist;
                 renderData.whiteList = this.ctx.app.config.multipart.whitelist;
+                renderData.imType = tenderConst.imType;
                 // 获取附件列表
                 // 获取附件列表
                 const attData = await ctx.service.stageAtt.getDataByTenderIdAndStageId(ctx.tender.id, ctx.params.order);
                 const attData = await ctx.service.stageAtt.getDataByTenderIdAndStageId(ctx.tender.id, ctx.params.order);
                 for (const index in attData) {
                 for (const index in attData) {
@@ -186,6 +187,86 @@ module.exports = app => {
             }
             }
         }
         }
 
 
+        async _getStageLedgerData(ctx) {
+            const ledgerData = await ctx.service.ledger.getData(ctx.tender.id);
+            const dgnData = await ctx.service.stageBillsDgn.getDgnData(ctx.tender.id);
+            for (const d of dgnData) {
+                const l = ctx.app._.find(ledgerData, {id: d.id});
+                ctx.app._.assignIn(l, d);
+            }
+            let curStageData, preStageData;
+            // 当前操作人查看最新数据,其他人查看历史数据
+            if (ctx.stage.readOnly) {
+                curStageData = await ctx.service.stageBills.getAuditorStageData(ctx.tender.id, ctx.stage.id, ctx.stage.curTimes, ctx.stage.curOrder);
+            } else {
+                curStageData = await ctx.service.stageBills.getLastestStageData(ctx.tender.id, ctx.stage.id);
+            }
+            // 查询截止上期数据
+            if (ctx.stage.order > 1) {
+                preStageData = await ctx.service.stageBillsFinal.getFinalData(ctx.tender.data, ctx.stage.order - 1);
+                //renderData.preStageData = await ctx.service.stageBills.getEndStageData(ctx.tender.id, ctx.stage.order - 1);
+            } else {
+                preStageData = [];
+            }
+            this.ctx.helper.assignRelaData(ledgerData, [
+                {data: curStageData, fields: ['contract_qty', 'contract_tp', 'qc_qty', 'qc_tp', 'postil'], prefix: '', relaId: 'lid',},
+                {data: preStageData, fields: ['contract_qty', 'contract_tp', 'qc_qty', 'qc_tp'], prefix: 'pre_', relaId: 'lid',}
+            ]);
+            return ledgerData;
+        }
+        async _getStagePosData(ctx) {
+            let curStageData, preStageData;
+            const posData = await ctx.service.pos.getPosDataWithAddStageOrder({tid: ctx.tender.id});
+            // 根据当前人,或指定对象查询数据
+            //console.time('cur');
+            if (ctx.stage.readOnly) {
+                curStageData = await ctx.service.stagePos.getAuditorStageData2(ctx.tender.id,
+                    ctx.stage.id, ctx.stage.curTimes, ctx.stage.curOrder);
+            } else {
+                curStageData = await ctx.service.stagePos.getLastestStageData2(ctx.tender.id, ctx.stage.id);
+            }
+            //console.timeEnd('cur');
+            // 查询截止上期数据
+            //console.time('pre');
+            if (ctx.stage.order > 1) {
+                preStageData = await ctx.service.stagePosFinal.getFinalData(ctx.tender.data, ctx.stage.order - 1);
+                //responseData.data.preStageData = await ctx.service.stagePos.getEndStageData(ctx.tender.id, ctx.stage.order - 1);
+            } else {
+                preStageData = [];
+            }
+            //console.timeEnd('pre');
+            //console.time('assign');
+            console.log('cur: ' + curStageData.length);
+            console.log('pre: ' + preStageData.length);
+            this.ctx.helper.assignRelaData(posData, [
+                {data: curStageData, fields: ['contract_qty', 'qc_qty', 'postil'], prefix: '', relaId: 'pid'},
+                {data: preStageData, fields: ['contract_qty', 'qc_qty'], prefix: 'pre_', relaId: 'pid'}
+            ]);
+            return posData;
+        }
+        async _getStageDetailData(ctx) {
+            if (ctx.stage.readOnly) {
+                return await ctx.service.stageDetail.getAuditorStageData(ctx.tender.id, ctx.stage.id, ctx.stage.curTimes, ctx.stage.curOrder);
+            } else {
+                return await ctx.service.stageDetail.getLastestStageData(ctx.tender.id, ctx.stage.id);
+            }
+        }
+
+        async getStageData(ctx) {
+            try {
+                const ledgerData = await this._getStageLedgerData(ctx);
+                const posData = await this._getStagePosData(ctx);
+                const detailData = await this._getStageDetailData(ctx);
+
+                ctx.body = {err: 0, msg: '', data: {
+                    ledgerData, posData, detailData
+                }};
+            } catch (err) {
+                this.log(err);
+                ctx.body = {err: 1, msg: err.toString(), data: null};
+            }
+        }
+
         /**
         /**
          * 获取期数据(截止上期 & 本期) (Ajax)
          * 获取期数据(截止上期 & 本期) (Ajax)
          * @param ctx
          * @param ctx

+ 12 - 0
app/public/css/main.css

@@ -92,6 +92,12 @@ font-size: .875rem;
 .sjs-height-4,.sjs-height-5,.sjs-height-6,.sjs-option-height{
 .sjs-height-4,.sjs-height-5,.sjs-height-6,.sjs-option-height{
   overflow: auto;
   overflow: auto;
 }
 }
+.sjs-bar-1,.sjs-bar-2,.sjs-bar-3,.sjs-bar-4{
+  height:30px;
+}
+.sjs-bar{
+  height:30px;
+}
 .sjs-bottom{
 .sjs-bottom{
   height:400px;
   height:400px;
   overflow-y: auto;
   overflow-y: auto;
@@ -728,6 +734,11 @@ body{
 }
 }
 label{
 label{
   margin-bottom:.3rem;
   margin-bottom:.3rem;
+  color:#757575;
+}
+.form-control-plaintext.form-control-lg, .form-control-plaintext.form-control-sm {
+  padding-left:.5rem;
+  background: #f2f2f280
 }
 }
 .invalid-feedback{
 .invalid-feedback{
   font-size:100%;
   font-size:100%;
@@ -786,6 +797,7 @@ label{
 }
 }
 .panel-content .panel-title{
 .panel-content .panel-title{
   padding-left:175px;
   padding-left:175px;
+  background: linear-gradient( #ccc,2%, #ffffff);
 }
 }
 .nav-link{
 .nav-link{
   padding:.3rem .5rem;
   padding:.3rem .5rem;

+ 2 - 4
app/public/js/global.js

@@ -21,11 +21,9 @@ function autoFlashHeight(){
     $(".sjs-height-0").height($(window).height()-cHeader-90+45);
     $(".sjs-height-0").height($(window).height()-cHeader-90+45);
     $(".sjs-height-1").height($(window).height()-cHeader-bcontent-90+45);
     $(".sjs-height-1").height($(window).height()-cHeader-bcontent-90+45);
     $(".sjs-height-2").height($(window).height()-cHeader-sBarz-110);
     $(".sjs-height-2").height($(window).height()-cHeader-sBarz-110);
-    $(".sjs-height-3").height($(window).height()-cHeader-sBar-492+15);
+    $(".sjs-height-3").height($(window).height()-cHeader-sBar-492+15);/*492*/
     $(".sjs-height-4").height($(window).height()-cHeader-pBarz-110+65);
     $(".sjs-height-4").height($(window).height()-cHeader-pBarz-110+65);
-    $(".sjs-height-5").height($(window).height()-cHeader-sBart-555);
-    $(".sjs-height-6").height($(window).height()-cHeader-bdtopc-156);
-    $(".sjs-height-7").height($(window).height()-cHeader-sBar-110);
+    $(".sjs-height-5").height($(window).height()-cHeader-sBar-492+45);/*492*/
     $(".sp-wrap").height(bcontent-40);
     $(".sp-wrap").height(bcontent-40);
     /*侧栏高度*/
     /*侧栏高度*/
     $(".sjs-sh-1").height($(window).height()-cHeader-sBar1-92+45);
     $(".sjs-sh-1").height($(window).height()-cHeader-sBar1-92+45);

+ 7 - 0
app/public/js/spreadjs_rela/spreadjs_zh.js

@@ -326,6 +326,13 @@ const SpreadJsObj = {
         sheet.getRange(0, 0, sheet.getRowCount(), sheet.getColumnCount()).locked(setting.readOnly);
         sheet.getRange(0, 0, sheet.getRowCount(), sheet.getColumnCount()).locked(setting.readOnly);
         this.endMassOperation(sheet);
         this.endMassOperation(sheet);
     },
     },
+    reLoadSheetHeader: function (sheet) {
+        if (sheet.zh_setting) {
+            this.beginMassOperation(sheet);
+            this._initSheetHeader(sheet);
+            this.endMassOperation(sheet);
+        }
+    },
     _loadRowData: function (sheet, data, row) {
     _loadRowData: function (sheet, data, row) {
         // 单元格重新写入数据
         // 单元格重新写入数据
         if (!data) { return }
         if (!data) { return }

+ 772 - 12
app/public/js/stage.js

@@ -128,6 +128,7 @@ function getNodeList(node) {
 }
 }
 
 
 $(document).ready(() => {
 $(document).ready(() => {
+    let detail;
     // 界面布局
     // 界面布局
     autoFlashHeight();
     autoFlashHeight();
     // 初始化 台账树结构 数据结构
     // 初始化 台账树结构 数据结构
@@ -319,6 +320,7 @@ $(document).ready(() => {
                     stageTreeSpreadObj.refreshTreeNodes(slSpread.getActiveSheet(), nodes);
                     stageTreeSpreadObj.refreshTreeNodes(slSpread.getActiveSheet(), nodes);
                     stagePosSpreadObj.loadCurPosData();
                     stagePosSpreadObj.loadCurPosData();
                     needCheckDetail();
                     needCheckDetail();
+                    detail.loadStageLedgerUpdateData(result);
                     self.obj.modal('hide');
                     self.obj.modal('hide');
                 });
                 });
             })
             })
@@ -459,15 +461,6 @@ $(document).ready(() => {
     };
     };
     SpreadJsObj.initSheet(slSpread.getActiveSheet(), ledgerSpreadSetting);
     SpreadJsObj.initSheet(slSpread.getActiveSheet(), ledgerSpreadSetting);
 
 
-    stageTree.loadDatas(ledgerData);
-    // stageTree.loadCurStageData(curStageData);
-    // stageTree.loadPreStageData(preStageData);
-    // 根据设置 计算 台账树结构
-    treeCalc.calculateAll(stageTree);
-    // 绘制界面
-    SpreadJsObj.loadSheetData(slSpread.getActiveSheet(), 'tree', stageTree);
-    SpreadJsObj.loadTopAndSelect(slSpread.getActiveSheet(), ckBillsSpread);
-
     //初始化所有附件列表
     //初始化所有附件列表
     getAllList();
     getAllList();
 
 
@@ -585,9 +578,13 @@ $(document).ready(() => {
                 }
                 }
 
 
                 postData(window.location.href + '/update', {bills: updateData}, function (data) {
                 postData(window.location.href + '/update', {bills: updateData}, function (data) {
+                    // tag update
                     const nodes = stageTree.loadPostStageData(data);
                     const nodes = stageTree.loadPostStageData(data);
                     stageTreeSpreadObj.refreshTreeNodes(slSpread.getActiveSheet(), nodes);
                     stageTreeSpreadObj.refreshTreeNodes(slSpread.getActiveSheet(), nodes);
                     needCheckDetail();
                     needCheckDetail();
+                    detail.loadStageLedgerUpdateData(data);
+                }, function () {
+                    SpreadJsObj.reLoadRowData(info.sheet, info.row);
                 });
                 });
             }
             }
         },
         },
@@ -658,6 +655,7 @@ $(document).ready(() => {
                         const nodes = stageTree.loadPostStageData(result);
                         const nodes = stageTree.loadPostStageData(result);
                         stageTreeSpreadObj.refreshTreeNodes(slSpread.getActiveSheet(), nodes);
                         stageTreeSpreadObj.refreshTreeNodes(slSpread.getActiveSheet(), nodes);
                         needCheckDetail();
                         needCheckDetail();
+                        detail.loadStageLedgerUpdateData(result);
                     });
                     });
                 }
                 }
             }
             }
@@ -761,6 +759,10 @@ $(document).ready(() => {
                         const nodes = stageTree.loadPostStageData(data);
                         const nodes = stageTree.loadPostStageData(data);
                         stageTreeSpreadObj.refreshTreeNodes(slSpread.getActiveSheet(), nodes.concat(filterNodes));
                         stageTreeSpreadObj.refreshTreeNodes(slSpread.getActiveSheet(), nodes.concat(filterNodes));
                         needCheckDetail();
                         needCheckDetail();
+                        detail.loadStageLedgerUpdateData(data);
+                    }, function () {
+                        // todo
+                        //stageTreeSpreadObj.refreshTreeNodes(slSpread.getActiveSheet(), filterNodes);
                     });
                     });
                 } else {
                 } else {
                     stageTreeSpreadObj.refreshTreeNodes(slSpread.getActiveSheet(), filterNodes);
                     stageTreeSpreadObj.refreshTreeNodes(slSpread.getActiveSheet(), filterNodes);
@@ -805,6 +807,7 @@ $(document).ready(() => {
                 stageTreeSpreadObj.refreshTreeNodes(slSpread.getActiveSheet(), nodes);
                 stageTreeSpreadObj.refreshTreeNodes(slSpread.getActiveSheet(), nodes);
                 stagePosSpreadObj.loadCurPosData();
                 stagePosSpreadObj.loadCurPosData();
                 needCheckDetail();
                 needCheckDetail();
+                detail.loadStagePosUpdateData(result);
                 toastr.success('已计量' + data.updateData.length + '条');
                 toastr.success('已计量' + data.updateData.length + '条');
             }, function () {
             }, function () {
                 stagePosSpreadObj.loadCurPosData();
                 stagePosSpreadObj.loadCurPosData();
@@ -1093,6 +1096,7 @@ $(document).ready(() => {
                     stageTreeSpreadObj.refreshTreeNodes(slSpread.getActiveSheet(), refreshData);
                     stageTreeSpreadObj.refreshTreeNodes(slSpread.getActiveSheet(), refreshData);
                     stagePosSpreadObj.loadCurPosData();
                     stagePosSpreadObj.loadCurPosData();
                     needCheckDetail();
                     needCheckDetail();
+                    detail.loadStagePosUpdateData(result);
                 }, function () {
                 }, function () {
                     stagePosSpreadObj.loadCurPosData();
                     stagePosSpreadObj.loadCurPosData();
                 });
                 });
@@ -1208,6 +1212,7 @@ $(document).ready(() => {
                     stageTreeSpreadObj.refreshTreeNodes(slSpread.getActiveSheet(), nodes);
                     stageTreeSpreadObj.refreshTreeNodes(slSpread.getActiveSheet(), nodes);
                     stagePosSpreadObj.loadCurPosData();
                     stagePosSpreadObj.loadCurPosData();
                     needCheckDetail();
                     needCheckDetail();
+                    detail.loadStagePosUpdateData(result);
                 }, function () {
                 }, function () {
                     stagePosSpreadObj.loadCurPosData();
                     stagePosSpreadObj.loadCurPosData();
                 });
                 });
@@ -1253,6 +1258,7 @@ $(document).ready(() => {
                         const nodes = stageTree.loadPostStageData(result.ledger);
                         const nodes = stageTree.loadPostStageData(result.ledger);
                         stageTreeSpreadObj.refreshTreeNodes(slSpread.getActiveSheet(), nodes);
                         stageTreeSpreadObj.refreshTreeNodes(slSpread.getActiveSheet(), nodes);
                         needCheckDetail();
                         needCheckDetail();
+                        detail.loadStagePosUpdateData(result);
                         // todo 只加载改变项
                         // todo 只加载改变项
                         stagePosSpreadObj.loadCurPosData();
                         stagePosSpreadObj.loadCurPosData();
                     });
                     });
@@ -1277,6 +1283,7 @@ $(document).ready(() => {
                         stageTreeSpreadObj.refreshTreeNodes(slSpread.getActiveSheet(), refreshData);
                         stageTreeSpreadObj.refreshTreeNodes(slSpread.getActiveSheet(), refreshData);
                         stagePosSpreadObj.loadCurPosData();
                         stagePosSpreadObj.loadCurPosData();
                         needCheckDetail();
                         needCheckDetail();
+                        detail.loadStagePosUpdateData(result);
                     });
                     });
                 }
                 }
             }
             }
@@ -1298,13 +1305,23 @@ $(document).ready(() => {
 
 
     // 加载计量单元数据 - 暂时统一加载,如有需要,切换成动态加载并缓存
     // 加载计量单元数据 - 暂时统一加载,如有需要,切换成动态加载并缓存
     console.time('loadPosFromServer');
     console.time('loadPosFromServer');
-    postData(window.location.pathname + '/pos', null, function (result) {
+    postData(window.location.pathname + '/load', null, function (result) {
         console.timeEnd('loadPosFromServer');
         console.timeEnd('loadPosFromServer');
-        console.log('pos: ' + result.length);
-        stagePos.loadDatas(result);
+        // 加载树结构
+        stageTree.loadDatas(result.ledgerData);
+        // stageTree.loadCurStageData(curStageData);
+        // stageTree.loadPreStageData(preStageData);
+        treeCalc.calculateAll(stageTree);
+        SpreadJsObj.loadSheetData(slSpread.getActiveSheet(), 'tree', stageTree);
+        SpreadJsObj.loadTopAndSelect(slSpread.getActiveSheet(), ckBillsSpread);
+        // 加载部位明细
+        stagePos.loadDatas(result.posData);
         stagePos.calculateAll();
         stagePos.calculateAll();
         stagePosSpreadObj.loadCurPosData();
         stagePosSpreadObj.loadCurPosData();
         SpreadJsObj.resetTopAndSelect(spSpread.getActiveSheet());
         SpreadJsObj.resetTopAndSelect(spSpread.getActiveSheet());
+        // 加载中间计量
+        stageIm.init(stage, imType);
+        stageIm.loadData(result.ledgerData, result.posData, result.detailData);
     }, null, true);
     }, null, true);
     spSpread.bind(spreadNS.Events.EditEnded, stagePosSpreadObj.editEnded);
     spSpread.bind(spreadNS.Events.EditEnded, stagePosSpreadObj.editEnded);
     spSpread.bind(spreadNS.Events.ClipboardPasting, stagePosSpreadObj.clipboardPasting);
     spSpread.bind(spreadNS.Events.ClipboardPasting, stagePosSpreadObj.clipboardPasting);
@@ -1736,6 +1753,745 @@ $(document).ready(() => {
             }
             }
         }
         }
     });
     });
+
+    class Detail {
+        constructor (obj) {
+            const self = this;
+            this.spreadSetting = {
+                cols: [
+                    {title: '编号', colSpan: '1', rowSpan: '1', field: 'code', hAlign: 0, width: 80, formatter: '@', readOnly: true},
+                    {title: '中间计量表号', colSpan: '1', rowSpan: '1', field: 'im_code', hAlign: 0, width: 150, formatter: '@', readOnly: true},
+                    {title: '交工证书/凭证号', colSpan: '1', rowSpan: '1', field: 'doc_code', hAlign: 0, width: 180, formatter: '@'},
+                    {title: '分部分项工程', colSpan: '1', rowSpan: '1', field: 'fbfx', hAlign: 0, width: 150, formatter: '@', readOnly: true},
+                    {
+                        title: stage.im_type === imType.tz.value ? '本期计量金额' : '本期计量数量',
+                        colSpan: '1', rowSpan: '1', field: 'jl', hAlign: 2, width: 220, formatter: '@', readOnly: true
+                    },
+                ],
+                headRows: 1,
+                emptyRows: 0,
+                headRowHeight: [32],
+                defaultRowHeight: 21,
+                headerFont: '12px 微软雅黑',
+                font: '12px 微软雅黑',
+                readOnly: readOnly,
+            };
+            this.spread = SpreadJsObj.createNewSpread(obj[0]);
+            this.sheet = this.spread.getActiveSheet();
+            this.spread.options.allowUserDragFill = true;
+            this.spread.options.defaultDragFillType = spreadNS.Fill.AutoFillType.fillSeries;
+            SpreadJsObj.initSheet(this.spread.getActiveSheet(), this.spreadSetting);
+
+            this.detailObj = {
+                selectionChanged: function (e, info) {
+                    self.reLoadDetailData();
+                },
+                editEnded: function(e, info) {
+                    if (info.sheet.zh_setting) {
+                        const col = info.sheet.zh_setting.cols[info.col];
+                        if (col.field !== 'doc_code') {
+                            SpreadJsObj.reLoadRowData(info.sheet, info.row);
+                            return;
+                        }
+                        const data = SpreadJsObj.getSelectObject(info.sheet);
+                        if (data) {
+                            const updateData = {lid: data.lid};
+                            if (data.uuid) {
+                                updateData.uuid = data.uuid;
+                            } else {
+                                updateData.code = data.code;
+                                updateData.name = data.name;
+                                updateData.unit = data.unit;
+                                updateData.unit_price = data.unit_price;
+                            }
+                            updateData.doc_code = info.editingText;
+                            postData(window.location.pathname + '/detail/save', updateData, function (result) {
+                                stageIm.loadUpdateDetailData(result);
+                                SpreadJsObj.reLoadRowData(info.sheet, info.row);
+                                needCheckDetail();
+                            }, function () {
+                                SpreadJsObj.reLoadRowData(info.sheet, info.row);
+                            });
+                        } else {
+                            SpreadJsObj.reLoadRowData(info.sheet, info.row);
+                        }
+                    }
+                },
+                clipboardPasted: function (e, info) {
+                    if (info.sheet.zh_setting && info.sheet.zh_data) {
+                        const col = info.sheet.zh_setting.cols[info.cellRange.col];
+                        if (info.cellRange.colCount > 1) {
+                            toastr.warning('请勿同时复制粘贴多列数据');
+                            SpreadJsObj.reLoadSheetData(paySpread.getActiveSheet());
+                            return;
+                        }
+                        if (col.field !== 'doc_code') {
+                            SpreadJsObj.reLoadSheetData(paySpread.getActiveSheet());
+                            return;
+                        }
+
+                        const datas = [];
+                        for (let iRow = 0; iRow < info.cellRange.rowCount; iRow++) {
+                            const curRow = info.cellRange.row + iRow;
+                            const data = info.sheet.zh_data[curRow];
+                            if (data) {
+                                const updateData = {lid: data.lid};
+                                if (data.uuid) {
+                                    updateData.uuid = data.uuid;
+                                } else {
+                                    updateData.code = data.code;
+                                    updateData.name = data.name;
+                                    updateData.unit = data.unit;
+                                    updateData.unit_price = data.unit_price;
+                                }
+                                updateData.doc_code = info.sheet.getText(curRow, info.cellRange.col).replace('\n', '');
+                                datas.push(updateData);
+                            }
+                        }
+                        if (datas.length > 0) {
+                            postData(window.location.pathname + '/detail/save', datas, function (result) {
+                                stageIm.loadUpdateDetailData(result);
+                                SpreadJsObj.reLoadRowData(info.sheet, info.cellRange.row, info.cellRange.rowCount);
+                                needCheckDetail();
+                            }, function () {
+                                SpreadJsObj.reLoadRowData(info.sheet, info.cellRange.row, info.cellRange.rowCount);
+                            })
+                        }
+                    }
+                },
+                deletePress: function (sheet) {
+                    if (sheet.zh_setting) {
+                        const datas = [];
+                        const sel = sheet.getSelections()[0];
+                        for (let iCol = sel.col; iCol < sel.col + sel.colCount; iCol++) {
+                            const col = sheet.zh_setting.cols[iCol];
+                            for (let iRow = sel.row; iRow < sel.row + sel.rowCount; iRow++) {
+                                const data = sheet.zh_data[iRow];
+                                if (col.field === 'doc_code') {
+                                    const updateData = {lid: data.lid};
+                                    if (data.uuid) {
+                                        updateData.uuid = data.uuid;
+                                        updateData.doc_code = null;
+                                        datas.push(updateData);
+                                    }
+                                }
+                            }
+                        }
+                        if (datas.length > 0) {
+                            postData(window.location.pathname + '/detail/save', datas, function (result) {
+                                stageIm.loadUpdateDetailData(result);
+                                SpreadJsObj.reLoadRowData(sheet, sel.row, sel.rowCount);
+                                needCheckDetail();
+                            }, function () {
+                                SpreadJsObj.reLoadRowData(sheet, sel.row, sel.rowCount);
+                            });
+                        }
+                    }
+                },
+                dragFillBlock: function (e, info) {
+                    info.cancel = true;
+                    if (!info.sheet.zh_setting || !info.sheet.zh_data) return;
+                    const sel = info.sheet.getSelections()[0];
+                    const col = info.sheet.zh_setting.cols[info.fillRange.col];
+                    if (info.fillRange.colCount > 1 || !sel || col.field !== 'doc_code') return;
+                    const text = info.sheet.getText(sel.row + sel.rowCount - 1, sel.col);
+                    if (text === '') return;
+
+                    const regRst = /(\d+)$/g.exec(text), datas = [];
+                    for (let iRow = 0; iRow < info.fillRange.rowCount; iRow++) {
+                        const curRow = info.fillRange.row + iRow;
+                        const data = info.sheet.zh_data[curRow];
+                        if (data) {
+                            const updateData = {lid: data.lid};
+                            if (data.uuid) {
+                                updateData.uuid = data.uuid;
+                            } else {
+                                updateData.code = data.code;
+                                updateData.name = data.name;
+                                updateData.unit = data.unit;
+                                updateData.unit_price = data.unit_price;
+                            }
+                            if (regRst) {
+                                updateData.doc_code = text.substr(0, regRst.index) + (parseInt(regRst[0]) + iRow + 1);
+                            } else {
+                                updateData.doc_code = text.replace('\n', '');
+                            }
+                            datas.push(updateData);
+                        }
+                    }
+                    if (datas.length > 0) {
+                        postData(window.location.pathname + '/detail/save', datas, function (result) {
+                            stageIm.loadUpdateDetailData(result);
+                            SpreadJsObj.reLoadRowData(info.sheet, info.fillRange.row, info.fillRange.rowCount);
+                            needCheckDetail();
+                        }, function () {
+                            SpreadJsObj.reLoadRowData(info.sheet, info.fillRange.row, info.fillRange.rowCount);
+                        })
+                    }
+                },
+            };
+
+            this.spread.bind(spreadNS.Events.SelectionChanged, this.detailObj.selectionChanged);
+            if (!readOnly) {
+                this.spread.bind(spreadNS.Events.EditEnded, this.detailObj.editEnded);
+                this.spread.bind(spreadNS.Events.ClipboardPasted, this.detailObj.clipboardPasted);
+                this.spread.bind(spreadNS.Events.DragFillBlock, this.detailObj.dragFillBlock);
+                SpreadJsObj.addDeleteBind(this.spread, this.detailObj.deletePress);
+            }
+
+            this._initImTypeSetRela();
+            this._initModifyDetail();
+            // 草图相关
+            this._initImageRela();
+            // $('#done-detail').click(function () {
+            //     postData(window.location.pathname + '/done', {}, function () {
+            //         needCheckDetail(false);
+            //         $('#done').modal('hide');
+            //     })
+            // });
+            this.reBuildImData();
+        }
+        _initImTypeSetRela() {
+            const self = this;
+            const gatherConfirmPopover = {
+                reBind: function (obj, eventName, fun) {
+                    obj.unbind(eventName);
+                    obj.bind(eventName, fun);
+                },
+                check: function (pos, hint, okCallback) {
+                    const confirmObj = $('#gather-confirm'), hintObj = $('#gather-confirm-hint');
+                    const okObj = $('#gather-confirm-ok'), cancelObj = $('#gather-confirm-cancel');
+                    this.reBind(cancelObj, 'click', function () {
+                        confirmObj.hide();
+                    });
+                    this.reBind(okObj, 'click', function () {
+                        okCallback();
+                        confirmObj.hide();
+                    });
+                    hintObj.text(hint);
+                    confirmObj.css("top", pos.y).css("left", pos.x).show();
+                }
+            };
+            this.gsTree = stageIm.getGsTree();
+
+            if (stage.im_type === imType.tz.value) {
+                $('#type-title-contract').text('本期合同计量金额');
+                $('#type-title-qc').text('本期变更计量金额');
+            } else {
+                $('#type-title-contract').text('本期合同计量数量');
+                $('#type-title-qc').text('本期变更计量数量');
+            }
+
+            // 选择中间计量模式
+            $('div[name="im-type"]').click(function () {
+                function chooseType(obj) {
+                    obj.style.cursor = 'default';
+                    $(obj).children().addClass('text-primary');
+                    $('h5', obj).prepend('<i class="fa fa-check pull-right"></i>');
+                }
+                function validType(obj) {
+                    obj.style.cursor = 'pointer';
+                    $(obj).children().removeClass('text-primary');
+                    $('i', obj).remove();
+                }
+                if (this.style.cursor === 'pointer') {
+                    const typeArr = $('div[name="im-type"]');
+                    for (const t of typeArr) {
+                        if ($(t).attr('im-type') === $(this).attr('im-type')) {
+                            chooseType(t);
+                        } else {
+                            validType(t)
+                        }
+                    }
+                }
+            });
+            $('#choose').on('show.bs.modal', function () {
+                function chooseType(obj) {
+                    obj.style.cursor = 'default';
+                    $(obj).children().addClass('text-primary');
+                    $('i', obj).remove();
+                    $('h5', obj).prepend('<i class="fa fa-check pull-right"></i>');
+                }
+                function validType(obj) {
+                    obj.style.cursor = 'pointer';
+                    $(obj).children().removeClass('text-primary');
+                    $('i', obj).remove();
+                }
+                $('#im-pre').val(stage.im_pre ? stage.im_pre : '');
+                const typeArr = $('div[name="im-type"]');
+                for (const t of typeArr) {
+                    if (parseInt($(t).attr('im-type')) === stage.im_type) {
+                        chooseType(t);
+                    } else {
+                        validType(t)
+                    }
+                }
+            });
+            // 提交 中间计量模式
+            $('#choose-ok').click(() => {
+                const chooseType = _.find($('div[name="im-type"]', '#im-type'), function (it) {
+                    return it.style.cursor !== 'pointer';
+                });
+                const data = {
+                    im_type: parseInt($(chooseType).attr('im-type')),
+                    im_pre: $('#im-pre').val(),
+                };
+                postData(window.location.pathname + '/detail/build', data, function (result) {
+                    stage.im_type = data.im_type;
+                    stage.im_pre = data.im_pre;
+                    needCheckDetail();
+                    if (stage.im_type === imType.tz.value) {
+                        const jlCol = self.spreadSetting.cols.find(function (x) {return x.field === 'jl'});
+                        jlCol.title = '本期计量金额';
+                        SpreadJsObj.reLoadSheetHeader(self.sheet);
+                        $('#type-title-contract').text('本期合同计量金额');
+                        $('#type-title-qc').text('本期变更计量金额');
+                    } else {
+                        const jlCol = self.spreadSetting.cols.find(function (x) {return x.field === 'jl'});
+                        jlCol.title = '本期计量金额';
+                        SpreadJsObj.reLoadSheetHeader(self.sheet);
+                        $('#type-title-contract').text('本期合同计量数量');
+                        $('#type-title-qc').text('本期变更计量数量');
+                    }
+                    // 加载生成数据
+                    self.reBuildImData();
+                    $('#choose').modal('hide');
+                });
+            });
+            // 显示树结构信息
+            $('#choose2').on('shown.bs.modal', function () {
+                if (!self.gsSpread) {
+                    self.gsSpread = SpreadJsObj.createNewSpread($('#im-gather-spread')[0]);
+                    SpreadJsObj.initSheet(self.gsSpread.getActiveSheet(), {
+                        cols: [
+                            {title: '计量\n汇总', colSpan: '1', rowSpan: '1', field: 'check', hAlign: 1, width: 50, formatter: '@', readOnly: true, cellType: 'checkbox'},
+                            {title: '项目节编号', colSpan: '1', rowSpan: '1', field: 'code', hAlign: 0, width: 150, formatter: '@', readOnly: true, cellType: 'tree'},
+                            {title: '清单编号', colSpan: '1', rowSpan: '1', field: 'b_code', hAlign: 0, width: 80, formatter: '@', readOnly: true},
+                            {title: '名称', colSpan: '1', rowSpan: '1', field: 'name', hAlign: 0, width: 230, formatter: '@', readOnly: true},
+                            {title: '单位', colSpan: '1', rowSpan: '1', field: 'unit', hAlign: 1, width: 60, formatter: '@', readOnly: true},
+                        ],
+                        headRows: 1,
+                        emptyRows: 0,
+                        headRowHeight: [32],
+                        defaultRowHeight: 21,
+                        headerFont: '12px 微软雅黑',
+                        font: '12px 微软雅黑',
+                    });
+                    self.gsSpread.bind(spreadNS.Events.ButtonClicked, function (e, info) {
+                        function checkParent(node) {
+                            const parent = self.gsTree.getParent(node);
+                            if (parent) {
+                                return parent.check ? parent.check : checkParent(parent);
+                            } else {
+                                return false;
+                            }
+                        }
+
+                        function checkChildren(node) {
+                            for (const child of node.children) {
+                                if (child.check) {
+                                    return true;
+                                } else if (checkChildren(child)) {
+                                    return true;
+                                }
+                            }
+                            return false;
+                        }
+
+                        if (!$('#im-gather-check')[0].checked) { return; }
+
+                        const sheet = info.sheet, cellType = sheet.getCellType(info.row, info.col);
+                        if (cellType instanceof  spreadNS.CellTypes.CheckBox) {
+                            if (sheet.isEditing()) {
+                                sheet.endEdit(true);
+                            }
+                        }
+                        if (info.sheet.zh_setting) {
+                            const col = info.sheet.zh_setting.cols[info.col];
+                            if (col.field !== 'check') {
+                                return;
+                            }
+
+                            const sortData = info.sheet.zh_dataType === 'tree' ? info.sheet.zh_tree.nodes : info.sheet.zh_data;
+                            const node = sortData[info.row];
+                            if (!node.check) {
+                                if (checkParent(node)) {
+                                    const rect = info.sheet.getCellRect(info.row, info.col);
+                                    gatherConfirmPopover.check({
+                                        x: rect.x + rect.width / 2 + 25,
+                                        y: rect.y + rect.height / 2 + 3,
+                                    }, '父项已勾选,继续将取消父项勾选。', function () {
+                                        node.check = true;
+                                        const parents = self.gsTree.getFullPathNodes(self.gsTree.getParent(node).full_path);
+                                        const rows = [self.gsTree.nodes.indexOf(node)];
+                                        for (const p of parents) {
+                                            if (p.check) {
+                                                p.check = false;
+                                                rows.push(self.gsTree.nodes.indexOf(p));
+                                            }
+                                        }
+                                        SpreadJsObj.reLoadRowsData(info.sheet, rows);
+                                    });
+                                } else if (checkChildren(node)) {
+                                    const rect = info.sheet.getCellRect(info.row, info.col);
+                                    gatherConfirmPopover.check({
+                                        x: rect.x + rect.width / 2 + 25,
+                                        y: rect.y + rect.height / 2 + 3,
+                                    }, '子项已勾选,继续将取消子项勾选。', function () {
+                                        node.check = true;
+                                        const posterity = self.gsTree.getPosterity(node);
+                                        const rows = [self.gsTree.nodes.indexOf(node)];
+                                        for (const p of posterity) {
+                                            if (p.check) {
+                                                rows.push(self.gsTree.nodes.indexOf(p));
+                                                p.check = false;
+                                            }
+                                        }
+                                        SpreadJsObj.reLoadRowsData(info.sheet, rows);
+                                    });
+                                } else {
+                                    node.check = true;
+                                    SpreadJsObj.reLoadRowsData(info.sheet, [self.gsTree.nodes.indexOf(node)]);
+                                }
+                            } else {
+                                node.check = false;
+                                SpreadJsObj.reLoadRowsData(info.sheet, [self.gsTree.nodes.indexOf(node)]);
+                            }
+                        }
+                    });
+                    const gatherNodes = stage.im_gather_node ? _.map(stage.im_gather_node.split(',')) : [];
+                    for (const node of self.gsTree.datas) {
+                        node.check = gatherNodes.indexOf(node.id + '') !== -1;
+                    }
+                    SpreadJsObj.loadSheetData(self.gsSpread.getActiveSheet(), SpreadJsObj.DataType.Tree, self.gsTree);
+                    self.gsTree.expandByLevel(4);
+                    SpreadJsObj.refreshTreeRowVisible(self.gsSpread.getActiveSheet());
+                    SpreadJsObj.resetFieldReadOnly(self.gsSpread.getActiveSheet, 'check', !$('#im-gather-check')[0].checked);
+                } else {
+                    const gatherNodes = stage.im_gather_node ? _.map(stage.im_gather_node.split(',')) : [];
+                    for (const node of self.gsTree.datas) {
+                        node.check = gatherNodes.indexOf(node.id + '') !== -1;
+                    }
+                    SpreadJsObj.reLoadColsData(self.gsSpread.getActiveSheet(), [0]);
+                }
+            });
+            // 提交 高级设置
+            $('#choose2-ok').click(() => {
+                if (!self.gsTree) { return; }
+                const nodes = [];
+                for (const node of self.gsTree.datas) {
+                    if (node.check) {
+                        nodes.push(node.id);
+                    }
+                }
+                const data = {
+                    im_gather: $('#im-gather-check')[0].checked,
+                    im_gather_node: nodes.join(','),
+                };
+                postData(window.location.pathname + '/detail/adv', data, function (result) {
+                    stage.im_gather = data.im_gather;
+                    stage.im_gather_node = data.im_gather_node;
+                    needCheckDetail();
+                    $('#choose2').modal('hide');
+                });
+            });
+        }
+        _initModifyDetail() {
+            const self = this;
+            // 编辑
+            $('#edit-detail').click(function () {
+                $(this).hide();
+                $('#save-detail').show();
+                $('#cancel-detail').show();
+                $('#detail-show').hide();
+                $('#detail-edit').show();
+            });
+            // 保存
+            $('#save-detail').click(() => {
+                function check(field, obj, org, update) {
+                    const newValue = obj.val();
+                    if (!org[field]) {
+                        if (newValue !== '') {
+                            update[field] = newValue;
+                        }
+                    } else if (newValue !== org[field]){
+                        update[field] = newValue;
+                    }
+                }
+
+                const data = SpreadJsObj.getSelectObject(self.spread.getActiveSheet());
+                const updateData = {lid: data.lid};
+                if (data.uuid) {
+                    updateData.uuid = data.uuid;
+                } else {
+                    updateData.code = data.code;
+                    updateData.name = data.name;
+                    updateData.unit = data.unit;
+                    updateData.unit_price = data.unit_price;
+                }
+                updateData.bgl_code = $('#bgl-code').val();
+                updateData.bw = $('#bw-name').val();
+                updateData.start_peg = $('#start-peg').val();
+                updateData.end_peg = $('#end-peg').val();
+                updateData.jldy = $('#unit-name').val();
+                updateData.drawing_code = $('#drawing-code').val();
+                updateData.calc_memo = $('#calc-memo').val();
+                postData(window.location.pathname + '/detail/save', updateData, function (result) {
+                    _.assign(data, result);
+                    $('#edit-detail').show();
+                    $('#save-detail').hide();
+                    $('#cancel-detail').hide();
+                    self.reLoadDetailData();
+                    needCheckDetail();
+                });
+            });
+            // 取消
+            $('#cancel-detail').click(() => {
+                $('#edit-detail').show();
+                $('#cancel-detail').hide();
+                $('#save-detail').hide();
+                self.reLoadDetailData();
+            });
+        }
+        _initImageRela() {
+            const self = this;
+            function setdraggrable(){
+                $( ".img-item" ).draggable({ containment: "parent" },{stop: function( event, ui ) {
+                    }}).resizable({ containment: "parent" },{ handles: 'n, e, s, w, ne, se, sw, nw' },{ maxWidth: parseFloat($('#imgwidth').val())},{maxHeight: parseFloat($('#imgheight').val())},{
+                    stop: function( event, ui ) {
+                    }
+                });
+            }
+            // 移动图片
+            const moveImageItem = function (ev) {
+                const item = this;
+                const view = $('.img-view')[0];
+                let oEvent = ev;
+                // 浏览器有一些图片的默认事件,这里要阻止
+                oEvent.preventDefault();
+                let disX = oEvent.clientX - item.offsetLeft;
+                let disY = oEvent.clientY - item.offsetTop;
+                view.onmousemove = function (ev) {
+                    oEvent = ev;
+                    oEvent.preventDefault();
+                    let x = oEvent.clientX -disX;
+                    let y = oEvent.clientY -disY;
+
+                    // 图形移动的边界判断
+                    x = x <= 0 ? 0 : x;
+                    x = x >= view.offsetWidth - item.offsetWidth ? view.offsetWidth - item.offsetWidth : x;
+                    y = y <= 0 ? 0 : y;
+                    y = y >= view.offsetHeight - item.offsetHeight ? view.offsetHeight - item.offsetHeight : y;
+                    item.style.left = x + 'px';
+                    item.style.top = y + 'px';
+                };
+                // 图形移出父盒子取消移动事件,防止移动过快触发鼠标移出事件,导致鼠标弹起事件失效
+                view.onmouseleave = function () {
+                    view.onmousemove = null;
+                    view.onmouseup = null;
+                };
+                // 鼠标弹起后停止移动
+                view.onmouseup=function() {
+                    view.onmousemove = null;
+                    view.onmouseup = null;
+                };
+            };
+            const removeImageItem = function () {
+                $(this).parent().remove();
+            };
+            // 加载草图组成
+            $('#edit-img').on('show.bs.modal', function () {
+                const data = SpreadJsObj.getSelectObject(self.spread.getActiveSheet());
+                const items = data.calc_img_org ? JSON.parse(data.calc_img_org) : [];
+                const html = [];
+                for (const item of items) {
+                    const itemStyle = 'top:' + item.top + ';' + 'left:' + item.left + ';' + 'width:' + item.width + ';' + 'height:' + item.height + ';';
+                    html.push('<div class="img-item" style="' + itemStyle + '">');
+                    html.push('<div class="img-bar">');
+                    html.push('<a href="javascript: void(0);" class="text-danger" title="删除"><i class="fa fa-remove"></i></a>');
+                    html.push('</div>');
+                    html.push('<div class="focus" style="width:100%; height:100%"><img src="', item.src, '" id="draggable" style="width:100%; height:100%"></div>');
+                    html.push('</div>');
+                }
+                $('.img-view').html(html.join(''));
+                $('.img-bar').click(removeImageItem);
+                setdraggrable();
+            });
+            // 上传图片
+            $('#upload-img').click(function () {
+                $('#upload-img-file').trigger('click');
+            });
+            $('#upload-img-file').change(function () {
+                const file = this.files[0];
+                const ext = file.name.toLowerCase().split('.').splice(-1)[0];
+                const imgStr = /(jpg|jpeg|png|bmp|BMP|JPG|PNG|JPEG)$/;
+                if (!imgStr.test(ext)) {
+                    toastr.error('请上传正确的图片格式文件');
+                    return
+                }
+                if ($(this).val()) {
+                    const formData = new FormData();
+                    formData.append('file', this.files[0]);
+                    postDataWithFile(window.location.pathname + '/detail/add-img', formData, function (result) {
+                        const html = [];
+                        html.push('<div class="img-item">');
+                        html.push('<div class="img-bar">');
+                        html.push('<a href="javascript: void(0);" class="text-danger" title="删除"><i class="fa fa-remove"></i></a>');
+                        html.push('</div>');
+                        html.push('<div class="focus" style="width:100%; height:100%"><img src="', '/' + result, '" id="draggable" style="width:100%; height:100%"></div>');
+                        html.push('</div>');
+                        $('.img-view').append(html.join(''));
+                        $('.img-bar').click(removeImageItem);
+                        setdraggrable();
+                        needCheckDetail();
+                    });
+                }
+            });
+
+            // 保存草图修改结果
+            $('#edit-img-ok').click(function () {
+                // 记录上传的图片的信息
+                const items = $('.img-item');
+                const data = SpreadJsObj.getSelectObject(self.spread.getActiveSheet());
+                if (items.length > 0) {
+                    const itemInfo = [];
+                    for (const item of items) {
+                        const itemData = {
+                            src: $('img', item).attr('src'),
+                            left: item.style.left,
+                            top: item.style.top,
+                            width: item.style.width,
+                            height: item.style.height,
+                        };
+                        itemInfo.push(itemData);
+                    }
+                    // 获取合并好的图片数据
+                    const canvas = document.createElement('canvas');
+                    const view = $('.img-view')[0];
+                    canvas.height = view.clientHeight;
+                    canvas.width = view.clientWidth;
+                    const ctx = canvas.getContext('2d');
+                    ctx.fillStyle = '#ffffff';
+                    ctx.fillRect(0, 0, canvas.width, canvas.height);
+                    for (const b of $('.img-item')) {
+                        const pos = $(b).position();
+                        const img = $('img', b)[0];
+                        ctx.drawImage(img, pos.left, pos.top, img.width, img.height);
+                    }
+                    // 生成上传数据
+                    const updateData = {updateType: 'update', lid: data.lid};
+                    if (data.uuid) {
+                        updateData.uuid = data.uuid;
+                    } else {
+                        updateData.code = data.code;
+                        updateData.name = data.name;
+                        updateData.unit = data.unit;
+                        updateData.unit_price = data.unit_price;
+                    }
+                    updateData.img = canvas.toDataURL('image/jpeg');
+                    updateData.imgInfo = itemInfo;
+                    postData(window.location.pathname + '/detail/merge-img', updateData, function (result) {
+                        _.assign(data, result);
+                        self.reLoadDetailData();
+                        $('#edit-img').modal('hide');
+                        needCheckDetail();
+                    });
+                } else if (data.calc_img) {
+                    postData(window.location.pathname + '/detail/merge-img', {updateType: 'clear', lid: data.lid, uuid: data.uuid}, function (result) {
+                        _.assign(data, result);
+                        self.reLoadDetailData();
+                        $('#edit-img').modal('hide');
+                        needCheckDetail();
+                    });
+                }
+            });
+        }
+        reBuildImData() {
+            const imData = stageIm.buildImData();
+            SpreadJsObj.loadSheetData(this.sheet, SpreadJsObj.DataType.Data, imData);
+            this.reLoadDetailData();
+        }
+        loadStageLedgerUpdateData(data) {
+            const imData = stageIm.loadUpdateLedgerData(data);
+            SpreadJsObj.loadSheetData(this.sheet, SpreadJsObj.DataType.Data, imData);
+            this.reLoadDetailData();
+        }
+        loadStagePosUpdateData(data) {
+            const imData = stageIm.loadUpdatePosData(data);
+            SpreadJsObj.loadSheetData(this.sheet, SpreadJsObj.DataType.Data, imData);
+            this.reLoadDetailData();
+        }
+        reLoadDetailData() {
+            const data = SpreadJsObj.getSelectObject(this.spread.getActiveSheet());
+
+            if (data) {
+                $('#edit-detail').show();
+                $('#modify-img').show();
+            } else {
+                $('#edit-detail').hide();
+                $('#modify-img').hide();
+            }
+            $('#save-detail').hide();
+            $('#cancel-detail').hide();
+
+            $('#detail-show').show();
+            $('#detail-edit').hide();
+
+            const contractJl = data && data.contract_jl ? data.contract_jl : '';
+            $('#show-contract-jl').text(contractJl);
+            $('#contract-jl').val(contractJl);
+
+            const qcJl = data && data.qc_jl ? data.qc_jl : '';
+            $('#show-qc-jl').text(qcJl);
+            $('#qc-jl').val(qcJl);
+
+            const bglCode = data && data.bgl_code ? data.bgl_code : '';
+            $('#show-bgl-code').text(bglCode);
+            $('#bgl-code').val(bglCode);
+
+            const bwName = data && data.bw ? data.bw : '';
+            $('#show-bw-name').text(bwName);
+            $('#bw-name').val(bwName);
+
+            const peg = data && data.peg ? data.peg : '';
+            $('#show-peg').text(peg);
+            $('#peg').val(peg);
+
+            const xmjName = data && data.leaf_xmj_name ? data.leaf_xmj_name: '';
+            $('#show-xmj-name').text(xmjName);
+            $('#xmj-name').val(xmjName);
+
+            const drawingCode = data && data.drawing_code ? data.drawing_code: '';
+            $('#show-drawing-code').text(drawingCode);
+            $('#drawing-code').val(drawingCode);
+
+            const calcMemo = data && data.calc_memo ? data.calc_memo: '';
+            $('#show-calc-memo').html(calcMemo.replace('\n', '<br/>'));
+            $('#calc-memo').val(calcMemo);
+
+            const calcImgSrc = data && data.calc_img ? '/' + data.calc_img : '';
+            $('#show-calc-img').attr('src', calcImgSrc);
+            $('#calc-img').attr('src', calcImgSrc);
+            $('#view-calc-img').attr('src', calcImgSrc);
+        }
+        // needCheckDetail(check = true) {
+        //     if (check) {
+        //         stage.check_detail = true;
+        //         $('#check_point').show();
+        //         $('#check-detail').show();
+        //         $('#sub-sp-btn').attr('data-target', '#sub-sp3');
+        //         $('#sp-done-btn').attr('data-target', '#sub-sp3');
+        //         $('#sp-list2-btn').attr('data-target', '#sub-sp3');
+        //     } else {
+        //         stage.check_detail = false;
+        //         $('#check_point').hide();
+        //         $('#check-detail').hide();
+        //         $('#sub-sp-btn').attr('data-target', '#sub-sp');
+        //         $('#sp-done-btn').attr('data-target', '#sp-done');
+        //         $('#sp-list2-btn').attr('data-target', '#sp-list2');
+        //     }
+        // }
+    }
     // 展开收起附件
     // 展开收起附件
     $('a', '.right-nav').bind('click', function () {
     $('a', '.right-nav').bind('click', function () {
         //const main = $('#main-view'), tool = $('#tools-view');
         //const main = $('#main-view'), tool = $('#tools-view');
@@ -1777,6 +2533,10 @@ $(document).ready(() => {
                 const node = SpreadJsObj.getSelectObject(slSpread.getActiveSheet());
                 const node = SpreadJsObj.getSelectObject(slSpread.getActiveSheet());
                 getNodeList(node.id);
                 getNodeList(node.id);
             }
             }
+            if (tab.attr('content') === '#zhongjian') {
+                detail = new Detail($('#detail-spread'));
+                detail.spread.refresh();
+            }
         } else {
         } else {
             tab.removeClass('active');
             tab.removeClass('active');
             tabPanel.removeClass('active');
             tabPanel.removeClass('active');

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

@@ -148,7 +148,7 @@ $(document).ready(() => {
                 }
                 }
                 const data = SpreadJsObj.getSelectObject(info.sheet);
                 const data = SpreadJsObj.getSelectObject(info.sheet);
                 if (data) {
                 if (data) {
-                    const updateData = {lid: data.lid}
+                    const updateData = {lid: data.lid};
                     if (data.uuid) {
                     if (data.uuid) {
                         updateData.uuid = data.uuid;
                         updateData.uuid = data.uuid;
                     } else {
                     } else {

+ 25 - 3
app/public/js/stage_im.js

@@ -186,7 +186,7 @@ const stageIm = (function () {
             if (!p.gather_qty || checkZero(p.gather_qty)) { continue; }
             if (!p.gather_qty || checkZero(p.gather_qty)) { continue; }
             let lp = _.find(lx.pos, {name: p.name});
             let lp = _.find(lx.pos, {name: p.name});
             if (!lp) {
             if (!lp) {
-                lp = {name: p.name, qty: p.quantity};
+                lp = {name: p.name, qty: p.gather_qty};
                 lx.pos.push(lp);
                 lx.pos.push(lp);
             }
             }
             lp.jl = ZhCalc.add(lp.jl, p.gather_qty);
             lp.jl = ZhCalc.add(lp.jl, p.gather_qty);
@@ -239,6 +239,8 @@ const stageIm = (function () {
                 lid: node.id,
                 lid: node.id,
                 code: node.code,
                 code: node.code,
                 jl: node.gather_tp,
                 jl: node.gather_tp,
+                contract_jl: node.contract_tp,
+                qc_jl: node.qc_tp,
                 im_code: getNewImCode(),
                 im_code: getNewImCode(),
                 fbfx: getFbfx(node, peg),
                 fbfx: getFbfx(node, peg),
                 peg: peg ? peg.name : '',
                 peg: peg ? peg.name : '',
@@ -248,7 +250,6 @@ const stageIm = (function () {
                 im.bw = node.name;
                 im.bw = node.name;
             } else {
             } else {
                 im.jldy = node.name;
                 im.jldy = node.name;
-                // to do
                 im.bw = node.name
                 im.bw = node.name
             }
             }
             checkCustomDetail(im);
             checkCustomDetail(im);
@@ -279,6 +280,8 @@ const stageIm = (function () {
                     unit: p.unit,
                     unit: p.unit,
                     unit_price: p.unit_price,
                     unit_price: p.unit_price,
                     jl: 0,
                     jl: 0,
+                    contract_jl: 0,
+                    qc_jl: 0,
                     im_code: getNewImCode(),
                     im_code: getNewImCode(),
                     fbfx: getFbfx(node, peg),
                     fbfx: getFbfx(node, peg),
                     peg: peg ? peg.name : '',
                     peg: peg ? peg.name : '',
@@ -296,6 +299,8 @@ const stageIm = (function () {
             }
             }
             generateLeafXmjData(p, im, 'gather_qty');
             generateLeafXmjData(p, im, 'gather_qty');
             im.jl = ZhCalc.add(im.jl, p.gather_qty);
             im.jl = ZhCalc.add(im.jl, p.gather_qty);
+            im.contract_jl = ZhCalc.add(im.contract_jl, p.contract_qty);
+            im.qc_jl = ZhCalc.add(im.qc_jl, p.qc_qty);
         }
         }
     }
     }
 
 
@@ -333,6 +338,9 @@ const stageIm = (function () {
         recursiveBuildImData(gsTree.children);
         recursiveBuildImData(gsTree.children);
         for (const im of ImData) {
         for (const im of ImData) {
             im.calc_memo = getCalcMemo(im);
             im.calc_memo = getCalcMemo(im);
+            if (im.leafXmjs && im.leafXmjs.length === 1) {
+                im.leaf_xmj_name = im.leafXmjs[0].name;
+            }
         }
         }
         return ImData;
         return ImData;
     }
     }
@@ -358,18 +366,32 @@ const stageIm = (function () {
         }
         }
     }
     }
 
 
+    function loadUpdateLedgerData(data) {
+        gsTree.loadPostStageData(data);
+        return buildImData();
+    }
+    function loadUpdatePosData(data) {
+        if (data.pos) {
+            gsPos.updateDatas(data.pos.pos);
+            gsPos.loadCurStageData(data.pos.curStageData);
+        }
+        gsTree.loadPostStageData(data.ledger);
+        return buildImData();
+    }
+
     return {
     return {
         init,
         init,
         initCheck,
         initCheck,
         loadData,
         loadData,
         buildImData,
         buildImData,
         loadUpdateDetailData,
         loadUpdateDetailData,
+        loadUpdateLedgerData,
+        loadUpdatePosData,
         getGsTree: function () {
         getGsTree: function () {
             return gsTree;
             return gsTree;
         },
         },
         getImData: function () {
         getImData: function () {
             return ImData;
             return ImData;
         },
         },
-
     }
     }
 })();
 })();

+ 1 - 0
app/router.js

@@ -141,6 +141,7 @@ module.exports = app => {
     // 期计量详细
     // 期计量详细
     // 本期计量台账
     // 本期计量台账
     app.get('/tender/:id/measure/stage/:order', sessionAuth, tenderCheck, stageCheck, 'stageController.index');
     app.get('/tender/:id/measure/stage/:order', sessionAuth, tenderCheck, stageCheck, 'stageController.index');
+    app.post('/tender/:id/measure/stage/:order/load', sessionAuth, tenderCheck, stageCheck, 'stageController.getStageData');
     app.post('/tender/:id/measure/stage/:order/pos', sessionAuth, tenderCheck, stageCheck, 'stageController.getStagePosData');
     app.post('/tender/:id/measure/stage/:order/pos', sessionAuth, tenderCheck, stageCheck, 'stageController.getStagePosData');
     app.post('/tender/:id/measure/stage/:order/update', sessionAuth, tenderCheck, stageCheck, 'stageController.updateStageData');
     app.post('/tender/:id/measure/stage/:order/update', sessionAuth, tenderCheck, stageCheck, 'stageController.updateStageData');
     app.post('/tender/:id/measure/stage/:order/valid-change', sessionAuth, tenderCheck, stageCheck, 'stageController.searchValidChange');
     app.post('/tender/:id/measure/stage/:order/valid-change', sessionAuth, tenderCheck, stageCheck, 'stageController.searchValidChange');

Plik diff jest za duży
+ 257 - 2
app/view/stage/index.ejs


+ 172 - 23
app/view/stage/modal.ejs

@@ -197,6 +197,122 @@
         </div>
         </div>
     </div>
     </div>
 </div>
 </div>
+<!--上传附件-->
+<div class="modal fade" id="upload" data-backdrop="static">
+    <div class="modal-dialog" role="document">
+        <div class="modal-content">
+            <div class="modal-header">
+                <h5 class="modal-title">上传附件</h5>
+            </div>
+            <div class="modal-body">
+                <div class="form-group">
+                    <label for="formGroupExampleInput">大小限制:10MB,支持<span data-toggle="tooltip" data-placement="bottom" title="" data-original-title="doc,docx,xls,xlsx,ppt,pptx,pdf">office等文档格式</span>、<span data-toggle="tooltip" data-placement="bottom" title="" data-original-title="jpg,png,bmp">图片格式</span>、<span data-toggle="tooltip" data-placement="bottom" title="" data-original-title="rar,zip">压缩包格式</span></label>
+                    <input type="file" class="form-control form-control-sm" id="upload-file" multiple>
+                </div>
+            </div>
+            <div class="modal-footer">
+                <button type="button" class="btn btn-secondary btn-sm" data-dismiss="modal">关闭</button>
+                <button type="button" class="btn btn-primary btn-sm" id="upload-file-btn">确认</button>
+            </div>
+        </div>
+    </div>
+</div>
+
+<%%>
+<!--正在修订提示-->
+<div class="modal fade" id="unedit" data-backdrop="static">
+    <div class="modal-dialog " role="document" >
+        <div class="modal-content">
+            <div class="modal-header">
+                <h5 class="modal-title">提示</h5>
+            </div>
+            <div class="modal-body">
+                <h5>台帐正在进行修订,本期计量无法进行任何操作。</h5>
+            </div>
+            <div class="modal-footer">
+                <button type="button" class="btn btn-secondary" data-dismiss="modal">好的</button>
+            </div>
+        </div>
+    </div>
+</div>
+
+<!--设置生成规则-->
+<div class="modal fade" id="choose" data-backdrop="static">
+    <div class="modal-dialog " role="document">
+        <div class="modal-content">
+            <div class="modal-header">
+                <h5 class="modal-title">设置中间计量生成规则</h5>
+            </div>
+            <div class="modal-body">
+                <div class="form-group">
+                    <label>中间计量模式 <a href="/public/images/example/jiliangmoshi.png" target="_blank" data-toggle="tooltip" data-placement="bottom" data-original-title="点击查看相关报表"><i class="fa fa-question-circle-o"></i></a></label>
+                    <div class="row" id="im-type">
+                        <% for (const i in imType) { %>
+                        <% console.log(ctx.stage.im_type === imType[i].value); %>
+                        <div class="col-6">
+                            <div class="card border-primary" name="im-type" im-type="<%- imType[i].value %>" <% if (ctx.stage.im_type !== imType[i].value) { %>style="cursor:pointer;"<% } %>>
+                                <div class="card-body<% if (ctx.stage.im_type === imType[i].value) { %> text-primary<% } %>">
+                                    <h5 class="card-title mb-0" im-type="<%- imType[i].value %>">
+                                        <% if (ctx.stage.im_type === imType[i].value) { %><i class="fa fa-check pull-right"></i><% } %>
+                                        <%- imType[i].name %>
+                                    </h5>
+                                </div>
+                            </div>
+                        </div>
+                        <% }%>
+                    </div>
+                </div>
+                <div class="form-group">
+                    <label>中间计量表号前缀</label>
+                    <input type="text" class="form-control form-control-sm" value="<%- ctx.stage.im_pre ? ctx.stage.im_pre : '' %>" id="im-pre" maxlength="10">
+                </div>
+                <div class="form-group">
+                    <label> </label>
+                    <a  href="#choose2" data-toggle="modal" data-target="#choose2">高级设置</a>
+                </div>
+            </div>
+            <div class="modal-footer">
+                <button type="button" class="btn btn-secondary btn-sm" data-dismiss="modal">关闭</button>
+                <% if (!stage.readOnly && stage.user_id === ctx.session.sessionUser.accountId) { %>
+                <button type="button" class="btn btn-primary btn-sm" id="choose-ok">重新生成</button>
+                <% } %>
+            </div>
+        </div>
+    </div>
+</div>
+<!--设置生成规则2-->
+<div class="modal fade" id="choose2" data-backdrop="static">
+    <div class="modal-dialog modal-lg" role="document">
+        <div class="modal-content">
+            <div class="modal-header">
+                <h5 class="modal-title">高级设置</h5>
+            </div>
+            <div class="modal-body">
+                <div class="custom-control custom-checkbox mb-2">
+                    <input type="checkbox" class="custom-control-input" id="im-gather-check" <% if (ctx.stage.im_gather) { %> checked="checked"<% } %>>
+                    <label class="custom-control-label" for="im-gather-check">汇总计量节点</label>
+                </div>
+                <div class="modal-height-500" id="im-gather-spread">
+                </div>
+                <div class="popover bs-popover-right" role="tooltip" id="gather-confirm" style="display: none">
+                    <div class="arrow" style="top:30px"></div>
+                    <div class="popover-body">
+                        <p id="gather-confirm-hint">父项已勾选,继续将取消父项勾选。</p>
+                        <p class="mb-0 d-flex justify-content-end">
+                            <button class="btn btn-sm btn-secondary" id="gather-confirm-cancel">取消</button>&nbsp;<button class="btn btn-sm btn-success" id="gather-confirm-ok">继续</button>
+                        </p>
+                    </div>
+                </div>
+            </div>
+            <div class="modal-footer">
+                <button type="button" class="btn btn-secondary btn-sm" data-dismiss="modal">关闭</button>
+                <% if (!stage.readOnly && stage.user_id === ctx.session.sessionUser.accountId) { %>
+                <button type="button" class="btn btn-primary btn-sm" id="choose2-ok">确定</button>
+                <% } %>
+            </div>
+        </div>
+    </div>
+</div>
 <!--添加草图-->
 <!--添加草图-->
 <div class="modal fade" id="edit-img" data-backdrop="static">
 <div class="modal fade" id="edit-img" data-backdrop="static">
     <div class="modal-dialog modal-lgx" role="document">
     <div class="modal-dialog modal-lgx" role="document">
@@ -205,48 +321,81 @@
                 <h5 class="modal-title">添加草图</h5>
                 <h5 class="modal-title">添加草图</h5>
             </div>
             </div>
             <div class="modal-body">
             <div class="modal-body">
-                <p><a href="" class="btn btn-outline-primary btn-sm">上传图片</a></p>
+                <p>
+                    <input type="file" id="upload-img-file" style="display: none;">
+                    <a href="javascript: void(0);" class="btn btn-outline-primary btn-sm" id="upload-img">上传图片</a>
+                </p>
                 <div class="img-view">
                 <div class="img-view">
-                    <div class="img-item">
-                        <div class="img-bar">
-                            <a href="" class="text-danger" title="删除"><i class="fa fa-remove"></i></a>
-                        </div>
-                        <!--<img src="img/sketch/1.png" id="draggable">-->
-                    </div>
-                    <div class="img-item" style="left:300px;">
-                        <div class="img-bar">
-                            <a href="" class="text-danger" title="删除"><i class="fa fa-remove"></i></a>
-                        </div>
-                        <!--<img src="img/sketch/2.png" id="draggable">-->
-                    </div>
                 </div>
                 </div>
             </div>
             </div>
             <div class="modal-footer">
             <div class="modal-footer">
                 <button type="button" class="btn btn-secondary btn-sm" data-dismiss="modal">关闭</button>
                 <button type="button" class="btn btn-secondary btn-sm" data-dismiss="modal">关闭</button>
-                <button type="button" class="btn btn-primary btn-sm" >确认</button>
+                <button type="button" class="btn btn-primary btn-sm" id="edit-img-ok">确认</button>
             </div>
             </div>
         </div>
         </div>
     </div>
     </div>
 </div>
 </div>
-<!--上传附件-->
-<div class="modal fade" id="upload" data-backdrop="static">
-    <div class="modal-dialog" role="document">
+<!--计量汇总-->
+<div class="modal fade" id="choose" data-backdrop="static">
+    <div class="modal-dialog modal-lg" role="document">
         <div class="modal-content">
         <div class="modal-content">
             <div class="modal-header">
             <div class="modal-header">
-                <h5 class="modal-title">上传附件</h5>
+                <h5 class="modal-title">计量汇总</h5>
             </div>
             </div>
             <div class="modal-body">
             <div class="modal-body">
-                <div class="form-group">
-                    <label for="formGroupExampleInput">大小限制:10MB,支持<span data-toggle="tooltip" data-placement="bottom" title="" data-original-title="doc,docx,xls,xlsx,ppt,pptx,pdf">office等文档格式</span>、<span data-toggle="tooltip" data-placement="bottom" title="" data-original-title="jpg,png,bmp">图片格式</span>、<span data-toggle="tooltip" data-placement="bottom" title="" data-original-title="rar,zip">压缩包格式</span></label>
-                    <input type="file" class="form-control form-control-sm" id="upload-file" multiple>
+                <div class="modal-height-500">
+                    <table class="table table-sm table-bordered">
+                        <tr><th width="70">计量汇总</th><th>项目节编号</th><th>清单编号</th><th>名称</th><th>单位</th></tr>
+                        <tr><td><input type="checkbox"></td><td>1</td><td></td><td>第一部分 建筑安装工程费</td><td></td></tr>
+                        <tr><td><input type="checkbox"></td><td>1-2</td><td></td><td>路基工程</td><td></td></tr>
+                        <tr><td><input type="checkbox"></td><td>1-2-2</td><td></td><td>挖方</td><td></td></tr>
+                        <tr><td><input type="checkbox"></td><td>1-2-2-1</td><td></td><td>挖土方</td><td></td></tr>
+                        <tr><td><input type="checkbox"></td><td>1-2-2-1-1</td><td></td><td>挖路基土方</td><td></td></tr>
+                        <tr><td><input type="checkbox"></td><td></td><td>203-1-a</td><td>挖土方</td><td></td></tr>
+                    </table>
                 </div>
                 </div>
             </div>
             </div>
             <div class="modal-footer">
             <div class="modal-footer">
                 <button type="button" class="btn btn-secondary btn-sm" data-dismiss="modal">关闭</button>
                 <button type="button" class="btn btn-secondary btn-sm" data-dismiss="modal">关闭</button>
-                <button type="button" class="btn btn-primary btn-sm" id="upload-file-btn">确认</button>
+                <% if (!stage.readOnly) { %>
+                <button type="button" class="btn btn-primary btn-sm" >确认</button>
+                <% } %>
+            </div>
+        </div>
+    </div>
+</div>
+<!--完成中间计量-->
+<div class="modal fade" id="done" data-backdrop="static">
+    <div class="modal-dialog " role="document" >
+        <div class="modal-content">
+            <div class="modal-header">
+                <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>
+                <a id="done-detail" href="javascript: void(0);" class="btn btn-success btn-sm" >确认完成</a>
+            </div>
+        </div>
+    </div>
+</div>
+<!--草图预览-->
+<div class="modal fade" id="imgview" data-backdrop="static">
+    <div class="modal-dialog modal-lgx" role="document">
+        <div class="modal-content">
+            <div class="modal-header">
+                <h5 class="modal-title">查看草图</h5>
+            </div>
+            <div class="modal-body">
+                <img src="" id="view-calc-img">
+            </div>
+            <div class="modal-footer">
+                <button type="button" class="btn btn-secondary" data-dismiss="modal">关闭</button>
             </div>
             </div>
         </div>
         </div>
     </div>
     </div>
 </div>
 </div>
-
 <% include ./audit_modal.ejs %>
 <% include ./audit_modal.ejs %>

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

@@ -29,7 +29,7 @@
                 </div>
                 </div>
             </div>
             </div>
             <div class="c-body col">
             <div class="c-body col">
-                <div class="side-bar-1 sjs-bar"></div>
+                <div class="side-bar-1"></div>
                 <div class="sjs-sh-1">
                 <div class="sjs-sh-1">
                     <table class="table table-bordered">
                     <table class="table table-bordered">
                         <tr><th></th><th>可选基数</th><th>计算代号</th><th>值</th></tr>
                         <tr><th></th><th>可选基数</th><th>计算代号</th><th>值</th></tr>

+ 1 - 0
config/web.js

@@ -219,6 +219,7 @@ const JsFiles = {
                     "/public/js/spreadjs_rela/spreadjs_zh.js",
                     "/public/js/spreadjs_rela/spreadjs_zh.js",
                     "/public/js/zh_calc.js",
                     "/public/js/zh_calc.js",
                     "/public/js/path_tree.js",
                     "/public/js/path_tree.js",
+                    "/public/js/stage_im.js",
                     "/public/js/stage.js",
                     "/public/js/stage.js",
                     "/public/js/stage_audit.js",
                     "/public/js/stage_audit.js",
                 ],
                 ],