corgi/src/models/user/UserCoupon.ts
2021-07-02 20:39:20 +08:00

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 })