| 
					
				 | 
			
			
				@ -27,6 +27,7 @@ const REDIS_KEYS = require('../../include/commons').REDIS_KEYS; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				const SESSION_TYPES = require('../../include/commons').SESSION_TYPES; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				const STICKY_SESSION_BASE_SCORE = require('../../include/commons').STICKY_SESSION_BASE_SCORE; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				const PARTICIPANT_ROLES = require('../../include/commons').PARTICIPANT_ROLES; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				const SESSION_STATUS = require('../../include/commons').SESSION_STATUS; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				class Sessions extends RedisModel { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				    constructor() { 
			 | 
		
	
	
		
			
				| 
					
				 | 
			
			
				@ -445,6 +446,137 @@ class Sessions extends RedisModel { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				        ]); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				    } 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				    /** 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				     * 根据用户ID获取用户已经结束咨询的session列表 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				     * @param userId 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				     * @param page 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				     * @param size 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				     * @param businessType 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				     */ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				    getUserStatusSessions(userId,status,businessType,page, size) { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				        let userSessionKey = RedisModel.makeRedisKey(REDIS_KEYS.UserSessions, userId); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				        let self = this; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				        async.waterfall([ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				            // 获取会话ID列表 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				            function (callback) { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				                SessionRepo.findAllByTypeAndStatus(userId,businessType,status,page,size,function(err,res){ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				                    if (res.length == 0) { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				                        ModelUtil.emitOK(self.eventEmitter, []); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				                        return; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				                    } 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				                    var sessionIds=[]; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				                    for(var j in res){ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				                        sessionIds.push(res[j].id); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				                    } 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				                    callback(null,sessionIds); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				                }) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				            }, 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				            // 遍历会话 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				            function (sessionIds) { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				                let sessionList = []; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				                let functionList = []; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				                for (let j = 0; j < sessionIds.length; j++) { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				                    let fun = function (index, callback) { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				                        if (!callback) { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				                            callback = index, index = 0 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				                        } 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				                        let sessionId = sessionIds[index]; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				                        let sessionKey = RedisModel.makeRedisKey(REDIS_KEYS.Session, sessionId); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				                        let participantsRoleKey = RedisModel.makeRedisKey(REDIS_KEYS.SessionParticipantsRole, sessionId); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				                        let sessionParticipantsKey = RedisModel.makeRedisKey(REDIS_KEYS.SessionParticipants, sessionId); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				                        redis.multi() 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				                            .hgetall(sessionKey)                       // 会话实体 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				                            .hget(participantsRoleKey, userId)         // 用户在此会话中的角色 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				                            .zscore(sessionParticipantsKey, userId)    // 用户在此会话中最后一次获取未读消息的时间 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				                            .zrange(sessionParticipantsKey, 0, -1) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				                            .zrange(sessionParticipantsKey, 0,-1,'withscores')  // 所有用户在此会话中最后一次获取未读消息的时间 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				                            .execAsync() 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				                            .then(function (res) { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				                                let session = res[0]; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				                                let role = res[1]; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				                                let lastFetchTime = res[2]; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				                                let users = res[3]; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				                                let participantsTimeArray = res[4]; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				                                let participantsTime = []; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				                                for(var j = 0 ;j<participantsTimeArray.length;j++){ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				                                    if(j%2!=0)continue; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				                                    let participantsTimeJson = {}; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				                                    participantsTimeJson[participantsTimeArray[j]] = participantsTimeArray[j+1]; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				                                    participantsTime.push(participantsTimeJson); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				                                } 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				                                let sessionName = ""; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				                                let otherUserId = ""; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				                                if (session.type == SESSION_TYPES.P2P) { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				                                    for (let j in users) { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				                                        if (users[j] != userId) { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				                                            otherUserId = users[j]; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				                                        } 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				                                    } 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				                                } 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				                                if (!role) role = 0; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				                                if (!lastFetchTime) lastFetchTime = new Date().getTime(); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				                                // 计算未读消息数 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				                                let messagesByTimestampKey = RedisModel.makeRedisKey(REDIS_KEYS.MessagesByTimestamp, sessionId); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				                                redis.zcountAsync(messagesByTimestampKey, lastFetchTime, new Date().getTime()) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				                                    .then(function (count) { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				                                        if (!otherUserId) otherUserId = userId; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				                                        ParticipantRepo.findNameById(otherUserId, function (err, res) { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				                                            if ((res && res.length == 0) || session.type != SESSION_TYPES.P2P) { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				                                                sessionName = session.name; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				                                            } else { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				                                                sessionName = res[0].name; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				                                            } 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				                                            var bir = new Date().getTime(); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				                                            if (res.length != 0 && res[0].birthdate) { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				                                                bir = res[0].birthdate.getTime(); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				                                            } 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				                                            var sex = 1; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				                                            if (res.length != 0 && res[0].sex) { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				                                                sex = res[0].sex; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				                                            } 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				                                            sessionList.push({ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				                                                id: sessionId, 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				                                                name: sessionName, 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				                                                create_date: session.create_date, 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				                                                last_content_type: session.last_content_type, 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				                                                last_content: session.last_content, 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				                                                sender_id: session.sender_id, 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				                                                type: session.type, 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				                                                sender_name: session.sender_name, 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				                                                unread_count: count, 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				                                                business_type: session.business_type, 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				                                                my_role: role, 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				                                                sender_sex: sex, 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				                                                sender_birthday: bir, 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				                                                participantsTimeArray:participantsTime, 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				                                                status:session.status 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				                                            }); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				                                            index = (parseInt(index) + 1); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				                                            if (index == sessionIds.length) { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				                                                ModelUtil.emitOK(self.eventEmitter, sessionList); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				                                            } else { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				                                                callback(null, index); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				                                            } 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				                                        }) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				                                    }) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				                            }) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				                            .catch(function (err) { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				                                logger.error("Get sessions failed: ", err); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				                            }); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				                    }; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				                    functionList.push(fun); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				                } 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				                async.waterfall(functionList); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				            } 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				        ]); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				    } 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				    /** 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				     * 获取会话消息。全部,不管已读/未读状态。 
			 | 
		
	
	
		
			
				| 
					
				 | 
			
			
				@ -868,13 +1000,12 @@ class Sessions extends RedisModel { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				                            ModelUtil.logError("Push message from session: get participant's id list failed: ", err); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				                        } else { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				                            message.session_id = sessionId; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				                            res.forEach(function (participant) { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				                                if (participant.id !== message.sender_id && 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				                                    participant.participant_role == PARTICIPANT_ROLES.HOST) { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				                                    Sessions.pushNotification(participant.id, participant.name, message); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				                                if (participant.id == message.sender_id){ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				                                    message.sender_img = participant.avatar; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				                                    callPush(res,message); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				                                } 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				                            }); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				                            }) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				                        } 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				                    }) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				                }).catch(function (err) { 
			 | 
		
	
	
		
			
				| 
					
				 | 
			
			
				@ -884,6 +1015,14 @@ class Sessions extends RedisModel { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				                ModelUtil.emitDataNotFound(self.eventEmitter, {message: "当前会话找不到此发送者"}); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				            } 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				        }); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				        function callPush(participants,message){ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				            participants.forEach(function (participant) { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				                if (participant.id !== message.sender_id && 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				                    participant.participant_role == PARTICIPANT_ROLES.HOST) { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				                    Sessions.pushNotification(participant.id, participant.name, message); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				                } 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				            }); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				        } 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				    } 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				    sendTopicMessages(topicId, message) { 
			 | 
		
	
	
		
			
				| 
					
				 | 
			
			
				@ -950,11 +1089,11 @@ class Sessions extends RedisModel { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				                        } else { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				                            message.session_id = sessionId; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				                            res.forEach(function (participant) { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				                                if (participant.id !== message.sender_id && 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				                                    participant.participant_role == PARTICIPANT_ROLES.HOST) { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				                                    Sessions.pushNotification(participant.id, participant.name, message); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				                                if (participant.id == message.sender_id){ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				                                    message.sender_img = participant.avatar; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				                                    callPush(res,message); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				                                } 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				                            }); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				                            }) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				                        } 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				                    }) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				                }).catch(function (err) { 
			 | 
		
	
	
		
			
				| 
					
				 | 
			
			
				@ -963,7 +1102,15 @@ class Sessions extends RedisModel { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				            } else { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				                if (handler){ handler("用户不在此会话当中!", messageId);return;} 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				            } 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				        }) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				        }); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				        function callPush(participants,message){ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				            participants.forEach(function (participant) { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				                if (participant.id !== message.sender_id && 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				                    participant.participant_role == PARTICIPANT_ROLES.HOST) { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				                    Sessions.pushNotification(participant.id, participant.name, message); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				                } 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				            }); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				        } 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				    } 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				    /** 
			 |