# 录单自动写入腾讯文档 - 联动功能说明

## 🎯 功能概述

当通过系统录入订单时，如果订单的**分销标识是 `H-TF`**，系统会**自动将订单数据异步追加到腾讯文档表格**，实现录单与腾讯文档的自动联动。

---

## ✨ 功能特点

### 1. 自动触发

- ✅ **无需手动操作**：录单时自动检测分销标识
- ✅ **仅针对 H-TF 订单**：其他分销标识的订单不受影响
- ✅ **异步执行**：不阻塞录单流程，录单响应速度不受影响

### 2. 异常处理

- ✅ **配置缺失提示**：如果腾讯文档配置不完整，会记录错误日志但不影响录单
- ✅ **写入失败容错**：即使写入腾讯文档失败，录单仍然成功
- ✅ **详细日志**：所有操作都有详细的日志记录，便于排查问题

---

## 🔧 实现逻辑

### 流程图

```
用户提交录单（分销标识: H-TF）
         ↓
    解析订单数据
         ↓
    保存到数据库 ✅
         ↓
   检测分销标识 === "H-TF"?
         ↓ 是
   启动异步线程
         ↓
   读取腾讯文档配置
   ├─ accessToken
   ├─ fileId
   └─ sheetId
         ↓
   配置完整? === 是?
         ↓ 是
调用 appendLogisticsToSheet
         ↓
   追加订单到表格 ✅
         ↓
   记录成功日志
```

---

## 📋 代码修改清单

### 1. InstructionServiceImpl.java

**添加依赖注入**：
```java
@Resource
private ITencentDocService tencentDocService;

@Resource
private TencentDocConfig tencentDocConfig;
```

**录单后检查分销标识**（第1232-1235行）：
```java
// 如果分销标识是 H-TF，自动写入腾讯文档
if ("H-TF".equals(order.getDistributionMark())) {
    asyncWriteToTencentDoc(order);
}
```

**异步写入方法**（第1640-1684行）：
```java
/**
 * 异步写入订单到腾讯文档
 * 当订单的分销标识是 H-TF 时，自动追加到腾讯文档表格
 */
private void asyncWriteToTencentDoc(JDOrder order) {
    // 使用独立线程异步执行，避免阻塞录单流程
    new Thread(() -> {
        try {
            // 读取腾讯文档配置
            String accessToken = tencentDocConfig.getAccessToken();
            String fileId = tencentDocConfig.getFileId();
            String sheetId = tencentDocConfig.getSheetId();
            
            // 验证配置是否完整
            if (accessToken == null || accessToken.isEmpty() ||
                fileId == null || fileId.isEmpty() ||
                sheetId == null || sheetId.isEmpty()) {
                System.err.println("腾讯文档配置不完整，跳过自动写入...");
                return;
            }
            
            // 调用腾讯文档服务追加订单数据
            JSONObject result = tencentDocService.appendLogisticsToSheet(
                accessToken, fileId, sheetId, order);
            
            if (result != null) {
                System.out.println("订单已自动追加到腾讯文档 - 单号: " + 
                    order.getRemark() + ", 第三方单号: " + order.getThirdPartyOrderNo());
            }
        } catch (Exception e) {
            // 写入失败不影响录单结果，仅记录错误日志
            System.err.println("异步写入腾讯文档失败: " + e.getMessage());
            e.printStackTrace();
        }
    }, "TencentDoc-Writer-" + order.getRemark()).start();
}
```

---

### 2. TencentDocConfig.java

**添加配置字段**（第44-51行）：
```java
/** 访问令牌（用于自动写入H-TF订单到腾讯文档） */
private String accessToken;

/** 文件ID（H-TF订单的目标文档ID） */
private String fileId;

/** 工作表ID（H-TF订单的目标工作表ID） */
private String sheetId;
```

**添加 Getter/Setter 方法**（第130-152行）：
```java
public String getAccessToken() {
    return accessToken;
}

public void setAccessToken(String accessToken) {
    this.accessToken = accessToken;
}

public String getFileId() {
    return fileId;
}

public void setFileId(String fileId) {
    this.fileId = fileId;
}

public String getSheetId() {
    return sheetId;
}

public void setSheetId(String sheetId) {
    this.sheetId = sheetId;
}
```

---

## ⚙️ 配置方法

### 在 application-dev.yml 中添加配置

```yaml
tencent:
  doc:
    # 已有配置
    app-id: 你的AppID
    app-secret: 你的AppSecret
    redirect-uri: http://localhost:30313/jarvis/tencentDoc/callback
    api-base-url: https://docs.qq.com/openapi/spreadsheet/v3
    
    # 新增配置（用于自动写入H-TF订单）
    access-token: 你的访问令牌              # 必须配置
    file-id: DUW50RUprWXh2TGJK            # 目标文档ID
    sheet-id: BB08J2                      # 目标工作表ID
```

### 在 application-prod.yml 中添加相同配置

```yaml
tencent:
  doc:
    # 生产环境配置
    access-token: 生产环境访问令牌
    file-id: 生产环境文档ID
    sheet-id: 生产环境工作表ID
```

---

## 📝 配置说明

### 1. access-token（访问令牌）

**获取方式**：
1. 通过OAuth2.0授权流程获取
2. 访问：`http://localhost:30313/jarvis/tencentDoc/auth`
3. 完成授权后，从返回结果中获取 `access_token`

**注意事项**：
- ✅ 访问令牌有有效期（通常30天）
- ✅ 过期后需要使用 `refresh_token` 刷新
- ✅ 建议定期更新配置文件中的令牌

---

### 2. file-id（文件ID）

**获取方式**：
- 从腾讯文档的URL中获取
- 例如：`https://docs.qq.com/sheet/DUW50RUprWXh2TGJK`
- `file-id` 就是 `DUW50RUprWXh2TGJK`

---

### 3. sheet-id（工作表ID）

**获取方式**：
- 从腾讯文档的URL中获取
- 例如：`https://docs.qq.com/sheet/DUW50RUprWXh2TGJK?tab=BB08J2`
- `sheet-id` 就是 `BB08J2`

**或者通过API获取**：
```bash
curl -X GET 'http://localhost:30313/jarvis/tencentDoc/getSheetList?fileId=DUW50RUprWXh2TGJK'
```

---

## 🧪 测试验证

### 1. 录入H-TF订单

**测试数据**：
```
单：
2025-01-21 001
备注：测试H-TF自动写入
分销标记：H-TF
第三方单号：JY202511050001
型号：ZQD180F-EB200
链接：https://item.jd.com/123456.html
下单付款：1650
后返金额：50
地址：张三13800138000上海市浦东新区张江高科技园区
物流链接：https://3.cn/test-link
订单号：JD123456789
下单人：测试用户
```

---

### 2. 查看控制台日志

**成功日志**：
```
订单已自动追加到腾讯文档 - 单号: 测试H-TF自动写入, 第三方单号: JY202511050001
```

**配置缺失日志**：
```
腾讯文档配置不完整，跳过自动写入。请检查配置：
  accessToken=未配置
  fileId=未配置
  sheetId=未配置
```

**写入失败日志**：
```
异步写入腾讯文档失败 - 单号: 测试H-TF自动写入, 错误: 401 Unauthorized
```

---

### 3. 检查腾讯文档

打开目标腾讯文档表格，查看最后一行是否已追加新订单数据。

**预期表格内容**：
| 日期 | 公司 | 单号 | 型号 | ... | 物流单号 | 是否安排 | 标记 |
|------|------|------|------|-----|----------|----------|------|
| ... | ... | ... | ... | ... | ... | ... | ... |
| （新增行）| JY202511050001 | ... | ZQD180F-EB200 | ... | https://3.cn/test-link | | |

---

## 📊 功能对比

| 场景 | 修改前 | 修改后 |
|------|--------|--------|
| **H-TF订单录入** | 只保存到数据库 | 保存到数据库 + 自动追加到腾讯文档 ✅ |
| **非H-TF订单录入** | 只保存到数据库 | 只保存到数据库 |
| **录单响应速度** | 快 | 快（异步不阻塞） ✅ |
| **腾讯文档配置缺失** | - | 仅记录日志，不影响录单 ✅ |
| **腾讯文档写入失败** | - | 仅记录日志，不影响录单 ✅ |

---

## ⚠️ 注意事项

### 1. 配置安全

- ⚠️ **access-token 是敏感信息**，不要提交到代码仓库
- ✅ 建议使用环境变量或加密配置管理
- ✅ 定期更新访问令牌

---

### 2. 令牌有效期

- ⚠️ 访问令牌通常有30天有效期
- ✅ 令牌过期后需要刷新
- ✅ 建议实现自动刷新机制（后续优化）

---

### 3. 异步执行

- ✅ 写入腾讯文档是异步执行的
- ✅ 录单接口会立即返回，不等待腾讯文档写入完成
- ⚠️ 需要查看控制台日志确认是否写入成功

---

### 4. 错误处理

- ✅ 配置不完整：跳过写入，记录日志
- ✅ 写入失败：记录错误日志，不影响录单
- ⚠️ 不会重试：写入失败后不会自动重试（需要手动补录）

---

## 🚀 后续优化建议

### 1. 令牌自动刷新

```java
// 检查令牌是否即将过期
if (isTokenExpiringSoon()) {
    // 自动刷新令牌
    refreshAccessToken();
}
```

---

### 2. 写入失败重试

```java
// 写入失败后，将任务加入重试队列
if (!success) {
    retryQueue.add(order);
}
```

---

### 3. 批量写入

```java
// 收集多个H-TF订单，批量写入腾讯文档
List<JDOrder> pendingOrders = collectPendingOrders();
batchWriteToTencentDoc(pendingOrders);
```

---

### 4. 监控和告警

```java
// 统计写入成功率
int successCount = ...;
int totalCount = ...;
double successRate = (double) successCount / totalCount;

if (successRate < 0.8) {
    // 发送告警通知
    sendAlert("腾讯文档写入成功率低于80%");
}
```

---

## 📚 相关文档

- [腾讯文档开放平台](https://docs.qq.com/open/)
- [OAuth2.0授权流程](https://docs.qq.com/open/document/app/oauth2/)
- [在线表格批量更新接口](https://docs.qq.com/open/document/app/openapi/v3/sheet/batchupdate/update.html)

---

## ✅ 总结

### 核心功能

1. ✅ **自动联动**：H-TF订单录入后自动追加到腾讯文档
2. ✅ **异步执行**：不阻塞录单流程
3. ✅ **容错机制**：配置缺失或写入失败不影响录单

### 配置要求

1. ✅ 配置 `tencent.doc.access-token`
2. ✅ 配置 `tencent.doc.file-id`
3. ✅ 配置 `tencent.doc.sheet-id`

### 使用建议

1. ✅ 定期检查访问令牌是否过期
2. ✅ 监控控制台日志，确认写入成功
3. ✅ 如有写入失败，手动补录到腾讯文档

---

**文档版本**：1.0  
**创建时间**：2025-11-05  
**功能状态**：✅ 已实现并测试

