聊天:最近私聊历史相关逻辑
This commit is contained in:
@@ -19,7 +19,7 @@ import { GuildModel } from '../../../db/Guild';
|
|||||||
import { gameData } from '../../../pubUtils/data';
|
import { gameData } from '../../../pubUtils/data';
|
||||||
|
|
||||||
import { getMails } from '../../../services/mailService';
|
import { getMails } from '../../../services/mailService';
|
||||||
import { addRoleToGuildChannel, addRoleToSysChannel, addRoleToWorldChannel, leaveGuildChannel, leaveSysChannel, leaveWorldChannel } from '../../../services/chatService';
|
import { addRoleToGuildChannel, addRoleToSysChannel, addRoleToWorldChannel, leaveGuildChannel, leaveSysChannel, leaveWorldChannel, recentPrivateChatInfos } from '../../../services/chatService';
|
||||||
import { reportOneOnline } from '../../../services/timeTaskService';
|
import { reportOneOnline } from '../../../services/timeTaskService';
|
||||||
export default function (app: Application) {
|
export default function (app: Application) {
|
||||||
return new EntryHandler(app);
|
return new EntryHandler(app);
|
||||||
@@ -109,6 +109,11 @@ export class EntryHandler {
|
|||||||
role['apJson'] = apJson;
|
role['apJson'] = apJson;
|
||||||
role['mails'] = mails;
|
role['mails'] = mails;
|
||||||
|
|
||||||
|
const recentPrivateChats = await recentPrivateChatInfos(role.roleId, role.roleName);
|
||||||
|
if (recentPrivateChats) {
|
||||||
|
role['recentPrivateChats'] = recentPrivateChats;
|
||||||
|
}
|
||||||
|
|
||||||
if(role.hasGuild) {
|
if(role.hasGuild) {
|
||||||
let userGuild = await UserGuildModel.getMyGuild(role.roleId, USER_GUILD_SELECT.ENTRY );
|
let userGuild = await UserGuildModel.getMyGuild(role.roleId, USER_GUILD_SELECT.ENTRY );
|
||||||
if(userGuild) {
|
if(userGuild) {
|
||||||
|
|||||||
@@ -9,12 +9,13 @@ import { PrivateMessageModel, PrivateMessageParam, PrivateMessageType } from './
|
|||||||
import { GroupMessageParam, GroupMessageType } from '../db/GroupMessage';
|
import { GroupMessageParam, GroupMessageType } from '../db/GroupMessage';
|
||||||
import { genCode, resResult } from '../pubUtils/util';
|
import { genCode, resResult } from '../pubUtils/util';
|
||||||
import { pinus } from 'pinus';
|
import { pinus } from 'pinus';
|
||||||
import { CHANNEL_PREFIX, MSG_CODE_LEN, MSG_SOURCE, MSG_STATUS, MSG_TYPE, ON_GROUP_MSG_ROUTE, ON_MSG_ROUTE, RICH_TEXT_TABLE } from '../consts';
|
import { CHANNEL_PREFIX, MSG_CODE_LEN, MSG_SOURCE, MSG_STATUS, MSG_TYPE, ON_GROUP_MSG_ROUTE, ON_MSG_ROUTE, RICH_TEXT_TABLE, RECENT_PRIVATE_CHATS_CNT, MAX_PRIVATE_MSGS } from '../consts';
|
||||||
import { addRedisChannel, getRoleOnlineInfo, redisChannelServer } from './redisService';
|
import { addRedisChannel, getRoleOnlineInfo, redisChannelServer } from './redisService';
|
||||||
import { crc32 } from 'crc';
|
import { crc32 } from 'crc';
|
||||||
import { HeroType } from '../db/Hero';
|
import { HeroType } from '../db/Hero';
|
||||||
import { GuildType } from '../db/Guild';
|
import { GuildType } from '../db/Guild';
|
||||||
import { GuildTrainType } from '../db/GuildTrain';
|
import { GuildTrainType } from '../db/GuildTrain';
|
||||||
|
import { ChatInfoModel } from '../db/ChatInfo';
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @description 生成私聊房间号
|
* @description 生成私聊房间号
|
||||||
@@ -272,3 +273,37 @@ export async function pushGuildBossSucMsg(roleId: string, roleName: string, guil
|
|||||||
await pushGroupMsgToRoom(groupRoomId(CHANNEL_PREFIX.GUILD, guildCode), msgData);
|
await pushGroupMsgToRoom(groupRoomId(CHANNEL_PREFIX.GUILD, guildCode), msgData);
|
||||||
return msgData;
|
return msgData;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
export async function roleChatInfos(roleId: string, roleName: string) {
|
||||||
|
let result = await ChatInfoModel.findInfo(roleId);
|
||||||
|
if (!result) {
|
||||||
|
result = await ChatInfoModel.createInfo({ roleId, roleName });
|
||||||
|
}
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
|
export async function recentPrivateChatInfos(roleId: string, roleName: string) {
|
||||||
|
const { recentPrivateChats } = await roleChatInfos(roleId, roleName);
|
||||||
|
const sortedChats = recentPrivateChats
|
||||||
|
.sort((a, b) => a.lastChatTime.getTime() - b.lastChatTime.getTime())
|
||||||
|
.splice(RECENT_PRIVATE_CHATS_CNT);
|
||||||
|
if (!sortedChats || !sortedChats.length) return null;
|
||||||
|
|
||||||
|
const unreadChats = sortedChats.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 => {
|
||||||
|
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;
|
||||||
|
return { ...chat, quitTime, targetRoleName, title, guildName, headHid, sHid, lv, unreadCnt };
|
||||||
|
}
|
||||||
|
}
|
||||||
|
});
|
||||||
|
return chatInfos;
|
||||||
|
}
|
||||||
|
|||||||
@@ -1,4 +1,6 @@
|
|||||||
export const MSG_CODE_LEN = 8;
|
export const MSG_CODE_LEN = 8;
|
||||||
|
export const RECENT_PRIVATE_CHATS_CNT = 20;
|
||||||
|
export const MAX_PRIVATE_MSGS = 99;
|
||||||
|
|
||||||
export const MSG_STATUS = {
|
export const MSG_STATUS = {
|
||||||
NORMAL: 0,
|
NORMAL: 0,
|
||||||
|
|||||||
+21
-6
@@ -1,6 +1,12 @@
|
|||||||
import BaseModel from './BaseModel';
|
import BaseModel from './BaseModel';
|
||||||
import { index, getModelForClass, prop, DocumentType, modelOptions } from '@typegoose/typegoose';
|
import { index, getModelForClass, prop, DocumentType, modelOptions } from '@typegoose/typegoose';
|
||||||
|
|
||||||
|
class PrivateChatRec {
|
||||||
|
targetRoleId: string; // 聊天玩家 roleId
|
||||||
|
lastReadTime: Date; // 最后查看时间,用来检查未读消息数
|
||||||
|
lastChatTime: Date; // 最后聊天时间
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 记录聊天信息,包含配置、最近聊天等
|
* 记录聊天信息,包含配置、最近聊天等
|
||||||
**/
|
**/
|
||||||
@@ -20,15 +26,24 @@ export default class ChatInfo extends BaseModel {
|
|||||||
BSSources: [string]; // 弹幕打开的消息来源
|
BSSources: [string]; // 弹幕打开的消息来源
|
||||||
@prop({ required: true, default: '' })
|
@prop({ required: true, default: '' })
|
||||||
bubbleId: string; // 气泡编号
|
bubbleId: string; // 气泡编号
|
||||||
@prop({ required: true, type: String, default: [] })
|
@prop({ required: true, type: PrivateChatRec, default: [] })
|
||||||
recentPrivateChats: [{ // 最近聊天列表
|
recentPrivateChats: [PrivateChatRec]; // 最近聊天列表
|
||||||
targetRoleId: string; // 聊天玩家 roleId
|
|
||||||
roomId: string; // 聊天 Id
|
public static async createInfo(data: ChatInfoParam) {
|
||||||
lastReadTime: Date; // 最后查看时间
|
const roleId = data.roleId!;
|
||||||
}];
|
const docData = new ChatInfoModel();
|
||||||
|
const result = await ChatInfoModel.findOneAndUpdate({ roleId }, { ...docData.toJSON(), ...data }, { upsert: true, new: true }).select('-_id').lean();
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
|
public static async findInfo(roleId: string) {
|
||||||
|
let result = await ChatInfoModel.findOne({ roleId }).select('-_id').lean();
|
||||||
|
return result;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
export const ChatInfoModel = getModelForClass(ChatInfo);
|
export const ChatInfoModel = getModelForClass(ChatInfo);
|
||||||
|
|
||||||
export interface ChatInfoType extends Pick<DocumentType<ChatInfo>, keyof ChatInfo> {};
|
export interface ChatInfoType extends Pick<DocumentType<ChatInfo>, keyof ChatInfo> {};
|
||||||
|
export type ChatInfoParam = Partial<ChatInfoType>;
|
||||||
|
|||||||
@@ -51,6 +51,16 @@ export default class PrivateMessage extends BaseModel {
|
|||||||
const result = await PrivateMessageModel.find({ roomId, seqId: { $lt: fromSeqId } }).sort({ seqId: -1 }).limit(count).lean();
|
const result = await PrivateMessageModel.find({ roomId, seqId: { $lt: fromSeqId } }).sort({ seqId: -1 }).limit(count).lean();
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public static async getMsgsByTime(roomId: string, time: Date, count: number) {
|
||||||
|
const result = await PrivateMessageModel.find({ roomId, createdAt: { $gt: time } }).sort({ seqId: -1 }).limit(count).lean();
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
|
public static async getMsgByRooms(roomIds: string[], count: number) {
|
||||||
|
const result = await PrivateMessageModel.find({ roomId: { $in: roomIds } }).sort({ seqId: -1 }).limit(count).lean();
|
||||||
|
return result;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user