浏览代码

医生socket开发

8 年之前
父节点
当前提交
e1ac47a3c6

+ 7 - 1
src/server/endpoints/v2/session.endpoint.js

@ -67,6 +67,7 @@ router.get("/", function (req, res) {
    let size = req.query.size;
    let userId = req.query.user_id;
    let businessType = req.query.business_type;
    let status = req.query.status;
    if (!page) {
        throw {httpStatus: 406, message: 'Missing page.'};
    }
@ -79,7 +80,12 @@ router.get("/", function (req, res) {
    let sessions = new Sessions();
    ControllerUtil.regModelEventHandler(sessions, res);
    sessions.getUserSessions(userId, page, size, businessType);
    //传入参数齐全走过滤方法
    if(status&&businessType&&userId&&size&&page){
        sessions.getUserStatusSessions(userId,status,businessType,page,size);
    }else{
        sessions.getUserSessions(userId, page, size, businessType);
    }
});

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

@ -43,6 +43,11 @@ const TOPIC_STATUS = {
    ENDED: 10        // 结束
};
exports.SESSION_STATUS = {
    PROCEEDINGS: 0,     // 进行中
    ENDED:1        // 结束
};
/**
 * 会话业务类型
 */

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

@ -89,7 +89,8 @@ class WechatClient extends RedisModel {
            content: message.content,
            timestamp: ObjectUtil.timestampToLong(message.timestamp),
            type: message.content_type,          // legacy support
            name: message.sender_name
            name: message.sender_name,
            sender_img : message.sender_img
        });
    }
@ -128,7 +129,7 @@ class WechatClient extends RedisModel {
            return;
        }
        let sendDoctorClient = clientCache.findByIdAndType(message.sender_id,SOCKET_TYPES.DOCTOR);
        if(sendDoctorClient.sessionId==doctorClient.sessionId){
        if(sendDoctorClient&&sendDoctorClient.sessionId==doctorClient.sessionId){
            sendDoctorClient.socket.emit('message', {
                id: message.id,
                session_id: message.session_id,

+ 157 - 10
src/server/models/sessions/sessions.js

@ -27,6 +27,7 @@ const REDIS_KEYS = require('../../include/commons').REDIS_KEYS;
const SESSION_TYPES = require('../../include/commons').SESSION_TYPES;
const STICKY_SESSION_BASE_SCORE = require('../../include/commons').STICKY_SESSION_BASE_SCORE;
const PARTICIPANT_ROLES = require('../../include/commons').PARTICIPANT_ROLES;
const SESSION_STATUS = require('../../include/commons').SESSION_STATUS;
class Sessions extends RedisModel {
    constructor() {
@ -445,6 +446,137 @@ class Sessions extends RedisModel {
        ]);
    }
    /**
     * 根据用户ID获取用户已经结束咨询的session列表
     * @param userId
     * @param page
     * @param size
     * @param businessType
     */
    getUserStatusSessions(userId,status,businessType,page, size) {
        let userSessionKey = RedisModel.makeRedisKey(REDIS_KEYS.UserSessions, userId);
        let self = this;
        async.waterfall([
            // 获取会话ID列表
            function (callback) {
                SessionRepo.findAllByTypeAndStatus(userId,businessType,status,page,size,function(err,res){
                    if (res.length == 0) {
                        ModelUtil.emitOK(self.eventEmitter, []);
                        return;
                    }
                    var sessionIds=[];
                    for(var j in res){
                        sessionIds.push(res[j].id);
                    }
                    callback(null,sessionIds);
                })
            },
            // 遍历会话
            function (sessionIds) {
                let sessionList = [];
                let functionList = [];
                for (let j = 0; j < sessionIds.length; j++) {
                    let fun = function (index, callback) {
                        if (!callback) {
                            callback = index, index = 0
                        }
                        let sessionId = sessionIds[index];
                        let sessionKey = RedisModel.makeRedisKey(REDIS_KEYS.Session, sessionId);
                        let participantsRoleKey = RedisModel.makeRedisKey(REDIS_KEYS.SessionParticipantsRole, sessionId);
                        let sessionParticipantsKey = RedisModel.makeRedisKey(REDIS_KEYS.SessionParticipants, sessionId);
                        redis.multi()
                            .hgetall(sessionKey)                       // 会话实体
                            .hget(participantsRoleKey, userId)         // 用户在此会话中的角色
                            .zscore(sessionParticipantsKey, userId)    // 用户在此会话中最后一次获取未读消息的时间
                            .zrange(sessionParticipantsKey, 0, -1)
                            .zrange(sessionParticipantsKey, 0,-1,'withscores')  // 所有用户在此会话中最后一次获取未读消息的时间
                            .execAsync()
                            .then(function (res) {
                                let session = res[0];
                                let role = res[1];
                                let lastFetchTime = res[2];
                                let users = res[3];
                                let participantsTimeArray = res[4];
                                let participantsTime = [];
                                for(var j = 0 ;j<participantsTimeArray.length;j++){
                                    if(j%2!=0)continue;
                                    let participantsTimeJson = {};
                                    participantsTimeJson[participantsTimeArray[j]] = participantsTimeArray[j+1];
                                    participantsTime.push(participantsTimeJson);
                                }
                                let sessionName = "";
                                let otherUserId = "";
                                if (session.type == SESSION_TYPES.P2P) {
                                    for (let j in users) {
                                        if (users[j] != userId) {
                                            otherUserId = users[j];
                                        }
                                    }
                                }
                                if (!role) role = 0;
                                if (!lastFetchTime) lastFetchTime = new Date().getTime();
                                // 计算未读消息数
                                let messagesByTimestampKey = RedisModel.makeRedisKey(REDIS_KEYS.MessagesByTimestamp, sessionId);
                                redis.zcountAsync(messagesByTimestampKey, lastFetchTime, new Date().getTime())
                                    .then(function (count) {
                                        if (!otherUserId) otherUserId = userId;
                                        ParticipantRepo.findNameById(otherUserId, function (err, res) {
                                            if ((res && res.length == 0) || session.type != SESSION_TYPES.P2P) {
                                                sessionName = session.name;
                                            } else {
                                                sessionName = res[0].name;
                                            }
                                            var bir = new Date().getTime();
                                            if (res.length != 0 && res[0].birthdate) {
                                                bir = res[0].birthdate.getTime();
                                            }
                                            var sex = 1;
                                            if (res.length != 0 && res[0].sex) {
                                                sex = res[0].sex;
                                            }
                                            sessionList.push({
                                                id: sessionId,
                                                name: sessionName,
                                                create_date: session.create_date,
                                                last_content_type: session.last_content_type,
                                                last_content: session.last_content,
                                                sender_id: session.sender_id,
                                                type: session.type,
                                                sender_name: session.sender_name,
                                                unread_count: count,
                                                business_type: session.business_type,
                                                my_role: role,
                                                sender_sex: sex,
                                                sender_birthday: bir,
                                                participantsTimeArray:participantsTime,
                                                status:session.status
                                            });
                                            index = (parseInt(index) + 1);
                                            if (index == sessionIds.length) {
                                                ModelUtil.emitOK(self.eventEmitter, sessionList);
                                            } else {
                                                callback(null, index);
                                            }
                                        })
                                    })
                            })
                            .catch(function (err) {
                                logger.error("Get sessions failed: ", err);
                            });
                    };
                    functionList.push(fun);
                }
                async.waterfall(functionList);
            }
        ]);
    }
    /**
     * 获取会话消息。全部,不管已读/未读状态。
@ -868,13 +1000,12 @@ class Sessions extends RedisModel {
                            ModelUtil.logError("Push message from session: get participant's id list failed: ", err);
                        } else {
                            message.session_id = sessionId;
                            res.forEach(function (participant) {
                                if (participant.id !== message.sender_id &&
                                    participant.participant_role == PARTICIPANT_ROLES.HOST) {
                                    Sessions.pushNotification(participant.id, participant.name, message);
                                if (participant.id == message.sender_id){
                                    message.sender_img = participant.avatar;
                                    callPush(res,message);
                                }
                            });
                            })
                        }
                    })
                }).catch(function (err) {
@ -884,6 +1015,14 @@ class Sessions extends RedisModel {
                ModelUtil.emitDataNotFound(self.eventEmitter, {message: "当前会话找不到此发送者"});
            }
        });
        function callPush(participants,message){
            participants.forEach(function (participant) {
                if (participant.id !== message.sender_id &&
                    participant.participant_role == PARTICIPANT_ROLES.HOST) {
                    Sessions.pushNotification(participant.id, participant.name, message);
                }
            });
        }
    }
    sendTopicMessages(topicId, message) {
@ -950,11 +1089,11 @@ class Sessions extends RedisModel {
                        } else {
                            message.session_id = sessionId;
                            res.forEach(function (participant) {
                                if (participant.id !== message.sender_id &&
                                    participant.participant_role == PARTICIPANT_ROLES.HOST) {
                                    Sessions.pushNotification(participant.id, participant.name, message);
                                if (participant.id == message.sender_id){
                                    message.sender_img = participant.avatar;
                                    callPush(res,message);
                                }
                            });
                            })
                        }
                    })
                }).catch(function (err) {
@ -963,7 +1102,15 @@ class Sessions extends RedisModel {
            } else {
                if (handler){ handler("用户不在此会话当中!", messageId);return;}
            }
        })
        });
        function callPush(participants,message){
            participants.forEach(function (participant) {
                if (participant.id !== message.sender_id &&
                    participant.participant_role == PARTICIPANT_ROLES.HOST) {
                    Sessions.pushNotification(participant.id, participant.name, message);
                }
            });
        }
    }
    /**

+ 2 - 1
src/server/models/sessions/topics.js

@ -18,6 +18,7 @@ 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 {
@ -331,7 +332,7 @@ class Topics extends RedisModel {
                } else {
                    ModelUtil.emitOK(self.eventEmitter, {status: 200, "id": msgId, "message": "结束成功!"});
                    TopicsRepo.endTopic(topicId, endUser, msg.timestamp, msgId, TOPIC_STATUS.ENDED);
                    sessions.updateSessionStatus(sessionId,1);
                    sessions.updateSessionStatus(sessionId,SESSION_STATUS.ENDED);
                }
            })
        }

+ 2 - 2
src/server/repository/mysql/participant.repo.js

@ -50,10 +50,10 @@ class ParticipantRepo {
     */
    static findIds(sessionId, handler) {
        let sql =
            "SELECT u.id, u.name, false is_patient, p.participant_role FROM sessions s, participants p, doctors u " +
            "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 " +
            "UNION " +
            "SELECT u.id, u.name, true is_patient, p.participant_role FROM sessions s, participants p, patients u " +
            "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";
        ImDb.execQuery({

+ 20 - 0
src/server/repository/mysql/session.repo.js

@ -69,6 +69,26 @@ class SessionRepo {
        });
    }
    static findAllByTypeAndStatus(userId, businessType,status,page,pagesize, handler) {
        if (page > 0) {
            if (page == 1) {
                page = 0;
            }else{
                page = (parseInt(page)-1) * parseInt(pagesize);
            }
        }
        let sql = "select session_id from " + DB_TABLES.Participants + " w where w.participant_id = ? group by w.session_id";
        let sessionSQL = "select * from "
            + DB_TABLES.Sessions + " s where s.id in(" + sql + ") and s.business_type = ? and s.status = ? limit "+page+","+pagesize;
        ImDb.execQuery({
            "sql": sessionSQL,
            "args": [userId, businessType,status],
            "handler": handler || function (err, res) {
                if(err) log.error(err);
            }
        });
    }
    /**
     * 按时间跨度查询会话。
     *

+ 1 - 1
src/server/repository/redis/redis.client.js

@ -66,7 +66,7 @@ function uncaughtExceptionHandler(err){
    if(err && err.code == 'ECONNREFUSED'){
        //do someting
    }else{
        process.exit(1);
        log.error(err+"exit in redis");
    }
}
process.on('uncaughtException', uncaughtExceptionHandler);