wechat.client.js 47 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485868788899091929394959697989910010110210310410510610710810911011111211311411511611711811912012112212312412512612712812913013113213313413513613713813914014114214314414514614714814915015115215315415515615715815916016116216316416516616716816917017117217317417517617717817918018118218318418518618718818919019119219319419519619719819920020120220320420520620720820921021121221321421521621721821922022122222322422522622722822923023123223323423523623723823924024124224324424524624724824925025125225325425525625725825926026126226326426526626726826927027127227327427527627727827928028128228328428528628728828929029129229329429529629729829930030130230330430530630730830931031131231331431531631731831932032132232332432532632732832933033133233333433533633733833934034134234334434534634734834935035135235335435535635735835936036136236336436536636736836937037137237337437537637737837938038138238338438538638738838939039139239339439539639739839940040140240340440540640740840941041141241341441541641741841942042142242342442542642742842943043143243343443543643743843944044144244344444544644744844945045145245345445545645745845946046146246346446546646746846947047147247347447547647747847948048148248348448548648748848949049149249349449549649749849950050150250350450550650750850951051151251351451551651751851952052152252352452552652752852953053153253353453553653753853954054154254354454554654754854955055155255355455555655755855956056156256356456556656756856957057157257357457557657757857958058158258358458558658758858959059159259359459559659759859960060160260360460560660760860961061161261361461561661761861962062162262362462562662762862963063163263363463563663763863964064164264364464564664764864965065165265365465565665765865966066166266366466566666766866967067167267367467567667767867968068168268368468568668768868969069169269369469569669769869970070170270370470570670770870971071171271371471571671771871972072172272372472572672772872973073173273373473573673773873974074174274374474574674774874975075175275375475575675775875976076176276376476576676776876977077177277377477577677777877978078178278378478578678778878979079179279379479579679779879980080180280380480580680780880981081181281381481581681781881982082182282382482582682782882983083183283383483583683783883984084184284384484584684784884985085185285385485585685785885986086186286386486586686786886987087187287387487587687787887988088188288388488588688788888989089189289389489589689789889990090190290390490590690790890991091191291391491591691791891992092192292392492592692792892993093193293393493593693793893994094194294394494594694794894995095195295395495595695795895996096196296396496596696796896997097197297397497597697797897998098198298398498598698798898999099199299399499599699799899910001001100210031004100510061007100810091010101110121013101410151016
  1. /**
  2. * 用户微信客户端。
  3. */
  4. "use strict";
  5. let RedisClient = require('../../repository/redis/redis.client');
  6. let RedisModel = require('../redis.model');
  7. let ObjectUtil = require("../../util/object.util.js");
  8. let ModelUtil = require('../../util/model.util');
  9. let WechatSDK = require('../../util/wechat.sdk');
  10. let PatientRepo = require('../../repository/mysql/patient.repo');
  11. let TopicRepo = require("../../repository/mysql/topics.repo.js");
  12. let ParticipantRepo = require("../../repository/mysql/participant.repo");
  13. let redisConn = RedisClient.redisClient().connection;
  14. let clientCache = require('../socket.io/client.cache').clientCache();
  15. let configFile = require('../../include/commons').CONFIG_FILE;
  16. let config = require('../../resources/config/' + configFile);
  17. let log = require("../../util/log.js");
  18. let https = require('https');
  19. let http = require('http');
  20. let async = require('async');
  21. let querystring = require('querystring');
  22. let HlwyyWechatAssistantSDK = require("../../util/hlwyyWechatAssistant.sdk");
  23. var reqq = require('request');
  24. const CONTENT_TYPES = require('../../include/commons').CONTENT_TYPES;
  25. const SESSION_TYPES = require('../../include/commons').SESSION_TYPES;
  26. const SOCKET_TYPES = require('../../include/commons').SOCKET_TYPES;
  27. const REDIS_KEYS = require('../../include/commons').REDIS_KEYS;
  28. class WechatClient extends RedisModel {
  29. constructor() {
  30. super();
  31. }
  32. /**
  33. * 取得用户微信端状态。若Redis中找不到,则从MySQL中查找。
  34. *
  35. * @param userId
  36. * @param handler
  37. */
  38. static getWechatStatus(userId, handler) {
  39. redisConn.hgetallAsync(RedisModel.makeRedisKey(REDIS_KEYS.UserWechatStatus, userId))
  40. .then(function (status) {
  41. if (status == null) {
  42. PatientRepo.findWechatOpenId(userId, handler);
  43. } else {
  44. handler(null, {openid: status.openid});
  45. }
  46. })
  47. .catch(function (err) {
  48. handler(err, null);
  49. });
  50. }
  51. /**
  52. * 向微信端用户发送消息。若用户微信端在线,通过Web Socket推送给患者,如果不在线则通过微信的模板消息。
  53. *
  54. * 只推送文本、图片及语音消息
  55. *
  56. * @param targetUserId
  57. * @param message 消息体
  58. */
  59. static sendMessage(targetUserId, targetUserName, message) {
  60. if (message&&(message.content_type == CONTENT_TYPES.PlainText ||
  61. message.content_type == CONTENT_TYPES.Image ||
  62. message.content_type == CONTENT_TYPES.Audio||
  63. message.content_type == CONTENT_TYPES.PrescriptionBloodStatus ||
  64. message.content_type == CONTENT_TYPES.PrescriptionFollowupContent ||
  65. message.content_type == CONTENT_TYPES.ReservationDoorCardInfo ||
  66. message.content_type == CONTENT_TYPES.ChangeDoorCardInfo ||
  67. message.content_type == CONTENT_TYPES.ChangeDoorDoctor ||
  68. message.content_type == CONTENT_TYPES.ChangeDoorPackageItems ||
  69. message.content_type == CONTENT_TYPES.VideoAnswerStatus
  70. )) {
  71. let patientClient = clientCache.findById(targetUserId);
  72. let pc_patientClient = clientCache.findById("pcpatient_"+targetUserId);
  73. let doctorClient = clientCache.findByIdAndType(message.sender_id,SOCKET_TYPES.DOCTOR);
  74. let pc_doctorClient = clientCache.findByIdAndType("pc_"+message.sender_id,SOCKET_TYPES.PC_DOCTOR);
  75. let pc_patient_system_Client = clientCache.findByIdAndType("pcpatient_system_"+targetUserId,SOCKET_TYPES.PC_PATIENT_SYSTEM);
  76. var count = 0;
  77. if (patientClient || pc_patientClient || pc_patient_system_Client) {
  78. if(patientClient){
  79. log.warn("User's wechat endpoint is online, sending via web socket. User id: ", targetUserId);
  80. WechatClient.sendViaWebSocket(patientClient.socket, message);
  81. }
  82. if(pc_patientClient){
  83. log.warn("User's pc endpoint is online, sending via web socket. User id: ", targetUserId);
  84. WechatClient.sendViaWebSocket(pc_patientClient.socket, message);
  85. }
  86. if(pc_patient_system_Client){
  87. log.warn("User's pc systme endpoint is online, sending via web socket. User id: ", targetUserId);
  88. WechatClient.sendViaWebSocket(pc_patient_system_Client.socket, message);
  89. }
  90. if(doctorClient && (patientClient || pc_patientClient) ){
  91. log.error("doctor sessionid "+doctorClient.sessionId);
  92. if(patientClient && patientClient.sessionId==doctorClient.sessionId){
  93. log.error("patient sessionid "+patientClient.sessionId);
  94. //用户socket在线,推送给用户后,告知医生此消息已读
  95. WechatClient.updateParticipantLastFetchTime(doctorClient.sessionId, targetUserId, ObjectUtil.timestampToLong(message.timestamp));
  96. WechatClient.sendReadDoctor(doctorClient.socket, message);
  97. }
  98. if(pc_patientClient && pc_patientClient.sessionId==doctorClient.sessionId){
  99. log.error("pc_patient sessionid "+pc_patientClient.sessionId);
  100. //用户socket在线,推送给用户后,告知医生此消息已读
  101. WechatClient.updateParticipantLastFetchTime(doctorClient.sessionId, targetUserId, ObjectUtil.timestampToLong(message.timestamp));
  102. WechatClient.sendReadDoctor(doctorClient.socket, message);
  103. }
  104. }else{
  105. count++;
  106. }
  107. if(pc_doctorClient){
  108. log.error("pc_doctor sessionid "+pc_doctorClient.sessionId);
  109. if(patientClient){
  110. log.error("patient sessionid "+patientClient.sessionId);
  111. if(patientClient.sessionId==pc_doctorClient.sessionId){
  112. //用户socket在线,推送给用户后,告知医生此消息已读
  113. WechatClient.updateParticipantLastFetchTime(pc_doctorClient.sessionId, targetUserId, ObjectUtil.timestampToLong(message.timestamp));
  114. WechatClient.sendReadDoctor(pc_doctorClient.socket, message);
  115. }
  116. }
  117. if(pc_patientClient){
  118. log.error("pc_patient sessionid "+pc_patientClient.sessionId);
  119. if(pc_patientClient.sessionId==pc_doctorClient.sessionId){
  120. //用户socket在线,推送给用户后,告知医生此消息已读
  121. WechatClient.updateParticipantLastFetchTime(pc_doctorClient.sessionId, targetUserId, ObjectUtil.timestampToLong(message.timestamp));
  122. WechatClient.sendReadDoctor(pc_doctorClient.socket, message);
  123. }
  124. }
  125. }else{
  126. count++;
  127. }
  128. if(count==0){
  129. log.error("doctor client not found");
  130. }
  131. } else {
  132. log.info("User's wechat and pc endpoint is not online, sending via wechat template message. User id: ", targetUserId);
  133. var isSendWXTem = true;//是否发送微信模板
  134. if(message.content_type == CONTENT_TYPES.PrescriptionBloodStatus||message.content_type == CONTENT_TYPES.PrescriptionFollowupContent){
  135. var content = JSON.parse(message.content);
  136. if(content.isSendWxTemplate){
  137. message.content = content.text;
  138. }else {
  139. isSendWXTem = false;
  140. }
  141. }
  142. if(isSendWXTem){
  143. //发送第三方接口的微信模版消息
  144. WechatClient.sendThirdMessageTemplate(targetUserId, targetUserName, message);
  145. //发送厦门i健康的微信模版消息
  146. // WechatClient.sendViaMessageTemplate(targetUserId, targetUserName, message);
  147. }
  148. }
  149. } else if(message.content_type == CONTENT_TYPES.TopicEnd){
  150. let patientClient = clientCache.findById(targetUserId);
  151. if(patientClient){//结束咨询的告知患者
  152. WechatClient.sendViaWebSocket(patientClient.socket, message);
  153. }
  154. let pc_patientClient = clientCache.findById("pcpatient_"+targetUserId);
  155. if(pc_patientClient)//结束咨询的告知患者
  156. {
  157. WechatClient.sendViaWebSocket(pc_patientClient.socket, message);
  158. }
  159. }
  160. };
  161. static sendViaWebSocket(socket, message) {
  162. socket.emit('message', {
  163. id: message.id,
  164. session_id: message.session_id,
  165. sender_id: message.sender_id,
  166. sender_name: message.sender_name,
  167. content_type: message.content_type,
  168. content: message.content,
  169. timestamp: ObjectUtil.timestampToLong(message.timestamp),
  170. type: message.content_type, // legacy support
  171. name: message.sender_name,
  172. sender_img : message.sender_img
  173. });
  174. }
  175. static sendAllRead(doctorId,sessionId){
  176. let doctorClient = clientCache.findByIdAndType(doctorId,SOCKET_TYPES.DOCTOR);
  177. let pc_doctorClient = clientCache.findByIdAndType("pc_"+doctorId,SOCKET_TYPES.PC_DOCTOR);
  178. if(doctorClient){
  179. if(doctorClient.sessionId==sessionId){
  180. doctorClient.socket.emit('message',{ read:"all"});
  181. }else{
  182. log.warn(" doctor not in the same session ");
  183. }
  184. }else{
  185. if(pc_doctorClient && pc_doctorClient.sessionId == sessionId){
  186. pc_doctorClient.socket.emit('message',{ read:"all"});
  187. }else{
  188. log.warn(doctorId+" target doctor is not online!");
  189. }
  190. }
  191. }
  192. static sendMucAllRead(doctorId,loginUserId,sessionId){
  193. let loginClinet = clientCache.findByIdAndType(loginUserId,SOCKET_TYPES.DOCTOR);
  194. if(loginClinet){
  195. //muc是医生来获取数据不能更新成已读
  196. log.warn("type is muc login is doctor not send all read to other doctor!")
  197. return;
  198. }
  199. let doctorClient = clientCache.findByIdAndType(doctorId,SOCKET_TYPES.DOCTOR);
  200. let pc_doctorClient = clientCache.findByIdAndType("pc_"+doctorId,SOCKET_TYPES.PC_DOCTOR);
  201. if(doctorClient){
  202. if(doctorClient.sessionId==sessionId){
  203. doctorClient.socket.emit('message',{ read:"all"});
  204. }else{
  205. log.warn(" doctor not in the same session ");
  206. }
  207. }else{
  208. if(pc_doctorClient && pc_doctorClient.sessionId == sessionId){
  209. pc_doctorClient.socket.emit('message',{ read:"all"});
  210. }else{
  211. log.warn(doctorId+" target doctor is not online!");
  212. }
  213. }
  214. }
  215. static sendReadDoctor(socket, message) {
  216. socket.emit('message', {
  217. id: message.id,
  218. session_id: message.session_id,
  219. sender_id: message.sender_id,
  220. sender_name: message.sender_name,
  221. content_type: message.content_type,
  222. content: message.content,
  223. timestamp: ObjectUtil.timestampToLong(message.timestamp),
  224. type: message.content_type, // legacy support
  225. name: message.sender_name,
  226. read:"one"
  227. });
  228. }
  229. static sendReadDoctorByDoctorId(doctorId, message) {
  230. let doctorClient = clientCache.findByIdAndType(doctorId,SOCKET_TYPES.DOCTOR);
  231. let pc_doctorClient = clientCache.findByIdAndType("pc_"+doctorId,SOCKET_TYPES.PC_DOCTOR);
  232. if(!doctorClient&&!pc_doctorClient){
  233. log.warn("target doctor is not online!");
  234. return;
  235. }
  236. let sendDoctorClient = clientCache.findByIdAndType(message.sender_id,SOCKET_TYPES.DOCTOR);
  237. if(!sendDoctorClient){
  238. sendDoctorClient = clientCache.findByIdAndType("pc_"+message.sender_id,SOCKET_TYPES.PC_DOCTOR);
  239. }
  240. var count = 0;
  241. if(doctorClient&&sendDoctorClient&&sendDoctorClient.sessionId==doctorClient.sessionId){
  242. WechatClient.updateParticipantLastFetchTime(doctorClient.sessionId, doctorId, ObjectUtil.timestampToLong(message.timestamp));
  243. sendDoctorClient.socket.emit('message', {
  244. id: message.id,
  245. session_id: message.session_id,
  246. sender_id: message.sender_id,
  247. sender_name: message.sender_name,
  248. content_type: message.content_type,
  249. content: message.content,
  250. timestamp: ObjectUtil.timestampToLong(message.timestamp),
  251. type: message.content_type, // legacy support
  252. name: message.sender_name,
  253. read:"one"
  254. });
  255. }else{
  256. count++;
  257. }
  258. //发送pc版医生端
  259. if(pc_doctorClient&&sendDoctorClient&&sendDoctorClient.sessionId==pc_doctorClient.sessionId){
  260. WechatClient.updateParticipantLastFetchTime(pc_doctorClient.sessionId, doctorId, ObjectUtil.timestampToLong(message.timestamp));
  261. pc_doctorClient.socket.emit('message', {
  262. id: message.id,
  263. session_id: message.session_id,
  264. sender_id: message.sender_id,
  265. sender_name: message.sender_name,
  266. content_type: message.content_type,
  267. content: message.content,
  268. timestamp: ObjectUtil.timestampToLong(message.timestamp),
  269. type: message.content_type, // legacy support
  270. name: message.sender_name,
  271. read:"one"
  272. });
  273. }else{
  274. count++;
  275. }
  276. if(count==2){
  277. log.warn("doctor is not in the same session or is not online");
  278. }
  279. }
  280. static sendSocketMessageToDoctor(doctorId, message) {
  281. let doctorClient = clientCache.findByIdAndType(doctorId,SOCKET_TYPES.DOCTOR);
  282. let pc_doctorClient = clientCache.findByIdAndType("pc_"+doctorId,SOCKET_TYPES.PC_DOCTOR);
  283. if(!doctorClient&&!pc_doctorClient){
  284. log.warn("target doctor is not online!");
  285. return;
  286. }
  287. // let sendClient = clientCache.findByIdAndType(message.sender_id,SOCKET_TYPES.DOCTOR);//app医生发送的消息
  288. // if(!sendClient){//pc医生发送的消息
  289. // sendClient = clientCache.findByIdAndType("pc_"+message.sender_id,SOCKET_TYPES.PC_DOCTOR);
  290. // }
  291. // if(!sendClient){//居民发送的消息
  292. // sendClient = clientCache.findByIdAndType(message.sender_id,SOCKET_TYPES.PATIENT);
  293. // }
  294. var count = 0;
  295. if(doctorClient&&message.session_id==doctorClient.sessionId){
  296. WechatClient.updateParticipantLastFetchTime(doctorClient.sessionId, doctorId, ObjectUtil.timestampToLong(message.timestamp));
  297. doctorClient.socket.emit('message', {
  298. id: message.id,
  299. session_id: message.session_id,
  300. sender_id: message.sender_id,
  301. sender_name: message.sender_name,
  302. content_type: message.content_type,
  303. content: message.content,
  304. timestamp: ObjectUtil.timestampToLong(message.timestamp),
  305. type: message.content_type, // legacy support
  306. name: message.sender_name,
  307. });
  308. }else{
  309. count++;
  310. }
  311. //发送pc端 - PC端消息不做sessionid的判断,前端自己判断消息归属于哪个会话,自行渲染--20191012-huangwenjie
  312. // if(pc_doctorClient&&message.session_id==pc_doctorClient.sessionId){
  313. if(pc_doctorClient){
  314. WechatClient.updateParticipantLastFetchTime(pc_doctorClient.sessionId, doctorId, ObjectUtil.timestampToLong(message.timestamp));
  315. pc_doctorClient.socket.emit('message', {
  316. id: message.id,
  317. session_id: message.session_id,
  318. sender_id: message.sender_id,
  319. sender_name: message.sender_name,
  320. content_type: message.content_type,
  321. content: message.content,
  322. timestamp: ObjectUtil.timestampToLong(message.timestamp),
  323. type: message.content_type, // legacy support
  324. name: message.sender_name,
  325. });
  326. }else{
  327. count++;
  328. }
  329. if(count==2){
  330. log.warn("doctor is not in the same session or is not online");
  331. }
  332. }
  333. /**
  334. * 推送MDT,医生外层新消息
  335. * @param doctorId
  336. * @param message
  337. */
  338. static sendMDTSocketMessageToDoctor(doctorId, message) {
  339. // let doctorMDTClient = clientCache.findByIdAndType("pcim_"+doctorId,SOCKET_TYPES.PCIM_DOCTOR);
  340. let doctorSYSTEMClient = clientCache.findByIdAndType("pc_system_"+doctorId,SOCKET_TYPES.PC_DOCTOR_SYSTEM);
  341. let doctorAPPSYSTEMClient = clientCache.findByIdAndType("doctor_system_"+doctorId,SOCKET_TYPES.DOCTOR_SYSTEM);
  342. //外层
  343. if(!doctorSYSTEMClient){
  344. log.warn("target system doctor is not online!");
  345. }else{
  346. doctorSYSTEMClient.socket.emit('message', {
  347. id: message.id,
  348. session_id: message.session_id,
  349. sender_id: message.sender_id,
  350. sender_name: message.sender_name,
  351. content_type: 1,
  352. content: {"socket_sms_type":4},
  353. timestamp: ObjectUtil.timestampToLong(message.timestamp),
  354. type: message.content_type, // legacy support
  355. name: message.sender_name,
  356. patient_name:message.patient_name,
  357. patient_age:message.patient_age,
  358. patient_sex:message.patient_sex
  359. });
  360. }
  361. if(!doctorAPPSYSTEMClient){
  362. log.warn("target system app doctor is not online!");
  363. }else{
  364. doctorAPPSYSTEMClient.socket.emit('message', {
  365. id: message.id,
  366. session_id: message.session_id,
  367. sender_id: message.sender_id,
  368. sender_name: message.sender_name,
  369. content_type: 1,
  370. content: {"socket_sms_type":4},
  371. timestamp: ObjectUtil.timestampToLong(message.timestamp),
  372. type: message.content_type, // legacy support
  373. name: message.sender_name,
  374. patient_name:message.patient_name,
  375. patient_age:message.patient_age,
  376. patient_sex:message.patient_sex
  377. });
  378. }
  379. }
  380. static sendPcImSocket(targetId, message, sessionType) {
  381. if (message.content_type == CONTENT_TYPES.PlainText ||
  382. message.content_type == CONTENT_TYPES.Image ||
  383. message.content_type == CONTENT_TYPES.Audio||
  384. message.content_type == CONTENT_TYPES.Video||
  385. message.content_type == CONTENT_TYPES.GoTo||
  386. sessionType==SESSION_TYPES.SYSTEM) {
  387. let pcim_doctorClient = clientCache.findByIdAndType("pcim_"+targetId,SOCKET_TYPES.PCIM_DOCTOR);
  388. if(pcim_doctorClient) {
  389. let customData = {
  390. session_id: message.session_id||'',
  391. session_type: sessionType,
  392. from: message.sender_id|| '',
  393. data: message.content,
  394. business_type: message.business_type || 1
  395. };
  396. pcim_doctorClient.socket.emit('message', {
  397. session_id: message.session_id||'',
  398. session_type: sessionType,
  399. from: message.sender_id|| '',
  400. data: message.content,
  401. business_type: message.business_type || 1,
  402. sender_name: message.sender_name,
  403. content_type: message.content_type,
  404. content: message.content,
  405. timestamp: ObjectUtil.timestampToLong(message.timestamp),
  406. type: message.content_type, // legacy support
  407. name: message.sender_name,
  408. patient_name:message.patient_name,
  409. patient_age:message.patient_age,
  410. patient_sex:message.patient_sex
  411. });
  412. }
  413. }
  414. }
  415. static sendSocketMessageToPatient(patientId, message) {
  416. let patientClient = clientCache.findByIdAndType(patientId,SOCKET_TYPES.PATIENT);
  417. let pc_patientClient = clientCache.findByIdAndType("pcpatient_"+patientId,SOCKET_TYPES.PC_PATIENT);
  418. if(!patientClient&&!pc_patientClient){
  419. log.warn("target patient is not online!");
  420. return;
  421. }
  422. // let sendClient = clientCache.findByIdAndType(message.sender_id,SOCKET_TYPES.DOCTOR);//app医生发送的消息
  423. // if(!sendClient){//pc医生发送的消息
  424. // sendClient = clientCache.findByIdAndType("pc_"+message.sender_id,SOCKET_TYPES.PC_DOCTOR);
  425. // }
  426. // if(!sendClient){//居民发送的消息
  427. // sendClient = clientCache.findByIdAndType(message.sender_id,SOCKET_TYPES.PATIENT);
  428. // }
  429. var count = 0;
  430. if(patientClient&&message.session_id==patientClient.sessionId){
  431. WechatClient.updateParticipantLastFetchTime(patientClient.sessionId, patientId, ObjectUtil.timestampToLong(message.timestamp));
  432. patientClient.socket.emit('message', {
  433. id: message.id,
  434. session_id: message.session_id,
  435. sender_id: message.sender_id,
  436. sender_name: message.sender_name,
  437. content_type: message.content_type,
  438. content: message.content,
  439. timestamp: ObjectUtil.timestampToLong(message.timestamp),
  440. type: message.content_type, // legacy support
  441. name: message.sender_name,
  442. });
  443. }else{
  444. count++;
  445. }
  446. //发送pc端
  447. if(pc_patientClient&&message.session_id==pc_patientClient.sessionId){
  448. WechatClient.updateParticipantLastFetchTime(pc_patientClient.sessionId, patientId, ObjectUtil.timestampToLong(message.timestamp));
  449. pc_patientClient.socket.emit('message', {
  450. id: message.id,
  451. session_id: message.session_id,
  452. sender_id: message.sender_id,
  453. sender_name: message.sender_name,
  454. content_type: message.content_type,
  455. content: message.content,
  456. timestamp: ObjectUtil.timestampToLong(message.timestamp),
  457. type: message.content_type, // legacy support
  458. name: message.sender_name,
  459. });
  460. }else{
  461. count++;
  462. }
  463. if(count==2){
  464. log.warn("patient is not in the same session or is not online");
  465. }
  466. }
  467. //推送居民、居民PC、医生、医生PC外层推送
  468. static sendSystemSocketMessage(targetUserId, message) {
  469. //居民外层消息推送
  470. let patientClient = clientCache.findByIdAndType("patient_system_"+targetUserId,SOCKET_TYPES.PATIENT_SYSTEM);
  471. let pc_patientClient = clientCache.findByIdAndType("pcpatient_system_"+targetUserId,SOCKET_TYPES.PC_PATIENT_SYSTEM);
  472. if(!patientClient&&!pc_patientClient){
  473. log.warn("target patient systemt is not online!");
  474. // return;
  475. }
  476. var patientcount = 0;
  477. if(patientClient&&message.session_id==patientClient.sessionId){
  478. WechatClient.updateParticipantLastFetchTime(patientClient.sessionId, targetUserId, ObjectUtil.timestampToLong(message.timestamp));
  479. patientClient.socket.emit('message', {
  480. id: message.id,
  481. session_id: message.session_id,
  482. sender_id: message.sender_id,
  483. sender_name: message.sender_name,
  484. content_type: message.content_type,
  485. content: message.content,
  486. timestamp: ObjectUtil.timestampToLong(message.timestamp),
  487. type: message.content_type, // legacy support
  488. name: message.sender_name,
  489. });
  490. }else{
  491. patientcount++;
  492. }
  493. //发送pc端
  494. if(pc_patientClient&&message.session_id==pc_patientClient.sessionId){
  495. WechatClient.updateParticipantLastFetchTime(pc_patientClient.sessionId, targetUserId, ObjectUtil.timestampToLong(message.timestamp));
  496. pc_patientClient.socket.emit('message', {
  497. id: message.id,
  498. session_id: message.session_id,
  499. sender_id: message.sender_id,
  500. sender_name: message.sender_name,
  501. content_type: message.content_type,
  502. content: message.content,
  503. timestamp: ObjectUtil.timestampToLong(message.timestamp),
  504. type: message.content_type, // legacy support
  505. name: message.sender_name,
  506. });
  507. }else{
  508. patientcount++;
  509. }
  510. if(patientcount==2){
  511. log.warn("patient system is not in the same session or is not online");
  512. }
  513. //医生外层消息推送
  514. let doctorClient = clientCache.findByIdAndType("doctor_system_"+targetUserId,SOCKET_TYPES.DOCTOR_SYSTEM);
  515. let pc_doctorClient = clientCache.findByIdAndType("pc_system_"+targetUserId,SOCKET_TYPES.PC_DOCTOR_SYSTEM);
  516. if(!doctorClient&&!pc_doctorClient){
  517. log.warn("target doctor system is not online!");
  518. // return;
  519. }
  520. var doctorcount = 0;
  521. if(doctorClient&&message.session_id==doctorClient.sessionId){
  522. WechatClient.updateParticipantLastFetchTime(doctorClient.sessionId, targetUserId, ObjectUtil.timestampToLong(message.timestamp));
  523. doctorClient.socket.emit('message', {
  524. id: message.id,
  525. session_id: message.session_id,
  526. sender_id: message.sender_id,
  527. sender_name: message.sender_name,
  528. content_type: message.content_type,
  529. content: message.content,
  530. timestamp: ObjectUtil.timestampToLong(message.timestamp),
  531. type: message.content_type, // legacy support
  532. name: message.sender_name,
  533. });
  534. }else{
  535. doctorcount++;
  536. }
  537. //发送pc端 - PC端消息不做sessionid的判断,前端自己判断消息归属于哪个会话,自行渲染--20191012-huangwenjie
  538. // if(pc_doctorClient&&message.session_id==pc_doctorClient.sessionId){
  539. if(pc_doctorClient){
  540. WechatClient.updateParticipantLastFetchTime(pc_doctorClient.sessionId, targetUserId, ObjectUtil.timestampToLong(message.timestamp));
  541. pc_doctorClient.socket.emit('message', {
  542. id: message.id,
  543. session_id: message.session_id,
  544. sender_id: message.sender_id,
  545. sender_name: message.sender_name,
  546. content_type: message.content_type,
  547. content: message.content,
  548. timestamp: ObjectUtil.timestampToLong(message.timestamp),
  549. type: message.content_type, // legacy support
  550. name: message.sender_name,
  551. });
  552. }else{
  553. doctorcount++;
  554. }
  555. if(doctorcount==2){
  556. log.warn("doctor system is not in the same session or is not online");
  557. }
  558. }
  559. //推送托盘消息
  560. static sendMDTSystemSocketMessage(targetUserId, message) {
  561. //居民外层消息推送
  562. let mdtDcotorClient = clientCache.findByIdAndType("pcim_"+targetUserId,SOCKET_TYPES.PCIM_DOCTOR);
  563. if(!mdtDcotorClient){
  564. log.warn("target mdt doctor is not online!");
  565. }
  566. var mdtDoctorCount = 0;
  567. if(mdtDcotorClient&&message.session_id==mdtDcotorClient.sessionId){
  568. WechatClient.updateParticipantLastFetchTime(mdtDcotorClient.sessionId, targetUserId, ObjectUtil.timestampToLong(message.timestamp));
  569. mdtDcotorClient.socket.emit('message', {
  570. id: message.id,
  571. session_id: message.session_id,
  572. sender_id: message.sender_id,
  573. sender_name: message.sender_name,
  574. content_type: message.content_type,
  575. content: message.content,
  576. timestamp: ObjectUtil.timestampToLong(message.timestamp),
  577. type: message.content_type, // legacy support
  578. name: message.sender_name,
  579. });
  580. }else{
  581. mdtDoctorCount++;
  582. }
  583. if(mdtDoctorCount==2){
  584. log.warn("doctor system is not in the same session or is not online");
  585. }
  586. }
  587. /**
  588. *
  589. * 发送微信模板消息给居民
  590. *
  591. * @param targetUserId
  592. * @param message
  593. */
  594. static sendViaMessageTemplate(targetUserId, targetUserName, message) {
  595. async.waterfall([
  596. // 获取微信openid
  597. function (callback) {
  598. PatientRepo.findWechatOpenIds(targetUserId, function (err, res) {
  599. if (err) {
  600. ModelUtil.logError("Get wechat openid failed", err);
  601. return;
  602. }
  603. var map = new Map();
  604. res.forEach(function (participant) {
  605. let openid = participant.openid;
  606. if (targetUserId==participant.code) {
  607. if (!openid) {
  608. ModelUtil.logError("User haven't bound with wechat, user id: " + targetUserId);
  609. }
  610. map.set("openid",participant);
  611. }else {
  612. if(!map.has(openid)){
  613. map.set(openid,participant);
  614. }
  615. }
  616. })
  617. //
  618. // let openid = result && result.length > 0 ? result[0].openid : null;
  619. // if (!openid) {
  620. // ModelUtil.logError("User haven't bound with wechat, user id: " + targetUserId);
  621. // return;
  622. // }
  623. //
  624. // log.warn("Send via wechat message template, user id: " + targetUserId + ", openid: " + openid);
  625. callback(null, map);
  626. });
  627. },
  628. // 获取议题信息
  629. function (map, callback) {
  630. TopicRepo.findLastTopicStatusAndType(message.session_id, function (err, res) {
  631. if (err) {
  632. ModelUtil.logError("Get topic failed", err);
  633. return;
  634. }
  635. if (!res || res.length == 0) {
  636. ModelUtil.logError("Unable to find session last topic");
  637. return;
  638. }
  639. callback(null, map, message.sender_name, res[0]);
  640. });
  641. },
  642. // 发送消息
  643. function (map, senderName, topic,callback) {
  644. let replyContent = message.content;
  645. switch (Number.parseInt(message.content_type)) {
  646. case CONTENT_TYPES.Image:
  647. replyContent = "[图片]";
  648. break;
  649. case CONTENT_TYPES.Audio:
  650. replyContent = "[语音]";
  651. break;
  652. default:
  653. break;
  654. }
  655. var patient = map.get("openid");
  656. map.delete("openid");
  657. let agent = topic.agent;
  658. let consultTitle = null;
  659. let description = null;
  660. let url = config.wechatConfig.baseUrl;
  661. switch (topic.type) {
  662. case 8:
  663. consultTitle = "续方";
  664. description = "续方咨询";
  665. url = url + "/wx/html/yszx/html/prescription-consulting.html";
  666. case 11:
  667. consultTitle = "上门服务";
  668. description = "上门服务咨询";
  669. url = url + "wx/html/appoint_service/html/appoint-serviceDetail.html";
  670. default:
  671. consultTitle = "健康";
  672. description = topic.description;
  673. url = url + "/wx/html/yszx/html/consulting-doctor.html";
  674. }
  675. if(agent){//代理人发起的议题
  676. var agentOpenid = "";
  677. if(map.size>0){
  678. for(var key of map.keys()){
  679. var member = map.get(key);
  680. if(agent == member.code){
  681. agentOpenid = key;
  682. var openid = key;
  683. var first = "您的家人("+patient.name+")的"+consultTitle+"咨询有新的回复";
  684. // 发送模板消息
  685. WechatSDK.sendTemplateMessage({
  686. touser: openid,
  687. name: member.name,
  688. patient: member.code,
  689. template_id: config.wechatConfig.template.consultTemplate,
  690. url: url + "?openid=" + openid + "&type="+topic.type+"&doctor="+message.sender_id+
  691. "&consult=" + topic.id + "&toUser=" + member.code + "&toName=" + member.name+"&represented="+patient.code,
  692. data: {
  693. first: {value: first, color: "#000000"}
  694. , remark: {value: "", color: "#000000"}
  695. , keyword1: {value: description, color: "#000000"}
  696. , keyword2: {value: replyContent, color: "#000000"}
  697. , keyword3: {value: senderName, color: "#000000"}
  698. }
  699. }, function (err, res) {
  700. err ? log.error(err) : log.info(res);
  701. });
  702. }
  703. }
  704. }
  705. if(patient.openid&&patient.openid!=agentOpenid){
  706. var first = "您的"+consultTitle+"咨询有新的回复";
  707. // 发送模板消息
  708. WechatSDK.sendTemplateMessage({
  709. touser: patient.openid,
  710. name: targetUserName,
  711. patient: targetUserId,
  712. template_id: config.wechatConfig.template.consultTemplate,
  713. url: url + "?openid=" + patient.openid +"&type="+topic.type+"&doctor="+message.sender_id+
  714. "&consult=" + topic.id + "&toUser=" + targetUserId + "&toName=" + targetUserName+"&represented="+patient.code,
  715. data: {
  716. first: {value: first, color: "#000000"}
  717. , remark: {value: "", color: "#000000"}
  718. , keyword1: {value: description, color: "#000000"}
  719. , keyword2: {value: replyContent, color: "#000000"}
  720. , keyword3: {value: senderName, color: "#000000"}
  721. }
  722. }, function (err, res) {
  723. err ? log.error(err) : log.info(res);
  724. });
  725. }
  726. }else {//自己发起的议题
  727. // 发送模板消息
  728. if(patient.openid){
  729. WechatSDK.sendTemplateMessage({
  730. touser: patient.openid,
  731. name: targetUserName,
  732. patient: targetUserId,
  733. template_id: config.wechatConfig.template.consultTemplate,
  734. url: url + "?openid=" + patient.openid +"&type="+topic.type+"&doctor="+message.sender_id+
  735. "&consult=" + topic.id + "&toUser=" + targetUserId + "&toName=" + targetUserName+"&represented="+patient.code,
  736. data: {
  737. first: {value: "您的"+consultTitle+"咨询有新的回复", color: "#000000"}
  738. , remark: {value: "", color: "#000000"}
  739. , keyword1: {value: description, color: "#000000"}
  740. , keyword2: {value: replyContent, color: "#000000"}
  741. , keyword3: {value: senderName, color: "#000000"}
  742. }
  743. }, function (err, res) {
  744. err ? log.error(err) : log.info(res);
  745. });
  746. }
  747. if(map.size>0){
  748. for(var key of map.keys()){
  749. if(!patient.openid||key!=patient.openid){
  750. var member = map.get(key);
  751. var openid = key;
  752. var first = "您的家人("+patient.name+")的"+consultTitle+"咨询有新的回复";
  753. // 发送模板消息
  754. WechatSDK.sendTemplateMessage({
  755. touser: openid,
  756. name: member.name,
  757. patient: member.code,
  758. template_id: config.wechatConfig.template.consultTemplate,
  759. url: url + "?openid=" + openid +"&type="+topic.type+"&doctor="+message.sender_id+
  760. "&consult=" + topic.id + "&toUser=" + member.code + "&toName=" + member.name+"&represented="+patient.code,
  761. data: {
  762. first: {value: first, color: "#000000"}
  763. , remark: {value: "", color: "#000000"}
  764. , keyword1: {value: description, color: "#000000"}
  765. , keyword2: {value: replyContent, color: "#000000"}
  766. , keyword3: {value: senderName, color: "#000000"}
  767. }
  768. }, function (err, res) {
  769. err ? log.error(err) : log.info(res);
  770. });
  771. }
  772. }
  773. }
  774. }
  775. callback(null, null);
  776. }
  777. ],
  778. function (err, res) {
  779. if (!err) {
  780. log.info("Send via wechat template message, DONE!");
  781. }
  782. });
  783. };
  784. static updateParticipantLastFetchTime(sessionId, userId, score) {
  785. score = score + 1000;
  786. let participantsKey = RedisModel.makeRedisKey(REDIS_KEYS.SessionParticipants, sessionId);
  787. redisConn.zaddAsync(participantsKey, score, userId)
  788. .then(function (res) {
  789. ParticipantRepo.updateLastFetchTime(new Date(score), sessionId, userId, function (err, res) {
  790. if (err) {
  791. log.error("Update participant last fetch time failed: ", err);
  792. }
  793. });
  794. })
  795. .catch(function (err) {
  796. log.error("Update participant last fetch time failed: ", err);
  797. });
  798. };
  799. /**
  800. * 发送第三方接口的微信模版消息
  801. * @param targetUserId
  802. * @param message
  803. */
  804. static sendThirdMessageTemplate(targetUserId, targetUserName, message) {
  805. async.waterfall([
  806. // 获取微信openid
  807. function (callback) {
  808. PatientRepo.findOne(targetUserId, function (err, res) {
  809. if (err) {
  810. ModelUtil.logError("Get wechat openid failed", err);
  811. return;
  812. }
  813. var map = new Map();
  814. res.forEach(function (participant) {
  815. let openid = participant.openid;
  816. let idcard = participant.idcard;
  817. let mobile = participant.mobile;
  818. let name = participant.name;
  819. let id = participant.id;
  820. map.set("openid",openid);
  821. map.set("idcard",idcard);
  822. map.set("mobile",mobile);
  823. map.set("name",name);
  824. map.set("id",id);
  825. })
  826. //
  827. // let openid = result && result.length > 0 ? result[0].openid : null;
  828. // if (!openid) {
  829. // ModelUtil.logError("User haven't bound with wechat, user id: " + targetUserId);
  830. // return;
  831. // }
  832. //
  833. // log.warn("Send via wechat message template, user id: " + targetUserId + ", openid: " + openid);
  834. callback(null, map);
  835. });
  836. },
  837. // 获取议题信息
  838. function (map, callback) {
  839. TopicRepo.findLastTopicStatusAndType(message.session_id, function (err, res) {
  840. if (err) {
  841. ModelUtil.logError("Get topic failed", err);
  842. return;
  843. }
  844. if (!res || res.length == 0) {
  845. ModelUtil.logError("Unable to find session last topic");
  846. return;
  847. }
  848. callback(null, map, message.sender_name, res[0]);
  849. });
  850. },
  851. // 发送消息
  852. function (map, senderName, topic,callback) {
  853. let replyContent = message.content;
  854. switch (Number.parseInt(message.content_type)) {
  855. case CONTENT_TYPES.Image:
  856. replyContent = "[图片]";
  857. break;
  858. case CONTENT_TYPES.Audio:
  859. replyContent = "[语音]";
  860. break;
  861. default:
  862. break;
  863. }
  864. let consultTitle = null;
  865. let description = null;
  866. let url = config.thirdApiMessageConfig.baseUrl;
  867. switch (topic.type) {
  868. case 8:
  869. consultTitle = "续方";
  870. description = "续方咨询";
  871. url = url + "/wx/html/yszx/html/prescription-consulting.html";
  872. case 11:
  873. consultTitle = "上门服务";
  874. description = "上门服务咨询";
  875. url = url + "wx/html/appoint_service/html/appoint-serviceDetail.html";
  876. default:
  877. consultTitle = "咨询回复提醒";
  878. description = topic.description;
  879. if("xmijk" == config.imClientType.id){
  880. url = "http://zb.xmtyw.cn/ims-wx/index.html#/chatRoom?type=1&consultCode="+topic.id;
  881. }else if("zsyy" == config.imClientType.id){
  882. url = "http://hlwyy.xmzsh.com/ims-wx/index.html#/chatRoom?type=1&consultCode="+topic.id;
  883. }else if("xm_xzzx_wx" == config.imClientType.id){
  884. url = "http://ih.xmheart.com/hlwyy/ims-wx/index.html#/chatRoom?type=1&consultCode="+topic.id;
  885. }else{}
  886. }
  887. // 发送模板消息
  888. if(map != null){
  889. let userName = map.get("name");
  890. let idCard = map.get("idcard");
  891. let phone = map.get("mobile");
  892. let title = consultTitle;
  893. let content = "您的咨询有新的回复";
  894. let contentString = replyContent;
  895. // log.info("推送居民公众号:params:"+params)
  896. let params = 'senderName='+encodeURIComponent(senderName)+'&userName='+encodeURIComponent(userName)+'&idCard='+idCard+"&phone="+phone+'&title='+encodeURIComponent(consultTitle)+'&content='+encodeURIComponent(content)+'&contentString='+encodeURIComponent(contentString)+'&url='+encodeURIComponent(url);
  897. HlwyyWechatAssistantSDK.request(userName,idCard,phone,title,content,contentString,url,params, function (err, res) {
  898. // WlyyAssistantSDK.request('admin', '0a5c5258-8863-4b07-a3f9-88c768528ab4', '', 'admin_imei', '/doctor/feldsher/sendDoctorTemplate', param, function (err, res) {
  899. // WlyySDK.request('admin', '0a5c5258-8863-4b07-a3f9-88c768528ab4', '', 'admin_imei', '/doctor/feldsher/sendDoctorTemplate?' + params, 'GET', function (err, res) {
  900. if(err){
  901. log.error(err);
  902. }else {
  903. log.info(res);
  904. }
  905. });
  906. }
  907. callback(null, null);
  908. }
  909. ],
  910. function (err, res) {
  911. if (!err) {
  912. log.info("Send via wechat template message, DONE!");
  913. }
  914. });
  915. };
  916. }
  917. module.exports = WechatClient;