|  | @ -7,9 +7,9 @@ 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 DoctorRepo = require('../../repository/mysql/doctor.repo');
 | 
	
		
			
				|  |  | let WechatSDK = require('../../util/wechat.sdk');
 | 
	
		
			
				|  |  | let PatientRepo = require('../../repository/mysql/patient.repo');
 | 
	
		
			
				|  |  | let TopicRepo = require("../../repository/mysql/topics.repo.js");
 | 
	
		
			
				|  |  | 
 | 
	
		
			
				|  |  | let redisConn = RedisClient.redisClient().connection;
 | 
	
		
			
				|  |  | let clientCache = require('../socket.io/client.cache').clientCache();
 | 
	
	
		
			
				|  | @ -17,6 +17,7 @@ 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 REDIS_KEYS = require('../../include/commons').REDIS_KEYS;
 | 
	
	
		
			
				|  | @ -38,7 +39,7 @@ class WechatClient extends RedisModel {
 | 
	
		
			
				|  |  |                 if (status == null) {
 | 
	
		
			
				|  |  |                     PatientRepo.findWechatOpenId(userId, handler);
 | 
	
		
			
				|  |  |                 } else {
 | 
	
		
			
				|  |  |                     handler(null, {open_id: status.open_id});
 | 
	
		
			
				|  |  |                     handler(null, {openid: status.openid});
 | 
	
		
			
				|  |  |                 }
 | 
	
		
			
				|  |  |             })
 | 
	
		
			
				|  |  |             .catch(function (err) {
 | 
	
	
		
			
				|  | @ -49,95 +50,119 @@ class WechatClient extends RedisModel {
 | 
	
		
			
				|  |  |     /**
 | 
	
		
			
				|  |  |      * 向微信端用户发送消息。若用户微信端在线,通过Web Socket推送给患者,如果不在线则通过微信的模板消息。
 | 
	
		
			
				|  |  |      *
 | 
	
		
			
				|  |  |      * @param targetUserId
 | 
	
		
			
				|  |  |      * @param message 消息
 | 
	
		
			
				|  |  |      */
 | 
	
		
			
				|  |  |     static sendMessage(message) {
 | 
	
		
			
				|  |  |         let patientClient = clientCache.findById(message.to);
 | 
	
		
			
				|  |  |     static sendMessage(targetUserId, message) {
 | 
	
		
			
				|  |  |         let patientClient = clientCache.findById(targetUserId);
 | 
	
		
			
				|  |  | 
 | 
	
		
			
				|  |  |         if (patientClient) {
 | 
	
		
			
				|  |  |             WechatClient.sendViaWebSocket(patientClient.socket, message);
 | 
	
		
			
				|  |  |         } else {
 | 
	
		
			
				|  |  |             log.info("User of wechat endpoint is not online, user id: ", message.to, ", sending via wechat template message.");
 | 
	
		
			
				|  |  |             log.info("User's wechat endpoint is not online, sending via wechat template message. User id: ", targetUserId);
 | 
	
		
			
				|  |  | 
 | 
	
		
			
				|  |  |             WechatClient.sendViaTemplateMessage(message);
 | 
	
		
			
				|  |  |             WechatClient.sendViaTemplateMessage(targetUserId, message);
 | 
	
		
			
				|  |  |         }
 | 
	
		
			
				|  |  |     };
 | 
	
		
			
				|  |  | 
 | 
	
		
			
				|  |  |     static sendViaWebSocket(socket, message){
 | 
	
		
			
				|  |  |         message.timestamp = ObjectUtil.timestampToLong(message.timestamp);
 | 
	
		
			
				|  |  |         socket.emit('message', 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)
 | 
	
		
			
				|  |  |         });
 | 
	
		
			
				|  |  |     }
 | 
	
		
			
				|  |  | 
 | 
	
		
			
				|  |  |     /**
 | 
	
		
			
				|  |  |      * 发送微信模板消息给居民
 | 
	
		
			
				|  |  |      *
 | 
	
		
			
				|  |  |      * @param targetUserId
 | 
	
		
			
				|  |  |      * @param message
 | 
	
		
			
				|  |  |      */
 | 
	
		
			
				|  |  |     static sendViaTemplateMessage(message) {
 | 
	
		
			
				|  |  |         function sendWxMessage(openid, name, topic) {
 | 
	
		
			
				|  |  |             let replyContent = message.content;
 | 
	
		
			
				|  |  |             switch (Number.parseInt(message.contentType)) {
 | 
	
		
			
				|  |  |                 case CONTENT_TYPES.Image:
 | 
	
		
			
				|  |  |                     replyContent = "[图片]";
 | 
	
		
			
				|  |  |                     break;
 | 
	
		
			
				|  |  |                 case CONTENT_TYPES.Audio:
 | 
	
		
			
				|  |  |                     replyContent = "[语音]";
 | 
	
		
			
				|  |  |                     break;
 | 
	
		
			
				|  |  |                 case 0:
 | 
	
		
			
				|  |  |                 case CONTENT_TYPES.Article:
 | 
	
		
			
				|  |  |                 case CONTENT_TYPES.GoTo:
 | 
	
		
			
				|  |  |                 case CONTENT_TYPES.TopicBegin:
 | 
	
		
			
				|  |  |                 case CONTENT_TYPES.TopicEnd:
 | 
	
		
			
				|  |  |                     return;
 | 
	
		
			
				|  |  |                 default:
 | 
	
		
			
				|  |  |                     break;
 | 
	
		
			
				|  |  |             }
 | 
	
		
			
				|  |  | 
 | 
	
		
			
				|  |  |             // 发送模板消息
 | 
	
		
			
				|  |  |             WechatSDK.sendTemplateMessage({
 | 
	
		
			
				|  |  |                 touser: openid,
 | 
	
		
			
				|  |  |                 template_id: config.wechatConfig.template.consultTemplate,
 | 
	
		
			
				|  |  |                 url: config.wechatConfig.baseUrl + "/wx/html/yszx/html/consulting-doctor.html?openid=" + openid +
 | 
	
		
			
				|  |  |                 "&consult=" + topic.name + "&toUser=" + message.to,
 | 
	
		
			
				|  |  |                 data: {
 | 
	
		
			
				|  |  |                     first: {value: "您的健康咨询有新的回复", color: "#000000"}
 | 
	
		
			
				|  |  |                     , remark: {value: "", color: "#000000"}
 | 
	
		
			
				|  |  |                     , keyword1: {value: topic.description, color: "#000000"}
 | 
	
		
			
				|  |  |                     , keyword2: {value: replyContent, color: "#000000"}
 | 
	
		
			
				|  |  |                     , keyword3: {value: name, color: "#000000"}
 | 
	
		
			
				|  |  |                 }
 | 
	
		
			
				|  |  |             });
 | 
	
		
			
				|  |  |         }
 | 
	
		
			
				|  |  |     static sendViaTemplateMessage(targetUserId, message) {
 | 
	
		
			
				|  |  |         async.waterfall([
 | 
	
		
			
				|  |  |                 // 获取微信openid
 | 
	
		
			
				|  |  |                 function (callback) {
 | 
	
		
			
				|  |  |                     PatientRepo.findWechatOpenId(targetUserId, function (err, result) {
 | 
	
		
			
				|  |  |                         if (err) {
 | 
	
		
			
				|  |  |                             ModelUtil.logError("Get wechat openid failed", err);
 | 
	
		
			
				|  |  |                             return;
 | 
	
		
			
				|  |  |                         }
 | 
	
		
			
				|  |  | 
 | 
	
		
			
				|  |  |         // 查询微信OpenId及医生信息,用于构建微信模板消息
 | 
	
		
			
				|  |  |         PatientRepo.findWechatOpenId(message.to, function (err, result) {
 | 
	
		
			
				|  |  |             if (err) {
 | 
	
		
			
				|  |  |                 ModelUtil.logError("Get wechat openid failed", err);
 | 
	
		
			
				|  |  |                 return;
 | 
	
		
			
				|  |  |             }
 | 
	
		
			
				|  |  | 
 | 
	
		
			
				|  |  |             let openid = result && result.length > 0 ? result[0].openid : "";
 | 
	
		
			
				|  |  |             if (openid) {
 | 
	
		
			
				|  |  |                 DoctorRepo.findOne(message.from, function (err, result) {
 | 
	
		
			
				|  |  |                     if (err) {
 | 
	
		
			
				|  |  |                         ModelUtil.logError("Get doctor info failed", err);
 | 
	
		
			
				|  |  |                         return;
 | 
	
		
			
				|  |  |                     }
 | 
	
		
			
				|  |  |                         let openid = result && result.length > 0 ? result[0].openid : null;
 | 
	
		
			
				|  |  |                         if (!openid) {
 | 
	
		
			
				|  |  |                             ModelUtil.logError("User haven't bound with wechat, user id: " + targetUserId);
 | 
	
		
			
				|  |  |                             return;
 | 
	
		
			
				|  |  |                         }
 | 
	
		
			
				|  |  | 
 | 
	
		
			
				|  |  |                         callback(null, openid);
 | 
	
		
			
				|  |  |                     });
 | 
	
		
			
				|  |  |                 },
 | 
	
		
			
				|  |  |                 // 获取议题信息
 | 
	
		
			
				|  |  |                 function (openid, callback) {
 | 
	
		
			
				|  |  |                     TopicRepo.findLastTopicStatus(message.session_id, function (err, res) {
 | 
	
		
			
				|  |  |                         if (err) {
 | 
	
		
			
				|  |  |                             ModelUtil.logError("Get topic failed", err);
 | 
	
		
			
				|  |  |                             return;
 | 
	
		
			
				|  |  |                         }
 | 
	
		
			
				|  |  | 
 | 
	
		
			
				|  |  |                     if (result && result.length > 0) {
 | 
	
		
			
				|  |  |                         let name = result[0].name;
 | 
	
		
			
				|  |  |                         let topic = result && result.length > 0 ? result[0] : "";
 | 
	
		
			
				|  |  |                         if (topic) {
 | 
	
		
			
				|  |  |                             sendWxMessage(openid, name, topic);
 | 
	
		
			
				|  |  |                         if (!res || res.length == 0) {
 | 
	
		
			
				|  |  |                             ModelUtil.logError("Unable to find session last topic");
 | 
	
		
			
				|  |  |                             return;
 | 
	
		
			
				|  |  |                         }
 | 
	
		
			
				|  |  |                     } else {
 | 
	
		
			
				|  |  |                         ModelUtil.logError("Can not find user info", err);
 | 
	
		
			
				|  |  | 
 | 
	
		
			
				|  |  |                         callback(null, openid, message.sender_name, res[0]);
 | 
	
		
			
				|  |  |                     });
 | 
	
		
			
				|  |  |                 },
 | 
	
		
			
				|  |  |                 // 发送消息
 | 
	
		
			
				|  |  |                 function (openid, senderName, topic, callback) {
 | 
	
		
			
				|  |  |                     let replyContent = message.content;
 | 
	
		
			
				|  |  |                     switch (Number.parseInt(message.contentType)) {
 | 
	
		
			
				|  |  |                         case CONTENT_TYPES.Image:
 | 
	
		
			
				|  |  |                             replyContent = "[图片]";
 | 
	
		
			
				|  |  |                             break;
 | 
	
		
			
				|  |  |                         case CONTENT_TYPES.Audio:
 | 
	
		
			
				|  |  |                             replyContent = "[语音]";
 | 
	
		
			
				|  |  |                             break;
 | 
	
		
			
				|  |  |                         case 0:
 | 
	
		
			
				|  |  |                         case CONTENT_TYPES.Article:
 | 
	
		
			
				|  |  |                         case CONTENT_TYPES.GoTo:
 | 
	
		
			
				|  |  |                         case CONTENT_TYPES.TopicBegin:
 | 
	
		
			
				|  |  |                         case CONTENT_TYPES.TopicEnd:
 | 
	
		
			
				|  |  |                             return;
 | 
	
		
			
				|  |  |                         default:
 | 
	
		
			
				|  |  |                             break;
 | 
	
		
			
				|  |  |                     }
 | 
	
		
			
				|  |  |                 });
 | 
	
		
			
				|  |  |             } else {
 | 
	
		
			
				|  |  |                 ModelUtil.logError("User haven't bound with wechat, user id: " + message.to, err);
 | 
	
		
			
				|  |  |             }
 | 
	
		
			
				|  |  |         });
 | 
	
		
			
				|  |  | 
 | 
	
		
			
				|  |  |                     // 发送模板消息
 | 
	
		
			
				|  |  |                     WechatSDK.sendTemplateMessage({
 | 
	
		
			
				|  |  |                         touser: openid,
 | 
	
		
			
				|  |  |                         template_id: config.wechatConfig.template.consultTemplate,
 | 
	
		
			
				|  |  |                         url: config.wechatConfig.baseUrl + "/wx/html/yszx/html/consulting-doctor.html?openid=" + openid +
 | 
	
		
			
				|  |  |                         "&consult=" + topic.name + "&toUser=" + targetUserId,
 | 
	
		
			
				|  |  |                         data: {
 | 
	
		
			
				|  |  |                             first: {value: "您的健康咨询有新的回复", color: "#000000"}
 | 
	
		
			
				|  |  |                             , remark: {value: "", color: "#000000"}
 | 
	
		
			
				|  |  |                             , keyword1: {value: topic.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!");
 | 
	
		
			
				|  |  |                 }
 | 
	
		
			
				|  |  |             });
 | 
	
		
			
				|  |  |     };
 | 
	
		
			
				|  |  | }
 | 
	
		
			
				|  |  | 
 |