11 KiB
11 KiB
物流链接自动填充 - 多字段更新功能
✅ 新功能说明
在成功匹配订单并写入物流链接的同时,自动更新以下三个字段:
| 字段 | 写入内容 | 说明 |
|---|---|---|
| 物流单号 | 物流链接 URL | 从数据库中查询到的物流链接 |
| 是否安排 | 2 |
固定值,表示已安排 |
| 标记 | 当天日期 | 格式:yyMMdd(如:251105) |
🎯 实现效果
修改前(只更新一个字段)
写入物流链接 - 单元格: M3, 单号: JY2025110329041
表格更新:
| 行 | 单号 | ... | 物流单号 | 是否安排 | 标记 |
|---|---|---|---|---|---|
| 3 | JY2025110329041 | ... | ✅ https://... | (空) | (空) |
修改后(同时更新三个字段)
成功写入数据 - 行: 3, 单号: JY2025110329041,
物流链接: https://3.cn/2ume-Ak1, 是否安排: 2, 标记: 251105
表格更新:
| 行 | 单号 | ... | 物流单号 | 是否安排 | 标记 |
|---|---|---|---|---|---|
| 3 | JY2025110329041 | ... | ✅ https://... | ✅ 2 | ✅ 251105 |
🔧 技术实现
1. 自动识别列位置
在读取表头时,自动识别所有相关列:
// 查找所有相关列
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 格式化当前日期:
// 获取今天的日期,格式:yyMMdd(如:251105)
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,在一个请求中更新同一行的多个单元格:
// 使用 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 辅助方法
构建单个单元格的更新请求:
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 请求示例
请求体结构
{
"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 |
批量更新表格的接口方法 |
接口定义:
/**
* 批量更新表格(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 的静态方法 |
方法签名:
public static JSONObject batchUpdate(
String accessToken,
String appId,
String openId,
String fileId,
JSONObject requestBody,
String apiBaseUrl
)
🧪 测试验证
测试请求
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:
{
"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 调用次数不变,但更新的字段更多!
📚 相关官方文档
✅ 总结
功能增强
- ✅ 自动识别更多列:单号、物流单号、是否安排、标记
- ✅ 一次性更新多个字段:物流单号 + 是否安排 + 标记
- ✅ 自动填充日期:标记列自动填入当天日期(
yyMMdd格式) - ✅ 状态标记:"是否安排"列自动填入
2
技术优势
- ✅ 使用
batchUpdateAPI 一次性更新多个字段 - ✅ API 调用次数不变,效率更高
- ✅ 代码结构清晰,易于维护
- ✅ 兼容性好:如果列不存在,自动跳过,不影响主流程
文档版本:1.0
创建时间:2025-11-05
功能状态:✅ 已实现