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/group/invite.ts

113 lines
2.1 KiB
TypeScript

import {
getModelForClass,
prop,
DocumentType,
Ref,
ReturnModelType,
} from '@typegoose/typegoose';
import { Base, TimeStamps } from '@typegoose/typegoose/lib/defaultClasses';
import moment from 'moment';
import type { Types } from 'mongoose';
import { nanoid } from 'nanoid';
import { User } from '../user/user';
import { Group } from './group';
import promiseRetry from 'promise-retry';
function generateCode() {
return nanoid(8);
}
export class GroupInvite extends TimeStamps implements Base {
_id: Types.ObjectId;
id: string;
@prop({
index: true,
unique: true,
default: () => generateCode(),
})
code!: string;
@prop({
ref: () => User,
})
creator: Ref<User>;
@prop({
ref: () => Group,
})
groupId!: Ref<Group>;
/**
*
*/
@prop()
expiredAt?: Date;
/**
* 使
*/
@prop({
default: 0,
})
usage: number;
/**
* 使
*/
@prop()
usageLimit?: number;
/**
*
* @param groupId id
* @param type (7)
*/
static async createGroupInvite(
this: ReturnModelType<typeof GroupInvite>,
groupId: string,
creator: string,
inviteType: 'normal' | 'permanent'
): Promise<GroupInviteDocument> {
let expiredAt = moment().add(7, 'day').toDate(); // 默认7天
if (inviteType === 'permanent') {
expiredAt = undefined;
}
const code = await promiseRetry(
async () => {
const code = generateCode();
const exists = await this.exists({ code });
if (exists) {
throw new Error('Cannot find unused invite code, please try again.');
}
return code;
},
{
minTimeout: 0,
maxTimeout: 0,
retries: 5,
}
);
const invite = await this.create({
groupId,
code,
creator,
expiredAt,
});
return invite;
}
}
export type GroupInviteDocument = DocumentType<GroupInvite>;
const model = getModelForClass(GroupInvite);
export type GroupInviteModel = typeof model;
export default model;