Explorar o código

1. 标段列表,显示至
2. 标段概况,显示功能,台账新增列

MaiXinRong %!s(int64=2) %!d(string=hai) anos
pai
achega
f6e0f62234

+ 1 - 0
app/const/tender_info.js

@@ -109,6 +109,7 @@ const defaultInfo = {
             dgnQty: false,
             clQty: false,
         },
+        exMemo: true,
         thousandth: false,
         stage: {
             realComplete: false,

+ 1 - 1
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.getSjsRela(ctx.session.sessionProject.id);
+            const sjsRela = await this.ctx.service.project.getTenderSjsRela(ctx.session.sessionProject.id);
             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);

+ 1 - 1
app/controller/ledger_audit_controller.js

@@ -69,7 +69,7 @@ module.exports = app => {
                     measureType,
                 };
                 const [ledgerSpread, posSpread] = this._getSpreadSetting();
-                const sjsRela = await this.ctx.service.project.getSjsRela(ctx.session.sessionProject.id);
+                const sjsRela = await this.ctx.service.project.getTenderSjsRela(ctx.session.sessionProject.id);
                 this.ctx.helper.refreshSpreadShow(sjsRela.ledgerCol, [ledgerSpread, posSpread]);
 
                 const curAuditor = await ctx.service.ledgerAudit.getCurAuditor(ctx.tender.id, ctx.tender.data.ledger_times);

+ 3 - 3
app/controller/ledger_controller.js

@@ -141,7 +141,7 @@ module.exports = app => {
             try {
                 const tender = ctx.tender;
                 const [ledgerSpread, posSpread] = await this._getSpreadSetting();
-                const sjsRela = await this.ctx.service.project.getSjsRela(ctx.session.sessionProject.id);
+                const sjsRela = await this.ctx.service.project.getTenderSjsRela(ctx.session.sessionProject.id);
                 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 +481,7 @@ module.exports = app => {
          */
         async loadExplodeData(ctx) {
             try {
-                const sjsRela = await this.ctx.service.project.getSjsRela(ctx.session.sessionProject.id);
+                const sjsRela = await ctx.service.project.getTenderSjsRela(ctx.session.sessionProject.id);
                 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 +692,7 @@ module.exports = app => {
          */
         async bwtz(ctx) {
             try {
-                const sjsRela = await this.ctx.service.project.getSjsRela(ctx.session.sessionProject.id);
+                const sjsRela = await ctx.service.project.getTenderSjsRela(ctx.session.sessionProject.id);
                 const renderData = {
                     tender: ctx.tender.data,
                     jsFiles: this.app.jsFiles.common.concat(this.app.jsFiles.ledger.bwtz),

+ 2 - 2
app/controller/revise_controller.js

@@ -290,7 +290,7 @@ module.exports = app => {
 
         async _getDefaultReviseInfoData(ctx, revise) {
             const [ledgerSpread, posSpread] = this._getSpreadSetting(revise);
-            const sjsRela = await this.ctx.service.project.getSjsRela(ctx.session.sessionProject.id);
+            const sjsRela = await ctx.service.project.getTenderSjsRela(ctx.session.sessionProject.id);
             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);
@@ -487,7 +487,7 @@ module.exports = app => {
                 const revise = ctx.revise;
 
                 const [ledgerSpread, posSpread] = this._getSpreadSetting(revise);
-                const sjsRela = await this.ctx.service.project.getSjsRela(ctx.session.sessionProject.id);
+                const sjsRela = await ctx.service.project.getTenderSjsRela(ctx.session.sessionProject.id);
                 this.ctx.helper.refreshSpreadShow(sjsRela.ledgerCol, [ledgerSpread, posSpread]);
                 ledgerSpread.readOnly = true;
                 posSpread.readOnly = true;

+ 9 - 7
app/controller/stage_controller.js

@@ -183,7 +183,7 @@ module.exports = app => {
                 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.getSjsRela(ctx.session.sessionProject.id);
+                const sjsRela = await this.ctx.service.project.getTenderSjsRela(ctx.session.sessionProject.id);
                 this.ctx.helper.refreshSpreadShow(sjsRela.ledgerCol, [renderData.ledgerSpread, renderData.posSpread]);
                 renderData.changeConst = changeConst;
                 renderData.jsFiles = this.app.jsFiles.common.concat(this.app.jsFiles.stage.index);
@@ -256,10 +256,12 @@ module.exports = app => {
             if (this.ctx.session.sessionProject.dagl) this.posExtraColumn.push('dagl_status', 'dagl_url', 'dagl_limit');
 
             if (!sjsRela) return;
-            for (const field of sjsRela.ledgerCol) {
-                if (field.show) {
-                    this.ledgerColumn.push(field.field);
-                    this.posColumn.push(field.field);
+            if (sjsRela) {
+                for (const field of sjsRela.ledgerCol) {
+                    if (field.show) {
+                        this.ledgerColumn.push(field.field);
+                        this.posColumn.push(field.field);
+                    }
                 }
             }
         }
@@ -340,7 +342,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.getSjsRela(ctx.session.sessionProject.id);
+                const sjsRela = await this.ctx.service.project.getTenderSjsRela(ctx.session.sessionProject.id);
                 this._getLedgerColumn(sjsRela);
                 for (const f of filter) {
                     switch (f) {
@@ -1463,7 +1465,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.getSjsRela(ctx.session.sessionProject.id);
+                const sjsRela = await this.ctx.service.project.getTenderSjsRela(ctx.session.sessionProject.id);
                 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 - 2
app/lib/spread_setting.js

@@ -66,7 +66,7 @@ const getLedgerSpreadSetting = async function(ctx, tid, readOnly) {
     if (tender.data.measure_type === measureType.tz.value) removeFieldCols(ledger, spreadConst.filterCols.tzWithoutCols);
     if (!tender.info.display.ledger.dgnQty) removeFieldCols(ledger, spreadConst.filterCols.dgnCols);
 
-    const sjsRela = await ctx.service.project.getSjsRela(ctx.session.sessionProject.id);
+    const sjsRela = await ctx.service.project.getTenderSjsRela(ctx.session.sessionProject.id);
     refreshSpreadShow(sjsRela.ledgerCol, [ledger, pos]);
 
     return [ledger, pos];
@@ -101,7 +101,7 @@ const getStageSpreadSetting = async function (ctx, tid, readOnly, funInfo) {
     ledger.readOnly = readOnly;
     pos.readOnly = readOnly;
 
-    const sjsRela = await ctx.service.project.getSjsRela(ctx.session.sessionProject.id);
+    const sjsRela = await ctx.service.project.getTenderSjsRela(ctx.session.sessionProject.id);
     refreshSpreadShow(sjsRela.ledgerCol, [ledger, pos]);
 
     return [ledger, pos];

+ 54 - 0
app/public/js/shares/show_level.js

@@ -0,0 +1,54 @@
+'use strict';
+
+/**
+ *
+ *
+ * @author Mai
+ * @date
+ * @version
+ */
+$.cs_showLevel = function (setting) {
+    const sortTitle = ['第一层', '第二层', '第三层','第四层', '第五层'];
+    if (!setting.selector) throw '未指定模块';
+    if (!setting.levels) {
+        setting.levels = [
+            { type: 'sort', count: 5, },
+            { type: 'last', title: '最底层' },
+            // { type: 'leafXmj', title: '只显示项目节' },
+            // { type: 'curMeasure', title: '只显示本期计量' },
+        ];
+    }
+
+    const initShowLevel = function () {
+        const obj = $(setting.selector);
+        const html = [];
+        html.push('<button class="btn btn-sm btn-light dropdown-toggle text-primary" type="button" id="dropdownMenuButton" data-toggle="dropdown" aria-haspopup="true" aria-expanded="false">' +
+            '<i class="fa fa-list-ol"></i> 显示层级</button>');
+        html.push('<div class="dropdown-menu" aria-labelledby="dropdownMenuButton" id="showLevelList">');
+        for (const l of setting.levels) {
+            if (l.type === 'sort') {
+                let count = typeof l.count === 'function' ? l.count() : l.count;
+                count = Math.min(count, 5);
+                for (let i = 1; i <= count; ++i) {
+                    html.push(`<a class="dropdown-item" name="showLevel" tag="${i}" href="javascript: void(0);">${sortTitle[i-1]}</a>`);
+                }
+            } else {
+                html.push(`<a class="dropdown-item" name="showLevel" tag="${l.type}" href="javascript: void(0);">${l.title}</a>`);
+            }
+        }
+        html.push('</div>');
+        obj.html(html.join(''));
+
+
+        $('a[name=showLevel]').click(function () {
+            setTimeout(() => {
+                const tag = $(this).attr('tag');
+                showWaitingView();
+                setting.showLevel(tag);
+                closeWaitingView();
+            });
+        });
+    };
+
+    return { initShowLevel } ;
+};

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

@@ -369,6 +369,7 @@ $(document).ready(() => {
     // initTenderTree();
     // $('.c-body').html(getTenderTreeHtml());
     bindTenderUrl();
+    tenderTreeShowLevel.initShowLevel();
     // localHideList();
 
     // 分类

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

@@ -448,6 +448,7 @@ $(document).ready(() => {
     $('.c-body').html(getTenderTreeHtml());
     bindTenderUrl();
     localHideList();
+    tenderTreeShowLevel.initShowLevel();
     // 分类
     $('#cate-set').on('show.bs.modal', function () {
         createTree();

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

@@ -384,6 +384,7 @@ $(document).ready(() => {
     $('.c-body').html(getTenderTreeHtml());
     bindTenderUrl();
     localHideList();
+    tenderTreeShowLevel.initShowLevel();
     // 分类
     $('#cate-set').on('show.bs.modal', function () {
         createTree();

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

@@ -420,6 +420,7 @@ $(document).ready(() => {
     $('.c-body').html(getTenderTreeHtml());
     bindTenderUrl();
     localHideList();
+    tenderTreeShowLevel.initShowLevel();
     // 分类
     $('#cate-set').on('show.bs.modal', function () {
         createTree();

+ 75 - 2
app/public/js/tender_showhide.js

@@ -18,7 +18,7 @@ const findTenderTreeNode = function(sortId, tree) {
             findTenderTreeNode(sortId, item.children);
         }
     });
-}
+};
 
 function removeValueToCate(cate) {
     const changeCate = JSON.parse(JSON.stringify(cate));
@@ -29,6 +29,40 @@ function removeValueToCate(cate) {
     }
     return newCate;
 }
+
+function recursiveExpand(nodes, parent, checkFun) {
+    for (const node of nodes) {
+        const expanded = checkFun(node);
+        if (!expanded && node.sort_id) hideList.push({sort_id: node.sort_id});
+        if (node.expanded !== expanded) {
+            node.expanded = expanded;
+            if (node.sort_id) {
+                if (node.expanded) {
+                    $('.c-body tr td span[cid="' + node.sort_id + '"]').children('i').removeClass('fa-plus-square-o').addClass('fa-minus-square-o');
+                    $('.c-body tr td span[cid="' + node.sort_id + '"]').attr('title', '收起');
+                } else {
+                    $('.c-body tr td span[cid="' + node.sort_id + '"]').children('i').removeClass('fa-minus-square-o').addClass('fa-plus-square-o');
+                    $('.c-body tr td span[cid="' + node.sort_id + '"]').attr('title', '展开');
+                }
+                doTrStatus(node, node.expanded ? 'show' : 'hide');
+            }
+        }
+        node.visible = parent ? (parent.expanded && parent.visible) : true;
+        if (node.children) recursiveExpand(node.children, node, checkFun);
+    }
+}
+function expandByCustom(checkFun) {
+    hideList = [];
+    recursiveExpand(tenderTree, null, checkFun);
+}
+
+function expandByLevel(level) {
+    expandByCustom(function (n) {
+        return n.level < level;
+    });
+    setLocalCache(uphlname, JSON.stringify(hideList));
+}
+
 // 根据标段类别设置排序
 function sortTenderTree(teTree = tenderTree) {
     for (const tender of teTree) {
@@ -120,6 +154,8 @@ function doTrStatus(node, status, all = '') {
     }
 }
 
+let tenderTreeShowLevel;
+
 $(document).ready(() => {
     // 展开和收起
     $('body').on('click', '.fold-switch', function () {
@@ -169,7 +205,44 @@ $(document).ready(() => {
             }
         }
         setTopTr();
-    })
+    });
+
+    tenderTreeShowLevel = $.cs_showLevel({
+        selector: '#show-level',
+        levels: [
+            {
+                type: 'sort', count: function () {
+                    const getChildrenLevel = function (node) {
+                        let iLevel = node.level;
+                        if (node.children && node.children.length > 0) {
+                            for (const c of node.children) {
+                                iLevel = Math.max(iLevel, getChildrenLevel(c));
+                            }
+                        }
+                        return iLevel;
+                    };
+                    return tenderTree.map(getChildrenLevel).reduce((x, y) => { return Math.max(x, y); }, 0) - 1;
+                }
+            },
+            { type: 'last', title: '最底层' },
+        ],
+        showLevel: function (tag) {
+
+            switch (tag) {
+                case "1":
+                case "2":
+                case "3":
+                case "4":
+                case "5":
+                    expandByLevel(parseInt(tag));
+                    break;
+                case "last":
+                    expandByLevel(20);
+                    break;
+                default: return;
+            }
+        }
+    });
 });
 
 

+ 8 - 0
app/service/project.js

@@ -177,6 +177,14 @@ module.exports = app => {
             return result;
         }
 
+        async getTenderSjsRela(id, show) {
+            const projectData = await this.db.get(this.tableName, { id });
+            const result = projectData.sjs_rela ? JSON.parse(projectData.sjs_rela) : {};
+            this.ctx.helper._.defaults(result, sjsRelaConst);
+            if (!show) result.ledgerCol.forEach(x => { x.show = 0 });
+            return result;
+        }
+
         async updateSjsRela(id, sub, field, key, value) {
             const sjsRela = await this.getSjsRela(id);
             if (!sjsRela[sub]) throw '数据异常';

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

@@ -699,6 +699,10 @@
                         <label class="custom-control-label" for="ledger-cl-qty">错漏增减</label>
                     </div>
                     <div class="custom-control custom-checkbox mb-2">
+                        <input type="checkbox" class="custom-control-input" id="ex-memo" checked="">
+                        <label class="custom-control-label" for="ex-memo">台账新增列</label>
+                    </div>
+                    <div class="custom-control custom-checkbox mb-2">
                         <input type="checkbox" class="custom-control-input" id="thousandth" checked="">
                         <label class="custom-control-label" for="thousandth">千分位</label>
                     </div>
@@ -1484,6 +1488,7 @@
     function loadDisplayProperty () {
         $('#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;
         $('#thousandth')[0].checked = property.display.thousandth;
         $('#stage-rc')[0].checked = property.display.stage.realComplete;
         $('#stage-correct')[0].checked = property.display.stage.correct;
@@ -1496,6 +1501,7 @@
         const prop = {
             display: {
                 ledger: { 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 },
                 dayMode: $('#dayMode')[0].checked,

+ 1 - 0
app/view/tender/sub_menu.ejs

@@ -9,6 +9,7 @@
                     <a class="dropdown-item tree-toggle" href="javascript:void(0);" data-item="hide">收起所有</a>
                 </div>
             </div>
+            <div class="d-inline-block" id="show-level"></div>
             <div class="d-inline-block">
                 <div class="btn-group btn-group-toggle group-tab" data-toggle="buttons">
                     <label class="btn btn-sm btn-light <% if (ctx.url === '/list') { %>active<% } %>" onclick="window.location.href='/list'">

+ 4 - 0
config/web.js

@@ -61,6 +61,7 @@ const JsFiles = {
                     '/public/js/PinYinOrder.bundle.js',
                     '/public/js/shares/tender_list_order.js',
                     '/public/js/tender_showhide.js',
+                    '/public/js/shares/show_level.js',
                     '/public/js/tender_list.js',
                 ],
                 mergeFile: 'tender_list',
@@ -72,6 +73,7 @@ const JsFiles = {
                     '/public/js/PinYinOrder.bundle.js',
                     '/public/js/shares/tender_list_order.js',
                     '/public/js/tender_showhide.js',
+                    '/public/js/shares/show_level.js',
                     '/public/js/tender_list_info.js',
                 ],
                 mergeFile: 'tender_list_info',
@@ -83,6 +85,7 @@ const JsFiles = {
                     '/public/js/PinYinOrder.bundle.js',
                     '/public/js/shares/tender_list_order.js',
                     '/public/js/tender_showhide.js',
+                    '/public/js/shares/show_level.js',
                     '/public/js/tender_list_progress.js',
                 ],
                 mergeFile: 'tender_list_progress',
@@ -94,6 +97,7 @@ const JsFiles = {
                     '/public/js/PinYinOrder.bundle.js',
                     '/public/js/shares/tender_list_order.js',
                     '/public/js/tender_showhide.js',
+                    '/public/js/shares/show_level.js',
                     '/public/js/tender_list_manage.js',
                 ],
                 mergeFile: 'tender_list_manage',