Files
quyun-v2/docs/coupon_plan.md

4.1 KiB
Raw Blame History

优惠券功能规划(先规划,后执行)

1. 目标与范围

  • 支持租户侧创建/管理优惠券模板。
  • 支持用户领取/选择/使用优惠券,订单创建时自动校验与核销。
  • 优惠券状态可追踪:未使用/已使用/已过期。
  • 保持多租户隔离,避免跨租户误用。

2. 当前现状

  • 数据表已存在:couponsuser_couponsorders.coupon_id
  • 服务层已有部分能力:Coupon.ListUserCouponsCoupon.ValidateCoupon.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.CouponTypefix_amount / discount
    • consts.UserCouponStatusunused / 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. 补测试 + 回归订单流程。