You cannot select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
tailchat/server/models/chat/converse.ts

99 lines
1.8 KiB
TypeScript

import {
getModelForClass,
prop,
DocumentType,
Ref,
ReturnModelType,
} from '@typegoose/typegoose';
import { Base, TimeStamps } from '@typegoose/typegoose/lib/defaultClasses';
import { Types } from 'mongoose';
import { NAME_REGEXP } from '../../lib/const';
import { User } from '../user/user';
/**
* 设计参考: https://discord.com/developers/docs/resources/channel
*/
const converseType = [
'DM', // 私信
'Multi', // 多人会话
'Group', // 群组
] as const;
/**
* 聊天会话
*/
export class Converse extends TimeStamps implements Base {
_id: Types.ObjectId;
id: string;
@prop({
trim: true,
match: NAME_REGEXP,
})
name?: string;
/**
* 会话类型
*/
@prop({
enum: converseType,
type: () => String,
})
type!: (typeof converseType)[number];
/**
* 会话参与者
* DM会话与多人会话有值
*/
@prop({ ref: () => User })
members?: Ref<User>[];
/**
* 查找固定成员已存在的会话
*/
static async findConverseWithMembers(
this: ReturnModelType<typeof Converse>,
members: string[]
): Promise<DocumentType<Converse> | null> {
const converse = await this.findOne({
members: {
$all: [...members],
$size: members.length,
},
});
return converse;
}
/**
* 获取用户所有加入的会话
*/
static async findAllJoinedConverseId(
this: ReturnModelType<typeof Converse>,
userId: string
): Promise<string[]> {
const conserves = await this.find(
{
members: new Types.ObjectId(userId),
},
{
_id: 1,
}
);
return conserves
.map((c) => c.id)
.filter(Boolean)
.map(String);
}
}
export type ConverseDocument = DocumentType<Converse>;
const model = getModelForClass(Converse);
export type ConverseModel = typeof model;
export default model;