Files
ruoyi-java/doc/腾讯文档物流链接自动填充-实现逻辑说明.md
2025-11-06 10:57:22 +08:00

419 lines
16 KiB
Markdown
Raw Permalink Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

# 腾讯文档物流链接自动填充 - 实现逻辑说明
## 功能概述
自动从数据库中查询订单的物流链接,并填充到腾讯文档对应的单元格中。
---
## 📋 完整实现逻辑
### 第1步读取表头识别列位置
```java
// 读取 headerRow 行默认第2行
String headerRange = "A2:Z2";
JSONObject headerData = tencentDocService.readSheetData(accessToken, fileId, sheetId, headerRange);
```
**目的**
- 自动识别"单号"列的位置(`orderNoColumn`
- 自动识别"物流链接"列的位置(`logisticsLinkColumn`
**表头示例**
```
| A列 | B列 | C列 | D列 | ... | M列 | N列 |
|------|-----|-----|-----|-----|-----------|------|
| 日期 | 公司| 草号| 型号| ... | 物流单号 | 标记 |
```
自动识别结果:
- 草号列(单号列):索引 2C列
- 物流单号列:索引 12M列
---
### 第2步读取数据行
```java
// 计算读取范围
int startRow = headerRow + 1; // 表头下一行开始
int endRow = startRow + 200; // 每次最多读取200行
String range = "A3:Z203"; // 从第3行到第203行
JSONObject sheetData = tencentDocService.readSheetData(accessToken, fileId, sheetId, range);
```
**数据示例**
```
| A列 | B列 | C列 | ... | M列 | N列 |
|--------|-----|----------------|-----|-----------------|------|
| 3月10日| | JY20251032904 | ... | (空) | 是 |
| 3月10日| | JY20250309184 | ... | 6649902864 | 是 |
| 3月10日| | JY20250309143 | ... | (空) | 是 |
```
---
### 第3步遍历每一行匹配订单并收集需要更新的数据
```java
for (int i = 0; i < values.size(); i++) {
JSONArray row = values.getJSONArray(i);
// 1. 获取单号(草号列)
String orderNo = row.getString(orderNoColumn); // 例如JY20251032904
// 2. 检查是否为空
if (orderNo == null || orderNo.trim().isEmpty()) {
skippedCount++; // 跳过空单号
continue;
}
// 3. 检查物流链接列是否已有值
String existingLogisticsLink = row.getString(logisticsLinkColumn);
if (existingLogisticsLink != null && !existingLogisticsLink.trim().isEmpty()) {
skippedCount++; // 已有物流链接,跳过
continue;
}
// 4. 从数据库查询订单(使用第三方单号查询)
JDOrder order = jdOrderService.selectJDOrderByThirdPartyOrderNo(orderNo);
// 5. 检查是否找到订单且有物流链接
if (order != null && order.getLogisticsLink() != null && !order.getLogisticsLink().trim().isEmpty()) {
String logisticsLink = order.getLogisticsLink().trim();
// 6. 记录需要更新的信息
updates.add({
"row": excelRow, // 行号Excel行号如3表示第3行
"column": logisticsLinkColumn, // 列索引如12表示M列
"orderNo": orderNo, // 单号
"logisticsLink": logisticsLink // 物流链接
});
filledCount++;
} else {
errorCount++; // 未找到订单或物流链接为空
}
}
```
**处理结果示例**
```
找到3个需要更新的单元格
- M3: 订单号 JY20251032904 → 物流链接 6649906880
- M5: 订单号 JY20250309143 → 物流链接 6649914494
- M7: 订单号 JY20250307138 → 物流链接 6649909460
跳过2个已有物流链接的行
跳过1个单号为空的行
找不到物流链接的订单0个
```
---
### 第4步批量写入物流链接
```java
for (JSONObject update : updates) {
int row = update.getIntValue("row"); // 例如3
int column = update.getIntValue("column"); // 例如12
String logisticsLink = update.getString("logisticsLink");
// 1. 计算列字母0→A, 1→B, ..., 12→M
String columnLetter = getColumnLetter(column); // 12 → "M"
// 2. 构建单元格地址
String cellRange = columnLetter + row; // "M3"
// 3. 构建写入数据(二维数组格式)
Object[][] writeData = {{logisticsLink}};
// 4. 写入单个单元格
tencentDocService.writeSheetData(accessToken, fileId, sheetId, cellRange, writeData);
// 5. 延迟100ms避免API限流
Thread.sleep(100);
}
```
**写入示例**
```
写入 M3 单元格 = "6649906880"
写入 M5 单元格 = "6649914494"
写入 M7 单元格 = "6649909460"
```
---
## 🔍 关键字段说明
### 表格中的"单号"(草号)
- **表头名称**:草号
- **列索引**2C列
- **示例值**`JY20251032904`
- **用途**:用于在数据库中查询订单
### 数据库中的"第三方单号"
- **字段名**`third_party_order_no`
- **Java 属性**`thirdPartyOrderNo`
- **对应关系**:表格中的"草号" = 数据库中的"第三方单号"
**数据库查询SQL**
```sql
SELECT * FROM jd_order
WHERE third_party_order_no = #{thirdPartyOrderNo}
LIMIT 1
```
**Java 调用**
```java
// 根据第三方单号查询订单
JDOrder order = jdOrderService.selectJDOrderByThirdPartyOrderNo(orderNo);
```
---
## 📊 完整流程图
```
┌─────────────────────────────────────────────────────────────────┐
│ 1. 读取表头第2行
│ 识别列位置:单号列、物流链接列 │
└──────────────────────┬──────────────────────────────────────────┘
┌─────────────────────────────────────────────────────────────────┐
│ 2. 读取数据行第3行 ~ 第203行200行
│ range: A3:Z203 │
└──────────────────────┬──────────────────────────────────────────┘
┌─────────────────────────────────────────────────────────────────┐
│ 3. 遍历每一行 │
├─────────────────────────────────────────────────────────────────┤
│ ┌─────────────────────────────────────────────────┐ │
│ │ 3.1 读取单号草号列C列 │ │
│ └──────────────┬──────────────────────────────────┘ │
│ │ │
│ ▼ │
│ ┌─────────────────────────────────────────────────┐ │
│ │ 3.2 单号为空? │ │
│ │ 是 → 跳过 │ │
│ │ 否 → 继续 │ │
│ └──────────────┬──────────────────────────────────┘ │
│ │ │
│ ▼ │
│ ┌─────────────────────────────────────────────────┐ │
│ │ 3.3 物流链接列已有值? │ │
│ │ 是 → 跳过 │ │
│ │ 否 → 继续 │ │
│ └──────────────┬──────────────────────────────────┘ │
│ │ │
│ ▼ │
│ ┌─────────────────────────────────────────────────┐ │
│ │ 3.4 查询数据库 │ │
│ │ WHERE third_party_order_no = '单号' │ │
│ └──────────────┬──────────────────────────────────┘ │
│ │ │
│ ▼ │
│ ┌─────────────────────────────────────────────────┐ │
│ │ 3.5 找到订单 且 有物流链接? │ │
│ │ 是 → 记录到更新列表 │ │
│ │ 否 → 记录为错误 │ │
│ └──────────────────────────────────────────────────┘ │
└──────────────────────┬──────────────────────────────────────────┘
┌─────────────────────────────────────────────────────────────────┐
│ 4. 批量写入物流链接 │
├─────────────────────────────────────────────────────────────────┤
│ 对于每个需要更新的单元格: │
│ 1. 计算单元格地址(如 M3
│ 2. 调用写入API │
│ 3. 延迟100ms避免限流
└──────────────────────┬──────────────────────────────────────────┘
┌─────────────────────────────────────────────────────────────────┐
│ 5. 返回处理结果 │
│ - 成功填充数量 │
│ - 跳过数量 │
│ - 错误数量 │
└─────────────────────────────────────────────────────────────────┘
```
---
## 🔧 API 调用参数
### 请求参数
```json
{
"accessToken": "腾讯文档访问令牌",
"fileId": "DUW50RUprWXh2TGJK",
"sheetId": "BB08J2",
"headerRow": 2,
"orderNoColumn": 2,
"logisticsLinkColumn": 12
}
```
**参数说明**
- `accessToken`:必填,腾讯文档访问令牌
- `fileId`必填文件ID从文档URL中获取
- `sheetId`必填工作表ID从URL的tab参数中获取
- `headerRow`可选表头所在行号默认1但根据您的表格应该是2
- `orderNoColumn`:可选,单号列索引(如果不提供则自动识别)
- `logisticsLinkColumn`:可选,物流链接列索引(如果不提供则自动识别)
### 响应结果
```json
{
"msg": "物流链接填充成功",
"code": 200,
"data": {
"startRow": 3,
"endRow": 203,
"lastMaxRow": null,
"filledCount": 3,
"skippedCount": 2,
"errorCount": 0,
"message": "成功填充3个物流链接"
}
}
```
**结果说明**
- `startRow`:本次处理的起始行
- `endRow`:本次处理的结束行
- `filledCount`:成功填充的数量
- `skippedCount`:跳过的数量(已有值或单号为空)
- `errorCount`:错误数量(未找到订单或物流链接)
---
## 🎯 修改说明
### 修改前:使用 `remark` 字段查询
```java
// 错误:使用内部单号查询
JDOrder order = jdOrderService.selectJDOrderByRemark(orderNo);
```
**问题**
- `remark` 字段是"内部单号"
- 表格中的"草号"对应的是"第三方单号"
- 字段不匹配,查不到订单
### 修改后:使用 `thirdPartyOrderNo` 字段查询
```java
// 正确:使用第三方单号查询
JDOrder order = jdOrderService.selectJDOrderByThirdPartyOrderNo(orderNo);
```
**修复内容**
1. ✅ 在 `IJDOrderService` 接口中添加方法
2. ✅ 在 `JDOrderServiceImpl` 实现类中实现方法
3. ✅ 在 `JDOrderMapper` 接口中添加方法声明
4. ✅ 在 `JDOrderMapper.xml` 中添加SQL查询
5. ✅ 在 `TencentDocController` 中更新调用
**修改的文件**
- `ruoyi-system/src/main/java/com/ruoyi/jarvis/service/IJDOrderService.java`
- `ruoyi-system/src/main/java/com/ruoyi/jarvis/service/impl/JDOrderServiceImpl.java`
- `ruoyi-system/src/main/java/com/ruoyi/jarvis/mapper/JDOrderMapper.java`
- `ruoyi-system/src/main/resources/mapper/jarvis/JDOrderMapper.xml`
- `ruoyi-admin/src/main/java/com/ruoyi/web/controller/jarvis/TencentDocController.java`
---
## 📝 使用示例
### 示例1自动识别列位置
```bash
POST /api/tencent-doc/fill-logistics
{
"accessToken": "YOUR_ACCESS_TOKEN",
"fileId": "DUW50RUprWXh2TGJK",
"sheetId": "BB08J2",
"headerRow": 2
}
```
系统会自动识别:
- 包含"单号"的列作为订单号列
- 包含"物流"的列作为物流链接列
### 示例2手动指定列位置
```bash
POST /api/tencent-doc/fill-logistics
{
"accessToken": "YOUR_ACCESS_TOKEN",
"fileId": "DUW50RUprWXh2TGJK",
"sheetId": "BB08J2",
"headerRow": 2,
"orderNoColumn": 2,
"logisticsLinkColumn": 12
}
```
明确指定:
- 单号列在第3列索引2C列
- 物流链接列在第13列索引12M列
---
## 🚨 注意事项
### 1. 行列索引从0开始
- 列索引A列=0, B列=1, C列=2, ...
- 但行号是Excel行号从1开始
### 2. headerRow 参数
- 您的表格第1行是合并的标题
- 第2行才是真正的表头
- **必须设置 `headerRow: 2`**
### 3. 批量处理限制
- 每次最多处理200行
- 每次写入间隔100ms避免API限流
- 处理200行大约需要20-30秒
### 4. 数据库字段对应
| 表格列名 | 数据库字段名 | Java属性名 |
|---------|------------|-----------|
| 草号 | `third_party_order_no` | `thirdPartyOrderNo` |
| 物流单号 | `logistics_link` | `logisticsLink` |
---
## ✅ 功能特点
1.**自动识别列位置**:无需手动指定列索引
2.**智能跳过**:已有物流链接的行自动跳过
3.**批量处理**:一次处理多行数据
4.**增量处理**:记录上次处理位置,避免重复
5.**详细日志**:每一步都有日志记录
6.**错误处理**:完善的异常捕获和错误统计
---
**文档版本**1.0
**创建时间**2025-11-05
**修改内容**:使用 `thirdPartyOrderNo` 字段查询订单