feat(gvg): 组建期

This commit is contained in:
luying
2023-01-05 19:18:56 +08:00
parent 94c69089ac
commit 03fa74f3d1
50 changed files with 10354 additions and 38 deletions

48
shared/db/GVGConfig.ts Normal file
View File

@@ -0,0 +1,48 @@
import BaseModel from './BaseModel';
import { index, getModelForClass, prop, DocumentType } from '@typegoose/typegoose';
import { CounterModel } from './Counter';
import { COUNTER } from '../consts';
@index({ configId: -1 })
export default class GVGConfig extends BaseModel {
@prop({ required: true, default: 1 })
configId: number; // 配置唯一id
@prop({ required: true })
teamTime: number; // 组建期开始
@prop({ required: true })
prepareTime: number; // 准备期开始
@prop({ required: true })
battleTime: number; // 激战期开始
@prop({ required: true })
scheduleTime: number; // 下次定时任务时间
public static async createNewConfig(teamTime: number, prepareTime: number, battleTime: number, scheduleTime: number) {
const configId = await CounterModel.getNewCounter(COUNTER.GVG_CONFIG);
const result: GVGConfigType = await GVGConfigModel.findOneAndUpdate({ configId }, { $set: { teamTime, prepareTime, battleTime, scheduleTime } }, { upsert: true, new: true }).lean();
return result;
}
public static async findConfig() {
let configId = await CounterModel.getCounter(COUNTER.GVG_CONFIG);
const result: GVGConfigType = await GVGConfigModel.findOne({ configId }, { _id: 0 }).lean();
return result;
}
public static async updateConfig(configId: number, teamTime: number, prepareTime: number, battleTime: number, scheduleTime: number) {
const result: GVGConfigType = await GVGConfigModel.findOneAndUpdate({ configId }, { $set: { teamTime, prepareTime, battleTime, scheduleTime } }, { new: true }).lean();
return result;
}
}
export const GVGConfigModel = getModelForClass(GVGConfig);
export interface GVGConfigType extends Pick<DocumentType<GVGConfig>, keyof GVGConfig> {
id: number;
};
export type GVGConfigUpdate = Partial<GVGConfigType>; // 将所有字段变成可选项

195
shared/db/GVGLeague.ts Normal file
View File

@@ -0,0 +1,195 @@
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';
class Member {
@prop({ required: true })
roleId: string;
@prop({ required: true })
auth: 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: 0 })
leagueCe: 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, guildCe, 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 }));
const update = Object.assign(doc.toJSON(), { guildCodes: [code], name: `${name}联军`, guildCnt: 1, memberCnt, isAuto: true, leagueCe: guildCe, 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) {
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')
.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, _id: 0 }, 'Role')
.lean();
return leagues
}
public static async joinGuild(leagueCode: string, guild: GuildType) {
const { code, memberCnt, leader, guildCe, members } = guild;
let _leader = <RoleType>leader;
let _members = members.map(roleId => ({ roleId, auth: _leader.roleId == roleId? LEAGUE_AUTH.SUB_LEADER: LEAGUE_AUTH.MEMBER }));
const league: GVGLeagueType = await GVGLeagueModel.findOneAndUpdate({ leagueCode, status: 1 },
{ $push: { guildCodes: code, members: { $each: _members } }, $inc: { guildCnt: 1, memberCnt: memberCnt, leagueCe: guildCe }
}, { new: true }).lean();
return league
}
public static async findAllLeague() {
const leagues: { leagueCode: string, memberCnt: number }[] = await GVGLeagueModel.aggregate([
{ $match: { status: 1 } },
{ $project: { leagueCode: 1, memberCnt: 1 } }
]);
return leagues;
}
public static async quitGuild(leagueCode: string, guild: GuildType) {
const { code, memberCnt, members, guildCe } = guild;
const league: GVGLeagueType = await GVGLeagueModel.findOneAndUpdate({ leagueCode, status: 1 },
{ $pull: { guildCodes: code, members: { roleId: { $in: members } } }, $inc: { guildCnt: -1, memberCnt: -memberCnt, leagueCe: -guildCe }
}, { 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 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 updateCe(roleId: string, incCe: number) {
const league: GVGLeagueType = await GVGLeagueModel.findOneAndUpdate({ 'members.roleId': roleId, status: 1 }, { $inc: { leagueCe: incCe } }, { new: true }).lean();
return league;
}
public static async joinMember(leagueCode: string, roleId: string, ce: number) {
const league: GVGLeagueType = await GVGLeagueModel.findOneAndUpdate({ leagueCode, status: 1 }, { $push: { members: { roleId, auth: LEAGUE_AUTH.MEMBER } }, $inc: { memberCnt: 1, leagueCe: ce } }, { new: true }).lean();
return league;
}
public static async quitMember(leagueCode: string, roleId: string, ce: number) {
const league: GVGLeagueType = await GVGLeagueModel.findOneAndUpdate({ leagueCode, status: 1 }, { $pull: { members: { roleId } }, $inc: { memberCnt: -1, leagueCe: -ce } }, { 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
}
}
export const GVGLeagueModel = getModelForClass(GVGLeague);
export interface GVGLeagueType extends Pick<DocumentType<GVGLeague>, keyof GVGLeague> {
id: number;
};
export type GVGLeagueUpdate = Partial<GVGLeagueType>; // 将所有字段变成可选项

104
shared/db/GVGLeagueApply.ts Normal file
View File

@@ -0,0 +1,104 @@
import BaseModel from './BaseModel';
import { getModelForClass, prop, DocumentType, index, Ref } from '@typegoose/typegoose';
import GVGLeague, { GVGLeagueType } from './GVGLeague';
import Guild, { GuildType } from './Guild';
import { GVG_APPLY_TYPE } from '../consts';
@index({ leagueCode: 1, guildCode: 1, type: 1 })
export default class GVGLeagueApply extends BaseModel {
@prop({ required: true })
leagueCode: string; // 发起的联军 or 收到申请的联军
@prop({ required: true })
league: Ref<GVGLeague>;
@prop({ required: true })
guildCode: string; // 受邀的军团 or 发出申请的联军
@prop({ required: true })
guild: Ref<Guild>;
@prop({ required: true })
type: number; // 类型 1-邀请 2-申请
public static async findApplyFromGuild(guildCode: string) {
const result: GVGLeagueApplyType[] = await GVGLeagueApplyModel.find({ guildCode, type: GVG_APPLY_TYPE.APPLY }).lean();
return result;
}
public static async checkApply(leagueCode: string, guildCode: string, type: GVG_APPLY_TYPE) {
console.log('####', leagueCode, guildCode, type)
const result = await GVGLeagueApplyModel.exists({ guildCode, leagueCode,
type: type == GVG_APPLY_TYPE.ALL? { $in: [GVG_APPLY_TYPE.APPLY, GVG_APPLY_TYPE.INVITE] }: type
});
return result;
}
public static async createApply(league: GVGLeagueType, guild: GuildType, type: number) {
const result: GVGLeagueApplyType = await GVGLeagueApplyModel.findOneAndUpdate({ leagueCode: league.leagueCode, guildCode: guild.code, type }, { $set: { league: league._id, guild: guild._id, }}, { new: true, upsert: true })
.lean();
return result;
}
public static async findApplyFromLeague(leagueCode: string) {
const result: GVGLeagueApplyType[] = await GVGLeagueApplyModel.find({ leagueCode, type: GVG_APPLY_TYPE.APPLY })
.select({ _id: 0, guild: 1, guildCode: 1 })
.populate({
path: 'guild',
select: 'code icon name lv memberCnt leader guildCe +serverId',
model: 'Guild',
populate: {
path: 'leader',
select: 'roleName',
model: 'Role'
}
})
.lean();
return result;
}
public static async findInviteFromLeague(leagueCode: string) {
const result: GVGLeagueApplyType[] = await GVGLeagueApplyModel.find({ leagueCode, type: GVG_APPLY_TYPE.INVITE }).lean();
return result;
}
public static async findInviteFromGuild(guildCode: string) {
const result: GVGLeagueApplyType[] = await GVGLeagueApplyModel.find({ guildCode, type: GVG_APPLY_TYPE.INVITE })
.select({ _id: 0, guild: 1, guildCode: 1 })
.populate({
path: 'league',
// select: 'code icon name lv memberCnt leader guildCe +serverId',
model: 'GVGLeague',
populate: {
path: 'leader',
select: 'roleName',
model: 'Role'
}
})
.lean();
return result;
}
public static async deleteApply(guildCode: string, leagueCode: string) {
const n = await GVGLeagueApplyModel.deleteMany({ guildCode, leagueCode, type: GVG_APPLY_TYPE.APPLY });
return n;
}
public static async deleteAllGuildApply(guildCode: string) {
const n = await GVGLeagueApplyModel.deleteMany({ guildCode, type: GVG_APPLY_TYPE.APPLY });
return n;
}
public static async deleteInvite(guildCode: string, leagueCode: string) {
const n = await GVGLeagueApplyModel.deleteMany({ guildCode, leagueCode, type: GVG_APPLY_TYPE.INVITE });
return n;
}
}
export const GVGLeagueApplyModel = getModelForClass(GVGLeagueApply);
export interface GVGLeagueApplyType extends Pick<DocumentType<GVGLeagueApply>, keyof GVGLeagueApply> {
id: number;
};
export type GVGLeagueApplyUpdate = Partial<GVGLeagueApplyType>; // 将所有字段变成可选项

View File

@@ -0,0 +1,82 @@
import BaseModel from './BaseModel';
import { index, getModelForClass, prop, DocumentType, } from '@typegoose/typegoose';
class Tech {
@prop({ required: true, default: 0 })
id: number;
@prop({ required: true, default: 0 })
progress: number; // 贡献
@prop({ required: true, default: 0 })
status: number; // 0-已解锁 1-已激活
}
class DonateRec {
@prop({ required: true, default: 0 })
roleId: string;
@prop({ required: true, default: 0 })
time: number;
@prop({ required: true, default: 0 })
count: number;
}
class Resource {
@prop({ required: true, default: 0 })
food: number; // 粮食
@prop({ required: true, default: 0 })
mineral: number; // 矿物
@prop({ required: true, default: 0 })
wood: number; // 木堆
}
@index({ leagueCode: 1, configId: 1 })
export default class GVGLeaguePrepare extends BaseModel {
@prop({ required: true })
configId: number; // 赛期配置id
@prop({ required: true })
leagueCode: string; // 联军
@prop({ required: true, default: 1 })
lv: number; // 等级
@prop({ required: true, default: 0 })
maxMemberCnt: number; // 进入备战期初始玩家人数
@prop({ required: true, default: 0 })
producerCnt: number; // 选择内政人数
@prop({ required: true, default: 0 })
fighterCnt: number; // 选择外政人数
@prop({ required: true, default: [], type: Tech, _id: false })
tech: Tech[]; // 千机阁
@prop({ required: true, default: [], type: DonateRec, _id: false })
donateRec: DonateRec[]; // 捐献记录
@prop({ required: true, default: {food: 0, mineral: 0, wood: 0}, type: Resource, _id: false })
resources: Resource
public static async initData(configId: number, leagueCode: string, maxMemberCnt: number) {
const doc = new GVGLeaguePrepareModel();
const update = Object.assign(doc.toJSON(), { maxMemberCnt });
delete update._id;
const result: GVGLeaguePrepareType = await GVGLeaguePrepareModel.findOneAndUpdate({ configId, leagueCode }, { $setOnInsert: update }, { upsert: true, new: true })
.select({ _id: 0, __v: 0, createdAt: 0, updatedAt: 0 }).lean();
return result;
}
public static async findByLeague(configId: number, leagueCode: string) {
const result: GVGLeaguePrepareType = await GVGLeaguePrepareModel.findOne({ configId, leagueCode }).lean();
return result;
}
}
export const GVGLeaguePrepareModel = getModelForClass(GVGLeaguePrepare);
export interface GVGLeaguePrepareType extends Pick<DocumentType<GVGLeaguePrepare>, keyof GVGLeaguePrepare> {
id: number;
};
export type GVGLeaguePrepareUpdate = Partial<GVGLeaguePrepareType>; // 将所有字段变成可选项

View File

@@ -0,0 +1,41 @@
import BaseModel from './BaseModel';
import { index, getModelForClass, prop, DocumentType } from '@typegoose/typegoose';
/**
* 服务器分战区
*/
@index({ time: -1, serverId: -1 })
export default class GVGServerGroup extends BaseModel {
@prop({ required: true, default: 1 })
serverId: number; // 服务器id
@prop({ required: true, default: 1 })
groupId: number; // 战区id
@prop({ required: true, default: 0 })
time: number; // 生效时间
public static async findByTime(time: number) {
const serverGroup: { serverId: number, groupId: number }[] = await GVGServerGroupModel.aggregate([
{ $match: { time: { $lte: time } } },
{ $sort: { time: -1 } },
{ $group: { _id: "$id", serverId: { $first: "$serverId" }, groupId: { $first: "$groupId" }, time: { $first: "$time" }} },
{ $sort: { _id: -1 } },
{ $project: { _id: 0, id: "$_id", serverId: "$serverId", groupId: "$groupId", time: "$time" } }
]);
return serverGroup;
}
public static async updateByServerId(serverId: number, groupId: number, time: number) {
const result: GVGServerGroupType = await GVGServerGroupModel.findOneAndUpdate({ serverId, time }, { $set: { groupId } }, { new: true, upsert: true }).lean();
return result
}
}
export let GVGServerGroupModel = getModelForClass(GVGServerGroup);
export interface GVGServerGroupType extends Pick<DocumentType<GVGServerGroup>, keyof GVGServerGroup> {
id: number;
};
export type GVGServerGroupUpdate = Partial<GVGServerGroupType>; // 将所有字段变成可选项

81
shared/db/GVGUserData.ts Normal file
View File

@@ -0,0 +1,81 @@
import BaseModel from './BaseModel';
import { index, getModelForClass, prop, DocumentType, } from '@typegoose/typegoose';
class ActiveRec {
@prop({ required: true, default: 1 })
id: number; // 1-内政令消耗 2-征战令消耗 3-科技树捐献
@prop({ required: true, default: 0 })
count: number;
@prop({ required: true, default: 0 })
time: number;
}
class Box {
@prop({ required: true, default: 0 })
score: number; // 宝箱积分
@prop({ required: true, default: [], type: Number })
received: number[]; // 领取记录
}
@index({ leagueCode: 1, roleId: 1, configId: 1, status: 1 })
export default class GVGUserData extends BaseModel {
@prop({ required: true })
roleId: string; // 玩家
@prop({ required: true })
configId: number; // 赛季信息
@prop({ required: true })
leagueCode: string; // 所属联军
@prop({ required: true, default: 0 })
job: number; // 职能 1-贤臣 2-猛将
// 备战期
@prop({ required: true, default: 0 })
active: number; // 活跃度
@prop({ required: true, default: 0, type: ActiveRec, _id: false })
activeRec: ActiveRec[]; // 活跃度记录
@prop({ required: true, default: 0 })
receivedLv: number; // 领取到的等级奖励
@prop({ required: true, default: 0 })
receiveCurrencyTime: number; // 领取内政令&征战令时间
@prop({ required: true, default: { score: 0, received: []}, type: Box, _id: false })
box: Box;
@prop({ required: true, default: 0 })
sendFightRewardTime: number; // 发送征战奖励的时间
// 激战期
@prop({ required: true, default: 0 })
battleStatus: number; // 1-被挑战中 0-可被挑战
@prop({ required: true, default: 0 })
area: number; // 所处区域 1-进攻北站 2-混战 3-据点 4-防守备战
@prop({ required: true, default: 0 })
protectTime: number; // 保护期
public static async findByRole(configId: number, leagueCode: string, roleId: string) {
const result: GVGUserDataType = await GVGUserDataModel.findOneAndUpdate({ configId, leagueCode, roleId }, {}, { new: true, upsert: true}).lean();
return result;
}
public static async findByRoles(configId: number, leagueCode: string, roleIds: string[]) {
const result: GVGUserDataType[] = await GVGUserDataModel.find({ configId, leagueCode, roleId: { $in: roleIds } }).lean();
return result;
}
}
export const GVGUserDataModel = getModelForClass(GVGUserData);
export interface GVGUserDataType extends Pick<DocumentType<GVGUserData>, keyof GVGUserData> {
id: number;
};
export type GVGUserDataUpdate = Partial<GVGUserDataType>; // 将所有字段变成可选项

37
shared/db/GVGUserItem.ts Normal file
View File

@@ -0,0 +1,37 @@
import BaseModel from './BaseModel';
import { index, getModelForClass, prop, DocumentType, } from '@typegoose/typegoose';
import { nowSeconds } from '../pubUtils/timeUtil';
@index({ leagueCode: 1, roleId: 1, configId: 1, status: 1 })
export default class GVGUserItem extends BaseModel {
@prop({ required: true })
roleId: string; // 玩家
@prop({ required: true })
leagueCode: string; // 联军id
@prop({ required: true })
configId: number; // 赛期
@prop({ required: true })
id: number; // 道具: 包括 种子、铲子、斧子
@prop({ required: true, default: 0 })
count: number; // 数量
@prop({ required: true, default: 0 })
expireTime: number;
public static async findByRole(configId: number, leagueCode: string, roleId: string) {
const result: GVGUserItemType[] = await GVGUserItemModel.find({ configId, leagueCode, roleId, expireTime: { $gte: nowSeconds() } }, { _id: 0 }).lean();
return result;
}
}
export const GVGUserItemModel = getModelForClass(GVGUserItem);
export interface GVGUserItemType extends Pick<DocumentType<GVGUserItem>, keyof GVGUserItem> {
id: number;
};
export type GVGUserItemUpdate = Partial<GVGUserItemType>; // 将所有字段变成可选项

41
shared/db/GVGUserTask.ts Normal file
View File

@@ -0,0 +1,41 @@
import BaseModel from './BaseModel';
import { index, getModelForClass, prop, DocumentType, } from '@typegoose/typegoose';
import { getZeroPointD } from '../pubUtils/timeUtil';
@index({ leagueCode: 1, roleId: 1, configId: 1, status: 1 })
export default class GVGUserTask extends BaseModel {
@prop({ required: true, default: '' })
roleId: string; // 玩家
@prop({ required: true, default: '' })
leagueCode: string; // 联军id
@prop({ required: true, default: 0 })
configId: number; // 赛期
@prop({ required: true, default: 0 })
id: number; // 任务id
@prop({ required: true, default: 0 })
count: number; // 1-已达成
@prop({ required: true, default: 0 })
status: number; // 1-未领取 2-已领取
@prop({ required: true, default: 0 })
createTime: number; // 1-未领取 2-已领取
public static async findByRole(configId: number, leagueCode: string, roleId: string) {
let today = getZeroPointD();
const result: GVGUserTaskType[] = await GVGUserTaskModel.find({ configId, leagueCode, roleId, createdAt: { $gte: today } }, { _id: 0, id: 1, count: 1, status: 1 }).lean();
return result;
}
}
export const GVGUserTaskModel = getModelForClass(GVGUserTask);
export interface GVGUserTaskType extends Pick<DocumentType<GVGUserTask>, keyof GVGUserTask> {
id: number;
};
export type GVGUserTaskUpdate = Partial<GVGUserTaskType>; // 将所有字段变成可选项

View File

@@ -111,6 +111,9 @@ export default class Guild extends BaseModel {
@prop({ required: true })
sdkMark: boolean; // 37sdk标记有问题
@prop({ required: true, default: '' })
leagueCode: string; // 参与联军
public static async createGuild(params: { guildCode: string, 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, lvUpdateTime: nowSeconds() });
@@ -175,7 +178,7 @@ export default class Guild extends BaseModel {
if(serverId) condition.serverId = serverId;
const result: GuildType = await GuildModel.findOne(condition)
.select(select)
.populate('leader', {roleId: 1, roleName: 1, frame: 1, head: 1, spine: 1, frames: 1, heads: 1, spines: 1, lv: 1, quitTime: 1, ce: 1, title: 1, _id: 0}, 'Role')
.populate('leader', {roleId: 1, roleName: 1, frame: 1, head: 1, spine: 1, frames: 1, heads: 1, spines: 1, lv: 1, quitTime: 1, ce: 1, title: 1}, 'Role')
.lean({ getters: true, virtuals: true });
return result;
}
@@ -315,6 +318,41 @@ export default class Guild extends BaseModel {
const result = await GuildModel.count(searchObj);
return result;
}
public static async joinLeague(guildCode: string, leagueCode: string) {
const result: GuildType = await GuildModel.findOneAndUpdate({ code: guildCode }, { $set: { leagueCode } }, { new: true }).lean();
return result
}
public static async findGuildsForGVG(page: number, name: string, serverIds: number[]) {
let query: any = { status: GUILD_STATUS.RUNNING, lv: { $gte: 3 }, leagueCode: '', serverId: { $in: serverIds } };
if(name) {
query['name'] = { $regex: new RegExp(name, 'i') }
}
const result: GuildType[] = await GuildModel.find(query)
.populate('leader', { roleId: 1, roleName: 1, _id: 0 }, 'Role')
.skip((page - 1) * 30).limit(30)
.lean();
return result;
}
public static async findByCodes(codes: string[]) {
const result: GuildType[] = await GuildModel.find({ status: GUILD_STATUS.RUNNING, code: { $in: codes } })
.select('+serverId')
.populate('leader', { roleId: 1, roleName: 1, _id: 0 }, 'Role')
.lean();
return result;
}
public static async quitFromLeague(guildCode: string, leagueCode: string, select = null) {
const result: GuildType = await GuildModel.findOneAndUpdate({ code: guildCode, leagueCode }, { $set: { leagueCode: '' } }, { new: true }).select(select).lean();
return result;
}
public static async dissmissLeague(leagueCode: string) {
const result: GuildType = await GuildModel.findOneAndUpdate({ leagueCode }, { $set: { leagueCode: '' }}).lean();
return result;
}
}
export const GuildModel = getModelForClass(Guild);