Files
kami_backend/internal/logic/jd_cookie/README.md
danial bc2d58753b feat(jd_cookie):重构订单创建逻辑并优化相关模型
- 新增 CreateOrderReq 结构体用于统一订单创建参数- 修改 CreateOrder 方法签名,使用结构体传参替代多个参数
- 更新 jd_cookie 相关枚举值,增加 JdCookieStatusUnknown 状态
- 调整 OrderInfo 和 JdOrderInfo 模型字段,增强数据一致性
-优化订单与京东订单关联逻辑,移除冗余的 CurrentOrderId 字段
- 移除 ShouldExtractCard 方法,改为内部私有方法 shouldExtractCard- 精简 Callback 方法参数,移除不必要的 userOrderId 和 amount 参数
- 修复订单历史记录中订单号关联问题,直接使用 orderId 字段查询
- 更新控制器层参数传递方式,适配新的服务层接口定义
- 调整卡密提取逻辑,去除对用户订单实体的依赖
- 完善订单状态检查机制,提高卡密提取安全性
- 优化数据库查询逻辑,减少不必要的关联查询操作
2025-10-18 14:13:40 +08:00

7.7 KiB
Raw Blame History

JD Cookie 订单管理模块

📁 文件结构

jd_cookie/
├── account.go          # Cookie 账户管理
├── history.go          # 历史记录管理
├── index.go            # 服务注册
├── order_create.go     # 订单创建逻辑(带重试机制)
├── order_query.go      # 订单查询逻辑
├── order_jd.go         # 京东订单管理逻辑
├── order_utils.go      # 订单工具方法
├── order_test.go       # 测试文件
└── rotation.go         # Cookie 轮询

🎯 核心功能

1. 订单创建(带重试机制)

文件order_create.go

主要方法

  • CreateOrder() - 创建订单主入口
  • createNewJdOrderWithRetry() - 带重试的京东订单创建

流程

1. 检查订单是否已存在 → 已存在返回支付链接
2. 尝试复用现有京东订单
   ├─ 支付链接未过期 → 直接复用
   ├─ 支付链接已过期 → 尝试刷新
   │  ├─ 刷新成功 → 使用新链接
   │  └─ 刷新失败 → 标记失效,创建新订单
   └─ 无可复用订单 → 创建新订单
3. 创建新订单时启用重试机制
   ├─ 最多重试 10 次
   ├─ 每次失败自动切换 Cookie
   └─ 记录所有尝试过的 Cookie

重试机制详解

// 示例:创建订单时的重试流程
orderId := "ORDER123"
amount := 100.0
category := consts.ProductCategoryApple

// 调用创建订单
createOrderReq := &model.CreateOrderReq{
    UserOrderId: orderId,
    Amount:      amount,
    Category:    category,
}
result, err := service.CreateOrder(ctx, createOrderReq)
if err != nil {
    // 所有 Cookie 都失败,返回错误
    // 错误信息会包含:已尝试的 Cookie 数量
    return err
}
wxPayUrl := result.WxPayUrl
jdOrderId := result.JdOrderId

// 成功返回支付链接

内部重试逻辑

func createNewJdOrderWithRetry(...) {
    const maxRetryCount = 10
    var triedCookies []string
    
    for retryCount := 0; retryCount < maxRetryCount; retryCount++ {
        // 1. 获取可用 Cookie
        cookieId, err := GetAvailableCookie(ctx)
        if err != nil {
            break // 无可用 Cookie停止重试
        }
        
        // 2. 检查是否已尝试过
        if hasCookieBeenTried(triedCookies, cookieId) {
            continue
        }
        
        // 3. 记录已尝试
        triedCookies = append(triedCookies, cookieId)
        
        // 4. 调用京东下单
        jdOrderId, payId, wxPayUrl, err := callJdCreateOrder(ctx, cookieId, amount, category)
        if err != nil {
            // 失败:更新 Cookie 状态,继续下一次重试
            handleCookieFailure(ctx, cookieId, orderId)
            continue
        }
        
        // 5. 成功:创建订单记录并返回
        createJdOrderRecord(...)
        return jdOrderId, cookieId, wxPayUrl, nil
    }
    
    // 所有重试失败
    return "", "", "", error
}

2. 订单查询

文件order_query.go

主要方法

  • GetOrder() - 获取单个订单
  • ListOrder() - 订单列表查询
  • GetOrderStatus() - 查询订单状态
  • GetPaymentUrl() - 获取支付链接

示例

// 获取订单信息
order, err := service.GetOrder(ctx, "ORDER123")
if err != nil {
    return err
}

// 获取支付链接
wxPayUrl, expireTime, jdOrderId, err := service.GetPaymentUrl(ctx, "ORDER123")

3. 京东订单管理

文件order_jd.go

主要方法

  • GetJdOrder() - 获取京东订单
  • ListJdOrder() - 京东订单列表
  • CheckJdOrderPayment() - 检查支付状态
  • ExtractCardInfo() - 提取卡密信息
  • BatchCheckPaymentStatus() - 批量检查支付状态(定时任务)
  • CleanupExpiredOrders() - 清理过期订单(定时任务)
  • ReleaseExpiredJdOrders() - 释放过期订单关联(定时任务)

定时任务

// 批量检查支付状态(建议每 5 分钟执行)
err := service.BatchCheckPaymentStatus(ctx)

// 清理过期订单(建议每小时执行)
err := service.CleanupExpiredOrders(ctx)

// 释放过期订单关联(建议每 10 分钟执行)
err := service.ReleaseExpiredJdOrders(ctx)

4. 工具方法

文件order_utils.go

内部方法(不对外暴露):

  • 数据库查询:getOrderByOrderId(), getJdOrderByJdOrderId(), getCookieById()
  • 数据库更新:createJdOrderRecord(), createOrderRecord(), updateOrderLastRequest()
  • 京东接口:callJdCreateOrder(), refreshPaymentUrl(), callJdCheckPayment()
  • Cookie 处理:handleCookieFailure()

🔧 配置常量

internal/consts/jd_cookie.go 中定义:

const (
    JdCookieMaxFailureCount = 3    // Cookie 最大失败次数
    JdCookieSuspendDuration = 10   // Cookie 暂停时长(分钟)
    JdOrderExpireDuration   = 24   // 京东订单过期时间(小时)
    WxPayUrlExpireDuration  = 3    // 微信支付链接过期时间(分钟)
    JdOrderReuseTimeout     = 30   // 京东订单复用超时时间(分钟)
)

📊 状态流转

创建 → 正常 ⇄ 暂停 → 失效
              ↓
            删除

京东订单状态

待支付 → 已支付 → 已发货
  ↓
已过期/已取消

用户订单状态

待支付 → 已支付
  ↓
已过期/已取消

🚨 错误处理

// 自动处理流程:
1. 失败次数 +1
2. 失败次数 < 3  状态改为"暂停"10 分钟后自动恢复
3. 失败次数 >= 3  状态改为"失效"
4. 记录失败历史

订单创建失败

// 重试机制:
1. 尝试 Cookie 1  失败  暂停 Cookie 1
2. 尝试 Cookie 2  失败  暂停 Cookie 2
3. ...
4. 尝试 Cookie 10  失败  返回错误

📝 历史记录

所有重要操作都会记录历史:

  • 创建 (create)
  • 使用 (use)
  • 暂停 (suspend)
  • 恢复 (resume)
  • 失败 (fail)
  • 刷新失败 (refresh_fail) - 新增
  • 被替换 (replaced) - 新增
  • 删除 (delete)
  • 更新 (update)

京东订单变更历史

  • 创建 (create)
  • 绑定 (bind)
  • 解绑 (unbind)
  • 支付 (pay)
  • 过期 (expire)
  • 失效 (invalid) - 新增
  • 替换 (replace)

用户订单变更历史

  • 创建 (create)
  • 绑定 (bind)
  • 支付 (pay)
  • 过期 (expire)
  • 重新绑定 (rebind)

🧪 测试

运行测试:

go test ./internal/logic/jd_cookie/... -v

测试覆盖:

  • 卡密提取判断逻辑
  • 批量检查配置验证
  • 缓存键生成

🔍 日志示例

订单创建成功

[INFO] 复用现有京东订单 {"orderId":"ORDER123","jdOrderId":"JD456","cookieId":"COOKIE789"}
[INFO] 创建订单记录成功 {"orderId":"ORDER123","amount":100,"jdOrderId":"JD456"}

刷新支付链接失败

[WARN] 刷新支付链接失败,将创建新订单 {"jdOrderId":"JD456","error":"刷新失败"}
[INFO] 创建京东订单成功 {"orderId":"ORDER123","jdOrderId":"JD789","cookieId":"COOKIE999","retryCount":1}
[WARN] 京东下单失败尝试切换Cookie重试 {"orderId":"ORDER123","cookieId":"COOKIE1","retryCount":0,"error":"下单失败"}
[WARN] 京东下单失败尝试切换Cookie重试 {"orderId":"ORDER123","cookieId":"COOKIE2","retryCount":1,"error":"下单失败"}
[INFO] 创建京东订单成功 {"orderId":"ORDER123","jdOrderId":"JD789","cookieId":"COOKIE3","retryCount":2}

📚 相关文档


最后更新2025-10-11