dashboard_controller.js 47 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752
  1. 'use strict';
  2. /**
  3. * 控制面板
  4. *
  5. * @author CaiAoLin
  6. * @date 2017/11/23
  7. * @version
  8. */
  9. const auditConst = require('../const/audit');
  10. const officeList = require('../const/cld_office').list;
  11. const maintainConst = require('../const/maintain');
  12. const typeColMap = require('../const/advance').typeColMap;
  13. const moment = require('moment');
  14. const fs = require('fs');
  15. const path = require('path');
  16. const sendToWormhole = require('stream-wormhole');
  17. module.exports = app => {
  18. class DashboardController extends app.BaseController {
  19. /**
  20. * 控制面板页面
  21. *
  22. * @param {Object} ctx - egg全局变量
  23. * @return {void}
  24. */
  25. async workspace(ctx) {
  26. const allAuditTenders = await ctx.service.ledgerAudit.getAuditTender(ctx.session.sessionUser.accountId);
  27. const allAuditStages = await ctx.service.stageAudit.getAuditStage(ctx.session.sessionUser.accountId);
  28. const allAuditChanges = await ctx.service.changeAudit.getAuditChange(ctx.session.sessionUser.accountId);
  29. const allAuditRevise = await ctx.service.reviseAudit.getAuditRevise(ctx.session.sessionUser.accountId);
  30. const allAuditMaterial = await ctx.service.materialAudit.getAuditMaterial(ctx.session.sessionUser.accountId);
  31. const allAuditAdvance = await ctx.service.advanceAudit.getAuditAdvance(ctx.session.sessionUser.accountId);
  32. const allAuditChangeProject = await ctx.service.changeProjectAudit.getAuditChangeProject(ctx.session.sessionUser.accountId);
  33. const allAuditChangeApply = await ctx.service.changeApplyAudit.getAuditChangeApply(ctx.session.sessionUser.accountId);
  34. const allAuditChangePlan = await ctx.service.changePlanAudit.getAuditChangePlan(ctx.session.sessionUser.accountId);
  35. const allAuditPayments = await ctx.service.paymentDetailAudit.getAuditPayment(ctx.session.sessionUser.accountId);
  36. const allAuditStageAss = await ctx.service.stageAuditAss.getAuditStageAss(ctx.session.sessionUser.accountId);
  37. const allAuditFinancials = await ctx.service.financialPayAudit.getAuditFinancial(ctx.session.sessionUser.accountId);
  38. const allAuditInspections = await ctx.service.qualityInspectionAudit.getAuditInspection(ctx.session.sessionUser.accountId);
  39. const allAuditSafeInspections = await ctx.service.safeInspectionAudit.getAuditInspection(ctx.session.sessionUser.accountId);
  40. const allAuditSafeStage = await ctx.service.safeStageAudit.getAuditStage(ctx.session.sessionUser.accountId);
  41. const allAuditPhasePay = await ctx.service.phasePayAudit.getAuditStage(ctx.session.sessionUser.accountId);
  42. const pa = await ctx.service.projectAccount.getDataById(ctx.session.sessionUser.accountId);
  43. const auditShenpiTenders = await ctx.service.ledgerAudit.getDonesByAudit(ctx.session.sessionUser.accountId);
  44. const auditShenpiStages = await ctx.service.stageAudit.getDonesByAudit(ctx.session.sessionUser.accountId);
  45. const auditShenpiChanges = await ctx.service.changeAudit.getDonesByAudit(ctx.session.sessionUser.accountId);
  46. const auditShenpiRevise = await ctx.service.reviseAudit.getDonesByAudit(ctx.session.sessionUser.accountId);
  47. const auditShenpiMaterial = await ctx.service.materialAudit.getDonesByAudit(ctx.session.sessionUser.accountId);
  48. const auditShenpiAdvance = await ctx.service.advanceAudit.getDonesByAudit(ctx.session.sessionUser.accountId);
  49. const auditShenpiChangeProject = await ctx.service.changeProjectAudit.getDonesByAudit(ctx.session.sessionUser.accountId);
  50. const auditShenpiChangeApply = await ctx.service.changeApplyAudit.getDonesByAudit(ctx.session.sessionUser.accountId);
  51. const auditShenpiChangePlan = await ctx.service.changePlanAudit.getDonesByAudit(ctx.session.sessionUser.accountId);
  52. const auditShenpiPayment = await ctx.service.paymentDetailAudit.getDonesByAudit(ctx.session.sessionUser.accountId);
  53. const auditShenpiFinancial = await ctx.service.financialPayAudit.getDonesByAudit(ctx.session.sessionUser.accountId);
  54. const auditShenpiInspection = await ctx.service.qualityInspectionAudit.getDonesByAudit(ctx.session.sessionUser.accountId);
  55. const auditShenpiSafeInspection = await ctx.service.safeInspectionAudit.getDonesByAudit(ctx.session.sessionUser.accountId);
  56. const auditShenpiSafeStage = await ctx.service.safeStageAudit.getDonesByAudit(ctx.session.sessionUser.accountId);
  57. const auditShenpiPhasePay = await ctx.service.phasePayAudit.getDonesByAudit(ctx.session.sessionUser.accountId);
  58. const dashboardStatus = {
  59. all: 0,
  60. dashboard: 0,
  61. worry: 0,
  62. early: 0,
  63. shenpi: {
  64. ledger: 0,
  65. stage: 0,
  66. change: 0,
  67. revise: 0,
  68. material: 0,
  69. advance: 0,
  70. changeProject: 0,
  71. changeApply: 0,
  72. changePlan: 0,
  73. payment: 0,
  74. financial: 0,
  75. inspection: 0,
  76. safeInspection: 0,
  77. safeStage: 0,
  78. phasePay: 0,
  79. },
  80. };
  81. let noticeList = [];
  82. console.log(ctx.session.sessionUser.accountId);
  83. // 还要考虑功能关闭不展示对应类型情况
  84. const subProjects = await ctx.service.subProject.getSubProject(ctx.session.sessionProject.id, ctx.session.sessionUser.accountId, ctx.session.sessionUser.is_admin, true);
  85. for (const subProject of subProjects) {
  86. subProject.page_show = ctx.service.subProject.getPageShow(subProject.page_show);
  87. const spTenders = ctx.helper._.filter(auditShenpiTenders, { spid: subProject.id });
  88. noticeList.push(...ctx.helper.addKeyValue4ObjArray(spTenders, 'shenpi_type', 'ledger'));
  89. const spStages = ctx.helper._.filter(auditShenpiStages, { spid: subProject.id });
  90. noticeList.push(...ctx.helper.addKeyValue4ObjArray(spStages, 'shenpi_type', 'stage'));
  91. const spChanges = ctx.helper._.filter(auditShenpiChanges, { spid: subProject.id });
  92. noticeList.push(...ctx.helper.addKeyValue4ObjArray(spChanges, 'shenpi_type', 'change'));
  93. const spRevise = ctx.helper._.filter(auditShenpiRevise, { spid: subProject.id });
  94. noticeList.push(...ctx.helper.addKeyValue4ObjArray(spRevise, 'shenpi_type', 'revise'));
  95. const spMaterial = subProject.page_show.openMaterial ? ctx.helper._.filter(auditShenpiMaterial, { spid: subProject.id }) : [];
  96. noticeList.push(...ctx.helper.addKeyValue4ObjArray(spMaterial, 'shenpi_type', 'material'));
  97. const spAdvance = ctx.helper._.filter(auditShenpiAdvance, { spid: subProject.id });
  98. noticeList.push(...ctx.helper.addKeyValue4ObjArray(spAdvance, 'shenpi_type', 'advance'));
  99. const spChangeProject = subProject.page_show.openChangeProject ? ctx.helper._.filter(auditShenpiChangeProject, { spid: subProject.id }) : [];
  100. noticeList.push(...ctx.helper.addKeyValue4ObjArray(spChangeProject, 'shenpi_type', 'changeProject'));
  101. const spChangeApply = subProject.page_show.openChangeApply ? ctx.helper._.filter(auditShenpiChangeApply, { spid: subProject.id }) : [];
  102. noticeList.push(...ctx.helper.addKeyValue4ObjArray(spChangeApply, 'shenpi_type', 'changeApply'));
  103. const spChangePlan = subProject.page_show.openChangePlan ? ctx.helper._.filter(auditShenpiChangePlan, { spid: subProject.id }) : [];
  104. noticeList.push(...ctx.helper.addKeyValue4ObjArray(spChangePlan, 'shenpi_type', 'changePlan'));
  105. const spPayment = subProject.page_show.openPayment ? ctx.helper._.filter(auditShenpiPayment, { spid: subProject.id }) : [];
  106. noticeList.push(...ctx.helper.addKeyValue4ObjArray(spPayment, 'shenpi_type', 'payment'));
  107. const spFinancial = subProject.page_show.openFinancial ? ctx.helper._.filter(auditShenpiFinancial, { spid: subProject.id }) : [];
  108. noticeList.push(...ctx.helper.addKeyValue4ObjArray(spFinancial, 'shenpi_type', 'financial'));
  109. const spInspection = subProject.page_show.qualityInspection ? ctx.helper._.filter(auditShenpiInspection, { spid: subProject.id }) : [];
  110. noticeList.push(...ctx.helper.addKeyValue4ObjArray(spInspection, 'shenpi_type', 'inspection'));
  111. const spSafeInspection = subProject.page_show.safeInspection ? ctx.helper._.filter(auditShenpiSafeInspection, { spid: subProject.id }) : [];
  112. noticeList.push(...ctx.helper.addKeyValue4ObjArray(spSafeInspection, 'shenpi_type', 'safeInspection'));
  113. const spSafeStage = subProject.page_show.safeInspection ? ctx.helper._.filter(auditShenpiSafeStage, { spid: subProject.id }) : [];
  114. noticeList.push(...ctx.helper.addKeyValue4ObjArray(spSafeStage, 'shenpi_type', 'safeStage'));
  115. const spPhasePay = subProject.page_show.phasePay ? ctx.helper._.filter(auditShenpiPhasePay, { spid: subProject.id }) : [];
  116. noticeList.push(...ctx.helper.addKeyValue4ObjArray(spPhasePay, 'shenpi_type', 'phasePay'));
  117. }
  118. const noticeDayList = [];
  119. noticeList = ctx.helper._.orderBy(noticeList, ['shenpi_time'], ['desc']);
  120. for (const notice of noticeList) {
  121. const noticeDay = moment(new Date(notice.shenpi_time)).format('YYYY-MM-DD');
  122. if (noticeDayList.indexOf(noticeDay) === -1) noticeDayList.push(noticeDay);
  123. }
  124. const dashboardShenpis = [];
  125. // 审批时间状态提示,0:无预警,1,预警(当前时间大于创建时间常高于stageAuditEarly天时,触发提示),2,紧急(当前时间大于审批发起时常高于stageAuditWorry天时,触发提示)
  126. const auditTenders = await this.auditSet(ctx, allAuditTenders, subProjects, dashboardStatus, 'ledger');
  127. dashboardShenpis.push(...auditTenders);
  128. const auditStages = await this.auditSet(ctx, allAuditStages, subProjects, dashboardStatus, 'stage');
  129. dashboardShenpis.push(...auditStages);
  130. const auditChanges = await this.auditSet(ctx, allAuditChanges, subProjects, dashboardStatus, 'change');
  131. dashboardShenpis.push(...auditChanges);
  132. const auditRevise = await this.auditSet(ctx, allAuditRevise, subProjects, dashboardStatus, 'revise');
  133. dashboardShenpis.push(...auditRevise);
  134. const auditMaterial = await this.auditSet(ctx, allAuditMaterial, subProjects, dashboardStatus, 'material');
  135. dashboardShenpis.push(...auditMaterial);
  136. const auditAdvance = await this.auditSet(ctx, allAuditAdvance, subProjects, dashboardStatus, 'advance');
  137. dashboardShenpis.push(...auditAdvance);
  138. const auditChangeProject = await this.auditSet(ctx, allAuditChangeProject, subProjects, dashboardStatus, 'changeProject');
  139. dashboardShenpis.push(...auditChangeProject);
  140. const auditChangeApply = await this.auditSet(ctx, allAuditChangeApply, subProjects, dashboardStatus, 'changeApply');
  141. dashboardShenpis.push(...auditChangeApply);
  142. const auditChangePlan = await this.auditSet(ctx, allAuditChangePlan, subProjects, dashboardStatus, 'changePlan');
  143. dashboardShenpis.push(...auditChangePlan);
  144. const auditPayments = await this.auditSet(ctx, allAuditPayments, subProjects, dashboardStatus, 'payment');
  145. dashboardShenpis.push(...auditPayments);
  146. const auditStageAss = await this.auditSet(ctx, allAuditStageAss, subProjects, dashboardStatus, 'stageAss');
  147. dashboardShenpis.push(...auditStageAss);
  148. const auditFinancials = await this.auditSet(ctx, allAuditFinancials, subProjects, dashboardStatus, 'financial');
  149. dashboardShenpis.push(...auditFinancials);
  150. const auditInspections = await this.auditSet(ctx, allAuditInspections, subProjects, dashboardStatus, 'inspection');
  151. dashboardShenpis.push(...auditInspections);
  152. const auditSafeInspections = await this.auditSet(ctx, allAuditSafeInspections, subProjects, dashboardStatus, 'safeInspection');
  153. dashboardShenpis.push(...auditSafeInspections);
  154. const auditSafeStage = await this.auditSet(ctx, allAuditSafeStage, subProjects, dashboardStatus, 'safeStage');
  155. dashboardShenpis.push(...auditSafeStage);
  156. const auditPhasePay = await this.auditSet(ctx, allAuditPhasePay, subProjects, dashboardStatus, 'phasePay');
  157. dashboardShenpis.push(...auditPhasePay);
  158. // console.log(ctx.helper._.orderBy(dashboardShenpis, ['start_audit', 'shenpi_time'], ['desc', 'desc']));
  159. const projectData = await ctx.service.project.getDataById(ctx.session.sessionProject.id);
  160. // 获取销售人员数据
  161. const salesmanData = await ctx.service.manager.getDataById(projectData.manager_id);
  162. const officeName = officeList[salesmanData.office];
  163. // 获取版本信息
  164. const versionList = await ctx.service.version.getAllDataByCondition({ orders: [['id', 'desc']], limit: 5, offset: 0 });
  165. // 获取项目通知
  166. const msgList = await ctx.service.message.getMsgList(ctx.session.sessionProject.id, ctx.helper._.map(subProjects, 'id'), 10);
  167. // 获取系统通知
  168. const sysMsgList = await ctx.service.message.getMsgList(ctx.session.sessionProject.id, '', 1, 0, 2);
  169. // 获取系统维护信息
  170. const maintainData = await ctx.service.maintain.getDataById(1);
  171. // 最近使用项目列表
  172. const recentProjects = await ctx.service.subProjPermission.getRecentProjects(ctx.session.sessionUser.accountId);
  173. const renderData = {
  174. dashboardShenpis: ctx.helper._.orderBy(dashboardShenpis, ['start_audit', 'shenpi_time'], ['desc', 'asc']),
  175. dashboardStatus,
  176. role: pa.role,
  177. authMobile: pa.auth_mobile,
  178. acLedger: auditConst.ledger,
  179. acStage: auditConst.stage,
  180. acChange: auditConst.change,
  181. acRevise: auditConst.revise,
  182. acMaterial: auditConst.material,
  183. acAdvance: auditConst.advance,
  184. acChangeProject: auditConst.changeProject,
  185. acChangeApply: auditConst.changeApply,
  186. acChangePlan: auditConst.changeApply,
  187. acFinancial: auditConst.financial,
  188. acInspection: auditConst.inspection,
  189. acSafeStage: auditConst.safeStage,
  190. acPhasePay: auditConst.phasePay,
  191. noticeList,
  192. noticeDayList,
  193. pushType: auditConst.pushType,
  194. projectData,
  195. salesmanData,
  196. officeName,
  197. versionList: JSON.parse(JSON.stringify(versionList).replace(/\\r\\n/g, '<br>').replace(/\\"/g, '&#34;').replace(/'/g, '&#39;').replace(/\\t/g, '&#9;')),
  198. msgList: JSON.parse(JSON.stringify(msgList).replace(/\\r\\n/g, '<br>').replace(/\\"/g, '&#34;').replace(/'/g, '&#39;').replace(/\\t/g, '&#9;')),
  199. sysMsgList: JSON.parse(JSON.stringify(sysMsgList).replace(/\\r\\n/g, '<br>').replace(/\\"/g, '&#34;').replace(/'/g, '&#39;').replace(/\\t/g, '&#9;')),
  200. uid: ctx.session.sessionUser.accountId,
  201. maintainData,
  202. maintainConst,
  203. typeColMap,
  204. recentProjects,
  205. jsFiles: this.app.jsFiles.common.concat(this.app.jsFiles.dashboard.workspace),
  206. };
  207. await this.layout('dashboard/workspace.ejs', renderData, 'dashboard/modal.ejs');
  208. await ctx.service.projectAccount.defaultUpdate({
  209. id: this.ctx.session.sessionUser.accountId,
  210. last_notice: new Date(),
  211. });
  212. }
  213. async loadTenders(ctx) {
  214. try {
  215. const responseData = { err: 0, msg: '', data: {} };
  216. const subProjects = await ctx.service.subProject.getSubProject(ctx.session.sessionProject.id, ctx.session.sessionUser.accountId, ctx.session.sessionUser.is_admin, true);
  217. const tenders = [];
  218. const accountInfo = await ctx.service.projectAccount.getDataById(ctx.session.sessionUser.accountId);
  219. const userPermission = accountInfo !== undefined && accountInfo.permission !== '' ? JSON.parse(accountInfo.permission) : null;
  220. for (const subProject of subProjects) {
  221. subProject.page_show = ctx.service.subProject.getPageShow(subProject.page_show);
  222. // 获取每个项目下参与的标段
  223. const subProjectTenders = await ctx.service.tender.getList('', userPermission, ctx.session.sessionUser.is_admin, '', subProject);
  224. tenders.push(...subProjectTenders);
  225. }
  226. for (const t of tenders) {
  227. // 用标段管理的方法获取t数据
  228. await this.ctx.service.tenderCache.loadTenderCache(t, '');
  229. t.total_price = t.ledger_tp && t.ledger_tp.total_price ? t.ledger_tp.total_price : 0;
  230. // [t.change_tp, t.change_p_tp, t.change_n_tp, t.change_valuation_tp, t.change_unvaluation_tp] = await ctx.service.change.getChangeTp(t.id);
  231. }
  232. responseData.data.tenderList = tenders;
  233. ctx.body = responseData;
  234. } catch (err) {
  235. this.log(err);
  236. ctx.body = { err: 1, msg: err.toString(), data: null };
  237. }
  238. }
  239. async auditSet(ctx, allAudits, subProjects, dashboardStatus, type) {
  240. const audits = [];
  241. for (const t of allAudits) {
  242. const sp = subProjects.find(sp => sp.id === t.spid);
  243. if (sp) {
  244. t.sp_name = sp.name;
  245. t.start_audit = 0;
  246. let calcTime;
  247. let closeType = false;
  248. switch (type) {
  249. case 'ledger':
  250. calcTime = t.ledger_status === auditConst[type].status.checking ? t.begin_time : t.end_time;
  251. break;
  252. case 'revise':
  253. calcTime = t.status === auditConst[type].status.checking ? t.begin_time : t.end_time;
  254. break;
  255. case 'stage':
  256. calcTime = t.sstatus === auditConst[type].status.checkNo ? t.end_time : t.begin_time;
  257. break;
  258. case 'stageAss':
  259. calcTime = t.begin_time;
  260. break;
  261. case 'change':
  262. calcTime = t.begin_time ? t.begin_time : t.cin_time ? new Date(ctx.moment.unix(t.cin_time).format('YYYY-MM-DD HH:mm:ss')) : '';
  263. break;
  264. case 'changeProject':
  265. if (!sp.page_show.openChangeProject) closeType = true;
  266. calcTime = t.status !== auditConst[type].status.back ? t.begin_time : t.end_time;
  267. break;
  268. case 'changeApply':
  269. if (!sp.page_show.openChangeApply) closeType = true;
  270. calcTime = t.mstatus !== auditConst[type].status.checkNo ? t.begin_time : t.end_time;
  271. break;
  272. case 'changePlan':
  273. if (!sp.page_show.openChangePlan) closeType = true;
  274. calcTime = t.mstatus !== auditConst[type].status.checkNo ? t.begin_time : t.end_time;
  275. break;
  276. case 'material':
  277. if (!sp.page_show.openMaterial) closeType = true;
  278. calcTime = t.mstatus !== auditConst[type].status.checkNo ? t.begin_time : t.end_time;
  279. break;
  280. case 'advance':
  281. calcTime = t.mstatus !== auditConst[type].status.checkNo ? t.create_time : t.end_time;
  282. break;
  283. case 'payment':
  284. if (!sp.page_show.openPayment) closeType = true;
  285. calcTime = t.sstatus !== auditConst.stage.status.checkNo ? t.begin_time : t.end_time;
  286. break;
  287. case 'financial':
  288. if (!sp.page_show.openFinancial) closeType = true;
  289. calcTime = t.fpcstatus !== auditConst[type].status.checkNo ? t.begin_time : t.end_time;
  290. break;
  291. case 'inspection':
  292. if (!sp.page_show.qualityInspection) closeType = true;
  293. calcTime = t.status !== auditConst[type].status.checkNo ? t.begin_time : t.end_time;
  294. break;
  295. case 'safeInspection':
  296. if (!sp.page_show.safeInspection) closeType = true;
  297. calcTime = t.status !== auditConst.inspection.status.checkNo ? t.begin_time : t.end_time;
  298. break;
  299. case 'safeStage':
  300. if (!sp.page_show.safePayment) closeType = true;
  301. calcTime = t.create_time;
  302. break;
  303. case 'phasePay':
  304. if (!sp.page_show.phasePay) closeType = true;
  305. calcTime = t.create_time;
  306. break;
  307. default:
  308. closeType = true;
  309. }
  310. if (closeType) continue;
  311. if (sp.page_show.openStageAudit) {
  312. const now = new Date();
  313. const calcDay = ctx.helper.calculateDaysBetween(now, calcTime);
  314. if (sp.page_show.stageAuditWorry && calcDay >= sp.page_show.stageAuditWorry) {
  315. t.start_audit = 2;
  316. dashboardStatus.worry += 1;
  317. } else if (sp.page_show.stageAuditEarly && calcDay >= sp.page_show.stageAuditEarly) {
  318. t.start_audit = 1;
  319. dashboardStatus.early += 1;
  320. }
  321. }
  322. const calcType = type === 'stageAss' ? 'stage' : type;
  323. dashboardStatus.shenpi[calcType] += 1;
  324. t.shenpi_time = calcTime;
  325. t.shenpi_type = type;
  326. dashboardStatus.dashboard += 1;
  327. audits.push(t);
  328. }
  329. }
  330. return audits;
  331. }
  332. /**
  333. * 控制面板页面
  334. *
  335. * @param {Object} ctx - egg全局变量
  336. * @return {void}
  337. */
  338. async index(ctx) {
  339. const auditTenders = await ctx.service.ledgerAudit.getAuditTender(ctx.session.sessionUser.accountId, ctx.subProject.id);
  340. const auditStages = await ctx.service.stageAudit.getAuditStage(ctx.session.sessionUser.accountId, ctx.subProject.id);
  341. const auditChanges = await ctx.service.changeAudit.getAuditChange(ctx.session.sessionUser.accountId, ctx.subProject.id);
  342. const auditRevise = await ctx.service.reviseAudit.getAuditRevise(ctx.session.sessionUser.accountId, ctx.subProject.id);
  343. const auditMaterial = ctx.subProject.page_show.openMaterial ? await ctx.service.materialAudit.getAuditMaterial(ctx.session.sessionUser.accountId, ctx.subProject.id) : [];
  344. const auditAdvance = await ctx.service.advanceAudit.getAuditAdvance(ctx.session.sessionUser.accountId, ctx.subProject.id);
  345. const auditChangeProject = ctx.subProject.page_show.openChangeProject ? await ctx.service.changeProjectAudit.getAuditChangeProject(ctx.session.sessionUser.accountId, ctx.subProject.id) : [];
  346. const auditChangeApply = ctx.subProject.page_show.openChangeApply ? await ctx.service.changeApplyAudit.getAuditChangeApply(ctx.session.sessionUser.accountId, ctx.subProject.id) : [];
  347. const auditChangePlan = ctx.subProject.page_show.openChangePlan ? await ctx.service.changePlanAudit.getAuditChangePlan(ctx.session.sessionUser.accountId, ctx.subProject.id) : [];
  348. const auditPayments = ctx.subProject.page_show.openPayment ? await ctx.service.paymentDetailAudit.getAuditPayment(ctx.session.sessionUser.accountId, ctx.subProject.id) : [];
  349. const auditStageAss = await ctx.service.stageAuditAss.getAuditStageAss(ctx.session.sessionUser.accountId, ctx.subProject.id);
  350. const auditFinancials = ctx.subProject.page_show.openFinancial ? await ctx.service.financialPayAudit.getAuditFinancial(ctx.session.sessionUser.accountId, ctx.subProject.id) : [];
  351. const auditInspections = ctx.subProject.page_show.qualityInspection ? await ctx.service.qualityInspectionAudit.getAuditInspection(ctx.session.sessionUser.accountId, ctx.subProject.id) : [];
  352. const auditSafeInspections = ctx.subProject.page_show.safeInspection ? await ctx.service.safeInspectionAudit.getAuditInspection(ctx.session.sessionUser.accountId, ctx.subProject.id) : [];
  353. const auditSafeStage = ctx.subProject.page_show.safePayment ? await ctx.service.safeStageAudit.getAuditStage(ctx.session.sessionUser.accountId, ctx.subProject.id) : [];
  354. const auditPhasePay = ctx.subProject.page_show.phasePay ? await ctx.service.phasePayAudit.getAuditStage(ctx.session.sessionUser.accountId, ctx.subProject.id) : [];
  355. const pa = await ctx.service.projectAccount.getDataById(ctx.session.sessionUser.accountId);
  356. const noticeList = await ctx.service.noticePush.getNotice(ctx.session.sessionProject.id, pa.id, ctx.subProject.id);
  357. const projectData = await ctx.service.project.getDataById(ctx.session.sessionProject.id);
  358. // 获取销售人员数据
  359. const salesmanData = await ctx.service.manager.getDataById(projectData.manager_id);
  360. const officeName = officeList[salesmanData.office];
  361. // 获取版本信息
  362. const versionList = await ctx.service.version.getAllDataByCondition({ orders: [['id', 'desc']], limit: 5, offset: 0 });
  363. // 获取项目通知
  364. const msgList = await ctx.service.message.getMsgList(ctx.session.sessionProject.id, ctx.subProject.id);
  365. const userPermission = pa !== undefined && pa.permission !== '' ? JSON.parse(pa.permission) : null;
  366. const userMsgPermission = userPermission !== null && userPermission.project_msg !== undefined && parseInt(userPermission.project_msg) === 1;
  367. // 获取系统通知
  368. const sysMsgList = await ctx.service.message.getMsgList(ctx.session.sessionProject.id, '', 1, 0, 2);
  369. // 获取系统维护信息
  370. const maintainData = await ctx.service.maintain.getDataById(1);
  371. // 获取各个审批的次数及最后的审批时间
  372. const shenpi_count = [
  373. { count: await ctx.service.advanceAudit.getCountByChecked(ctx.session.sessionUser.accountId, ctx.subProject.id), name: '预付款' },
  374. { count: await ctx.service.ledgerAudit.getCountByChecked(ctx.session.sessionUser.accountId, ctx.subProject.id), name: '台账审批' },
  375. { count: await ctx.service.reviseAudit.getCountByChecked(ctx.session.sessionUser.accountId, ctx.subProject.id), name: '台账修订' },
  376. { count: await ctx.service.stageAudit.getCountByChecked(ctx.session.sessionUser.accountId, ctx.subProject.id), name: '计量审批' },
  377. { count: await ctx.service.changeAudit.getCountByChecked(ctx.session.sessionUser.accountId, ctx.subProject.id), name: '变更审批' },
  378. ];
  379. if (ctx.subProject.page_show.openChangeProject) shenpi_count.push({ count: await ctx.service.changeProjectAudit.getCountByChecked(ctx.session.sessionUser.accountId, ctx.subProject.id), name: '变更立项' });
  380. if (ctx.subProject.page_show.openChangeApply) shenpi_count.push({ count: await ctx.service.changeApplyAudit.getCountByChecked(ctx.session.sessionUser.accountId, ctx.subProject.id), name: '变更申请' });
  381. if (ctx.subProject.page_show.openChangePlan) shenpi_count.push({ count: await ctx.service.changePlanAudit.getCountByChecked(ctx.session.sessionUser.accountId, ctx.subProject.id), name: '变更方案' });
  382. if (ctx.subProject.page_show.openMaterial) shenpi_count.push({ count: await ctx.service.materialAudit.getCountByChecked(ctx.session.sessionUser.accountId, ctx.subProject.id), name: '材料调差' });
  383. if (ctx.subProject.page_show.openFinancial) shenpi_count.push({ count: await ctx.service.financialPayAudit.getCountByChecked(ctx.session.sessionUser.accountId, ctx.subProject.id), name: '资金支付' });
  384. if (ctx.subProject.page_show.qualityInspection) shenpi_count.push({ count: await ctx.service.qualityInspectionAudit.getCountByChecked(ctx.session.sessionUser.accountId, ctx.subProject.id), name: '质量巡检' });
  385. if (ctx.subProject.page_show.safeInspection) shenpi_count.push({ count: await ctx.service.safeInspectionAudit.getCountByChecked(ctx.session.sessionUser.accountId, ctx.subProject.id), name: '安全巡检' });
  386. if (ctx.subProject.page_show.safePayment) shenpi_count.push({ count: await ctx.service.safeStageAudit.getCountByChecked(ctx.session.sessionUser.accountId, ctx.subProject.id), name: '安全计量' });
  387. if (ctx.subProject.page_show.phasePay) shenpi_count.push({ count: await ctx.service.phasePayAudit.getCountByChecked(ctx.session.sessionUser.accountId, ctx.subProject.id), name: '合同支付' });
  388. // shenpi_count.push({ count: await ctx.service.advanceAudit.getCountByChecked(ctx.session.sessionUser.accountId), name: '预付款' });
  389. const total_count = ctx.app._.sumBy(shenpi_count, 'count');
  390. const shenpi_lastime = [
  391. await ctx.service.advanceAudit.getLastEndTimeByChecked(ctx.session.sessionUser.accountId, ctx.subProject.id),
  392. await ctx.service.ledgerAudit.getLastEndTimeByChecked(ctx.session.sessionUser.accountId, ctx.subProject.id),
  393. await ctx.service.reviseAudit.getLastEndTimeByChecked(ctx.session.sessionUser.accountId, ctx.subProject.id),
  394. await ctx.service.stageAudit.getLastEndTimeByChecked(ctx.session.sessionUser.accountId, ctx.subProject.id),
  395. await ctx.service.changeAudit.getLastEndTimeByChecked(ctx.session.sessionUser.accountId, ctx.subProject.id),
  396. ctx.subProject.page_show.openChangeProject ? await ctx.service.changeProjectAudit.getLastEndTimeByChecked(ctx.session.sessionUser.accountId, ctx.subProject.id) : null,
  397. ctx.subProject.page_show.openChangeApply ? await ctx.service.changeApplyAudit.getLastEndTimeByChecked(ctx.session.sessionUser.accountId, ctx.subProject.id) : null,
  398. ctx.subProject.page_show.openChangePlan ? await ctx.service.changePlanAudit.getLastEndTimeByChecked(ctx.session.sessionUser.accountId, ctx.subProject.id) : null,
  399. ctx.subProject.page_show.openMaterial ? await ctx.service.materialAudit.getLastEndTimeByChecked(ctx.session.sessionUser.accountId, ctx.subProject.id) : null,
  400. ctx.subProject.page_show.openFinancial ? await ctx.service.financialPayAudit.getLastEndTimeByChecked(ctx.session.sessionUser.accountId, ctx.subProject.id) : null,
  401. ctx.subProject.page_show.qualityInspection ? await ctx.service.qualityInspectionAudit.getLastEndTimeByChecked(ctx.session.sessionUser.accountId, ctx.subProject.id) : null,
  402. ctx.subProject.page_show.safeInspection ? await ctx.service.safeInspectionAudit.getLastEndTimeByChecked(ctx.session.sessionUser.accountId, ctx.subProject.id) : null,
  403. ctx.subProject.page_show.safeInspection ? await ctx.service.safeStageAudit.getLastEndTimeByChecked(ctx.session.sessionUser.accountId, ctx.subProject.id) : null,
  404. ctx.subProject.page_show.phasePay ? await ctx.service.phasePayAudit.getLastEndTimeByChecked(ctx.session.sessionUser.accountId, ctx.subProject.id) : null,
  405. ];
  406. const last_time = ctx.app._.max(shenpi_lastime);
  407. // console.log(ctx.app._.max(shenpi_lastime), ctx.helper.calcDayNum(last_time));
  408. const renderData = {
  409. auditTenders,
  410. auditStages,
  411. auditChanges,
  412. auditRevise,
  413. auditMaterial,
  414. auditAdvance,
  415. auditChangeProject,
  416. auditChangeApply,
  417. auditChangePlan,
  418. auditPayments,
  419. auditStageAss,
  420. auditFinancials,
  421. auditInspections,
  422. auditSafeInspections,
  423. auditSafeStage,
  424. auditPhasePay,
  425. shenpi_count,
  426. total_count,
  427. last_day: ctx.helper.calcDayNum(last_time),
  428. role: pa.role,
  429. authMobile: pa.auth_mobile,
  430. acLedger: auditConst.ledger,
  431. acStage: auditConst.stage,
  432. acChange: auditConst.change,
  433. acRevise: auditConst.revise,
  434. acMaterial: auditConst.material,
  435. acAdvance: auditConst.advance,
  436. acChangeProject: auditConst.changeProject,
  437. acChangeApply: auditConst.changeApply,
  438. acChangePlan: auditConst.changeApply,
  439. acFinancial: auditConst.financial,
  440. acInspection: auditConst.inspection,
  441. acSafeStage: auditConst.safeStage,
  442. acPhasePay: auditConst.phasePay,
  443. noticeList,
  444. pushType: auditConst.pushType,
  445. projectData,
  446. salesmanData,
  447. officeName,
  448. versionList: JSON.parse(JSON.stringify(versionList).replace(/\\r\\n/g, '<br>').replace(/\\"/g, '&#34;').replace(/'/g, '&#39;').replace(/\\t/g, '&#9;')),
  449. msgList: JSON.parse(JSON.stringify(msgList).replace(/\\r\\n/g, '<br>').replace(/\\"/g, '&#34;').replace(/'/g, '&#39;').replace(/\\t/g, '&#9;')),
  450. sysMsgList: JSON.parse(JSON.stringify(sysMsgList).replace(/\\r\\n/g, '<br>').replace(/\\"/g, '&#34;').replace(/'/g, '&#39;').replace(/\\t/g, '&#9;')),
  451. userMsgPermission,
  452. uid: ctx.session.sessionUser.accountId,
  453. maintainData,
  454. maintainConst,
  455. typeColMap,
  456. };
  457. await this.layout('dashboard/index.ejs', renderData, 'dashboard/modal.ejs');
  458. await ctx.service.projectAccount.defaultUpdate({
  459. id: this.ctx.session.sessionUser.accountId,
  460. last_notice: new Date(),
  461. });
  462. }
  463. /**
  464. * 控制面板-通知页面
  465. *
  466. * @param {Object} ctx - egg全局变量
  467. * @return {void}
  468. */
  469. async msg(ctx) {
  470. try {
  471. const page = ctx.page;
  472. const msgId = parseInt(ctx.params.mid) || 0;
  473. let msgInfo = msgId ? await ctx.service.message.getDataById(msgId) : null;
  474. const type = msgInfo ? msgInfo.type : ctx.request.query.type ? parseInt(ctx.request.query.type) : 1;
  475. if (msgInfo && msgInfo.type === 1 && msgInfo.project_id !== ctx.session.sessionProject.id) {
  476. throw '非该项目通知无权查看';
  477. }
  478. if (msgInfo) {
  479. msgInfo.content = JSON.parse(JSON.stringify(msgInfo.content).replace(/\\r\\n/g, '<br>').replace(/\\"/g, '&#34;').replace(/'/g, '&#39;').replace(/\\t/g, '&#9;'));
  480. msgInfo.files = await this.ctx.service.messageAtt.getAtt(msgInfo.id);
  481. }
  482. const total = type === 1 ?
  483. await ctx.service.message.count({ project_id: ctx.session.sessionProject.id, spid: [ctx.subProject.id, ''], type }) :
  484. await ctx.service.message.count({ status: 1, type });
  485. const limit = 5;
  486. const offset = limit * (this.ctx.page - 1);
  487. const msgList = await ctx.service.message.getMsgList(ctx.session.sessionProject.id, ctx.subProject.id, limit, offset, type);
  488. const pa = await ctx.service.projectAccount.getDataById(ctx.session.sessionUser.accountId);
  489. const userPermission = pa !== undefined && pa.permission !== '' ? JSON.parse(pa.permission) : null;
  490. const userMsgPermission = userPermission !== null && userPermission.project_msg !== undefined && parseInt(userPermission.project_msg) === 1;
  491. if (!msgInfo) {
  492. msgInfo = msgList[0];
  493. }
  494. // 分页相关
  495. const pageInfo = {
  496. page,
  497. total: Math.ceil(total / limit),
  498. queryData: JSON.stringify(ctx.urlInfo.query),
  499. };
  500. const renderData = {
  501. msgInfo,
  502. uid: ctx.session.sessionUser.accountId,
  503. type,
  504. pageInfo,
  505. userMsgPermission,
  506. msgList: JSON.parse(JSON.stringify(msgList).replace(/\\r\\n/g, '<br>').replace(/\\"/g, '&#34;').replace(/'/g, '&#39;').replace(/\\t/g, '&#9;')),
  507. };
  508. await this.layout('dashboard/msg.ejs', renderData);
  509. } catch (error) {
  510. console.log(error);
  511. this.log(error);
  512. ctx.session.postError = error.toString();
  513. ctx.redirect('/sp/' + ctx.subProject.id + '/dashboard');
  514. }
  515. }
  516. /**
  517. * 控制面板-通知添加和编辑页面
  518. *
  519. * @param {Object} ctx - egg全局变量
  520. * @return {void}
  521. */
  522. async msgAdd(ctx) {
  523. let id = ctx.params.mid;
  524. id = parseInt(id);
  525. try {
  526. if (isNaN(id) || id < 0) {
  527. throw '参数错误';
  528. }
  529. const rule = ctx.service.message.rule();
  530. const jsValidator = await this.jsValidator.convert(rule).build();
  531. const msgInfo = id === 0 ? {} : await ctx.service.message.getDataById(id);
  532. const files = await ctx.service.messageAtt.getAtt(id);
  533. const renderData = {
  534. jsValidator,
  535. msgInfo,
  536. files,
  537. whiteList: ctx.app.config.multipart.whitelist,
  538. moment,
  539. };
  540. await this.layout('dashboard/msg_add.ejs', renderData, 'dashboard/msg_modal.ejs');
  541. } catch (error) {
  542. console.log(error);
  543. // this.setMessage(error.toString(), this.messageType.ERROR);
  544. ctx.redirect(ctx.request.header.referer);
  545. }
  546. }
  547. /**
  548. * 控制面板-通知保存
  549. *
  550. * @param {Object} ctx - egg全局变量
  551. * @return {void}
  552. */
  553. async msgSet(ctx) {
  554. try {
  555. let id = ctx.params.mid;
  556. id = parseInt(id);
  557. if (isNaN(id) || id < 0) {
  558. throw '参数错误';
  559. }
  560. const rule = ctx.service.message.rule();
  561. ctx.helper.validate(rule);
  562. const result = await ctx.service.message.save(id, ctx.request.body, ctx.session.sessionUser, ctx.session.sessionProject.id, ctx.subProject.id);
  563. if (result) {
  564. // 新增的项目通知会发送微信模版消息通知客户
  565. if (id === 0) {
  566. // 获取该项目所有的openid,发送信息
  567. const wechats = await ctx.service.projectAccount.getOpenIdListByPid(ctx.session.sessionProject.id);
  568. if (wechats.length > 0) {
  569. const msgInfo = await ctx.service.message.getDataById(result);
  570. const projectData = await ctx.service.project.getDataById(ctx.session.sessionProject.id);
  571. // 绑定成功通知
  572. const templateId = 'VKUo4us4lt2dQY0EaaJxcui2jkjmriN3A0K7i4kpZwY';
  573. const url = ctx.protocol + '://' + ctx.host + '/wx/url2wap?project=' + ctx.session.sessionProject.code + '&url=' + ctx.protocol + '://' + ctx.host + '/wap/dashboard/msg/' + msgInfo.id;
  574. const msgData = {
  575. thing21: {
  576. value: ctx.helper.contentChange(projectData.name),
  577. },
  578. thing2: {
  579. value: ctx.helper.contentChange(msgInfo.title),
  580. },
  581. thing8: {
  582. value: msgInfo.creator,
  583. },
  584. time3: {
  585. value: moment(msgInfo.release_time * 1000).format('YYYY-MM-DD'),
  586. },
  587. };
  588. for (const wx of wechats) {
  589. const result = await app.wechat.api.sendTemplate(wx.wx_openid, templateId, url, '', msgData);
  590. }
  591. }
  592. }
  593. ctx.redirect('/sp/' + ctx.subProject.id + '/dashboard/msg');
  594. }
  595. } catch (error) {
  596. console.log(error);
  597. ctx.redirect(ctx.request.header.referer);
  598. }
  599. }
  600. /**
  601. * 控制面板-通知删除
  602. *
  603. * @param {Object} ctx - egg全局变量
  604. * @return {void}
  605. */
  606. async msgDelete(ctx) {
  607. try {
  608. let id = ctx.params.mid;
  609. id = parseInt(id);
  610. if (isNaN(id) || id <= 0) {
  611. throw '参数错误';
  612. }
  613. const msgInfo = await ctx.service.message.getDataById(id);
  614. if (!msgInfo || msgInfo.create_uid !== ctx.session.sessionUser.accountId) {
  615. throw '通知不存在或无权限操作';
  616. }
  617. const result = await ctx.service.message.deleteMsg(msgInfo.id);
  618. if (result) {
  619. ctx.redirect('/sp/' + ctx.subProject.id + '/dashboard/msg');
  620. }
  621. } catch (error) {
  622. console.log(error);
  623. ctx.redirect(ctx.request.header.referer);
  624. }
  625. }
  626. /**
  627. * 将推送记录设置为已读
  628. * @param {Object} ctx 上下文
  629. */
  630. async pushSet(ctx) {
  631. try {
  632. const { id } = JSON.parse(ctx.request.body.data);
  633. const data = await ctx.service.noticePush.set(id);
  634. ctx.body = { err: 0, msg: '' };
  635. } catch (err) {
  636. this.log(err);
  637. ctx.body = { err: 1, msg: err.toString(), data: null };
  638. }
  639. }
  640. /**
  641. * 上传附件
  642. * @param {*} ctx 上下文
  643. */
  644. async msgUploadFile(ctx) {
  645. let stream;
  646. try {
  647. const responseData = { err: 0, msg: '', data: {} };
  648. const mid = ctx.params.mid || 0;
  649. if (!mid) throw '参数有误';
  650. const parts = this.ctx.multipart({
  651. autoFields: true,
  652. });
  653. const files = [];
  654. const create_time = Date.parse(new Date()) / 1000;
  655. let idx = 0;
  656. while ((stream = await parts()) !== undefined) {
  657. if (!stream.filename) {
  658. // 如果没有传入直接返回
  659. return;
  660. }
  661. const fileInfo = path.parse(stream.filename);
  662. const filepath = `app/public/upload/message/fujian_${create_time + idx.toString() + fileInfo.ext}`;
  663. await ctx.app.fujianOss.put(ctx.app.config.fujianOssFolder + filepath, stream);
  664. files.push({ filepath, name: stream.filename, ext: fileInfo.ext });
  665. ++idx;
  666. stream && (await sendToWormhole(stream));
  667. }
  668. const in_time = new Date();
  669. const payload = files.map(file => {
  670. let idx;
  671. if (Array.isArray(parts.field.name)) {
  672. idx = parts.field.name.findIndex(name => name === file.name);
  673. } else {
  674. idx = 'isString';
  675. }
  676. const newFile = {
  677. project_id: ctx.session.sessionProject.id,
  678. mid,
  679. uid: ctx.session.sessionUser.accountId,
  680. filename: file.name,
  681. fileext: file.ext,
  682. filesize: ctx.helper.bytesToSize(idx === 'isString' ? parts.field.size : parts.field.size[idx]),
  683. filepath: file.filepath,
  684. upload_time: in_time,
  685. };
  686. return newFile;
  687. });
  688. // 执行文件信息写入数据库
  689. await ctx.service.messageAtt.saveFileMsgToDb(payload);
  690. // 将最新的当前标段的所有文件信息返回
  691. responseData.data = await ctx.service.messageAtt.getAtt(mid);
  692. ctx.body = responseData;
  693. } catch (err) {
  694. stream && (await sendToWormhole(stream));
  695. this.log(err);
  696. ctx.body = { err: 1, msg: err.toString(), data: null };
  697. }
  698. }
  699. /**
  700. * 删除附件
  701. * @param {Ojbect} ctx 上下文
  702. */
  703. async msgDeleteFile(ctx) {
  704. try {
  705. const mid = ctx.params.mid || 0;
  706. const responseData = { err: 0, msg: '', data: {} };
  707. const data = JSON.parse(ctx.request.body.data);
  708. const fileInfo = await ctx.service.messageAtt.getDataById(data.id);
  709. if (fileInfo) {
  710. // 先删除文件
  711. // await fs.unlinkSync(path.resolve(this.app.baseDir, './app', fileInfo.filepath));
  712. await ctx.app.fujianOss.delete(ctx.app.config.fujianOssFolder + fileInfo.filepath);
  713. // 再删除数据库
  714. await ctx.service.messageAtt.delete(data.id);
  715. } else {
  716. throw '不存在该文件';
  717. }
  718. responseData.data = await ctx.service.messageAtt.getAtt(mid);
  719. ctx.body = responseData;
  720. } catch (err) {
  721. this.log(err);
  722. ctx.body = { err: 1, msg: err.toString(), data: null };
  723. }
  724. }
  725. }
  726. return DashboardController;
  727. };