Files
ZYZ/shared/db/Jewel.ts
2022-10-24 18:46:24 +08:00

200 lines
7.8 KiB
TypeScript

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, 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<number, JewelType>();
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<DocumentType<Jewel>, keyof Jewel> {
id: number;
};
export type jewelUpdate = Partial<JewelType>; // 将所有字段变成可选项