瀏覽代碼

1. 清单汇总
2. 台账分解,台账审批部分bug

MaiXinRong 6 年之前
父節點
當前提交
db6f9f87a0

+ 65 - 0
app/const/spread.js

@@ -104,7 +104,71 @@ const stage = {
         headRows: 2,
         headRowHeight: [32, 32],
         defaultRowHeight: 21,
+    }
+};
+
+const stageGather = {
+    gcl: {
+        cols: [
+            {title: '清单编号', colSpan: '1', rowSpan: '2', field: 'b_code', hAlign: 0, width: 80, formatter: '@'},
+            {title: '名称', colSpan: '1', rowSpan: '2', field: 'name', hAlign: 0, width: 230, formatter: '@'},
+            {title: '单位', colSpan: '1', rowSpan: '2', field: 'unit', hAlign: 1, width: 60, formatter: '@'},
+            {title: '单价', colSpan: '1', rowSpan: '2', field: 'unit_price', hAlign: 2, width: 60, type: 'Number'},
+            {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'},
+            {title: '施工图复核|数量', colSpan: '2|1', rowSpan: '1|1', field: 'quantity', hAlign: 2, width: 60, type: 'Number'},
+            {title: '|金额', colSpan: '|1', rowSpan: '|1', field: 'total_price', hAlign: 2, width: 60, type: 'Number'},
+            {title: '本期合同计量|数量', colSpan: '2|1', rowSpan: '1|1', field: 'contract_qty', hAlign: 2, width: 60, type: 'Number'},
+            {title: '|金额', colSpan: '|1', rowSpan: '|1', field: 'contract_tp', hAlign: 2, width: 60, type: 'Number'},
+            {title: '本期数量变更|数量', colSpan: '3|1', rowSpan: '1|1', field: 'qc_qty', hAlign: 2, width: 60, type: 'Number'},
+            {title: '|金额', colSpan: '|1', rowSpan: '|1', field: 'qc_tp', hAlign: 2, width: 60, type: 'Number'},
+            {title: '|变更令', colSpan: '|1', rowSpan: '|1', field: 'qc_tp_bgl', hAlign: 2, width: 60, formatter: '@'},
+            {title: '本期完成计量|数量', colSpan: '2|1', rowSpan: '1|1', field: 'gather_qty', hAlign: 2, width: 60, type: 'Number'},
+            {title: '|金额', colSpan: '|1', rowSpan: '|1', field: 'gather_tp', hAlign: 2, width: 60, type: 'Number'},
+            {title: '截止本期合同计量|数量', colSpan: '2|1', rowSpan: '1|1', field: 'end_contract_qty', hAlign: 2, width: 60, type: 'Number'},
+            {title: '|金额', colSpan: '|1', rowSpan: '|1', field: 'end_contract_tp', hAlign: 2, width: 60, type: 'Number'},
+            {title: '截止本期数量变更|数量', colSpan: '2|1', rowSpan: '1|1', field: 'end_qc_qty', hAlign: 2, width: 60, type: 'Number'},
+            {title: '|金额', colSpan: '|1', rowSpan: '|1', field: 'end_qc_tp', hAlign: 2, width: 60, type: 'Number'},
+            {title: '截止本期完成计量|数量', colSpan: '2|1', rowSpan: '1|1', field: 'end_gather_qty', hAlign: 2, width: 60, type: 'Number'},
+            {title: '|金额', colSpan: '|1', rowSpan: '|1', field: 'end_gather_tp', hAlign: 2, width: 60, type: 'Number'},
+            {title: '施工图复核+变更令|数量', colSpan: '3|1', rowSpan: '1|1', field: 'final_qty', hAlign: 2, width: 60, type: 'Number'},
+            {title: '|金额', colSpan: '|1', rowSpan: '|1', field: 'final_tp', hAlign: 2, width: 60, type: 'Number'},
+            {title: '|累计完成率(%)', colSpan: '|1', rowSpan: '|1', field: 'percent', hAlign: 0, width: 100, type: 'Number'},
+        ],
+        emptyRows: 0,
+        headRows: 2,
+        headRowHeight: [32, 32],
+        defaultRowHeight: 21,
+        headerFont: '10pt 微软雅黑',
+        readOnly: true,
+        font: '10pt 微软雅黑',
     },
+    leafXmj: {
+        cols: [
+            {title: '项目节编号', colSpan: '1', rowSpan: '2', field: 'code', hAlign: 0, width: 100, formatter: '@'},
+            {title: '施工图复核数量', colSpan: '1', rowSpan: '2', field: 'quantity', hAlign: 2, width: 60, type: 'Number'},
+            {title: '本期计量数量|合同', colSpan: '3|1', rowSpan: '1|1', field: 'contract_qty', hAlign: 2, width: 60, type: 'Number'},
+            {title: '|数量变更', colSpan: '|1', rowSpan: '|1', field: 'qc_qty', hAlign: 2, width: 60, type: 'Number'},
+            {title: '|完成', colSpan: '|1', rowSpan: '1|1', field: 'gather_qty', hAlign: 2, width: 60, type: 'Number'},
+            {title: '截止本期计量数量|合同', colSpan: '3|1', rowSpan: '1|1', field: 'end_contract_qty', hAlign: 2, width: 60, type: 'Number'},
+            {title: '|数量变更', colSpan: '|1', rowSpan: '|1', field: 'end_qc_qty', hAlign: 2, width: 60, type: 'Number'},
+            {title: '|完成', colSpan: '|1', rowSpan: '|1', field: 'end_gather_qty', hAlign: 2, width: 60, type: 'Number'},
+            {title: '完成率(%)', colSpan: '1', rowSpan: '2', field: 'percent', hAlign: 0, width: 100, type: 'Number'},
+            {title: '单位工程', colSpan: '1', rowSpan: '2', field: 'dwgc', hAlign: 0, width: 80, formatter: '@'},
+            {title: '分部工程', colSpan: '1', rowSpan: '2', field: 'fbgc', hAlign: 0, width: 80, formatter: '@'},
+            {title: '分项工程', colSpan: '1', rowSpan: '2', field: 'fxgc', hAlign: 0, width: 80, formatter: '@'},
+            {title: '计量单元', colSpan: '1', rowSpan: '2', field: 'jldy', hAlign: 0, width: 80, formatter: '@'},
+            {title: '部位明细', colSpan: '1', rowSpan: '2', field: 'bwmx', hAlign: 0, width: 80, formatter: '@'},
+            {title: '图册号', colSpan: '1', rowSpan: '2', field: 'drawing_code', hAlign: 0, width: 80, formatter: '@'},
+        ],
+        emptyRows: 0,
+        headRows: 2,
+        headRowHeight: [32, 32],
+        defaultRowHeight: 21,
+        headerFont: '10pt 微软雅黑',
+        readOnly: true,
+        font: '10pt 微软雅黑',
+    }
 };
 
 // 计量台账 - cols需要二次计算得到
@@ -152,6 +216,7 @@ module.exports = {
     ledgerSpread,
     ledgerPosSpread,
     stage,
+    stageGather,
     filterCols: {
         tzWithoutCols,
         dgnCols,

+ 63 - 1
app/controller/stage_controller.js

@@ -317,7 +317,7 @@ module.exports = app => {
         }
 
         /**
-         * 中间计量,编辑中间计量草图
+         * 中间计量,添加草图,上传图片
          * @param ctx
          * @returns {Promise<void>}
          */
@@ -335,6 +335,11 @@ module.exports = app => {
             }
         }
 
+        /**
+         * 中间计量,设置草图
+         * @param ctx
+         * @returns {Promise<void>}
+         */
         async mergeCalcImage(ctx) {
             try {
                 await this._getStage(ctx);
@@ -407,6 +412,63 @@ module.exports = app => {
             }
         }
 
+        _getGatherSpreadSetting() {
+            const _ = this.app._;
+            function removeFieldCols(setting, cols) {
+                _.remove(setting.cols, function (c) {
+                    return cols.indexOf(c.field) > -1;
+                });
+            }
+            function setColFormat(cols, field, formatter) {
+                const filterCols = cols.filter(function (c) {
+                    return c.field.search(field) !== -1;
+                });
+                for (const col of filterCols) {
+                    col.formatter = formatter;
+                }
+            }
+            const tpFormatter = this.ctx.helper.getNumberFormatter(this.ctx.tender.info.decimal.tp);
+            const upFormatter = this.ctx.helper.getNumberFormatter(2);
+            const gcl = JSON.parse(JSON.stringify(spreadConst.stageGather.gcl));
+            setColFormat(gcl.cols, 'unit_price', upFormatter);
+            setColFormat(gcl.cols, 'total_price', tpFormatter);
+            setColFormat(gcl.cols, 'tp', tpFormatter);
+
+            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);
+            }
+            return [gcl, leafXmj];
+        }
+
+        /**
+         * 清单汇总
+         * @param ctx
+         * @returns {Promise<void>}
+         */
+        async gather(ctx) {
+            try {
+                await this._getStage(ctx);
+                const renderData = this._getDefaultRenderData(ctx);
+                [renderData.gclSpread, renderData.leafXmjSpread] = this._getGatherSpreadSetting();
+                renderData.ledger = await ctx.service.ledger.getDataByTenderId(ctx.tender.id, -1);
+                renderData.curLedgerData = await ctx.service.stageBills.getAuditorStageData(ctx.tender.id, ctx.stage.id, ctx.stage.times, 0);
+
+                renderData.pos = await ctx.service.pos.getPosData({tid: ctx.tender.id});
+                // todo 根据当前人,或指定对象查询数据
+                renderData.curPosData = await ctx.service.stagePos.getAuditorStageData(ctx.tender.id,
+                    ctx.stage.id, ctx.stage.times, ctx.stage.curAuditor ? ctx.stage.curAuditor.order : 0);
+                //renderData.gcl = await this.ctx.service.ledger.getAllLeafGclBills(this.ctx.tender.id);
+
+                renderData.jsFiles = this.app.jsFiles.common.concat(this.app.jsFiles.stage.gather);
+                await this.layout('stage/gather.ejs', renderData);
+            } catch (err) {
+                this.log(err);
+                ctx.redirect('/tender/' + ctx.tender.id + '/measure/stage');
+            }
+        }
+
         /**
          * 审核比较
          * @param ctx

+ 369 - 0
app/public/js/gcl_gather.js

@@ -0,0 +1,369 @@
+'use strict';
+
+/**
+ * 清单汇总(需使用path_tree.js, lodash.js)
+ *
+ * @author Mai
+ * @date
+ * @version
+ */
+
+const gclGatherModel = (function () {
+    // 需要汇总计算的字段
+    const ledgerGatherFields = ['quantity', 'total_price', 'deal_qty', 'deal_tp',
+        'contract_qty', 'contract_tp', 'qc_qty', 'qc_tp', 'gather_qty', 'gather_tp',
+        'end_contract_qty', 'end_contract_tp', 'end_qc_qty', 'end_qc_tp', 'end_gather_qty', 'end_gather_tp'];
+    const posGatherFields = ['quantity', 'contract_qty', 'qc_qty', 'gather_qty', 'end_contract_qty', 'end_qc_qty', 'end_gather_qty'];
+    // 初始化 清单树
+    const gsTreeSetting = {
+        id: 'ledger_id',
+        pid: 'ledger_pid',
+        order: 'order',
+        level: 'level',
+        rootId: -1,
+        keys: ['id', 'tender_id', 'ledger_id'],
+        stageId: 'id',
+    };
+    gsTreeSetting.updateFields = ['contract_qty', 'contract_tp', 'qc_qty', 'qc_tp'];
+    gsTreeSetting.calcFields = ['deal_tp', 'total_price', 'contract_tp', 'qc_tp', 'gather_tp', 'end_contract_tp', 'end_qc_tp', 'end_gather_tp'];
+    gsTreeSetting.calcFun = function (node) {
+        if (node.children && node.children.length === 0) {
+            node.gather_qty = _.toNumber(node.contract_qty) + _.toNumber(node.qc_qty);
+            node.end_contract_qty = _.toNumber(node.pre_contract_qty) + _.toNumber(node.contract_qty);
+            node.end_qc_qty = _.toNumber(node.pre_qc_qty) + _.toNumber(node.qc_qty);
+            node.end_gather_qty = _.toNumber(node.pre_gather_qty) + _.toNumber(node.gather_qty);
+        }
+        node.gather_tp = _.toNumber(node.contract_tp) + _.toNumber(node.qc_tp);
+        node.end_contract_tp = _.toNumber(node.pre_contract_tp) + _.toNumber(node.contract_tp);
+        node.end_qc_tp = _.toNumber(node.pre_qc_tp) + _.toNumber(node.qc_tp);
+        node.end_gather_tp = _.toNumber(node.pre_gather_tp) + _.toNumber(node.gather_tp);
+        if (checkZero(node.dgn_qty1)) {
+            node.dgn_price = _.round(node.total_price/node.dgn_qty1, 2);
+        } else {
+            node.dgn_price = null;
+        }
+    };
+    const gsTree = createNewPathTree('stage', gsTreeSetting);
+    // 初始化 部位明细
+    const posSetting = {
+        id: 'id', masterId: 'lid',
+        updateFields: ['contract_qty', 'qc_qty'],
+    };
+    posSetting.calcFun = function (pos) {
+        pos.gather_qty = _.toNumber(pos.contract_qty) + _.toNumber(pos.qc_qty);
+    };
+    const gsPos = new StagePosData(posSetting);
+
+    const gclList = [], leafXmjs = [];
+
+    /**
+     * 将所有数据加载至树结构
+     *
+     * @param ledger - 台账数据
+     * @param curStage - 当期计量数据
+     * @param preStage - 截止上期计量数据
+     * @param bgl - 变更令数据
+     */
+    function loadLedgerData (ledger, curStage, preStage, bgl) {
+        // 加载树结构数据
+        gsTree.loadDatas(ledger);
+        // 加载本期计量数据
+        gsTree.loadCurStageData(curStage);
+        // todo 加载截止上期计量数据
+        // todo 加载变更令数据
+        // 根据设置 计算 台账树结构
+        treeCalc.calculateAll(gsTree);
+    }
+
+    function loadPosData(pos, curPos, prePos) {
+        gsPos.loadDatas(pos);
+        gsPos.loadCurStageData(curPos);
+        gsPos.loadPreStageData(prePos);
+    }
+
+    function addNumber(a, b) {
+        if (b) {
+            if (a) {
+                return a + b;
+            } else {
+                return b;
+            }
+        } else {
+            return a;
+        }
+    }
+
+    function gatherfields(obj, src, fields) {
+        if (obj && src) {
+            for (const f of fields) {
+                obj[f] = addNumber(obj[f], src[f]);
+            }
+        }
+    }
+
+    /**
+     * 新建 清单汇总节点
+     * @param node - 最底层 工程量清单节点
+     * @returns {{b_code: *|string[], name, unit, unit_price: *|string[], leafXmjs: Array}}
+     */
+    function newGclNode(node) {
+        const gcl = {
+            b_code: node.b_code,
+            name: node.name,
+            unit: node.unit,
+            unit_price: node.unit_price,
+            leafXmjs: [],
+        };
+        gclList.push(gcl);
+        return gcl;
+    }
+
+    /**
+     * 获取清单汇总节点
+     *
+     * @param node - 最底层清单节点
+     * @returns {*}
+     */
+    function getGclNode(node) {
+        const gcl = gclList.find(function (g) {
+            return g.b_code === node.b_code && g.name === node.name && g.unit === node.unit && checkZero(g.unit_price - node.unit_price);
+        });
+        if (gcl) {
+            return gcl
+        } else {
+            return newGclNode(node);
+        }
+    }
+
+    /**
+     * 检查 text 是否是Peg
+     * e.g. K123+000(true) Kab+123(false) K123.234+234(false) K12+324.234(true)
+     *
+     * @param text
+     * @returns {*}
+     * @constructor
+     */
+    function CheckPeg(text) {
+        const pegReg = /[kK][0-9][++][0-9]{3}/;
+        return pegReg.test(text);
+    }
+
+    /**
+     * 获取 桩号节点
+     * @param node - 检索起始节点
+     * @returns {*}
+     */
+    function getPegNode (node) {
+        if (node) {
+            if (CheckPeg(node.name)) {
+                return node;
+            } else {
+                const parent = gsTree.getParent(node);
+                return parent ? getPegNode(parent) : null;
+            }
+        }
+    }
+
+    /**
+     * 获取节点的第N层父节点
+     *
+     * @param node - 节点(检索起点)
+     * @param level - 第N层
+     * @returns {*}
+     */
+    function getNodeByLevel(node, level) {
+        let cur = node;
+        while (cur && cur.level > level) {
+            cur = gsTree.getParent(cur);
+        }
+        return cur;
+    }
+
+    /**
+     * 获取 单位工程
+     *
+     * @param xmj - 计量单元(最底层项目节)
+     * @returns {string}
+     */
+    function getDwgc(xmj) {
+        const node = getNodeByLevel(xmj, 2);
+        return node ? node.name : '';
+    }
+
+    /**
+     * 获取 分部工程
+     *
+     * @param peg - 桩号节点
+     * @param xmj - 计量单元(最底层项目节)
+     * @returns {string}
+     */
+    function getFbgc(peg, xmj) {
+        if (peg && peg.id !== xmj.id) {
+            const node = getNodeByLevel(xmj, peg.level + 1);
+            return node ? node.name : '';
+        } else {
+            const node = getNodeByLevel(xmj, 3);
+            return node ? node.name : '';
+        }
+    }
+
+    /**
+     * 获取 分项工程
+     *
+     * @param peg - 桩号节点
+     * @param xmj - 计量单元(最底层项目节)
+     * @returns {string}
+     */
+    function getFxgc(peg, xmj) {
+        if (!peg) {
+            const node = getNodeByLevel(xmj, 4);
+            return node ? node.name : '';
+        } else if (peg.id === xmj.id) {
+            if (xmj.level > 4) {
+                let value = '';
+                for (let level = 4; level < xmj.level; level++) {
+                    const node = getNodeByLevel(xmj, level);
+                    value = value === '' ? node.name : node.name + '-' + value;
+                }
+                return value;
+            } else {
+                return '';
+            }
+        } else {
+            if (peg.level - 2 > xmj.level) {
+                let value = '';
+                for (let level = peg.level + 2; level < xmj.level; level++) {
+                    const node = getNodeByLevel(xmj, level);
+                    value = value === '' ? node.name : node.name + '-' + value;
+                }
+                return value;
+            } else {
+                return '';
+            }
+        }
+    }
+
+    /**
+     * 新建 最底层项目节 缓存数据
+     * @param leafXmj
+     * @returns {{id, code: *|string[], jldy, fbgc: string, fxgc: string, dwgc: string, bwmx: string, drawing_code: string}}
+     */
+    function newCacheLeafXmj(leafXmj) {
+        const peg = getPegNode(leafXmj);
+        const cacheLX = {
+            id: leafXmj.id,
+            code: leafXmj.code,
+            jldy: leafXmj.name,
+            fbgc: getFbgc(peg, leafXmj),
+            fxgc: getFxgc(peg, leafXmj),
+            dwgc: getDwgc(leafXmj),
+            drawing_code: leafXmj.drawing_code,
+        };
+        leafXmjs.push(cacheLX);
+        return cacheLX;
+    }
+
+    /**
+     * 获取缓存的最底层项目节数据
+     *
+     * @param leafXmj - 最底层项目节
+     * @returns {*}
+     */
+    function getCacheLeafXmj(leafXmj) {
+        const cacheLX = leafXmjs.find(function (lx) {
+            return lx.id === leafXmj.id;
+        });
+        if (!cacheLX) {
+            return newCacheLeafXmj(leafXmj);
+        } else {
+            return cacheLX;
+        }
+    }
+
+    /**
+     * 汇总节点
+     * @param node - 最底层 工程量清单 节点
+     * @param leafXmj - 所属 最底层 项目节
+     */
+    function loadGatherGclNode(node, leafXmj) {
+        const gcl = getGclNode(node);
+        gatherfields(gcl, node, ledgerGatherFields);
+        const cacheLeafXmj = getCacheLeafXmj(leafXmj);
+        const posRange = gsPos.getMasterRange(node.id);
+        const detail = posRange && posRange.length > 0 ? posRange : [node];
+        for (const d of detail) {
+            const dx = _.assign(cacheLeafXmj);
+            gatherfields(dx, d, posGatherFields);
+            dx.gcl_id = node.id;
+            if (d.name !== node.name) {
+                dx.bwmx = d.name;
+            }
+            if (d.drawing_code) {
+                dx.drawaing_code = d.drawing_code;
+            }
+            gcl.leafXmjs.push(dx);
+        }
+    }
+
+    /**
+     * (递归)汇总树节点
+     * @param nodes - 汇总节点列表
+     * @param leafXmj - 汇总节点所属的底层项目节
+     */
+    function recursiveGatherGclData(nodes, leafXmj) {
+        for (const node of nodes) {
+            if (node.b_code) {
+                if (node.children.length > 0) {
+                    recursiveGatherGclData(node.children, leafXmj);
+                } else {
+                    loadGatherGclNode(node, leafXmj);
+                }
+            } else if (node.children.length > 0) {
+                recursiveGatherGclData(node.children, node);
+            }
+        }
+    }
+
+    /**
+     * 根据树结构 清单汇总
+     */
+    function gatherGclData() {
+        // 清空旧数据
+        if (gclList.length > 0) {
+            gclList.splice(0, gclList.length - 1);
+        }
+        recursiveGatherGclData(gsTree.children, null);
+        gclList.sort(function (a, b) {
+            function compareCode(code1, code2) {
+                if (numReg.test(code1)) {
+                    if (numReg.test(code2)) {
+                        return _.toNumber(code1) - _.toNumber(code2);
+                    } else {
+                        return -1
+                    }
+                } else {
+                    if (numReg.test(code2)) {
+                        return 1;
+                    } else {
+                        return code1 === code2 ? 0 : (code1 < code2 ? -1 : 1);
+                    }
+                }
+            }
+            const numReg = /^[0-9]+$/;
+            const aCodes = a.b_code.split('-'), bCodes = b.b_code.split('-');
+            for (let i = 0, iLength = Math.min(aCodes.length, bCodes.length); i < iLength; ++i) {
+                const iCompare = compareCode(aCodes[i], bCodes[i]);
+                if (iCompare !== 0) {
+                    return iCompare;
+                }
+            }
+        });
+        return gclList;
+    }
+
+    return {
+        loadLedgerData,
+        loadPosData,
+        gatherGclData,
+    };
+})();

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

@@ -14,7 +14,7 @@ function autoFlashHeight(){
     var sBarz = $(".side-bar").height();
     var pBarz = $(".toolsbar-f").height();
     var bdtopc = $(".body-height-top").height();
-    var bcontent = $(".bcontent-wrap").height();
+    var bcontent = $(".bcontent-wrap").length > 0 ? $(".bcontent-wrap").height() : 0;
     $(".sjs-height-0").height($(window).height()-cHeader-110);
     $(".sjs-height-1").height($(window).height()-cHeader-bcontent-110);
     $(".sjs-height-2").height($(window).height()-cHeader-sBarz-110);
@@ -246,5 +246,5 @@ function getQueryVariable(variable) {
 
 const zeroRange = 0.00000001;
 function checkZero(value) {
-    return value && Math.abs(value) > zeroRange;
+    return _.isNumber(value) && value !== Math.abs(value) < zeroRange;
 }

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

@@ -406,6 +406,7 @@ $(document).ready(function() {
         },
     };
     // 绑定事件
+    ledgerSpread.bind(GC.Spread.Sheets.Events.SelectionChanged, treeOperationObj.selectionChanged);
     if (!ledgerSpreadSetting.readOnly) {
         ledgerSpread.bind(GC.Spread.Sheets.Events.SelectionChanged, function (e, info) {
             treeOperationObj.refreshOperationValid(info.sheet, info.newSelections);
@@ -421,7 +422,6 @@ $(document).ready(function() {
         });
         ledgerSpread.bind(GC.Spread.Sheets.Events.ClipboardPasting, function (e, info) {
         });
-        ledgerSpread.bind(GC.Spread.Sheets.Events.SelectionChanged, treeOperationObj.selectionChanged);
 
         // 绑定 删除等 顶部按钮
         $('#delete').click(function () {

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

@@ -19,7 +19,7 @@ function checkTzMeasureType () {
 $(document).ready(() => {
     autoFlashHeight();
     const ledgerSpread = SpreadJsObj.createNewSpread($('#ledger-spread')[0]);
-    const ledgerTree = createNewPathTree('active', {
+    const ledgerTree = createNewPathTree('base', {
         id: 'ledger_id',
         pid: 'ledger_pid',
         order: 'order',

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

@@ -113,6 +113,7 @@ class PosData {
 
 class StagePosData extends PosData {
     loadStageData(datas, fieldPre, fields) {
+        if (!datas) { return; }
         datas = datas instanceof Array ? datas : [datas];
         const loadedData = [];
         for (const data of datas) {

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

@@ -153,6 +153,18 @@ const SpreadJsObj = {
         spread.commandManager().setShortcutKey(null, GC.Spread.Commands.Key.del, false, false, false, false);
         spread.commandManager().setShortcutKey('deleteEvent', GC.Spread.Commands.Key.del, false, false, false, false);
     },
+    _initSheetDeafult: function (sheet) {
+        if (sheet.zh_setting.headerFont) {
+            const vStyle = new spreadNS.Style();
+            vStyle.font = sheet.zh_setting.headerFont;
+            sheet.setDefaultStyle(vStyle, spreadNS.SheetArea.colHeader);
+        }
+        if (sheet.zh_setting.font) {
+            const vStyle = new spreadNS.Style();
+            vStyle.font = sheet.zh_setting.font;
+            sheet.setDefaultStyle(vStyle, spreadNS.SheetArea.viewport);
+        }
+    },
     /**
      * 根据sheet.zh_setting初始化sheet表头
      * @param {GC.Spread.Sheets.Worksheet} sheet
@@ -195,6 +207,7 @@ const SpreadJsObj = {
     initSheet: function (sheet, setting) {
         this.beginMassOperation(sheet);
         sheet.zh_setting = setting;
+        this._initSheetDeafult(sheet);
         this._initSheetHeader(sheet);
         sheet.setRowCount(sheet.zh_setting.emptyRows);
         sheet.extendCellType = {};

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

@@ -0,0 +1,42 @@
+'use strict';
+
+/**
+ *
+ *
+ * @author Mai
+ * @date
+ * @version
+ */
+
+$(document).ready(function () {
+    autoFlashHeight();
+    // 初始化工程量清单
+    const gclSpread = SpreadJsObj.createNewSpread($('#gcl-spread')[0]);
+    SpreadJsObj.initSheet(gclSpread.getActiveSheet(), gclSpreadSetting);
+    // 初始化所属项目节
+    const leafXmjSpread = SpreadJsObj.createNewSpread($('#leaf-xmj-spread')[0]);
+    SpreadJsObj.initSheet(leafXmjSpread.getActiveSheet(), leafXmjSpreadSetting);
+    // 解析清单汇总数据
+    gclGatherModel.loadLedgerData(ledger, curLedgerData, []);
+    gclGatherModel.loadPosData(pos, curPosData);
+    const gclGatherData = gclGatherModel.gatherGclData();
+    // 获取项目节数据
+    function loadLeafXmjData(iGclRow) {
+        const gcl = gclGatherData[iGclRow];
+        if (gcl) {
+            SpreadJsObj.loadSheetData(leafXmjSpread.getActiveSheet(), SpreadJsObj.DataType.Data, gcl.leafXmjs);
+        } else {
+            SpreadJsObj.loadSheetData(leafXmjSpread.getActiveSheet(), SpreadJsObj.DataType.Data, []);
+        }
+    }
+    // 加载清单数据
+    SpreadJsObj.loadSheetData(gclSpread.getActiveSheet(), SpreadJsObj.DataType.Data, gclGatherData);
+    loadLeafXmjData(0);
+    // 切换清单行,读取所属项目节数据
+    gclSpread.getActiveSheet().bind(spreadNS.Events.SelectionChanged, function (e, info) {
+        const iOldRow = info.oldSelections[0].row, iNewRow = info.newSelections[0].row;
+        if (iNewRow !== iOldRow) {
+            loadLeafXmjData(iNewRow);
+        }
+    });
+});

+ 2 - 0
app/router.js

@@ -125,6 +125,8 @@ module.exports = app => {
     app.get('/tender/:id/measure/stage/:order/pay', sessionAuth, tenderCheck, 'stageController.pay');
     // 变更令
     app.get('/tender/:id/measure/stage/:order/change', sessionAuth, tenderCheck, 'stageController.change');
+    // 清单汇总
+    app.get('/tender/:id/measure/stage/:order/gather', sessionAuth, tenderCheck, 'stageController.gather');
     // 审核比较
     app.get('/tender/:id/measure/stage/:order/compare', sessionAuth, tenderCheck, 'stageController.compare');
     // 报表

+ 16 - 0
app/service/ledger.js

@@ -427,6 +427,22 @@ module.exports = app => {
         }
 
         /**
+         * 获取项目工程量
+         * @param tenderId
+         * @returns {Promise<*>}
+         */
+        async getGatherGclBills(tenderId) {
+            const sql = 'SELECT `b_code`, `name`, `unit`, `unit_price`, ' +
+                        '    Sum(`quantity`) As `quantity`, Sum(`total_price`) As `total_price`, ' +
+                        '    Sum(`deal_qty`) As `deal_qty`, Sum(`deal_tp`) As `deal_tp` ' +
+                        '  From ?? ' +
+                        '  WHERE `tender_id` = ? And `b_code` And `is_leaf` ' +
+                        '  GROUP BY `b_code`, `name`, `unit`, `unit_price`';
+            const sqlParam = [this.tableName, tenderId];
+            return await this.db.query(sql, sqlParam);
+        }
+
+        /**
          * 获取sql条件语句片段,仅供search、searchRange方法使用
          * @param {Object} where - 条件参数
          * @return {*[]}

+ 1 - 1
app/view/layout/menu.ejs

@@ -21,7 +21,7 @@
         </ul>
         <div class="dropright mb-1 ml-1">
             <a href="" class="btn btn-sm btn-light" data-toggle="dropdown" aria-haspopup="false" aria-expanded="false">
-                <%- ctx.session.sessionUser.name %>
+                <%- ctx.session.sessionUser.name.substr(ctx.session.sessionUser.name.length > 2 ? ctx.session.sessionUser.name.length - 2 : 0) %>
             </a>
             <div class="dropdown-menu">
                 <a href="/profile/info" class="dropdown-item">账号资料</a>

+ 1 - 1
app/view/ledger/audit.ejs

@@ -26,7 +26,7 @@
         <div class="row w-100 sub-content">
             <!--左栏-->
             <div class="c-body col-12">
-                <div class="sjs-height-1" id="ledger-spread">
+                <div class="sjs-height-0" id="ledger-spread">
                 </div>
                 <% if (tender.measure_type === measureType.tz.value) { %>
                 <div class="bcontent-wrap">

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

@@ -6,7 +6,7 @@
                 期列表
             </h2>
             <div>
-                <% if (ctx.session.sessionUser.accountId === ctx.tender.user_id && ctx.tender.ledger_status === auditConst.status.checked &&
+                <% if (ctx.session.sessionUser.accountId === ctx.tender.data.user_id && ctx.tender.data.ledger_status === auditConst.status.checked &&
                         (stages.length === 0 || stages[stages.length- 1].status === auditConst.status.checked)) { %>
                 <a href="#add-qi" data-toggle="modal" data-target="#add-qi" class="btn btn-primary btn-sm pull-right">开始新一期</a>
                 <% } %>

+ 1 - 1
app/view/measure/stage_modal.ejs

@@ -1,4 +1,4 @@
-<% if (ctx.session.sessionUser.accountId === ctx.tender.user_id && ctx.tender.ledger_status === auditConst.status.checked &&
+<% if (ctx.session.sessionUser.accountId === ctx.tender.data.user_id && ctx.tender.data.ledger_status === auditConst.status.checked &&
         (stages.length === 0 || stages[stages.length- 1].status === auditConst.status.checked)) { %>
 <!--弹出添加期-->
 <div class="modal fade" id="add-qi" data-backdrop="static">

+ 82 - 207
app/view/stage/deal.ejs

@@ -1,233 +1,108 @@
 <div class="panel-content">
-    <div class="panel-title fluid">
+    <div class="panel-title">
         <div class="title-main d-flex justify-content-between">
             <div>
                 <div class="d-inline-block">
-                    <ul class="nav nav-pills m-0">
-                        <li class="nav-item"><a class="nav-link" href="/stage">返回</a></li>
-                        <li class="nav-item"><a class="nav-link active" href="/stage/<%- stage.order %>/measure">本期计量台帐</a></li>
-                        <li class="nav-item"><a class="nav-link" href="/stage/<%- stage.order %>/deal">合同支付</a></li>
-                        <li class="nav-item"><a class="nav-link" href="/stage/<%- stage.order %>/report">报表</a></li>
-                    </ul>
+                    <a href="#" class="btn btn-sm" data-toggle="tooltip" data-placement="bottom" title="" data-original-title="插入"><i class="fa fa-sign-in" aria-hidden="true"></i></a>
+                    <a href="#" class="btn btn-sm" data-toggle="tooltip" data-placement="bottom" title="" data-original-title="添加"><i class="fa fa-plus" aria-hidden="true"></i></a>
+                    <a href="#" class="btn btn-sm" data-toggle="tooltip" data-placement="bottom" title="" data-original-title="删除"><i class="fa fa-remove" aria-hidden="true"></i></a>
+                    <a href="#" class="btn btn-sm" data-toggle="tooltip" data-placement="bottom" title="" data-original-title="下移"><i class="fa fa-arrow-down" aria-hidden="true"></i></a>
+                    <a href="#" class="btn btn-sm" data-toggle="tooltip" data-placement="bottom" title="" data-original-title="上移"><i class="fa fa-arrow-up" aria-hidden="true"></i></a>
+                    <a href="#" class="btn btn-sm" data-toggle="tooltip" data-placement="bottom" title="" data-original-title="上移"><i class="fa fa-unlock" aria-hidden="true"></i> 解锁</a>
+                </div>
+                <div class="d-inline-block">
+                    <div class="input-group input-group-sm ml-2 mt-1">
+                        <div class="input-group-prepend">
+                            <span class="input-group-text" id="basic-addon1">表达式</span>
+                        </div>
+                        <input type="text" class="form-control m-0">
+                    </div>
                 </div>
             </div>
             <div>
-                <a href="#sub-sp" data-toggle="modal" data-target="#sub-sp" class="btn btn-primary btn-sm pull-right">上报审批</a>
-                <a href="#sub-sp2" data-toggle="modal" data-target="#sub-sp2" class="btn btn-primary btn-sm pull-right">重新上报</a>
-                <a href="#sp-list" data-toggle="modal" data-target="#sp-list" class="btn btn-outline-secondary btn-sm pull-right">审批中</a>
-                <a href="#sp-list" data-toggle="modal" data-target="#sp-list" class="btn btn-outline-warning btn-sm pull-right text-muted">审批退回</a>
-                <!--审批-->
-                <a href="#sp-done" data-toggle="modal" data-target="#sp-done" class="btn btn-success btn-sm pull-right">审批通过</a>
-                <a href="#sp-back" data-toggle="modal" data-target="#sp-back" class="btn btn-warning btn-sm pull-right">审批退回</a>
+                <p class="text-danger"><i class="fa fa-warning"></i> 暂时无法上报审批,进入「中间计量」生成数据。</p>
             </div>
         </div>
     </div>
     <div class="content-wrap">
         <div class="c-header p-0"></div>
-        <div class="c-body">
-            <!--上部-->
-            <div class="body-height-top">
-                <div class="row">
-                    <!--左栏-->
-                    <div class="col-8">
-                        <!--工具栏-->
-                        <div class="row">
-                            <div class="col-7">
-                                <div class="btn-group">
-                                    <a href="#" class="btn btn-sm" data-toggle="tooltip" data-placement="bottom" title="" data-original-title="插入"><i class="fa fa-sign-in" aria-hidden="true"></i></a>
-                                    <a href="#" class="btn btn-sm" data-toggle="tooltip" data-placement="bottom" title="" data-original-title="添加"><i class="fa fa-plus" aria-hidden="true"></i></a>
-                                    <a href="#" class="btn btn-sm" data-toggle="tooltip" data-placement="bottom" title="" data-original-title="删除"><i class="fa fa-remove" aria-hidden="true"></i></a>
-                                    <a href="#" class="btn btn-sm" data-toggle="tooltip" data-placement="bottom" title="" data-original-title="下移"><i class="fa fa-arrow-down" aria-hidden="true"></i></a>
-                                    <a href="#" class="btn btn-sm" data-toggle="tooltip" data-placement="bottom" title="" data-original-title="上移"><i class="fa fa-arrow-up" aria-hidden="true"></i></a>
-                                    <a href="#" class="btn btn-sm" data-toggle="tooltip" data-placement="bottom" title="" data-original-title="上移"><i class="fa fa-unlock" aria-hidden="true"></i> 解锁</a>
-                                </div>
-                            </div>
-                            <div class="col-5">
-                                <div class="input-group input-group-sm mb-1">
-                                    <div class="input-group-prepend">
-                                        <span class="input-group-text" id="basic-addon1">表达式</span>
-                                    </div>
-                                    <input type="text" class="form-control" >
-                                </div>
-                            </div>
-                        </div>
-                        <div style="height:330px;overflow: auto;">
-                            <table class="table table-bordered">
-                                <tr><th></th><th>名称</th><th>扣款</th><th>本期金额(表达式)</th><th>累计金额</th><th>起扣金额</th><th>付(扣)款限额</th><th>附件</th><th>操作</th></tr>
-                                <tr><td>1</td><td>本期应付</td><td><input type="checkbox"></td><td></td><td></td><td></td><td></td><td><a class="btn btn-sm" href="#file" data-toggle="modal" data-target="#file"><i class="fa fa-paperclip "></i> 0</a></td>
-                                    <td>
-                                    </td>
-                                </tr>
-                                <tr><td>2</td><td>本期实付</td><td><input type="checkbox"></td><td></td><td></td><td></td><td></td><td><a class="btn btn-sm" href="#file" data-toggle="modal" data-target="#file"><i class="fa fa-paperclip "></i> 3</a></td>
-                                    <td>
-                                    </td>
-                                </tr>
-                                <tr><td>3</td><td>本期支付计量</td><td><input type="checkbox"></td><td></td><td></td><td></td><td></td><td><a class="btn btn-sm" href="#file" data-toggle="modal" data-target="#file"><i class="fa fa-paperclip "></i> 0</a></td>
-                                    <td>
-                                    </td>
-                                </tr>
-                                <!--被停用了-->
-                                <tr class="table-danger"><td>4</td><td>质量保证金</td><td><input type="checkbox"></td><td></td><td></td><td></td><td></td><td><a class="btn btn-sm" href="#file" data-toggle="modal" data-target="#file"><i class="fa fa-paperclip "></i> 0</a></td>
-                                    <td>
-                                        <a class="btn btn-sm btn-success" href="#">启用</a>
-                                    </td>
-                                </tr>
-                                <tr><td>5</td><td>扣回开工预付款</td><td><input type="checkbox"></td><td></td><td></td><td></td><td></td><td><a class="btn btn-sm" href="#file" data-toggle="modal" data-target="#file"><i class="fa fa-paperclip "></i> 0</a></td>
-                                    <td>
-                                        <div class="dropdown dropleft">
-                                            <button class="btn btn-sm btn-primary dropdown-toggle" type="button" id="dropdownMenuButton" data-toggle="dropdown" aria-haspopup="true" aria-expanded="false">
-                                                操作
-                                            </button>
-                                            <div class="dropdown-menu" aria-labelledby="dropdownMenuButton">
-                                                <a class="dropdown-item" href="#op2" data-toggle="modal" data-target="#op2">设置计提期限</a>
-                                                <a class="dropdown-item" href="#op3">不参与本期应付计算</a>
-                                                <a class="dropdown-item" href="#op4">停用</a>
-                                            </div>
-                                        </div>
-                                    </td>
-                                </tr>
-                                <!--不参与本期应付计算-->
-                                <tr class="table-secondary"><td>6</td><td>扣回材料预付款</td><td><input type="checkbox"></td><td></td><td></td><td></td><td></td><td><a class="btn btn-sm" href="#file" data-toggle="modal" data-target="#file"><i class="fa fa-paperclip "></i> 1</a></td>
-                                    <td>
-                                        <div class="dropdown dropleft">
-                                            <button class="btn btn-sm btn-primary dropdown-toggle" type="button" id="dropdownMenuButton" data-toggle="dropdown" aria-haspopup="true" aria-expanded="false">
-                                                操作
-                                            </button>
-                                            <div class="dropdown-menu" aria-labelledby="dropdownMenuButton">
-                                                <a class="dropdown-item" href="#op2" data-toggle="modal" data-target="#op2">设置计提期限</a>
-                                                <a class="dropdown-item" href="#op3">加入本期应付计算</a>
-                                                <a class="dropdown-item" href="#op4">停用</a>
-                                            </div>
-                                        </div>
-                                    </td>
-                                </tr>
-                            </table>
-                        </div>
-                    </div>
-                    <!--右栏-->
-                    <div class="col-4">
-                        <div style="height:365px;overflow: hidden;">
-                            <table class="table table-bordered">
-                                <tr><th></th><th>可选基数</th><th>计算代号</th></tr>
-                                <tr><td>1</td><td>签约合同价</td><td>htj</td></tr>
-                                <tr><td>2</td><td>签约开工预付款</td><td>kgyfk</td></tr>
-                                <tr><td>3</td><td>签约材料预付款</td><td>clyfk</td></tr>
-                                <tr><td>4</td><td>本期完成计量</td><td>bqwc</td></tr>
-                                <tr><td>5</td><td>本期支付计量</td><td>bqzf</td></tr>
-                                <tr><td>6</td><td>100章本期完成计量</td><td>ybbqwc</td></tr>
-                            </table>
-                        </div>
-                    </div>
-                </div>
-            </div>
-            <!--下部-->
-            <div class="body-height-bottom">
-                <legend>章节明细 <a href="#zjset" data-toggle="modal" data-target="#zjset" class="btn btn-sm">章节设置</a> <a href="#zfset" data-toggle="modal" data-target="#zfset" class="btn btn-sm">支付设置</a></legend>
-                <div class="sjs-height-6">
+        <div class="row w-100 sub-content">
+            <div class="c-body col-8">
+                <div class="sjs-height-0">
                     <table class="table table-bordered">
-                        <tr class="text-center"><th>章节名称</th><th>本期合同计量金额</th><th>本期变更计量金额</th><th>本期完成计量基金</th><th>累计完成计量金额</th><th>本期支付金额</th><th>累计支付金额</th></tr>
-                        <tr>
-                            <td>清单 第100章 总则</td>
-                            <td class="text-right">1000</td>
-                            <td class="text-right">1000</td>
-                            <td class="text-right">2000</td>
-                            <td class="text-right">2000</td>
-                            <td class="text-right">1000</td>
-                            <td class="text-right">2000</td>
-                        </tr>
-                        <tr>
-                            <td>清单 第200章 路基</td>
-                            <td class="text-right"></td>
-                            <td class="text-right"></td>
-                            <td class="text-right"></td>
-                            <td class="text-right"></td>
-                            <td class="text-right"></td>
-                            <td class="text-right"></td>
-                        </tr>
-                        <tr>
-                            <td>清单 第300章 路面</td>
-                            <td class="text-right"></td>
-                            <td class="text-right"></td>
-                            <td class="text-right"></td>
-                            <td class="text-right"></td>
-                            <td class="text-right"></td>
-                            <td class="text-right"></td>
-                        </tr>
-                        <tr>
-                            <td>清单 第400章 桥梁、涵洞</td>
-                            <td class="text-right"></td>
-                            <td class="text-right"></td>
-                            <td class="text-right"></td>
-                            <td class="text-right"></td>
-                            <td class="text-right"></td>
-                            <td class="text-right"></td>
+                        <tr><th></th><th>名称</th><th>扣款</th><th>本期金额(表达式)</th><th>累计金额</th><th>起扣金额</th><th>付(扣)款限额</th><th>附件</th><th>操作</th></tr>
+                        <tr><td>1</td><td>本期应付</td><td><input type="checkbox"></td><td></td><td></td><td></td><td></td><td><a class="btn btn-sm" href="#file" data-toggle="modal" data-target="#file"><i class="fa fa-paperclip "></i> 0</a></td>
+                            <td>
+                            </td>
                         </tr>
-                        <tr>
-                            <td>清单 第500章 隧道</td>
-                            <td class="text-right"></td>
-                            <td class="text-right"></td>
-                            <td class="text-right"></td>
-                            <td class="text-right"></td>
-                            <td class="text-right"></td>
-                            <td class="text-right"></td>
+                        <tr><td>2</td><td>本期实付</td><td><input type="checkbox"></td><td></td><td></td><td></td><td></td><td><a class="btn btn-sm" href="#file" data-toggle="modal" data-target="#file"><i class="fa fa-paperclip "></i> 3</a></td>
+                            <td>
+                            </td>
                         </tr>
-                        <tr>
-                            <td>清单 第600章 安全设施及预埋管线</td>
-                            <td class="text-right"></td>
-                            <td class="text-right"></td>
-                            <td class="text-right"></td>
-                            <td class="text-right"></td>
-                            <td class="text-right"></td>
-                            <td class="text-right"></td>
+                        <tr><td>3</td><td>本期完成计量 <a href="#detail" data-toggle="modal" data-target="#detail">明细</a></td><td><input type="checkbox"></td><td></td><td></td><td></td><td></td><td><a class="btn btn-sm" href="#file" data-toggle="modal" data-target="#file"><i class="fa fa-paperclip "></i> 0</a></td>
+                            <td>
+                            </td>
                         </tr>
-                        <tr>
-                            <td>清单 第700章 绿化及环境保护</td>
-                            <td class="text-right"></td>
-                            <td class="text-right"></td>
-                            <td class="text-right"></td>
-                            <td class="text-right"></td>
-                            <td class="text-right"></td>
-                            <td class="text-right"></td>
+                        <!--被停用了-->
+                        <tr class="table-secondary"><td>4</td><td>质量保证金</td><td><input type="checkbox"></td><td></td><td></td><td></td><td></td><td><a class="btn btn-sm" href="#file" data-toggle="modal" data-target="#file"><i class="fa fa-paperclip "></i> 0</a></td>
+                            <td>
+                                <a class="btn btn-sm btn-success" href="#">启用</a>
+                            </td>
                         </tr>
-                        <tr>
-                            <td>未计入章节清单合计</td>
-                            <td class="text-right"></td>
-                            <td class="text-right"></td>
-                            <td class="text-right"></td>
-                            <td class="text-right"></td>
-                            <td class="text-right"></td>
-                            <td class="text-right"></td>
-                        </tr>
-                        <tr>
-                            <td>清单小计(A)</td>
-                            <td class="text-right">1000</td>
-                            <td class="text-right">1000</td>
-                            <td class="text-right">2000</td>
-                            <td class="text-right">2000</td>
-                            <td class="text-right">2000</td>
-                            <td class="text-right">2000</td>
+                        <tr><td>5</td><td>扣回开工预付款</td><td><input type="checkbox"></td><td></td><td></td><td></td><td></td><td><a class="btn btn-sm" href="#file" data-toggle="modal" data-target="#file"><i class="fa fa-paperclip "></i> 0</a></td>
+                            <td>
+                                <div class="dropdown dropleft">
+                                    <button class="btn btn-sm btn-primary dropdown-toggle" type="button" id="dropdownMenuButton" data-toggle="dropdown" aria-haspopup="true" aria-expanded="false">
+                                        操作
+                                    </button>
+                                    <div class="dropdown-menu" aria-labelledby="dropdownMenuButton">
+                                        <a class="dropdown-item" href="#op2" data-toggle="modal" data-target="#op2">设置计提期限</a>
+                                        <a class="dropdown-item" href="#op3">不参与本期应付计算</a>
+                                        <a class="dropdown-item" href="#op4">停用</a>
+                                    </div>
+                                </div>
+                            </td>
                         </tr>
-                        <tr>
-                            <td>非清单单项费用(B)</td>
-                            <td class="text-right">500</td>
-                            <td class="text-right"></td>
-                            <td class="text-right">500</td>
-                            <td class="text-right">500</td>
-                            <td class="text-right">500</td>
-                            <td class="text-right">500</td>
+                        <!--不参与本期应付计算-->
+                        <tr class="table-secondary"><td>6</td><td>扣回材料预付款</td><td><input type="checkbox"></td><td></td><td></td><td></td><td></td><td><a class="btn btn-sm" href="#file" data-toggle="modal" data-target="#file"><i class="fa fa-paperclip "></i> 1</a></td>
+                            <td>
+                                <div class="dropdown dropleft">
+                                    <button class="btn btn-sm btn-primary dropdown-toggle" type="button" id="dropdownMenuButton" data-toggle="dropdown" aria-haspopup="true" aria-expanded="false">
+                                        操作
+                                    </button>
+                                    <div class="dropdown-menu" aria-labelledby="dropdownMenuButton">
+                                        <a class="dropdown-item" href="#op2" data-toggle="modal" data-target="#op2">设置计提期限</a>
+                                        <a class="dropdown-item" href="#op3">加入本期应付计算</a>
+                                        <a class="dropdown-item" href="#op4">停用</a>
+                                    </div>
+                                </div>
+                            </td>
                         </tr>
-                        <tr>
-                            <td>合计(C=A+B)</td>
-                            <td class="text-right">1500</td>
-                            <td class="text-right">1000</td>
-                            <td class="text-right">2500</td>
-                            <td class="text-right">2500</td>
-                            <td class="text-right">2500</td>
-                            <td class="text-right">2500</td>
+                        <!--新增-->
+                        <tr class="table-warning"><td>7</td><td>审核人新增数据</td><td><input type="checkbox"></td><td></td><td></td><td></td><td></td><td><a class="btn btn-sm" href="#file" data-toggle="modal" data-target="#file"><i class="fa fa-paperclip "></i> 1</a></td>
+                            <td>
+                                <button class="btn btn-sm btn-primary" type="button"  href="#op2" data-toggle="modal" data-target="#op2">
+                                    设置计提期限
+                                </button>
+                            </td>
                         </tr>
                     </table>
                 </div>
             </div>
+            <div class="c-body col">
+                <div class="side-bar-1 sjs-bar"></div>
+                <div class="sjs-sh-1">
+                    <table class="table table-bordered">
+                        <tr><th></th><th>可选基数</th><th>计算代号</th></tr>
+                        <tr><td>1</td><td>签约合同价</td><td>htj</td></tr>
+                        <tr><td>2</td><td>签约合同价(不含暂列金)</td><td>htjszl</td></tr>
+                        <tr><td>3</td><td>签约开工预付款</td><td>kgyfk</td></tr>
+                        <tr><td>4</td><td>签约材料预付款</td><td>clyfk</td></tr>
+                        <tr><td>5</td><td>本期完成计量</td><td>bqwc</td></tr>
+                        <tr><td>6</td><td>100章本期完成计量</td><td>ybbqwc</td></tr>
+                    </table>
+                </div>
+            </div>
         </div>
     </div>
 </div>

+ 83 - 0
app/view/stage/gather.ejs

@@ -0,0 +1,83 @@
+<% include ../tender/tender_sub_menu.ejs %>
+<div class="panel-content">
+    <div class="panel-title">
+        <div class="title-main d-flex justify-content-between">
+            <div>
+                <div class="dropdown">
+                    <button class="btn btn-sm btn-light dropdown-toggle text-primary" type="button" id="dropdownMenuButton" data-toggle="dropdown" aria-haspopup="true" aria-expanded="false">
+                        超计显示
+                    </button>
+                    <div class="dropdown-menu" aria-labelledby="dropdownMenuButton" style="width:290px">
+                        <span class="dropdown-item-text text-danger">累计完成合同计量 大于</span>
+                        <form class="px-4 py-3">
+                            <div class="form-group">
+                                <div class="custom-control custom-radio">
+                                    <input type="radio" id="customRadio1" name="customRadio" class="custom-control-input" checked="">
+                                    <label class="custom-control-label" for="customRadio1">施工图复核数量</label>
+                                </div>
+                            </div>
+                            <div class="form-group">
+                                <div class="custom-control custom-radio">
+                                    <input type="radio" id="customRadio2" name="customRadio" class="custom-control-input">
+                                    <label class="custom-control-label" for="customRadio2">签约清单数量</label>
+                                </div>
+                            </div>
+                            <div class="form-group mb-0">
+                                <div class="custom-control custom-radio">
+                                    <input type="radio" id="customRadio3" name="customRadio" class="custom-control-input">
+                                    <label class="custom-control-label" for="customRadio3">施工图复核数量 或 签约清单数量</label>
+                                </div>
+                            </div>
+                        </form>
+                    </div>
+                </div>
+            </div>
+            <div>
+                <a href="#sub-sp" data-toggle="modal" data-target="#sub-sp" class="btn btn-primary btn-sm pull-right">上报审批</a>
+                <a href="#sub-sp2" data-toggle="modal" data-target="#sub-sp2" class="btn btn-primary btn-sm pull-right">重新上报</a>
+            </div>
+        </div>
+    </div>
+    <div class="content-wrap">
+        <div class="c-header p-0"></div>
+        <div class="c-body">
+            <div class="sjs-height-1" id="gcl-spread">
+            </div>
+            <div class="bcontent-wrap">
+                <div class="bc-bar mb-1">
+                    <ul class="nav nav-tabs">
+                        <li class="nav-item">
+                            <a class="nav-link active" data-toggle="tab" href="#xmujie" role="tab">所属项目节</a>
+                        </li>
+                        <li class="nav-item">
+                            <a class="nav-link " data-toggle="tab" href="#biangeng" role="tab">相关变更令</a>
+                        </li>
+                    </ul>
+                </div>
+                <div class="tab-content">
+                    <div class="tab-pane active" id="xmujie">
+                        <div class="sp-wrap" id="leaf-xmj-spread">
+                        </div>
+                    </div>
+                    <div class="tab-pane" id="biangeng">
+                        <div class="sp-wrap">
+                            <table class="table table-sm table-bordered">
+                                <tr><th>变更令</th><th>名称</th><th>批复文号</th><th>变更图号</th><th>数量</th></tr>
+                                <tr><td>BGL01</td><td>XX变更令</td><td></td><td></td><td>100</td></tr>
+                                <tr><td>BGL02</td><td>YY变更令</td><td></td><td></td><td>80</td></tr>
+                            </table>
+                        </div>
+                    </div>
+                </div>
+            </div>
+        </div>
+    </div>
+</div>
+<script>
+    const gclSpreadSetting = JSON.parse('<%- JSON.stringify(gclSpread) %>');
+    const leafXmjSpreadSetting = JSON.parse('<%- JSON.stringify(leafXmjSpread) %>');
+    const ledger = JSON.parse('<%- JSON.stringify(ledger) %>');
+    const curLedgerData = JSON.parse('<%- JSON.stringify(curLedgerData) %>');
+    const pos = JSON.parse('<%- JSON.stringify(pos) %>');
+    const curPosData = JSON.parse('<%- JSON.stringify(curPosData) %>');
+</script>

+ 3 - 2
config/config.qa.js

@@ -46,10 +46,11 @@ module.exports = appInfo => {
     // session配置
     config.session = {
         key: 'ZHC_SESS',
-        maxAge: 3600 * 1000, // 1小时
+        maxAge: 8 * 3600 * 1000, // 8小时
         httpOnly: true,
         encrypt: true,
-        renew: true, // session临近过期更新过期时间
+        //renew: true, // session临近过期更新过期时间
+        rolling: true, // 每次都更新session有效期
     };
 
     // 是否压缩替换前端js

+ 12 - 0
config/web.js

@@ -108,6 +108,18 @@ const JsFiles = {
                     "/public/js/stage_detail.js",
                 ],
                 mergeFile: 'stage_detail',
+            },
+            gather: {
+                files: [
+                    "/public/js/spreadjs/sheets/gc.spread.sheets.all.10.0.1.min.js",
+                ],
+                mergeFiles: [
+                    "/public/js/spreadjs_rela/spreadjs_zh.js",
+                    "/public/js/path_tree.js",
+                    "/public/js/gcl_gather.js",
+                    "/public/js/stage_gather.js",
+                ],
+                mergeFile: 'stage_gather',
             }
         }
     }