123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452 |
- /**
- * 用户微信客户端。
- */
- "use strict";
- let RedisClient = require('../../repository/redis/redis.client');
- let RedisModel = require('../redis.model');
- let ObjectUtil = require("../../util/object.util.js");
- let ModelUtil = require('../../util/model.util');
- let WechatSDK = require('../../util/wechat.sdk');
- let PatientRepo = require('../../repository/mysql/patient.repo');
- let TopicRepo = require("../../repository/mysql/topics.repo.js");
- let ParticipantRepo = require("../../repository/mysql/participant.repo");
- let redisConn = RedisClient.redisClient().connection;
- let clientCache = require('../socket.io/client.cache').clientCache();
- let configFile = require('../../include/commons').CONFIG_FILE;
- let config = require('../../resources/config/' + configFile);
- let log = require("../../util/log.js");
- let https = require('https');
- let async = require('async');
- const CONTENT_TYPES = require('../../include/commons').CONTENT_TYPES;
- const SOCKET_TYPES = require('../../include/commons').SOCKET_TYPES;
- const REDIS_KEYS = require('../../include/commons').REDIS_KEYS;
- class WechatClient extends RedisModel {
- constructor() {
- super();
- }
- /**
- * 取得用户微信端状态。若Redis中找不到,则从MySQL中查找。
- *
- * @param userId
- * @param handler
- */
- static getWechatStatus(userId, handler) {
- redisConn.hgetallAsync(RedisModel.makeRedisKey(REDIS_KEYS.UserWechatStatus, userId))
- .then(function (status) {
- if (status == null) {
- PatientRepo.findWechatOpenId(userId, handler);
- } else {
- handler(null, {openid: status.openid});
- }
- })
- .catch(function (err) {
- handler(err, null);
- });
- }
- /**
- * 向微信端用户发送消息。若用户微信端在线,通过Web Socket推送给患者,如果不在线则通过微信的模板消息。
- *
- * 只推送文本、图片及语音消息
- *
- * @param targetUserId
- * @param message 消息体
- */
- static sendMessage(targetUserId, targetUserName, message) {
- if (message&&(message.content_type == CONTENT_TYPES.PlainText ||
- message.content_type == CONTENT_TYPES.Image ||
- message.content_type == CONTENT_TYPES.Audio)) {
- let patientClient = clientCache.findById(targetUserId);
- let doctorClient = clientCache.findByIdAndType(message.sender_id,SOCKET_TYPES.DOCTOR);
- if (patientClient) {
- log.warn("User's wechat endpoint is online, sending via web socket. User id: ", targetUserId);
- WechatClient.sendViaWebSocket(patientClient.socket, message);
- if(doctorClient){
- log.error("doctor sessionid "+doctorClient.sessionId);
- log.error("patient sessionid "+patientClient.sessionId);
- if(patientClient.sessionId==doctorClient.sessionId){
- //用户socket在线,推送给用户后,告知医生此消息已读
- WechatClient.updateParticipantLastFetchTime(doctorClient.sessionId, targetUserId, ObjectUtil.timestampToLong(message.timestamp));
- WechatClient.sendReadDoctor(doctorClient.socket, message);
- }
- }else{
- log.error("doctor client not found");
- }
- } else {
- log.info("User's wechat endpoint is not online, sending via wechat template message. User id: ", targetUserId);
- WechatClient.sendViaMessageTemplate(targetUserId, targetUserName, message);
- }
- } else if(message.content_type == CONTENT_TYPES.TopicEnd){
- let patientClient = clientCache.findById(targetUserId);
- if(patientClient)//结束咨询的告知患者
- WechatClient.sendViaWebSocket(patientClient.socket, message);
- }
- };
- static sendViaWebSocket(socket, message) {
- socket.emit('message', {
- id: message.id,
- session_id: message.session_id,
- sender_id: message.sender_id,
- sender_name: message.sender_name,
- content_type: message.content_type,
- content: message.content,
- timestamp: ObjectUtil.timestampToLong(message.timestamp),
- type: message.content_type, // legacy support
- name: message.sender_name,
- sender_img : message.sender_img
- });
- }
- static sendAllRead(doctorId,sessionId){
- let doctorClient = clientCache.findByIdAndType(doctorId,SOCKET_TYPES.DOCTOR);
- if(doctorClient){
- if(doctorClient.sessionId==sessionId){
- doctorClient.socket.emit('message',{ read:"all"});
- }else{
- log.warn(" doctor not in the same session ");
- }
- }else{
- log.warn(doctorId+" target doctor is not online!");
- }
- }
- static sendMucAllRead(doctorId,loginUserId,sessionId){
- let loginClinet = clientCache.findByIdAndType(loginUserId,SOCKET_TYPES.DOCTOR);
- if(loginClinet){
- //muc是医生来获取数据不能更新成已读
- log.warn("type is muc login is doctor not send all read to other doctor!")
- return;
- }
- let doctorClient = clientCache.findByIdAndType(doctorId,SOCKET_TYPES.DOCTOR);
- if(doctorClient){
- if(doctorClient.sessionId==sessionId){
- doctorClient.socket.emit('message',{ read:"all"});
- }else{
- log.warn(" doctor not in the same session ");
- }
- }else{
- log.warn(doctorId+" target doctor is not online!");
- }
- }
- static sendReadDoctor(socket, message) {
- socket.emit('message', {
- id: message.id,
- session_id: message.session_id,
- sender_id: message.sender_id,
- sender_name: message.sender_name,
- content_type: message.content_type,
- content: message.content,
- timestamp: ObjectUtil.timestampToLong(message.timestamp),
- type: message.content_type, // legacy support
- name: message.sender_name,
- read:"one"
- });
- }
- static sendReadDoctorByDoctorId(doctorId, message) {
- let doctorClient = clientCache.findByIdAndType(doctorId,SOCKET_TYPES.DOCTOR);
- // let pc_doctorClient = clientCache.findByIdAndType("pc_"+doctorId,SOCKET_TYPES.PC_DOCTOR);
- if(!doctorClient){
- log.warn("target doctor is not online!");
- return;
- }
- let sendDoctorClient = clientCache.findByIdAndType(message.sender_id,SOCKET_TYPES.DOCTOR);
- // let pc_sendDoctorClient = clientCache.findByIdAndType("pc_"+message.sender_id,SOCKET_TYPES.PC_DOCTOR);
- if(sendDoctorClient&&sendDoctorClient.sessionId==doctorClient.sessionId){
- WechatClient.updateParticipantLastFetchTime(doctorClient.sessionId, doctorId, ObjectUtil.timestampToLong(message.timestamp));
- sendDoctorClient.socket.emit('message', {
- id: message.id,
- session_id: message.session_id,
- sender_id: message.sender_id,
- sender_name: message.sender_name,
- content_type: message.content_type,
- content: message.content,
- timestamp: ObjectUtil.timestampToLong(message.timestamp),
- type: message.content_type, // legacy support
- name: message.sender_name,
- read:"one"
- });
- }else{
- log.warn("doctor is not in the same session or not online");
- }
- //发送pc版医生端
- // if(pc_doctorClient&&pc_sendDoctorClient&&pc_sendDoctorClient.sessionId==pc_doctorClient.sessionId){
- // WechatClient.updateParticipantLastFetchTime(pc_doctorClient.sessionId, doctorId, ObjectUtil.timestampToLong(message.timestamp));
- // pc_sendDoctorClient.socket.emit('message', {
- // id: message.id,
- // session_id: message.session_id,
- // sender_id: message.sender_id,
- // sender_name: message.sender_name,
- // content_type: message.content_type,
- // content: message.content,
- // timestamp: ObjectUtil.timestampToLong(message.timestamp),
- // type: message.content_type, // legacy support
- // name: message.sender_name,
- // read:"one"
- // });
- // }else{
- // log.warn("doctor is not in the same session or not online");
- // }
- }
- static sendSocketMessageToDoctor(doctorId, message) {
- let doctorClient = clientCache.findByIdAndType(doctorId,SOCKET_TYPES.DOCTOR);
- // let pc_doctorClient = clientCache.findByIdAndType("pc_"+doctorId,SOCKET_TYPES.PC_DOCTOR);
- if(!doctorClient){
- log.warn("target doctor is not online!");
- return;
- }
- let sendClient = clientCache.findByIdAndType(message.sender_id,SOCKET_TYPES.DOCTOR);//app医生发送的消息
- // if(!sendClient){//pc医生发送的消息
- // sendClient = clientCache.findByIdAndType("pc_"+message.sender_id,SOCKET_TYPES.PC_DOCTOR);
- // }
- if(!sendClient){//居民发送的消息
- sendClient = clientCache.findByIdAndType(message.sender_id,SOCKET_TYPES.PATIENT);
- }
- if(sendClient&&sendClient.sessionId==doctorClient.sessionId){
- WechatClient.updateParticipantLastFetchTime(doctorClient.sessionId, doctorId, ObjectUtil.timestampToLong(message.timestamp));
- doctorClient.socket.emit('message', {
- id: message.id,
- session_id: message.session_id,
- sender_id: message.sender_id,
- sender_name: message.sender_name,
- content_type: message.content_type,
- content: message.content,
- timestamp: ObjectUtil.timestampToLong(message.timestamp),
- type: message.content_type, // legacy support
- name: message.sender_name,
- });
- }else{
- log.warn("doctor is not in the same session or is not online");
- }
- //发送pc端
- // if(pc_doctorClient&&sendClient&&sendClient.sessionId==pc_doctorClient.sessionId){
- // WechatClient.updateParticipantLastFetchTime(pc_doctorClient.sessionId, doctorId, ObjectUtil.timestampToLong(message.timestamp));
- // pc_doctorClient.socket.emit('message', {
- // id: message.id,
- // session_id: message.session_id,
- // sender_id: message.sender_id,
- // sender_name: message.sender_name,
- // content_type: message.content_type,
- // content: message.content,
- // timestamp: ObjectUtil.timestampToLong(message.timestamp),
- // type: message.content_type, // legacy support
- // name: message.sender_name,
- // });
- // }else{
- // log.warn("doctor is not in the same session or is not online");
- // }
- }
- /**
- * 发送微信模板消息给居民
- *
- * @param targetUserId
- * @param message
- */
- static sendViaMessageTemplate(targetUserId, targetUserName, message) {
- async.waterfall([
- // 获取微信openid
- function (callback) {
- PatientRepo.findWechatOpenIds(targetUserId, function (err, res) {
- if (err) {
- ModelUtil.logError("Get wechat openid failed", err);
- return;
- }
- var map = new Map();
- res.forEach(function (participant) {
- let openid = participant.openid;
- if (targetUserId==participant.code) {
- if (!openid) {
- ModelUtil.logError("User haven't bound with wechat, user id: " + targetUserId);
- }
- map.set("openid",participant);
- }else {
- if(!map.has(openid)){
- map.set(openid,participant);
- }
- }
- })
- //
- // let openid = result && result.length > 0 ? result[0].openid : null;
- // if (!openid) {
- // ModelUtil.logError("User haven't bound with wechat, user id: " + targetUserId);
- // return;
- // }
- //
- // log.warn("Send via wechat message template, user id: " + targetUserId + ", openid: " + openid);
- callback(null, map);
- });
- },
- // 获取议题信息
- function (map, callback) {
- TopicRepo.findLastTopicStatusAndType(message.session_id, function (err, res) {
- if (err) {
- ModelUtil.logError("Get topic failed", err);
- return;
- }
- if (!res || res.length == 0) {
- ModelUtil.logError("Unable to find session last topic");
- return;
- }
- callback(null, map, message.sender_name, res[0]);
- });
- },
- // 发送消息
- function (map, senderName, topic,callback) {
- let replyContent = message.content;
- switch (Number.parseInt(message.content_type)) {
- case CONTENT_TYPES.Image:
- replyContent = "[图片]";
- break;
- case CONTENT_TYPES.Audio:
- replyContent = "[语音]";
- break;
- default:
- break;
- }
- var patient = map.get("openid");
- map.delete("openid");
- let agent = topic.agent;
- let consultTitle = topic.type==8?"续方":"健康";
- let description = topic.type==8?"续方咨询":topic.description;
- let url = config.wechatConfig.baseUrl + "/wx/html/yszx/html/consulting-doctor.html";
- if(agent){//代理人发起的议题
- var agentOpenid = "";
- if(map.size>0){
- for(var key of map.keys()){
- var member = map.get(key);
- if(agent == member.code){
- agentOpenid = key;
- var openid = key;
- var first = "您的家人("+patient.name+")的"+consultTitle+"咨询有新的回复";
- // 发送模板消息
- WechatSDK.sendTemplateMessage({
- touser: openid,
- template_id: config.wechatConfig.template.consultTemplate,
- url: url + "?openid=" + openid + "&type="+topic.type+"&doctor="+message.sender_id+
- "&consult=" + topic.id + "&toUser=" + member.code + "&toName=" + member.name+"&represented="+patient.code,
- data: {
- first: {value: first, color: "#000000"}
- , remark: {value: "", color: "#000000"}
- , keyword1: {value: description, color: "#000000"}
- , keyword2: {value: replyContent, color: "#000000"}
- , keyword3: {value: senderName, color: "#000000"}
- }
- }, function (err, res) {
- err ? log.error(err) : log.info(res);
- });
- }
- }
- }
- if(patient.openid&&patient.openid!=agentOpenid){
- var first = "您的"+consultTitle+"咨询有新的回复";
- // 发送模板消息
- WechatSDK.sendTemplateMessage({
- touser: patient.openid,
- template_id: config.wechatConfig.template.consultTemplate,
- url: url + "?openid=" + patient.openid +"&type="+topic.type+"&doctor="+message.sender_id+
- "&consult=" + topic.id + "&toUser=" + targetUserId + "&toName=" + targetUserName+"&represented="+patient.code,
- data: {
- first: {value: first, color: "#000000"}
- , remark: {value: "", color: "#000000"}
- , keyword1: {value: description, color: "#000000"}
- , keyword2: {value: replyContent, color: "#000000"}
- , keyword3: {value: senderName, color: "#000000"}
- }
- }, function (err, res) {
- err ? log.error(err) : log.info(res);
- });
- }
- }else {//自己发起的议题
- // 发送模板消息
- if(patient.openid){
- WechatSDK.sendTemplateMessage({
- touser: patient.openid,
- template_id: config.wechatConfig.template.consultTemplate,
- url: url + "?openid=" + patient.openid +"&type="+topic.type+"&doctor="+message.sender_id+
- "&consult=" + topic.id + "&toUser=" + targetUserId + "&toName=" + targetUserName+"&represented="+patient.code,
- data: {
- first: {value: "您的"+consultTitle+"咨询有新的回复", color: "#000000"}
- , remark: {value: "", color: "#000000"}
- , keyword1: {value: description, color: "#000000"}
- , keyword2: {value: replyContent, color: "#000000"}
- , keyword3: {value: senderName, color: "#000000"}
- }
- }, function (err, res) {
- err ? log.error(err) : log.info(res);
- });
- }
- if(map.size>0){
- for(var key of map.keys()){
- if(!patient.openid||key!=patient.openid){
- var member = map.get(key);
- var openid = key;
- var first = "您的家人("+patient.name+")的"+consultTitle+"咨询有新的回复";
- // 发送模板消息
- WechatSDK.sendTemplateMessage({
- touser: openid,
- template_id: config.wechatConfig.template.consultTemplate,
- url: url + "?openid=" + openid +"&type="+topic.type+"&doctor="+message.sender_id+
- "&consult=" + topic.id + "&toUser=" + member.code + "&toName=" + member.name+"&represented="+patient.code,
- data: {
- first: {value: first, color: "#000000"}
- , remark: {value: "", color: "#000000"}
- , keyword1: {value: description, color: "#000000"}
- , keyword2: {value: replyContent, color: "#000000"}
- , keyword3: {value: senderName, color: "#000000"}
- }
- }, function (err, res) {
- err ? log.error(err) : log.info(res);
- });
- }
- }
- }
- }
- callback(null, null);
- }
- ],
- function (err, res) {
- if (!err) {
- log.info("Send via wechat template message, DONE!");
- }
- });
- };
- static updateParticipantLastFetchTime(sessionId, userId, score) {
- score = score + 1000;
- let participantsKey = RedisModel.makeRedisKey(REDIS_KEYS.SessionParticipants, sessionId);
- redisConn.zaddAsync(participantsKey, score, userId)
- .then(function (res) {
- ParticipantRepo.updateLastFetchTime(new Date(score), sessionId, userId, function (err, res) {
- if (err) {
- log.error("Update participant last fetch time failed: ", err);
- }
- });
- })
- .catch(function (err) {
- log.error("Update participant last fetch time failed: ", err);
- });
- }
- }
- module.exports = WechatClient;
|