import BaseModel from './BaseModel'; import { getModelForClass, prop, DocumentType, index } from '@typegoose/typegoose'; export class Node { @prop({ required: true, default: '' }) detailCode: string; @prop({ required: true, default: 0 }) index: number; // 索引 @prop({ required: true, default: 0 }) nodeId: number; // 关卡id @prop({ required: true, type: Number, default: [], _id: false }) preNodeIndexs: number[]; // 连线的关卡,填上一层节点的索引 @prop({ required: true, default: 0 }) type: number; // 类型 @prop({ required: true, default: 0 }) isChoose: number; // 玩家选择 0-未选择,1-选择 } /** * 每场的每层数据 */ @index({ roleId: 1 }) @index({ gameCode: 1 }) @index({ gameCode: 1, layer: 1 }) @index({ gameCode: 1, hasPass: 1 }) export default class RougelikeLayer extends BaseModel { @prop({ required: true }) roleId: string; @prop({ required: true, default: '' }) gameCode: string; // 每场唯一code @prop({ required: true, default: 0 }) layer: number; // 第几层 @prop({ required: true, type: Node, default: [], _id: false }) layerNodes: Node[]; // 地图随机到的各种关卡,用于画图 @prop({ required: true, default: false }) hasPass: boolean; public static async updateByGameCode(gameCode: string, layer: number, params: { $set: RougelikeLayerPara }, lean = true) { const result: RougelikeLayerType[] = await RougelikeLayerModel.findOneAndUpdate({ gameCode, layer }, params, { new: true, upsert: true }).lean(lean); return result; } public static async updateByGameCodeAndLayer(gameCode: string, layer: number, detailCode: string, isChoose: number, params?: { $set?: RougelikeLayerPara }, lean = true) { const result: RougelikeLayerType[] = await RougelikeLayerModel.findOneAndUpdate({ gameCode, layer, 'layerNodes.detailCode': detailCode }, { ...params, 'layerNodes.$.isChoose': isChoose }, { new: true, upsert: true }).lean(lean); return result; } public static async bulkWriteUpdate(updateArr: { gameCode: string, roleId: string, layer: number, layerNodes: Node[] }[]) { if (updateArr.length == 0) return; await RougelikeLayerModel.bulkWrite(updateArr.map(({ gameCode, roleId, layer, layerNodes }) => { return { updateOne: { filter: { gameCode, roleId, layer }, update: { $set: { layerNodes } }, upsert: true } } })) } public static async findByGameCode(gameCode: string, lean = true) { const result: RougelikeLayerType[] = await RougelikeLayerModel.find({ gameCode }).lean(lean); return result; } public static async findByGameCodeAndLayer(gameCode: string, layer: number, lean = true) { const result: RougelikeLayerType = await RougelikeLayerModel.findOne({ gameCode, layer }).lean(lean); return result; } public static async findByGameCodeAndLayers(gameCode: string, layers: number[], lean = true) { const result: RougelikeLayerType[] = await RougelikeLayerModel.find({ gameCode, layer: { $in: layers } }).lean(lean); return result; } public static async findByGameCodeAndHasPass(gameCode: string, hasPass: boolean, lean = true) { const result: RougelikeLayerType[] = await RougelikeLayerModel.find({ gameCode, hasPass }).lean(lean); return result; } }; export const RougelikeLayerModel = getModelForClass(RougelikeLayer); export interface RougelikeLayerType extends Pick, keyof RougelikeLayer> { }; export type RougelikeLayerPara = Partial; // 将所有字段变成可选项