dashboard_controller.js 57 KB

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