corgi/src/models/user/UserReward.ts

221 lines
5.5 KiB
TypeScript

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<boolean>}
*/
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<String>} 由reward id组成的Set
*/
public static async userGotSet(accountId: string, shop: string, activityId: string) {
let records = await UserReward.find({ accountId, shop, activityId })
let result: Set<string> = new Set()
for (const record of records) {
result.add(record.rewardId)
}
return result
}
}
export const UserReward = getModelForClass(UserRewardClass, { existingConnection: UserRewardClass.db })