瀏覽代碼

变更方案会签或签及审批组功能

ellisran 1 年之前
父節點
當前提交
f35f1612b7

+ 122 - 68
app/controller/change_controller.js

@@ -2426,10 +2426,14 @@ module.exports = app => {
                         throw '验证码不正确!';
                     }
                 }
-                // 重新审批
-                const result = await ctx.service.changeProjectAudit.checkAgain(ctx.change);
-                if (!result) {
-                    throw '重新审批失败';
+                if ((ctx.change.finalAuditorIds.indexOf(ctx.session.sessionUser.accountId) >= 0) && ctx.change.status === audit.changeProject.status.checked) {
+                    // 重新审批
+                    const result = await ctx.service.changeProjectAudit.checkAgain(ctx.change);
+                    if (!result) {
+                        throw '重新审批失败';
+                    }
+                } else {
+                    throw '您无权进行该操作';
                 }
                 // ctx.redirect('/tender/' + changeData.tid + '/change/' + changeData.cid + '/info');
                 ctx.body = {
@@ -3223,23 +3227,6 @@ module.exports = app => {
         }
 
         /**
-         * 撤回审批
-         * @param ctx
-         * @return {Promise<void>}
-         */
-        async checkApplyAuditCancel(ctx) {
-            try {
-                if (!ctx.change.cancancel) throw '您无权进行该操作';
-
-                await ctx.service.changeApplyAudit.checkCancel(ctx.change);
-                ctx.body = { err: 0, url: ctx.request.header.referer, msg: '' };
-            } catch (err) {
-                this.log(err);
-                ctx.body = { err: 1, msg: err };
-            }
-        }
-
-        /**
          * 变更申请重新审批
          * @param {Object} ctx - egg全局变量
          * @return {void}
@@ -3247,8 +3234,8 @@ module.exports = app => {
         async checkApplyAgain(ctx) {
             try {
                 // 获取终审
-                const auditInfo = await this.ctx.service.changeApplyAudit.getAuditorByStatus(ctx.change.id, audit.changeApply.status.checked);
-                if (ctx.change.status !== audit.changeApply.status.checked || ctx.session.sessionUser.accountId !== auditInfo.aid) {
+                // const auditInfo = await this.ctx.service.changeApplyAudit.getAuditorByStatus(ctx.change.id, audit.changeApply.status.checked);
+                if (ctx.change.status !== audit.changeApply.status.checked) {
                     throw '您无权进行该操作';
                 }
                 // 判断是否被变更申请调用了,是则无法发起修订
@@ -3269,10 +3256,14 @@ module.exports = app => {
                         throw '验证码不正确!';
                     }
                 }
-                // 重新审批
-                const result = await ctx.service.changeApplyAudit.checkAgain(ctx.change);
-                if (!result) {
-                    throw '重新审批失败';
+                if ((ctx.change.finalAuditorIds.indexOf(ctx.session.sessionUser.accountId) >= 0) && ctx.change.status === audit.changeApply.status.checked) {
+                    // 重新审批
+                    const result = await ctx.service.changeApplyAudit.checkAgain(ctx.change);
+                    if (!result) {
+                        throw '重新审批失败';
+                    }
+                } else {
+                    throw '您无权进行该操作';
                 }
                 // ctx.redirect('/tender/' + changeData.tid + '/change/' + changeData.cid + '/info');
                 ctx.body = {
@@ -3387,7 +3378,10 @@ module.exports = app => {
             let page_total = 0;
             const tp = await ctx.service.changePlan.getTp(tender.id, status);
             for (const c of changes) {
-                c.curAuditor = await ctx.service.changePlanAudit.getAuditorByStatus(c.id, c.status, c.times);
+                c.curAuditors = await ctx.service.changePlanAudit.getAuditorsByStatus(c.id, c.status, c.times);
+                // if (c.status === audit.changePlan.status.checkNoPre) {
+                //     c.curAuditors2 = await ctx.service.changePlanAudit.getAuditorsByStatus(c.id, audit.changePlan.status.checking, c.times);
+                // }
                 page_total = ctx.helper.add(page_total, c.total_price);
             }
             const tender_userInfo = await ctx.service.projectAccount.getDataById(ctx.tender.data.user_id);
@@ -3464,6 +3458,7 @@ module.exports = app => {
                 auditConst: audit.changePlan,
                 ruleConst: codeRuleConst.measure,
                 changeConst,
+                auditType,
                 changeApplyList,
                 acLists,
                 page_total,
@@ -3506,6 +3501,25 @@ module.exports = app => {
         }
 
         /**
+         * 审批流程(Get)
+         * @param ctx
+         * @return {Promise<void>}
+         */
+        async changePlanAuditors(ctx) {
+            try {
+                const id = JSON.parse(ctx.request.body.data).id;
+                const tenderId = ctx.params.id;
+                const changeInfo = await ctx.service.changePlan.getDataById(id);
+                await ctx.service.changePlan.loadChangeUser(changeInfo);
+                await ctx.service.changePlan.loadChangeAuditViewData(changeInfo);
+                ctx.body = { err: 0, msg: '', data: changeInfo };
+            } catch (error) {
+                this.log(error);
+                ctx.body = { err: 1, msg: error.toString(), data: null };
+            }
+        }
+
+        /**
          * 新增变更方案 (Post)
          *
          * @param {Object} ctx - egg全局变量
@@ -3559,22 +3573,7 @@ module.exports = app => {
          * @private
          */
         async _getChangePlanAuditViewData(ctx) {
-            const auditConst = audit.changePlan;
-            const times = ctx.change.status === auditConst.status.checkNo || ctx.change.status === auditConst.status.revise ? ctx.change.times - 1 : ctx.change.times;
-            ctx.change.user = await ctx.service.projectAccount.getAccountInfoById(ctx.change.uid);
-            ctx.change.auditHistory = [];
-            if (times >= 1) {
-                for (let i = 1; i <= times; i++) {
-                    ctx.change.auditHistory.push(await ctx.service.changePlanAudit.getAuditors(ctx.change.id, i));
-                }
-            }
-            // 获取审批流程中左边列表
-            ctx.change.auditors2 = (ctx.change.status === auditConst.status.checkNo || ctx.change.status === auditConst.status.revise) && ctx.change.uid !== ctx.session.sessionUser.accountId ?
-                await ctx.service.changePlanAudit.getAuditorsWithOwner(ctx.change.id, times) :
-                await ctx.service.changePlanAudit.getAuditorsWithOwner(ctx.change.id, ctx.change.times);
-            if (ctx.change.status === auditConst.status.uncheck || ctx.change.status === auditConst.status.checkNo || ctx.change.status === auditConst.status.revise) {
-                ctx.change.auditorList = await ctx.service.changePlanAudit.getAuditors(ctx.change.id, ctx.change.times);
-            }
+            await ctx.service.changePlan.loadChangeAuditViewData(ctx.change);
         }
 
         async planInformation(ctx) {
@@ -3587,13 +3586,19 @@ module.exports = app => {
                 // 获取清单列表
                 const changeList = await ctx.service.changePlanList.getList(ctx.change.id);
                 if (ctx.change.status === audit.changePlan.status.checking || ctx.change.status === audit.changePlan.status.checked) {
-                    const listAudits = await ctx.service.changePlanAudit.getAuditGroupByList(ctx.change.id, ctx.change.times);
-                    ctx.change.listAudits = listAudits;
+                    // const listAudits = await ctx.service.changePlanAudit.getAuditGroupByList(ctx.change.id, ctx.change.times);
+                    // ctx.change.listAudits = listAudits;
                     for (const cl of changeList) {
                         const audit_amount = cl.audit_amount !== null && cl.audit_amount !== '' ? cl.audit_amount.split(',') : '';
                         // 清单表页赋值
-                        for (const [index, au] of listAudits.entries()) {
-                            cl['audit_amount_' + au.aid] = ctx.change.shenpiPower && au.aid === ctx.session.sessionUser.accountId ? cl.spamount : (audit_amount[index] ? parseFloat(audit_amount[index]) : null);
+                        for (const au in ctx.change.userGroups) {
+                            if (ctx.change.userGroups[au][0].audit_order !== 0) {
+                                cl['audit_amount_' + ctx.change.userGroups[au][0].audit_order] =
+                                    (ctx.change.userGroups[au][0].audit_type === auditType.key.and &&
+                                        ctx.helper._.findIndex(ctx.change.userGroups[au], { uid: ctx.session.sessionUser.accountId, status: audit.changePlan.status.checked }) !== -1) ||
+                                    (ctx.change.shenpiPower && ctx.helper._.findIndex(ctx.change.userGroups[au], { uid: ctx.session.sessionUser.accountId }) !== -1) ?
+                                        cl.spamount : (audit_amount[au - 1] !== undefined ? parseFloat(audit_amount[au - 1]) : null);
+                            }
                         }
                     }
                 }
@@ -3612,6 +3617,8 @@ module.exports = app => {
                     fileList,
                     whiteList,
                     authMobile: auth_mobile,
+                    auditType,
+                    shenpiConst,
                     tpUnit: ctx.change.decimal ? ctx.change.decimal.tp : ctx.tender.info.decimal.tp,
                     upUnit: ctx.change.decimal ? ctx.change.decimal.up : ctx.tender.info.decimal.up,
                     changeUnits: changeConst.units,
@@ -3620,20 +3627,24 @@ module.exports = app => {
                     jsFiles: this.app.jsFiles.common.concat(this.app.jsFiles.change.plan_information),
                     preUrl: '/tender/' + ctx.tender.id + '/change/plan/' + ctx.change.id + '/information',
                 };
-                if ((ctx.change.status === audit.changePlan.status.uncheck || ctx.change.status === audit.changePlan.status.checkNo || ctx.change.status === audit.changePlan.status.revise) && (ctx.session.sessionUser.accountId === ctx.change.uid || ctx.tender.isTourist)) {
+                // if ((ctx.change.status === audit.changePlan.status.uncheck || ctx.change.status === audit.changePlan.status.checkNo || ctx.change.status === audit.changePlan.status.revise) && (ctx.session.sessionUser.accountId === ctx.change.uid || ctx.tender.isTourist)) {
                     // data.accountGroup = accountGroup;
                     // 获取所有项目参与者
-                    const accountList = await ctx.service.projectAccount.getAllDataByCondition({
-                        where: { project_id: ctx.session.sessionProject.id, enable: 1 },
-                        columns: ['id', 'name', 'company', 'role', 'enable', 'is_admin', 'account_group', 'mobile'],
-                    });
-                    renderData.accountList = accountList;
-                    const unitList = await ctx.service.constructionUnit.getAllDataByCondition({ where: { pid: ctx.session.sessionProject.id } });
-                    renderData.accountGroup = unitList.map(item => {
-                        const groupList = accountList.filter(item1 => item1.company === item.name);
-                        return { groupName: item.name, groupList };
-                    });
+                const accountList = await ctx.service.projectAccount.getAllDataByCondition({
+                    where: { project_id: ctx.session.sessionProject.id, enable: 1 },
+                    columns: ['id', 'name', 'company', 'role', 'enable', 'is_admin', 'account_group', 'mobile'],
+                });
+                renderData.accountList = accountList;
+                const unitList = await ctx.service.constructionUnit.getAllDataByCondition({ where: { pid: ctx.session.sessionProject.id } });
+                renderData.accountGroup = unitList.map(item => {
+                    const groupList = accountList.filter(item1 => item1.company === item.name);
+                    return { groupName: item.name, groupList };
+                });
+                // 获取固定审批流列表
+                if (ctx.tender.info.shenpi.change === shenpiConst.sp_status.gdspl) {
+                    renderData.spGroupList = await ctx.service.shenpiGroup.getGroupListByChangeType(ctx.tender.id, shenpiConst.sp_type.change, 'changePlan');
                 }
+                // }
                 await this.layout('change/plan_information.ejs', renderData, 'change/plan_information_modal.ejs');
             } catch (err) {
                 this.log(err);
@@ -3641,6 +3652,20 @@ module.exports = app => {
             }
         }
 
+        async changePlanSpGroup(ctx) {
+            try {
+                const data = JSON.parse(ctx.request.body.data);
+                const result = await ctx.service.changePlanAudit.changeSpGroup(ctx.change, data.sp_group);
+                if (!result) {
+                    throw '切换审批组失败';
+                }
+                const auditors = await ctx.service.changePlanAudit.getUserGroup(ctx.change.id, ctx.change.times);
+                ctx.body = { err: 0, msg: '', data: auditors };
+            } catch (err) {
+                ctx.body = { err: 1, msg: err.toString(), data: null };
+            }
+        }
+
         // 审批相关
         /**
          * 添加审批人
@@ -3676,7 +3701,7 @@ module.exports = app => {
                     throw '添加审核人失败';
                 }
 
-                const auditors = await ctx.service.changePlanAudit.getAuditorsWithOwner(ctx.change.id, ctx.change.times);
+                const auditors = await ctx.service.changePlanAudit.getUserGroup(ctx.change.id, ctx.change.times);
                 ctx.body = { err: 0, msg: '', data: auditors };
             } catch (err) {
                 this.log(err);
@@ -3709,6 +3734,31 @@ module.exports = app => {
             }
         }
 
+        async savePlanAudit(ctx) {
+            try {
+                // if (ctx.change.revising) {
+                //     throw '台账修订中,请勿修改提交期数据';
+                // }
+                const data = JSON.parse(ctx.request.body.data);
+                if (ctx.session.sessionUser.is_admin && ctx.change.status !== audit.change.status.checked) {
+                    await ctx.service.changePlanAudit.saveAudit(ctx.change.id, ctx.change.times, ctx.change.sp_group, data);
+                    const auditors = await ctx.service.changePlanAudit.getUniqUserGroup(ctx.change.id, ctx.change.times);
+                    ctx.body = { err: 0, msg: '', data: auditors };
+                } else {
+                    throw '您无权进行该操作';
+                }
+            } catch (err) {
+                this.log(err);
+                // ctx.session.postError = err.toString();
+                // ctx.redirect(ctx.request.header.referer);
+                ctx.body = {
+                    err: 1,
+                    // url: ctx.request.header.referer,
+                    msg: err,
+                };
+            }
+        }
+
         /**
          * 上传附件
          * @param {*} ctx 上下文
@@ -3894,9 +3944,9 @@ module.exports = app => {
             try {
                 const auditConst = audit.changePlan;
                 if (!ctx.change || ctx.change.status !== auditConst.status.checking) {
-                    throw '当前材料调差期数据有误';
+                    throw '当前变更方案数据有误';
                 }
-                if (!ctx.change.curAuditor || ctx.change.curAuditor.aid !== ctx.session.sessionUser.accountId) {
+                if (ctx.change.curAuditorIds.length === 0 || ctx.change.curAuditorIds.indexOf(ctx.session.sessionUser.accountId) === -1) {
                     throw '您无权进行该操作';
                 }
                 const data = {
@@ -4027,8 +4077,8 @@ module.exports = app => {
         async checkPlanAgain(ctx) {
             try {
                 // 获取终审
-                const auditInfo = await this.ctx.service.changePlanAudit.getAuditorByStatus(ctx.change.id, audit.changePlan.status.checked);
-                if (ctx.change.status !== audit.changePlan.status.checked || ctx.session.sessionUser.accountId !== auditInfo.aid) {
+                // const auditInfo = await this.ctx.service.changePlanAudit.getAuditorByStatus(ctx.change.id, audit.changePlan.status.checked);
+                if (ctx.change.status !== audit.changePlan.status.checked) {
                     throw '您无权进行该操作';
                 }
                 // 判断是否被变更申请调用了,是则无法发起修订
@@ -4049,10 +4099,14 @@ module.exports = app => {
                         throw '验证码不正确!';
                     }
                 }
-                // 重新审批
-                const result = await ctx.service.changePlanAudit.checkAgain(ctx.change);
-                if (!result) {
-                    throw '重新审批失败';
+                if ((ctx.change.finalAuditorIds.indexOf(ctx.session.sessionUser.accountId) >= 0) && ctx.change.status === audit.changePlan.status.checked) {
+                    // 重新审批
+                    const result = await ctx.service.changePlanAudit.checkAgain(ctx.change);
+                    if (!result) {
+                        throw '重新审批失败';
+                    }
+                } else {
+                    throw '您无权进行该操作';
                 }
                 // ctx.redirect('/tender/' + changeData.tid + '/change/' + changeData.cid + '/info');
                 ctx.body = {

+ 12 - 8
app/middleware/change_apply_audit_check.js

@@ -68,15 +68,19 @@ module.exports = options => {
                     }
                 } else if (shenpi_status === shenpiConst.sp_status.gdzs) {
                     const shenpiInfo = yield this.service.shenpiAudit.getDataByCondition({ tid: this.tender.id, sp_type: shenpiConst.sp_type.change, sp_status: shenpi_status });
-                    // 判断最后一个id是否与固定终审id相同,不同则删除原审批流中如果存在的id和添加终审
-                    const lastAuditors = auditList.filter(x => { return x.order === auditList.length - 1; });
-                    if (shenpiInfo && (lastAuditors.length === 0 || (lastAuditors.length > 1 || shenpiInfo.audit_id !== lastAuditors[0].aid))) {
-                        yield this.service.changeApplyAudit.updateLastAudit(change, auditList, shenpiInfo.audit_id);
-                        yield this.service.changeApply.loadChangeUser(change);
-                        yield this.service.changeApply.doCheckChangeCanCancel(change);
-                    } else if (!shenpiInfo) {
-                        // 不存在终审人的状态下这里恢复为授权审批人
+                    if (!shenpiInfo || (shenpiInfo && shenpiInfo.audit_id === change.uid)) {
+                        // 不存在终审人 或 存在终审但与原报相同时, 这里恢复为授权审批人
                         this.tender.info.shenpi.change = shenpiConst.sp_status.sqspr;
+                    } else {
+                        // 判断最后一个id是否与固定终审id相同,不同则删除原审批流中如果存在的id和添加终审
+                        const lastAuditors = auditList.filter(x => {
+                            return x.order === auditList.length - 1;
+                        });
+                        if (shenpiInfo && (lastAuditors.length === 0 || (lastAuditors.length > 1 || shenpiInfo.audit_id !== lastAuditors[0].aid))) {
+                            yield this.service.changeApplyAudit.updateLastAudit(change, auditList, shenpiInfo.audit_id);
+                            yield this.service.changeApply.loadChangeUser(change);
+                            yield this.service.changeApply.doCheckChangeCanCancel(change);
+                        }
                     }
                 }
             }

+ 4 - 4
app/middleware/change_apply_check.js

@@ -28,7 +28,7 @@ module.exports = options => {
             }
             const caid = this.params.caid || this.request.body.caid;
             if (!caid) {
-                throw '您访问的变更立项不存在';
+                throw '您访问的变更申请不存在';
             }
             const change = yield this.service.changeApply.getDataById(caid);
             if (!change) throw '变更申请数据有误';
@@ -58,15 +58,15 @@ module.exports = options => {
                     throw '您无权查看该数据';
                 }
                 change.filePermission = true;
+            } else if (this.tender.isTourist) {
+                change.curTimes = change.times;
+                change.filePermission = this.tender.touristPermission.file || auditorIds.indexOf(accountId) !== -1;
             } else if (shareIds.indexOf(accountId) !== -1 || (permission !== null && permission.tender !== undefined && permission.tender.indexOf('2') !== -1)) { // 分享人
                 if (change.status === status.uncheck) {
                     throw '您无权查看该数据';
                 }
                 change.curTimes = change.status === status.checkNo || change.status === status.revise ? change.times - 1 : change.times;
                 change.filePermission = false;
-            } else if (this.tender.isTourist) {
-                change.curTimes = change.times;
-                change.filePermission = this.tender.touristPermission.file || auditorIds.indexOf(accountId) !== -1;
             } else { // 其他不可见
                 throw '您无权查看该数据';
             }

+ 103 - 0
app/middleware/change_plan_audit_check.js

@@ -0,0 +1,103 @@
+'use strict';
+
+/**
+ *
+ *
+ * @author Ellisran
+ * @date 2020/10/15
+ * @version
+ */
+
+const status = require('../const/audit').changePlan.status;
+const shenpiConst = require('../const/shenpi');
+const _ = require('lodash');
+
+module.exports = options => {
+    /**
+     * 标段校验 中间件
+     * 1. 读取标段数据(包括属性)
+     * 2. 检验用户是否可见标段(不校验具体权限)
+     *
+     * @param {function} next - 中间件继续执行的方法
+     * @return {void}
+     */
+    return function* changePlanAuditCheck(next) {
+        try {
+            // 获取revise
+            const id = this.params.cpid || this.request.body.cpid;
+            if (!id) {
+                throw '您访问的变更立项不存在';
+            }
+            // const change = yield this.service.change.getDataByCondition({ cid });
+            if (!this.change) {
+                const change = yield this.service.changePlan.getDataById(id);
+                if (!change) throw '变更立项数据有误';
+                yield this.service.changePlan.loadChangeUser(change);
+                this.change = change;
+            }
+            const change = this.change;
+            if ((change.status === status.uncheck || change.status === status.checkNo || change.status === status.revise) && this.tender.info.shenpi.change !== shenpiConst.sp_status.sqspr) {
+                const shenpi_status = this.tender.info.shenpi.change;
+                // 进一步比较审批流是否与审批流程设置的相同,不同则替换为固定审批流或固定的终审
+                const auditList = yield this.service.changePlanAudit.getAllDataByCondition({ where: { cpid: change.id, times: change.times }, orders: [['order', 'asc']] });
+                if (shenpi_status === shenpiConst.sp_status.gdspl) {
+                    // 判断并获取审批组
+                    const group = yield this.service.shenpiGroup.getSelectGroupByChangeType(this.tender.id, shenpiConst.sp_type.change, 'changePlan', change.sp_group);
+                    if ((group && change.sp_group !== group.id) || (!group && change.sp_group !== 0)) {
+                        change.sp_group = group ? group.id : 0;
+                        yield this.service.changePlan.defaultUpdate({ id: change.id, sp_group: change.sp_group });
+                    }
+                    const condition = { tid: this.tender.id, sp_type: shenpiConst.sp_type.change, sp_status: shenpi_status, sp_group: change.sp_group };
+                    const shenpiList = yield this.service.shenpiAudit.getAllDataByCondition({ where: condition, orders: [['audit_order', 'asc']] });
+                    yield this.service.shenpiAudit.noYbShenpiList(change.uid, shenpiList);
+                    // 判断2个id数组是否相同,不同则删除原审批流,切换成固定的审批流
+                    let sameAudit = auditList.length === shenpiList.length;
+                    if (sameAudit) {
+                        for (const audit of auditList) {
+                            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) {
+                                sameAudit = false;
+                                break;
+                            }
+                        }
+                    }
+                    if (!sameAudit) {
+                        yield this.service.changePlanAudit.updateNewAuditList(change, shenpiList);
+                        yield this.service.changePlan.loadChangeUser(change);
+                        yield this.service.changePlan.doCheckChangeCanCancel(change);
+                    }
+                } else if (shenpi_status === shenpiConst.sp_status.gdzs) {
+                    const shenpiInfo = yield this.service.shenpiAudit.getDataByCondition({ tid: this.tender.id, sp_type: shenpiConst.sp_type.change, sp_status: shenpi_status });
+                    if (!shenpiInfo || (shenpiInfo && shenpiInfo.audit_id === change.uid)) {
+                        // 不存在终审人 或 存在终审但与原报相同时, 这里恢复为授权审批人
+                        this.tender.info.shenpi.change = shenpiConst.sp_status.sqspr;
+                    } else {
+                        // 判断最后一个id是否与固定终审id相同,不同则删除原审批流中如果存在的id和添加终审
+                        const lastAuditors = auditList.filter(x => { return x.order === auditList.length - 1; });
+                        if (shenpiInfo && (lastAuditors.length === 0 || (lastAuditors.length > 1 || shenpiInfo.audit_id !== lastAuditors[0].aid))) {
+                            yield this.service.changePlanAudit.updateLastAudit(change, auditList, shenpiInfo.audit_id);
+                            yield this.service.changePlan.loadChangeUser(change);
+                            yield this.service.changePlan.doCheckChangeCanCancel(change);
+                        }
+                    }
+                }
+            }
+            yield next;
+        } catch (err) {
+            console.log(err);
+            // 输出错误到日志
+            if (err.stack) {
+                this.logger.error(err);
+            } else {
+                this.getLogger('fail').info(JSON.stringify({
+                    error: err,
+                    project: this.session.sessionProject,
+                    user: this.session.sessionUser,
+                    body: this.session.body,
+                }));
+            }
+            // 重定向值标段管理
+            this.redirect(this.request.headers.referer);
+        }
+    };
+};

+ 10 - 12
app/middleware/change_plan_check.js

@@ -31,30 +31,26 @@ module.exports = options => {
                 throw '您访问的变更方案不存在';
             }
             const change = yield this.service.changePlan.getDataById(cpid);
+            if (!change) throw '变更方案数据有误';
             // 读取原报、审核人数据
-            change.auditors = yield this.service.changePlanAudit.getAuditors(change.id, change.times);
-            change.curAuditor = yield this.service.changePlanAudit.getCurAuditor(change.id, change.times);
+            yield this.service.changePlan.loadChangeUser(change);
             // decimal小数位设置
             change.decimal = change.decimal ? JSON.parse(change.decimal) : { tp: this.tender.info.decimal.tp, up: this.tender.info.decimal.up, precision: this.tender.info.precision };
 
-            if (!change) throw '变更令数据有误';
             // 权限相关
             // todo 校验权限 (标段参与人、分享)
             const accountId = this.session.sessionUser.accountId,
-                auditorIds = _.map(change.auditors, 'aid'),
                 shareIds = [];
+            const permission = this.session.sessionUser.permission;
             if (accountId === change.uid) { // 原报
                 change.curTimes = change.times;
                 change.filePermission = true;
-            } else if (this.tender.isTourist) {
-                change.curTimes = change.times;
-                change.filePermission = this.tender.touristPermission.file || auditorIds.indexOf(accountId) !== -1;
-            } else if (auditorIds.indexOf(accountId) !== -1) { // 审批人
+            } else if (change.auditorIds.indexOf(accountId) !== -1) { // 审批人
                 if (change.status === status.uncheck) {
                     throw '您无权查看该数据';
                 }
                 // change.readOnly = change.status !== status.checking || accountId !== change.curAuditor.aid;
-                change.curTimes = change.status === status.checkNo ? change.times - 1 : change.times;
+                change.curTimes = change.status === status.checkNo || change.status === status.revise ? change.times - 1 : change.times;
                 change.filePermission = true;
             } else if ((change.status === status.checkNo || change.status === status.revise) && change.uid !== accountId) {
                 const preAuditors = yield this.service.changePlanAudit.getAuditors(change.id, change.times - 1);
@@ -63,7 +59,10 @@ module.exports = options => {
                     throw '您无权查看该数据';
                 }
                 change.filePermission = true;
-            } else if (shareIds.indexOf(accountId) !== -1) { // 分享人
+            } else if (this.tender.isTourist) {
+                change.curTimes = change.times;
+                change.filePermission = this.tender.touristPermission.file || change.auditorIds.indexOf(accountId) !== -1;
+            } else if (shareIds.indexOf(accountId) !== -1 || (permission !== null && permission.tender !== undefined && permission.tender.indexOf('2') !== -1)) { // 分享人
                 if (change.status === status.uncheck) {
                     throw '您无权查看该数据';
                 }
@@ -75,10 +74,9 @@ module.exports = options => {
             }
             // 调差的readOnly 指表格和页面只能看不能改,和审批无关
             change.readOnly = !((change.status === status.uncheck || change.status === status.checkNo || change.status === status.revise) && accountId === change.uid);
-            change.shenpiPower = change.status === status.checking && change.curAuditor.aid === accountId;
+            change.shenpiPower = change.status === status.checking && change.curAuditorIds.indexOf(accountId) !== -1;
             this.change = change;
             yield this.service.changePlan.doCheckChangeCanCancel(this.change);
-            console.log(this.change.cancancel);
             yield next;
         } catch (err) {
             console.log(err);

+ 10 - 8
app/middleware/change_project_audit_check.js

@@ -68,15 +68,17 @@ module.exports = options => {
                     }
                 } else if (shenpi_status === shenpiConst.sp_status.gdzs) {
                     const shenpiInfo = yield this.service.shenpiAudit.getDataByCondition({ tid: this.tender.id, sp_type: shenpiConst.sp_type.change, sp_status: shenpi_status });
-                    // 判断最后一个id是否与固定终审id相同,不同则删除原审批流中如果存在的id和添加终审
-                    const lastAuditors = auditList.filter(x => { return x.order === auditList.length - 1; });
-                    if (shenpiInfo && (lastAuditors.length === 0 || (lastAuditors.length > 1 || shenpiInfo.audit_id !== lastAuditors[0].aid))) {
-                        yield this.service.changeProjectAudit.updateLastAudit(change, auditList, shenpiInfo.audit_id);
-                        yield this.service.changeProject.loadChangeUser(change);
-                        yield this.service.changeProject.doCheckChangeCanCancel(change);
-                    } else if (!shenpiInfo) {
-                        // 不存在终审人的状态下这里恢复为授权审批人
+                    if (!shenpiInfo || (shenpiInfo && shenpiInfo.audit_id === change.uid)) {
+                        // 不存在终审人 或 存在终审但与原报相同时, 这里恢复为授权审批人
                         this.tender.info.shenpi.change = shenpiConst.sp_status.sqspr;
+                    } else {
+                        // 判断最后一个id是否与固定终审id相同,不同则删除原审批流中如果存在的id和添加终审
+                        const lastAuditors = auditList.filter(x => { return x.order === auditList.length - 1; });
+                        if (shenpiInfo && (lastAuditors.length === 0 || (lastAuditors.length > 1 || shenpiInfo.audit_id !== lastAuditors[0].aid))) {
+                            yield this.service.changeProjectAudit.updateLastAudit(change, auditList, shenpiInfo.audit_id);
+                            yield this.service.changeProject.loadChangeUser(change);
+                            yield this.service.changeProject.doCheckChangeCanCancel(change);
+                        }
                     }
                 }
             }

+ 3 - 3
app/middleware/change_project_check.js

@@ -59,15 +59,15 @@ module.exports = options => {
                     throw '您无权查看该数据';
                 }
                 change.filePermission = true;
+            } else if (this.tender.isTourist) {
+                change.curTimes = change.times;
+                change.filePermission = this.tender.touristPermission.file || change.auditorIds.indexOf(accountId) !== -1;
             } else if (shareIds.indexOf(accountId) !== -1 || (permission !== null && permission.tender !== undefined && permission.tender.indexOf('2') !== -1)) { // 分享人
                 if (change.status === status.uncheck) {
                     throw '您无权查看该数据';
                 }
                 change.curTimes = change.status === status.back || change.status === status.revise ? change.times - 1 : change.times;
                 change.filePermission = false;
-            } else if (this.tender.isTourist) {
-                change.curTimes = change.times;
-                change.filePermission = this.tender.touristPermission.file || change.auditorIds.indexOf(accountId) !== -1;
             } else { // 其他不可见
                 throw '您无权查看该数据';
             }

+ 0 - 7
app/public/js/change_apply.js

@@ -134,13 +134,6 @@ class codeRuleSet {
         });
     }
 }
-/**
- * 期计量 - 期列表页面 js
- *
- * @author Mai
- * @date 2018/12/7
- * @version
- */
 const getGroupAuditHtml = function (group) {
     return group.map(u => { return `<small class="d-inline-block text-dark mx-1" title="${u.role}" data-auditorId="${u.aid}">${u.name}</small>`; }).join('');
 };

+ 4 - 4
app/public/js/change_apply_audit.js

@@ -191,11 +191,11 @@ function makeSpHtml(datas) {
 // 检查上报情况
 function checkAuditorFrom () {
     if ($('#auditors li').length === 0) {
-        // if(shenpi_status === shenpiConst.sp_status.gdspl) {
-        //     toastr.error('请联系管理员添加审批人');
-        // } else {
+        if(shenpi_status === shenpiConst.sp_status.gdspl) {
+            toastr.error('请联系管理员添加审批人');
+        } else {
             toastr.error('请先选择审批人,再上报数据');
-        // }
+        }
         return false;
     }
     let flag = false;

+ 169 - 0
app/public/js/change_plan.js

@@ -134,8 +134,177 @@ class codeRuleSet {
         });
     }
 }
+const getGroupAuditHtml = function (group) {
+    return group.map(u => { return `<small class="d-inline-block text-dark mx-1" title="${u.role}" data-auditorId="${u.aid}">${u.name}</small>`; }).join('');
+};
 
+const getAuditTypeHtml = function (type) {
+    if (type === auditType.key.common) return '';
+    return `<div class="li-subscript"><span class="badge badge-pill badge-${auditType.info[type].class} p-1 badge-bg-small"><small>${auditType.info[type].short}</small></span></div>`;
+};
+
+const getAuditTypeText = function (type) {
+    if (type === auditType.key.common) return '';
+    return `<span class="text-${auditType.info[type].class}">${auditType.info[type].long}</span>`;
+};
 $(document).ready(() => {
+
+    $('#audit-list').on('click', 'a', function() {
+        const type = $(this).data('target')
+        const auditCard = $(this).parent().parent()
+        if (type === 'show') {
+            $(this).data('target', 'hide')
+            auditCard.find('.fold-card').slideDown('swing', () => {
+                auditCard.find('#end-target').text($(this).data('idx') + '#')
+                auditCard.find('#fold-btn').text('收起历史审核记录')
+            })
+        } else {
+            $(this).data('target', 'show')
+            auditCard.find('.fold-card').slideUp('swing', () => {
+                auditCard.find('#end-target').text('1#')
+                auditCard.find('#fold-btn').text('展开历史审核记录')
+            })
+        }
+    });
+
+    // 获取审批流程
+    $('a[data-target="#sp-list" ]').on('click', function () {
+        const data = {
+            id: $(this).attr('c-id'),
+        };
+        postData('/tender/' + tenderId + '/change/plan/auditors', data, function (result) {
+            const { auditHistory, auditors2, user } = result;
+            let auditorsHTML = [];
+            auditors2.forEach((group, idx) => {
+                if (idx === 0) {
+                    auditorsHTML.push(`<li class="list-group-item d-flex justify-content-between align-items-center">
+                        <span class="mr-1"><i class="fa fa fa-play-circle fa-rotate-90"></i></span>
+                    <span class="text-muted">${getGroupAuditHtml(group)}</span>
+                    <span class="badge badge-light badge-pill ml-auto"><small>原报</small></span>
+                    </li>`);
+                } else if(idx === auditors2.length -1 && idx !== 0) {
+                    auditorsHTML.push(`<li class="list-group-item d-flex justify-content-between align-items-center">
+                        <span class="mr-1"><i class="fa fa fa-stop-circle fa-rotate-90"></i></span>
+                    <span class="text-muted">${getGroupAuditHtml(group)}</span>
+                    <div class="d-flex ml-auto">
+                    ${getAuditTypeHtml(group[0].audit_type)}
+                    <span class="badge badge-light badge-pill ml-auto"><small>终审</small></span>
+                    </div>
+                    </li>`);
+                } else {
+                    auditorsHTML.push(`<li class="list-group-item d-flex justify-content-between align-items-center">
+                        <span class="mr-1"><i class="fa fa fa-chevron-circle-down"></i></span>
+                    <span class="text-muted">${getGroupAuditHtml(group)}</span>
+                    <div class="d-flex ml-auto">
+                    ${getAuditTypeHtml(group[0].audit_type)}
+                    <span class="badge badge-light badge-pill"><small>${transFormToChinese(idx)}审</small></span>
+                    </div>
+                    </li>`);
+                }
+            });
+            $('#auditor-list').empty();
+            $('#auditor-list').append(auditorsHTML.join(''));
+
+            let historyHTML = [];
+            auditHistory.forEach((his, idx) => {
+                if (idx === auditHistory.length - 1 && auditHistory.length !== 1) {
+                    historyHTML.push(`<div class="text-right"><a href="javascript: void(0);" id="fold-btn" data-target="show">展开历史审批流程</a></div>`);
+                }
+                historyHTML.push(`<div class="${idx < auditHistory.length - 1 ? 'fold-card' : ''}">`);
+                historyHTML.push(`<div class="text-center text-muted">${idx+1}#</div>`);
+                historyHTML.push(`<ul class="timeline-list list-unstyled mt-2 ${ idx === auditHistory.length - 1 && auditHistory.length !== 1 ? 'last-auditor-list' : '' }">`);
+                his.forEach((group, index) => {
+                    if (index === 0) {
+                        historyHTML.push(`<li class="timeline-list-item pb-2">
+                                            <div class="timeline-item-date">
+                                                ${group.beginYear}
+                                                <span>${group.beginDate}</span>
+                                                <span>${group.beginTime}</span>
+                                            </div>
+                                            <div class="timeline-item-tail"></div>
+                                            <div class="timeline-item-icon bg-success text-light"><i class="fa fa-caret-down"></i></div>
+                                            <div class="timeline-item-content">
+                                                <div class="py-1">
+                                                    <span class="text-black-50">原报</span>
+                                                    <span class="pull-right text-success">${idx !== 0 ? '重新' : '' }上报审批</span>
+                                                </div>
+                                                <div class="card">
+                                                    <div class="card-body px-3 py-0">
+                                                        <div class="card-text p-2 py-3 row">
+                                                            <div class="col">
+                                                                <span class="h6">${user.name}</span>
+                                                                <span class="text-muted ml-1">${user.role}</span>
+                                                            </div>
+                                                            <div class="col">
+                                                                <span class="pull-right text-success"><i class="fa fa-check-circle"></i></span>
+                                                            </div>
+                                                        </div>
+                                                    </div>
+                                                </div>
+                                            </div>
+                                        </li>`);
+                    }
+                    historyHTML.push(`<li class="timeline-list-item pb-2 ${ group.status === auditConst.status.uncheck && idx === auditHistory.length - 1 && auditHistory.length !== 1 ? 'is_uncheck' : ''}">`);
+                    if (group.endYear) {
+                        historyHTML.push(`<div class="timeline-item-date">${group.endYear}<span>${group.endDate}</span><span>${group.endTime}</span></div>`);
+                    }
+                    if (index < his.length - 1) {
+                        historyHTML.push('<div class="timeline-item-tail"></div>');
+                    }
+                    if (group.status === auditConst.status.checked || group.status === auditConst.status.cancelRevise) {
+                        historyHTML.push('<div class="timeline-item-icon bg-success text-light"><i class="fa fa-check"></i></div>');
+                    } else if (group.status === auditConst.status.checkNo || group.status === auditConst.status.revise || group.status === auditConst.status.checkCancel) {
+                        historyHTML.push('<div class="timeline-item-icon bg-warning text-light"><i class="fa fa-level-up"></i></div>');
+                    } else if (group.status === auditConst.status.checking) {
+                        historyHTML.push('<div class="timeline-item-icon bg-warning text-light"><i class="fa fa-ellipsis-h"></i></div>');
+                    } else if(group.status === auditConst.status.checkAgain) {
+                        historyHTML.push('<div class="timeline-item-icon bg-warning text-light"><i class="fa fa-check"></i></div>');
+                    } else {
+                        historyHTML.push('<div class="timeline-item-icon bg-secondary text-light"></div>');
+                    }
+
+                    historyHTML.push('<div class="timeline-item-content">');
+                    historyHTML.push('<div class="py-1">');
+                    const statuStr = group.status !== auditConst.status.uncheck ?
+                        `<span class="pull-right ${auditConst.statusClass[group.status]}">${auditConst.statusString[group.status]}</span>` : '';
+                    historyHTML.push(`
+                    <span class="text-black-50">
+                    ${ group.audit_order === 0 ? '原报' : !group.is_final ? group.audit_order + '审' : '终审' } ${getAuditTypeText(group.audit_type)}
+                    </span>
+                    ${statuStr}`);
+                    historyHTML.push('</div>');
+                    historyHTML.push('<div class="card"><div class="card-body px-3 py-0">');
+                    for (const [i, auditor] of group.auditors.entries()) {
+                        historyHTML.push(`<div class="card-text p-2 py-3 row ${ ( i > 0 ? 'border-top' : '') }">`);
+                        historyHTML.push(`<div class="col"><span class="h6">${auditor.name}</span><span class="text-muted ml-1">${auditor.role}</span></div>`);
+                        historyHTML.push('<div class="col">');
+                        if (auditor.status === auditConst.status.checked || group.status === auditConst.status.cancelRevise) {
+                            historyHTML.push('<span class="pull-right text-success"><i class="fa fa-check-circle"></i></span>');
+                        } else if (auditor.status === auditConst.status.checkNo || group.status === auditConst.status.revise || auditor.status === auditConst.status.checkCancel) {
+                            historyHTML.push('<span class="pull-right text-warning"><i class="fa fa-share-square fa-rotate-270"></i></span>');
+                        } else if (auditor.status === auditConst.status.checking) {
+                            historyHTML.push('<span class="pull-right text-warning"><i class="fa fa-commenting"></i></span>');
+                        } else if (auditor.status === auditConst.status.checkAgain) {
+                            historyHTML.push('<span class="pull-right text-warning"><i class="fa fa-check"></i></span>');
+                        }
+                        historyHTML.push('</div>');
+                        if (auditor.opinion) {
+                            historyHTML.push(`<div class="col-12 py-1 bg-light"><i class="fa fa-commenting-o mr-1"></i>${auditor.opinion}</div>`);
+                        }
+                        historyHTML.push('</div>');
+                    }
+                    historyHTML.push('</div></div>');
+                    historyHTML.push('</div>');
+                    historyHTML.push('</li>');
+                });
+                historyHTML.push('</div>');
+                historyHTML.push('</ul>');
+            });
+            $('#audit-list').empty();
+            $('#audit-list').append(historyHTML.join(''));
+        });
+    });
+
     // 首次进入设置
     let showNoNeed = false;
     if (cRuleFirst) {

+ 83 - 70
app/public/js/change_plan_audit.js

@@ -54,7 +54,7 @@ $(document).ready(function () {
     })
 
     // 添加审批流程按钮逻辑
-    $('.book-list').on('click', 'dt', function () {
+    $('body').on('click', '.book-list dt', function () {
         const idx = $(this).find('.acc-btn').attr('data-groupid')
         const type = $(this).find('.acc-btn').attr('data-type')
         if (type === 'hide') {
@@ -73,94 +73,57 @@ $(document).ready(function () {
     })
 
     // 添加到审批流程中
-    $('dl').on('click', 'dd', function () {
+    $('.search-user-list').on('click', 'dd', function () {
         const id = parseInt($(this).data('id'));
         if (id) {
             postData(preUrl + '/audit/add', { auditorId: id }, (datas) => {
-                const html = [];
-                // 如果是重新上报,添加到重新上报列表中
-                const auditorshtml = [];
-                for (const [index,data] of datas.entries()) {
-                    if (index !== 0) {
-                        html.push('<li class="list-group-item" auditorId="'+ data.aid +'">');
-                        html.push('<a href="javascript: void(0)" class="text-danger pull-right">移除</a>');
-                        html.push('<span>');
-                        html.push(data.order + ' ');
-                        html.push(data.name + ' ');
-                        html.push('</span>');
-                        html.push('<small class="text-muted">');
-                        html.push(data.role);
-                        html.push('</small></li>');
-                    }
-                    // 添加新审批人流程修改
-                    auditorshtml.push('<li class="list-group-item" data-auditorid="' + data.aid + '">');
-                    auditorshtml.push('<i class="fa ' + (index+1 === datas.length ? 'fa-stop-circle' : 'fa-chevron-circle-down') + '"></i> ');
-                    auditorshtml.push(data.name + ' <small class="text-muted">' + data.role + '</small>');
-                    if (index === 0) {
-                        auditorshtml.push('<span class="pull-right">原报</span>');
-                    } else if (index+1 === datas.length) {
-                        auditorshtml.push('<span class="pull-right">终审</span>');
-                    } else {
-                        auditorshtml.push('<span class="pull-right">'+ transFormToChinese(index) +'审</span>');
-                    }
-                    auditorshtml.push('</li>');
-                }
-                $('#auditors').html(html.join(''));
-
-
-                // 重新上报时。令其它的审批人流程图标转换
-                // $('#auditors-list li i').removeClass('fa-stop-circle').addClass('fa-chevron-circle-down');
-                // for (let i = 0; i < $('#auditors-list li').length; i++) {
-                //     $('#auditors-list li').eq(i).find('.pull-right').text(transFormToChinese(i+1) + '审');
-                //     $('#auditors-list2 li').eq(i).find('.pull-right').text(transFormToChinese(i+1) + '审');
-                // }
-
-                $('#auditors-list').html(auditorshtml.join(''));
-
-                // const auditorshtml2 = [];
-                // // 重新上报时。令其它的审批人流程图标转换
-                // $('#auditors-list2 li i').removeClass('fa-stop-circle').addClass('fa-chevron-circle-down');
-                // // 添加新审批人
-                // auditorshtml2.push('<li class="list-group-item" data-auditid="' + data.aid + '">');
-                // auditorshtml2.push('<h5 class="card-title"><i class="fa fa-stop-circle"></i> ');
-                // auditorshtml2.push(data.name + ' <small class="text-muted">' + data.role + '</small>');
-                // auditorshtml2.push('<span class="pull-right">终审</span>');
-                // auditorshtml2.push('</h5></li>');
-                // $('#auditors-list2').append(auditorshtml2.join(''));
+                makeSpHtml(datas);
             });
         }
     });
     // 删除审批人
-    $('body').on('click', '#auditors li>a', function () {
+    $('body').on('click', '#auditors li a', function () {
         const li = $(this).parent();
         const data = {
             auditorId: parseInt(li.attr('auditorId')),
         };
         postData(preUrl +  '/audit/delete', data, (result) => {
             li.remove();
-            for (const rst of result) {
-                const aLi = $('li[auditorId=' + rst.aid + ']');
-                $('span', aLi).text(rst.order + ' ' + rst.name + ' ');
-            }
+            let index = 1;
+            $('#auditors li').each(function () {
+                $(this).children('.col-auto').eq(0).text(index);
+                index++;
+            });
 
             // 如果是重新上报
             // 令最后一个图标转换
-            $('#auditors-list li[data-auditorid="' + data.auditorId + '"]').remove();
+            $('#auditors-list li[data-auditorId="' + data.auditorId + '"]').remove();
             if ($('#auditors-list li').length !== 0 && !$('#auditors-list li i').hasClass('fa-stop-circle')) {
-                $('#auditors-list li').eq($('#auditors-list li').length-1).children('i')
+                console.log($('#auditors-list li').length-1, $('#auditors-list li').eq($('#auditors-list li').length-1).find('i'));
+                $('#auditors-list li').eq($('#auditors-list li').length-1).find('i')
                     .removeClass('fa-chevron-circle-down').addClass('fa-stop-circle');
             }
-            // $('#auditors-list2 li[data-auditid="' + data.auditorId + '"]').remove();
-            // if ($('#auditors-list2 li').length !== 0 && !$('#auditors-list2 li i').hasClass('fa-stop-circle')) {
-            //     $('#auditors-list2 li').eq($('#auditors-list2 li').length-1).children('i')
-            //         .removeClass('fa-chevron-circle-down').addClass('fa-stop-circle');
-            // }
             for (let i = 0; i < $('#auditors-list li').length; i++) {
-                $('#auditors-list li').eq(i).find('.pull-right').text(i === 0 ? '原报' : (i+1 === $('#auditors-list li').length ? '终' : transFormToChinese(i)) + '审');
-                // $('#auditors-list2').eq(i).find('.pull-right').text((i+1 === $('#auditors-list2').length ? '终' : transFormToChinese(i+1)) + '审');
+                $('#auditors-list li').eq(i).find('.badge-pill').children('small').text(i === 0 ? '原报' : (i+1 === $('#auditors-list li').length ? '终' : transFormToChinese(i)) + '审');
             }
         });
     });
+
+    // 切换审批组
+    $('#change-sp-group').change(function () {
+        const data = {
+            type: 'change_sp_group',
+            sp_group: parseInt($(this).val()),
+        }
+        if (!data.sp_group) {
+            toastr.error('请选择固定审批组');
+            return false;
+        }
+        console.log(data);
+        postData(preUrl + '/audit/spgroup', data, (datas) => {
+            makeSpHtml(datas);
+        });
+    });
     // 退回选择修改审批人流程
     $('#hideSp').click(function () {
         $('#sp-list').modal('hide');
@@ -174,14 +137,64 @@ $(document).ready(function () {
         $(document.body).addClass('modal-open');
     });
 });
+function makeSpHtml(datas) {
+    const html = [];
+    // 如果是重新上报,添加到重新上报列表中
+    const auditorshtml = [];
+    for (const [index,data] of datas.entries()) {
+        if (index !== 0) {
+            html.push('<li class="list-group-item d-flex" auditorId="'+ data[0].aid +'">');
+            html.push(`<div class="col-auto">${index}</div>`);
+            html.push('<div class="col">');
+            for (const auditor of data) {
+                html.push(`<div class="d-inline-block mx-1" auditorId="${auditor.uid}"><i class="fa fa-user text-muted"></i> ${auditor.name} <small class="text-muted">${auditor.role}</small></div>`);
+            }
+            html.push('</div>');
+            html.push('<div class="col-auto">');
+            // todo 添加会签或签时
+            if (data[0].audit_type !== auditType.key.common) {
+                html.push(`<span class="badge badge-pill badge-${auditType.info[data[0].audit_type].class} badge-bg-small"><small>${auditType.info[data[0].audit_type].long}</small></span>`);
+            }
+            // html.push('<span class="badge badge-pill badge-primary badge-bg-small"><small></small></span>');
+            if (shenpi_status === shenpiConst.sp_status.sqspr || (shenpi_status === shenpiConst.sp_status.gdzs && index+1 !== datas.length)) {
+                html.push('<a href="javascript: void(0)" class="text-danger pull-right">移除</a>');
+            }
+            html.push('</div>');
+            html.push('</li>');
+        }
+        // 添加新审批人流程修改
+        auditorshtml.push('<li class="list-group-item d-flex justify-content-between align-items-center" data-auditorid="' + data[0].aid + '">');
+        auditorshtml.push('<span class="mr-1"><i class="fa ' + (index === 0 ? 'fa-play-circle fa-rotate-90' : index+1 === datas.length ? 'fa-stop-circle' : 'fa-chevron-circle-down') + '"></i></span>');
+        auditorshtml.push('<span class="text-muted">');
+        for (const auditor of data) {
+            auditorshtml.push(`<small class="d-inline-block text-dark mx-1" title="${auditor.role}" data-auditorId="${auditor.uid}">${auditor.name}</small>`);
+        }
+        auditorshtml.push('</span>');
+        auditorshtml.push('<div class="d-flex ml-auto">');
+        if (data[0].audit_type !== auditType.key.common) {
+            auditorshtml.push(`<span class="badge badge-pill badge-${auditType.info[data[0].audit_type].class} p-1"><small>${auditType.info[data[0].audit_type].short}</small></span>`);
+        }
+        if (index === 0) {
+            auditorshtml.push('<span class="badge badge-light badge-pill ml-auto"><small>原报</small></span>');
+        } else if (index+1 === datas.length) {
+            auditorshtml.push('<span class="badge badge-light badge-pill"><small>终审</small></span>');
+        } else {
+            auditorshtml.push('<span class="badge badge-light badge-pill"><small>'+ transFormToChinese(index) +'审</small></span>');
+        }
+        auditorshtml.push('</div>');
+        auditorshtml.push('</li>');
+    }
+    $('#auditors').html(html.join(''));
+    $('#auditors-list').html(auditorshtml.join(''));
+}
 // 检查上报情况
 function checkAuditorFrom () {
     if ($('#auditors li').length === 0) {
-        // if(shenpi_status === shenpiConst.sp_status.gdspl) {
-        //     toastr.error('请联系管理员添加审批人');
-        // } else {
+        if(shenpi_status === shenpiConst.sp_status.gdspl) {
+            toastr.error('请联系管理员添加审批人');
+        } else {
             toastr.error('请先选择审批人,再上报数据');
-        // }
+        }
         return false;
     }
     let flag = false;

+ 38 - 30
app/public/js/change_plan_information.js

@@ -204,27 +204,29 @@ $(document).ready(() => {
             colWidth: true,
         }
     };
-    console.log(changeList, change.listAudits);
+    console.log(changeList, change.userGroups);
 
     if (change.status === auditConst.status.checking || change.status === auditConst.status.checked) {
-        for (const audit of change.listAudits) {
-            // const userinfo = _.find(auditList2, { 'aid': aid });
-            const newColcount = {
-                title: audit.name + ' 审批|数量',
-                colSpan: '2|1', rowSpan: '1|1',
-                field: 'audit_amount_' + audit.aid,
-                hAlign: 2, width: 60, type: 'Number',
-                readOnly: !(change.shenpiPower && audit.aid === parseInt(cur_uid))
-            };
-            const newColTp = {
-                title: '|金额',
-                colSpan: '|1', rowSpan: '|1',
-                field: 'sa_tp_' + audit.aid,
-                hAlign: 2, width: 80, type: 'Number',
-                readOnly: true
-            };
-            changeSpreadSetting.cols.push(newColcount);
-            changeSpreadSetting.cols.push(newColTp);
+        for (const audit of change.userGroups) {
+            if (audit[0] && audit[0].audit_order !== 0) {
+                // const userinfo = _.find(auditList2, { 'aid': aid });
+                const newColcount = {
+                    title: (audit && audit.length > 1 ? (audit[0].audit_order + '审') : audit[0].name) + ' 审批|数量',
+                    colSpan: '2|1', rowSpan: '1|1',
+                    field: 'audit_amount_' + audit[0].audit_order,
+                    hAlign: 2, width: 60, type: 'Number',
+                    readOnly: !(change.shenpiPower && audit.aid === parseInt(cur_uid))
+                };
+                const newColTp = {
+                    title: '|金额',
+                    colSpan: '|1', rowSpan: '|1',
+                    field: 'sa_tp_' + audit[0].audit_order,
+                    hAlign: 2, width: 80, type: 'Number',
+                    readOnly: true
+                };
+                changeSpreadSetting.cols.push(newColcount);
+                changeSpreadSetting.cols.push(newColTp);
+            }
         }
     }
     changeSpreadSetting.cols.push({title: '备注1', colSpan: '1', rowSpan: '2', field: 'ex_memo1', hAlign: 0, width: 110, formatter: '@', readOnly: 'readOnly.isEdit2', cellType: 'ellipsisAutoTip', scrollHeightClass: '.sjs-height-0'});
@@ -275,16 +277,20 @@ $(document).ready(() => {
         },
         setAuditValue: function () {
             for (const c of changeList) {
-                for (const audit of change.listAudits) {
-                    c['audit_amount_' + audit.aid] = ZhCalc.round(c['audit_amount_' + audit.aid], findDecimal(c.unit));
-                    c['sa_tp_' + audit.aid] = ZhCalc.round(ZhCalc.mul(c['audit_amount_' + audit.aid], ZhCalc.round(c.unit_price, unitPriceUnit)), totalPriceUnit);
+                for (const audit of change.userGroups) {
+                    if (audit[0].audit_order !== 0) {
+                        c['audit_amount_' + audit[0].audit_order] = ZhCalc.round(c['audit_amount_' + audit[0].audit_order], findDecimal(c.unit));
+                        c['sa_tp_' + audit[0].audit_order] = ZhCalc.round(ZhCalc.mul(c['audit_amount_' + audit[0].audit_order], ZhCalc.round(c.unit_price, unitPriceUnit)), totalPriceUnit);
+                    }
                 }
             }
         },
         setRowValueAndSum: function (data, row, col) {
-            for (const j in change.listAudits) {
-                const sum = ZhCalc.round(ZhCalc.mul(ZhCalc.round(data.unit_price, unitPriceUnit), parseFloat(changeSpreadSheet.getValue(row, 11 + parseInt(j)*2))), totalPriceUnit);
-                changeSpreadSheet.setValue(row, 12 + j*2, sum !== 0 ? sum : null);
+            for (const j in change.userGroups) {
+                if (change.userGroups[j][0].audit_order !== 0) {
+                    const sum = ZhCalc.round(ZhCalc.mul(ZhCalc.round(data.unit_price, unitPriceUnit), parseFloat(changeSpreadSheet.getValue(row, 11 + parseInt(j - 1) * 2))), totalPriceUnit);
+                    changeSpreadSheet.setValue(row, 12 + (j - 1) * 2, sum !== 0 ? sum : null);
+                }
             }
             // const sum = ZhCalc.round(ZhCalc.mul(data.unit_price, data.spamount), totalPriceUnit);
             // changeSpreadSheet.setValue(row, col+1, sum !== 0 ? sum : null);
@@ -314,12 +320,14 @@ $(document).ready(() => {
             changeSpreadSheet.setValue(changeSpreadSheet.getRowCount() - 1, 8, cSum !== 0 ? cSum : null);
             changeSpreadSheet.setValue(changeSpreadSheet.getRowCount() - 1, 10, sSum !== 0 ? sSum : null);
             // 用户的数据合计
-            for (const j in change.listAudits) {
-                let audit_sum = 0;
-                for(let i = 0; i < rowCount - 1; i++){
-                    audit_sum = ZhCalc.add(audit_sum, changeSpreadSheet.getValue(i, 12 + j*2));
+            for (const j in change.userGroups) {
+                if (change.userGroups[j][0].audit_order !== 0) {
+                    let audit_sum = 0;
+                    for (let i = 0; i < rowCount - 1; i++) {
+                        audit_sum = ZhCalc.add(audit_sum, changeSpreadSheet.getValue(i, 12 + (j - 1) * 2));
+                    }
+                    changeSpreadSheet.setValue(changeSpreadSheet.getRowCount() - 1, 12 + (j - 1) * 2, audit_sum !== 0 ? audit_sum : null);
                 }
-                changeSpreadSheet.setValue(changeSpreadSheet.getRowCount() - 1, 12 + j*2, audit_sum !== 0 ? audit_sum : null);
             }
         },
         deletePress: function (sheet) {

+ 4 - 4
app/public/js/change_project_audit.js

@@ -293,11 +293,11 @@ function makeSpHtml(datas) {
 // 检查上报情况
 function checkAuditorFrom () {
     if ($('#auditors li').length === 0) {
-        // if(shenpi_status === shenpiConst.sp_status.gdspl) {
-        //     toastr.error('请联系管理员添加审批人');
-        // } else {
+        if(shenpi_status === shenpiConst.sp_status.gdspl) {
+            toastr.error('请联系管理员添加审批人');
+        } else {
             toastr.error('请先选择审批人,再上报数据');
-        // }
+        }
         return false;
     }
     let flag = false;

+ 6 - 2
app/router.js

@@ -15,6 +15,7 @@ module.exports = app => {
     const changeAuditCheck = app.middlewares.changeAuditCheck();
     const changeProjectAuditCheck = app.middlewares.changeProjectAuditCheck();
     const changeApplyAuditCheck = app.middlewares.changeApplyAuditCheck();
+    const changePlanAuditCheck = app.middlewares.changePlanAuditCheck();
     const uncheckTenderCheck = app.middlewares.uncheckTenderCheck();
     // 期读取中间件
     const stageCheck = app.middlewares.stageCheck();
@@ -613,20 +614,23 @@ module.exports = app => {
     app.post('/tender/:id/change/plan/add', sessionAuth, tenderCheck, uncheckTenderCheck, tenderBuildCheck, 'changeController.planAdd');
     app.post('/tender/:id/change/plan/delete', sessionAuth, tenderCheck, uncheckTenderCheck, tenderBuildCheck, 'changeController.planDelete');
     app.get('/tender/:id/change/plan/:cpid/info', sessionAuth, tenderCheck, uncheckTenderCheck, changePlanCheck, 'changeController.planInformation');// 针对旧数据wap端跳转web问题
-    app.get('/tender/:id/change/plan/:cpid/information', sessionAuth, tenderCheck, uncheckTenderCheck, changePlanCheck, 'changeController.planInformation');
+    app.get('/tender/:id/change/plan/:cpid/information', sessionAuth, tenderCheck, uncheckTenderCheck, changePlanCheck, changePlanAuditCheck, 'changeController.planInformation');
     app.post('/tender/:id/change/plan/:cpid/information/save', sessionAuth, tenderCheck, uncheckTenderCheck, changePlanCheck, 'changeController.planInformationSave');
     app.post('/tender/:id/change/plan/:cpid/information/file/upload', sessionAuth, tenderCheck, uncheckTenderCheck, changePlanCheck, 'changeController.uploadPlanFile');
     app.post('/tender/:id/change/plan/:cpid/information/file/delete', sessionAuth, tenderCheck, uncheckTenderCheck, changePlanCheck, 'changeController.deletePlanFile');
     app.get('/tender/:id/change/plan/:cpid/information/file/:fid/download', sessionAuth, tenderCheck, uncheckTenderCheck, changePlanCheck, 'changeController.downloadPlanFile');
     app.post('/tender/:id/change/plan/:cpid/information/audit/add', sessionAuth, tenderCheck, uncheckTenderCheck, changePlanCheck, 'changeController.addPlanAudit');
     app.post('/tender/:id/change/plan/:cpid/information/audit/delete', sessionAuth, tenderCheck, uncheckTenderCheck, changePlanCheck, 'changeController.deletePlanAudit');
-    app.post('/tender/:id/change/plan/:cpid/information/audit/start', sessionAuth, tenderCheck, uncheckTenderCheck, changePlanCheck, tenderBuildCheck, 'changeController.startPlanAudit');
+    app.post('/tender/:id/change/plan/:cpid/information/audit/start', sessionAuth, tenderCheck, uncheckTenderCheck, changePlanCheck, changePlanAuditCheck, tenderBuildCheck, 'changeController.startPlanAudit');
     app.post('/tender/:id/change/plan/:cpid/information/audit/check', sessionAuth, tenderCheck, uncheckTenderCheck, changePlanCheck, tenderBuildCheck, 'changeController.checkPlanAudit');
     app.post('/tender/:id/change/plan/:cpid/information/list/save', sessionAuth, tenderCheck, uncheckTenderCheck, changePlanCheck, 'changeController.savePlanListsData');
     app.post('/tender/:id/change/plan/cancel/audit', sessionAuth, tenderCheck, uncheckTenderCheck, tenderBuildCheck, changePlanCheck, 'changeController.checkPlanAuditCancel');
     app.post('/tender/:id/change/plan/check/revise', sessionAuth, tenderCheck, uncheckTenderCheck, tenderBuildCheck, changePlanCheck, 'changeController.checkPlanRevise');
     app.post('/tender/:id/change/plan/cancel/revise', sessionAuth, tenderCheck, uncheckTenderCheck, tenderBuildCheck, changePlanCheck, 'changeController.cancelPlanRevise');
     app.post('/tender/:id/change/plan/check/again', sessionAuth, tenderCheck, uncheckTenderCheck, tenderBuildCheck, changePlanCheck, 'changeController.checkPlanAgain');
+    app.post('/tender/:id/change/plan/:cpid/information/audit/save', sessionAuth, tenderCheck, uncheckTenderCheck, changePlanCheck, 'changeController.savePlanAudit');
+    app.post('/tender/:id/change/plan/:cpid/information/audit/spgroup', sessionAuth, tenderCheck, uncheckTenderCheck, changePlanCheck, 'changeController.changePlanSpGroup');
+    app.post('/tender/:id/change/plan/auditors', sessionAuth, tenderCheck, uncheckTenderCheck, 'changeController.changePlanAuditors');
     // 材料调差
     app.get('/tender/:id/measure/material', sessionAuth, tenderCheck, uncheckTenderCheck, 'materialController.index');
     app.post('/tender/:id/measure/material/add', sessionAuth, tenderCheck, uncheckTenderCheck, tenderBuildCheck, 'materialController.add');

+ 1 - 1
app/service/change_apply_audit.js

@@ -1263,7 +1263,7 @@ module.exports = app => {
                     const newAuditors = await transaction.select(this.tableName, { where: { caid: caId, times }, orders: [['order', 'asc']] });
                     const newAuditorGroup = this.ctx.helper.groupAuditors(newAuditors, 'order', true);
                     const uniqNewAuditorGroup = this.ctx.helper.groupAuditorsUniq(newAuditorGroup);
-                    await this.ctx.service.shenpiAudit.updateAuditListWithAuditType(transaction, this.ctx.tender.id, this.ctx.tender.info.shenpi.change, shenpiConst.sp_type.change, uniqNewAuditorGroup, sp_group);
+                    // await this.ctx.service.shenpiAudit.updateAuditListWithAuditType(transaction, this.ctx.tender.id, this.ctx.tender.info.shenpi.change, shenpiConst.sp_type.change, uniqNewAuditorGroup, sp_group);
                 } else if (this.ctx.tender.info.shenpi.change === shenpiConst.sp_status.gdzs) {
                     const newAuditors = await this.getAuditGroupByList(caId, times, transaction);
                     await this.ctx.service.shenpiAudit.updateAuditList(transaction, this.ctx.tender.id, this.ctx.tender.info.shenpi.change, shenpiConst.sp_type.change, this._.map(newAuditors, 'aid'));

+ 72 - 20
app/service/change_plan.js

@@ -9,6 +9,7 @@
  */
 
 const audit = require('../const/audit').changePlan;
+const auditType = require('../const/audit').auditType;
 // const smsTypeConst = require('../const/sms_type');
 // const SMS = require('../lib/sms');
 // const SmsAliConst = require('../const/sms_alitemplate');
@@ -31,6 +32,50 @@ module.exports = app => {
             this.tableName = 'change_plan';
         }
 
+        async loadChangeAuditViewData(change) {
+            const times = change.status === audit.status.checkNo || change.status === audit.status.revise ? change.times - 1 : change.times;
+
+            if (!change.user) change.user = await this.ctx.service.projectAccount.getAccountInfoById(change.uid);
+            change.auditHistory = await this.ctx.service.changePlanAudit.getAuditorHistory(change.id, times);
+            // 获取审批流程中左边列表
+            if ((change.status === audit.status.checkNo || change.status === audit.status.revise) && change.uid !== this.ctx.session.sessionUser.accountId && !this.ctx.session.sessionUser.is_admin) {
+                const auditors = await this.ctx.service.changePlanAudit.getAuditors(change.id, times); // 全部参与的审批人
+                const auditorGroups = this.ctx.helper.groupAuditors(auditors, 'order', true);
+                change.auditors2 = this.ctx.helper.groupAuditorsUniq(auditorGroups);
+                change.auditors2.unshift([{
+                    aid: change.user.id, order: 0, times: change.times - 1, audit_order: 0, audit_type: auditType.key.common,
+                    name: change.user.name, role: change.user.role, company: change.user.company,
+                }]);
+            } else {
+                change.auditors2 = change.userGroups;
+            }
+            if (change.status === audit.status.uncheck || change.status === audit.status.checkNo || change.status === audit.status.revise) {
+                change.auditorList = await this.ctx.service.changePlanAudit.getAuditors(change.id, change.times);
+            }
+        }
+
+        async loadChangeUser(change) {
+            const status = audit.status;
+            const accountId = this.ctx.session.sessionUser.accountId;
+
+            change.user = await this.ctx.service.projectAccount.getAccountInfoById(change.uid);
+            change.auditors = await this.ctx.service.changePlanAudit.getAuditors(change.id, change.times); // 全部参与的审批人
+            change.auditorIds = this._.map(change.auditors, 'aid');
+            change.curAuditors = change.auditors.filter(x => { return x.status === status.checking; }); // 当前流程中审批中的审批人
+            change.curAuditorIds = this._.map(change.curAuditors, 'aid');
+            change.flowAuditors = change.curAuditors.length > 0 ? change.auditors.filter(x => { return x.order === change.curAuditors[0].order; }) : []; // 当前流程中参与的审批人(包含会签时,审批通过的人)
+            change.flowAuditorIds = this._.map(change.flowAuditors, 'aid');
+            change.nextAuditors = change.curAuditors.length > 0 ? change.auditors.filter(x => { return x.order === change.curAuditors[0].order + 1; }) : [];
+            change.nextAuditorIds = this._.map(change.nextAuditors, 'aid');
+            change.auditorGroups = this.ctx.helper.groupAuditors(change.auditors, 'order', true);
+            change.userGroups = this.ctx.helper.groupAuditorsUniq(change.auditorGroups);
+            change.userGroups.unshift([{
+                aid: change.user.id, order: 0, times: change.times, audit_order: 0, audit_type: auditType.key.common,
+                name: change.user.name, role: change.user.role, company: change.user.company,
+            }]);
+            change.finalAuditorIds = change.userGroups[change.userGroups.length - 1].map(x => { return x.aid; });
+        }
+
         async add(tenderId, userId, code, apply_code, name) {
             const sql = 'SELECT COUNT(*) as count FROM ?? WHERE `tid` = ? AND `code` = ?';
             const sqlParam = [this.tableName, tenderId, code];
@@ -441,32 +486,39 @@ module.exports = app => {
             const auditors = change.auditors;
             change.cancancel = 0;
             if (change.status !== status.checked && change.status !== status.uncheck && change.status !== status.revise) {
-                if (change.status !== status.checkNo) {
-                    // 找出当前操作人上一个审批人,包括审批完成的和退回上一个审批人的,同时当前操作人为第一人时,就是则为原报
-                    const onAuditor = this._.find(auditors, function(item) {
-                        return item.aid === change.curAuditor.aid && item.status === status.checking;
-                    });
-                    const preAudit = onAuditor.order !== 1 ? this._.find(auditors, { order: onAuditor.order - 1 }) : false;
-                    const preAid = preAudit ? (preAudit.status !== status.checkAgain ? preAudit.aid : false) : change.uid;// 已发起重审无法撤回
-                    if (onAuditor && onAuditor.aid === preAid && preAudit.status === status.checkCancel) {
-                        return;// 不可以多次撤回
-                    } else if (preAid === accountId && preAid !== change.uid) {
-                        if (preAudit.status === status.checked) {
+                if (change.status === status.checkNo) {
+                    const lastAuditors = await this.service.changePlanAudit.getAuditors(change.id, change.times - 1);
+                    const onAuditor = this._.findLast(lastAuditors, { status: status.back });
+                    if (onAuditor && onAuditor.aid === accountId) {
+                        change.cancancel = 4;// 审批人撤回退回原报
+                        change.preAuditors = lastAuditors.filter(x => { return x.order === onAuditor.order; });
+                    }
+                } else {
+                    if (change.flowAuditors.find(x => { return x.status !== status.checking; }) && change.flowAuditorIds.indexOf(accountId) < 0) return; // 当前流程存在审批人审批通过时,不可撤回
+                    if (change.curAuditorIds.indexOf(accountId) < 0 && change.flowAuditorIds.indexOf(accountId) >= 0) {
+                        change.cancancel = 5; // 会签未全部审批通过时,审批人撤回审批通过
+                        return;
+                    }
+                    const preAuditors = change.curAuditors[0].order !== 1 ? change.auditors.filter(x => { return x.order === change.curAuditors[0].order - 1; }) : [];
+                    const preAuditorCheckAgain = preAuditors.find(pa => { return pa.status === status.checkAgain; });
+                    const preAuditorCheckCancel = preAuditors.find(pa => { return pa.status === status.checkCancel; });
+                    const preAuditorIds = preAuditorCheckAgain ? [] : preAuditors.map(x => { return x.aid; }); // 重审不可撤回
+                    if ((this._.isEqual(change.flowAuditorIds, preAuditorIds) && preAuditorCheckCancel)) {
+                        return; // 不可以多次撤回
+                    }
+                    const preAuditChecked = preAuditors.find(pa => { return pa.status === status.checked && pa.aid === accountId; });
+                    // const preAuditCheckNoPre = preAuditors.find(pa => { return pa.status === status.checkNoPre && pa.uid === accountId; });
+                    if (preAuditorIds.indexOf(accountId) >= 0) {
+                        if (preAuditChecked && change.status === status.checking) {
                             change.cancancel = 2;// 审批人撤回审批通过
                         }
-                        // else if (preAudit.status === status.checkNoPre) {
+                        // else if (preAuditCheckNoPre && change.status === status.checkNoPre) {
                         //     change.cancancel = 3;// 审批人撤回审批退回上一人
                         // }
-                        change.preAudit = preAudit;
-                    } else if (preAid === accountId && preAid === change.uid) {
+                        change.preAuditors = preAuditors;
+                    } else if (preAuditors.length === 0 && accountId === change.uid) {
                         change.cancancel = 1;// 原报撤回
                     }
-                } else {
-                    const lastAuditors = await this.service.changePlanAudit.getAuditors(change.id, change.times - 1);
-                    const onAuditor = this._.findLast(lastAuditors, { status: status.checkNo });
-                    if (onAuditor && onAuditor.aid === accountId) {
-                        change.cancancel = 4;// 审批人撤回退回原报
-                    }
                 }
             }
         }

文件差異過大導致無法顯示
+ 656 - 286
app/service/change_plan_audit.js


+ 2 - 2
app/service/change_project_audit.js

@@ -785,7 +785,7 @@ module.exports = app => {
          */
         async checkCancel(change) {
 
-            // 分4种情况,根据ctx.cancancel值判断:
+            // 分5种情况,根据ctx.cancancel值判断:
             // 1.原报发起撤回,当前流程删除,并回到待上报
             // 2.审批人撤回审批通过,增加流程,并回到它审批中
             // 3.审批人撤回审批终止,增加流程,并回到它审批中,并更新立项状态为审批中
@@ -1399,7 +1399,7 @@ module.exports = app => {
                     const newAuditors = await transaction.select(this.tableName, { where: { cpid: cpId, times }, orders: [['order', 'asc']] });
                     const newAuditorGroup = this.ctx.helper.groupAuditors(newAuditors, 'order', true);
                     const uniqNewAuditorGroup = this.ctx.helper.groupAuditorsUniq(newAuditorGroup);
-                    await this.ctx.service.shenpiAudit.updateAuditListWithAuditType(transaction, this.ctx.tender.id, this.ctx.tender.info.shenpi.change, shenpiConst.sp_type.change, uniqNewAuditorGroup, sp_group);
+                    // await this.ctx.service.shenpiAudit.updateAuditListWithAuditType(transaction, this.ctx.tender.id, this.ctx.tender.info.shenpi.change, shenpiConst.sp_type.change, uniqNewAuditorGroup, sp_group);
                 } else if (this.ctx.tender.info.shenpi.change === shenpiConst.sp_status.gdzs) {
                     const newAuditors = await this.getAuditGroupByList(cpId, times, transaction);
                     await this.ctx.service.shenpiAudit.updateAuditList(transaction, this.ctx.tender.id, this.ctx.tender.info.shenpi.change, shenpiConst.sp_type.change, this._.map(newAuditors, 'aid'));

+ 24 - 11
app/view/change/plan.ejs

@@ -67,7 +67,7 @@
         <div class="c-body">
             <div class="sjs-height-0">
                 <table class="table table-bordered">
-                    <thead>
+                    <thead class="text-center">
                     <tr>
                         <th width="15%" id="sort_change">变更方案编号</th><th width="20%">变更工程名称</th>
                         <th width="10%">变更性质</th><th width="15%">变更金额</th><th width="15%">变更申请编号</th>
@@ -80,20 +80,31 @@
                             <td><%- c.quality %></td>
                             <td style="text-align: right"><%- c.total_price %></td>
                             <td><%- c.apply_code %></td>
-                            <td>
-                                <% if ((c.status === auditConst.status.uncheck || c.status === auditConst.status.checkNo || c.status === auditConst.status.revise) && c.uid === ctx.session.sessionUser.accountId) { %>
-                                    <a href="/tender/<%- tender.id %>/change/plan/<%- c.id %>/information" class="btn <%- auditConst.statusButtonClass[c.status] %> btn-sm"><%- auditConst.statusButton[c.status] %></a>
-                                <% } else if (c.status === auditConst.status.checking && c.curAuditor && c.curAuditor.aid === ctx.session.sessionUser.accountId) { %>
-                                    <a href="/tender/<%- tender.id %>/change/plan/<%- c.id %>/information" class="btn <%- auditConst.statusButtonClass[c.status] %> btn-sm"><%- auditConst.statusButton[c.status] %></a>
+                            <td class="text-center">
+                                <% if (c.status === auditConst.status.uncheck && c.uid === ctx.session.sessionUser.accountId) { %>
+                                    <a href="/tender/<%- tender.id %>/change/project/<%- c.id %>/information" class="btn <%- auditConst.statusButtonClass[c.status] %> btn-sm"><%- auditConst.statusButton[c.status] %></a>
+                                <% } else if ((c.status === auditConst.status.checkNo || c.status === auditConst.status.revise) && c.curAuditors && c.aid === ctx.session.sessionUser.accountId) { %>
+                                    <a href="/tender/<%- tender.id %>/change/project/<%- c.id %>/information" class="btn <%- auditConst.statusButtonClass[c.status] %> btn-sm"><%- auditConst.statusButton[c.status] %></a>
+                                <% } else if (c.status === auditConst.status.checking && c.curAuditors && c.curAuditors.findIndex(x => { return x.aid === ctx.session.sessionUser.accountId; }) >= 0) { %>
+                                    <% const curAudit = c.curAuditors.find(x => { return x.aid === ctx.session.sessionUser.accountId; }); %>
+                                    <% if (curAudit.status === auditConst.status.checking) { %>
+                                        <a href="/tender/<%- tender.id %>/change/project/<%- c.id %>/information" class="btn <%- auditConst.statusButtonClass[c.status] %> btn-sm"><%- auditConst.statusButton[c.status] %></a>
+                                    <% } else { %>
+                                        <span class="<%- auditConst.auditStringClass[curAudit.status] %>"><%- auditConst.auditString[curAudit.status] %></span>
+                                    <% } %>
                                 <% } else { %>
-                                    <span class="<%- auditConst.auditProgressClass[c.status] %>"><%- auditConst.auditProgress[c.status] %></span>
+                                    <span class="<%- auditConst.auditStringClass[c.status] %>"><%- auditConst.auditString[c.status] %></span>
                                 <% } %>
                             </td>
-                            <td>
-                                <% if (c.status !== auditConst.status.uncheck) { %>
-                                    <%- c.curAuditor.name %>-<%- c.curAuditor.role %>
+                            <td class="<%- auditConst.auditProgressClass[c.status] %>">
+                                <% if (c.curAuditors && c.curAuditors.length > 0) { %>
+                                    <% if (c.curAuditors[0].audit_type === auditType.key.common) { %>
+                                        <a href="#sp-list" data-toggle="modal" data-target="#sp-list" c-id="<%- c.id %>"><%- c.curAuditors[0].name %><%if (c.curAuditors[0].role !== '' && c.curAuditors[0].role !== null) { %>-<%- c.curAuditors[0].role %><% } %></a>
+                                    <% } else { %>
+                                        <a href="#sp-list" data-toggle="modal" data-target="#sp-list" c-id="<%- c.id %>"><%- ctx.helper.transFormToChinese(c.curAuditors[0].audit_order) + '审' %></a>
+                                    <% } %>
                                 <% } %>
-                                <span class="<%- auditConst.statusClass[c.status] %>"><%- auditConst.statusString[c.status] %></span>
+                                <%- auditConst.auditProgress[c.status] %>
                             </td>
                             <td>
                                 <% if (c.uid === uid && (c.status === auditConst.status.uncheck || c.status === auditConst.status.checkNo)) { %><a href="#del-bg" cpid="<%= c.id %>" data-toggle="modal" data-target="#del-bg" class="btn btn-outline-danger btn-sm delete-cpid-modal">删除</a><% } %>
@@ -120,5 +131,7 @@
     const ruleType = parseInt('<%- ruleType %>');
     const openChangeApply = parseInt('<%- ctx.session.sessionProject.page_show.openChangeApply %>');
     const rulesType = '<%- rule_type %>';
+    const auditType = JSON.parse(unescape('<%- escape(JSON.stringify(auditType)) %>'));
+    const auditConst = JSON.parse(unescape('<%- escape(JSON.stringify(auditConst)) %>'));
     const changeApplyList = JSON.parse(unescape('<%- escape(JSON.stringify(changeApplyList)) %>'));
 </script>

+ 2 - 2
app/view/change/plan_information.ejs

@@ -33,7 +33,7 @@
                         <a id="sub-sp-btn" href="javascript: void(0);" data-toggle="modal" data-target="#sub-sp" class="btn btn-outline-secondary btn-sm">上报中</a>
                     <% } %>
                 <% } else if (ctx.change.status === auditConst.status.checking) { %>
-                    <% if (ctx.change.curAuditor && ctx.change.curAuditor.aid === ctx.session.sessionUser.accountId) { %>
+                    <% if (ctx.change.curAuditorIds.indexOf(ctx.session.sessionUser.accountId) >= 0) { %>
                         <a id="sp-done-btn" href="javascript: void(0);" data-toggle="modal" data-target="#sp-done" class="btn btn-success btn-sm">审批通过</a>
                         <a href="#sp-back" data-toggle="modal" data-target="#sp-back" class="btn btn-warning btn-sm">审批退回</a>
                     <% } else { %>
@@ -41,7 +41,7 @@
                     <% } %>
                 <% } else if (ctx.change.status === auditConst.status.checked) { %>
                     <a href="#sp-list" data-toggle="modal" data-target="#sp-list" class="btn btn-outline-success btn-sm">审批完成</a>
-                    <% if (ctx.session.sessionUser.accountId === ctx.change.auditors2[ctx.change.auditors2.length-1].aid) { %>
+                    <% if (ctx.change.auditors !== undefined && ctx.change.finalAuditorIds.indexOf(ctx.session.sessionUser.accountId) >= 0) { %>
                         <!--重新审批-->
                         <a href="#sp-down-back" data-toggle="modal" data-target="#sp-down-back" class="btn btn-warning btn-sm ml-2">重新审批</a>
                     <% } %>

文件差異過大導致無法顯示
+ 885 - 451
app/view/change/plan_information_modal.ejs


+ 25 - 1
app/view/change/plan_modal.ejs

@@ -17,7 +17,31 @@
         </div>
     </div>
 </div>
-
+<!--审批流程/结果-->
+<div class="modal fade" id="sp-list" data-backdrop="static">
+    <div class="modal-dialog modal-lg" 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-4 modal-height-500" style="overflow: auto">
+                        <div class="card mt-3">
+                            <ul class="list-group list-group-flush" id="auditor-list">
+                            </ul>
+                        </div>
+                    </div>
+                    <div class="col-8 modal-height-500" style="overflow: auto" id="audit-list">
+                    </div>
+                </div>
+            </div>
+            <div class="modal-footer">
+                <button type="button" class="btn btn-secondary btn-sm" data-dismiss="modal">关闭</button>
+            </div>
+        </div>
+    </div>
+</div>
 <% if (tender.user_id === uid) { %>
 <!--弹出添加变更令-->
 <div class="modal fade" id="add-bj-modal" data-backdrop="static">