/** * 议题模型。 */ "use strict"; let RedisClient = require('../../repository/redis/redis.client.js'); let TopicsRepo = require('../../repository/mysql/topics.repo'); let SessionRepo = require('../../repository/mysql/session.repo'); let TopicRepo = require('../../repository/mysql/topics.repo'); let ParticipantRepo = require('../../repository/mysql/participant.repo'); let RedisModel = require('./../redis.model.js'); let ModelUtil = require('../../util/model.util'); let Sessions = require("./sessions"); let log = require('../../util/log.js'); let redis = RedisClient.redisClient().connection; let configFile = require('../../include/commons').CONFIG_FILE; let config = require('../../resources/config/' + configFile); const REDIS_KEYS = require('../../include/commons').REDIS_KEYS; const TOPIC_STATUS = require('../../include/commons').TOPIC_STATUS; const SESSION_STATUS = require('../../include/commons').SESSION_STATUS; const SESSION_TYPES = require('../../include/commons').SESSION_TYPES; class Topics extends RedisModel { constructor() { super(); } getTopics(user, status, page, pagesize, sessionType) { let self = this; let session = new Sessions(); page = (page - 1 < 0 ? 0 : page - 1) * pagesize; if (!pagesize) pagesize = 10; pagesize = parseInt(pagesize); if (!sessionType) sessionType = SESSION_TYPES.MUC; SessionRepo.findAllByType(user, sessionType, function (err, res) { if (err) { ModelUtil.emitError(self.eventEmitter, "获取列表失败" + err); } else if (res && res.length == 0) { ModelUtil.emitOK(self.eventEmitter, []); } var sessionIds = []; for (var j in res) { sessionIds.push(res[j].id); } TopicsRepo.findAllBySessionIdsAndStatus(sessionIds, status, page, pagesize, function (err, res) { if (err) { ModelUtil.emitError(self.eventEmitter, "获取列表失败" + err); } else if (res && res.length == 0) { ModelUtil.emitOK(self.eventEmitter, []); } else { for (var j = 0; j < res.length; j++) { callAmount(j, res, res[j]); } } function callAmount(i, res, r) { session.getSessionUnreadMessageCount(res[i].session_id, user, function (err, msgcount) { if (err) { log.error("getSessionUnreadMessageCount is error:" + err); ModelUtil.emitError(self.eventEmitter, "获取未读消息失败!" + err); } else { callGetImg(i, res, r, msgcount); } }) } var result = []; function callGetImg(i, res, r, msgcount) { ParticipantRepo.findAll(res[i].session_id, function (err, p) { if (err) { log.error("获取头像失败:" + err); } else { r.create_time = r.create_time.getTime(); for (var j in p) { if (p[j].is_patient) { r.avatar = p[j].avatar; r.patient = p[j].id; r.patient_name = p[j].name; r.sex = p[j].sex; r.birthdate = p[j].birthdate.getTime(); if (r.status != TOPIC_STATUS.ENDED) { r.msg_count = msgcount; } } } result.push(r); if (result.length == res.length) { ModelUtil.emitOK(self.eventEmitter, res); } } }) } }) }) } /** * 根据状态和回复获取列表,已结束的不关心是否回复,所以传入status=10不reply无效 * @param user * @param reply * @param status * @param page * @param pagesize */ findAllByUserAndReplyAndStatus(users,reply, status, page, pagesize) { let self = this; page = (page - 1 < 0 ? 0 : page - 1) * pagesize; if (!pagesize) pagesize = 10; pagesize = parseInt(pagesize); TopicsRepo.findAllByUserAndReplyAndStatus(users,reply,status, page, pagesize, function (err, res) { if (err) { ModelUtil.emitError(self.eventEmitter, "获取列表失败" + err); } ModelUtil.emitOK(self.eventEmitter, res); }) } /** * 根据状态和回复获取列表,(过滤名医咨询) * @param user * @param reply * @param status * @param page * @param pagesize */ findAllByUserAndReplyAndStatusHealthTopic(users,reply, status, page, pagesize) { let self = this; page = (page - 1 < 0 ? 0 : page - 1) * pagesize; if (!pagesize) pagesize = 10; pagesize = parseInt(pagesize); TopicsRepo.findAllByUserAndReplyAndStatusHealthTopic(users,reply,status, page, pagesize, function (err, res) { if (err) { ModelUtil.emitError(self.eventEmitter, "获取列表失败" + err); } ModelUtil.emitOK(self.eventEmitter, res); }) } /** * 根据状态和回复及行政团队code获取列表,(过滤名医咨询) * @param user * @param reply * @param status * @param page * @param pagesize */ findAllByUserAndReplyAndStatusHealthTeamTopic(users,reply, status,adminTeamCode, page, pagesize) { let self = this; page = (page - 1 < 0 ? 0 : page - 1) * pagesize; if (!pagesize) pagesize = 10; pagesize = parseInt(pagesize); TopicsRepo.findAllByUserAndReplyAndStatusHealthTeamTopic(users,reply,status,adminTeamCode, page, pagesize, function (err, res) { if (err) { ModelUtil.emitError(self.eventEmitter, "获取列表失败" + err); } ModelUtil.emitOK(self.eventEmitter, res); }) } /** * 按类型查找医生的未回复,进行中,已完成的咨询 * @param users * @param reply * @param status * @param adminTeamCode * @param page * @param pagesize */ findAllTopicByType(users,reply, status,type,patientName,startTime,endTime, page, pagesize) { let self = this; page = (page - 1 < 0 ? 0 : page - 1) * pagesize; if (!pagesize) pagesize = 10; pagesize = parseInt(pagesize); TopicsRepo.findAllTopicByType(users,reply,status,type,patientName,startTime,endTime, page, pagesize, function (err, res) { if (err) { ModelUtil.emitError(self.eventEmitter, "获取列表失败" + err); } ModelUtil.emitOK(self.eventEmitter, res); }) } /** * 按类型查找医生的未回复,进行中,已完成的咨询 总数 * @param users * @param reply * @param status * @param adminTeamCode */ topicListCountByType(users,reply, status,type,patientName,startTime,endTime) { let self = this; TopicsRepo.topicListCountByType(users,reply,status,type,patientName,startTime,endTime, function (err, res) { if (err) { ModelUtil.emitError(self.eventEmitter, "获取总数失败" + err); } ModelUtil.emitOK(self.eventEmitter, {count:res[0].count}); }) } findReplyCount(users,reply, status,adminTeamCode) { let self = this; TopicsRepo.findReplyCount(users,reply,status,adminTeamCode, function (err, res) { if (err) { ModelUtil.emitError(self.eventEmitter, "获取列表失败" + err); } ModelUtil.emitOK(self.eventEmitter, res); }) } /** * 根据topicId获取对应的消息 * @param topicId * @param user * @param startMsgId * @param endMsgId * @param page * @param pagesize */ getTopicMessages(topicId, user, startMsgId, endMsgId, page, pagesize) { let self = this; TopicsRepo.findAllByTopicId(topicId, function (err, res) { if (err || res.length == 0) { ModelUtil.emitOK(self.eventEmitter, {status: -1, message: "找不到对应的会话记录!"}); } if(!res[0]||!res[0].session_id){ ModelUtil.emitOK(self.eventEmitter, {status: -1, message: err}); } let sessions = new Sessions(); sessions.getMessages(res[0].session_id, user, startMsgId, endMsgId, page, pagesize, 0, function (err, messages) { if (err) { ModelUtil.emitOK(self.eventEmitter, {status: 200, data: {"list":[],"users":[]}}); } else { if (messages && messages.length > 0) { ParticipantRepo.findAll(res[0].session_id, function (err, users) { if (err) { ModelUtil.emitOK(self.eventEmitter, {status: -1, message: err}); } else { ModelUtil.emitOK(self.eventEmitter, {status: 200, data: {"list": messages, "users": users}}); } }) } else { ModelUtil.emitOK(self.eventEmitter, {status: 200, data: {"list":[],"users":[]}}); } } }); }) } /** * 创建议题。 * * @param topicName 发起议题的名称 * @param topicId * @param sessionId * @param users 发起议题的患者,格式:{"userId1:role", "userId2:role"} * @param messages 发送的消息对象,格式:{description:"",title:"",img:"image1,image2",sender_id:"",sender_name:""},多个图片用逗号隔开 */ createTopic(topicName, topicId, sessionId, users, messages, sessionType) { let self = this; if (!sessionId && (sessionType == SESSION_TYPES.MUC|| sessionType == SESSION_TYPES.PRESCRIPTION || SESSION_TYPES.PRESCRIPTION_HOSPITAL || SESSION_TYPES.ONDOOR_NURSING)) { ModelUtil.emitOK(self.eventEmitter, {status: -1, message: "会话ID为空,请先生成会话ID"}); return; } if (!topicId) { ModelUtil.emitOK(self.eventEmitter, {status: -1, message: "议题ID为空,请先生成议题ID"}); return; } var pars = []; for (var j in users) { pars.push(j + ":" + users[j]); } let sessions = new Sessions(); sessions.createSession(sessionId, messages.sender_name, sessionType, pars, function (err, session) { sessionId = session.id; let datetime = session.create_date; //新增判断是否有未结束的咨询,用户网络差,会多次点击造成同时存在多个咨询 TopicRepo.findLastBySessionId(sessionId,function(err,res){ if(res&&res.length>0&&res[0].status!=10){ ModelUtil.emitOK(self.eventEmitter, {status: -1, message: "还有咨询未结束,不允许再次提交咨询!"}); return; }else{ self.saveTopicToRedis(topicName, topicId, sessionId, messages, datetime, function (err, startMsgId) { if (err) { log.error(err); ModelUtil.emitOK(self.eventEmitter, {status: -1, message: "议题创建失败!"}); return; } //返回给前端 ModelUtil.emitOK(self.eventEmitter, {status: 200, message: "议题创建成功!", start_msg_id: startMsgId}); sessions.updateSessionStatus(sessionId,SESSION_STATUS.PROCEEDINGS,function(err,res){}); //执行数据库操作 self.saveTopicToMySQL(topicName, topicId, sessionId, startMsgId, new Date(datetime), messages.description, TOPIC_STATUS.NEW, messages.agent, function (err, res) { if (err) { ModelUtil.logError("Save topic to mysql failed", err); } }) }) } }) }); } saveTopicToRedis(topicName, topicId, sessionId, messages, datetime, handler) { let topics_key = RedisModel.makeRedisKey(REDIS_KEYS.Topics, sessionId); let topic_key = RedisModel.makeRedisKey(REDIS_KEYS.Topic, topicId); let sessions = new Sessions(); //step1:创建topic到redis redis.zaddAsync(topics_key, datetime, topicId).then(function (res) { redis.hmsetAsync(topic_key, "name", topicName, "session_id", sessionId, "create_time", datetime, "description", messages.description, "status", TOPIC_STATUS.NEW, "end_time", "", "end_by", "" ).then(function (res) { sendBeginMsg(); }).catch(function (err) { handler(err, null); return; }); }).catch(function (err) { handler(err, null); return; }); //step2:发送开始会话 function sendBeginMsg() { let msg = {}; msg.sender_id = messages.sender_id; msg.sender_name = "系统";//messages.sender_name;发起和结束咨询的消息由系统发出,发送者ID记录操作人! msg.content_type = 10; msg.content = messages.sender_name + "发起了咨询"; msg.agent = null; msg.timestamp = new Date(datetime); sessions.saveMessageByTopic(msg, sessionId, function (err, msgId) { if (err) { handler(err, null); } else { sendQuesionMsg(); handler(null, msgId); } }) } //step3:发送求助内容的文本 function sendQuesionMsg() { let msg = {}; msg.sender_id = messages.sender_id; msg.sender_name = messages.sender_name; msg.content_type = 6; msg.content = messages.description; msg.agent = messages.agent; msg.timestamp = new Date(datetime+200); sessions.saveMessageByTopic(msg, sessionId, function (err, msgId) { if (messages.img) { setTimeout(function(){ sendQuesionImg(); },100); } if (err) { log.info("send create message error " + msg); } }); } //step4:发送求助内容的图片 function sendQuesionImg() { let imgs = messages.img.split(","); for (var j in imgs) { let msgimg = {}; msgimg.sender_id = messages.sender_id; msgimg.sender_name = messages.sender_name; msgimg.content_type = 2; msgimg.content = imgs[j]; msgimg.agent = messages.agent; msgimg.timestamp = new Date(datetime+(200*j)); sessions.saveMessageByTopic(msgimg, sessionId, function (err, msgId) { if (err) { log.info("send create img error " + imgs[j]); } }) } } } saveTopicToMySQL(topicName, topicId, sessionId, messageId, date, description, status, agent, handler) { TopicsRepo.saveTopic(topicName, topicId, sessionId, messageId, date, description, status, agent, handler); } /** * 议题是否已结束。 * * @param sessionId * @param topicId * @param handler */ isTopicEnded(sessionId, topicId, handler) { let self = this; if (topicId == "current") { TopicsRepo.findLastTopicStatus(sessionId, callback); } else { TopicsRepo.findTopicStatus(topicId, callback); } function callback(err, res) { if (err) { handler != null ? handler(err, res) : ModelUtil.emitError(self.eventEmitter, err); } else { if (null == res) { handler != null ? handler(err, res) : ModelUtil.emitOK(self.eventEmitter, {}); } else { let ended = res[0].status == TOPIC_STATUS.ENDED; handler != null ? handler(err, res) : ModelUtil.emitOK(self.eventEmitter, res[0]); } } } } /** * 结束议题 * @param topicId * @param endUser * @param endUserName */ endTopic(topicId, endUser, endUserName,agent) { let endDate = new Date(); let self = this; let topic_key = RedisModel.makeRedisKey(REDIS_KEYS.Topic, topicId); redis.hmsetAsync(topic_key, "end_time", endDate.getTime(), "end_by", endUser, "status", TOPIC_STATUS.ENDED).then(function (res) { // redis.hgetallAsync(topic_key).then(function (topic) { // callEnd(topic.session_id); // }) // redis 出错的时候 根据topic_key无法取出正确的sessionId,改成从数据库取 TopicsRepo.findOne(topicId,function (err, res){ if(err){ ModelUtil.emitOK(self.eventEmitter, {status: -1, "message": err}); }else { callEnd(res[0].session_id,topicId); } }); }); /** * 结束消息发送 */ function callEnd(sessionId,topicId) { let endMsgContent = "{\"msg\":\""+endUserName+"结束了咨询\",\"consultcode\":\""+topicId+"\"}" let msg = { sender_id: endUser, sender_name: "系统",//endUserName,发起和结束咨询的消息由系统发出,发送者ID记录操作人! agent: agent, content_type: 7, content: endMsgContent, timestamp: new Date() }; let sessions = new Sessions(); sessions.saveMessageByTopic(msg, sessionId, function (err, msgId) { if (err) { ModelUtil.emitOK(self.eventEmitter, {status: -1, "message": err}); } else { ModelUtil.emitOK(self.eventEmitter, {status: 200, "id": msgId, "message": "结束成功!"}); TopicsRepo.endTopic(topicId, endUser, msg.timestamp, msgId, TOPIC_STATUS.ENDED); sessions.updateSessionStatus(sessionId,SESSION_STATUS.ENDED,function(err,res){ log.info("update session end is success!"); }); } }) } } /** * 进入议题(发送提示医生,医生不在线就不发送) * @param topicId * @param intoUser * @param intoUserName */ intoTopic(topicId,intoUser,intoUserName,senderId,content){ log.info("1--进入议题:" + senderId); let intoDate = new Date(); let self = this; let topic_key = RedisModel.makeRedisKey(REDIS_KEYS.Topic, topicId); redis.hmsetAsync(topic_key, "into_time", intoDate.getTime(), "into_by", intoUser).then(function (res) { redis.hgetallAsync(topic_key).then(function (topic) { callEnd(topic.session_id); }) }); let agent = null; if(senderId!=intoUser){ agent = intoUser; } /** * 进入消息发送 */ function callEnd(sessionId) { let msg = { sender_id: senderId, sender_name: "系统",//endUserName,发起和结束(进入)咨询的消息由系统发出,发送者ID记录操作人! content_type: 14, //content: intoUserName + "进入了咨询", content: content, agent: agent, timestamp: new Date() }; let sessions = new Sessions(); sessions.saveIntoMessageByTopic(msg, sessionId, function (err, msgId) { log.info("3--sessions.saveIntoMessageByTopic: sessionId:" + sessionId); if (err) { ModelUtil.emitOK(self.eventEmitter, {status: -1, "message": err}); } else { ModelUtil.emitOK(self.eventEmitter, {status: 200, "id": msgId, "message": "进入成功!"}); } }) } } updateTopic(topicId, valueJson) { let self = this; let topickey = RedisModel.makeRedisKey(REDIS_KEYS.Topic, topicId); var dataArray = []; for (var j in valueJson) { dataArray.push(j); dataArray.push(valueJson[j]); } redis.hmsetAsync(topickey, dataArray).then(function (res) { TopicsRepo.updateTopics(topicId, valueJson, function (err, res) { if (!err) { ModelUtil.emitOK(self.eventEmitter, {"status": 200}); } else { ModelUtil.emitOK(self.eventEmitter, {"status": -1}); } }); }); } getTopicByTopicId(topicId){ let self = this; TopicsRepo.findAllByTopicId(topicId,function (err,res) { if (!err) { ModelUtil.emitOK(self.eventEmitter, {"status": 200,"data":res}); } else { ModelUtil.emitOK(self.eventEmitter, {"status": -1}); } }) } } // Expose class module.exports = Topics;