diff --git a/src/api/controllers/coupon.controller.ts b/src/api/controllers/coupon.controller.ts index bdb8f26..6e15dc1 100644 --- a/src/api/controllers/coupon.controller.ts +++ b/src/api/controllers/coupon.controller.ts @@ -6,6 +6,7 @@ import { Shop } from '../../models/shop/Shop' import { Coupon } from '../../models/shop/Coupon' import { getCouponUrl } from '../../services/File' import { GameUser } from 'models/user/GameUser' +import { UserCouponRecord } from 'models/user/UserCouponRecord' class CouponController extends BaseController { /** @@ -13,10 +14,10 @@ class CouponController extends BaseController { * 用于核销页面获取优惠券信息 */ @role('anon') - @router('get /pub/coupon/:shop/:id') + @router('post /pub/coupon/:shop/:id') @router('post /api/:accountId/coupon/info') async info(req: any) { - const { id, shop } = req.params + const { id, shop, accountId } = req.params if (!id || !shop) { throw new ZError(10, '缺少必要参数') } @@ -28,6 +29,11 @@ class CouponController extends BaseController { if (!record) { throw new ZError(11, 'no matched records') } + if (accountId) { + if (record.accountId !== accountId) { + throw new ZError(13, '无法查看不是自己的优惠券信息') + } + } if (record.expire) { // 如果有过期时间设置, 且已经过期, 则将未使用和已分享但未被领取的记录更新为已过期 if (Date.now() >= record.expire && (record.status === 0 || record.status === 2)) { @@ -46,6 +52,7 @@ class CouponController extends BaseController { couponUrl: coupon.imageUrl, status: record.status, expire: record.expire, + useTime: record.useTime, user: user.nickname, userAvatar: user.avatar, } @@ -54,13 +61,17 @@ class CouponController extends BaseController { * 核销 */ @role('anon') - @router('post /pub/coupon/:shop/:id') + @router('post /pub/coupon_use/:id') async use(req: any) { - const { id, shop } = req.params - if (!id || !shop) { + const { id, shop, accountId } = req.params + if (!id || !shop || !accountId) { throw new ZError(10, '缺少必要参数') } - const record = await UserCoupon.findOne({ sid: id, shop }) + const shopData = await Shop.fetchByID(shop) + if (!shopData) { + throw new ZError(12, 'no match shop') + } + const record = await UserCoupon.findOne({ sid: id, shop: shopData.id }) if (!record) { throw new ZError(11, 'no matched records') } @@ -71,11 +82,13 @@ class CouponController extends BaseController { await record.save() } } - if (record.status !== 0) { - throw new ZError(12, 'record status not matched') + if (record.status !== 0 && record.status !== 2) { + throw new ZError(13, 'record status not matched') } record.status = 1 + record.useTime = Date.now() await record.save() + await UserCouponRecord.log(accountId, shop, id, { ip: req.ip, hostname: req.hostname, protocol: req.protocol }) return {} } /** @@ -116,7 +129,7 @@ class CouponController extends BaseController { if (result.nModified !== 1) { throw new ZError(11, '未找到符合条件的记录, 可能已被别人领走') } - //TODO: 生成新的优惠券图 + const record = await UserCoupon.findOne({ sid: id, accountId: sender }) const recordNew = record.copy() recordNew.accountId = accountId diff --git a/src/api/controllers/game_user.controller.ts b/src/api/controllers/game_user.controller.ts index 7070885..dc6ca62 100644 --- a/src/api/controllers/game_user.controller.ts +++ b/src/api/controllers/game_user.controller.ts @@ -130,7 +130,7 @@ class GameUserController extends BaseController { couponMap.set(coupon.id, coupon) } name = couponMap.get(reward.coupon).name - couponUrl = reward.icon || couponMap.get(reward.coupon).imageUrl + couponUrl = reward.icon || couponMap.get(reward.coupon).imageUrl } if (!gotSet.has(reward._id + '') && numInvite >= reward.rank) { let obj = await UserReward.saveOneRecord({ diff --git a/src/models/user/UserCoupon.ts b/src/models/user/UserCoupon.ts index c715f16..239a0cf 100644 --- a/src/models/user/UserCoupon.ts +++ b/src/models/user/UserCoupon.ts @@ -86,6 +86,9 @@ class UserCouponClass extends BaseModule { @prop({ default: 0 }) public expire: number + @prop() + public useTime: 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 diff --git a/src/models/user/UserCouponRecord.ts b/src/models/user/UserCouponRecord.ts new file mode 100644 index 0000000..38b38e9 --- /dev/null +++ b/src/models/user/UserCouponRecord.ts @@ -0,0 +1,38 @@ +import { getModelForClass, index, modelOptions, mongoose, post, prop, Severity } from '@typegoose/typegoose' +import { dbconn } from '../../decorators/dbconn' +import { BaseModule } from '../Base' + +/** + * 优惠券核销记录 + */ +@dbconn() +@index({ accountId: 1 }, { unique: false }) +@index({ shop: 1 }, { unique: false }) +@index({ item: 1 }, { unique: false }) +@modelOptions({ + schemaOptions: { collection: 'user_coupon_record', timestamps: true }, + options: { allowMixed: Severity.ALLOW }, +}) +class UserCouponRecordClass extends BaseModule { + @prop() + public item: string + @prop() + public accountId: string + @prop() + public shop: string + @prop({ type: mongoose.Schema.Types.Mixed }) + public data: {} + + public static async log(accountId: string, shop: string, itemId: string, moreparam?: any) { + let record = new UserCouponRecord() + record.accountId = accountId + record.item = itemId + record.shop = shop + record.data = moreparam + await record.save() + } +} + +export const UserCouponRecord = getModelForClass(UserCouponRecordClass, { + existingConnection: UserCouponRecordClass['db'], +})