Pārlūkot izejas kodu

协同配置相关

MaiXinRong 11 mēneši atpakaļ
vecāks
revīzija
5f52bbfb61

+ 1 - 0
app/const/audit.js

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

+ 1 - 1
app/const/spread.js

@@ -284,7 +284,7 @@ const glSpreadTemplate = {
         { key: 'position', valid: 1 },
         { key: 'position', valid: 1 },
         { key: 'unit', valid: 1 },
         { key: 'unit', valid: 1 },
         { key: 'unit_price', valid: 1 },
         { key: 'unit_price', valid: 1 },
-        { key: 'deal_calc', valid: 0, },
+        { key: 'deal_calc', valid: 1, },
         { key: 'tz_calc', valid: 1 },
         { key: 'tz_calc', valid: 1 },
         { key: 'real_qty', valid: 1 },
         { key: 'real_qty', valid: 1 },
         { key: 'estimate_qty', valid: 1 },
         { key: 'estimate_qty', valid: 1 },

+ 30 - 0
app/controller/tender_controller.js

@@ -1252,6 +1252,36 @@ module.exports = app => {
             }
             }
         }
         }
 
 
+        async loadJointAudit(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);
+                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'],
+                        where: { tender_id: ctx.tender.id }
+                    });
+                    result.ledgerList = ledgerData.filter(x => { return !x.b_code; });
+                }
+                ctx.body = { err: 0, msg: '', data: result };
+            } catch (err) {
+                this.log(err);
+                ctx.body = { err: 1, msg: err.toString(), data: [] };
+            }
+        }
+
+        async saveJointAudit(ctx) {
+            try {
+                const data = JSON.parse(ctx.request.body.data);
+                await ctx.service.shenpiAudit.saveJointAudit(ctx.tender.id, data);
+                ctx.body = {err: 0, msg: '', data: null};
+            } catch(err) {
+                ctx.log(err);
+                ctx.ajaxErrorBody(err, '保存协同审批数据错误');
+            }
+        }
+
         async billsTag(ctx) {
         async billsTag(ctx) {
             try {
             try {
                 const isValidTourist = ctx.tender.isTourist && ctx.tender.touristPermission.tag;
                 const isValidTourist = ctx.tender.isTourist && ctx.tender.touristPermission.tag;

+ 1 - 1
app/middleware/stage_check.js

@@ -148,7 +148,7 @@ module.exports = options => {
                     if (sameAudit) {
                     if (sameAudit) {
                         for (const audit of auditList) {
                         for (const audit of auditList) {
                             const shenpi = shenpiList.find(x => { return x.audit_id === audit.aid; });
                             const shenpi = shenpiList.find(x => { return x.audit_id === audit.aid; });
-                            if (!shenpi || shenpi.audit_order !== audit.audit_order || shenpi.audit_type !== audit.audit_type) {
+                            if (!shenpi || shenpi.audit_order !== audit.audit_order || shenpi.audit_type !== audit.audit_type || shenpi.audit_ledger_id !== audit.audit_ledger_id) {
                                 sameAudit = false;
                                 sameAudit = false;
                                 break;
                                 break;
                             }
                             }

+ 111 - 0
app/public/js/shenpi.js

@@ -302,6 +302,9 @@ $(document).ready(function () {
             if (type !== auditType.key.common || auditGroup.length === 0) {
             if (type !== auditType.key.common || auditGroup.length === 0) {
                 html.push(this.getSelectAuditHtml(code));
                 html.push(this.getSelectAuditHtml(code));
             }
             }
+            if (type === auditType.key.joint && auditGroup.length > 0) {
+                html.push(`<button class="btn btn-sm btn-outline-primary">协同设置</button>`);
+            }
             html.push('</span>');
             html.push('</span>');
             return html.join('');
             return html.join('');
         },
         },
@@ -961,6 +964,114 @@ $(document).ready(function () {
     }
     }
     const auditAss = new AuditAss();
     const auditAss = new AuditAss();
 
 
+    class AuditJoint {
+        constructor() {
+            this.spread = SpreadJsObj.createNewSpread($('#joint-spread')[0]);
+            this.sheet = this.spread.getActiveSheet();
+            this.tree = createNewPathTree('base', {
+                id: 'ledger_id',
+                pid: 'ledger_pid',
+                order: 'order',
+                level: 'level',
+                rootId: -1,
+            });
+            this.selectJoint = [{ 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 },
+                ],
+                emptyRows: 0,
+                headRows: 1,
+                headRowHeight: [32],
+                defaultRowHeight: 21,
+                headerFont: '12px 微软雅黑',
+                font: '12px 微软雅黑',
+            };
+            sjsSettingObj.setFxTreeStyle(this.spreadSetting, sjsSettingObj.FxTreeStyle.jz);
+            SpreadJsObj.initSheet(this.sheet, this.spreadSetting);
+
+            const self = this;
+            SpreadJsObj.addDeleteBind(this.spread, function() { return; });
+            SpreadJsObj.selChangedRefreshBackColor(this.sheet);
+            this.spread.bind(spreadNS.Events.EditEnded, function(e, info) {
+                const node = SpreadJsObj.getSelectObject(info.sheet);
+                const col = info.sheet.zh_setting.cols[info.col];
+                node[col.field] = info.editingText;
+            });
+
+            $('#joint').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');
+                });
+            });
+        }
+        _refreshJointTree() {
+            const ledgerAss = {};
+            for (const a of this.auditors) {
+                a.lid.forEach(l => { ledgerAss[l] = a; });
+            }
+            for (const n of this.tree.nodes) {
+                const la = ledgerAss[n.ledger_id];
+                n.audit_id = la ? la.audit_id : 0;
+                n.audit_name = la ? la.name : '';
+            }
+            SpreadJsObj.reloadColData(this.sheet, 2);
+        }
+        setJointAuditors(auditors) {
+            this.auditors = auditors;
+            this.selectJoint.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 });
+            }
+            $('#joint_table').html(html.join(''));
+            this._refreshJointTree();
+        }
+        loadJointData(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) {
+                self.loaded = true;
+                if (result.ledgerList) {
+                    self.tree.loadDatas(result.ledgerList);
+                    SpreadJsObj.loadSheetData(self.sheet, SpreadJsObj.DataType.Tree, self.tree);
+                }
+                self.setJointAuditors(result.jointAuditors);
+                if (self.auditors.length > 0) {
+                    $('#joint').modal('show');
+                } else {
+                    toastr.warning(`${audit_order}审未添加任何协同人,请先添加协同人再分配协同台账`);
+                }
+            });
+        }
+        getJointAuditLedgerData() {
+            this.auditors.forEach(a => { a.lid = []; });
+            for (const node of this.tree.nodes) {
+                if (node.audit_id > 0) {
+                    const relaAudit = this.auditors.find(x => { return x.audit_id === node.audit_id; });
+                    if (relaAudit) relaAudit.lid.push(node.ledger_id);
+                }
+            }
+            return this.auditors.map(a => {
+                return { id: a.id, audit_ledger_id: a.lid.join(',') };
+            });
+        }
+    }
+    const auditJoint = new AuditJoint();
+    $('body').on('click', '[name=joint-set]', function() {
+        auditJoint.loadJointData(this.getAttribute('sp_type'), this.getAttribute('audit_order'));
+    });
+
     $.subMenu({
     $.subMenu({
         menu: '#sub-menu', miniMenu: '#sub-mini-menu', miniMenuList: '#mini-menu-list',
         menu: '#sub-menu', miniMenu: '#sub-mini-menu', miniMenuList: '#mini-menu-list',
         toMenu: '#to-menu', toMiniMenu: '#to-mini-menu',
         toMenu: '#to-menu', toMiniMenu: '#to-mini-menu',

+ 2 - 0
app/router.js

@@ -189,6 +189,8 @@ module.exports = app => {
     app.post('/tender/:id/shenpi/audit/save', sessionAuth, tenderCheck, 'tenderController.saveShenpiAudit');
     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/ass/load', sessionAuth, tenderCheck, 'tenderController.loadAuditAss');
     app.post('/tender/:id/shenpi/save-sign', sessionAuth, tenderCheck, 'tenderController.saveCooperateSign');
     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/copy-setting', sessionAuth, tenderCheck, 'tenderController.copyTender');
     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/tourist/audit/save', sessionAuth, tenderCheck, uncheckTenderCheck, 'tenderController.saveTourist');
     app.post('/tender/:id/map/save', sessionAuth, tenderCheck, uncheckTenderCheck, 'tenderController.saveMap');
     app.post('/tender/:id/map/save', sessionAuth, tenderCheck, uncheckTenderCheck, 'tenderController.saveMap');

+ 1 - 1
app/service/settle_audit.js

@@ -437,7 +437,7 @@ module.exports = app => {
                 });
                 });
                 await this.ctx.service.noticeAgain.stopNoticeAgain(transaction, this.tableName, selfAudit.id);
                 await this.ctx.service.noticeAgain.stopNoticeAgain(transaction, this.tableName, selfAudit.id);
                 let auditStatus;
                 let auditStatus;
-                if (settle.curAuditors.length === 1 || selfAudit.audit_type !== auditType.key.and) {
+                if (settle.curAuditors.length === 1 || selfAudit.audit_type === auditType.key.or) {
                     // 或签更新他人审批状态
                     // 或签更新他人审批状态
                     if (selfAudit.audit_type === auditType.key.or) {
                     if (selfAudit.audit_type === auditType.key.or) {
                         const updateOther = [];
                         const updateOther = [];

+ 16 - 0
app/service/shenpi_audit.js

@@ -54,6 +54,13 @@ module.exports = app => {
             return await this.db.queryOne(sql, sqlParam);
             return await this.db.queryOne(sql, sqlParam);
         }
         }
 
 
+        async getJointAudit(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];
+            return await this.db.query(sql, sqlParam);
+        }
+
         async getAuditList(tid, type, status, group_id = 0) {
         async getAuditList(tid, type, status, group_id = 0) {
             const sql = 'SELECT sp.id, sp.audit_id, sp.audit_type, pa.name FROM ?? AS sp LEFT JOIN ?? AS pa ON sp.audit_id = pa.id' +
             const sql = 'SELECT sp.id, sp.audit_id, sp.audit_type, pa.name 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 sp.sp_group = ? ORDER BY sp.audit_order ASC, sp.id ASC';
                 ' WHERE sp.tid = ? AND sp.sp_type = ? AND sp.sp_status = ? AND sp.sp_group = ? ORDER BY sp.audit_order ASC, sp.id ASC';
@@ -480,6 +487,15 @@ module.exports = app => {
                 shenpiList.splice(yBIndex, 1);
                 shenpiList.splice(yBIndex, 1);
             }
             }
         }
         }
+
+        async saveJointAudit(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 '保存数据错误,请刷新页面后重试';
+            }
+            const updateData = data.map(x => { return { id: x.id, audit_ledger_id: x.audit_ledger_id }; });
+            if (updateData.length > 0) await this.db.updateRows(this.tableName, updateData);
+        }
     }
     }
 
 
     return ShenpiAudit;
     return ShenpiAudit;

+ 2 - 2
app/service/stage_audit.js

@@ -478,7 +478,7 @@ module.exports = app => {
                     sf_tp: sfPay.tp,
                     sf_tp: sfPay.tp,
                 };
                 };
                 this.ctx.stage.tp_history.push({ times, order: selfAudit.order, ...stageTp });
                 this.ctx.stage.tp_history.push({ times, order: selfAudit.order, ...stageTp });
-                if (audits.length === 1 || selfAudit.audit_type !== auditType.key.and) {
+                if (audits.length === 1 || selfAudit.audit_type === auditType.key.or) {
                     // 或签更新他人审批状态
                     // 或签更新他人审批状态
                     if (selfAudit.audit_type === auditType.key.or) {
                     if (selfAudit.audit_type === auditType.key.or) {
                         const updateOther = [];
                         const updateOther = [];
@@ -1976,7 +1976,7 @@ module.exports = app => {
                     newAuditors.push({
                     newAuditors.push({
                         tid: stage.tid, sid: stage.id, aid: auditor.audit_id,
                         tid: stage.tid, sid: stage.id, aid: auditor.audit_id,
                         times: stage.times, order: auditor.audit_order, status: auditConst.status.uncheck,
                         times: stage.times, order: auditor.audit_order, status: auditConst.status.uncheck,
-                        audit_type: auditor.audit_type, audit_order: auditor.audit_order,
+                        audit_type: auditor.audit_type, audit_order: auditor.audit_order, audit_ledger_id: auditor.audit_ledger_id,
                     });
                     });
                 }
                 }
                 if(newAuditors.length > 0) await transaction.insert(this.tableName, newAuditors);
                 if(newAuditors.length > 0) await transaction.insert(this.tableName, newAuditors);

+ 3 - 0
app/view/tender/shenpi.ejs

@@ -105,6 +105,9 @@
                                                 </div>
                                                 </div>
                                                 </span>
                                                 </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>
+                                                <% } %>
                                             </span>
                                             </span>
                                         </li>
                                         </li>
                                         <% } %>
                                         <% } %>

+ 32 - 0
app/view/tender/shenpi_modal.ejs

@@ -166,6 +166,38 @@
         </div>
         </div>
     </div>
     </div>
 </div>
 </div>
+<div class="modal fade" id="joint" data-backdrop="static">
+    <div class="modal-dialog modal-xl" role="document">
+        <div class="modal-content">
+            <div class="modal-header">
+                <h5 class="modal-title">协同审批</h5>
+            </div>
+            <div class="modal-body">
+                <div class="row">
+                    <div class="col-6">
+                        <div class="modal-height-500" style="overflow: auto;">
+                            <table class="table table-hover table-bordered">
+                                <thead class="text-center" >
+                                <tr><th>姓名</th><th>单位</th><th>协同处理</th></tr>
+                                </thead>
+                                <tbody id="joint_table">
+                                </tbody>
+                            </table>
+                        </div>
+                    </div>
+                    <div class="col-6">
+                        <div class="modal-height-500" style="overflow: auto;" id="joint-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>
+            </div>
+        </div>
+    </div>
+</div>
 <!--存为审批组-->
 <!--存为审批组-->
 <div class="modal fade" id="spzsave" data-backdrop="static">
 <div class="modal fade" id="spzsave" data-backdrop="static">
     <div class="modal-dialog" role="document">
     <div class="modal-dialog" role="document">

+ 5 - 0
sql/update.sql

@@ -445,6 +445,11 @@ ALTER TABLE `zh_budget_std`
 ADD COLUMN `ht_project_template_id` varchar(255) CHARACTER SET ascii COLLATE ascii_general_ci NOT NULL DEFAULT '' COMMENT '合同-项目合同模版-id列表(‘,’分隔)' AFTER `zb_bills_id`,
 ADD COLUMN `ht_project_template_id` varchar(255) CHARACTER SET ascii COLLATE ascii_general_ci NOT NULL DEFAULT '' COMMENT '合同-项目合同模版-id列表(‘,’分隔)' AFTER `zb_bills_id`,
 ADD COLUMN `ht_tender_template_id` varchar(255) CHARACTER SET ascii COLLATE ascii_general_ci NOT NULL DEFAULT '' COMMENT '合同-标段合同模版-id列表(‘,’分隔)' AFTER `ht_project_template_id`;
 ADD COLUMN `ht_tender_template_id` varchar(255) CHARACTER SET ascii COLLATE ascii_general_ci NOT NULL DEFAULT '' COMMENT '合同-标段合同模版-id列表(‘,’分隔)' AFTER `ht_project_template_id`;
 
 
+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`;
 
 
 -- update请放在最后
 -- update请放在最后