# 优惠券状态管理功能说明

## 📋 功能概述

本功能实现了完整的优惠券状态管理系统，包括可用、已使用、过期三种状态的自动管理和API接口。

## 🎯 核心功能

### 1. 状态管理
- **可用状态 (STATUS_UNUSED = 0)**: 优惠券未使用且未过期
- **已使用状态 (STATUS_USED = 1)**: 优惠券已在订单中使用
- **已过期状态 (STATUS_EXPIRED = 2)**: 优惠券已过期

### 2. 自动状态更新
- 定时任务自动检测和更新过期优惠券
- 查询时实时检查优惠券状态
- 订单使用时自动更新状态

### 3. 状态验证
- 订单使用前验证优惠券可用性
- 检查最低消费金额限制
- 验证适用商品范围

## 🔧 API接口

### 用户优惠券查询

#### 获取可用优惠券
```http
GET /api/shop/user-coupon/my/available
```

#### 获取已使用优惠券
```http
GET /api/shop/user-coupon/my/used
```

#### 获取已过期优惠券
```http
GET /api/shop/user-coupon/my/expired
```

#### 获取优惠券统计
```http
GET /api/shop/user-coupon/my/statistics
```

### 优惠券状态管理

#### 验证优惠券可用性
```http
POST /api/shop/coupon-status/validate
Content-Type: application/json

{
  "userCouponId": 1,
  "totalAmount": 150.00,
  "goodsIds": [1, 2, 3]
}
```

#### 使用优惠券
```http
POST /api/shop/coupon-status/use
Content-Type: application/x-www-form-urlencoded

userCouponId=1&orderId=123&orderNo=ORDER123456
```

#### 退还优惠券
```http
POST /api/shop/coupon-status/return/123
```

## 💻 代码使用示例

### 1. 检查优惠券状态
```java
@Autowired
private CouponStatusService couponStatusService;

// 获取用户可用优惠券
List<ShopUserCoupon> availableCoupons = couponStatusService.getAvailableCoupons(userId);

// 检查优惠券是否可用
ShopUserCoupon coupon = shopUserCouponService.getById(couponId);
if (coupon.isAvailable()) {
    // 优惠券可用
}
```

### 2. 使用优惠券
```java
// 验证优惠券
CouponValidationResult result = couponStatusService.validateCouponForOrder(
    userCouponId, totalAmount, goodsIds);

if (result.isValid()) {
    // 使用优惠券
    boolean success = couponStatusService.useCoupon(userCouponId, orderId, orderNo);
}
```

### 3. 实体类便捷方法
```java
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`

### 每小时状态检查（可选）
- **执行时间**: 每小时整点
- **功能**: 及时发现和处理刚过期的优惠券
- **环境**: 仅生产环境执行

## 🗄️ 数据库优化

### 索引优化
```sql
-- 用户优惠券状态查询索引
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;
```

### 视图简化查询
```sql
-- 用户可用优惠券视图
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;
```

## 📊 状态统计

### 优惠券状态分布
```sql
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;
```

### 使用率统计
```sql
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 配置
```yaml
# 优惠券配置
coupon:
  expire:
    # 定时任务执行时间
    cron: "0 0 2 * * ?"  # 每天凌晨2点
  status:
    # 是否启用自动状态更新
    auto-update: true
    # 批量处理大小
    batch-size: 1000
```

## 🚀 部署步骤

### 1. 执行数据库脚本
```bash
mysql -u root -p < src/main/resources/sql/coupon_status_optimization.sql
```

### 2. 更新应用配置
确保 `application.yml` 中包含优惠券相关配置。

### 3. 重启应用
重启应用以加载新的功能和定时任务。

### 4. 验证功能
- 访问 API 文档: `http://localhost:9200/doc.html`
- 测试优惠券状态查询接口
- 检查定时任务日志

## 🐛 故障排查

### 常见问题

1. **定时任务不执行**
   - 检查 `@EnableScheduling` 注解
   - 确认 cron 表达式正确
   - 查看应用日志

2. **状态更新不及时**
   - 检查数据库索引
   - 确认事务配置
   - 查看错误日志

3. **性能问题**
   - 检查数据库索引是否生效
   - 优化查询条件
   - 考虑分页查询

### 日志监控
```bash
# 查看定时任务日志
grep "过期优惠券处理" logs/application.log

# 查看状态更新日志
grep "更新优惠券状态" logs/application.log
```

## 📈 性能优化建议

1. **数据库层面**
   - 添加必要的索引
   - 定期清理过期数据
   - 使用分区表（大数据量时）

2. **应用层面**
   - 使用缓存减少数据库查询
   - 批量处理状态更新
   - 异步处理非关键操作

3. **监控告警**
   - 监控优惠券使用率
   - 设置过期优惠券数量告警
   - 监控定时任务执行状态

## 🔄 后续扩展

1. **消息通知**
   - 优惠券即将过期提醒
   - 优惠券使用成功通知

2. **数据分析**
   - 优惠券使用趋势分析
   - 用户行为分析
   - ROI 计算

3. **高级功能**
   - 优惠券组合使用
   - 动态优惠券推荐
   - A/B 测试支持
