ソースを参照

台账分解、台账审批、多期比较、计量台账,记住台账展开收起状态,并保持同步。

MaiXinRong 4 年 前
コミット
6d87761a4b

+ 82 - 38
app/public/js/ledger.js

@@ -48,6 +48,9 @@ $(document).ready(function() {
         rootId: -1,
         keys: ['id', 'tender_id', 'ledger_id'],
         preUrl: '/tender/' + getTenderId() + '/ledger',
+        //treeCacheKey: 'ledger_bills_fold' + '_' + getTenderId(),
+        markFoldKey: 'bills-fold',
+        markFoldSubKey: window.location.pathname.split('/')[2],
     };
     if (checkTzMeasureType()) {
         treeSetting.calcFields = ['sgfh_tp', 'sjcl_tp', 'qtcl_tp', 'total_price'];
@@ -2190,14 +2193,14 @@ $(document).ready(function() {
                 if (!dealBills) {
                     dealBills = new DealBills('#deal-bills-spread', {
                         cols: [
-                            {title: '清单编号', field: 'code', hAlign: 0, width: 85, formatter: '@', readOnly: true},
-                            {title: '名称', field: 'name', hAlign: 0, width: 150, formatter: '@', readOnly: true},
-                            {title: '单位', field: 'unit', hAlign: 1, width: 50, formatter: '@', readOnly: true},
-                            {title: '单价', field: 'unit_price', hAlign: 2, width: 50, readOnly: true},
-                            {title: '数量', field: 'quantity', hAlign: 2, width: 50, readOnly: true},
-                            {title: '金额', field: 'total_price', hAlign: 2, width: 50, readOnly: true},
+                            {title: '清单编号', field: 'code', hAlign: 0, width: 85, formatter: '@'},
+                            {title: '名称', field: 'name', hAlign: 0, width: 150, formatter: '@'},
+                            {title: '单位', field: 'unit', hAlign: 1, width: 50, formatter: '@'},
+                            {title: '单价', field: 'unit_price', hAlign: 2, width: 50},
+                            {title: '数量', field: 'quantity', hAlign: 2, width: 50},
+                            {title: '金额', field: 'total_price', hAlign: 2, width: 50},
                         ],
-                        emptyRows: 0,
+                        emptyRows: 3,
                         headRows: 1,
                         headRowHeight: [32],
                         defaultRowHeight: 21,
@@ -2205,6 +2208,7 @@ $(document).ready(function() {
                         font: '12px 微软雅黑',
                         headColWidth: [0],
                         selectedBackColor: '#fffacd',
+                        readOnly: true,
                     });
                     dealBills.loadData();
                 }
@@ -2260,44 +2264,47 @@ $(document).ready(function() {
             this.url = '/tender/' + getTenderId() + '/deal';
             this.spreadSetting = spreadSetting;
             this.spread = SpreadJsObj.createNewSpread(this.obj);
+            this.sheet = this.spread.getActiveSheet();
             SpreadJsObj.initSheet(this.spread.getActiveSheet(), this.spreadSetting);
             if (!readOnly) {
                 this.spread.bind(spreadNS.Events.CellDoubleClick, function (e, info) {
-                const dealSheet = info.sheet;
-                const mainSheet = ledgerSpread.getActiveSheet();
+                    const dealSheet = info.sheet;
+                    if (!dealSheet.zh_setting.readOnly) return;
 
-                const dealBills = SpreadJsObj.getSelectObject(dealSheet);
-                if (!dealBills) { return; }
-                const mainTree = mainSheet.zh_tree;
-                const mainNode = SpreadJsObj.getSelectObject(mainSheet);
-                if (!mainNode || !mainTree) { return; }
+                    const mainSheet = ledgerSpread.getActiveSheet();
 
-                if (mainNode.code && mainNode.code !== '' && !mainTree.isLeafXmj(mainNode)) {
-                    toastr.error('非最底层项目下,不应添加清单');
-                    return;
-                }
+                    const dealBills = SpreadJsObj.getSelectObject(dealSheet);
+                    if (!dealBills) { return; }
+                    const mainTree = mainSheet.zh_tree;
+                    const mainNode = SpreadJsObj.getSelectObject(mainSheet);
+                    if (!mainNode || !mainTree) { return; }
 
-                postData(window.location.pathname + '/update', {
-                    postType: 'add-deal',
-                    postData: {
-                        id: mainNode.ledger_id,
-                        type: mainNode.code ? 'child' : 'next',
-                        dealBills: {
-                            b_code: dealBills.code, name: dealBills.name, unit: dealBills.unit,
-                            unit_price: dealBills.unit_price,
-                        }
-                    },
-                }, function (result) {
-                    const refreshData = mainTree.loadPostData(result);
-                    treeOperationObj.refreshTree(mainSheet, refreshData);
-                    const sel = mainSheet.getSelections()[0];
-                    mainSheet.setSelection(refreshData.create[0].index, sel.col, sel.rowCount, sel.colCount);
-                    SpreadJsObj.reloadRowsBackColor(mainSheet, [sel.row, refreshData.create[0].index]);
-                    treeOperationObj.refreshOperationValid(mainSheet);
-                    ledgerSpread.focus();
-                    posOperationObj.loadCurPosData();
+                    if (mainNode.code && mainNode.code !== '' && !mainTree.isLeafXmj(mainNode)) {
+                        toastr.error('非最底层项目下,不应添加清单');
+                        return;
+                    }
+
+                    postData(window.location.pathname + '/update', {
+                        postType: 'add-deal',
+                        postData: {
+                            id: mainNode.ledger_id,
+                            type: mainNode.code ? 'child' : 'next',
+                            dealBills: {
+                                b_code: dealBills.code, name: dealBills.name, unit: dealBills.unit,
+                                unit_price: dealBills.unit_price,
+                            }
+                        },
+                    }, function (result) {
+                        const refreshData = mainTree.loadPostData(result);
+                        treeOperationObj.refreshTree(mainSheet, refreshData);
+                        const sel = mainSheet.getSelections()[0];
+                        mainSheet.setSelection(refreshData.create[0].index, sel.col, sel.rowCount, sel.colCount);
+                        SpreadJsObj.reloadRowsBackColor(mainSheet, [sel.row, refreshData.create[0].index]);
+                        treeOperationObj.refreshOperationValid(mainSheet);
+                        ledgerSpread.focus();
+                        posOperationObj.loadCurPosData();
+                    });
                 });
-            });
             }
             $('#upload-deal-bills').click(function () {
                     const file = $('#deal-bills-file')[0];
@@ -2319,6 +2326,43 @@ $(document).ready(function() {
                         return target.hitTestType === spreadNS.SheetArea.viewport || target.hitTestType === spreadNS.SheetArea.rowHeader;
                     },
                     items: {
+                        edit: {
+                            name: '进入编辑模式',
+                            icon: 'fa-edit',
+                            visible: function (key, opt) {
+                                return self.sheet.zh_setting.readOnly;
+                            },
+                            callback: function (key, opt) {
+                                self.sheet.zh_setting.readOnly = false;
+                                SpreadJsObj.refreshSheetReadOnly(self.sheet);
+                            },
+                        },
+                        read: {
+                            name: '退出编辑模式',
+                            icon: 'fa-sign-out',
+                            visible: function (key, opt) {
+                                return !self.sheet.zh_setting.readOnly;
+                            },
+                            callback: function (key, opt) {
+                                self.sheet.zh_setting.readOnly = true;
+                                SpreadJsObj.refreshSheetReadOnly(self.sheet);
+                            },
+                        },
+                        del: {
+                            name: '删除',
+                            icon: 'fa-times',
+                            visible: function (key, opt) {
+                                return !self.sheet.zh_setting.readOnly;
+                            },
+                            disabled: function (key, opt) {
+                                const select = SpreadJsObj.getSelectObject(self.sheet);
+                                return !select;
+                            },
+                            callback: function (key, opt) {
+
+                            },
+                        },
+                        sprEdit: '---------',
                         apply: {
                             name: '应用全部清单单价至台账',
                             icon: 'fa-magic',

+ 2 - 0
app/public/js/ledger_audit.js

@@ -28,6 +28,8 @@ $(document).ready(() => {
         rootId: -1,
         keys: ['id', 'tender_id', 'ledger_id'],
         preUrl: '/ledger',
+        markFoldKey: 'bills-fold',
+        markFoldSubKey: window.location.pathname.split('/')[2],
     };
     if (checkTzMeasureType()) {
         treeSetting.calcFields = ['sgfh_tp', 'sjcl_tp', 'qtcl_tp', 'total_price'];

ファイルの差分が大きいため隠しています
+ 7 - 0
app/public/js/local-forage/localforage.min.js


+ 2 - 0
app/public/js/measure_compare.js

@@ -144,6 +144,8 @@ $(document).ready(() => {
         masterId: 'id',
         minorId: 'lid',
         calcFields: [],
+        markFoldKey: 'bills-fold',
+        markFoldSubKey: window.location.pathname.split('/')[2],
     });
     const cPos = new MasterPosData({
         id: 'id', ledgerId: 'lid', masterId: 'id', minorId: 'pid',

+ 73 - 23
app/public/js/path_tree.js

@@ -263,6 +263,7 @@ const createNewPathTree = function (type, setting) {
          * 构造函数
          */
         constructor(setting) {
+            const self = this;
             // 无索引
             this.datas = [];
             // 以key为索引
@@ -273,6 +274,23 @@ const createNewPathTree = function (type, setting) {
             this.children = [];
             // 树设置
             this.setting = setting;
+
+            if (this.setting.markFoldKey) {
+                const markStr = getLocalCache(this.setting.markFoldKey);
+                const markData = markStr ? markStr.split('|') : ['', ''];
+                try {
+                    this.markFold = markData[0] === this.setting.markFoldSubKey
+                        ? (markData[1] ? markData[1].split(',').map(x => { return parseInt(x) }) : [])
+                        : [];
+                } catch {
+                    this.markFold = [];
+                }
+            }
+            // if (this.setting.treeCacheKey) {
+            //     localforage.getItem(this.setting.treeCacheKey).then(function (v) {
+            //         self.markFold = v && v.markFold ? v.markFold : [];
+            //     });
+            // }
         }
         /**
          * 树结构根据显示排序
@@ -309,6 +327,7 @@ const createNewPathTree = function (type, setting) {
          * @param datas
          */
         loadDatas(datas) {
+            self = this;
             // 清空旧数据
             this.items = {};
             this.nodes = [];
@@ -342,6 +361,9 @@ const createNewPathTree = function (type, setting) {
             });
             this.sortTreeNode(true);
             if (this.setting.autoExpand >= 0) this.expandByLevel(this.setting.autoExpand);
+            if (this.setting.markFoldKey) this.expandByCustom(function (node) {
+                return self.markFold.indexOf(node[self.setting.id]) === -1;
+            });
         }
 
         getItemsByIndex(index) {
@@ -487,6 +509,49 @@ const createNewPathTree = function (type, setting) {
             const siblings = this.getChildren(this.getParent(node));
             return (siblings && siblings.length > 0) ? node.order === siblings[siblings.length - 1].order : false;
         };
+
+        /**
+         * 提取节点key和索引数据
+         * @param {Object} node - 节点
+         * @returns {key}
+         */
+        getNodeKeyData(node) {
+            const data = {};
+            for (const key of this.setting.keys) {
+                data[key] = node[key];
+            }
+            return data;
+        };
+        /**
+         * 得到树结构构成id
+         * @param node
+         * @returns {*}
+         */
+        getNodeKey(node) {
+            return node[this.setting.id];
+        };
+
+        _markFold(node) {
+            if (!this.setting.markFoldKey || !this.setting.markFoldSubKey) return;
+            // if (!this.setting.treeCacheKey) return;
+
+            if (!node.expanded) {
+                if (this.markFold.indexOf(node[this.setting.id]) === -1) this.markFold.push(node[this.setting.id]);
+            } else {
+                if (this.markFold.indexOf(node[this.setting.id]) >= 0) this.markFold.splice(this.markFold.indexOf(node[this.setting.id]), 1);
+            }
+        }
+        _saveMarkFold() {
+            if (this.setting.markFoldKey && this.setting.markFoldSubKey) {
+                setLocalCache(this.setting.markFoldKey, this.setting.markFoldSubKey + '|' + this.markFold.join(','));
+            }
+            // if (this.setting.treeCacheKey) {
+            //     localforage.setItem(this.setting.treeCacheKey, {
+            //         markFold: this.markFold,
+            //         time: new Date(),
+            //     });
+            // }
+        }
         /**
          * 刷新子节点是否可见
          * @param {Object} node
@@ -510,30 +575,10 @@ const createNewPathTree = function (type, setting) {
          */
         setExpanded(node, expanded) {
             node.expanded = expanded;
+            this._markFold(node);
             this._refreshChildrenVisible(node);
+            this._saveMarkFold();
         };
-
-        /**
-         * 提取节点key和索引数据
-         * @param {Object} node - 节点
-         * @returns {key}
-         */
-        getNodeKeyData(node) {
-            const data = {};
-            for (const key of this.setting.keys) {
-                data[key] = node[key];
-            }
-            return data;
-        };
-        /**
-         * 得到树结构构成id
-         * @param node
-         * @returns {*}
-         */
-        getNodeKey(node) {
-            return node[this.setting.id];
-        };
-
         /**
          * 递归 设置节点展开状态
          * @param {Array} nodes - 需要设置状态的节点
@@ -543,7 +588,11 @@ const createNewPathTree = function (type, setting) {
          */
         _recursiveExpand(nodes, parent, checkFun) {
             for (const node of nodes) {
-                node.expanded = checkFun(node);
+                const expanded = checkFun(node);
+                if (node.expanded !== expanded) {
+                    node.expanded = expanded;
+                    this._markFold(node);
+                }
                 node.visible = parent ? (parent.expanded && parent.visible) : true;
                 this._recursiveExpand(node.children, node, checkFun);
             }
@@ -554,6 +603,7 @@ const createNewPathTree = function (type, setting) {
          */
         expandByCustom(checkFun) {
             this._recursiveExpand(this.children, null, checkFun);
+            this._saveMarkFold();
         }
         /**
          * 展开到第几层

+ 2 - 0
app/public/js/stage.js

@@ -163,6 +163,8 @@ $(document).ready(() => {
         rootId: -1,
         keys: ['id', 'tender_id', 'ledger_id'],
         stageId: 'id',
+        markFoldKey: 'bills-fold',
+        markFoldSubKey: window.location.pathname.split('/')[2],
     };
     // 台账树结构计算相关设置
     stageTreeSetting.updateFields = ['contract_qty', 'contract_tp', 'qc_qty', 'qc_tp', 'postil', 'used', 'contract_expr'];