|
|
@@ -1,29 +1,16 @@
|
|
|
'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 tenderId = ctx.params.id;
|
|
|
- const tender = await this.ctx.service.tender.getDataById(tenderId);
|
|
|
- if (!tender) {
|
|
|
- ctx.body = { code: -1, msg: '标段不存在', data: null };
|
|
|
- return;
|
|
|
- }
|
|
|
- const renderData = {
|
|
|
- tender: tender.data,
|
|
|
- };
|
|
|
-
|
|
|
- tender.info = await ctx.service.tenderInfo.getTenderInfo(tenderId);
|
|
|
- ctx.tender = tender;
|
|
|
- if (!ctx.tender.isTourist) {
|
|
|
- ctx.tender.isTourist = false; // 设置默认值
|
|
|
- }
|
|
|
-
|
|
|
- renderData.stages = await ctx.service.stage.getValidStages(tenderId, this.ctx.session.sessionUser.is_admin);
|
|
|
- for (const s of renderData.stages) {
|
|
|
+ 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);
|
|
|
@@ -35,10 +22,7 @@ module.exports = app => {
|
|
|
}
|
|
|
}
|
|
|
}
|
|
|
- renderData.unCompleteStageCount = renderData.stages.filter(s => {
|
|
|
- return s.status !== auditConsts.stage.status.checked;
|
|
|
- }).length;
|
|
|
- ctx.body = { code: 0, msg: '', data: renderData };
|
|
|
+ ctx.body = { code: 0, msg: '', data: stages };
|
|
|
|
|
|
} catch (err) {
|
|
|
this.log(err);
|
|
|
@@ -46,41 +30,189 @@ module.exports = app => {
|
|
|
}
|
|
|
}
|
|
|
|
|
|
- async detail(ctx) {
|
|
|
- try {
|
|
|
- const stageId = ctx.params.stageId;
|
|
|
- const stage = await ctx.service.stage.getDataById(stageId);
|
|
|
|
|
|
- if (!stage) {
|
|
|
- ctx.body = { code: -1, msg: '计量期不存在', data: null };
|
|
|
- return;
|
|
|
+ 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; });
|
|
|
}
|
|
|
- const tender = await ctx.service.tender.getDataById(stage.tid);
|
|
|
- if (!tender) {
|
|
|
- ctx.body = { code: -1, msg: '标段不存在', data: null };
|
|
|
- return;
|
|
|
+ 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 '您无权查看该数据';
|
|
|
}
|
|
|
- ctx.tender = tender;
|
|
|
- if (!ctx.tender.isTourist) {
|
|
|
- ctx.tender.isTourist = false;
|
|
|
+ }
|
|
|
+ // 判断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;
|
|
|
+ }
|
|
|
}
|
|
|
+ }
|
|
|
+ }
|
|
|
|
|
|
- await ctx.service.stage.loadStageUser(stage);
|
|
|
- await ctx.service.stage.loadStageAuditViewData(stage);
|
|
|
+ async detail(ctx) {
|
|
|
+ try {
|
|
|
+ await this.auditCheck(ctx);
|
|
|
|
|
|
- stage.auditHistory = stage.auditHistory && stage.auditHistory.length && stage.auditHistory[stage.auditHistory.length - 1].reduce((prev, curr, idx) => {
|
|
|
+ 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: stage.user.id,
|
|
|
+ audit_id: ctx.stage.user.id,
|
|
|
audit_order: 0,
|
|
|
audit_type: 1,
|
|
|
- status: stage.status === auditConsts.stage.status.uncheck ? auditConsts.stage.status.uncheck : auditConsts.stage.status.checked,
|
|
|
- times: stage.status === auditConsts.stage.status.checkNo ? stage.times - 1 : stage.times,
|
|
|
+ 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: stage.user.name,
|
|
|
- company: stage.user.company,
|
|
|
- role: stage.user.role,
|
|
|
+ name: ctx.stage.user.name,
|
|
|
+ company: ctx.stage.user.company,
|
|
|
+ role: ctx.stage.user.role,
|
|
|
mobile: '',
|
|
|
opinion: '',
|
|
|
|
|
|
@@ -101,26 +233,26 @@ module.exports = app => {
|
|
|
return prev;
|
|
|
}, []);
|
|
|
|
|
|
- if (!stage.final_auditor_str || stage.status !== auditConsts.stage.status.checked) {
|
|
|
- if (stage.status === auditConsts.stage.status.checkNoPre) {
|
|
|
- stage.status = auditConsts.stage.status.checking;
|
|
|
+ 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 (stage.status !== auditConsts.stage.status.checkNo) {
|
|
|
- stage.curAuditors = await ctx.service.stageAudit.getAuditorsByStatus(stage.id, stage.status, stage.times);
|
|
|
+ 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 (stage.status === auditConsts.stage.status.checked) {
|
|
|
- const final_auditor_str = (stage.curAuditors[0].audit_type === auditConsts.auditType.key.common)
|
|
|
- ? `${stage.curAuditors[0].name}${(stage.curAuditors[0].role ? '-' + stage.curAuditors[0].role : '')}`
|
|
|
- : ctx.helper.transFormToChinese(stage.curAuditors[0].audit_order) + '审';
|
|
|
- await ctx.service.stage.defaultUpdate({ id: stage.id, final_auditor_str });
|
|
|
+ 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 });
|
|
|
}
|
|
|
}
|
|
|
|
|
|
- stage.tp = ctx.helper.sum([stage.contract_tp, stage.qc_tp, stage.pc_tp]);
|
|
|
- stage.pre_tp = ctx.helper.add(stage.pre_contract_tp, stage.pre_qc_tp);
|
|
|
- stage.end_tp = ctx.helper.add(stage.pre_tp, stage.tp);
|
|
|
+ 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: stage };
|
|
|
+ ctx.body = { code: 0, msg: '', data: ctx.stage };
|
|
|
|
|
|
} catch (err) {
|
|
|
this.log(err);
|
|
|
@@ -130,20 +262,7 @@ module.exports = app => {
|
|
|
|
|
|
async checkAudit(ctx) {
|
|
|
try {
|
|
|
- const stageId = ctx.params.stageId;
|
|
|
- const stage = await ctx.service.stage.getDataById(stageId);
|
|
|
-
|
|
|
- if (!stage) {
|
|
|
- ctx.body = { code: -1, msg: '计量期不存在', data: null };
|
|
|
- return;
|
|
|
- }
|
|
|
-
|
|
|
- ctx.stage = stage;
|
|
|
- await ctx.service.stage.loadStageUser(stage);
|
|
|
- await ctx.service.stage.loadPreCheckedStage(stage);
|
|
|
- await ctx.service.stage.doCheckStage(stage);
|
|
|
- await ctx.service.stage.loadStageAuditViewData(stage);
|
|
|
-
|
|
|
+ await this.auditCheck(ctx);
|
|
|
if (ctx.stage.readOnly) {
|
|
|
ctx.body = { code: -1, msg: '该计量期当前您无权操作', data: null };
|
|
|
return;
|
|
|
@@ -156,6 +275,7 @@ module.exports = app => {
|
|
|
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;
|
|
|
@@ -165,13 +285,14 @@ module.exports = app => {
|
|
|
return;
|
|
|
}
|
|
|
|
|
|
- const data = ctx.request.body;
|
|
|
+ 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) {
|
|
|
@@ -181,6 +302,7 @@ module.exports = app => {
|
|
|
}
|
|
|
}
|
|
|
|
|
|
+
|
|
|
}
|
|
|
|
|
|
return WeappMeasureController;
|