浏览代码

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

Tony Kang 2 年之前
父节点
当前提交
dce99e4e6a

+ 1 - 0
app/const/material.js

@@ -21,6 +21,7 @@ const m_type = [
     { text: '油料', value: 4 },
     { text: '水泥', value: 5 },
     { text: '半成品', value: 6 },
+    { text: '砂石料', value: 8 },
     { text: '其他', value: 7 },
 ];
 // 指数调差类型

+ 6 - 2
app/const/spread.js

@@ -8,7 +8,7 @@
  * @version
  */
 
-const tzWithoutCols = ['deal_qty', 'deal_tp'];
+const dealCols = ['deal_qty', 'deal_tp'];
 const dgnCols = ['dgn_qty1', 'dgn_qty2', 'dgn_price'];
 const clCols = ['sjcl_qty', 'sjcl_tp', 'qtcl_qty', 'qtcl_tp', 'quantity', 'total_price'];
 const stageDgnCols = ['deal_dgn_qty1', 'deal_dgn_qty2', 'c_dgn_qty1', 'c_dgn_qty2', 'final_dgn_price'];
@@ -31,6 +31,8 @@ const withCl = {
             {title: '项目节数量|数量1',  colSpan: '2|1', rowSpan: '1|1', field: 'dgn_qty1', hAlign: 2, width: 60, type: 'Number'},
             {title: '|数量2',  colSpan: '|1', rowSpan: '|1', field: 'dgn_qty2', hAlign: 2, width: 60, type: 'Number'},
             {title: '经济指标',  colSpan: '1', rowSpan: '2', field: 'dgn_price', hAlign: 2, width: 60, type: 'Number', readOnly: true},
+            {title: '签约|数量', colSpan: '2|1', rowSpan: '1|1', field: 'deal_qty', hAlign: 2, width: 60, type: 'Number'},
+            {title: '|金额', colSpan: '|1', rowSpan: '|1', field: 'deal_tp', hAlign: 2, width: 60, type: 'Number', readOnly: true},
             {title: '设计量|数量', colSpan: '2|1', rowSpan: '1|1', field: 'sgfh_qty', hAlign: 2, width: 60, type: 'Number'},
             {title: '|金额', colSpan: '|1', rowSpan: '|1', field: 'sgfh_tp', hAlign: 2, width: 60, type: 'Number', readOnly: true},
             {title: '设计错漏增减|数量', colSpan: '2|1', rowSpan: '1|1', field: 'sjcl_qty', hAlign: 2, width: 60, type: 'Number'},
@@ -85,6 +87,8 @@ const withoutCl = {
             {title: '项目节数量|数量1',  colSpan: '2|1', rowSpan: '1|1', field: 'dgn_qty1', hAlign: 2, width: 60, type: 'Number'},
             {title: '|数量2',  colSpan: '|1', rowSpan: '|1', field: 'dgn_qty2', hAlign: 2, width: 60, type: 'Number'},
             {title: '经济指标',  colSpan: '1', rowSpan: '2', field: 'dgn_price', hAlign: 2, width: 60, type: 'Number', readOnly: true},
+            {title: '签约|数量', colSpan: '2|1', rowSpan: '1|1', field: 'deal_qty', hAlign: 2, width: 60, type: 'Number'},
+            {title: '|金额', colSpan: '|1', rowSpan: '|1', field: 'deal_tp', hAlign: 2, width: 60, type: 'Number', readOnly: true},
             {title: '设计量|数量', colSpan: '2|1', rowSpan: '1|1', field: 'sgfh_qty', hAlign: 2, width: 60, type: 'Number'},
             {title: '|金额', colSpan: '|1', rowSpan: '|1', field: 'sgfh_tp', hAlign: 2, width: 60, type: 'Number', readOnly: true},
             {title: '图(册)号', colSpan: '1', rowSpan: '2', field: 'drawing_code', hAlign: 0, width: 80, formatter: '@'},
@@ -599,7 +603,7 @@ module.exports = {
     stageNoCl,
     stageGather,
     stageCompare,
-    filterCols: { tzWithoutCols, dgnCols, clCols, stageDgnCols, realCompleteCols, thirdPartyCols, minusNoValueCols},
+    filterCols: { dealCols, dgnCols, clCols, stageDgnCols, realCompleteCols, thirdPartyCols, minusNoValueCols},
     measure,
     blank,
 };

+ 2 - 2
app/const/tender.js

@@ -59,9 +59,9 @@ const measureType = {
 const valuationField = function (mt) {
     switch (mt) {
         case measureType.tz.value:
-            return { std_bills: 'bill_id', std_xmj: 'chapter_id', template: 'template_id' };
+            return { std_bills: 'bill_id', std_xmj: 'chapter_id', template: 'template_id', glj_lib: 'glj_lib_id' };
         case measureType.gcl.value:
-            return { std_bills: 'list_bill_id', std_xmj: 'list_chapter_id', template: 'list_template_id' };
+            return { std_bills: 'list_bill_id', std_xmj: 'list_chapter_id', template: 'list_template_id', glj_lib: 'list_glj_lib_id' };
         default:
             return null;
     }

+ 1 - 0
app/const/tender_info.js

@@ -106,6 +106,7 @@ const defaultInfo = {
     // 显示设置
     display: {
         ledger: {
+            deal: false,
             dgnQty: false,
             clQty: false,
         },

+ 2 - 2
app/controller/change_controller.js

@@ -1617,7 +1617,7 @@ module.exports = app => {
 
         async _getDefaultReviseInfoData(ctx, change, edit) {
             const [ledgerSpread, posSpread] = this._getSpreadSetting(change, edit);
-            const sjsRela = await this.ctx.service.project.getTenderSjsRela(ctx.session.sessionProject.id);
+            const sjsRela = await this.ctx.service.project.getTenderSjsRela(ctx.session.sessionProject.id, ctx.tender.info.display.exMemo);
             this.ctx.helper.refreshSpreadShow(sjsRela.ledgerCol, [ledgerSpread, posSpread]);
             const [stdBills, stdChapters] = await this.ctx.service.valuation.getValuationStdList(
                 ctx.tender.data.valuation, ctx.tender.data.measure_type);
@@ -1661,7 +1661,7 @@ module.exports = app => {
                 pos.readOnly = true;
             }
             if (tender.data.measure_type === measureType.tz.value) {
-                removeFieldCols(ledger, spreadConst.filterCols.tzWithoutCols);
+                removeFieldCols(ledger, spreadConst.filterCols.dealCols);
             }
             if (!tender.info.display.ledger.dgnQty) {
                 removeFieldCols(ledger, spreadConst.filterCols.dgnCols);

+ 3 - 31
app/controller/ledger_audit_controller.js

@@ -8,9 +8,9 @@
  * @version
  */
 const auditConst = require('../const/audit').ledger;
-const spreadConst = require('../const/spread');
 const shenpiConst = require('../const/shenpi');
 const measureType = require('../const/tender').measureType;
+const spreadSetting = require('../lib/spread_setting');
 
 module.exports = app => {
     class LedgerAuditController extends app.BaseController {
@@ -26,34 +26,6 @@ module.exports = app => {
         }
 
         /**
-         * 获取SpreadSetting
-         * @private
-         */
-        _getSpreadSetting() {
-            const _ = this.app._;
-            function removeFieldCols(setting, cols) {
-                _.remove(setting.cols, function(c) {
-                    return cols.indexOf(c.field) > -1;
-                });
-            }
-            const tender = this.ctx.tender;
-            const setting = tender.data.measure_type === measureType.tz.value
-                ? (tender.info.display.ledger.clQty ? spreadConst.withCl : spreadConst.withoutCl)
-                : (tender.info.display.ledger.clQty ? spreadConst.withClGcl : spreadConst.withoutClGcl);
-            const ledger = JSON.parse(JSON.stringify(setting.ledger));
-            const pos = setting.pos ? JSON.parse(JSON.stringify(setting.pos)) : spreadConst.blank;
-            ledger.readOnly = true;
-            pos.readOnly = true;
-            if (tender.data.measure_type === measureType.tz.value) {
-                removeFieldCols(ledger, spreadConst.filterCols.tzWithoutCols);
-            }
-            if (!tender.info.display.ledger.dgnQty) {
-                removeFieldCols(ledger, spreadConst.filterCols.dgnCols);
-            }
-            return [ledger, pos];
-        }
-
-        /**
          * 台账审批页面(get)
          *
          * @param ctx
@@ -68,8 +40,8 @@ module.exports = app => {
                     preUrl: '/tender/' + ctx.tender.id,
                     measureType,
                 };
-                const [ledgerSpread, posSpread] = this._getSpreadSetting();
-                const sjsRela = await this.ctx.service.project.getTenderSjsRela(ctx.session.sessionProject.id);
+                const [ledgerSpread, posSpread] = await spreadSetting.getLedgerSpreadSetting(ctx, ctx.tender.id, true);
+                const sjsRela = await this.ctx.service.project.getTenderSjsRela(ctx.session.sessionProject.id, ctx.tender.info.display.exMemo);
                 this.ctx.helper.refreshSpreadShow(sjsRela.ledgerCol, [ledgerSpread, posSpread]);
 
                 const curAuditor = await ctx.service.ledgerAudit.getCurAuditor(ctx.tender.id, ctx.tender.data.ledger_times);

+ 7 - 45
app/controller/ledger_controller.js

@@ -18,7 +18,6 @@ const moment = require('moment');
 const auditConst = audit.ledger;
 const tenderMenu = require('../../config/menu').tenderMenu;
 const measureType = require('../const/tender').measureType;
-const spreadConst = require('../const/spread');
 const shenpiConst = require('../const/shenpi');
 const externalDataConst = require('../const/external_data.js');
 const fs = require('fs');
@@ -30,6 +29,7 @@ const billsPosConvert = require('../lib/bills_pos_convert');
 const xlsx = require('js-xlsx');
 const stdConst = require('../const/standard');
 const sendToWormhole = require('stream-wormhole');
+const spreadSetting = require('../lib/spread_setting');
 
 module.exports = app => {
 
@@ -72,52 +72,13 @@ module.exports = app => {
                 (tender.ledger_status === auditConst.status.checked && isAuditor && upPermission);
         }
 
-        /**
-         * 获取SpreadSetting
-         * @private
-         */
-        _getSpreadSetting() {
-            const _ = this.app._;
-            function removeFieldCols(setting, cols) {
-                _.remove(setting.cols, function(c) {
-                    return cols.indexOf(c.field) > -1;
-                });
-            }
-            function hideFieldCols(setting, cols) {
-                for (const c of setting.cols) {
-                    if (cols.indexOf(c.field) > -1) {
-                        c.visible = false;
-                    }
-                }
-            }
-            const tender = this.ctx.tender;
-            const setting = tender.data.measure_type === measureType.tz.value
-                ? (tender.info.display.ledger.clQty ? spreadConst.withCl : spreadConst.withoutCl)
-                : (tender.info.display.ledger.clQty ? spreadConst.withClGcl : spreadConst.withoutClGcl);
-            const ledger = JSON.parse(JSON.stringify(setting.ledger));
-            const pos = setting.pos ? JSON.parse(JSON.stringify(setting.pos)) : spreadConst.blank;
-
-            if (this._ledgerReadOnly(tender.data)) {
-                ledger.readOnly = true;
-                pos.readOnly = true;
-            }
-            if (tender.data.measure_type === measureType.tz.value) {
-                removeFieldCols(ledger, spreadConst.filterCols.tzWithoutCols);
-            }
-            if (!tender.info.display.ledger.dgnQty) {
-                removeFieldCols(ledger, spreadConst.filterCols.dgnCols);
-            }
-
-            return [ledger, pos];
-        }
-
         _getLedgerColumn(sjsRela) {
             const tender = this.ctx.tender;
             const ledgerColumn = [
                 'id', 'tender_id', 'ledger_id', 'ledger_pid', 'level', 'order', 'full_path', 'is_leaf',
                 'code', 'b_code', 'name', 'unit', 'unit_price', 'quantity', 'total_price',
                 'sgfh_qty', 'sgfh_expr', 'sgfh_tp', 'memo', 'drawing_code', 'node_type'];
-            if (tender.data.measure_type === measureType.gcl.value) ledgerColumn.push('deal_qty', 'deal_tp');
+            if (tender.info.display.ledger.deal) ledgerColumn.push('deal_qty', 'deal_tp');
             if (tender.info.display.ledger.dgnQty) ledgerColumn.push('dgn_qty1', 'dgn_qty2');
             if (tender.info.display.ledger.clQty) ledgerColumn.push('sjcl_qty', 'qtcl_qty', 'sjcl_expr', 'qtcl_expr', 'sjcl_tp', 'qtcl_tp');
             const posColumn = ['id', 'tid', 'lid', 'name', 'position', 'porder', 'sgfh_qty', 'sgfh_expr', 'add_stage_order', 'drawing_code', 'quantity'];
@@ -140,8 +101,9 @@ module.exports = app => {
         async explode(ctx) {
             try {
                 const tender = ctx.tender;
-                const [ledgerSpread, posSpread] = await this._getSpreadSetting();
-                const sjsRela = await this.ctx.service.project.getTenderSjsRela(ctx.session.sessionProject.id);
+                const [ledgerSpread, posSpread] = await spreadSetting.getLedgerSpreadSetting(ctx, tender.id,
+                    this._ledgerReadOnly(tender.data));
+                const sjsRela = await this.ctx.service.project.getTenderSjsRela(ctx.session.sessionProject.id, ctx.tender.info.display.exMemo);
                 this.ctx.helper.refreshSpreadShow(sjsRela.ledgerCol, [ledgerSpread, posSpread]);
                 const times = tender.data.ledger_status === auditConst.status.checkNo ? tender.data.ledger_times - 1 : tender.data.ledger_times;
 
@@ -481,7 +443,7 @@ module.exports = app => {
          */
         async loadExplodeData(ctx) {
             try {
-                const sjsRela = await ctx.service.project.getTenderSjsRela(ctx.session.sessionProject.id);
+                const sjsRela = await ctx.service.project.getTenderSjsRela(ctx.session.sessionProject.id, ctx.tender.info.display.exMemo);
                 const [ledgerColumn, posColumn] = this._getLedgerColumn(sjsRela);
                 const ledgerData = ctx.tender.ledgerReadOnly && ctx.tender.his
                     ? await ctx.helper.loadLedgerDataFromOss(ctx.tender.his.bills_file)
@@ -692,7 +654,7 @@ module.exports = app => {
          */
         async bwtz(ctx) {
             try {
-                const sjsRela = await ctx.service.project.getTenderSjsRela(ctx.session.sessionProject.id);
+                const sjsRela = await ctx.service.project.getTenderSjsRela(ctx.session.sessionProject.id, ctx.tender.info.display.exMemo);
                 const renderData = {
                     tender: ctx.tender.data,
                     jsFiles: this.app.jsFiles.common.concat(this.app.jsFiles.ledger.bwtz),

+ 7 - 2
app/controller/material_controller.js

@@ -410,7 +410,9 @@ module.exports = app => {
                     renderData.calcBase = calcBaseList;
                 }
                 // }
-
+                const [stdBills, stdChapters, gljLists] = await this.ctx.service.valuation.getValuationStdList(
+                    ctx.tender.data.valuation, ctx.tender.data.measure_type);
+                renderData.gljLists = gljLists;
                 // 取当前期截止上期含税金额
                 renderData.material.m_tax_tp = renderData.material.m_tax_tp ? renderData.material.m_tax_tp : renderData.material.m_tp;
                 renderData.pre_tp_hs = await ctx.service.material.getPreTpHs(ctx.tender.id, ctx.material.order, ctx.material.decimal.tp);
@@ -869,7 +871,7 @@ module.exports = app => {
                         responseData.data = await ctx.service.materialBills.del(data.id);
                         break;
                     case 'changeOrder':
-                        await ctx.service.materialBills.changeOrder(data.id1, data.id2);
+                        await ctx.service.materialBills.changeOrder(data.postData);
                         break;
                     case 'update':
                         if (data.updateData.code === '' || data.updateData.code === null) {
@@ -914,6 +916,9 @@ module.exports = app => {
                         // responseData.data.info = await ctx.service.materialBills.getAllDataByCondition({ where: searchsql, orders: [['order', 'asc']] });
                         responseData.data.info = await this._getMaterialBillsData(ctx);
                         break;
+                    case 'add-glj':
+                        responseData.data = await ctx.service.materialBills.addByGlj(data.postData, data.order);
+                        break;
                     default: throw '参数有误';
                 }
                 if (ctx.material.material_tax) {

+ 1 - 0
app/controller/report_controller.js

@@ -372,6 +372,7 @@ module.exports = app => {
                 // console.log('pageSize: ' + pageSize);
                 const renderData = {
                     size: pageSize,
+                    OSS_PATH: ctx.app.config.fujianOssPath,
                     // orientation: params.orientation,
                 };
                 await ctx.render('report/rpt_individual.ejs', renderData);

+ 6 - 37
app/controller/revise_controller.js

@@ -17,11 +17,11 @@ const audit = require('../const/audit');
 const accountGroup = require('../const/account_group').group;
 const tenderMenu = require('../../config/menu').tenderMenu;
 const measureType = require('../const/tender').measureType;
-const spreadConst = require('../const/spread');
 const shenpiConst = require('../const/shenpi');
 const fs = require('fs');
 const LzString = require('lz-string');
 const stdConst = require('../const/standard');
+const spreadSetting = require('../lib/spread_setting');
 
 module.exports = app => {
     class ReviseController extends app.BaseController {
@@ -257,41 +257,9 @@ module.exports = app => {
             }
         }
 
-        /**
-         * 获取SpreadSetting
-         * @private
-         */
-        _getSpreadSetting(revise) {
-            const _ = this.app._;
-            function removeFieldCols(setting, cols) {
-                _.remove(setting.cols, function(c) {
-                    return cols.indexOf(c.field) > -1;
-                });
-            }
-            const tender = this.ctx.tender;
-            const setting = tender.data.measure_type === measureType.tz.value
-                ? (tender.info.display.ledger.clQty ? spreadConst.withCl : spreadConst.withoutCl)
-                : (tender.info.display.ledger.clQty ? spreadConst.withClGcl : spreadConst.withoutClGcl);
-            const ledger = JSON.parse(JSON.stringify(setting.ledger));
-            const pos = setting.pos ? JSON.parse(JSON.stringify(setting.pos)) : spreadConst.blank;
-
-            if (revise.status === audit.revise.status.checking || revise.status === audit.revise.status.checked) {
-                ledger.readOnly = true;
-                pos.readOnly = true;
-            }
-            if (tender.data.measure_type === measureType.tz.value) {
-                removeFieldCols(ledger, spreadConst.filterCols.tzWithoutCols);
-            }
-            if (!tender.info.display.ledger.dgnQty) {
-                removeFieldCols(ledger, spreadConst.filterCols.dgnCols);
-            }
-            return [ledger, pos];
-        }
-
         async _getDefaultReviseInfoData(ctx, revise) {
-            const [ledgerSpread, posSpread] = this._getSpreadSetting(revise);
-            const sjsRela = await ctx.service.project.getTenderSjsRela(ctx.session.sessionProject.id);
-            this.ctx.helper.refreshSpreadShow(sjsRela.ledgerCol, [ledgerSpread, posSpread]);
+            const [ledgerSpread, posSpread] = await spreadSetting.getLedgerSpreadSetting(ctx, revise.tid,
+                revise.status === audit.revise.status.checking || revise.status === audit.revise.status.checked);
             const [stdBills, stdChapters] = await this.ctx.service.valuation.getValuationStdList(
                 ctx.tender.data.valuation, ctx.tender.data.measure_type);
             const curAuditor = await ctx.service.reviseAudit.getCurAuditor(revise.id, revise.times);
@@ -486,8 +454,9 @@ module.exports = app => {
             try {
                 const revise = ctx.revise;
 
-                const [ledgerSpread, posSpread] = this._getSpreadSetting(revise);
-                const sjsRela = await ctx.service.project.getTenderSjsRela(ctx.session.sessionProject.id);
+                const [ledgerSpread, posSpread] = await spreadSetting.getLedgerSpreadSetting(ctx, revise.tid,
+                    revise.status === audit.revise.status.checking || revise.status === audit.revise.status.checked);
+                const sjsRela = await ctx.service.project.getTenderSjsRela(ctx.session.sessionProject.id, ctx.tender.info.display.exMemo);
                 this.ctx.helper.refreshSpreadShow(sjsRela.ledgerCol, [ledgerSpread, posSpread]);
                 ledgerSpread.readOnly = true;
                 posSpread.readOnly = true;

+ 6 - 76
app/controller/stage_controller.js

@@ -26,6 +26,7 @@ const billsPosConvert = require('../lib/bills_pos_convert');
 const fs = require('fs');
 const stdConst = require('../const/standard');
 const LzString = require('lz-string');
+const spreadSetting = require('../lib/spread_setting');
 
 module.exports = app => {
     class StageController extends app.BaseController {
@@ -85,57 +86,6 @@ module.exports = app => {
         }
 
         /**
-         * 获取SpreadSetting
-         * @private
-         */
-        _getSpreadSetting(funInfo) {
-            const _ = this.app._;
-            function removeFieldCols(setting, cols) {
-                _.remove(setting.cols, function(c) {
-                    return cols.indexOf(c.field) > -1;
-                });
-            }
-            function hiddenFieldCols(setting, cols) {
-                setting.cols.forEach(x => {
-                    if (cols.indexOf(x.field) >= 0) {
-                        x.defaultVisible = false;
-                        x.visible = false;
-                    }
-                });
-            }
-            const tender = this.ctx.tender,
-                stage = this.ctx.stage;
-            const stageSetting = tender.data.measure_type === measureType.tz.value
-                ? spreadConst.stageTz
-                : (tender.info.display.ledger.clQty ? spreadConst.stageCl : spreadConst.stageNoCl);
-            const ledger = JSON.parse(JSON.stringify(stageSetting.ledger));
-            if (!tender.info.display.ledger.dgnQty) {
-                removeFieldCols(ledger, spreadConst.filterCols.stageDgnCols);
-            }
-            const pos = JSON.parse(JSON.stringify(stageSetting.pos));
-            if (!tender.info.display.stage.realComplete) {
-                removeFieldCols(pos, spreadConst.filterCols.realCompleteCols);
-            }
-            if (!this.ctx.session.sessionProject.gxby) {
-                removeFieldCols(ledger, spreadConst.filterCols.thirdPartyCols.gxby);
-                removeFieldCols(pos, spreadConst.filterCols.thirdPartyCols.gxby);
-            }
-            if (!this.ctx.session.sessionProject.dagl) {
-                removeFieldCols(ledger, spreadConst.filterCols.thirdPartyCols.dagl);
-                removeFieldCols(pos, spreadConst.filterCols.thirdPartyCols.dagl);
-            }
-            if (!funInfo.minusNoValue || !tender.info.fun_rela.stage_change.minusNoValue) {
-                hiddenFieldCols(ledger, spreadConst.filterCols.minusNoValueCols);
-                hiddenFieldCols(pos, spreadConst.filterCols.minusNoValueCols);
-            }
-            if (this.ctx.stage.readOnly || this.ctx.stage.revising) {
-                ledger.readOnly = true;
-                pos.readOnly = true;
-            }
-            return [ledger, pos];
-        }
-
-        /**
          * 获取审批界面所需的 原报、审批人数据等
          * @param ctx
          * @return {Promise<void>}
@@ -182,9 +132,8 @@ module.exports = app => {
                 const renderData = await this._getDefaultRenderData(ctx);
                 const projectFunInfo = await this.ctx.service.project.getFunRela(ctx.session.sessionProject.id);
                 renderData.minusNoValue = projectFunInfo.minusNoValue && ctx.tender.info.fun_rela.stage_change.minusNoValue;
-                [renderData.ledgerSpread, renderData.posSpread] = this._getSpreadSetting({minusNoValue: renderData.minusNoValue});
-                const sjsRela = await this.ctx.service.project.getTenderSjsRela(ctx.session.sessionProject.id);
-                this.ctx.helper.refreshSpreadShow(sjsRela.ledgerCol, [renderData.ledgerSpread, renderData.posSpread]);
+                [renderData.ledgerSpread, renderData.posSpread] = await spreadSetting.getStageSpreadSetting(ctx, ctx.tender.id,
+                    this.ctx.stage.readOnly || this.ctx.stage.revising, {minusNoValue: renderData.minusNoValue});
                 renderData.changeConst = changeConst;
                 renderData.jsFiles = this.app.jsFiles.common.concat(this.app.jsFiles.stage.index);
                 renderData.whiteList = this.ctx.app.config.multipart.whitelist;
@@ -342,7 +291,7 @@ module.exports = app => {
                 const filter = data.filter.split(';');
                 const responseData = { err: 0, msg: '', data: {}, hpack: [] };
                 const hpack = true;
-                const sjsRela = await this.ctx.service.project.getTenderSjsRela(ctx.session.sessionProject.id);
+                const sjsRela = await this.ctx.service.project.getTenderSjsRela(ctx.session.sessionProject.id, ctx.tender.info.display.exMemo);
                 this._getLedgerColumn(sjsRela);
                 for (const f of filter) {
                     switch (f) {
@@ -1362,25 +1311,6 @@ module.exports = app => {
             }
         }
 
-        // 清单汇总相关
-        _getGatherSpreadSetting() {
-            const _ = this.app._;
-            function removeFieldCols(setting, cols) {
-                _.remove(setting.cols, function(c) {
-                    return cols.indexOf(c.field) > -1;
-                });
-            }
-            const gcl = JSON.parse(JSON.stringify(spreadConst.stageGather.gcl));
-
-            const leafXmj = JSON.parse(JSON.stringify(spreadConst.stageGather.leafXmj));
-            const tender = this.ctx.tender;
-            if (tender.data.measure_type === measureType.tz.value) {
-                removeFieldCols(gcl, spreadConst.filterCols.tzWithoutCols);
-            } else {
-                removeFieldCols(leafXmj, ['quantity']);
-            }
-            return [gcl, leafXmj];
-        }
         /**
          * 清单汇总 页面 (Get)
          * @param ctx
@@ -1390,7 +1320,7 @@ module.exports = app => {
             try {
                 await this._getStageAuditViewData(ctx);
                 const renderData = await this._getDefaultRenderData(ctx);
-                [renderData.gclSpread, renderData.leafXmjSpread] = this._getGatherSpreadSetting();
+                [renderData.gclSpread, renderData.leafXmjSpread] = await spreadSetting.getStageGatherSpreadSetting(ctx);
                 const projectFunInfo = await this.ctx.service.project.getFunRela(ctx.session.sessionProject.id);
                 renderData.hintOver = projectFunInfo.hintOver && ctx.tender.info.fun_rela.hintOver;
 
@@ -1465,7 +1395,7 @@ module.exports = app => {
                 await this._getStageAuditViewData(ctx);
                 const renderData = await this._getDefaultRenderData(ctx);
                 renderData.jsFiles = this.app.jsFiles.common.concat(this.app.jsFiles.stage.bwtz);
-                const sjsRela = await this.ctx.service.project.getTenderSjsRela(ctx.session.sessionProject.id);
+                const sjsRela = await this.ctx.service.project.getTenderSjsRela(ctx.session.sessionProject.id, ctx.tender.info.display.exMemo);
                 renderData.ex_memo1 = sjsRela.ledgerCol.find(x => { return x.field === 'ex_memo1'; });
                 renderData.ex_memo2 = sjsRela.ledgerCol.find(x => { return x.field === 'ex_memo2'; });
                 renderData.ex_memo3 = sjsRela.ledgerCol.find(x => { return x.field === 'ex_memo3'; });

+ 2 - 1
app/controller/standard_lib_controller.js

@@ -32,6 +32,7 @@ module.exports = app => {
                         break;
                     case 'glj':
                         responseData.data = await this.ctx.service.gljLib.getData(data.list_id);
+                        break;
                     default:
                         throw '查询的标准清单不存在';
                 }
@@ -84,4 +85,4 @@ module.exports = app => {
     }
 
     return StandardLibController;
-};
+};

+ 5 - 0
app/lib/analysis_excel.js

@@ -516,6 +516,8 @@ class AnalysisExcelTree {
             pos: {value: ['计量单元'], type: colDefineType.match},
             name: {value: ['名称'], type: colDefineType.match},
             unit: {value: ['单位'], type: colDefineType.match},
+            deal_qty: {value: ['签约数量'], type: colDefineType.match},
+            deal_tp: {value: ['签约金额'], type: colDefineType.match},
             quantity: {value: ['清单数量'], type: colDefineType.match},
             dgn_qty1: {value: ['设计数量1'], type: colDefineType.match},
             dgn_qty2: {value: ['设计数量2'], type: colDefineType.match},
@@ -552,6 +554,7 @@ class AnalysisExcelTree {
             node.unit = this.ctx.helper.replaceReturn(row[this.colsDef.unit]);
             node.dgn_qty1 = aeUtils.toNumber(row[this.colsDef.dgn_qty1]);
             node.dgn_qty2 = aeUtils.toNumber(row[this.colsDef.dgn_qty2]);
+            node.deal_tp = this.ctx.helper.round(aeUtils.toNumber(row[this.colsDef.deal_tp]), this.decimal.tp);
             node.total_price = this.ctx.helper.round(aeUtils.toNumber(row[this.colsDef.total_price]), this.decimal.tp);
             node.drawing_code = this.ctx.helper.replaceReturn(row[this.colsDef.drawing_code]);
             node.memo = this.ctx.helper.replaceReturn(row[this.colsDef.memo]);
@@ -583,11 +586,13 @@ class AnalysisExcelTree {
         node.name = this.ctx.helper.replaceReturn(row[this.colsDef.name]);
         node.unit = this.ctx.helper.replaceReturn(row[this.colsDef.unit]);
         const precision = this.ctx.helper.findPrecision(this.precision, node.unit);
+        node.deal_qty = this.ctx.helper.round(aeUtils.toNumber(row[this.colsDef.deal_qty]), precision.value);
         node.quantity = this.ctx.helper.round(aeUtils.toNumber(row[this.colsDef.quantity]), precision.value);
         node.sgfh_qty = node.quantity;
         node.unit_price = this.ctx.helper.round(aeUtils.toNumber(row[this.colsDef.unit_price]), this.decimal.up);
         node.drawing_code = this.ctx.helper.replaceReturn(row[this.colsDef.drawing_code]);
         node.memo = this.ctx.helper.replaceReturn(row[this.colsDef.memo]);
+        node.deal_tp = node.deal_qty && node.unit_price ? this.ctx.helper.mul(node.deal_qty, node.unit_price, this.decimal.tp) : 0;
         if (node.quantity && node.unit_price) {
             node.total_price = this.ctx.helper.mul(node.quantity, node.unit_price, this.decimal.tp);
         } else {

+ 19 - 3
app/lib/spread_setting.js

@@ -13,6 +13,8 @@ const _ = require('lodash');
 const measureType = require('../const/tender').measureType;
 
 const getCtxTender = async function (ctx, tid) {
+    if (tid === ctx.tender.id) return ctx.tender;
+
     const tender = { id: tid };
     tender.data = await ctx.service.tender.getDataById(tid);
     tender.info = await ctx.service.tenderInfo.getTenderInfo(tid);
@@ -63,10 +65,11 @@ const getLedgerSpreadSetting = async function(ctx, tid, readOnly) {
     const pos = setting.pos ? JSON.parse(JSON.stringify(setting.pos)) : spreadConst.blank;
     ledger.readOnly = readOnly;
     pos.readOnly = readOnly;
-    if (tender.data.measure_type === measureType.tz.value) removeFieldCols(ledger, spreadConst.filterCols.tzWithoutCols);
+    if (tender.data.measure_type === measureType.tz.value && !tender.info.display.ledger.deal)
+        removeFieldCols(ledger, spreadConst.filterCols.dealCols);
     if (!tender.info.display.ledger.dgnQty) removeFieldCols(ledger, spreadConst.filterCols.dgnCols);
 
-    const sjsRela = await ctx.service.project.getTenderSjsRela(ctx.session.sessionProject.id);
+    const sjsRela = await ctx.service.project.getTenderSjsRela(ctx.session.sessionProject.id, ctx.tender.info.display.exMemo);
     refreshSpreadShow(sjsRela.ledgerCol, [ledger, pos]);
 
     return [ledger, pos];
@@ -101,13 +104,26 @@ const getStageSpreadSetting = async function (ctx, tid, readOnly, funInfo) {
     ledger.readOnly = readOnly;
     pos.readOnly = readOnly;
 
-    const sjsRela = await ctx.service.project.getTenderSjsRela(ctx.session.sessionProject.id);
+    const sjsRela = await ctx.service.project.getTenderSjsRela(ctx.session.sessionProject.id, ctx.tender.info.display.exMemo);
     refreshSpreadShow(sjsRela.ledgerCol, [ledger, pos]);
 
     return [ledger, pos];
 };
 
+const getStageGatherSpreadSetting = async function (ctx, tid) {
+    const tender = tid ? await getCtxTender(ctx, tid) : ctx.tender;
+    const gcl = JSON.parse(JSON.stringify(spreadConst.stageGather.gcl));
+    const leafXmj = JSON.parse(JSON.stringify(spreadConst.stageGather.leafXmj));
+
+    // if (tender.data.measure_type === measureType.tz.value && !tender.info.display.ledger.deal)
+    //     removeFieldCols(gcl, spreadConst.filterCols.dealCols);
+
+    if (tender.data.measure_type === measureType.gcl.value) removeFieldCols(leafXmj, ['quantity']);
+    return [gcl, leafXmj];
+};
+
 module.exports = {
     getLedgerSpreadSetting,
     getStageSpreadSetting,
+    getStageGatherSpreadSetting,
 };

+ 1 - 2
app/public/js/change_information_set.js

@@ -1128,7 +1128,6 @@ $(document).ready(() => {
             $('#table-list-select tr').attr('data-charu', '');
             $('#addlist').modal('hide');
         });
-
     });
 
     // 选中input所有值
@@ -1841,7 +1840,7 @@ function remakeChangeSpread(cOrder = changeOrder) {
                 mx_id,
             };
             const radionInfo = changeList.find(function (info) {
-                return info.code === code && (info.lid == lid || parseInt(info.lid) === parseInt(lindex)) && gcl_id == info.gcl_id && (info.bwmx === bwmx || info.bwmx === xmj_jldy) && parseInt(info.oamount) === parseInt(oamount);
+                return info.code === code && (info.lid == lid || parseInt(info.lid) === parseInt(lindex)) && gcl_id == info.gcl_id && (info.bwmx === bwmx || (info.bwmx === xmj_jldy && info.mx_id && info.mx_id === mx_id)) && parseInt(info.oamount) === parseInt(oamount);
             });
             if (radionInfo) {
                 trlist.camount = radionInfo.camount;

+ 3 - 3
app/public/js/gcl_gather.js

@@ -377,11 +377,11 @@ const gclGatherModel = (function () {
             gcl.end_final_tp = ZhCalc.add(gcl.end_qc_tp, gcl.total_price);
             gcl.final_qty = ZhCalc.add(gcl.quantity, gcl.change_bills_qty);
             gcl.final_tp = ZhCalc.add(gcl.total_price, gcl.change_bills_tp);
-            gcl.deal_final_qty = ZhCalc.add(gcl.deal_qty, gcl.change_bills_qty);
-            gcl.deal_final_tp = ZhCalc.add(gcl.deal_tp, gcl.change_bills_tp);
+            gcl.deal_final_qty = ZhCalc.add(gcl.deal_bills_qty, gcl.change_bills_qty);
+            gcl.deal_final_tp = ZhCalc.add(gcl.deal_bills_tp, gcl.change_bills_tp);
             gcl.final_1_qty = ZhCalc.add(gcl.quantity, gcl.end_qc_minus_qty);
             gcl.final_1_tp = ZhCalc.mul(gcl.unit_price, gcl.final_1_qty, tpDecimal);
-            gcl.deal_final_1_qty = ZhCalc.add(gcl.deal_qty, gcl.end_qc_minus_qty);
+            gcl.deal_final_1_qty = ZhCalc.add(gcl.deal_bills_qty, gcl.end_qc_minus_qty);
             gcl.deal_final_1_tp = ZhCalc.add(gcl.unit_price, gcl.deal_final_1_qty, tpDecimal);
             gcl.end_final_1_qty = ZhCalc.add(gcl.final_1_qty, gcl.end_qc_qty);
             gcl.end_final_1_tp = ZhCalc.add(gcl.final_1_tp, gcl.end_qc_tp);

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

@@ -1057,7 +1057,39 @@ const checkUtils = {
                     : data.end_contract_qty < data.deal_final_1_qty || data.end_contract_qty > 0;
             }
         }
-    }
+    },
+    compareCode(str1, str2, symbol = '-') {
+        if (!str1) {
+            return 1;
+        } else if (!str2) {
+            return -1;
+        }
+
+        function compareSubCode(code1, code2) {
+            if (numReg.test(code1)) {
+                if (numReg.test(code2)) {
+                    return parseInt(code1) - parseInt(code2);
+                } else {
+                    return -1
+                }
+            } else {
+                if (numReg.test(code2)) {
+                    return 1;
+                } else {
+                    return code1 === code2 ? 0 : (code1 < code2 ? -1 : 1); //code1.localeCompare(code2);
+                }
+            }
+        }
+        const numReg = /^[0-9]+$/;
+        const aCodes = str1.split(symbol), bCodes = str2.split(symbol);
+        for (let i = 0, iLength = Math.min(aCodes.length, bCodes.length); i < iLength; ++i) {
+            const iCompare = compareSubCode(aCodes[i], bCodes[i]);
+            if (iCompare !== 0) {
+                return iCompare;
+            }
+        }
+        return aCodes.length - bCodes.length;
+    },
 };
 
 Number.prototype.format2Str = function (pattern) {
@@ -1167,4 +1199,4 @@ const spreadColor = {
 
 $(document).ready(function () {
   $('.modal').draggable({handle: '.modal-header'});
-});
+});

+ 9 - 5
app/public/js/ledger.js

@@ -76,12 +76,13 @@ $(document).ready(function() {
         // markFoldSubKey: window.location.pathname.split('/')[2],
         markExpandKey: 'bills-expand',
         markExpandSubKey: window.location.pathname.split('/')[2],
+        calcFields: ['deal_tp', 'sgfh_tp', 'sjcl_tp', 'qtcl_tp', 'total_price'],
     };
-    if (checkTzMeasureType()) {
-        treeSetting.calcFields = ['sgfh_tp', 'sjcl_tp', 'qtcl_tp', 'total_price'];
-    } else {
-        treeSetting.calcFields = ['deal_tp', 'sgfh_tp', 'sjcl_tp', 'qtcl_tp', 'total_price'];
-    }
+    // if (checkTzMeasureType()) {
+    //     treeSetting.calcFields = ['sgfh_tp', 'sjcl_tp', 'qtcl_tp', 'total_price'];
+    // } else {
+    //     treeSetting.calcFields = ['deal_tp', 'sgfh_tp', 'sjcl_tp', 'qtcl_tp', 'total_price'];
+    // }
     treeSetting.calcFun = function (node) {
         node.dgn_price = ZhCalc.round(ZhCalc.div(node.total_price, node.dgn_qty1), 2);
     };
@@ -3445,6 +3446,8 @@ $(document).ready(function() {
                 {title: '计量单元', colSpan: '1', rowSpan: '1', field: 'pos_code', hAlign: 1, width: 70, formatter: '@'},
                 {title: '名称', colSpan: '1', rowSpan: '1', field: 'name', hAlign: 0, width: 300, formatter: '@'},
                 {title: '单位', colSpan: '1', rowSpan: '1', field: 'unit', hAlign: 1, width: 60, formatter: '@'},
+                {title: '签约数量', colSpan: '1', rowSpan: '1', field: 'deal_qty', hAlign: 2, width: 80, type: 'Number'},
+                {title: '签约金额', colSpan: '1', rowSpan: '1', field: 'deal_tp', hAlign: 2, width: 80, type: 'Number'},
                 {title: '清单数量', colSpan: '1', rowSpan: '1', field: 'quantity', hAlign: 2, width: 80, type: 'Number'},
                 {title: '设计数量1', colSpan: '1', rowSpan: '1', field: 'dgn_qty1', hAlign: 2, width: 80, type: 'Number'},
                 {title: '设计数量2', colSpan: '1', rowSpan: '1', field: 'dgn_qty2', hAlign: 2, width: 80, type: 'Number'},
@@ -3466,6 +3469,7 @@ $(document).ready(function() {
             data.push({
                 code: node.code, b_code: node.b_code, name: node.name, unit: node.unit,
                 unit_price: node.unit_price, quantity: node[qtyF], total_price: node[tpF],
+                deal_qty: node.deal_qty, deal_tp: node.deal_tp,
                 dgn_qty1: node.dgn_qty1, dgn_qty2: node.dgn_qty2,
                 drawing_code: node.drawing_code, memo: node.memo
             });

+ 226 - 66
app/public/js/material.js

@@ -155,7 +155,7 @@ $(document).ready(() => {
             {title: '|调差金额(材料税)', colSpan: '|1', rowSpan: '|1', field: 'm_tax_tp', hAlign: 2, width: 100, type: 'Number', readOnly: true, getValue: 'getValue.m_tax_tp'},
             {title: '截止上期|调差金额', colSpan: '2|1', rowSpan: '1|1', field: 'pre_tp', hAlign: 2, width: 100, type: 'Number', readOnly: true},
             {title: '|调差金额(材料税)', colSpan: '|1', rowSpan: '|1', field: 'tax_pre_tp', hAlign: 2, width: 100, type: 'Number', readOnly: true},
-            {title: '备注', colSpan: '1', rowSpan: '2', field: 'remark', hAlign: 0, width: 50, formatter: '@', readOnly: 'readOnly.remark'},
+            {title: '备注', colSpan: '1', rowSpan: '2', field: 'remark', hAlign: 0, width: 50, formatter: '@', cellType: 'ellipsisAutoTip', readOnly: 'readOnly.remark'},
             {title: '是否汇总', colSpan: '1', rowSpan: '2', field: 'is_summary', hAlign: 1, width: 60, cellType: 'checkbox', readOnly: 'readOnly.isEdit'}
         ])
     } else {
@@ -164,7 +164,7 @@ $(document).ready(() => {
             {title: '|本期应耗数量', colSpan: '|1', rowSpan: '|1', field: 'quantity', hAlign: 2, width: 90, type: 'Number', readOnly: true},
             {title: '|调差金额', colSpan: '|1', rowSpan: '|1', field: 'm_tp', hAlign: 2, width: 100, type: 'Number', readOnly: true, getValue: 'getValue.m_tp'},
             {title: '截止上期|调差金额', colSpan: '1|1', rowSpan: '1|1', field: 'pre_tp', hAlign: 2, width: 100, type: 'Number', readOnly: true},
-            {title: '备注', colSpan: '1', rowSpan: '2', field: 'remark', hAlign: 0, width: 50, formatter: '@', readOnly: 'readOnly.remark'},
+            {title: '备注', colSpan: '1', rowSpan: '2', field: 'remark', hAlign: 0, width: 50, formatter: '@', cellType: 'ellipsisAutoTip', readOnly: 'readOnly.remark'},
             {title: '是否汇总', colSpan: '1', rowSpan: '2', field: 'is_summary', hAlign: 1, width: 60, cellType: 'checkbox', readOnly: 'readOnly.isEdit'}
         ])
     }
@@ -362,7 +362,7 @@ $(document).ready(() => {
                     materialSpreadObj.refreshActn();
                     // 月信息价需要同时添加空白的list
                     if (months.length > 0) {
-                        const one_month ={ mb_id: result.id, code: '', name: null, origin: null, unit: null, order: result.order };
+                        const one_month ={ mb_id: result.info.id, code: '', name: null, origin: null, unit: null, order: result.info.order };
                         for (const m of months) {
                             one_month[m] = null;
                         }
@@ -419,73 +419,112 @@ $(document).ready(() => {
             if($('#bills0_list').is(':checked')) {
                 return;
             }
+            const data = {
+                type: 'changeOrder',
+                postData: [],
+            };
             const sheet = materialSpread.getActiveSheet();
-            const cur = SpreadJsObj.getSelectObject(sheet);
-            const up = materialBillsData[materialBillsData.indexOf(cur) - 1];
-            const mbIndex = materialBillsData.indexOf(cur);
-            postData(window.location.pathname + '/save', {type: 'changeOrder', id1: cur.id, id2: up.id}, function () {
-                const order = cur.order;
-                cur.order = up.order;
-                up.order = order;
-                materialBillsData.sort(function (a, b) {
-                    return a.order - b.order
-                });
-                SpreadJsObj.reLoadSheetData(sheet);
-                const sel = sheet.getSelections();
-                const index = materialBillsData.indexOf(cur);
-                sheet.setSelection(index, sel.length > 0 ? sel[0].col : 0, 1, 1);
+            const selection = sheet.getSelections();
+            const row = selection[0].row, count = selection[0].rowCount;
+            const first = sheet.zh_data[row];
+            if (!first) {
                 materialSpreadObj.refreshActn();
-                if (months.length > 0) {
-                    const monthCur = monthsList[mbIndex];
-                    const monthUp = monthsList[mbIndex - 1];
-                    const monthOrder = monthCur.order;
-                    monthCur.order = monthUp.order;
-                    monthUp.order = monthOrder;
-                    monthsList.sort(function (a, b) {
+                return false;
+            }
+            const pre = sheet.zh_data[row - 1], preUpdate = {id: pre.id};
+            for (let iRow = 0; iRow < count; iRow++) {
+                const posData = sheet.zh_data[iRow + row];
+                if (posData) {
+                    data.postData.push({id: posData.id, order: sheet.zh_data[iRow + row - 1].order});
+                    preUpdate.order = posData.order;
+                }
+            }
+            console.log(monthsList);
+            data.postData.push(preUpdate);
+            console.log(data);
+            if (data.postData.length > 0) {
+                postData(window.location.pathname + '/save', data, function () {
+                    _.forEach(data.postData, function (item) {
+                        const cl = _.find(materialBillsData, { id: item.id });
+                        cl.order = item.order;
+                    });
+                    materialBillsData.sort(function (a, b) {
                         return a.order - b.order
                     });
-                    const materialMonthSheet = materialMonthSpread.getActiveSheet();
-                    SpreadJsObj.reLoadSheetData(materialMonthSheet);
-                }
-            });
+                    SpreadJsObj.reLoadSheetData(sheet);
+                    const sel = selection[0];
+                    if (sel) {
+                        sheet.setSelection(sheet.zh_data.indexOf(first), sel.col, sel.rowCount, sel.colCount);
+                    }
+                    if (months.length > 0) {
+                        _.forEach(data.postData, function (item) {
+                            const cl = _.find(monthsList, { mb_id: item.id });
+                            cl.order = item.order;
+                        });
+                        monthsList.sort(function (a, b) {
+                            return a.order - b.order
+                        });
+                        const materialMonthSheet = materialMonthSpread.getActiveSheet();
+                        SpreadJsObj.reLoadSheetData(materialMonthSheet);
+                    }
+                    materialSpreadObj.refreshActn();
+                });
+            }
         },
         downMove: function () {
             if($('#bills0_list').is(':checked')) {
                 return;
             }
-            const sheet = materialSpread.getActiveSheet();
-            const cur = SpreadJsObj.getSelectObject(sheet);
-            const down = materialBillsData[materialBillsData.indexOf(cur) + 1];
-            const mbIndex = materialBillsData.indexOf(cur);
-            postData(window.location.pathname + '/save', {
+            const data = {
                 type: 'changeOrder',
-                id1: cur.id,
-                id2: down.id
-            }, function () {
-                const order = cur.order;
-                cur.order = down.order;
-                down.order = order;
-                materialBillsData.sort(function (a, b) {
-                    return a.order - b.order
-                });
-                SpreadJsObj.reLoadSheetData(sheet);
-                const sel = sheet.getSelections();
-                const index = materialBillsData.indexOf(cur);
-                sheet.setSelection(index, sel.length > 0 ? sel[0].col : 0, 1, 1);
+                postData: [],
+            };
+            const sheet = materialSpread.getActiveSheet();
+            const selection = sheet.getSelections();
+            const row = selection[0].row, count = selection[0].rowCount;
+            const first = sheet.zh_data[row];
+            if (!first) {
                 materialSpreadObj.refreshActn();
-                if (months.length > 0) {
-                    const monthCur = monthsList[mbIndex];
-                    const monthDown = monthsList[mbIndex + 1];
-                    const monthOrder = monthCur.order;
-                    monthCur.order = monthDown.order;
-                    monthDown.order = monthOrder;
-                    monthsList.sort(function (a, b) {
+                return false;
+            }
+            const next = sheet.zh_data[row + count], nextUpdate = {id: next.id};
+            for (let iRow = count - 1; iRow >= 0; iRow--) {
+                const posData = sheet.zh_data[iRow + row];
+                if (posData) {
+                    data.postData.push({id: posData.id, order: sheet.zh_data[iRow + row + 1].order});
+                    nextUpdate.order = posData.order;
+                }
+            }
+            data.postData.push(nextUpdate);
+            console.log(data);
+            if (data.postData.length > 0) {
+                postData(window.location.pathname + '/save', data, function () {
+                    _.forEach(data.postData, function (item) {
+                        const cl = _.find(materialBillsData, { id: item.id });
+                        cl.order = item.order;
+                    });
+                    materialBillsData.sort(function (a, b) {
                         return a.order - b.order
                     });
-                    const materialMonthSheet = materialMonthSpread.getActiveSheet();
-                    SpreadJsObj.reLoadSheetData(materialMonthSheet);
-                }
-            });
+                    SpreadJsObj.reLoadSheetData(sheet);
+                    const sel = selection[0];
+                    if (sel) {
+                        sheet.setSelection(sheet.zh_data.indexOf(first), sel.col, sel.rowCount, sel.colCount);
+                    }
+                    if (months.length > 0) {
+                        _.forEach(data.postData, function (item) {
+                            const cl = _.find(monthsList, { mb_id: item.id });
+                            cl.order = item.order;
+                        });
+                        monthsList.sort(function (a, b) {
+                            return a.order - b.order
+                        });
+                        const materialMonthSheet = materialMonthSpread.getActiveSheet();
+                        SpreadJsObj.reLoadSheetData(materialMonthSheet);
+                    }
+                    materialSpreadObj.refreshActn();
+                });
+            }
         },
         selectionChanged: function (e, info) {
             const sel = info.sheet.getSelections()[0];
@@ -1497,6 +1536,114 @@ $(document).ready(() => {
         materialSpreadObj.refreshActn();
     });
 
+    let gljLib;
+    const gljLibCellDoubleClick = function (e, info) {
+        if (readOnly) return;
+        const gljSheet = info.sheet;
+        if (!gljSheet.zh_setting || !gljSheet.zh_tree) { return; }
+
+        const gljTree = gljSheet.zh_tree;
+        const gljNode = gljTree.nodes[info.row];
+        const sheet = materialSpread.getActiveSheet();
+        const select = SpreadJsObj.getSelectObject(sheet);
+        if (!gljNode) return;
+
+        if (gljNode && gljNode.is_leaf === 0) {
+            toastr.warning('非最底层项目下,不应添加');
+            return;
+        }
+
+        postData(window.location.pathname + '/save', { type:'add-glj', postData: gljNode, order: select ? select.order : null }, function (result) {
+            if (result) {
+                // 比order大的+1
+                const maxData = select ? _.filter(materialBillsData, (item) => { return item.order > select.order }) : [];
+                _.forEach(maxData, function (item) {
+                    const cl = _.find(materialBillsData, { id: item.id });
+                    cl.order = item.order + 1;
+                });
+                materialBillsData.push(result.info);
+                materialBillsData.sort(function (a, b) {
+                    return a.order - b.order
+                });
+                console.log(materialBillsData);
+                if (isStageSelf) {
+                    materialSpreadObj.updateMaterialData(result);
+                    materialSpreadObj.getMaterialBillsData();
+                }
+                // sheet.addRows(materialBillsData.length - 1, 1);
+                // SpreadJsObj.reLoadRowData(sheet, materialBillsData.length - 1);
+                let newMaterialBillsData = materialBillsData;
+                if($('#bills0_list').is(':checked')) {
+                    newMaterialBillsData = _.filter(materialBillsData, function (item) {
+                        return item.quantity !== null && item.quantity !== 0;
+                    });
+                }
+                SpreadJsObj.loadSheetData(materialSpread.getActiveSheet(), SpreadJsObj.DataType.Data, newMaterialBillsData);
+                // materialSpreadObj.materialSheetReset();
+                sheet.setSelection(sheet.zh_data.indexOf(select) + 1, 0, 1, 1);
+                materialSpreadObj.refreshActn();
+                // 月信息价需要同时添加空白的list
+                if (months.length > 0) {
+                    const one_month ={ mb_id: result.info.id, code: result.info.code, name: result.info.name, origin: result.info.origin, unit: result.info.unit, order: result.info.order };
+                    for (const m of months) {
+                        one_month[m] = null;
+                    }
+                    _.forEach(maxData, function (item) {
+                        const cl = _.find(monthsList, { mb_id: item.id });
+                        cl.order = item.order + 1;
+                    });
+                    monthsList.push(one_month);
+                    monthsList.sort(function (a, b) {
+                        return a.order - b.order
+                    });
+                    console.log(monthsList);
+                    // const newMonthsList = _.filter(monthsList, function (item) {
+                    //     return _.findIndex(newMaterialBillsData, { code: item.code }) !== -1;
+                    // });
+                    // materialMonthSpread.getActiveSheet().addRows(newMonthsList.length - 1, 1);
+                    // SpreadJsObj.reLoadRowData(materialMonthSpread.getActiveSheet(), newMonthsList.length - 1);
+                    monthFunGather.monthsListSet();
+                    // materialMonthSpreadObj.monthsListSet();
+                }
+            }
+        });
+    };
+    const gljLibSetting = {
+        selector: '#material-tab',
+        stdType: 'glj',
+        libs: gljLists,
+        treeSetting: {
+            id: 'glj_id',
+            pid: 'glj_pid',
+            order: 'order',
+            level: 'level',
+            rootId: -1,
+            keys: ['id', 'list_id', 'glj_id'],
+        },
+        spreadSetting: {
+            cols: [
+                {title: '编号', field: 'code', hAlign: 0, width: 120, formatter: '@', readOnly: true, cellType: 'tree'},
+                {title: '名称', field: 'name', hAlign: 0, width: 150, formatter: '@', readOnly: true},
+                {title: '单位', field: 'unit', hAlign: 1, width: 50, formatter: '@', readOnly: true},
+                {title: '参考上涨幅度', field: 'rise_range', hAlign: 1, width: 50, formatter: '@', readOnly: true},
+                {title: '参考下跌幅度', field: 'fall_range', hAlign: 1, width: 50, formatter: '@', readOnly: true},
+            ],
+            treeCol: 0,
+            emptyRows: 0,
+            headRows: 1,
+            headRowHeight: [32],
+            defaultRowHeight: 21,
+            headerFont: '12px 微软雅黑',
+            font: '12px 微软雅黑',
+            headColWidth: [30],
+            selectedBackColor: '#fffacd',
+        },
+        spreadClassCss: 'sjs-material',
+        cellDoubleClick: gljLibCellDoubleClick,
+        page: 'material',
+        tid: window.location.pathname.split('/')[2],
+    };
+
     $.subMenu({
         menu: '#sub-menu', miniMenu: '#sub-mini-menu', miniMenuList: '#mini-menu-list',
         toMenu: '#to-menu', toMiniMenu: '#to-mini-menu',
@@ -1520,6 +1667,7 @@ $(document).ready(() => {
         callback: function () {
             materialSpread.refresh();
             materialMonthSpread.refresh();
+            if (gljLib) gljLib.spread.refresh();
             const width = (($('#right-view').width()/$('#right-view').parent('div').width())*100).toFixed();
             setLocalCache('material_month_' + materialID, width);
         }
@@ -1533,10 +1681,10 @@ $(document).ready(() => {
             const height = $('.bcontent-wrap').height();
             const cutHeight = isStageSelf ? getObjHeight($('#myTab')) : 0;
             $('.sjs-height-material').height($('.sjs-height-1').height() - cutHeight);
-            $('.sjs-height-material-month').height($('.sjs-height-1').height() - getObjHeight($('.sjs-bar-1')));
-            $('.material-table-height').height($('.bcontent-wrap').height() - getObjHeight($('.bc-bar')));
+            updateSjsHeight();
             materialSpread.refresh();
             materialMonthSpread.refresh();
+            if (gljLib) gljLib.spread.refresh();
             setLocalCache('material_bills_' + materialID, height);
         }
     });
@@ -1547,7 +1695,7 @@ $(document).ready(() => {
         const tab = $(this), tabPanel = $(tab.attr('content'));
         if (!tab.hasClass('active')) {
             $('a', '.side-menu').removeClass('active');
-            $('.tab-content .tab-select-show').removeClass('active');
+            $('.tab-content .tab-pane').removeClass('active');
             tab.addClass('active');
             tabPanel.addClass('active');
             showSideTools(tab.hasClass('active'));
@@ -1555,6 +1703,12 @@ $(document).ready(() => {
                 const width = (($('#right-view').width()/$('#right-view').parent('div').width())*100).toFixed();
                 setLocalCache('material_month_' + materialID, width);
                 materialMonthSpread.refresh();
+            } else if (tab.attr('content') === '#material-tab') {
+                if (!gljLib) {
+                    gljLib = $.gljLib(gljLibSetting);
+                }
+                updateSjsHeight();
+                gljLib.spread.refresh();
             }
         } else {
             removeLocalCache('material_month_' + materialID);
@@ -1563,13 +1717,13 @@ $(document).ready(() => {
             showSideTools(tab.hasClass('active'));
         }
         materialSpread.refresh();
-        materialMonthSpread.refresh();
+        // materialMonthSpread.refresh();
     });
     // 根据浏览器记录展开收起
     if (getLocalCache('material_month_' + materialID) && !isStageSelf) {
         const tab = $('.right-nav a[content="#month-tab"]'), tabPanel = $(tab.attr('content'));
         $('a', '.side-menu').removeClass('active');
-        $('.tab-content .tab-select-show').removeClass('active');
+        $('.tab-content .tab-pane').removeClass('active');
         tab.addClass('active');
         tabPanel.addClass('active');
         $('#right-view').width(getLocalCache('material_month_' + materialID) + '%');
@@ -1585,16 +1739,22 @@ $(document).ready(() => {
         $(".sp-wrap").height(bcontent-30);
         $('.sjs-height-1').height($(window).height()-cHeader-bcontent-90+53);
         $('.sjs-height-material').height($('.sjs-height-1').height() - cutHeight);
-        $('.sjs-height-material-month').height($('.sjs-height-1').height() - getObjHeight($('.sjs-bar-1')));
-        $('.material-table-height').height($('.bcontent-wrap').height() - getObjHeight($('.bc-bar')));
+        updateSjsHeight();
         materialSpread.refresh();
         materialMonthSpread.refresh();
+        if (gljLib) gljLib.spread.refresh();
     } else {
         $('.sjs-height-material').height($('.sjs-height-1').height() - cutHeight);
-        $('.sjs-height-material-month').height($('.sjs-height-1').height() - getObjHeight($('.sjs-bar-1')));
-        $('.material-table-height').height($('.bcontent-wrap').height() - getObjHeight($('.bc-bar')));
+        updateSjsHeight();
         materialSpread.refresh();
         materialMonthSpread.refresh();
+        if (gljLib) gljLib.spread.refresh();
+    }
+
+    function updateSjsHeight() {
+        $('.sjs-height-material-month').height($('.sjs-height-1').height() - getObjHeight($('.sjs-bar-1')));
+        $('.material-table-height').height($('.bcontent-wrap').height() - getObjHeight($('.bc-bar')));
+        $('.sjs-material').height($('.sjs-height-1').height() - getObjHeight($('.sjs-bar')));
     }
     function getObjHeight(select) {
         return select.length > 0 ? select.height() : 0;

+ 2 - 1
app/public/js/material_list.js

@@ -455,6 +455,7 @@ $(document).ready(() => {
             selfSheet.setCellType(1, 3, new TipCellType(), spreadNS.SheetArea.colHeader);
             selfSheet.resumePaint();
             checkNotJoinMaterialData();
+            ledgerSpread.getActiveSheet().setSelection(0, 0, 1, 1);
         }
     }
 
@@ -1635,7 +1636,7 @@ $(document).ready(() => {
                     const [iGclRow, iRow, nRow, sheet, lselect] = leafXmjSpreadObj.getSelect();
                     gclGatherData[iGclRow].leafXmjs[iRow].jiacha = calcOneBQJC(lselect);
                     calculateJiaCha(gclGatherData, iGclRow);
-                    // SpreadJsObj.reLoadRowData(sheet, nRow);
+                    SpreadJsObj.reLoadRowData(sheet, nRow);
                     SpreadJsObj.reLoadRowData(ledgerSpread.getActiveSheet(), iGclRow);
                     loadXmjMaterialData(iGclRow, nRow);
                 }, function () {

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

@@ -327,9 +327,9 @@ $(function () {
                     for (const one of insertGcl) {
                         if (one.leafXmjs && one.leafXmjs.length > 0) {
                             for (const xmj of one.leafXmjs) {
-                                const is_self = _.findIndex(selfList, { gcl_id: xmj.gcl_id, xmj_id: xmj.id, mx_id: xmj.mx_id ? xmj.mx_id : null }) !== -1;// 区分单独计量的明细工料含量
+                                const is_self = _.findIndex(selfList, { gcl_id: xmj.gcl_id, xmj_id: xmj.id, mx_id: xmj.mx_id ? xmj.mx_id : '' }) !== -1;// 区分单独计量的明细工料含量
                                 if (is_self) {
-                                    const billsList = _.filter(materialListForSelf, { gcl_id: xmj.gcl_id, xmj_id: xmj.id, mx_id: xmj.mx_id ? xmj.mx_id : null });
+                                    const billsList = _.filter(materialListForSelf, { gcl_id: xmj.gcl_id, xmj_id: xmj.id, mx_id: xmj.mx_id ? xmj.mx_id : '' });
                                     for (const bill of billsList) {
                                         if (!_.find(hadQtySelfList, bill)) {
                                             hadQtySelfList.push(bill);
@@ -415,7 +415,6 @@ $(function () {
                             const is_self = _.findIndex(selfList, { gcl_id: xmj.gcl_id, xmj_id: xmj.id, mx_id: xmj.mx_id ? xmj.mx_id : null }) !== -1;// 区分单独计量的明细工料含量
                             if (is_self) {
                                 const billsList = _.filter(materialListForSelf, { gcl_id: xmj.gcl_id, xmj_id: xmj.id, mx_id: xmj.mx_id ? xmj.mx_id : null });
-                                console.log(billsList);
                                 for (const bill of billsList) {
                                     hadQtySelfList.push(bill);
                                     insertSelfList.push({

+ 4 - 0
app/public/js/shares/cs_gcl_gather.js

@@ -75,7 +75,11 @@
 
         const gather = function (node) {
             $(`#${setting.id}-info`).html(`${node.code || ''}${node.b_code || ''} ${node.name || ''} - ${moment(new Date()).format('YYYY-MM-DD HH:mm:ss')}`);
+            result.length = 0;
             recursiveGather([node]);
+            result.sort((a, b) => {
+                return checkUtils.compareCode(a.b_code, b.b_code);
+            });
             SpreadJsObj.reLoadSheetData(sheet);
         };
 

+ 184 - 1
app/public/js/shares/cs_tools.js

@@ -685,6 +685,7 @@ const showSelectTab = function(select, spread, afterShow) {
         };
 
         const getTagDisplayHtml = function (tag) {
+            console.log(tag);
             const tagClass = classIndexes.find(x => {return x.color === tag.color}) || {};
             const tagHtml = [];
             tagHtml.push('<div name="tag-view">');
@@ -693,7 +694,7 @@ const showSelectTab = function(select, spread, afterShow) {
             tagHtml.push('</div>');
             tag.node && tagHtml.push((tag.node.code || '') + (tag.node.b_code || ''), ' / ', tag.node.name || '');
             if (tag.share) {
-                tagHtml.push('<i class="fa fa-users pull-right text-warning" data-toggle="tooltip" data-placement="bottom" title="" data-original-title="所有参与台账审批管理的用户都可以看到这条书签"></i>')
+                tagHtml.push(`<div class="pull-right"><i class="fa fa-users text-warning" data-toggle="tooltip" data-placement="bottom" title="" data-original-title="所有参与台账审批管理的用户都可以看到这条书签"></i> <span>${tag.u_name}</span></div>`);
             }
             tagHtml.push('<div class="pull-right edit-tag-btn">');
             const lid = tag.node ? tag.node.ledger_id : -1;
@@ -1306,4 +1307,186 @@ const showSelectTab = function(select, spread, afterShow) {
 
         return { spread }
     };
+
+    $.gljLib = function (setting) {
+        if (!setting.selector) return;
+        const obj = $(setting.selector);
+        const stdLibHtml = setting.libs.map(l => {
+            return `<option value="${l.id}" >${l.name}</option>`;
+        });
+        const relaSelect = {
+            showLevel: `std-${setting.stdType}-sl`,
+            searchText: `std-${setting.stdType}-st`,
+            searchResult: `std-${setting.stdType}-sr`,
+            searchPre: `std-${setting.stdType}-sp`,
+            searchNext: `std-${setting.stdType}-sn`,
+            searchClose: `std-${setting.stdType}-sc`,
+        };
+        obj.html(
+            '<div class="sjs-bar d-flex">\n' +
+            `    <div class="input-group input-group-sm pr-1"><select class="form-control form-control-sm col-auto">${stdLibHtml.join('')}</select></div>\n` +
+            '    <div class="ml-1">\n' +
+            '        <div class="dropdown">\n' +
+            '            <button class="btn btn-sm btn-outline-secondary dropdown-toggle" type="button" id="dropdownMenuButton" data-toggle="dropdown" aria-haspopup="true" aria-expanded="false">\n' +
+            '                <i class="fa fa-search"></i>\n' +
+            '            </button>\n' +
+            '            <div class="dropdown-menu dropdown-menu-right">\n' +
+            '                <div class="px-2 border-primary border-1 d-flex" style="width: 300px">\n' +
+            '                    <div class="d-inline-block">\n' +
+            '                        <div class="input-group input-group-sm mr-1">' +
+            `                            <input type="text" class="form-control" placeholder="输入编号/名称查找" id="${relaSelect.searchText}">\n` +
+            `                            <div class="input-group-append" ><span class="input-group-text" id="${relaSelect.searchResult}">结果:0</span></div>\n` +
+            '                            <div class="input-group-append" >\n' +
+            `                                <button class="btn btn-outline-secondary" type="button" title="上一个" id="${relaSelect.searchPre}"><i class="fa fa-angle-double-left"></i></button>\n` +
+            `                                <button class="btn btn-outline-secondary" type="button" title="下一个" id="${relaSelect.searchNext}"><i class="fa fa-angle-double-right"></i></button>\n` +
+            '                            </div>\n' +
+            '                        </div>\n' +
+            '                    </div>\n' +
+            `                    <div class="d-inline-block"><button class="btn btn-light text-danger btn-sm ml-1" type="button" id="${relaSelect.searchClose}"><i class="fa fa-remove"></i></button></div>\n` +
+            '                </div>\n' +
+            '            </div>\n' +
+            '        </div>\n' +
+            '    </div>' +
+            '</div>\n' +
+            `<div id="std-${setting.stdType}-spread" class="${setting.spreadClassCss ? setting.spreadClassCss : 'sjs-sh'}"></div>\n`
+        );
+        autoFlashHeight();
+        const pathTree = createNewPathTree('base', setting.treeSetting);
+
+        const spreadSetting = {
+            cols: [
+                {title: '名称', field: 'name', hAlign: 0, width: 180, formatter: '@'},
+                {title: '单位', field: 'unit', hAlign: 1, width: 60, formatter: '@'},
+            ],
+            treeCol: 0,
+            emptyRows: 0,
+            headRows: 1,
+            headRowHeight: [32],
+            defaultRowHeight: 21,
+            headerFont: '12px 微软雅黑',
+            font: '12px 微软雅黑',
+            headColWidth: [30],
+            selectedBackColor: '#fffacd',
+            readOnly: true,
+            stdType: setting.stdType,
+        };
+        spreadSetting.cols.unshift(setting.stdType === 'xmj'
+            ? {title: '项目节编号', field: 'code', hAlign: 0, width: 150, formatter: '@', cellType: 'tree'}
+            : {title: '清单编号', field: 'b_code', hAlign: 0, width: 150, formatter: '@', cellType: 'tree'});
+
+        const spread = SpreadJsObj.createNewSpread($(`#std-${setting.stdType}-spread`)[0]);
+        const sheet = spread.getActiveSheet();
+        SpreadJsObj.initSheet(sheet, setting.spreadSetting ? setting.spreadSetting : spreadSetting);
+
+        if (setting.cellDoubleClick) sheet.bind(spreadNS.Events.CellDoubleClick, setting.cellDoubleClick);
+        sheet.bind(spreadNS.Events.SelectionChanged, function (e, info) {
+            if (!info.oldSelections || !info.oldSelections[0] || info.newSelections[0].row !== info.oldSelections[0].row) {
+                SpreadJsObj.saveTopAndSelect(info.sheet, cacheKey.node);
+            }
+        });
+        sheet.bind(spreadNS.Events.TopRowChanged, function (e, info) {
+            SpreadJsObj.saveTopAndSelect(info.sheet, cacheKey.node);
+        });
+
+        const cacheLib = [];
+        const cacheKey = {
+            lib: setting.page + '-' + setting.tid + '-' + setting.stdType,
+        };
+
+        $('select', setting.selector).change(function () {
+            loadLib(parseInt(this.value), true);
+        });
+
+        const loadLib = function(listId, reload = false) {
+            cacheKey.node = cacheLib.lib + '-' + listId;
+            const locateMemory = function () {
+                if (!reload) {
+                    SpreadJsObj.loadTopAndSelect(sheet, cacheKey.node);
+                } else {
+                    removeLocalCache(cacheKey.node);
+                }
+            };
+            const cacheData = cacheLib.find(function (lib) {
+                return lib.id === listId;
+            });
+            if (cacheData) {
+                pathTree.loadDatas(cacheData.data);
+                SpreadJsObj.loadSheetData(sheet, 'tree', pathTree);
+                locateMemory();
+                setLocalCache(cacheKey.lib, listId);
+            } else {
+                postData(`/std-lib/get-data`, {stdType: setting.stdType, list_id: listId}, function (data) {
+                    cacheLib.push({id: listId, data: data});
+                    pathTree.loadDatas(data);
+                    SpreadJsObj.loadSheetData(sheet, 'tree', pathTree);
+                    locateMemory();
+                    setLocalCache(cacheKey.lib, listId);
+                });
+            }
+        };
+
+        const _loadCacheLib = function() {
+            let libId = getLocalCache(cacheKey.lib);
+            if (libId) {
+                $('select', setting.selector).val(libId);
+                loadLib(parseInt(libId));
+            } else {
+                loadLib(parseInt($('select', setting.selector).val()));
+            }
+        };
+        _loadCacheLib();
+
+        const searchObj = {
+            result: [],
+            cur: 0,
+            searchStdNode: function() {
+                const keyword = $(`#${relaSelect.searchText}`).val();
+                searchObj.result = keyword ? pathTree.nodes.filter(x => {
+                    return x.code.indexOf(keyword) >= 0 || x.name.indexOf(keyword) >= 0;
+                }) : [];
+                // searchObj.result = [];
+                // for (const x of pathTree.nodes) {
+                //     if (x.code.indexOf(keyword) >= 0 || x.b_code.indexOf(keyword) >= 0 || x.name.indexOf(keyword) >= 0) {
+                //         searchObj.result.push(x);
+                //     }
+                // }
+                $(`#${relaSelect.searchResult}`)[0].innerText = `结果:${searchObj.result.length}`;
+                searchObj.cur = 0;
+                if (searchObj.result.length > 0) {
+                    SpreadJsObj.locateTreeNode(sheet, pathTree.getNodeKey(searchObj.result[searchObj.cur]));
+                }
+            },
+            searchPre: function () {
+                if (searchObj.result.length === 0) return;
+                searchObj.cur = searchObj.cur === 0 ? searchObj.result.length - 1 : this.cur - 1;
+                SpreadJsObj.locateTreeNode(sheet, pathTree.getNodeKey(searchObj.result[searchObj.cur]), true);
+            },
+            searchNext: function () {
+                if (searchObj.result.length === 0) return;
+                searchObj.cur = searchObj.cur === searchObj.result.length - 1 ? 0 : searchObj.cur + 1;
+                SpreadJsObj.locateTreeNode(sheet, pathTree.getNodeKey(searchObj.result[searchObj.cur]), true);
+            },
+            clear: function () {
+                $(`#${relaSelect.searchText}`).val('');
+                $(`#${relaSelect.searchResult}`)[0].innerText = `结果:${0}`;
+                searchObj.result = [];
+                searchObj.cur = 0;
+            }
+        };
+        $(`#${relaSelect.searchText}`).change(searchObj.searchStdNode);
+        $(`#${relaSelect.searchPre}`).click(function (e) {
+            searchObj.searchPre();
+            e.stopPropagation();
+        });
+        $(`#${relaSelect.searchNext}`).click(function (e) {
+            searchObj.searchNext();
+            e.stopPropagation();
+        });
+        $(`#${relaSelect.searchClose}`).click(function (e) {
+            searchObj.clear();
+            e.stopPropagation();
+        });
+
+        return { spread }
+    };
 })(jQuery);

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

@@ -1377,7 +1377,7 @@ $(document).ready(() => {
                         gather_qty: node.gather_qty, gather_tp: node.gather_tp,
                         end_contract_qty: node.end_contract_qty, end_contract_tp: node.end_contract_tp,
                         end_qc_qty: node.end_qc_qty, end_qc_tp: node.end_qc_tp,
-                        end_gather_qty: node.end_gather_qty, end_gather_tp: node.end_gather_tp, end_gather_percent: node.end_gather_percent,
+                        end_gather_qty: node.end_gather_qty, end_gather_tp: node.end_gather_tp, end_final_1_percent: node.end_final_1_percent,
                         deal_dgn_qty1: node.deal_dgn_qty1, deal_dgn_qty2: node.deal_dgn_qty2,
                         c_dgn_qty1: node.c_dgn_qty1, c_dgn_qty2: node.c_dgn_qty2,
                         final_dgn_price: node.final_dgn_price,

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

@@ -97,6 +97,7 @@ $(document).ready(function () {
         const nPercent = Math.min(Math.max(ZhCalc.div(parseFloat($('#over-percent').val()), 100), 0.5), 1);
         for (const node of data) {
             if (node) {
+                if (node.b_code === '103-4')console.log(node);
                 const bOverRangeTz = billsGatherOver(node, 'final_1_qty', 'final_1_tp', nPercent);
                 const bOverRangeDeal = billsGatherOver(node, 'deal_final_1_qty', 'deal_final_1_tp', nPercent);
                 node.overRange = bQty ? bOverRangeTz : (bDealQty ? bOverRangeDeal : bOverRangeTz || bOverRangeDeal);

+ 8 - 42
app/service/ledger.js

@@ -645,37 +645,6 @@ module.exports = app => {
             return result;
         }
 
-        async _importCacheTreeNodes(transaction, nodes) {
-            const datas = [];
-            for (const node of nodes) {
-                datas.push({
-                    id: node.id,
-                    tender_id: this.ctx.tender.id,
-                    ledger_id: node.ledger_id,
-                    ledger_pid: node.ledger_pid,
-                    level: node.level,
-                    order: node.order,
-                    is_leaf: !node.children || node.children.length === 0,
-                    full_path: node.full_path,
-                    code: node.code,
-                    b_code: node.b_code,
-                    name: node.name,
-                    unit: node.unit,
-                    sgfh_qty: node.sgfh_qty,
-                    sgfh_tp: node.sgfh_tp,
-                    quantity: node.quantity,
-                    unit_price: node.unit_price,
-                    total_price: node.total_price,
-                    dgn_qty1: node.dgn_qty1,
-                    dgn_qty2: node.dgn_qty2,
-                    memo: node.memo,
-                    drawing_code: node.drawing_code,
-                });
-            }
-            await transaction.insert(this.tableName, datas);
-            return datas;
-        }
-
         /**
          * 导入Excel数据
          * @param excelData
@@ -712,18 +681,15 @@ module.exports = app => {
                         memo: node.memo,
                         drawing_code: node.drawing_code,
                         node_type: node.node_type,
+                        // 项目节不导入金额
+                        // todo 最底层项目节其实应该导入,但是由于目前项目节不能输入金额,也不能计量,导入金额就会有矛盾,故暂时不导入
+                        sgfh_qty: node.quantity,
+                        sgfh_tp: node.b_code ? node.total_price : 0,
+                        quantity: node.quantity,
+                        total_price: node.b_code ? node.total_price : 0,
+                        deal_qty: node.deal_qty,
+                        deal_tp: node.b_code ? node.deal_tp : 0,
                     };
-                    // 项目节不导入金额
-                    // todo 最底层项目节其实应该导入,但是由于目前项目节不能输入金额,也不能计量,导入金额就会有矛盾,故暂时不导入
-                    if (this.ctx.tender.data.measure_type === measureType.tz.value) {
-                        data.sgfh_qty = node.quantity;
-                        data.sgfh_tp = node.b_code ? node.total_price : 0;
-                        data.quantity = node.quantity;
-                        data.total_price = node.b_code ? node.total_price : 0;
-                    } else if (this.ctx.tender.data.measure_type === measureType.gcl.value) {
-                        data.deal_qty = node.quantity;
-                        data.deal_tp = node.b_code ? node.total_price : 0;
-                    }
                     datas.push(data);
                 }
                 await transaction.insert(this.tableName, datas);

+ 4 - 7
app/service/ledger_tag.js

@@ -31,13 +31,9 @@ module.exports = app => {
          * @returns {Promise<void>}
          */
         async getDatas(tid, sid = -1) {
-            // return await this.db.select(this.tableName, {
-            //     where: {tid: tid, sid: -1},
-            //     columns: ['id', 'uid', 'lid', 'share', 'color', 'comment'],
-            //     orders: [['create_time', 'desc']],
-            // });
-            const sql = 'SELECT id, uid, lid, share, color, comment FROM ' + this.tableName +
-                '  WHERE tid = ? and sid = ? and (uid = ? or share) ORDER BY create_time DESC';
+            const sql = 'SELECT la.id, la.uid, la.lid, la.share, la.color, la.comment, pa.name as u_name FROM ' + this.tableName + ' la ' +
+                '  LEFT JOIN ' + this.ctx.service.projectAccount.tableName + ' pa ON la.uid = pa.id' +
+                '  WHERE la.tid = ? and la.sid = ? and (la.uid = ? or la.share) ORDER BY la.create_time DESC';
             return await this.db.query(sql, [tid, sid, this.ctx.session.sessionUser.accountId]);
         }
 
@@ -67,6 +63,7 @@ module.exports = app => {
             }
             const result = await this.db.insert(this.tableName, data);
             data.id = result.insertId;
+            data.u_name = this.ctx.session.sessionUser.name;
             return data;
         }
 

+ 101 - 11
app/service/material_bills.js

@@ -75,6 +75,93 @@ module.exports = app => {
             }
         }
 
+        /**
+         * 添加工料
+         * @return {void}
+         */
+        async addByGlj(data, order = null) {
+            if (!this.ctx.tender || !this.ctx.material) {
+                throw '数据错误';
+            }
+            const newOrder = order ? parseInt(order) + 1 : await this._getMaxOrder(this.ctx.tender.id);
+            const transaction = await this.db.beginTransaction();
+            try {
+                // order以下的工料+1
+                await this._syncOrder(transaction, this.ctx.tender.id, newOrder, '+');
+                const resultData = {};
+                const newBills = {
+                    tid: this.ctx.tender.id,
+                    mid: this.ctx.material.id,
+                    code: data.code,
+                    name: data.name,
+                    unit: data.unit,
+                    m_up_risk: data.rise_range,
+                    m_down_risk: data.fall_range,
+                    spec: data.spec,
+                    m_type: data.type,
+                    remark: data.memo,
+                    order: newOrder,
+                    in_time: new Date(),
+                };
+                // 新增工料
+                const result = await transaction.insert(this.tableName, newBills);
+                if (result.affectedRows !== 1) {
+                    throw '新增工料数据失败';
+                }
+                if (this.ctx.material.is_stage_self) {
+                    await this.ctx.service.materialStageBills.add(transaction, result.insertId, data.memo);
+                    resultData.pushStageBillsData = await transaction.select(this.ctx.service.materialStageBills.tableName, { where: { mid: this.ctx.material.id, mb_id: result.insertId } });
+                }
+                const insertArray = [];
+                const material_month = this.ctx.material.months ? this.ctx.material.months.split(',') : [];
+                for (const ym of material_month) {
+                    const one_month = {
+                        tid: this.ctx.tender.id,
+                        mid: this.ctx.material.id,
+                        mb_id: result.insertId,
+                        msg_tp: null,
+                        yearmonth: ym,
+                    };
+                    insertArray.push(one_month);
+                }
+                if (insertArray.length !== 0) await transaction.insert(this.ctx.service.materialMonth.tableName, insertArray);
+                await transaction.commit();
+                resultData.info = await this.getDataById(result.insertId);
+                return resultData;
+            } catch (error) {
+                console.log(error);
+                await transaction.rollback();
+                throw error;
+            }
+        }
+
+        /**
+         * 移除清单时,同步其后清单order
+         * @param transaction - 事务
+         * @param {Number} cid - 变更cid
+         * @param {Number} order - order之后的
+         * @return {Promise<*>}
+         * @private
+         */
+        async _syncOrder(transaction, tid, order, selfOperate = '-', num = 1) {
+            this.initSqlBuilder();
+            this.sqlBuilder.setAndWhere('tid', {
+                value: this.db.escape(tid),
+                operate: '=',
+            });
+            this.sqlBuilder.setAndWhere('order', {
+                value: order,
+                operate: '>=',
+            });
+            this.sqlBuilder.setUpdateData('order', {
+                value: num,
+                selfOperate,
+            });
+            const [sql, sqlParam] = this.sqlBuilder.build(this.tableName, 'update');
+            const data = await transaction.query(sql, sqlParam);
+            return data;
+        }
+
         async _getMaxOrder(tenderId) {
             const sql = 'SELECT Max(??) As value FROM ?? Where tid = ' + tenderId;
             const sqlParam = ['order', this.tableName];
@@ -121,6 +208,8 @@ module.exports = app => {
                 if (material_month.length > 0) {
                     await transaction.delete(this.ctx.service.materialMonth.tableName, { mb_id: id });
                 }
+                // order以下的清单-1
+                await this._syncOrder(transaction, this.ctx.tender.id, mbInfo.order, '-');
                 await transaction.commit();
                 return result;
             } catch (err) {
@@ -135,23 +224,24 @@ module.exports = app => {
          * @param {Number} id2 - 工料2的id
          * @returns {Promise<void>}
          */
-        async changeOrder(id1, id2) {
+        async changeOrder(datas) {
             if (!this.ctx.tender || !this.ctx.material) {
                 throw '数据错误';
             }
-            const bill1 = await this.getDataByCondition({ tid: this.ctx.tender.id, id: id1 });
-            const bill2 = await this.getDataByCondition({ tid: this.ctx.tender.id, id: id2 });
-            if (!bill1 || !bill2) {
-                throw '数据错误';
-            }
+            // const bill1 = await this.getDataByCondition({ tid: this.ctx.tender.id, id: id1 });
+            // const bill2 = await this.getDataByCondition({ tid: this.ctx.tender.id, id: id2 });
+            // if (!bill1 || !bill2) {
+            //     throw '数据错误';
+            // }
 
             const transaction = await this.db.beginTransaction();
             try {
-                const order = bill1.order;
-                bill1.order = bill2.order;
-                bill2.order = order;
-                await transaction.update(this.tableName, { id: bill1.id, order: bill1.order });
-                await transaction.update(this.tableName, { id: bill2.id, order: bill2.order });
+                // const order = bill1.order;
+                // bill1.order = bill2.order;
+                // bill2.order = order;
+                // await transaction.update(this.tableName, { id: bill1.id, order: bill1.order });
+                // await transaction.update(this.tableName, { id: bill2.id, order: bill2.order });
+                await transaction.updateRows(this.tableName, datas);
                 await transaction.commit();
                 return true;
             } catch (err) {

+ 2 - 1
app/service/material_stage_bills.js

@@ -94,7 +94,7 @@ module.exports = app => {
         }
 
         // 添加工料时同步生成
-        async add(transaction, id) {
+        async add(transaction, id, remark = null) {
             for (const sid of this.ctx.material.stage_id.split(',')) {
                 const msInfo = await transaction.get(this.ctx.service.materialStage.tableName, { tid: this.ctx.tender.id, sid });
                 const insertData = {
@@ -103,6 +103,7 @@ module.exports = app => {
                     ms_id: msInfo.id,
                     mb_id: id,
                 };
+                if (remark) insertData.remark = remark;
                 await transaction.insert(this.tableName, insertData);
             }
         }

+ 7 - 1
app/view/material/info.ejs

@@ -67,7 +67,7 @@
                     <div class="c-body" id="right-view" style="width: 30%">
                         <div class="resize-x" id="right-spr" r-Type="width" div1="#left-view" div2="#right-view" title="调整大小" a-type="percent"><!--调整左右高度条--></div>
                         <div class="tab-content" style="width: 100%">
-                            <div id="qianyue" class="tab-pane active">
+                            <div id="month-tab" class="tab-pane active">
                                 <% if ((material.status === auditConst.status.uncheck || material.status === auditConst.status.checkNo) && ctx.session.sessionUser.accountId === material.user_id) {%>
                                     <div class="sjs-bar-1">
                                         <div class="pb-1">
@@ -79,6 +79,8 @@
                                 <div class="sjs-height-material-month" id="material-month-spread">
                                 </div>
                             </div>
+                            <div id="material-tab" class="tab-pane">
+                            </div>
                         </div>
                     </div>
                 </div>
@@ -209,6 +211,9 @@
                     <a class="nav-link" content="#month-tab" href="javascript: void(0);">月信息价</a>
                 </li>
                 <% } %>
+                <li class="nav-item">
+                    <a class="nav-link" content="#material-tab" href="javascript: void(0);">工料机库</a>
+                </li>
             </ul>
         </div>
     </div>
@@ -248,4 +253,5 @@
     }
     const months = JSON.parse('<%- JSON.stringify(months) %>');
     let monthsList = JSON.parse('<%- JSON.stringify(monthsList) %>');
+    const gljLists = JSON.parse(unescape('<%- escape(JSON.stringify(gljLists)) %>'));
 </script>

+ 1 - 0
app/view/report/rpt_individual.ejs

@@ -32,6 +32,7 @@
 </body>
 <SCRIPT type="text/javascript">
     const SCREEN_DPI = [96, 96];
+    const OSS_PATH = '<%- OSS_PATH %>';
     const WAIT_TIME_EXPORT = 300000;
     const current_stage_status = 3;
     const PAGE_SHOW = {closeWatermark: 0, closeExportPdf: 0, closeExportExcel: 0, showArchive: 0};

+ 6 - 1
app/view/tender/detail_modal.ejs

@@ -691,6 +691,10 @@
             <div class="modal-body">
                 <div class="form-group">
                     <div class="custom-control custom-checkbox mb-2">
+                        <input type="checkbox" class="custom-control-input" id="ledger-deal" checked="">
+                        <label class="custom-control-label" for="ledger-deal">签约数量、金额</label>
+                    </div>
+                    <div class="custom-control custom-checkbox mb-2">
                         <input type="checkbox" class="custom-control-input" id="ledger-dgn-qty" checked="">
                         <label class="custom-control-label" for="ledger-dgn-qty">项目节数量</label>
                     </div>
@@ -1486,6 +1490,7 @@
 
     // 显示设置
     function loadDisplayProperty () {
+        $('#ledger-deal')[0].checked = property.display.ledger.deal;
         $('#ledger-dgn-qty')[0].checked = property.display.ledger.dgnQty;
         $('#ledger-cl-qty')[0].checked = property.display.ledger.clQty;
         $('#ex-memo')[0].checked = property.display.exMemo;
@@ -1500,7 +1505,7 @@
     function post5 () {
         const prop = {
             display: {
-                ledger: { dgnQty: $('#ledger-dgn-qty')[0].checked, clQty: $('#ledger-cl-qty')[0].checked, },
+                ledger: { deal: $('#ledger-deal')[0].checked, dgnQty: $('#ledger-dgn-qty')[0].checked, clQty: $('#ledger-cl-qty')[0].checked, },
                 exMemo: $('#ex-memo')[0].checked,
                 thousandth: $('#thousandth')[0].checked,
                 stage: { realComplete: $('#stage-rc')[0].checked, correct: $('#stage-correct')[0].checked },

+ 5 - 1
sql/update.sql

@@ -56,4 +56,8 @@ CREATE TABLE `zh_material_stage_bills`  (
 ) ENGINE = InnoDB DEFAULT CHARSET=utf8 COLLATE=utf8_unicode_ci;
 
 ALTER TABLE `zh_project_account`
-ADD COLUMN `invalid_time`  varchar(50) NOT NULL DEFAULT '' AFTER `wx_name`;
+ADD COLUMN `invalid_time`  varchar(50) NOT NULL DEFAULT '' AFTER `wx_name`;
+
+ALTER TABLE `zh_valuation_list` ADD `glj_lib_id` VARCHAR(255) NOT NULL DEFAULT '' COMMENT '(0号台账模式)zh_glj_lib_list id列表,逗号分隔' AFTER `chapter_id`;
+ALTER TABLE `zh_valuation_list` ADD `list_glj_lib_id` VARCHAR(255) NOT NULL DEFAULT '' COMMENT '(工程量清单模式)zh_glj_lib_list id列表,逗号分隔' AFTER `list_chapter_id`;
+