|
@@ -9,6 +9,9 @@
|
|
|
*/
|
|
|
|
|
|
const audit = require('../const/audit');
|
|
|
+const shenpiConst = require('../const/shenpi');
|
|
|
+const sendToWormhole = require('stream-wormhole');
|
|
|
+const path = require('path');
|
|
|
|
|
|
module.exports = app => {
|
|
|
|
|
@@ -81,12 +84,48 @@ module.exports = app => {
|
|
|
}
|
|
|
}
|
|
|
|
|
|
- async del() {
|
|
|
+ async del(ctx) {
|
|
|
+ try {
|
|
|
+ if (!ctx.session.sessionUser.is_admin && ctx.request.body.confirm !== '确认删除本期') throw '请输入文本确认删除本期';
|
|
|
+ const phase_id = ctx.request.body.phase_id;
|
|
|
+ const phasePay = await ctx.service.phasePay.getDataById(phase_id);
|
|
|
+ if (!phasePay) throw '删除的期不存在,请刷新页面';
|
|
|
+ if (!ctx.session.sessionUser.is_admin && phasePay.create_user_id !== ctx.session.sessionUser.accountId) throw '您无权删除本期';
|
|
|
+ // 获取最新的期数
|
|
|
+ const phasePayCount = await ctx.service.phasePay.count({ tid: ctx.tender.id });
|
|
|
+ if (phasePay.phase_order !== phasePayCount) throw '非最新一期,不可删除';
|
|
|
|
|
|
+ await ctx.service.phasePay.delete(phase_id);
|
|
|
+ // todo 刷新金额概况缓存
|
|
|
+ // await ctx.service.tenderCache.refreshPayCache(phasePay.tenderId);
|
|
|
+ ctx.redirect('/tender/' + ctx.tender.id + '/pay');
|
|
|
+ } catch (err) {
|
|
|
+ ctx.log(err);
|
|
|
+ ctx.redirect(ctx.request.header.referer);
|
|
|
+ }
|
|
|
}
|
|
|
|
|
|
- async save() {
|
|
|
-
|
|
|
+ async save(ctx) {
|
|
|
+ try {
|
|
|
+ const phase_id = ctx.request.body.phase_id;
|
|
|
+ const data = {
|
|
|
+ phase_date: ctx.request.body.date,
|
|
|
+ memo: ctx.request.body.memo,
|
|
|
+ };
|
|
|
+ const phasePay = await ctx.service.phasePay.getPhasePay(phase_id);
|
|
|
+ if (!phasePay) throw '删除的期不存在,请刷新页面';
|
|
|
+ if (!ctx.session.sessionUser.is_admin && phasePay.create_user_id !== ctx.session.sessionUser.accountId) throw '您无权修改该数据';
|
|
|
+ await this.ctx.service.phasePay.save(phasePay, data);
|
|
|
+ if (phasePay.audit_status === audit.common.status.uncheck && ctx.request.body.stage) {
|
|
|
+ const stages = await ctx.service.stage.getAllDataByCondition({ where: { tid: ctx.tender.id, order: ctx.request.body.stage } });
|
|
|
+ await this.ctx.service.phasePay.resetRelaStageId(phasePay, stages);
|
|
|
+ }
|
|
|
+ ctx.redirect('/tender/' + ctx.tender.id + '/pay');
|
|
|
+ } catch (err) {
|
|
|
+ console.log(err);
|
|
|
+ this.log(err);
|
|
|
+ ctx.redirect('/tender/' + ctx.tender.id + '/pay');
|
|
|
+ }
|
|
|
}
|
|
|
|
|
|
async detail(ctx) {
|
|
@@ -96,6 +135,15 @@ module.exports = app => {
|
|
|
const calcBase = this.ctx.service.phasePay.getPhasePayCalcBase(ctx.phasePay, ctx.tender.info);
|
|
|
const projectFunInfo = await this.ctx.service.project.getFunRela(ctx.session.sessionProject.id);
|
|
|
const lastStage = await this.ctx.service.stage.getLastestCompleteStage(ctx.tender.id);
|
|
|
+ const accountList = await ctx.service.projectAccount.getAllDataByCondition({
|
|
|
+ where: { project_id: ctx.session.sessionProject.id, enable: 1 },
|
|
|
+ columns: ['id', 'name', 'company', 'role', 'enable', 'is_admin', 'account_group', 'mobile'],
|
|
|
+ });
|
|
|
+ const unitList = await ctx.service.constructionUnit.getAllDataByCondition({ where: { pid: ctx.session.sessionProject.id } });
|
|
|
+ const accountGroup = unitList.map(item => {
|
|
|
+ const groupList = accountList.filter(item1 => item1.company === item.name);
|
|
|
+ return { groupName: item.name, groupList };
|
|
|
+ });
|
|
|
const renderData = {
|
|
|
pays,
|
|
|
calcBase,
|
|
@@ -103,7 +151,10 @@ module.exports = app => {
|
|
|
auditConst: audit.common,
|
|
|
deadlineType: this.ctx.service.phasePayDetail.deadlineType,
|
|
|
maxStageOrder: lastStage.order,
|
|
|
- jsFiles: this.app.jsFiles.common.concat(this.app.jsFiles.phasePay.detail)
|
|
|
+ jsFiles: this.app.jsFiles.common.concat(this.app.jsFiles.phasePay.detail),
|
|
|
+ accountList,
|
|
|
+ accountGroup,
|
|
|
+ shenpiConst,
|
|
|
};
|
|
|
await this.layout('phase_pay/detail.ejs', renderData, 'phase_pay/detail_modal.ejs');
|
|
|
} catch (err) {
|
|
@@ -113,6 +164,35 @@ module.exports = app => {
|
|
|
}
|
|
|
}
|
|
|
|
|
|
+ async detailLoad(ctx) {
|
|
|
+ try {
|
|
|
+ const data = JSON.parse(ctx.request.body.data);
|
|
|
+ if (!data.filter) throw '参数错误';
|
|
|
+ const filter = data.filter.split(',');
|
|
|
+
|
|
|
+ const result = {};
|
|
|
+ for (const f of filter) {
|
|
|
+ switch(f) {
|
|
|
+ case 'pay':
|
|
|
+ result.pay = await this.ctx.service.phasePayDetail.getDetailData(ctx.phasePay);
|
|
|
+ break;
|
|
|
+ case 'base':
|
|
|
+ result.base = this.ctx.service.phasePay.getPhasePayCalcBase(ctx.phasePay, ctx.tender.info);
|
|
|
+ break;
|
|
|
+ case 'add':
|
|
|
+ result.add = ctx.phasePay.calc_base;
|
|
|
+ break;
|
|
|
+ case 'file':
|
|
|
+ result.file = await this.ctx.service.phasePayFile.getData(ctx.phasePay.id, 'pay');
|
|
|
+ }
|
|
|
+ }
|
|
|
+ ctx.body = { err: 0, msg: '', data: result };
|
|
|
+ } catch (err) {
|
|
|
+ ctx.log(err);
|
|
|
+ ctx.ajaxErrorBody(err, '读取合同支付数据错误');
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
async detailUpdate(ctx) {
|
|
|
try {
|
|
|
const data = JSON.parse(ctx.request.body.data);
|
|
@@ -168,34 +248,33 @@ module.exports = app => {
|
|
|
async uploadFile(ctx) {
|
|
|
let stream;
|
|
|
try {
|
|
|
- const parts = ctx.multipart({ autoFields: true });
|
|
|
+ const parts = ctx.multipart({autoFields: true});
|
|
|
+
|
|
|
let index = 0;
|
|
|
const create_time = Date.parse(new Date()) / 1000;
|
|
|
let stream = await parts();
|
|
|
- const bonus = await ctx.service.stageBonus.getStageDataById(parts.field.bonus_id);
|
|
|
- //if (!bonus || bonus.sid !== ctx.stage.id) throw '该奖罚金,当前不允许上传附件';
|
|
|
+ const user = await ctx.service.projectAccount.getDataById(ctx.session.sessionUser.accountId);
|
|
|
+ const rela_type = parts.fields.type;
|
|
|
+ const rela_id = parts.field.rela_id;
|
|
|
+
|
|
|
+ const uploadfiles = [];
|
|
|
while (stream !== undefined) {
|
|
|
- if (!stream.filename) {
|
|
|
- throw '未发现上传文件!';
|
|
|
- }
|
|
|
+ if (!stream.filename) throw '未发现上传文件!';
|
|
|
|
|
|
const fileInfo = path.parse(stream.filename);
|
|
|
- const dirName = 'app/public/upload/extra/' + moment().format('YYYYMMDD');
|
|
|
- const fileName = create_time + '_' + index + fileInfo.ext;
|
|
|
+ const filepath = `app/public/upload/${ctx.phasePay.tid}/phasePay/${ctx.moment().format('YYYYMMDD')}/${create_time + '_' + index + fileInfo.ext}`;
|
|
|
|
|
|
// 保存文件
|
|
|
- await ctx.helper.saveStreamFile(stream, path.join(this.app.baseDir, dirName, fileName));
|
|
|
+ await ctx.app.fujianOss.put(ctx.app.config.fujianOssFolder + filepath, stream);
|
|
|
await sendToWormhole(stream);
|
|
|
|
|
|
// 插入到stage_pay对应的附件列表中
|
|
|
- bonus.proof_file.push({
|
|
|
+ uploadfiles.push({
|
|
|
+ rela_id,
|
|
|
filename: fileInfo.name,
|
|
|
fileext: fileInfo.ext,
|
|
|
filesize: Array.isArray(parts.field.size) ? parts.field.size[index] : parts.field.size,
|
|
|
- filepath: path.join(dirName, fileName),
|
|
|
- uid: ctx.session.sessionUser.accountId,
|
|
|
- in_time: moment(create_time * 1000).format('YYYY-MM-DD'),
|
|
|
- renew: bonus.sid === ctx.stage.id ? ctx.stage.status === auditConst.status.checked : true,
|
|
|
+ filepath,
|
|
|
});
|
|
|
++index;
|
|
|
if (Array.isArray(parts.field.size) && index < parts.field.size.length) {
|
|
@@ -204,59 +283,56 @@ module.exports = app => {
|
|
|
stream = undefined;
|
|
|
}
|
|
|
}
|
|
|
- const result = await ctx.service.stageBonus.updateDatas({
|
|
|
- update: [
|
|
|
- { id: bonus.id, proof_file: bonus.proof_file },
|
|
|
- ]
|
|
|
- });
|
|
|
- for (const pf of bonus.proof_file) {
|
|
|
- pf.username = (await ctx.service.projectAccount.getAccountInfoById(pf.uid)).name;
|
|
|
- if (ctx.helper.canPreview(pf.fileext)){
|
|
|
- pf.viewpath = pf.filepath.substr(3, pf.filepath.length - 3);
|
|
|
- }
|
|
|
- delete pf.filepath;
|
|
|
- }
|
|
|
- ctx.body = {err: 0, msg: '', data: bonus.proof_file};
|
|
|
+
|
|
|
+ const result = await ctx.service.phasePayFile.addFiles(ctx.phasePay, 'pay', uploadfiles, user);
|
|
|
+ ctx.body = {err: 0, msg: '', data: result};
|
|
|
} catch (error) {
|
|
|
- ctx.helper.log(error);
|
|
|
+ ctx.log(error);
|
|
|
// 失败需要消耗掉stream 以防卡死
|
|
|
- if (stream) {
|
|
|
- await sendToWormhole(stream);
|
|
|
- }
|
|
|
+ if (stream) await sendToWormhole(stream);
|
|
|
ctx.body = this.ajaxErrorBody(error, '上传附件失败,请重试');
|
|
|
}
|
|
|
}
|
|
|
|
|
|
async deleteFile(ctx) {
|
|
|
- try {
|
|
|
+ try{
|
|
|
const data = JSON.parse(ctx.request.body.data);
|
|
|
+ if (!data) throw '缺少参数';
|
|
|
+ const result = await ctx.service.phasePayFile.delFiles(data);
|
|
|
+ ctx.body = { err: 0, msg: '', data: result };
|
|
|
+ } catch(error) {
|
|
|
+ this.log(error);
|
|
|
+ ctx.ajaxErrorBody(error, '删除附件失败');
|
|
|
+ }
|
|
|
+ }
|
|
|
|
|
|
- const bonus = await ctx.service.stageBonus.getStageDataById(data.b_id);
|
|
|
- if (!bonus || !bonus.proof_file || !bonus.proof_file[data.index]) throw '删除的文件不存在';
|
|
|
+ async auditUpdate(ctx) {
|
|
|
+ try {
|
|
|
+ if (!ctx.session.sessionUser.accountId !== ctx.phasePay.create_user_id) throw '您无权进行操作';
|
|
|
+ if (ctx.phasePay.status !== audit.common.status.uncheck && ctx.phasePay.status !== audit.common.status.checkNo) throw '已上报,不可修改审批流程';
|
|
|
|
|
|
- const fileInfo = bonus.proof_file[data.index];
|
|
|
- if (fileInfo.uid !== ctx.session.sessionUser.accountId) throw '您无权删除该文件';
|
|
|
+ const data = JSON.parse(ctx.request.body.data);
|
|
|
+ await ctx.service.phasePayAudit.saveAudit(ctx.phasePay, data);
|
|
|
+ const auditors = await ctx.service.phasePayAudit.getUniqUserGroup(ctx.phasePay.id, ctx.phasePay.audit_times);
|
|
|
+ ctx.body = { err: 0, msg: '', data: auditors };
|
|
|
+ } catch (err) {
|
|
|
+ ctx.log(err);
|
|
|
+ ctx.body = this.ajaxErrorBody(err, '保存审批人数据失败');
|
|
|
+ }
|
|
|
+ }
|
|
|
|
|
|
- const deleteFilePermission = PermissionCheck.delFile(this.ctx.session.sessionUser.permission);
|
|
|
- if (ctx.stage.status === auditConst.status.checked && !fileInfo.renew && !deleteFilePermission) throw '不可删除该文件';
|
|
|
+ async auditSave(ctx) {
|
|
|
+ try {
|
|
|
+ if (!ctx.session.sessionUser.is_admin) throw '您无权进行操作';
|
|
|
+ if (ctx.phasePay.status === audit.common.status.checked) throw '已审批通过,不可修改审批流程';
|
|
|
|
|
|
- // 先删除文件
|
|
|
- await fs.unlinkSync(path.join(this.app.baseDir, fileInfo.filepath));
|
|
|
- // 再删除数据库
|
|
|
- bonus.proof_file.splice(data.index, 1);
|
|
|
- const result = await ctx.service.stageBonus.updateDatas({
|
|
|
- update: [
|
|
|
- { id: bonus.id, proof_file: bonus.proof_file },
|
|
|
- ]
|
|
|
- });
|
|
|
- for (const pf of bonus.proof_file) {
|
|
|
- delete pf.filepath;
|
|
|
- pf.username = (await ctx.service.projectAccount.getAccountInfoById(pf.uid)).name;
|
|
|
- }
|
|
|
- ctx.body = {err: 0, msg: '', data: bonus.proof_file};
|
|
|
+ const data = JSON.parse(ctx.request.body.data);
|
|
|
+ await ctx.service.phasePayAudit.saveAudit(ctx.phasePay, data);
|
|
|
+ const auditors = await ctx.service.phasePayAudit.getUniqUserGroup(ctx.phasePay.id, ctx.phasePay.audit_times);
|
|
|
+ ctx.body = { err: 0, msg: '', data: auditors };
|
|
|
} catch (err) {
|
|
|
- this.log(err);
|
|
|
- this.ctx.ajaxErrorBody(err, '删除文件失败');
|
|
|
+ ctx.log(err);
|
|
|
+ ctx.body = this.ajaxErrorBody(err, '保存审批人数据失败');
|
|
|
}
|
|
|
}
|
|
|
}
|