# 订单创建流程重构报告

## 修改时间

2025-10-18

## 修改原因

原有流程只有在京东订单创建成功后才会创建本地订单记录，这导致京东订单创建失败时无法追踪失败原因和用户请求。

## 修改内容

### 1. 数据库表结构调整

#### 修改 `jd_cookie_order` 表

在 `sql/jd_cookie_tables.sql` 中更新了订单表结构：

```sql
-- 添加字段
ALTER TABLE `jd_cookie_order` 
ADD COLUMN `user_order_id` varchar(64) NOT NULL COMMENT '用户订单号' AFTER `order_id`,
ADD COLUMN `failure_reason` text DEFAULT NULL COMMENT '失败原因' AFTER `status`,
ADD UNIQUE KEY `uk_user_order_id` (`user_order_id`);

-- 更新状态字段注释
ALTER TABLE `jd_cookie_order` 
MODIFY COLUMN `status` tinyint NOT NULL DEFAULT 1 COMMENT '状态：1待支付 2已支付 3已过期 4已取消 5Ck失败';
```

**新增字段说明：**

- `user_order_id`: 用户订单号，用于唯一标识用户的订单请求
- `failure_reason`: 失败原因，记录京东订单创建失败的详细错误信息

### 2. 订单创建流程调整

#### 原有流程

```mermaid
graph TD
    A[接收创建订单请求] --> B[检查订单是否存在]
    B -->|存在| C[返回已有订单]
    B -->|不存在| D[尝试复用京东订单]
    D --> E[创建京东订单]
    E -->|成功| F[创建本地订单记录]
    E -->|失败| G[返回错误,无记录]
    F --> H[返回订单信息]
```

#### 新流程

```mermaid
graph TD
    A[接收创建订单请求] --> B[检查订单是否存在]
    B -->|存在| C[返回已有订单]
    B -->|不存在| D[创建本地订单记录]
    D --> E[记录订单创建历史]
    E --> F[尝试复用京东订单]
    F --> G[创建京东订单]
    G -->|成功| H[更新订单的京东订单ID]
    G -->|失败| I[更新订单状态为失败]
    I --> J[记录失败原因]
    H --> K[返回订单信息]
    J --> L[返回错误]
```

### 3. 代码修改详情

#### 修改文件

1. **internal/logic/jd_cookie/order_create.go**
    - 调整 `CreateOrder` 方法，先创建本地订单，再创建京东订单
    - 失败时更新订单状态和失败原因
    - 成功时更新订单的京东订单ID和支付链接

2. **internal/logic/jd_cookie/order_utils.go**
    - 新增 `updateOrderFailure` 方法：更新订单失败信息
    - 修改 `updateOrderJdOrderId` 方法：支持同时更新京东订单ID和支付链接

3. **sql/jd_cookie_tables.sql**
    - 更新订单表结构定义

4. **sql/add_order_fields.sql** (新增)
    - 提供数据库迁移SQL

### 4. 关键改进点

#### 4.1 错误追踪

- **改进前**: 京东订单创建失败时，没有任何本地记录
- **改进后**: 所有订单请求都会创建本地记录，失败时记录详细错误原因

#### 4.2 状态管理

- **改进前**: 订单状态不明确
- **改进后**:
    - 初始状态：待支付（1）
    - 京东订单创建失败：Ck失败（5）
    - 京东订单创建成功：待支付（1），关联京东订单ID

#### 4.3 历史记录

- 在创建本地订单后立即记录订单创建历史
- 无论京东订单是否创建成功，都有完整的操作记录

### 5. 执行步骤

#### 5.1 数据库迁移

执行以下SQL文件更新数据库表结构：

```bash
# 连接数据库后执行
source sql/add_order_fields.sql
```

或手动执行：

```sql
-- 添加字段
ALTER TABLE `jd_cookie_order` 
ADD COLUMN `user_order_id` varchar(64) NOT NULL COMMENT '用户订单号' AFTER `order_id`,
ADD COLUMN `failure_reason` text DEFAULT NULL COMMENT '失败原因' AFTER `status`,
ADD UNIQUE KEY `uk_user_order_id` (`user_order_id`);

-- 更新状态注释
ALTER TABLE `jd_cookie_order` 
MODIFY COLUMN `status` tinyint NOT NULL DEFAULT 1 COMMENT '状态：1待支付 2已支付 3已过期 4已取消 5Ck失败';
```

#### 5.2 重新生成DAO

```bash
cd e:\projects\kami\kami_backend
gf gen dao
```

#### 5.3 更新代码

代码已经更新，需要重新编译：

```bash
go build .
```

### 6. 注意事项

1. **数据库迁移**:
    - 必须先执行数据库迁移SQL
    - 然后重新生成DAO模型
    - 最后部署新代码

2. **向后兼容性**:
    - 新增字段有默认值，不影响现有数据
    - 旧的订单记录 `user_order_id` 字段需要数据迁移填充

3. **失败原因记录**:
    - 当前通过日志记录失败原因
    - 数据库迁移完成后，会自动存储到 `failure_reason` 字段

### 7. 测试建议

1. **正常流程测试**:
    - 创建订单成功的场景
    - 复用京东订单的场景

2. **异常流程测试**:
    - Cookie不可用导致创建失败
    - 库存不足导致创建失败
    - 网络超时导致创建失败

3. **并发测试**:
    - 同一用户订单号并发请求
    - 验证分布式锁是否生效

### 8. 回滚方案

如果需要回滚到原有逻辑：

1. 恢复代码到之前的版本
2. 保留数据库表结构（不影响旧逻辑）
3. 重新部署

## 预期效果

1. **完整的订单追踪**: 每个用户请求都有对应的本地订单记录
2. **明确的失败原因**: 京东订单创建失败时，可以查看详细错误信息
3. **更好的用户体验**: 用户可以通过订单号查询失败原因
4. **便于问题排查**: 运营人员可以快速定位订单创建失败的原因

## 相关文件

- `internal/logic/jd_cookie/order_create.go`: 订单创建核心逻辑
- `internal/logic/jd_cookie/order_utils.go`: 订单工具方法
- `sql/jd_cookie_tables.sql`: 数据库表结构定义
- `sql/add_order_fields.sql`: 数据库迁移SQL
