'use strict';
/**
* 控制面板
*
* @author CaiAoLin
* @date 2017/11/23
* @version
*/
const auditConst = require('../const/audit');
const officeList = require('../const/cld_office').list;
const maintainConst = require('../const/maintain');
const typeColMap = require('../const/advance').typeColMap;
const moment = require('moment');
const fs = require('fs');
const path = require('path');
const sendToWormhole = require('stream-wormhole');
module.exports = app => {
class DashboardController extends app.BaseController {
/**
* 控制面板页面
*
* @param {Object} ctx - egg全局变量
* @return {void}
*/
async index(ctx) {
const auditTenders = await ctx.service.ledgerAudit.getAuditTender(ctx.session.sessionUser.accountId);
const auditStages = await ctx.service.stageAudit.getAuditStage(ctx.session.sessionUser.accountId);
const auditChanges = await ctx.service.changeAudit.getAuditChange(ctx.session.sessionUser.accountId);
const auditRevise = await ctx.service.reviseAudit.getAuditRevise(ctx.session.sessionUser.accountId);
const auditMaterial = ctx.subProject.page_show.openMaterial ? await ctx.service.materialAudit.getAuditMaterial(ctx.session.sessionUser.accountId) : [];
const auditAdvance = await ctx.service.advanceAudit.getAuditAdvance(ctx.session.sessionUser.accountId);
const auditChangeProject = ctx.subProject.page_show.openChangeProject ? await ctx.service.changeProjectAudit.getAuditChangeProject(ctx.session.sessionUser.accountId) : [];
const auditChangeApply = ctx.subProject.page_show.openChangeApply ? await ctx.service.changeApplyAudit.getAuditChangeApply(ctx.session.sessionUser.accountId) : [];
const auditChangePlan = ctx.subProject.page_show.openChangePlan ? await ctx.service.changePlanAudit.getAuditChangePlan(ctx.session.sessionUser.accountId) : [];
const auditPayments = ctx.subProject.page_show.openPayment ? await ctx.service.paymentDetailAudit.getAuditPayment(ctx.session.sessionUser.accountId) : [];
const auditStageAss = await ctx.service.stageAuditAss.getAuditStageAss(ctx.session.sessionUser.accountId);
const auditFinancials = ctx.subProject.page_show.openFinancial ? await ctx.service.financialPayAudit.getAuditFinancial(ctx.session.sessionUser.accountId) : [];
const pa = await ctx.service.projectAccount.getDataById(ctx.session.sessionUser.accountId);
const noticeList = await ctx.service.noticePush.getNotice(ctx.session.sessionProject.id, pa.id);
const projectData = await ctx.service.project.getDataById(ctx.session.sessionProject.id);
// 获取销售人员数据
const salesmanData = await ctx.service.manager.getDataById(projectData.manager_id);
const officeName = officeList[salesmanData.office];
// 获取版本信息
const versionList = await ctx.service.version.getAllDataByCondition({ orders: [['id', 'desc']], limit: 5, offset: 0 });
// 获取项目通知
const msgList = await ctx.service.message.getMsgList(ctx.session.sessionProject.id);
const userPermission = pa !== undefined && pa.permission !== '' ? JSON.parse(pa.permission) : null;
const userMsgPermission = userPermission !== null && userPermission.project_msg !== undefined && parseInt(userPermission.project_msg) === 1;
// 获取系统通知
const sysMsgList = await ctx.service.message.getMsgList(ctx.session.sessionProject.id, 1, 0, 2);
// 获取系统维护信息
const maintainData = await ctx.service.maintain.getDataById(1);
// 获取各个审批的次数及最后的审批时间
const shenpi_count = [
{ count: await ctx.service.advanceAudit.getCountByChecked(ctx.session.sessionUser.accountId), name: '预付款' },
{ count: await ctx.service.ledgerAudit.getCountByChecked(ctx.session.sessionUser.accountId), name: '台账审批' },
{ count: await ctx.service.reviseAudit.getCountByChecked(ctx.session.sessionUser.accountId), name: '台账修订' },
{ count: await ctx.service.stageAudit.getCountByChecked(ctx.session.sessionUser.accountId), name: '计量审批' },
{ count: await ctx.service.changeAudit.getCountByChecked(ctx.session.sessionUser.accountId), name: '变更审批' },
];
if (ctx.subProject.page_show.openChangeProject) shenpi_count.push({ count: await ctx.service.changeProjectAudit.getCountByChecked(ctx.session.sessionUser.accountId), name: '变更立项' });
if (ctx.subProject.page_show.openChangeApply) shenpi_count.push({ count: await ctx.service.changeApplyAudit.getCountByChecked(ctx.session.sessionUser.accountId), name: '变更申请' });
if (ctx.subProject.page_show.openChangePlan) shenpi_count.push({ count: await ctx.service.changePlanAudit.getCountByChecked(ctx.session.sessionUser.accountId), name: '变更方案' });
if (ctx.subProject.page_show.openMaterial) shenpi_count.push({ count: await ctx.service.materialAudit.getCountByChecked(ctx.session.sessionUser.accountId), name: '材料调差' });
if (ctx.subProject.page_show.openFinancial) shenpi_count.push({ count: await ctx.service.financialPayAudit.getCountByChecked(ctx.session.sessionUser.accountId), name: '资金支付' });
// shenpi_count.push({ count: await ctx.service.advanceAudit.getCountByChecked(ctx.session.sessionUser.accountId), name: '预付款' });
const total_count = ctx.app._.sumBy(shenpi_count, 'count');
const shenpi_lastime = [
await ctx.service.advanceAudit.getLastEndTimeByChecked(ctx.session.sessionUser.accountId),
await ctx.service.ledgerAudit.getLastEndTimeByChecked(ctx.session.sessionUser.accountId),
await ctx.service.reviseAudit.getLastEndTimeByChecked(ctx.session.sessionUser.accountId),
await ctx.service.stageAudit.getLastEndTimeByChecked(ctx.session.sessionUser.accountId),
await ctx.service.changeAudit.getLastEndTimeByChecked(ctx.session.sessionUser.accountId),
ctx.subProject.page_show.openChangeProject ? await ctx.service.changeProjectAudit.getLastEndTimeByChecked(ctx.session.sessionUser.accountId) : null,
ctx.subProject.page_show.openChangeApply ? await ctx.service.changeApplyAudit.getLastEndTimeByChecked(ctx.session.sessionUser.accountId) : null,
ctx.subProject.page_show.openChangePlan ? await ctx.service.changePlanAudit.getLastEndTimeByChecked(ctx.session.sessionUser.accountId) : null,
ctx.subProject.page_show.openMaterial ? await ctx.service.materialAudit.getLastEndTimeByChecked(ctx.session.sessionUser.accountId) : null,
ctx.subProject.page_show.openFinancial ? await ctx.service.financialPayAudit.getLastEndTimeByChecked(ctx.session.sessionUser.accountId) : null,
];
const last_time = ctx.app._.max(shenpi_lastime);
// console.log(ctx.app._.max(shenpi_lastime), ctx.helper.calcDayNum(last_time));
const renderData = {
auditTenders,
auditStages,
auditChanges,
auditRevise,
auditMaterial,
auditAdvance,
auditChangeProject,
auditChangeApply,
auditChangePlan,
auditPayments,
auditStageAss,
auditFinancials,
shenpi_count,
total_count,
last_day: ctx.helper.calcDayNum(last_time),
role: pa.role,
authMobile: pa.auth_mobile,
acLedger: auditConst.ledger,
acStage: auditConst.stage,
acChange: auditConst.change,
acRevise: auditConst.revise,
acMaterial: auditConst.material,
acAdvance: auditConst.advance,
acChangeProject: auditConst.changeProject,
acChangeApply: auditConst.changeApply,
acChangePlan: auditConst.changeApply,
acFinancial: auditConst.financial,
noticeList,
pushType: auditConst.pushType,
projectData,
salesmanData,
officeName,
versionList: JSON.parse(JSON.stringify(versionList).replace(/\\r\\n/g, '
').replace(/\\"/g, '"').replace(/'/g, ''').replace(/\\t/g, ' ')),
msgList: JSON.parse(JSON.stringify(msgList).replace(/\\r\\n/g, '
').replace(/\\"/g, '"').replace(/'/g, ''').replace(/\\t/g, ' ')),
sysMsgList: JSON.parse(JSON.stringify(sysMsgList).replace(/\\r\\n/g, '
').replace(/\\"/g, '"').replace(/'/g, ''').replace(/\\t/g, ' ')),
userMsgPermission,
uid: ctx.session.sessionUser.accountId,
maintainData,
maintainConst,
typeColMap,
};
await this.layout('dashboard/index.ejs', renderData, 'dashboard/modal.ejs');
await ctx.service.projectAccount.defaultUpdate({
id: this.ctx.session.sessionUser.accountId,
last_notice: new Date(),
});
}
/**
* 控制面板-通知页面
*
* @param {Object} ctx - egg全局变量
* @return {void}
*/
async msg(ctx) {
try {
const page = ctx.page;
const msgId = parseInt(ctx.params.id) || 0;
let msgInfo = msgId ? await ctx.service.message.getDataById(msgId) : null;
const type = msgInfo ? msgInfo.type : ctx.request.query.type ? parseInt(ctx.request.query.type) : 1;
if (msgInfo && msgInfo.type === 1 && msgInfo.project_id !== ctx.session.sessionProject.id) {
throw '非该项目通知无权查看';
}
if (msgInfo) {
msgInfo.content = JSON.parse(JSON.stringify(msgInfo.content).replace(/\\r\\n/g, '
').replace(/\\"/g, '"').replace(/'/g, ''').replace(/\\t/g, ' '));
msgInfo.files = await this.ctx.service.messageAtt.getAtt(msgInfo.id);
}
const total = type === 1 ?
await ctx.service.message.count({ project_id: ctx.session.sessionProject.id, type }) :
await ctx.service.message.count({ status: 1, type });
const limit = 5;
const offset = limit * (this.ctx.page - 1);
const msgList = await ctx.service.message.getMsgList(ctx.session.sessionProject.id, limit, offset, type);
const pa = await ctx.service.projectAccount.getDataById(ctx.session.sessionUser.accountId);
const userPermission = pa !== undefined && pa.permission !== '' ? JSON.parse(pa.permission) : null;
const userMsgPermission = userPermission !== null && userPermission.project_msg !== undefined && parseInt(userPermission.project_msg) === 1;
if (!msgId) {
msgInfo = msgList[0];
}
// 分页相关
const pageInfo = {
page,
total: Math.ceil(total / limit),
queryData: JSON.stringify(ctx.urlInfo.query),
};
const renderData = {
msgInfo,
uid: ctx.session.sessionUser.accountId,
type,
pageInfo,
userMsgPermission,
msgList: JSON.parse(JSON.stringify(msgList).replace(/\\r\\n/g, '
').replace(/\\"/g, '"').replace(/'/g, ''').replace(/\\t/g, ' ')),
};
await this.layout('dashboard/msg.ejs', renderData);
} catch (error) {
console.log(error);
this.log(error);
ctx.session.postError = error.toString();
ctx.redirect('/dashboard');
}
}
/**
* 控制面板-通知添加和编辑页面
*
* @param {Object} ctx - egg全局变量
* @return {void}
*/
async msgAdd(ctx) {
let id = ctx.params.id;
id = parseInt(id);
try {
if (isNaN(id) || id < 0) {
throw '参数错误';
}
const rule = ctx.service.message.rule();
const jsValidator = await this.jsValidator.convert(rule).build();
const msgInfo = id === 0 ? {} : await ctx.service.message.getDataById(id);
const files = await ctx.service.messageAtt.getAtt(id);
const renderData = {
jsValidator,
msgInfo,
files,
whiteList: ctx.app.config.multipart.whitelist,
moment,
};
await this.layout('dashboard/msg_add.ejs', renderData, 'dashboard/msg_modal.ejs');
} catch (error) {
console.log(error);
// this.setMessage(error.toString(), this.messageType.ERROR);
ctx.redirect(ctx.request.header.referer);
}
}
/**
* 控制面板-通知保存
*
* @param {Object} ctx - egg全局变量
* @return {void}
*/
async msgSet(ctx) {
try {
let id = ctx.params.id;
id = parseInt(id);
if (isNaN(id) || id < 0) {
throw '参数错误';
}
const rule = ctx.service.message.rule();
ctx.helper.validate(rule);
const result = await ctx.service.message.save(id, ctx.request.body, ctx.session.sessionUser, ctx.session.sessionProject.id);
if (result) {
// 新增的项目通知会发送微信模版消息通知客户
if (id === 0) {
// 获取该项目所有的openid,发送信息
const wechats = await ctx.service.projectAccount.getOpenIdListByPid(ctx.session.sessionProject.id);
if (wechats.length > 0) {
const msgInfo = await ctx.service.message.getDataById(result);
const projectData = await ctx.service.project.getDataById(ctx.session.sessionProject.id);
// 绑定成功通知
const templateId = 'VKUo4us4lt2dQY0EaaJxcui2jkjmriN3A0K7i4kpZwY';
const url = ctx.protocol + '://' + ctx.host + '/wx/url2wap?project=' + ctx.session.sessionProject.code + '&url=' + ctx.protocol + '://' + ctx.host + '/wap/dashboard/msg/' + msgInfo.id;
const msgData = {
thing21: {
value: ctx.helper.contentChange(projectData.name),
},
thing2: {
value: ctx.helper.contentChange(msgInfo.title),
},
thing8: {
value: msgInfo.creator,
},
time3: {
value: moment(msgInfo.release_time * 1000).format('YYYY-MM-DD'),
},
};
for (const wx of wechats) {
const result = await app.wechat.api.sendTemplate(wx.wx_openid, templateId, url, '', msgData);
}
}
}
ctx.redirect('/dashboard/msg');
}
} catch (error) {
console.log(error);
ctx.redirect(ctx.request.header.referer);
}
}
/**
* 控制面板-通知删除
*
* @param {Object} ctx - egg全局变量
* @return {void}
*/
async msgDelete(ctx) {
try {
let id = ctx.params.id;
id = parseInt(id);
if (isNaN(id) || id <= 0) {
throw '参数错误';
}
const msgInfo = await ctx.service.message.getDataById(id);
if (!msgInfo || msgInfo.create_uid !== ctx.session.sessionUser.accountId) {
throw '通知不存在或无权限操作';
}
const result = await ctx.service.message.deleteMsg(msgInfo.id);
if (result) {
ctx.redirect('/dashboard/msg');
}
} catch (error) {
console.log(error);
ctx.redirect(ctx.request.header.referer);
}
}
/**
* 将推送记录设置为已读
* @param {Object} ctx 上下文
*/
async pushSet(ctx) {
try {
const { id } = JSON.parse(ctx.request.body.data);
const data = await ctx.service.noticePush.set(id);
ctx.body = { err: 0, msg: '' };
} catch (err) {
this.log(err);
ctx.body = { err: 1, msg: err.toString(), data: null };
}
}
/**
* 上传附件
* @param {*} ctx 上下文
*/
async msgUploadFile(ctx) {
let stream;
try {
const responseData = { err: 0, msg: '', data: {} };
const mid = ctx.params.id || 0;
if (!mid) throw '参数有误';
const parts = this.ctx.multipart({
autoFields: true,
});
const files = [];
const create_time = Date.parse(new Date()) / 1000;
let idx = 0;
while ((stream = await parts()) !== undefined) {
if (!stream.filename) {
// 如果没有传入直接返回
return;
}
const fileInfo = path.parse(stream.filename);
const filepath = `app/public/upload/message/fujian_${create_time + idx.toString() + fileInfo.ext}`;
await ctx.app.fujianOss.put(ctx.app.config.fujianOssFolder + filepath, stream);
files.push({ filepath, name: stream.filename, ext: fileInfo.ext });
++idx;
stream && (await sendToWormhole(stream));
}
const in_time = new Date();
const payload = files.map(file => {
let idx;
if (Array.isArray(parts.field.name)) {
idx = parts.field.name.findIndex(name => name === file.name);
} else {
idx = 'isString';
}
const newFile = {
project_id: ctx.session.sessionProject.id,
mid,
uid: ctx.session.sessionUser.accountId,
filename: file.name,
fileext: file.ext,
filesize: ctx.helper.bytesToSize(idx === 'isString' ? parts.field.size : parts.field.size[idx]),
filepath: file.filepath,
upload_time: in_time,
};
return newFile;
});
// 执行文件信息写入数据库
await ctx.service.messageAtt.saveFileMsgToDb(payload);
// 将最新的当前标段的所有文件信息返回
responseData.data = await ctx.service.messageAtt.getAtt(mid);
ctx.body = responseData;
} catch (err) {
stream && (await sendToWormhole(stream));
this.log(err);
ctx.body = { err: 1, msg: err.toString(), data: null };
}
}
/**
* 删除附件
* @param {Ojbect} ctx 上下文
*/
async msgDeleteFile(ctx) {
try {
const mid = ctx.params.id || 0;
const responseData = { err: 0, msg: '', data: {} };
const data = JSON.parse(ctx.request.body.data);
const fileInfo = await ctx.service.messageAtt.getDataById(data.id);
if (fileInfo) {
// 先删除文件
// await fs.unlinkSync(path.resolve(this.app.baseDir, './app', fileInfo.filepath));
await ctx.app.fujianOss.delete(ctx.app.config.fujianOssFolder + fileInfo.filepath);
// 再删除数据库
await ctx.service.messageAtt.delete(data.id);
} else {
throw '不存在该文件';
}
responseData.data = await ctx.service.messageAtt.getAtt(mid);
ctx.body = responseData;
} catch (err) {
this.log(err);
ctx.body = { err: 1, msg: err.toString(), data: null };
}
}
}
return DashboardController;
};