wechat.js 23 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464
  1. 'use strict';
  2. /**
  3. * 微信模板信息发送相关接口
  4. *
  5. * @author ellisran
  6. * @date 2018/1/25
  7. * @version
  8. */
  9. // const xmlReader = require('xmlreader');
  10. const _ = require('lodash');
  11. const moment = require('moment');
  12. const wxConst = require('../const/wechat_template.js');
  13. const wxWork = require('./wx_work');
  14. class WX {
  15. /**
  16. * 构造函数
  17. *
  18. * @param {Object} ctx - egg全局变量
  19. * @return {void}
  20. */
  21. constructor(ctx) {
  22. this.ctx = ctx;
  23. }
  24. /**
  25. * 发送微信审批通知模板
  26. *
  27. * @param {Array} wx_openid - 发送的微信账号
  28. * @param {String} template - 模板id
  29. * @param {Object} data - 一些模板展示数据
  30. * @return {Boolean} - 发送结果
  31. */
  32. async Send(wx_openid, template, data) {
  33. let flag = false;
  34. try {
  35. // const templateId = template;
  36. let templateId = '';
  37. // const sck = 'https://scn.ink/';
  38. const sck = '';
  39. for (const openid of wx_openid) {
  40. let url = '';
  41. let msgData = '';
  42. let remark = '';
  43. switch (template) {
  44. case wxConst.template.stage :
  45. templateId = wxConst.templateId.stage;
  46. url = this.ctx.protocol + '://' + this.ctx.host + '/wx/url2wap?project=' + data.code + '&url=' + sck + data.wap_url;
  47. msgData = {
  48. first: {
  49. value: '您好,本期计量' + data.tips,
  50. },
  51. keyword1: {
  52. value: data.projectName,
  53. },
  54. keyword2: {
  55. value: data.tenderName,
  56. },
  57. keyword3: {
  58. value: '第' + data.qi + '期',
  59. },
  60. keyword4: {
  61. value: data.status,
  62. },
  63. remark: {
  64. value: '查看审批详情,请登录PC端系统。',
  65. },
  66. };
  67. break;
  68. case wxConst.template.change:
  69. templateId = wxConst.templateId.change;
  70. url = data.wap_url ? this.ctx.protocol + '://' + this.ctx.host + '/wx/url2wap?project=' + data.code + '&url=' + sck + data.wap_url : '';
  71. remark = data.status === wxConst.status.check ? (data.type && _.indexOf(['apply', 'project'], data.type) !== -1 ? '微信暂无法在线审批' : '微信可快速审批,如需进行详细审批') :
  72. (data.status === wxConst.status.success ? '审批已通过,查看审批结果' :
  73. (data.status === wxConst.status.back ? '审批被退回,查看退回结果' : '审批已终止,查看终止结果'));
  74. msgData = {
  75. first: {
  76. value: '您好,' + (data.type ? wxConst.changeType[data.type] : '工程变更申请') + data.tips,
  77. },
  78. keyword1: {
  79. value: data.projectName,
  80. },
  81. keyword2: {
  82. value: data.tenderName,
  83. },
  84. keyword3: {
  85. value: data.c_name,
  86. },
  87. remark: {
  88. value: remark + ',请登录PC端系统。',
  89. },
  90. };
  91. break;
  92. case wxConst.template.ledger:
  93. templateId = wxConst.templateId.ledger;
  94. remark = data.status === wxConst.status.check ? '微信暂无法在线审批' :
  95. (data.status === wxConst.status.success ? '审批已通过,查看审批结果' : '审批被退回,查看退回结果');
  96. msgData = {
  97. first: {
  98. value: '您好,台账' + data.tips,
  99. },
  100. keyword1: {
  101. value: data.projectName,
  102. },
  103. keyword2: {
  104. value: data.tenderName,
  105. },
  106. keyword3: {
  107. value: moment(new Date(data.begin_time)).format('YYYY-MM-DD'),
  108. },
  109. remark: {
  110. value: remark + ',请登录PC端系统。',
  111. },
  112. };
  113. break;
  114. case wxConst.template.revise:
  115. templateId = wxConst.templateId.revise;
  116. url = this.ctx.protocol + '://' + this.ctx.host + '/wx/url2wap?project=' + data.code + '&url=' + sck + data.wap_url;
  117. remark = data.status === wxConst.status.check ? '微信可快速审批,如需进行详细审批' :
  118. (data.status === wxConst.status.success ? '审批已通过,查看审批结果' :
  119. (data.status === wxConst.status.back ? '审批被退回,查看退回结果' : '审批已上报,查看审批结果'));
  120. msgData = {
  121. first: {
  122. value: '您好,台账修订' + data.tips,
  123. },
  124. keyword1: {
  125. value: data.projectName,
  126. },
  127. keyword2: {
  128. value: data.tenderName,
  129. },
  130. keyword3: {
  131. value: moment(new Date(data.begin_time)).format('YYYY-MM-DD'),
  132. },
  133. remark: {
  134. value: remark + ',请登录PC端系统。',
  135. },
  136. };
  137. break;
  138. case wxConst.template.material:
  139. templateId = wxConst.templateId.material;
  140. // url = this.ctx.protocol + '://' + this.ctx.host + '/wx/url2wap?project=' + data.code + '&url=' + sck + data.wap_url;
  141. remark = data.status === wxConst.status.check ? '微信暂无法在线审批' :
  142. (data.status === wxConst.status.success ? '审批已通过,查看审批结果' : '审批被退回,查看退回结果');
  143. msgData = {
  144. first: {
  145. value: '您好,第' + data.qi + '期材料调差申请' + data.tips,
  146. },
  147. keyword1: {
  148. value: data.projectName,
  149. },
  150. keyword2: {
  151. value: data.tenderName,
  152. },
  153. keyword3: {
  154. value: moment(new Date(data.begin_time)).format('YYYY-MM-DD'),
  155. },
  156. keyword4: {
  157. value: data.m_tp ? data.m_tp.toString() : null,
  158. },
  159. keyword5: {
  160. value: data.hs_m_tp ? data.hs_m_tp.toString() : null,
  161. },
  162. remark: {
  163. value: remark + ',请登录PC端系统。',
  164. },
  165. };
  166. break;
  167. case wxConst.template.advance:
  168. templateId = wxConst.templateId.advance;
  169. url = this.ctx.protocol + '://' + this.ctx.host + '/wx/url2wap?project=' + data.code + '&url=' + sck + data.wap_url;
  170. remark = data.status === wxConst.status.check ? '微信可快速审批,如需进行详细审批' :
  171. (data.status === wxConst.status.success ? '审批已通过,查看审批结果' : '审批被退回,查看退回结果');
  172. msgData = {
  173. first: {
  174. value: '您好,预付款申请' + data.tips,
  175. },
  176. keyword1: {
  177. value: data.projectName,
  178. },
  179. keyword2: {
  180. value: data.tenderName,
  181. },
  182. keyword3: {
  183. value: data.qi,
  184. },
  185. keyword4: {
  186. value: data.tp ? data.tp.toString() : null,
  187. },
  188. remark: {
  189. value: remark + ',请登录PC端系统。',
  190. },
  191. };
  192. break;
  193. default:break;
  194. }
  195. if (msgData !== '' && templateId) {
  196. // console.log(openid, templateId, url, msgData);
  197. await this.ctx.app.wechat.api.sendTemplate(openid, templateId, url, '', msgData);
  198. }
  199. }
  200. flag = true;
  201. } catch (e) {
  202. console.log(e);
  203. flag = false;
  204. }
  205. return flag;
  206. }
  207. /**
  208. * 发送微信审批通知模板
  209. *
  210. * @param {Array} corps - 发送的微信账号
  211. * @param {String} template - 模板id
  212. * @param {Object} data - 一些模板展示数据
  213. * @return {Boolean} - 发送结果
  214. */
  215. async Send4Work(corps, template, data) {
  216. let flag = false;
  217. try {
  218. // const sck = 'https://scn.ink/';
  219. const sck = '';
  220. const qywx = new wxWork(this.ctx);
  221. for (const c in corps) {
  222. let url = '';
  223. let title = '';
  224. let desc = '';
  225. let content = '';
  226. let msgData = '';
  227. let remark = '';
  228. let btntxt = '';
  229. const userids = corps[c];
  230. switch (template) {
  231. case wxConst.template.stage:
  232. title = '计量申请审批通知';
  233. desc = `您好, 本期计量${data.tips}`;
  234. remark = '查看审批详情';
  235. content = [
  236. {
  237. keyname: '建设项目',
  238. value: data.projectName,
  239. },
  240. {
  241. keyname: '标段',
  242. value: data.tenderName,
  243. },
  244. {
  245. keyname: '状态',
  246. value: data.status,
  247. },
  248. {
  249. keyname: '备注',
  250. value: `${remark},请登录PC端系统。`,
  251. },
  252. ];
  253. msgData = `<div class="gray">您好, 本期计量${data.tips}</div>
  254. <div class="normal">建设项目: ${data.projectName}</div>
  255. <div class="normal">标段: ${data.tenderName}</div>
  256. <div class="normal">计量期: 第${data.qi}期</div>
  257. <div class="normal">状态: ${data.status}</div>
  258. <div class="normal">备注: ${remark},请登录PC端系统。</div>`;
  259. url = this.ctx.protocol + '://' + this.ctx.host + `/wx/work/${c}/url2wap?project=` + data.code + '&url=' + sck + data.wap_url;
  260. break;
  261. case wxConst.template.change:
  262. title = '工程变更申请审批通知';
  263. desc = `您好, ${data.type ? wxConst.changeType[data.type] : '工程变更申请'}${data.tips}`;
  264. remark = data.status === wxConst.status.check ? (data.type && _.indexOf(['apply', 'project'], data.type) !== -1 ? '暂无法在线审批' : '可快速审批,如需进行详细审批') :
  265. (data.status === wxConst.status.success ? '审批已通过,查看审批结果' :
  266. (data.status === wxConst.status.back ? '审批被退回,查看退回结果' : '审批已终止,查看终止结果'));
  267. content = [
  268. {
  269. keyname: '建设项目',
  270. value: data.projectName,
  271. },
  272. {
  273. keyname: '标段',
  274. value: data.tenderName,
  275. },
  276. {
  277. keyname: '变更名称',
  278. value: data.c_name,
  279. },
  280. {
  281. keyname: '备注',
  282. value: `${remark},请登录PC端系统。`,
  283. },
  284. ];
  285. msgData = `<div class="gray">您好, ${data.type ? wxConst.changeType[data.type] : '工程变更申请'}${data.tips}</div>
  286. <div class="normal">建设项目: ${data.projectName}</div>
  287. <div class="normal">标段: ${data.tenderName}</div>
  288. <div class="normal">变更名称: ${data.c_name}</div>
  289. <div class="normal">备注: ${remark},请登录PC端系统。</div>`;
  290. url = data.wap_url ? this.ctx.protocol + '://' + this.ctx.host + `/wx/work/${c}/url2wap?project=` + data.code + '&url=' + sck + data.wap_url : '';
  291. btntxt = '详情';
  292. break;
  293. case wxConst.template.ledger:
  294. title = '台帐申请审批通知';
  295. desc = `您好, 台账${data.tips}`;
  296. remark = data.status === wxConst.status.check ? '暂无法在线审批' :
  297. (data.status === wxConst.status.success ? '审批已通过,查看审批结果' : '审批被退回,查看退回结果');
  298. content = [
  299. {
  300. keyname: '建设项目',
  301. value: data.projectName,
  302. },
  303. {
  304. keyname: '标段',
  305. value: data.tenderName,
  306. },
  307. {
  308. keyname: '上报时间',
  309. value: moment(new Date(data.begin_time)).format('YYYY-MM-DD'),
  310. },
  311. {
  312. keyname: '备注',
  313. value: `${remark},请登录PC端系统。`,
  314. },
  315. ];
  316. msgData = `<div class="gray">您好, 台账${data.tips}</div>
  317. <div class="normal">建设项目: ${data.projectName}</div>
  318. <div class="normal">标段: ${data.tenderName}</div>
  319. <div class="normal">上报时间: ${moment(new Date(data.begin_time)).format('YYYY-MM-DD')}</div>
  320. <div class="normal">备注: ${remark},请登录PC端系统。</div>`;
  321. url = this.ctx.protocol + '://' + this.ctx.host + `/wx/tips?msg=${remark},请登录PC端系统。`;
  322. break;
  323. case wxConst.template.revise:
  324. title = '台帐修订申请审批通知';
  325. desc = `您好, 台账修订${data.tips}`;
  326. remark = data.status === wxConst.status.check ? '可快速审批,如需进行详细审批' :
  327. (data.status === wxConst.status.success ? '审批已通过,查看审批结果' :
  328. (data.status === wxConst.status.back ? '审批被退回,查看退回结果' : '审批已上报,查看审批结果'));
  329. content = [
  330. {
  331. keyname: '建设项目',
  332. value: data.projectName,
  333. },
  334. {
  335. keyname: '标段',
  336. value: data.tenderName,
  337. },
  338. {
  339. keyname: '上报时间',
  340. value: moment(new Date(data.begin_time)).format('YYYY-MM-DD'),
  341. },
  342. {
  343. keyname: '备注',
  344. value: `${remark},请登录PC端系统。`,
  345. },
  346. ];
  347. msgData = `<div class="gray">您好, 台账修订${data.tips}</div>
  348. <div class="normal">建设项目: ${data.projectName}</div>
  349. <div class="normal">标段: ${data.tenderName}</div>
  350. <div class="normal">上报时间: ${moment(new Date(data.begin_time)).format('YYYY-MM-DD')}</div>
  351. <div class="normal">备注: ${remark},请登录PC端系统。</div>`;
  352. url = this.ctx.protocol + '://' + this.ctx.host + `/wx/work/${c}/url2wap?project=` + data.code + '&url=' + sck + data.wap_url;
  353. btntxt = '详情';
  354. break;
  355. case wxConst.template.material:
  356. title = '材料调差申请审批通知';
  357. desc = `您好, 第${data.qi}期材料调差申请${data.tips}`;
  358. remark = data.status === wxConst.status.check ? '暂无法在线审批' :
  359. (data.status === wxConst.status.success ? '审批已通过,查看审批结果' : '审批被退回,查看退回结果');
  360. content = [
  361. {
  362. keyname: '建设项目',
  363. value: data.projectName,
  364. },
  365. {
  366. keyname: '标段',
  367. value: data.tenderName,
  368. },
  369. {
  370. keyname: '价差费用',
  371. value: data.m_tp ? data.m_tp.toString() : null,
  372. },
  373. {
  374. keyname: '价差费用含税',
  375. value: data.hs_m_tp ? data.hs_m_tp.toString() : null,
  376. },
  377. {
  378. keyname: '备注',
  379. value: `${remark},请登录PC端系统。`,
  380. },
  381. ];
  382. msgData = `<div class="gray">您好, 第${data.qi}期材料调差申请${data.tips}</div>
  383. <div class="normal">建设项目: ${data.projectName}</div>
  384. <div class="normal">标段: ${data.tenderName}</div>
  385. <div class="normal">上报时间: ${moment(new Date(data.begin_time)).format('YYYY-MM-DD')}</div>
  386. <div class="normal">价差费用: ${data.m_tp ? data.m_tp.toString() : null}</div>
  387. <div class="normal">价差费用含税: ${data.hs_m_tp ? data.hs_m_tp.toString() : null}</div>
  388. <div class="normal">备注: ${remark},请登录PC端系统。</div>`;
  389. url = this.ctx.protocol + '://' + this.ctx.host + `/wx/tips?msg=${remark},请登录PC端系统。`;
  390. break;
  391. case wxConst.template.advance:
  392. title = '预付款申请审批通知';
  393. desc = `您好, 预付款申请${data.tips}`;
  394. remark = data.status === wxConst.status.check ? '可快速审批,如需进行详细审批' :
  395. (data.status === wxConst.status.success ? '审批已通过,查看审批结果' : '审批被退回,查看退回结果');
  396. content = [
  397. {
  398. keyname: '建设项目',
  399. value: data.projectName,
  400. },
  401. {
  402. keyname: '标段',
  403. value: data.tenderName,
  404. },
  405. {
  406. keyname: '期数',
  407. value: data.qi,
  408. },
  409. {
  410. keyname: '本期支付金额',
  411. value: data.tp ? data.tp.toString() : null,
  412. },
  413. {
  414. keyname: '备注',
  415. value: `${remark},请登录PC端系统。`,
  416. },
  417. ];
  418. msgData = `<div class="gray">您好, 预付款申请${data.tips}</div>
  419. <div class="normal">建设项目: ${data.projectName}</div>
  420. <div class="normal">标段: ${data.tenderName}</div>
  421. <div class="normal">期数: ${data.qi}</div>
  422. <div class="normal">本期支付金额: ${data.tp ? data.tp.toString() : null}</div>
  423. <div class="normal">备注: ${remark},请登录PC端系统。</div>`;
  424. url = this.ctx.protocol + '://' + this.ctx.host + `/wx/work/${c}/url2wap?project=` + data.code + '&url=' + sck + data.wap_url;
  425. btntxt = '详情';
  426. break;
  427. default:
  428. break;
  429. }
  430. if (title !== '') {
  431. // console.log(userids, c, title, desc, content, url, btntxt);
  432. // await qywx.sendTextCard(userids, c, title, msgData, url, btntxt);
  433. await qywx.sendTemplateCard(userids, c, title, desc, content, url, btntxt);
  434. }
  435. }
  436. flag = true;
  437. } catch (e) {
  438. console.log(e);
  439. flag = false;
  440. }
  441. return flag;
  442. }
  443. /**
  444. * 关键字转换,并限制20个字以内
  445. *
  446. * @param {String} content - 内容
  447. * @return {Object} - 解析结果
  448. */
  449. async contentChange(content) {
  450. let str = content.replace(/【/g, '(');
  451. str = str.replace(/】/g, ')');
  452. str = str.replace(/工程款/g, '***');
  453. str = str.length > 20 ? str.substring(0, 17) + '...' : str;
  454. return str;
  455. }
  456. }
  457. module.exports = WX;