161 lines
3.9 KiB
TypeScript
161 lines
3.9 KiB
TypeScript
import { dbconn } from '../../decorators/dbconn'
|
|
import { getModelForClass, index, modelOptions, pre, prop } from '@typegoose/typegoose'
|
|
import { BaseModule } from '../Base'
|
|
import { ItemRecord } from './ItemRecord'
|
|
import { customAlphabet } from 'nanoid'
|
|
import { UserReward } from './UserReward'
|
|
import { isObjectId } from '../../utils/string.util'
|
|
import { Shop } from '../shop/Shop'
|
|
import { Coupon } from '../shop/Coupon'
|
|
import { getCouponUrl } from '../../services/File'
|
|
const nanoid = customAlphabet('2345678abcdefghjkmnpqrstwxy', 10)
|
|
|
|
@dbconn()
|
|
@index({ accountId: 1, shop: 1 }, { unique: false })
|
|
@index({ sid: 1, shop: 1 }, { unique: true })
|
|
@index({ accountId: 1, shop: 1, item: 1 }, { unique: false })
|
|
@modelOptions({ schemaOptions: { collection: 'user_coupons', timestamps: true } })
|
|
@pre<UserCouponClass>('save', async function () {
|
|
if (!this.sid) {
|
|
let sid = ''
|
|
while (!sid) {
|
|
sid = nanoid()
|
|
const records = await UserCoupon.find({ sid, shop: this.shop }, { _id: 1 }).limit(1)
|
|
records.length > 0 && (sid = '')
|
|
}
|
|
this.sid = sid
|
|
}
|
|
})
|
|
class UserCouponClass extends BaseModule {
|
|
/**
|
|
* 当前拥有者的帐号id
|
|
*/
|
|
@prop()
|
|
public accountId: string
|
|
/**
|
|
* 所属店铺id
|
|
*/
|
|
@prop()
|
|
public shop: string
|
|
/**
|
|
* 真实的优惠券id
|
|
*/
|
|
@prop()
|
|
public item: string
|
|
/**
|
|
* 短id, 用于生成二维码, 店铺唯一
|
|
*/
|
|
@prop()
|
|
public sid: string
|
|
|
|
@prop({ default: 0 })
|
|
public count: number
|
|
/**
|
|
* 来源
|
|
*/
|
|
@prop()
|
|
public source: string
|
|
/**
|
|
* 活动or挑战id
|
|
*/
|
|
@prop()
|
|
public activityId: string
|
|
/**
|
|
* UserReward的记录id
|
|
*/
|
|
@prop()
|
|
public rewardId: string
|
|
|
|
/**
|
|
* 状态
|
|
* 0: 未使用
|
|
* 1: 已使用
|
|
* 2: 赠送中
|
|
* 3: 已赠送
|
|
* 9: 已过期
|
|
* @type {number}
|
|
*/
|
|
@prop()
|
|
public status: number
|
|
|
|
public static async fetchCount({ accountId, shop, item }: { accountId: string; shop: string; item: string }) {
|
|
let record = await UserCoupon.findOne({ accountId, shop, item })
|
|
return record?.count || 0
|
|
}
|
|
|
|
/**
|
|
* 添加一件物品
|
|
*/
|
|
public static async addOne({
|
|
accountId,
|
|
shop,
|
|
item,
|
|
count,
|
|
source,
|
|
activityId,
|
|
rewardId,
|
|
}: {
|
|
accountId: string
|
|
shop: string
|
|
item: string
|
|
count: number
|
|
source: string
|
|
activityId: string
|
|
rewardId: string
|
|
}) {
|
|
for (let i = 0; i < count; i++) {
|
|
let record = new UserCoupon({})
|
|
record.accountId = accountId
|
|
record.shop = shop
|
|
record.item = item
|
|
record.count = 1
|
|
record.activityId = activityId
|
|
record.source = source
|
|
record.rewardId = rewardId
|
|
record.status = 0
|
|
await record.save()
|
|
}
|
|
}
|
|
|
|
public static async ticketList(accountId: string, shopId?: string) {
|
|
let params: any = { accountId }
|
|
let shopMap: Map<string, string> = new Map()
|
|
if (shopId) {
|
|
if (!isObjectId(shopId)) {
|
|
let shopData = await Shop.fetchByID(shopId)
|
|
shopId = shopData.id
|
|
shopMap.set(shopId, shopData.showName)
|
|
}
|
|
params.shop = shopId
|
|
}
|
|
let records = await UserCoupon.find(params)
|
|
let results: any = []
|
|
|
|
let couponMap: Map<string, any> = new Map()
|
|
for (let record of records) {
|
|
let sid = record.shop
|
|
if (!shopMap.has(record.shop)) {
|
|
let shop = await Shop.fetchByID(record.shop)
|
|
shopMap.set(record.shop, shop.showName)
|
|
sid = shop.id
|
|
}
|
|
if (!couponMap.has(record.item)) {
|
|
let coupon = await Coupon.findById(record.item)
|
|
couponMap.set(coupon.id, coupon)
|
|
}
|
|
results.push({
|
|
id: record.sid,
|
|
shop: record.shop,
|
|
shopName: shopMap.get(record.shop),
|
|
coupon: record.item,
|
|
couponName: couponMap.get(record.item).name,
|
|
couponUrl: getCouponUrl(sid, record.item),
|
|
status: record.status,
|
|
})
|
|
}
|
|
return results
|
|
}
|
|
}
|
|
|
|
export const UserCoupon = getModelForClass(UserCouponClass, { existingConnection: UserCouponClass.db })
|