178 lines
8.2 KiB
TypeScript
178 lines
8.2 KiB
TypeScript
import BaseModel from './BaseModel';
|
|
import { index, getModelForClass, prop, DocumentType, mongoose } from '@typegoose/typegoose';
|
|
import { RoleType } from './Role';
|
|
import { getZeroPoint } from '../pubUtils/timeUtil';
|
|
|
|
export class Lineup {
|
|
@prop({ required: true })
|
|
actorId: number; // 武将
|
|
@prop({ required: true })
|
|
dataId: number; // 出兵表上所占位置
|
|
@prop({ required: true })
|
|
order: number; // 行动顺序
|
|
@prop({ required: true })
|
|
ce: number; // 战力
|
|
@prop({ required: true })
|
|
correspondingVar?: number;
|
|
}
|
|
|
|
@index({ day: 1, groupKey: 1, vestigeId: 1, rank: 1 })
|
|
@index({ roleId: 1 })
|
|
export default class GVGVestigeRank extends BaseModel {
|
|
|
|
@prop({ required: true })
|
|
configId: number; // 赛期
|
|
|
|
@prop({ required: true })
|
|
day: number; // 每天5点
|
|
|
|
@prop({ required: true })
|
|
groupKey: string; // 战区
|
|
|
|
@prop({ required: true })
|
|
vestigeId: number; // 遗迹id
|
|
|
|
@prop({ required: true })
|
|
roleId: string; // 玩家
|
|
|
|
@prop({ required: true })
|
|
leagueCode: string; // 联军
|
|
|
|
@prop({ required: true })
|
|
name: string; // 联军名字
|
|
|
|
@prop({ required: true, default: 0 })
|
|
rank: number; // 排名
|
|
|
|
@prop({ required: true, default: 0 })
|
|
oldRank: number; // 交换前排名
|
|
|
|
@prop({ required: true, default: 0 })
|
|
historyRank: number; // 历史最高排名
|
|
|
|
@prop({ required: true, default: false })
|
|
hasDefense: boolean; // 是否调整过阵容,首次挑战自动保存阵容
|
|
|
|
@prop({ required: true, type: Lineup, default: [], _id: false })
|
|
lineup: Lineup[]; // 阵容
|
|
|
|
@prop({ required: true, type: Number, default: [], _id: false })
|
|
oppRanks: number[]; // 对手的排名
|
|
|
|
@prop({ required: true, default: 0 })
|
|
refreshCnt: number; // 刷新次数
|
|
|
|
public static async findAllByRole(roleId: string) {
|
|
let today = getZeroPoint();
|
|
let result: GVGVestigeRankType[] = await GVGVestigeRankModel.find({ day: today, roleId }).lean();
|
|
return result;
|
|
}
|
|
|
|
public static async findByRole(vestigeId: number, roleId: string) {
|
|
let today = getZeroPoint();
|
|
let result: GVGVestigeRankType = await GVGVestigeRankModel.findOne({ day: today, vestigeId, roleId }).lean();
|
|
return result;
|
|
}
|
|
|
|
public static async findByRank(configId: number, groupKey: string, vestigeId: number, rank: number) {
|
|
let today = getZeroPoint();
|
|
let result: GVGVestigeRankType = await GVGVestigeRankModel.findOne({ configId, groupKey, day: today, vestigeId, rank }).lean();
|
|
return result;
|
|
}
|
|
|
|
public static async initRank(configId: number, vestigeId: number, groupKey: string, role: RoleType, leagueCode: string, name: string, oppRanks: number[]) {
|
|
let today = getZeroPoint();
|
|
let doc = new GVGVestigeRankModel();
|
|
let update = Object.assign(doc.toJSON(), { role: role._id, configId, groupKey, oppRanks, leagueCode, name });
|
|
let result: GVGVestigeRankType = await GVGVestigeRankModel.findOneAndUpdate({ day: today, vestigeId, roleId: role.roleId }, { $setOnInsert: update }, { new: true, upsert: true }).lean();
|
|
return result;
|
|
}
|
|
|
|
public static async updateByRoleId(vestigeId: number, roleId: string, update: GVGVestigeRankUpdate) {
|
|
let today = getZeroPoint();
|
|
let result: GVGVestigeRankType = await GVGVestigeRankModel.findOneAndUpdate({ day: today, vestigeId, roleId }, { $set: update }, { new: true, upsert: true }).lean();
|
|
return result;
|
|
}
|
|
|
|
public static async findByRanks(groupKey: string, vestigeId: number, ranks: number[]) {
|
|
let today = getZeroPoint();
|
|
let result: GVGVestigeRankType[] = await GVGVestigeRankModel.find({ day: today, vestigeId, groupKey, rank: { $in: ranks } })
|
|
.lean();
|
|
return result;
|
|
}
|
|
|
|
public static async updateCe(roleId: string, hid: number, ce: number) {
|
|
let today = getZeroPoint();
|
|
await GVGVestigeRankModel.updateMany({ day: today, hasDefense: true, roleId, 'lineup.actorId': hid }, { $set: { 'lineup.$.ce': ce } });
|
|
}
|
|
|
|
public static async changeRank(isSuccess: boolean, vestigeId: number, attackInfo: { roleId: string }, defenseInfo: { isRobot: boolean, roleId: string, oldRank: number }): Promise<{ isChange: boolean, atkData?: GVGVestigeRankType, defData?: GVGVestigeRankType, endTime: number }> {
|
|
|
|
let today = getZeroPoint();
|
|
const session = await mongoose.connection.startSession();
|
|
session.startTransaction()
|
|
try {
|
|
let newAtkData: GVGVestigeRankType, newDefData: GVGVestigeRankType, isChange = false, endTime = Date.now();
|
|
if(defenseInfo.isRobot) {
|
|
let atkData = await GVGVestigeRankModel.findOne({ day: today, vestigeId, roleId: attackInfo.roleId }).lean();
|
|
if(isSuccess && atkData && (atkData.rank == 0 || atkData.rank > defenseInfo.oldRank)) {
|
|
newAtkData = await GVGVestigeRankModel.findOneAndUpdate({ day: today, vestigeId, roleId: attackInfo.roleId }, { $set: { rank: defenseInfo.oldRank, oldRank: atkData.rank } }, { new: true, session }).lean();
|
|
isChange = true;
|
|
endTime = Date.now();
|
|
} else {
|
|
newAtkData = atkData;
|
|
}
|
|
} else {
|
|
let atkData = await GVGVestigeRankModel.findOne({ day: today, vestigeId, roleId: attackInfo.roleId }).lean();
|
|
let defData = await GVGVestigeRankModel.findOne({ day: today, vestigeId, roleId: defenseInfo.roleId }).lean();
|
|
if(isSuccess && atkData && defData && (atkData.rank == 0 || atkData.rank > defData.rank)) {
|
|
newAtkData = await GVGVestigeRankModel.findOneAndUpdate({ day: today, vestigeId, roleId: attackInfo.roleId }, { $set: { rank: defData.rank, oldRank: atkData.rank } }, { new: true, session }).lean();
|
|
newDefData = await GVGVestigeRankModel.findOneAndUpdate({ day: today, vestigeId, roleId: defenseInfo.roleId }, { $set: { rank: atkData.rank, oldRank: defData.rank } }, { new: true, session }).lean();
|
|
isChange = true;
|
|
endTime = Date.now();
|
|
} else {
|
|
newAtkData = atkData;
|
|
newDefData = defData;
|
|
}
|
|
}
|
|
await session.commitTransaction()
|
|
return { isChange, atkData: newAtkData, defData: newDefData, endTime }
|
|
} finally {
|
|
session.endSession()
|
|
}
|
|
}
|
|
|
|
public static async refreshOpp(roleId: string, vestigeId: number, oppRanks: number[]) {
|
|
let today = getZeroPoint();
|
|
let result: GVGVestigeRankType = await GVGVestigeRankModel.findOneAndUpdate({ day: today, vestigeId, roleId }, { $set: { oppRanks }, $inc: { refreshCnt: 1 } }, { new: true, upsert: true }).lean();
|
|
return result;
|
|
}
|
|
|
|
public static async findRank(): Promise<{ _id: { groupKey: string, vestigeId: number }, arr: { roleId: string, rank: number }[], roleIds: string[] }[]> {
|
|
let today = getZeroPoint();
|
|
let ranks = await GVGVestigeRankModel.aggregate([
|
|
{ $match: { day: today } },
|
|
{ $group: {
|
|
_id: { groupKey: "$groupKey", vestigeId: "$vestigeId" },
|
|
arr: { $push: { roleId: "$roleId", rank: "$rank" } }, roleIds: { $addToSet: "$roleId" }
|
|
}},
|
|
]);
|
|
return ranks;
|
|
}
|
|
|
|
public static async findRankByVestige(groupKey: string, vestigeId: number) {
|
|
let today = getZeroPoint();
|
|
let result: GVGVestigeRankType[] = await GVGVestigeRankModel.find({ day: today, vestigeId, groupKey, rank: { $gt: 0 } }).sort({ rank: 1 }).select('roleId rank lineup').lean();
|
|
return result;
|
|
}
|
|
|
|
public static async removeBySub(roleId: string, subHid: number) {
|
|
await GVGVestigeRankModel.updateMany({ roleId, hasDefense: true }, { $pull: { lineup: { actorId: subHid } } });
|
|
}
|
|
}
|
|
|
|
export const GVGVestigeRankModel = getModelForClass(GVGVestigeRank);
|
|
|
|
export interface GVGVestigeRankType extends Pick<DocumentType<GVGVestigeRank>, keyof GVGVestigeRank> {};
|
|
export type GVGVestigeRankUpdate = Partial<GVGVestigeRankType>; // 将所有字段变成可选项
|