import BaseModel from './BaseModel'; import { getModelForClass, prop, DocumentType, index } from '@typegoose/typegoose'; import { getZeroPointD } from '../pubUtils/timeUtil'; import { SHOP_REFRESH_TYPE } from '../consts'; @index({ roleId: 1, refTime: 1 }) @index({ refTime: 1, receiveNum: 1 }) export default class RougelikeScore extends BaseModel { @prop({ required: true }) roleId: string; @prop({ required: true, default: new Date() }) refTime: Date; // 每周刷新奖励 @prop({ required: true, default: 0 }) score: number; // 积分 @prop({ required: true, type: Number, default: [], _id: false }) received: number[]; // 已领取的id @prop({ required: true, default: 0 }) receiveNum: number; // 已领取的id @prop({ required: true, default: 0 }) takeoutRewardCnt: number; // 额外奖励已领取的次数(每日) @prop({ required: true, default: () => new Date() }) refDaily: Date; public static async findByRoleId(roleId: string) { let refTime = getZeroPointD(SHOP_REFRESH_TYPE.WEEKLY); let result: RougelikeScoreType = await RougelikeScoreModel.findOne({ roleId, refTime }).lean(); let today = getZeroPointD(); if (result && result.refDaily) { let newResult = await RougelikeScoreModel.findOneAndUpdate({ roleId, refTime, refDaily: { $lt: today } }, { $set: { takeoutRewardCnt: 0, refDaily: new Date() }, $setOnInsert: { received: [], receiveNum: 0, score: 0 } }, { new: true }).lean(); if (newResult) return newResult; } return result; } public static async incScore(roleId: string, score: number) { let refTime = getZeroPointD(SHOP_REFRESH_TYPE.WEEKLY); let result: RougelikeScoreType = await RougelikeScoreModel.findOneAndUpdate({ roleId, refTime }, { $inc: { score }, $setOnInsert: { received: [], receiveNum: 0, takeoutRewardCnt: 0, refDaily: new Date() } }, { new: true, upsert: true }).lean(); return result; } public static async receive(roleId: string, targetScore: number, index: number) { let refTime = getZeroPointD(SHOP_REFRESH_TYPE.WEEKLY); let result: RougelikeScoreType = await RougelikeScoreModel.findOneAndUpdate({ roleId, refTime, score: { $gte: targetScore } }, { $push: { received: index }, $inc: { receiveNum: 1 } }, { new: true }).lean(); return result; } public static async findByReceiveNum(refTime: Date, maxNum: number) { let result: RougelikeScoreType[] = await RougelikeScoreModel.find({ refTime, receiveNum: { $lt: maxNum } }).lean(); return result; } public static async findByRefTime(refTime: Date) { let result: RougelikeScoreType[] = await RougelikeScoreModel.find({ refTime }).lean(); return result; } public static async receiveAll(_ids: string[], maxNum: number) { await RougelikeScoreModel.updateMany({ _id: { $in: _ids } }, { $set: { receiveNum: maxNum } }); } public static async receiveTakeoutReward(roleId: string, maxNum: number, refDaily = new Date()) { let refTime = getZeroPointD(SHOP_REFRESH_TYPE.WEEKLY); // await RougelikeScoreModel.findOneAndUpdate({ roleId, refTime }, { $setOnInsert: { score: 0, received: [], receiveNum: 0, takeoutRewardCnt: 0, refDaily } }, { upsert: true }); await this.findByRoleId(roleId); let result: RougelikeScoreType = await RougelikeScoreModel.findOneAndUpdate({ roleId, refTime, takeoutRewardCnt: { $lt: maxNum } }, { $set: { refDaily }, $inc: { takeoutRewardCnt: 1 } }, { new: true }).lean(); return result; } public static async bulkWriteUpdate(updateArr: RougelikeScorePara[]) { if (updateArr.length == 0) return; await RougelikeScoreModel.bulkWrite(updateArr.map((param) => { delete param._id; const { roleId, refTime } = param return { updateOne: { filter: { roleId, refTime }, update: { $set: { ...param } }, upsert: true } } })) } } export const RougelikeScoreModel = getModelForClass(RougelikeScore); export interface RougelikeScoreType extends Pick, keyof RougelikeScore> { }; export type RougelikeScorePara = Partial; // 将所有字段变成可选项