feat(gvg): 征战中原排行榜奖励

This commit is contained in:
luying
2023-02-04 12:08:29 +08:00
parent fc2a86ad81
commit eb772484c2
21 changed files with 678 additions and 100 deletions

View File

@@ -109,7 +109,7 @@ export default class GVGLeague extends BaseModel {
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')
.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
}

View File

@@ -139,7 +139,7 @@ export default class GVGLeagueFarm extends BaseModel {
public static async lockMineOrForestry(configId: number, leagueCode: string, farmId: number, type: number, roleId: string, fieldId: number, itemId: number) {
// 先创建
await GVGLeagueFarmModel.findOneAndUpdate({ configId, leagueCode, farmId, fieldId }, { $setOnInsert: { unlockTime: 0, itemId: 0, type } }, { upsert: true });
let unlockTime = nowSeconds() + type == GVG_RESOURCE_TYPE.MINERAL? GVG.GVG_MINE_LOCK_TIME: GVG.GVG_FORESTRY_LOCK_TIME;
let unlockTime = nowSeconds() + (type == GVG_RESOURCE_TYPE.MINERAL? GVG.GVG_MINE_LOCK_TIME: GVG.GVG_FORESTRY_LOCK_TIME);
const result: GVGLeagueFarmType = await GVGLeagueFarmModel.findOneAndUpdate(
{ configId, leagueCode, farmId, fieldId, $or:[{ unlockTime: { $lt: nowSeconds() } }, {lockRoleId: roleId}] },
{ $set: { unlockTime, lockRoleId: roleId, itemId } },

View File

@@ -0,0 +1,80 @@
import BaseModel from './BaseModel';
import { index, getModelForClass, prop, DocumentType } from '@typegoose/typegoose';
import { DAY_TO_SECOND, getZeroPoint } from '../pubUtils/timeUtil';
@index({ day: 1, groupId: 1, serverType: 1, score: 1 })
@index({ leagueCode: 1 })
export default class GVGVestigeLeagueRank extends BaseModel {
@prop({ required: true })
configId: number; // 赛期
@prop({ required: true })
day: number; // 每天5点
@prop({ required: true })
leagueCode: string; // 玩家id
@prop({ required: true })
groupId: number; // 战区id
@prop({ required: true })
serverType: number; // 1-单服 2-跨服
@prop({ required: true })
score: number; // 得分
@prop({ required: true })
rank: number; // 最后的排名每天22点定格
@prop({ required: true })
isReceived: boolean; // 是否领取过
public static async incScore(configId: number, leagueCode: string, groupId: number, serverType: number, inc: number) {
let today = getZeroPoint();
let result: GVGVestigeLeagueRankType = await GVGVestigeLeagueRankModel.findOneAndUpdate({
day: today, groupId, serverType, leagueCode
}, { $inc: { score: inc }, $set: { configId }, $setOnInsert: { rank: 0, isReceived: false } }, { new: true, upsert: true }).lean();
return result;
}
// 排行榜
public static async findRank(): Promise<{ _id: { groupId: number, serverType: number }, arr: { leagueCode: string, score: number, updatedAt: Date }[], leagueCodes: string[] }[]> {
let today = getZeroPoint();
let ranks = await GVGVestigeLeagueRankModel.aggregate([
{ $match: { day: today } },
{ $group: {
_id: { groupId: "$groupId", serverType: "$serverType" },
arr: { $push: { leagueCode: "$leagueCode", score: "$score", updatedAt: "$updatedAt" } }, leagueCodes: { $addToSet: "$leagueCode" }
}},
]);
return ranks;
}
public static async saveRank(groupId: number, serverType: number, ranks: { rank: number, field: string }[]) {
let today = getZeroPoint();
await GVGVestigeLeagueRankModel.bulkWrite(ranks.map(({ field, rank }) => {
return { updateOne: { filter: { day: today, groupId, serverType, leagueCode: field }, update: { $set: { rank } }} }
}));
}
public static async getYesterdayRank(leagueCode: string) {
let yesterday = getZeroPoint() - DAY_TO_SECOND;
let result: GVGVestigeLeagueRankType = await GVGVestigeLeagueRankModel.findOne({ day: yesterday, leagueCode }).lean();
return result;
}
public static async getCanReceiveRanks(configId: number, leagueCode: string) {
let result: GVGVestigeLeagueRankType[] = await GVGVestigeLeagueRankModel.find({ configId, leagueCode, rank: { $gt: 0 }, isReceived: false }).lean();
return result;
}
public static async receiveRanks(_ids: string[]) {
await GVGVestigeLeagueRankModel.updateMany({ _id: { $in: _ids } }, { $set: { isReceived: true } });
}
}
export const GVGVestigeLeagueRankModel = getModelForClass(GVGVestigeLeagueRank);
export interface GVGVestigeLeagueRankType extends Pick<DocumentType<GVGVestigeLeagueRank>, keyof GVGVestigeLeagueRank> {};
export type GVGVestigeLeagueRankUpdate = Partial<GVGVestigeLeagueRankType>; // 将所有字段变成可选项

View File

@@ -1,6 +1,6 @@
import BaseModel from './BaseModel';
import { index, getModelForClass, prop, DocumentType, mongoose, Ref } from '@typegoose/typegoose';
import Role, { RoleType } from './Role';
import { index, getModelForClass, prop, DocumentType, mongoose } from '@typegoose/typegoose';
import { RoleType } from './Role';
import { getZeroPoint } from '../pubUtils/timeUtil';
export class Lineup {
@@ -36,6 +36,9 @@ export default class GVGVestigeRank extends BaseModel {
@prop({ required: true })
roleId: string; // 玩家
@prop({ required: true })
leagueCode: string; // 联军
@prop({ required: true, default: 0 })
rank: number; // 排名
@@ -75,10 +78,10 @@ export default class GVGVestigeRank extends BaseModel {
return result;
}
public static async initRank(configId: number, vestigeId: number, groupId: number, serverType: number, role: RoleType, oppRanks: number[]) {
public static async initRank(configId: number, vestigeId: number, groupId: number, serverType: number, role: RoleType, leagueCode: string, oppRanks: number[]) {
let today = getZeroPoint();
let doc = new GVGVestigeRankModel();
let update = Object.assign(doc.toJSON(), { role: role._id, configId, groupId, serverType, oppRanks });
let update = Object.assign(doc.toJSON(), { role: role._id, configId, groupId, serverType, oppRanks, leagueCode });
let result: GVGVestigeRankType = await GVGVestigeRankModel.findOneAndUpdate({ day: today, vestigeId, roleId: role.roleId }, { $setOnInsert: update }, { new: true, upsert: true }).lean();
return result;
}
@@ -153,10 +156,9 @@ export default class GVGVestigeRank extends BaseModel {
return ranks;
}
public static async findRankByVestige(groupId: number, serverType: number, vestigeId: number) {
let today = getZeroPoint();
let result: GVGVestigeRankType[] = await GVGVestigeRankModel.find({ day: today, vestigeId, groupId, serverType }).sort({ rank: 1 }).select('roleId rank lineup').lean();
let result: GVGVestigeRankType[] = await GVGVestigeRankModel.find({ day: today, vestigeId, groupId, serverType, rank: { $gt: 0 } }).sort({ rank: 1 }).select('roleId rank lineup').lean();
return result;
}
}

View File

@@ -32,6 +32,9 @@ export default class GVGVestigeRec extends BaseModel {
@prop({ required: true })
defenseRoleId: string; // 守方玩家id
@prop({ required: true })
configId: number; // 赛期
@prop({ required: true })
groupId: number; // 战区id
@@ -65,7 +68,7 @@ export default class GVGVestigeRec extends BaseModel {
@prop({ required: true, default: false })
hasRpl: boolean; // 是否存在对应录像
public static async createRec(configId: number, vestigeId: number, groupId: number, serverType: number, warId: number, attackInfo: OppPlayerInfo, defenseInfo: OppPlayerInfo, leagueGoods: LeagueGood[]) {
public static async createRec(configId: number, vestigeId: number, groupId: number, serverType: number, warId: number, attackInfo: OppPlayerInfo, defenseInfo: OppPlayerInfo, leagueGoods: LeagueGood[]) {
const battleCode = genCode(10);
const result: GVGVestigeRecType = await GVGVestigeRecModel.findOneAndUpdate({ battleCode }, {
$set: { configId, vestigeId, groupId, serverType, attackRoleId: attackInfo.roleId, defenseRoleId: defenseInfo.roleId, warId, checkTime: Date.now(), attackInfo, defenseInfo, leagueGoods }

View File

@@ -0,0 +1,49 @@
import BaseModel from './BaseModel';
import { index, getModelForClass, prop, DocumentType } from '@typegoose/typegoose';
import { getZeroPoint } from '../pubUtils/timeUtil';
@index({ day: 1, groupId: 1, serverType: 1, score: 1 })
@index({ roleId: 1 })
export default class GVGVestigeSumRank extends BaseModel {
@prop({ required: true })
day: number; // 每天5点
@prop({ required: true })
roleId: string; // 玩家id
@prop({ required: true })
groupId: number; // 战区id
@prop({ required: true })
serverType: number; // 1-单服 2-跨服
@prop({ required: true })
score: number; // 得分
public static async incScore(roleId: string, groupId: number, serverType: number, inc: number) {
let today = getZeroPoint();
let result: GVGVestigeSumRankType = await GVGVestigeSumRankModel.findOneAndUpdate({
day: today, groupId, serverType, roleId
}, { $inc: { score: inc } }, { new: true, upsert: true }).lean();
return result;
}
// 排行榜
public static async findRank(): Promise<{ _id: { groupId: number, serverType: number }, arr: { roleId: string, score: number, updatedAt: Date }[], roleIds: string[] }[]> {
let today = getZeroPoint();
let ranks = await GVGVestigeSumRankModel.aggregate([
{ $match: { day: today } },
{ $group: {
_id: { groupId: "$groupId", serverType: "$serverType" },
arr: { $push: { roleId: "$roleId", score: "$score", updatedAt: "$updatedAt" } }, roleIds: { $addToSet: "$roleId" }
}},
]);
return ranks;
}
}
export const GVGVestigeSumRankModel = getModelForClass(GVGVestigeSumRank);
export interface GVGVestigeSumRankType extends Pick<DocumentType<GVGVestigeSumRank>, keyof GVGVestigeSumRank> {};
export type GVGVestigeSumRankUpdate = Partial<GVGVestigeSumRankType>; // 将所有字段变成可选项