321 lines
14 KiB
TypeScript
321 lines
14 KiB
TypeScript
import BaseModel from './BaseModel';
|
||
import { index, getModelForClass, prop, DocumentType, Ref } from '@typegoose/typegoose';
|
||
import Role, { RoleType } from './Role';
|
||
import { GUILD_AUTH, USER_GUILD_STATUS, GUILD_JOB, SHOP_REFRESH_TYPE } from '../consts';
|
||
import { getZeroPointD, nowSeconds, isToday } from '../pubUtils/timeUtil';
|
||
import { ARMY } from '../pubUtils/dicParam';
|
||
class ActiveRecord {
|
||
@prop({ required: true })
|
||
id: number;
|
||
@prop({ required: true })
|
||
count: number;
|
||
}
|
||
|
||
export class WishGood {
|
||
@prop({ required: true })
|
||
id: string;//随机生成的唯一id
|
||
@prop({ required: true })
|
||
type: number;//1:表示装备池,2:武将池
|
||
@prop({ required: true })
|
||
goodId: number;
|
||
@prop({ required: true })
|
||
count: number; //许愿次数
|
||
@prop({ required: true, default:0 })
|
||
receiveCnt: number; //收到次数
|
||
@prop({ required: true, default:0 })
|
||
drawCnt: number; //可以领取次数
|
||
@prop({ required: true, type: String, default: [] })
|
||
donateNames: string[];
|
||
}
|
||
|
||
class RefineRecord {
|
||
@prop({ required: true })
|
||
quality: number;
|
||
@prop({ required: true })
|
||
count: number;
|
||
}
|
||
|
||
export class TrainBoxRewardRecord {
|
||
@prop({ required: true })
|
||
hid: number;
|
||
@prop({ required: true })
|
||
guildCode: string;
|
||
}
|
||
|
||
@index({ roleId: 1 })
|
||
@index({ guildCode: 1 })
|
||
export default class UserGuild extends BaseModel {
|
||
@prop({ required: true })
|
||
guildCode: string;
|
||
|
||
@prop({ required: true })
|
||
roleId: string;
|
||
|
||
@prop({ required: true })
|
||
role: Ref<Role>;
|
||
|
||
@prop({ required: true, default: GUILD_AUTH.MEMBER, enum: GUILD_AUTH })
|
||
auth: number;
|
||
|
||
@prop({ required: true, default: GUILD_JOB.SHIBING, enum: GUILD_JOB })
|
||
job: number;
|
||
|
||
@prop({ required: true, default: 0 })
|
||
activeWeekly: number;
|
||
|
||
@prop({ required: true, default: 0 })
|
||
activeDaily: number;
|
||
|
||
@prop({ required: true, default: nowSeconds() })
|
||
activeUpdateTime: number;
|
||
|
||
@prop({ required: true, default: USER_GUILD_STATUS.ON, enum: USER_GUILD_STATUS})
|
||
status: number;
|
||
|
||
@prop({ required: true, type: ActiveRecord, default: [], _id: false })
|
||
activeRecord: ActiveRecord[];
|
||
|
||
@prop({ required: true, type: Number, default: [] })
|
||
receivedActive: number[];
|
||
|
||
@prop({ required: true, select: false })
|
||
refTimeDaily: Date;
|
||
//练兵场
|
||
@prop({ required: true, default: 0 })
|
||
trainCount: number;//每日挑战训练场的次数
|
||
|
||
@prop({ required: true, default: 0 })
|
||
buyTrainCount: number;//每日挑战训练场购买次数
|
||
|
||
@prop({ required: true, default: 0 })
|
||
trainTime: number;//上次刷新挑战训练场次数的时间每天5点
|
||
|
||
@prop({ required: true, default: [], type: Number })
|
||
trainRewards: Array<number>;//领取过的进阶等级
|
||
|
||
@prop({ required: true, default: [], type: TrainBoxRewardRecord, _id: false })
|
||
trainBoxRewards: Array<TrainBoxRewardRecord>;//领取过的挑战奖励
|
||
|
||
//捐献所
|
||
@prop({ required: true, default: [], type: Number })
|
||
receiveBoxs: Array<number>; //今天捐献所领取宝箱id记录,
|
||
|
||
@prop({ required: true, default: 0 })
|
||
donateCnt: number;//今天捐献所次数
|
||
//许愿池
|
||
@prop({ required: true, default: [], type: WishGood, _id: false })
|
||
wishGoods: Array<WishGood>;
|
||
|
||
@prop({ required: true, default: [], type: Number })
|
||
receivedWishPool: number[];
|
||
|
||
@prop({ required: true, default: 0 })
|
||
wishDntCnt: number;//今天许愿池捐献次数
|
||
|
||
// 演武台
|
||
@prop({ required: true })
|
||
refBossTime: Date;
|
||
|
||
@prop({ required: true, default: 0 })
|
||
encourageCnt: number; //今天鼓舞次数
|
||
|
||
@prop({ required: true, default: 0 })
|
||
bossChallengeCnt: number;//今天挑战演舞台次数
|
||
|
||
// 炼器堂
|
||
@prop({ required: true, type: RefineRecord })
|
||
refineCnt: RefineRecord[];
|
||
|
||
@prop({ required: true })
|
||
refRefineTime: Date;
|
||
|
||
public static async getMyGuild(roleId: string, select?: string) {
|
||
|
||
const myGuild: UserGuildType = await UserGuildModel.findOne({ roleId, status: USER_GUILD_STATUS.ON })
|
||
.select(select).lean();
|
||
return myGuild;
|
||
}
|
||
|
||
public static async getListByGuild(guildCode: string, select?: string, sort: { auth?: number, activeWeekly?: number, activeUpdateTime?: number } = {auth: 1}) {
|
||
const userGuilds: UserGuildType[] = await UserGuildModel.find({ guildCode, status: USER_GUILD_STATUS.ON })
|
||
.select(select)
|
||
.sort(sort)
|
||
.populate('role', 'roleId roleName ce head frame spine heads frames spines lv title quitTime loginTime', 'Role')
|
||
.lean({ getters: true, virtuals: true });
|
||
return userGuilds;
|
||
}
|
||
|
||
public static async findTopActive(guildCode: string, select?: string) {
|
||
const userGuilds: UserGuildType[] = await UserGuildModel.find({ guildCode, status: USER_GUILD_STATUS.ON, auth: { $ne: GUILD_AUTH.LEADER } })
|
||
.sort({ activeWeekly: -1, activeUpdateTime: 1 })
|
||
.select(select)
|
||
.populate('role', 'roleId roleName ce head frame spine heads frames spines lv title quitTime', 'Role')
|
||
.lean({getters: true, virtuals: true });
|
||
return userGuilds;
|
||
}
|
||
|
||
public static async createUserGuild(guildCode: string, role: RoleType, isLeader: boolean) {
|
||
const lastGuild = await UserGuildModel.findMyLastGuild(role.roleId, '+refTimeDaily');
|
||
let { receiveBoxs = [], donateCnt = 0, receivedActive = [], encourageCnt = 0, bossChallengeCnt = 0, receivedWishPool = [], wishGoods = [], wishDntCnt = 0, refTimeDaily, refBossTime, trainCount, buyTrainCount, trainTime, trainRewards = [], refineCnt = [], refRefineTime, trainBoxRewards = [] } = lastGuild||{};
|
||
|
||
const doc = new UserGuildModel();
|
||
let job = isLeader? GUILD_JOB.DAJIANGJUN: GUILD_JOB.SHIBING;
|
||
let auth = isLeader? GUILD_AUTH.LEADER: GUILD_AUTH.MEMBER;
|
||
const update = Object.assign(doc.toJSON(), { guildCode, roleId: role.roleId, role: role._id, job, auth, receiveBoxs, donateCnt, receivedActive, encourageCnt, bossChallengeCnt, receivedWishPool, wishGoods, wishDntCnt, refTimeDaily, refBossTime, trainCount, buyTrainCount, trainTime, trainRewards, refineCnt, refRefineTime, trainBoxRewards });
|
||
|
||
// trainRewards: 试炼奖励, 无论在任何情况下都不能被清空(次数可以重置,奖励领过就不能再领了,无论在哪个军团)
|
||
// 【退出军团】 和 【再加入军团】不在同一天; 此处包含: 首次加入军团(lastGuild == null)
|
||
if (!isToday(role.quitGuildTime) && lastGuild) {
|
||
// 之前加入过军团 - 清空之前的数据
|
||
update.receiveBoxs = [];
|
||
update.donateCnt = 0;
|
||
update.receivedActive = [];
|
||
update.encourageCnt = 0;
|
||
update.bossChallengeCnt = 0;
|
||
update.receivedWishPool = [];
|
||
update.wishGoods = [];
|
||
update.wishDntCnt = 0;
|
||
update.trainCount = 0;
|
||
update.buyTrainCount = 0;
|
||
update.trainTime = 0;
|
||
update.refineCnt = [];
|
||
}
|
||
delete update._id;
|
||
|
||
const result: UserGuildType = await UserGuildModel.findOneAndUpdate({ roleId: role.roleId, guildCode, status: USER_GUILD_STATUS.ON }, { $set: update }, { upsert: true, new: true })
|
||
.select('activeDaily activeRecord activeWeekly activeUpdateTime job auth receivedActive guildCode trainBoxRewards')
|
||
.lean();
|
||
|
||
return result;
|
||
}
|
||
|
||
public static async findMyLastGuild(roleId: string, select: string) {
|
||
const userGuild = await UserGuildModel.findOne({ roleId, status: { $ne: USER_GUILD_STATUS.ON } }).select(select).sort({ createdAt: -1 }).lean();
|
||
return userGuild;
|
||
}
|
||
|
||
/**
|
||
* 查询我今天所有加入过的军团(从上次的刷新时间(5AM)到现在)
|
||
*
|
||
* @static
|
||
* @param {string} roleId
|
||
* @param {string} select
|
||
* @return {*}
|
||
* @memberof UserGuild
|
||
*/
|
||
public static async findMyGuildsOfToday(roleId: string, select: string) {
|
||
const userGuilds = await UserGuildModel.find({ roleId, createdAt: { $gt: getZeroPointD() } }).select(select).lean();
|
||
return userGuilds;
|
||
}
|
||
|
||
public static async dismiss(guildCode: string) {
|
||
const result = await UserGuildModel.updateMany({ guildCode }, { status: USER_GUILD_STATUS.DISMISSED });
|
||
|
||
return result;
|
||
}
|
||
|
||
// 玩家退出公会
|
||
public static async quit(guildCode: string, roleId: string) {
|
||
const result = await UserGuildModel.findOneAndUpdate({ guildCode, roleId, status: USER_GUILD_STATUS.ON }, {status: USER_GUILD_STATUS.QUIT}, {new: true});
|
||
return result;
|
||
}
|
||
|
||
public static async updateInfo(roleId: string, update: UserGuildUpdateParam, incParam: { activeDaily?: number, activeWeekly?: number, trainCount?: number }, select?: string) {
|
||
const result: UserGuildType = await UserGuildModel.findOneAndUpdate({ roleId, status: USER_GUILD_STATUS.ON }, { $set: update, $inc: incParam }, { new: true }).select(select).lean();
|
||
return result;
|
||
}
|
||
|
||
public static async receiveTrainRewards(roleId: string, trainId: number, lean = true) {
|
||
const result = await UserGuildModel.findOneAndUpdate({ roleId, status: USER_GUILD_STATUS.ON},
|
||
{ $push:{trainRewards: trainId} },{new: true}).lean(lean);
|
||
return result;
|
||
}
|
||
|
||
/**
|
||
* 记录玩家领取过的试炼宝箱奖励(每个武将都有一个抽卡奖励)
|
||
*
|
||
* @static
|
||
* @param {string} roleId
|
||
* @param {number} trainId
|
||
* @param {boolean} [lean=true]
|
||
* @return {*}
|
||
* @memberof UserGuild
|
||
*/
|
||
public static async receiveTrainBoxRewards(roleId: string, hid: number, guildCode: string, lean = true) {
|
||
const result = await UserGuildModel.findOneAndUpdate({ roleId, status: USER_GUILD_STATUS.ON},
|
||
{ $push:{trainBoxRewards: {hid, guildCode}} },{new: true}).lean(lean);
|
||
return result;
|
||
}
|
||
|
||
public static async addTrainCount(roleId: string, trainCount: number, lean = true) {
|
||
const result = await UserGuildModel.findOneAndUpdate({ roleId, status: USER_GUILD_STATUS.ON},
|
||
{ $inc: { trainCount, buyTrainCount: trainCount } }, {new: true}).lean(lean);
|
||
return result;
|
||
}
|
||
|
||
public static async resetTrainUserGuild(guildCode: string) {
|
||
const result = await UserGuildModel.updateMany({ guildCode }, {$set: { trainCount: ARMY.ARMY_TRAIN_BUYTIMES, buyTrainCount: 0, trainTime: nowSeconds(), trainRewards: [] }});
|
||
return result;
|
||
}
|
||
|
||
/**
|
||
* 重置上周加入的队员的试炼数据(本周加入的不能重置,否则会多领奖励)
|
||
*
|
||
* @static
|
||
* @param {string} guildCode
|
||
* @return {*}
|
||
* @memberof UserGuild
|
||
*/
|
||
public static async resetTrainUserGuildLastWeekJoinedIn(guildCode: string) {
|
||
const result = await UserGuildModel.updateMany({ guildCode, createdAt: {$lt: getZeroPointD(SHOP_REFRESH_TYPE.WEEKLY)} }, {$set: { trainCount: ARMY.ARMY_TRAIN_BUYTIMES, buyTrainCount: 0, trainTime: nowSeconds(), trainRewards: [], trainBoxRewards: [] }});
|
||
return result;
|
||
}
|
||
|
||
public static async donateFund(roleId: string, donateCnt: number, lean = true) {
|
||
const result = await UserGuildModel.findOneAndUpdate({ roleId, status: USER_GUILD_STATUS.ON},
|
||
{$inc: { donateCnt }}, {new: true}).lean(lean);
|
||
return result;
|
||
}
|
||
|
||
public static async getWishPoolGoods(guildCode: string, select?: string, lean = true) {
|
||
const userGuilds: UserGuildType[] = await UserGuildModel.find({ guildCode, status: USER_GUILD_STATUS.ON, refTimeDaily: { $gte: getZeroPointD() } })
|
||
.select(select).lean(lean);
|
||
return userGuilds;
|
||
}
|
||
|
||
public static async pushAndUpdate(roleId: string, update: UserGuildUpdateParam, pushData:{wishGoods?: WishGood}, select?: string) {
|
||
const result: UserGuildType = await UserGuildModel.findOneAndUpdate({ roleId, status: USER_GUILD_STATUS.ON }, { $set: update, $push: pushData }, { new: true }).select(select).lean();
|
||
return result;
|
||
}
|
||
|
||
public static async donateGoods(roleId: string, wishDntCnt: number, select?: string) {
|
||
const result: UserGuildType = await UserGuildModel.findOneAndUpdate({ roleId, status: USER_GUILD_STATUS.ON }, { $inc: { wishDntCnt } }, { new: true }).select(select).lean();
|
||
return result;
|
||
}
|
||
|
||
public static async donateUpdate(roleId: string, dntRoleName: string, id: string, select?: string) {
|
||
const result: UserGuildType = await UserGuildModel.findOneAndUpdate({ roleId, status: USER_GUILD_STATUS.ON, 'wishGoods.id': id }, { $inc: { 'wishGoods.$.receiveCnt': 1, 'wishGoods.$.drawCnt': 1}, $push:{'wishGoods.$.donateNames': dntRoleName} }, { new: true }).select(select).lean();
|
||
return result;
|
||
}
|
||
|
||
|
||
public static async resetDailyInfo(roleId: string) {
|
||
const result: UserGuildType = await UserGuildModel.findOneAndUpdate({ roleId, status: USER_GUILD_STATUS.ON }, { $set: {
|
||
receivedActive: [], refTimeDaily: new Date(), activeDaily: 0, activeRecord: [], wishGoods: [], receivedWishPool: [], receiveBoxs: [], wishDntCnt: 0, donateCnt: 0
|
||
} }, { new: true }).lean();
|
||
return result;
|
||
}
|
||
|
||
public static async resetDailyInfoByRefTimeDaily(roleId: string, refTimeDaily: Date | null) {
|
||
const result: UserGuildType = await UserGuildModel.findOneAndUpdate({ roleId, status: USER_GUILD_STATUS.ON, refTimeDaily }, { $set: {
|
||
receivedActive: [], refTimeDaily: new Date(), activeDaily: 0, activeRecord: [], wishGoods: [], receivedWishPool: [], receiveBoxs: [], wishDntCnt: 0, donateCnt: 0
|
||
} }, { new: true }).lean();
|
||
return result;
|
||
}
|
||
}
|
||
|
||
export const UserGuildModel = getModelForClass(UserGuild);
|
||
|
||
export interface UserGuildType extends Pick<DocumentType<UserGuild>, keyof UserGuild> { };
|
||
export type UserGuildUpdateParam = Partial<UserGuildType>; // 将所有字段变成可选项
|