Просмотр исходного кода

审批退回,勾选锁定相关

MaiXinRong 9 часов назад
Родитель
Сommit
2e81c78904
4 измененных файлов с 127 добавлено и 6 удалено
  1. 1 0
      app/middleware/stage_check.js
  2. 10 4
      app/public/js/path_tree.js
  3. 113 0
      app/public/js/stage.js
  4. 3 2
      app/service/stage_audit.js

+ 1 - 0
app/middleware/stage_check.js

@@ -74,6 +74,7 @@ module.exports = options => {
             // todo 校验权限 (标段参与人、分享、游客)
             const accountId = this.session.sessionUser.accountId;
             const shareIds = [];
+            console.log(stage.curAuditors);
             if (stage.status === status.uncheck) {
                 stage.readOnly = accountId !== stage.user_id && stage.userAssistIds.indexOf(accountId) < 0;
                 if (!stage.readOnly) {

+ 10 - 4
app/public/js/path_tree.js

@@ -423,20 +423,29 @@ const createNewPathTree = function (type, setting) {
             }
         }
 
+        refreshNodeVisible() {
+            for (const node of this.nodes) {
+                const parent = this.getParent(node);
+                node.visible = parent ? (parent.expanded && parent.visible && !node.filter) : !node.filter;
+            }
+        }
         loadFilter(select, filterType = 'access') {
             const defaultValue = filterType === 'access' ? true : false;
             this.select = select ? select.split(',') : [];
             for (const d of this.datas) {
                 d.filter = defaultValue;
+                d._fixed = defaultValue;
             }
             const parents = [];
             for (const s of this.select) {
                 const node = this.getItems(s);
                 if (!node) continue;
                 node.filter = !defaultValue;
+                node._fixed = !defaultValue;
                 const posterity = this.getPosterity(node);
                 for (const p of posterity) {
                     p.filter = !defaultValue;
+                    p._fixed = !defaultValue;
                 }
                 parents.push(...this.getAllParents(node));
             }
@@ -446,10 +455,7 @@ const createNewPathTree = function (type, setting) {
                 parent.filter = !parent.children.find(x => { return !x.filter });
 
             }
-            for (const node of this.nodes) {
-                const parent = this.getParent(node);
-                node.visible = parent ? (parent.expanded && parent.visible && !node.filter) : !node.filter;
-            }
+            this.refreshNodeVisible();
         }
         loadAssValid(select) {
             const keyField = this.setting.id;

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

@@ -5166,6 +5166,7 @@ $(document).ready(() => {
             opinion: $(`${'#sp-back'}`).find('[name=opinion]').val().replace(/\r\n/g, '<br/>').replace(/\n/g, '<br/>').replace(/\s/g, ' '),
             coop_checked: confirm && confirm.length > 0 ? confirm.map(x => { return x.id; }) : [],
             checkType,
+            audit_locked_lid: $('[name=audit_locked_lid]').val(),
         };
         if ($('#warning-text').length) $('#warning-text').remove();
         if (!checkType && !$('#warning-text').length) {
@@ -5473,6 +5474,118 @@ $(document).ready(() => {
             stageAssistRela.refreshAssistTable();
         });
     });
+
+    // 审批退回锁定
+    const spBackLock = (function(){
+        let lockSpread, lockSheet, lockTree;
+        const getLockedLid = function() {
+            if (!lockTree) return '';
+            const lockedLid = lockTree.nodes.filter(x => { return x.locked; }).map(y => { return y.ledger_id; });
+            if (lockedLid.length > 200) throw '锁定的节点过多,请尽量在父项锁定数据';
+            return lockedLid.join(',');
+        };
+        const init = function(setting) {
+            if (lockSpread) return;
+            lockSpread = SpreadJsObj.createNewSpread($('#sp-lock-spread')[0]);
+            lockSheet = lockSpread.getActiveSheet();
+            const spreadSetting = {
+                cols: [
+                    {title: '锁定', colSpan: '1', rowSpan: '1', field: 'locked', hAlign: 1, width: 60, cellType: 'checkbox'},
+                    {title: '项目节编号', colSpan: '1', rowSpan: '1', field: 'code', hAlign: 0, width: 145, formatter: '@', cellType: 'tree'},
+                    {title: '清单编号', colSpan: '1', rowSpan: '1', field: 'b_code', hAlign: 0, width: 70, formatter: '@'},
+                    {title: '名称', colSpan: '1', rowSpan: '1', field: 'name', hAlign: 0, width: 185, formatter: '@', },
+                    {title: '单位', colSpan: '1', rowSpan: '1', field: 'unit', hAlign: 1, width: 50, formatter: '@', cellType: 'unit'},
+                    {title: '单价', colSpan: '1', rowSpan: '1', field: 'unit_price', hAlign: 2, width: 60, type: 'Number',},
+                    {title: '本期合同金额', colSpan: '1', rowSpan: '1', field: 'contract_tp', hAlign: 2, width: 100, type: 'Number'},
+                    {title: '本期变更金额', colSpan: '1', rowSpan: '1', field: 'qc_tp', hAlign: 2, width: 100, type: 'Number'},
+                    {title: '本期完成金额', colSpan: '1', rowSpan: '1', field: 'gather_tp', hAlign: 2, width: 100, type: 'Number'},
+                ],
+                emptyRows: 0,
+                headRows: 1,
+                headRowHeight: [32],
+                defaultRowHeight: 21,
+                headerFont: '12px 微软雅黑',
+                font: '12px 微软雅黑',
+                frozenLineColor: '#93b5e4',
+                readOnly: true,
+            };
+            sjsSettingObj.setFxTreeStyle(spreadSetting, sjsSettingObj.FxTreeStyle.jz);
+            SpreadJsObj.initSheet(lockSheet, spreadSetting);
+            lockTree = createNewPathTree('stage', {
+                id: 'ledger_id', pid: 'ledger_pid', order: 'order',
+                level: 'level', rootId: -1,
+                keys: ['id', 'tender_id', 'ledger_id'],
+                stageId: 'id',
+                calcFields: [],
+            });
+            const lockDatas = setting.tree.datas.map(y => {
+                return {
+                    id: y.id, tender_id: y.tender_id,
+                    ledger_id: y.ledger_id, ledger_pid: y.ledger_pid, order: y.order,
+                    level: y.level, is_leaf: y.is_leaf, full_path: y.full_path,
+                    code: y.code, b_code: y.b_code, name: y.name, unit: y.unit,
+                    unit_price: y.unit_price, quantity: y.quantity, total_price: y.total_price,
+                    contract_tp: y.contract_tp, qc_tp: y.qc_tp, gather_tp: y.gather_tp,
+                    filter: y.filter, _fixed: y._fixed, locked: 0,
+                }
+            });
+            lockTree.loadDatas(lockDatas);
+            lockTree.refreshNodeVisible();
+            SpreadJsObj.loadSheetData(lockSheet, SpreadJsObj.DataType.Tree, lockTree);
+
+            lockSpread.bind(spreadNS.Events.ButtonClicked, function(e, info) {
+                if (!info.sheet.zh_setting || !info.sheet.zh_tree) return;
+
+                const col = info.sheet.zh_setting.cols[info.col];
+                if (col.field !== 'locked') return;
+
+                const node = SpreadJsObj.getSelectObject(info.sheet);
+                if (node._fixed) {
+                    toastr.warning('无权锁定该节点,如需锁定,请在子项尝试');
+                    return;
+                }
+                if (!node.locked) {
+                    const parents = info.sheet.zh_tree.getAllParents(node);
+                    if (parents.find(x => { return x.locked; })) {
+                        toastr.warning('父项已锁定,请勿在子项重复锁定');
+                        return;
+                    }
+                }
+                node.locked = !node.locked;
+                SpreadJsObj.reLoadRowData(info.sheet, info.row, 1);
+            });
+
+            $('#sp-lock-ok').click(function() {
+                setting.callback(getLockedLid());
+                $('#sp-lock').modal('hide');
+                $('#sp-back').modal('show');
+            });
+            $('#sp-lock').on('shown.bs.modal', function() {
+                lockSpread.refresh();
+            });
+        };
+        const loadLockedLid = function(lid) {
+            if (!lid) return;
+            const lidList = lid.split(',');
+            lockTree.nodes.forEach(x => {
+                if (lidList.indexOf(x.ledger_id + '') >= 0) x.locked = 1;
+            })
+        };
+        const show = function(setting) {
+            init(setting);
+            loadLockedLid(setting.locked_lid);
+            $('#sp-back').modal('hide');
+            $('#sp-lock').modal('show');
+        };
+        return { show }
+    })();
+    $('#sp-back-lock').click(function(){
+        spBackLock.show({
+            tree: stageTree,
+            locked_lid: $('[name=audit_locked_lid]').val(),
+            callback: function(lid) { $('[name=audit_locked_lid]').val(lid) },
+        })
+    });
 });
 function makeOneShouFang(sf) {
     const lData = _.find(ledgerData, { id: sf.lid });

+ 3 - 2
app/service/stage_audit.js

@@ -516,7 +516,7 @@ module.exports = app => {
                         // 流程至下一审批人
                         const updateData = nextAudits.map(x => {
                             return {
-                                id: x.id, status: x.audit_locked ? auditConst.status.checking : x.status,
+                                id: x.id, status: x.audit_locked ? x.status : auditConst.status.checking,
                                 begin_time: x.audit_locked ? x.begin_time : time, audit_locked: 0,
                             };
                         });
@@ -2372,13 +2372,14 @@ module.exports = app => {
         }
 
         async getUniqAuditor(stageId, times) {
-            const auditors = await this.ctx.service.stageAudit.getAuditors(stageId, times); // 全部参与的审批人
+            const auditors = await this.ctx.service.stageAudit.getAuditors(stageId, times, 'DESC'); // 全部参与的审批人
             const result = [];
             auditors.forEach(x => {
                 if (result.findIndex(r => { return x.aid === r.aid && x.audit_order === r.audit_order; }) < 0) {
                     result.push(x);
                 }
             });
+            result.reverse();
             return result;
         }