import BaseModel from './BaseModel'; import { index, getModelForClass, prop, Ref, mongoose } from '@typegoose/typegoose'; import Equip from './Equip'; import { updateCe } from '../pubUtils/util'; /** * 英雄表 */ @index({ roleId: 1, hid: 1 }) @index({ roleId: 1, seqId: 1 }) export default class Hero extends BaseModel { @prop({ required: true }) roleId: string; // 角色 id @prop({ required: true }) roleName: string; // 角色名称 @prop({ required: true }) serverId: number; // 区服 id @prop({ required: true }) hid: number; // 武将 id @prop({ required: true }) hName: string; // 武将名 @prop({ required: true }) seqId: number; // 武将表自增 id @prop({ required: true, default: 0 }) exp: number; // 经验值 @prop({ required: true, default: 1 }) lv: number; // 武将等级 @prop({ required: true, default: 0 }) ce: number; // 武将战力 @prop({ required: true, default: 0 }) historyCe: number; // 武将历史最高战力 @prop({ required: true, default: 0 }) star: number; // 星级 @prop({ required: true, default: 0 }) fire: number; // 觉醒的火,在满星了之后会继续进行觉醒,显示类似6星1火 @prop({ required: true, default: 1 }) rank: number; // 阶数 @prop({ required: true, default: 0 }) favour: number; // 好感度 @prop({ required: true, default: 1 }) favourLv: number; // 好感等级 @prop({ required: true, default: [] }) conections: [{ // 羁绊 id: number; // 羁绊编号 name: string; // 羁绊名称 valid: boolean; // 是否开启 }]; @prop({ required: true, default: [] }) skins: [{ // 皮肤 id: number; // id enable: boolean; // 是否装备 }] @prop({ ref: Equip, type: mongoose.Schema.Types.ObjectId }) equips: Ref[]; // 武将装备引用数组 public static async findByRole(roleId: string, lean = true) { const heros = await HeroModel.find({ roleId }).populate('equips').lean(lean); return heros || []; } public static async findBySeqIdRange(seqIds: Array, roleId: string, lean = true) { const hero = await HeroModel.find({ seqId: {$in: seqIds}, roleId }).lean(lean); return hero; } public static async findBySeqIdAndRole(seqId: number, roleId: string, lean = true) { const hero = await HeroModel.findOne({ seqId, roleId }).lean(lean); return hero; } public static async findByHidAndRole(hid: number, roleId: string, lean = true) { const hero = await HeroModel.findOne({ hid, roleId }).lean(lean); return hero; } public static async addEquip(roleId: string, hid: number, equipId: string, lean = true) { const hero = await HeroModel.findOneAndUpdate({ roleId, hid }, {$push: {equips: equipId}}, {new: true}).lean(lean); if (hero) { await Equip.putOn(hero.hid, equipId); await updateCe(roleId, hero ) } return hero; } public static async createHero(heroInfo: {roleId: string, roleName: string, hid: number, star: number, hName: string, seqId: number, lv?:number, ce: number}, lean = true) { const doc = new HeroModel(); const update = Object.assign(doc.toJSON(), heroInfo); delete update._id; const hero = await HeroModel.findOneAndUpdate({roleId: heroInfo.roleId, hid: heroInfo.hid}, update, {upsert: true, new: true}).lean(lean); await updateCe(heroInfo.roleId, hero); return hero; } public static async sumTopHeroCe(roleId: string, num: number) { let ce = await HeroModel.aggregate([ { $match : { roleId } }, { $sort: {historyCe: -1} }, { $limit: num }, { $group: { _id: null, historyCe: { $sum: '$historyCe' } } } ]); return ce.length > 0?ce[0].historyCe:0; } public static async sumHeroCe(roleId: string) { let ce = await HeroModel.aggregate([ { $match : { roleId } }, { $group: { _id: null, ce: { $sum: '$ce' } } } ]); return ce.length > 0?ce[0].ce:0; } public static async getTopHero(roleId: string, num: number, lean = true) { const heroes = await HeroModel.find({roleId}).limit(num).sort({ce: -1}).lean(lean); return heroes; } public static async updateCe(roleId: string, hid: number, ce: number, oldCe: number, historyCe: number, lean = true) { let distance = ce - oldCe; let historyDistance = ce > historyCe ?ce - historyCe: 0; let result = await HeroModel.findOneAndUpdate({roleId, hid}, {$inc:{ce: distance, historyCe: historyDistance}}).lean(lean); return result||{}; } public static async deleteAccount(roleId: string, lean = true) { let result = await HeroModel.deleteMany({roleId}).lean(lean); return result||{}; } } export const HeroModel = getModelForClass(Hero);