From f178bf0ab41f349ce9205c55314c81a66ee2822b Mon Sep 17 00:00:00 2001 From: Leo Date: Wed, 4 Feb 2026 16:54:00 +0800 Subject: [PATCH] 1 --- doc/WPS365获取文件列表-测试说明.md | 14 +-- .../service/impl/WPS365ApiServiceImpl.java | 96 ++++++++++++++----- 2 files changed, 80 insertions(+), 30 deletions(-) diff --git a/doc/WPS365获取文件列表-测试说明.md b/doc/WPS365获取文件列表-测试说明.md index baa103f..fdc5444 100644 --- a/doc/WPS365获取文件列表-测试说明.md +++ b/doc/WPS365获取文件列表-测试说明.md @@ -52,14 +52,14 @@ curl -s -X GET "http://localhost:30313/jarvis/wps365/files?userId=default_user&p - `msg` 为「用户未授权」则需先完成 WPS365 授权; - 其他错误可根据 `msg` 或后端日志排查。 -## 后端实际请求的 WPS API +## 后端实际请求的 WPS API(已按官方文档调整) -- **URL**:`{apiBaseUrl}/yundoc/files`,例如 `https://openapi.wps.cn/api/v1/yundoc/files` -- **方法**:GET -- **Query**:`page`、`page_size`(由后端把 `page` 和 `pageSize` 映射过去) -- **鉴权**:Header 中带 WPS365 的 `access_token` - -若 WPS 侧返回 404 或参数错误,需对照 [WPS 开放平台-云文档 API](https://open.wps.cn/documents/app-integration-dev/wps365/server/yundoc/introduce.html) 确认路径、参数名(如是否需 `drive_id`、`parent_id` 等)是否与当前实现一致,必要时调整 `WPS365ApiServiceImpl.getFileList` 中的 URL 与参数。 +- **官方结构**:云文档文件在「驱动盘」下,路径为 `GET https://openapi.wps.cn/v7/drives/{drive_id}/files`(参见 [云文档业务域概述](https://open.wps.cn/documents/app-integration-dev/wps365/server/yundoc/introduce.html))。 +- **当前实现**: + 1. 先请求 `GET https://openapi.wps.cn/v7/drives` 获取驱动盘列表,取第一个或 `allotee_type=user` 的 `drive_id`; + 2. 若无则尝试 `GET https://openapi.wps.cn/v7/drives/me`; + 3. 再请求 `GET https://openapi.wps.cn/v7/drives/{drive_id}/files?page=1&page_size=20`。 +- **鉴权**:Header 中带 WPS365 的 `access_token`(Bearer)。若接口要求 KSO-1 签名,需按官方文档在请求头中增加签名后再试。 ## 成功后的下一步 diff --git a/ruoyi-system/src/main/java/com/ruoyi/jarvis/service/impl/WPS365ApiServiceImpl.java b/ruoyi-system/src/main/java/com/ruoyi/jarvis/service/impl/WPS365ApiServiceImpl.java index db05dfc..682cfc0 100644 --- a/ruoyi-system/src/main/java/com/ruoyi/jarvis/service/impl/WPS365ApiServiceImpl.java +++ b/ruoyi-system/src/main/java/com/ruoyi/jarvis/service/impl/WPS365ApiServiceImpl.java @@ -54,35 +54,85 @@ public class WPS365ApiServiceImpl implements IWPS365ApiService { @Override public JSONObject getFileList(String accessToken, Map params) { + // 官方文档:云文档文件在「驱动盘」下,路径为 GET https://openapi.wps.cn/v7/drives/{drive_id}/files + // /api/v1/yundoc/files 会 404,需先取 drive_id 再请求 v7/drives/{drive_id}/files + String baseV7 = "https://openapi.wps.cn/v7"; + int page = params != null && params.get("page") != null ? ((Number) params.get("page")).intValue() : 1; + int pageSize = params != null && params.get("page_size") != null ? ((Number) params.get("page_size")).intValue() : 20; + if (params != null && params.get("pageSize") != null) { + pageSize = ((Number) params.get("pageSize")).intValue(); + } + + String driveId = null; + // 1) 尝试获取驱动盘列表:GET /v7/drives try { - // WPS365文件列表API路径可能是 /yundoc/files 而不是 /files - // 根据WPS365 API文档,文件相关API通常在 /yundoc 路径下 - StringBuilder url = new StringBuilder(wps365Config.getApiBaseUrl() + "/yundoc/files"); - - // 添加查询参数 - if (params != null && !params.isEmpty()) { - url.append("?"); - boolean first = true; - for (Map.Entry entry : params.entrySet()) { - if (!first) { - url.append("&"); + JSONObject drivesRes = WPS365ApiUtil.httpRequest("GET", baseV7 + "/drives", accessToken, null); + if (drivesRes != null) { + JSONArray items = drivesRes.getJSONArray("items"); + if (items == null) { + items = drivesRes.getJSONArray("drives"); + } + if (items == null && drivesRes.get("data") != null) { + Object data = drivesRes.get("data"); + if (data instanceof JSONArray) { + items = (JSONArray) data; + } else if (data instanceof JSONObject) { + JSONObject dataObj = (JSONObject) data; + items = dataObj.getJSONArray("items"); + if (items == null) { + items = dataObj.getJSONArray("drives"); + } } - // URL编码参数值 - try { - String key = entry.getKey(); - String value = entry.getValue() != null ? entry.getValue().toString() : ""; - url.append(key).append("=").append(java.net.URLEncoder.encode(value, "UTF-8")); - } catch (java.io.UnsupportedEncodingException e) { - url.append(entry.getKey()).append("=").append(entry.getValue()); + } + if (items != null && !items.isEmpty()) { + for (int i = 0; i < items.size(); i++) { + JSONObject item = items.getJSONObject(i); + String id = item.getString("id"); + if (id != null && !id.isEmpty()) { + // 优先个人盘 allotee_type=user(我的云文档) + if ("user".equalsIgnoreCase(item.getString("allotee_type"))) { + driveId = id; + break; + } + if (driveId == null) { + driveId = id; + } + } } - first = false; } } - - log.debug("调用文件列表API: {}", url.toString()); - return WPS365ApiUtil.httpRequest("GET", url.toString(), accessToken, null); } catch (Exception e) { - log.error("获取文件列表失败 - url: {}", wps365Config.getApiBaseUrl() + "/yundoc/files", e); + log.debug("获取驱动盘列表失败,尝试其他方式: {}", e.getMessage()); + } + + // 2) 若没有 drive_id,尝试「当前用户默认盘」常见路径 + if (driveId == null) { + try { + JSONObject meRes = WPS365ApiUtil.httpRequest("GET", baseV7 + "/drives/me", accessToken, null); + if (meRes != null && meRes.getString("id") != null) { + driveId = meRes.getString("id"); + } + } catch (Exception e) { + log.debug("v7/drives/me 失败: {}", e.getMessage()); + } + } + + if (driveId == null) { + throw new RuntimeException("获取文件列表失败:无法获取驱动盘ID(drive_id)。请确认已授权且 WPS 开放平台云文档接口可用,参见 open.wps.cn 云文档业务域文档。"); + } + + // 3) 获取该盘下的文件列表 + String filesUrl = baseV7 + "/drives/" + driveId + "/files?page=" + page + "&page_size=" + pageSize; + try { + log.debug("调用文件列表API: {}", filesUrl); + JSONObject result = WPS365ApiUtil.httpRequest("GET", filesUrl, accessToken, null); + // 前端期望 data.files;v7 可能返回 items,统一成 files + if (result != null && result.get("files") == null && result.getJSONArray("items") != null) { + result.put("files", result.getJSONArray("items")); + } + return result != null ? result : new JSONObject(); + } catch (Exception e) { + log.error("获取文件列表失败 - url: {}", filesUrl, e); throw new RuntimeException("获取文件列表失败: " + e.getMessage(), e); } }