feat(优惠券): 实现优惠券状态管理功能

- 新增优惠券状态管理相关实体类字段和方法
- 实现优惠券状态自动更新和手动更新功能- 添加优惠券适用范围验证逻辑
- 新增优惠券状态查询和统计接口
- 优化数据库索引和查询性能
This commit is contained in:
2025-08-15 00:35:55 +08:00
parent b09141e848
commit b2e0aa9f28
13 changed files with 1681 additions and 14 deletions

View File

@@ -170,3 +170,20 @@ springdoc:
# 启用 Knife4j
knife4j:
enable: true
# 优惠券配置
coupon:
# 过期处理定时任务配置
expire:
# 定时任务执行时间cron表达式
# 生产环境每天凌晨2点执行
# 开发环境每10分钟执行一次
cron: "0 0 2 * * ?"
# 开发环境可以设置为: "0 */10 * * * ?"
# 状态管理配置
status:
# 是否启用自动状态更新
auto-update: true
# 批量处理大小
batch-size: 1000

View File

@@ -0,0 +1,194 @@
-- 优惠券状态管理优化SQL脚本
-- 作者: WebSoft
-- 日期: 2025-01-15
-- 说明: 优化优惠券查询性能,添加必要的索引
-- ========================================
-- 1. 添加索引优化查询性能
-- ========================================
-- 用户优惠券表索引优化
CREATE INDEX IF NOT EXISTS idx_user_coupon_status ON shop_user_coupon(user_id, status, expire_time);
CREATE INDEX IF NOT EXISTS idx_user_coupon_expire ON shop_user_coupon(expire_time) WHERE status = 0;
CREATE INDEX IF NOT EXISTS idx_user_coupon_order ON shop_user_coupon(order_id) WHERE status = 1;
-- 优惠券模板表索引优化
CREATE INDEX IF NOT EXISTS idx_coupon_status_expire ON shop_coupon(status, expire_type, end_time);
-- ========================================
-- 2. 统一状态字段(如果需要数据迁移)
-- ========================================
-- 检查现有数据的状态一致性
SELECT
'状态一致性检查' as check_item,
COUNT(*) as total_count,
SUM(CASE WHEN status = 0 AND is_use = 0 AND is_expire = 0 THEN 1 ELSE 0 END) as available_count,
SUM(CASE WHEN status = 1 AND is_use = 1 THEN 1 ELSE 0 END) as used_count,
SUM(CASE WHEN status = 2 OR is_expire = 1 THEN 1 ELSE 0 END) as expired_count,
SUM(CASE WHEN
(status = 0 AND (is_use = 1 OR is_expire = 1)) OR
(status = 1 AND is_use = 0) OR
(status = 2 AND is_expire = 0)
THEN 1 ELSE 0 END) as inconsistent_count
FROM shop_user_coupon;
-- 修复状态不一致的数据
UPDATE shop_user_coupon
SET status = 1, is_use = 1
WHERE status = 0 AND is_use = 1 AND is_expire = 0;
UPDATE shop_user_coupon
SET status = 2, is_expire = 1
WHERE status = 0 AND is_expire = 1;
UPDATE shop_user_coupon
SET status = 2, is_expire = 1
WHERE status IN (0, 1) AND end_time < NOW();
-- ========================================
-- 3. 添加触发器自动更新过期状态(可选)
-- ========================================
DELIMITER $$
-- 创建触发器:在查询时自动检查过期状态
CREATE TRIGGER IF NOT EXISTS tr_check_coupon_expire
BEFORE UPDATE ON shop_user_coupon
FOR EACH ROW
BEGIN
-- 如果是未使用状态且已过期,自动更新为过期状态
IF NEW.status = 0 AND NEW.end_time < NOW() THEN
SET NEW.status = 2;
SET NEW.is_expire = 1;
END IF;
END$$
DELIMITER ;
-- ========================================
-- 4. 创建视图简化查询
-- ========================================
-- 创建用户可用优惠券视图
CREATE OR REPLACE VIEW v_user_available_coupons AS
SELECT
uc.*,
c.name as coupon_name,
c.description as coupon_description,
c.apply_range,
c.apply_range_config,
CASE
WHEN uc.end_time < NOW() THEN '已过期'
WHEN uc.status = 1 THEN '已使用'
WHEN uc.status = 0 THEN '可使用'
ELSE '未知状态'
END as status_desc
FROM shop_user_coupon uc
LEFT JOIN shop_coupon c ON uc.coupon_id = c.id
WHERE uc.deleted = 0;
-- 创建优惠券统计视图
CREATE OR REPLACE VIEW v_coupon_statistics AS
SELECT
user_id,
COUNT(*) as total_count,
SUM(CASE WHEN status = 0 AND end_time >= NOW() THEN 1 ELSE 0 END) as available_count,
SUM(CASE WHEN status = 1 THEN 1 ELSE 0 END) as used_count,
SUM(CASE WHEN status = 2 OR end_time < NOW() THEN 1 ELSE 0 END) as expired_count
FROM shop_user_coupon
WHERE deleted = 0
GROUP BY user_id;
-- ========================================
-- 5. 存储过程:批量处理过期优惠券
-- ========================================
DELIMITER $$
CREATE PROCEDURE IF NOT EXISTS sp_update_expired_coupons()
BEGIN
DECLARE done INT DEFAULT FALSE;
DECLARE update_count INT DEFAULT 0;
-- 声明异常处理
DECLARE CONTINUE HANDLER FOR SQLEXCEPTION
BEGIN
ROLLBACK;
RESIGNAL;
END;
START TRANSACTION;
-- 批量更新过期优惠券
UPDATE shop_user_coupon
SET status = 2, is_expire = 1
WHERE status = 0
AND end_time < NOW()
AND deleted = 0;
-- 获取更新数量
SET update_count = ROW_COUNT();
COMMIT;
-- 返回更新数量
SELECT update_count as updated_count;
END$$
DELIMITER ;
-- ========================================
-- 6. 性能监控查询
-- ========================================
-- 查看优惠券状态分布
SELECT
status,
CASE
WHEN status = 0 THEN '未使用'
WHEN status = 1 THEN '已使用'
WHEN status = 2 THEN '已过期'
ELSE '未知'
END as status_name,
COUNT(*) as count,
ROUND(COUNT(*) * 100.0 / (SELECT COUNT(*) FROM shop_user_coupon WHERE deleted = 0), 2) as percentage
FROM shop_user_coupon
WHERE deleted = 0
GROUP BY status
ORDER BY status;
-- 查看即将过期的优惠券7天内
SELECT
COUNT(*) as expiring_soon_count,
MIN(end_time) as earliest_expire_time,
MAX(end_time) as latest_expire_time
FROM shop_user_coupon
WHERE status = 0
AND end_time BETWEEN NOW() AND DATE_ADD(NOW(), INTERVAL 7 DAY)
AND deleted = 0;
-- 查看优惠券使用率统计
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
AND create_time >= DATE_SUB(NOW(), INTERVAL 30 DAY)
GROUP BY DATE(create_time)
ORDER BY date DESC;
-- ========================================
-- 7. 清理和维护
-- ========================================
-- 清理过期很久的优惠券记录(可选,谨慎使用)
-- DELETE FROM shop_user_coupon
-- WHERE status = 2
-- AND end_time < DATE_SUB(NOW(), INTERVAL 1 YEAR)
-- AND deleted = 0;
COMMIT;