import BaseModel from './BaseModel'; import { index, getModelForClass, prop, DocumentType, modelOptions } from '@typegoose/typegoose'; export class PrivateChatRec { @prop({ required: true, default: '' }) targetRoleId: string; // 聊天玩家 roleId @prop({ required: false }) lastReadTime: Date; // 最后查看时间,用来检查未读消息数 @prop({ required: true }) lastChatTime: Date; // 最后聊天时间 @prop({ required: true, default: 0 }) unreadCnt: number; // 未读消息数 @prop({ required: true }) isTop: boolean; // 是否置顶 @prop({ required: true }) setTopTime: Date; // 置顶时间 } /** * 记录聊天信息,包含配置、最近聊天等 **/ @modelOptions({ schemaOptions: { id: false } }) @index({ roleId: 1 }) export default class ChatInfo extends BaseModel { @prop({ required: true, default: '' }) roleId: string; // 消息发送者 roleId @prop({ required: true, default: '' }) roleName: string; // 消息发送者名称 @prop({ required: true, type: String, default: [] }) sources: [string]; // 打开的消息来源,主要用于系统通知筛选 @prop({ required: true, type: String, default: [] }) BSChannels: [string]; // 弹幕打开的频道,BS:bullet screen @prop({ required: true, type: String, default: [] }) BSSources: [string]; // 弹幕打开的消息来源 @prop({ required: true, default: '' }) bubbleId: string; // 气泡编号 @prop({ required: true, type: PrivateChatRec, default: [], _id: false }) recentPrivateChats: [PrivateChatRec]; // 最近聊天列表 public static async createInfo(data: ChatInfoParam) { const roleId = data.roleId!; const docData = new ChatInfoModel(); const result: ChatInfoType = await ChatInfoModel.findOneAndUpdate({ roleId }, { ...docData.toJSON(), ...data }, { upsert: true, new: true }).select('-_id').lean(); return result; } public static async findInfo(roleId: string) { let result: ChatInfoType = await ChatInfoModel.findOne({ roleId }).select('-_id').lean(); return result; } public static async updateInfo(data: ChatInfoParam) { const roleId = data.roleId!; const result: ChatInfoType = await ChatInfoModel.findOneAndUpdate({ roleId }, { $set: { ...data } }, { new: true }).select('-_id').lean(); return result; } public static async updateReadInfo(roleId: string, targetRoleId: string, time: Date) { const result: ChatInfoType = await ChatInfoModel .findOneAndUpdate( { roleId, 'recentPrivateChats.targetRoleId': targetRoleId }, { 'recentPrivateChats.$.lastReadTime': time, 'recentPrivateChats.$.unreadCnt': 0 }, { new: true }) .select('-_id').lean(); return result; } public static async setTop(roleId: string, targetRoleId: string, isTop: boolean, time: Date) { const result: ChatInfoType = await ChatInfoModel .findOneAndUpdate( { roleId, 'recentPrivateChats.targetRoleId': targetRoleId }, { 'recentPrivateChats.$.isTop': isTop, 'recentPrivateChats.$.setTopTime': time }, { new: true }) .select('-_id').lean(); return result; } public static async delMsg(roleId: string, targetRoleId: string) { const result: ChatInfoType = await ChatInfoModel .findOneAndUpdate( { roleId }, { $pull: { recentPrivateChats: { targetRoleId } } }, { new: true }) .select('-_id').lean(); return result; } } export const ChatInfoModel = getModelForClass(ChatInfo); export interface ChatInfoType extends Pick, keyof ChatInfo> {}; export type ChatInfoParam = Partial;