Browse Source

审批流程,协同相关

MaiXinRong 9 months ago
parent
commit
d08e9ba6c5

+ 1 - 1
app/const/audit.js

@@ -13,7 +13,7 @@ const auditType = (function () {
         { key: 'common', name: '个人', value: 1, short: '', long: '', class: '' },
         { key: 'and', name: '会签', value: 2, short: '会', long: '多人会签', class: 'primary' },
         { key: 'or', name: '或签', value: 3, short: '或', long: '多人或签', class: 'success' },
-        { key: 'joint', name: '协同', value: 4, short: '协', long: '多人协同', class: 'warning'},
+        { key: 'union', name: '协同', value: 4, short: '协', long: '多人协同', class: 'warning'},
     ];
     const key = {};
     const info = [];

+ 3 - 1
app/controller/stage_controller.js

@@ -368,7 +368,9 @@ module.exports = app => {
                             } else {
                                 responseData.data.ledgerData = await this._getStageLedgerData(ctx);
                             }
-                            responseData.data.locked = await ctx.service.stageAuditAss.getLockedId(ctx.stage);
+                            const assistLocked = await ctx.service.stageAuditAss.getLockedId(ctx.stage);
+                            const auditLocked = await ctx.service.stageAudit.getLockedId(ctx.stage);
+                            responseData.data.locked = [...assistLocked, ...auditLocked];
                             break;
                         case 'pos':
                             if (hpack) {

+ 4 - 4
app/controller/tender_controller.js

@@ -1252,11 +1252,11 @@ module.exports = app => {
             }
         }
 
-        async loadJointAudit(ctx) {
+        async loadUnionAudit(ctx) {
             try {
                 const data = JSON.parse(ctx.request.body.data);
                 const result = {};
-                result.jointAuditors = await ctx.service.shenpiAudit.getJointAudit(ctx.tender.id, shenpiConst.sp_type[data.sp_type], data.audit_order);
+                result.unionAuditors = await ctx.service.shenpiAudit.getUnionAudit(ctx.tender.id, shenpiConst.sp_type[data.sp_type], data.audit_order);
                 if (data.ledger) {
                     const ledgerData = await ctx.service.ledger.getAllDataByCondition({
                         columns: ['id', 'tender_id', 'ledger_id', 'ledger_pid', 'level', 'order', 'full_path', 'is_leaf', 'code', 'b_code', 'name'],
@@ -1271,10 +1271,10 @@ module.exports = app => {
             }
         }
 
-        async saveJointAudit(ctx) {
+        async saveUnionAudit(ctx) {
             try {
                 const data = JSON.parse(ctx.request.body.data);
-                await ctx.service.shenpiAudit.saveJointAudit(ctx.tender.id, data);
+                await ctx.service.shenpiAudit.saveUnionAudit(ctx.tender.id, data);
                 ctx.body = {err: 0, msg: '', data: null};
             } catch(err) {
                 ctx.log(err);

+ 8 - 2
app/middleware/stage_check.js

@@ -9,6 +9,7 @@
 
 const status = require('../const/audit').stage.status;
 const reviseStatus = require('../const/audit').revise.status;
+const auditType = require('../const/audit').auditType;
 const shenpiConst = require('../const/shenpi');
 const _ = require('lodash');
 
@@ -103,8 +104,13 @@ module.exports = options => {
                     stage.curOrder = stage.curAuditors[0].order - 1
                 }
                 if (!stage.readOnly) {
-                    stage.readOnly = !_.isEqual(stage.flowAuditorIds, stage.curAuditorIds);
-                    stage.canCheck = true;
+                    if (stage.curAuditors[0].audit_type === auditType.key.and) {
+                        stage.readOnly = !_.isEqual(stage.flowAuditorIds, stage.curAuditorIds);
+                        stage.canCheck = true;
+                    } else if (stage.curAuditors[0].audit_type === auditType.key.union) {
+                        stage.readOnly = stage.relaAuditor.status === status.checked;
+                        stage.canCheck = !stage.readOnly
+                    }
                 }
             }
             if (stage.readOnly) {

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

@@ -1384,7 +1384,7 @@ const createNewPathTree = function (type, setting) {
         _loadLockedNodes(ids){
             this.Locked = ids || [];
             for (const f of this.Locked) {
-                f.ass_ledger_id = f.ass_ledger_id ? f.ass_ledger_id.split(',') : [];
+                f.locked_ledger_id = f.ass_ledger_id ? f.ass_ledger_id.split(',') : (f.audit_ledger_id ? f.audit_ledger_id.split(',') : []);
                 for (const id of f.ass_ledger_id) {
                     const node = this.getItems(id);
                     node.locked = true;

+ 3 - 1
app/public/js/shares/cs_tools.js

@@ -581,6 +581,7 @@ const showSelectTab = function(select, spread, afterShow) {
             searchResult = [];
             const sortData = SpreadJsObj.getSortData(searchSheet);
             for (const node of sortData) {
+                if (node.filter) continue;
                 if ((node.code && node.code.indexOf(keyword) > -1) ||
                     (node.b_code && node.b_code.indexOf(keyword) > -1) ||
                     (node.name && node.name.indexOf(keyword) > -1) ||
@@ -956,7 +957,8 @@ const showSelectTab = function(select, spread, afterShow) {
         const getTagDisplayHtml = function (tag) {
             const tagClass = classIndexes.find(x => {return x.color === tag.color}) || {};
             const tagHtml = [];
-            tagHtml.push('<div name="tag-view">');
+            const hidden = tag.node.filter ? 'style="display: none;"' : '';
+            tagHtml.push(`<div name="tag-view" ${hidden}>`);
             tagHtml.push('<div class="card-header p-2"><div class="dropdown">');
             tagHtml.push(`<div class="pull-left mr-2"><i class="fa fa-tag ${tagClass.tagClass}"></i></div>`);
             tagHtml.push('</div>');

+ 25 - 25
app/public/js/shenpi.js

@@ -302,8 +302,8 @@ $(document).ready(function () {
             if (type !== auditType.key.common || auditGroup.length === 0) {
                 html.push(this.getSelectAuditHtml(code));
             }
-            if (type === auditType.key.joint && auditGroup.length > 0) {
-                html.push(`<button class="btn btn-sm btn-outline-primary">协同设置</button>`);
+            if (type === auditType.key.union && auditGroup.length > 0) {
+                html.push(`<button class="btn btn-sm btn-outline-primary" sp_type="${code}" audit_order="${i}" name="union-set">协同设置</button>`);
             }
             html.push('</span>');
             return html.join('');
@@ -964,9 +964,9 @@ $(document).ready(function () {
     }
     const auditAss = new AuditAss();
 
-    class AuditJoint {
+    class AuditUnion {
         constructor() {
-            this.spread = SpreadJsObj.createNewSpread($('#joint-spread')[0]);
+            this.spread = SpreadJsObj.createNewSpread($('#union-spread')[0]);
             this.sheet = this.spread.getActiveSheet();
             this.tree = createNewPathTree('base', {
                 id: 'ledger_id',
@@ -975,12 +975,12 @@ $(document).ready(function () {
                 level: 'level',
                 rootId: -1,
             });
-            this.selectJoint = [{ value: 0, text: '' }];
+            this.selectUnion = [{ value: 0, text: '' }];
             this.spreadSetting = {
                 cols: [
                     {title: '编号', colSpan: '1', rowSpan: '1', field: 'code', hAlign: 0, width: 165, formatter: '@', cellType: 'tree', readOnly: true },
                     {title: '名称', colSpan: '1', rowSpan: '1', field: 'name', hAlign: 0, width: 185, formatter: '@', readOnly: true },
-                    {title: '协同人', colSpan: '1', rowSpan: '1', field: 'audit_id', hAlign: 1, width: 100, cellType: 'customizeCombo', comboItems: this.selectJoint },
+                    {title: '协同人', colSpan: '1', rowSpan: '1', field: 'audit_id', hAlign: 1, width: 100, cellType: 'customizeCombo', comboItems: this.selectUnion },
                 ],
                 emptyRows: 0,
                 headRows: 1,
@@ -1001,17 +1001,17 @@ $(document).ready(function () {
                 node[col.field] = info.editingText;
             });
 
-            $('#joint').on('shown.bs.modal', function() {
+            $('#union').on('shown.bs.modal', function() {
                self.spread.refresh();
             });
-            $('#joint-ok').click(function() {
-                const data = self.getJointAuditLedgerData();
-                postData(`/tender/${cur_tenderid}/shenpi/joint/save`, data, function(result) {
-                    $('#joint').modal('hide');
+            $('#union-ok').click(function() {
+                const data = self.getUnionAuditLedgerData();
+                postData(`/tender/${cur_tenderid}/shenpi/union/save`, data, function(result) {
+                    $('#union').modal('hide');
                 });
             });
         }
-        _refreshJointTree() {
+        _refreshUnionTree() {
             const ledgerAss = {};
             for (const a of this.auditors) {
                 a.lid.forEach(l => { ledgerAss[l] = a; });
@@ -1023,38 +1023,38 @@ $(document).ready(function () {
             }
             SpreadJsObj.reloadColData(this.sheet, 2);
         }
-        setJointAuditors(auditors) {
+        setUnionAuditors(auditors) {
             this.auditors = auditors;
-            this.selectJoint.length = 1;
+            this.selectUnion.length = 1;
             const html = [];
             for (const auditor of auditors) {
                 auditor.lid = auditor.audit_ledger_id ? auditor.audit_ledger_id.split(',') : [];
                 html.push(`<tr><td>${auditor.name}</td><td>${auditor.company}</td><td>${auditor.lid.length}<button class="ml-2 btn btn-sm btn-outline-danger" jaid="${auditor.audit_id}">清空</button></td></tr>`);
-                this.selectJoint.push({ value: auditor.audit_id, text: auditor.name });
+                this.selectUnion.push({ value: auditor.audit_id, text: auditor.name });
             }
-            $('#joint_table').html(html.join(''));
-            this._refreshJointTree();
+            $('#union_table').html(html.join(''));
+            this._refreshUnionTree();
         }
-        loadJointData(sp_type, audit_order) {
+        loadUnionData(sp_type, audit_order) {
             const data = { sp_type, audit_order };
             if (!this.loaded) data.ledger = 1;
 
             const self = this;
-            postData(`/tender/${cur_tenderid}/shenpi/joint/load`, data, function(result) {
+            postData(`/tender/${cur_tenderid}/shenpi/union/load`, data, function(result) {
                 self.loaded = true;
                 if (result.ledgerList) {
                     self.tree.loadDatas(result.ledgerList);
                     SpreadJsObj.loadSheetData(self.sheet, SpreadJsObj.DataType.Tree, self.tree);
                 }
-                self.setJointAuditors(result.jointAuditors);
+                self.setUnionAuditors(result.unionAuditors);
                 if (self.auditors.length > 0) {
-                    $('#joint').modal('show');
+                    $('#union').modal('show');
                 } else {
                     toastr.warning(`${audit_order}审未添加任何协同人,请先添加协同人再分配协同台账`);
                 }
             });
         }
-        getJointAuditLedgerData() {
+        getUnionAuditLedgerData() {
             this.auditors.forEach(a => { a.lid = []; });
             for (const node of this.tree.nodes) {
                 if (node.audit_id > 0) {
@@ -1067,9 +1067,9 @@ $(document).ready(function () {
             });
         }
     }
-    const auditJoint = new AuditJoint();
-    $('body').on('click', '[name=joint-set]', function() {
-        auditJoint.loadJointData(this.getAttribute('sp_type'), this.getAttribute('audit_order'));
+    const auditUnion = new AuditUnion();
+    $('body').on('click', '[name=union-set]', function() {
+        auditUnion.loadUnionData(this.getAttribute('sp_type'), this.getAttribute('audit_order'));
     });
 
     $.subMenu({

+ 21 - 6
app/public/js/stage.js

@@ -2385,7 +2385,11 @@ $(document).ready(() => {
     postData(window.location.pathname + '/load', { filter: 'ledger;pos;detail;stageChange;import_change;tag' }, function (result) {
         // 加载树结构
         stageTree.loadDatas(result.ledgerData, result.locked);
-        if (stage.assist) stageTree.loadFilter(stage.assist.ass_ledger_id);
+        if (stage.assist) {
+            stageTree.loadFilter(stage.assist.ass_ledger_id);
+        } else if (stage.relaAuditor) {
+            stageTree.loadFilter(stage.relaAuditor.audit_ledger_id);
+        }
         // 加载部位明细
         stagePos.loadDatas(result.posData);
         checkShowLast(result.ledgerData.length);
@@ -2413,6 +2417,11 @@ $(document).ready(() => {
         // 加载中间计量
         stageIm.init(tenderInfo, stage, imType, tenderInfo.decimal, stage.assist ? stage.assist.ass_ledger_id : '');
         stageIm.loadData(result.ledgerData, result.posData, result.detailData, result.stageChange, result.import_change, result.detailAtt);
+        if (stage.assist) {
+            stageIm.loadFilter(stage.assist.ass_ledger_id);
+        } else if (stage.relaAuditor) {
+            stageIm.loadFilter(stage.relaAuditor.audit_ledger_id);
+        }
 
         errorList.loadHisErrorData();
         checkList.loadHisCheckData();
@@ -4155,13 +4164,16 @@ $(document).ready(() => {
                             const changeBills = SpreadJsObj.getSelectObject(self.changeBillsSheet);
                             if (change.is_import) {
                                 if (changeBills.pos && changeBills.pos.length > 0) {
+                                    const node = stageTree.getItems(changeBills.pos[0].ledger_id);
+                                    if (!node || node.filter) return;
+
                                     SpreadJsObj.locateTreeNode(slSpread.getActiveSheet(), changeBills.pos[0].ledger_id, true);
                                     SpreadJsObj.resetTopAndSelect(spSpread.getActiveSheet());
                                     stagePosSpreadObj.loadCurPosData();
                                 }
                             } else if (changeBills.gcl_id) {
                                 const node = stageTree.nodes.find(x => {return x.id === changeBills.gcl_id});
-                                if (!node) return;
+                                if (!node || node.filter) return;
 
                                 SpreadJsObj.locateTreeNode(slSpread.getActiveSheet(), node.ledger_id, true);
                                 SpreadJsObj.resetTopAndSelect(spSpread.getActiveSheet());
@@ -4180,6 +4192,7 @@ $(document).ready(() => {
                                 };
                                 for (const node of stageTree.nodes) {
                                     if (node.children && node.children.length > 0) continue;
+                                    if (node.filter) continue;
 
                                     const b = {
                                         b_code: node.b_code || '',
@@ -4234,7 +4247,7 @@ $(document).ready(() => {
                             return !changeBills || curChange.is_import;
                         },
                         visible: function (key, opt) {
-                            return is_debug && stage.status === 1;
+                            return stage.status === 1 && stage.isCheckFirst && !stage.assist;
                         }
                     },
                 }
@@ -4284,7 +4297,7 @@ $(document).ready(() => {
                             return !curChange || !changeBills || curChange.is_import;
                         },
                         visible: function (key, opt) {
-                            return stage.status === 1 && stage.isCheckFirst;
+                            return stage.status === 1 && stage.isCheckFirst && !stage.assist;
                         }
                     },
                     'autoUseAll': {
@@ -4300,7 +4313,7 @@ $(document).ready(() => {
                             return !curChange || curChange.is_import;
                         },
                         visible: function (key, opt) {
-                            return stage.status === 1 && stage.isCheckFirst;
+                            return stage.status === 1 && stage.isCheckFirst && !stage.assist;
                         }
                     }
                 }
@@ -4398,6 +4411,7 @@ $(document).ready(() => {
                 return null;
             } else if (changeBills.gcl_id) {
                 const node = stageTree.nodes.find(x => {return x.id === changeBills.gcl_id});
+                if (node.filter) return null;
                 if (node.settle_status === settleStatus.finish) return null;
 
                 posData = stagePos.getLedgerPos(node.id) || [];
@@ -4421,7 +4435,8 @@ $(document).ready(() => {
                 };
                 for (const node of stageTree.nodes) {
                     if (node.children && node.children.length > 0) continue;
-                    if (node.settle_status === settleStatus.finish) return null;
+                    if (node.filter) continue;
+                    if (node.settle_status === settleStatus.finish) continue;
 
                     const b = {
                         b_code: node.b_code || '',

+ 11 - 0
app/public/js/stage_im.js

@@ -92,6 +92,10 @@ const stageIm = (function () {
         detailsAtt = stageDetailAtt;
     }
 
+    function loadFilter(filter) {
+        gsTree.loadFilter(filter);
+    }
+
     function loadData4Rela(ledger, pos, stageDetail, stageChange, stageDetailAtt) {
         up_field = 'org_unit_price';
         gsTree.loadDatas(ledger);
@@ -607,6 +611,7 @@ const stageIm = (function () {
                 custom_define: [],
                 source: [{id: node.ledger_id, code: node.code, b_code: node.b_code}],
                 im_type: imType.tz.value,
+                visible: !node.filter,
             };
             if (stage.im_gather && node.check) {
                 im.bw = getZlGatherBw(node, peg);
@@ -673,6 +678,7 @@ const stageIm = (function () {
                 custom_define: [],
                 source: [{id: node.ledger_id, code: node.code, b_code: node.b_code}],
                 im_type: imType.bb.value,
+                visible: !node.filter,
             };
             for (const p of posterity) {
                 if (p.children && p.children.length > 0) continue;
@@ -697,6 +703,7 @@ const stageIm = (function () {
                                 custom_define: [],
                                 source: [],
                                 im_type: imType.bb.value,
+                                visible: !node.filter,
                             };
                             nodeImData.push(im);
                         }
@@ -840,6 +847,7 @@ const stageIm = (function () {
                     custom_define: [],
                     source: [],
                     im_type: imType.zl.value,
+                    visible: !node.filter,
                 };
                 if (stage.im_gather && node.check) {
                     im.bw = getZlGatherBw(node, peg);
@@ -891,6 +899,7 @@ const stageIm = (function () {
                         custom_define: [],
                         source: [{id: p.ledger_id, code: p.code, b_code: p.b_code, pos_id: pp.id, pos_name: pp.name}],
                         im_type: imType.bw.value,
+                        visible: !node.filter,
                     };
                     im.calc_memo = '本期计量:' + (checkZero(im.jl) ? 0 : im.jl) + (im.qc_minus_jl ? (` (不计价 ${im.qc_minus_jl}) `) : ' ') + im.unit;
                     ImData.push(im);
@@ -917,6 +926,7 @@ const stageIm = (function () {
                     custom_define: [],
                     source: [{id: p.ledger_id, code: p.code, b_code: p.b_code}],
                     im_type: imType.bw.value,
+                    visible: !node.filter,
                 };
                 im.calc_memo = '本期计量:' + (checkZero(im.jl) ? 0 : im.jl) + (im.qc_minus_jl ? (` (不计价 ${im.qc_minus_jl}) `) : ' ') + im.unit;
                 ImData.push(im);
@@ -1223,6 +1233,7 @@ const stageIm = (function () {
         init,
         initCheck,
         loadData,
+        loadFilter,
         loadData4Rela,
         buildImData,
         loadUpdateDetailData,

+ 2 - 2
app/router.js

@@ -189,8 +189,8 @@ module.exports = app => {
     app.post('/tender/:id/shenpi/audit/save', sessionAuth, tenderCheck, 'tenderController.saveShenpiAudit');
     app.post('/tender/:id/shenpi/ass/load', sessionAuth, tenderCheck, 'tenderController.loadAuditAss');
     app.post('/tender/:id/shenpi/save-sign', sessionAuth, tenderCheck, 'tenderController.saveCooperateSign');
-    app.post('/tender/:id/shenpi/joint/load', sessionAuth, tenderCheck, 'tenderController.loadJointAudit');
-    app.post('/tender/:id/shenpi/joint/save', sessionAuth, tenderCheck, 'tenderController.saveJointAudit');
+    app.post('/tender/:id/shenpi/union/load', sessionAuth, tenderCheck, 'tenderController.loadUnionAudit');
+    app.post('/tender/:id/shenpi/union/save', sessionAuth, tenderCheck, 'tenderController.saveUnionAudit');
     app.post('/tender/:id/copy-setting', sessionAuth, tenderCheck, 'tenderController.copyTender');
     app.post('/tender/:id/tourist/audit/save', sessionAuth, tenderCheck, uncheckTenderCheck, 'tenderController.saveTourist');
     app.post('/tender/:id/map/save', sessionAuth, tenderCheck, uncheckTenderCheck, 'tenderController.saveMap');

+ 2 - 2
app/service/shenpi_audit.js

@@ -54,7 +54,7 @@ module.exports = app => {
             return await this.db.queryOne(sql, sqlParam);
         }
 
-        async getJointAudit(tid, type, audit_order) {
+        async getUnionAudit(tid, type, audit_order) {
             const sql = 'SELECT sp.id, sp.audit_id, sp.audit_ledger_id, pa.name, pa.company FROM ?? AS sp LEFT JOIN ?? AS pa ON sp.audit_id = pa.id' +
                 ' WHERE sp.tid = ? AND sp.sp_type = ? AND sp.sp_status = ? AND audit_order = ?';
             const sqlParam = [this.tableName, this.ctx.service.projectAccount.tableName, tid, type, shenpiConst.sp_status.gdspl, audit_order];
@@ -488,7 +488,7 @@ module.exports = app => {
             }
         }
 
-        async saveJointAudit(tid, data) {
+        async saveUnionAudit(tid, data) {
             const orgData = await this.getAllDataByCondition({ where: { id: data.map(x => { return x.id; }) } });
             for (const od of orgData) {
                 if (od.tid !== tid) throw '保存数据错误,请刷新页面后重试';

+ 2 - 1
app/service/stage.js

@@ -89,6 +89,7 @@ module.exports = app => {
                 name: stage.user.name, role: stage.user.role, company: stage.user.company
             }]);
             stage.finalAuditorIds = stage.userGroups[stage.userGroups.length - 1].map(x => { return x.aid; });
+            stage.relaAuditor = stage.auditors.find(x => { return x.aid === accountId });
 
             stage.assists = await this.service.stageAuditAss.getData(stage); // 全部协同人
             stage.assists = stage.assists.filter(x => {
@@ -234,7 +235,7 @@ module.exports = app => {
                     const flowAssists = stage.auditAssists.filter(x => { return stage.flowAuditorIds.indexOf(x.user_id) >= 0; });
                     if (flowAssists.find(x => { return x.confirm; })) return; //当前流程存在协审人确认时,不可撤回
                     if (stage.curAuditorIds.indexOf(accountId) < 0 && stage.flowAuditorIds.indexOf(accountId) >= 0) {
-                        stage.cancancel = 5; // 会签未全部审批通过时,审批人撤回审批通过
+                        stage.cancancel = 5; // 会签/协同 未全部审批通过时,审批人撤回审批通过
                         return;
                     }
 

+ 35 - 19
app/service/stage_audit.js

@@ -79,7 +79,7 @@ module.exports = app => {
 
         async getLastestAuditor(stageId, times, status) {
             const sql =
-                'SELECT la.`aid`, pa.`name`, pa.`company`, pa.`role`, pa.`mobile`, pa.`telephone`, la.audit_type, la.audit_order,' +
+                'SELECT la.`aid`, pa.`name`, pa.`company`, pa.`role`, pa.`mobile`, pa.`telephone`, la.audit_type, la.audit_order, la.audit_ledger_id,' +
                 '    la.`times`, la.`order`, la.`status`, la.`opinion`, la.`begin_time`, la.`end_time` ' +
                 '    FROM ' + this.tableName + ' AS la' +
                 '    Left Join ' + this.ctx.service.projectAccount.tableName + ' AS pa ON la.`aid` = pa.`id`' +
@@ -91,7 +91,7 @@ module.exports = app => {
 
         async getLastestAuditors(stageId, times, status) {
             const sql =
-                'SELECT la.`aid`, pa.`name`, pa.`company`, pa.`role`, pa.`mobile`, pa.`telephone`, la.audit_type, la.audit_order,' +
+                'SELECT la.`aid`, pa.`name`, pa.`company`, pa.`role`, pa.`mobile`, pa.`telephone`, la.audit_type, la.audit_order, la.audit_ledger_id,' +
                 '    la.`times`, la.`order`, la.`status`, la.`opinion`, la.`begin_time`, la.`end_time` ' +
                 '    FROM ' + this.tableName + ' AS la' +
                 '    Left Join ' + this.ctx.service.projectAccount.tableName + ' AS pa ON la.`aid` = pa.`id`' +
@@ -112,7 +112,7 @@ module.exports = app => {
          * @return {Promise<*>}
          */
         async getAuditors(stageId, times = 1, order_sort = 'asc') {
-            const sql = 'SELECT la.id, la.aid, la.times, la.order, la.status, la.opinion, la.begin_time, la.end_time, la.audit_type, la.audit_order,' +
+            const sql = 'SELECT la.id, la.aid, la.times, la.order, la.status, la.opinion, la.begin_time, la.end_time, la.audit_type, la.audit_order, la.audit_ledger_id,' +
                 '    pa.name, pa.company, pa.role, pa.mobile, pa.telephone, pa.sign_path' +
                 `  FROM ${this.tableName} la LEFT JOIN ${this.ctx.service.projectAccount.tableName} pa ON la.aid = pa.id` +
                 '  WHERE la.sid = ? AND la.times = ?' +
@@ -160,7 +160,7 @@ module.exports = app => {
          */
         async getCurAuditor(stageId, times = 1) {
             const sql =
-                'SELECT la.`aid`, pa.`name`, pa.`company`, pa.`role`, pa.`mobile`, pa.`telephone`, la.`times`, la.`order`, la.`status`, la.`opinion`, la.`begin_time`, la.`end_time`, la.audit_type, la.audit_order ' +
+                'SELECT la.`aid`, pa.`name`, pa.`company`, pa.`role`, pa.`mobile`, pa.`telephone`, la.`times`, la.`order`, la.`status`, la.`opinion`, la.`begin_time`, la.`end_time`, la.audit_type, la.audit_order, la.audit_ledger_id ' +
                 '  FROM ?? AS la Left Join ?? AS pa On la.`aid` = pa.`id`' +
                 '  WHERE la.`sid` = ? and la.`status` = ? and la.`times` = ?';
             const sqlParam = [this.tableName, this.ctx.service.projectAccount.tableName, stageId, auditConst.status.checking, times];
@@ -169,7 +169,7 @@ module.exports = app => {
 
         async getCurAuditors(stageId, times = 1) {
             const sql =
-                'SELECT la.`aid`, pa.`name`, pa.`company`, pa.`role`, pa.`mobile`, pa.`telephone`, la.`times`, la.`order`, la.`status`, la.`opinion`, la.`begin_time`, la.`end_time`, la.audit_type, la.audit_order ' +
+                'SELECT la.`aid`, pa.`name`, pa.`company`, pa.`role`, pa.`mobile`, pa.`telephone`, la.`times`, la.`order`, la.`status`, la.`opinion`, la.`begin_time`, la.`end_time`, la.audit_type, la.audit_order, la.audit_ledger_id ' +
                 '  FROM ?? AS la Left Join ?? AS pa On la.`aid` = pa.`id`' +
                 '  WHERE la.`sid` = ? and la.`status` = ? and la.`times` = ?';
             const sqlParam = [this.tableName, this.ctx.service.projectAccount.tableName, stageId, auditConst.status.checking, times];
@@ -653,7 +653,7 @@ module.exports = app => {
                return {
                    aid: x.aid, tid: selfAudit.tid, sid: selfAudit.sid,
                    times: times + 1, order: x.audit_order, status: auditConst.status.uncheck,
-                   audit_type: x.audit_type, audit_order: x.audit_order,
+                   audit_type: x.audit_type, audit_order: x.audit_order, audit_ledger_id: x.audit_ledger_id,
                }
             });
 
@@ -862,6 +862,7 @@ module.exports = app => {
                         times: x.times, order: selfAudit.order + 1,
                         status: auditConst.status.checking, begin_time: time,
                         audit_type: x.audit_type, audit_order: x.audit_order,
+                        audit_ledger_id: x.audit_ledger_id,
                     });
                 });
                 // 获取ids值
@@ -877,6 +878,7 @@ module.exports = app => {
                         times: x.times, order: selfAudit.order + 2,
                         status: auditConst.status.uncheck,
                         audit_type: x.audit_type, audit_order: x.audit_order,
+                        audit_ledger_id: x.audit_ledger_id,
                     });
                 });
                 await transaction.insert(this.tableName, newFlowAuditors);
@@ -1018,7 +1020,7 @@ module.exports = app => {
                         times: x.times, order: x.order + 1,
                         status: !selfAudit || x.aid === selfAudit.aid ? auditConst.status.checkAgain : auditConst.status.checkSkip,
                         begin_time: time, end_time: time, opinion: '',
-                        audit_type: x.audit_type, audit_order: x.audit_order,
+                        audit_type: x.audit_type, audit_order: x.audit_order, audit_ledger_id: x.audit_ledger_id,
                     });
                 });
                 audits.forEach(x => {
@@ -1027,7 +1029,7 @@ module.exports = app => {
                         times: x.times, order: x.order + 2,
                         status: auditConst.status.checking,
                         begin_time: time, end_time: time, opinion: '',
-                        audit_type: x.audit_type, audit_order: x.audit_order,
+                        audit_type: x.audit_type, audit_order: x.audit_order, audit_ledger_id: x.audit_ledger_id,
                     });
                 });
                 await transaction.insert(this.tableName, checkAgainAuditors);
@@ -1239,7 +1241,7 @@ module.exports = app => {
                         times: x.times, order: x.order + 1,
                         status: x.aid === selfAuditor.aid ? auditConst.status.checkCancel : auditConst.status.checkSkip,
                         begin_time: time, end_time: time, opinion: '',
-                        audit_type: x.audit_type, audit_order: x.audit_order,
+                        audit_type: x.audit_type, audit_order: x.audit_order, audit_ledger_id: x.audit_ledger_id,
                     });
                 });
                 stage.preAuditors.forEach(x => {
@@ -1248,7 +1250,7 @@ module.exports = app => {
                         times: x.times, order: x.order + 2,
                         status: auditConst.status.checking,
                         begin_time: time, end_time: time, opinion: '',
-                        audit_type: x.audit_type, audit_order: x.audit_order,
+                        audit_type: x.audit_type, audit_order: x.audit_order, audit_ledger_id: x.audit_ledger_id,
                     });
                 });
                 await transaction.insert(this.tableName, [...checkCancelAuditors, ...checkingAuditors]);
@@ -1338,7 +1340,7 @@ module.exports = app => {
                         times: x.times, order: x.order + 1,
                         status: x.aid === selfAuditor.aid ? auditConst.status.checkCancel : auditConst.status.checkSkip,
                         begin_time: time, end_time: time, opinion: '',
-                        audit_type: x.audit_type, audit_order: x.audit_order,
+                        audit_type: x.audit_type, audit_order: x.audit_order, audit_ledger_id: x.audit_ledger_id,
                     });
                 });
                 await transaction.insert(this.tableName, newAuditors);
@@ -1429,7 +1431,7 @@ module.exports = app => {
                         times: x.times, order: x.order + 1,
                         status: x.aid === selfAuditor.aid ? auditConst.status.checkCancel : auditConst.status.checkSkip,
                         begin_time: time, end_time: time, opinion: '',
-                        audit_type: x.audit_type, audit_order: x.audit_order,
+                        audit_type: x.audit_type, audit_order: x.audit_order, audit_ledger_id: x.audit_ledger_id,
                     });
                 });
                 stage.preAuditors.forEach(x => {
@@ -1438,7 +1440,7 @@ module.exports = app => {
                         times: x.times, order: x.order + 2,
                         status: auditConst.status.checking,
                         begin_time: time, end_time: time, opinion: '',
-                        audit_type: x.audit_type, audit_order: x.audit_order,
+                        audit_type: x.audit_type, audit_order: x.audit_order, audit_ledger_id: x.audit_ledger_id,
                     });
                 });
                 await transaction.insert(this.tableName, [...checkCancelAuditors, ...checkingAuditors]);
@@ -1675,7 +1677,7 @@ module.exports = app => {
             //     '  WHERE la.`sid` = ? and la.`times` = ? and la.`is_old` = 0 GROUP BY la.`aid` ORDER BY la.`order`';
             // const sqlParam = [this.tableName, this.ctx.service.projectAccount.tableName, stageId, times];
             const sql =
-                'SELECT la.`aid`, pa.`name`, pa.`company`, pa.`role`, la.`times`, la.`sid`, la.`order`, la.`status`, la.audit_type, la.audit_order' +
+                'SELECT la.`aid`, pa.`name`, pa.`company`, pa.`role`, la.`times`, la.`sid`, la.`order`, la.`status`, la.audit_type, la.audit_order, la.audit_ledger_id' +
                 ' FROM (SELECT `aid`, max(`order`) `order` FROM ?? WHERE `sid` = ? and `times` = ? and `is_old` = ? GROUP BY aid) sa' +
                 ' LEFT JOIN ?? la ON sa.`aid` = la.`aid` AND sa.`order` = la.`order`' +
                 ' Left JOIN ?? AS pa On la.`aid` = pa.`id` WHERE la.`sid` = ? and la.`times` = ? and la.`is_old` = ? order BY la.`order`';
@@ -1724,6 +1726,7 @@ module.exports = app => {
                     status: auditConst.status.uncheck,
                     audit_type: a.audit_type,
                     audit_order: a.audit_order,
+                    audit_ledger_id: x.audit_ledger_id,
                 };
                 newAuditors.push(na);
             }
@@ -1783,7 +1786,7 @@ module.exports = app => {
                     cur = await this.db.queryOne(`SELECT * From ${this.tableName} where sid = ? AND times = ? AND status = ? ORDER By times DESC, ` + '`order` DESC', [stageId, times, status]);
                     if (!cur) return [];
 
-                    sql = 'SELECT la.`aid`, pa.`name`, pa.`company`, pa.`role`, la.`times`, la.`sid`, la.`order`, la.audit_order, la.audit_type ' +
+                    sql = 'SELECT la.`aid`, pa.`name`, pa.`company`, pa.`role`, la.`times`, la.`sid`, la.`order`, la.audit_order, la.audit_type, la.audit_ledger_id ' +
                         '  FROM ?? AS la Left Join ?? AS pa On la.`aid` = pa.`id` ' +
                         '  WHERE la.`sid` = ? and la.`order` = ? and times = ?';
                     sqlParam = [this.tableName, this.ctx.service.projectAccount.tableName, stageId, cur.order, times];
@@ -1793,7 +1796,7 @@ module.exports = app => {
                     cur = await this.db.queryOne(`SELECT * From ${this.tableName} where sid = ? AND times = ? AND status = ? ORDER By times DESC, ` + '`order` DESC', [stageId, parseInt(times) - 1, status]);
                     if (!cur) return [];
 
-                    sql = 'SELECT la.`aid`, pa.`name`, pa.`company`, pa.`role`, la.`times`, la.`sid`, la.`order`, la.audit_order, la.audit_type ' +
+                    sql = 'SELECT la.`aid`, pa.`name`, pa.`company`, pa.`role`, la.`times`, la.`sid`, la.`order`, la.audit_order, la.audit_type, la.audit_ledger_id ' +
                         '  FROM ?? AS la Left Join ?? AS pa On la.`aid` = pa.`id` ' +
                         '  WHERE la.`sid` = ? and la.`order` = ? and la.`times` = ?';
                     sqlParam = [this.tableName, this.ctx.service.projectAccount.tableName, stageId, cur.order, parseInt(times) - 1];
@@ -1895,7 +1898,7 @@ module.exports = app => {
                     await this._timesDelete(this.ctx.stage.id, nowTimes, transaction);
                 }
                 // 添加上一次审批人
-                const sql = 'SELECT `tid`, `sid`, `aid`, `order`, `audit_type`, `audit_order` FROM ?? WHERE `sid` = ? and `times` = ? GROUP BY `aid` ORDER BY `id` ASC';
+                const sql = 'SELECT `tid`, `sid`, `aid`, `order`, `audit_type`, `audit_order`, `audit_ledger_id` FROM ?? WHERE `sid` = ? and `times` = ? GROUP BY `aid` ORDER BY `id` ASC';
                 const sqlParam = [this.tableName, this.ctx.stage.id, nowTimes - 1];
                 const auditors = await this.db.query(sql, sqlParam);
                 let order = 1;
@@ -1976,7 +1979,8 @@ module.exports = app => {
                     newAuditors.push({
                         tid: stage.tid, sid: stage.id, aid: auditor.audit_id,
                         times: stage.times, order: auditor.audit_order, status: auditConst.status.uncheck,
-                        audit_type: auditor.audit_type, audit_order: auditor.audit_order, audit_ledger_id: auditor.audit_ledger_id,
+                        audit_type: auditor.audit_type, audit_order: auditor.audit_order,
+                        audit_ledger_id: auditor.audit_type === auditType.key.union ? auditor.audit_ledger_id : '',
                     });
                 }
                 if(newAuditors.length > 0) await transaction.insert(this.tableName, newAuditors);
@@ -2026,7 +2030,7 @@ module.exports = app => {
         async getFinalAuditGroup(stageId, times) {
             const sql =
                 'SELECT la.`aid`, pa.`name`, pa.`company`, pa.`role`, pa.`mobile`, pa.`telephone`, pa.`sign_path`,' +
-                '  la.`times`, la.`sid`, la.`audit_order`, la.`audit_type`, Max(la.`order`) as max_order ' +
+                '  la.`times`, la.`sid`, la.`audit_order`, la.`audit_type`, la.`audit_ledger_id`, Max(la.`order`) as max_order ' +
                 '  FROM ?? AS la Left Join ?? AS pa On la.`aid` = pa.`id`' +
                 '  WHERE la.`sid` = ? and la.`times` = ? GROUP BY la.`aid` ORDER BY la.`order`';
             const sqlParam = [this.tableName, this.ctx.service.projectAccount.tableName, stageId, times];
@@ -2246,6 +2250,18 @@ module.exports = app => {
             });
             return result;
         }
+
+        async cancelLock(stage, uid, transaction) {
+            if (transaction) {
+                await transaction.update(this.tableName, { locked: 0 }, { where: { sid: stage.id, times: stage.times, aid: uid } });
+            } else {
+                await this.db.update(this.tableName, { locked: 0 }, { where: { sid: stage.id, times: stage.times, aid: uid } });
+            }
+        }
+
+        async getLockedId(stage) {
+            return await this.getAllDataByCondition({ where: { sid: stage.id, times: stage.times, audit_locked: 1 } });
+        }
     }
 
     return StageAudit;

+ 2 - 2
app/view/tender/shenpi.ejs

@@ -105,8 +105,8 @@
                                                 </div>
                                                 </span>
                                                 <% } %>
-                                                <% if (auditGroup[0].audit_type === auditType.key.joint) { %>
-                                                <button class="btn btn-outline-primary btn-sm" sp_type="<%- sp.code %>" audit_order="<%- auditGroup[0].audit_order %>" name="joint-set">协同设置</button>
+                                                <% if (auditGroup[0].audit_type === auditType.key.union) { %>
+                                                <button class="btn btn-outline-primary btn-sm" sp_type="<%- sp.code %>" audit_order="<%- auditGroup[0].audit_order %>" name="union-set">协同设置</button>
                                                 <% } %>
                                             </span>
                                         </li>

+ 4 - 4
app/view/tender/shenpi_modal.ejs

@@ -166,7 +166,7 @@
         </div>
     </div>
 </div>
-<div class="modal fade" id="joint" data-backdrop="static">
+<div class="modal fade" id="union" data-backdrop="static">
     <div class="modal-dialog modal-xl" role="document">
         <div class="modal-content">
             <div class="modal-header">
@@ -180,20 +180,20 @@
                                 <thead class="text-center" >
                                 <tr><th>姓名</th><th>单位</th><th>协同处理</th></tr>
                                 </thead>
-                                <tbody id="joint_table">
+                                <tbody id="union_table">
                                 </tbody>
                             </table>
                         </div>
                     </div>
                     <div class="col-6">
-                        <div class="modal-height-500" style="overflow: auto;" id="joint-spread">
+                        <div class="modal-height-500" style="overflow: auto;" id="union-spread">
                         </div>
                     </div>
                 </div>
             </div>
             <div class="modal-footer">
                 <button type="button" class="btn btn-sm btn-secondary" data-dismiss="modal">关闭</button>
-                <button type="button" class="btn btn-sm btn-primary" id="joint-ok">保存</button>
+                <button type="button" class="btn btn-sm btn-primary" id="union-ok">保存</button>
             </div>
         </div>
     </div>

+ 2 - 1
sql/update.sql

@@ -449,7 +449,8 @@ ALTER TABLE `zh_shenpi_audit`
 ADD COLUMN `audit_ledger_id` varchar(5000) NOT NULL DEFAULT '' COMMENT '审批台账id' AFTER `audit_order`;
 
 ALTER TABLE `zh_stage_audit`
-ADD COLUMN `audit_ledger_id` varchar(5000) NOT NULL DEFAULT '' COMMENT '审批台账id' AFTER `audit_order`;
+ADD COLUMN `audit_ledger_id` varchar(5000) NOT NULL DEFAULT '' COMMENT '审批台账id' AFTER `audit_order`,
+ADD COLUMN `audit_locked` tinyint(1) NOT NULL DEFAULT 0  COMMENT '审批锁定(仅协审用)' AFTER `audit_ledger_id`;
 
 -- update请放在最后