'use strict'; /** * 版本数据模型 * * @author CaiAoLin * @date 2017/10/25 * @version */ const shenpiConst = require('../const/shenpi'); const auditType = require('../const/audit').auditType; module.exports = app => { class ShenpiAudit extends app.BaseService { /** * 构造函数 * * @param {Object} ctx - egg全局变量 * @return {void} */ constructor(ctx) { super(ctx); this.tableName = 'shenpi_audit'; } async getShenpi(tid, info) { const spConst = this._.cloneDeep(shenpiConst); for (const sp of spConst.sp_lc) { sp.status = info.shenpi ? info.shenpi[sp.code] : shenpiConst.sp_status.sqspr; if (sp.status === shenpiConst.sp_status.gdspl) { sp.groupList = await this.ctx.service.shenpiGroup.getGroupList(tid, sp.type) || []; if (sp.groupList && sp.groupList.length > 0) { for (const group of sp.groupList) { if (group.change_type) group.change_type = JSON.parse(group.change_type); group.auditGroupList = await this.getAuditGroupList(tid, sp.type, sp.status, group.id); if (group.is_select) sp.auditGroupList = group.auditGroupList; } } else { sp.auditGroupList = await this.getAuditGroupList(tid, sp.type, sp.status); } } else if (sp.status === shenpiConst.sp_status.gdzs) { sp.audit = await this.getAudit(tid, sp.type, sp.status); } } return spConst; } async getAudit(tid, type, status) { const sql = 'SELECT sp.audit_id, sp.audit_type, pa.name FROM ?? AS sp LEFT JOIN ?? AS pa ON sp.audit_id = pa.id' + ' WHERE sp.tid = ? AND sp.sp_type = ? AND sp.sp_status = ?'; const sqlParam = [this.tableName, this.ctx.service.projectAccount.tableName, tid, type, status]; return await this.db.queryOne(sql, sqlParam); } async getUnionAudit(tid, type, audit_order) { const sql = 'SELECT sp.id, sp.audit_id, sp.audit_ledger_id, pa.name, pa.company FROM ?? AS sp LEFT JOIN ?? AS pa ON sp.audit_id = pa.id' + ' WHERE sp.tid = ? AND sp.sp_type = ? AND sp.sp_status = ? AND audit_order = ?'; const sqlParam = [this.tableName, this.ctx.service.projectAccount.tableName, tid, type, shenpiConst.sp_status.gdspl, audit_order]; return await this.db.query(sql, sqlParam); } async getAuditList(tid, type, status, group_id = 0) { const sql = 'SELECT sp.id, sp.audit_id, sp.audit_type, pa.name FROM ?? AS sp LEFT JOIN ?? AS pa ON sp.audit_id = pa.id' + ' WHERE sp.tid = ? AND sp.sp_type = ? AND sp.sp_status = ? AND sp.sp_group = ? ORDER BY sp.audit_order ASC, sp.id ASC'; const sqlParam = [this.tableName, this.ctx.service.projectAccount.tableName, tid, type, status, group_id]; return await this.db.query(sql, sqlParam); } async getAuditGroupList(tid, type, status, group_id = 0) { const sql = 'SELECT sp.audit_id, sp.audit_type, sp.audit_order, sp.sp_group, pa.name FROM ?? AS sp LEFT JOIN ?? AS pa ON sp.audit_id = pa.id' + ' WHERE sp.tid = ? AND sp.sp_type = ? AND sp.sp_status = ? AND sp.sp_group = ? ORDER BY sp.audit_order ASC, sp.id ASC'; const sqlParam = [this.tableName, this.ctx.service.projectAccount.tableName, tid, type, status, group_id]; const audits = await this.db.query(sql, sqlParam); const result = []; for (const a of audits) { if (a.audit_order > 0) { if (result[a.audit_order - 1]) { result[a.audit_order - 1].push(a); } else { result.push([a]); } } else { result.push([a]); } } return result; } async addAudit(data) { let result; const transaction = await this.db.beginTransaction(); try { if (parseInt(data.code) === shenpiConst.sp_type.stage && parseInt(data.status) === shenpiConst.sp_status.gdspl) { const options = { where: { tid: this.ctx.tender.id, user_id: data.audit_id, }, }; const updateData = { status: 1, }; await transaction.update(this.ctx.service.ledgerCooperation.tableName, updateData, options); } const group = await this.ctx.service.shenpiGroup.getGroupBySelect(this.ctx.tender.id, data.code); const insertData = { tid: this.ctx.tender.id, sp_type: data.code, sp_status: data.status, audit_id: data.audit_id, sp_group: group ? group.id : 0, }; if (data.audit_type) insertData.audit_type = data.audit_type; if (data.audit_order) insertData.audit_order = data.audit_order; result = await transaction.insert(this.tableName, insertData); await transaction.commit(); } catch (err) { await transaction.rollback(); throw err; } if (result.affectedRows !== 1) throw '添加审批人失败'; data.id = result.insertId; return data; } async removeAudit(data) { const group = await this.ctx.service.shenpiGroup.getGroupBySelect(this.ctx.tender.id, data.code); const delData = { tid: this.ctx.tender.id, sp_type: data.code, sp_status: data.status, audit_id: data.audit_id, sp_group: group ? group.id : 0, }; const audit = await this.getDataByCondition(delData); const conditon = { tid: this.ctx.tender.id, sp_type: data.code, sp_status: data.status }; if (group) conditon.sp_group = group.id; const allAudit = await this.getAllDataByCondition({ where: conditon }); const sameOrder = allAudit.filter(x => { return x.audit_order === audit.audit_order; }); const updateData = []; if (sameOrder.length === 1) { for (const aa of allAudit) { if (aa.audit_order > audit.audit_order) updateData.push({ id: aa.id, audit_order: aa.audit_order - 1 }); } } const transaction = await this.db.beginTransaction(); try { await transaction.delete(this.tableName, delData); if (updateData.length > 0) await transaction.updateRows(this.tableName, updateData); if (parseInt(data.code) === shenpiConst.sp_type.stage && parseInt(data.status) === shenpiConst.sp_status.gdspl) { const options = { where: { tid: this.ctx.tender.id, user_id: data.audit_id, }, }; const updateData = { status: 0, }; await transaction.update(this.ctx.service.ledgerCooperation.tableName, updateData, options); } await transaction.commit(); return true; } catch (err) { await transaction.rollback(); throw err; } } async copyAudit2otherTender(data) { const transaction = await this.db.beginTransaction(); try { const shenpi_status = parseInt(data.status); // 1.复制修改当前审批到其他的tender_info里 // 2.删除其他的shenpiAudit // 3.添加新的shenpiAudit(还要针对该标段是否为原报进行处理) const tenderInfoUpdateList = []; const tenders = []; for (const tid of data.tidList.split(',')) { // 获取原报 const tender = await this.ctx.service.tender.getDataById(tid); if (tender) { tenders.push({ id: parseInt(tid), user_id: tender.user_id }); const shenpiInfo = await this.ctx.service.tenderInfo.getTenderShenpiInfo(tid); // 把当前期状态复制到其他标段里 if (shenpiInfo[data.code] !== shenpi_status) { shenpiInfo[data.code] = shenpi_status; tenderInfoUpdateList.push({ row: { shenpi: JSON.stringify(shenpiInfo) }, where: { tid: parseInt(tid) } }); } } } if (tenderInfoUpdateList.length > 0) await transaction.updateRows(this.ctx.service.tenderInfo.tableName, tenderInfoUpdateList); const insertList = []; const needYB = ['ledger', 'revise', 'change']; const canYB = needYB.indexOf(data.code) !== -1; let is_group = false; let groupList = []; if (shenpi_status === shenpiConst.sp_status.gdspl) { groupList = await this.ctx.service.shenpiGroup.getGroupList(this.ctx.tender.id, shenpiConst.sp_type[data.code]); if (groupList.length > 0) { is_group = true; for (const g of groupList) { g.auditList = await this.getAllDataByCondition({ where: { tid: this.ctx.tender.id, sp_type: shenpiConst.sp_type[data.code], sp_status: shenpi_status, sp_group: g.id } }); } } } for (const t of tenders) { if (shenpi_status !== shenpiConst.sp_status.sqspr) { if (shenpi_status === shenpiConst.sp_status.gdspl) { await transaction.delete(this.ctx.service.shenpiGroup.tableName, { tid: t.id, sp_type: shenpiConst.sp_type[data.code], }); } await transaction.delete(this.tableName, { tid: t.id, sp_type: shenpiConst.sp_type[data.code], sp_status: shenpi_status }); if (is_group) { for (const g of groupList) { const result = await transaction.insert(this.ctx.service.shenpiGroup.tableName, { tid: t.id, sp_type: shenpiConst.sp_type[data.code], name: g.name, is_select: g.is_select, change_type: g.change_type, create_time: new Date(), }); for (const s of g.auditList) { insertList.push({ tid: t.id, sp_type: shenpiConst.sp_type[data.code], sp_status: shenpi_status, audit_id: s.audit_id, audit_type: s.audit_type, audit_order: s.audit_order, sp_group: result.insertId, }); } } } else { const sourceList = data.auditList.filter(x => { return x.audit_id && (x.audit_id !== t.user_id || canYB); }); sourceList.sort((a, b) => { return a.audit_order - b.audit_order; }); let audit_order = 0, curAuditOrder = 0; for (const s of sourceList) { if (s.audit_order !== curAuditOrder) { curAuditOrder = s.audit_order; audit_order = audit_order + 1; } insertList.push({ tid: t.id, sp_type: shenpiConst.sp_type[data.code], sp_status: shenpi_status, audit_id: s.audit_id, audit_type: s.audit_type, audit_order: audit_order, sp_group: 0, }); } } } } // console.log(tenderInfoUpdateList, insertList); if (insertList.length > 0) await transaction.insert(this.tableName, insertList); await transaction.commit(); return true; } catch (err) { await transaction.rollback(); throw err; } } async copyAudit2otherShenpi(data) { const transaction = await this.db.beginTransaction(); try { const shenpi_status = parseInt(data.status); // 1.修改当前审批到它的tender_info里 // 2.删除相同审批状态的shenpiAudit // 3.添加新的shenpiAudit(还要针对该标段是否为原报进行处理) const insertList = []; const needYB = ['ledger', 'revise', 'change']; const shenpiInfo = await this.ctx.service.tenderInfo.getTenderShenpiInfo(this.ctx.tender.id); for (const code of data.shenpiList.split(',')) { // 把当前审批状态复制到其他标段里 if (shenpiInfo[code] !== shenpi_status) { shenpiInfo[code] = shenpi_status; } if (shenpiInfo[code] !== shenpiConst.sp_status.sqspr) { if (shenpiInfo[code] === shenpiConst.sp_status.gdspl) { const group = await this.ctx.service.shenpiGroup.getAllDataByCondition({ where: { tid: this.ctx.tender.id, sp_type: shenpiConst.sp_type[code] } }); if (group && group.length > 0) { throw '选择同步的流程中存在审批组,无法设置同步'; } } await transaction.delete(this.tableName, { tid: this.ctx.tender.id, sp_type: shenpiConst.sp_type[code], sp_status: shenpiInfo[code] }); for (const aid of data.aidList.split(',')) { if (aid && parseInt(aid) !== this.ctx.tender.data.user_id || (parseInt(aid) === this.ctx.tender.data.user_id && needYB.indexOf(code) !== -1)) { const insertData = { tid: this.ctx.tender.id, sp_type: shenpiConst.sp_type[code], sp_status: shenpi_status, audit_id: parseInt(aid), audit_order: insertList.length + 1, }; insertList.push(insertData); } } } } await transaction.update(this.ctx.service.tenderInfo.tableName, { shenpi: JSON.stringify(shenpiInfo), }, { where: { tid: this.ctx.tender.id, }, }); if (insertList.length > 0) await transaction.insert(this.tableName, insertList); await transaction.commit(); return true; } catch (err) { await transaction.rollback(); throw err; } } async setAuditType(data) { const conn = await this.db.beginTransaction(); try { const updateData = { audit_type: data.audit_type }; const group = await this.ctx.service.shenpiGroup.getGroupBySelect(this.ctx.tender.id, data.code); const condition = { tid: this.ctx.tender.id, sp_type: data.code, sp_status: data.status, audit_id: data.audit_id, sp_group: group ? group.id : 0, }; await conn.update(this.tableName, updateData, { where: condition }); await conn.commit(); } catch (err) { await conn.rollback(); throw err; } } // 更新审批流程 async updateAuditList(transaction, tenderId, sp_status, sp_type, ids) { if (sp_status === shenpiConst.sp_status.gdspl) { const auditList = await this.getAuditList(tenderId, sp_type, sp_status); const oldIds = this._.map(auditList, 'audit_id'); if (this._.isEqual(ids, oldIds)) { return; } // 更新固定审批流 await transaction.delete(this.tableName, { tid: tenderId, sp_type, sp_status }); const insertDatas = []; for (const [i, id] of ids.entries()) { insertDatas.push({ tid: tenderId, sp_type, sp_status, audit_id: id, audit_order: i + 1, }); } await transaction.insert(this.tableName, insertDatas); if (sp_type === shenpiConst.sp_type.stage) { // 判断哪些audit_id不存在了,哪些audit_为新增 const exist = this._.difference(ids, oldIds);// 判断新增的 const unExist = this._.difference(oldIds, ids);// 判断已删除的 console.log(ids, oldIds, exist, unExist); if (exist.length > 0) { const options = { where: { tid: this.ctx.tender.id, user_id: exist, }, }; const updateData = { status: 1, }; await transaction.update(this.ctx.service.ledgerCooperation.tableName, updateData, options); } if (unExist.length > 0) { const options2 = { where: { tid: this.ctx.tender.id, user_id: unExist, }, }; const updateData2 = { status: 0, }; await transaction.update(this.ctx.service.ledgerCooperation.tableName, updateData2, options2); } } } else if (sp_status === shenpiConst.sp_status.gdzs) { const audit = await this.getAudit(tenderId, sp_type, sp_status); if (audit && audit.audit_id !== ids[ids.length - 1]) { // 更换终审 await transaction.update(this.tableName, { audit_id: ids[ids.length - 1] }, { where: { tid: tenderId, sp_type, sp_status } }); } else if (!audit) { await transaction.insert(this.tableName, { tid: tenderId, sp_type, sp_status, audit_id: ids[ids.length - 1] }); } } } async updateAuditListWithAuditType(transaction, tenderId, sp_status, sp_type, auditGroup, sp_group = 0) { const auditList = await this.getAuditList(tenderId, sp_type, sp_status, sp_group); const newAuditList = []; for (const group of auditGroup) { newAuditList.push(...group); } let sameAudit = auditList.length === newAuditList.length; if (sameAudit) { for (const audit of auditList) { const newAudit = newAuditList.find(x => { return x.audit_id === audit.aid; }); if (!newAudit || newAudit.audit_order !== audit.audit_order || newAudit.audit_type !== audit.audit_type) { sameAudit = false; break; } } } if (sameAudit) return; // 更新固定审批流 await transaction.delete(this.tableName, { tid: tenderId, sp_type, sp_status, sp_group }); const insertDatas = []; for (const a of newAuditList) { insertDatas.push({ tid: tenderId, sp_type, sp_status, audit_id: a.aid || a.uid || a.audit_id, audit_order: a.audit_order, audit_type: a.audit_type, sp_group, }); } await transaction.insert(this.tableName, insertDatas); } async getRemoveTenders(tenders) { const removeTenders = []; for (const tender of tenders) { const shenpiInfo = await this.ctx.service.tenderInfo.getTenderShenpiInfo(tender.id); if (!shenpiInfo) { removeTenders.push(tender.id); } else { tender.shenpiInfo = shenpiInfo; // 获取所有的固定审批流或固定终审 const shenpiauditList = {}; for (const shenpi in tender.shenpiInfo) { if (tender.shenpiInfo[shenpi] === shenpiConst.sp_status.gdspl) { const group = await this.ctx.service.shenpiGroup.getGroupBySelect(tender.id, shenpiConst.sp_type[shenpi]); const shenpiList = await this.getAuditList(tender.id, shenpiConst.sp_type[shenpi], tender.shenpiInfo[shenpi], group ? group.id : 0); const shenpiIdList = this._.map(shenpiList, 'audit_id'); shenpiauditList[shenpi] = shenpiIdList.length ? shenpiIdList : null; } else if (tender.shenpiInfo[shenpi] === shenpiConst.sp_status.gdzs) { const shenpiInfo = await this.getDataByCondition({ tid: tender.id, sp_type: shenpiConst.sp_type[shenpi], sp_status: tender.shenpiInfo[shenpi] }); shenpiauditList[shenpi] = shenpiInfo && shenpiInfo.audit_id ? [shenpiInfo.audit_id] : null; } } tender.shenpiauditList = shenpiauditList; } } return removeTenders; } async noYbShenpiList(uid, shenpiList) { // 剔除原报及分析审批流中的审批人 const yBIndex = shenpiList.findIndex(x => { return x.audit_id === uid; }); if (yBIndex !== -1) { const yB = shenpiList[yBIndex]; if (yB.audit_type !== auditType.key.common) { // 如果是会签或签且人数只有2人,则audit_type变为common const curSps = shenpiList.filter(x => { return x.audit_order === yB.audit_order; }); if (curSps.length === 1) { shenpiList.forEach(x => { if (x.audit_order > yB.audit_order) x.audit_order--; }); } else if (curSps.length === 2) { curSps.forEach(x => { x.audit_type = auditType.key.common; }); } } else { // 比它大的audit_order都要-1; shenpiList.forEach(x => { if (x.audit_order > yB.audit_order) x.audit_order--; }); } shenpiList.splice(yBIndex, 1); } } async saveUnionAudit(tid, data) { const orgData = await this.getAllDataByCondition({ where: { id: data.map(x => { return x.id; }) } }); for (const od of orgData) { if (od.tid !== tid) throw '保存数据错误,请刷新页面后重试'; } const updateData = data.map(x => { return { id: x.id, audit_ledger_id: x.audit_ledger_id }; }); if (updateData.length > 0) await this.db.updateRows(this.tableName, updateData); } } return ShenpiAudit; };