import { getModelForClass, index, modelOptions, prop } from '@typegoose/typegoose' import { dbconn } from '../../decorators/dbconn' import { BaseModule } from '../Base' import { Coupon } from '../shop/Coupon' import { getCouponUrl } from '../../services/File' import { PuzzleSessionClass } from '../match/PuzzleSession' import { LOTTERY_TICKET } from '../../constants/BaseConst' import { UserItem } from './UserItem' import { UserCoupon } from './UserCoupon' /** * 用户挑战或活动获得的奖励记录 * 1. 用于判断某活动或挑战的奖励是否已经领取 */ @dbconn() @index({ accountId: 1 }, { unique: false }) @index({ accountId: 1, shop: 1 }, { unique: false }) @index({ accountId: 1, shop: 1, activityId: 1 }, { unique: false }) @index({ accountId: 1, shop: 1, rewardId: 1, source: 1, activityId: 1 }, { unique: false }) @modelOptions({ schemaOptions: { collection: 'game_user_reward', timestamps: true } }) class UserRewardClass extends BaseModule { @prop() public sid: string @prop() public accountId: string @prop() public shop: string /** * 活动id * @type {string} */ @prop() public activityId: string /** * PuzzleSession的id * @type {string} */ @prop() public sessionId: string /** * 来源 * @type {string} */ @prop() public source: string /** * 券的id * @type {string} */ @prop() public item: string /** * 活动或挑战中奖励配置id * @type {string} */ @prop() public rewardId: string /** * 奖励类型 * @type {number} 0: 优惠券, 1: 抽奖券 */ @prop({ default: 0 }) public rewardType: number @prop({ default: 1 }) public count: number public static async saveOneRecord({ accountId, itemId, count, shop, rewardId, sessionId, activityId, source, }: { accountId: string itemId: string count: number shop: string rewardId: string activityId: string sessionId?: string source?: string }) { let ids: string[] = [] let saveRecord = async function (rewardType: number, cCount: number) { let record = new UserReward({ accountId, shop: shop, sessionId, status: 0, rewardId, item: itemId, rewardType, count: cCount, source: source, }) record.activityId = activityId await record.save() ids.push(record.sid) } let name = '' let url = '' let rewardType = 0 let expire = 0 if (itemId === LOTTERY_TICKET) { rewardType = 1 await saveRecord(1, count) let params = { activity: activityId, rewardId } await UserItem.addOne({ accountId, shop, item: itemId, count, reason: source, params }) name = '抽奖券' } else { rewardType = 0 await saveRecord(0, count) let cdata = await Coupon.findById(itemId) name = cdata.name if (cdata.validDays) { expire = Date.now() + cdata.validDays * 24 * 60 * 60 * 1000 } await UserCoupon.addOne({ accountId, shop, item: itemId, count, source, activityId, rewardId, expire }) await Coupon.updateCount(itemId, count) url = getCouponUrl(shop, itemId) } return { coupon: itemId, name, count, couponUrl: url, ids, rewardType, expire, } } /** * 添加一条奖励获取记录 * @param history 挑战记录 * @param accountId 帐号信息 * @param rewardId 奖励id * @param coupon 优惠券id * @param count 数量 */ public static async addOneRecord( history: PuzzleSessionClass, accountId: string, rewardId: string, coupon: string, count: number, ) { return await UserReward.saveOneRecord({ accountId, itemId: coupon, count, shop: history.shop, rewardId, activityId: history.activityId, sessionId: history._id + '', source: history.type === 1 ? 'activity' : 'exam', }) } /** * 检查挑战的奖励是否已领取 * @param {PuzzleSessionClass} history * @param {string} accountId * @param rewardId * @return {Promise} */ public static async examRewardGot(history: PuzzleSessionClass, accountId: string, rewardId: string) { let source = history.type === 1 ? 'activity' : 'exam' return UserReward.rewardGot({ accountId, shop: history.shop, rewardId, activityId: history.activityId, source }) } /** * 判断特定条件下一个奖励是否已经获取 * @returns {Boolean} */ public static async rewardGot({ accountId, shop, activityId, rewardId, source, }: { accountId: string shop: string activityId: string rewardId: string source: string }) { let records = await UserReward.find( { accountId, activityId: activityId, rewardId, shop, source }, { _id: 1 }, ).limit(1) return records.length > 0 } /** * 获取已经获得的奖励奖励信息, 用于判断指定的reward是否已经获得过了 * @param accountId 帐号id * @param shop 所属店铺 * @param activityId 活动id * @returns {Set} 由reward id组成的Set */ public static async userGotSet(accountId: string, shop: string, activityId: string) { let records = await UserReward.find({ accountId, shop, activityId }) let result: Set = new Set() for (const record of records) { result.add(record.rewardId) } return result } } export const UserReward = getModelForClass(UserRewardClass, { existingConnection: UserRewardClass.db })