'use strict'; const auditConsts = require('../const/audit'); const shenpiConst = require('../const/shenpi'); const auditType = require('../const/audit').auditType; const _ = require('lodash'); module.exports = app => { class WeappMeasureController extends app.BaseController { async stage(ctx) { try { const stages = await ctx.service.stage.getValidStages(ctx.tender.id, this.ctx.session.sessionUser.is_admin); for (const s of stages) { if (!s.final_auditor_str || s.status !== auditConsts.stage.status.checked) { if (s.status === auditConsts.stage.status.checkNoPre) s.status = auditConsts.stage.status.checking; if (s.status !== auditConsts.stage.status.checkNo) s.curAuditors = await ctx.service.stageAudit.getAuditorsByStatus(s.id, s.status, s.times); if (s.status === auditConsts.stage.status.checked) { const final_auditor_str = (s.curAuditors[0].audit_type === auditConsts.auditType.key.common) ? `${s.curAuditors[0].name}${(s.curAuditors[0].role ? '-' + s.curAuditors[0].role : '')}` : ctx.helper.transFormToChinese(s.curAuditors[0].audit_order) + '审'; await ctx.service.stage.defaultUpdate({ id: s.id, final_auditor_str }); } } } ctx.body = { code: 0, msg: '', data: stages }; } catch (err) { this.log(err); ctx.body = { code: 1, msg: err.toString(), data: null }; } } async auditCheck(ctx) { const stageId = ctx.request.query.stageId || ctx.request.body.stageId; const stageOrder = ctx.request.query.order || ctx.request.body.order; if (!stageId && !stageOrder) { ctx.body = { code: -1, msg: '计量期参数错误', data: null }; return; } const stage = await ctx.service.stage.getDataByCondition({ tid: ctx.tender.id, order: stageOrder, }); if (!stage) { ctx.body = { code: -1, msg: '计量期不存在', data: null }; return; } await ctx.service.stage.loadStageUser(stage); await ctx.service.stage.loadPreCheckedStage(stage); await ctx.service.stage.doCheckStage(stage); await ctx.service.stage.loadStageAuditViewData(stage); const tender = ctx.tender.data; const info = ctx.tender.info; // 历史台账 if (stage.status === auditConsts.stage.status.checked) { stage.ledgerHis = await this.service.ledgerHistory.getDataById(stage.his_id); } // 获取最新的期 stage.highOrder = await this.service.stage.count({ tid: tender.id, }); const materials = await this.service.material.getAllDataByCondition({ columns: ['stage_id', 's_order'], where: { tid: tender.id } }); stage.hadMaterial = materials.find(function(item) { return item.s_order.split(',').indexOf(stage.highOrder.toString()) !== -1; }); const phasePays = await this.service.phasePay.getAllDataByCondition({ columns: ['rela_stage'], where: { tid: tender.id } }); stage.hadPhasePay = phasePays.find(function(pp) { pp.rela_stage = pp.rela_stage ? JSON.parse(pp.rela_stage) : []; return pp.rela_stage.find(x => { return x.stage_id === stage.id; }); }); // 权限相关 // todo 校验权限 (标段参与人、分享、游客) const accountId = this.ctx.session.sessionUser.accountId; const shareIds = []; if (stage.status === auditConsts.stage.status.uncheck) { stage.readOnly = accountId !== stage.user_id && stage.userAssistIds.indexOf(accountId) < 0; if (!stage.readOnly) { stage.assist = stage.userAssists.find(x => { return x.ass_user_id === accountId; }); } stage.curTimes = stage.times; stage.curOrder = 0; } else if (stage.status === auditConsts.stage.status.checkNo) { stage.readOnly = accountId !== stage.user_id && stage.userAssistIds.indexOf(accountId) < 0; const checkNoAudit = await this.service.stageAudit.getDataByCondition({ sid: stage.id, times: stage.times - 1, status: auditConsts.stage.status.checkNo, }); if (!stage.readOnly) { stage.assist = stage.userAssists.find(x => { return x.ass_user_id === accountId; }); stage.curTimes = stage.times; stage.curOrder = 0; } else { stage.curTimes = stage.times - 1; stage.curOrder = checkNoAudit.order; } } else if (stage.status === auditConsts.stage.status.checked) { stage.readOnly = true; stage.curTimes = stage.times; stage.curOrder = _.max(_.map(stage.auditors, 'order')); } else { const ass = stage.auditAssists.find(x => { return stage.flowAuditorIds.indexOf(x.user_id) >= 0 && x.ass_user_id === accountId; }); stage.readOnly = stage.flowAuditorIds.indexOf(accountId) < 0 && !ass; stage.curTimes = stage.times; if (!stage.readOnly) { stage.assist = ass; stage.curOrder = stage.curAuditors[0].order; } else { stage.curOrder = stage.curAuditors[0].order - 1; } if (!stage.readOnly) { if (stage.curAuditors[0].audit_type === auditType.key.and) { stage.readOnly = !_.isEqual(stage.flowAuditorIds, stage.curAuditorIds); stage.canCheck = true; } else if (stage.curAuditors[0].audit_type === auditType.key.union) { stage.readOnly = stage.relaAuditor.status === auditConsts.stage.status.checked; stage.canCheck = !stage.readOnly; } } } if (stage.readOnly) { stage.assist = accountId === stage.user_id || stage.auditorIds.indexOf(accountId) >= 0 ? null : stage.auditAssists.find(x => { return x.ass_user_id === accountId; }); } const permission = this.ctx.session.sessionUser.permission; if (stage.userIds.indexOf(accountId) >= 0 || this.ctx.session.sessionUser.is_admin) { stage.filePermission = true; } else { if (shareIds.indexOf(accountId) !== -1 || (permission !== null && permission.tender !== undefined && permission.tender.indexOf('2') !== -1)) { // 分享人 if (stage.status === auditConsts.status.uncheck) { throw '您无权查看该数据'; } stage.filePermission = false; } else if (this.ctx.tender.isTourist || this.ctx.session.sessionUser.is_admin) { stage.filePermission = this.ctx.tender.touristPermission.file || stage.auditorIds.indexOf(accountId) !== -1; } else { throw '您无权查看该数据'; } } // 判断stage流程可否撤回,是哪一种撤回 // yield this.service.stage.doCheckStageCanCancel(stage); // 是否台账修订中 const lastRevise = await this.service.ledgerRevise.getLastestRevise(this.ctx.tender.id); stage.revising = (lastRevise && lastRevise.status !== auditConsts.revise.status.checked) || false; // 根据状态判断是否需要更新审批人列表 await this.service.stage.doCheckStageCanCancel(stage); stage.readySettle = await this.service.settle.getReadySettle(stage.tid); ctx.stage = stage; // 根据状态判断是否需要更新审批人列表 if ((stage.status === auditConsts.stage.status.uncheck || stage.status === auditConsts.stage.status.checkNo) && this.ctx.tender.info.shenpi.stage !== shenpiConst.sp_status.sqspr) { const shenpi_status = this.ctx.tender.info.shenpi.stage; // 进一步比较审批流是否与审批流程设置的相同,不同则替换为固定审批流或固定的终审 const auditList = await this.service.stageAudit.getAllDataByCondition({ where: { sid: stage.id, times: stage.times }, orders: [['order', 'asc']] }); if (shenpi_status === shenpiConst.sp_status.gdspl) { // 判断并获取审批组 const group = await this.service.shenpiGroup.getSelectGroupByStageType(this.ctx.tender.id, shenpiConst.sp_type.stage, stage.sp_group); if ((group && stage.sp_group !== group.id) || (!group && stage.sp_group !== 0)) { stage.sp_group = group ? group.id : 0; await this.service.stage.defaultUpdate({ sp_group: stage.sp_group }, { where: { id: stage.id } }); } const condition = { tid: this.ctx.tender.id, sp_type: shenpiConst.sp_type.stage, sp_status: shenpi_status, sp_group: stage.sp_group }; const shenpiList = await this.service.shenpiAudit.getAllDataByCondition({ where: condition, orders: [['audit_order', 'asc']] }); // 判断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 || shenpi.audit_ledger_id !== audit.audit_ledger_id) { sameAudit = false; break; } } } if (!sameAudit) { await this.service.stageAudit.updateNewAuditList(stage, shenpiList); await this.service.stage.loadStageUser(stage); } } else if (shenpi_status === shenpiConst.sp_status.gdzs) { const shenpiInfo = await this.service.shenpiAudit.getDataByCondition({ tid: stage.tid, sp_type: shenpiConst.sp_type.stage, sp_status: shenpi_status }); // 判断最后一个id是否与固定终审id相同,不同则删除原审批流中如果存在的id和添加终审 const lastAuditors = auditList.filter(x => { x.order === auditList[auditList.length - 1].order; }); if (shenpiInfo && (lastAuditors.length === 0 || (lastAuditors.length > 1 || shenpiInfo.audit_id !== lastAuditors[0].aid))) { await this.service.stageAudit.updateLastAudit(stage, auditList, shenpiInfo.audit_id); await this.service.stage.loadStageUser(stage); } else if (!shenpiInfo) { // 不存在终审人的状态下这里恢复为授权审批人 info.shenpi.stage = shenpiConst.sp_status.sqspr; } } } } async detail(ctx) { try { await this.auditCheck(ctx); ctx.stage.auditHistory = ctx.stage.auditHistory && ctx.stage.auditHistory.length && ctx.stage.auditHistory[ctx.stage.auditHistory.length - 1].reduce((prev, curr, idx) => { if (idx === 0) { const reportor = { audit_id: ctx.stage.user.id, audit_order: 0, audit_type: 1, status: ctx.stage.status === auditConsts.stage.status.uncheck ? auditConsts.stage.status.uncheck : auditConsts.stage.status.checked, times: ctx.stage.status === auditConsts.stage.status.checkNo ? ctx.stage.times - 1 : ctx.stage.times, begin_time: curr.begin_time, end_time: curr.begin_time, name: ctx.stage.user.name, company: ctx.stage.user.company, role: ctx.stage.user.role, mobile: '', opinion: '', }; prev.push({ name: '原报', status: reportor.status, audit_type: reportor.audit_type, auditors: [reportor], }); } prev.push({ name: curr.is_final ? '终审' : `${curr.audit_order}审`, audit_type: curr.audit_type, status: curr.status, auditors: curr.auditors, }); return prev; }, []); if (!ctx.stage.final_auditor_str || ctx.stage.status !== auditConsts.stage.status.checked) { if (ctx.stage.status === auditConsts.stage.status.checkNoPre) { ctx.stage.status = auditConsts.stage.status.checking; } if (ctx.stage.status !== auditConsts.stage.status.checkNo) { ctx.stage.curAuditors = await ctx.service.stageAudit.getAuditorsByStatus(ctx.stage.id, ctx.stage.status, ctx.stage.times); } if (ctx.stage.status === auditConsts.stage.status.checked) { const final_auditor_str = (ctx.stage.curAuditors[0].audit_type === auditConsts.auditType.key.common) ? `${ctx.stage.curAuditors[0].name}${(ctx.stage.curAuditors[0].role ? '-' + ctx.stage.curAuditors[0].role : '')}` : ctx.helper.transFormToChinese(ctx.stage.curAuditors[0].audit_order) + '审'; await ctx.service.stage.defaultUpdate({ id: ctx.stage.id, final_auditor_str }); } } ctx.stage.tp = ctx.helper.sum([ctx.stage.contract_tp, ctx.stage.qc_tp, ctx.stage.pc_tp]); ctx.stage.pre_tp = ctx.helper.add(ctx.stage.pre_contract_tp, ctx.stage.pre_qc_tp); ctx.stage.end_tp = ctx.helper.add(ctx.stage.pre_tp, ctx.stage.tp); ctx.body = { code: 0, msg: '', data: ctx.stage }; } catch (err) { this.log(err); ctx.body = { code: -1, msg: err.toString(), data: null }; } } async checkAudit(ctx) { try { await this.auditCheck(ctx); if (ctx.stage.readOnly) { ctx.body = { code: -1, msg: '该计量期当前您无权操作', data: null }; return; } if (ctx.stage.revising) { ctx.body = { code: -1, msg: '台账修订中,请勿修改提交期数据', data: null }; return; } if (ctx.stage.assist && ctx.stage.assist.confirm) { ctx.body = { code: -1, msg: '协同数据已确认,如需修改,请撤销上报或重新审批', data: null }; return; } if (ctx.stage.status !== auditConsts.stage.status.checking && ctx.stage.status !== auditConsts.stage.status.checkNoPre) { ctx.body = { code: -1, msg: '当前期数据有误', data: null }; return; } if (ctx.stage.curAuditorIds && ctx.stage.curAuditorIds.indexOf(ctx.session.sessionUser.accountId) < 0) { ctx.body = { code: -1, msg: '您无权进行该操作', data: null }; return; } const data = ctx.request.body.checkData; data.checkType = parseInt(data.checkType); if (!data.checkType || isNaN(data.checkType)) { ctx.body = { code: -1, msg: '提交数据错误', data: null }; return; } await ctx.service.stageAudit.check(ctx.stage.id, data, ctx.stage.times); ctx.body = { code: 0, msg: '审批成功', data: null }; } catch (err) { this.log(err); ctx.body = { code: -1, msg: err.toString() || '提交失败', data: null }; ctx.session.postError = err.toString(); } } } return WeappMeasureController; };