Files
ZYZ/shared/db/Guild.ts
2021-01-26 13:26:33 +08:00

216 lines
8.6 KiB
TypeScript
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
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';
import { getCurWeekTime } from '../pubUtils/timeUtil';
class Structure {
@prop({ required: true })
id: number;
@prop({ required: true })
lv: number;
}
@index({ code: 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: 0 })
managerCnt: number;
@prop({ required: true })
leader: Ref<Role>;
@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: Date.now() })
activeUpdateTime: number;
@prop({ required: true, default: new Date(), select: false })
refTimeDaily: 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; // 分服
@prop({ required: true, default: 1 })
trainId: number; // 试炼id
@prop({ required: true, default: 0 })
resetTrainTime: 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: 1, roleName: 1, sHid: 1, headHid: 1, lv: 1, loginTime: 1, ce: 1, title: 1, _id: 0 }, 'Role')
.lean();
return result;
}
public static async checkName(name: string, serverId: number) {
const result: GuildType = 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: GuildType[] = 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: 1, _id: 0 }, 'Role')
.lean();
return guildList;
}
public static async getRank(serverId: number, page: number = 1) {
const guildList: GuildType[] = await GuildModel.find({ status: GUILD_STATUS.RUNNING, serverId }, {_id: 0})
.sort({ activeWeekly: -1, activeUpdateTime: -1 })
.limit(100).skip((page - 1) * 100)
.select('code icon name lv leader activeWeekly activeUpdateTime')
.populate('leader', {roleName: 1, title: 1, sHid: 1, headHid: 1, lv: 1, _id: 0}, 'Role')
.lean();
return guildList;
}
public static async findAllGuild(select?: string) {
const guildList: GuildType[] = await GuildModel.find({ status: GUILD_STATUS.RUNNING }).select(select).lean();
return guildList;
}
public static async findByCode(code: string, serverId: number, select?: string) {
const result: GuildType = await GuildModel.findOne({ code, status: GUILD_STATUS.RUNNING, serverId })
.select(select)
.populate('leader', {roleId: 1, roleName: 1, sHid: 1, headHid: 1, lv: 1, loginTime: 1, ce: 1, title: 1, _id: 0}, 'Role')
.lean();
return result;
}
public static async addGuild(code: string, roleId: string, maxMemberCnt: number, serverId: number, ce: number) {
let result: GuildType = await GuildModel.findOneAndUpdate({ code, memberCnt: {$lt: maxMemberCnt }, serverId }, { $inc: { memberCnt: 1, guildCe: ce }, $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: GuildType = 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: GuildType = 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, fund?: number, activeDaily?: number, activeWeekly?: number }, select?: string) {
const result: GuildType = 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: GuildType = 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: GuildType = 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: GuildType = await GuildModel.findOneAndUpdate({ code, fund: {$gte: cost}}, { $inc: { fund: -1 * cost } }, {new: true}).lean();
return result;
}
public static async findGuild(code: string, serverId: number, select?: string, lean = true) {
const result: GuildType = await GuildModel.findOne({ code, status: GUILD_STATUS.RUNNING, serverId }).select(select).lean(lean);
return result;
}
public static async updateCe(roleId: string, inc: number ) {
const result = await GuildModel.findOneAndUpdate({ $elemMatch: {members: roleId}, status: GUILD_STATUS.RUNNING}, {$inc: {guildCe: inc}}, {new: true}).lean();
return result;
}
public static async resetGuildTrain(code: string, serverId: number, lean = true) {
const time = getCurWeekTime(1, 5);//每周一5点刷新
const result = await GuildModel.findOneAndUpdate({ code, status: GUILD_STATUS.RUNNING, serverId, resetTrainTime:{$ne:time}},{$set: {trainId: 1}}).lean(lean);
return result;
}
}
export const GuildModel = getModelForClass(Guild);
export interface GuildType extends Pick<DocumentType<Guild>, keyof Guild> { };
export type GuildUpdateParam = Partial<GuildType>; // 将所有字段变成可选项
function getInitStructure() {
let structure = new Array<Structure>();
for (let id = GUILD_STRUCTURE.START; id < GUILD_STRUCTURE.END; id++) {
structure.push({ id, lv: 1 });
}
return structure;
}