|
@@ -9,6 +9,7 @@
|
|
|
*/
|
|
|
|
|
|
const auditConst = require('../const/audit').ledger;
|
|
|
+const auditType = require('../const/audit').auditType;
|
|
|
const smsTypeConst = require('../const/sms_type');
|
|
|
const SMS = require('../lib/sms');
|
|
|
const SmsAliConst = require('../const/sms_alitemplate');
|
|
@@ -30,6 +31,7 @@ module.exports = app => {
|
|
|
this.tableName = 'ledger_audit';
|
|
|
}
|
|
|
|
|
|
+
|
|
|
/**
|
|
|
* 获取标段审核人信息
|
|
|
*
|
|
@@ -39,7 +41,7 @@ module.exports = app => {
|
|
|
* @return {Promise<*>}
|
|
|
*/
|
|
|
async getAuditor(tenderId, auditorId, 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` ' +
|
|
|
+ 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.`tender_id` = ? and la.`audit_id` = ? and la.`times` = ?';
|
|
|
const sqlParam = [this.tableName, this.ctx.service.projectAccount.tableName, tenderId, auditorId, times];
|
|
@@ -47,17 +49,29 @@ module.exports = app => {
|
|
|
}
|
|
|
|
|
|
async getAuditorByOrder(tenderId, 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.`status`, la.`opinion`, la.`begin_time`, la.`end_time` ' +
|
|
|
+ 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.`tender_id` = ? and la.`audit_order` = ? and la.`times` = ?';
|
|
|
const sqlParam = [this.tableName, this.ctx.service.projectAccount.tableName, tenderId, order, times];
|
|
|
return await this.db.queryOne(sql, sqlParam);
|
|
|
}
|
|
|
|
|
|
+ async getAuditorsByOrder(tenderId, 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.`tender_id` = ? and la.`audit_order` = ? and la.`times` = ?' +
|
|
|
+ ' ORDER BY `audit_order` DESC';
|
|
|
+ const sqlParam = [tenderId, order, times ? times: 1];
|
|
|
+ return await this.db.query(sql, sqlParam);
|
|
|
+ }
|
|
|
+
|
|
|
async getLastestAuditor(tenderId, times, status) {
|
|
|
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.`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.`tender_id` = ? and la.`status` = ? and la.`times` = ?' +
|
|
@@ -66,44 +80,239 @@ module.exports = app => {
|
|
|
return await this.db.queryOne(sql, sqlParam);
|
|
|
}
|
|
|
|
|
|
+ async getLastestAuditors(tenderId, 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.`tender_id` = ? and la.`status` = ? and la.`times` = ?' +
|
|
|
+ ' ORDER BY `audit_order` DESC';
|
|
|
+ const sqlParam = [tenderId, 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 });
|
|
|
+ }
|
|
|
+
|
|
|
/**
|
|
|
- * 获取标段审核人最后一位的名称
|
|
|
+ * 获取标段审核列表信息
|
|
|
*
|
|
|
* @param {Number} tenderId - 标段id
|
|
|
- * @param {Number} auditorId - 审核人id
|
|
|
* @param {Number} times - 第几次审批
|
|
|
* @return {Promise<*>}
|
|
|
*/
|
|
|
- async getStatusName(tenderId, times) {
|
|
|
- const sql = 'SELECT pa.`name` FROM ?? AS la Left Join ?? AS pa ON la.`audit_id` = pa.`id`' +
|
|
|
- ' WHERE la.`tender_id` = ? and la.`status` != ? ORDER BY la.`times` DESC, la.`audit_order` DESC';
|
|
|
- const sqlParam = [this.tableName, this.ctx.service.projectAccount.tableName, tenderId, auditConst.status.uncheck];
|
|
|
- return await this.db.queryOne(sql, sqlParam);
|
|
|
+ async getAuditors(tenderId, 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.tender_id = ? AND la.times = ?' +
|
|
|
+ ' ORDER BY la.audit_order ' + order_sort;
|
|
|
+ const sqlParam = [tenderId, times];
|
|
|
+ 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;
|
|
|
}
|
|
|
|
|
|
/**
|
|
|
- * 获取标段审核列表信息
|
|
|
+ * 获取标段当前审核人
|
|
|
*
|
|
|
* @param {Number} tenderId - 标段id
|
|
|
* @param {Number} times - 第几次审批
|
|
|
* @return {Promise<*>}
|
|
|
*/
|
|
|
- async getAuditors(tenderId, times = 1) {
|
|
|
+ async getCurAuditor(tenderId, 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`, g.`sort` ' +
|
|
|
- 'FROM ?? AS la, ?? AS pa, (SELECT t1.`audit_id`,(@i:=@i+1) as `sort` FROM (SELECT t.`audit_id`, t.`audit_order` FROM (select `audit_id`, `audit_order` from ?? WHERE `tender_id` = ? AND `times` = ? ORDER BY `audit_order` LIMIT 200) t GROUP BY t.`audit_id` ORDER BY t.`audit_order`) t1, (select @i:=0) as it) as g ' +
|
|
|
- 'WHERE la.`tender_id` = ? and la.`times` = ? and la.`audit_id` = pa.`id` and g.`audit_id` = la.`audit_id` order by la.`audit_order`';
|
|
|
- const sqlParam = [this.tableName, this.ctx.service.projectAccount.tableName, this.tableName, tenderId, times, tenderId, times];
|
|
|
- const result = await this.db.query(sql, sqlParam);
|
|
|
- const sql2 = 'SELECT COUNT(a.`audit_id`) as num FROM (SELECT `audit_id` FROM ?? WHERE `tender_id` = ? AND `times` = ? GROUP BY `audit_id`) as a';
|
|
|
- const sqlParam2 = [this.tableName, tenderId, times];
|
|
|
- const count = await this.db.queryOne(sql2, sqlParam2);
|
|
|
- for (const i in result) {
|
|
|
- result[i].max_sort = count.num;
|
|
|
+ '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.`tender_id` = ? and la.`status` = ? and la.`times` = ?';
|
|
|
+ const sqlParam = [this.tableName, this.ctx.service.projectAccount.tableName, tenderId, auditConst.status.checking, times];
|
|
|
+ return await this.db.queryOne(sql, sqlParam);
|
|
|
+ }
|
|
|
+
|
|
|
+ async getCurAuditors(tenderId, 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.`tender_id` = ? and la.`status` = ? and la.`times` = ?';
|
|
|
+ const sqlParam = [this.tableName, this.ctx.service.projectAccount.tableName, tenderId, auditConst.status.checking, times];
|
|
|
+ return await this.db.query(sql, sqlParam);
|
|
|
+ }
|
|
|
+
|
|
|
+ async getAuditorGroup(tenderId, times) {
|
|
|
+ const auditors = await this.getAuditors(tenderId, times); // 全部参与的审批人
|
|
|
+ return this.ctx.helper.groupAuditors(auditors, 'audit_order');
|
|
|
+ }
|
|
|
+
|
|
|
+ async getUserGroup(tenderId, times) {
|
|
|
+ const group = await this.getAuditorGroup(tenderId, times);
|
|
|
+ const sql =
|
|
|
+ 'SELECT pa.`id` As audit_id, pa.`name`, pa.`company`, pa.`role`, ? As times, ? As tender_id, 0 As audit_order, 1 As audit_type' +
|
|
|
+ ' FROM ' + this.ctx.service.tender.tableName + ' As t' +
|
|
|
+ ' LEFT JOIN ' + this.ctx.service.projectAccount.tableName + ' As pa' +
|
|
|
+ ' ON t.user_id = pa.id' +
|
|
|
+ ' WHERE t.id = ?';
|
|
|
+ const sqlParam = [times, tenderId, tenderId];
|
|
|
+ const user = await this.db.queryOne(sql, sqlParam);
|
|
|
+ group.unshift([ user ]);
|
|
|
+ return group;
|
|
|
+ }
|
|
|
+
|
|
|
+ async getUniqUserGroup(tenderId, times) {
|
|
|
+ const group = await this.getAuditorGroup(tenderId, times);
|
|
|
+ const sql =
|
|
|
+ 'SELECT pa.`id` As audit_id, pa.`name`, pa.`company`, pa.`role`, ? As times, ? As tender_id, 0 As audit_order, 1 As audit_type' +
|
|
|
+ ' FROM ' + this.ctx.service.tender.tableName + ' As t' +
|
|
|
+ ' LEFT JOIN ' + this.ctx.service.projectAccount.tableName + ' As pa' +
|
|
|
+ ' ON t.user_id = pa.id' +
|
|
|
+ ' WHERE t.id = ?';
|
|
|
+ const sqlParam = [times, tenderId, tenderId];
|
|
|
+ const user = await this.db.queryOne(sql, sqlParam);
|
|
|
+ group.unshift([ user ]);
|
|
|
+ return this.ctx.helper.groupAuditorsUniq(group, 'audit_order');
|
|
|
+ }
|
|
|
+
|
|
|
+ async getAuditorHistory(tenderId, times, reverse = false) {
|
|
|
+ const history = [];
|
|
|
+ if (times >= 1) {
|
|
|
+ for (let i = 1; i <= times; i++) {
|
|
|
+ const auditors = await this.getAuditors(tenderId, 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(tenderId, times) {
|
|
|
+ const auditors = await this.getAuditors(tenderId, 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 loadLedgerUser(tender) {
|
|
|
+ const status = auditConst.status;
|
|
|
+ const accountId = this.ctx.session.sessionUser.accountId;
|
|
|
+
|
|
|
+ tender.user = await this.ctx.service.projectAccount.getAccountInfoById(tender.user_id);
|
|
|
+ tender.auditors = await this.getAuditors(tender.id, tender.ledger_times); // 全部参与的审批人
|
|
|
+ tender.auditorIds = this._.map(tender.auditors, 'audit_id');
|
|
|
+ tender.curAuditors = tender.auditors.filter(x => { return x.status === status.checking; }); // 当前流程中审批中的审批人
|
|
|
+ tender.curAuditorIds = this._.map(tender.curAuditors, 'audit_id');
|
|
|
+ tender.flowAuditors = tender.curAuditors.length > 0 ? tender.auditors.filter(x => { return x.audit_order === tender.curAuditors[0].audit_order; }) : []; // 当前流程中参与的审批人(包含会签时,审批通过的人)
|
|
|
+ tender.flowAuditorIds = this._.map(tender.flowAuditors, 'audit_id');
|
|
|
+ tender.nextAuditors = tender.curAuditors.length > 0 ? tender.auditors.filter(x => { return x.audit_order === tender.curAuditors[0].audit_order + 1; }) : [];
|
|
|
+ tender.nextAuditorIds = this._.map(tender.nextAuditors, 'audit_id');
|
|
|
+ tender.auditorGroups = this.ctx.helper.groupAuditors(tender.auditors, 'audit_order');
|
|
|
+ tender.userGroups = this.ctx.helper.groupAuditorsUniq(tender.auditorGroups);
|
|
|
+ tender.userGroups.unshift([{
|
|
|
+ aid: tender.user.id, order: 0, times: tender.ledger_times, audit_order: 0, audit_type: auditType.key.common,
|
|
|
+ name: tender.user.name, role: tender.user.role, company: tender.user.company
|
|
|
+ }]);
|
|
|
+ tender.finalAuditorIds = tender.userGroups[tender.userGroups.length - 1].map(x => { return x.aid; });
|
|
|
+ tender.relaAuditor = tender.auditors.find(x => { return x.aid === accountId });
|
|
|
+
|
|
|
+ tender.assists = [];// await this.service.ledgerAuditAss.getData(tender); // 全部协同人
|
|
|
+ tender.assists = tender.assists.filter(x => {
|
|
|
+ return x.user_id === tender.user_id || tender.auditorIds.indexOf(x.user_id) >= 0;
|
|
|
+ }); // 过滤无效协同人
|
|
|
+ tender.userAssists = tender.assists.filter(x => { return x.user_id === tender.user_id; }); // 原报协同人
|
|
|
+ tender.userAssistIds = this._.map(tender.userAssists, 'ass_user_id');
|
|
|
+ tender.auditAssists = tender.assists.filter(x => { return x.user_id !== tender.user_id; }); // 审批协同人
|
|
|
+ tender.auditAssistIds = this._.map(tender.auditAssists, 'ass_user_id');
|
|
|
+ tender.relaAssists = tender.assists.filter(x => { return x.user_id === accountId }); // 登录人的协同人
|
|
|
+ tender.userIds = tender.status === status.uncheck // 当前流程下全部参与人id
|
|
|
+ ? [tender.user_id]
|
|
|
+ : [tender.user_id, ...tender.userAssistIds, ...tender.auditorIds, ...tender.auditAssistIds];
|
|
|
+ }
|
|
|
+
|
|
|
+ async loadLedgerAuditViewData(tender) {
|
|
|
+ const times = tender.ledger_status === auditConst.status.checkNo ? tender.ledger_times - 1 : tender.ledger_times;
|
|
|
+
|
|
|
+ if (!tender.user) tender.user = await this.ctx.service.projectAccount.getAccountInfoById(tender.user_id);
|
|
|
+ tender.auditHistory = await this.getAuditorHistory(tender.id, times);
|
|
|
+ // 获取审批流程中左边列表
|
|
|
+ if (tender.status === auditConst.status.checkNo && tender.user_id !== this.ctx.session.sessionUser.accountId) {
|
|
|
+ const auditors = await this.getAuditors(tender.id, times); // 全部参与的审批人
|
|
|
+ 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,
|
|
|
+ name: tender.user.name, role: tender.user.role, company: tender.user.company
|
|
|
+ }]);
|
|
|
+ } else {
|
|
|
+ tender.auditors2 = tender.userGroups;
|
|
|
+ }
|
|
|
+ if (tender.ledger_status === auditConst.status.uncheck || tender.ledger_status === auditConst.status.checkNo) {
|
|
|
+ tender.auditorList = await this.getAuditors(tender.id, tender.ledger_times);
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
+ /**
|
|
|
+ * 获取标段审核人最后一位的名称
|
|
|
+ *
|
|
|
+ * @param {Number} tenderId - 标段id
|
|
|
+ * @param {Number} auditorId - 审核人id
|
|
|
+ * @param {Number} times - 第几次审批
|
|
|
+ * @return {Promise<*>}
|
|
|
+ */
|
|
|
+ async getStatusName(tenderId, times) {
|
|
|
+ const sql = 'SELECT pa.`name` FROM ?? AS la Left Join ?? AS pa ON la.`audit_id` = pa.`id`' +
|
|
|
+ ' WHERE la.`tender_id` = ? and la.`status` != ? ORDER BY la.`times` DESC, la.`audit_order` DESC';
|
|
|
+ const sqlParam = [this.tableName, this.ctx.service.projectAccount.tableName, tenderId, auditConst.status.uncheck];
|
|
|
+ return await this.db.queryOne(sql, sqlParam);
|
|
|
+ }
|
|
|
+
|
|
|
async getFinalAuditGroup(tenderId, times = 1) {
|
|
|
const sql =
|
|
|
'SELECT la.`audit_id`, pa.`name`, pa.`company`, pa.`role`, pa.`mobile`, pa.`telephone`, pa.`sign_path`, la.`times`, la.`tender_id`, Max(la.`audit_order`) as max_order ' +
|
|
@@ -122,22 +331,6 @@ module.exports = app => {
|
|
|
}
|
|
|
|
|
|
/**
|
|
|
- * 获取标段当前审核人
|
|
|
- *
|
|
|
- * @param {Number} tenderId - 标段id
|
|
|
- * @param {Number} times - 第几次审批
|
|
|
- * @return {Promise<*>}
|
|
|
- */
|
|
|
- async getCurAuditor(tenderId, 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` ' +
|
|
|
- ' FROM ?? AS la Left Join ?? AS pa On la.`audit_id` = pa.`id`' +
|
|
|
- ' WHERE la.`tender_id` = ? and la.`status` = ? and la.`times` = ?';
|
|
|
- const sqlParam = [this.tableName, this.ctx.service.projectAccount.tableName, tenderId, auditConst.status.checking, times];
|
|
|
- return await this.db.queryOne(sql, sqlParam);
|
|
|
- }
|
|
|
-
|
|
|
- /**
|
|
|
* 获取最新审核顺序
|
|
|
*
|
|
|
* @param {Number} tenderId - 标段id
|
|
@@ -172,6 +365,7 @@ module.exports = app => {
|
|
|
times,
|
|
|
audit_order: newOrder,
|
|
|
status: auditConst.status.uncheck,
|
|
|
+ audit_type: 0,
|
|
|
};
|
|
|
const result = await transaction.insert(this.tableName, data);
|
|
|
await transaction.commit();
|
|
@@ -250,8 +444,8 @@ module.exports = app => {
|
|
|
* @return {Promise<boolean>}
|
|
|
*/
|
|
|
async start(tenderId, times = 1) {
|
|
|
- const audit = await this.getDataByCondition({ tender_id: tenderId, times, audit_order: 1 });
|
|
|
- if (!audit) {
|
|
|
+ const audits = await this.getAllDataByCondition({ where: { tender_id: tenderId, times, audit_order: 1 } });
|
|
|
+ if (audits.length === 0) {
|
|
|
if(this.ctx.tender.info.shenpi.ledger === shenpiConst.sp_status.gdspl) {
|
|
|
throw '请联系管理员添加审批人';
|
|
|
} else {
|
|
@@ -264,11 +458,9 @@ module.exports = app => {
|
|
|
|
|
|
const transaction = await this.db.beginTransaction();
|
|
|
try {
|
|
|
- await transaction.update(this.tableName, {
|
|
|
- id: audit.id,
|
|
|
- status: auditConst.status.checking,
|
|
|
- begin_time: new Date(),
|
|
|
- });
|
|
|
+ const begin_time = new Date();
|
|
|
+ const updateAuditData = audits.map(a => { return { id: a.id, status: auditConst.status.checking, begin_time }; });
|
|
|
+ await transaction.updateRows(this.tableName, updateAuditData);
|
|
|
await transaction.update(this.ctx.service.tender.tableName, {
|
|
|
id: tenderId,
|
|
|
ledger_status: auditConst.status.checking,
|
|
@@ -276,27 +468,30 @@ module.exports = app => {
|
|
|
deal_tp: sum.deal_tp,
|
|
|
his_id: his_id,
|
|
|
});
|
|
|
- await this.ctx.service.tenderCache.updateLedgerCache4Start(transaction, tenderId, auditConst.status.checking, audit, sum);
|
|
|
+ await this.ctx.service.tenderCache.updateLedgerCache4Start(transaction, tenderId, auditConst.status.checking, audits, sum);
|
|
|
|
|
|
// 添加短信通知-需要审批提醒功能
|
|
|
- await this.ctx.helper.sendAliSms(audit.audit_id, smsTypeConst.const.TZ, smsTypeConst.judge.approval.toString(), SmsAliConst.template.ledger_check);
|
|
|
+ const auditorIds = audits.map(x => { return x.audit_id; });
|
|
|
+ await this.ctx.helper.sendAliSms(auditorIds, 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(new Date()),
|
|
|
};
|
|
|
- await this.ctx.helper.sendWechat(audit.audit_id, smsTypeConst.const.TZ, smsTypeConst.judge.approval.toString(), wxConst.template.ledger, wechatData);
|
|
|
- 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,
|
|
|
- });
|
|
|
+ await this.ctx.helper.sendWechat(auditorIds, smsTypeConst.const.TZ, smsTypeConst.judge.approval.toString(), wxConst.template.ledger, wechatData);
|
|
|
+ for (const audit of audits) {
|
|
|
+ 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,
|
|
|
+ });
|
|
|
+ }
|
|
|
await transaction.commit();
|
|
|
} catch (err) {
|
|
|
await transaction.rollback();
|
|
@@ -314,133 +509,122 @@ module.exports = app => {
|
|
|
* @return {Promise<void>}
|
|
|
*/
|
|
|
async check(tenderId, checkType, opinion, times = 1) {
|
|
|
+ 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 flowAuditors = await this.getAllDataByCondition({ where: { tender_id: tenderId, times, audit_order: selfAuditor.audit_order } });
|
|
|
+ const nextAuditors = await this.getAllDataByCondition({ where: { tender_id: tenderId, times, audit_order: selfAuditor.audit_order + 1 } });
|
|
|
+ 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: checkType, content: noticeContent };
|
|
|
+
|
|
|
const transaction = await this.db.beginTransaction();
|
|
|
try {
|
|
|
- // 整理当前流程审核人状态更新
|
|
|
- const time = new Date();
|
|
|
- const audit = await this.getDataByCondition({
|
|
|
- tender_id: tenderId,
|
|
|
- times,
|
|
|
- status: auditConst.status.checking,
|
|
|
- });
|
|
|
- if (!audit) {
|
|
|
- throw '审核数据错误';
|
|
|
- }
|
|
|
-
|
|
|
- // 获取审核人列表
|
|
|
+ // 获取审核人列表,添加提醒
|
|
|
+ const records = [{ uid: this.ctx.tender.data.user_id, ...defaultNoticeRecord } ];
|
|
|
const auditList = await this.getAuditors(tenderId, times);
|
|
|
- // 添加推送
|
|
|
- const noticeContent = await this.getNoticeContent(audit.tender_id, pid, audit.audit_id, opinion);
|
|
|
- const records = [
|
|
|
- {
|
|
|
- pid,
|
|
|
- type: pushType.ledger,
|
|
|
- uid: this.ctx.tender.data.user_id,
|
|
|
- status: checkType,
|
|
|
- content: noticeContent,
|
|
|
- },
|
|
|
- ];
|
|
|
auditList.forEach(audit => {
|
|
|
- records.push({
|
|
|
- pid,
|
|
|
- type: pushType.ledger,
|
|
|
- uid: audit.audit_id,
|
|
|
- status: checkType,
|
|
|
- content: noticeContent,
|
|
|
- });
|
|
|
+ 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));
|
|
|
+
|
|
|
// 更新当前审核流程
|
|
|
- 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);
|
|
|
- const begin_audit = await this.getDataByCondition({
|
|
|
- tender_id: tenderId,
|
|
|
- audit_order: 1,
|
|
|
- });
|
|
|
- const tenderMsg = await this.ctx.service.tender.getDataById(tenderId);
|
|
|
- const users = this._.uniq(this._.concat(this._.map(auditList, 'audit_id'), tenderMsg.user_id));
|
|
|
+ await transaction.update(this.tableName, { id: selfAuditor.id, status: checkType, opinion, end_time: time });
|
|
|
+ // 审批提醒
|
|
|
+ await this.ctx.service.noticeAgain.stopNoticeAgain(transaction, this.tableName, selfAuditor.id);
|
|
|
+
|
|
|
if (checkType === auditConst.status.checked) {
|
|
|
- const nextAudit = await this.getDataByCondition({
|
|
|
- tender_id: tenderId,
|
|
|
- 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 this.ctx.service.tenderCache.updateLedgerCache(transaction, tenderId, auditConst.status.checking, checkType, nextAudit);
|
|
|
- await this.ctx.helper.sendAliSms(nextAudit.audit_id, 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(begin_audit.begin_time),
|
|
|
- };
|
|
|
- await this.ctx.helper.sendWechat(nextAudit.audit_id, smsTypeConst.const.TZ, smsTypeConst.judge.approval.toString(), wxConst.template.ledger, wechatData);
|
|
|
- await this.ctx.service.noticeAgain.addNoticeAgain(transaction, smsTypeConst.const.TZ, {
|
|
|
- pid: this.ctx.session.sessionProject.id,
|
|
|
- tid: tenderId,
|
|
|
- uid: nextAudit.audit_id,
|
|
|
- sp_type: 'ledger',
|
|
|
- sp_id: nextAudit.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: new Date()}, transaction);
|
|
|
- // const users = this._.pull(this._.map(auditList, 'audit_id'), audit.id);
|
|
|
- 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(begin_audit.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);
|
|
|
+ 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);
|
|
|
+ }
|
|
|
+ // 无下一审核人表示,审核结束
|
|
|
+ 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,
|
|
|
+ });
|
|
|
+ // 微信模板通知
|
|
|
+ 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,
|
|
|
+ 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 });
|
|
|
+ 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'],
|
|
|
+ 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 };
|
|
|
});
|
|
|
- const insertAuditors = [];
|
|
|
- for (const a of auditors) {
|
|
|
- if (insertAuditors.find(x => { return x.audit_id === a.audit_id; })) continue;
|
|
|
- a.audit_order = insertAuditors.length + 1;
|
|
|
- a.times = times + 1;
|
|
|
- a.status = auditConst.status.uncheck;
|
|
|
- insertAuditors.push(a)
|
|
|
- }
|
|
|
await transaction.insert(this.tableName, insertAuditors);
|
|
|
|
|
|
- // const users = this._.pull(this._.map(auditList, 'audit_id'), audit.id);
|
|
|
await this.ctx.helper.sendAliSms(users, smsTypeConst.const.TZ, smsTypeConst.judge.result.toString(), SmsAliConst.template.ledger_result, {
|
|
|
status: SmsAliConst.status.back,
|
|
|
});
|
|
@@ -448,7 +632,7 @@ module.exports = app => {
|
|
|
const wechatData = {
|
|
|
status: wxConst.status.back,
|
|
|
tips: wxConst.tips.back,
|
|
|
- begin_time: Date.parse(begin_audit.begin_time),
|
|
|
+ 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);
|
|
|
}
|
|
@@ -463,7 +647,7 @@ module.exports = app => {
|
|
|
|
|
|
/**
|
|
|
* 重新审批
|
|
|
- * @param {Number} stageId - 标段id
|
|
|
+ * @param {Number} tenderId - 标段id
|
|
|
* @param {Number} times - 第几次审批
|
|
|
* @return {Promise<void>}
|
|
|
*/
|
|
@@ -647,19 +831,18 @@ module.exports = app => {
|
|
|
return result;
|
|
|
}
|
|
|
|
|
|
- async updateNewAuditList(tender, newIdList) {
|
|
|
+ async updateNewAuditList(tender, newList) {
|
|
|
const transaction = await this.db.beginTransaction();
|
|
|
try {
|
|
|
// 先删除旧的审批流,再添加新的
|
|
|
await transaction.delete(this.tableName, { tender_id: tender.id, times: tender.ledger_times });
|
|
|
const newAuditors = [];
|
|
|
- let order = 1;
|
|
|
- for (const aid of newIdList) {
|
|
|
+ for (const auditor of newList) {
|
|
|
newAuditors.push({
|
|
|
- tender_id: tender.id, audit_id: aid,
|
|
|
- times: tender.ledger_times, audit_order: order, status: auditConst.status.uncheck,
|
|
|
- });
|
|
|
- order++;
|
|
|
+ tender_id: tender.id, audit_id: auditor.audit_id,
|
|
|
+ times: tender.ledger_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();
|
|
@@ -698,7 +881,7 @@ module.exports = app => {
|
|
|
|
|
|
/**
|
|
|
* 删除本次审批流程
|
|
|
- * @param {Number} stageId - 标段id
|
|
|
+ * @param {Number} tenderId - 标段id
|
|
|
* @param {Number} times - 第几次审批
|
|
|
* @param {Object} data - 更改参数
|
|
|
* @return {Promise<void>}
|
|
@@ -729,14 +912,6 @@ module.exports = app => {
|
|
|
}
|
|
|
await transaction.delete(this.tableName, { tender_id: tenderId, times, audit_id: now_audit.audit_id, audit_order: now_audit.audit_order });
|
|
|
await this._syncOrderByDelete(transaction, tenderId, now_audit.audit_order, times);
|
|
|
- // // 旧的更新为is_old为1
|
|
|
- // await transaction.update(this.tableName, { is_old: 1 }, {
|
|
|
- // where: {
|
|
|
- // sid: stageId,
|
|
|
- // times,
|
|
|
- // aid: data.old_aid,
|
|
|
- // }
|
|
|
- // });
|
|
|
} else if (data.operate === 'change') {
|
|
|
const nowAudit = await this.getDataByCondition({ tender_id: tenderId, times, audit_id: now_audit.audit_id, audit_order: now_audit.audit_order });
|
|
|
if (now_audit.status !== auditConst.status.uncheck || !nowAudit) {
|
|
@@ -744,14 +919,6 @@ module.exports = app => {
|
|
|
}
|
|
|
nowAudit.audit_id = data.new_aid;
|
|
|
await transaction.update(this.tableName, nowAudit);
|
|
|
- // 旧的更新为is_old为1
|
|
|
- // await transaction.update(this.tableName, { is_old: 1 }, {
|
|
|
- // where: {
|
|
|
- // sid: stageId,
|
|
|
- // times,
|
|
|
- // aid: data.old_aid,
|
|
|
- // }
|
|
|
- // });
|
|
|
}
|
|
|
if (this.ctx.tender.info.shenpi.ledger === shenpiConst.sp_status.gdspl || this.ctx.tender.info.shenpi.ledger === shenpiConst.sp_status.gdzs) {
|
|
|
const newAuditors = await this.getAuditGroupByList(tenderId, times, transaction);
|