scaffold-coupon 优惠券模块

模块概述

scaffold-coupon 是 Scaffold v2 的优惠券管理模块,提供完整的优惠券生命周期管理:模板创建、审核、发放、领取、核销、统计。支持多种券类型(满减/折扣/立减)、多发放渠道(内部渠道 + 微信卡券)、多种核销方式(扫码/手动/线上)。采用 SPI + 策略模式实现可插拔扩展。

功能列表

  • 优惠券模板管理:创建/更新/删除/审核/变更状态,支持满减券、折扣券、立减券
  • 优惠券发放:创建发放批次、指定用户发放、暂停/恢复发放
  • 用户优惠券:领取/查询我的券/下单时可用券查询
  • 优惠券核销:扫码核销、手动核销、核销回退、生成核销码
  • 优惠券统计:全局统计概览、按模板统计
  • 定时任务:过期提醒(每天 9 点)、过期状态更新(每小时)
  • 多渠道策略:内部渠道已完成,微信卡券渠道(骨架已就绪)

核心组件

分层架构

层 类 职责
Controller CouponTemplateController, CouponPublishController, CouponUserController, CouponStatisticsController, CouponVerifyController, MobileCouponController REST 接口
Service CouponTemplateService, CouponPublishService, CouponUserService, CouponStatisticsService, CouponVerifyService, CouponNotifyService 业务逻辑
Repository CouponTemplateRepository, CouponChannelConfigRepository, CouponPublishBatchRepository, CouponUserRepository, CouponVerifyRecordRepository, CouponVerifyCodeRepository, CouponNotifyLogRepository 数据访问
Mapper 对应 7 个实体的 Mapper ORM 映射

数据实体

实体 说明
CouponTemplate 优惠券模板,定义券类型/面额/使用条件/有效期/库存等
CouponUser 用户持有的优惠券
CouponPublishBatch 发放批次
CouponChannelConfig 渠道配置(内部/微信)
CouponNotifyLog 通知日志
CouponVerifyCode 核销码
CouponVerifyRecord 核销记录

枚举类型

枚举 值 说明
CouponType FULL_REDUCTION / DISCOUNT / FIXED 满减券 / 折扣券 / 立减券
CouponCategory GENERAL / CATEGORY / PRODUCT 通用 / 品类 / 单品
CouponValidityType FIXED / RELATIVE 固定时间段 / 领取后 N 天
CouponStatus DRAFT / ENABLED / DISABLED / EXPIRED 草稿/启用/禁用/过期
CouponUserStatus UNUSED / USED / EXPIRED 未使用/已使用/已过期
PublishType AUTO / MANUAL 自动发放/手动发放
VerifyType ONLINE / MANUAL / SCAN 线上/手动/扫码
RefundPolicy REFUNDABLE / NON_REFUNDABLE 可退/不可退

状态字段规范:

  • enabled 字段遵循布尔语义:1 = 启用,0 = 禁用

SPI 扩展点

模块通过 SPI 机制实现 5 个可插拔扩展点,均定义了 Default 默认实现,业务模块可覆盖。

CouponStockOperator -- 库存操作

控制优惠券库存的扣减/回补/查询/限购检查。

方法 说明
deductStock(templateId, count) 扣减库存
addStock(templateId, count) 回补库存
getStock(templateId) 查询库存
checkUserLimit(templateId, userId, perLimit) 检查用户限领
incrementUserClaimed(templateId, userId) 记录用户已领数量
  • 默认实现:DbCouponStockOperator(数据库操作)
  • 增强实现:RedisCouponStockOperator(Redis 原子操作,依赖 scaffold-redis)

CouponProductChecker -- 商品范围校验

校验商品是否在优惠券适用范围内。

方法 说明
isProductInScope(productId, scopeConfig) 单个商品校验
filterProducts(productIds, scopeConfig) 批量过滤
  • 默认实现:DefaultCouponProductChecker(始终返回 true)
  • 增强实现:ProductCouponProductChecker(依赖 scaffold-product)

CouponNotifier -- 通知服务

发送优惠券相关通知(过期提醒、领取成功等)。

方法 说明
notifyExpire(userId, couponName, expireTime) 过期提醒
notifyClaimSuccess(userId, couponName) 领取成功通知
  • 默认实现:DefaultCouponNotifier(日志输出)
  • 增强实现:WechatCouponNotifier(微信模板消息,依赖 scaffold-wechat)

CouponApprovalHandler -- 审批流程

优惠券模板的审核流程对接。

方法 说明
submitApproval(templateId, templateName) 提交审核
queryApprovalStatus(templateId) 查询审核状态
  • 默认实现:DefaultCouponApprovalHandler(直接通过)
  • 增强实现:BpmCouponApprovalHandler(BPM 审批,依赖 scaffold-bpm)

CouponPaymentHandler -- 折扣计算

下单时计算优惠券折扣金额。

方法 说明
calculateDiscount(couponUserId, orderAmount) 计算折扣金额
  • 默认实现:DefaultCouponPaymentHandler(按模板规则计算)

渠道策略 CouponChannelStrategy

控制优惠券在不同渠道的发布/领取/核销/回退。支持内部渠道和微信卡券渠道。

方法 说明
publish(template, config) 发布到渠道
sync(template, config) 同步状态
revoke(config) 撤回
claim(userId, template, config) 渠道领取
verify(couponUser, config) 渠道核销
rollbackVerify(couponUser, record, config) 核销回退
  • 内部渠道:InternalCouponChannelStrategy(完整实现)
  • 微信卡券渠道:WechatCouponChannelStrategy(骨架已就绪,6 个 TODO 待接入 WxMpCardService)

配置参数

配置前缀:scaffold.coupon

参数 类型 默认值 说明
enabled boolean true 模块开关

API 接口列表

CouponTemplateController -- 优惠券模板管理 (/v1/coupon/template)

方法 路径 说明
POST /create 创建优惠券模板
POST /update 更新优惠券模板
POST /delete/{id} 删除优惠券模板
POST /submitAudit/{id} 提交审核
POST /changeStatus?id=&status= 变更状态
GET /detail?id= 模板详情
POST /page 分页查询

CouponPublishController -- 优惠券发放管理 (/v1/coupon/publish)

方法 路径 说明
POST /create 创建发放批次
POST /assign 指定用户发放
POST /changeStatus?id=&status= 暂停/恢复
POST /page 发放批次分页

CouponUserController -- 用户优惠券 (/v1/coupon/user)

方法 路径 说明
POST /claim 领取优惠券
POST /myList 我的券列表
GET /detail?id= 券详情
POST /available?userId=&orderNo= 下单时可用券

CouponVerifyController -- 优惠券核销管理 (/v1/coupon/verify)

方法 路径 说明
POST /scan 扫码核销
POST /manual 手动核销
POST /rollback?id= 核销回退
POST /generateCode?couponUserId= 生成核销码
POST /page 核销记录分页
GET /detail?id= 核销记录详情

CouponStatisticsController -- 优惠券数据统计 (/v1/coupon/statistics)

方法 路径 说明
GET /overview 全局统计概览
GET /template?templateId= 按模板统计

MobileCouponController -- 移动端优惠券 (/v1/mobile/coupon)

方法 路径 说明
POST /list 可领取优惠券列表
POST /claim 移动端领券
POST /my 我的优惠券

使用示例

1. 创建满减券模板

POST /v1/coupon/template/create
{
  "name": "满100减20",
  "type": "FULL_REDUCTION",
  "category": "GENERAL",
  "faceValue": 2000,
  "minAmount": 10000,
  "validityType": "RELATIVE",
  "validDays": 30,
  "totalStock": 1000,
  "perLimit": 1,
  "refundPolicy": "NON_REFUNDABLE"
}

2. 创建发放批次

POST /v1/coupon/publish/create
{
  "templateId": 100,
  "channel": "INTERNAL",
  "publishType": "AUTO",
  "startTime": "2026-04-27 00:00:00",
  "endTime": "2026-05-27 23:59:59"
}

3. 用户领取优惠券

POST /v1/coupon/user/claim
{
  "templateId": 100
}

4. 核销优惠券

POST /v1/coupon/verify/scan
{
  "couponUserId": 200,
  "verifyCode": "ABC123"
}

注意事项

  1. SPI 覆盖机制:默认 SPI 实现通过 @ConditionalOnMissingBean 注册,业务模块只需提供对应接口的实现类并标记为 @Component/@Service 即可覆盖
  2. 金额单位:faceValue(面额)和 minAmount(最低消费)统一使用分为单位
  3. 库存安全:默认使用数据库库存操作;生产环境建议启用 RedisCouponStockOperator,使用 Redis 原子操作防止超发
  4. 有效期:FIXED 类型为固定时间段(startTime/endTime),RELATIVE 类型为领取后 N 天生效
  5. 定时任务:过期提醒每天 9 点执行,过期状态更新每小时执行,需确保 @EnableScheduling 已开启
  6. 状态枚举:
    • enabled 字段遵循布尔语义:1 = 启用,0 = 禁用
    • CouponStatus、CouponUserStatus 为多态状态机,不遵循布尔语义规范

待完善功能

  • 微信卡券渠道接入(WechatCouponChannelStrategy 中 6 个 TODO):
    • 调用 WxJava 的 WxMpCardService 创建/同步/删除/领取/核销/取消核销卡券