wap_controller.js 55 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485868788899091929394959697989910010110210310410510610710810911011111211311411511611711811912012112212312412512612712812913013113213313413513613713813914014114214314414514614714814915015115215315415515615715815916016116216316416516616716816917017117217317417517617717817918018118218318418518618718818919019119219319419519619719819920020120220320420520620720820921021121221321421521621721821922022122222322422522622722822923023123223323423523623723823924024124224324424524624724824925025125225325425525625725825926026126226326426526626726826927027127227327427527627727827928028128228328428528628728828929029129229329429529629729829930030130230330430530630730830931031131231331431531631731831932032132232332432532632732832933033133233333433533633733833934034134234334434534634734834935035135235335435535635735835936036136236336436536636736836937037137237337437537637737837938038138238338438538638738838939039139239339439539639739839940040140240340440540640740840941041141241341441541641741841942042142242342442542642742842943043143243343443543643743843944044144244344444544644744844945045145245345445545645745845946046146246346446546646746846947047147247347447547647747847948048148248348448548648748848949049149249349449549649749849950050150250350450550650750850951051151251351451551651751851952052152252352452552652752852953053153253353453553653753853954054154254354454554654754854955055155255355455555655755855956056156256356456556656756856957057157257357457557657757857958058158258358458558658758858959059159259359459559659759859960060160260360460560660760860961061161261361461561661761861962062162262362462562662762862963063163263363463563663763863964064164264364464564664764864965065165265365465565665765865966066166266366466566666766866967067167267367467567667767867968068168268368468568668768868969069169269369469569669769869970070170270370470570670770870971071171271371471571671771871972072172272372472572672772872973073173273373473573673773873974074174274374474574674774874975075175275375475575675775875976076176276376476576676776876977077177277377477577677777877978078178278378478578678778878979079179279379479579679779879980080180280380480580680780880981081181281381481581681781881982082182282382482582682782882983083183283383483583683783883984084184284384484584684784884985085185285385485585685785885986086186286386486586686786886987087187287387487587687787887988088188288388488588688788888989089189289389489589689789889990090190290390490590690790890991091191291391491591691791891992092192292392492592692792892993093193293393493593693793893994094194294394494594694794894995095195295395495595695795895996096196296396496596696796896997097197297397497597697797897998098198298398498598698798898999099199299399499599699799899910001001100210031004100510061007100810091010101110121013101410151016101710181019102010211022102310241025102610271028102910301031103210331034103510361037103810391040104110421043104410451046104710481049105010511052105310541055105610571058105910601061106210631064106510661067106810691070107110721073107410751076107710781079108010811082108310841085108610871088108910901091109210931094109510961097109810991100110111021103110411051106110711081109111011111112111311141115111611171118111911201121112211231124112511261127112811291130113111321133113411351136113711381139114011411142114311441145114611471148114911501151115211531154115511561157115811591160116111621163116411651166116711681169117011711172117311741175117611771178117911801181118211831184118511861187118811891190119111921193119411951196119711981199120012011202120312041205120612071208120912101211121212131214121512161217121812191220122112221223122412251226122712281229123012311232123312341235123612371238123912401241
  1. 'use strict';
  2. /**
  3. * 登录页面控制器
  4. *
  5. * @author CaiAoLin
  6. * @date 2017/11/15
  7. * @version
  8. */
  9. const URL = require('url');
  10. const maintainConst = require('../const/maintain');
  11. const auditConst = require('../const/audit');
  12. const tenderConst = require('../const/tender');
  13. const changeConst = require('../const/change');
  14. const advanceConst = require('../const/advance');
  15. const materialConst = require('../const/material');
  16. const fs = require('fs');
  17. const path = require('path');
  18. const sendToWormhole = require('stream-wormhole');
  19. const moment = require('moment');
  20. const auditType = require('../const/audit').auditType;
  21. const AiInspect = require('../lib/ai_inspect');
  22. const uuid = require('node-uuid');
  23. const nlsToken = require('../lib/nls_token');
  24. module.exports = app => {
  25. class WapController extends app.BaseController {
  26. /**
  27. * 登录页面
  28. *
  29. * @param {Object} ctx - egg全局页面
  30. * @return {void}
  31. */
  32. async index(ctx) {
  33. if (!ctx.helper.isMobile(ctx.request.header['user-agent'])) {
  34. ctx.redirect('/');
  35. return;
  36. }
  37. const errorMessage = ctx.session.loginError;
  38. // 显示完删除
  39. ctx.session.loginError = null;
  40. // 获取系统维护信息
  41. const maintainData = await ctx.service.maintain.getDataById(1);
  42. if (!ctx.app.config.is_debug) {
  43. await ctx.service.maintain.syncMaintainData();
  44. }
  45. let projectData = '';
  46. if (ctx.session.wapTenderID) {
  47. const tenderData = await ctx.service.tender.getDataById(ctx.session.wapTenderID);
  48. if (tenderData) projectData = await ctx.service.project.getDataById(tenderData.project_id);
  49. }
  50. const renderData = {
  51. maintainData,
  52. maintainConst,
  53. errorMessage,
  54. projectData,
  55. };
  56. await ctx.render('wap/login.ejs', renderData);
  57. }
  58. /**
  59. * 登录操作
  60. *
  61. * @param {Object} ctx - egg全局变量
  62. * @return {void}
  63. */
  64. async login(ctx) {
  65. let loginType = ctx.request.body.type;
  66. try {
  67. loginType = parseInt(loginType);
  68. const result = await ctx.service.projectAccount.accountLogin(ctx.request.body, loginType);
  69. if (!result) {
  70. throw '用户名或密码错误';
  71. }
  72. if (result === 2) {
  73. // 判断是否有设置停用提示,有则展示
  74. const msg = await ctx.service.projectStopmsg.getMsg(ctx.session.sessionProject.id);
  75. throw msg;
  76. }
  77. // 调用 rotateCsrfSecret 刷新用户的 CSRF token
  78. ctx.rotateCsrfSecret();
  79. // 判断是否已经有对应用户信息,没有则跳转初始化页面
  80. const needBoot = await ctx.service.customer.isNeedBoot(ctx.request.body);
  81. const url = needBoot ? '/boot' : '/wap/dashboard';
  82. const query = URL.parse(ctx.request.header.referer, true).query;
  83. let referer = '';
  84. if (ctx.session.wapTenderID) {
  85. referer = query.referer ? query.referer + '#shenpi' : url;
  86. ctx.session.wapTenderID = null;
  87. }
  88. ctx.redirect(referer ? referer : url);
  89. } catch (error) {
  90. this.log(error);
  91. ctx.session.loginError = error;
  92. ctx.redirect('/wap');
  93. }
  94. }
  95. /**
  96. * 退出登录
  97. *
  98. * @param {Object} ctx - egg全局变量
  99. * @return {void}
  100. */
  101. async logout(ctx) {
  102. // 删除session并跳转
  103. ctx.session = null;
  104. ctx.redirect('/wap');
  105. }
  106. /**
  107. * 待办页
  108. *
  109. * @param {Object} ctx - egg全局变量
  110. * @return {void}
  111. */
  112. async dashboard(ctx) {
  113. // 获取待审批的期
  114. const auditStages = await ctx.service.stageAudit.getAuditStageByWap(ctx.session.sessionUser.accountId);
  115. const subProjects = [];
  116. for (const audit of auditStages) {
  117. if (audit.status !== auditConst.stage.status.uncheck) {
  118. const isLastage = await ctx.service.stage.isLastStage(audit.tid, audit.id);
  119. if (isLastage) await this.ctx.service.stage.checkStageGatherData(audit);
  120. }
  121. audit.gather_tp = ctx.helper.sum([audit.contract_tp, audit.qc_tp, audit.pc_tp]);
  122. audit.end_contract_tp = ctx.helper.sum([audit.contract_tp, audit.pre_contract_tp, audit.contract_pc_tp]);
  123. audit.end_qc_tp = ctx.helper.sum([audit.qc_tp, audit.pre_qc_tp, audit.qc_pc_tp]);
  124. audit.pre_gather_tp = ctx.helper.add(audit.pre_contract_tp, audit.pre_qc_tp);
  125. audit.end_gather_tp = ctx.helper.add(audit.gather_tp, audit.pre_gather_tp);
  126. let sp = null;
  127. if (audit.spid) {
  128. if (ctx.helper._.findIndex(subProjects, { id: audit.spid }) !== -1) {
  129. sp = ctx.helper._.find(subProjects, { id: audit.spid });
  130. } else {
  131. sp = await ctx.service.subProject.getDataById(audit.spid);
  132. subProjects.push(sp);
  133. }
  134. }
  135. if (sp) {
  136. const pageShow = JSON.parse(sp.page_show);
  137. audit.closeWapYfSf = pageShow.closeWapYfSf || 0;
  138. } else {
  139. audit.closeWapYfSf = 0;
  140. }
  141. }
  142. // 获取待审批的变更期
  143. const auditChanges = await ctx.service.changeAudit.getAuditChangeByWap(ctx.session.sessionUser.accountId);
  144. // 获取待审批的变更立项
  145. const auditChangeProjects = [];
  146. const changeProjects = await ctx.service.changeProjectAudit.getAuditChangeProjectByWap(ctx.session.sessionUser.accountId);
  147. for (const cp of changeProjects) {
  148. let sp = null;
  149. if (cp.spid) {
  150. if (ctx.helper._.findIndex(subProjects, { id: cp.spid }) !== -1) {
  151. sp = ctx.helper._.find(subProjects, { id: cp.spid });
  152. } else {
  153. sp = await ctx.service.subProject.getDataById(cp.spid);
  154. subProjects.push(sp);
  155. }
  156. }
  157. if (sp) {
  158. const pageShow = JSON.parse(sp.page_show);
  159. if (pageShow.openChangeProject) {
  160. auditChangeProjects.push(cp);
  161. }
  162. }
  163. }
  164. // 获取待审批的变更申请
  165. const auditChangeApplys = [];
  166. const changeApplys = await ctx.service.changeApplyAudit.getAuditChangeApplyByWap(ctx.session.sessionUser.accountId);
  167. for (const ca of changeApplys) {
  168. let sp = null;
  169. if (ca.spid) {
  170. if (ctx.helper._.findIndex(subProjects, { id: ca.spid }) !== -1) {
  171. sp = ctx.helper._.find(subProjects, { id: ca.spid });
  172. } else {
  173. sp = await ctx.service.subProject.getDataById(ca.spid);
  174. subProjects.push(sp);
  175. }
  176. }
  177. if (sp) {
  178. const pageShow = JSON.parse(sp.page_show);
  179. if (pageShow.openChangeApply) {
  180. auditChangeApplys.push(ca);
  181. }
  182. }
  183. }
  184. // 获取待审批的变更方案
  185. const auditChangePlans = [];
  186. const changePlans = await ctx.service.changePlanAudit.getAuditChangePlanByWap(ctx.session.sessionUser.accountId);
  187. for (const cp of changePlans) {
  188. let sp = null;
  189. if (cp.spid) {
  190. if (ctx.helper._.findIndex(subProjects, { id: cp.spid }) !== -1) {
  191. sp = ctx.helper._.find(subProjects, { id: cp.spid });
  192. } else {
  193. sp = await ctx.service.subProject.getDataById(cp.spid);
  194. subProjects.push(sp);
  195. }
  196. }
  197. if (sp) {
  198. const pageShow = JSON.parse(sp.page_show);
  199. if (pageShow.openChangePlan) {
  200. auditChangePlans.push(cp);
  201. }
  202. } else {
  203. auditChangePlans.push(cp);
  204. }
  205. }
  206. // 获取待审批的台账修订
  207. const auditRevise = await ctx.service.reviseAudit.getAuditReviseByWap(ctx.session.sessionUser.accountId);
  208. for (const revise of auditRevise) {
  209. const yb_audit = await ctx.service.projectAccount.getAccountInfoById(revise.audit_id);
  210. revise.yb_name = yb_audit.name;
  211. }
  212. // 获取待审批的预付款
  213. const auditAdvance = await ctx.service.advanceAudit.getAuditAdvanceByWap(ctx.session.sessionUser.accountId);
  214. const materialList = await ctx.service.materialAudit.getAuditMaterialByWap(ctx.session.sessionUser.accountId);
  215. const auditMaterials = [];
  216. for (const audit of materialList) {
  217. audit.decimal = audit.decimal ? JSON.parse(audit.decimal) : materialConst.decimal;
  218. let sp = null;
  219. if (audit.spid) {
  220. if (ctx.helper._.findIndex(subProjects, { id: audit.spid }) !== -1) {
  221. sp = ctx.helper._.find(subProjects, { id: audit.spid });
  222. } else {
  223. sp = await ctx.service.subProject.getDataById(audit.spid);
  224. subProjects.push(sp);
  225. }
  226. }
  227. if (sp) {
  228. const pageShow = JSON.parse(sp.page_show);
  229. if (pageShow.openMaterial) {
  230. auditMaterials.push(audit);
  231. }
  232. }
  233. }
  234. const renderData = {
  235. auditStages,
  236. auditChanges,
  237. auditChangeProjects,
  238. auditChangeApplys,
  239. auditChangePlans,
  240. auditMaterials,
  241. auditRevise,
  242. auditAdvance,
  243. changeConst,
  244. advanceConst,
  245. tpUnit: 2,
  246. };
  247. await ctx.render('wap/dashboard.ejs', renderData);
  248. }
  249. async subproj(ctx) {
  250. try {
  251. const renderData = {
  252. jsFiles: this.app.jsFiles.common.concat(this.app.jsFiles.subProject.wap),
  253. };
  254. renderData.projectList = await ctx.service.subProject.getSubProject(ctx.session.sessionProject.id, ctx.session.sessionUser.accountId, ctx.session.sessionUser.is_admin);
  255. renderData.tenderList = await ctx.service.tender.getManageTenderList(ctx.session.sessionProject.id);
  256. await ctx.render('wap/sub_proj.ejs', renderData);
  257. } catch (err) {
  258. ctx.log(err);
  259. ctx.session.postError = err.toString();
  260. ctx.redirect('/wap/dashboard');
  261. }
  262. }
  263. /**
  264. * 标段列表页
  265. *
  266. * @param {Object} ctx - egg全局变量
  267. * @return {void}
  268. */
  269. async list(ctx) {
  270. try {
  271. // 获取用户新建标段权利
  272. const accountInfo = await this.ctx.service.projectAccount.getDataById(ctx.session.sessionUser.accountId);
  273. const userPermission = accountInfo !== undefined && accountInfo.permission !== '' ? JSON.parse(accountInfo.permission) : null;
  274. const tenderList = await this.ctx.service.tender.getBuildList('', userPermission);
  275. for (const t of tenderList) {
  276. await this.ctx.service.tenderCache.loadTenderCache(t, this.ctx.session.sessionUser.accountId);
  277. }
  278. const categoryData = await this.ctx.service.category.getAllCategory(ctx.subProject);
  279. const valuations = await this.ctx.service.valuation.getProjectValidValuation(this.ctx.session.sessionProject.id);
  280. const renderData = {
  281. tenderList,
  282. categoryData,
  283. auditConst,
  284. userPermission,
  285. valuations,
  286. uid: this.ctx.session.sessionUser.accountId,
  287. pid: this.ctx.session.sessionProject.id,
  288. };
  289. await ctx.render('wap/list.ejs', renderData);
  290. } catch (err) {
  291. this.log(err);
  292. this.ctx.redirect('/wap/dashboard');
  293. }
  294. }
  295. /**
  296. * 标段详细页
  297. *
  298. * @param {Object} ctx - egg全局变量
  299. * @return {void}
  300. */
  301. async tender(ctx) {
  302. try {
  303. const tender = ctx.tender.data;
  304. if (tender.user_id === this.ctx.session.sessionUser.accountId && (
  305. tender.ledger_status === auditConst.ledger.status.checkNo || tender.ledger_status === auditConst.ledger.status.uncheck)) {
  306. const sum = await this.ctx.service.ledger.addUp({tender_id: tender.id/*, is_leaf: true*/});
  307. tender.total_price = sum.total_price;
  308. tender.deal_tp = sum.deal_tp;
  309. }
  310. const [change_tp, change_p_tp, change_n_tp, change_valuation_tp, change_unvaluation_tp] = await ctx.service.change.getChangeTp(ctx.tender.id);
  311. tender.change_tp = change_tp;
  312. tender.change_p_tp = change_p_tp;
  313. tender.change_n_tp = change_n_tp;
  314. tender.change_valuation_tp = change_valuation_tp;
  315. tender.change_unvaluation_tp = change_unvaluation_tp;
  316. const stages = await ctx.service.stage.getValidStages(ctx.tender.id);
  317. const lastStage = stages.length > 0 ? stages[0] : null; //await ctx.service.stage.getLastestStage(ctx.tender.id);
  318. if (lastStage) {
  319. await this.ctx.service.stage.checkStageGatherData(lastStage);
  320. tender.gather_tp = ctx.helper.sum([lastStage.contract_tp, lastStage.qc_tp, lastStage.pc_tp]);
  321. tender.end_contract_tp = ctx.helper.sum([lastStage.contract_tp, lastStage.pre_contract_tp, lastStage.contract_pc_tp]);
  322. tender.end_qc_tp = ctx.helper.sum([lastStage.qc_tp, lastStage.pre_qc_tp, lastStage.qc_pc_tp]);
  323. tender.pre_gather_tp = ctx.helper.add(lastStage.pre_contract_tp, lastStage.pre_qc_tp);
  324. tender.end_gather_tp = ctx.helper.add(tender.gather_tp, tender.pre_gather_tp);
  325. tender.yf_tp = lastStage.yf_tp;
  326. tender.qc_ratio = ctx.helper.mul(ctx.helper.div(tender.end_qc_tp, ctx.tender.info.deal_param.contractPrice, 2), 100);
  327. tender.sum = ctx.helper.add(tender.total_price, tender.change_tp);
  328. tender.pre_ratio = ctx.helper.mul(ctx.helper.div(tender.pre_gather_tp, tender.sum, 2), 100);
  329. tender.cur_ratio = ctx.helper.mul(ctx.helper.div(tender.gather_tp, tender.sum, 2), 100);
  330. tender.other_tp = ctx.helper.sub(ctx.helper.sub(tender.sum, tender.pre_gather_tp), tender.gather_tp);
  331. tender.other_ratio = Math.max(0, 100 - tender.pre_ratio - tender.cur_ratio);
  332. }
  333. const monthProgress = [];
  334. for (const s of stages) {
  335. if (s.s_time) {
  336. let progress = monthProgress.find(function(x) {
  337. return x.month === s.s_time;
  338. });
  339. if (!progress) {
  340. progress = { month: s.s_time };
  341. monthProgress.push(progress);
  342. }
  343. progress.tp = ctx.helper.add(ctx.helper.add(progress.tp, s.contract_tp), s.qc_tp);
  344. }
  345. }
  346. monthProgress.sort(function(x, y) {
  347. return Date.parse(x.month) - Date.parse(y.month);
  348. });
  349. let sum = 0;
  350. for (const p of monthProgress) {
  351. p.ratio = ctx.helper.mul(ctx.helper.div(p.tp, tender.sum, 4), 100);
  352. sum = ctx.helper.add(sum, p.tp);
  353. p.end_tp = sum;
  354. p.end_ratio = ctx.helper.mul(ctx.helper.div(p.end_tp, tender.sum, 4), 100);
  355. }
  356. // 台账修订列表
  357. const revises = await ctx.service.ledgerRevise.getReviseList(ctx.tender.id);
  358. for (const lr of revises) {
  359. if (lr.valid) {
  360. lr.curAuditor = await ctx.service.reviseAudit.getAuditorByStatus(lr.id, lr.status, lr.times);
  361. }
  362. }
  363. // 预付款期数获取
  364. const advanceList = [];
  365. for (const t of advanceConst.typeCol) {
  366. const advance = await ctx.service.advance.getLastestAdvance(ctx.tender.id, t.type, true);
  367. advanceList.push(advance);
  368. }
  369. // 材料调差
  370. const materials = await ctx.service.material.getValidMaterials(ctx.tender.id);
  371. let openMaterialTax = ctx.subProject.page_show.openMaterialTax;
  372. const tenderMsg = await ctx.service.tender.getTender(ctx.tender.id, ['material_col_show']);
  373. const material_col_show = tenderMsg.material_col_show ? JSON.parse(tenderMsg.material_col_show) : ctx.helper._.cloneDeep(tenderConst.materialColShow);
  374. let allMaterialTax = true;
  375. for (const s of materials) {
  376. if (!s.final_auditor_str || s.status !== auditConst.material.status.checked) {
  377. // 根据期状态返回展示用户
  378. s.curAuditors = await ctx.service.materialAudit.getAuditorsByStatus(s.id, s.status, s.times);
  379. if (s.status === auditConst.material.status.checked && s.curAuditors.length > 0) {
  380. const final_auditor_str = (s.curAuditors[0].audit_type === auditType.key.common)
  381. ? `${s.curAuditors[0].name}${(s.curAuditors[0].role ? '-' + s.curAuditors[0].role : '')}`
  382. : ctx.helper.transFormToChinese(s.curAuditors[0].audit_order) + '审';
  383. await ctx.service.material.defaultUpdate({ id: s.id, final_auditor_str });
  384. }
  385. }
  386. if (allMaterialTax && s.material_tax === 0) {
  387. allMaterialTax = false;
  388. }
  389. if (!openMaterialTax && s.material_tax === 1) {
  390. openMaterialTax = 1;
  391. }
  392. s.decimal = s.decimal ? JSON.parse(s.decimal) : materialConst.decimal;
  393. }
  394. const renderData = {
  395. tender,
  396. stages,
  397. revises,
  398. advanceList,
  399. materials,
  400. openMaterialTax,
  401. allMaterialTax,
  402. materialColShow: material_col_show,
  403. auditConst: auditConst.stage,
  404. auditReviseConst: auditConst.revise,
  405. auditMaterialConst: auditConst.material,
  406. advanceConst,
  407. tpUnit: ctx.tender.info.decimal.tp,
  408. monthProgress,
  409. stagesEcharts: JSON.parse(JSON.stringify(stages)).reverse(),
  410. auditType: auditConst.auditType,
  411. };
  412. if (stages.length > 0) {
  413. for (const s of stages) {
  414. // s.curAuditor = null;
  415. // 根据期状态返回展示用户
  416. s.curAuditors = await ctx.service.stageAudit.getAuditorsByStatus(s.id, s.status, s.times);
  417. if (s.status === auditConst.stage.status.checkNoPre) {
  418. s.curAuditors2 = await ctx.service.stageAudit.getAuditorsByStatus(s.id, auditConst.stage.status.checking);
  419. }
  420. }
  421. renderData.stage = stages[0];
  422. const times = renderData.stage.status === auditConst.stage.status.checkNo ? renderData.stage.times - 1 : renderData.stage.times;
  423. renderData.stage.user = await ctx.service.projectAccount.getAccountInfoById(renderData.stage.user_id);
  424. renderData.stage.auditors = await ctx.service.stageAudit.getAuditors(renderData.stage.id, times);
  425. // 获取审批流程中左边列表
  426. renderData.stage.auditors2 = await ctx.service.stageAudit.getAuditGroupByList(renderData.stage.id, times);
  427. }
  428. await ctx.render('wap/tender.ejs', renderData);
  429. } catch (err) {
  430. this.log(err);
  431. ctx.redirect('/wap/sp/' + ctx.subProject.id + '/list');
  432. }
  433. }
  434. /**
  435. * 期审批详细页
  436. *
  437. * @param {Object} ctx - egg全局变量
  438. * @return {void}
  439. */
  440. async stage(ctx) {
  441. try {
  442. const tender = ctx.tender.data;
  443. // const stages = await ctx.service.stage.getValidStages(ctx.tender.id);
  444. // const lastStage = stages.length > 0 ? stages[0] : null;
  445. // if (lastStage) {
  446. // await this.ctx.service.stage.checkStageGatherData(lastStage);
  447. // }
  448. const stage = ctx.stage;
  449. if (stage) {
  450. if (stage.status !== auditConst.stage.status.checked) await this.ctx.service.stage.checkStageGatherData(stage);
  451. stage.tp = this.ctx.helper.sum([stage.contract_tp, stage.qc_tp, stage.pc_tp]);
  452. stage.pre_tp = this.ctx.helper.add(stage.pre_contract_tp, stage.pre_qc_tp);
  453. stage.end_tp = this.ctx.helper.add(stage.pre_tp, stage.tp);
  454. }
  455. await ctx.service.stage.loadStageAuditViewData(stage);
  456. const renderData = {
  457. moment,
  458. tender,
  459. stage,
  460. auditConst: auditConst.stage,
  461. auditType,
  462. };
  463. // const times = renderData.stage.status === auditConst.stage.status.checkNo ? renderData.stage.times - 1 : renderData.stage.times;
  464. // renderData.stage.user = await ctx.service.projectAccount.getAccountInfoById(renderData.stage.user_id);
  465. // renderData.stage.auditors = await ctx.service.stageAudit.getAuditors(renderData.stage.id, times);
  466. // // 获取审批流程中左边列表
  467. // renderData.stage.auditors2 = await ctx.service.stageAudit.getAuditGroupByList(renderData.stage.id, times);
  468. renderData.stage.lastAuditors = await ctx.service.stageAudit.getAuditorsByStatus(stage.id, stage.status, stage.times);
  469. await ctx.render('wap/shenpi_stage.ejs', renderData);
  470. } catch (err) {
  471. this.log(err);
  472. ctx.redirect('/wap/sp/' + ctx.subProject.id + '/list');
  473. }
  474. }
  475. /**
  476. * 调差期审批详细页
  477. *
  478. * @param {Object} ctx - egg全局变量
  479. * @return {void}
  480. */
  481. async material(ctx) {
  482. try {
  483. const tender = ctx.tender.data;
  484. const material = ctx.material;
  485. await ctx.service.material.loadMaterialAuditViewData(material);
  486. const renderData = {
  487. moment,
  488. tender,
  489. material,
  490. auditConst: auditConst.material,
  491. auditType,
  492. };
  493. renderData.material.m_tax_tp = renderData.material.m_tax_tp ? renderData.material.m_tax_tp : renderData.material.m_tp;
  494. renderData.pre_tp_hs = await ctx.service.material.getPreTpHs(ctx.tender.id, ctx.material.order, ctx.material.decimal.tp);
  495. renderData.ex_pre_tp_hs = await ctx.service.material.getExPreTpHs(ctx.tender.id, ctx.material.order, ctx.material.decimal.tp);
  496. renderData.months = ctx.material.months ? ctx.material.months.split(',') : [];
  497. renderData.material.lastAuditors = await ctx.service.materialAudit.getAuditorsByStatus(material.id, material.status, material.times);
  498. renderData.old_had_tax = await ctx.service.material.getOldMaterialTax(ctx.tender.id, ctx.material.order);
  499. await ctx.render('wap/shenpi_material.ejs', renderData);
  500. } catch (err) {
  501. this.log(err);
  502. ctx.redirect('/wap/sp/' + ctx.subProject.id + '/list');
  503. }
  504. }
  505. /**
  506. * 工程变更列表页
  507. *
  508. * @param {Object} ctx - egg全局变量
  509. * @return {void}
  510. */
  511. async changeIndex(ctx) {
  512. try {
  513. // 变更令列表
  514. const changes = await ctx.service.change.getListByStatus(ctx.tender.id, 0, 0);
  515. for (const c of changes) {
  516. c.showApprovalBtn = false;
  517. c.curAuditors = await ctx.service.changeAudit.getAuditorsByStatus(c.cid, c.status, c.times);
  518. if (c.status === auditConst.change.status.checkNoPre) {
  519. c.curAuditors2 = await ctx.service.changeAudit.getAuditorsByStatus(c.cid, auditConst.change.status.checking, c.times);
  520. const curAudit = c.curAuditors2.find(function(x) {
  521. return x.uid === ctx.session.sessionUser.accountId;
  522. });
  523. if (curAudit && curAudit.status === auditConst.change.status.checking) {
  524. c.showApprovalBtn = true;
  525. }
  526. } else {
  527. const curAudit = c.curAuditors.find(function(x) {
  528. return x.uid === ctx.session.sessionUser.accountId;
  529. });
  530. if (curAudit && curAudit.status === auditConst.change.status.checking) {
  531. c.showApprovalBtn = true;
  532. }
  533. }
  534. }
  535. // 变更立项列表
  536. let changeProjects = [];
  537. if (ctx.subProject.page_show.openChangeProject) {
  538. changeProjects = await ctx.service.changeProject.getListByStatus(ctx.tender.id, 0, 0);
  539. for (const c of changeProjects) {
  540. c.showApprovalBtn = false;
  541. c.curAuditors = await ctx.service.changeProjectAudit.getAuditorsByStatus(c.id, c.status, c.times);
  542. const curAudit = c.curAuditors.find(function(x) {
  543. return x.aid === ctx.session.sessionUser.accountId;
  544. });
  545. if (curAudit && curAudit.status === auditConst.changeProject.status.checking) {
  546. c.showApprovalBtn = true;
  547. }
  548. }
  549. }
  550. // 变更申请列表
  551. let changeApplys = [];
  552. if (ctx.subProject.page_show.openChangeApply) {
  553. changeApplys = await ctx.service.changeApply.getListByStatus(ctx.tender.id, 0, 0);
  554. for (const c of changeApplys) {
  555. c.showApprovalBtn = false;
  556. c.curAuditors = await ctx.service.changeApplyAudit.getAuditorsByStatus(c.id, c.status, c.times);
  557. const curAudit = c.curAuditors.find(function(x) {
  558. return x.aid === ctx.session.sessionUser.accountId;
  559. });
  560. if (curAudit && curAudit.status === auditConst.changeApply.status.checking) {
  561. c.showApprovalBtn = true;
  562. }
  563. }
  564. }
  565. // 变更方案列表
  566. let changePlans = [];
  567. if (ctx.subProject.page_show.openChangePlan) {
  568. changePlans = await ctx.service.changePlan.getListByStatus(ctx.tender.id, 0, 0);
  569. for (const c of changePlans) {
  570. c.showApprovalBtn = false;
  571. c.curAuditors = await ctx.service.changePlanAudit.getAuditorsByStatus(c.id, c.status, c.times);
  572. const curAudit = c.curAuditors.find(function(x) {
  573. return x.aid === ctx.session.sessionUser.accountId;
  574. });
  575. if (curAudit && curAudit.status === auditConst.changePlan.status.checking) {
  576. c.showApprovalBtn = true;
  577. }
  578. }
  579. }
  580. const renderData = {
  581. tender: ctx.tender,
  582. changes,
  583. changeProjects,
  584. changeApplys,
  585. changePlans,
  586. auditChangeConst: auditConst.change,
  587. auditChangeProjectConst: auditConst.changeProject,
  588. auditChangeApplyConst: auditConst.changeApply,
  589. auditChangePlanConst: auditConst.changePlan,
  590. changeConst,
  591. tpUnit: ctx.tender.info.decimal.tp,
  592. auditType: auditConst.auditType,
  593. };
  594. await ctx.render('wap/shenpi_change_index.ejs', renderData);
  595. } catch (err) {
  596. this.log(err);
  597. ctx.redirect('/wap/sp/' + ctx.subProject.id + '/list');
  598. }
  599. }
  600. /**
  601. * 变更审批详细页
  602. *
  603. * @param {Object} ctx - egg全局变量
  604. * @return {void}
  605. */
  606. async change(ctx) {
  607. try {
  608. const tender = ctx.tender.data;
  609. const change = ctx.change;
  610. const times = change.status !== auditConst.change.status.checkNo && change.status !== auditConst.change.status.revise ? change.times : change.times - 1;
  611. const auditList = await ctx.service.changeAudit.getListOrderByTimes(change.cid, times);
  612. const auditGroupList = await ctx.service.changeAudit.getListGroupByTimes(change.cid, times);
  613. await ctx.service.change.loadChangeAuditViewData(ctx.change);
  614. const renderData = {
  615. moment,
  616. tender,
  617. change,
  618. auditList,
  619. auditGroupList,
  620. auditConst: auditConst.change,
  621. changeConst,
  622. tpUnit: ctx.tender.info.decimal.tp,
  623. auditType,
  624. };
  625. await ctx.render('wap/shenpi_change.ejs', renderData);
  626. } catch (err) {
  627. this.log(err);
  628. ctx.redirect('/wap/sp/' + ctx.subProject.id + '/list');
  629. }
  630. }
  631. /**
  632. * 变更立项审批详细页
  633. *
  634. * @param {Object} ctx - egg全局变量
  635. * @return {void}
  636. */
  637. async changeProject(ctx) {
  638. try {
  639. const tender = ctx.tender.data;
  640. const change = ctx.change;
  641. await ctx.service.changeProject.loadChangeAuditViewData(ctx.change);
  642. const renderData = {
  643. moment,
  644. tender,
  645. change,
  646. auditConst: auditConst.changeProject,
  647. changeConst,
  648. tpUnit: ctx.tender.info.decimal.tp,
  649. auditType,
  650. };
  651. await ctx.render('wap/shenpi_change_project.ejs', renderData);
  652. } catch (err) {
  653. this.log(err);
  654. ctx.redirect('/wap/sp/' + ctx.subProject.id + '/list');
  655. }
  656. }
  657. /**
  658. * 变更申请审批详细页
  659. *
  660. * @param {Object} ctx - egg全局变量
  661. * @return {void}
  662. */
  663. async changeApply(ctx) {
  664. try {
  665. const tender = ctx.tender.data;
  666. const change = ctx.change;
  667. await ctx.service.changeApply.loadChangeAuditViewData(ctx.change);
  668. const renderData = {
  669. moment,
  670. tender,
  671. change,
  672. auditConst: auditConst.changeApply,
  673. changeConst,
  674. tpUnit: ctx.tender.info.decimal.tp,
  675. auditType,
  676. };
  677. await ctx.render('wap/shenpi_change_apply.ejs', renderData);
  678. } catch (err) {
  679. this.log(err);
  680. ctx.redirect('/wap/sp/' + ctx.subProject.id + '/list');
  681. }
  682. }
  683. /**
  684. * 变更方案审批详细页
  685. *
  686. * @param {Object} ctx - egg全局变量
  687. * @return {void}
  688. */
  689. async changePlan(ctx) {
  690. try {
  691. const tender = ctx.tender.data;
  692. const change = ctx.change;
  693. await ctx.service.changePlan.loadChangeAuditViewData(ctx.change);
  694. const renderData = {
  695. moment,
  696. tender,
  697. change,
  698. auditConst: auditConst.changeApply,
  699. changeConst,
  700. tpUnit: ctx.tender.info.decimal.tp,
  701. auditType,
  702. };
  703. await ctx.render('wap/shenpi_change_plan.ejs', renderData);
  704. } catch (err) {
  705. this.log(err);
  706. ctx.redirect('/wap/sp/' + ctx.subProject.id + '/list');
  707. }
  708. }
  709. /**
  710. * 修订审批详细页
  711. *
  712. * @param {Object} ctx - egg全局变量
  713. * @return {void}
  714. */
  715. async revise(ctx) {
  716. try {
  717. const tender = ctx.tender.data;
  718. const revise = await ctx.service.ledgerRevise.getDataByCondition({ id: ctx.params.rid });
  719. revise.user = await ctx.service.projectAccount.getAccountInfoById(revise.uid);
  720. const times = revise.status === auditConst.revise.status.checkNo ? revise.times - 1 : revise.times;
  721. revise.curAuditor = await ctx.service.reviseAudit.getAuditorByStatus(revise.id, revise.status, times);
  722. revise.auditors = await ctx.service.reviseAudit.getAuditors(revise.id, times);
  723. console.log(times, revise.auditors);
  724. const renderData = {
  725. tender,
  726. revise,
  727. auditConst: auditConst.revise,
  728. };
  729. await ctx.render('wap/shenpi_revise.ejs', renderData);
  730. } catch (err) {
  731. this.log(err);
  732. ctx.redirect('/wap/sp/' + ctx.subProject.id + '/list');
  733. }
  734. }
  735. /**
  736. * 预付款列表页
  737. *
  738. * @param {Object} ctx - egg全局变量
  739. * @return {void}
  740. */
  741. async advance(ctx) {
  742. try {
  743. const tender = ctx.tender.data;
  744. const { decimal } = ctx.tender.info;
  745. this.decimal = decimal.pay ? decimal.payTp : decimal.tp;
  746. const advancePayTotalList = [];
  747. const advanceList = [];
  748. for (const t of advanceConst.typeCol) {
  749. const advancePayTotal = ctx.tender.info.deal_param[t.key + 'Advance'];
  750. advancePayTotalList.push(advancePayTotal);
  751. const advances = await ctx.service.advance.getAdvanceList(ctx.tender.id, t.type, this.decimal, advancePayTotal);
  752. advanceList.push(advances);
  753. }
  754. const renderData = {
  755. tender,
  756. advancePayTotalList,
  757. advanceList,
  758. auditConst: auditConst.advance,
  759. advanceConst,
  760. };
  761. await ctx.render('wap/shenpi_advance.ejs', renderData);
  762. } catch (err) {
  763. this.log(err);
  764. ctx.redirect('/wap/sp/' + ctx.subProject.id + '/list');
  765. }
  766. }
  767. /**
  768. * 预付款详情页 GET
  769. * @param {Object} ctx 全局上下文
  770. */
  771. async advanceDetail(ctx) {
  772. try {
  773. const tender = ctx.tender.data;
  774. ctx.advance.advancePayTotal = ctx.tender.info.deal_param[ advanceConst.typeCol[ctx.advance.type].key + 'Advance'];
  775. const times = ctx.advance.status === auditConst.advance.status.checkNo ? ctx.advance.times - 1 : ctx.advance.times;
  776. if (ctx.advance.status === auditConst.advance.status.checkNo) {
  777. ctx.advance.curAuditor = await ctx.service.advanceAudit.getAuditorByStatus(ctx.advance.id, ctx.advance.status, times);
  778. ctx.advance.auditors = await ctx.service.advanceAudit.getAuditors(ctx.advance.id, times);
  779. }
  780. // 获取审批流程中左边列表
  781. ctx.advance.auditors2 = await ctx.service.advanceAudit.getAuditGroupByList(ctx.advance.id, times);
  782. const renderData = {
  783. tender,
  784. advance: ctx.advance,
  785. auditConst: auditConst.advance,
  786. advanceConst,
  787. };
  788. await ctx.render('wap/shenpi_advance_detail.ejs', renderData);
  789. } catch (error) {
  790. this.log(error);
  791. ctx.redirect('/wap/tender/' + ctx.tender.id + '/advance');
  792. }
  793. }
  794. /**
  795. * 变更令审批
  796. * @param {Object} ctx - egg全局变量
  797. * @return {void}
  798. */
  799. async changeApproval(ctx) {
  800. try {
  801. const cid = ctx.request.body.change_id;
  802. const changeData = await ctx.service.change.getDataByCondition({ cid });
  803. if (!changeData) {
  804. throw '变更令数据错误';
  805. }
  806. // 判断是否到你审批,如果不是则无法审批
  807. const curAuditor = await ctx.service.changeAudit.getCurAuditors(changeData.cid, changeData.times);
  808. if (!curAuditor || (curAuditor && ctx.helper._.findIndex(curAuditor, { uid: ctx.session.sessionUser.accountId }) === -1)) {
  809. throw '该变更令当前您无权操作';
  810. }
  811. const readySettle = await ctx.service.settle.getReadySettle(changeData.tid);
  812. if (readySettle && readySettle.settle_order !== ctx.tender.data.settle_order) {
  813. throw '结算数据发生变化,请刷新页面再提交';
  814. }
  815. const status = parseInt(ctx.request.body.status);
  816. const pid = this.ctx.session.sessionProject.id;
  817. let result = false;
  818. switch (status) {
  819. case 3:// 审批通过
  820. result = await ctx.service.change.approvalSuccess(pid, ctx.request.body, changeData);
  821. break;
  822. // case 4:// 审批终止
  823. // result = await ctx.service.change.approvalStop(ctx.request.body);
  824. // break;
  825. case 5:// 审批退回到原报人
  826. result = await ctx.service.change.approvalCheckNo(pid, ctx.request.body, changeData);
  827. break;
  828. case 6:// 审批退回到上一个审批人
  829. result = await ctx.service.change.approvalCheckNoPre(pid, ctx.request.body, changeData);
  830. break;
  831. default:break;
  832. }
  833. if (!result) {
  834. throw '审批失败';
  835. }
  836. ctx.redirect(ctx.request.header.referer);
  837. } catch (err) {
  838. console.log(err);
  839. ctx.redirect(ctx.request.header.referer);
  840. }
  841. }
  842. /**
  843. * 收方单附件上传页
  844. * @param {Object} ctx - egg全局变量
  845. * @return {void}
  846. */
  847. async shoufangUpload(ctx) {
  848. try {
  849. const tid = parseInt(ctx.query.tid) || 0;
  850. const order = parseInt(ctx.query.order) || 0;
  851. const sfid = parseInt(ctx.query.sfid) || 0;
  852. if (!tid || !order || !sfid) {
  853. throw '参数有误';
  854. }
  855. const tender = await ctx.service.tender.getDataById(tid);
  856. if (!tender) {
  857. throw '该标段不存在';
  858. }
  859. const sfInfo = await ctx.service.stageShoufang.getDataByCondition({ id: sfid, tid, order });
  860. if (!sfInfo) {
  861. throw '该收方单不存在';
  862. }
  863. // 查找对应的台账或计量单元名称
  864. const ledger = await ctx.service.ledger.getData(tid);
  865. const ledgerInfo = ctx.helper._.find(ledger, { id: sfInfo.lid });
  866. let name = ledgerInfo.b_code;
  867. if (sfInfo.pid) {
  868. const pos = await ctx.service.pos.getPosData({ tid });
  869. const posInfo = ctx.helper._.find(pos, { lid: sfInfo.lid, id: sfInfo.pid });
  870. name += ' / ' + posInfo.name;
  871. }
  872. const renderData = {
  873. tender,
  874. order,
  875. name,
  876. sfid,
  877. whiteList: this.ctx.app.config.multipart.whitelist,
  878. };
  879. await ctx.render('wap/shoufangupload.ejs', renderData);
  880. } catch (error) {
  881. this.log(error);
  882. ctx.redirect('/wap/login');
  883. }
  884. }
  885. /**
  886. * 上传附件
  887. * @param {Object} ctx - egg全局变量
  888. * @return {void}
  889. */
  890. async shoufangUpFile(ctx) {
  891. const responseData = {
  892. err: 0,
  893. msg: '',
  894. data: [],
  895. };
  896. let stream;
  897. try {
  898. const parts = ctx.multipart({ autoFields: true });
  899. const files = [];
  900. let index = 0;
  901. while ((stream = await parts()) !== undefined) {
  902. // 判断是否存在
  903. const sfInfo = await ctx.service.stageShoufang.getDataById(parts.field.sfid);
  904. if (!sfInfo) {
  905. throw '该清单 / 计量单元下不存在收方单';
  906. }
  907. // 判断用户是否选择上传文件
  908. if (!stream.filename) {
  909. throw '请选择上传的文件!';
  910. }
  911. // const dirName = 'app/public/upload/stage/' + moment().format('YYYYMMDD');
  912. // 判断文件夹是否存在,不存在则直接创建文件夹
  913. // if (!fs.existsSync(path.join(this.app.baseDir, dirName))) {
  914. // await fs.mkdirSync(path.join(this.app.baseDir, dirName));
  915. // }
  916. const fileInfo = path.parse(stream.filename);
  917. const now_time = new Date();
  918. const create_time = Date.parse(now_time) / 1000;
  919. const filepath = `app/public/upload/${sfInfo.tid}/stage/shoufang/fujian_${create_time + index.toString() + fileInfo.ext}`;
  920. // await ctx.helper.saveStreamFile(stream, path.resolve(this.app.baseDir, filepath));
  921. await ctx.app.fujianOss.put(ctx.app.config.fujianOssFolder + filepath, stream);
  922. // console.log(await fs.existsSync(path.resolve(this.app.baseDir, 'app', filepath)));
  923. // const fileInfo = path.parse(stream.filename);
  924. // const fileName = 'stage' + create_time + '_' + index + fileInfo.ext;
  925. // 保存文件
  926. // await ctx.helper.saveStreamFile(stream, path.resolve(this.app.baseDir, dirName, fileName));
  927. if (stream) {
  928. await sendToWormhole(stream);
  929. }
  930. // 保存数据到att表
  931. const fileData = {
  932. tid: sfInfo.tid,
  933. sid: sfInfo.sid,
  934. sfid: sfInfo.id,
  935. in_time: now_time,
  936. filename: fileInfo.name,
  937. fileext: fileInfo.ext,
  938. filesize: Array.isArray(parts.field.size) ? parts.field.size[index] : parts.field.size,
  939. filepath,
  940. };
  941. // if (ctx.reUploadPermission) {
  942. // fileData.re_upload = 1;
  943. // }
  944. const result = await ctx.service.stageShoufangAtt.save(fileData);
  945. if (!result) {
  946. throw '导入数据库保存失败';
  947. }
  948. const attData = await ctx.service.stageShoufangAtt.getDataByFid(result.insertId);
  949. attData.in_time = moment(create_time * 1000).format('YYYY-MM-DD');
  950. files.length !== 0 ? files.unshift(attData) : files.push(attData);
  951. ++index;
  952. }
  953. responseData.data = files;
  954. } catch (err) {
  955. this.log(err);
  956. // 失败需要消耗掉stream 以防卡死
  957. if (stream) {
  958. await sendToWormhole(stream);
  959. }
  960. this.setMessage(err.toString(), this.messageType.ERROR);
  961. responseData.err = 1;
  962. responseData.msg = err.toString();
  963. }
  964. ctx.body = responseData;
  965. }
  966. /**
  967. * 删除附件
  968. * @param {Object} ctx - egg全局变量
  969. * @return {void}
  970. */
  971. async shoufangDeleteFile(ctx) {
  972. const responseData = {
  973. err: 0,
  974. msg: '',
  975. data: '',
  976. };
  977. try {
  978. const data = JSON.parse(ctx.request.body.data);
  979. const fileInfo = await ctx.service.stageShoufangAtt.getDataById(data.id);
  980. if (!fileInfo || !Object.keys(fileInfo).length) {
  981. throw '该文件不存在';
  982. }
  983. if (fileInfo !== undefined && fileInfo !== '') {
  984. // 先删除文件
  985. // await fs.unlinkSync(path.join(this.app.baseDir, fileInfo.filepath));
  986. await ctx.app.fujianOss.delete(ctx.app.config.fujianOssFolder + fileInfo.filepath);
  987. // 再删除数据库
  988. await ctx.service.stageShoufangAtt.deleteById(data.id);
  989. responseData.data = '';
  990. } else {
  991. throw '不存在该文件';
  992. }
  993. } catch (err) {
  994. responseData.err = 1;
  995. responseData.msg = err;
  996. }
  997. ctx.body = responseData;
  998. }
  999. /**
  1000. * 编辑附件
  1001. * @param {Object} ctx - egg全局变量
  1002. * @return {void}
  1003. */
  1004. async shoufangEditFile(ctx) {
  1005. const responseData = {
  1006. err: 0,
  1007. msg: '',
  1008. data: '',
  1009. };
  1010. try {
  1011. const data = JSON.parse(ctx.request.body.data);
  1012. const fileInfo = await ctx.service.stageShoufangAtt.getDataById(data.id);
  1013. if (!fileInfo || !Object.keys(fileInfo).length) {
  1014. throw '该文件不存在';
  1015. }
  1016. await ctx.service.stageShoufangAtt.edit(data);
  1017. } catch (err) {
  1018. responseData.err = 1;
  1019. responseData.msg = err;
  1020. }
  1021. ctx.body = responseData;
  1022. }
  1023. /**
  1024. * 下载附件
  1025. * @param {Object} ctx - egg全局变量
  1026. * @return {void}
  1027. */
  1028. async messageDownloadFile(ctx) {
  1029. const id = ctx.params.fid;
  1030. if (id) {
  1031. try {
  1032. const fileInfo = await ctx.service.messageAtt.getDataById(id);
  1033. if (fileInfo !== undefined && fileInfo !== '') {
  1034. // const fileName = path.join(this.app.baseDir, fileInfo.filepath);
  1035. // 解决中文无法下载问题
  1036. const userAgent = (ctx.request.header['user-agent'] || '').toLowerCase();
  1037. let disposition = '';
  1038. if (userAgent.indexOf('msie') >= 0 || userAgent.indexOf('chrome') >= 0) {
  1039. disposition = 'attachment; filename=' + encodeURIComponent(fileInfo.filename + fileInfo.fileext);
  1040. } else if (userAgent.indexOf('firefox') >= 0) {
  1041. disposition = 'attachment; filename*="utf8\'\'' + encodeURIComponent(fileInfo.filename + fileInfo.fileext) + '"';
  1042. } else {
  1043. /* safari等其他非主流浏览器只能自求多福了 */
  1044. disposition = 'attachment; filename=' + new Buffer(fileInfo.filename + fileInfo.fileext).toString('binary');
  1045. }
  1046. ctx.response.set({
  1047. 'Content-Type': 'application/octet-stream',
  1048. 'Content-Disposition': disposition,
  1049. 'Content-Length': fileInfo.filesize,
  1050. });
  1051. // ctx.body = await fs.createReadStream(fileName);
  1052. ctx.body = await ctx.helper.ossFileGet(fileInfo.filepath);
  1053. } else {
  1054. throw '不存在该文件';
  1055. }
  1056. } catch (err) {
  1057. this.log(err);
  1058. this.setMessage(err.toString(), this.messageType.ERROR);
  1059. }
  1060. }
  1061. }
  1062. /**
  1063. * 下载附件
  1064. * @param {Object} ctx - egg全局变量
  1065. * @return {void}
  1066. */
  1067. async shoufangDownloadFile(ctx) {
  1068. const id = ctx.params.fid;
  1069. if (id) {
  1070. try {
  1071. const fileInfo = await ctx.service.stageShoufangAtt.getDataById(id);
  1072. if (fileInfo !== undefined && fileInfo !== '') {
  1073. // const fileName = path.join(this.app.baseDir, fileInfo.filepath);
  1074. // 解决中文无法下载问题
  1075. const userAgent = (ctx.request.header['user-agent'] || '').toLowerCase();
  1076. let disposition = '';
  1077. if (userAgent.indexOf('msie') >= 0 || userAgent.indexOf('chrome') >= 0) {
  1078. disposition = 'attachment; filename=' + encodeURIComponent(fileInfo.filename + fileInfo.fileext);
  1079. } else if (userAgent.indexOf('firefox') >= 0) {
  1080. disposition = 'attachment; filename*="utf8\'\'' + encodeURIComponent(fileInfo.filename + fileInfo.fileext) + '"';
  1081. } else {
  1082. /* safari等其他非主流浏览器只能自求多福了 */
  1083. disposition = 'attachment; filename=' + new Buffer(fileInfo.filename + fileInfo.fileext).toString('binary');
  1084. }
  1085. ctx.response.set({
  1086. 'Content-Type': 'application/octet-stream',
  1087. 'Content-Disposition': disposition,
  1088. 'Content-Length': fileInfo.filesize,
  1089. });
  1090. // ctx.body = await fs.createReadStream(fileName);
  1091. ctx.body = await ctx.helper.ossFileGet(fileInfo.filepath);
  1092. } else {
  1093. throw '不存在该文件';
  1094. }
  1095. } catch (err) {
  1096. this.log(err);
  1097. this.setMessage(err.toString(), this.messageType.ERROR);
  1098. }
  1099. }
  1100. }
  1101. async msg(ctx) {
  1102. try {
  1103. const msgId = parseInt(ctx.params.id) || 0;
  1104. if (!msgId) {
  1105. throw '参数有误';
  1106. }
  1107. const msgInfo = await ctx.service.message.getDataById(msgId);
  1108. const files = await ctx.service.messageAtt.getAtt(msgId);
  1109. if (!msgInfo) {
  1110. throw '项目通知不存在';
  1111. }
  1112. if (msgInfo && msgInfo.type === 1 && msgInfo.project_id !== ctx.session.sessionProject.id) {
  1113. throw '非该项目通知无权查看';
  1114. }
  1115. if (msgInfo) {
  1116. msgInfo.content = JSON.parse(JSON.stringify(msgInfo.content).replace(/\\r\\n/g, '<br>').replace(/\\"/g, '&#34;').replace(/'/g, '&#39;').replace(/\\t/g, '&#9;'));
  1117. }
  1118. const renderData = {
  1119. msgInfo,
  1120. moment,
  1121. files,
  1122. };
  1123. await ctx.render('wap/msg.ejs', renderData);
  1124. } catch (error) {
  1125. console.log(error);
  1126. this.log(error);
  1127. ctx.redirect('/wap/dashboard');
  1128. }
  1129. }
  1130. async inspection(ctx) {
  1131. const renderData = {
  1132. };
  1133. await ctx.render('wap/inspection.ejs', renderData);
  1134. }
  1135. async inspectionAiAsk(ctx) {
  1136. const responseData = {
  1137. err: 0,
  1138. msg: '',
  1139. data: '',
  1140. };
  1141. try {
  1142. const { user_input, conversationId } = JSON.parse(ctx.request.body.data);
  1143. if (!user_input) {
  1144. throw '参数有误';
  1145. }
  1146. const ai = new AiInspect({
  1147. chatflowId: conversationId,
  1148. });
  1149. const result = await ai.ask(user_input);
  1150. let answerText = result.answer || '';
  1151. let jsonPart = null;
  1152. const jsonMatch = answerText.match(/\{[\s\S]*\}/);
  1153. if (jsonMatch) {
  1154. jsonPart = JSON.parse(jsonMatch[0]);
  1155. answerText = answerText.replace(jsonMatch[0], '').trim();
  1156. }
  1157. responseData.data = {
  1158. answer_text: answerText,
  1159. answer_json: jsonPart,
  1160. conversation_id: result.conversation_id || '',
  1161. };
  1162. } catch (error) {
  1163. responseData.err = 1;
  1164. responseData.msg = error.message ? error.message : error;
  1165. }
  1166. ctx.body = responseData;
  1167. }
  1168. async voiceToken(ctx) {
  1169. const responseData = {
  1170. err: 0,
  1171. msg: '',
  1172. data: '',
  1173. };
  1174. try {
  1175. const token = await nlsToken.getToken();
  1176. responseData.data = token;
  1177. } catch (error) {
  1178. responseData.err = 1;
  1179. responseData.msg = error.message ? error.message : error;
  1180. }
  1181. ctx.body = responseData;
  1182. }
  1183. }
  1184. return WapController;
  1185. };