'use strict'; const auditConst = require('../const/audit'); const changeMap = require('../const/weapp').changeMap; const measureType = require('../const/tender').measureType; const advanceConst = require('../const/advance'); const shenpiConst = require('../const/shenpi'); const stdConst = require('../const/standard'); const _ = require('lodash'); module.exports = app => { class WeappTenderController extends app.BaseController { async listManage(ctx) { try { const projectId = ctx.query.projectId; if (!projectId) { ctx.body = { err: 1, msg: '缺少projectId参数', data: null }; return; } const accountInfo = ctx.session.sessionUser; const userPermission = accountInfo !== undefined && accountInfo.permission !== '' ? JSON.parse(accountInfo.permission) : null; if (userPermission !== null && userPermission.tender !== undefined && userPermission.tender.indexOf('1') !== -1) { const subProject = await this.ctx.service.subProject.getDataById(projectId); const tenderList = await this.ctx.service.tender.getList('', userPermission, ctx.session.sessionUser.is_admin, '', subProject); for (const tender of tenderList) { // 查询当前审批期以及状态 const stage = await this.ctx.service.stage.getLastestStage(tender.id, true); tender.stage_order = stage && stage.order ? stage.order : null; tender.stage_status = stage && stage.status ? stage.status : null; } const categoryData = await this.ctx.service.category.getAllCategory(subProject); const renderData = { categoryData, tenderList, }; ctx.body = { err: 0, msg: '', data: renderData }; } else { ctx.body = { err: 1, msg: '您没有管理权限', data: null }; } } catch (err) { this.log(err); ctx.body = { err: 1, msg: err.toString(), data: null }; } } async detail(ctx) { try { const tender = ctx.tender.data; let bCalcTp = ctx.tender.data.user_id === ctx.session.sessionUser.accountId && ( ctx.tender.ledger_status === auditConst.ledger.status.checkNo || ctx.tender.ledger_status === auditConst.ledger.status.uncheck); const stages = await ctx.service.stage.getValidStages(ctx.tender.id); const lastStage = stages.length > 0 ? stages[0] : null; // await ctx.service.stage.getLastestStage(ctx.tender.id); const [change_tp, change_p_tp, change_n_tp, change_valuation_tp, change_unvaluation_tp] = await ctx.service.change.getChangeTp(ctx.tender.id); tender.change_tp = change_tp; tender.change_p_tp = change_p_tp; tender.change_n_tp = change_n_tp; tender.change_valuation_tp = change_valuation_tp; tender.change_unvaluation_tp = change_unvaluation_tp; if (lastStage) { await this.ctx.service.stage.checkStageGatherData(lastStage, ctx.session.sessionUser.is_admin); if ((!bCalcTp) && tender.measure_type === measureType.gcl.value) { bCalcTp = lastStage.status !== auditConst.stage.status.checked && !lastStage.readOnly; } if (bCalcTp) { const sum = await this.ctx.service.ledger.addUp({ tender_id: ctx.tender.id/* , is_leaf: true*/ }); tender.total_price = sum.total_price; tender.deal_tp = sum.deal_tp; } tender.sum = ctx.tender.info.calc_type === 'tp' ? ctx.helper.add(tender.total_price, tender.change_valuation_tp) : ctx.helper.add(tender.total_price, tender.change_tp); tender.gather_tp = ctx.helper.sum([lastStage.contract_tp, lastStage.qc_tp, lastStage.pc_tp]); tender.end_contract_tp = ctx.helper.sum([lastStage.contract_tp, lastStage.pre_contract_tp, lastStage.contract_pc_tp]); tender.end_qc_tp = ctx.helper.sum([lastStage.qc_tp, lastStage.pre_qc_tp, lastStage.qc_pc_tp]); tender.end_positive_qc_tp = ctx.helper.sum([lastStage.positive_qc_tp, lastStage.pre_positive_qc_tp, lastStage.positive_qc_pc_tp]); tender.end_negative_qc_tp = ctx.helper.sum([lastStage.negative_qc_tp, lastStage.pre_negative_qc_tp, lastStage.negative_qc_pc_tp]); tender.end_gather_tp = ctx.helper.add(tender.end_contract_tp, tender.end_qc_tp); tender.pre_gather_tp = ctx.helper.add(lastStage.pre_contract_tp, lastStage.pre_qc_tp); tender.yf_tp = lastStage.yf_tp; tender.sf_tp = lastStage.sf_tp; tender.qc_ratio = ctx.helper.mul(ctx.helper.div(tender.end_qc_tp, ctx.tender.info.deal_param.contractPrice, 2), 100); tender.pre_ratio = ctx.helper.mul(ctx.helper.div(tender.pre_gather_tp, tender.sum, 2), 100); tender.cur_ratio = ctx.helper.mul(ctx.helper.div(tender.gather_tp, tender.sum, 2), 100); tender.other_tp = ctx.helper.sub(ctx.helper.sub(tender.sum, tender.pre_gather_tp), tender.gather_tp); tender.other_ratio = Math.max(0, 100 - tender.pre_ratio - tender.cur_ratio); tender.end_yf_tp = ctx.helper.add(lastStage.yf_tp, lastStage.pre_yf_tp); tender.end_sf_tp = ctx.helper.add(lastStage.sf_tp, lastStage.pre_sf_tp); tender.undone_tp = ctx.helper.sub(ctx.helper.sub(ctx.helper.add(tender.total_price, change_tp), tender.end_contract_tp), tender.end_qc_tp); } else { if (bCalcTp) { const sum = await this.ctx.service.ledger.addUp({ tender_id: ctx.tender.id/* , is_leaf: true*/ }); tender.total_price = sum.total_price; tender.deal_tp = sum.deal_tp; } tender.sum = ctx.helper.add(tender.total_price, tender.change_tp); } // const monthProgress = []; // for (const s of stages) { // if (s.s_time) { // let progress = monthProgress.find(function(x) { // return x.month === s.s_time; // }); // if (!progress) { // progress = { month: s.s_time }; // monthProgress.push(progress); // } // progress.tp = ctx.helper.add(ctx.helper.add(progress.tp, s.contract_tp), s.qc_tp); // } // } // monthProgress.sort(function(x, y) { // return Date.parse(x.month) - Date.parse(y.month); // }); // let sum = 0; // for (const p of monthProgress) { // p.ratio = ctx.helper.mul(ctx.helper.div(p.tp, tender.sum, 4), 100); // sum = ctx.helper.add(sum, p.tp); // p.end_tp = sum; // p.end_ratio = ctx.helper.mul(ctx.helper.div(p.end_tp, tender.sum, 4), 100); // } ctx.body = { code: 0, msg: '', data: { tender, // monthProgress, // stagesEcharts: JSON.parse(JSON.stringify(stages)).reverse(), }, }; } catch (error) { this.log(error); ctx.body = { code: -1, msg: error.toString(), data: null }; } } async advanceList(ctx) { try { const { advanceType } = ctx.query; const typeCol = advanceConst.typeCol.find(x => x.type === Number(advanceType)); if (!typeCol) { ctx.body = { code: -1, msg: '预付款类型错误', data: null }; return; } const { decimal } = ctx.tender.info; const advancePayTotal = ctx.tender.info.deal_param[typeCol.key + 'Advance']; const advances = await ctx.service.advance.getAdvanceList(ctx.tender.id, typeCol.type, decimal.pay ? decimal.payTp : decimal.tp, advancePayTotal); ctx.body = { code: 0, msg: '', data: advances }; } catch (error) { this.log(error); ctx.body = { code: -1, msg: error.toString(), data: null }; } } async advanceCheck(advance) { if (!advance) { throw '预付款数据错误'; } const times = advance.status === auditConst.advance.status.checkNo ? advance.times - 1 : advance.times; advance.user = await this.service.projectAccount.getAccountInfoById(advance.uid); // 读取审核人列表数据 advance.auditors = await this.service.advanceAudit.getAuditorsWithOwner(advance.id, advance.status === auditConst.advance.status.checkNo && this.ctx.session.sessionUser.accountId !== advance.uid ? times : advance.times); advance.auditHistory = await this.service.advanceAudit.getAuditors(advance.id, advance.times); advance.curAuditor = await this.service.advanceAudit.getCurAuditor(advance.id, advance.times); // 根据状态判断是否需要更新审批人列表 if ((advance.status === auditConst.advance.status.uncheck || advance.status === auditConst.advance.status.checkNo) && this.ctx.tender.info.shenpi.advance !== shenpiConst.sp_status.sqspr) { const shenpi_status = this.ctx.tender.info.shenpi.advance; // 进一步比较审批流是否与审批流程设置的相同,不同则替换为固定审批流或固定的终审 const auditList = await this.service.advanceAudit.getAllDataByCondition({ where: { vid: advance.id, times: advance.times }, orders: [['order', 'asc']] }); const auditIdList = _.map(auditList, 'audit_id'); if (shenpi_status === shenpiConst.sp_status.gdspl) { const shenpiList = await this.service.shenpiAudit.getAllDataByCondition({ where: { tid: advance.tid, sp_type: shenpiConst.sp_type.advance, sp_status: shenpi_status } }); const shenpiIdList = _.map(shenpiList, 'audit_id'); // 判断2个id数组是否相同,不同则删除原审批流,切换成固定的审批流 if (!_.isEqual(auditIdList, shenpiIdList)) { await this.service.advanceAudit.updateNewAuditList(advance, shenpiIdList); } } else if (shenpi_status === shenpiConst.sp_status.gdzs) { const shenpiInfo = await this.service.shenpiAudit.getDataByCondition({ tid: advance.tid, sp_type: shenpiConst.sp_type.advance, sp_status: shenpi_status }); // 判断最后一个id是否与固定终审id相同,不同则删除原审批流中如果存在的id和添加终审 if (shenpiInfo && shenpiInfo.audit_id !== _.last(auditIdList)) { await this.service.advanceAudit.updateLastAudit(advance, auditList, shenpiInfo.audit_id); } else if (!shenpiInfo) { // 不存在终审人的状态下这里恢复为授权审批人 this.ctx.tender.info.shenpi.advance = shenpiConst.sp_status.sqspr; } } } advance.advancePayTotal = this.ctx.tender.info.deal_param[advanceConst.typeCol[advance.type].key + 'Advance']; if (advance.status === auditConst.advance.status.checkNo) { advance.curAuditor = await this.service.advanceAudit.getAuditorByStatus(advance.id, advance.status, times); advance.auditHistory = await this.service.advanceAudit.getAuditors(advance.id, times); } } async advanceDetail(ctx) { try { const { id } = ctx.query; const advance = await this.service.advance.getDataById(id); if (!advance) { throw '预付款数据错误'; } await this.advanceCheck(advance); advance.auditHistory = advance.auditHistory.reduce((prev, curr, idx) => { if (idx === 0) { const reportor = { audit_id: advance.uid, audit_order: 0, audit_type: 1, status: advance.status === auditConst.advance.status.uncheck ? auditConst.advance.status.uncheck : auditConst.advance.status.checked, times: curr.times, begin_time: advance.pay_time, end_time: advance.auditHistory.length ? advance.auditHistory[0].create_time : null, name: advance.user.name, company: advance.user.company, role: advance.user.role, mobile: '', opinion: '', }; prev.push({ name: '原报', status: reportor.status, audit_type: reportor.audit_type, auditors: [reportor], }); } const currentOrder = advance.auditors.find(auditor => auditor.audit_id === curr.audit_id).order; prev.push( { name: currentOrder === curr.max_sort ? '终审' : `${currentOrder}审`, status: curr.status, audit_type: 1, auditors: [{ audit_id: curr.audit_id, audit_order: curr.order, audit_type: curr.type, status: curr.status, max_sort: curr.max_sort, begin_time: curr.create_time, end_time: curr.end_time, name: curr.name, company: curr.company, mobile: curr.mobile, opinion: curr.opinion, role: curr.role, times: curr.times, }], } ); return prev; }, []); if (advance.curAuditor) { advance.curAuditor.audit_order = advance.auditors.find(auditor => auditor.audit_id === advance.curAuditor.audit_id).order; } ctx.body = { code: 0, msg: '', data: { advance } }; } catch (error) { this.log(error); ctx.body = { code: -1, msg: error.toString(), data: null }; } } async advanceAudit(ctx) { try { const advance = await this.service.advance.getDataById(ctx.request.body.id); await this.advanceCheck(advance); ctx.advance = advance; const data = { checkType: parseInt(ctx.request.body.checkType), opinion: ctx.request.body.opinion, }; if (!advance || advance.status !== auditConst.advance.status.checking) { throw '当前预付款数据有误'; } if (!advance.curAuditor || advance.curAuditor.audit_id !== ctx.session.sessionUser.accountId) { throw '您无权进行该操作'; } if (!data.checkType || isNaN(data.checkType)) { throw '提交数据错误'; } if (data.checkType === auditConst.advance.status.checkNo) { if (!data.checkType || isNaN(data.checkType)) { throw '提交数据错误'; } } await ctx.service.advanceAudit.check(advance.id, data, advance.times, advance.type); ctx.body = { code: 0, msg: '操作成功', data: null }; } catch (error) { this.log(error); ctx.body = { code: -1, msg: error.toString(), data: null }; } } async reviseDetail(ctx) { try { const { rid } = ctx.query; const revise = rid ? await ctx.service.ledgerRevise.getRevise(ctx.tender.id, rid) : ctx.service.ledgerRevise.getLastestRevise(ctx.tender.id); revise.preHis = revise.pre_his_id ? await ctx.service.ledgerHistory.getDataById(revise.pre_his_id) : null; revise.curHis = revise.his_id ? await ctx.service.ledgerHistory.getDataById(revise.his_id) : null; await ctx.service.reviseAudit.loadReviseUser(revise); await ctx.service.reviseAudit.loadReviseAuditViewData(revise); revise.auditHistory = revise.auditors.reduce((prev, curr, idx) => { if (idx === 0) { const reportor = { audit_id: revise.uid, audit_order: 0, audit_type: 1, status: revise.status === auditConst.revise.status.uncheck ? auditConst.revise.status.uncheck : auditConst.revise.status.checked, times: curr.times, begin_time: revise.in_time, end_time: revise.auditors.length ? revise.auditors[0].begin_time : null, name: revise.user.name, company: revise.user.company, role: revise.user.role, mobile: '', opinion: '', }; prev.push({ name: '原报', status: reportor.status, audit_type: reportor.audit_type, auditors: [reportor], }); } const currentOrder = curr.audit_order; prev.push( { name: currentOrder === curr.max_sort ? '终审' : `${currentOrder}审`, status: curr.status, audit_type: 1, auditors: [{ audit_id: curr.audit_id, audit_order: curr.audit_order, audit_type: curr.audit_type, status: curr.status, max_sort: curr.max_sort, begin_time: curr.begin_time, end_time: curr.end_time, name: curr.name, company: curr.company, mobile: curr.mobile, opinion: curr.opinion, role: curr.role, times: curr.times, }], } ); return prev; }, []); const GclGather = require('../lib/gcl_gather'); const gclGatherModal = new GclGather.gclCompareGather(this.ctx); const spec = { zlj: stdConst.zlj, jrg: stdConst.jrg }; spec.zlj.deal_bills_tp = ctx.tender.info.deal_param.zanLiePrice; gclGatherModal.init(ctx.tender.info.chapter, spec); const reviseBillsData = revise.readOnly && revise.curHis ? await ctx.helper.loadLedgerDataFromOss(revise.curHis.bills_file) : await ctx.service.reviseBills.getAllDataByCondition({ where: { tender_id: ctx.tender.id } }); const revisePosData = revise.readOnly && revise.curHis ? await this.ctx.helper.loadLedgerDataFromOss(revise.curHis.pos_file) : await ctx.service.revisePos.getAllDataByCondition({ where: { tid: ctx.tender.id } }); const price = await this.ctx.service.revisePrice.getAllDataByCondition({ where: { rid: revise.id } }); gclGatherModal.gatherReviseLedgerData(reviseBillsData, revisePosData, { prefix: 'new_' }, price, ctx.tender.info.decimal); const billsData = revise.preHis ? await this.ctx.helper.loadLedgerDataFromOss(revise.preHis.bills_file) : []; const posData = revise.preHis ? await this.ctx.helper.loadLedgerDataFromOss(revise.preHis.pos_file) : []; gclGatherModal.gatherLedgerData(billsData, posData, { prefix: 'org_' }); revise.chapterList = gclGatherModal.chapterData(); revise.new_tp = gclGatherModal.otherChapter.hj.new_total_price || 0; revise.org_tp = gclGatherModal.otherChapter.hj.org_total_price || 0; console.log(ctx.tender.data.name); revise.tenderName = ctx.tender.data.name; ctx.body = { code: 0, msg: '', data: { revise } }; } catch (error) { ctx.log(error); ctx.body = { code: -1, msg: error.toString(), data: null }; } } async ledgerAuditCheck(ctx) { const tender = ctx.tender.data; const info = ctx.tender.info; if (info.shenpi.ledger === shenpiConst.sp_status.sqspr) return; if (tender.ledger_status !== auditConst.ledger.status.uncheck && tender.ledger_status !== auditConst.ledger.status.checkNo) return; const shenpi_status = info.shenpi.ledger; // 进一步比较审批流是否与审批流程设置的相同,不同则替换为固定审批流或固定的终审 const auditList = await ctx.service.ledgerAudit.getAuditors(tender.id, tender.ledger_times); if (shenpi_status === shenpiConst.sp_status.gdspl) { const shenpiList = await ctx.service.shenpiAudit.getAllDataByCondition({ where: { tid: tender.id, sp_type: shenpiConst.sp_type.ledger, sp_status: shenpi_status } }); // 判断2个id数组是否相同,不同则删除原审批流,切换成固定的审批流 let sameAudit = auditList.length === shenpiList.length; if (sameAudit) { for (const audit of auditList) { const shenpi = shenpiList.find(x => { return x.audit_id === audit.audit_id; }); if (!shenpi || shenpi.audit_order !== audit.audit_order || shenpi.audit_type !== audit.audit_type || shenpi.audit_ledger_id !== audit.audit_ledger_id) { sameAudit = false; break; } } } if (!sameAudit) await ctx.service.ledgerAudit.updateNewAuditList(tender, shenpiList); } else if (shenpi_status === shenpiConst.sp_status.gdzs) { const shenpiInfo = await ctx.service.shenpiAudit.getDataByCondition({ tid: tender.id, sp_type: shenpiConst.sp_type.ledger, sp_status: shenpi_status }); // 判断最后一个id是否与固定终审id相同,不同则删除原审批流中如果存在的id和添加终审 const lastAuditors = auditList.filter(x => { x.audit_order === auditList[auditList.length - 1].audit_order; }); if (shenpiInfo && (lastAuditors.length === 0 || (lastAuditors.length > 1 || shenpiInfo.audit_id !== lastAuditors[0].audit_id))) { await ctx.service.ledgerAudit.updateLastAudit(tender, auditList, shenpiInfo.audit_id); } else if (!shenpiInfo) { // 不存在终审人的状态下这里恢复为授权审批人 info.shenpi.ledger = shenpiConst.sp_status.sqspr; } } } async ledgerDetail(ctx) { try { await this.ledgerAuditCheck(ctx); const tender = ctx.tender.data; await ctx.service.ledgerAudit.loadLedgerUser(tender); await ctx.service.ledgerAudit.loadLedgerAuditViewData(tender); const auditHistory = tender.auditHistory && tender.auditHistory.length && tender.auditHistory[tender.auditHistory.length - 1].reduce((prev, curr, idx) => { if (idx === 0) { const reportor = { audit_id: tender.user.id, audit_order: 0, audit_type: 1, status: tender.ledger_status === auditConst.ledger.status.uncheck ? auditConst.ledger.status.uncheck : auditConst.ledger.status.checked, times: tender.ledger_status === auditConst.ledger.status.checkNo ? tender.ledger_times - 1 : tender.ledger_times, begin_time: curr.begin_time, end_time: curr.begin_time, name: tender.user.name, company: tender.user.company, role: tender.user.role, mobile: '', opinion: '', }; prev.push({ name: '原报', status: reportor.status, audit_type: reportor.audit_type, auditors: [reportor], }); } prev.push({ name: curr.is_final ? '终审' : `${curr.order}审`, audit_type: curr.audit_type, status: curr.status, auditors: curr.auditors, }); return prev; }, []); const curAuditors = tender.curAuditors; const ledger = { contractPrice: ctx.tender.info.deal_param.contractPrice, totalPrice: tender.total_price || 0, auditHistory, curAuditors, }; ctx.body = { code: 0, msg: '', data: { ledger } }; } catch (error) { this.log(error); ctx.body = { code: -1, msg: error.toString(), data: null }; } } async ledgerAudit(ctx) { try { await this.ledgerAuditCheck(ctx); const tender = ctx.tender; if (!tender.data || tender.data.ledger_status !== auditConst.ledger.status.checking) { throw '当前标段数据有误'; } const curAudits = await ctx.service.ledgerAudit.getCurAuditors(tender.id, tender.data.ledger_times); const curAuditIds = curAudits.map(x => { return x.audit_id; }); if (curAuditIds.indexOf(ctx.session.sessionUser.accountId) < 0) { throw '审批失败'; } const checkType = parseInt(ctx.request.body.checkType); if (!checkType || isNaN(checkType)) { throw '提交数据错误'; } await ctx.service.ledgerAudit.check(tender.id, checkType, ctx.request.body.opinion, tender.data.ledger_times); ctx.body = { code: 0, msg: '操作成功', data: null }; } catch (error) { this.log(error); ctx.body = { code: -1, msg: error.toString(), data: null }; } } async changeList(ctx) { try { const { type } = ctx.request.query; const curChangeMap = changeMap[type]; if (!curChangeMap) { throw '变更类型错误'; } const tender = ctx.tender.data; const list = await ctx.service[curChangeMap.service].getListByStatus(tender.id, 0, 1, 0, 0, 0); ctx.body = { code: 0, msg: '', data: list }; } catch (error) { this.log(error); ctx.body = { code: -1, msg: error.toString(), data: null }; } } async changeCheck(ctx) { try { const { type } = ctx.request.query || ctx.request.body; const curChangeMap = changeMap[type]; const subProject = await ctx.service.subProject.getDataById(ctx.tender.data.spid); if (curChangeMap && curChangeMap.pageShowKey && !subProject.page_show[curChangeMap.pageShowKey]) { throw '该功能已关闭'; } const id = ctx.request.query.id || this.request.body.id; if (!id) { throw '您访问的变更数据不存在'; } const condition = { [type === 'change' ? 'cid' : 'id']: id }; const change = await ctx.service[curChangeMap.service].getDataByCondition(condition); console.log(change); if (!change) throw '变更方案数据有误'; // 读取原报、审核人数据 await ctx.service[curChangeMap.service].loadChangeUser(change); // decimal小数位设置 change.decimal = change.decimal ? JSON.parse(change.decimal) : { tp: ctx.tender.info.decimal.tp, up: ctx.tender.info.decimal.up, precision: ctx.tender.info.precision }; // 权限相关 // todo 校验权限 (标段参与人、分享) const accountId = ctx.session.sessionUser.accountId, shareIds = []; const permission = ctx.session.sessionUser.permission; const status = auditConst[type].status; if (accountId === change.uid) { // 原报 change.curTimes = change.times; change.filePermission = true; } else if (change.auditorIds.indexOf(accountId) !== -1) { // 审批人 if (change.status === status.uncheck) { throw '您无权查看该数据'; } // change.readOnly = change.status !== status.checking || accountId !== change.curAuditor.aid; change.curTimes = change.status === status.checkNo || change.status === status.revise ? change.times - 1 : change.times; change.filePermission = true; } else if ((change.status === status.checkNo || change.status === status.revise) && change.uid !== accountId) { const preAuditors = await ctx.service[curChangeMap.auditService].getAuditors(change.id, change.times - 1); const preAuditorIds = _.map(preAuditors, 'aid'); if (preAuditorIds.indexOf(accountId) === -1) { throw '您无权查看该数据'; } change.filePermission = true; } else if (ctx.tender.isTourist || ctx.session.sessionUser.is_admin) { change.curTimes = change.times; change.filePermission = ctx.tender.touristPermission.file || change.auditorIds.indexOf(accountId) !== -1; } else if (shareIds.indexOf(accountId) !== -1 || (permission !== null && permission.tender !== undefined && permission.tender.indexOf('2') !== -1)) { // 分享人 if (change.status === auditConsts[type].status.uncheck) { throw '您无权查看该数据'; } // change.readOnly = true; change.curTimes = change.status === auditConsts[type].status.checkNo || change.status === auditConsts[type].status.revise ? change.times - 1 : change.times; change.filePermission = false; } else { // 其他不可见 throw '您无权查看该数据'; } // 调差的readOnly 指表格和页面只能看不能改,和审批无关 change.readOnly = !((change.status === status.uncheck || change.status === status.checkNo || change.status === status.revise) && accountId === change.uid); change.shenpiPower = change.status === status.checking && change.curAuditorIds.indexOf(accountId) !== -1; this.change = change; await ctx.service[curChangeMap.service].doCheckChangeCanCancel(this.change); } catch (error) { this.log(error); ctx.body = { code: -1, msg: error.toString(), data: null }; } } async changeDetail(ctx) { try { await this.changeCheck(ctx); const { type } = ctx.request.query || ctx.request.body; const curChangeMap = changeMap[type]; await ctx.service[curChangeMap.service].loadChangeUser(this.change); await ctx.service[curChangeMap.service].loadChangeAuditViewData(this.change); const tpUnit = ctx.tender.info.decimal.tp; const subProject = await ctx.service.subProject.getDataById(ctx.tender.data.spid); const fun_set = subProject.fun_set; const auditHistory = this.change.auditHistory && this.change.auditHistory.length && this.change.auditHistory[this.change.auditHistory.length - 1].reduce((prev, curr, idx) => { prev.push({ name: curr.is_final ? '终审' : curr.audit_order === 0 ? '原报' : `${curr.audit_order}审`, audit_type: curr.audit_type, status: curr.status, auditors: curr.auditors.map(a => ({...a, audit_id: a.uid})), }); return prev; }, []); const curAuditors = this.change.curAuditors; const change = { id: this.change.id || this.change.cid, name: this.change.name, status: this.change.status, code: this.change.code, p_code: this.change.p_code, quality: this.change.quality, auditHistory, originHistory: this.change.auditHistory, curAuditors: curAuditors.map(a => ({...a, audit_id: a.uid})), total_price: ctx.helper.add(this.change.total_price, tpUnit), valuation_tp: ctx.helper.add(this.change.valuation_tp, tpUnit), unvaluation_tp: ctx.helper.add(this.change.unvaluation_tp, tpUnit), state_name: subProject.page_show.openChangeState ? ctx.helper._.find(fun_set.change_state, { order: this.change.state }).name : '', plan_code: this.change.plan_code, peg: this.change.peg, org_name: this.change.org_name, }; ctx.body = { code: 0, msg: '', data: { change, } }; } catch (error) { this.log(error); ctx.body = { code: -1, msg: error.toString(), data: null }; } } async changeAuditCheck(ctx) { const id = ctx.request.body.id; if (!id) { throw '您访问的变更数据不存在'; } const type = ctx.request.body.type; const curChangeMap = changeMap[type]; if (!this.change) { const change = await this.service[curChangeMap.service].getDataById(id); if (!change) throw '变更数据有误'; await this.service[curChangeMap.service].loadChangeUser(change); this.change = change; } const change = this.change; const status = auditConst[type].status; if ((change.status === status.uncheck || change.status === status.checkNo || change.status === status.revise) && ctx.tender.info.shenpi.change !== shenpiConst.sp_status.sqspr) { const shenpi_status = ctx.tender.info.shenpi.change; // 进一步比较审批流是否与审批流程设置的相同,不同则替换为固定审批流或固定的终审 const auditList = await ctx.service[curChangeMap.auditService].getAllDataByCondition({ where: { caid: change.id, times: change.times }, orders: [['order', 'asc']] }); if (shenpi_status === shenpiConst.sp_status.gdspl) { // 判断并获取审批组 const group = await ctx.service.shenpiGroup.getSelectGroupByChangeType(ctx.tender.id, shenpiConst.sp_type.change, type, change.sp_group); if ((group && change.sp_group !== group.id) || (!group && change.sp_group !== 0)) { change.sp_group = group ? group.id : 0; await ctx.service[curChangeMap.service].defaultUpdate({ id: change.id, sp_group: change.sp_group }); } const condition = { tid: ctx.tender.id, sp_type: shenpiConst.sp_type.change, sp_status: shenpi_status, sp_group: change.sp_group }; const shenpiList = await ctx.service.shenpiAudit.getAllDataByCondition({ where: condition, orders: [['audit_order', 'asc']] }); await ctx.service.shenpiAudit.noYbShenpiList(change.uid, shenpiList); if (change.sp_group === 0 && shenpiList.length === 0) { ctx.tender.info.shenpi.change = shenpiConst.sp_status.sqspr; } else { // 判断2个id数组是否相同,不同则删除原审批流,切换成固定的审批流 let sameAudit = auditList.length === shenpiList.length; if (sameAudit) { for (const audit of auditList) { const shenpi = shenpiList.find(x => { return x.audit_id === audit.aid; }); if (!shenpi || shenpi.audit_order !== audit.audit_order || shenpi.audit_type !== audit.audit_type) { sameAudit = false; break; } } } if (!sameAudit) { await ctx.service[curChangeMap.auditService].updateNewAuditList(change, shenpiList); await ctx.service[curChangeMap.service].loadChangeUser(change); await ctx.service[curChangeMap.service].doCheckChangeCanCancel(change); } } } else if (shenpi_status === shenpiConst.sp_status.gdzs) { const shenpiInfo = await ctx.service.shenpiAudit.getDataByCondition({ tid: ctx.tender.id, sp_type: shenpiConst.sp_type.change, sp_status: shenpi_status }); if (!shenpiInfo || (shenpiInfo && shenpiInfo.audit_id === change.uid)) { // 不存在终审人 或 存在终审但与原报相同时, 这里恢复为授权审批人 ctx.tender.info.shenpi.change = shenpiConst.sp_status.sqspr; } else { // 判断最后一个id是否与固定终审id相同,不同则删除原审批流中如果存在的id和添加终审 const lastAuditors = auditList.filter(x => { return x.order === auditList.length - 1; }); if (shenpiInfo && (lastAuditors.length === 0 || (lastAuditors.length > 1 || shenpiInfo.audit_id !== lastAuditors[0].aid))) { await ctx.service[curChangeMap.auditService].updateLastAudit(change, auditList, shenpiInfo.audit_id); await ctx.service[curChangeMap.service].loadChangeUser(change); await ctx.service[curChangeMap.service].doCheckChangeCanCancel(change); } } } } } async changeAudit(ctx) { try { const { type } = ctx.request.body; await this.changeCheck(ctx); await this.changeAuditCheck(ctx); const curChangeMap = changeMap[type]; const auditConst = auditConsts[type]; if (!ctx.change || ctx.change.status !== auditConst.status.checking) { throw '当前变更申请数据有误'; } if (ctx.change.curAuditorIds.length === 0 || ctx.change.curAuditorIds.indexOf(ctx.session.sessionUser.accountId) === -1) { throw '您无权进行该操作'; } const data = { checkType: parseInt(ctx.request.body.checkType), opinion: ctx.request.body.opinion, }; if (!data.checkType || isNaN(data.checkType)) { throw '提交数据错误'; } await ctx.service[auditConst.auditService].check(ctx.change.id, data, ctx.change.times); ctx.body = { code: 0, msg: '操作成功', data: null }; } catch (error) { this.log(error); ctx.body = { code: -1, msg: error.toString(), data: null }; } } } return WeappTenderController; };