|
@ -12,18 +12,23 @@ const PLATFORMS = require('../../include/commons').PLATFORM;
|
|
let RedisModel = require('../redis.model');
|
|
let RedisModel = require('../redis.model');
|
|
let Doctor = require('./doctor');
|
|
let Doctor = require('./doctor');
|
|
let Patient = require('./patient');
|
|
let Patient = require('./patient');
|
|
let Sessions = require('../sessions/sessions');
|
|
|
|
|
|
|
|
let ImDb = require('../../repository/mysql/db/im.db');
|
|
let ImDb = require('../../repository/mysql/db/im.db');
|
|
|
|
let ParticipantRepo = require('../../repository/mysql/participant.repo');
|
|
let DoctorRepo = require('../../repository/mysql/doctor.repo');
|
|
let DoctorRepo = require('../../repository/mysql/doctor.repo');
|
|
let PatientRepo = require('../../repository/mysql/patient.repo');
|
|
let PatientRepo = require('../../repository/mysql/patient.repo');
|
|
let AppStatusRepo = require('../../repository/mysql/app.status.repo');
|
|
let AppStatusRepo = require('../../repository/mysql/app.status.repo');
|
|
|
|
let SessionRepo = require('../../repository/mysql/session.repo');
|
|
|
|
let TopicRepo = require('../../repository/mysql/topic.repo');
|
|
|
|
let MessageRepo = require('../../repository/mysql/message.repo');
|
|
let ModelUtil = require('../../util/model.util');
|
|
let ModelUtil = require('../../util/model.util');
|
|
|
|
|
|
let RedisClient = require('../../repository/redis/redis.client');
|
|
let RedisClient = require('../../repository/redis/redis.client');
|
|
|
|
|
|
let redisConn = RedisClient.redisClient().connection;
|
|
let redisConn = RedisClient.redisClient().connection;
|
|
let async = require('async');
|
|
let async = require('async');
|
|
let log = require('../../util/log');
|
|
let log = require('../../util/log');
|
|
|
|
let configFile = require('../../include/commons').CONFIG_FILE;
|
|
|
|
let config = require('../../resources/config/' + configFile);
|
|
|
|
|
|
class Users extends RedisModel {
|
|
class Users extends RedisModel {
|
|
constructor() {
|
|
constructor() {
|
|
@ -52,7 +57,7 @@ class Users extends RedisModel {
|
|
let repoProto = isPatientId ? PatientRepo : DoctorRepo;
|
|
let repoProto = isPatientId ? PatientRepo : DoctorRepo;
|
|
repoProto.findOne(userId, function (err, res) {
|
|
repoProto.findOne(userId, function (err, res) {
|
|
let user = isPatientId ? new Doctor() : new Patient();
|
|
let user = isPatientId ? new Doctor() : new Patient();
|
|
if(res.length > 0){
|
|
|
|
|
|
if (res.length > 0) {
|
|
user.name = res[0].name;
|
|
user.name = res[0].name;
|
|
user.sex = res[0].sex;
|
|
user.sex = res[0].sex;
|
|
user.birthdate = res[0].birthdate;
|
|
user.birthdate = res[0].birthdate;
|
|
@ -65,31 +70,49 @@ class Users extends RedisModel {
|
|
]);
|
|
]);
|
|
}
|
|
}
|
|
|
|
|
|
|
|
/**
|
|
|
|
* 取得用户微信端状态。
|
|
|
|
*
|
|
|
|
* @param userId
|
|
|
|
* @param outCallback
|
|
|
|
*/
|
|
|
|
getWechatStatus(userId) {
|
|
|
|
let self = this;
|
|
|
|
redisConn.hgetallAsync(self.makeRedisKey(REDIS_KEYS.UserWechatStatus, userId))
|
|
|
|
.then(function (res) {
|
|
|
|
if (res) {
|
|
|
|
ModelUtil.emitData(self, res);
|
|
|
|
} else {
|
|
|
|
ModelUtil.emitDataNotFound(self, {"message": "User is offline, unable to get wechat status."});
|
|
|
|
}
|
|
|
|
});
|
|
|
|
}
|
|
|
|
|
|
/**
|
|
/**
|
|
* 获取客户端App状态。
|
|
* 获取客户端App状态。
|
|
*
|
|
*
|
|
* @param userId
|
|
* @param userId
|
|
* @param outCallback
|
|
* @param outCallback
|
|
*/
|
|
*/
|
|
getAppStatus(userId, outCallback){
|
|
|
|
|
|
getAppStatus(userId, outCallback) {
|
|
let self = this;
|
|
let self = this;
|
|
async.waterfall([
|
|
async.waterfall([
|
|
// get from redis
|
|
// get from redis
|
|
function (callback) {
|
|
function (callback) {
|
|
let userStatusKey = self.makeRedisKey(REDIS_KEYS.UserStatus, userId);
|
|
let userStatusKey = self.makeRedisKey(REDIS_KEYS.UserStatus, userId);
|
|
redisConn.hgetallAsync(userStatusKey).then(function (res) {
|
|
redisConn.hgetallAsync(userStatusKey).then(function (res) {
|
|
if(res === null){
|
|
|
|
callback(null); // get from mysql
|
|
|
|
} else {
|
|
|
|
outCallback(null, res);
|
|
|
|
}
|
|
|
|
|
|
if (res === null) {
|
|
|
|
callback(null); // get from mysql
|
|
|
|
} else {
|
|
|
|
outCallback(null, res);
|
|
|
|
}
|
|
});
|
|
});
|
|
},
|
|
},
|
|
// get from MySQL
|
|
// get from MySQL
|
|
function () {
|
|
function () {
|
|
AppStatusRepo.findOne(userId, function (err, res) {
|
|
AppStatusRepo.findOne(userId, function (err, res) {
|
|
let userStatus = null;
|
|
let userStatus = null;
|
|
if(res.length > 0){
|
|
|
|
|
|
if (res.length > 0) {
|
|
userStatus = {};
|
|
userStatus = {};
|
|
userStatus.platform = res[0].platform;
|
|
userStatus.platform = res[0].platform;
|
|
userStatus.token = res[0].token;
|
|
userStatus.token = res[0].token;
|
|
@ -111,29 +134,18 @@ class Users extends RedisModel {
|
|
* @param appInBg
|
|
* @param appInBg
|
|
* @param outCallback
|
|
* @param outCallback
|
|
*/
|
|
*/
|
|
updateAppStatus(userId, appInBg, outCallback){
|
|
|
|
|
|
updateAppStatus(userId, appInBg, outCallback) {
|
|
let self = this;
|
|
let self = this;
|
|
DoctorRepo.updateStatus(userId, status,
|
|
|
|
function (err, result) {
|
|
|
|
if (err) {
|
|
|
|
ModelUtil.emitDbError(self.eventEmitter, 'Update user status failed', err);
|
|
|
|
return;
|
|
|
|
|
|
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."});
|
|
}
|
|
}
|
|
|
|
|
|
ModelUtil.emitData(self.eventEmitter, {});
|
|
|
|
});
|
|
});
|
|
}
|
|
}
|
|
|
|
|
|
/**
|
|
|
|
* 取得用户微信端状态。
|
|
|
|
*
|
|
|
|
* @param userId
|
|
|
|
* @param outCallback
|
|
|
|
*/
|
|
|
|
getWechatStatus(userId, outCallback){
|
|
|
|
let self = this;
|
|
|
|
}
|
|
|
|
|
|
|
|
/**
|
|
/**
|
|
* 用户登录。
|
|
* 用户登录。
|
|
*
|
|
*
|
|
@ -146,7 +158,7 @@ class Users extends RedisModel {
|
|
*
|
|
*
|
|
* @return 用户token
|
|
* @return 用户token
|
|
*/
|
|
*/
|
|
login(userId, platform, token, clientId){
|
|
|
|
|
|
login(userId, platform, token, clientId) {
|
|
let self = this;
|
|
let self = this;
|
|
let loginFromApp = platform === PLATFORMS.Wechat;
|
|
let loginFromApp = platform === PLATFORMS.Wechat;
|
|
|
|
|
|
@ -159,7 +171,7 @@ class Users extends RedisModel {
|
|
// get user info from mysql
|
|
// get user info from mysql
|
|
function (callback) {
|
|
function (callback) {
|
|
self.getUser(userId, function (err, userInfo) {
|
|
self.getUser(userId, function (err, userInfo) {
|
|
if(userInfo === null){
|
|
|
|
|
|
if (userInfo === null) {
|
|
ModelUtil.emitDataNotFound(self, 'User not exists.');
|
|
ModelUtil.emitDataNotFound(self, 'User not exists.');
|
|
return;
|
|
return;
|
|
}
|
|
}
|
|
@ -169,12 +181,12 @@ class Users extends RedisModel {
|
|
},
|
|
},
|
|
// cache user info and app/wechat status
|
|
// cache user info and app/wechat status
|
|
function (userInfo, callback) {
|
|
function (userInfo, callback) {
|
|
let multi = redisConn.multi()
|
|
|
|
|
|
let multi = redisConn.multiAsync()
|
|
.zadd(usersKey, lastLoginTime.getMilliseconds(), userId)
|
|
.zadd(usersKey, lastLoginTime.getMilliseconds(), userId)
|
|
.hmset(userKey, 'avatar', userInfo.avatar, 'birthdate', userInfo.birthdate,
|
|
.hmset(userKey, 'avatar', userInfo.avatar, 'birthdate', userInfo.birthdate,
|
|
'name', userInfo.name, 'role', loginFromApp ? 'doctor' : 'patient');
|
|
'name', userInfo.name, 'role', loginFromApp ? 'doctor' : 'patient');
|
|
|
|
|
|
if(loginFromApp){
|
|
|
|
|
|
if (loginFromApp) {
|
|
// cache app status
|
|
// cache app status
|
|
multi = multi.hmset(userStatusKey, 'platform', platform, 'app_in_bg', false, 'client_id', clientId,
|
|
multi = multi.hmset(userStatusKey, 'platform', platform, 'app_in_bg', false, 'client_id', clientId,
|
|
'token', token, 'last_login_time', lastLoginTime);
|
|
'token', token, 'last_login_time', lastLoginTime);
|
|
@ -183,31 +195,117 @@ class Users extends RedisModel {
|
|
multi = multi.hmset(userKey, 'open_id', userInfo.open_id);
|
|
multi = multi.hmset(userKey, 'open_id', userInfo.open_id);
|
|
}
|
|
}
|
|
|
|
|
|
multi.execAsnyc().then(function (res) {
|
|
|
|
callback(null);
|
|
|
|
});
|
|
|
|
|
|
multi.execAsync().then(function (res) {
|
|
|
|
callback(null);
|
|
|
|
});
|
|
},
|
|
},
|
|
// cache sessions
|
|
|
|
|
|
// cache sessions, participants, topics, messages
|
|
function (callback) {
|
|
function (callback) {
|
|
let sessions = new Sessions();
|
|
|
|
sessions.getUserSessionsFromMysql();
|
|
|
|
|
|
SessionRepo.findAll(userId, function (err, sessions) {
|
|
|
|
for (let i = 0; i < sessions.length; ++i) {
|
|
|
|
let sessionId = sessions[i].id;
|
|
|
|
let name = sessions[i].name;
|
|
|
|
let type = sessions[i].type;
|
|
|
|
let createDate = sessions[i].create_date;
|
|
|
|
|
|
|
|
(function (sessionId, userId) {
|
|
|
|
// cache sessions
|
|
|
|
redisConn.multiAsync()
|
|
|
|
.zadd(self.makeRedisKey(REDIS_KEYS.UserSessions, userId))
|
|
|
|
.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);
|
|
|
|
ParticipantRepo.findParticipants(sessionId, function (err, participants) {
|
|
|
|
for (let participant in participants) {
|
|
|
|
let participantId = participant.participant_id;
|
|
|
|
let score = new Date().getMilliseconds();
|
|
|
|
|
|
|
|
redisConn.multiAsync()
|
|
|
|
.zaddAsync(sessionParticipantsKey, participantId, score)
|
|
|
|
.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.multiAsync()
|
|
|
|
.hset(messagesKey, id, msgJson)
|
|
|
|
.zadd(messagesByTimestampKey, id)
|
|
|
|
.execAsync()
|
|
|
|
.then(function (res) {
|
|
|
|
});
|
|
|
|
}
|
|
|
|
});
|
|
|
|
|
|
|
|
// cache topics for MUC session
|
|
|
|
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 = topic.create_time;
|
|
|
|
let endBy = topic.end_by;
|
|
|
|
let startMesssageId = topic.start_message_id;
|
|
|
|
let endMessageId = topic.end_message_id;
|
|
|
|
redisConn.multiAsync()
|
|
|
|
.zadd(topicsKey, topicId)
|
|
|
|
.hmset(topicKey, 'name', name, 'session_id', sessionId, 'create_time',
|
|
|
|
createTime, 'end_by', endBy, 'start_message_id',
|
|
|
|
startMesssageId, 'end_message_id', endMessageId)
|
|
|
|
.execAsync().then(function (res) {
|
|
|
|
});
|
|
|
|
}
|
|
|
|
});
|
|
|
|
});
|
|
|
|
})(sessionId, userId);
|
|
|
|
}
|
|
|
|
});
|
|
|
|
|
|
ModelUtil.emitData(self.eventEmitter, {token: token.value});
|
|
|
|
|
|
ModelUtil.emitData(self.eventEmitter, {});
|
|
}
|
|
}
|
|
]);
|
|
]);
|
|
}
|
|
}
|
|
|
|
|
|
logout(userId, outCallback){
|
|
|
|
|
|
logout(userId) {
|
|
let self = this;
|
|
let self = this;
|
|
DoctorRepo.logout(userId,
|
|
|
|
function (err, result) {
|
|
|
|
if (err) {
|
|
|
|
ModelUtil.emitDbError(self.eventEmitter, 'Logout failed', err);
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
async.waterfall([
|
|
|
|
function (callback) {
|
|
|
|
self.isPatientId(userId, function (err, isPatient) {
|
|
|
|
callback(null, isPatient)
|
|
|
|
});
|
|
|
|
},
|
|
|
|
function (callback, isPatient) {
|
|
|
|
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.multiAsync()
|
|
|
|
.del(usersKey)
|
|
|
|
.del(userKey)
|
|
|
|
.del(userStatusKey)
|
|
|
|
.execAsync().then(function (res) {
|
|
|
|
})
|
|
|
|
}],
|
|
|
|
function (err, res) {
|
|
ModelUtil.emitData(self.eventEmitter, {});
|
|
ModelUtil.emitData(self.eventEmitter, {});
|
|
});
|
|
|
|
|
|
}
|
|
|
|
);
|
|
}
|
|
}
|
|
|
|
|
|
/**
|
|
/**
|