Files
ruoyi-java/doc/物流链接自动填充-多字段更新功能.md
2025-11-06 12:03:48 +08:00

451 lines
11 KiB
Markdown
Raw 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.

# 物流链接自动填充 - 多字段更新功能
## ✅ 新功能说明
在成功匹配订单并写入物流链接的同时,自动更新以下三个字段:
| 字段 | 写入内容 | 说明 |
|------|----------|------|
| **物流单号** | 物流链接 URL | 从数据库中查询到的物流链接 |
| **是否安排** | `2` | 固定值,表示已安排 |
| **标记** | 当天日期 | 格式:`yyMMdd`(如:`251105` |
---
## 🎯 实现效果
### 修改前(只更新一个字段)
```
写入物流链接 - 单元格: M3, 单号: JY2025110329041
```
**表格更新**
| 行 | 单号 | ... | 物流单号 | 是否安排 | 标记 |
|----|------|-----|----------|----------|------|
| 3 | JY2025110329041 | ... | ✅ https://... | (空) | (空) |
---
### 修改后(同时更新三个字段)
```
成功写入数据 - 行: 3, 单号: JY2025110329041,
物流链接: https://3.cn/2ume-Ak1, 是否安排: 2, 标记: 251105
```
**表格更新**
| 行 | 单号 | ... | 物流单号 | 是否安排 | 标记 |
|----|------|-----|----------|----------|------|
| 3 | JY2025110329041 | ... | ✅ https://... | ✅ 2 | ✅ 251105 |
---
## 🔧 技术实现
### 1. 自动识别列位置
在读取表头时,自动识别所有相关列:
```java
// 查找所有相关列
for (int i = 0; i < headerRowData.size(); i++) {
String cellValue = headerRowData.getString(i);
if (cellValue != null) {
String cellValueTrim = cellValue.trim();
// 识别"单号"列
if (orderNoColumn == null && cellValueTrim.contains("单号")) {
orderNoColumn = i;
}
// 识别"物流单号"列
if (logisticsLinkColumn == null && (cellValueTrim.contains("物流单号") || cellValueTrim.contains("物流链接"))) {
logisticsLinkColumn = i;
}
// 识别"是否安排"列
if (arrangedColumn == null && cellValueTrim.contains("是否安排")) {
arrangedColumn = i;
}
// 识别"标记"列
if (markColumn == null && cellValueTrim.contains("标记")) {
markColumn = i;
}
}
}
```
**识别结果示例**
```
识别到 '单号' 列:第 3 列索引2
识别到 '物流单号' 列:第 13 列索引12
识别到 '是否安排' 列:第 12 列索引11
识别到 '标记' 列:第 15 列索引14
```
---
### 2. 获取当前日期
使用 `SimpleDateFormat` 格式化当前日期:
```java
// 获取今天的日期格式yyMMdd251105
String today = new java.text.SimpleDateFormat("yyMMdd").format(new java.util.Date());
```
**日期格式示例**
| 日期 | 格式化结果 |
|------|-----------|
| 2025年11月5日 | `251105` |
| 2025年11月1日 | `251101` |
| 2025年12月31日 | `251231` |
---
### 3. 使用 batchUpdate 一次性更新多个字段
使用腾讯文档的 `batchUpdate` API在一个请求中更新同一行的多个单元格
```java
// 使用 batchUpdate 一次性更新多个字段
JSONArray requests = new JSONArray();
// 1. 更新物流单号
requests.add(buildUpdateCellRequest(sheetId, row - 1, logisticsLinkColumn, logisticsLink));
// 2. 更新"是否安排"列(如果存在)
if (arrangedColumn != null) {
requests.add(buildUpdateCellRequest(sheetId, row - 1, arrangedColumn, "2"));
}
// 3. 更新"标记"列(如果存在)
if (markColumn != null) {
requests.add(buildUpdateCellRequest(sheetId, row - 1, markColumn, today));
}
// 构建完整的 batchUpdate 请求体
JSONObject batchUpdateBody = new JSONObject();
batchUpdateBody.put("requests", requests);
// 调用 batchUpdate API
tencentDocService.batchUpdate(accessToken, fileId, batchUpdateBody);
```
---
### 4. buildUpdateCellRequest 辅助方法
构建单个单元格的更新请求:
```java
private JSONObject buildUpdateCellRequest(String sheetId, int rowIndex, int columnIndex, String value) {
// 构建 updateRangeRequest
JSONObject updateRangeRequest = new JSONObject();
updateRangeRequest.put("sheetId", sheetId);
// 构建 gridData
JSONObject gridData = new JSONObject();
gridData.put("startRow", rowIndex);
gridData.put("startColumn", columnIndex);
// 构建 rows 数组
JSONArray rows = new JSONArray();
JSONObject rowData = new JSONObject();
JSONArray cellValues = new JSONArray();
// 构建单元格数据
JSONObject cellData = new JSONObject();
JSONObject cellValue = new JSONObject();
cellValue.put("text", value);
cellData.put("cellValue", cellValue);
cellValues.add(cellData);
rowData.put("values", cellValues);
rows.add(rowData);
gridData.put("rows", rows);
updateRangeRequest.put("gridData", gridData);
// 包装为 request 对象
JSONObject request = new JSONObject();
request.put("updateRangeRequest", updateRangeRequest);
return request;
}
```
---
## 📊 完整的 batchUpdate 请求示例
### 请求体结构
```json
{
"requests": [
{
"updateRangeRequest": {
"sheetId": "BB08J2",
"gridData": {
"startRow": 2,
"startColumn": 12,
"rows": [
{
"values": [
{
"cellValue": {
"text": "https://3.cn/2ume-Ak1"
}
}
]
}
]
}
}
},
{
"updateRangeRequest": {
"sheetId": "BB08J2",
"gridData": {
"startRow": 2,
"startColumn": 11,
"rows": [
{
"values": [
{
"cellValue": {
"text": "2"
}
}
]
}
]
}
}
},
{
"updateRangeRequest": {
"sheetId": "BB08J2",
"gridData": {
"startRow": 2,
"startColumn": 14,
"rows": [
{
"values": [
{
"cellValue": {
"text": "251105"
}
}
]
}
]
}
}
}
]
}
```
**说明**
- 第1个请求更新第3行索引2、第13列索引12- 物流单号
- 第2个请求更新第3行索引2、第12列索引11- 是否安排
- 第3个请求更新第3行索引2、第15列索引14- 标记
---
## 🔄 处理流程
```
1. 读取表头
├─ 识别"单号"列(必需)
├─ 识别"物流单号"列(必需)
├─ 识别"是否安排"列(可选)
└─ 识别"标记"列(可选)
2. 读取数据行
3. 逐行处理
├─ 提取单号
├─ 查询数据库
└─ 如果找到订单和物流链接
├─ 构建 updateRangeRequest物流单号
├─ 构建 updateRangeRequest是否安排 = "2"- 如果列存在
├─ 构建 updateRangeRequest标记 = 当天日期)- 如果列存在
└─ 调用 batchUpdate API 一次性更新
4. 返回统计结果
```
---
## 📝 新增方法清单
### Controller 层TencentDocController.java
| 方法名 | 说明 |
|--------|------|
| `buildUpdateCellRequest` | 构建单个单元格的更新请求 |
**修改内容**
- ✅ 识别"是否安排"列和"标记"列
- ✅ 获取当前日期(`yyMMdd` 格式)
- ✅ 使用 `batchUpdate` 一次性更新多个字段
---
### Service 层ITencentDocService.java / TencentDocServiceImpl.java
| 方法名 | 说明 |
|--------|------|
| `batchUpdate` | 批量更新表格的接口方法 |
**接口定义**
```java
/**
* 批量更新表格batchUpdate API
*
* @param accessToken 访问令牌
* @param fileId 文件ID
* @param requestBody batchUpdate 请求体,包含 requests 数组
* @return 更新结果
*/
JSONObject batchUpdate(String accessToken, String fileId, JSONObject requestBody);
```
---
### Util 层TencentDocApiUtil.java
| 方法名 | 说明 |
|--------|------|
| `batchUpdate` | 调用腾讯文档 batchUpdate API 的静态方法 |
**方法签名**
```java
public static JSONObject batchUpdate(
String accessToken,
String appId,
String openId,
String fileId,
JSONObject requestBody,
String apiBaseUrl
)
```
---
## 🧪 测试验证
### 测试请求
```bash
curl -X POST 'http://localhost:30313/jarvis/tencentDoc/fillLogisticsByOrderNo' \
-H 'Content-Type: application/json' \
-d '{
"accessToken": "YOUR_ACCESS_TOKEN",
"fileId": "DUW50RUprWXh2TGJK",
"sheetId": "BB08J2",
"headerRow": 2
}'
```
### 预期日志
```
识别到 '单号' 列:第 3 列索引2
识别到 '物流单号' 列:第 13 列索引12
识别到 '是否安排' 列:第 12 列索引11
识别到 '标记' 列:第 15 列索引14
找到订单物流链接 - 单号: JY2025110329041, 物流链接: https://3.cn/2ume-Ak1, 行号: 3
批量更新表格batchUpdate- fileId: DUW50RUprWXh2TGJK, requests数量: 3
成功写入数据 - 行: 3, 单号: JY2025110329041,
物流链接: https://3.cn/2ume-Ak1, 是否安排: 2, 标记: 251105
```
### 预期结果
**返回 JSON**
```json
{
"msg": "填充物流链接完成",
"code": 200,
"data": {
"filledCount": 45,
"skippedCount": 3,
"errorCount": 0,
"message": "处理完成:成功填充 45 条,跳过 3 条,错误 0 条"
}
}
```
**表格变化**
| 单号 | 物流单号 | 是否安排 | 标记 |
|------|----------|----------|------|
| JY2025110329041 | ✅ https://3.cn/2ume-Ak1 | ✅ 2 | ✅ 251105 |
---
## ⚠️ 注意事项
### 1. 列必须存在
- **必需列**:单号、物流单号
- **可选列**:是否安排、标记
如果表头中没有"是否安排"或"标记"列,系统会跳过这些字段的更新,不会报错。
### 2. 日期格式
日期格式固定为 `yyMMdd`
- 年份2位数`25` = 2025年
- 月份2位数`11` = 11月
- 日期2位数`05` = 5日
### 3. API 调用次数
使用 `batchUpdate` 可以在一个请求中更新多个单元格,减少 API 调用次数:
**修改前**每行调用1次 API只更新物流单号
**修改后**每行仍然调用1次 API但一次更新3个字段
**API 调用次数不变,但更新的字段更多!**
---
## 📚 相关官方文档
- [批量更新接口batchUpdate](https://docs.qq.com/open/document/app/openapi/v3/sheet/batchupdate/update.html)
- [UpdateRangeRequest 说明](https://docs.qq.com/open/document/app/openapi/v3/sheet/batchupdate/request.html#updaterangerequest)
---
## ✅ 总结
### 功能增强
1.**自动识别更多列**:单号、物流单号、是否安排、标记
2.**一次性更新多个字段**:物流单号 + 是否安排 + 标记
3.**自动填充日期**:标记列自动填入当天日期(`yyMMdd` 格式)
4.**状态标记**"是否安排"列自动填入 `2`
### 技术优势
- ✅ 使用 `batchUpdate` API 一次性更新多个字段
- ✅ API 调用次数不变,效率更高
- ✅ 代码结构清晰,易于维护
- ✅ 兼容性好:如果列不存在,自动跳过,不影响主流程
---
**文档版本**1.0
**创建时间**2025-11-05
**功能状态**:✅ 已实现