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

11 KiB
Raw Permalink Blame History

物流链接自动填充 - 多字段更新功能

新功能说明

在成功匹配订单并写入物流链接的同时,自动更新以下三个字段:

字段 写入内容 说明
物流单号 物流链接 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 格式化当前日期:

// 获取今天的日期格式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在一个请求中更新同一行的多个单元格

// 使用 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 调用次数不变,但更新的字段更多!


📚 相关官方文档


总结

功能增强

  1. 自动识别更多列:单号、物流单号、是否安排、标记
  2. 一次性更新多个字段:物流单号 + 是否安排 + 标记
  3. 自动填充日期:标记列自动填入当天日期(yyMMdd 格式)
  4. 状态标记"是否安排"列自动填入 2

技术优势

  • 使用 batchUpdate API 一次性更新多个字段
  • API 调用次数不变,效率更高
  • 代码结构清晰,易于维护
  • 兼容性好:如果列不存在,自动跳过,不影响主流程

文档版本1.0
创建时间2025-11-05
功能状态 已实现