import { HANG_UP_CONSTS } from './../consts/consts'; import BaseModel from './BaseModel'; import { index, getModelForClass, prop } from '@typegoose/typegoose'; import User from './User'; import { shouldRefresh } from '../pubUtils/util'; /** * 角色字段接口 */ @index({ roleId: 1 }) // @index({ userInfo.uid: 1, serverId: 1 }) export default class Role extends BaseModel { @prop({ required: true }) userInfo: User; @prop({ required: true }) seqId: number; @prop({ required: true }) roleId: string; // 角色 id,生成编码 @prop({ required: true }) roleName: string; // 角色名 @prop({ required: true }) serverType: string; // 服务器类型 @prop({ required: true }) serverId: number; // 区服 id @prop({ required: true, default: false }) blocked: boolean; // 是否屏蔽 @prop({ required: true }) code: string; // 邀请码 @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: 100 }) tili: number; // 体力值 @prop({ required: true, default: 0 }) vLv: number; // VIP 等级 @prop({ required: true, default: 100 }) gold: number; // 总金币 @prop({ required: true, default: 0 }) paidGold: number; // 支付所得金币 @prop({ required: true, default: 100 }) giftGold: number; // 赠送所得金币 @prop({ required: true, default: 0 }) totalPay: number; // 总支付金额 @prop({ required: true, default: 0 }) totalBuy: number; // 总金币购买 @prop({ required: true, default: 0 }) totalCost: number; // 金币总花费 @prop({ required: true, default: [] }) payRecord: [{ // 支付记录 id: string; // 购买项 product id cnt: number; // 购买次数 }]; @prop({ required: true, default: 0 }) coin: number; // 总铜钱 @prop({ required: true, default: [] }) consumeGoods: [{ // 消耗品 id: number; // id count: number; // 数量 }]; @prop({ required: true, default: [] }) souls: [{ // 将魂 id: number; // 武将 id count: number; // 数量 }]; @prop({ required: true, default: [] }) pieces: [{ // 装备碎片 id: number; // 装备 id count: number; // 数量 }]; @prop({ required: true, default: [] }) jewels: [{ // 珠宝 id: number; // 待定,也可能是 type + lv count: number; // 数量 }]; @prop({ required: true, default: [] }) warStar: [{ // 关卡星级 id: number; // 关卡 id warType: number; // 关卡类型 star: number; // 星级 }]; @prop({ required: true, default: 1 }) loginCnt: number; // 登录次数 @prop({ required: true }) createTime: Date; // 创建时间 @prop({ required: true }) loginTime: Date; // 更新 / 登录时间 @prop({ required: true, default: 1 }) towerLv: number; // 天梯当前层数 @prop({ required: true }) eventStatus: number; // 奇遇开启状态, 0-未开启 1-开启了第一场事件 2-完全开启 // @prop({ required: false }) // hangUpTime: Date; // 当前挂机开始时间 @prop({ required: true, default: HANG_UP_CONSTS.MAX_SPD_UP_CNT}) hangUpSpdUpCnt: number; // 挂机加速次数 @prop({ required: true, default: new Date()}) lastSpdUpTime: Date; // 最后一次挂机加速时间 @prop({ required: true }) expeditionPoint: number; // 远征点数 public static async findByUid(uid: number, serverId: number, lean = true) { const role = await RoleModel.findOne({ 'userInfo.uid': uid, serverId }).lean(lean); return role; } public static async findByRoleId(roleId: string, lean = true) { const role = await RoleModel.findOne({ roleId }).lean(lean); return role; } public static async createRole(uid: number, serverId: number, roleInfo: {roleId: string; roleName: string; seqId: number; code: string}, lean = true) { const user = await User.findUserByUid(uid); if (!user) return null; const doc = new RoleModel(); const update = Object.assign(doc.toJSON(), roleInfo, { userInfo: user, serverType: user.serverType, serverId }); const role = await RoleModel.findOneAndUpdate({ 'userInfo.uid': uid, serverId }, update, { upsert: true, new: true }).lean(lean); return role; } public static async findRoleByField(field: string, value?: Array, lean = true) { let searchObj = {}; if(field != 'all') { searchObj[field] = { $in: value }; } //.select('uid tel username') const user = await RoleModel.find(searchObj).lean(lean); return user; } public static async setEventStatus(roleId: string, eventStatus: number, lean = true) { await RoleModel.findOneAndUpdate({ roleId }, { eventStatus }, {new: true}).lean(lean); } public static async towerLvUp(roleId: string, lean = true) { let role = await RoleModel.findOneAndUpdate({roleId}, {$inc: {towerLv: 1}}, {new: true}).lean(lean); return role; } public static async hangUpSpdUp(roleId: string, cnt: number, curTime: Date, lean = true) { if (cnt < 0) return null; const result = await RoleModel.findOneAndUpdate({roleId}, {$inc: {hangUpSpdUpCnt: -cnt}, lastSpdUpTime: curTime}, {new: true}).lean(lean); const lastSpdUpTime = result?result.lastSpdUpTime: curTime; let role = null; if (shouldRefresh(lastSpdUpTime, curTime, HANG_UP_CONSTS.REFRESH_TIME, 1) && cnt <= HANG_UP_CONSTS.MAX_SPD_UP_CNT) { role = await RoleModel.findOneAndUpdate({roleId}, {hangUpSpdUpCnt: HANG_UP_CONSTS.MAX_SPD_UP_CNT - cnt, lastSpdUpTime: curTime}, {new: true}).lean(lean); } else { role = await RoleModel.findOneAndUpdate({roleId, hangUpSpdUpCnt: {$gte: cnt}}, {$inc: {hangUpSpdUpCnt: -cnt}, lastSpdUpTime: curTime}, {new: true}).lean(lean); } return role; } public static async increaseExpeditionPoint(roleId: string, point: number, lean = true) { let role = await RoleModel.findOneAndUpdate({roleId}, {$inc: { expeditionPoint: point }}, {new: true}).lean(lean); return role; } public static async levelup(roleId: string, lv: number, exp: number, lean = true) { console.log(lv, exp) let role = await RoleModel.findOneAndUpdate({roleId}, {$set: { exp, lv }}, {new: true}).lean(lean); return role; } public static async deleteAccount(roleId: string, lean = true) { let result = await RoleModel.deleteMany({roleId}).lean(lean); return result||{}; } public static async addItems(roleId: string, field: string, id: number, cnt: number, lean = true) { try { let role = await RoleModel.findOne({roleId}).lean(lean); let item = role?role[field]:[]; let curItem = item.find(cur => cur.id == id); if(!curItem) { let addToSet = {}; addToSet[field] = {id, count: cnt}; let result = await RoleModel.findOneAndUpdate({roleId}, { $addToSet: addToSet }, { "new": true, "upsert": true}).lean(lean); return result; } else { let condition = { roleId }; condition[`${field}.id`] = id; let update = {}; update[`${field}.$.count`] = cnt; let result = await RoleModel.findOneAndUpdate(condition, { $inc: update }, { "new": true, "upsert": true}).lean(lean); return result; } }catch(e) { console.error(e) } } public static async addCoin(roleId: string, cnt: number, lean = true) { let result = await RoleModel.findOneAndUpdate({roleId}, { $inc: {coin: cnt} }, { "new": true, "upsert": true}).lean(lean); return result; } public static async addGoldFree(roleId: string, cnt: number, lean = true) { let result = await RoleModel.findOneAndUpdate({roleId}, { $inc: { gold: cnt, giftGold: cnt } }, { "new": true, "upsert": true}).lean(lean); return result; } public static async pushWarStar(roleId: string, battleId: number, warType: number, star: number, lean = true) { let result = await RoleModel.findOneAndUpdate({roleId}, { $addToSet: { warStar: {id: battleId, warType, star }} }, { "new": true, "upsert": true}).lean(lean); return result; } public static async updateWarStar(roleId: string, battleId: number, star: number, lean = true) { let result = await RoleModel.findOneAndUpdate( {roleId, 'warStar.id': battleId}, { $set: { 'warStar.$.star': star } }, { "new": true, "upsert": true} ).lean(lean); return result; } } export const RoleModel = getModelForClass(Role);