02-优惠券核销前效验接口.md 12 KB

Web端商户优惠券核销接口文档

概述

本接口用于核销订单前的效验,支持代金券和团购券两种类型的验证。


接口信息

核销订单前效验

  • 接口名称:核销订单前效验
  • 接口路径GET /couponManage/verifyOrder
  • 请求方式:GET
  • 接口描述:在核销订单前进行效验,验证券是否可用

请求参数

参数名 类型 必填 说明
orderCode String 劵code(券码)

请求示例

GET /couponManage/verifyOrder?orderCode=ABC123456789

响应参数

成功响应(效验通过)

{
    "code": 200,
    "success": true,
    "data": "效验通过",
    "msg": "效验通过"
}

失败响应示例

1. 券不是待使用状态

{
    "code": 500,
    "success": false,
    "data": null,
    "msg": "该劵不是待使用状态"
}

2. 券不在有效期内

{
    "code": 500,
    "success": false,
    "data": null,
    "msg": "该劵不在有效期内"
}

3. 券在不可用日期内

{
    "code": 500,
    "success": false,
    "data": null,
    "msg": "该劵在不可用日期内"
}

4. 超过今日核销次数

{
    "code": 500,
    "success": false,
    "data": null,
    "msg": "该订单已经超过今日单次核销数量"
}

业务逻辑

验证流程图

开始验证
    ↓
根据券码查询订单券中间表
    ↓
检查券状态(status=1 待使用)
    ↓
查询用户订单
    ↓
判断券类型
    ├─ couponType=1 → 代金券验证流程
    └─ couponType=2 → 团购券验证流程

代金券验证流程

代金券验证开始
    ↓
1. 验证有效期
    ├─ 类型1:指定天数(支付时间+天数)
    └─ 类型2:指定时间段(开始-结束日期)
    ↓
2. 验证不可用日期
    ├─ 类型2:限制星期 + 节日
    └─ 类型3:自定义日期范围
    ↓
3. 验证使用时间段
    ├─ 正常时间段(如 9:00-18:00)
    └─ 跨天时间段(如 22:00-3:00)
    ↓
4. 验证单次核销数量
    └─ 检查今日已核销次数是否超限
    ↓
验证通过

团购券验证流程

团购券验证开始
    ↓
1. 验证有效期
    ├─ 类型0:指定天数(支付时间+天数)
    └─ 类型1:指定时间段(开始-结束日期)
    ↓
2. 验证不可用日期
    ├─ 类型1:限制星期 + 节日
    └─ 类型2:自定义日期范围
    ↓
验证通过

详细验证规则

1. 有效期验证

代金券有效期

ExpirationType 说明 验证逻辑
1 指定天数 支付时间 + 天数 > 当前时间
2 指定时间段 开始时间 ≤ 当前时间 ≤ 结束时间

代金券有效期字段

  • expirationType:有效期类型("1"-指定天数,"2"-指定时间段)
  • expirationDate:有效天数(当类型为1时)
  • validityPeriod:有效时间段(当类型为2时,格式:时间戳1,时间戳2)

团购券有效期

EffectiveDateType 说明 验证逻辑
0 指定天数 支付时间 + 天数 > 当前时间
1 指定时间段 开始日期 ≤ 当前日期 ≤ 结束日期

团购券有效期字段

  • effectiveDateType:有效期类型(0-指定天数,1-指定时间段)
  • effectiveDateValue:有效期值
    • 类型0:天数(如 "30")
    • 类型1:日期段(如 "2025-01-01,2025-12-31")

2. 不可用日期验证

代金券不可用日期

UnusedType 说明 格式 示例
2 限制星期+节日 星期;节日ID 星期一,星期二;1,2,3
3 自定义日期范围 开始,结束;开始,结束 2025-01-01,2025-01-03;2025-02-01,2025-02-05

代金券字段

  • unusedType:不可用类型("2"-限制星期+节日,"3"-自定义日期)
  • unavaiLableDate:不可用日期值

团购券不可用日期

DisableDateType 说明 格式 示例
1 限制星期+节日 星期;节日ID 星期一,星期二;1,2,3
2 自定义日期范围 开始,结束;开始,结束 2025-01-01,2025-01-03;2025-02-01,2025-02-05

团购券字段

  • disableDateType:不可用类型(1-限制星期+节日,2-自定义日期)
  • disableDateValue:不可用日期值

3. 使用时间段验证(仅代金券)

验证当前时间是否在允许使用的时间段内。

字段 说明 格式
buyUseStartTime 开始时间 小时数(0-24)
buyUseEndTime 结束时间 小时数(0-24)

验证规则

正常时间段(如 9-18):
  9 ≤ 当前小时 ≤ 18

跨天时间段(如 22-3):
  当前小时 ≥ 22 OR 当前小时 ≤ 3

示例

  • 9,18:9点到18点可用
  • 22,3:22点到次日3点可用
  • 0,24:全天可用

4. 单次核销数量验证(仅代金券)

验证同一订单今日是否已超过核销次数限制。

字段 说明
singleCanUse 单次可核销次数

验证逻辑

SELECT COUNT(*) 
FROM order_coupon_middle
WHERE order_id = ? 
  AND used_time BETWEEN '今日00:00:00' AND '今日23:59:59'
  AND status = 2

IF count >= singleCanUse THEN
  返回"该订单已经超过今日单次核销数量"

特殊值

  • "0":无限制
  • "1":每天只能核销1次
  • "N":每天最多核销N次

数据库表

涉及的表

  1. order_coupon_middle(订单券中间表)

    • coupon_code:券码
    • status:状态(1-待使用,2-已使用)
    • order_id:订单ID
    • coupon_id:券ID
    • used_time:使用时间
  2. life_user_order(用户订单表)

    • id:订单ID
    • coupon_type:券类型(1-代金券,2-团购)
    • pay_time:支付时间
  3. life_coupon(代金券表)

    • id:券ID
    • expiration_type:有效期类型
    • expiration_date:有效天数
    • validity_period:有效时间段
    • unused_type:不可用类型
    • unavai_lable_date:不可用日期
    • buy_use_start_time:开始使用时间
    • buy_use_end_time:结束使用时间
    • single_can_use:单次可核销次数
  4. life_group_buy_main(团购主表)

    • id:团购ID
    • effective_date_type:有效期类型
    • effective_date_value:有效期值
    • disable_date_type:不可用类型
    • disable_date_value:不可用日期值
  5. essential_holiday_comparison(节日对照表)

    • id:节日ID
    • start_time:开始时间
    • end_time:结束时间

错误码说明

错误信息 说明 处理建议
该劵不是待使用状态 券已被使用/过期/取消 检查券状态
该劵不在有效期内 券已过期或未到使用时间 检查有效期配置
该劵在不可用日期内 当前日期在不可用范围内 更换使用日期
该订单已经超过今日单次核销数量 今日核销次数达到上限 明日再试
订单不存在 订单ID无效 检查订单数据
代金券不存在 券ID无效 检查券数据
团购券不存在 团购ID无效 检查团购数据
有效期配置异常 配置数据格式错误 检查配置
使用时间配置异常 时间格式错误 检查配置

技术实现

Controller 层

@ApiOperation("核销订单前效验")
@GetMapping("/verifyOrder")
public R<String> verifyOrder(@RequestParam("orderCode") String orderCode) {
    log.info("CouponManageController.verifyOrder?orderCode={}", orderCode);
    try {
        return couponManageService.verifyOrder(orderCode);
    } catch (Exception e) {
        log.error("CouponManageController.verifyOrder ERROR: {}", e.getMessage(), e);
        return R.fail("效验失败:" + e.getMessage());
    }
}

Service 层架构

verifyOrder (主入口)
    ↓
    ├─ verifyCoupon (代金券验证)
    │   ├─ validateCouponValidity (有效期验证)
    │   ├─ validateCouponUnavailableDate (不可用日期验证)
    │   ├─ validateCouponUseTime (使用时间验证)
    │   └─ validateCouponSingleUse (单次核销验证)
    │
    └─ verifyGroupBuy (团购券验证)
        ├─ validateGroupBuyValidity (有效期验证)
        └─ validateGroupBuyUnavailableDate (不可用日期验证)

优势

  • ✅ 模块化设计,每个验证逻辑独立
  • ✅ 易于扩展和维护
  • ✅ 完整的日志记录
  • ✅ 详细的异常处理

测试用例

测试场景

1. 正常场景

场景 券码 预期结果
有效的代金券 COUPON001 效验通过
有效的团购券 GROUP001 效验通过

2. 异常场景

场景 预期结果
券码不存在 该劵不是待使用状态
券已使用 该劵不是待使用状态
券已过期 该劵不在有效期内
当前星期不可用 该劵在不可用日期内
当前时间不可用 该劵不在有效期内
超过核销次数 该订单已经超过今日单次核销数量

注意事项

  1. 时间相关

    • 所有时间比较都基于服务器当前时间
    • 跨天时间段需要特殊处理(如22点-3点)
    • 日期格式统一使用 yyyy-MM-dd
  2. 数据格式

    • 多个值使用逗号分隔(如 星期一,星期二
    • 范围值使用分号分隔(如 星期;节日ID
    • 日期范围使用逗号分隔(如 2025-01-01,2025-01-03
  3. 空值处理

    • 配置为空或"0"时,表示无限制
    • 需要对所有字段进行空值检查
  4. 性能优化

    • 数据库查询使用索引(券码、订单ID等)
    • 复杂验证逻辑可考虑缓存节日信息
  5. 安全性

    • 验证失败统一返回错误信息,不暴露内部逻辑
    • 记录详细日志用于问题排查

迁移说明

原接口(app端)

  • 路径/alienStore/coupon/orderVerify
  • ControllerLifeCouponController
  • ServiceLifeCouponService.orderVerify()

新接口(web端)

  • 路径/couponManage/verifyOrder
  • ControllerCouponManageController
  • ServiceCouponManageService.verifyOrder()

改进点

  1. 代码结构优化

    • 将验证逻辑拆分为多个独立方法
    • 每个验证步骤职责单一
  2. 错误处理增强

    • 添加更详细的异常信息
    • 完整的日志记录
  3. 代码可读性

    • 使用清晰的方法命名
    • 添加详细的注释
  4. 业务逻辑复用

    • 完全复用原有业务逻辑
    • 保持与app端一致的验证规则

更新日志

2025-11-13

新增功能

  • ✅ 创建 CouponManageController(优惠券管理控制器)
  • ✅ 创建 CouponManageService 接口
  • ✅ 创建 CouponManageServiceImpl 实现类
  • ✅ 实现 verifyOrder 核销前效验接口
  • ✅ 支持代金券和团购券两种类型验证
  • ✅ 完整的验证逻辑:
    • 有效期验证
    • 不可用日期验证
    • 使用时间段验证
    • 单次核销数量验证
  • ✅ 完整的日志记录和异常处理
  • ✅ Linter检查:无错误

涉及文件

  • CouponManageController.java - 新增
  • CouponManageService.java - 新增
  • CouponManageServiceImpl.java - 新增
  • API_COUPON_VERIFY.md - 新增(本文档)

开发人员:ssk


常见问题

Q1:券码格式有什么要求?

A:券码由系统生成,通常是字母+数字组合,无固定格式要求。

Q2:一张券可以被核销多次吗?

A:取决于代金券的 singleCanUse 配置:

  • "0":无限制
  • "1":每天只能核销1次
  • "N":每天最多核销N次

Q3:跨天时间段如何处理?

A:例如22点-3点表示22:00-次日03:00,验证逻辑为:

当前小时 >= 22 OR 当前小时 <= 3 → 可用

Q4:节日ID从哪里获取?

A:节日ID来自 essential_holiday_comparison 表,由系统管理员配置。

Q5:如何测试这个接口?

A

  1. 准备测试数据(创建订单券)
  2. 使用 Swagger UI 测试:http://localhost:port/doc.html
  3. 或使用 Postman/curl 发送GET请求

文档版本:v1.0
最后更新:2025-11-13
维护人员:ssk