91 lines
3.6 KiB
TypeScript
91 lines
3.6 KiB
TypeScript
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: [] })
|
||
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<DocumentType<RougelikeLayer>, keyof RougelikeLayer> { };
|
||
export type RougelikeLayerPara = Partial<RougelikeLayerType>; // 将所有字段变成可选项
|