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 = 禁用
    • CouponStatusCouponUserStatus 为多态状态机,不遵循布尔语义规范

待完善功能

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