import { SHOP_REFRESH_TYPE } from '../consts'; import { getZeroPointOfTimeD } from '../pubUtils/timeUtil'; import BaseModel from './BaseModel'; import { getModelForClass, prop, DocumentType, index } from '@typegoose/typegoose'; export class RewardInter { @prop({ required: true }) id: number; @prop({ required: true }) count: number; @prop({ required: true }) expireTime?: number; } /** * 每场获得的圣物&特性卡 */ @index({ roleId: 1 }) @index({ gameCode: 1 }) @index({ roleId: 1, status: 1 }) export default class RougelikeRecord extends BaseModel { @prop({ required: true }) roleId: string; // 角色id @prop({ required: true, default: '' }) gameCode: string; // 每场唯一code @prop({ required: true, default: 0 }) grade: number; // 难度 @prop({ required: true, default: 0 }) type: number; // 试炼类型 @prop({ required: true, default: 0 }) authorType: number; // 流派类型 @prop({ required: true, default: 0 }) maxLayer: number; // 总共多少层 @prop({ required: true, default: 0 }) curLayer: number; // 当前在第几层 @prop({ required: true, default: 0 }) status: number; // 0-选角色卡, 1-进行中 2-已达成 @prop({ required: true, default: 0 }) score: number; // 本场获得的积分 @prop({ required: true, type: RewardInter, default: [], _id: false }) takeoutReward: RewardInter[]; // 本场获得了的奖励(灵石,记录一下)id&count @prop({ required: true, default: false }) hasReceivedTakeout: boolean; // 是否已带出 @prop({ required: true, default: 0 }) coin: number; // 试炼币 @prop({ required: true, default: 0 }) coinTotal: number; // 试炼币累计值 @prop({ required: true, default: 0 }) techScore: number; // 科技分 // public static async updateByGameCode(gameCode: string, params: { $set: RougelikeRecordPara, $inc?: { coin?: number, score?: number, techScore?: number } }, lean = true) { // let doc = new RougelikeRecordModel(); // let insert = Object.assign(doc); // for (let key in params.$inc) { // if (insert[key] != undefined) delete insert[key]; // } // for (let key in params.$set) { // if (insert[key] != undefined) delete insert[key]; // } // const result: RougelikeRecordType = await RougelikeRecordModel.findOneAndUpdate({ gameCode }, { $setOnInsert: insert, ...params }, { new: true, upsert: true }).lean(lean); // return result; // } public static async updateByGameCode(gameCode: string, params: { $set?: RougelikeRecordPara, $inc?: { coin?: number, coinTotal?: number, score?: number, techScore?: number } }, lean = true) { const result: RougelikeRecordType = await RougelikeRecordModel.findOneAndUpdate({ gameCode }, params, { new: true, upsert: true }).lean(lean); return result; } public static async findByGameCode(gameCode: string, lean = true) { const result: RougelikeRecordType = await RougelikeRecordModel.findOne({ gameCode }).lean(lean); return result; } public static async findByRoleIdAndStatus(roleId: string, status: number, lean = true) { const result: RougelikeRecordType = await RougelikeRecordModel.findOne({ roleId, status: { $lt: status } }).lean(lean); return result; } public static async takeout(gameCode: string) { const result: RougelikeRecordType = await RougelikeRecordModel.findOneAndUpdate({ gameCode }, { $set: { hasReceivedTakeout: true } }, { new: true }).lean(); return result; } public static async costCoin(gameCode: string, costCoin: number) { const result: RougelikeRecordType = await RougelikeRecordModel.findOneAndUpdate({ gameCode, coin: { $gte: costCoin } }, { $inc: { coin: -costCoin } }, { new: true }).lean(); return result; } public static async getLastMaxLv(roleId: string) { let endTime = getZeroPointOfTimeD(Date.now() - 86400000, SHOP_REFRESH_TYPE.WEEKLY); let startTime = new Date(endTime.getTime() - (86400000 * 7)); const result: RougelikeRecordType[] = await RougelikeRecordModel.find({ roleId, updatedAt: { $gt: startTime, $lt: endTime } }).lean(true); let lastMaxLv = 1; for (const { grade = 1 } of result) { lastMaxLv = Math.max(lastMaxLv, grade); } return lastMaxLv; } public static async getLastMaxLvMap(roleIds: string[]) { let endTime = getZeroPointOfTimeD(Date.now() - 86400000, SHOP_REFRESH_TYPE.WEEKLY); let startTime = new Date(endTime.getTime() - (86400000 * 7)); const result: RougelikeRecordType[] = await RougelikeRecordModel.find({ roleId: { $in: roleIds }, updatedAt: { $gt: startTime, $lt: endTime } }).lean(true); let lastMaxLvMap = new Map(); for (const { roleId, grade } of result) { if (!grade) continue; let tempLv = lastMaxLvMap.has(roleId) ? lastMaxLvMap.get(roleId) : 1; lastMaxLvMap.set(roleId, Math.max(tempLv, grade)); } return lastMaxLvMap; } }; export const RougelikeRecordModel = getModelForClass(RougelikeRecord); export interface RougelikeRecordType extends Pick, keyof RougelikeRecord> { }; export type RougelikeRecordPara = Partial; // 将所有字段变成可选项