Files
ruoyi-java/doc/腾讯文档API完整修复总结.md
2025-11-06 10:26:40 +08:00

12 KiB
Raw Blame History

腾讯文档API完整修复总结

修复日期

2025-11-05

修复概述

针对腾讯文档开放平台 V3 API 集成,完成了以下全面修复:

  1. 修正了 API 基础路径配置
  2. 修正了 API 端点路径结构
  3. 修正了鉴权方式(从 Authorization: Bearer 改为三个独立请求头)
  4. 更新了所有 Service 层调用以支持新的鉴权方式

修复详情

1. API 基础路径修复

修改文件

  • ruoyi-system/src/main/java/com/ruoyi/jarvis/config/TencentDocConfig.java
  • ruoyi-admin/src/main/resources/application-dev.yml
  • ruoyi-admin/src/main/resources/application-prod.yml

修改内容

// 修改前
private String apiBaseUrl = "https://docs.qq.com/open/v1";

// 修改后
private String apiBaseUrl = "https://docs.qq.com/openapi/spreadsheet/v3";

配置文件修改

# application-dev.yml 和 application-prod.yml
# 修改前
api-base-url: https://docs.qq.com/open/v1

# 修改后
api-base-url: https://docs.qq.com/openapi/spreadsheet/v3

2. API 端点路径结构修复

修改文件

  • ruoyi-system/src/main/java/com/ruoyi/jarvis/util/TencentDocApiUtil.java

修改的 API 端点

2.1 读取表格数据 (readSheetData)
// 修改前
String apiUrl = String.format("%s/spreadsheets/%s/%s/%s", apiBaseUrl, fileId, sheetId, range);

// 修改后
String apiUrl = String.format("%s/files/%s/%s/%s", apiBaseUrl, fileId, sheetId, range);

// 完整路径示例:
// https://docs.qq.com/openapi/spreadsheet/v3/files/{fileId}/{sheetId}/{range}
2.2 写入表格数据 (writeSheetData)
// 修改前
String apiUrl = String.format("%s/spreadsheets/%s/batchUpdate", apiBaseUrl, fileId);

// 修改后
String apiUrl = String.format("%s/files/%s/batchUpdate", apiBaseUrl, fileId);

// 完整路径示例:
// https://docs.qq.com/openapi/spreadsheet/v3/files/{fileId}/batchUpdate
2.3 追加表格数据 (appendSheetData)
// 修改前
String infoUrl = String.format("%s/spreadsheets/%s", apiBaseUrl, fileId);

// 修改后
String infoUrl = String.format("%s/files/%s", apiBaseUrl, fileId);

// 完整路径示例:
// https://docs.qq.com/openapi/spreadsheet/v3/files/{fileId}
2.4 获取文件信息 (getFileInfo)
// 修改前
String apiUrl = String.format("%s/spreadsheets/%s", apiBaseUrl, fileId);

// 修改后
String apiUrl = String.format("%s/files/%s", apiBaseUrl, fileId);

// 完整路径示例:
// https://docs.qq.com/openapi/spreadsheet/v3/files/{fileId}
2.5 获取工作表列表 (getSheetList)
// 修改前
String apiUrl = String.format("%s/spreadsheets/%s", apiBaseUrl, fileId);

// 修改后
String apiUrl = String.format("%s/files/%s", apiBaseUrl, fileId);

// 完整路径示例:
// https://docs.qq.com/openapi/spreadsheet/v3/files/{fileId}

3. 鉴权方式修复

3.1 callApi 方法签名修改

// 修改前
public static JSONObject callApi(String accessToken, String apiUrl, String method, String body)

// 修改后
public static JSONObject callApi(String accessToken, String clientId, String openId, String apiUrl, String method, String body)

3.2 请求头修改

// 修改前(错误的鉴权方式)
conn.setRequestProperty("Authorization", "Bearer " + accessToken);

// 修改后(正确的鉴权方式)
conn.setRequestProperty("Access-Token", accessToken);
conn.setRequestProperty("Client-Id", clientId);
conn.setRequestProperty("Open-Id", openId);

3.3 新增辅助方法

getUserInfo 方法

用于获取用户信息(包含 Open-Id使用传统的 Authorization: Bearer 鉴权方式。

/**
 * 获取用户信息包含Open-Id
 * 
 * @param accessToken 访问令牌
 * @return 用户信息(包含 openId 字段)
 */
public static JSONObject getUserInfo(String accessToken) {
    // 腾讯文档用户信息接口https://docs.qq.com/open/document/app/oauth2/userinfo.html
    // 注意此接口使用不同的鉴权方式Authorization: Bearer
    String apiUrl = "https://docs.qq.com/oauth/v2/userinfo";
    return callApiLegacy(accessToken, apiUrl, "GET", null);
}
callApiLegacy 方法

用于支持旧版 OAuth2 用户信息接口的 Authorization: Bearer 鉴权方式。

/**
 * 调用腾讯文档API使用传统的 Authorization: Bearer 鉴权方式)
 * 仅用于 OAuth2 用户信息接口
 */
private static JSONObject callApiLegacy(String accessToken, String apiUrl, String method, String body) {
    try {
        // ... 连接设置 ...
        conn.setRequestMethod(method);
        conn.setRequestProperty("Authorization", "Bearer " + accessToken);
        conn.setRequestProperty("Content-Type", "application/json");
        // ... 处理请求和响应 ...
    } catch (Exception e) {
        // ... 错误处理 ...
    }
}

4. Service 层更新

修改文件

  • ruoyi-system/src/main/java/com/ruoyi/jarvis/service/impl/TencentDocServiceImpl.java

修改的方法

所有与腾讯文档 API 交互的方法都进行了更新,在调用 API 前先获取 Open-Id

4.1 uploadLogisticsToSheet 方法
@Override
public JSONObject uploadLogisticsToSheet(String accessToken, String fileId, String sheetId, List<JDOrder> orders) {
    try {
        // ... 参数验证 ...
        
        // 获取用户信息包含Open-Id
        JSONObject userInfo = TencentDocApiUtil.getUserInfo(accessToken);
        String openId = userInfo.getString("openId");
        if (openId == null || openId.isEmpty()) {
            throw new RuntimeException("无法获取Open-Id请检查Access Token是否有效");
        }
        
        // ... 构建数据 ...
        
        // 追加数据到表格
        return TencentDocApiUtil.appendSheetData(
            accessToken, 
            tencentDocConfig.getAppId(), 
            openId, 
            fileId, 
            sheetId, 
            values, 
            tencentDocConfig.getApiBaseUrl()
        );
    } catch (Exception e) {
        // ... 错误处理 ...
    }
}
4.2 appendLogisticsToSheet 方法

类似的修改模式:先获取 openId然后传递给 API 调用。

4.3 readSheetData 方法
@Override
public JSONObject readSheetData(String accessToken, String fileId, String sheetId, String range) {
    try {
        // 获取用户信息包含Open-Id
        JSONObject userInfo = TencentDocApiUtil.getUserInfo(accessToken);
        String openId = userInfo.getString("openId");
        if (openId == null || openId.isEmpty()) {
            throw new RuntimeException("无法获取Open-Id请检查Access Token是否有效");
        }
        
        return TencentDocApiUtil.readSheetData(
            accessToken, 
            tencentDocConfig.getAppId(), 
            openId, 
            fileId, 
            sheetId, 
            range, 
            tencentDocConfig.getApiBaseUrl()
        );
    } catch (Exception e) {
        // ... 错误处理 ...
    }
}
4.4 writeSheetData 方法

同样的模式。

4.5 getFileInfo 方法

同样的模式。

4.6 getSheetList 方法

同样的模式。

完整的修复清单

配置文件3个

  1. TencentDocConfig.java - 修正 API 基础路径
  2. application-dev.yml - 修正 API 基础路径
  3. application-prod.yml - 修正 API 基础路径

Util 工具类1个

  1. TencentDocApiUtil.java
    • 修正 callApi 方法签名(添加 clientId, openId 参数)
    • 修正请求头设置(改用 Access-Token, Client-Id, Open-Id
    • 新增 getUserInfo 方法(获取用户信息和 Open-Id
    • 新增 callApiLegacy 方法(支持旧版 OAuth2 接口)
    • 修正 readSheetData 方法(更新 API 路径和参数)
    • 修正 writeSheetData 方法(更新 API 路径和参数)
    • 修正 appendSheetData 方法(更新 API 路径和参数)
    • 修正 getFileInfo 方法(更新 API 路径和参数)
    • 修正 getSheetList 方法(更新 API 路径和参数)

Service 服务类1个

  1. TencentDocServiceImpl.java
    • 修正 uploadLogisticsToSheet 方法(添加 Open-Id 获取逻辑)
    • 修正 appendLogisticsToSheet 方法(添加 Open-Id 获取逻辑)
    • 修正 readSheetData 方法(添加 Open-Id 获取逻辑)
    • 修正 writeSheetData 方法(添加 Open-Id 获取逻辑)
    • 修正 getFileInfo 方法(添加 Open-Id 获取逻辑)
    • 修正 getSheetList 方法(添加 Open-Id 获取逻辑)

官方文档参考

API 路径规范

基础URLhttps://docs.qq.com/openapi/spreadsheet/v3

API 端点:
- 批量更新POST /files/{fileId}/batchUpdate
- 获取文件信息GET /files/{fileId}
- 读取表格数据GET /files/{fileId}/{sheetId}/{range}

鉴权方式规范

根据官方文档(https://docs.qq.com/open/document/app/openapi/v3/sheet/batchUpdate.html 所有 V3 API 请求必须包含以下三个请求头:

Access-Token: ACCESS_TOKEN
Client-Id: CLIENT_ID
Open-Id: OPEN_ID

Open-Id 获取

通过 OAuth2 用户信息接口获取:

GET https://docs.qq.com/oauth/v2/userinfo
Authorization: Bearer ACCESS_TOKEN

响应示例:

{
  "openId": "用户的开放平台ID",
  "unionId": "用户的联合ID",
  "nickname": "用户昵称",
  ...
}

测试建议

1. 配置验证

# 检查配置文件中的 API 基础地址是否正确
grep "api-base-url" ruoyi-admin/src/main/resources/application-*.yml

2. 编译验证

cd ruoyi-java
mvn clean compile

3. 功能测试步骤

  1. 启动应用
  2. 进行 OAuth2 授权,获取 Access Token
  3. 调用 getUserInfo API验证是否能正确获取 Open-Id
  4. 调用 getFileInfo API验证是否能正确访问文档
  5. 调用 readSheetData API验证是否能正确读取数据
  6. 调用 writeSheetData API验证是否能正确写入数据
  7. 调用 appendSheetData API验证是否能正确追加数据

4. 错误排查

如果仍然出现 404 错误:

  • 检查 fileId 是否正确
  • 检查 sheetId 是否正确
  • 检查 Access Token 是否有效
  • 检查 Open-Id 是否成功获取
  • 检查网络连接和代理设置

如果出现 401 错误:

  • 检查 Access Token 是否过期
  • 检查 Client-Id (AppId) 是否正确
  • 检查 Open-Id 是否正确
  • 检查用户是否有权限访问该文档

注意事项

  1. 代理设置:代码中已添加 Proxy.NO_PROXY 设置,确保直接连接腾讯文档 API避免代理干扰。

  2. Open-Id 获取:每次调用 V3 API 前都会先调用 getUserInfo 获取 Open-Id。如果频繁调用可能影响性能建议后续优化为缓存机制。

  3. 错误处理:所有 API 调用都包含完善的错误处理和日志记录,便于问题排查。

  4. API 版本:确保使用 V3 版本的 APIV1 和 V2 版本可能已经废弃或行为不同。

  5. 鉴权方式差异

    • V3 Spreadsheet API使用 Access-Token, Client-Id, Open-Id 三个请求头
    • OAuth2 用户信息 API使用 Authorization: Bearer {token} 请求头

总结

本次修复完全基于腾讯文档开放平台官方 V3 API 文档,修正了以下核心问题:

  1. API 基础路径从 /open/v1 修正为 /openapi/spreadsheet/v3
  2. API 端点路径从 /spreadsheets/ 修正为 /files/
  3. 鉴权方式从 Authorization: Bearer 修正为 Access-Token, Client-Id, Open-Id 三个独立请求头
  4. Service 层所有调用都已更新以支持新的鉴权方式
  5. 新增 getUserInfo 方法自动获取 Open-Id

所有修改已通过代码编译检查,无 lint 错误。接下来需要进行实际的集成测试以验证 API 调用是否正常。