sand 8 роки тому
батько
коміт
96a939c59a

+ 4 - 0
readme.md

@ -87,6 +87,10 @@ IM提供了开发SDK,一个JS脚本。客户端可以通过引用此脚本或
- REST API相关的放在endpoints
- 与页面相关的放在controllers
### 模型与控制层之间的交互
控制层提供两种类型的API:含有回调与不含回调。不含回调的API通过事件向外发送消息,用于与controller之间的交互。含回调的API通过回调与其他API交互,用于模型之间的交互。
### 消息发送
	实时与延时

+ 7 - 13
src/server/include/commons.js

@ -31,11 +31,7 @@ exports.CONTENT_TYPE = {
    Article: 4,     // 文章信息
    GoTo: 5,        // 跳转信息
    SessionBegin: 6,// 咨询开始
    SessionEnd: 7,  // 咨询结束
    commaValues: function () {
        return "1,2,3,4,5,6,7";
    }
    SessionEnd: 7   // 咨询结束
};
/**
@ -92,18 +88,16 @@ exports.REDIS_KEYS = {
    UserAppStatus: "users:" + REDIS_KEY_REPLACER + ":app_status",
    UserWechatStatus: "users:" + REDIS_KEY_REPLACER + ":wechat_status",
    UsersSessions: "users:"+REDIS_KEY_REPLACER+":sessions",
    Participants:"participants:"+REDIS_KEY_REPLACER,
    UserSessions: "users:" + REDIS_KEY_REPLACER + ":sessions",
    Sessions: "sessions:",
    Session: "sessions:" + REDIS_KEY_REPLACER,
    Messages: "sessions:" + REDIS_KEY_REPLACER + ":messages",
    MessagesTimestamp: "sessions:" + REDIS_KEY_REPLACER + ":messages_by_timestamp",
    Participants: "participants:" + REDIS_KEY_REPLACER,
    Topics: "sessions:" + REDIS_KEY_REPLACER + ":topics",
    Topic: "topics:" + REDIS_KEY_REPLACER
    Topic: "topics:" + REDIS_KEY_REPLACER,
    Messages: "sessions:" + REDIS_KEY_REPLACER + ":messages",
    MessagesByTimestamp: "sessions:" + REDIS_KEY_REPLACER + ":messages_by_timestamp"
};
exports.STICK_NUM = 90000000000000;

+ 1 - 1
src/server/models/messages/messages.js

@ -139,7 +139,7 @@ class Messages extends RedisModel {
    saveMessageForRedis(message_id,sessionId,message){
        let message_key = super.makeRedisKey(RedisKey.Messages,sessionId);
        let message_timestamp_key = super.makeRedisKey(RedisKey.MessagesTimestamp,sessionId);
        let message_timestamp_key = super.makeRedisKey(RedisKey.MessagesByTimestamp,sessionId);
        redis.hsetAsync(message_key, message_id, JSON.stringify(message)).then(function (res) {
            log.info("success save redis message by session :"+sessionId);
            //保存message_timestamp_key redis

+ 1 - 1
src/server/models/sessions/participants.js

@ -124,7 +124,7 @@ class Participants extends RedisModel {
    createParticipantsToRedis(session_id,users,createDate,handler){
        let participants_key =  super.makeRedisKey(RedisKey.Participants,session_id);
        for(var j in users){
            let user_session_key =  super.makeRedisKey(RedisKey.UsersSessions,users[j]);
            let user_session_key =  super.makeRedisKey(RedisKey.UserSessions,users[j]);
            redis.zaddAsync(participants_key, createDate.getTime(),users[j]).then(function(res){
                    return  redis.zaddAsync(user_session_key,createDate.getTime(),session_id);
              }

+ 5 - 5
src/server/models/sessions/sessions.js

@ -46,7 +46,7 @@ class Sessions extends RedisModel {
     * @param userId
     */
    getUserSessions(userId,page,pagesize){
        let user_session_key =  super.makeRedisKey(RedisKeys.UsersSessions,userId);
        let user_session_key =  super.makeRedisKey(RedisKeys.UserSessions,userId);
        let self = this;
        let _super = super.makeRedisKey;
        if(page >0){
@ -86,7 +86,7 @@ class Sessions extends RedisModel {
             * @param restimestamp 当前会话当前用户的最后一次时间搓
             */
            function callamount(res,j,_len,session,restimestamp){
                let message_time_key = _super(RedisKeys.MessagesTimestamp,session);
                let message_time_key = _super(RedisKeys.MessagesByTimestamp,session);
                redis.zrangebyscoreAsync(message_time_key,restimestamp,(new Date().getTime())).then(function(messagetimelist){
                    res.sessionId = session;
                    res.message = messagetimelist.length;
@ -122,7 +122,7 @@ class Sessions extends RedisModel {
     */
    getSessionMessages(sessionId,user,page,pagesize){
        let self = this;
        let message_timestamp_key = super.makeRedisKey(RedisKeys.MessagesTimestamp,sessionId);
        let message_timestamp_key = super.makeRedisKey(RedisKeys.MessagesByTimestamp,sessionId);
        let message_key = super.makeRedisKey(RedisKeys.Messages,sessionId);
        let participants_key = super.makeRedisKey(RedisKeys.Participants,sessionId);
        //超过最大限制后从mysql获取数据
@ -286,7 +286,7 @@ class Sessions extends RedisModel {
     *置顶操作
     */
    stickSession(sessionId,user){
        let user_session_key = super.makeRedisKey(RedisKeys.UsersSessions,user);
        let user_session_key = super.makeRedisKey(RedisKeys.UserSessions,user);
        let self = this;
        //取出最大的session
        redis.zrevrangeAsync(user_session_key,0,0).then(function(res){
@ -316,7 +316,7 @@ class Sessions extends RedisModel {
     *取消置顶操作
     */
    cancelStickSession(sessionId,user){
        let user_session_key = super.makeRedisKey(RedisKeys.UsersSessions,user);
        let user_session_key = super.makeRedisKey(RedisKeys.UserSessions,user);
        let participants_key = super.makeRedisKey(RedisKeys.Participants,sessionId);
        let self = this;
        redis.zscoreAsync(participants_key,user).then(function(res){

+ 37 - 8
src/server/models/user/users.js

@ -18,6 +18,7 @@ let ImDb = require('../../repository/mysql/db/im.db');
let DoctorRepo = require('../../repository/mysql/doctor.repo');
let PatientRepo = require('../../repository/mysql/patient.repo');
let AppStatusRepo = require('../../repository/mysql/app.status.repo');
let ModelUtil = require('../../util/model.util');
let RedisClient = require('../../repository/redis/redis.client');
let redisConn = RedisClient.redisClient().connection;
@ -142,28 +143,56 @@ class Users extends RedisModel {
     * @param platform
     * @param token
     * @param clientId
     * @param outCallback
     *
     * @return 用户token
     */
    login(userId, platform, token, clientId, outCallback){
    login(userId, platform, token, clientId){
        let self = this;
        let loginFromApp = platform === PLATFORMS.Wechat;
        let usersKey = REDIS_KEYS.Users;
        let userKey = self.makeRedisKey(REDIS_KEYS.User, userId);
        let userStatusKey = platform === PLATFORMS.Wechat ? REDIS_KEYS.UserWechatStatus : REDIS_KEYS.UserWechatStatus;
        userStatusKey = self.makeRedisKey(userStatusKey, userId);
        let userStatusKey = self.makeRedisKey(loginFromApp ? REDIS_KEYS.UserWechatStatus : REDIS_KEYS.UserWechatStatus, userId);
        let lastLoginTime = new Date();
        async.waterfall([
            // save user info and app status
            // get user info
            function (callback) {
                let
                self.getUser(userId, function (err, userInfo) {
                    if(userInfo === null){
                        ModelUtil.emitDataNotFound(self, 'User not exists.');
                        return;
                    }
                    callback(null, userInfo);
                })
            },
            // save user info and app status/wechat status
            function (userInfo, callback) {
                let multi = redisConn.multi()
                    .zadd(usersKey, lastLoginTime.getMilliseconds(), userId)
                    .hmset(userKey, 'avatar', userInfo.avatar, 'birthdate', userInfo.birthdate,
                        'name', userInfo.name, 'role', loginFromApp ? 'doctor' : 'patient');
                if(loginFromApp){
                    // app status
                    multi = multi.hmset(userStatusKey, 'platform', platform, 'app_in_bg', false, 'client_id', clientId,
                        'token', token, 'last_login_time', lastLoginTime);
                } else {
                    // wechat status
                    multi = multi.hmset(userKey, 'open_id', userInfo.open_id);
                }
                multi.execAsnyc().then(function (res) {
                        callback(null);
                    });
            },
            // load sessions
            function (callback) {
                let sessions = new Sessions();
                sessions.getUserSessionsFromMysql();
                /*let sessions = new Sessions();
                sessions.getUserSessionsFromMysql();*/
            }
        ]);
        DoctorRepo.deleteToken(token, function (err, result) {
            if (err) {
                ModelUtil.emitDbError(self.eventEmitter, 'Error occurs when user login and delete token', err);