import BaseModel from './BaseModel'; import { index, getModelForClass, prop, DocumentType, Ref } from '@typegoose/typegoose'; import Role, { RoleType } from './Role'; import { genCode } from '../pubUtils/util'; import { GUILD_STRUCTURE, GUILD_STATUS, GUILD_PER_PAGE } from '../consts'; class Structure { @prop({ required: true }) id: number; @prop({ required: true }) lv: number; } @index({ roleId: 1 }) export default class Guild extends BaseModel { @prop({ required: true }) code: string; @prop({ required: true }) name: string; @prop({ required: true }) icon: number; @prop({ required: true, default: 1 }) lv: number; @prop({ required: true, default: 1 }) memberCnt: number; @prop({ required: true, default: false, select: false }) isMemberMax: boolean; @prop({ required: true, default: 1 }) managerCnt: number; @prop({ required: true }) leader: Ref; @prop({ required: true, default: true }) isAuto: boolean; @prop({ required: true, default: 0 }) ceLimit: number; @prop({ required: true, default: '' }) notice: string; @prop({ required: true, default: '' }) introduce: string; @prop({ required: true, default: 0 }) fund: number; @prop({ required: true, default: 0 }) activeDaily: number; @prop({ required: true, default: 0 }) activeWeekly: number; @prop({ required: true, default: new Date(), select: false }) refTimeDaily: Date; @prop({ required: true, default: new Date(), select: false }) refTimeWeekly: Date; @prop({ required: true, default: 0 }) guildCe: number; // 总战力 @prop({ required: true, type: String, default: [], select: false }) members: string[]; // 军团成员的roleId,用于增加战力的时候加入总战力 @prop({ required: true, type: Structure, default: getInitStructure(), _id: false }) structure: Structure[] @prop({ required: true, default: GUILD_STATUS.RUNNING, enum: GUILD_STATUS }) status: number; @prop({ required: true, default: 1, select: false }) serverId: number; // 分服 public static async createGuild(params: { name: string, icon: number, notice: string }, role: RoleType, serverId: number) { const doc = new GuildModel(); const update = Object.assign(doc.toJSON(), params, { leader: role._id, members: [role.roleId], guildCe: role.ce, serverId }); delete update._id; const code = genCode(6); const result: GuildType = await GuildModel.findOneAndUpdate({ code }, update, { upsert: true, new: true }) .populate('leader', 'roleId roleName sHid headHid lv loginTime ce', 'Role') .lean(); return result; } public static async checkName(name: string, serverId: number) { const result = await GuildModel.findOne({ name, status: GUILD_STATUS.RUNNING, serverId }).lean(); return !!result; } public static async findByCondition(page: number, showPeopleMax: boolean, name: string, serverId: number) { const condition = { status: GUILD_STATUS.RUNNING, serverId }; if(!showPeopleMax) { condition['isMemberMax'] = false; } if(!!name) { condition['name'] = { $regex: new RegExp(name, 'i') } } const guildList = await GuildModel.find(condition) .sort({ lv: -1, guildCe: -1 }) .limit(GUILD_PER_PAGE).skip((page - 1) * GUILD_PER_PAGE) .select('code icon name lv memberCnt leader ceLimit isAuto') .populate('leader', 'roleName', 'Role') .lean(); return guildList; } public static async findByCode(code: string, serverId: number, select?: string) { const result = await GuildModel.findOne({ code, status: GUILD_STATUS.RUNNING, serverId }) .select(select) .populate('leader', 'roleId roleName sHid headHid lv loginTime ce', 'Role') .lean(); return result; } public static async addGuild(code: string, roleId: string, maxMemberCnt: number, serverId: number) { let result = await GuildModel.findOneAndUpdate({ code, memberCnt: {$lt: maxMemberCnt }, serverId }, { $inc: { memberCnt: 1 }, $push: { members: roleId } }, { new: true }).lean(); if(result && result.memberCnt >= maxMemberCnt) { result = await GuildModel.findOneAndUpdate({ code }, { $set: { isMemberMax: true } }).lean(); } return result; } public static async dismiss(code: string, serverId: number) { const result = await GuildModel.findOneAndUpdate({ code, status: GUILD_STATUS.RUNNING, serverId }, { status: GUILD_STATUS.DISMISSED }, { new: true }) .select('+members').lean(); return result; } public static async quit(code: string, roleId: string, serverId: number) { const result = await GuildModel.findOneAndUpdate({ code, serverId }, { $inc: { memberCnt: -1}, $pull: { members: roleId }, isMemberMax: false }, { new: true }).lean(); return result; } public static async updateInfo(code: string, update: GuildUpdateParam, incParam: { managerCnt?: number }, select?: string) { const result = await GuildModel.findOneAndUpdate({ code }, { $set: update, $inc: incParam }, { new: true }).select(select).lean(); return result; } public static async upStructure(code: string, id: number, select?: string) { if (id == GUILD_STRUCTURE.ARMY_CENTER) { const result = await GuildModel.findOneAndUpdate({ code, 'structure.id': id }, { $inc: { 'structure.$.lv': 1, lv: 1 }, $set: { isMemberMax: false } }, { new: true }).select(select).lean(); return result; } else { const result = await GuildModel.findOneAndUpdate({ code, 'structure.id': id }, { $inc: { 'structure.$.lv': 1 } }, { new: true }).select(select).lean(); return result; } } public static async costFund(code: string, cost: number) { const result = await GuildModel.findOneAndUpdate({ code, fund: {$gte: cost}}, { $inc: { fund: -1 * cost } }, {new: true}).lean(); return result; } } export const GuildModel = getModelForClass(Guild); export interface GuildType extends Pick, keyof Guild> { }; export type GuildUpdateParam = Partial; // 将所有字段变成可选项 function getInitStructure() { let structure = new Array(); for (let id = GUILD_STRUCTURE.START; id < GUILD_STRUCTURE.END; id++) { structure.push({ id, lv: 1 }); } return structure; }