Files
ZYZ/shared/db/UserGuild.ts

321 lines
14 KiB
TypeScript
Raw Permalink Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
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>; // 将所有字段变成可选项