Files
quyun-v2/docs/coupon_plan.md

103 lines
4.1 KiB
Markdown
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
# 优惠券功能规划(先规划,后执行)
## 1. 目标与范围
- 支持租户侧创建/管理优惠券模板。
- 支持用户领取/选择/使用优惠券,订单创建时自动校验与核销。
- 优惠券状态可追踪:未使用/已使用/已过期。
- 保持多租户隔离,避免跨租户误用。
## 2. 当前现状
- 数据表已存在:`coupons``user_coupons``orders.coupon_id`
- 服务层已有部分能力:`Coupon.ListUserCoupons``Coupon.Validate``Coupon.MarkUsed`
- 用户侧 API 已有:`GET /t/:tenantCode/v1/me/coupons`
- 前端已有「我的优惠券」页面,但暂无领取/选择流程。
## 3. 领域规则V1
- `total_quantity = 0` 表示不限量;>0 表示最多可领取次数。
- 每个用户对同一优惠券默认只允许领取一次(可通过规则调整)。
- 过期判断以 `end_at` 为准:`end_at < now` 则视为过期。
- 使用时:订单金额需满足 `min_order_amount`;折扣券需遵守 `max_discount`
## 4. 枚举与类型规范(必做)
- 新增枚举类型并统一使用(避免硬编码字符串):
- `consts.CouponType``fix_amount` / `discount`
- `consts.UserCouponStatus``unused` / `used` / `expired`
- `backend/database/.transform.yaml` 映射:
- `coupons.type -> consts.CouponType`
- `user_coupons.status -> consts.UserCouponStatus`
- 运行 `atomctl gen enum` + `atomctl gen model`,保持生成文件一致性。
## 5. 接口规划(按模块)
### 5.1 用户侧UserCenter
- `GET /t/:tenantCode/v1/me/coupons?status=unused|used|expired`
- 已有,补齐过期自动标记逻辑。
- `GET /t/:tenantCode/v1/me/coupons/available?amount=<int64>`
- 返回「当前订单金额可用」的优惠券列表(用于结算页选择)。
- `POST /t/:tenantCode/v1/me/coupons/receive`
- 领取优惠券(参数:`coupon_id`)。
### 5.2 租户侧CreatorCenter
- `POST /t/:tenantCode/v1/creator/coupons`
- 创建优惠券模板。
- `GET /t/:tenantCode/v1/creator/coupons`
- 分页查询模板列表(支持状态、有效期、类型过滤)。
- `GET /t/:tenantCode/v1/creator/coupons/:id<int>`
- 查看模板详情。
- `PUT /t/:tenantCode/v1/creator/coupons/:id<int>`
- 更新模板(仅未开始或未领取时允许修改核心字段)。
- `POST /t/:tenantCode/v1/creator/coupons/:id<int>/grant`
- 定向发放给用户(参数:`user_ids` 批量)。
## 6. 服务层设计(关键逻辑)
- `Coupon.Create/Update/List/Get`:模板管理。
- `Coupon.Receive`
- 校验有效期与库存(`total_quantity`)。
- 校验用户是否已领取。
- 事务内写入 `user_coupons`
- `Coupon.ListUserCoupons`
- join `coupons` 读取模板信息。
- 对过期券自动标记 `expired`(可更新 DB
- `Coupon.ListAvailable`
- `status = unused`
- `start_at <= now <= end_at`
- `min_order_amount <= amount`
- `Coupon.Validate` / `MarkUsed`
- 已有,改用枚举类型 + 统一错误码语义。
## 7. 并发与一致性
- 领取优惠券时在事务中锁定 `coupons` 行或使用条件更新,防止超发:
- `total_quantity > 0` 时,基于 `COUNT(user_coupons)` 判断库存。
- 若性能成为瓶颈,再考虑新增 `claimed_quantity` 字段V2 优化)。
## 8. 前端联动
- 结算页新增「选择优惠券」抽屉(参考 `docs/design/portal/PAGE_ORDER.md`)。
- 用户中心「优惠券」页保持与后端状态一致unused/used/expired
- 订单创建前调用 `available` 接口,展示可用券。
## 9. 测试规划
- Service 单测:
- 领取成功/重复领取/超库存/过期不可领取。
- Validate金额不足、折扣封顶、跨租户禁止。
- MarkUsed幂等/重复使用失败。
- Order 相关:
- 使用优惠券创建订单成功并核销。
## 10. 实施顺序(建议)
1) 枚举 + transform + gen保证类型安全
2) ServiceReceive/ListAvailable/ListUserCoupons 过期处理。
3) HTTP用户端 + CreatorCenter 管理端接口。
4) 前端:结算页优惠券选择 + 领券入口。
5) 补测试 + 回归订单流程。