浏览代码

取消与家庭医生后台数据库的关联;用户登录时取消用户本身的信息缓存,只缓存用户状态信息;完成用户登录、更新状态及退出接口和单元测试

Sand 8 年之前
父节点
当前提交
c4a890c42b

+ 5 - 5
src/client/im.client.js

@ -39,7 +39,7 @@ var ENDPOINTS = {
    },
    Management: {
        Health: '/management/health',
        DbStatus: '/db'
        DbStatus: '/management/db'
    },
    Users: {
        Login: '/users/login',
@ -175,8 +175,8 @@ var imClient = {
        }
    },
    Management: {
        health: function (success, failure) {
            httpClient.get(ENDPOINTS.Management.Health,
        getDbStatus: function (success, failure) {
            httpClient.get(ENDPOINTS.Management.DbStatus,
                {},
                success,
                failure);
@ -204,9 +204,9 @@ var imClient = {
        },
        // 更新用户状态
        updateStatus: function (userId, status, success, failure) {
        updateStatus: function (userId, appInBg, success, failure) {
            httpClient.put(ENDPOINTS.Users.UserStatus.replace(UserPath, userId),
                {status: status},
                {app_in_bg: appInBg},
                success,
                failure);
        },

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

@ -55,20 +55,20 @@ router.post(APIv2.Users.Login, function (req, res) {
 *  {status: 1}, app状态,0在后台,1在前台
 */
router.put(APIv2.Users.UserStatus, function (req, res) {
    let userId = req.param('user_id');
    let userId = req.params.user_id;
    let status = req.body;
    if (!ObjectUtil.isJsonObject(status)) {
        throw {httpStatus: 406, message: "Problems parsing json."};
    }
    if (userId === null || (status.status != 0 && status.status != 1)) {
        throw {httpStatus: 406, message: 'Validation Failed. Missing fields.'};
    if (userId === null) {
        throw {httpStatus: 406, message: 'Validation Failed. Missing field(s): user_id.'};
    }
    let userStatus = new Users();
    ControllerUtil.regModelEventHandler(userStatus, res);
    let users = new Users();
    ControllerUtil.regModelEventHandler(users, res);
    userStatus.updateStatus(userId, status.status);
    users.updateAppStatus(userId, status.app_in_bg);
});
/**

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

@ -72,7 +72,8 @@ exports.GROUP_TYPE = {
exports.MODEL_EVENTS = {
    Error: "error",                 // 数据库访问出错
    DataNotFound: "no_data",        // 找不到指定的数据
    OK: "ok"                        // 操作结束或有数据返回
    OK: "ok",                       // 操作结束或有数据返回
    Exists: "exists"                // 数据已存在
};
/**

+ 16 - 16
src/server/models/group.js

@ -33,7 +33,7 @@ class GroupMessage extends BaseModel {
        let self = this;
        GroupRepo.isGroupMember(message.group, message.groupType, message.from, function (err, result) {
            if (err) {
                ModelUtil.emitDbError(self.eventEmitter, 'Check group member failed', err);
                ModelUtil.emitError(self.eventEmitter, 'Check group member failed', err);
                return;
            }
@ -45,19 +45,19 @@ class GroupMessage extends BaseModel {
            // 保存群组消息
            GroupMsgRepo.save(message.from, message.group, message.at, message.contentType, message.content, function (err, insertedRow) {
                if (err) {
                    ModelUtil.emitDbError(self.eventEmitter, 'Save group message failed', err);
                    ModelUtil.emitError(self.eventEmitter, 'Save group message failed', err);
                    return;
                }
                GroupMsgRepo.findOneMessage(insertedRow.insertId, function (err, groupMsg) {
                    if (err) {
                        ModelUtil.emitDbError(self.eventEmitter, 'Save group message success, but return this message failed', err);
                        ModelUtil.emitError(self.eventEmitter, 'Save group message success, but return this message failed', err);
                        return;
                    }
                    // 关闭网络连接后执行后续操作
                    let feedback = Doctor.fillMessages(groupMsg);
                    ModelUtil.emitData(self.eventEmitter, feedback);
                    ModelUtil.emitOK(self.eventEmitter, feedback);
                    // 推送通知消息给群组成员
                    GroupRepo.getMembers(message.group, message.groupType, function (err, members) {
@ -135,13 +135,13 @@ class GroupMessage extends BaseModel {
        let self = this;
        GroupMsgRepo.findAllMessages(groupId, !contentType ? "1,2,3,5,6" : contentType, msgStartId, msgEndId, count, function (err, rows) {
            if (err) {
                ModelUtil.emitDbError(self.eventEmitter, 'Get group message failed', err);
                ModelUtil.emitError(self.eventEmitter, 'Get group message failed', err);
                return;
            }
            // 先给客户端返回数据
            let messages = Doctor.fillMessages(rows);
            ModelUtil.emitData(self.eventEmitter, messages);
            ModelUtil.emitOK(self.eventEmitter, messages);
            // 清空统计信息
            StatsRepo.clearGroupChatSummary(memberId, groupId, function (err, result) {
@ -158,25 +158,25 @@ class GroupMessage extends BaseModel {
        let self = this;
        StatsRepo.getGroupChatSummary(memberId, groupId, function (err, summary) {
                if (err) {
                    ModelUtil.emitDbError(self.eventEmitter, "Get unread group messages failed", err);
                    ModelUtil.emitError(self.eventEmitter, "Get unread group messages failed", err);
                    return;
                }
                let messages = {startId: 0, count: 0, records: []};
                if (summary.length == 0 || summary[0].new_msg_count === 0) {
                    ModelUtil.emitData(messages);
                    ModelUtil.emitOK(messages);
                    return;
                }
                messages.count = summary[0].new_msg_count;
                GroupMsgRepo.findUnread(groupId, MAX_INT, messages.count, function (err, rows) {
                    if (err) {
                        ModelUtil.emitDbError(self.eventEmitter, "Get unread group messages failed", err);
                        ModelUtil.emitError(self.eventEmitter, "Get unread group messages failed", err);
                        return;
                    }
                    let feedback = Doctor.fillMessages(rows);
                    ModelUtil.emitData(feedback);
                    ModelUtil.emitOK(feedback);
                });
            }
        )
@ -192,7 +192,7 @@ class GroupMessage extends BaseModel {
        let self = this;
        StatsRepo.getGroupChatAllUnReadCount(memberId, function (err, result) {
            if (err) {
                ModelUtil.emitDbError(self.eventEmitter, 'Get all unread messages failed', err);
                ModelUtil.emitError(self.eventEmitter, 'Get all unread messages failed', err);
                return;
            }
@ -208,7 +208,7 @@ class GroupMessage extends BaseModel {
                }
            }
            ModelUtil.emitData(self.eventEmitter, data);
            ModelUtil.emitOK(self.eventEmitter, data);
        });
    }
@ -222,7 +222,7 @@ class GroupMessage extends BaseModel {
        let self = this;
        StatsRepo.getGroupChatSummary(memberId, groupId, function (err, result) {
            if (err) {
                ModelUtil.emitDbError(self.eventEmitter, 'Get group stats failed', err);
                ModelUtil.emitError(self.eventEmitter, 'Get group stats failed', err);
                return;
            }
@ -248,7 +248,7 @@ class GroupMessage extends BaseModel {
                data.timestamp = ObjectUtil.timestampToLong(row.timestamp)
            }
            ModelUtil.emitData(self.eventEmitter, data);
            ModelUtil.emitOK(self.eventEmitter, data);
        });
    }
@ -262,7 +262,7 @@ class GroupMessage extends BaseModel {
        let avatars = [];
        GroupRepo.getMembersAvatar(groups, function (err, members) {
            if (err) {
                ModelUtil.emitDbError(self.eventEmitter, "Get group member's avatar list failed", err);
                ModelUtil.emitError(self.eventEmitter, "Get group member's avatar list failed", err);
                return;
            }
@ -288,7 +288,7 @@ class GroupMessage extends BaseModel {
                });
            }
            ModelUtil.emitData(self.eventEmitter, avatars);
            ModelUtil.emitOK(self.eventEmitter, avatars);
        });
    }
}

+ 24 - 24
src/server/models/search.js

@ -28,7 +28,7 @@ class Search extends BaseModel {
        searchRepo.searchPatients(userId, userRole, keyword, function (err, patients) {
            if (err) {
                modelUtil.emitDbError(self.eventEmitter, "Search patient on basic information failed", err);
                modelUtil.emitError(self.eventEmitter, "Search patient on basic information failed", err);
                return;
            }
@ -48,7 +48,7 @@ class Search extends BaseModel {
            }
            searchRepo.searchGroupPatients(userId, keyword, function (err, groups) {
                if (err) {
                    modelUtil.emitDbError(self.eventEmitter, "Search talk group failed", err);
                    modelUtil.emitError(self.eventEmitter, "Search talk group failed", err);
                    return;
                }
                var group = null;
@ -64,7 +64,7 @@ class Search extends BaseModel {
                searchRepo.searchPatientPM(userId, keyword, function (err, chats) {
                    if (err) {
                        modelUtil.emitDbError(self.eventEmitter, "Search patient on private messages failed", err);
                        modelUtil.emitError(self.eventEmitter, "Search patient on private messages failed", err);
                        return;
                    }
@ -93,7 +93,7 @@ class Search extends BaseModel {
                        lastPatient.msg_id = chat.msg_id;
                        data.chats.push(lastPatient);
                    }
                    modelUtil.emitData(self.eventEmitter, data);
                    modelUtil.emitOK(self.eventEmitter, data);
                });
            });
        });
@ -112,7 +112,7 @@ class Search extends BaseModel {
        if (type == 1) {
            searchRepo.searchPatients(userId, userRole, keyword, function (err, patients) {
                if (err) {
                    modelUtil.emitDbError(self.eventEmitter, "Search patient on basic information failed", err);
                    modelUtil.emitError(self.eventEmitter, "Search patient on basic information failed", err);
                    return;
                }
                for (var i = 0; i < patients.length; ++i) {
@ -125,13 +125,13 @@ class Search extends BaseModel {
                        avatar: patient.photo === null ? "" : patient.photo
                    });
                }
                modelUtil.emitData(self.eventEmitter, data);
                modelUtil.emitOK(self.eventEmitter, data);
            });
        }
        if (type == 3) {
            searchRepo.searchPatientPM(userId, keyword, function (err, chats) {
                if (err) {
                    modelUtil.emitDbError(self.eventEmitter, "Search patient on private messages failed", err);
                    modelUtil.emitError(self.eventEmitter, "Search patient on private messages failed", err);
                    return;
                }
                for (var i = 0; i < chats.length; ++i) {
@ -157,13 +157,13 @@ class Search extends BaseModel {
                    lastPatient.type = chat.type;
                    data.push(lastPatient);
                }
                modelUtil.emitData(self.eventEmitter, data);
                modelUtil.emitOK(self.eventEmitter, data);
            });
        }
        if (type == 2) {
            searchRepo.searchGroupPatients(userId, keyword, function (err, groups) {
                if (err) {
                    modelUtil.emitDbError(self.eventEmitter, "Search talk group failed", err);
                    modelUtil.emitError(self.eventEmitter, "Search talk group failed", err);
                    return;
                }
                var group = null;
@ -176,7 +176,7 @@ class Search extends BaseModel {
                    };
                    data.push(group);
                }
                modelUtil.emitData(self.eventEmitter, data);
                modelUtil.emitOK(self.eventEmitter, data);
            });
        }
    }
@ -194,7 +194,7 @@ class Search extends BaseModel {
        searchRepo.searchPatientPMList(userId, keyword, groupId, type, function (err, chats) {
            var data = [];
            if (err) {
                modelUtil.emitDbError(self.eventEmitter, "Search searchPatientPMList on private messages failed", err);
                modelUtil.emitError(self.eventEmitter, "Search searchPatientPMList on private messages failed", err);
                return;
            }
            for (var i = 0; i < chats.length; ++i) {
@ -210,7 +210,7 @@ class Search extends BaseModel {
                lastPatient.msg_id = chat.msg_id;
                data.push(lastPatient);
            }
            modelUtil.emitData(self.eventEmitter, data);
            modelUtil.emitOK(self.eventEmitter, data);
        })
    }
@ -223,7 +223,7 @@ class Search extends BaseModel {
        //搜索单对单医生聊天
        searchRepo.searchP2Pdoctors(userId, keyword, function (err, doctors) {
            if (err) {
                modelUtil.emitDbError(self.eventEmitter, "Search doctor on basic information failed", err);
                modelUtil.emitError(self.eventEmitter, "Search doctor on basic information failed", err);
                return;
            }
@ -242,7 +242,7 @@ class Search extends BaseModel {
            // 搜索讨论组名称及成员名称(讨论组)
            searchRepo.searchGroupDoctors(userId, keyword, function (err, groups) {
                if (err) {
                    modelUtil.emitDbError(self.eventEmitter, "Search talk group failed", err);
                    modelUtil.emitError(self.eventEmitter, "Search talk group failed", err);
                    return;
                }
@ -260,7 +260,7 @@ class Search extends BaseModel {
                // 搜索医生间的私信
                searchRepo.searchDoctorsContent(userId, keyword, function (err, messages) {
                    if (err) {
                        modelUtil.emitDbError(self.eventEmitter, "Search doctor private messages failed", err);
                        modelUtil.emitError(self.eventEmitter, "Search doctor private messages failed", err);
                        return;
                    }
                    var message = null;
@ -279,7 +279,7 @@ class Search extends BaseModel {
                        };
                        data.content.push(message);
                    }
                    modelUtil.emitData(self.eventEmitter, data);
                    modelUtil.emitOK(self.eventEmitter, data);
                });
            });
        });
@ -291,7 +291,7 @@ class Search extends BaseModel {
        if (type == 1) {
            searchRepo.searchP2Pdoctors(userId, keyword, function (err, doctors) {
                if (err) {
                    modelUtil.emitDbError(self.eventEmitter, "Search doctor on basic information failed", err);
                    modelUtil.emitError(self.eventEmitter, "Search doctor on basic information failed", err);
                    return;
                }
                for (var i = 0; i < doctors.length; ++i) {
@ -304,12 +304,12 @@ class Search extends BaseModel {
                        avatar: doctor.photo === null ? "" : doctor.photo
                    });
                }
                modelUtil.emitData(self.eventEmitter, data);
                modelUtil.emitOK(self.eventEmitter, data);
            });
        } else if (type == 2) {
            searchRepo.searchGroupDoctors(userId, keyword, function (err, groups) {
                if (err) {
                    modelUtil.emitDbError(self.eventEmitter, "Search talk group failed", err);
                    modelUtil.emitError(self.eventEmitter, "Search talk group failed", err);
                    return;
                }
                var group = null;
@ -323,12 +323,12 @@ class Search extends BaseModel {
                    };
                    data.push(group);
                }
                modelUtil.emitData(self.eventEmitter, data);
                modelUtil.emitOK(self.eventEmitter, data);
            });
        } else if (type == 3) {
            searchRepo.searchDoctorsContent(userId, keyword, function (err, messages) {
                if (err) {
                    modelUtil.emitDbError(self.eventEmitter, "Search doctor private messages failed", err);
                    modelUtil.emitError(self.eventEmitter, "Search doctor private messages failed", err);
                    return;
                }
                var message = null;
@ -346,7 +346,7 @@ class Search extends BaseModel {
                    };
                    data.push(message);
                }
                modelUtil.emitData(self.eventEmitter, data);
                modelUtil.emitOK(self.eventEmitter, data);
            });
        }
    }
@ -363,7 +363,7 @@ class Search extends BaseModel {
        var data = [];
        searchRepo.searchDoctorsContentDetail(userId, keyword, groupcode, type, function (err, doctors) {
            if (err) {
                modelUtil.emitDbError(self.eventEmitter, "Search doctor on basic information failed", err);
                modelUtil.emitError(self.eventEmitter, "Search doctor on basic information failed", err);
                return;
            }
            for (var i = 0; i < doctors.length; ++i) {
@ -377,7 +377,7 @@ class Search extends BaseModel {
                    groupType: doctor.group_type
                });
            }
            modelUtil.emitData(self.eventEmitter, data);
            modelUtil.emitOK(self.eventEmitter, data);
        });
    }

+ 6 - 15
src/server/models/server/management.js

@ -9,11 +9,10 @@
let configFile = require('../../include/commons').CONFIG_FILE;
let config = require('../../resources/config/' + configFile);
let wlyyRepo = require('../../repository/mysql/db/im.db');
let imRepo = require('../../repository/mysql/db/im.db');
let BaseModel = require('../base.model');
let modeUtil = require("../../util/model.util");
let ModeUtil = require("../../util/model.util");
let ImDb = require('../../repository/mysql/db/im.db');
class Management extends BaseModel {
    constructor() {
@ -24,21 +23,13 @@ class Management extends BaseModel {
        let self = this;
        let data = new Array(0);
        imRepo.execQuery({
        ImDb.execQuery({
            "sql": "SELECT table_name FROM information_schema.TABLES WHERE TABLE_SCHEMA = ?",
            "args": [config.imDbConfig.database],
            "handler": function (err, result) {
                Management.makeResponse(data, config.wlyyDbConfig.database, err, result);
                wlyyRepo.execQuery({
                    "sql": "SELECT table_name FROM information_schema.TABLES WHERE TABLE_SCHEMA = ?",
                    "args": [config.wlyyDbConfig.database],
                    "handler": function (err, result) {
                        Management.makeResponse(data, config.imDbConfig.database, err, result);
                Management.makeResponse(data, config.imDbConfig.database, err, result);
                        modeUtil.emitData(self.eventEmitter, data);
                    }
                });
                ModeUtil.emitOK(self.eventEmitter, data);
            }
        });
    }

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

@ -136,12 +136,12 @@ class Participants extends RedisModel {
                //3.移除数据库中的人员记录
                self.deleteUserFromMysql(sessionId, userId);
                ModelUtil.emitData(self.eventEmitter, {"status": 200, "msg": "人员删除成功!"});
                ModelUtil.emitOK(self.eventEmitter, {"status": 200, "msg": "人员删除成功!"});
            }).catch(function (err) {
                ModelUtil.emitData(self.eventEmitter, {"status": -1, "msg": "人员删除失败!" + err});
                ModelUtil.emitOK(self.eventEmitter, {"status": -1, "msg": "人员删除失败!" + err});
            })
        }).catch(function (err) {
            ModelUtil.emitData(self.eventEmitter, {"status": -1, "msg": "人员删除失败!" + err});
            ModelUtil.emitOK(self.eventEmitter, {"status": -1, "msg": "人员删除失败!" + err});
        })
    }
@ -170,7 +170,7 @@ class Participants extends RedisModel {
            if (res) {
                self.saveParticipantsToMysql(sessionId, users);
            } else {
                ModelUtil.emitData(self.eventEmitter, {"status": -1, "msg": "人员添加失败!"});
                ModelUtil.emitOK(self.eventEmitter, {"status": -1, "msg": "人员添加失败!"});
            }
        })
    }

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

@ -46,7 +46,7 @@ class Sessions extends RedisModel {
                userArray.push(key);
            }
            if(userArray.length>2){
                ModelUtil.emitData(self.eventEmitter, {"status": -1, "msg": "会话人数超过2个无法创建P2P会话!"});
                ModelUtil.emitOK(self.eventEmitter, {"status": -1, "msg": "会话人数超过2个无法创建P2P会话!"});
                return false;
            }
            ParticipantRepo.findSessionIdByParticipantIds(userArray[0],userArray[0],function(err,res){
@ -64,7 +64,7 @@ class Sessions extends RedisModel {
            // 将session加入redis
            participants.saveParticipantsToRedis(sessionId, users, createDate, function (res) {
                if (!res) {
                    ModelUtil.emitData(self.eventEmitter, {"status": -1, "msg": res});
                    ModelUtil.emitOK(self.eventEmitter, {"status": -1, "msg": res});
                } else {
                    let messages = {};
                    messages.senderId = "system";
@ -76,7 +76,7 @@ class Sessions extends RedisModel {
                    if(config.sessionConfig.MUC==type){
                        handler(true);
                    }else {
                        modelUtil.emitData(self.eventEmitter, {"status": 200, "msg": "session create success!"});
                        modelUtil.emitOK(self.eventEmitter, {"status": 200, "msg": "session create success!"});
                    }
                    self.saveSessionToMysql(sessionId, name, type, createDate);
                    participants.saveParticipantsToMysql(sessionId, users); //创建session成员到数据库
@ -133,7 +133,7 @@ class Sessions extends RedisModel {
        redis.zrevrangeAsync(user_session_key, page, pagesize).then(function (res) {
            let sessionlist = [];
            if (res.length == 0) {
                ModelUtil.emitData(self.eventEmitter, {"status": 200, "data": res});
                ModelUtil.emitOK(self.eventEmitter, {"status": 200, "data": res});
            } else {
                for (var j in res) {
                    calllist(res[j], j, res.length);
@ -194,11 +194,11 @@ class Sessions extends RedisModel {
            function callback(res, j, _len) {
                sessionlist.push(res);
                if (j == (_len - 1)) {
                    ModelUtil.emitData(self.eventEmitter, {"status": 200, "data": sessionlist});
                    ModelUtil.emitOK(self.eventEmitter, {"status": 200, "data": sessionlist});
                }
            }
        }).catch(function (res) {
            ModelUtil.emitData(self.eventEmitter, "get list error " + res + ",user:" + userId);
            ModelUtil.emitOK(self.eventEmitter, "get list error " + res + ",user:" + userId);
        })
    }
@ -219,9 +219,9 @@ class Sessions extends RedisModel {
        if (page * pagesize >= config.sessionConfig.maxMessageCount) {
            self.getMessageFromMySQL(sessionId, page, pagesize, function (err, res) {
                if (!err) {
                    ModelUtil.emitData(self.eventEmitter, {"status": 200, "data": res});
                    ModelUtil.emitOK(self.eventEmitter, {"status": 200, "data": res});
                } else {
                    ModelUtil.emitData(self.eventEmitter, {"status": -1, "data": err});
                    ModelUtil.emitOK(self.eventEmitter, {"status": -1, "data": err});
                }
            })
        } else {
@ -232,19 +232,19 @@ class Sessions extends RedisModel {
            let participants = new Participants();
            participants.existsParticipant(sessionId, user, function (res) {
                if (!res) {
                    ModelUtil.emitData(self.eventEmitter, {"status": -1, "msg": "用户不在此会话中!"});
                    ModelUtil.emitOK(self.eventEmitter, {"status": -1, "msg": "用户不在此会话中!"});
                } else {
                    //倒序取出最后N条消息
                    redis.zrevrangeAsync(message_timestamp_key, page, pagesize).then(function (res) {
                        //取出消息实体
                        if (res.length == 0) {
                            ModelUtil.emitData(self.eventEmitter, {"status": 200, "data": []});
                            ModelUtil.emitOK(self.eventEmitter, {"status": 200, "data": []});
                            return;
                        }
                        redis.hmgetAsync(message_key, res).then(function (messages) {
                            console.log(messages)
                            //将取到的消息返回给前端
                            ModelUtil.emitData(self.eventEmitter, {"status": 200, "data": messages});
                            ModelUtil.emitOK(self.eventEmitter, {"status": 200, "data": messages});
                        }).then(function () {
                            //更新患者最后一次获取消息的日期
                            redis.zaddAsync(participants_key, (new Date().getTime()), user).then(function (res) {
@ -254,7 +254,7 @@ class Sessions extends RedisModel {
                            })
                        })
                    }).catch(function (res) {
                        ModelUtil.emitData(self.eventEmitter, {"status": -1, "msg": res});
                        ModelUtil.emitOK(self.eventEmitter, {"status": -1, "msg": res});
                    })
                }
            })
@ -316,13 +316,13 @@ class Sessions extends RedisModel {
                    //操作mysql数据库
                    messages.saveMessageToMysql(message, session_type, message_id, sessionId);
                    //返回数据给前端。
                    ModelUtil.emitData(self.eventEmitter, {"status": 200, "msg": "发送成功!"});
                    ModelUtil.emitOK(self.eventEmitter, {"status": 200, "msg": "发送成功!"});
                    //消息推送
                }).catch(function (res) {
                    ModelUtil.emitData(self.eventEmitter, {"status": -1, "msg": res});
                    ModelUtil.emitOK(self.eventEmitter, {"status": -1, "msg": res});
                })
            } else {
                ModelUtil.emitData(self.eventEmitter, {"status": -1, "msg": "用户不在此会话当中!"});
                ModelUtil.emitOK(self.eventEmitter, {"status": -1, "msg": "用户不在此会话当中!"});
            }
        })
    }
@ -386,7 +386,7 @@ class Sessions extends RedisModel {
                    //初始化置顶
                    redis.zaddAsync(user_session_key, Commons.STICKY_SESSION_BASE_SCORE, sessionId).then(function (res) {
                        log.info("stickSession:" + sessionId + ",res:" + res);
                        ModelUtil.emitData(self.eventEmitter, {"status": 200, "msg": "置顶成功!"});
                        ModelUtil.emitOK(self.eventEmitter, {"status": 200, "msg": "置顶成功!"});
                    }).then(function () {
                        SessionRepo.saveStickySession(sessionId, user, Commons.STICKY_SESSION_BASE_SCORE);
                    })
@ -395,7 +395,7 @@ class Sessions extends RedisModel {
                    scoreres = Number(scoreres) + 1;
                    redis.zaddAsync(user_session_key, scoreres, sessionId).then(function () {
                        log.info("stickSession:" + sessionId + ",res:" + res);
                        ModelUtil.emitData(self.eventEmitter, {"status": 200, "msg": "置顶成功!"});
                        ModelUtil.emitOK(self.eventEmitter, {"status": 200, "msg": "置顶成功!"});
                    }).then(function () {
                        SessionRepo.saveStickySession(sessionId, user, scoreres);
                    })
@ -417,7 +417,7 @@ class Sessions extends RedisModel {
            }
            redis.zaddAsync(user_session_key, res, sessionId).then(function (res) {
                log.info("cancelStickSession:" + sessionId);
                ModelUtil.emitData(self.eventEmitter, {"status": 200, "msg": "取消置顶成功!"});
                ModelUtil.emitOK(self.eventEmitter, {"status": 200, "msg": "取消置顶成功!"});
            }).then(function () {
                SessionRepo.unstickSession(sessionId, user);
            });

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

@ -44,7 +44,7 @@ class Topics extends RedisModel {
            redis.zrevrangebyscoreAsync(message_time_key,end_time,create_time).then(function (messages) {
                //取出消息实例
                redis.hmgetAsync(message_key,messages).then(function(res){
                    modelUtil.emitData(self.eventEmitter,res);
                    modelUtil.emitOK(self.eventEmitter,res);
                })
            })
        })
@ -98,7 +98,7 @@ class Topics extends RedisModel {
            msg.timestamp=date;
            sessions.saveMessageByTopic(msg,patient,function(err,msgId){
                if(err){
                    modelUtil.emitData(self.eventEmitter,err);
                    modelUtil.emitOK(self.eventEmitter,err);
                }else{
                    self.saveTopicsToSql(topicName,topicId,patient,msgId,date);
                    callBeginMsg();
@ -133,7 +133,7 @@ class Topics extends RedisModel {
                    })
                }
            }
            modelUtil.emitData(self.eventEmitter,"创建成功!");
            modelUtil.emitOK(self.eventEmitter,"创建成功!");
        }
    }
@ -169,9 +169,9 @@ class Topics extends RedisModel {
            let sessions = new Sessions();
            sessions.saveMessageByTopic(msg,sessionId,function(err,msgId){
                if(err){
                    modelUtil.emitData(self.eventEmitter,err);
                    modelUtil.emitOK(self.eventEmitter,err);
                }else{
                    modelUtil.emitData(self.eventEmitter,"结束成功!");
                    modelUtil.emitOK(self.eventEmitter,"结束成功!");
                    TopicsRepo.endTopic(topicId,endUser,msg.date,msgId);
                }
            })

+ 2 - 2
src/server/models/stats.js

@ -21,12 +21,12 @@ class StatsMessage extends BaseModel{
        let self = this;
        statsRepo.getBadgeNumber(userId, function (err, result) {
            if (err) {
                modelUtil.emitDbError(self.eventEmitter, "Get badge number failed: ", err);
                modelUtil.emitError(self.eventEmitter, "Get badge number failed: ", err);
                return;
            }
            let data = {userId: userId, badge: result};
            modelUtil.emitData(self.eventEmitter, data);
            modelUtil.emitOK(self.eventEmitter, data);
        });
    }
}

+ 41 - 41
src/server/models/user/doctor.js

@ -43,19 +43,19 @@ class Doctor extends RedisModel {
        PrivateMsgRepo.save(message.to, message.from, message.contentType, tempContent, function (err, result) {
            if (err) {
                ModelUtil.emitDbError(self.eventEmitter, 'Save private message failed', err);
                ModelUtil.emitError(self.eventEmitter, 'Save private message failed', err);
                return;
            }
            // 返回新插入的消息数据,并推送
            PrivateMsgRepo.findOneMessage(result.insertId, function (err, msg) {
                if (err) {
                    ModelUtil.emitDbError(self.eventEmitter, 'Save private message success, but return last message failed', err);
                    ModelUtil.emitError(self.eventEmitter, 'Save private message success, but return last message failed', err);
                    return;
                }
                // 先结束网络连接,再推送给客户端
                ModelUtil.emitData(self.eventEmitter, Doctor.fillMessages(msg));
                ModelUtil.emitOK(self.eventEmitter, Doctor.fillMessages(msg));
                Doctor.pushMessage(message, 'p2p_msg');
            });
@ -86,12 +86,12 @@ class Doctor extends RedisModel {
            message.content,
            function (err, result) {
                if (err) {
                    ModelUtil.emitDbError(self.eventEmitter, "Save system message failed", err);
                    ModelUtil.emitError(self.eventEmitter, "Save system message failed", err);
                    return;
                }
                // 先结束网络连接,再推送给客户端
                ModelUtil.emitData(self.eventEmitter, {});
                ModelUtil.emitOK(self.eventEmitter, {});
                Doctor.pushMessage(message, 'system_msg');
            });
@ -196,7 +196,7 @@ class Doctor extends RedisModel {
        let self = this;
        StatsRepo.getRecentChats(userId, days, function (err, rows) {
            if (err) {
                ModelUtil.emitDbError(self.eventEmitter, 'Get recent chat objects failed', err);
                ModelUtil.emitError(self.eventEmitter, 'Get recent chat objects failed', err);
                return;
            }
@ -229,7 +229,7 @@ class Doctor extends RedisModel {
                }
            }
            ModelUtil.emitData(self.eventEmitter, data);
            ModelUtil.emitOK(self.eventEmitter, data);
        });
    }
@ -244,7 +244,7 @@ class Doctor extends RedisModel {
        // 与患者的私信
        PrivateMsgRepo.findAllP2PWithPatient(userId, function (err, patients) {
            if (err) {
                ModelUtil.emitDbError(self.eventEmitter, 'Get chat list with patient failed', err);
                ModelUtil.emitError(self.eventEmitter, 'Get chat list with patient failed', err);
                return;
            }
@ -267,7 +267,7 @@ class Doctor extends RedisModel {
            // 含有患者的群
            GroupMsgRepo.findAllGroupsWithPatient(userId, function (err, groups) {
                if (err) {
                    ModelUtil.emitDbError(self.eventEmitter, 'Get group list with patient failed', err);
                    ModelUtil.emitError(self.eventEmitter, 'Get group list with patient failed', err);
                    return;
                }
@ -291,7 +291,7 @@ class Doctor extends RedisModel {
                // 医生间的私聊
                PrivateMsgRepo.findAllP2PWithDoctor(userId, function (err, doctors) {
                    if (err) {
                        ModelUtil.emitDbError(self.eventEmitter, 'Get chat list with doctor failed', err);
                        ModelUtil.emitError(self.eventEmitter, 'Get chat list with doctor failed', err);
                        return;
                    }
@ -312,7 +312,7 @@ class Doctor extends RedisModel {
                    // 获取医生间的组
                    GroupMsgRepo.findAllGroupsWithDoctor(userId, function (err, groups) {
                        if (err) {
                            ModelUtil.emitDbError(self.eventEmitter, 'Get group list with doctor failed', err);
                            ModelUtil.emitError(self.eventEmitter, 'Get group list with doctor failed', err);
                            return;
                        }
@ -329,7 +329,7 @@ class Doctor extends RedisModel {
                            });
                        }
                        ModelUtil.emitData(self.eventEmitter, chats);
                        ModelUtil.emitOK(self.eventEmitter, chats);
                    });
                });
            })
@ -344,7 +344,7 @@ class Doctor extends RedisModel {
        PrivateMsgRepo.findAllP2PWithPatient(userId, function (err, patients) {
            if (err) {
                ModelUtil.emitDbError(self.eventEmitter, 'Get chat list with patient failed', err);
                ModelUtil.emitError(self.eventEmitter, 'Get chat list with patient failed', err);
                return;
            }
@ -366,7 +366,7 @@ class Doctor extends RedisModel {
            GroupMsgRepo.findAllGroupsWithPatient(userId, function (err, groups) {
                if (err) {
                    ModelUtil.emitDbError(self.eventEmitter, 'Get group list with patient failed', err);
                    ModelUtil.emitError(self.eventEmitter, 'Get group list with patient failed', err);
                    return;
                }
@ -387,7 +387,7 @@ class Doctor extends RedisModel {
                    });
                }
                ModelUtil.emitData(self.eventEmitter, chats);
                ModelUtil.emitOK(self.eventEmitter, chats);
            })
        });
    }
@ -403,7 +403,7 @@ class Doctor extends RedisModel {
        // 先获取医生间的私聊
        PrivateMsgRepo.findAllP2PWithDoctor(userId, function (err, doctors) {
            if (err) {
                ModelUtil.emitDbError(self.eventEmitter, 'Get chat list with doctor failed', err);
                ModelUtil.emitError(self.eventEmitter, 'Get chat list with doctor failed', err);
                return;
            }
@ -425,7 +425,7 @@ class Doctor extends RedisModel {
            // 再获取医生间的组
            GroupMsgRepo.findAllGroupsWithDoctor(userId, function (err, groups) {
                if (err) {
                    ModelUtil.emitDbError(self.eventEmitter, 'Get group list with doctor failed', err);
                    ModelUtil.emitError(self.eventEmitter, 'Get group list with doctor failed', err);
                    return;
                }
@ -442,7 +442,7 @@ class Doctor extends RedisModel {
                    });
                }
                ModelUtil.emitData(self.eventEmitter, chats);
                ModelUtil.emitOK(self.eventEmitter, chats);
            });
        });
    }
@ -458,7 +458,7 @@ class Doctor extends RedisModel {
        // 先获取医生间的私聊
        PrivateMsgRepo.findAllP2PWithDoctor(userId, function (err, doctors) {
            if (err) {
                ModelUtil.emitDbError(self.eventEmitter, 'Get chat list with doctor failed', err);
                ModelUtil.emitError(self.eventEmitter, 'Get chat list with doctor failed', err);
                return;
            }
            var amount = 0;
@ -471,7 +471,7 @@ class Doctor extends RedisModel {
            // 再获取医生间的组
            GroupMsgRepo.findAllGroupsWithDoctor(userId, function (err, groups) {
                if (err) {
                    ModelUtil.emitDbError(self.eventEmitter, 'Get group list with doctor failed', err);
                    ModelUtil.emitError(self.eventEmitter, 'Get group list with doctor failed', err);
                    return;
                }
@ -486,7 +486,7 @@ class Doctor extends RedisModel {
                //获取患者记录数量
                PrivateMsgRepo.findAllP2PWithPatient(userId, function (err, patients) {
                    if (err) {
                        ModelUtil.emitDbError(self.eventEmitter, 'Get chat list with patient failed', err);
                        ModelUtil.emitError(self.eventEmitter, 'Get chat list with patient failed', err);
                        return;
                    }
                    for (let i = 0; i < patients.length; i++) {
@ -499,7 +499,7 @@ class Doctor extends RedisModel {
                    //获取患者记录数量
                    GroupMsgRepo.findAllGroupsWithPatient(userId, function (err, groups) {
                        if (err) {
                            ModelUtil.emitDbError(self.eventEmitter, 'Get group list with patient failed', err);
                            ModelUtil.emitError(self.eventEmitter, 'Get group list with patient failed', err);
                            return;
                        }
                        for (let i = 0; i < groups.length; i++) {
@ -511,7 +511,7 @@ class Doctor extends RedisModel {
                            patientAmount = patientAmount+ group.new_msg_count;
                        }
                        chats.patient = patientAmount;
                        ModelUtil.emitData(self.eventEmitter, chats);
                        ModelUtil.emitOK(self.eventEmitter, chats);
                    });
                });
            });
@ -534,12 +534,12 @@ class Doctor extends RedisModel {
        PrivateMsgRepo.findAllMessages(userId, peerId, contentType === undefined ? "0,1,2,3,4,5,6" : contentType, msgStartId, msgEndId, count, closedInterval, function (err, rows) {
            if (err) {
                ModelUtil.emitDbError(self.eventEmitter, 'Get private message failed', err);
                ModelUtil.emitError(self.eventEmitter, 'Get private message failed', err);
                return;
            }
            let messages = Doctor.fillMessages(rows);
            ModelUtil.emitData(self.eventEmitter, messages);
            ModelUtil.emitOK(self.eventEmitter, messages);
            // 清空统计信息
            StatsRepo.clearPrivateChatSummary(userId, peerId, function (err, result) {
@ -559,7 +559,7 @@ class Doctor extends RedisModel {
        StatsRepo.getPrivateChatAllUnReadCount(userId, function (err, result) {
            if (err) {
                ModelUtil.emitDbError(self.eventEmitter, "Get unread private message count failed", err);
                ModelUtil.emitError(self.eventEmitter, "Get unread private message count failed", err);
                return;
            }
@ -568,7 +568,7 @@ class Doctor extends RedisModel {
                data.newMessageCount += result[i].new_msg_count;
            }
            ModelUtil.emitData(self.eventEmitter, data);
            ModelUtil.emitOK(self.eventEmitter, data);
        });
    }
@ -582,7 +582,7 @@ class Doctor extends RedisModel {
        StatsRepo.getChatAllUnReadCount(userId, function (err, result) {
            if (err) {
                ModelUtil.emitDbError(self.eventEmitter, "Get all unread message count failed", err);
                ModelUtil.emitError(self.eventEmitter, "Get all unread message count failed", err);
                return;
            }
@ -591,7 +591,7 @@ class Doctor extends RedisModel {
                data.newMessageCount += result[index].new_msg_count;
            }
            ModelUtil.emitData(self.eventEmitter, data);
            ModelUtil.emitOK(self.eventEmitter, data);
        });
    }
@ -605,24 +605,24 @@ class Doctor extends RedisModel {
        let self = this;
        StatsRepo.getPrivateChatSummary(userId, peerId, function (err, summary) {
            if (err) {
                ModelUtil.emitDbError(self.eventEmitter, 'Get unread private messages failed', err);
                ModelUtil.emitError(self.eventEmitter, 'Get unread private messages failed', err);
                return;
            }
            // 没有未读消息,直接返回
            if (summary.length == 0 || summary[0].new_msg_count === 0) {
                ModelUtil.emitData(self.eventEmitter, {startId: 0, count: 0, records: []});
                ModelUtil.emitOK(self.eventEmitter, {startId: 0, count: 0, records: []});
                return;
            }
            PrivateMsgRepo.findUnread(peerId, userId, MAX_INT, summary[0].new_msg_count, function (err, rows) {
                if (err) {
                    ModelUtil.emitDbError(self.eventEmitter, "Get unread private messages failed", err);
                    ModelUtil.emitError(self.eventEmitter, "Get unread private messages failed", err);
                    return;
                }
                let messages = Doctor.fillMessages(rows);
                ModelUtil.emitData(self.eventEmitter, messages);
                ModelUtil.emitOK(self.eventEmitter, messages);
            });
        });
    }
@ -637,7 +637,7 @@ class Doctor extends RedisModel {
        let self = this;
        StatsRepo.getPrivateChatSummary(userId, peerId, function (err, result) {
            if (err) {
                ModelUtil.emitDbError(self.eventEmitter, "Get private messages statistic failed", err);
                ModelUtil.emitError(self.eventEmitter, "Get private messages statistic failed", err);
                return;
            }
@ -661,7 +661,7 @@ class Doctor extends RedisModel {
                data.timestamp = ObjectUtil.timestampToLong(row.timestamp)
            }
            ModelUtil.emitData(self.eventEmitter, data);
            ModelUtil.emitOK(self.eventEmitter, data);
        });
    }
@ -672,7 +672,7 @@ class Doctor extends RedisModel {
            // 私信
            PrivateMsgRepo.findOneMessage(messageId, function (err, result) {
                if (err) {
                    ModelUtil.emitDbError(self.eventEmitter, "Get message failed", err);
                    ModelUtil.emitError(self.eventEmitter, "Get message failed", err);
                    return;
                }
@ -681,7 +681,7 @@ class Doctor extends RedisModel {
                    return;
                }
                ModelUtil.emitData(self.eventEmitter, {
                ModelUtil.emitOK(self.eventEmitter, {
                    id: result[0].msg_id,
                    from: result[0].from_uid,
                    to: result[0].to_uid,
@ -694,7 +694,7 @@ class Doctor extends RedisModel {
            // 群信
            GroupMsgRepo.findOneMessage(messageId, function (err, result) {
                if (err) {
                    ModelUtil.emitDbError(self.eventEmitter, "Get message failed", err);
                    ModelUtil.emitError(self.eventEmitter, "Get message failed", err);
                    return;
                }
@ -703,7 +703,7 @@ class Doctor extends RedisModel {
                    return;
                }
                ModelUtil.emitData(self.eventEmitter, {
                ModelUtil.emitOK(self.eventEmitter, {
                    id: result[0].msg_id,
                    from: result[0].from_uid,
                    at: result[0].at_uid,
@ -724,7 +724,7 @@ class Doctor extends RedisModel {
        PrivateMsgRepo.isCurrentSessionFinished(doctorId, patientId, function (err, result) {
            if (err) {
                ModelUtil.emitDbError(self.eventEmitter, "Get session finish status failed: ", err);
                ModelUtil.emitError(self.eventEmitter, "Get session finish status failed: ", err);
                return;
            }
@ -738,7 +738,7 @@ class Doctor extends RedisModel {
                }
            }
            ModelUtil.emitData(self.eventEmitter, data);
            ModelUtil.emitOK(self.eventEmitter, data);
        })
    }

+ 9 - 9
src/server/models/user/patient.js

@ -49,18 +49,18 @@ class Patient extends RedisModel {
        PmRepo.save(message.to, message.from, message.contentType, tempContent, function (err, result) {
            if (err) {
                ModelUtil.emitDbError(self.eventEmitter, 'Save private message failed', err);
                ModelUtil.emitError(self.eventEmitter, 'Save private message failed', err);
                return;
            }
            // 结束网络连接,后续操作继续执行
            PmRepo.findOnePatientMessage(result.insertId, function (err, msg) {
                if (err) {
                    ModelUtil.emitDbError(self.eventEmitter, 'Save private message success, but return last message failed', err);
                    ModelUtil.emitError(self.eventEmitter, 'Save private message success, but return last message failed', err);
                    return;
                }
                ModelUtil.emitData(self.eventEmitter, Doctor.fillMessages(msg));
                ModelUtil.emitOK(self.eventEmitter, Doctor.fillMessages(msg));
                // 通过Web Socket推送给患者
                let patientClient = clientCache.findById(message.to);
@ -104,7 +104,7 @@ class Patient extends RedisModel {
        }
        GroupRepo.getOnGroupMsg(message.msgId, function (err, result) {
            if (err) {
                ModelUtil.emitDbError(self.eventEmitter, "get group msg info failed", err);
                ModelUtil.emitError(self.eventEmitter, "get group msg info failed", err);
            }
            var msg = result ? result[0] : "";
@ -167,7 +167,7 @@ class Patient extends RedisModel {
        // 查询居民openid
        PatientRepo.getPatientOpenid(message.to, function (err, result) {
            if (err) {
                ModelUtil.emitDbError(self.eventEmitter, "get patient openid failed", err);
                ModelUtil.emitError(self.eventEmitter, "get patient openid failed", err);
                return;
            }
@ -177,7 +177,7 @@ class Patient extends RedisModel {
                // 查询医生信息
                DoctorRepo.findOne(message.from, function (err, result) {
                    if (err) {
                        ModelUtil.emitDbError(self.eventEmitter, "get doctor info failed", err);
                        ModelUtil.emitError(self.eventEmitter, "get doctor info failed", err);
                        return;
                    }
                    if (result && result.length > 0) {
@ -186,7 +186,7 @@ class Patient extends RedisModel {
                        if (message.group) {
                            GroupRepo.getGroupConsultInfo(message.group, function (err, result) {
                                if (err) {
                                    ModelUtil.emitDbError(self.eventEmitter, "get patient and doctor consult info failed", err);
                                    ModelUtil.emitError(self.eventEmitter, "get patient and doctor consult info failed", err);
                                    return;
                                }
@ -200,7 +200,7 @@ class Patient extends RedisModel {
                            // 查询医生与居民对应的咨询信息
                            PatientRepo.getPatientDoctorConsult(message.to, message.from, function (err, result) {
                                if (err) {
                                    ModelUtil.emitDbError(self.eventEmitter, "get patient and doctor consult info failed", err);
                                    ModelUtil.emitError(self.eventEmitter, "get patient and doctor consult info failed", err);
                                    return;
                                }
@ -212,7 +212,7 @@ class Patient extends RedisModel {
                            });
                        }
                    } else {
                        ModelUtil.emitDbError(self.eventEmitter, "can not find doctor info", err);
                        ModelUtil.emitError(self.eventEmitter, "can not find doctor info", err);
                    }
                });
            } else {

+ 140 - 136
src/server/models/user/users.js

@ -42,7 +42,7 @@ class Users extends RedisModel {
     * @param userId
     * @param outCallback
     */
    getUser(userId, outCallback) {
    getUserFromMySQL(userId, outCallback) {
        let self = this;
        async.waterfall([
            // determine user type
@ -80,7 +80,7 @@ class Users extends RedisModel {
        redisConn.hgetallAsync(self.makeRedisKey(REDIS_KEYS.UserWechatStatus, userId))
            .then(function (res) {
                if (res) {
                    ModelUtil.emitData(self, res);
                    ModelUtil.emitOK(self, res);
                } else {
                    ModelUtil.emitDataNotFound(self, {"message": "User is offline, unable to get wechat status."});
                }
@ -134,21 +134,25 @@ class Users extends RedisModel {
     */
    updateAppStatus(userId, appInBg) {
        let self = this;
        redisConn.hsetAsync(self.makeRedisKey(REDIS_KEYS.UserAppStatus, userId), 'app_in_bg', appInBg)
            .then(function (res) {
                if (res) {
                    ModelUtil.emitData(self.eventEmitter, {});
                } else {
                    ModelUtil.emitDataNotFound(self.eventEmitter, {"message": "User is offline, unable to update app status."});
                }
            });
        let userStatusKey = self.makeRedisKey(REDIS_KEYS.UserAppStatus, userId);
        redisConn.hgetAsync(userStatusKey, 'app_in_bg').then(function (res) {
            if (res !== null) {
                redisConn.hsetAsync(userStatusKey, 'app_in_bg', appInBg).then(function (res) {
                    ModelUtil.emitOK(self.eventEmitter, {});
                });
            } else {
                ModelUtil.emitDataNotFound(self.eventEmitter, {"message": "User is offline, unable to update app status."});
            }
        });
    }
    /**
     * 用户登录。
     * 用户登录,仅缓存用户客户端状态信息,不缓存用户基本信息。
     *
     * 用户登录时会加载与之相关的会话列表,会话消息,用户自身信息:App状态与微信状态。
     *
     * TODO: 如果用户已经登录,但因为异常退出重新登录,是否需要刷新状态信息。
     *
     * @param userId
     * @param platform
     * @param token
@ -166,127 +170,127 @@ class Users extends RedisModel {
        let lastLoginTime = new Date();
        async.waterfall([
            // get user info from mysql
            function (callback) {
                self.getUser(userId, function (err, userInfo) {
                    if (userInfo === null) {
                        ModelUtil.emitDataNotFound(self, 'User not exists.');
                        return;
                    }
                    callback(null, userInfo);
                })
            },
            // cache user info and app/wechat status
            function (userInfo, callback) {
                let multi = redisConn.multi()
                    .zadd(usersKey, lastLoginTime.getMilliseconds(), userId)
                    .hmset(userKey, 'avatar', userInfo.avatar ? userInfo.avatar : '', 'birthdate', userInfo.birthdate? userInfo.birthdate : '',
                        'name', userInfo.name, 'role', loginFromApp ? 'doctor' : 'patient');
                if (loginFromApp) {
                    // cache app status
                    multi = multi.hmset(userStatusKey, 'platform', platform, 'app_in_bg', false, 'client_id', clientId,
                        'token', token, 'last_login_time', lastLoginTime);
                } else {
                    // cache wechat status
                    multi = multi.hmset(userKey, 'open_id', userInfo.open_id);
                }
                // get user info from mysql
                function (callback) {
                    self.getUserFromMySQL(userId, function (err, userInfo) {
                        if (userInfo === null) {
                            ModelUtil.emitDataNotFound(self, 'User not exists.');
                            return;
                        }
                multi.execAsync().then(function (res) {
                    callback(null);
                });
            },
            // cache sessions, participants, topics, messages
            function (callback) {
                SessionRepo.findAll(userId, function (err, sessions) {
                    for (let session in sessions) {
                        let sessionId = session.id;
                        let name = session.name;
                        let type = session.type;
                        let createDate = session.create_date;
                        (function (sessionId, userId) {
                            // cache sessions
                            redisConn.multi()
                                .zadd(self.makeRedisKey(REDIS_KEYS.Sessions), lastLoginTime)                // 会话的最后活动时间设置为此用户的登录时间
                                .zadd(self.makeRedisKey(REDIS_KEYS.UserSessions, userId), lastLoginTime)    // 会话的最后活动时间设置为此用户的登录时间
                                .hmset(self.makeRedisKey(REDIS_KEYS.Session, sessionId, 'name', name, 'type', type, 'create_date', createDate))
                                .execAsync().then(function (res) {
                                // cache participants
                                let sessionParticipantsKey = self.makeRedisKey(REDIS_KEYS.Participants, sessionId);
                                let sessionParticipantsRoleKey = self.makeRedisKey(REDIS_KEYS.ParticipantsRole, sessionId);
                                ParticipantRepo.findParticipants(sessionId, function (err, participants) {
                                    for (let participant in participants) {
                                        let participantId = participant.participant_id;
                                        let participantRole = participant.participant_role;
                                        let score = new Date().getMilliseconds();
                                        redisConn.multi()
                                            .zadd(sessionParticipantsKey, participantId, score)
                                            .hset(sessionParticipantsRoleKey, participantId, participantRole)
                                            .execAsync().then(function (res) {
                                        });
                                    }
                                });
                        callback(null, userInfo);
                    })
                },
                // cache user app/wechat status
                function (userInfo, callback) {
                    let multi = redisConn.multi()
                        .zadd(usersKey, lastLoginTime.getMilliseconds(), userId);
                        //.hmset(userKey, 'avatar', userInfo.avatar ? userInfo.avatar : '', 'birthdate', userInfo.birthdate ? userInfo.birthdate : '',
                        //    'name', userInfo.name, 'role', loginFromApp ? 'doctor' : 'patient');
                    if (loginFromApp) {
                        // cache app status
                        multi = multi.hmset(userStatusKey, 'platform', platform, 'app_in_bg', false, 'client_id', clientId,
                            'token', token, 'last_login_time', lastLoginTime);
                    } else {
                        // cache wechat status
                        multi = multi.hmset(userKey, 'open_id', userInfo.open_id);
                    }
                                // cache messages
                                let messagesKey = self.makeRedisKey(REDIS_KEYS.Messages, sessionId);
                                let messagesByTimestampKey = self.makeRedisKey(REDIS_KEYS.MessagesByTimestamp, sessionId);
                                MessageRepo.findBySessionId(sessionId, 0, config.sessionConfig.maxMessageCount, function (err, messages) {
                                    for (let message in messages) {
                                        let id = message.id;
                                        let msgJson = {
                                            sessionId: message.session_id,
                                            senderId: message.sender_id,
                                            senderName: message.sender_name,
                                            contentType: message.content_type,
                                            content: message.content,
                                            timestamp: message.timestamp
                                        };
                                        redisConn.multi()
                                            .hset(messagesKey, id, msgJson)
                                            .zadd(messagesByTimestampKey, id)
                                            .execAsync()
                                            .then(function (res) {
                    multi.execAsync().then(function (res) {
                        callback(null);
                    });
                },
                // cache sessions, participants, topics, messages
                function (callback) {
                    SessionRepo.findAll(userId, function (err, sessions) {
                        for (let session in sessions) {
                            let sessionId = session.id;
                            let name = session.name;
                            let type = session.type;
                            let createDate = session.create_date;
                            (function (sessionId, userId) {
                                // cache sessions
                                redisConn.multi()
                                    .zadd(self.makeRedisKey(REDIS_KEYS.Sessions), lastLoginTime)                // 会话的最后活动时间设置为此用户的登录时间
                                    .zadd(self.makeRedisKey(REDIS_KEYS.UserSessions, userId), lastLoginTime)    // 会话的最后活动时间设置为此用户的登录时间
                                    .hmset(self.makeRedisKey(REDIS_KEYS.Session, sessionId, 'name', name, 'type', type, 'create_date', createDate))
                                    .execAsync().then(function (res) {
                                    // cache participants
                                    let sessionParticipantsKey = self.makeRedisKey(REDIS_KEYS.Participants, sessionId);
                                    let sessionParticipantsRoleKey = self.makeRedisKey(REDIS_KEYS.ParticipantsRole, sessionId);
                                    ParticipantRepo.findParticipants(sessionId, function (err, participants) {
                                        for (let participant in participants) {
                                            let participantId = participant.participant_id;
                                            let participantRole = participant.participant_role;
                                            let score = new Date().getMilliseconds();
                                            redisConn.multi()
                                                .zadd(sessionParticipantsKey, participantId, score)
                                                .hset(sessionParticipantsRoleKey, participantId, participantRole)
                                                .execAsync().then(function (res) {
                                            });
                                    }
                                });
                                // cache topics for MUC
                                let topicsKey = self.makeRedisKey(REDIS_KEYS.Topics, sessionId);
                                TopicRepo.findAll(sessionId, function (err, topics) {
                                    for (let topic in topics) {
                                        let topicKey = self.makeRedisKey(REDIS_KEYS.Topic, topic.id);
                                        let topicId = topic.id;
                                        let name = topic.name;
                                        let createTime = ObjectUtil.timestampToLong(topic.create_time);
                                        let endBy = topic.end_by;
                                        let endTime = ObjectUtil.timestampToLong(topic.end_time);
                                        let startMessageId = topic.start_message_id;
                                        let endMessageId = topic.end_message_id;
                                        redisConn.multi()
                                            .zadd(topicsKey, topicId)
                                            .hmset(topicKey, 'name', name, 'session_id', sessionId, 'create_time',
                                                createTime, 'end_by', endBy, 'end_time', endTime, 'start_message_id',
                                                startMessageId, 'end_message_id', endMessageId)
                                            .execAsync().then(function (res) {
                                        });
                                    }
                                        }
                                    });
                                    // cache messages
                                    let messagesKey = self.makeRedisKey(REDIS_KEYS.Messages, sessionId);
                                    let messagesByTimestampKey = self.makeRedisKey(REDIS_KEYS.MessagesByTimestamp, sessionId);
                                    MessageRepo.findBySessionId(sessionId, 0, config.sessionConfig.maxMessageCount, function (err, messages) {
                                        for (let message in messages) {
                                            let id = message.id;
                                            let msgJson = {
                                                sessionId: message.session_id,
                                                senderId: message.sender_id,
                                                senderName: message.sender_name,
                                                contentType: message.content_type,
                                                content: message.content,
                                                timestamp: message.timestamp
                                            };
                                            redisConn.multi()
                                                .hset(messagesKey, id, msgJson)
                                                .zadd(messagesByTimestampKey, id)
                                                .execAsync()
                                                .then(function (res) {
                                                });
                                        }
                                    });
                                    // cache topics for MUC
                                    let topicsKey = self.makeRedisKey(REDIS_KEYS.Topics, sessionId);
                                    TopicRepo.findAll(sessionId, function (err, topics) {
                                        for (let topic in topics) {
                                            let topicKey = self.makeRedisKey(REDIS_KEYS.Topic, topic.id);
                                            let topicId = topic.id;
                                            let name = topic.name;
                                            let createTime = ObjectUtil.timestampToLong(topic.create_time);
                                            let endBy = topic.end_by;
                                            let endTime = ObjectUtil.timestampToLong(topic.end_time);
                                            let startMessageId = topic.start_message_id;
                                            let endMessageId = topic.end_message_id;
                                            redisConn.multi()
                                                .zadd(topicsKey, topicId)
                                                .hmset(topicKey, 'name', name, 'session_id', sessionId, 'create_time',
                                                    createTime, 'end_by', endBy, 'end_time', endTime, 'start_message_id',
                                                    startMessageId, 'end_message_id', endMessageId)
                                                .execAsync().then(function (res) {
                                            });
                                        }
                                    });
                                });
                            });
                        })(sessionId, userId);
                    }
                });
                            })(sessionId, userId);
                        }
                    });
                callback(null, null);
            }
        ],
        function (err, res) {
            ModelUtil.emitData(self.eventEmitter, {});
        });
                    callback(null, null);
                }
            ],
            function (err, res) {
                ModelUtil.emitOK(self.eventEmitter, {});
            });
    }
    logout(userId) {
@ -297,23 +301,23 @@ class Users extends RedisModel {
                        callback(null, isPatient)
                    });
                },
                function (callback, isPatient) {
                function (isPatient, callback) {
                    let usersKey = REDIS_KEYS.Users;
                    let userKey = self.makeRedisKey(REDIS_KEYS.User, userId);
                    let userStatusKey = self.makeRedisKey(isPatient ? REDIS_KEYS.UserWechatStatus : REDIS_KEYS.UserAppStatus, userId);
                    redisConn.multi()
                        .del(usersKey)
                        .del(userKey)
                        .zrem(usersKey, userId)
                        .del(userStatusKey)
                        .execAsync().then(function (res) {
                            if(res.length > 0 && res[0] === 0){
                        .execAsync()
                        .then(function (res) {
                            if (res.length > 0 && res[0] === 0) {
                                ModelUtil.emitDataNotFound(self.eventEmitter, {message: "User not found."});
                            } else {
                                ModelUtil.emitData(self.eventEmitter, {});
                                ModelUtil.emitOK(self.eventEmitter, {});
                            }
                    });
                        });
                }],
            function (err, res) {}
            function (err, res) {
            }
        );
    }

+ 0 - 11
src/server/resources/config/config.dev.js

@ -1,15 +1,5 @@
"use strict";
// 三师后台数据库配置
let wlyyDbConfig = {
    host: '172.19.103.77',
    user: 'root',
    password: '123456',
    database: 'wlyy',
    connectionLimit: '50',
    charset: 'utf8mb4'
};
// IM数据库配置
let imDbConfig = {
    host: '172.19.103.77',
@ -86,7 +76,6 @@ exports.serverPort = 3008;
exports.sessionExpire = 1800;
exports.showSQL = true;
exports.wlyyDbConfig = wlyyDbConfig;
exports.imDbConfig = imDbConfig;
exports.redisConfig = redisConfig;

+ 0 - 10
src/server/resources/config/config.prod.js

@ -1,14 +1,5 @@
"use strict";
let wlyyDbConfig = {
    host: '59.61.92.94',
    user: 'wlyy',
    password: 'jkzlehr@123',
    database: 'wlyy',
    connectionLimit: '100',
    charset : 'utf8mb4'
};
let imDbConfig = {
    host: '59.61.92.94',
    user: 'wlyy',
@ -80,7 +71,6 @@ exports.serverPort = 3000;
exports.sessionExpire = 1800;
exports.showSQL = false;
exports.wlyyDbConfig = wlyyDbConfig;
exports.imDbConfig = imDbConfig;
exports.redisConfig = redisConfig;

+ 0 - 10
src/server/resources/config/config.test.js

@ -1,14 +1,5 @@
"use strict";
var wlyyDbConfig = {
    host: '172.17.110.160',
    user: 'ssgg',
    password: 'ssgg',
    database: 'wlyy',
    connectionLimit: '100',
    charset : 'utf8mb4'
};
var imDbConfig = {
    host: '172.17.110.160',
    user: 'ssgg',
@ -76,7 +67,6 @@ exports.serverPort = 3000;
exports.sessionExpire = 1800;
exports.showSQL= true;
exports.wlyyDbConfig = wlyyDbConfig;
exports.imDbConfig = imDbConfig;
exports.redisConfig = redisConfig;

+ 6 - 2
src/server/util/model.util.js

@ -16,7 +16,11 @@ class ModelUtil {
     * @param eventEmitter
     * @param data
     */
    static emitData(eventEmitter, data) {
    static emitOK(eventEmitter, data) {
        eventEmitter.emit(MODEL_EVENTS.OK, data);
    };
    static emitAlreadyExist(eventEmitter, data){
        eventEmitter.emit(MODEL_EVENTS.OK, data);
    };
@ -37,7 +41,7 @@ class ModelUtil {
     * @param err
     * @param description
     */
    static emitDbError(eventEmitter, description, err) {
    static emitError(eventEmitter, description, err) {
        ModelUtil.logError(description, err);
        eventEmitter.emit(MODEL_EVENTS.Error, {message: description});

+ 10 - 5
test/client/im.client.management.Test.js

@ -10,11 +10,16 @@ var $ = require('jquery');
let assert = require('assert');
let imClient = require('../../src/client/im.client');
describe("IM SDK: management Unit Test", function () {
    // 管理API
    describe("Management  API", function () {
        describe("db_status", function () {
            it("return 200 while database is ok", function (done) {
// 管理API
describe("Management API", function () {
    describe("db_status", function () {
        it("return success while database is ok", function (done) {
            imClient.Management.getDbStatus(function (data) {
                assert.strictEqual(Object.keys(data).length > 0, true);
                done();
            },
            function (xhr, status, error) {
                assert.ok(false, xhr.responseJSON.message);
                done();
            });
        });

+ 53 - 50
test/client/im.client.user.Test.js

@ -20,72 +20,75 @@ let TD = {
    }
};
describe("IM SDK: user", function () {
describe("User API", function () {
    /**
     * 用户API。测试范围:
     * 1 有效/无效用户ID登录/状态更新/退出
     */
    describe("User API", function () {
        describe("login", function () {
            it("return 200 with valid user", function (done) {
                imClient.Users.login(TD.DoctorA.id, TD.DoctorA.token, TD.DoctorA.clientId, TD.DoctorA.platform,
                    function (data) {
                        assert.strictEqual(Object.keys(data).length, 0);
                        done();
                    },
                    function (xhr, status, error) {
                        assert.ok(false, xhr.responseJSON.message);
                        done();
                    });
            });
    describe("login", function () {
        it("return success with valid user", function (done) {
            imClient.Users.login(TD.DoctorA.id, TD.DoctorA.token, TD.DoctorA.clientId, TD.DoctorA.platform,
                function (data) {
                    assert.strictEqual(Object.keys(data).length, 0);
                    done();
                },
                function (xhr, status, error) {
                    assert.ok(false, xhr.responseJSON.message);
                    done();
                });
        });
            it("return 404 with invalid user", function (done) {
                done();
            });
        it("return failed with invalid user", function (done) {
            done();
        });
    });
        describe("updateStatus", function () {
            it("return 200 with valid user", function (done) {
                imClient.Users.updateStatus(TD.DoctorA.id, 1, function (data) {
    describe("updateStatus", function () {
        it("return success with valid user", function (done) {
            imClient.Users.updateStatus(TD.DoctorA.id, true, function (data) {
                    assert.strictEqual(Object.keys(data).length, 0);
                    done();
                },
                function (xhr, status, error) {
                    console.error(xhr.responseJSON.message);
                    assert.strictEqual(xhr.status, 200);
                    done();
                });
            });
        });
            it("return 404 with invalid user", function (done) {
                imClient.Users.updateStatus("invalid_user_id", 1, function (data) {
                        done();
                    },
                    function (xhr, status, error) {
                        done();
                    });
            });
        it("return failed with invalid user", function (done) {
            imClient.Users.updateStatus("invalid_user_id", true, function (data) {
                    assert.ok(false, "Update status with invalid user id must NOT return success");
                    done();
                },
                function (xhr, status, error) {
                    assert.strictEqual(xhr.status, 404);
                    done()
                });
        });
    });
        describe("logout", function () {
            it("return 200 with valid user", function (done) {
                imClient.Users.logout(TD.DoctorA.id, function (data) {
                        assert.strictEqual(Object.keys(data).length, 0);
                        done();
                    },
                    function (xhr, status, error) {
                        assert.strictEqual(status, "error");
                        done()
                    });
            });
    describe("logout", function () {
        it("return success with valid user", function (done) {
            imClient.Users.logout(TD.DoctorA.id, function (data) {
                    assert.strictEqual(Object.keys(data).length, 0);
                    done();
                },
                function (xhr, status, error) {
                    assert.ok(false, xhr.responseJSON.message);
                    done()
                });
        });
            it("return 404 with invalid user id", function (done) {
                imClient.Users.logout("invalid_user_id", function (data) {
                        assert.ok(false, "Logout with invalid user id must NOT return success");
                        done();
                    },
                    function (xhr, status, error) {
                        assert.strictEqual(xhr.status, 404);
                        done()
                    });
            });
        it("return failed with invalid user id", function (done) {
            imClient.Users.logout("invalid_user_id", function (data) {
                    assert.ok(false, "Logout with invalid user id must NOT return success");
                    done();
                },
                function (xhr, status, error) {
                    assert.strictEqual(xhr.status, 404);
                    done()
                });
        });
    });
});