浏览代码

台账修订,会签或签审批相关

MaiXinRong 9 月之前
父节点
当前提交
46a4848db9
共有 3 个文件被更改,包括 354 次插入320 次删除
  1. 149 105
      app/service/ledger_audit.js
  2. 202 200
      app/service/revise_audit.js
  3. 3 15
      app/view/revise/info_modal.ejs

+ 149 - 105
app/service/ledger_audit.js

@@ -287,7 +287,7 @@ module.exports = app => {
                 const auditorGroups = this.ctx.helper.groupAuditors(auditors, 'audit_order');
                 tender.auditors2 = this.ctx.helper.groupAuditorsUniq(auditorGroups, 'audit_order');
                 tender.auditors2.unshift([{
-                    aid: tender.user.id, order: 0, times: tender.ledger_times - 1, audit_order: 0, audit_type: auditConst.auditType.key.common,
+                    aid: tender.user.id, order: 0, times: tender.ledger_times - 1, audit_order: 0, audit_type: auditType.key.common,
                     name: tender.user.name, role: tender.user.role, company: tender.user.company
                 }]);
             } else {
@@ -499,19 +499,78 @@ module.exports = app => {
             return true;
         }
 
-        /**
-         * 审批
-         * @param {Number} tenderId - 标段id
-         * @param {auditConst.status.checked|auditConst.status.checkNo} checkType - 审批结果
-         * @param {String} opinion 审批意见
-         * @param {Number} times - 第几次审批
-         * @return {Promise<void>}
-         */
-        async check(tenderId, checkType, opinion, times = 1) {
+        async _checkNo(tenderId, opinion, times) {
             const accountId = this.ctx.session.sessionUser.accountId;
-            if (checkType !== auditConst.status.checked && checkType !== auditConst.status.checkNo) {
-                throw '提交数据错误';
+            const pid = this.ctx.session.sessionProject.id;
+            const auditors = await this.getAllDataByCondition({ where: { tender_id: tenderId, times, status: auditConst.status.checking } });
+            if (auditors.length === 0) throw '审核数据错误';
+            const selfAuditor = auditors.find(x => { return x.audit_id === accountId; });
+            if (!selfAuditor) throw '当前标段您无权审批';
+
+            const beginAuditors = await this.getAllDataByCondition({ where: { tender_id: tenderId, audit_order: 1, times } });
+            const time = new Date();
+
+            const noticeContent = await this.getNoticeContent(selfAuditor.tender_id, pid, accountId, opinion);
+            const defaultNoticeRecord = { pid, type: pushType.ledger, status: auditConst.status.checkNo, content: noticeContent };
+
+            const transaction = await this.db.beginTransaction();
+            try {
+                // 获取审核人列表,添加提醒
+                const records = [{ uid: this.ctx.tender.data.user_id, ...defaultNoticeRecord } ];
+                const auditList = await this.getAuditors(tenderId, times);
+                auditList.forEach(audit => {
+                    records.push({ uid: audit.audit_id, ...defaultNoticeRecord});
+                });
+                await transaction.insert('zh_notice', records);
+                const users = this._.uniq(this._.concat(this._.map(auditList, 'audit_id'), this.ctx.tender.data.user_id));
+
+                // 更新当前审核流程
+                const updateAuditData = auditors.map(x => {
+                    return {
+                        id: x.id,
+                        status: x.audit_id === selfAuditor.audit_id ? auditConst.status.checkNo : auditConst.status.checkSkip,
+                        opinion: x.audit_id === selfAuditor.aid ? opinion : '',
+                        end_time: x.audit_id === selfAuditor.aid ? time : null,
+                    };
+                });
+                await transaction.updateRows(this.tableName, updateAuditData);
+                // 审批提醒
+                await this.ctx.service.noticeAgain.stopNoticeAgain(transaction, this.tableName, this._.map(auditors, 'id'));
+
+                // 同步标段信息
+                await transaction.update(this.ctx.service.tender.tableName, {
+                    id: tenderId, ledger_times: times + 1, ledger_status: auditConst.status.checkNo,
+                });
+                await this.ctx.service.tenderCache.updateLedgerCache(transaction, tenderId, auditConst.status.checkNo, auditConst.status.checkNo, [{ audit_id: this.ctx.tender.data.user_id }]);
+                // 拷贝新一次审核流程列表
+                const orgAuditors = await this.getAllDataByCondition({
+                    where: { tender_id: tenderId, times },
+                    columns: ['tender_id', 'audit_order', 'audit_id', 'audit_type', 'audit_ledger_id'],
+                });
+                const insertAuditors = orgAuditors.map(x => {
+                    return { ...x, times: times + 1, status: auditConst.status.uncheck };
+                });
+                await transaction.insert(this.tableName, insertAuditors);
+
+                await this.ctx.helper.sendAliSms(users, smsTypeConst.const.TZ, smsTypeConst.judge.result.toString(), SmsAliConst.template.ledger_result, {
+                    status: SmsAliConst.status.back,
+                });
+                // 微信模板通知
+                const wechatData = {
+                    status: wxConst.status.back,
+                    tips: wxConst.tips.back,
+                    begin_time: Date.parse(beginAuditors[0].begin_time),
+                };
+                await this.ctx.helper.sendWechat(users, smsTypeConst.const.TZ, smsTypeConst.judge.result.toString(), wxConst.template.ledger, wechatData);
+                await transaction.commit();
+            } catch (err) {
+                await transaction.rollback();
+                throw err;
             }
+        }
+
+        async _checked(tenderId, opinion, times) {
+            const accountId = this.ctx.session.sessionUser.accountId;
             const pid = this.ctx.session.sessionProject.id;
             const auditors = await this.getAllDataByCondition({ where: { tender_id: tenderId, times, status: auditConst.status.checking } });
             if (auditors.length === 0) throw '审核数据错误';
@@ -524,7 +583,7 @@ module.exports = app => {
             const time = new Date();
 
             const noticeContent = await this.getNoticeContent(selfAuditor.tender_id, pid, accountId, opinion);
-            const defaultNoticeRecord = { pid, type: pushType.ledger, status: checkType, content: noticeContent };
+            const defaultNoticeRecord = { pid, type: pushType.ledger, status: auditConst.status.checked, content: noticeContent };
 
             const transaction = await this.db.beginTransaction();
             try {
@@ -538,104 +597,72 @@ module.exports = app => {
                 const users = this._.uniq(this._.concat(this._.map(auditList, 'audit_id'), this.ctx.tender.data.user_id));
 
                 // 更新当前审核流程
-                await transaction.update(this.tableName, { id: selfAuditor.id, status: checkType, opinion, end_time: time });
+                await transaction.update(this.tableName, { id: selfAuditor.id, status: auditConst.status.checked, opinion, end_time: time });
                 // 审批提醒
-                await this.ctx.service.noticeAgain.stopNoticeAgain(transaction, this.tableName, selfAuditor.id);
-
-                if (checkType === auditConst.status.checked) {
-                    if (auditors.length === 1 || selfAuditor.audit_type === auditType.key.or) {
-                        // 或签更新他人审批状态
-                        if (selfAuditor.audit_type === auditType.key.or) {
-                            const updateOther = [];
-                            for (const audit of auditors) {
-                                if (audit.audit_id === selfAuditor.audit_id) continue;
-                                updateOther.push({
-                                    id: audit.id,
-                                    status: auditConst.status.checkSkip,
-                                    opinion: '',
-                                    end_time: time,
-                                });
-                                await this.ctx.service.noticeAgain.stopNoticeAgain(transaction, this.tableName, audit.id);
-                            }
-                            if (updateOther.length > 0) transaction.updateRows(this.tableName, updateOther);
+                await this.ctx.service.noticeAgain.stopNoticeAgain(transaction, this.tableName, this._.map(auditors, 'id'));
+
+                if (auditors.length === 1 || selfAuditor.audit_type === auditType.key.or) {
+                    // 或签更新他人审批状态
+                    if (selfAuditor.audit_type === auditType.key.or) {
+                        const updateOther = [];
+                        for (const audit of auditors) {
+                            if (audit.audit_id === selfAuditor.audit_id) continue;
+                            updateOther.push({ id: audit.id, status: auditConst.status.checkSkip, opinion: '', end_time: time });
                         }
-                        // 无下一审核人表示,审核结束
-                        if (nextAuditors.length > 0) {
-                            const nextAuditUpdateData = nextAuditors.map(x => { return {id: x.id, status: auditConst.status.checking, begin_time: time }; });
-                            await transaction.updateRows(this.tableName, nextAuditUpdateData);
-
-                            await this.ctx.service.tenderCache.updateLedgerCache(transaction, tenderId, auditConst.status.checking, checkType, nextAuditors);
-                            const nextAuditorIds = nextAuditors.map(x => { return x.audit_id; });
-                            await this.ctx.helper.sendAliSms(nextAuditorIds, smsTypeConst.const.TZ, smsTypeConst.judge.approval.toString(), SmsAliConst.template.ledger_check);
-                            // 微信模板通知
-                            const wechatData = {
-                                status: wxConst.status.check,
-                                tips: wxConst.tips.check,
-                                begin_time: Date.parse(beginAuditors[0].begin_time),
-                            };
-                            await this.ctx.helper.sendWechat(nextAuditorIds, smsTypeConst.const.TZ, smsTypeConst.judge.approval.toString(), wxConst.template.ledger, wechatData);
-                            for (const audit of nextAuditors) {
-                                await this.ctx.service.noticeAgain.addNoticeAgain(transaction, smsTypeConst.const.TZ, {
-                                    pid: this.ctx.session.sessionProject.id,
-                                    tid: tenderId,
-                                    uid: audit.audit_id,
-                                    sp_type: 'ledger',
-                                    sp_id: audit.id,
-                                    table_name: this.tableName,
-                                    template: wxConst.template.ledger,
-                                    wx_data: wechatData,
-                                });
-                            }
-                        } else {
-                            // 同步标段信息
-                            await transaction.update(this.ctx.service.tender.tableName, {
-                                id: tenderId, ledger_status: checkType,
-                            });
-                            await this.ctx.service.tenderCache.updateLedgerCache(transaction, tenderId, checkType, checkType);
-                            // 审批通过,添加标记
-                            await this.ctx.service.tenderTag.saveTenderTag(tenderId, { ledger_time: time }, transaction);
-                            await this.ctx.helper.sendAliSms(users, smsTypeConst.const.TZ, smsTypeConst.judge.result.toString(), SmsAliConst.template.ledger_result, {
-                                status: SmsAliConst.status.success,
+                        if (updateOther.length > 0) {
+                            await transaction.updateRows(this.tableName, updateOther);
+                            await this.ctx.service.noticeAgain.stopNoticeAgain(transaction, this.tableName, updateOther.map(x => { return x.id}));
+                        }
+                    }
+                    // 无下一审核人表示,审核结束
+                    if (nextAuditors.length > 0) {
+                        const nextAuditUpdateData = nextAuditors.map(x => { return {id: x.id, status: auditConst.status.checking, begin_time: time }; });
+                        await transaction.updateRows(this.tableName, nextAuditUpdateData);
+
+                        await this.ctx.service.tenderCache.updateLedgerCache(transaction, tenderId, auditConst.status.checking, auditConst.status.checked, nextAuditors);
+                        const nextAuditorIds = nextAuditors.map(x => { return x.audit_id; });
+                        await this.ctx.helper.sendAliSms(nextAuditorIds, smsTypeConst.const.TZ, smsTypeConst.judge.approval.toString(), SmsAliConst.template.ledger_check);
+                        // 微信模板通知
+                        const wechatData = {
+                            status: wxConst.status.check,
+                            tips: wxConst.tips.check,
+                            begin_time: Date.parse(beginAuditors[0].begin_time),
+                        };
+                        await this.ctx.helper.sendWechat(nextAuditorIds, smsTypeConst.const.TZ, smsTypeConst.judge.approval.toString(), wxConst.template.ledger, wechatData);
+                        for (const audit of nextAuditors) {
+                            await this.ctx.service.noticeAgain.addNoticeAgain(transaction, smsTypeConst.const.TZ, {
+                                pid: this.ctx.session.sessionProject.id,
+                                tid: tenderId,
+                                uid: audit.audit_id,
+                                sp_type: 'ledger',
+                                sp_id: audit.id,
+                                table_name: this.tableName,
+                                template: wxConst.template.ledger,
+                                wx_data: wechatData,
                             });
-                            // 微信模板通知
-                            const wechatData = {
-                                status: wxConst.status.success,
-                                tips: wxConst.tips.success,
-                                begin_time: Date.parse(beginAuditors[0].begin_time),
-                            };
-                            await this.ctx.helper.sendWechat(users, smsTypeConst.const.TZ, smsTypeConst.judge.result.toString(), wxConst.template.ledger, wechatData);
-                            // 审批通过 - 检查三方特殊推送
-                            await this.ctx.service.specMsg.addLedgerMsg(transaction, pid, this.ctx.tender, pushOperate.ledger.checked);
                         }
+                    } else {
+                        // 同步标段信息
+                        await transaction.update(this.ctx.service.tender.tableName, {
+                            id: tenderId, ledger_status: auditConst.status.checked,
+                        });
+                        await this.ctx.service.tenderCache.updateLedgerCache(transaction, tenderId, auditConst.status.checked, auditConst.status.checked);
+                        // 审批通过,添加标记
+                        await this.ctx.service.tenderTag.saveTenderTag(tenderId, { ledger_time: time }, transaction);
+                        await this.ctx.helper.sendAliSms(users, smsTypeConst.const.TZ, smsTypeConst.judge.result.toString(), SmsAliConst.template.ledger_result, {
+                            status: SmsAliConst.status.success,
+                        });
+                        // 微信模板通知
+                        const wechatData = {
+                            status: wxConst.status.success,
+                            tips: wxConst.tips.success,
+                            begin_time: Date.parse(beginAuditors[0].begin_time),
+                        };
+                        await this.ctx.helper.sendWechat(users, smsTypeConst.const.TZ, smsTypeConst.judge.result.toString(), wxConst.template.ledger, wechatData);
+                        // 审批通过 - 检查三方特殊推送
+                        await this.ctx.service.specMsg.addLedgerMsg(transaction, pid, this.ctx.tender, pushOperate.ledger.checked);
                     }
-                } else {
-                    // 同步标段信息
-                    await transaction.update(this.ctx.service.tender.tableName, {
-                        id: tenderId, ledger_times: times + 1, ledger_status: checkType,
-                    });
-                    await this.ctx.service.tenderCache.updateLedgerCache(transaction, tenderId, checkType, checkType, [{ audit_id: this.ctx.tender.data.user_id }]);
-                    // 拷贝新一次审核流程列表
-                    const auditors = await this.getAllDataByCondition({
-                        where: { tender_id: tenderId, times },
-                        columns: ['tender_id', 'audit_order', 'audit_id', 'audit_type', 'audit_ledger_id'],
-                    });
-                    const insertAuditors = auditors.map(x => {
-                        return { ...x, times: times + 1, status: auditConst.status.uncheck };
-                    });
-                    await transaction.insert(this.tableName, insertAuditors);
-
-                    await this.ctx.helper.sendAliSms(users, smsTypeConst.const.TZ, smsTypeConst.judge.result.toString(), SmsAliConst.template.ledger_result, {
-                        status: SmsAliConst.status.back,
-                    });
-                    // 微信模板通知
-                    const wechatData = {
-                        status: wxConst.status.back,
-                        tips: wxConst.tips.back,
-                        begin_time: Date.parse(beginAuditors[0].begin_time),
-                    };
-                    await this.ctx.helper.sendWechat(users, smsTypeConst.const.TZ, smsTypeConst.judge.result.toString(), wxConst.template.ledger, wechatData);
                 }
-
                 await transaction.commit();
             } catch (err) {
                 await transaction.rollback();
@@ -645,6 +672,23 @@ module.exports = app => {
 
 
         /**
+         * 审批
+         * @param {Number} tenderId - 标段id
+         * @param {auditConst.status.checked|auditConst.status.checkNo} checkType - 审批结果
+         * @param {String} opinion 审批意见
+         * @param {Number} times - 第几次审批
+         * @return {Promise<void>}
+         */
+        async check(tenderId, checkType, opinion, times = 1) {
+            switch (checkType) {
+                case auditConst.status.checked: await this._checked(tenderId, opinion, times); break;
+                case auditConst.status.checkNo: await this._checkNo(tenderId, opinion, times); break;
+                default: throw '提交数据错误';
+            }
+        }
+
+
+        /**
          * 重新审批
          * @param {Number} tenderId - 标段id
          * @param {Number} times - 第几次审批

+ 202 - 200
app/service/revise_audit.js

@@ -277,7 +277,6 @@ module.exports = app => {
             revise.nextAuditors = revise.curAuditors.length > 0 ? revise.auditors.filter(x => { return x.audit_order === revise.curAuditors[0].audit_order + 1; }) : [];
             revise.nextAuditorIds = this._.map(revise.nextAuditors, 'audit_id');
             revise.auditorGroups = this.ctx.helper.groupAuditors(revise.auditors, 'audit_order');
-            console.log(revise.auditorGroups);
             revise.userGroups = this.ctx.helper.groupAuditorsUniq(revise.auditorGroups);
             revise.userGroups.unshift([{
                 aid: revise.user.id, order: 0, times: revise.times, audit_order: 0, audit_type: auditType.key.common,
@@ -311,7 +310,7 @@ module.exports = app => {
                 const auditorGroups = this.ctx.helper.groupAuditors(auditors, 'audit_order');
                 revise.auditors2 = this.ctx.helper.groupAuditorsUniq(auditorGroups, 'audit_order');
                 revise.auditors2.unshift([{
-                    aid: revise.user.id, order: 0, times: revise.times - 1, audit_order: 0, audit_type: auditConst.auditType.key.common,
+                    aid: revise.user.id, order: 0, times: revise.times - 1, audit_order: 0, audit_type: auditType.key.common,
                     name: revise.user.name, role: revise.user.role, company: revise.user.company
                 }]);
             } else {
@@ -561,243 +560,230 @@ module.exports = app => {
             await transaction.query(pSql, sqlParam);
         }
 
-        /**
-         * 审批
-         * @param {Object} revise - 修订
-         * @param {auditConst.status.checked|auditConst.status.checkNo} checkType - 审批结果
-         * @param {String} opinion - 审批意见
-         * @param {Number} times - 第几次审批
-         * @return {Promise<void>}
-         */
-        async check(revise, checkType, opinion, times = 1) {
-            if (checkType !== auditConst.status.checked && checkType !== auditConst.status.checkNo) throw '提交数据错误';
-            const audit = await this.getDataByCondition({
-                rid: revise.id,
-                times,
-                status: auditConst.status.checking,
-            });
-            if (!audit) throw '审核数据错误';
+        async _checked(revise, opinion, times) {
+            const accountId = this.ctx.session.sessionUser.accountId;
             const pid = this.ctx.session.sessionProject.id;
+            const auditors = await this.getAllDataByCondition({ where: { rid: revise.id, times, status: auditConst.status.checking } });
+            const selfAuditor = auditors.find(x => { return x.audit_id === accountId; });
+            if (!selfAuditor) throw '审核数据错误';
+
+            const flowAuditors = await this.getAllDataByCondition({ where: { rid: revise.id, times, audit_order: selfAuditor.audit_order } });
+            const nextAuditors = await this.getAllDataByCondition({ where: { rid: revise.id, times, audit_order: selfAuditor.audit_order + 1 } });
+            const beginAuditors = await this.getAllDataByCondition({ where: { rid: revise.id, audit_order: 1, times } });
+            const time = new Date();
+
+            const noticeContent = await this.getNoticeContent(pid, selfAuditor.tender_id, revise.id, selfAuditor.audit_id, opinion);
+            const defaultNoticeRecord = { pid, type: pushType.revise, status: auditConst.status.checked, content: noticeContent};
+
             const transaction = await this.db.beginTransaction();
             try {
                 const auditList = await this.getAuditors(revise.id, times);
                 // 审核通过添加到推送表
-                const noticeContent = await this.getNoticeContent(pid, audit.tender_id, audit.rid, audit.audit_id, opinion);
-                const records = [
-                    {
-                        pid,
-                        type: pushType.revise,
-                        uid: revise.uid,
-                        status: checkType,
-                        content: noticeContent,
-                    },
-                ];
+                const records = [ { uid: revise.uid, ...defaultNoticeRecord } ];
                 auditList.forEach(audit => {
-                    records.push({
-                        pid,
-                        type: pushType.revise,
-                        uid: audit.audit_id,
-                        status: checkType,
-                        content: noticeContent,
-                    });
+                    records.push({ uid: audit.audit_id, ...defaultNoticeRecord });
                 });
                 await transaction.insert('zh_notice', records);
 
                 // 整理当前流程审核人状态更新
-                const time = new Date();
                 // 更新当前审核流程
-                await transaction.update(this.tableName, {
-                    id: audit.id,
-                    status: checkType,
-                    opinion,
-                    end_time: time,
-                });
-                await this.ctx.service.noticeAgain.stopNoticeAgain(transaction, this.tableName, audit.id);
-                if (checkType === auditConst.status.checked) {
-                    const nextAudit = await this.getDataByCondition({
-                        rid: revise.id,
-                        times,
-                        audit_order: audit.audit_order + 1,
-                    });
-                    // 无下一审核人表示,审核结束
-                    if (nextAudit) {
-                        await transaction.update(this.tableName, {
-                            id: nextAudit.id,
-                            status: auditConst.status.checking,
-                            begin_time: time,
-                        });
+                await transaction.update(this.tableName, { id: selfAuditor.id, status: auditConst.status.checked, opinion, end_time: time });
+                await this.ctx.service.noticeAgain.stopNoticeAgain(transaction, this.tableName, selfAuditor.id);
+                if (auditors.length === 1 || selfAuditor.audit_type === auditType.key.or) {
+                    // 或签更新他人审批状态
+                    if (selfAuditor.audit_type === auditType.key.or) {
+                        const updateOther = [];
+                        for (const audit of auditors) {
+                            if (audit.audit_id === selfAuditor.audit_id) continue;
+                            updateOther.push({ id: audit.id, status: auditConst.status.checkSkip, opinion: '', end_time: time });
+                        }
+                        if (updateOther.length > 0) {
+                            await this.ctx.service.noticeAgain.stopNoticeAgain(transaction, this.tableName, updateOther.map(x => { return x.id}));
+                            await transaction.updateRows(this.tableName, updateOther);
+                        }
+                    }
+                }
 
-                        // 短信通知-需要审批提醒功能
-                        // 下一人
-                        // await this.ctx.helper.sendUserSms(nextAudit.user_id, smsTypeConst.const.XD,
-                        //     smsTypeConst.judge.approval.toString(), '台账修订需要您审批,请登录系统处理。');
-                        await this.ctx.helper.sendAliSms(nextAudit.audit_id, smsTypeConst.const.XD, smsTypeConst.judge.approval.toString(), SmsAliConst.template.revise_check);
-                        // 微信模板通知
-                        const shenpiUrl = await this.ctx.helper.urlToShort(
-                            this.ctx.protocol + '://' + this.ctx.host + '/wap/tender/' + revise.tid + '/revise/' + revise.id + '/info'
-                        );
-                        const wechatData = {
-                            wap_url: shenpiUrl,
-                            status: wxConst.status.check,
-                            tips: wxConst.tips.check,
-                            code: this.ctx.session.sessionProject.code,
-                            begin_time: Date.parse(revise.begin_time),
-                        };
-                        await this.ctx.helper.sendWechat(nextAudit.audit_id, smsTypeConst.const.XD, smsTypeConst.judge.approval.toString(), wxConst.template.revise, wechatData);
+                // 无下一审核人表示,审核结束
+                if (nextAuditors.length > 0) {
+                    const nextAuditUpdateData = nextAuditors.map(x => { return { id: x.id, status: auditConst.status.checking, begin_time: time }});
+                    await transaction.updateRows(this.tableName, nextAuditUpdateData);
+
+                    // 短信通知-需要审批提醒功能
+                    const nextAuditorIds = nextAuditors.map(x => { return x.audit_id; });
+                    await this.ctx.helper.sendAliSms(nextAuditorIds, smsTypeConst.const.XD, smsTypeConst.judge.approval.toString(), SmsAliConst.template.revise_check);
+                    // 微信模板通知
+                    const shenpiUrl = await this.ctx.helper.urlToShort(
+                        this.ctx.protocol + '://' + this.ctx.host + '/wap/tender/' + revise.tid + '/revise/' + revise.id + '/info'
+                    );
+                    const wechatData = {
+                        wap_url: shenpiUrl,
+                        status: wxConst.status.check,
+                        tips: wxConst.tips.check,
+                        code: this.ctx.session.sessionProject.code,
+                        begin_time: Date.parse(revise.begin_time),
+                    };
+                    await this.ctx.helper.sendWechat(nextAuditorIds, smsTypeConst.const.XD, smsTypeConst.judge.approval.toString(), wxConst.template.revise, wechatData);
+                    for (const audit of nextAuditors) {
                         await this.ctx.service.noticeAgain.addNoticeAgain(transaction, smsTypeConst.const.XD, {
                             pid: this.ctx.session.sessionProject.id,
                             tid: this.ctx.tender.id,
-                            uid: nextAudit.audit_id,
+                            uid: audit.audit_id,
                             sp_type: 'revise',
-                            sp_id: nextAudit.id,
+                            sp_id: audit.id,
                             table_name: this.tableName,
                             template: wxConst.template.revise,
                             wx_data: wechatData,
                         });
-                        // 其他参与人
-                        const users = this._.pull(this._.map(auditList, 'audit_id'), audit.audit_id);
-                        users.push(revise.uid);
-                        // await this.ctx.helper.sendUserSms(users, smsTypeConst.const.XD,
-                        //     smsTypeConst.judge.result.toString(), '台账修订审批通过。');
-                        await this.ctx.helper.sendAliSms(users, smsTypeConst.const.XD, smsTypeConst.judge.result.toString(), SmsAliConst.template.revise_result2, {
-                            status: SmsAliConst.status.success,
-                        });
-
-                        // 微信模板通知
-                        // const wechatData2 = {
-                        //     status: wxConst.status.success,
-                        //     tips: wxConst.tips.success,
-                        //     begin_time: Date.parse(revise.begin_time),
-                        // };
-                        // await this.ctx.helper.sendWechat(users, smsTypeConst.const.XD, smsTypeConst.judge.result.toString(), wxConst.template.revise, wechatData2);
-                    } else {
-                        // 同步修订信息
-                        await transaction.update(this.ctx.service.ledgerRevise.tableName, {
-                            id: revise.id,
-                            status: checkType,
-                            end_time: time,
-                        });
-                        await this.ctx.service.tenderTag.saveTenderTag(revise.tid, {revise_time: new Date()}, transaction);
-                        // 最新一期跟台账相关的缓存数据应过期
-                        const lastStage = await this.ctx.service.stage.getFlowLatestStage(revise.tid, true);
-                        const cacheTime = new Date();
-                        if (lastStage) {
-                            await transaction.update(this.ctx.service.stage.tableName, {
-                                id: lastStage.id,
-                                cache_time_l: cacheTime,
-                                cache_time_r: cacheTime,
-                            });
-                        }
-                        // 重算台账、计量、工程变更
-                        const reviseCalc = new RevisePrice(this.ctx);
-                        const pcTp = await reviseCalc.calcRevise(revise, transaction);
-                        const sum = revise.sum || await this.ctx.service.reviseBills.addUp({
-                            tender_id: revise.tid, /* , is_leaf: true*/
-                        });
-                        await transaction.update(this.ctx.service.tender.tableName, {
-                            id: revise.tid,
-                            total_price: sum.total_price,
-                            deal_tp: sum.deal_tp,
-                        });
-                        // 修订附件取消修订中标记
-                        await transaction.update(this.ctx.service.ledgerAtt.tableName, { revising: 0 }, { where: { revise_id: revise.id } });
-                        await this.ctx.service.tenderCache.updateStageCache4Revise(transaction, revise.tid, sum, pcTp);
-                        // 清除变更新增部位maxLid缓存,防止树结构混乱
-                        await this.ctx.service.changeLedger._removeCacheMaxLid(audit.tender_id);
-                        // 短信通知-审批通过提醒功能
-                        // 下一人
-                        // const msg = '台账修订审批通过,请登录系统处理。';
-                        // await this.ctx.helper.sendUserSms(revise.uid, smsTypeConst.const.XD,
-                        //     smsTypeConst.judge.result.toString(), msg);
-                        await this.ctx.helper.sendAliSms(revise.uid, smsTypeConst.const.XD, smsTypeConst.judge.result.toString(), SmsAliConst.template.revise_result, {
-                            status: SmsAliConst.status.success,
-                        });
-                        // 其他参与人
-                        const users = this._.pull(this._.map(auditList, 'audit_id'), revise.uid);
-                        // await this.ctx.helper.sendUserSms(users, smsTypeConst.const.XD,
-                        //     smsTypeConst.judge.result.toString(), '台账修订审批通过。');
-                        await this.ctx.helper.sendAliSms(users, smsTypeConst.const.XD, smsTypeConst.judge.result.toString(), SmsAliConst.template.revise_result2, {
-                            status: SmsAliConst.status.success,
-                        });
-
-                        users.push(revise.uid);
-
-                        // 微信模板通知
-                        const shenpiUrl = await this.ctx.helper.urlToShort(
-                            this.ctx.protocol + '://' + this.ctx.host + '/wap/tender/' + revise.tid + '/revise/' + revise.id + '/info'
-                        );
-                        const wechatData2 = {
-                            wap_url: shenpiUrl,
-                            status: wxConst.status.success,
-                            tips: wxConst.tips.success,
-                            begin_time: Date.parse(revise.begin_time),
-                            code: this.ctx.session.sessionProject.code,
-                        };
-                        await this.ctx.helper.sendWechat(users, smsTypeConst.const.XD, smsTypeConst.judge.result.toString(), wxConst.template.revise, wechatData2);
-                        // 审批通过 - 检查三方特殊推送
-                        await this.ctx.service.specMsg.addReviseMsg(transaction, pid, revise, pushOperate.ledger.checked);
                     }
+                    const users = this._.map(auditList.filter(x => { return x.audit_id !== accountId}), 'audit_id');
+                    users.push(revise.uid);
+                    await this.ctx.helper.sendAliSms(users, smsTypeConst.const.XD, smsTypeConst.judge.result.toString(), SmsAliConst.template.revise_result2, {
+                        status: SmsAliConst.status.success,
+                    });
                 } else {
                     // 同步修订信息
                     await transaction.update(this.ctx.service.ledgerRevise.tableName, {
-                        id: revise.id,
-                        times: times + 1,
-                        status: checkType,
+                        id: revise.id, status: auditConst.status.checked, end_time: time,
                     });
-                    // 拷贝新一次审核流程列表
-                    const auditors = await this.getAllDataByCondition({
-                        where: { rid: revise.id, times },
-                        columns: ['tender_id', 'rid', 'audit_order', 'audit_id'],
-                    });
-                    for (const a of auditors) {
-                        a.times = times + 1;
-                        a.status = auditConst.status.uncheck;
-                        a.in_time = time;
+                    await this.ctx.service.tenderTag.saveTenderTag(revise.tid, {revise_time: new Date()}, transaction);
+                    // 最新一期跟台账相关的缓存数据应过期
+                    const lastStage = await this.ctx.service.stage.getFlowLatestStage(revise.tid, true);
+                    const cacheTime = new Date();
+                    if (lastStage) {
+                        await transaction.update(this.ctx.service.stage.tableName, {
+                            id: lastStage.id,
+                            cache_time_l: cacheTime,
+                            cache_time_r: cacheTime,
+                        });
                     }
-                    await transaction.insert(this.tableName, auditors);
-                    await transaction.update(this.ctx.service.ledgerHistory.tableName, { id: revise.his_id, valid: 0 });
+                    // 重算台账、计量、工程变更
+                    const reviseCalc = new RevisePrice(this.ctx);
+                    const pcTp = await reviseCalc.calcRevise(revise, transaction);
+                    const sum = revise.sum || await this.ctx.service.reviseBills.addUp({
+                        tender_id: revise.tid, /* , is_leaf: true*/
+                    });
+                    await transaction.update(this.ctx.service.tender.tableName, {
+                        id: revise.tid,
+                        total_price: sum.total_price, deal_tp: sum.deal_tp,
+                    });
+                    // 修订附件取消修订中标记
+                    await transaction.update(this.ctx.service.ledgerAtt.tableName, { revising: 0 }, { where: { revise_id: revise.id } });
+                    // 更新台账缓存
+                    await this.ctx.service.tenderCache.updateStageCache4Revise(transaction, revise.tid, sum, pcTp);
+                    // 清除变更新增部位maxLid缓存,防止树结构混乱
+                    await this.ctx.service.changeLedger._removeCacheMaxLid(audit.tender_id);
 
-                    // 短信通知-审批退回提醒功能
-                    // 下一人
-                    // await this.ctx.helper.sendUserSms(revise.uid, smsTypeConst.const.XD,
-                    //     smsTypeConst.judge.result.toString(), '台账修订审批退回,请登录系统处理。');
+                    // 短信通知-审批通过提醒功能
                     await this.ctx.helper.sendAliSms(revise.uid, smsTypeConst.const.XD, smsTypeConst.judge.result.toString(), SmsAliConst.template.revise_result, {
-                        status: SmsAliConst.status.back,
+                        status: SmsAliConst.status.success,
+                    });
+                    const users = this._.pull(this._.map(auditList, 'audit_id'), revise.uid);
+                    await this.ctx.helper.sendAliSms(users, smsTypeConst.const.XD, smsTypeConst.judge.result.toString(), SmsAliConst.template.revise_result2, {
+                        status: SmsAliConst.status.success,
                     });
+                    users.push(revise.uid);
                     // 微信模板通知
                     const shenpiUrl = await this.ctx.helper.urlToShort(
                         this.ctx.protocol + '://' + this.ctx.host + '/wap/tender/' + revise.tid + '/revise/' + revise.id + '/info'
                     );
-                    const wechatData = {
-                        wap_url: shenpiUrl,
-                        status: wxConst.status.back,
-                        tips: wxConst.tips.back,
-                        begin_time: Date.parse(revise.begin_time),
-                        code: this.ctx.session.sessionProject.code,
-                    };
-                    await this.ctx.helper.sendWechat(revise.uid, smsTypeConst.const.XD, smsTypeConst.judge.result.toString(), wxConst.template.revise, wechatData);
-                    // 其他参与人
-                    // await this.ctx.helper.sendUserSms(this._.map(auditors, 'user_id'),
-                    //     smsTypeConst.const.XD, smsTypeConst.judge.result.toString(), '台账修订审批退回。');
-                    await this.ctx.helper.sendAliSms(
-                        this._.map(auditors, 'user_id'),
-                        smsTypeConst.const.XD,
-                        smsTypeConst.judge.result.toString(),
-                        SmsAliConst.template.revise_result2,
-                        {
-                            status: SmsAliConst.status.back,
-                        }
-                    );
-                    // 微信模板通知
                     const wechatData2 = {
                         wap_url: shenpiUrl,
-                        status: wxConst.status.back,
-                        tips: wxConst.tips.back,
+                        status: wxConst.status.success,
+                        tips: wxConst.tips.success,
                         begin_time: Date.parse(revise.begin_time),
                         code: this.ctx.session.sessionProject.code,
                     };
-                    await this.ctx.helper.sendWechat(this._.map(auditors, 'user_id'), smsTypeConst.const.XD, smsTypeConst.judge.result.toString(), wxConst.template.revise, wechatData2);
+                    await this.ctx.helper.sendWechat(users, smsTypeConst.const.XD, smsTypeConst.judge.result.toString(), wxConst.template.revise, wechatData2);
+                    // 审批通过 - 检查三方特殊推送
+                    await this.ctx.service.specMsg.addReviseMsg(transaction, pid, revise, pushOperate.ledger.checked);
                 }
+                await transaction.commit();
+            } catch (err) {
+                await transaction.rollback();
+                throw err;
+            }
+        }
+
+        async _checkNo(revise, opinion, times) {
+            const accountId = this.ctx.session.sessionUser.accountId;
+            const pid = this.ctx.session.sessionProject.id;
+            let audits = await this.getAllDataByCondition({ where: { rid: revise.id, times, status: auditConst.status.checking } });
+            const selfAuditor = audits.find(x => { return x.audit_id === accountId; });
+            if (!selfAuditor) throw '当前标段您无权审批';
+
+            const beginAuditors = await this.getAllDataByCondition({ where: { rid: revise.id, audit_order: 1, times } });
+            const time = new Date();
+
+            const noticeContent = await this.getNoticeContent(pid, revise.tid, revise.id, accountId, opinion);
+            const defaultNoticeRecord = { pid, type: pushType.revise, status: auditConst.status.checkNo, content: noticeContent };
+
+            // 整理当前流程审核人状态更新 warning(在try catch中写,会报auditors未初始化)
+            const updateAuditData = audits.map(x => {
+                return {
+                    id: x.id,
+                    status: x.audit_id === selfAuditor.audit_id ? auditConst.status.checkNo : auditConst.status.checkSkip,
+                    opinion: x.audit_id === selfAuditor.aid ? opinion : '',
+                    end_time: x.audit_id === selfAuditor.aid ? time : null,
+                };
+            });
+
+            const transaction = await this.db.beginTransaction();
+            try {
+                const auditList = await this.getAuditors(revise.id, times);
+                // 审核通过添加到推送表
+                const records = [{ uid: revise.uid, ...defaultNoticeRecord }];
+                auditList.forEach(audit => {
+                    records.push({ uid: audit.audit_id, ...defaultNoticeRecord });
+                });
+                await transaction.insert('zh_notice', records);
+
+                // 更新当前审核流程
+                await transaction.updateRows(this.tableName, updateAuditData);
+                await this.ctx.service.noticeAgain.stopNoticeAgain(transaction, this.tableName, this._.map(audits, 'id'));
+                // 同步修订信息
+                await transaction.update(this.ctx.service.ledgerRevise.tableName, {
+                    id: revise.id, times: times + 1, status: auditConst.status.checkNo,
+                });
+                // 拷贝新一次审核流程列表
+                const orgAuditors = await this.getAllDataByCondition({
+                    where: { rid: revise.id, times },
+                    columns: ['tender_id', 'rid', 'audit_order', 'audit_id', 'audit_type', 'audit_ledger_id'],
+                });
+                const insertAuditors = orgAuditors.map(x => {
+                    return { ...x, times: times + 1, status: auditConst.status.uncheck, in_time: time };
+                });
+                await transaction.insert(this.tableName, insertAuditors);
+                await transaction.update(this.ctx.service.ledgerHistory.tableName, { id: revise.his_id, valid: 0 });
+
+                // 短信通知-审批退回提醒功能
+                await this.ctx.helper.sendAliSms(revise.uid, smsTypeConst.const.XD, smsTypeConst.judge.result.toString(), SmsAliConst.template.revise_result, {
+                    status: SmsAliConst.status.back,
+                });
+                // 微信模板通知
+                const shenpiUrl = await this.ctx.helper.urlToShort(
+                    this.ctx.protocol + '://' + this.ctx.host + '/wap/tender/' + revise.tid + '/revise/' + revise.id + '/info'
+                );
+                const wechatData = {
+                    wap_url: shenpiUrl,
+                    status: wxConst.status.back,
+                    tips: wxConst.tips.back,
+                    begin_time: Date.parse(revise.begin_time),
+                    code: this.ctx.session.sessionProject.code,
+                };
+                await this.ctx.helper.sendWechat(revise.uid, smsTypeConst.const.XD, smsTypeConst.judge.result.toString(), wxConst.template.revise, wechatData);
+                // 其他参与人
+                const users = this._.map(orgAuditors.filter(x => { return x.audit_id !== accountId; }), 'audit_id');
+                await this.ctx.helper.sendAliSms(users, smsTypeConst.const.XD, smsTypeConst.judge.result.toString(), SmsAliConst.template.revise_result2, {status: SmsAliConst.status.back});
+                // 微信模板通知
+                const wechatData2 = {
+                    wap_url: shenpiUrl,
+                    status: wxConst.status.back,
+                    tips: wxConst.tips.back,
+                    begin_time: Date.parse(revise.begin_time),
+                    code: this.ctx.session.sessionProject.code,
+                };
+                await this.ctx.helper.sendWechat(users, smsTypeConst.const.XD, smsTypeConst.judge.result.toString(), wxConst.template.revise, wechatData2);
 
                 await transaction.commit();
             } catch (err) {
@@ -807,6 +793,22 @@ module.exports = app => {
         }
 
         /**
+         * 审批
+         * @param {Object} revise - 修订
+         * @param {auditConst.status.checked|auditConst.status.checkNo} checkType - 审批结果
+         * @param {String} opinion - 审批意见
+         * @param {Number} times - 第几次审批
+         * @return {Promise<void>}
+         */
+        async check(revise, checkType, opinion, times = 1) {
+            switch (checkType) {
+                case auditConst.status.checked: await this._checked(revise, opinion, times); break;
+                case auditConst.status.checkNo: await this._checkNo(revise, opinion, times); break;
+                default: throw '提交数据错误';
+            }
+        }
+
+        /**
          * 取待审批修订列表(wap用)
          *
          * @param auditorId

+ 3 - 15
app/view/revise/info_modal.ejs

@@ -142,8 +142,7 @@
     <<!--审批通过-->
     <div class="modal fade sp-location-list" id="sp-done" data-backdrop="static">
         <div class="modal-dialog modal-lg" role="document">
-            <form class="modal-content" action="/tender/<%- ctx.tender.id %>/revise/audit/check" method="post"
-                onsubmit="return auditCheck(0);">
+            <form class="modal-content" action="/tender/<%- ctx.tender.id %>/revise/audit/check" method="post" onsubmit="return auditCheck(0);">
                 <div class="modal-header">
                     <h5 class="modal-title">审批通过</h5>
                 </div>
@@ -320,8 +319,7 @@
     <!--审批退回-->
     <div class="modal fade sp-location-list" id="sp-back" data-backdrop="static">
         <div class="modal-dialog modal-lg" role="document">
-            <form class="modal-content modal-lg" action="/tender/<%- ctx.tender.id %>/revise/audit/check" method="post"
-                onsubmit="return auditCheck(1);">
+            <form class="modal-content modal-lg" action="/tender/<%- ctx.tender.id %>/revise/audit/check" method="post" onsubmit="return auditCheck(1);">
                 <div class="modal-header">
                     <h5 class="modal-title">审批退回</h5>
                 </div>
@@ -488,6 +486,7 @@
                 <div class="modal-footer">
                     <button type="button" class="btn btn-secondary btn-sm" data-dismiss="modal">关闭</button>
                     <input type="hidden" name="_csrf_j" value="<%= ctx.csrf %>" />
+                    <input type="hidden" name="checkType" value="<%= auditConst.status.checkNo %>" />
                     <button type="submit" class="btn btn-warning btn-sm">确认退回</button>
                 </div>
             </form>
@@ -865,19 +864,8 @@
 
         // texterea换行
         function auditCheck(i) {
-            const inlineRadio1 = $('#inlineRadio1:checked').val()
-            const inlineRadio2 = $('#inlineRadio2:checked').val()
             const opinion = $('textarea[name="opinion"]').eq(i).val().replace(/\r\n/g, '<br/>').replace(/\n/g, '<br/>').replace(/\s/g, ' ');
             $('textarea[name="opinion"]').eq(i).val(opinion);
-            if (i === 1) {
-                if (!inlineRadio1 && !inlineRadio2) {
-                    if (!$('#warning-text').length) {
-                        $('#reject-process').prepend('<p id="warning-text" style="color: red; margin: 0;">请选择退回流程</p>');
-                    }
-                    return false;
-                }
-                if ($('#warning-text').length) $('#warning-text').remove()
-            }
             return true;
         }
         $('.sp-location-list').on('shown.bs.modal', function () {