Parcourir la source

消息推送测试

Sand il y a 8 ans
Parent
commit
bfc7b300e3

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

@ -68,7 +68,7 @@ exports.PARTICIPANT_ROLES = PARTICIPANT_ROLES;
/**
 *  消息内容类型。
 */
const CONTENT_TYPE = {
const CONTENT_TYPES = {
    PlainText: 1,   // 信息
    Image: 2,       // 图片信息
    Audio: 3,       // 语音信息
@ -78,9 +78,9 @@ const CONTENT_TYPE = {
    TopicEnd: 7,    // 议题结束
    typeToDescription: function (type, defaultDescription) {
        if (type === CONTENT_TYPES.Image) {
        if (CONTENT_TYPES.Image === type) {
            return '[图片]';
        } else if (type === CONTENT_TYPES.Audio) {
        } else if (CONTENT_TYPES.Audio === type) {
            return '[语音]';
        } else if (type > 3) {
            return defaultDescription;
@ -90,7 +90,7 @@ const CONTENT_TYPE = {
    }
};
exports.CONTENT_TYPE = CONTENT_TYPE;
exports.CONTENT_TYPES = CONTENT_TYPES;
/**
 * 客户端平台。

+ 25 - 42
src/server/models/client/app.client.js

@ -10,10 +10,10 @@ let ObjectUtil = require("../../util/object.util.js");
let ModelUtil = require('../../util/model.util');
let log = require("../../util/log.js");
let pusher = require('../pusher');
let pusher = require('../push/pusher');
let redisConn = RedisClient.redisClient().connection;
const CONTENT_TYPES = require('../../include/commons').CONTENT_TYPE;
const CONTENT_TYPES = require('../../include/commons').CONTENT_TYPES;
const REDIS_KEYS = require('../../include/commons').REDIS_KEYS;
const PLATFORMS = require('../../include/commons').PLATFORM;
@ -34,7 +34,7 @@ class AppClient extends RedisModel {
        let userStatusKey = RedisModel.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) {
                redisConn.hsetAsync(userStatusKey, 'app_in_bg', appInBg ? 1 : 0).then(function (res) {
                    if (handler) {
                        handler(null, true);
                    } else {
@ -58,7 +58,7 @@ class AppClient extends RedisModel {
     * @param handler
     */
    static getAppStatus(userId, handler) {
        let userStatusKey = RedisModel.makeRedisKey(REDIS_KEYS.UserStatus, userId);
        let userStatusKey = RedisModel.makeRedisKey(REDIS_KEYS.UserAppStatus, userId);
        redisConn.hgetallAsync(userStatusKey)
            .then(function (res) {
                if (res != null) {
@ -73,7 +73,7 @@ class AppClient extends RedisModel {
                                platform: res[0].platform,
                                token: res[0].token,
                                client_id: res[0].client_id,
                                app_in_bg: res[0].app_in_bg,
                                app_in_bg: res[0].app_in_bg === 1,
                                last_login_time: res[0].last_login_time
                            }
                        }
@ -93,57 +93,40 @@ class AppClient extends RedisModel {
     * @param message
     * @param sessionType
     */
    static sendNotification(message, sessionType) {
        AppClient.getAppStatus(message.to, function (err, userStatus) {
    static sendNotification(targetId, message, sessionType) {
        AppClient.getAppStatus(targetId, function (err, userStatus) {
            if (err) {
                ModelUtil.logError("Get user app status failed", err);
                return;
            }
            let tipMessage = CONTENT_TYPES.typeToDescription(message.content_type, "您有一条新消息") || message.content;
            let tipMessage = CONTENT_TYPES.typeToDescription(parseInt(message.content_type), "您有一条新消息") || message.content;
            let customData = {
                session_id: '' || message.session_id,
                session_type: sessionType,
                topic_id: '' || message.topic_id,
                from: '' || message.from,
                from: '' || message.sender_id,
                data: message.content
            };
            AppClient.getAppStatus(userId, function (err, userStatus) {
                if (userStatus.platform === PLATFORMS.iOS) {
                    pusher.pushToSingleViaAPN(tipMessage, customData, message.contentType, userStatus.token, handler);
                } else if (userStatus.platform === PLATFORMS.Android) {
                    let title = '新消息';
                    pusher.pushToSingleViaAndroid(title, tipMessage, customData, userStatus.client_id, userStatus.app_in_bg, handler);                }
            });
            if (userStatus.platform == PLATFORMS.iOS) {
                pusher.pushToSingleViaAPN(tipMessage, customData, message.contentType, userStatus.token, function (err, res) {
                    if (err) {
                        ModelUtil.logError("Send notification via APN failed", err);
                    }
                });
            } else if (userStatus.platform == PLATFORMS.Android) {
                let title = '新消息';
                pusher.pushToSingleViaAndroid(title, tipMessage, customData, userStatus.client_id, userStatus.app_in_bg, function (err, res) {
                    if (err) {
                        ModelUtil.logError("Send notification via Android failed", err);
                    } else {
                        log.info("Send notification via Android succeed: ", JSON.stringify(res));
                    }
                });
            }
        });
    }
    /**
     * 将消息的返回结果合并成JSON。
     *
     * @param rows
     */
    static fillMessages(rows) {
        let messages = {startId: rows.length > 0 ? rows[0].msg_id : '', count: rows.length, records: []};
        for (let i = 0; i < rows.length; i++) {
            let row = rows[i];
            let record = {
                id: row.msg_id,
                from: row.from_uid,
                contentType: row.type,
                content: row.content,
                timestamp: ObjectUtil.timestampToLong(row.timestamp)
            };
            if (row.to_uid !== undefined) record.to = row.to_uid;
            if (row.at_uid !== undefined) record.at = row.at_uid;
            messages.records.push(record);
        }
        return messages;
    }
}
// Expose class

+ 2 - 2
src/server/models/client/wechat.client.js

@ -18,7 +18,7 @@ let config = require('../../resources/config/' + configFile);
let log = require("../../util/log.js");
let https = require('https');
const CONTENT_TYPES = require('../../include/commons').CONTENT_TYPE;
const CONTENT_TYPES = require('../../include/commons').CONTENT_TYPES;
const REDIS_KEYS = require('../../include/commons').REDIS_KEYS;
class WechatClient extends RedisModel {
@ -51,7 +51,7 @@ class WechatClient extends RedisModel {
     *
     * @param message 消息
     */
    sendMessage(message) {
    static sendMessage(message) {
        let patientClient = clientCache.findById(message.to);
        if (patientClient) {
            this.sendViaWebSocket(patientClient.socket, message);

+ 29 - 21
src/server/models/messages/messages.js

@ -4,14 +4,16 @@
"use strict";
let MessageRepo = require('../../repository/mysql/message.repo');
let SessionRepo = require('../../repository/mysql/session.repo');
let RedisModel = require('./../redis.model.js');
let RedisClient = require('../../repository/redis/redis.client.js');
var ObjectUtil = require("../../util/object.util.js");
let redis = RedisClient.redisClient().connection;
let log = require('../../util/log.js');
let configFile = require('../../include/commons').CONFIG_FILE;
let config = require('../../resources/config/' + configFile);
var ObjectUtil = require("../../util/object.util.js");
let logger = require('../../util/log');
const REDIS_KEYS = require('../../include/commons').REDIS_KEYS;
@ -44,8 +46,8 @@ class Messages extends RedisModel {
     * @param pagesize
     * @param handler
     */
    getMessageFromMySQL(sessionId, page, pagesize,messageType, handler) {
        MessageRepo.findBySessionId(sessionId, page, pagesize,messageType, handler);
    getMessageFromMySQL(sessionId, page, pagesize, messageType, handler) {
        MessageRepo.findBySessionId(sessionId, page, pagesize, messageType, handler);
    }
    /**
@ -55,13 +57,13 @@ class Messages extends RedisModel {
     * @param pagesize
     * @param handler
     */
    getMessageByType(sessionId, page, pagesize,messageType) {
        MessageRepo.findBySessionId(sessionId, page, pagesize,messageType,function(err,res){
                if(err){
                    ModelUtil.emitError(self.eventEmitter, {message: "Error get message by session and type : " + err});
                }else{
                    ModelUtil.emitOK(self.eventEmitter, {data:res});
                }
    getMessageByType(sessionId, page, pagesize, messageType) {
        MessageRepo.findBySessionId(sessionId, page, pagesize, messageType, function (err, res) {
            if (err) {
                ModelUtil.emitError(self.eventEmitter, {message: "Error get message by session and type : " + err});
            } else {
                ModelUtil.emitOK(self.eventEmitter, {data: res});
            }
        });
    }
@ -113,17 +115,13 @@ class Messages extends RedisModel {
     * @param sessionType
     * @param messageId
     * @param sessionId
     * @param handler
     * @type type 会话类型,1表示MUC会话,2表示P2P,3表示群会话,4表示临时讨论组
     */
    saveMessageToMysql(sessionId, sessionType, messageId, message, handler) {
        MessageRepo.save(message, sessionType, messageId, sessionId, handler);
    }
    updateLastContentToMysql(sessionKey, sessionType, name, message){
    }
    /**
     * 更新会话最后一条消息
     *
@ -131,9 +129,10 @@ class Messages extends RedisModel {
     * @param sessionType
     * @param name 议题名称
     * @param message
     * @param businessType
     * @returns {*}
     */
    static updateLastContent(sessionKey, sessionType, name, message,businessType) {
    static updateLastContent(sessionKey, sessionType, name, message, businessType) {
        redis.hmsetAsync(sessionKey,
            "create_date", message.timestamp.getTime(),
            "last_content", message.content,
@ -141,11 +140,20 @@ class Messages extends RedisModel {
            "sender_id", message.sender_id,
            "sender_name", message.sender_name
        );
        let sessionid =sessionKey.replace("sessions:","");
        MessageRepo.updateLastContent(message.sender_id,message.sender_name,message.timestamp,message.content,message.content_type,sessionid);
        if(name != null) redis.hsetAsync(sessionKey, "name", name);
        if(sessionType != null) redis.hsetAsync(sessionKey, "type", sessionType);
        if(businessType != null) redis.hsetAsync(sessionKey, "business_type", businessType);
        let sessionid = sessionKey.replace("sessions:", "");
        SessionRepo.updateSessionLastStatus(message.sender_id,
            message.sender_name,
            message.timestamp,
            message.content,
            message.content_type,
            sessionid, function (err, res) {
                if(err) logger.error("Update session last status failed: ", err);
            });
        if (name != null) redis.hsetAsync(sessionKey, "name", name);
        if (sessionType != null) redis.hsetAsync(sessionKey, "type", sessionType);
        if (businessType != null) redis.hsetAsync(sessionKey, "business_type", businessType);
    }
    /**

+ 6 - 6
src/server/models/pusher.js

@ -5,7 +5,7 @@
 */
"use strict";
let RedisModel = require('./redis.model');
let RedisModel = require('../redis.model');
let GeTui = require('getui/GT.push');
let Target = require('getui/getui/Target');
@ -19,16 +19,16 @@ let NotificationTemplate = require('getui/getui/template/NotificationTemplate');
let TransmissionTemplate = require('getui/getui/template/TransmissionTemplate');
let SingleMessage = require('getui/getui/message/SingleMessage');
let AppMessage = require('getui/getui/message/AppMessage');
let log = require("../util/log.js");
let configFile = require('../include/commons').CONFIG_FILE;
let config = require('../resources/config/' + configFile);
let log = require("../../util/log.js");
let configFile = require('../../include/commons').CONFIG_FILE;
let config = require('../../resources/config/' + configFile);
class Pusher extends RedisModel {
    constructor() {
        super();
        this.getuiConfig = config.geTuiAppStoreCfg;
        this.getuiConfig = config.getTuiConfig;
        this.gt = new GeTui(this.getuiConfig.HOST, this.getuiConfig.APPKEY, this.getuiConfig.MASTERSECRET);
    }
@ -82,7 +82,7 @@ class Pusher extends RedisModel {
     * @param handler
     */
    pushToSingleViaAndroid(title, message, customData, clientid, appInBg, handler) {
        if (appInBg) {
        if (appInBg == 1) {
            this._pushAndroidNotify(clientid, title, message, customData, handler);
        } else {
            this._pushAndroidTransmission(clientid, customData, handler);

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

@ -22,7 +22,6 @@ class Participants extends RedisModel {
     * 获取会话的成员列表,直接从MySQL获取。
     *
     * @param sessionId
     * @param handler
     */
    getParticipants(sessionId) {
        let self = this;

+ 23 - 8
src/server/models/sessions/sessions.js

@ -514,8 +514,20 @@ class Sessions extends RedisModel {
                        }
                    });
                }).then(function (res) {
                    // TODO: 消息推送
                    pusher.pushTo
                    // 推送消息
                    ParticipantRepo.findIds(sessionId, function (err, res) {
                        if (err) {
                            ModelUtil.logError("Push message: get participant's id list failed: ", err);
                        } else {
                            message.session_id = sessionId;
                            res.forEach(function (participant) {
                                if (participant.id !== message.sender_id) {
                                    Sessions.pushNotification(participant.id, message);
                                }
                            });
                        }
                    })
                }).catch(function (err) {
                    ModelUtil.emitError(self.eventEmitter, {message: "Error occurred while save message to session: " + err});
                })
@ -638,11 +650,14 @@ class Sessions extends RedisModel {
        let participantsKey = RedisModel.makeRedisKey(REDIS_KEYS.SessionParticipants, sessionId);
        redis.zaddAsync(participantsKey, score, userId)
            .then(function (res) {
                logger.info("update participant last fetch time success.");
                ParticipantRepo.updateLastTime(new Date(score), sessionId, userId);
                ParticipantRepo.updateLastFetchTime(new Date(score), sessionId, userId, function (err, res) {
                    if (err) {
                        logger.error("Update participant last fetch time failed: ", err);
                    }
                });
            })
            .catch(function (err) {
                logger.error("Update participant last fetch time error: ", err);
                logger.error("Update participant last fetch time failed: ", err);
            });
    }
@ -653,12 +668,12 @@ class Sessions extends RedisModel {
     * @param message
     */
    static pushNotification(targetUserId, message) {
        Users.isPatientId(targetUserId, function (isPatient) {
        Users.isPatientId(targetUserId, function (err, isPatient) {
            if (isPatient) {
                WechatClient.sendMessage(message);
                WechatClient.sendMessage(targetUserId, message);
            }
            else {
                AppClient.sendMessage(message);
                AppClient.sendNotification(targetUserId, message);
            }
        });
    }

+ 1 - 752
src/server/models/user/doctor.js

@ -3,20 +3,7 @@
 */
"use strict";
let log = require("../../util/log.js");
//let getui = require('getui');
let RedisModel = require('./../redis.model');
let Schedule = require("./../schedule/schedule.js");
let DoctorRepo = require('../../repository/mysql/doctor.repo.js');
let PrivateMsgRepo = require('../../repository/mysql/private.msg.repo');
let SystemMsgRepo = require("../../repository/mysql/system.msg.repo.js");
let ObjectUtil = require("../../util/object.util.js");
let ModelUtil = require('../../util/model.util');
const CONTENT_TYPES = require('../../include/commons').CONTENT_TYPE;
const PLATFORMS = require('../../include/commons').PLATFORM;
const MAX_INT = require('../../include/commons').MAX_INT;
class Doctor extends RedisModel {
    constructor(doctorId) {
@ -25,747 +12,9 @@ class Doctor extends RedisModel {
        this._id = doctorId;
    }
    get id(){
    get id() {
        return this._id;
    }
    /**
     * 向医生发送消息。
     *
     * @param message
     */
    sendMessage(message) {
        let self = this;
        let tempContent = message.contentType === CONTENT_TYPES.Article ? JSON.stringify(message.content) : message.content;
        PrivateMsgRepo.save(message.to, message.from, message.contentType, tempContent, function (err, result) {
            if (err) {
                ModelUtil.emitError(self.eventEmitter, 'Save private message failed', err);
                return;
            }
            // 返回新插入的消息数据,并推送
            PrivateMsgRepo.findOneMessage(result.insertId, function (err, msg) {
                if (err) {
                    ModelUtil.emitError(self.eventEmitter, 'Save private message success, but return last message failed', err);
                    return;
                }
                // 先结束网络连接,再推送给客户端
                ModelUtil.emitOK(self.eventEmitter, Doctor.fillMessages(msg));
                Doctor.pushMessage(message, 'p2p_msg');
            });
            // 更新自身的聊天统计信息
            StatsRepo.updatePrivateChatSummary(message.from, message.to, message.from, message.contentType, message.content, function (err, result) {
                if (err) log.error(err);
            });
            // 更新对端的聊天统计信息
            StatsRepo.updatePrivateChatSummary(message.to, message.from, message.from, message.contentType, message.content, function (err, result) {
                if (err) log.error(err);
            });
        });
    }
    /**
     * 向医生发送系统消息。
     *
     * @param message
     */
    sendSystemMessage(message) {
        let self = this;
        SystemMsgRepo.save(message.to,
            message.contentType,
            message.title,
            message.summary,
            message.content,
            function (err, result) {
                if (err) {
                    ModelUtil.emitError(self.eventEmitter, "Save system message failed", err);
                    return;
                }
                // 先结束网络连接,再推送给客户端
                ModelUtil.emitOK(self.eventEmitter, {});
                Doctor.pushMessage(message, 'system_msg');
            });
    }
    /**
     * 推送消息。
     *
     * @param message
     * @param channel
     */
    static pushMessage(message, channel){
        DoctorRepo.getUserStatus(message.to, function (err, result) {
            if (err) {
                log.error('Lookup notify message receiver failed: ' + message.to);
                return;
            }
            if (result.length == 0) {
                log.warn('Notify message receiver is not found: ', message.to);
                return;
            }
            let userStatus = result[0];
            let isOnline = result.length > 0 && userStatus.is_online === 1;
            let delay = null;
            // 构建通知消息
            let notifyMessage = {type: channel, data: message.content};
            if (message.from) notifyMessage.from_uid = message.from;
            if (message.gid) notifyMessage.gid = message.gid;
            if (message.delay && message.delay !== "null") delay = new Date(Date.parse(message.delay));
            let title = '新消息';
            let content = message.content;
            if (message.contentType === CONTENT_TYPES.Image) {
                content = '[图片]';
            } else if (message.contentType === CONTENT_TYPES.Audio) {
                content = '[语音]';
            } else if (message.contentType > 3) {
                content = '您有一条新消息';
            }
            // 保存通知消息到数据库中,并根据用户在线状态推送此消息
            NotifyMsgRepo.save(message.to, message.contentType, title, content, JSON.stringify(notifyMessage), isOnline, delay, function (err, result) {
                if (err) {
                    log.error('Save notify message failed, ', err);
                    return;
                }
                if (delay) {
                    Schedule.dateSchedule(delay, function (message, client_id, status, token, title, content, notifyMessage, platform) {
                        Doctor.pushToClient(message.to, client_id, status, token, message.contentType,
                            title, content, notifyMessage, platform, function (err, result) {
                                if (err != null) {
                                    log.error(err);
                                } else {
                                    log.info(result);
                                }
                            });
                    }.bind(null, message, userStatus.client_id, userStatus.status, userStatus.token, title, content, notifyMessage, userStatus.platform));
                } else if (isOnline) {
                    Doctor.pushToClient(message.to, userStatus.client_id, userStatus.status, userStatus.token, message.contentType,
                        title, content, notifyMessage, userStatus.platform, function (err, result) {
                            if (err != null) {
                                log.error(err);
                            } else {
                                log.info(result);
                            }
                        });
                }
            });
        });
    }
    /**
     * 推送消息给医生客户端。
     *
     * @param userId            用户ID
     * @param clientId          客户端设备ID
     * @param appStatus         客户端App状态
     * @param token
     * @param contentType
     * @param title
     * @param content
     * @param notifyMessage
     * @param platform
     * @param handler
     */
    static pushToClient(userId, clientId, appStatus, token, contentType, title, content, notifyMessage, platform, handler) {
        if (platform === PLATFORMS.iOS) {
            getui.pushAPN(userId, token, contentType, title, content, notifyMessage, handler);
        } else if (platform === PLATFORMS.Android) {
            getui.pushAndroid(clientId, contentType, title, content, notifyMessage, appStatus, handler);
        }
    }
    /**
     * 获取最近聊天的用户,组。
     */
    getRecentChatList(userId, days) {
        let self = this;
        StatsRepo.getRecentChats(userId, days, function (err, rows) {
            if (err) {
                ModelUtil.emitError(self.eventEmitter, 'Get recent chat objects failed', err);
                return;
            }
            let data = {patients: [], doctors: [], groups: []};
            if (rows.length > 0) {
                for (let i = 0; i < rows.length; ++i) {
                    let row = rows[i];
                    if (row.type.indexOf('patient') > -1) {
                        data.patients.push({
                            code: row.code,
                            name: row.name,
                            birthday: row.birthday === null ? "" : row.birthday,
                            sex: row.sex,
                            avatar: row.photo === null ? "" : row.photo
                        });
                    } else if (row.type.indexOf('doctor') > -1) {
                        data.doctors.push({
                            code: row.code,
                            name: row.name,
                            birthday: row.birthday === null ? "" : row.birthday,
                            sex: row.sex,
                            avatar: row.photo === null ? "" : row.photo
                        });
                    } else if (row.type.indexOf('group') > -1) {
                        data.groups.push({
                            code: row.code,
                            name: row.name
                        });
                    }
                }
            }
            ModelUtil.emitOK(self.eventEmitter, data);
        });
    }
    /**
     * 获取参与的聊天列表,包括:点对点,参与的讨论组,系统消息等。
     *
     * @param userId
     */
    getChatList(userId) {
        let self = this;
        // 与患者的私信
        PrivateMsgRepo.findAllP2PWithPatient(userId, function (err, patients) {
            if (err) {
                ModelUtil.emitError(self.eventEmitter, 'Get chat list with patient failed', err);
                return;
            }
            let chats = {patients: [], doctors: [], groups: []};
            for (let i = 0; i < patients.length; i++) {
                let patient = patients[i];
                chats.patients.push({
                    code: patient.code,
                    name: patient.name,
                    birthday: patient.birthday,
                    sex: patient.sex,
                    avatar: patient.photo == null ? "" : patient.photo,
                    newMessageCount: patient.new_msg_count,
                    lastContentType: patient.last_content_type,
                    lastContent: patient.last_content,
                    timestamp: ObjectUtil.timestampToLong(patient.timestamp)
                });
            }
            // 含有患者的群
            GroupMsgRepo.findAllGroupsWithPatient(userId, function (err, groups) {
                if (err) {
                    ModelUtil.emitError(self.eventEmitter, 'Get group list with patient failed', err);
                    return;
                }
                for (let i = 0; i < groups.length; i++) {
                    let group = groups[i];
                    // 过滤掉医生间的求助团队
                    if (group.group_type === 2) continue;
                    chats.groups.push({
                        code: group.code,
                        name: group.name,
                        groupType: group.msg_type,
                        newMessageCount: group.new_msg_count,
                        lastContentType: group.last_content_type,
                        lastContent: group.last_content,
                        timestamp: ObjectUtil.timestampToLong(group.timestamp)
                    });
                }
                // 医生间的私聊
                PrivateMsgRepo.findAllP2PWithDoctor(userId, function (err, doctors) {
                    if (err) {
                        ModelUtil.emitError(self.eventEmitter, 'Get chat list with doctor failed', err);
                        return;
                    }
                    for (let i = 0; i < doctors.length; i++) {
                        let doctor = doctors[i];
                        chats.doctors.push({
                            code: doctor.code,
                            name: doctor.name,
                            sex: doctor.sex,
                            avatar: doctor.photo === null ? "" : doctor.photo,
                            newMessageCount: doctor.new_msg_count,
                            lastContentType: doctor.last_content_type,
                            lastContent: doctor.last_content,
                            timestamp: ObjectUtil.timestampToLong(doctor.timestamp)
                        });
                    }
                    // 获取医生间的组
                    GroupMsgRepo.findAllGroupsWithDoctor(userId, function (err, groups) {
                        if (err) {
                            ModelUtil.emitError(self.eventEmitter, 'Get group list with doctor failed', err);
                            return;
                        }
                        for (let i = 0; i < groups.length; i++) {
                            let group = groups[i];
                            chats.groups.push({
                                code: group.code,
                                name: group.name,
                                groupType: group.group_type, // 行政团队 or 求助
                                newMessageCount: group.new_msg_count,
                                lastContentType: group.last_content_type,
                                lastContent: group.last_content,
                                timestamp: ObjectUtil.timestampToLong(group.timestamp)
                            });
                        }
                        ModelUtil.emitOK(self.eventEmitter, chats);
                    });
                });
            })
        });
    }
    /**
     * 获取与患者的聊天列表。
     */
    getChatsListWithPatient(userId) {
        let self = this;
        PrivateMsgRepo.findAllP2PWithPatient(userId, function (err, patients) {
            if (err) {
                ModelUtil.emitError(self.eventEmitter, 'Get chat list with patient failed', err);
                return;
            }
            let chats = {patients: [], groups: []};
            for (let i = 0; i < patients.length; i++) {
                let patient = patients[i];
                chats.patients.push({
                    code: patient.code,
                    name: patient.name,
                    birthday: patient.birthday,
                    sex: patient.sex,
                    avatar: patient.photo == null ? "" : patient.photo,
                    newMessageCount: patient.new_msg_count,
                    lastContentType: patient.last_content_type,
                    lastContent: patient.last_content,
                    timestamp: ObjectUtil.timestampToLong(patient.timestamp)
                });
            }
            GroupMsgRepo.findAllGroupsWithPatient(userId, function (err, groups) {
                if (err) {
                    ModelUtil.emitError(self.eventEmitter, 'Get group list with patient failed', err);
                    return;
                }
                for (let i = 0; i < groups.length; i++) {
                    let group = groups[i];
                    // 过滤掉医生间的求助团队
                    if (group.group_type === 2) continue;
                    chats.groups.push({
                        code: group.code,
                        name: group.name,
                        groupType: group.msg_type,
                        newMessageCount: group.new_msg_count,
                        lastContentType: group.last_content_type,
                        lastContent: group.last_content,
                        timestamp: ObjectUtil.timestampToLong(group.timestamp)
                    });
                }
                ModelUtil.emitOK(self.eventEmitter, chats);
            })
        });
    }
    /**
     * 获取与医生的聊天列表,包括:点对点,参与的讨论组。
     *
     * @param userId
     */
    getChatListWithDoctor(userId) {
        let self = this;
        // 先获取医生间的私聊
        PrivateMsgRepo.findAllP2PWithDoctor(userId, function (err, doctors) {
            if (err) {
                ModelUtil.emitError(self.eventEmitter, 'Get chat list with doctor failed', err);
                return;
            }
            let chats = {doctors: [], groups: []};
            for (let i = 0; i < doctors.length; i++) {
                let doctor = doctors[i];
                chats.doctors.push({
                    code: doctor.code,
                    name: doctor.name,
                    sex: doctor.sex,
                    avatar: doctor.photo === null ? "" : doctor.photo,
                    newMessageCount: doctor.new_msg_count,
                    lastContentType: doctor.last_content_type,
                    lastContent: doctor.last_content,
                    timestamp: ObjectUtil.timestampToLong(doctor.timestamp)
                });
            }
            // 再获取医生间的组
            GroupMsgRepo.findAllGroupsWithDoctor(userId, function (err, groups) {
                if (err) {
                    ModelUtil.emitError(self.eventEmitter, 'Get group list with doctor failed', err);
                    return;
                }
                for (let i = 0; i < groups.length; i++) {
                    let group = groups[i];
                    chats.groups.push({
                        code: group.code,
                        name: group.name,
                        groupType: group.group_type, // 行政团队 or 求助
                        newMessageCount: group.new_msg_count,
                        lastContentType: group.last_content_type,
                        lastContent: group.last_content,
                        timestamp: ObjectUtil.timestampToLong(group.timestamp)
                    });
                }
                ModelUtil.emitOK(self.eventEmitter, chats);
            });
        });
    }
    /**
     * 获取与医生,患者的聊天列表,包括:点对点,参与的讨论组。消息数量
     *
     * @param userId
     */
    getChatListMsgAmount(userId) {
        let self = this;
        let chats = {doctor: {}, patient: {}};
        // 先获取医生间的私聊
        PrivateMsgRepo.findAllP2PWithDoctor(userId, function (err, doctors) {
            if (err) {
                ModelUtil.emitError(self.eventEmitter, 'Get chat list with doctor failed', err);
                return;
            }
            var amount = 0;
            for (let i = 0; i < doctors.length; i++) {
                let doctor = doctors[i];
                //过滤结束的咨询
                //if(doctor.last_content_type==7)continue;
                amount = doctor.new_msg_count+amount;
            }
            // 再获取医生间的组
            GroupMsgRepo.findAllGroupsWithDoctor(userId, function (err, groups) {
                if (err) {
                    ModelUtil.emitError(self.eventEmitter, 'Get group list with doctor failed', err);
                    return;
                }
                for (let i = 0; i < groups.length; i++) {
                    let group = groups[i];
                    //过滤结束的咨询
                    //if(group.last_content_type==7)continue;
                    amount =   group.new_msg_count+amount;
                }
                chats.doctor = amount;
                var patientAmount =0;
                //获取患者记录数量
                PrivateMsgRepo.findAllP2PWithPatient(userId, function (err, patients) {
                    if (err) {
                        ModelUtil.emitError(self.eventEmitter, 'Get chat list with patient failed', err);
                        return;
                    }
                    for (let i = 0; i < patients.length; i++) {
                        let patient = patients[i];
                        //过滤结束的咨询
                        // if(patient.last_content_type==7)continue;
                        patientAmount =patientAmount+ patient.new_msg_count;
                    }
                    //获取患者记录数量
                    GroupMsgRepo.findAllGroupsWithPatient(userId, function (err, groups) {
                        if (err) {
                            ModelUtil.emitError(self.eventEmitter, 'Get group list with patient failed', err);
                            return;
                        }
                        for (let i = 0; i < groups.length; i++) {
                            let group = groups[i];
                            // 过滤掉医生间的求助团队
                            if (group.group_type === 2) continue;
                            //过滤结束的咨询
                            //if(group.last_content_type==7)continue;
                            patientAmount = patientAmount+ group.new_msg_count;
                        }
                        chats.patient = patientAmount;
                        ModelUtil.emitOK(self.eventEmitter, chats);
                    });
                });
            });
        });
    }
    /**
     * 获取与指定用户的聊天记录。
     *
     * @param userId
     * @param peerId
     * @param contentType
     * @param msgStartId
     * @param msgEndId
     * @param count
     * @param closedInterval
     */
    getPrivateMessages(userId, peerId, contentType, msgStartId, msgEndId, count, closedInterval) {
        let self = this;
        PrivateMsgRepo.findAllMessages(userId, peerId, contentType === undefined ? "0,1,2,3,4,5,6" : contentType, msgStartId, msgEndId, count, closedInterval, function (err, rows) {
            if (err) {
                ModelUtil.emitError(self.eventEmitter, 'Get private message failed', err);
                return;
            }
            let messages = Doctor.fillMessages(rows);
            ModelUtil.emitOK(self.eventEmitter, messages);
            // 清空统计信息
            StatsRepo.clearPrivateChatSummary(userId, peerId, function (err, result) {
                if (err) log.error(err);
            });
        });
    }
    /**
     * 获取与某人聊天的未读消息数。
     *
     * @param userId
     * @param peerId
     */
    getUnreadMessageCount(userId, peerId) {
        let self = this;
        StatsRepo.getPrivateChatAllUnReadCount(userId, function (err, result) {
            if (err) {
                ModelUtil.emitError(self.eventEmitter, "Get unread private message count failed", err);
                return;
            }
            let data = {userId: userId, messageType: 1, newMessageCount: 0};
            for (let i = 0; i < result.length; i++) {
                data.newMessageCount += result[i].new_msg_count;
            }
            ModelUtil.emitOK(self.eventEmitter, data);
        });
    }
    /**
     * 获取所有未读的消息数,包括群。
     *
     * @param userId
     */
    getAllUnreadMessageCount(userId) {
        let self = this;
        StatsRepo.getChatAllUnReadCount(userId, function (err, result) {
            if (err) {
                ModelUtil.emitError(self.eventEmitter, "Get all unread message count failed", err);
                return;
            }
            let data = {userId: userId, messageType: 0, newMessageCount: 0};
            for (let index = 0; index < result.length; index++) {
                data.newMessageCount += result[index].new_msg_count;
            }
            ModelUtil.emitOK(self.eventEmitter, data);
        });
    }
    /**
     * 获取与指定用户的未读聊天记录。
     *
     * @param userId
     * @param peerId
     */
    getUnreadPrivateMessages(userId, peerId) {
        let self = this;
        StatsRepo.getPrivateChatSummary(userId, peerId, function (err, summary) {
            if (err) {
                ModelUtil.emitError(self.eventEmitter, 'Get unread private messages failed', err);
                return;
            }
            // 没有未读消息,直接返回
            if (summary.length == 0 || summary[0].new_msg_count === 0) {
                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.emitError(self.eventEmitter, "Get unread private messages failed", err);
                    return;
                }
                let messages = Doctor.fillMessages(rows);
                ModelUtil.emitOK(self.eventEmitter, messages);
            });
        });
    }
    /**
     * 获取聊天统计摘要。
     *
     * @param userId
     * @param peerId
     */
    getChatSummary(userId, peerId) {
        let self = this;
        StatsRepo.getPrivateChatSummary(userId, peerId, function (err, result) {
            if (err) {
                ModelUtil.emitError(self.eventEmitter, "Get private messages statistic failed", err);
                return;
            }
            let data = {
                userId: userId,
                peerId: peerId,
                lastCContentType: 1,
                lastContent: "",
                newMessageCount: 0,
                timestamp: 0
            };
            if (result.length > 0) {
                let row = result[0];
                data.userId = row.uid;
                data.peerId = row.from_uid;
                data.lastContentType = row.last_content_type;
                data.lastContent = row.last_content;
                data.newMessageCount = row.new_msg_count;
                data.timestamp = ObjectUtil.timestampToLong(row.timestamp)
            }
            ModelUtil.emitOK(self.eventEmitter, data);
        });
    }
    getMessage(messageId, messageType) {
        let self = this;
        if (messageType == 1) {
            // 私信
            PrivateMsgRepo.findOneMessage(messageId, function (err, result) {
                if (err) {
                    ModelUtil.emitError(self.eventEmitter, "Get message failed", err);
                    return;
                }
                if (result.length == 0) {
                    ModelUtil.emitDataNotFound(self.eventEmitter, "Message not found.");
                    return;
                }
                ModelUtil.emitOK(self.eventEmitter, {
                    id: result[0].msg_id,
                    from: result[0].from_uid,
                    to: result[0].to_uid,
                    contentType: result[0].type,
                    content: result[0].content,
                    timestamp: ObjectUtil.timestampToLong(result[0].timestamp)
                });
            })
        } else {
            // 群信
            GroupMsgRepo.findOneMessage(messageId, function (err, result) {
                if (err) {
                    ModelUtil.emitError(self.eventEmitter, "Get message failed", err);
                    return;
                }
                if (result.length == 0) {
                    ModelUtil.emitDataNotFound(self.eventEmitter, "Message not found.");
                    return;
                }
                ModelUtil.emitOK(self.eventEmitter, {
                    id: result[0].msg_id,
                    from: result[0].from_uid,
                    at: result[0].at_uid,
                    groupId: result[0].to_gid,
                    contentType: result[0].type,
                    content: result[0].content,
                    timestamp: ObjectUtil.timestampToLong(result[0].timestamp)
                });
            });
        }
    }
    /**
     * 判断与患者的最新咨询会话是否已经结束。
     */
    isConsultFinished(doctorId, patientId) {
        let self = this;
        PrivateMsgRepo.isCurrentSessionFinished(doctorId, patientId, function (err, result) {
            if (err) {
                ModelUtil.emitError(self.eventEmitter, "Get session finish status failed: ", err);
                return;
            }
            let data = {finished: true, consultId: ''};
            if (result.length > 0) {
                let finishRow = result[0];
                data.finished = finishRow.finished === 1;
                if (!data.finished) {
                    data.consultId = finishRow.consult_id;
                }
            }
            ModelUtil.emitOK(self.eventEmitter, data);
        })
    }
    /**
     * 将消息的返回结果合并成JSON。
     *
     * @param rows
     *
     * @returns {startId: 0, count: 0, records: []}
     */
    static fillMessages(rows) {
        let messages = {startId: rows.length > 0 ? rows[0].msg_id : '', count: rows.length, records: []};
        for (let i = 0; i < rows.length; i++) {
            let row = rows[i];
            let record = {
                id: row.msg_id,
                from: row.from_uid,
                contentType: row.type,
                content: row.content,
                timestamp: ObjectUtil.timestampToLong(row.timestamp)
            };
            if (row.to_uid !== undefined) record.to = row.to_uid;
            if (row.at_uid !== undefined) record.at = row.at_uid;
            messages.records.push(record);
        }
        return messages;
    }
}
// Expose class

+ 2 - 202
src/server/models/user/patient.js

@ -3,24 +3,10 @@
 */
"use strict";
let configFile = require('../../include/commons').CONFIG_FILE;
let config = require('../../resources/config/' + configFile);
let log = require("../../util/log.js");
let RedisModel = require('../redis.model');
let ObjectUtil = require("../../util/object.util.js");
let ModelUtil = require('../../util/model.util');
let WechatClient = require('../../models/client/wechat.client');
let Doctor = require('./doctor');
let DoctorRepo = require('../../repository/mysql/doctor.repo');
let PatientRepo = require('../../repository/mysql/patient.repo');
let PmRepo = require('../../repository/mysql/private.msg.repo');
let clientCache = require('../socket.io/client.cache').clientCache();
const CONTENT_TYPES = require('../../include/commons').CONTENT_TYPE;
let configFile = require('../../include/commons').CONFIG_FILE;
let config = require('../../resources/config/' + configFile);
class Patient extends RedisModel {
    constructor(patientId) {
@ -32,192 +18,6 @@ class Patient extends RedisModel {
    get id(){
        return this._id;
    }
    /**
     * 向患者发送消息。
     *
     * 注意:患者消息的保存发送与医生的实现不同。
     *
     * @param message 消息
     */
    sendMessage(message) {
        // 保存消息
        let self = this;
        let tempContent = message.contentType === CONTENT_TYPES.Article ? JSON.stringify(message.content) : message.content;
        PmRepo.save(message.to, message.from, message.contentType, tempContent, function (err, result) {
            if (err) {
                ModelUtil.emitError(self.eventEmitter, 'Save private message failed', err);
                return;
            }
            // 结束网络连接,后续操作继续执行
            PmRepo.findOnePatientMessage(result.insertId, function (err, msg) {
                if (err) {
                    ModelUtil.emitError(self.eventEmitter, 'Save private message success, but return last message failed', err);
                    return;
                }
                ModelUtil.emitOK(self.eventEmitter, Doctor.fillMessages(msg));
                // 通过Web Socket推送给患者
                let patientClient = clientCache.findById(message.to);
                if (!patientClient) {
                    log.warn("User is not online, user id: ", message.to);
                    //发送微信模板消息
                    self.sendConsultWechatReplyTempMsg(message);
                    return;
                }
                let row = msg[0];
                row.timestamp = ObjectUtil.timestampToLong(row.timestamp);
                patientClient.socketServer.sockets.emit('message', row);
            });
            // 更新自身的聊天统计信息
            StatsRepo.updatePrivateChatSummary(message.from, message.to, message.from, message.contentType, message.content, function (err, result) {
                if (err) log.error(err);
            });
            // 更新对端的聊天统计信息
            StatsRepo.updatePrivateChatSummary(message.to, message.from, message.from, message.contentType, message.content, function (err, result) {
                if (err) log.error(err);
            });
        });
    };
    /**
     * 推送群组消息给居民
     *
     * @param message
     */
    pushGroupMessage(message) {
        let self = this;
        // 通过Web Socket推送给患者
        let patientClient = clientCache.findById(message.to);
        if (!patientClient) {
            log.warn("User is not online, user id: ", message.to);
            //发送微信模板消息
            self.sendConsultWechatReplyTempMsg(message);
            return;
        }
        GroupRepo.getOnGroupMsg(message.msgId, function (err, result) {
            if (err) {
                ModelUtil.emitError(self.eventEmitter, "get group msg info failed", err);
            }
            var msg = result ? result[0] : "";
            if (msg) {
                patientClient.socketServer.sockets.emit('message', msg);
            }
        })
    };
    /**
     * 发送微信模板消息给居民
     *
     * @param message
     */
    sendConsultWechatReplyTempMsg(message) {
        let self = this;
        // 发送微信消息
        function sendWxMessage(openid, name, consult) {
            var replyContent = message.content;
            switch (Number.parseInt(message.contentType)) {
                case CONTENT_TYPES.Image:
                    replyContent = "[图片]";
                    break;
                case CONTENT_TYPES.Audio:
                    replyContent = "[语音]";
                    break;
                case 0:
                case CONTENT_TYPES.Article:
                case CONTENT_TYPES.GoTo:
                case CONTENT_TYPES.TopicBegin:
                case CONTENT_TYPES.TopicEnd:
                    return;
                default:
                    break;
            }
            // 模板消息数据
            var msg = {
                touser: openid,
                template_id: config.wechatConfig.template.consultTemplate,
                url: config.wechatConfig.baseUrl + "/wx/html/yszx/html/consulting-doctor.html?openid=" + openid +
                "&consult=" + consult.consult + "&toUser=" + message.to,
                data: {
                    first: {value: "您的健康咨询有新的回复", color: "#000000"}
                    , remark: {value: "", color: "#000000"}
                    , keyword1: {value: consult.symptoms, color: "#000000"}
                    , keyword2: {value: replyContent, color: "#000000"}
                    , keyword3: {value: name, color: "#000000"}
                }
            };
            // 发送模板消息
            WechatClient.sendWxTemplateMessage(msg);
        }
        // 查询居民openid
        PatientRepo.findPatientOpenId(message.to, function (err, result) {
            if (err) {
                ModelUtil.emitError(self.eventEmitter, "get patient openid failed", err);
                return;
            }
            var openid = result && result.length > 0 ? result[0].openid : "";
            if (openid) {
                // 查询医生信息
                DoctorRepo.findOne(message.from, function (err, result) {
                    if (err) {
                        ModelUtil.emitError(self.eventEmitter, "get doctor info failed", err);
                        return;
                    }
                    if (result && result.length > 0) {
                        var name = result[0].name;
                        if (message.group) {
                            GroupRepo.getGroupConsultInfo(message.group, function (err, result) {
                                if (err) {
                                    ModelUtil.emitError(self.eventEmitter, "get patient and doctor consult info failed", err);
                                    return;
                                }
                                var consult = result && result.length > 0 ? result[0] : "";
                                if (consult) {
                                    sendWxMessage(openid, name, consult);
                                }
                            });
                        } else {
                            // 查询医生与居民对应的咨询信息
                            PatientRepo.getPatientDoctorConsult(message.to, message.from, function (err, result) {
                                if (err) {
                                    ModelUtil.emitError(self.eventEmitter, "get patient and doctor consult info failed", err);
                                    return;
                                }
                                var consult = result && result.length > 0 ? result[0] : "";
                                if (consult) {
                                    sendWxMessage(openid, name, consult);
                                }
                            });
                        }
                    } else {
                        ModelUtil.emitError(self.eventEmitter, "can not find doctor info", err);
                    }
                });
            } else {
                ModelUtil.logError("patient does not bind wechat", err);
            }
        });
    };
}
module.exports = Patient;

+ 1 - 1
src/server/models/user/users.js

@ -111,7 +111,7 @@ class Users extends RedisModel {
                    if (loginFromApp) {
                        // 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', 0, 'client_id', clientId,
                            'token', token, 'last_login_time', lastLoginTime.getTime());
                    } else {
                        // cache wechat status

+ 6 - 15
src/server/repository/mysql/message.repo.js

@ -23,7 +23,7 @@ class MessageRepo {
     * @param size
     * @param handler
     */
    static findBySessionId(sessionId, page, size,messageType, handler) {
    static findBySessionId(sessionId, page, size, messageType, handler) {
        if (page < 0) {
            page = 0;
        }
@ -34,7 +34,7 @@ class MessageRepo {
                    handler(null, null);
                    return;
                }
                var params =[];
                var params = [];
                let type = res[0].type;
                let MessageTable = "";
                if (type == 1) {
@ -46,12 +46,12 @@ class MessageRepo {
                }
                let where = " w.session_id = ? ";
                params.push(sessionId);
                if(messageType){
                if (messageType) {
                    where += " and content_type=? ";
                    params.push(messageType);
                }
                let sql = "select id, session_id, sender_id, sender_name, content_type, content, timestamp from " +
                    MessageTable + " w where "+where+" order by w.id limit ?, ?";
                    MessageTable + " w where " + where + " order by w.id limit ?, ?";
                params.push(page);
                params.push(size);
                ImDb.execQuery({
@ -77,22 +77,13 @@ class MessageRepo {
        ImDb.execQuery({
            "sql": sql,
            "args": [messageId, sessionId, message.sender_id, message.sender_name, message.content_type, message.content, message.timestamp],
            "handler": handler||function(err,res){
            "handler": handler || function (err, res) {
                log.info(res);
            }
        });
    }
    static  updateLastContent(lastSenderId,lastSenderName,lastMessageTime,lastContent,lastContentType,sessionId,handler){
        let sql ="update "+DB_TABLES.Sessions+" set last_sender_id=?,last_sender_name=?,last_message_time=?,last_content=?,last_content_type=? where id = ?";
        ImDb.execQuery({
            "sql": sql,
            "args": [lastSenderId,lastSenderName,lastMessageTime,lastContent,lastContentType,sessionId],
            "handler": handler||function(err,res){
                log.info(res);
            }
        });
    }
}
module.exports = MessageRepo;

+ 31 - 8
src/server/repository/mysql/participant.repo.js

@ -31,6 +31,25 @@ class ParticipantRepo {
        });
    }
    /**
     * 获取会话的成员ID列表
     *
     * @param sessionId
     * @param handler
     */
    static findIds(sessionId, handler) {
        let sql = "select u.id, false is_patient from sessions s, participants p, doctors u " +
            "where s.id = ? and s.id = p.session_id and p.participant_id = u.id union " +
            "select u.id, true is_patient from sessions s, participants p, patients u " +
            "where s.id = ? and s.id = p.session_id and p.participant_id = u.id";
        ImDb.execQuery({
            "sql": sql,
            "args": [sessionId, sessionId],
            "handler": handler
        });
    }
    /**
     * 获取会话的成员头像列表
     *
@ -79,19 +98,23 @@ class ParticipantRepo {
        handler(null, sessionId);
    }
    static  updateLastTime(lastMessageTime,sessionId,participantId,handler){
        let sql ="update "+DB_TABLES.Participants+" set last_fetch_time=? where session_id = ? and participant_id =?";
    /**
     * 更新最后消息获取时间。
     *
     * @param lastMessageTime
     * @param sessionId
     * @param participantId
     * @param handler
     */
    static updateLastFetchTime(lastMessageTime, sessionId, participantId, handler) {
        let sql = "update " + DB_TABLES.Participants + " set last_fetch_time=? where session_id = ? and participant_id =?";
        ImDb.execQuery({
            "sql": sql,
            "args": [lastMessageTime,sessionId,participantId],
            "handler": handler||function(err,res){
                log.info(res);
            }
            "args": [lastMessageTime, sessionId, participantId],
            "handler": handler
        });
    }
    /**
     * 用户是否在指定Session中
     *

+ 25 - 6
src/server/repository/mysql/session.repo.js

@ -73,14 +73,35 @@ class SessionRepo {
     * @param name
     * @param type
     * @param createDate
     * @param businessType
     * @param handler
     */
    static saveSession(sessionId, name, type, createDate,businessType, handler) {
    static saveSession(sessionId, name, type, createDate, businessType, handler) {
        let sql = "insert into " + DB_TABLES.Sessions + " (id, name, type, create_date,business_type) VALUES (?,?,?,?,?) " +
            "ON DUPLICATE KEY UPDATE name = ?";
        ImDb.execQuery({
            "sql": sql,
            "args": [sessionId, name, type, createDate, name,businessType],
            "args": [sessionId, name, type, createDate, name, businessType],
            "handler": handler
        });
    }
    /**
     * 更新会话的最终状态。
     *
     * @param lastSenderId
     * @param lastSenderName
     * @param lastMessageTime
     * @param lastContent
     * @param lastContentType
     * @param sessionId
     * @param handler
     */
    static updateSessionLastStatus(lastSenderId, lastSenderName, lastMessageTime, lastContent, lastContentType, sessionId, handler) {
        let sql = "update " + DB_TABLES.Sessions + " set last_sender_id=?,last_sender_name=?,last_message_time=?,last_content=?,last_content_type=? where id = ?";
        ImDb.execQuery({
            "sql": sql,
            "args": [lastSenderId, lastSenderName, lastMessageTime, lastContent, lastContentType, sessionId],
            "handler": handler
        });
    }
@ -92,8 +113,7 @@ class SessionRepo {
     * @param user
     * @param score
     */
    static
    saveStickySession(sessionId, user, score) {
    static saveStickySession(sessionId, user, score) {
        let sql = "insert into " + DB_TABLES.StickySessions + " (user_id,session_id,score) VALUES (?,?,?) ";
        ImDb.execQuery({
            "sql": sql,
@ -112,8 +132,7 @@ class SessionRepo {
     * @param sessionId
     * @param userId
     */
    static
    unstickSession(sessionId, userId) {
    static unstickSession(sessionId, userId) {
        let sql = "delete from " + DB_TABLES.StickySessions + " where user_id=? and session_id=? ";
        ImDb.execQuery({
            "sql": sql,

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

@ -14,7 +14,7 @@ let imDbConfig = {
let redisConfig = {
    host: '192.168.1.220',
    port: 6379,
    db: 13
    db: 10
};
// 三师后台
@ -24,11 +24,19 @@ let wlyyServerConfig = {
};
// 个推AppStore版参数
let geTuiAppStoreCfg = {
/*let getTuiConfig = {
    HOST: 'https://api.getui.com/apiex.htm',
    APPID: 'H6FYbDejks6VjMmW3uH7V6',
    APPKEY: '0PFWlKmLBN9YzhCfFWVgYA',
    MASTERSECRET: 'pvjCGtRZJx9SRVODkxc816'
};*/
let getTuiConfig = {
    HOST: 'https://api.getui.com/apiex.htm',
    APPID: 'DKgbGvbacm74nJJzen5ilA',
    APPSECRET: '4kGcL7e7kU6mbSqfEGZFW7',
    APPKEY: 'ArZfS2qvoA7N3hawOAGVC5',
    MASTERSECRET: '9lpy5vEss46tVzP1RCJiC4'
};
// 微信配置
@ -61,7 +69,7 @@ exports.showSQL = true;
exports.imDbConfig = imDbConfig;
exports.redisConfig = redisConfig;
exports.geTuiAppStoreCfg = geTuiAppStoreCfg;
exports.getTuiConfig = getTuiConfig;
exports.wlyyServerConfig = wlyyServerConfig;
exports.wechatConfig = wechatConfig;
exports.sessionConfig = sessionConfig;

+ 2 - 2
src/server/resources/config/config.prod.js

@ -17,7 +17,7 @@ let redisConfig = {
};
// 个推AppStore版参数
let geTuiAppStoreCfg = {
let getTuiConfig = {
    HOST: 'https://api.getui.com/apiex.htm',
    APPID: 'H6FYbDejks6VjMmW3uH7V6',
    APPKEY: '0PFWlKmLBN9YzhCfFWVgYA',
@ -60,7 +60,7 @@ exports.showSQL = false;
exports.imDbConfig = imDbConfig;
exports.redisConfig = redisConfig;
exports.geTuiAppStoreCfg = geTuiAppStoreCfg;
exports.getTuiConfig = getTuiConfig;
exports.wlyyServerConfig = wlyyServerConfig;
exports.wechatConfig = wechatConfig;
exports.sessionConfig = sessionConfig;

+ 2 - 2
src/server/resources/config/config.test.js

@ -23,7 +23,7 @@ var wlyyServerConfig = {
};
// 个推AppStore版参数
var geTuiAppStoreCfg = {
var getTuiConfig = {
    HOST : 'https://api.getui.com/apiex.htm',
    APPID : 'H6FYbDejks6VjMmW3uH7V6',
    APPKEY : '0PFWlKmLBN9YzhCfFWVgYA',
@ -56,7 +56,7 @@ exports.showSQL= true;
exports.imDbConfig = imDbConfig;
exports.redisConfig = redisConfig;
exports.geTuiAppStoreCfg = geTuiAppStoreCfg;
exports.getTuiConfig = getTuiConfig;
exports.wlyyServerConfig = wlyyServerConfig;
exports.wechatConfig = wechatConfig;
exports.sessionConfig = sessionConfig;

+ 38 - 0
src/server/util/message.util.js

@ -0,0 +1,38 @@
/**
 * 消息工具。
 *
 * author: Sand
 * since: 1/9/2017
 */
"use strict";
let ObjectUtil = require("./object.util.js");
class MessageUtil {
     /**
     * 将消息的返回结果合并成JSON。
     *
     * @param dataRows
     */
    static fillMessages(dataRows) {
        let messages = {start_id: dataRows.length > 0 ? dataRows[0].msg_id : '', count: dataRows.length, records: []};
        for (let i = 0; i < dataRows.length; i++) {
            let row = dataRows[i];
            let record = {
                id: row.msg_id,
                from: row.from_uid,
                content_type: row.type,
                content: row.content,
                timestamp: ObjectUtil.timestampToLong(row.timestamp)
            };
            if (row.to !== undefined) record.to = row.to;
            if (row.at !== undefined) record.at = row.at;
            messages.records.push(record);
        }
        return messages;
    }
}

+ 4 - 4
test/client/im.client.session.p2p.Test.js

@ -21,15 +21,15 @@ let TD = {
            id: "cd92414c-5b06-11e6-8344-fa163e8aee56",
            name: "周美丽",
            token: "0PFWlKmLBN9YzhCfFWVgYA",
            clientId: "H6FYbDejks6VjMmW3uH7V6",
            platform: 0
            clientId: "c9e1c2cef42e609085ff15bac54004e3",
            platform: 1
        },
        DoctorB: {
            id: "cd919343-5b06-11e6-8344-fa163e8aee56",
            name: "李毅",
            token: "0PFWlKmLBN9YzhCfFWVgYA",
            clientId: "H6FYbDejks6VjMmW3uH7V6",
            platform: 0
            clientId: "8fc0fb1d53b725aa7406b8fae66c0a5b",
            platform: 1
        }
    }
};