refactor: 兑换机制改为一图章一奖品并引入库存

- 废弃 RedemptionRule(集 N 换 1),新增 Prize 表与 Stamp 1:1 关联
- Redemption 记录直接绑定到 stampId + prizeId + prizeName 快照
- 兑换事务用 updateMany + stock>0 条件作乐观锁
- 兑换后保留 Collection 记录,图章持续彩色点亮并标记"已兑换"
- 用户端入口改为点击已收集图章弹出兑换,库存为 0 时按钮禁用
- 管理后台删除 /admin/rules,奖品编辑嵌入 StampForm

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
This commit is contained in:
2026-04-20 15:30:28 +08:00
parent 52169ac71d
commit 394b643304
20 changed files with 581 additions and 642 deletions

View File

@@ -4,6 +4,14 @@ export type ApiResponse<T = unknown> = {
error?: { code: string; message: string };
};
export type PrizeInfo = {
id: string;
name: string;
description: string | null;
stock: number;
enabled: boolean;
};
export type StampWithStatus = {
id: string;
name: string;
@@ -13,19 +21,15 @@ export type StampWithStatus = {
sortOrder: number;
collected: boolean;
collectedAt: string | null;
};
export type RedemptionRuleInfo = {
id: string;
name: string;
description: string | null;
threshold: number;
redeemed: boolean;
prize: PrizeInfo | null;
};
export type RedemptionRecord = {
id: string;
ruleName: string;
stampCount: number;
stampId: string;
stampName: string;
prizeName: string;
redeemedAt: string;
};