import BaseModel from './BaseModel'; import { index, getModelForClass, prop, DocumentType, modelOptions } from '@typegoose/typegoose'; // import { COUNTER } from '../consts'; // import { CounterModel } from './Counter'; import { SearchJewelParam } from '../domain/backEndField/search'; import { RoleModel } from './Role'; import { CounterModel } from './Counter'; import { COUNTER } from '../consts'; import { HeroModel } from './Hero'; export class JewelSe { @prop({ required: true }) id: number; // 随机属性位置id @prop({ required: true }) seid: number; // 随机属性池id @prop({ required: true }) rand: number; // 随机属性内需要随机的值 constructor(id: number, seid: number, rand: number) { this.id = id; this.seid = seid; this.rand = rand; } } export class RandSe extends JewelSe { @prop({ required: true }) preRand?: number; // 淬炼失败的是随机出的值 @prop({ required: true }) locked: boolean = false; // 洗炼是否锁定 @prop({ required: false, default: false }) quenched: boolean = false; // 是否淬炼了 @prop({ required: false, default: 0 }) quenchCnt: number = 0; // 淬炼次数 } @index({ roleId: 1, hid: 1, id: 1 }) @index({ seqId: 1 }) @modelOptions({ schemaOptions: { id: false } }) export default class Jewel extends BaseModel { @prop({ required: true }) roleId: string; // 角色 id @prop({ required: true }) roleName: string; // 角色名称 @prop({ required: true }) seqId: number; // 装备表自增 id @prop({ required: true }) id: number; // 装备 id @prop({ required: true }) name: string; // 装备名称 @prop({ required: false, default: 0 }) hid: number; // 装备此装备的武将 id @prop({ required: false, default: 0 }) ePlaceId: number; // 武将装备的部位 @prop({ required: false, type: JewelSe, default: [], _id: false }) rareSe: JewelSe[]; // 强化随机属性 @prop({ required: false, type: RandSe, default: [], _id: false }) randSe: RandSe[]; // 强化随机属性 @prop({ required: false, type: RandSe, default: [], _id: false }) previewRandSe: RandSe[]; // 强化随机属性预览 public static async findbyRole(roleId: string, select = '') { const jewels: JewelType[] = await JewelModel.find({ roleId }).select(select).lean(); return jewels; } public static async findbyRoleAndHids(roleId: string, hids: number[]) { const jewels: JewelType[] = await JewelModel.find({ roleId, hid: { $in: hids } }).lean(); return jewels; } public static async findMapbyRoleAndHids(roleId: string, hids: number[]) { const jewels = await JewelModel.findbyRoleAndHids(roleId, hids); let map = new Map(); for(let jewel of jewels) { map.set(jewel.seqId, jewel); } return map; } public static async findbySeqId(seqId: number, select?: string ) { const jewel: JewelType = await JewelModel.findOne({ seqId }).select(select).lean(); return jewel; } public static async findbySeqIds(seqIds: number[], select?: string ) { const jewel: JewelType[] = await JewelModel.find({ seqId: { $in: seqIds } }).select(select).lean(); return jewel; } public static async createJewel(jewelInfo: jewelUpdate) { const seqId = await CounterModel.getNewCounter(COUNTER.JEWEL_ID); const doc = new JewelModel(); const update = Object.assign(doc.toJSON(), seqId, jewelInfo); delete update._id; const jewel: JewelType = await JewelModel.findOneAndUpdate({ seqId }, update, { upsert: true, new: true }).lean(); if (jewelInfo.hid > 0) { await HeroModel.findOneAndUpdate( { roleId: jewelInfo.roleId, hid: jewelInfo.hid, 'ePlace.id': jewelInfo.ePlaceId }, { $set: { 'ePlace.$.jewel': seqId } }, { new: true }).lean(); } return jewel; } public static async createJewels(roleId: string, jewelInfos: jewelUpdate[]) { let result: JewelType[] = []; for(let jewelInfo of jewelInfos) { let jewel = await this.createJewel(jewelInfo); result.push(jewel); } await RoleModel.increaseJewel(roleId, result.length); return result; } public static async putOnOrOff(seqId: number, hid: number, ePlaceId: number) { let rec: JewelType = await JewelModel.findOneAndUpdate({ seqId }, { $set: { hid, ePlaceId } }, { new: true }).lean(); return rec; } public static async lock(seqId: number, id: number, lock: boolean) { let result: JewelType = await JewelModel.findOneAndUpdate({ seqId, 'randSe.id': id }, { $set: { 'randSe.$.locked': lock } }, { new: true }).select('seqId id randSe').lean(); return result; } public static async chooseQuench(seqId: number, id: number) { let result: JewelType = await JewelModel.findOneAndUpdate({ seqId, 'randSe.id': id }, { $set: { 'randSe.$.quenched': true } }, { new: true }).lean(); return result; } public static async quench(seqId: number, isSuccess: boolean, rand: number) { if(isSuccess) { let result: JewelType = await JewelModel.findOneAndUpdate({ seqId, 'randSe.quenched': true }, { $set: { 'randSe.$.rand': rand } }, { new: true }).lean(); return result; } else { let result: JewelType = await JewelModel.findOneAndUpdate({ seqId, 'randSe.quenched': true }, { $inc: { 'randSe.$.quenchCnt': 1 }, $set: { 'randSe.$.preRand': rand } }, { new: true }).lean(); return result; } } public static async updateInfo(seqId: number, update: jewelUpdate) { let result: JewelType = await JewelModel.findOneAndUpdate({ seqId }, { $set: update }, {new: true}).lean(); return result; } public static async deleteBySeqIds(roleId: string, seqIds: number[]) { let jewels = await JewelModel.findbySeqIds(seqIds); await JewelModel.deleteMany({ roleId, seqId: { $in: seqIds } }); await RoleModel.increaseJewel(roleId, -1 * seqIds.length); return jewels; } public static async deleteAccount(roleId: string) { let result = await JewelModel.deleteMany({ roleId }); return result; } private static getSearchObj(form: SearchJewelParam) { let searchObj = {}; if(form.roleId) searchObj['roleId'] = form.roleId; if(form.roleName) searchObj['roleName'] = { $regex: new RegExp(form.roleName.toString(), 'i') }; if(form.id) searchObj['id'] = form.id; return searchObj } public static async findByCondition(page: number, pageSize: number, sortField: string = 'updatedAt', sortOrder: string = 'descend', form: SearchJewelParam = {}) { let searchObj = this.getSearchObj(form); let sort = {}; if(sortField && sortOrder) { if(sortOrder == 'ascend') { sort[sortField] = 1; } else if (sortOrder == 'descend') { sort[sortField] = -1; } } const result: JewelType[] = await JewelModel.find(searchObj).limit(pageSize).skip((page - 1) * pageSize).sort(sort).lean({ getters: true, virtuals: true }); return result; } public static async countByCondition(form: SearchJewelParam = {}) { let searchObj = this.getSearchObj(form); const result = await JewelModel.count(searchObj); return result; } } export const JewelModel = getModelForClass(Jewel); export interface JewelType extends Pick, keyof Jewel> { id: number; }; export type jewelUpdate = Partial; // 将所有字段变成可选项