|
@@ -9,6 +9,7 @@
|
|
|
*/
|
|
|
|
|
|
const auditConst = require('../const/audit').revise;
|
|
|
+const auditType = require('../const/audit').auditType;
|
|
|
const smsTypeConst = require('../const/sms_type');
|
|
|
const SmsAliConst = require('../const/sms_alitemplate');
|
|
|
const wxConst = require('../const/wechat_template');
|
|
@@ -47,6 +48,52 @@ module.exports = app => {
|
|
|
return await this.db.queryOne(sql, sqlParam);
|
|
|
}
|
|
|
|
|
|
+ async getAuditorByOrder(reviseId, order, times = 1) {
|
|
|
+ const sql = 'SELECT la.`audit_id`, pa.`name`, pa.`company`, pa.`role`, pa.`mobile`, pa.`telephone`, la.`times`, la.`audit_order`, la.`audit_type`, la.`audit_ledger_id`, la.`status`, la.`opinion`, la.`begin_time`, la.`end_time` ' +
|
|
|
+ ' FROM ?? AS la Left Join ?? AS pa ON la.`audit_id` = pa.`id`' +
|
|
|
+ ' WHERE la.`rid` = ? and la.`audit_order` = ? and la.`times` = ?';
|
|
|
+ const sqlParam = [this.tableName, this.ctx.service.projectAccount.tableName, reviseId, order, times];
|
|
|
+ return await this.db.queryOne(sql, sqlParam);
|
|
|
+ }
|
|
|
+
|
|
|
+ async getAuditorsByOrder(reviseId, order, times) {
|
|
|
+ const sql =
|
|
|
+ 'SELECT la.`audit_id`, pa.`name`, pa.`company`, pa.`role`, pa.`mobile`, pa.`telephone`,' +
|
|
|
+ ' la.`times`, la.`audit_order`, la.`status`, la.`opinion`, la.`begin_time`, la.`end_time`, la.audit_type, la.audit_ledger_id ' +
|
|
|
+ ' FROM ' + this.tableName + ' AS la' +
|
|
|
+ ' Left Join ' + this.ctx.service.projectAccount.tableName + ' AS pa ON la.`audit_id` = pa.`id`' +
|
|
|
+ ' WHERE la.`rid` = ? and la.`audit_order` = ? and la.`times` = ?' +
|
|
|
+ ' ORDER BY `audit_order` DESC';
|
|
|
+ const sqlParam = [reviseId, order, times ? times: 1];
|
|
|
+ return await this.db.query(sql, sqlParam);
|
|
|
+ }
|
|
|
+
|
|
|
+ async getLatestAuditor(reviseId, times, status) {
|
|
|
+ const sql =
|
|
|
+ 'SELECT la.`audit_id`, pa.`name`, pa.`company`, pa.`role`, pa.`mobile`, pa.`telephone`,' +
|
|
|
+ ' la.`times`, la.`audit_order`, la.`audit_type`, la.`audit_ledger_id`, la.`status`, la.`opinion`, la.`begin_time`, la.`end_time` ' +
|
|
|
+ ' FROM ' + this.tableName + ' AS la' +
|
|
|
+ ' Left Join ' + this.ctx.service.projectAccount.tableName + ' AS pa ON la.`audit_id` = pa.`id`' +
|
|
|
+ ' WHERE la.`rid` = ? and la.`status` = ? and la.`times` = ?' +
|
|
|
+ ' ORDER BY `audit_order` DESC';
|
|
|
+ const sqlParam = [reviseId, status, times ? times : 1];
|
|
|
+ return await this.db.queryOne(sql, sqlParam);
|
|
|
+ }
|
|
|
+
|
|
|
+ async getLatestAuditors(reviseId, times, status) {
|
|
|
+ const sql =
|
|
|
+ 'SELECT la.`audit_id`, pa.`name`, pa.`company`, pa.`role`, pa.`mobile`, pa.`telephone`, la.audit_type, la.audit_order, la.audit_ledger_id,' +
|
|
|
+ ' la.`times`, la.`audit_order`, la.`status`, la.`opinion`, la.`begin_time`, la.`end_time` ' +
|
|
|
+ ' FROM ' + this.tableName + ' AS la' +
|
|
|
+ ' Left Join ' + this.ctx.service.projectAccount.tableName + ' AS pa ON la.`audit_id` = pa.`id`' +
|
|
|
+ ' WHERE la.`rid` = ? and la.`status` = ? and la.`times` = ?' +
|
|
|
+ ' ORDER BY `audit_order` DESC';
|
|
|
+ const sqlParam = [reviseId, status, times ? times: 1];
|
|
|
+ const result = await this.db.query(sql, sqlParam);
|
|
|
+ if (result.length === 0) return [];
|
|
|
+ return result.filter(x => { return x.audit_order === result[0].audit_order });
|
|
|
+ }
|
|
|
+
|
|
|
/**
|
|
|
* 获取标段审核列表信息
|
|
|
*
|
|
@@ -54,16 +101,19 @@ module.exports = app => {
|
|
|
* @param {Number} times - 第几次审批
|
|
|
* @return {Promise<*>}
|
|
|
*/
|
|
|
- async getAuditors(reviseId, times = 1) {
|
|
|
- const sql =
|
|
|
- 'SELECT la.`audit_id`, la.`times`, la.`audit_order`, la.`status`, la.`opinion`, la.`begin_time`, la.`end_time`,' +
|
|
|
- ' pa.`name`, pa.`company`, pa.`role`, pa.`mobile`, pa.`telephone`' +
|
|
|
- ' FROM ' + this.tableName + ' AS la ' +
|
|
|
- ' INNER JOIN ' + this.ctx.service.projectAccount.tableName +
|
|
|
- ' AS pa ON la.`rid` = ? and la.`times` = ? and la.`audit_id` = pa.`id`' +
|
|
|
- ' ORDER BY la.`audit_order`';
|
|
|
+ async getAuditors(reviseId, times = 1, order_sort = 'asc') {
|
|
|
+ const sql = 'SELECT la.id, la.audit_id, la.times, la.audit_order, la.audit_type, la.audit_ledger_id, la.status, la.opinion, la.begin_time, la.end_time, ' +
|
|
|
+ ' pa.name, pa.company, pa.role, pa.mobile, pa.telephone, pa.sign_path' +
|
|
|
+ ` FROM ${this.tableName} la LEFT JOIN ${this.ctx.service.projectAccount.tableName} pa ON la.audit_id = pa.id` +
|
|
|
+ ' WHERE la.rid = ? AND la.times = ?' +
|
|
|
+ ' ORDER BY la.audit_order ' + order_sort;
|
|
|
const sqlParam = [reviseId, times];
|
|
|
- return await this.db.query(sql, sqlParam);
|
|
|
+ const result = await this.db.query(sql, sqlParam);
|
|
|
+ const max_sort = this._.max(result.map(x => { return x.audit_order; }));
|
|
|
+ for (const i in result) {
|
|
|
+ result[i].max_sort = max_sort;
|
|
|
+ }
|
|
|
+ return result;
|
|
|
}
|
|
|
|
|
|
/**
|
|
@@ -105,6 +155,172 @@ module.exports = app => {
|
|
|
return await this.db.queryOne(sql, sqlParam);
|
|
|
}
|
|
|
|
|
|
+ async getCurAuditors(reviseId, times = 1) {
|
|
|
+ const sql =
|
|
|
+ 'SELECT la.`audit_id`, pa.`name`, pa.`company`, pa.`role`, pa.`mobile`, pa.`telephone`, la.`times`, la.`audit_order`, la.`status`, la.`opinion`, la.`begin_time`, la.`end_time`, la.audit_type, la.audit_order, la.audit_ledger_id ' +
|
|
|
+ ' FROM ?? AS la Left Join ?? AS pa On la.`audit_id` = pa.`id`' +
|
|
|
+ ' WHERE la.`rid` = ? and la.`status` = ? and la.`times` = ?';
|
|
|
+ const sqlParam = [this.tableName, this.ctx.service.projectAccount.tableName, reviseId, auditConst.status.checking, times];
|
|
|
+ return await this.db.query(sql, sqlParam);
|
|
|
+ }
|
|
|
+
|
|
|
+ async getAuditorGroup(reviseId, times) {
|
|
|
+ const auditors = await this.getAuditors(reviseId, times); // 全部参与的审批人
|
|
|
+ return this.ctx.helper.groupAuditors(auditors, 'audit_order');
|
|
|
+ }
|
|
|
+
|
|
|
+ async getUserGroup(reviseId, times) {
|
|
|
+ const group = await this.getAuditorGroup(reviseId, times);
|
|
|
+ const sql =
|
|
|
+ 'SELECT pa.`id` As audit_id, pa.`name`, pa.`company`, pa.`role`, ? As times, ? As rid, 0 As audit_order, 1 As audit_type' +
|
|
|
+ ' FROM ' + this.ctx.service.ledgerRevise.tableName + ' As r' +
|
|
|
+ ' LEFT JOIN ' + this.ctx.service.projectAccount.tableName + ' As pa' +
|
|
|
+ ' ON r.uid = pa.id' +
|
|
|
+ ' WHERE r.id = ?';
|
|
|
+ const sqlParam = [times, reviseId, reviseId];
|
|
|
+ const user = await this.db.queryOne(sql, sqlParam);
|
|
|
+ group.unshift([ user ]);
|
|
|
+ return group;
|
|
|
+ }
|
|
|
+
|
|
|
+ async getUniqUserGroup(reviseId, times) {
|
|
|
+ const group = await this.getAuditorGroup(reviseId, times);
|
|
|
+ const sql =
|
|
|
+ 'SELECT pa.`id` As audit_id, pa.`name`, pa.`company`, pa.`role`, ? As times, ? As rid, 0 As audit_order, 1 As audit_type' +
|
|
|
+ ' FROM ' + this.ctx.service.ledgerRevise.tableName + ' As r' +
|
|
|
+ ' LEFT JOIN ' + this.ctx.service.projectAccount.tableName + ' As pa' +
|
|
|
+ ' ON r.uid = pa.id' +
|
|
|
+ ' WHERE r.id = ?';
|
|
|
+ const sqlParam = [times, reviseId, reviseId];
|
|
|
+ const user = await this.db.queryOne(sql, sqlParam);
|
|
|
+ group.unshift([ user ]);
|
|
|
+ return this.ctx.helper.groupAuditorsUniq(group, 'audit_order');
|
|
|
+ }
|
|
|
+
|
|
|
+ async getAuditorHistory(reviseId, times, reverse = false) {
|
|
|
+ const history = [];
|
|
|
+ if (times >= 1) {
|
|
|
+ for (let i = 1; i <= times; i++) {
|
|
|
+ const auditors = await this.getAuditors(reviseId, i);
|
|
|
+ const group = this.ctx.helper.groupAuditors(auditors, 'audit_order');
|
|
|
+ const historyGroup = [];
|
|
|
+ const max_order = group.length > 0 && group[group.length - 1].length > 0 ? group[group.length - 1][0].audit_order : -1;
|
|
|
+ for (const g of group) {
|
|
|
+ const his = {
|
|
|
+ beginYear: '', beginDate: '', beginTime: '', endYear: '', endDate: '', endTime: '', begin_time: null, end_time: null,
|
|
|
+ audit_type: g[0].audit_type, audit_order: g[0].audit_order,
|
|
|
+ auditors: g
|
|
|
+ };
|
|
|
+ if (his.audit_type === auditType.key.common) {
|
|
|
+ his.name = g[0].name;
|
|
|
+ } else {
|
|
|
+ his.name = this.ctx.helper.transFormToChinese(his.audit_order) + '审';
|
|
|
+ }
|
|
|
+ his.is_final = his.audit_order === max_order;
|
|
|
+ if (g[0].begin_time) {
|
|
|
+ his.begin_time = g[0].begin_time;
|
|
|
+ const beginTime = this.ctx.moment(g[0].begin_time);
|
|
|
+ his.beginYear = beginTime.format('YYYY');
|
|
|
+ his.beginDate = beginTime.format('MM-DD');
|
|
|
+ his.beginTime = beginTime.format('HH:mm:ss');
|
|
|
+ }
|
|
|
+ let end_time;
|
|
|
+ g.forEach(x => {
|
|
|
+ if (x.status === auditConst.status.checkSkip) return;
|
|
|
+ if (!his.status || x.status === auditConst.status.checking) his.status = x.status;
|
|
|
+ if (x.end_time && (!end_time || x.end_time > end_time)) {
|
|
|
+ end_time = x.end_time;
|
|
|
+ if (his.status !== auditConst.status.checking) his.status = x.status;
|
|
|
+ }
|
|
|
+ });
|
|
|
+ if (end_time) {
|
|
|
+ his.end_time = end_time;
|
|
|
+ const endTime = this.ctx.moment(end_time);
|
|
|
+ his.endYear = endTime.format('YYYY');
|
|
|
+ his.endDate = endTime.format('MM-DD');
|
|
|
+ his.endTime = endTime.format('HH:mm:ss');
|
|
|
+ }
|
|
|
+ historyGroup.push(his);
|
|
|
+ }
|
|
|
+ if (reverse) {
|
|
|
+ history.push(historyGroup.reverse());
|
|
|
+ } else {
|
|
|
+ history.push(historyGroup);
|
|
|
+ }
|
|
|
+ }
|
|
|
+ }
|
|
|
+ return history;
|
|
|
+ }
|
|
|
+
|
|
|
+ async getUniqAuditor(reviseId, times) {
|
|
|
+ const auditors = await this.getAuditors(reviseId, times); // 全部参与的审批人
|
|
|
+ const result = [];
|
|
|
+ auditors.forEach(x => {
|
|
|
+ if (result.findIndex(r => { return x.audit_id === r.audit_id && x.audit_order === r.audit_order; }) < 0) {
|
|
|
+ result.push(x);
|
|
|
+ }
|
|
|
+ });
|
|
|
+ return result;
|
|
|
+ }
|
|
|
+
|
|
|
+ async loadReviseUser(revise) {
|
|
|
+ const status = auditConst.status;
|
|
|
+ const accountId = this.ctx.session.sessionUser.accountId;
|
|
|
+
|
|
|
+ revise.user = await this.ctx.service.projectAccount.getAccountInfoById(revise.uid);
|
|
|
+ revise.auditors = await this.getAuditors(revise.id, revise.times); // 全部参与的审批人
|
|
|
+ revise.auditorIds = this._.map(revise.auditors, 'audit_id');
|
|
|
+ revise.curAuditors = revise.auditors.filter(x => { return x.status === status.checking; }); // 当前流程中审批中的审批人
|
|
|
+ revise.curAuditorIds = this._.map(revise.curAuditors, 'audit_id');
|
|
|
+ revise.flowAuditors = revise.curAuditors.length > 0 ? revise.auditors.filter(x => { return x.audit_order === revise.curAuditors[0].audit_order; }) : []; // 当前流程中参与的审批人(包含会签时,审批通过的人)
|
|
|
+ revise.flowAuditorIds = this._.map(revise.flowAuditors, 'audit_id');
|
|
|
+ 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');
|
|
|
+ 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,
|
|
|
+ name: revise.user.name, role: revise.user.role, company: revise.user.company
|
|
|
+ }]);
|
|
|
+ revise.finalAuditorIds = revise.userGroups[revise.userGroups.length - 1].map(x => { return x.aid; });
|
|
|
+ revise.relaAuditor = revise.auditors.find(x => { return x.aid === accountId });
|
|
|
+
|
|
|
+ revise.assists = [];// await this.service.ledgerAuditAss.getData(tender); // 全部协同人
|
|
|
+ revise.assists = revise.assists.filter(x => {
|
|
|
+ return x.user_id === revise.uid || revise.auditorIds.indexOf(x.uid) >= 0;
|
|
|
+ }); // 过滤无效协同人
|
|
|
+ revise.userAssists = revise.assists.filter(x => { return x.user_id === revise.uid; }); // 原报协同人
|
|
|
+ revise.userAssistIds = this._.map(revise.userAssists, 'ass_user_id');
|
|
|
+ revise.auditAssists = revise.assists.filter(x => { return x.user_id !== revise.uid; }); // 审批协同人
|
|
|
+ revise.auditAssistIds = this._.map(revise.auditAssists, 'ass_user_id');
|
|
|
+ revise.relaAssists = revise.assists.filter(x => { return x.user_id === accountId }); // 登录人的协同人
|
|
|
+ revise.userIds = revise.status === status.uncheck // 当前流程下全部参与人id
|
|
|
+ ? [revise.user_id, ...revise.userAssistIds]
|
|
|
+ : [revise.user_id, ...revise.userAssistIds, ...revise.auditorIds, ...revise.auditAssistIds];
|
|
|
+ }
|
|
|
+
|
|
|
+ async loadReviseAuditViewData(revise) {
|
|
|
+ const times = revise.status === auditConst.status.checkNo ? revise.times - 1 : revise.times;
|
|
|
+
|
|
|
+ if (!revise.user) revise.user = await this.ctx.service.projectAccount.getAccountInfoById(revise.uid);
|
|
|
+ revise.auditHistory = await this.getAuditorHistory(revise.id, times);
|
|
|
+ // 获取审批流程中左边列表
|
|
|
+ if (revise.status === auditConst.status.checkNo && revise.user_id !== this.ctx.session.sessionUser.accountId) {
|
|
|
+ const auditors = await this.getAuditors(revise.id, times); // 全部参与的审批人
|
|
|
+ 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: auditType.key.common,
|
|
|
+ name: revise.user.name, role: revise.user.role, company: revise.user.company
|
|
|
+ }]);
|
|
|
+ } else {
|
|
|
+ revise.auditors2 = revise.userGroups;
|
|
|
+ }
|
|
|
+ if (revise.status === auditConst.status.uncheck || revise.status === auditConst.status.checkNo) {
|
|
|
+ revise.auditorList = await this.getAuditors(revise.id, revise.times);
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
/**
|
|
|
* 获取最新审核顺序
|
|
|
*
|
|
@@ -222,8 +438,8 @@ module.exports = app => {
|
|
|
* @return {Promise<boolean>}
|
|
|
*/
|
|
|
async start(revise, times = 1) {
|
|
|
- const audit = await this.getDataByCondition({ rid: revise.id, times, audit_order: 1 });
|
|
|
- if (!audit) {
|
|
|
+ const audits = await this.getAllDataByCondition({ where: { rid: revise.id, times, audit_order: 1 } });
|
|
|
+ if (!audits.length === 0) {
|
|
|
if(this.ctx.tender.info.shenpi.revise === shenpiConst.sp_status.gdspl) {
|
|
|
throw '请联系管理员添加审批人';
|
|
|
} else {
|
|
@@ -237,21 +453,17 @@ module.exports = app => {
|
|
|
|
|
|
const transaction = await this.db.beginTransaction();
|
|
|
try {
|
|
|
- await transaction.update(this.tableName, {
|
|
|
- id: audit.id,
|
|
|
- status: auditConst.status.checking,
|
|
|
- begin_time: time,
|
|
|
- bills_file: revise.bills_file,
|
|
|
- pos_file: revise.pos_file,
|
|
|
- });
|
|
|
+ const updateAuditData = audits.map(a => { return {
|
|
|
+ id: a.id, status: auditConst.status.checking, begin_time: time,
|
|
|
+ bills_file: revise.bills_file, pos_file: revise.pos_file
|
|
|
+ }; });
|
|
|
+ await transaction.updateRows(this.tableName, updateAuditData);
|
|
|
const reviseData = {
|
|
|
id: revise.id,
|
|
|
status: auditConst.status.checking,
|
|
|
his_id, sum: JSON.stringify(sum),
|
|
|
};
|
|
|
- if (revise.times === 1) {
|
|
|
- reviseData.begin_time = time;
|
|
|
- }
|
|
|
+ if (revise.times === 1) reviseData.begin_time = time;
|
|
|
await transaction.update(this.ctx.service.ledgerRevise.tableName, reviseData);
|
|
|
|
|
|
// 投资进度改变状态
|
|
@@ -261,7 +473,8 @@ module.exports = app => {
|
|
|
// 下一人
|
|
|
// await this.ctx.helper.sendUserSms(audit.audit_id, smsTypeConst.const.XD,
|
|
|
// smsTypeConst.judge.approval.toString(), '台账修订需要您审批,请登录系统处理。');
|
|
|
- await this.ctx.helper.sendAliSms(audit.audit_id, smsTypeConst.const.XD, smsTypeConst.judge.approval.toString(), SmsAliConst.template.revise_check);
|
|
|
+ const auditorIds = audits.map(x => { return x.audit_id; });
|
|
|
+ await this.ctx.helper.sendAliSms(auditorIds, 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'
|
|
@@ -273,20 +486,22 @@ module.exports = app => {
|
|
|
code: this.ctx.session.sessionProject.code,
|
|
|
begin_time: Date.parse(time),
|
|
|
};
|
|
|
- await this.ctx.helper.sendWechat(audit.audit_id, smsTypeConst.const.XD, smsTypeConst.judge.approval.toString(), wxConst.template.revise, wechatData);
|
|
|
- await this.ctx.service.noticeAgain.addNoticeAgain(transaction, smsTypeConst.const.XD, {
|
|
|
- pid: this.ctx.session.sessionProject.id,
|
|
|
- tid: this.ctx.tender.id,
|
|
|
- uid: audit.audit_id,
|
|
|
- sp_type: 'revise',
|
|
|
- sp_id: audit.id,
|
|
|
- table_name: this.tableName,
|
|
|
- template: wxConst.template.revise,
|
|
|
- wx_data: wechatData,
|
|
|
- });
|
|
|
+ await this.ctx.helper.sendWechat(auditorIds, smsTypeConst.const.XD, smsTypeConst.judge.approval.toString(), wxConst.template.revise, wechatData);
|
|
|
+ for (const audit of audits) {
|
|
|
+ await this.ctx.service.noticeAgain.addNoticeAgain(transaction, smsTypeConst.const.XD, {
|
|
|
+ pid: this.ctx.session.sessionProject.id,
|
|
|
+ tid: this.ctx.tender.id,
|
|
|
+ uid: audit.audit_id,
|
|
|
+ sp_type: 'revise',
|
|
|
+ sp_id: audit.id,
|
|
|
+ table_name: this.tableName,
|
|
|
+ template: wxConst.template.revise,
|
|
|
+ wx_data: wechatData,
|
|
|
+ });
|
|
|
+ }
|
|
|
// 其他参与人
|
|
|
const auditList = await this.getAuditors(revise.id, times);
|
|
|
- const users = this._.pull(this._.map(auditList, 'user_id'), audit.audit_id);
|
|
|
+ const users = this._.map(auditList.filter(x => { return auditorIds.indexOf(x.audit_id) < 0; }, 'audit_id'));
|
|
|
// 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_report);
|
|
@@ -345,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,
|
|
|
- });
|
|
|
- // 拷贝新一次审核流程列表
|
|
|
- const auditors = await this.getAllDataByCondition({
|
|
|
- where: { rid: revise.id, times },
|
|
|
- columns: ['tender_id', 'rid', 'audit_order', 'audit_id'],
|
|
|
+ id: revise.id, status: auditConst.status.checked, end_time: time,
|
|
|
});
|
|
|
- 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) {
|
|
@@ -591,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
|
|
@@ -808,20 +1026,19 @@ module.exports = app => {
|
|
|
return this.db.query(sql, sqlParam);
|
|
|
}
|
|
|
|
|
|
- async updateNewAuditList(revise, newIdList) {
|
|
|
+ async updateNewAuditList(revise, newList) {
|
|
|
const transaction = await this.db.beginTransaction();
|
|
|
try {
|
|
|
// 先删除旧的审批流,再添加新的
|
|
|
await transaction.delete(this.tableName, { rid: revise.id, times: revise.times });
|
|
|
const newAuditors = [];
|
|
|
- let order = 1;
|
|
|
- for (const aid of newIdList) {
|
|
|
+ const in_time = new Date();
|
|
|
+ for (const auditor of newList) {
|
|
|
newAuditors.push({
|
|
|
- tender_id: revise.tid, audit_id: aid,
|
|
|
- times: revise.times, audit_order: order, status: auditConst.status.uncheck,
|
|
|
- rid: revise.id,in_time: new Date(),
|
|
|
- });
|
|
|
- order++;
|
|
|
+ tender_id: revise.tid, audit_id: auditor.audit_id, rid: revise.id, in_time,
|
|
|
+ times: revise.times, audit_order: auditor.audit_order, status: auditConst.status.uncheck,
|
|
|
+ audit_type: auditor.audit_type, audit_ledger_id: auditor.audit_type === auditType.key.union ? auditor.audit_ledger_id : '',
|
|
|
+ })
|
|
|
}
|
|
|
if(newAuditors.length > 0) await transaction.insert(this.tableName, newAuditors);
|
|
|
await transaction.commit();
|
|
@@ -835,14 +1052,22 @@ module.exports = app => {
|
|
|
const transaction = await this.db.beginTransaction();
|
|
|
try {
|
|
|
// 先判断auditList里的aid是否与lastId相同,相同则删除并重新更新order
|
|
|
- const idList = this._.map(auditList, 'audit_id');
|
|
|
- let order = idList.length + 1;
|
|
|
- if (idList.indexOf(lastId) !== -1) {
|
|
|
- await transaction.delete(this.tableName, { rid: revise.id, times: revise.times, audit_id: lastId });
|
|
|
- const audit = this._.find(auditList, { 'audit_id': lastId });
|
|
|
- // 顺移之后审核人流程顺序
|
|
|
- await this._syncOrderByDelete(transaction, revise.id, audit.audit_order, revise.times);
|
|
|
- order = order - 1;
|
|
|
+ const existAudit = auditList.find(x => { return x.aid === lastId });
|
|
|
+ let order = auditList.length > 0 ? auditList.reduce((rst, a) => { return Math.max(rst, a.audit_order)}, 0) + 1 : 1; // 最大值 + 1
|
|
|
+ if (existAudit) {
|
|
|
+ await transaction.delete(this.tableName, { sid: stage.id, times: stage.times, audit_id: lastId });
|
|
|
+ const sameOrder = auditList.filter(x => { return x.audit_order === existAudit.audit_order });
|
|
|
+ if (sameOrder.length === 1) {
|
|
|
+ const updateData = [];
|
|
|
+ auditList.forEach(x => {
|
|
|
+ if (x.audit_order <= existAudit.audit_order) return;
|
|
|
+ updateData.push({id: x.id, audit_order: x.audit_order - 1});
|
|
|
+ });
|
|
|
+ if (updateData.length > 0) {
|
|
|
+ await transaction.updateRows(updateData);
|
|
|
+ }
|
|
|
+ order = order - 1;
|
|
|
+ }
|
|
|
}
|
|
|
|
|
|
// 添加终审
|