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; } export class Quest { @prop({ required: true, default: 0 }) randomEventId: number; //问号点:随机事件id @prop({ required: true, type: Number, default: [], _id: false }) EventOptions: number[]; // 问号点用:随机事件的选项 } export class RecoveryChara { @prop({ required: true, default: '' }) charaCode: string @prop({ required: true, default: 0 }) charaId: number; // 恢复的武将 @prop({ required: true, default: 0 }) beforeHp: number; // 恢复前的hp @prop({ required: true, default: 0 }) afterHp: number; // 恢复后的hp } export class Recruit { @prop({ required: true, default: 0 }) index: number; // 索引 @prop({ required: true, default: 0 }) charaId: number; // 角色卡id @prop({ required: true, default: 0 }) status: number; // 0-未领取 1-已领取 }; export class TrainCard { @prop({ required: true, default: '' }) cardCode: string; @prop({ required: true, default: 0 }) cardId: number; // 特训的卡牌 @prop({ required: true, default: 0 }) beforeLv: number; // 特训前等级 @prop({ required: true, default: 0 }) afterLv: number; // 特训后等级 }; export class RestPoint { @prop({ required: true }) restType: number; // 休整点用:玩家选择的类型 @prop({ required: false }) recoveryCnt?: number; // 恢复的次数 @prop({ required: false, type: RecoveryChara, _id: false }) recoveryCharas?: RecoveryChara[];//恢复的数据 // @prop({ required: false, type: Recruit }) // recruits: Recruit[]; // 休整点:提供的随机可供招募的武将 @prop({ required: false }) trainCardCnt?: number; //休整点:特训 特训次数 @prop({ required: false, type: TrainCard, _id: false }) trainCards?: TrainCard[]; //特训卡 } export class Challenge { @prop({ required: true, default: 0 }) challengeId: number; // 挑战id @prop({ required: true, default: 0 }) status: number; // 0-未选择 1-已选择 2-已达成 3-已领取 @prop({ required: true, default: 0 }) progress: number; // 挑战进度 }; export class Shop { @prop({ required: true, default: 0 }) optionIndex: number; //商店物品索引 @prop({ required: true, default: 0 }) rewardType: number; //特性卡、圣物类型 @prop({ required: true, default: 0 }) rewardId: number; // 特性卡、圣物id @prop({ required: true, default: 0 }) optionStatus: number; // 0-未领取 1-已领取 @prop({ required: true, default: 0 }) price: number; // 原价 @prop({ required: true, default: 0 }) discountPrice: number; //购买时折扣价格 } export class WeightRecord { @prop({ required: false, default: 0 }) originalWight?: number; @prop({ required: false, default: 0 }) passiveRedWight?: number; @prop({ required: false, default: 0 }) holyRedWight?: number; @prop({ required: false, default: 0 }) authorAddWeight?: number; @prop({ required: false, default: 0 }) passiveLableNum?: number; @prop({ required: false, default: 0 }) passiveLableNumAddWeight?: number; @prop({ required: false, default: 0 }) holyLableNum?: number; @prop({ required: false, default: 0 }) holyLableNumAddWeight?: number; @prop({ required: false, default: 0 }) finalWeight?: number; @prop({ required: false, default: 0 }) holyAddWeight?: number; } export class RandomRec { @prop({ required: false, default: 0 }) id?: number; @prop({ required: false, default: 0 }) planId?: number; // 方案编号 @prop({ required: false, default: 0 }) cardId?: number; // 角色卡id @prop({ required: false, default: 0 }) weight?: number; // 权重 @prop({ required: false, type: WeightRecord, default: {}, _id: false }) weightRecord?: WeightRecord; } export class Option { @prop({ required: true, default: 0 }) optionIndex: number; @prop({ required: true, default: 0 }) rewardId: number; // 角色卡、特性卡、圣物id @prop({ required: true, default: 0 }) optionStatus: number; // 0-未领取 1-已领取 @prop({ required: false, type: Number, default: [], _id: false }) passiveCardIds?: number[]; //高级学员自带特性卡 // @prop({ required: false, type: WeightRecord, default: {} }) // weightRecord?: WeightRecord //用于测试权重记录 } export class RewardIn { @prop({ required: true, default: 0 }) groupIndex: number; // 组index @prop({ required: true, default: 0 }) rewardType: number; // 奖励类型 @prop({ required: false, type: Option, _id: false }) options?: Option[]; // 组内随机的奖励 @prop({ required: true, default: 0 }) groupStatus: number; // 组选择 0-未选择 1-已选择 @prop({ required: true, default: 0 }) chooseNum: number; // 这一组总共能选的数量3选2 @prop({ required: false, default: 0 }) reRandRewardCnt: number; // 重新随机奖励 } /** * 每场的每层选择的关卡的数据 */ @index({ roleId: 1 }) @index({ gameCode: 1 }) @index({ gameCode: 1, detailCode: 1 }) @index({ gameCode: 1, layer: 1, nodeId: 1 }) export default class RougelikeRecordDetail extends BaseModel { @prop({ required: true }) roleId: string; //角色id @prop({ required: true, default: '' }) gameCode: string; // 每场唯一code @prop({ required: true, default: '' }) detailCode: string; // 层+关卡id唯一code @prop({ required: true, default: 0 }) layer: number; // 层 @prop({ required: true, default: 0 }) nodeId: number; // 关卡id @prop({ required: true, default: 0 }) nodeType: number; // 关卡类型 普通关、精英关、挑战关、试炼商店、休整点、问号点、boss @prop({ required: false }) warId?: number; // 关卡id //【普通关、精英关、boss关】 @prop({ required: false }) battleCode?: string; // battleRecord的code @prop({ required: true, default: 0 }) status: number; // 关卡状态 0-默认值 1-成功 2-失败 @prop({ required: false, type: Quest, default: [], _id: false }) question?: Quest; // 问好点随机事件 @prop({ required: false, default: 0 }) questType?: number; // 问好点随机type @prop({ required: false, type: RestPoint, default: [], _id: false }) restPoints?: RestPoint[]; @prop({ required: false, type: Challenge, default: {}, _id: false }) challenge?: Challenge; // 【挑战点】 @prop({ required: false, type: Shop, default: [], _id: false }) shops?: Shop[]; // 商店内的随机商品 @prop({ required: false, type: RewardIn, default: [], _id: false }) rewards?: RewardIn[]; // 通用过关后的奖励,挑战后的奖励 @prop({ required: false, type: RandomRec, default: [], _id: false }) weightRecords?: RandomRec[]; public static async updateByCode(gameCode: string, detailCode: string, params: { $set: RougelikeRecordDetailPara, $inc?: { reRandRewardCnt: 1 } }, lean = true) { const result: RougelikeRecordDetailType = await RougelikeRecordDetailModel.findOneAndUpdate({ gameCode, detailCode }, params, { new: true, upsert: true }).lean(lean); return result; } public static async updateRewardByGroupIndex(gameCode: string, detailCode: string, groupIndex: number, groupStatus: number, options: Option[], params?: { $set: RougelikeRecordDetailPara }, lean = true) { const result: RougelikeRecordDetailType = await RougelikeRecordDetailModel.findOneAndUpdate({ gameCode, detailCode, 'rewards.groupIndex': groupIndex }, { ...params, 'rewards.$.options': options, 'rewards.$.groupStatus': groupStatus, }, { new: true, upsert: true }).lean(lean); return result; } public static async updateShopByCode(gameCode: string, detailCode: string, optionIndex: number, optionStatus: number, params?: { $set: RougelikeRecordDetailPara }, lean = true) { const result: RougelikeRecordDetailType = await RougelikeRecordDetailModel.findOneAndUpdate({ gameCode, detailCode, 'shops.optionIndex': optionIndex }, { ...params, 'shops.$.optionStatus': optionStatus }, { new: true, upsert: true }).lean(lean); return result; } public static async findByGameCode(gameCode: string, lean = true) { const result: RougelikeRecordDetailType[] = await RougelikeRecordDetailModel.find({ gameCode }).lean(lean); return result; } public static async findByCode(gameCode: string, detailCode: string, lean = true) { const result: RougelikeRecordDetailType = await RougelikeRecordDetailModel.findOne({ gameCode, detailCode }).lean(lean); return result; } public static async findByGameCodeAndLtLayer(gameCode: string, layer: number, lean = true) { const result: RougelikeRecordDetailType[] = await RougelikeRecordDetailModel.find({ gameCode, layer: { $lt: layer } }).lean(lean); return result; } public static async findByGameCodeAndLayer(gameCode: string, layer: number, lean = true) { const result: RougelikeRecordDetailType = await RougelikeRecordDetailModel.findOne({ gameCode, layer }).lean(lean); return result; } public static async bulkWriteUpdate(updateArr: RougelikeRecordDetailPara[]) { if (updateArr.length == 0) return; await RougelikeRecordDetailModel.bulkWrite(updateArr.map((param) => { const { gameCode, detailCode } = param return { updateOne: { filter: { gameCode, detailCode }, update: { $set: { ...param } }, upsert: true } } })) } }; export const RougelikeRecordDetailModel = getModelForClass(RougelikeRecordDetail); export interface RougelikeRecordDetailType extends Pick, keyof RougelikeRecordDetail> { }; export type RougelikeRecordDetailPara = Partial; // 将所有字段变成可选项