# 京东Cookie管理模块重构设计

<cite>
**本文档引用文件**  
- [jd_cookie_tables.sql](file://sql/jd_cookie_tables.sql)
- [jd_cookie.go](file://internal/service/jd_cookie.go)
- [account.go](file://internal/logic/jd_cookie/account.go)
- [order.go](file://internal/logic/jd_cookie/order.go)
- [rotation.go](file://internal/logic/jd_cookie/rotation.go)
- [jd_cookie.go](file://internal/consts/jd_cookie.go)
- [v1/account.go](file://api/jd_cookie/v1/account.go)
- [v1/order.go](file://api/jd_cookie/v1/order.go)
</cite>

## 目录
1. [引言](#引言)
2. [架构设计与业务场景](#架构设计与业务场景)
3. [数据库表结构与索引设计](#数据库表结构与索引设计)
4. [API接口规范](#api接口规范)
5. [业务逻辑](#业务逻辑)
6. [支付链接管理与失效处理流程](#支付链接管理与失效处理流程)
7. [并发控制策略和变更记录机制](#并发控制策略和变更记录机制)
8. [缓存策略与性能优化方案](#缓存策略与性能优化方案)
9. [监控告警体系](#监控告警体系)
10. [数据安全与接口安全措施](#数据安全与接口安全措施)
11. [测试策略](#测试策略)
12. [实用示例与故障排除指南](#实用示例与故障排除指南)
13. [结论](#结论)

## 引言
本文档详细阐述了京东Cookie管理模块的重构设计方案，涵盖架构设计、数据库结构、API规范、核心业务逻辑、安全机制、监控体系等多个方面。该模块旨在实现对京东Cookie账户的高效管理，支持订单创建、支付链接获取、状态查询等核心功能，并通过Cookie轮询、状态管理、订单复用等机制提升系统稳定性和资源利用率。

## 架构设计与业务场景

京东Cookie管理模块采用分层架构设计，主要包括API层、服务层、逻辑层和数据访问层。API层定义了清晰的接口规范，服务层封装了核心业务逻辑，逻辑层实现了具体的业务处理，数据访问层负责与数据库交互。

该模块主要服务于需要通过京东渠道进行商品兑换的业务场景，如礼品卡充值、游戏点卡购买等。核心业务流程包括：用户提交订单请求，系统通过轮询机制选择可用的Cookie账户，调用京东接口创建订单并获取支付链接，将支付链接返回给用户，定期检查订单支付状态，并在订单完成后释放资源。

```mermaid
graph TD
A[客户端] --> B[API层]
B --> C[服务层]
C --> D[逻辑层]
D --> E[数据访问层]
E --> F[(数据库)]
```

**图示来源**  
- [jd_cookie.go](file://internal/service/jd_cookie.go)
- [account.go](file://internal/logic/jd_cookie/account.go)
- [order.go](file://internal/logic/jd_cookie/order.go)

## 数据库表结构与索引设计

### 表结构说明

重构后的京东Cookie管理系统包含五张核心表：

1.  **京东Cookie账户表 (jd_cookie_account)**：存储Cookie账户的基本信息，包括Cookie内容、状态、使用情况等。
2.  **京东订单表 (jd_cookie_jd_order)**：存储通过京东接口创建的订单信息，包括支付链接、过期时间等。
3.  **订单表 (jd_cookie_order)**：存储系统内部的订单信息，与京东订单关联。
4.  **Cookie变更历史表 (jd_cookie_change_history)**：记录每个Cookie账户的所有状态变更历史。
5.  **京东订单变更历史表 (jd_cookie_jd_order_change_history)**：记录每个京东订单的所有状态变更历史。

### 核心字段与索引

| 表名 | 核心字段 | 索引设计 | 说明 |
| :--- | :--- | :--- | :--- |
| `jd_cookie_account` | `cookie_id`, `status`, `last_used_at` | `uk_cookie_id` (唯一索引), `idx_status`, `idx_last_used` | `cookie_id`为唯一标识，`status`和`last_used_at`用于快速筛选和轮询。 |
| `jd_cookie_jd_order` | `jd_order_id`, `status`, `order_expire_at` | `uk_jd_order_id` (唯一索引), `idx_status`, `idx_order_expire` | `jd_order_id`为唯一标识，`status`和`order_expire_at`用于订单状态管理和过期清理。 |
| `jd_cookie_order` | `order_id`, `status`, `last_request_at` | `uk_order_id` (唯一索引), `idx_status`, `idx_last_request` | `order_id`为唯一标识，`status`用于状态查询，`last_request_at`用于活跃度分析。 |

```mermaid
erDiagram
jd_cookie_account {
string cookie_id PK
text cookie_value
string account_name
tinyint status
int failure_count
datetime last_used_at
datetime suspend_until
datetime created_at
datetime updated_at
string remark
}
jd_cookie_jd_order {
string jd_order_id PK
string pay_id
decimal amount
string category
string cookie_id FK
tinyint status
text wx_pay_url
datetime wx_pay_expire_at
datetime order_expire_at
bigint current_order_id FK
datetime created_at
datetime updated_at
}
jd_cookie_order {
string order_id PK
decimal amount
string category
string jd_order_id FK
tinyint status
text wx_pay_url
datetime last_request_at
datetime created_at
datetime updated_at
}
jd_cookie_change_history {
string history_uuid PK
string cookie_id FK
string change_type
tinyint status_before
tinyint status_after
string user_order_id
int failure_count
datetime created_at
}
jd_cookie_jd_order_change_history {
string history_uuid PK
string jd_order_id FK
string change_type
string order_id
text wx_pay_url
datetime created_at
}
jd_cookie_account ||--o{ jd_cookie_jd_order : "使用"
jd_cookie_jd_order ||--o{ jd_cookie_order : "关联"
jd_cookie_account ||--o{ jd_cookie_change_history : "拥有"
jd_cookie_jd_order ||--o{ jd_cookie_jd_order_change_history : "拥有"
```

**图示来源**  
- [jd_cookie_tables.sql](file://sql/jd_cookie_tables.sql)

## API接口规范

### Cookie账户管理API

| 接口 | 路径 | 方法 | 请求体 | 响应体 | 说明 |
| :--- | :--- | :--- | :--- | :--- | :--- |
| 创建Cookie账户 | `/jd-cookie/account/create` | POST | `CreateAccountReq` | `CreateAccountRes` | 创建单个Cookie账户。 |
| 批量创建Cookie账户 | `/jd-cookie/account/batch-create` | POST | `BatchCreateReq` | `BatchCreateRes` | 批量创建多个Cookie账户。 |
| 查询Cookie账户列表 | `/jd-cookie/account/list` | GET | `ListAccountReq` | `ListAccountRes` | 分页查询Cookie账户列表。 |
| 获取单个Cookie账户 | `/jd-cookie/account/get` | GET | `GetAccountReq` | `GetAccountRes` | 根据Cookie ID获取账户详情。 |
| 更新Cookie账户 | `/jd-cookie/account/update` | PUT | `UpdateAccountReq` | `UpdateAccountRes` | 更新Cookie账户信息。 |
| 删除Cookie账户 | `/jd-cookie/account/delete` | DELETE | `DeleteAccountReq` | `DeleteAccountRes` | 删除指定Cookie账户。 |
| 批量检测Cookie状态 | `/jd-cookie/account/batch-check` | POST | `BatchCheckReq` | `BatchCheckRes` | 批量检测多个Cookie的状态。 |

### 订单处理API

| 接口 | 路径 | 方法 | 请求体 | 响应体 | 说明 |
| :--- | :--- | :--- | :--- | :--- | :--- |
| 创建订单 | `/jd-cookie/order/create` | POST | `CreateOrderReq` | `CreateOrderRes` | 创建新订单并获取支付链接。 |
| 获取支付链接 | `/jd-cookie/order/payment-url` | POST | `GetPaymentUrlReq` | `GetPaymentUrlRes` | 获取指定订单的支付链接。 |
| 查询订单状态 | `/jd-cookie/order/status` | GET | `GetOrderStatusReq` | `GetOrderStatusRes` | 查询订单的当前状态。 |
| 获取单个订单 | `/jd-cookie/order/get` | GET | `GetOrderReq` | `GetOrderRes` | 获取指定订单的详细信息。 |
| 获取单个京东订单 | `/jd-cookie/order/jd-order` | GET | `GetJdOrderReq` | `GetJdOrderRes` | 获取指定京东订单的详细信息。 |
| 订单列表查询 | `/jd-cookie/order/list` | GET | `ListOrderReq` | `ListOrderRes` | 分页查询订单列表。 |
| 京东订单列表查询 | `/jd-cookie/order/jd-list` | GET | `ListJdOrderReq` | `ListJdOrderRes` | 分页查询京东订单列表。 |
| 检查京东订单支付状态 | `/jd-cookie/order/jd-payment-status` | POST | `CheckJdOrderPaymentReq` | `CheckJdOrderPaymentRes` | 检查京东订单的支付状态。 |
| 获取京东订单历史 | `/jd-cookie/order/jd-order-history` | GET | `GetJdOrderHistoryReq` | `GetJdOrderHistoryRes` | 获取指定订单关联的京东订单历史。 |

**图示来源**  
- [v1/account.go](file://api/jd_cookie/v1/account.go)
- [v1/order.go](file://api/jd_cookie/v1/order.go)

## 业务逻辑

### Cookie轮询机制

系统采用轮询（Round-Robin）策略来分配Cookie账户。`GetAvailableCookie`方法会查询所有状态为“正常”的Cookie账户，并选择`last_used_at`时间最久远的账户进行分配。在分配前，系统会自动调用`unlockExpiredCookies`方法，将所有暂停时间已过的Cookie账户状态恢复为“正常”，确保资源池的可用性。

### 状态管理

Cookie账户有三种状态：
- **正常 (1)**：可被正常分配使用。
- **暂停 (2)**：因连续失败而被暂时禁用，`suspend_until`字段记录了解除暂停的时间。
- **失效 (3)**：因失败次数过多而被永久标记为失效。

当一个Cookie在下单时失败，系统会调用`handleCookieFailure`方法，根据当前的`failure_count`决定是将其状态改为“暂停”还是“失效”，并记录相应的变更历史。

### 订单复用机制

为了提高资源利用率，系统实现了订单复用功能。当用户创建新订单时，`CreateOrder`方法会优先调用`findReusableJdOrder`方法，查找是否存在金额和品类相同、状态为“待支付”、且未绑定到其他订单的京东订单。如果找到可复用的订单，系统会检查其支付链接是否过期，若过期则调用`refreshPaymentUrl`刷新链接，然后将新订单与该京东订单绑定，避免重复下单。

```mermaid
flowchart TD
Start([创建订单]) --> CheckExist["检查订单是否已存在"]
CheckExist --> |是| GetPayment["获取支付链接"]
CheckExist --> |否| FindReusable["查找可复用京东订单"]
FindReusable --> |找到| CheckExpire["检查支付链接是否过期"]
CheckExpire --> |是| Refresh["刷新支付链接"]
CheckExpire --> |否| UseDirect["直接使用"]
Refresh --> UpdateJdOrder["更新京东订单支付链接"]
UseDirect --> BindOrder["绑定订单"]
UpdateJdOrder --> BindOrder
BindOrder --> RecordHistory["记录历史"]
FindReusable --> |未找到| GetCookie["获取可用Cookie"]
GetCookie --> CreateJdOrder["创建京东订单"]
CreateJdOrder --> CreateOrder["创建订单"]
CreateOrder --> BindOrder
RecordHistory --> End([返回支付链接])
```

**图示来源**  
- [order.go](file://internal/logic/jd_cookie/order.go)
- [rotation.go](file://internal/logic/jd_cookie/rotation.go)

## 支付链接管理与失效处理流程

支付链接（`wx_pay_url`）的有效期由`WxPayUrlExpireDuration`常量定义（默认3分钟）。当用户请求支付链接时，系统会执行以下流程：
1.  首先检查订单关联的京东订单是否存在。
2.  检查京东订单的支付链接是否有效（未过期）。
3.  如果支付链接已过期，则调用`refreshPaymentUrl`方法向京东接口请求新的支付链接，并更新数据库中的记录。
4.  返回最新的支付链接给用户。

对于过期的京东订单，系统通过定时任务`CleanupExpiredOrders`进行清理。该任务会扫描所有状态为“待支付”且`order_expire_at`时间已过的京东订单，将其状态更新为“已过期”，并释放其与内部订单的绑定关系，使其可以被后续订单复用。

## 并发控制策略和变更记录机制

### 并发控制

系统通过数据库的唯一约束（如`uk_cookie_id`, `uk_order_id`）来防止重复创建。对于关键的订单创建和Cookie分配操作，虽然当前代码未显式使用分布式锁，但可以通过`OrderLockKeyPrefix`和`CookieLockKeyPrefix`常量在Redis中实现，以防止高并发下的资源竞争。

### 变更记录机制

系统通过三张历史表来完整记录所有关键操作：
- **Cookie变更历史**：记录Cookie的创建、状态变更、使用、失败等操作。
- **京东订单变更历史**：记录京东订单的创建、绑定、支付、过期等操作。
- **订单变更历史**：记录内部订单的创建、绑定、支付等操作。

每次状态变更或关键操作发生时，系统都会调用`RecordCookieHistory`、`RecordJdOrderHistory`或`RecordOrderHistory`方法，将变更类型、前后状态、关联订单号等信息写入对应的历史表，确保所有操作可追溯。

**图示来源**  
- [rotation.go](file://internal/logic/jd_cookie/rotation.go)
- [jd_cookie.go](file://internal/consts/jd_cookie.go)

## 缓存策略与性能优化方案

### 缓存策略

目前代码中定义了`CookieRotationKey`和`CookieAvailableKey`等Redis键名常量，表明系统设计了基于Redis的缓存策略。`CookieRotationKey`可用于存储轮询索引，`CookieAvailableKey`可用于缓存可用Cookie列表，从而避免每次分配时都进行数据库查询，显著提升性能。

### 性能优化

1.  **数据库索引**：所有核心查询字段（如`status`, `last_used_at`, `order_expire_at`）均已建立索引，确保查询效率。
2.  **批量操作**：提供了批量创建和批量检测的API，减少网络开销。
3.  **异步处理**：部分非关键操作（如记录历史）使用`go`关键字异步执行，避免阻塞主流程。
4.  **连接池**：使用GoFrame框架的数据库连接池，提高数据库访问效率。

## 监控告警体系

系统通过`glog`组件记录关键操作和错误日志，如Cookie分配、订单创建、接口调用失败等。这些日志可用于后续的分析和问题排查。此外，`monitor`模块的存在表明系统具备健康检查能力。建议在此基础上集成Prometheus和Grafana，对以下指标进行监控：
-  **可用Cookie数量**：监控资源池的健康状况。
-  **订单创建成功率**：监控核心业务的稳定性。
-  **支付链接刷新频率**：监控京东接口的稳定性。
-  **数据库查询延迟**：监控数据库性能。

当关键指标异常时，可通过`notify`模块发送告警通知。

## 数据安全与接口安全措施

### 数据安全

1.  **Cookie加密存储**：虽然代码中未直接体现，但最佳实践是应对`cookie_value`字段进行加密存储，防止敏感信息泄露。
2.  **数据库权限控制**：严格限制数据库访问权限，仅允许应用服务账户访问。

### 接口安全

1.  **输入校验**：API层使用`v:"required#..."`等标签对所有请求参数进行严格校验，防止无效或恶意数据。
2.  **身份认证**：通过`middleware/auth.go`进行身份认证，确保只有授权用户才能调用API。
3.  **错误处理**：统一的错误处理机制（`errHandler`）可以防止敏感错误信息暴露给客户端。
4.  **防刷机制**：可通过`utility/limiter`模块实现接口限流，防止恶意刷单。

## 测试策略

1.  **单元测试**：对`logic`层的每个方法（如`CreateAccount`, `CreateOrder`, `GetAvailableCookie`）编写单元测试，覆盖正常流程和各种异常情况（如Cookie不存在、余额不足等）。
2.  **集成测试**：测试API接口的完整调用链，从API层到数据库，验证数据的一致性和正确性。
3.  **模拟测试**：对于依赖外部京东接口的方法（如`callJdCreateOrder`），使用Mock技术模拟接口响应，确保在不同网络状况下的稳定性。
4.  **压力测试**：使用工具模拟高并发场景，测试系统的吞吐量和稳定性，验证缓存和并发控制策略的有效性。

## 实用示例与故障排除指南

### 实用示例

**场景**：创建一个Apple充值订单。

1.  **创建订单**：
    ```bash
    curl -X POST http://localhost:8080/jd-cookie/order/create \
    -H "Content-Type: application/json" \
    -d '{"orderId": "ORDER_001", "amount": 100.00, "category": "apple"}'
    ```
    **响应**：
    ```json
    {
      "wxPayUrl": "https://wxpay.jd.com/xxx",
      "expireTime": "2025-10-08 14:05:00",
      "jdOrderId": "JD_123456"
    }
    ```

2.  **查询订单状态**：
    ```bash
    curl -G http://localhost:8080/jd-cookie/order/status \
    --data-urlencode "orderId=ORDER_001"
    ```

### 故障排除指南

| 问题 | 可能原因 | 解决方案 |
| :--- | :--- | :--- |
| 创建订单失败，提示“没有可用的Cookie” | 所有Cookie账户状态均为“暂停”或“失效”。 | 检查`jd_cookie_account`表，确认是否有状态为“正常”的账户。检查`failure_count`和`suspend_until`字段，等待暂停时间结束或手动恢复。 |
| 支付链接返回404或无效 | 支付链接已过期，且刷新失败。 | 检查京东接口是否正常。查看日志中`refreshPaymentUrl`的调用结果，确认是否因Cookie失效导致刷新失败。 |
| 订单状态长时间为“待支付” | 京东支付状态检查接口未被调用或调用失败。 | 确认定时任务`CheckJdOrderPayment`是否正常运行。检查日志中是否有调用京东接口失败的记录。 |
| 批量创建Cookie账户部分失败 | 部分Cookie内容格式不正确或为空。 | 检查`BatchCreateReq`中的`cookies`列表，确保每个`cookieValue`都不为空。 |

**图示来源**  
- [order.go](file://internal/logic/jd_cookie/order.go)
- [jd_cookie.go](file://internal/service/jd_cookie.go)

## 结论
本次京东Cookie管理模块的重构设计，通过清晰的分层架构、完善的数据库设计、高效的业务逻辑和健全的安全监控体系，构建了一个稳定、可靠、可扩展的系统。Cookie轮询、状态管理、订单复用等核心机制有效提升了资源利用率和系统健壮性。未来可进一步完善缓存策略和监控告警，以应对更高并发的业务场景。