'use strict'; /** * * * @author Mai * @date 2018/8/14 * @version */ const audit = require('../const/audit'); const fs = require('fs'); const path = require('path'); module.exports = app => { class Change extends app.BaseService { /** * 构造函数 * * @param {Object} ctx - egg全局变量 * @return {void} */ constructor(ctx) { super(ctx); this.tableName = 'change'; } /** * 查找数据 * * @param {Object} data - 筛选表单中的get数据 * @return {void} */ searchFilter(data) { this.initSqlBuilder(); // this.sqlBuilder.columns = ['id', 'username', 'real_name', 'create_time', 'last_login', 'login_ip', // 'group_id', 'token', 'can_login']; data.type = parseInt(data.status); if (data.keyword !== undefined) { switch (data.type) { // 用户名 case 1: this.sqlBuilder.setAndWhere('username', { value: this.db.escape(data.keyword + '%'), operate: 'like', }); break; // 姓名 case 2: this.sqlBuilder.setAndWhere('real_name', { value: this.db.escape(data.keyword + '%'), operate: 'like', }); break; // 联系电话 case 3: this.sqlBuilder.setAndWhere('telephone', { value: this.db.escape(data.keyword + '%'), operate: 'like', }); break; default: break; } } // 办事处筛选 if (data.office !== undefined && data.office !== '') { this.sqlBuilder.setAndWhere('office', { value: this.db.escape(data.office), operate: '=', }); } } async add(tenderId, userId, code, name) { const count = await this.count({ tid: tenderId, code }); if (count > 0) { throw '变更令号重复'; } // 初始化事务 this.transaction = await this.db.beginTransaction(); let result = false; try { const cid = this.uuid.v4(); const change = { cid, tid: tenderId, uid: userId, status: audit.flow.status.uncheck, times: 1, valid: true, in_time: new Date(), code, name, }; const operate = await this.transaction.insert(this.tableName, change); if (operate.affectedRows <= 0) { throw '新建变更令数据失败'; } // 把提交人信息添加到zh_change_audit const userInfo = await this.ctx.service.projectAccount.getDataById(userId); const changeaudit = { tid: tenderId, cid, uid: userId, name: userInfo.name, jobs: userInfo.role, company: userInfo.company, times: 1, usite: 0, usort: 0, status: 2, }; await this.transaction.insert(this.ctx.service.changeAudit.tableName, changeaudit); result = change; this.transaction.commit(); } catch (error) { console.log(error); // 回滚 await this.transaction.rollback(); } return result; } async pendingDatas(tenderId, userId) { return await this.getAllDataByCondition({ tid: tenderId, uid: userId, status: audit.flow.status.checking, }); } async uncheckDatas(tenderId, userId) { return await this.getAllDataByCondition({ tid: tenderId, uid: userId, status: audit.flow.status.uncheck, }); } async checkingDatas(tenderId, userId) { return await this.getAllDataByCondition({ tid: tenderId, uid: userId, status: audit.flow.status.checking, }); } async checkedDatas(tenderId, userId) { return await this.getAllDataByCondition({ tid: tenderId, uid: userId, status: audit.flow.status.checked, }); } async checkNoDatas(tenderId, userId) { return await this.getAllDataByCondition({ tid: tenderId, uid: userId, status: audit.flow.status.checkNo, }); } async checkNoCount(tenderId, userId) { return await this.count({ tid: tenderId, uid: userId, status: audit.flow.status.checkNo, }); } /** * 获取变更令列表 * @param {int} tenderId - 标段id * @param {int} status - 状态 * @return {object} list - 列表 */ async getListByStatus(tenderId, status = 0) { let sql = ''; let sqlParam = ''; switch (status) { case 0:// 包含你的所有变更令 sql = 'SELECT a.* FROM ?? AS a WHERE a.tid = ? AND ' + '(a.uid = ? OR (a.status != 1 AND a.cid IN (SELECT b.cid FROM ?? AS b WHERE b.uid = ? GROUP BY b.cid))) ORDER BY a.in_time DESC'; sqlParam = [this.tableName, tenderId, this.ctx.session.sessionUser.accountId, this.ctx.service.changeAudit.tableName, this.ctx.session.sessionUser.accountId]; break; case 1:// 待处理(你的) sql = 'SELECT a.* FROM ?? as a WHERE cid in(SELECT b.cid FROM ?? as b WHERE tid = ? AND uid = ? AND status = ?) ORDER BY in_time DESC'; sqlParam = [this.tableName, this.ctx.service.changeAudit.tableName, tenderId, this.ctx.session.sessionUser.accountId, 2]; break; case 5:// 待上报(所有的)PS:取未上报和退回的变更令 sql = 'SELECT a.* FROM ?? AS a WHERE ' + 'a.cid IN (SELECT b.cid FROM ?? AS b WHERE b.uid = ? GROUP BY b.cid) AND ' + '(a.status = 1 OR a.status = 5) AND a.tid = ? ORDER BY a.in_time DESC'; sqlParam = [this.tableName, this.ctx.service.changeAudit.tableName, this.ctx.session.sessionUser.accountId, tenderId]; break; case 2:// 进行中(所有的) case 3:// 已完成(所有的) case 4:// 终止(所有的) sql = 'SELECT a.* FROM ?? AS a WHERE ' + 'a.cid IN (SELECT b.cid FROM ?? AS b WHERE b.uid = ? GROUP BY b.cid) AND ' + 'a.status = ? AND a.tid = ? ORDER BY a.in_time DESC'; sqlParam = [this.tableName, this.ctx.service.changeAudit.tableName, this.ctx.session.sessionUser.accountId, status, tenderId]; break; default: break; } const limit = this.app.config.pageSize; const offset = limit * (this.ctx.page - 1); const limitString = offset >= 0 ? offset + ',' + limit : limit; sql += ' LIMIT ' + limitString; const list = await this.db.query(sql, sqlParam); return list; } /** * 获取变更令个数 * @param {int} tenderId - 标段id * @param {int} status - 状态 * @return {void} */ async getCountByStatus(tenderId, status) { switch (status) { case 0:// 包含你的所有变更令 const sql = 'SELECT count(*) AS count FROM ?? AS a WHERE a.tid = ? AND ' + '(a.uid = ? OR a.cid IN (SELECT b.cid FROM ?? AS b WHERE b.uid = ? GROUP BY b.cid))'; const sqlParam = [this.tableName, tenderId, this.ctx.session.sessionUser.accountId, this.ctx.service.changeAudit.tableName, this.ctx.session.sessionUser.accountId]; const result = await this.db.query(sql, sqlParam); return result[0].count; case 1:// 待处理(你的) return await this.ctx.service.changeAudit.count({ tid: tenderId, uid: this.ctx.session.sessionUser.accountId, status: 2, }); case 5:// 待上报(所有的)PS:取未上报和退回的变更令 const sql2 = 'SELECT count(*) AS count FROM ?? AS a WHERE ' + 'a.cid IN (SELECT b.cid FROM ?? AS b WHERE b.uid = ? GROUP BY b.cid) ' + 'AND (a.status = 1 OR a.status = 5) AND a.tid = ?'; const sqlParam2 = [this.tableName, this.ctx.service.changeAudit.tableName, this.ctx.session.sessionUser.accountId, tenderId]; const result2 = await this.db.query(sql2, sqlParam2); return result2[0].count; case 2:// 进行中(所有的) case 3:// 已完成(所有的) case 4:// 终止(所有的) const sql3 = 'SELECT count(*) AS count FROM ?? AS a WHERE ' + 'a.cid IN (SELECT b.cid FROM ?? AS b WHERE b.uid = ? GROUP BY b.cid) AND a.status = ? AND a.tid = ?'; const sqlParam3 = [this.tableName, this.ctx.service.changeAudit.tableName, this.ctx.session.sessionUser.accountId, status, tenderId]; const result3 = await this.db.query(sql3, sqlParam3); return result3[0].count; default: break; } } /** * 上报或重新上报或保存修改功能 * @param {int} postData - 表单提交的数据 * @param {int} tenderId - 标段id * @return {void} */ async save(postData, tenderId) { // 初始化事务 this.transaction = await this.db.beginTransaction(); let result = false; try { // 变更令信息 const changeInfo = await this.getDataByCondition({ cid: postData.cid }); // 该变更令原报人信息 const lastUser = await this.ctx.service.changeAudit.getLastUser(changeInfo.cid, changeInfo.times, 0); // 先删除本次原有的变更审批人和清单 await this.ctx.service.changeAudit.deleteAuditData(this.transaction, changeInfo.cid, changeInfo.times); await this.transaction.delete(this.ctx.service.changeAuditList.tableName, { cid: changeInfo.cid }); let change_status = false; // 获取变更令提交状态 if (postData.changestatus !== undefined && parseInt(postData.changestatus) === 1) { change_status = true; // 更新原报人审批状态 await this.transaction.update(this.ctx.service.changeAudit.tableName, { id: lastUser.id, status: 3, sin_time: new Date() }); } // 再插入postData里的变更审批人和清单 if (postData.changeaudit !== undefined && postData.changeaudit !== '') { const changeAudit = postData.changeaudit.split(','); const insertCA = []; let uSite = 1; let uSort = parseInt(lastUser.usort) + 1; for (const [index, ca] of changeAudit.entries()) { const auditInfo = ca.split('/%/'); const uStatus = change_status && index === 0 ? 2 : 1; const sin_time = change_status && index === 0 ? new Date() : null; const caArray = { tid: tenderId, cid: changeInfo.cid, uid: auditInfo[0], name: auditInfo[1], jobs: auditInfo[2], company: auditInfo[3], times: changeInfo.times, usite: uSite, usort: uSort, status: uStatus, sin_time, }; uSite++; uSort++; insertCA.push(caArray); } await this.transaction.insert(this.ctx.service.changeAudit.tableName, insertCA); } let changeList = []; if (postData.changelist !== undefined && postData.changelist !== '') { changeList = postData.changelist.split('^_^'); } let changeWhiteList = []; if (postData.changewhitelist !== undefined && postData.changewhitelist !== '') { changeWhiteList = postData.changewhitelist.split('^_^'); } changeList.push.apply(changeList, changeWhiteList); const insertCL = []; let total_price = 0; if (changeList.length > 0) { for (const cl of changeList) { const clInfo = cl.split(';'); const clArray = { tid: tenderId, cid: changeInfo.cid, lid: clInfo[7], code: clInfo[0], name: clInfo[1], unit: clInfo[2], unit_price: clInfo[3], oamount: clInfo[4], camount: clInfo[5], samount: '', detail: clInfo[6], }; insertCL.push(clArray); total_price = this.ctx.helper.accAdd(total_price, this.ctx.helper.accMul(clArray.unit_price, clArray.camount)); } await this.transaction.insert(this.ctx.service.changeAuditList.tableName, insertCL); } // 修改变更令基本数据 const cArray = { code: postData.code, name: postData.name, peg: postData.peg, org_name: postData.org_name, org_code: postData.org_code, new_name: postData.new_name, new_code: postData.new_code, content: postData.content, basis: postData.basis, memo: postData.memo, type: postData.type.join(','), class: postData.class, quality: postData.quality, company: postData.company, charge: postData.charge, total_price, }; const options = { where: { cid: changeInfo.cid, }, }; if (change_status) { cArray.status = 2; cArray.cin_time = Date.parse(new Date()) / 1000; } await this.transaction.update(this.tableName, cArray, options); await this.transaction.commit(); result = true; } catch (error) { await this.transaction.rollback(); result = false; } return result; } /** * 审批通过 * @param {int} postData - 表单提交的数据 * @return {void} */ async approvalSuccess(postData) { // 初始化事务 this.transaction = await this.db.beginTransaction(); let result = false; try { // 设置审批人通过 const audit_update = { id: postData.audit_id, sdesc: postData.sdesc, status: 3, sin_time: new Date(), }; const change_update = { w_code: postData.w_code, status: 2, cin_time: Date.parse(new Date()) / 1000, }; await this.transaction.update(this.ctx.service.changeAudit.tableName, audit_update); // 清单数据更新 const bills_list = postData.bills_list.split(','); let total_price = 0; for (const bl of bills_list) { const listInfo = bl.split('_'); const lid = listInfo[0]; const amount = listInfo[1]; const changeListInfo = await this.ctx.service.changeAuditList.getDataById(lid); if (changeListInfo !== undefined) { total_price += this.ctx.helper.accMul(changeListInfo.unit_price, parseFloat(amount)); const audit_amount = changeListInfo.audit_amount !== null && changeListInfo.audit_amount !== '' ? changeListInfo.audit_amount.split(',') : []; audit_amount.push(amount); const list_update = { id: lid, audit_amount: audit_amount.join(','), }; if (postData.audit_next_id === undefined) { list_update.samount = amount; } await this.transaction.update(this.ctx.service.changeAuditList.tableName, list_update); } } if (postData.audit_next_id === undefined) { // 变更令审批完成 change_update.status = 3; change_update.p_code = postData.p_code; change_update.sin_time = Date.parse(new Date()) / 1000; change_update.total_price = total_price; } else { // 设置下一个审批人为审批状态 const nextAudit_update = { id: postData.audit_next_id, status: 2, }; await this.transaction.update(this.ctx.service.changeAudit.tableName, nextAudit_update); } const options = { where: { cid: postData.change_id, }, }; await this.transaction.update(this.tableName, change_update, options); await this.transaction.commit(); result = true; } catch (error) { await this.transaction.rollback(); result = false; } return result; } /** * 审批终止 * @param {int} postData - 表单提交的数据 * @return {void} */ async approvalStop(postData) { // 初始化事务 this.transaction = await this.db.beginTransaction(); let result = false; try { // 设置审批人终止 const audit_update = { id: postData.audit_id, sdesc: postData.sdesc, status: 4, sin_time: new Date(), }; await this.transaction.update(this.ctx.service.changeAudit.tableName, audit_update); // 设置变更令终止 const change_update = { w_code: postData.w_code, status: 4, cin_time: Date.parse(new Date()) / 1000, }; const options = { where: { cid: postData.change_id, }, }; await this.transaction.update(this.tableName, change_update, options); await this.transaction.commit(); result = true; } catch (error) { await this.transaction.rollback(); result = false; } return result; } /** * 审批退回到原报人 * @param {int} postData - 表单提交的数据 * @return {void} */ async approvalBack(postData) { // 初始化事务 this.transaction = await this.db.beginTransaction(); let result = false; try { const changeInfo = await this.getDataByCondition({ cid: postData.change_id }); // 设置审批人退回 const audit_update = { id: postData.audit_id, sdesc: postData.sdesc, status: 5, sin_time: new Date(), }; await this.transaction.update(this.ctx.service.changeAudit.tableName, audit_update); // 新增新一次的审批人列表 // 获取当前次数审批人列表 const auditList = await this.ctx.service.changeAudit.getListGroupByTimes(changeInfo.cid, changeInfo.times); const lastauditInfo = await this.ctx.service.changeAudit.getLastUser(changeInfo.cid, changeInfo.times, 1, 0); let usort = lastauditInfo.usort + 1; const newTimes = changeInfo.times + 1; const insert_audit_array = []; for (const al of auditList) { const insert_audit = { tid: al.tid, cid: al.cid, uid: al.uid, name: al.name, jobs: al.jobs, company: al.company, times: newTimes, usite: al.usite, usort, status: al.usite !== 0 ? 1 : 2, }; insert_audit_array.push(insert_audit); usort++; } await this.transaction.insert(this.ctx.service.changeAudit.tableName, insert_audit_array); // 设置变更令退回 const change_update = { w_code: postData.w_code, status: 5, times: newTimes, cin_time: Date.parse(new Date()) / 1000, }; const options = { where: { cid: postData.change_id, }, }; await this.transaction.update(this.tableName, change_update, options); await this.transaction.commit(); result = true; } catch (error) { await this.transaction.rollback(); result = false; } return result; } /** * 审批退回到上一个审批人 * @param {int} postData - 表单提交的数据 * @return {void} */ async approvalBackNew(postData) { // 初始化事务 this.transaction = await this.db.beginTransaction(); let result = false; try { const changeInfo = await this.getDataByCondition({ cid: postData.change_id }); // 设置审批人退回 const audit_update = { id: postData.audit_id, sdesc: postData.sdesc, status: 6, sin_time: new Date(), }; await this.transaction.update(this.ctx.service.changeAudit.tableName, audit_update); // 获取当前审批人信息 const auditInfo = await this.ctx.service.changeAudit.getDataById(postData.audit_id); // 获取当前次数审批人列表 const auditList = await this.ctx.service.changeAudit.getNextAuditList(changeInfo.cid, auditInfo.usort); let usort = auditInfo.usort + 1; // 获取上一个审批人信息 const lastauditInfo = await this.ctx.service.changeAudit.getDataById(postData.audit_last_id); // 新增2个审批人到审批列表中 const insert_audit1 = { tid: lastauditInfo.tid, cid: lastauditInfo.cid, uid: lastauditInfo.uid, name: lastauditInfo.name, jobs: lastauditInfo.jobs, company: lastauditInfo.company, times: lastauditInfo.times, usite: lastauditInfo.usite, usort, status: 2, }; await this.transaction.insert(this.ctx.service.changeAudit.tableName, insert_audit1); usort++; // 新增2个审批人到审批列表中 const insert_audit2 = { tid: auditInfo.tid, cid: auditInfo.cid, uid: auditInfo.uid, name: auditInfo.name, jobs: auditInfo.jobs, company: auditInfo.company, times: auditInfo.times, usite: auditInfo.usite, usort, status: 1, }; await this.transaction.insert(this.ctx.service.changeAudit.tableName, insert_audit2); // 把接下未审批的审批人排序都加2 for (const al of auditList) { const audit_update = { id: al.id, usort: al.usort + 2, }; await this.transaction.update(this.ctx.service.changeAudit.tableName, audit_update); } // 审批列表数据也要回退 const changeList = await this.ctx.service.changeAuditList.getAllDataByCondition({ where: { cid: changeInfo.cid } }); for (const cl of changeList) { const audit_amount = cl.audit_amount.split(','); audit_amount.splice(-1, 1); const list_update = { id: cl.id, audit_amount: audit_amount.join(','), }; await this.transaction.update(this.ctx.service.changeAuditList.tableName, list_update); } // 设置变更令退回 const change_update = { w_code: postData.w_code, status: 6, cin_time: Date.parse(new Date()) / 1000, }; const options = { where: { cid: postData.change_id, }, }; await this.transaction.update(this.tableName, change_update, options); await this.transaction.commit(); result = true; } catch (error) { await this.transaction.rollback(); result = false; } return result; } /** * 查询可用的变更令 * @param bills - 查询的清单 * @param pos - 查询的部位 * @returns {Promise<*>} - 可用的变更令列表 */ async getValidChanges(bills, pos) { const filter = 'cb.`code` = ' + this.db.escape(bills.b_code) + (pos ? ' And cb.`detail` = ' + this.db.escape(pos.name) : ''); const sql = 'SELECT c.cid, c.code, c.name, c.w_code, c.p_code, c.peg, c.org_name, c.org_code, c.new_name, c.new_code,' + ' c.content, c.basis, c.memo, c.type, c.class, c.quality, c.company, c.charge, ' + ' cb.code As b_code, cb.name As b_name, cb.unit As b_unit, cb.samount As b_amount, cb.detail As b_detail ' + ' FROM ?? As c ' + ' Left Join ?? As cb ' + ' On c.cid = cb.cid ' + ' WHERE c.status = ? And ' + filter; const sqlParam = [this.tableName, this.ctx.service.changeAuditList.tableName, audit.flow.status.checked]; const changes = await this.db.query(sql, sqlParam); for (const c of changes) { const aSql = 'SELECT ca.*, pa.name As u_name, pa.role As u_role ' + ' FROM ?? As ca ' + ' Left Join ?? As pa ' + ' On ca.uid = pa.id ' + ' Where ca.cid = ?'; const aSqlParam = [this.ctx.service.changeAtt.tableName, this.ctx.service.projectAccount.tableName, c.cid]; c.attachments = await this.db.query(aSql, aSqlParam); } // const sql = 'SELECT c.* FROM ?? As c' + // ' WHERE c.`cid` in (' + // ' SELECT cb.`cid` FROM ?? As cb' + // ' WHERE ' + filter + // ' GROUP BY cb.`cid`) ' + // ' And c.status = ?'; // const sqlParam = [this.tableName, this.ctx.service.changeAuditList.tableName, audit.flow.status.checked]; // const changes = await this.db.query(sql, sqlParam); // for (const c of changes) { // c.bills = await this.ctx.service.changeAuditList.getDataByCondition({cid: c.cid, code: bills.b_code}); // } return changes; } /** * 查询可用的变更令 * @param { string } cid - 查询的清单 * @return {Promise<*>} - 可用的变更令列表 */ async delete(cid) { // 初始化事务 this.transaction = await this.db.beginTransaction(); let result = false; try { // 先删除清单,审批人列表 await this.transaction.delete(this.ctx.service.changeAuditList.tableName, { cid }); await this.transaction.delete(this.ctx.service.changeAudit.tableName, { cid }); // 再删除附件和附件文件 const attList = await this.ctx.service.changeAtt.getAllDataByCondition({ where: { cid } }); if (attList.length !== 0) { for (const att of attList) { await fs.unlinkSync(path.join(this.app.baseDir, att.filepath)); } await this.transaction.delete(this.ctx.service.changeAtt.tableName, { cid }); } // 最后删除变更令 await this.transaction.delete(this.tableName, { cid }); await this.transaction.commit(); result = true; } catch (e) { await this.transaction.rollback(); result = false; } return result; } } return Change; };