yeshijie 7 vuotta sitten
vanhempi
commit
5ef8d29752

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

@ -210,6 +210,8 @@ const DB_TABLES = {
    WlyyConsult:"wlyy_consults",
    WlyyConsultTeam:"wlyy.wlyy_consult_team",
    WlyyConsultS:"wlyy.wlyy_consult",
    MessageNoticeSetting:"wlyy.wlyy_message_notice_setting",
    SignFamily:"wlyy.wlyy_sign_family",
    sessionTypeToTableName: function (sessionType) {
        if (sessionType == SESSION_TYPES.SYSTEM)

+ 29 - 0
src/server/models/client/app.client.js

@ -6,6 +6,8 @@
let RedisClient = require('../../repository/redis/redis.client');
let RedisModel = require('./../redis.model');
let AppStatusRepo = require('../../repository/mysql/app.status.repo');
let MessageNoticeSettingRepo = require('../../repository/mysql/message.noticeSetting.repo');
let SignFamilyRepo = require('../../repository/mysql/sign.family.repo');
let ModelUtil = require('../../util/model.util');
let clientCache = require('../socket.io/client.cache').clientCache();
let WlyyAssistantSDK = require("../../util/wlyyAssistant.sdk");
@ -111,6 +113,33 @@ class AppClient extends RedisModel {
                    return;
                }
                if(sessionType==SESSION_TYPES.SYSTEM||
                    sessionType==SESSION_TYPES.MUC||
                    sessionType==SESSION_TYPES.P2P||
                    sessionType==SESSION_TYPES.GROUP||
                    sessionType==SESSION_TYPES.DISCUSSION||
                    sessionType==SESSION_TYPES.PRESCRIPTION){
                    //是否发送消息
                    MessageNoticeSettingRepo.findOne(targetId,'1',function (err,res) {
                        if(res&&res.length>0){
                            let master_switch = res[0].master_switch;
                            let im_switch = res[0].im_switch;
                            let family_topic_switch = res[0].family_topic_switch;
                            if(master_switch==0||im_switch==0){
                                ModelUtil.logError(targetId+"-关闭im消息,消息id", message.id);
                                return;
                            }else if(sessionType==SESSION_TYPES.MUC&&family_topic_switch==0){
                                SignFamilyRepo.isHealthDoctor(message.session_id,targetId,function (err,res) {
                                    if(res&&res.length==0){
                                        ModelUtil.logError("全科医生:"+targetId+"-关闭im消息,消息id", message.id);
                                        return;
                                    }
                                })
                            }
                        }
                    });
                }
                // let pc_doctorClient = clientCache.findByIdAndType("pc_"+targetId,SOCKET_TYPES.PC_DOCTOR);
                // if(pc_doctorClient){
                //     log.warn("User's pc is online, user id: " + targetId + ", we cannot send getui.");

+ 26 - 136
src/server/models/redis/pubSub.js

@ -45,150 +45,40 @@ class PubSub{
            {
                console.log("接收消息:"+message);
                message = JSON.parse(message);
                message.timestamp = new Date(message.timestamp);
                let sessionId = message.session_id;
                let sessionKey = RedisModel.makeRedisKey(REDIS_KEYS.Session, sessionId);
                redis.hexistsAsync(sessionKey, sessionId).then(function(res){
                    if(res==0){
                        ////新增session时 要先把session缓存到redis
                        SessionRepo.findOne(sessionId, function (err, res) {
                            if (res.length > 0) {//已经存在
                                let type =  res[0].type;
                                let createDate = res[0].create_date;
                                let session = {
                                    id: sessionId,
                                    name: res[0].name,
                                    type: type,
                                    create_date: createDate.getTime(),
                                    business_type: res[0].business_type
                                };
                                redis.hmsetAsync(sessionKey, session).then(function () {
                                    ParticipantRepo.findParricipantBySessionId(sessionId,function (err,res) {
                                        // 构造会话,成员及成员角色zset, hash所需要的数据
                                        let userSessions = {};
                                        let sessionParticipants = [];
                                        let sessionParticipantsRoles = [];
                                        res.forEach(function (item) {
                                            let participant_id = item.participant_id;
                                            let participant_role = item.participant_role;
                                            userSessions[RedisModel.makeRedisKey(REDIS_KEYS.UserSessions, participant_id)] = [createDate.getTime(), sessionId];
                                            sessionParticipants.push(createDate.getTime());
                                            sessionParticipants.push(participant_id);
                                            sessionParticipantsRoles.push(participant_id, participant_role);
                                        });
                                        // 向会话成员、会话成员角色集合中添加数据
                                        let sessionParticipantsKey = RedisModel.makeRedisKey(REDIS_KEYS.SessionParticipants, sessionId);
                                        let sessionParticipantsRoleKey = RedisModel.makeRedisKey(REDIS_KEYS.SessionParticipantsRole, sessionId);
                                        let multi = redis.multi()
                                            .zadd(sessionParticipantsKey, sessionParticipants)
                                            .hmset(sessionParticipantsRoleKey, sessionParticipantsRoles);
                if(config.pubSubSwitch){//接收订阅消息处理开关,本地运行和测试库单独运行时防止用户接收消息2次
                    //Sessions.getRedisPushNotification(message);这里不知为什么无法调用这个方法,提示getRedisPushNotification不是方法
                    if (message.targetType=='patient') {
                        if(config.environment!='local'){//pc版接收要发给居民的消息不做处理
                            WechatClient.sendMessage(message.targetUserId, message.targetUserName, message);
                        }
                    } else {
                        if(message.sessionType=="1"){
                            WechatClient.sendReadDoctorByDoctorId(message.targetUserId, message);
                        }
                        //告知医生新消息
                        WechatClient.sendSocketMessageToDoctor(message.targetUserId,message);
                        if(config.environment!='local'){//pc版不推送个推
                            WlyySDK.request(message.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);
                                }
                                        // 更新用户参与的会话列表
                                        for (let key in userSessions) {
                                            multi = multi.zadd(key, userSessions[key]);
                                        }
                                        multi.execAsync().then(function (res) {
                                            sendMessage(sessionId,message,sessionKey);
                                        }).catch(function (ex) {
                                            logger.error("Save participants to redis failed: ", ex);
                                        });
                                    });
                                })
                            }
                        });
                    }else {
                        sendMessage(sessionId,message,sessionKey);
                                AppClient.sendNotification(message.targetUserId, message,message.sessionType,count);
                            });
                        }
                        //外网pcim通过socket推送
                        WechatClient.sendPcImSocket(message.targetUserId,message,message.sessionType);
                    }
                })
                }
                //action(message);
            }
        }
        this.alredyPublishs=[];
        this.subConnected=false;
        
        function sendMessage(sessionId,message,sessionKey) {
            let participants = new Participants();
            // 检查会话中是否存在此成员
            participants.existsParticipant(sessionId, message.sender_id, function (err, res) {
                if (res) {
                    redis.hmgetAsync(sessionKey, ["type", "name"]).then(function (res) {
                        let sessionType = res[0];
                        let sessionName = res[1];
                        if (sessionType) {
                            // 消息保存到Redis,并更新会话最后状态、用户最后消息获取时间
                            let sessionKey = RedisModel.makeRedisKey(REDIS_KEYS.Session, sessionId);
                            let messageKey = RedisModel.makeRedisKey(REDIS_KEYS.Messages, sessionId);
                            let messageTimestampKey = RedisModel.makeRedisKey(REDIS_KEYS.MessagesByTimestamp, sessionId);
                            let msgJson = {
                                id: message.id,
                                sender_id: message.sender_id,
                                sender_name: message.sender_name,
                                timestamp: message.timestamp.getTime(),
                                content_type: message.content_type,
                                content: message.content,
                                business_type:message.business_type||1
                            };
                            redis.multi()
                                .hset(messageKey, message.id, JSON.stringify(msgJson))               // 保存消息
                                .zadd(messageTimestampKey, message.timestamp.getTime(), message.id)  // 保存消息时间
                                .execAsync()
                                .then(function (res) {
                                    Messages.updateLastContent(sessionKey, sessionType, null, message);
                                    Messages.cleanOutRangeMessage(sessionId); // clean out range messages
                                })
                                .catch(function (ex) {
                                    logger.error("Save message to redis failed: ", ex);
                                });
                            Messages.updateLastContent(sessionKey, sessionType, sessionName, message);
                            var score = message.timestamp.getTime() + 1;
                            let participantsKey = RedisModel.makeRedisKey(REDIS_KEYS.SessionParticipants, sessionId);
                            redis.zaddAsync(participantsKey, score, message.sender_id)
                                .then(function (res) {
                                    //这个代码需要消息存入缓存后才能执行,否则用户拉取消息列表时可能缺少消息
                                    if(config.pubSubSwitch){//接收订阅消息处理开关,本地运行和测试库单独运行时防止用户接收消息2次
                                        //Sessions.getRedisPushNotification(message);这里不知为什么无法调用这个方法,提示getRedisPushNotification不是方法
                                        if (message.targetType=='patient') {
                                            if(config.environment!='local'){//pc版接收要发给居民的消息不做处理
                                                WechatClient.sendMessage(message.targetUserId, message.targetUserName, message);
                                            }
                                        } else {
                                            if(message.sessionType=="1"){
                                                WechatClient.sendReadDoctorByDoctorId(message.targetUserId, message);
                                            }
                                            //告知医生新消息
                                            WechatClient.sendSocketMessageToDoctor(message.targetUserId,message);
                                            if(config.environment!='local'){//pc版不推送个推
                                                WlyySDK.request(message.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);
                                                    }
                                                    AppClient.sendNotification(message.targetUserId, message,message.sessionType,count);
                                                });
                                            }
                                            //外网pcim通过socket推送
                                            WechatClient.sendPcImSocket(message.targetUserId,message,message.sessionType);
                                        }
                                    }
                                })
                                .catch(function (err) {
                                    logger.error("Update participant last fetch time failed: ", err);
                                });
                        }
                    }).catch(function (err) {
                        logger.error({message: "Error occurred while save message to session: " + err});
                    })
                } else {
                    logger.error({message: "当前会话找不到此发送者"});
                }
            });
        }
    }
    publish(channel,message)

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

@ -0,0 +1,56 @@
/**
 * 消息提醒设置
 * Created by ysj on 2017/12/4.
 */
"use strict";
let log = require('../../util/log');
let ImDb = require('../mysql/db/im.db');
const DB_TABLES = require('../../include/commons').DB_TABLES;
class MessageNoticeSettingRepo{
    constructor(){
    }
    /**
     * 获取单个MessageNoticeSetting对象
     *
     * @param user
     * @param type
     * @param handler
     * return  master_switch 总开关(1开,0关)',im_switch im消息开关(1开,0关)',family_topic_switch 健管师邀请后推送开关(1开,0关)',
     */
    static findOne(user,type, handler) {
        let sql = "select master_switch,im_switch,family_topic_switch from " + DB_TABLES.MessageNoticeSetting + " s where s.user = ? and s.type=? ";
        ImDb.execQuery({
            "sql": sql,
            "args": [user,type],
            "handler": handler || function (err, res) {
                if(err) log.error(err);
            }
        });
    }
    /**
     * 保存MessageNoticeSetting
     *
     * @param user 用户id
     * @param type 用户类型 1doctor 2patient
     * @param createTime
     * @param handler 回调函数
     */
    static save(user, type, createTime, handler) {
        let sql = "insert into " + DB_TABLES.MessageNoticeSetting + " (user,type,master_switch,im_switch,family_topic_switch," +
            "sign_switch,health_sign_switch,system_switch,prescription_switch,sound_switch,vibration_switch,coordination_switch,create_time)" +
            " values (?,?,1,1,1,1,1,1,1,1,1,1,?)";
        ImDb.execQuery({
            "sql": sql,
            "args": [user, type, createTime.getTime()],
            "handler": handler
        });
    }
}
module.exports = MessageNoticeSettingRepo;

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

@ -122,9 +122,9 @@ class ParticipantRepo {
     * @param handler
     */
    static findAllAvatars(sessionId, handler) {
        let sql = "SELECT u.id, u.avatar,'0' as ispatient FROM sessions s, participants p, doctors u " +
        let sql = "SELECT u.id, u.avatar,'0' as ispatient,u.name as name 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.avatar,'1' as ispatient FROM sessions s, participants p, patients u " +
            "SELECT u.id, u.avatar,'1' as ispatient,u.name as name FROM sessions s, participants p, patients u " +
            "WHERE s.id = ? AND s.id = p.session_id AND p.participant_id = u.id";
        ImDb.execQuery({

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

@ -20,7 +20,7 @@ class SearchRepo {
    static findTopicEndedSessionIdList(userId, handler) {
        let sql = "SELECT s.id " +
            "FROM sessions s, topics t, participants p " +
            "WHERE p.participant_id = ? AND p.session_id = s.id AND s.id = t.session_id AND t.end_message_id IS NOT NULL AND s.`type` IN (1,2) " +
            "WHERE p.participant_id = ? AND p.session_id = s.id AND s.id = t.session_id AND t.end_message_id IS NOT NULL AND s.`type` IN (1,2,8) " +
            " UNION " +
            "SELECT s.id " +
            "FROM sessions s, participants p " +
@ -42,7 +42,7 @@ class SearchRepo {
    static findTopicActiveSessionIdList(userId, handler) {
        let sql = "SELECT s.id " +
            "FROM sessions s, topics t, participants p " +
            "WHERE p.participant_id = ? AND p.session_id = s.id AND s.id = t.session_id AND t.end_message_id IS NULL  AND s.`type` IN (1,2) " +
            "WHERE p.participant_id = ? AND p.session_id = s.id AND s.id = t.session_id AND t.end_message_id IS NULL  AND s.`type` IN (1,2,8) " +
            " UNION " +
            "SELECT s.id " +
            "FROM sessions s, participants p " +

+ 51 - 0
src/server/repository/mysql/sign.family.repo.js

@ -0,0 +1,51 @@
/**
 * Created by ysj on 2017/12/4.
 */
"use strict";
let log = require('../../util/log');
let ImDb = require('../mysql/db/im.db');
const DB_TABLES = require('../../include/commons').DB_TABLES;
class SignFamilyRepo{
    constructor(){
    }
    /**
     * 获取单个MessageNoticeSetting对象
     *
     * @param session_id
     * @param handler
     */
    static findDoctor(session_id, handler) {
        let sql = "SELECT s.doctor,s.doctor_health from "+DB_TABLES.Participants+" p,"+DB_TABLES.SignFamily+" s WHERE p.session_id = ? and p.participant_id = s.patient and s.`status`>0";
        ImDb.execQuery({
            "sql": sql,
            "args": [session_id],
            "handler": handler || function (err, res) {
                if(err) log.error(err);
            }
        });
    }
    /**
     * 判断医生在会话中是否是健管师
     * @param session_id
     * @param doctor
     * @param handler
     */
    static isHealthDoctor(session_id,doctor, handler) {
        let sql = "SELECT s.doctor_health from "+DB_TABLES.Participants+" p,"+DB_TABLES.SignFamily+" s WHERE p.session_id = ? and p.participant_id = s.patient and s.doctor_health=? and s.`status`>0";
        ImDb.execQuery({
            "sql": sql,
            "args": [session_id,doctor],
            "handler": handler || function (err, res) {
                if(err) log.error(err);
            }
        });
    }
}
module.exports = SignFamilyRepo;

+ 5 - 5
src/server/resources/config/config.dev.js

@ -20,13 +20,13 @@ let imDbConfig = {
// Redis
let redisConfig = {
    host: '192.168.1.220',
    host: '172.19.103.88',
    port: 6379,
    db: 1
};
// 内网Redis
let innerRedisConfig = {
    host: '192.168.1.220',
    host: '172.19.103.88',
    port: 6379,
    db: 1
};
@ -104,8 +104,8 @@ let topicConfig = {
exports.environment = 'dev';
exports.pubChannel = 'dev';
exports.subChannel = 'dev';
exports.pubSubSwitch = false;
exports.subChannel = 'test';
exports.pubSubSwitch = true;
exports.app = 'IM.Server';
exports.version = '2.0.0';
@ -113,7 +113,7 @@ exports.debug = true;
exports.serverPort = 3000;
exports.sessionExpire = 1800;
exports.showSQL = true;
exports.showSQL = false;
exports.imDbConfig = imDbConfig;
exports.redisConfig = redisConfig;
exports.innerRedisConfig = innerRedisConfig;

+ 9 - 3
src/server/resources/config/config.prod.js

@ -12,11 +12,17 @@ let imDbConfig = {
// Redis
let redisConfig = {
    host: '192.168.120.14',
    port: 6380,
    host: '59.61.92.90',
    port: 9054,
    db: 1,
    password:'jkzl_ehr'
    password:'jkzlehr'
};
// let redisConfig = {
//     host: '192.168.120.14',
//     port: 6380,
//     db: 1,
//     password:'jkzl_ehr'
// };
// 内网Redis
let innerRedisConfig = {
    host: '59.61.92.90',

+ 9 - 4
src/server/resources/config/config.test.js

@ -11,13 +11,18 @@ let imDbConfig = {
// Redis
let redisConfig = {
    host: '192.168.1.220',
    host: '172.19.103.88',
    port: 6379,
    db: 1
};
// let redisConfig = {
//     host: '192.168.1.220',
//     port: 6379,
//     db: 1
// };
// 内网Redis
let innerRedisConfig = {
    host: '192.168.1.220',
    host: '172.19.103.88',
    port: 6379,
    db: 1
};
@ -71,7 +76,7 @@ let topicConfig = {
exports.environment = 'test';
exports.pubChannel = 'test';
exports.subChannel = 'dev';
exports.pubSubSwitch = false;
exports.pubSubSwitch = true;
exports.app = 'im.server';
exports.version = '2.0.0';
@ -79,7 +84,7 @@ exports.debug = true;
exports.serverPort = 3000;
exports.sessionExpire = 1800;
exports.showSQL = true;
exports.showSQL = false;
exports.imDbConfig = imDbConfig;
exports.redisConfig = redisConfig;
exports.innerRedisConfig = innerRedisConfig;