You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
6.3 KiB
6.3 KiB
优惠券状态管理功能说明
📋 功能概述
本功能实现了完整的优惠券状态管理系统,包括可用、已使用、过期三种状态的自动管理和API接口。
🎯 核心功能
1. 状态管理
- 可用状态 (STATUS_UNUSED = 0): 优惠券未使用且未过期
- 已使用状态 (STATUS_USED = 1): 优惠券已在订单中使用
- 已过期状态 (STATUS_EXPIRED = 2): 优惠券已过期
2. 自动状态更新
- 定时任务自动检测和更新过期优惠券
- 查询时实时检查优惠券状态
- 订单使用时自动更新状态
3. 状态验证
- 订单使用前验证优惠券可用性
- 检查最低消费金额限制
- 验证适用商品范围
🔧 API接口
用户优惠券查询
获取可用优惠券
GET /api/shop/user-coupon/my/available
获取已使用优惠券
GET /api/shop/user-coupon/my/used
获取已过期优惠券
GET /api/shop/user-coupon/my/expired
获取优惠券统计
GET /api/shop/user-coupon/my/statistics
优惠券状态管理
验证优惠券可用性
POST /api/shop/coupon-status/validate
Content-Type: application/json
{
"userCouponId": 1,
"totalAmount": 150.00,
"goodsIds": [1, 2, 3]
}
使用优惠券
POST /api/shop/coupon-status/use
Content-Type: application/x-www-form-urlencoded
userCouponId=1&orderId=123&orderNo=ORDER123456
退还优惠券
POST /api/shop/coupon-status/return/123
💻 代码使用示例
1. 检查优惠券状态
@Autowired
private CouponStatusService couponStatusService;
// 获取用户可用优惠券
List<ShopUserCoupon> availableCoupons = couponStatusService.getAvailableCoupons(userId);
// 检查优惠券是否可用
ShopUserCoupon coupon = shopUserCouponService.getById(couponId);
if (coupon.isAvailable()) {
// 优惠券可用
}
2. 使用优惠券
// 验证优惠券
CouponValidationResult result = couponStatusService.validateCouponForOrder(
userCouponId, totalAmount, goodsIds);
if (result.isValid()) {
// 使用优惠券
boolean success = couponStatusService.useCoupon(userCouponId, orderId, orderNo);
}
3. 实体类便捷方法
ShopUserCoupon userCoupon = shopUserCouponService.getById(id);
// 判断状态
boolean available = userCoupon.isAvailable(); // 是否可用
boolean used = userCoupon.isUsed(); // 是否已使用
boolean expired = userCoupon.isExpired(); // 是否已过期
// 获取状态描述
String statusDesc = userCoupon.getStatusDesc(); // "可使用"、"已使用"、"已过期"
// 标记为已使用
userCoupon.markAsUsed(orderId, orderNo);
// 标记为已过期
userCoupon.markAsExpired();
⏰ 定时任务
过期优惠券处理
- 执行时间: 每天凌晨2点(生产环境)
- 功能: 自动将过期的优惠券状态更新为已过期
- 配置:
coupon.expire.cron
每小时状态检查(可选)
- 执行时间: 每小时整点
- 功能: 及时发现和处理刚过期的优惠券
- 环境: 仅生产环境执行
🗄️ 数据库优化
索引优化
-- 用户优惠券状态查询索引
CREATE INDEX idx_user_coupon_status ON shop_user_coupon(user_id, status, expire_time);
-- 过期优惠券查询索引
CREATE INDEX idx_user_coupon_expire ON shop_user_coupon(expire_time) WHERE status = 0;
-- 订单优惠券查询索引
CREATE INDEX idx_user_coupon_order ON shop_user_coupon(order_id) WHERE status = 1;
视图简化查询
-- 用户可用优惠券视图
CREATE VIEW v_user_available_coupons AS
SELECT uc.*, c.name as coupon_name
FROM shop_user_coupon uc
LEFT JOIN shop_coupon c ON uc.coupon_id = c.id
WHERE uc.deleted = 0;
📊 状态统计
优惠券状态分布
SELECT
status,
CASE
WHEN status = 0 THEN '未使用'
WHEN status = 1 THEN '已使用'
WHEN status = 2 THEN '已过期'
END as status_name,
COUNT(*) as count
FROM shop_user_coupon
WHERE deleted = 0
GROUP BY status;
使用率统计
SELECT
DATE(create_time) as date,
COUNT(*) as issued_count,
SUM(CASE WHEN status = 1 THEN 1 ELSE 0 END) as used_count,
ROUND(SUM(CASE WHEN status = 1 THEN 1 ELSE 0 END) * 100.0 / COUNT(*), 2) as usage_rate
FROM shop_user_coupon
WHERE deleted = 0
GROUP BY DATE(create_time);
🔧 配置说明
application.yml 配置
# 优惠券配置
coupon:
expire:
# 定时任务执行时间
cron: "0 0 2 * * ?" # 每天凌晨2点
status:
# 是否启用自动状态更新
auto-update: true
# 批量处理大小
batch-size: 1000
🚀 部署步骤
1. 执行数据库脚本
mysql -u root -p < src/main/resources/sql/coupon_status_optimization.sql
2. 更新应用配置
确保 application.yml
中包含优惠券相关配置。
3. 重启应用
重启应用以加载新的功能和定时任务。
4. 验证功能
- 访问 API 文档:
http://localhost:9200/doc.html
- 测试优惠券状态查询接口
- 检查定时任务日志
🐛 故障排查
常见问题
-
定时任务不执行
- 检查
@EnableScheduling
注解 - 确认 cron 表达式正确
- 查看应用日志
- 检查
-
状态更新不及时
- 检查数据库索引
- 确认事务配置
- 查看错误日志
-
性能问题
- 检查数据库索引是否生效
- 优化查询条件
- 考虑分页查询
日志监控
# 查看定时任务日志
grep "过期优惠券处理" logs/application.log
# 查看状态更新日志
grep "更新优惠券状态" logs/application.log
📈 性能优化建议
-
数据库层面
- 添加必要的索引
- 定期清理过期数据
- 使用分区表(大数据量时)
-
应用层面
- 使用缓存减少数据库查询
- 批量处理状态更新
- 异步处理非关键操作
-
监控告警
- 监控优惠券使用率
- 设置过期优惠券数量告警
- 监控定时任务执行状态
🔄 后续扩展
-
消息通知
- 优惠券即将过期提醒
- 优惠券使用成功通知
-
数据分析
- 优惠券使用趋势分析
- 用户行为分析
- ROI 计算
-
高级功能
- 优惠券组合使用
- 动态优惠券推荐
- A/B 测试支持