Browse Source

Merge branch 'feature-refactor' of yeshijie/im.doctor into feature-refactor

yeshijie 7 years ago
parent
commit
50739ba4d0

+ 15 - 1
src/server/endpoints/v2/topic.endpoint.js

@ -116,11 +116,25 @@ router.post(APIv2.Sessions.TopicEnded, function (req, res) {
    let endUser = payload.end_user;
    let endUserName = payload.end_user_name;
    let topicId = payload.topic_id;
    let agent = payload.agent;
    let topic = new Topics();
    ControllerUtil.regModelEventHandler(topic, res);
    topic.endTopic(topicId, endUser, endUserName);
    topic.endTopic(topicId, endUser, endUserName,agent);
});
router.post(APIv2.Sessions.TopicInto, function (req, res) {
    let payload = req.body;
    let intoUser = payload.into_user;
    let senderId = payload.sender_id;
    let intoUserName = payload.into_user_name;
    let topicId = payload.topic_id;
    let topic = new Topics();
    ControllerUtil.regModelEventHandler(topic, res);
    topic.intoTopic(topicId, intoUser, intoUserName,senderId,payload.content);
});

+ 1 - 0
src/server/include/commons.js

@ -80,6 +80,7 @@ const CONTENT_TYPES = {
    GoTo: 5,        // 跳转信息,求组其他医生或者邀请其他医生发送的推送消息
    TopicBegin: 6,  // 议题开始
    TopicEnd: 7,    // 议题结束 10 11 系统发送的会话消息
    TopicInto: 14,    // 进入议题 系统发送的会话消息
    Video:12,//视频
    System:13,//系统消息
    typeToDescription: function (type, defaultDescription) {

+ 1 - 0
src/server/include/endpoints.js

@ -34,6 +34,7 @@ const APIv2 = {
        Topics: '/:topic_id/topics',
        Topic: '/topics/:topic_id',                          // 议题,指定ID的议题将返回其信息
        TopicEnded: '/:session_id/topics/:topic_id/ended',              // 议题是否已结束,若top_id为current,则检查最后一个议题的状态
        TopicInto: '/:session_id/topics/:topic_id/into',              // 居民进入议题
        TopicList:'/topics',
        HealthTopicList:'/healthTopics', //健康咨询
        TopicReplyCount:"/topics/count/reply",

+ 3 - 2
src/server/models/client/wechat.client.js

@ -71,7 +71,8 @@ class WechatClient extends RedisModel {
                    log.error("patient sessionid "+patientClient.sessionId);
                    if(patientClient.sessionId==doctorClient.sessionId){
                    //用户socket在线,推送给用户后,告知医生此消息已读
                        WechatClient.updateParticipantLastFetchTime(doctorClient.sessionId, targetUserId, ObjectUtil.timestampToLong(message.timestamp));
                        //WechatClient.updateParticipantLastFetchTime(doctorClient.sessionId, targetUserId, ObjectUtil.timestampToLong(message.timestamp));
                        WechatClient.updateParticipantLastFetchTime(doctorClient.sessionId, message.sender_id, ObjectUtil.timestampToLong(message.timestamp));
                        WechatClient.sendReadDoctor(doctorClient.socket, message);
                    }
                }else{
@ -269,7 +270,7 @@ class WechatClient extends RedisModel {
                        touser: openid,
                        template_id: config.wechatConfig.template.consultTemplate,
                        url: config.wechatConfig.baseUrl + "/wx/html/yszx/html/consulting-doctor.html?openid=" + openid +
                        "&consult=" + topic.id + "&toUser=" + targetUserId + "&toName=" + targetUserName,
                        "&consult=" + topic.id + "&toUser=" + targetUserId + "&toName=" + targetUserName+"&represented="+message.sender_id,
                        data: {
                            first: {value: "您的健康咨询有新的回复", color: "#000000"}
                            , remark: {value: "", color: "#000000"}

+ 116 - 0
src/server/models/sessions/sessions.js

@ -11,6 +11,7 @@ let Users = require('../user/users');
let Participants = require('./participants');
let SessionRepo = require('../../repository/mysql/session.repo');
let TopicRepo = require('../../repository/mysql/topics.repo');
let MessageRepo = require('../../repository/mysql/message.repo');
let ParticipantRepo = require('../../repository/mysql/participant.repo');
let ImDb = require('../../repository/mysql/db/im.db');
let WlyySDK = require("../../util/wlyy.sdk");
@ -1171,6 +1172,7 @@ class Sessions extends RedisModel {
        let self = this;
        let sessionType = 0;
        let sessionName = "";
        let agent = message.agent;//代理人
        message.id = messageId;
        if(!message.timestamp){
            message.timestamp = new Date();
@ -1228,10 +1230,97 @@ class Sessions extends RedisModel {
                    participant.participant_role == PARTICIPANT_ROLES.HOST) {
                    Sessions.pushNotification(participant.id, participant.name, message,sessionType);
                }
                // if(agent&&participant.id == message.sender_id&&
                //     participant.participant_role == PARTICIPANT_ROLES.HOST){
                //     //有代理人时,也会发送消息给被代理者(此时)
                //     Sessions.pushNotification(participant.id, participant.name, message,sessionType);
                // }
            });
        }
    }
    /**
     * 保存代理人进入的消息
     *
     * @param message
     * @param sessionId
     * @param handler
     */
    saveIntoMessageByTopic(message, sessionId, handler) {
        let messages = new Messages();
        let participants = new Participants();
        let session_key = RedisModel.makeRedisKey(REDIS_KEYS.Session, sessionId);
        let messageId = mongoose.Types.ObjectId().toString();
        let self = this;
        let sessionType = 0;
        let sessionName = "";
        let agent = message.agent;//代理人
        message.id = messageId;
        if(!message.timestamp){
            message.timestamp = new Date();
        }
        // 发送成员必须处于会话中
        participants.existsParticipant(sessionId, message.sender_id, function (err, res) {
            if (res) {
                redis.hmgetAsync(session_key, ["type", "name"]).then(function (res) {
                    sessionType = res[0];
                    sessionName = res[1];
                    if (!sessionType || !sessionName) {
                        logger.error("Unknown session key " + session_key);
                        if (handler) {
                            handler(new Error("Unknown session key " + session_key));return;
                        };
                    }
                }).then(function (res) {
                    //查找最后一条数据,如果一致就不保存
                    MessageRepo.findLastMessage(sessionId,sessionType,function (err, res) {
                        if (err) {
                            logger.error(err);
                        } else {
                            res.forEach(function (mes) {
                                // if(mes.content==message.content&&message.content_type==mes.content_type){
                                if(mes.agent==message.agent){
                                    handler(null, messageId);
                                    return;
                                }else {
                                    // 消息数据双写,并更新用户最后消息获取时间,会话新状态等
                                    messages.saveMessageToRedis(sessionId, sessionType, messageId, message);
                                    messages.saveMessageToMysql(sessionId, sessionType, messageId, message);
                                    // 更新会话最新状态及成员最后一次消息获取时间
                                    Sessions.updateParticipantLastFetchTime(sessionId, message.sender_id, message.timestamp.getTime());
                                    Messages.updateLastContent(session_key, sessionType, sessionName, message);
                                    SessionRepo.updateSessionLastStatus(message.sender_id, message.sender_name, message.timestamp, message.content, message.content_type, sessionId);
                                    if (handler) {
                                        handler(null, messageId);
                                        return;
                                    }
                                }
                            })
                        }
                    });
                }).then(function (res) {
                    // 推送消息
                    ParticipantRepo.findDoctorIds(sessionId, function (err, res) {
                        if (err) {
                            logger.error(err);
                        } else {
                            message.session_id = sessionId;
                            res.forEach(function (participant) {
                                Sessions.pushIntoNotification(participant.id, participant.name, message,sessionType);
                            })
                        }
                    })
                }).catch(function (err) {
                    log.error(err);
                    return;
                })
            } else {
                if (handler){ handler("用户不在此会话当中!", messageId);return;}
            }
        });
    }
    /**
     * 置顶操作
     */
@ -1319,6 +1408,18 @@ class Sessions extends RedisModel {
        Users.isPatientId(targetUserId, function (err, isPatient) {
            if (isPatient) {
                WechatClient.sendMessage(targetUserId, targetUserName, message);
                // 推送代理人消息
                ParticipantRepo.findFamilyIds(message.session_id, function (err, res) {
                    if (err) {
                        logger.error(err);
                    } else {
                        res.forEach(function (participant) {
                            if (participant.id != message.sender_id){
                                WechatClient.sendMessage(participant.id, participant.name, message);
                            }
                        })
                    }
                })
            }
            else {
                if(sessionType==SESSION_TYPES.P2P){
@ -1339,6 +1440,21 @@ class Sessions extends RedisModel {
        });
    }
    /**
     * 向APP端通过socket发送通知消息。
     *
     * @param targetUserId
     * @param message
     */
    static pushIntoNotification(targetUserId, targetUserName, message,sessionType) {
        if(sessionType==SESSION_TYPES.P2P){
            WechatClient.sendReadDoctorByDoctorId(targetUserId, message);
        }
        //告知医生新消息
        WechatClient.sendSocketMessageToDoctor(targetUserId,message);
    }
    /**
     * 针对MUC模式更新会话的当前状态
     * @param sessionId

+ 54 - 4
src/server/models/sessions/topics.js

@ -229,7 +229,7 @@ class Topics extends RedisModel {
                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, 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);
                    }
@ -267,6 +267,7 @@ class Topics extends RedisModel {
            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) {
@ -285,6 +286,7 @@ class Topics extends RedisModel {
            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) {
@ -306,6 +308,7 @@ class Topics extends RedisModel {
                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) {
@ -317,8 +320,8 @@ class Topics extends RedisModel {
    }
    saveTopicToMySQL(topicName, topicId, sessionId, messageId, date, description, status, handler) {
        TopicsRepo.saveTopic(topicName, topicId, sessionId, messageId, date, description, status, handler);
    saveTopicToMySQL(topicName, topicId, sessionId, messageId, date, description, status, agent, handler) {
        TopicsRepo.saveTopic(topicName, topicId, sessionId, messageId, date, description, status, agent, handler);
    }
    /**
@ -357,7 +360,7 @@ class Topics extends RedisModel {
     * @param endUser
     * @param endUserName
     */
    endTopic(topicId, endUser, endUserName) {
    endTopic(topicId, endUser, endUserName,agent) {
        let endDate = new Date();
        let self = this;
        let topic_key = RedisModel.makeRedisKey(REDIS_KEYS.Topic, topicId);
@ -374,6 +377,7 @@ class Topics extends RedisModel {
            let msg = {
                sender_id: endUser,
                sender_name: "系统",//endUserName,发起和结束咨询的消息由系统发出,发送者ID记录操作人!
                agent: agent,
                content_type: 7,
                content: endUserName + "结束了咨询",
                timestamp: new Date()
@ -394,6 +398,52 @@ class Topics extends RedisModel {
        }
    }
    /**
     * 进入议题(发送提示医生,医生不在线就不发送)
     * @param topicId
     * @param intoUser
     * @param intoUserName
     */
    intoTopic(topicId,intoUser,intoUserName,senderId,content){
        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) {
                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);

+ 35 - 7
src/server/repository/mysql/message.repo.js

@ -77,18 +77,46 @@ class MessageRepo {
     * @param handler
     */
    static save(message, sessionType, messageId, sessionId, handler) {
        let sql = "INSERT INTO " + DB_TABLES.sessionTypeToTableName(sessionType) +
            " (id, session_id, sender_id, sender_name,content_type, content, timestamp,business_type) VALUES (?,?,?,?,?,?,?,?)";
        if(message.agent){
            let sql = "INSERT INTO " + DB_TABLES.sessionTypeToTableName(sessionType) +
                " (id, session_id, sender_id, sender_name,content_type, content, timestamp,business_type,agent) VALUES (?,?,?,?,?,?,?,?,?)";
            ImDb.execQuery({
                "sql": sql,
                "args": [messageId, sessionId, message.sender_id, message.sender_name, message.content_type, message.content, message.timestamp, message.business_type || 1,message.agent],
                "handler": handler || function (err, res) {
                    if(err) log.error(err);
                }
            });
        }else {
            let sql = "INSERT INTO " + DB_TABLES.sessionTypeToTableName(sessionType) +
                " (id, session_id, sender_id, sender_name,content_type, content, timestamp,business_type) VALUES (?,?,?,?,?,?,?,?)";
            ImDb.execQuery({
                "sql": sql,
                "args": [messageId, sessionId, message.sender_id, message.sender_name, message.content_type, message.content, message.timestamp, message.business_type || 1],
                "handler": handler || function (err, res) {
                    if(err) log.error(err);
                }
            });
        }
    }
    /**
     * 获取会话医生的id
     * @param sessionId
     * @param handler
     */
    static findLastMessage(sessionId,sessionType,handler){
        let sql =
            "SELECT s.content_type, s.content,s.agent FROM " + DB_TABLES.sessionTypeToTableName(sessionType) + " s " +
            "WHERE s.session_id = ? order by s.timestamp desc limit 1 ";
        ImDb.execQuery({
            "sql": sql,
            "args": [messageId, sessionId, message.sender_id, message.sender_name, message.content_type, message.content, message.timestamp, message.business_type || 1],
            "handler": handler || function (err, res) {
                if(err) log.error(err);
            }
            "args": [sessionId],
            "handler": handler
        });
    }
}
module.exports = MessageRepo;

+ 37 - 1
src/server/repository/mysql/participant.repo.js

@ -56,7 +56,7 @@ class ParticipantRepo {
            "WHERE s.id = ? AND s.id = p.session_id AND p.participant_id = u.id " +
            "UNION " +
            "SELECT u.id, u.name, true is_patient, p.participant_role,u.avatar FROM sessions s, participants p, patients u " +
            "WHERE s.id = ? AND s.id = p.session_id AND p.participant_id = u.id";
            "WHERE s.id = ? AND s.id = p.session_id AND p.participant_id = u.id ";
        ImDb.execQuery({
            "sql": sql,
@ -65,6 +65,42 @@ class ParticipantRepo {
        });
    }
    /**
     * 获取会话医生的id
     * @param sessionId
     * @param handler
     */
    static findDoctorIds(sessionId,handler){
        let sql =
            "SELECT u.id, u.name, false is_patient, p.participant_role,u.avatar FROM sessions s, participants p, doctors u " +
            "WHERE s.id = ? AND s.id = p.session_id AND p.participant_id = u.id ";
        ImDb.execQuery({
            "sql": sql,
            "args": [sessionId],
            "handler": handler
        });
    }
    /**
     * 获取会话的居民的家庭成员
     * @param sessionId
     * @param handler
     */
    static findFamilyIds(sessionId, handler){
        let sql =
            "SELECT u.id, u.name, true is_patient, p.participant_role,u.avatar " +
            "FROM sessions s, participants p, patients u ,wlyy.wlyy_patient_family_member m " +
            "WHERE s.id = ? and s.id = p.session_id and p.participant_id = m.id AND m.family_member = u.id";
        //新增发送代理人
        ImDb.execQuery({
            "sql": sql,
            "args": [sessionId],
            "handler": handler
        });
    }
    /**
     * 获取会话的成员头像列表
     *

+ 4 - 3
src/server/repository/mysql/topics.repo.js

@ -227,13 +227,14 @@ class TopicRepo {
     * @param date
     * @param description
     * @param status
     * @param agent
     * @param handler
     */
    static saveTopic(topicName, topicId, sessionId, messageId, date, description, status, handler) {
        let sql = "insert into " + DB_TABLES.Topics + " (id,session_id,name,create_time,start_message_id,description,status) VALUES (?,?,?,?,?,?,?)";
    static saveTopic(topicName, topicId, sessionId, messageId, date, description, status, agent, handler) {
        let sql = "insert into " + DB_TABLES.Topics + " (id,session_id,name,create_time,start_message_id,description,status,agent) VALUES (?,?,?,?,?,?,?,?)";
        ImDb.execQuery({
            "sql": sql,
            "args": [topicId, sessionId, topicName, date, messageId, description, status],
            "args": [topicId, sessionId, topicName, date, messageId, description, status, agent],
            "handler": function (err, res) {
                handler(err, res);
            }