浏览代码

金额汇总调整

MaiXinRong 3 月之前
父节点
当前提交
f57e276772

+ 1 - 1
app/controller/spss_controller.js

@@ -34,7 +34,7 @@ module.exports = app => {
                     categoryData,
                     jsFiles: this.app.jsFiles.common.concat(this.app.jsFiles.spss.gatherInfo)
                 };
-                await this.layout('spss/gather_info.ejs', renderData, 'spss/spss_select_modal.ejs');
+                await this.layout('spss/gather_info.ejs', renderData, 'spss/gather_info_modal.ejs');
             } catch (err) {
                 ctx.helper.log(err);
             }

+ 11 - 2
app/public/js/shares/tenders2tree.js

@@ -73,12 +73,21 @@ const Tender2Tree = (function () {
         return tenderCategory;
     }
 
-    function convert (category, tenders, ledgerAuditConst, stageAuditConst, loadFun) {
+    function convert (category, tenders, ledgerAuditConst, stageAuditConst, loadFun, selfLevel = '', force = false) {
         tenderTree = createNewPathTree('gather', treeSetting);
         tenderTree.clearDatas();
 
+        let selfLevelSort = selfLevel ? selfLevel.split(',') : [];
+        selfLevelSort = selfLevelSort.filter(x => {
+            return category.find(c => { return c.id + '' === x; });
+        });
+        category.forEach(cate => {
+            cate.is_self = force || selfLevelSort.length > 0;
+            cate.self_level = selfLevelSort.indexOf(cate.id + '') + 1;
+            cate.show_level = cate.is_self ? cate.self_level : cate.level;
+        });
         const levelCategory = category.filter(function (c) {
-            return c.level && c.level > 0;
+            return  c.show_level && c.show_level > 0; // c.level && c.level > 0;
         });
 
         for (const t of tenders) {

+ 218 - 19
app/public/js/spss_gather_stage_info.js

@@ -33,6 +33,39 @@ $(document).ready(() => {
     SpreadJsObj.initSheet(infoSheet, infoSpreadSetting);
     let infoTree;
 
+    const infoObj = {
+        tenders: [],
+        rebuildInfoTree: function(categoryLevel) {
+            infoTree = Tender2Tree.convert(category, this.tenders, null, null, function(node, tender) {
+                node.measure_type_str = tender.info.measure_type_str;
+                node.progress = tender.info.progress;
+                node.progress_str = `${node.progress.title}(${node.progress.status})`;
+                node.stage_filter = tender.stage_filter;
+                node.contract_price = tender.info.contract_price;
+                node.total_price = tender.total_price;
+                node.contract_tp = tender.info.contract_tp;
+                node.qc_tp = tender.info.qc_tp;
+                node.gather_tp = tender.info.gather_tp;
+                node.end_contract_tp = tender.info.end_contract_tp;
+                node.end_qc_tp = tender.info.end_qc_tp;
+                node.end_gather_tp = tender.info.end_gather_tp;
+                node.yf_tp = tender.info.yf_tp;
+                node.end_yf_tp = tender.info.end_yf_tp;
+                node.sf_tp = tender.info.sf_tp;
+                node.end_sf_tp = tender.info.end_sf_tp;
+            }, categoryLevel, true);
+        },
+        refreshInfoTree: function(categoryLevel) {
+            this.rebuildInfoTree(categoryLevel);
+            SpreadJsObj.loadSheetData(infoSheet, SpreadJsObj.DataType.Tree, infoTree, true);
+        },
+        loadTenders: function(tenders) {
+            this.tenders = tenders;
+            const categoryLevel = infoCate.getCategoryLevel();
+            this.refreshInfoTree(categoryLevel);
+        }
+    };
+
     const tenderSelect = TenderSelectMulti({
         title: '汇总标段',
         type: 'gather',
@@ -40,25 +73,7 @@ $(document).ready(() => {
         afterSelect: function(select) {
             const data = { filter: 'info', tender: select };
             postData(`/sp/${spid}/spss/load`, data, function(result) {
-                infoTree = Tender2Tree.convert(category, result, null, null, function(node, tender) {
-                    node.measure_type_str = tender.info.measure_type_str;
-                    node.progress = tender.info.progress;
-                    node.progress_str = `${node.progress.title}(${node.progress.status})`;
-                    node.stage_filter = tender.stage_filter;
-                    node.contract_price = tender.info.contract_price;
-                    node.total_price = tender.total_price;
-                    node.contract_tp = tender.info.contract_tp;
-                    node.qc_tp = tender.info.qc_tp;
-                    node.gather_tp = tender.info.gather_tp;
-                    node.end_contract_tp = tender.info.end_contract_tp;
-                    node.end_qc_tp = tender.info.end_qc_tp;
-                    node.end_gather_tp = tender.info.end_gather_tp;
-                    node.yf_tp = tender.info.yf_tp;
-                    node.end_yf_tp = tender.info.end_yf_tp;
-                    node.sf_tp = tender.info.sf_tp;
-                    node.end_sf_tp = tender.info.end_sf_tp;
-                });
-                SpreadJsObj.loadSheetData(infoSheet, SpreadJsObj.DataType.Tree, infoTree, true);
+                infoObj.loadTenders(result);
             });
         },
     });
@@ -109,4 +124,188 @@ $(document).ready(() => {
             infoSpread.refresh();
         }
     });
+
+    const infoCate = (function(setting) {
+        const levelTreeSetting = {
+            view: {
+                selectedMulti: false
+            },
+            data: {
+                simpleData: {
+                    idKey: 'lid',
+                    pIdKey: 'lpId',
+                    rootPId: 0,
+                    enable: true,
+                }
+            },
+            edit: {
+                enable: true,
+                showRemoveBtn: false,
+                showRenameBtn: false,
+                drag: {
+                    autoExpandTrigger: true,
+                    isCopy: false,
+                    isMove:  true,
+                    prev: false,
+                    next: false,
+                    inner: true,
+                }
+            },
+            callback: {
+                beforeDrop: function (treeId, treeNodes, targetNode, moveType, isCopy) {
+                    if (targetNode !== null && targetNode.lid !== 1) {
+                        const parent = targetNode.getParentNode();
+                        if (parent && parent.lid === 1) {
+                            return false;
+                        }
+                    }
+                    for (var i=0,l=treeNodes.length; i<l; i++) {
+                        if (treeNodes[i].drag === false) {
+                            return false;
+                        }
+                        if (!targetNode && treeNodes[i].dropRoot === false) {
+                            return false;
+                        }
+                        if(treeNodes[i].isParent === true && targetNode.lid !== 1){
+                            return false;
+                        }
+                    }
+                    return true;
+                },
+                onDrop: function onDropNode(event, treeId, treeNodes, targetNode, moveType) {
+                    const zTree = $.fn.zTree.getZTreeObj(treeId);
+                    function resetFixNode(id) {
+                        const node = zTree.getNodeByParam('lid', id);
+                        node.isParent = true;
+                        zTree.updateNode(node, false);
+                        zTree.expandNode(node, true);
+                    }
+                    function moveChildren(children, node) {
+                        if (!children || children.length === 0) { return }
+                        for (const c of children) {
+                            moveChildren(c.children, node);
+                            zTree.moveNode(node, c, 'inner');
+                        }
+                    }
+                    resetFixNode(1);
+                    resetFixNode(2);
+                    if (targetNode !== null && targetNode.lid === 1 && treeNodes[0].children && treeNodes[0].children.length !== 0) {
+                        moveChildren(treeNodes[0].children, zTree.getNodeByParam('lid', 1));
+                    } else if (targetNode !== null && targetNode.lid !== 1) {
+                        if (targetNode.children.length >= 2) {
+                            for (const c of targetNode.children) {
+                                if (c.lid !== treeNodes[0].lid) {
+                                    zTree.moveNode(treeNodes[0], c, 'inner');
+                                }
+                            }
+                        }
+                    }
+                },
+            }
+        };
+        const levelNodes =[];
+        const default_category_level = setting.defaultCategoryLevel;
+        let selfLevelSort;
+        function createTree(key) {
+            const zTree = $.fn.zTree.getZTreeObj(key);
+            if (zTree) zTree.destroy();
+            $.fn.zTree.init($(`#${key}`), levelTreeSetting, levelNodes);
+        }
+        function findNode (key, value, arr) {
+            for (const a of arr) {
+                if (a[key] && a[key] === value) {
+                    return a;
+                }
+            }
+        }
+        function getPId(level) {
+            if (level !== 1) {
+                const p = findNode('show_level', level - 1, levelNodes);
+                if (p) {
+                    return p.lid
+                } else {
+                    return 1;
+                }
+            } else {
+                return 2;
+            }
+        }
+        function loadSelfCategoryLevel(selfLevel, force = false){
+            selfLevelSort = selfLevel ? selfLevel.split(',') : [];
+            selfLevelSort = selfLevelSort.filter(x => {
+                return category.find(c => { return c.id + '' === x; });
+            });
+            category.forEach(cate => {
+                cate.is_self = force || selfLevelSort.length > 0;
+                cate.self_level = selfLevelSort.indexOf(cate.id + '') + 1;
+            });
+        }
+        function sortCategory() {
+            category.forEach(cate => {
+                cate.show_level = cate.is_self ? cate.self_level : cate.level;
+            });
+            category.sort(function (a, b) {
+                return a.show_level ? (b.show_level ? a.show_level - b.show_level : -1) : a.id - b.id;
+            });
+        }
+        function initCategoryLevelNode() {
+            levelNodes.length = 0;
+            levelNodes.push(
+                { lid:1, lpId:0, name:"可用类别", open:true, isParent: true, drag: false},
+                { lid:2, lpId:0, name:"已用类别", open:true, isParent: true, drag: false}
+            );
+            for (const c of category) {
+                const cate = JSON.parse(JSON.stringify(c));
+                cate.lid = levelNodes.length + 1;
+                cate.open = true;
+                cate.dropRoot = false;
+                if (!cate.show_level) {
+                    cate.lpId = 1;
+                    levelNodes.push(cate);
+                } else {
+                    cate.lpId = getPId(cate.show_level);
+                    levelNodes.push(cate);
+                }
+            }
+        }
+        const setSelfCategoryLevel = function(level, force) {
+            loadSelfCategoryLevel(level, force);
+            sortCategory();
+            initCategoryLevelNode();
+        };
+        setSelfCategoryLevel(default_category_level);
+        createTree('treeLevel-info');
+        const getCategoryLevel = function () {
+            const zTree = $.fn.zTree.getZTreeObj('treeLevel-info');
+            const selfLevel = [];
+            for (const c of category) {
+                const node = zTree.getNodeByParam('id', c.id);
+                const parent = node.getParentNode();
+                if (parent.lid != 1) {
+                    selfLevel.push({id: c.id, level: node.getPath().length - 1});
+                }
+            }
+            const selfLevelStr = selfLevel.sort((x, y) => { return x.level - y.level; }).map(x => {return x.id; }).join(',');
+            return selfLevelStr;
+        };
+        $('#info-cate-ok').click(function () {
+            const categoryLevel = getCategoryLevel();
+            setSelfCategoryLevel(categoryLevel, true);
+            setting.afterCate(categoryLevel);
+            $('#info-cate').modal('hide');
+        });
+        $('#info-cate').on('show.bs.modal', function () {
+            createTree('treeLevel-info');
+        });
+        $('#info-cate-reset').click(function () {
+            setSelfCategoryLevel(default_category_level);
+            createTree('treeLevel-info');
+        });
+        return { getCategoryLevel }
+    })({
+        afterCate: function(gatherCate) {
+            infoObj.refreshInfoTree(gatherCate);
+        },
+        defaultCategoryLevel: selfCategoryLevel,
+    });
 });

+ 4 - 0
app/view/spss/gather_info.ejs

@@ -6,6 +6,9 @@
             <div class="title-main  d-flex justify-content-between">
                 <div>
                     <div class="d-inline-block mr-2">
+                        <div class="btn-group">
+                            <button href="#info-cate" class="btn btn-sm btn-light text-primary" data-toggle="modal" data-target="#info-cate"><i class="fa fa-sitemap fa-rotate-270"></i> 类别设置</button>
+                        </div>
                         <!--展开/收起-->
                         <div class="btn-group">
                             <button type="button" class="btn btn-sm btn-light text-primary dropdown-toggle" data-toggle="dropdown" id="zhankai" aria-expanded="false">显示层级</button>
@@ -31,4 +34,5 @@
 </div>
 <script>
     const category = JSON.parse('<%- JSON.stringify(categoryData) %>');
+    const selfCategoryLevel = '<%- ctx.subProject.permission.self_category_level %>';
 </script>

+ 20 - 0
app/view/spss/gather_info_modal.ejs

@@ -0,0 +1,20 @@
+<% include ./spss_select_modal.ejs %>
+<div class="modal fade" id="info-cate" data-backdrop="static">
+    <div class="modal-dialog" role="document">
+        <div class="modal-content">
+            <div class="modal-header">
+                <h5 class="modal-title">分类设置</h5>
+            </div>
+            <div class="modal-body">
+                <div class="modal-height-300">
+                    <ul id="treeLevel-info" class="ztree"></ul>
+                </div>
+            </div>
+            <div class="modal-footer">
+                <button type="button" class="btn btn-primary btn-sm" id="info-cate-reset">重置</button>
+                <button type="button" class="btn btn-secondary btn-sm" data-dismiss="modal">关闭</button>
+                <button type="button" class="btn btn-primary btn-sm" id="info-cate-ok">确定</button>
+            </div>
+        </div>
+    </div>
+</div>

+ 7 - 12
config/web.js

@@ -1892,8 +1892,8 @@ const JsFiles = {
                     '/public/js/decimal.min.js',
                     '/public/js/math.min.js',
                     '/public/js/file-saver/FileSaver.js',
-                    '/public/js/datepicker/datepicker.min.js',
-                    '/public/js/datepicker/datepicker.zh.js',
+                    '/public/js/datepicker/datepicker.min.js', '/public/js/datepicker/datepicker.zh.js',
+                    '/public/js/ztree/jquery.ztree.core.js', '/public/js/ztree/jquery.ztree.exedit.js',
                 ],
                 mergeFiles: [
                     '/public/js/sub_menu.js',
@@ -1916,8 +1916,7 @@ const JsFiles = {
                     '/public/js/decimal.min.js',
                     '/public/js/math.min.js',
                     '/public/js/file-saver/FileSaver.js',
-                    '/public/js/datepicker/datepicker.min.js',
-                    '/public/js/datepicker/datepicker.zh.js',
+                    '/public/js/datepicker/datepicker.min.js', '/public/js/datepicker/datepicker.zh.js',
                 ],
                 mergeFiles: [
                     '/public/js/sub_menu.js',
@@ -1940,8 +1939,7 @@ const JsFiles = {
                     '/public/js/decimal.min.js',
                     '/public/js/math.min.js',
                     '/public/js/file-saver/FileSaver.js',
-                    '/public/js/datepicker/datepicker.min.js',
-                    '/public/js/datepicker/datepicker.zh.js',
+                    '/public/js/datepicker/datepicker.min.js', '/public/js/datepicker/datepicker.zh.js',
                 ],
                 mergeFiles: [
                     '/public/js/sub_menu.js',
@@ -1964,8 +1962,7 @@ const JsFiles = {
                     '/public/js/decimal.min.js',
                     '/public/js/math.min.js',
                     '/public/js/file-saver/FileSaver.js',
-                    '/public/js/datepicker/datepicker.min.js',
-                    '/public/js/datepicker/datepicker.zh.js',
+                    '/public/js/datepicker/datepicker.min.js', '/public/js/datepicker/datepicker.zh.js',
                 ],
                 mergeFiles: [
                     '/public/js/sub_menu.js',
@@ -1988,8 +1985,7 @@ const JsFiles = {
                     '/public/js/decimal.min.js',
                     '/public/js/math.min.js',
                     '/public/js/file-saver/FileSaver.js',
-                    '/public/js/datepicker/datepicker.min.js',
-                    '/public/js/datepicker/datepicker.zh.js',
+                    '/public/js/datepicker/datepicker.min.js', '/public/js/datepicker/datepicker.zh.js',
                 ],
                 mergeFiles: [
                     '/public/js/sub_menu.js',
@@ -2012,8 +2008,7 @@ const JsFiles = {
                     '/public/js/decimal.min.js',
                     '/public/js/math.min.js',
                     '/public/js/file-saver/FileSaver.js',
-                    '/public/js/datepicker/datepicker.min.js',
-                    '/public/js/datepicker/datepicker.zh.js',
+                    '/public/js/datepicker/datepicker.min.js', '/public/js/datepicker/datepicker.zh.js',
                 ],
                 mergeFiles: [
                     '/public/js/sub_menu.js',