import BaseModel from './BaseModel'; import { index, getModelForClass, prop, DocumentType } from '@typegoose/typegoose'; import { DAY_TO_SECOND, getZeroPoint } from '../pubUtils/timeUtil'; @index({ day: 1, groupKey: 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 }) groupKey: string; // 1-单服 2-跨服 @prop({ required: true }) score: number; // 得分 @prop({ required: true }) rank: number; // 最后的排名,每天22点定格 @prop({ required: true, type: String }) receiveMembers: string[]; // 是否领取过 public static async incScore(configId: number, leagueCode: string, groupKey: string, inc: number) { let today = getZeroPoint(); let result: GVGVestigeLeagueRankType = await GVGVestigeLeagueRankModel.findOneAndUpdate({ day: today, groupKey, leagueCode }, { $inc: { score: inc }, $set: { configId }, $setOnInsert: { rank: 0, receiveMembers: [] } }, { new: true, upsert: true }).lean(); return result; } // 排行榜 public static async findRank(): Promise<{ _id: string, arr: { leagueCode: string, score: number, updatedAt: Date }[], leagueCodes: string[] }[]> { let today = getZeroPoint(); let ranks = await GVGVestigeLeagueRankModel.aggregate([ { $match: { day: today } }, { $group: { _id: "$groupKey", arr: { $push: { leagueCode: "$leagueCode", score: "$score", updatedAt: "$updatedAt" } }, leagueCodes: { $addToSet: "$leagueCode" } }}, ]); return ranks; } public static async saveRank(groupKey: string, ranks: { rank: number, field: string }[]) { let today = getZeroPoint(); await GVGVestigeLeagueRankModel.bulkWrite(ranks.map(({ field, rank }) => { return { updateOne: { filter: { day: today, groupKey, 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, roleId: string) { let result: GVGVestigeLeagueRankType[] = await GVGVestigeLeagueRankModel.find({ configId, leagueCode, rank: { $gt: 0 }, receiveMembers: { $nin: [roleId] } }).lean(); return result; } public static async receiveRanks(_ids: string[], roleId: string) { await GVGVestigeLeagueRankModel.updateMany({ _id: { $in: _ids } }, { $push: { receiveMembers: roleId } }); } public static async receiveManyRanks(arr: { _id: string, roleIds: string[]}[]) { await GVGVestigeLeagueRankModel.bulkWrite(arr.map(({ _id, roleIds}) => { return { updateOne: { filter: { _id }, update: { $push: { receiveMembers: roleIds } } } } })); } public static async getAllCanReceiveRanks(configId: number, leagueCodes: string[]) { let result: GVGVestigeLeagueRankType[] = await GVGVestigeLeagueRankModel.find({ configId, rank: { $gt: 0 }, leagueCode: { $in: leagueCodes } }).lean(); return result; } } export const GVGVestigeLeagueRankModel = getModelForClass(GVGVestigeLeagueRank); export interface GVGVestigeLeagueRankType extends Pick, keyof GVGVestigeLeagueRank> {}; export type GVGVestigeLeagueRankUpdate = Partial; // 将所有字段变成可选项