wechat.client.js 49 KB

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