import BaseModel from './BaseModel'; import { index, getModelForClass, prop, DocumentType, modelOptions } from '@typegoose/typegoose'; import { BAG } from '../pubUtils/dicParam'; import { nowSeconds } from '../pubUtils/timeUtil'; @index({ roleId: 1, id: 1 }) @modelOptions({ schemaOptions: { id: false } }) export default class ActivityItem extends BaseModel { @prop({ required: true, default: '' }) roleId: string; // 角色 id @prop({ required: true, default: '' }) roleName: string; // 角色名称 @prop({ required: true, default: '' }) id: number; // 道具 id @prop({ required: true, default: '' }) itemName: string; // 道具名称 @prop({ required: true, default: 0 }) expireTime: number; // 限时 @prop({ required: true }) count: number; // 道具数量 public static async findbyRole(roleId: string, select = '') { const items: ActivityItemType[] = await ActivityItemModel.find({ roleId, count: {$gte: 0}, expireTime: { $gte: nowSeconds() } }).select(select).lean(); return items; } public static async findbyRoleAndIds(roleId: string, ids: Array, lean = true) { const items: ActivityItemType[] = await ActivityItemModel.find({ roleId, id: { $in: ids }, count: {$gte: 0}, expireTime: { $gte: nowSeconds() } }).select('id count expireTime').lean(lean); return items; } public static async findbyRoleAndGid(roleId: string, id: number, lean = true) { const items: ActivityItemType = await ActivityItemModel.findOne({ roleId, id }).select('id count expireTime').lean(lean); return items; } public static async increaseActivityItem(roleId: string, id: number, count: number, itemInfo: { roleId: string, roleName: string, id: number, itemName: string, expireTime?: number }) { const doc = new ActivityItemModel(); const setOnInsert = Object.assign(doc.toJSON(), itemInfo); delete setOnInsert.expireTime; let items: ActivityItemType = await ActivityItemModel.findOneAndUpdate({ roleId, id, expireTime: { $gte: nowSeconds() } }, { $setOnInsert: setOnInsert, $inc: { count }, $set: { expireTime: itemInfo.expireTime } }, { new: true, upsert: true }).lean(); if(items.count > BAG.BAG_GOODS_UPLIMITED) { items = await ActivityItemModel.findOneAndUpdate({ roleId, id, count: { $gte: BAG.BAG_GOODS_UPLIMITED }, expireTime: { $gte: nowSeconds() } }, { $set: { count: BAG.BAG_GOODS_UPLIMITED, expireTime: itemInfo.expireTime } }, { new: true }).lean(); } return items; } public static async decreaseActivityItems(roleId: string, items: Array<{ id: number, count: number }>, lean = true) { let updateActivityItems = new Array<{ id: number, count: number }>(), hasError: boolean = false, result = new Array(); for (let { id, count } of items) { let rec: ActivityItemType = await ActivityItemModel.findOneAndUpdate({ roleId, id, count: { $gte: count }, expireTime: { $gte: nowSeconds() } }, { $inc: { count: -1 * count } }, { new: true }).lean(lean); if (!!rec) { let index = result.findIndex(cur => cur.id == rec.id); if (index != -1) { result[index].count = rec.count; result[index].inc += -count; } else { result.push({ id: rec.id, count: rec.count, expireTime: rec.expireTime, inc: -count }); } updateActivityItems.push({ id, count }); } else { hasError = true; break; } } if (hasError) { // 数量不足 for (let { id, count } of updateActivityItems) { await ActivityItemModel.findOneAndUpdate({ roleId, id, expireTime: { $gte: nowSeconds() } }, { $inc: { count: -count } }, { new: true }).lean(lean); } return { hasError: true } } else { return { hasError: false, result } } } } export const ActivityItemModel = getModelForClass(ActivityItem); export interface ActivityItemType extends Pick, keyof ActivityItem> { id: number; };