226 lines
10 KiB
TypeScript
226 lines
10 KiB
TypeScript
import BaseModel from './BaseModel';
|
|
import { index, getModelForClass, prop, DocumentType, mongoose, Ref } from '@typegoose/typegoose';
|
|
import Role, { RoleType } from '../db/Role';
|
|
import { genCode } from '../pubUtils/util';
|
|
import { GuildType } from './Guild';
|
|
import { LEAGUE_AUTH } from '../consts';
|
|
import { nowSeconds } from '../pubUtils/timeUtil';
|
|
|
|
class Member {
|
|
@prop({ required: true })
|
|
roleId: string;
|
|
@prop({ required: true })
|
|
guildCode: string;
|
|
@prop({ required: true })
|
|
auth: number;
|
|
@prop({ required: true })
|
|
time: number;
|
|
}
|
|
|
|
@index({ leagueCode: 1, status: 1 })
|
|
@index({ guildCodes: 1, status: 1 })
|
|
@index({ 'members.roleId': 1, status: 1 })
|
|
export default class GVGLeague extends BaseModel {
|
|
|
|
@prop({ required: true })
|
|
leagueCode: string; // 唯一id
|
|
|
|
@prop({ required: true, type: String })
|
|
guildCodes: string[]; // 包含军团
|
|
|
|
@prop({ required: true, ref: () => Role, type: mongoose.Schema.Types.ObjectId })
|
|
leader: Ref<Role>;
|
|
|
|
@prop({ required: true, default: '' })
|
|
name: string; // 名称
|
|
|
|
@prop({ required: true, default: 1 })
|
|
icon: number; // 图标
|
|
|
|
@prop({ required: true, default: '' })
|
|
notice: string; // 公告
|
|
|
|
@prop({ required: true, default: 0 })
|
|
guildCnt: number; // 军团数量
|
|
|
|
@prop({ required: true, default: 0 })
|
|
memberCnt: number; // 玩家人数
|
|
|
|
@prop({ required: true, default: false })
|
|
isAuto: boolean; // 是否是自动创建的
|
|
|
|
@prop({ required: true, default: 1 })
|
|
status: number; // 1-健在 0-解散
|
|
|
|
@prop({ required: true, default: 1 })
|
|
type: number; // 1-单服 2-跨服
|
|
|
|
@prop({ required: true, default: 1 })
|
|
serverId: number; // 服务器id
|
|
|
|
@prop({ required: true, default: [], type: Member, _id: false })
|
|
members: Member[];
|
|
|
|
public static async checkName(name: string) {
|
|
const result = await GVGLeagueModel.exists({ name, status: 1 });
|
|
return result;
|
|
}
|
|
|
|
public static async createLeague(guild: GuildType, params: GVGLeagueUpdate) {
|
|
const { code, name, memberCnt, leader, members } = guild;
|
|
const doc = new GVGLeagueModel();
|
|
const leagueCode = genCode(6);
|
|
let _leader = <RoleType>leader;
|
|
let _members = members.map(roleId => ({ roleId, auth: _leader.roleId == roleId? LEAGUE_AUTH.LEADER: LEAGUE_AUTH.MEMBER, guildCode: code, time: nowSeconds() }));
|
|
const update = Object.assign(doc.toJSON(), { guildCodes: [code], name: `${name}联军`, guildCnt: 1, memberCnt, isAuto: true, leader: _leader?._id, members: _members, leagueCode }, params);
|
|
delete update._id;
|
|
|
|
const result: GVGLeagueType = await GVGLeagueModel.findOneAndUpdate({ guildCodes: code, status: 1 }, { $setOnInsert: update }, { upsert: true, new: true })
|
|
.select({ _id: 0, __v: 0, createdAt: 0, updatedAt: 0 })
|
|
.populate('leader', { roleId: 1, roleName: 1, head: 1, frame: 1, spine: 1, lv: 1, quitTime: 1, ce: 1, title: 1, serverId: 1, _id: 0 }, 'Role')
|
|
.lean();
|
|
return result;
|
|
}
|
|
|
|
public static async findLeagueByGuild(guildCode: string) {
|
|
const league: GVGLeagueType = await GVGLeagueModel.findOne({ guildCodes: guildCode, status: 1 })
|
|
.populate('leader', { roleId: 1, roleName: 1, head: 1, frame: 1, spine: 1, lv: 1, quitTime: 1, ce: 1, title: 1, serverId: 1, _id: 0 }, 'Role')
|
|
.lean();
|
|
return league
|
|
}
|
|
|
|
public static async findByCondition(type: number, serverIds: number[], page: number, name: string) {
|
|
let query = {
|
|
status: 1, type, serverId: { $in: serverIds }
|
|
};
|
|
if(name) {
|
|
query['name'] = { $regex: new RegExp(name, 'i') };
|
|
}
|
|
const league: GVGLeagueType[] = await GVGLeagueModel.find(query)
|
|
.populate('leader', { roleId: 1, roleName: 1, head: 1, frame: 1, spine: 1, lv: 1, quitTime: 1, ce: 1, title: 1, serverId: 1, _id: 0 }, 'Role')
|
|
.skip((page - 1) * 30).limit(30)
|
|
.lean();
|
|
return league
|
|
}
|
|
|
|
public static async findByCode(leagueCode: string, select = '') {
|
|
const league: GVGLeagueType = await GVGLeagueModel.findOne({ leagueCode, status: 1 })
|
|
.populate('leader', { roleId: 1, roleName: 1, head: 1, frame: 1, spine: 1, lv: 1, quitTime: 1, ce: 1, title: 1, serverId: 1, _id: 0 }, 'Role')
|
|
.select(select)
|
|
.lean();
|
|
return league
|
|
}
|
|
|
|
public static async findByCodeWithoutPopulate(leagueCode: string, select = '') {
|
|
const league: GVGLeagueType = await GVGLeagueModel.findOne({ leagueCode, status: 1 }).select(select).lean();
|
|
return league
|
|
}
|
|
|
|
public static async findByCodes(leagueCodes: string[]) {
|
|
const leagues: GVGLeagueType[] = await GVGLeagueModel.find({ leagueCode: { $in: leagueCodes }, status: 1 })
|
|
.populate('leader', { roleId: 1, roleName: 1, head: 1, frame: 1, spine: 1, lv: 1, quitTime: 1, ce: 1, title: 1, serverId: 1, guildName: 1, _id: 0 }, 'Role')
|
|
.lean();
|
|
return leagues
|
|
}
|
|
|
|
public static async findByCodesWithoutPopulate(leagueCodes: string[], select = '') {
|
|
const leagues: GVGLeagueType[] = await GVGLeagueModel.find({ leagueCode: { $in: leagueCodes }, status: 1 }).select(select).lean();
|
|
return leagues
|
|
}
|
|
|
|
public static async joinGuild(leagueCode: string, guild: GuildType) {
|
|
const { code, memberCnt, leader, members } = guild;
|
|
let _leader = <RoleType>leader;
|
|
let _members = members.map(roleId => ({ roleId, auth: _leader.roleId == roleId? LEAGUE_AUTH.SUB_LEADER: LEAGUE_AUTH.MEMBER, guildCode: code, time: nowSeconds() }));
|
|
|
|
const league: GVGLeagueType = await GVGLeagueModel.findOneAndUpdate({ leagueCode, status: 1 },
|
|
{ $push: { guildCodes: code, members: { $each: _members } }, $inc: { guildCnt: 1, memberCnt: memberCnt }
|
|
}, { new: true }).lean();
|
|
return league
|
|
}
|
|
|
|
public static async findAllLeague() {
|
|
const leagues: { leagueCode: string, memberCnt: number, serverId: number }[] = await GVGLeagueModel.aggregate([
|
|
{ $match: { status: 1 } },
|
|
{ $project: { leagueCode: 1, memberCnt: 1, serverId: 1 } }
|
|
]);
|
|
return leagues;
|
|
}
|
|
|
|
public static async findActiveLeagueMembers() {
|
|
const leagues: { members: Member[] }[] = await GVGLeagueModel.aggregate([
|
|
{ $match: { status: 1 } },
|
|
{ $project: { members: 1 } }
|
|
]);
|
|
return leagues;
|
|
}
|
|
|
|
public static async quitGuild(leagueCode: string, guild: GuildType) {
|
|
const { code, memberCnt, members } = guild;
|
|
const league: GVGLeagueType = await GVGLeagueModel.findOneAndUpdate({ leagueCode, status: 1 },
|
|
{ $pull: { guildCodes: code, members: { roleId: { $in: members } } }, $inc: { guildCnt: -1, memberCnt: -memberCnt }
|
|
}, { new: true }).lean();
|
|
return league
|
|
}
|
|
|
|
public static async dismiss(leagueCode: string) {
|
|
const league: GVGLeagueType = await GVGLeagueModel.findOneAndUpdate({ leagueCode, status: 1 }, { $set: { status: 0 }}, { new: true }).lean();
|
|
return league
|
|
}
|
|
|
|
public static async dismissByIds(_ids: string[]) {
|
|
await GVGLeagueModel.updateMany({ _id: { $in: _ids } }, { $set: { status: 0 }});
|
|
}
|
|
|
|
public static async abdicate(leagueCode: string, fromRoleId: string, toRoleId: string, leader: string) {
|
|
let league: GVGLeagueType = await GVGLeagueModel.findOneAndUpdate({ leagueCode, status: 1, 'members.roleId': fromRoleId }, { $set: { 'members.$.auth': LEAGUE_AUTH.SUB_LEADER }}, { new: true }).lean();
|
|
league = await GVGLeagueModel.findOneAndUpdate({ leagueCode, status: 1, 'members.roleId': toRoleId }, { $set: { 'members.$.auth': LEAGUE_AUTH.LEADER, leader }}, { new: true }).lean();
|
|
return league
|
|
}
|
|
|
|
public static async setInfo(leagueCode: string, name: string, notice: string, icon: number) {
|
|
let updateInfo: GVGLeagueUpdate = {};
|
|
if(name != undefined) updateInfo.name = name;
|
|
if(notice != undefined) updateInfo.notice = notice;
|
|
if(icon != undefined) updateInfo.icon = icon;
|
|
const league: GVGLeagueType = await GVGLeagueModel.findOneAndUpdate({ leagueCode, status: 1 }, { $set: updateInfo }, { new: true }).lean();
|
|
return league;
|
|
}
|
|
|
|
public static async joinMember(leagueCode: string, roleId: string, guildCode: string) {
|
|
const league: GVGLeagueType = await GVGLeagueModel.findOneAndUpdate({ leagueCode, status: 1 }, { $push: { members: { roleId, auth: LEAGUE_AUTH.MEMBER, guildCode, time: nowSeconds() } }, $inc: { memberCnt: 1 } }, { new: true }).lean();
|
|
return league;
|
|
}
|
|
|
|
public static async quitMember(leagueCode: string, roleId: string) {
|
|
const league: GVGLeagueType = await GVGLeagueModel.findOneAndUpdate({ leagueCode, status: 1 }, { $pull: { members: { roleId } }, $inc: { memberCnt: -1 } }, { new: true }).lean();
|
|
return league;
|
|
}
|
|
|
|
public static async abdicateGuild(leagueCode: string, fromRoleId: string, toRoleId: string, leader: string) {
|
|
let league: GVGLeagueType = await GVGLeagueModel.findOneAndUpdate({ leagueCode, status: 1, 'members.roleId': fromRoleId }, { $set: { 'members.$.auth': LEAGUE_AUTH.MEMBER }}).lean();
|
|
const member = league.members.find(cur => cur.roleId == fromRoleId);
|
|
const updateInfo = { 'members.$.auth': member?.auth };
|
|
if(member?.auth == LEAGUE_AUTH.LEADER) updateInfo['leader'] = leader;
|
|
league = await GVGLeagueModel.findOneAndUpdate({ leagueCode, status: 1, 'members.roleId': toRoleId }, { $set: updateInfo }, { new: true }).lean();
|
|
return league
|
|
}
|
|
|
|
public static async findAutoCreateLeague() {
|
|
let leagues: GVGLeagueType[] = await GVGLeagueModel.find({ isAuto: true, status: 1 }).lean();
|
|
return leagues
|
|
}
|
|
|
|
public static async setMemberTime(leagueCode: string, roleId: string, time: number) {
|
|
let league: GVGLeagueType = await GVGLeagueModel.findOneAndUpdate({ leagueCode, status: 1, 'members.roleId': roleId }, { $set: { 'members.$.time': time} }, { new: true }).lean();
|
|
return league
|
|
}
|
|
}
|
|
|
|
export const GVGLeagueModel = getModelForClass(GVGLeague);
|
|
|
|
export interface GVGLeagueType extends Pick<DocumentType<GVGLeague>, keyof GVGLeague> {
|
|
id: number;
|
|
};
|
|
export type GVGLeagueUpdate = Partial<GVGLeagueType>; // 将所有字段变成可选项
|