Browse Source

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

yeshijie 6 years ago
parent
commit
fd7d73d9bd

+ 10 - 1
readme.md

@ -266,12 +266,21 @@ select m.`timestamp` as begin_date,m2.`timestamp` as end_date,t.session_id from
##专科医生的业务
1、专科医生和家庭医生聊天
/api/v2/sessions
 session_id : 居民code+"_"+专科医生行政团队code
 session_name : 某居民-共管对话
 session_type : 5
 participants: 此会话的成员列表,格式:["userId1:role", "userId2:role"],用户的ID及角色。
2.修改会话名称
/api/v2/sessions/:session_id/name
post请求
入参:sessionId:会话id
     name:新的会话名称
     name:新的会话名称
3、临时聊天组(由医生单聊在拉其他医生进来聊天后生成的新的会话)
/api/v2/sessions
 session_id : 为空(后台自动生成)
 session_name : 显示群组人名,用顿号隔开。超过10字省略显示
 session_type : 4
 participants: 此会话的成员列表,格式:["userId1:role", "userId2:role"],用户的ID及角色。

+ 47 - 0
src/server/endpoints/v2/session.endpoint.js

@ -89,6 +89,53 @@ router.get("/", function (req, res) {
});
/**
 * 按会话类型获取会话列表
 * 请求URL /sessions/sessionListByType?user_id=3121&page=0&size=10&type=4
 */
router.get(APIv2.Sessions.SessionListByType, function (req, res) {
    let page = req.query.page;
    let size = req.query.size;
    let userId = req.query.user_id;
    let type = req.query.type;
    if (!page) {
        throw {httpStatus: 406, message: 'Missing page.'};
    }
    if (!size) {
        throw {httpStatus: 406, message: 'Missing size.'};
    }
    if (!type) {
        throw {httpStatus: 406, message: 'Missing type.'};
    }
    if (!userId) {
        throw {httpStatus: 406, message: 'Missing user.'};
    }
    let sessions = new Sessions();
    ControllerUtil.regModelEventHandler(sessions, res);
    sessions.getUserSessionsByType(userId,type,page,size);
});
/**
 * 按会话类型获取会话总数
 * 请求URL /sessions/sessionCountByType?user_id=3121&type=4
 */
router.get(APIv2.Sessions.SessionCountByType, function (req, res) {
    let userId = req.query.user_id;
    let type = req.query.type;
    if (!type) {
        throw {httpStatus: 406, message: 'Missing type.'};
    }
    if (!userId) {
        throw {httpStatus: 406, message: 'Missing user.'};
    }
    let sessions = new Sessions();
    ControllerUtil.regModelEventHandler(sessions, res);
    sessions.getSessionCountByType(userId,type);
});
router.get(APIv2.Sessions.Session,function(req,res){
    let sessionId = req.params.session_id;
    let userId = req.query.user_id;

+ 1 - 1
src/server/endpoints/v2/user.endpoint.js

@ -53,7 +53,7 @@ router.post(APIv2.Users.Login, function (req, res) {
 *  /users/:user_id/status
 *
 * POST参数格式:
 *  {status: 1}, app状态,0在后台,1在前台
 *  {status: 1}, app状态,1在后台,0在前台(1的时候个推推送app消息)
 */
router.put(APIv2.Users.UserStatus, function (req, res) {
    let userId = req.params.user_id;

+ 4 - 2
src/server/include/commons.js

@ -84,6 +84,8 @@ const CONTENT_TYPES = {
    GoTo: 5,        // 跳转信息,求组其他医生或者邀请其他医生发送的推送消息
    TopicBegin: 6,  // 议题开始
    TopicEnd: 7,    // 议题结束 10 11 系统发送的会话消息
    PersonalCard: 18,    // 个人名片
    MessageForward: 19,    // 消息转发
    TopicInto: 14,    // 进入议题 系统发送的会话消息
    Video:12,//视频
    System:13,//系统消息
@ -202,7 +204,6 @@ const DB_TABLES = {
    P2pMessages: "p2p_messages",
    MucMessages: "muc_messages",
    GroupMessages: "group_messages",
    DiscussionMessages: "discussion_messages",
    SystemMessages: "system_messages",
    Participants: "participants",
    Sessions: "sessions",
@ -211,6 +212,7 @@ const DB_TABLES = {
    WlyyConsult:"wlyy_consults",
    WlyyConsultTeam:"wlyy.wlyy_consult_team",
    WlyyConsultS:"wlyy.wlyy_consult",
    WlyyMessage:"wlyy.wlyy_message",
    MessageNoticeSetting:"wlyy.wlyy_message_notice_setting",
    SignFamily:"wlyy.wlyy_sign_family",
@ -224,7 +226,7 @@ const DB_TABLES = {
        else if (sessionType == SESSION_TYPES.GROUP)
            return DB_TABLES.GroupMessages;
        else if (sessionType == SESSION_TYPES.DISCUSSION)
            return DB_TABLES.DiscussionMessages;
            return DB_TABLES.GroupMessages;
        else if (sessionType == SESSION_TYPES.PRESCRIPTION)
            return DB_TABLES.MucMessages;
        else if (sessionType == SESSION_TYPES.SPECIALISTGROUP)

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

@ -27,6 +27,8 @@ const APIv2 = {
        Base: '/api/v2/sessions',
        Session: '/:session_id/session',                                // 获取会话
        SessionListByType: '/sessionListByType',                        // 按会话类型获取会话
        SessionCountByType: '/sessionCountByType',                      // 按会话类型获取会话数量
        SessionSticky: '/:session_id/sticky',                           // 会话置顶,置顶使用PUT,取消置顶使用DELETE
        SessionStatus: '/:session_id/status',                           // 更新状态
        SessionName: '/:session_id/name',                               // 更新会话名称

+ 196 - 13
src/server/models/sessions/sessions.js

@ -121,8 +121,12 @@ class Sessions extends RedisModel {
            }
        } else {
            if (!sessionId) {
                handler("MUC OR GROUP session sessionId is not  allow null .", null);
                return;
                if(type == SESSION_TYPES.DISCUSSION){
                    sessionId = messageId;
                }else {
                    handler("MUC OR GROUP session sessionId is not  allow null .", null);
                    return;
                }
            }
            callBusinessType(sessionId);
        }
@ -130,6 +134,8 @@ class Sessions extends RedisModel {
        function callBusinessType(sessionId) {
            if(type == SESSION_TYPES.MUC||type == SESSION_TYPES.PRESCRIPTION){
                callCreate(sessionId, SESSION_BUSINESS_TYPE.PATIENT);
            }else if(type==SESSION_TYPES.DISCUSSION||type==SESSION_TYPES.GROUP){
                callCreate(sessionId, SESSION_BUSINESS_TYPE.DOCTOR);
            }else {
                ParticipantRepo.getBusinessType(participantIdArray, function (err, businessType) {
                    callCreate(sessionId, businessType);
@ -186,6 +192,9 @@ class Sessions extends RedisModel {
                    sessionId = res;
                    callBusinessType();
                });
            } else if(type == SESSION_TYPES.DISCUSSION){
                sessionId = messageId;
                callBusinessType();
            } else {
                return handler("MUC模式和团队模式,不允许sessionId为空!", null);
            }
@ -197,7 +206,7 @@ class Sessions extends RedisModel {
        function callBusinessType() {
            if(type==SESSION_TYPES.MUC||type==SESSION_TYPES.PRESCRIPTION){
                callCreateSession(SESSION_BUSINESS_TYPE.PATIENT);
            }else if(type==SESSION_TYPES.SPECIALISTGROUP){
            }else if(type==SESSION_TYPES.SPECIALISTGROUP||type==SESSION_TYPES.DISCUSSION){
                callCreateSession(SESSION_BUSINESS_TYPE.DOCTOR);
            }else{
                ParticipantRepo.getBusinessType(participantIdArray, function (err, businessType) {
@ -661,6 +670,149 @@ class Sessions extends RedisModel {
        ]);
    }
    /**
     * 查找会话数
     * @param userId
     * @param type
     * @param handler
     */
    getSessionCountByType(userId,type,handler){
        let self = this;
        SessionRepo.findSessionCountByType(userId,type,function (err,res) {
            if(res){
                ModelUtil.emitOK(self.eventEmitter,{status:200,count:res[0].count});
                return;
            }else {
                ModelUtil.emitOK(self.eventEmitter,{status:200,count:0});
                return;
            }
        })
    }
    /**
     * 根据用户类型获取用户的session列表
     * @param userId
     * @param page
     * @param size
     * @param businessType
     */
    getUserSessionsByType(userId,type,page, size) {
        let userSessionKey = RedisModel.makeRedisKey(REDIS_KEYS.UserSessions, userId);
        let self = this;
        async.waterfall([
            // 获取会话ID列表
            function (callback) {
                SessionRepo.findListByType(userId,type,page,size,function(err,res){
                    if (res.length == 0) {
                        ModelUtil.emitOK(self.eventEmitter, []);
                        return;
                    }
                    callback(null,res);
                })
            },
            // 遍历会话
            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 mysqlSession = sessionIds[index];
                        let sessionId = mysqlSession.id;
                        let sessionKey = RedisModel.makeRedisKey(REDIS_KEYS.Session, sessionId);
                        let sessionParticipantsKey = RedisModel.makeRedisKey(REDIS_KEYS.SessionParticipants, sessionId);
                        redis.multi()
                            .hgetall(sessionKey)                       // 会话实体
                            .zscore(sessionParticipantsKey, userId)    // 用户在此会话中最后一次获取未读消息的时间
                            .zrange(sessionParticipantsKey, 0, -1)
                            .zrange(sessionParticipantsKey, 0,-1,'withscores')  // 所有用户在此会话中最后一次获取未读消息的时间
                            .execAsync()
                            .then(function (res) {
                                let session = res[0];
                                let lastFetchTime = res[1];
                                let users = res[2];
                                let participantsTimeArray = res[3];
                                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 (!lastFetchTime) lastFetchTime = new Date().getTime();
                                // 计算未读消息数
                                let messagesByTimestampKey = RedisModel.makeRedisKey(REDIS_KEYS.MessagesByTimestamp, sessionId);
                                redis.zcountAsync(messagesByTimestampKey, parseInt(lastFetchTime)+1, 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: new Date(mysqlSession.last_message_time).getTime(),
                                                last_content_type: session.last_content_type,
                                                last_content: session.last_content,
                                                sender_id: session.last_sender_id,
                                                type: session.type,
                                                sender_name: session.last_sender_name,
                                                unread_count: count,
                                                business_type: session.business_type,
                                                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:"+sessionId+" failed: ", err);
                            });
                    };
                    functionList.push(fun);
                }
                async.waterfall(functionList);
            }
        ]);
    }
    /**
     * 根据用户ID获取用户已经结束咨询的session列表
     * @param userId
@ -1305,6 +1457,7 @@ class Sessions extends RedisModel {
                            })
                        }
                    }
                    // 消息保存到Redis,并更新会话最后状态、用户最后消息获取时间
                    messages.saveMessageToRedis(sessionId, sessionType, messageId, message);
                    Messages.updateLastContent(sessionKey, sessionType, sessionName, message);
@ -1351,6 +1504,10 @@ class Sessions extends RedisModel {
        }
    }
    static getMessagesBySessionId(){
    }
    sendTopicMessages(topicId, message) {
        let self = this;
        TopicRepo.findAllByTopicId(topicId, function (err, res) {
@ -1629,20 +1786,46 @@ class Sessions extends RedisModel {
                //告知医生新消息
                WechatClient.sendSocketMessageToDoctor(targetUserId,message);
                WlyySDK.request(targetUserId, '', '', '', '/im/common/message/messages', 'POST', function (err, res) {
                    let count = 0;
                    res =  JSON.parse(res)
                    if (res.status == 200) {
                        let data = res.data;
                        count = parseInt(JSON.parse(data.imMsgCount).count) + parseInt(data.system.amount) + parseInt(data.healthIndex.amount) + parseInt(data.sign.amount);
                let count = 0;
                //系统消息
                MessageRepo.getWlyyMessageCount(targetUserId,function (err,res) {
                    if(res){
                        count = res[0].count;
                    }
                    if(config.environment!='local'){//pc版不推送个推,通过redis的publish
                        AppClient.sendNotification(targetUserId, message,sessionType,count);
                });
                //im消息
                let sessions = new Sessions();
                sessions.getAllSessionsUnreadMessageCount(targetUserId,function (err,res) {
                    if(res){
                        count += res;
                    }
                    //外网pcim通过socket推送
                    WechatClient.sendPcImSocket(targetUserId,message,sessionType);
                });
                if(config.environment!='local'){//pc版不推送个推,通过redis的publish
                    AppClient.sendNotification(targetUserId, message,sessionType,count);
                }
                //外网pcim通过socket推送
                WechatClient.sendPcImSocket(targetUserId,message,sessionType);
                // WlyySDK.request(targetUserId, '', '', '', '/im/common/message/messages', 'POST', function (err, res) {
                //     let count = 0;
                //     if(err){
                //         logger.error(err);
                //     }else {
                //         logger.error(res);
                //         res =  JSON.parse(res)
                //         if (res.status == 200) {
                //             let data = res.data;
                //             count = parseInt(JSON.parse(data.imMsgCount).count) + parseInt(data.system.amount) + parseInt(data.healthIndex.amount) + parseInt(data.sign.amount);
                //         }
                //     }
                //     if(config.environment!='local'){//pc版不推送个推,通过redis的publish
                //         AppClient.sendNotification(targetUserId, message,sessionType,count);
                //     }
                //     //外网pcim通过socket推送
                //     WechatClient.sendPcImSocket(targetUserId,message,sessionType);
                // });
                message.targetUserId = targetUserId;
                message.targetUserName = targetUserName;
                message.sessionType = sessionType;

+ 14 - 0
src/server/repository/mysql/message.repo.js

@ -117,6 +117,20 @@ class MessageRepo {
        });
    }
    /**
     * i健康未读消息数
     * @param user
     * @param handler
     */
    static getWlyyMessageCount(user, handler) {
        let sql = "SELECT count(1) as count FROM "+DB_TABLES.WlyyMessage+" a WHERE a.has_read= 1 and a.receiver = ?";
        ImDb.execQuery({
            "sql": sql,
            "args": [user],
            "handler": handler
        });
    }
}
module.exports = MessageRepo;

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

@ -111,6 +111,51 @@ class SessionRepo {
        });
    }
    /**
     * 查找某类型的用户的会话数量
     * @param userId
     * @param type
     * @param handler
     */
    static findSessionCountByType(userId,type,handler){
        let sql = "select session_id count from " + DB_TABLES.Participants + " w where w.participant_id = ? group by w.session_id";
        let sessionSQL = "select count(id) count from " + DB_TABLES.Sessions + " s where s.id in(" + sql + ") and s.type=?";
        ImDb.execQuery({
            "sql": sessionSQL,
            "args": [userId, type],
            "handler": handler || function (err, res) {
                if(err) log.error(err);
            }
        });
    }
    /**
     * 分页获取用户会话列表
     * @param userId
     * @param type
     * @param handler
     */
    static findListByType(userId, type,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 id, name, type, create_date, last_sender_id, last_sender_name, last_content_type, last_content, last_message_time from "
            + DB_TABLES.Sessions + " s where s.id in(" + sql + ") and s.type=? order by s.last_message_time desc limit "+page+","+pagesize;
        ImDb.execQuery({
            "sql": sessionSQL,
            "args": [userId, type],
            "handler": handler || function (err, res) {
                if(err) log.error(err);
            }
        });
    }
    static findAllByTypeAndStatus(userId, businessType,status,page,pagesize, handler) {
        if (page > 0) {
            if (page == 1) {