diff --git a/game-server/app/services/chatService.ts b/game-server/app/services/chatService.ts index 873e43658..c2d77a4a0 100644 --- a/game-server/app/services/chatService.ts +++ b/game-server/app/services/chatService.ts @@ -1,3 +1,4 @@ +import { PrivateChatRec } from './../db/ChatInfo'; import { BossInstanceType } from './../db/BossInstance'; import { isString } from 'underscore'; import { cloneDeep, isArray, pick } from 'lodash'; @@ -14,7 +15,6 @@ import { addRedisChannel, getRoleOnlineInfo, redisChannelServer } from './redisS import { crc32 } from 'crc'; import { HeroType } from '../db/Hero'; import { GuildType } from '../db/Guild'; -import { GuildTrainType } from '../db/GuildTrain'; import { ChatInfoModel } from '../db/ChatInfo'; /** @@ -94,6 +94,24 @@ async function createGroupMsgData(roleId: string, roleName: string, channel: str export async function createPrivateMsg(roleId: string, roleName: string, type: number, source: number, content: string, targetRoleId: string, targetMsgCode: string) { const msgData: PrivateMessageParam = await createPrivateMsgData(roleId, roleName, type, source, content, targetRoleId, targetMsgCode); const result: PrivateMessageType = await PrivateMessageModel.createMsg(msgData); + + const curTime = new Date(); + const { recentPrivateChats: senderRecentChats } = await ChatInfoModel.findInfo(roleId); + const senderRecIdx = senderRecentChats.findIndex(chat => { return chat.targetRoleId === targetRoleId }); + const newSenderRec: PrivateChatRec = { + targetRoleId, lastChatTime: curTime, lastReadTime: curTime + }; + senderRecIdx === -1 ? senderRecentChats.push(newSenderRec) : senderRecentChats[senderRecIdx] = newSenderRec; + await ChatInfoModel.updateInfo({ roleId, recentPrivateChats: senderRecentChats}); + + const { recentPrivateChats: receiverRecentChats } = await ChatInfoModel.findInfo(targetRoleId); + const receiverRecIdx = receiverRecentChats.findIndex(chat => { return chat.targetRoleId === roleId }); + const newReceiverRec: PrivateChatRec = { + targetRoleId: roleId, lastChatTime: curTime, lastReadTime: curTime + }; + receiverRecIdx === -1 ? receiverRecentChats.push(newReceiverRec) : receiverRecentChats[receiverRecIdx].lastChatTime = curTime; + await ChatInfoModel.updateInfo({ roleId: targetRoleId, recentPrivateChats: receiverRecentChats}); + return result; } @@ -284,20 +302,20 @@ export async function roleChatInfos(roleId: string, roleName: string) { export async function recentPrivateChatInfos(roleId: string, roleName: string) { const { recentPrivateChats } = await roleChatInfos(roleId, roleName); - const sortedChats = recentPrivateChats + recentPrivateChats .sort((a, b) => a.lastChatTime.getTime() - b.lastChatTime.getTime()) .splice(RECENT_PRIVATE_CHATS_CNT); - if (!sortedChats || !sortedChats.length) return null; + if (!recentPrivateChats || !recentPrivateChats.length) return null; - const unreadChats = sortedChats.filter(chat => { return chat.lastChatTime > chat.lastReadTime }); + const unreadChats = recentPrivateChats.filter(chat => { return chat.lastChatTime > chat.lastReadTime }); let unreadMsgs = {}; for (let { targetRoleId, lastReadTime } of unreadChats) { const msgs = await PrivateMessageModel.getMsgsByTime(privateRoomId(roleId, targetRoleId), lastReadTime, MAX_PRIVATE_MSGS); unreadMsgs[targetRoleId] = msgs; } - const roleInfos = await RoleModel.findRoleByField('roleId', sortedChats.map(chat => { return chat.targetRoleId })); - const chatInfos = sortedChats.map( chat => { + const roleInfos = await RoleModel.findRoleByField('roleId', recentPrivateChats.map(chat => { return chat.targetRoleId })); + const chatInfos = recentPrivateChats.map( chat => { for (let { roleId: targetRoleId, quitTime, roleName: targetRoleName, title, guildName, headHid, sHid, lv } of roleInfos) { if (targetRoleId === chat.targetRoleId) { const unreadCnt = unreadMsgs[targetRoleId] ? unreadMsgs[targetRoleId].length : 0; diff --git a/game-server/test/chat.test.ts b/game-server/test/chat.test.ts index 0a989d796..ff09ddf4d 100644 --- a/game-server/test/chat.test.ts +++ b/game-server/test/chat.test.ts @@ -154,6 +154,25 @@ describe('聊天测试', function() { }, 1000); }); + it('最近私聊的用户信息', function() { + function checkChatInfos(roleInfo) { + const chatInfos = roleInfo.recentPrivateChats; + if (!chatInfos) { + console.warn(`用户${roleInfo.roleName}没有最近的私聊信息`); + return; + } + for (let chatInfo of chatInfos) { + expect(chatInfo.targetRoleId).to.be.a('string'); + expect(chatInfo.targetRoleName).to.be.a('string'); + expect(Date.parse(chatInfo.lastChatTime)).to.be.a('number'); + expect(Date.parse(chatInfo.lastReadTime)).to.be.a('number'); + expect(chatInfo.unreadCnt).to.be.a('number'); + } + } + checkChatInfos(roleInfo); + checkChatInfos(roleInfoT); + }); + it('测试系统频道橙将合成消息', function(done) { let msgReceiveCnt = 0; pinusClientT.on(ON_GROUP_MSG_ROUTE, (res) => { diff --git a/shared/db/ChatInfo.ts b/shared/db/ChatInfo.ts index 1760c7c1f..8cd7ba840 100644 --- a/shared/db/ChatInfo.ts +++ b/shared/db/ChatInfo.ts @@ -1,9 +1,12 @@ import BaseModel from './BaseModel'; import { index, getModelForClass, prop, DocumentType, modelOptions } from '@typegoose/typegoose'; -class PrivateChatRec { +export class PrivateChatRec { + @prop({ required: true, default: '' }) targetRoleId: string; // 聊天玩家 roleId + @prop({ required: false }) lastReadTime: Date; // 最后查看时间,用来检查未读消息数 + @prop({ required: true }) lastChatTime: Date; // 最后聊天时间 } @@ -26,7 +29,7 @@ export default class ChatInfo extends BaseModel { BSSources: [string]; // 弹幕打开的消息来源 @prop({ required: true, default: '' }) bubbleId: string; // 气泡编号 - @prop({ required: true, type: PrivateChatRec, default: [] }) + @prop({ required: true, type: PrivateChatRec, default: [], _id: false }) recentPrivateChats: [PrivateChatRec]; // 最近聊天列表 public static async createInfo(data: ChatInfoParam) { @@ -40,6 +43,12 @@ export default class ChatInfo extends BaseModel { let result = await ChatInfoModel.findOne({ roleId }).select('-_id').lean(); return result; } + + public static async updateInfo(data: ChatInfoParam) { + const roleId = data.roleId!; + const result = await ChatInfoModel.findOneAndUpdate({ roleId }, { $set: { ...data } }, { new: true }).select('-_id').lean(); + return result; + } }