1
This commit is contained in:
@@ -1,119 +0,0 @@
|
||||
# WPS365 回调地址配置说明
|
||||
|
||||
## 错误信息
|
||||
|
||||
如果遇到以下错误:
|
||||
```json
|
||||
{
|
||||
"code": 40000001,
|
||||
"msg": "invalid_request",
|
||||
"debug": {
|
||||
"desc": "The 'redirect_uri' parameter does not match any of the OAuth 2.0 Client's pre-registered redirect urls."
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
**原因**:`redirect_uri` 参数与WPS365开放平台配置的回调地址不一致。
|
||||
|
||||
## 解决方案
|
||||
|
||||
### 1. 检查当前配置的回调地址
|
||||
|
||||
查看 `application.yml` 中的配置:
|
||||
```yaml
|
||||
wps365:
|
||||
redirect-uri: https://jarvis.van333.cn/wps365-callback
|
||||
```
|
||||
|
||||
### 2. 在WPS365开放平台配置回调地址
|
||||
|
||||
1. **登录WPS365开放平台**
|
||||
- 访问:https://open.wps.cn/
|
||||
- 进入你的应用管理页面
|
||||
|
||||
2. **找到"安全设置"或"回调配置"**
|
||||
- 通常在"开发配置" > "安全设置" 或 "事件与回调" 中
|
||||
|
||||
3. **配置授权回调地址**
|
||||
- 回调地址必须与配置文件中的 `redirect-uri` **完全一致**
|
||||
- 包括:
|
||||
- ✅ 协议:`https://`(不能是 `http://`)
|
||||
- ✅ 域名:`jarvis.van333.cn`(不能有 `www` 或其他前缀)
|
||||
- ✅ 路径:`/wps365-callback`(不能有多余的斜杠)
|
||||
- ✅ 端口:如果使用默认端口443,不需要写端口号
|
||||
|
||||
4. **正确的配置示例**
|
||||
```
|
||||
https://jarvis.van333.cn/wps365-callback
|
||||
```
|
||||
|
||||
5. **错误的配置示例(会导致错误)**
|
||||
```
|
||||
❌ http://jarvis.van333.cn/wps365-callback (协议错误)
|
||||
❌ https://www.jarvis.van333.cn/wps365-callback (域名不一致)
|
||||
❌ https://jarvis.van333.cn/wps365-callback/ (末尾多斜杠)
|
||||
❌ https://jarvis.van333.cn:443/wps365-callback (端口号多余)
|
||||
❌ https://jarvis.van333.cn/jarvis/wps365/oauth/callback (路径不一致)
|
||||
```
|
||||
|
||||
### 3. 验证回调地址
|
||||
|
||||
配置完成后,WPS365平台会发送一个challenge验证请求到你的回调地址。确保:
|
||||
- ✅ 回调接口支持GET和POST请求
|
||||
- ✅ 能正确处理challenge参数并返回
|
||||
- ✅ 接口可以正常访问(不被防火墙拦截)
|
||||
|
||||
### 4. 常见问题排查
|
||||
|
||||
#### 问题1:配置了但验证失败
|
||||
- 检查回调接口是否支持POST请求
|
||||
- 检查是否能正确处理challenge参数
|
||||
- 查看后端日志,确认是否收到challenge请求
|
||||
|
||||
#### 问题2:授权时提示redirect_uri不匹配
|
||||
- 检查WPS365平台配置的回调地址
|
||||
- 检查配置文件中的redirect-uri
|
||||
- 确保两者完全一致(包括大小写、斜杠等)
|
||||
|
||||
#### 问题3:回调地址访问失败
|
||||
- 检查nginx配置是否正确代理
|
||||
- 检查前端白名单是否已配置
|
||||
- 检查域名DNS解析是否正常
|
||||
|
||||
### 5. 调试步骤
|
||||
|
||||
1. **查看后端日志**
|
||||
```
|
||||
生成授权URL: https://openapi.wps.cn/oauth2/auth?client_id=xxx&redirect_uri=...
|
||||
使用回调地址: https://jarvis.van333.cn/wps365-callback
|
||||
```
|
||||
|
||||
2. **复制日志中的回调地址**
|
||||
- 确保WPS365平台配置的地址与日志中的地址完全一致
|
||||
|
||||
3. **测试回调地址**
|
||||
- 直接在浏览器访问:`https://jarvis.van333.cn/wps365-callback`
|
||||
- 应该能看到授权页面或提示信息
|
||||
|
||||
4. **重新授权**
|
||||
- 修改配置后,重新点击"立即授权"
|
||||
- 如果还是失败,检查WPS365平台的配置
|
||||
|
||||
## 配置检查清单
|
||||
|
||||
- [ ] WPS365开放平台已配置回调地址
|
||||
- [ ] 回调地址与配置文件中的redirect-uri完全一致
|
||||
- [ ] 回调接口支持GET和POST请求
|
||||
- [ ] 回调接口能正确处理challenge验证
|
||||
- [ ] 前端白名单已配置 `/wps365-callback`
|
||||
- [ ] nginx已配置 `/wps365-callback` 路由
|
||||
- [ ] 域名DNS解析正常
|
||||
- [ ] SSL证书有效
|
||||
|
||||
## 注意事项
|
||||
|
||||
1. **回调地址必须使用HTTPS**(生产环境)
|
||||
2. **路径不能有末尾斜杠**(除非是根路径)
|
||||
3. **域名必须完全匹配**(不能有www前缀等)
|
||||
4. **配置后需要等待几分钟生效**(WPS365平台可能有缓存)
|
||||
|
||||
@@ -1,259 +0,0 @@
|
||||
# WPS365 授权错误排查指南
|
||||
|
||||
## 常见错误类型
|
||||
|
||||
### 1. invalid_request (40000001) - redirect_uri不匹配
|
||||
|
||||
```json
|
||||
{
|
||||
"code": 40000001,
|
||||
"msg": "invalid_request",
|
||||
"debug": {
|
||||
"desc": "The request is missing a required parameter, includes an invalid parameter value, includes a parameter more than once, or is otherwise malformed. The 'redirect_uri' parameter does not match any of the OAuth 2.0 Client's pre-registered redirect urls."
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
**错误含义**:redirect_uri参数值与WPS365平台配置的回调地址不一致
|
||||
|
||||
### 2. invalid_scope (40000005) - scope权限无效 ⚠️
|
||||
|
||||
```json
|
||||
{
|
||||
"code": 40000005,
|
||||
"msg": "invalid_scope",
|
||||
"debug": {
|
||||
"desc": "The requested scope is invalid, unknown, or malformed. The OAuth 2.0 Client is not allowed to request scope 'file.read,ksheet.read,user.info'."
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
**错误含义**:请求的scope权限格式不正确,或者应用未申请这些权限
|
||||
|
||||
## 错误含义总览
|
||||
|
||||
授权错误可能由以下原因导致:
|
||||
|
||||
1. **缺少必需参数** - 授权请求中缺少某个必需的参数
|
||||
2. **参数值无效** - 某个参数的值格式不正确
|
||||
3. **参数重复** - 某个参数在请求中出现了多次
|
||||
4. **redirect_uri不匹配** - redirect_uri参数值与WPS365平台配置的回调地址不一致
|
||||
5. **scope无效** - scope权限格式不正确或未申请
|
||||
|
||||
## 排查步骤
|
||||
|
||||
### 1. 查看后端日志
|
||||
|
||||
查看后端日志中的授权URL和参数清单,例如:
|
||||
|
||||
```
|
||||
生成授权URL: https://openapi.wps.cn/oauth2/auth?client_id=xxx&redirect_uri=...
|
||||
📋 授权请求参数清单:
|
||||
- client_id: AK20260114NNQJKV
|
||||
- redirect_uri: https://jarvis.van333.cn/wps365-callback
|
||||
- response_type: code
|
||||
- scope: file.read,ksheet.read,user.info
|
||||
- state: xxxxx
|
||||
```
|
||||
|
||||
### 2. 检查参数名是否正确
|
||||
|
||||
**问题**:WPS365可能使用 `app_id` 而不是标准的 `client_id`
|
||||
|
||||
**解决方案**:
|
||||
- 如果使用 `client_id` 报错,尝试改为 `app_id`
|
||||
- 查看WPS365官方文档确认正确的参数名
|
||||
|
||||
**当前代码使用**:`client_id`(标准OAuth2参数名)
|
||||
|
||||
### 3. 检查必需参数是否齐全
|
||||
|
||||
授权请求必须包含以下参数:
|
||||
|
||||
| 参数名 | 是否必需 | 说明 | 当前值 |
|
||||
|--------|---------|------|--------|
|
||||
| `client_id` 或 `app_id` | ✅ 必需 | 应用ID | 从配置读取 |
|
||||
| `redirect_uri` | ✅ 必需 | 回调地址 | 从配置读取 |
|
||||
| `response_type` | ✅ 必需 | 固定值 `code` | `code` |
|
||||
| `scope` | ✅ 必需 | 权限范围 | `file.read,ksheet.read,user.info` |
|
||||
| `state` | ⚠️ 推荐 | 防CSRF攻击 | 自动生成 |
|
||||
|
||||
### 4. 检查redirect_uri是否匹配
|
||||
|
||||
这是最常见的错误原因。必须确保:
|
||||
|
||||
1. **协议一致**:必须是 `https://`(不能是 `http://`)
|
||||
2. **域名一致**:必须是 `jarvis.van333.cn`(不能有 `www` 前缀)
|
||||
3. **路径一致**:必须是 `/wps365-callback`(不能有末尾斜杠)
|
||||
4. **端口一致**:使用默认443端口,不需要写端口号
|
||||
|
||||
**在WPS365平台配置的回调地址必须与日志中的redirect_uri完全一致**
|
||||
|
||||
### 5. 检查scope权限是否已申请(重要!)
|
||||
|
||||
**如果遇到 `invalid_scope` 错误,请按以下步骤排查:**
|
||||
|
||||
#### 5.1 检查WPS365平台后台的scope格式
|
||||
|
||||
1. 登录WPS365开放平台
|
||||
2. 进入"开发配置" > "权限管理"
|
||||
3. 查看已申请的权限列表,**注意权限的格式**:
|
||||
- 必须以 `kso.` 开头,如:`kso.file.read`、`kso.file.readwrite`
|
||||
- 不是 `file.read` 或 `ksheet.read`(这些格式不存在)
|
||||
- 根据官方文档:https://open.wps.cn/documents/app-integration-dev/wps365/server/
|
||||
|
||||
#### 5.2 检查scope分隔符
|
||||
|
||||
**根据WPS365官方文档,必须使用英文逗号分隔**(不是空格):
|
||||
|
||||
| 分隔符 | 示例 | 说明 |
|
||||
|--------|------|------|
|
||||
| **逗号(正确)** | `kso.file.readwrite,kso.doclib.readwrite` | ✅ WPS365官方要求 |
|
||||
| **空格(错误)** | `kso.file.readwrite kso.doclib.readwrite` | ❌ 会导致invalid_scope |
|
||||
| **逗号+空格** | `kso.file.readwrite, kso.doclib.readwrite` | ⚠️ 可能支持,但不推荐 |
|
||||
|
||||
**重要**:WPS365官方文档明确要求使用英文逗号 `,` 分隔,不能使用空格。
|
||||
|
||||
#### 5.3 在配置文件中指定scope
|
||||
|
||||
在 `application.yml` 中添加 `scope` 配置,**必须使用英文逗号分隔**:
|
||||
|
||||
```yaml
|
||||
wps365:
|
||||
# 根据WPS365平台后台"权限管理"中显示的实际权限名称配置
|
||||
# 使用英文逗号分隔(WPS365官方要求)
|
||||
# 权限名称必须以 kso. 开头
|
||||
scope: kso.file.readwrite
|
||||
```
|
||||
|
||||
多个权限示例:
|
||||
|
||||
```yaml
|
||||
wps365:
|
||||
# 多个权限用英文逗号分隔,不能有空格
|
||||
# 权限名称必须以 kso. 开头
|
||||
scope: kso.file.read,kso.file.readwrite
|
||||
```
|
||||
|
||||
#### 5.4 确认权限已申请且名称正确
|
||||
|
||||
**关键步骤**:
|
||||
|
||||
1. **登录WPS365开放平台**
|
||||
- 访问:https://open.wps.cn/
|
||||
- 进入你的应用管理页面
|
||||
|
||||
2. **查看已申请的权限**
|
||||
- 进入"开发配置" > "权限管理"
|
||||
- 查看已申请权限的**准确名称**(注意大小写、分隔符、命名空间)
|
||||
|
||||
3. **对比权限名称**
|
||||
- 权限名称必须与后台显示的**完全一致**
|
||||
- 例如:如果后台显示的是 `kso.doclib.readwrite`,不能写成 `kso.doclib.readWrite` 或 `kso_doclib_readwrite`
|
||||
|
||||
4. **常见权限名称示例**(仅供参考,以平台后台实际显示为准):
|
||||
- `kso.doclib.readwrite` - 文档库读写权限
|
||||
- `kso.doclib.read` - 文档库读取权限
|
||||
- `ksheet.read` - 在线表格读取权限(如果支持)
|
||||
|
||||
**重要提示**:
|
||||
- ⚠️ `file.read`、`ksheet.read`、`user.info` 这些权限名称可能不存在
|
||||
- ✅ 必须查看WPS365平台后台实际显示的权限名称
|
||||
- ✅ 权限名称必须完全匹配(包括大小写、分隔符、命名空间)
|
||||
- ✅ 必须使用英文逗号分隔多个权限
|
||||
|
||||
### 6. 尝试修改参数名
|
||||
|
||||
如果确认所有参数都正确,但仍然报错,可能是参数名问题:
|
||||
|
||||
**测试方案1**:将 `client_id` 改为 `app_id`
|
||||
|
||||
修改 `WPS365OAuthServiceImpl.java` 中的代码:
|
||||
```java
|
||||
// 原代码
|
||||
authUrl.append("?client_id=").append(appId);
|
||||
|
||||
// 改为
|
||||
authUrl.append("?app_id=").append(appId);
|
||||
```
|
||||
|
||||
**测试方案2**:同时提供两个参数(如果WPS365支持)
|
||||
```java
|
||||
authUrl.append("?app_id=").append(appId);
|
||||
authUrl.append("&client_id=").append(appId);
|
||||
```
|
||||
|
||||
### 7. 检查URL编码
|
||||
|
||||
确保 `redirect_uri` 参数正确进行了URL编码:
|
||||
- 空格应该编码为 `%20`
|
||||
- 斜杠 `/` 应该编码为 `%2F`
|
||||
- 冒号 `:` 应该编码为 `%3A`
|
||||
|
||||
查看日志中的"编码后"值,确认编码是否正确。
|
||||
|
||||
### 8. 验证WPS365平台配置
|
||||
|
||||
登录WPS365开放平台,检查:
|
||||
|
||||
1. **应用ID(AppId)** 是否与配置文件中的 `app-id` 一致
|
||||
2. **回调地址配置** 是否与日志中的 `redirect_uri` 完全一致
|
||||
3. **权限配置** 是否已申请所需的scope权限
|
||||
4. **应用状态** 是否为"已上线"或"测试中"
|
||||
|
||||
## 常见问题
|
||||
|
||||
### Q1: 参数名应该用 `client_id` 还是 `app_id`?
|
||||
|
||||
**A**: 根据WPS365官方文档确认。标准OAuth2使用 `client_id`,但某些平台可能使用 `app_id`。如果 `client_id` 不工作,尝试 `app_id`。
|
||||
|
||||
### Q2: 为什么redirect_uri明明配置了还是报错?
|
||||
|
||||
**A**: 最常见的原因是:
|
||||
- 平台配置的回调地址与代码中的不完全一致(多了/少了斜杠、协议不同等)
|
||||
- 平台配置未保存或未生效
|
||||
- 使用了错误的配置环境(开发/生产)
|
||||
|
||||
### Q3: scope权限在哪里申请?
|
||||
|
||||
**A**: 在WPS365开放平台的"开发配置" > "权限管理"中申请。
|
||||
|
||||
### Q4: 如何确认参数是否正确?
|
||||
|
||||
**A**: 查看后端日志,会打印完整的授权URL和参数清单。对比WPS365平台配置,确保完全一致。
|
||||
|
||||
### Q5: 遇到 `invalid_scope` 错误怎么办? ⚠️
|
||||
|
||||
**A**: 这是scope格式或权限问题,按以下步骤排查:
|
||||
|
||||
1. **查看WPS365平台后台的权限格式**
|
||||
- 进入"开发配置" > "权限管理"
|
||||
- 查看已申请权限的**确切格式**(包括分隔符、大小写)
|
||||
|
||||
2. **尝试不同的scope格式**
|
||||
- 空格分隔:`file.read ksheet.read user.info`(当前默认)
|
||||
- 逗号分隔:`file.read,ksheet.read,user.info`
|
||||
- 在 `application.yml` 中配置 `scope` 参数进行测试
|
||||
|
||||
3. **确认权限已申请且已审核通过**
|
||||
- 权限必须处于"已通过"或"可用"状态
|
||||
- 如果权限未申请,需要先申请并等待审核
|
||||
|
||||
4. **查看后端日志中的scope值**
|
||||
- 日志会显示实际使用的scope格式
|
||||
- 对比WPS365平台显示的格式,确保完全一致
|
||||
|
||||
## 调试建议
|
||||
|
||||
1. **启用DEBUG日志**:在 `application.yml` 中设置日志级别为DEBUG
|
||||
2. **查看完整授权URL**:复制日志中的授权URL,在浏览器中访问,查看具体错误
|
||||
3. **对比官方文档**:查看WPS365官方OAuth文档,确认参数名和格式
|
||||
4. **联系WPS365技术支持**:如果所有参数都正确但仍报错,可能是平台问题
|
||||
|
||||
## 下一步
|
||||
|
||||
如果按照以上步骤排查后仍然报错,请提供:
|
||||
1. 后端日志中的完整授权URL和参数清单
|
||||
2. WPS365平台配置的回调地址截图
|
||||
3. WPS365平台的应用配置截图(隐藏敏感信息)
|
||||
|
||||
@@ -1,39 +0,0 @@
|
||||
# WPS365 智能表格(AirSheet)接口说明
|
||||
|
||||
## 当前情况
|
||||
|
||||
- **智能表格(AirSheet)** 在 open.wps.cn 开放平台申请的权限为 `kso.airsheet.readwrite`,但 **openapi.wps.cn 下目前没有可用的 AirSheet REST 接口**:
|
||||
- `https://openapi.wps.cn/api/v1/openapi/airsheet/{fileId}/...` → 404
|
||||
- `https://openapi.wps.cn/v7/airsheet/{fileId}/...` → 404
|
||||
|
||||
因此直接按「智能表格」调 AirSheet 读/写会报 **读取AirSheet数据失败、statusCode=404**。
|
||||
|
||||
## 代码中的处理
|
||||
|
||||
- **读**:`readAirSheetCells` 会依次尝试
|
||||
1)AirSheet 路径 → 2)**KSheet(在线表格)路径**(同一 `fileId` 当作 `file_token`)→ 3)v7 AirSheet。
|
||||
若都 404,会抛出带说明的异常。
|
||||
- **写**:`updateAirSheetCells` 同样会先试 AirSheet,再回退到 **KSheet 写入**,再试 v7。
|
||||
|
||||
即:当 AirSheet 接口 404 时,会自动用同一 ID 试 **在线表格(KSheet)** 接口;若文档在 WPS 文件列表里是以 KSheet 形式存在的,有可能用 KSheet 读/写成功。
|
||||
|
||||
## 建议用法(避免 404)
|
||||
|
||||
1. **优先用「文件列表」返回的 file_token 调 KSheet 接口**
|
||||
- 调用 `GET /jarvis/wps365/files`(或等价的文件列表接口),拿到目标文档的 **file_token**。
|
||||
- 用该 **file_token** 调用 **KSheet** 读/写接口,不要用浏览器地址栏或分享链接里的 ID 当作 file_token:
|
||||
- 读:`GET /jarvis/wps365/readCells?userId=xxx&fileToken=文件列表返回的file_token&sheetIdx=0&range=A1:B5`
|
||||
- 写:`POST /jarvis/wps365/updateCells`,body 里 `fileToken` 填文件列表返回的 file_token。
|
||||
- 这样即使用户创建的是「智能表格」,只要在文件列表里存在且后端用 KSheet 能访问,就可正常读/写。
|
||||
|
||||
2. **确认文档来源**
|
||||
- 若文档是在 **金山文档(kdocs.cn)** 创建的,当前项目用的是 **open.wps.cn(WPS365)** 的 OAuth 与 API,token 不能直接访问金山文档。
|
||||
- 要在后端读/写金山文档里的表格,需要接 **金山文档开放平台(developer.kdocs.cn)** 的 KSheet 服务端 API,并使用该平台的鉴权方式。
|
||||
|
||||
3. **若必须用「智能表格」且仅支持 AirScript**
|
||||
- 若官方仅提供通过 **AirScript(脚本)** 操作智能表格(例如 `POST https://www.kdocs.cn/api/v3/ide/file/:file_id/script/:script_id/sync_task`),则需在表格内编写脚本,后端只调该脚本接口,而不是直接调 REST 读单元格。
|
||||
|
||||
## 小结
|
||||
|
||||
- **404 原因**:openapi.wps.cn 下当前没有可用的智能表格(AirSheet)REST 读/写接口。
|
||||
- **可行方案**:用 **文件列表接口拿 file_token**,用 **KSheet 读/写接口**(readCells / updateCells)操作该文档;若文档在金山文档,需改用金山文档开放平台的 API。
|
||||
@@ -1,70 +0,0 @@
|
||||
# WPS365 获取文件列表 - 测试说明
|
||||
|
||||
## 关于接口与文档
|
||||
|
||||
- **用户信息接口**:官方文档(open.wps.cn 用户授权流程)只写“通过 access_token 获取用户信息”,**未给出具体 URL**。项目中曾用 `/api/v1/user/info`,该地址会 404。已改为依次尝试 `v7/user`、`v7/userinfo`、`userinfo`、`user/info`;若均不可用则**降级返回**(不报 500,返回 token 中的 user_id 与占位信息)。若需完整用户信息,请以 [WPS 开放平台文档](https://open.wps.cn/documents) 为准确认正确路径后再改。
|
||||
- 其他 WPS 接口(文件列表、KSheet 等)请以 open.wps.cn 对应文档为准,发现路径不一致时以文档为准修改。
|
||||
|
||||
## 接口说明
|
||||
|
||||
- **后端接口**:`GET /jarvis/wps365/files`
|
||||
- **参数**:
|
||||
- `userId`(必填):与授权时保存 Token 使用的用户标识,前端 WPS365 页目前固定为 `default_user`
|
||||
- `page`(可选,默认 1):页码
|
||||
- `pageSize`(可选,默认 20):每页条数
|
||||
- **鉴权**:需登录系统(请求头带 JWT),后端用 `userId` 从 Redis 取 WPS365 的 access_token,再请求 WPS 云文档文件列表 API。
|
||||
|
||||
## 前置条件
|
||||
|
||||
1. **已完成 WPS365 授权**
|
||||
在系统里至少完成一次 WPS365 授权,且回调成功后 Token 已保存(与 `userId` 对应,一般为 `default_user`)。
|
||||
2. **已登录系统**
|
||||
使用已登录账号访问前端或调用接口(需携带有效 JWT)。
|
||||
|
||||
## 测试方式一:前端页面(推荐)
|
||||
|
||||
1. 登录若依前端。
|
||||
2. 打开 **WPS365 在线表格管理** 页面:侧边栏 **文档同步配置** → **WPS365 在线表格管理**(或直接访问 `/docSync/wps365`)。
|
||||
3. 若未授权:点击「立即授权」,在新窗口完成 WPS365 授权后关闭,回到本页。
|
||||
4. 确认顶部为「已授权」绿色提示。
|
||||
5. 在「文件列表」卡片中点击 **「加载文件」**。
|
||||
6. 观察:
|
||||
- 表格中是否出现文件行(文件名、文件 Token、类型等);
|
||||
- 浏览器开发者工具 → 网络:找到 `files` 请求,查看请求 URL 是否为 `/jarvis/wps365/files?userId=default_user&page=1&pageSize=20`,以及响应 body 中是否有文件数据。
|
||||
|
||||
**预期**:能拉取到 WPS 云文档中的文件列表;列表中每条会包含 `file_token`,后续读/写单元格需使用该 `file_token`。
|
||||
|
||||
若提示「用户未授权」:说明当前 `userId`(如 `default_user`)下没有 WPS365 Token,需重新走一遍授权并确保回调成功。
|
||||
若提示「获取文件列表失败」且带 HTTP 状态码或 WPS 错误信息:需看后端日志中请求的 WPS API 地址与返回内容,再对照 [WPS 开放平台-云文档](https://open.wps.cn/documents/app-integration-dev/wps365/server/yundoc/introduce.html) 文档排查。
|
||||
|
||||
## 测试方式二:curl(需 JWT)
|
||||
|
||||
1. 从浏览器登录后,在开发者工具中复制当前请求的 `Authorization` 头(或从 localStorage 等获取 token 拼成 `Bearer <token>`)。
|
||||
2. 执行(将 `YOUR_JWT` 和 `BASE_URL` 替换为实际值):
|
||||
|
||||
```bash
|
||||
curl -s -X GET "http://localhost:30313/jarvis/wps365/files?userId=default_user&page=1&pageSize=20" \
|
||||
-H "Authorization: Bearer YOUR_JWT"
|
||||
```
|
||||
|
||||
3. 查看响应:
|
||||
- `code: 200` 且 `data` 中有文件列表(如 `data.files`、`data.total` 等)则说明获取文件列表能力正常;
|
||||
- `msg` 为「用户未授权」则需先完成 WPS365 授权;
|
||||
- 其他错误可根据 `msg` 或后端日志排查。
|
||||
|
||||
## 后端实际请求的 WPS API(已按官方文档调整)
|
||||
|
||||
- **官方结构**:云文档文件在「驱动盘」下,路径为 `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 签名,需按官方文档在请求头中增加签名后再试。
|
||||
|
||||
## 成功后的下一步
|
||||
|
||||
- 从文件列表结果中取目标文件的 **`file_token`**。
|
||||
- 读单元格:使用 **KSheet 读接口** `readCells`,参数中 `fileToken` 填该 `file_token`。
|
||||
- 写单元格:使用 **KSheet 写接口** `updateCells`,同样使用该 `file_token`。
|
||||
|
||||
这样可避免用分享链接里的 ID 直接调接口导致的 404,改为用「文件列表」返回的 `file_token` 访问表格。
|
||||
@@ -1,271 +0,0 @@
|
||||
# WPS365 读取在线表格内容配置指南
|
||||
|
||||
## 概述
|
||||
|
||||
本指南详细说明如何配置WPS365应用,以实现读取自己创建的在线表格内容。
|
||||
|
||||
## 一、WPS365开放平台配置步骤
|
||||
|
||||
### 1. 应用基础配置
|
||||
|
||||
1. **登录WPS365开放平台**
|
||||
- 访问:https://open.wps.cn/
|
||||
- 使用WPS账号登录
|
||||
|
||||
2. **创建应用**
|
||||
- 进入"应用管理"
|
||||
- 点击"创建应用"
|
||||
- 填写应用名称(如:Jarvis同步WPS)
|
||||
- 选择应用类型:**服务端应用**
|
||||
|
||||
3. **获取应用凭证**
|
||||
- 记录 `AppID`(应用ID)
|
||||
- 记录 `AppKey`(应用密钥,注意保密)
|
||||
|
||||
### 2. 配置回调地址
|
||||
|
||||
1. **进入"开发配置" > "事件与回调"**
|
||||
2. **配置回调地址**
|
||||
- 回调地址:`https://jarvis.van333.cn/wps365-callback`
|
||||
- 点击"验证"按钮,确保验证通过
|
||||
- 如果验证失败,检查:
|
||||
- 回调接口是否支持GET和POST请求
|
||||
- 是否能正确处理challenge参数
|
||||
- 前端白名单是否已配置
|
||||
|
||||
### 3. 配置权限(关键步骤)
|
||||
|
||||
#### 3.1 进入权限管理
|
||||
|
||||
1. 在左侧导航栏选择 **"开发配置" > "权限管理"**
|
||||
2. 查看当前应用的权限列表
|
||||
|
||||
#### 3.2 添加必要权限
|
||||
|
||||
需要添加以下权限才能读取在线表格内容:
|
||||
|
||||
**基础权限:**
|
||||
- ✅ `file.read` - 读取文件权限
|
||||
- ✅ `file.readwrite` - 读取和写入文件权限(如果只需要读取,可以只选read)
|
||||
- ✅ `user.info` - 获取用户信息权限
|
||||
|
||||
**在线表格(KSheet)权限:**
|
||||
- ✅ `ksheet:read` - 读取在线表格数据
|
||||
- ✅ `ksheet:write` - 写入在线表格数据(如果需要编辑功能)
|
||||
|
||||
**权限说明:**
|
||||
- 这些权限决定了你的应用能访问哪些资源
|
||||
- 用户授权时,会看到这些权限的说明
|
||||
- 只有用户同意授权后,应用才能访问对应的资源
|
||||
|
||||
#### 3.3 权限申请流程
|
||||
|
||||
1. 在权限管理页面,点击"添加权限"
|
||||
2. 搜索并选择上述权限
|
||||
3. 提交权限申请(部分权限可能需要审核)
|
||||
4. 等待审核通过
|
||||
|
||||
### 4. 应用能力配置(可选)
|
||||
|
||||
根据图片显示,WPS365开放平台提供了多种应用能力:
|
||||
|
||||
**协作与会话:**
|
||||
- WPS协作机器人
|
||||
- 工作台小组件
|
||||
- WPS协作网页应用
|
||||
|
||||
**多维表格:**
|
||||
- 记录卡片插件
|
||||
- 字段插件
|
||||
- 视图插件
|
||||
- 仪表盘插件
|
||||
- 数据连接器插件
|
||||
- 自动化插件
|
||||
|
||||
**注意:**
|
||||
- 如果只是读取在线表格内容,通常不需要开启这些插件能力
|
||||
- 这些能力主要用于扩展表格功能,不是读取数据的必要条件
|
||||
- 读取数据主要依赖API权限,而不是这些插件能力
|
||||
|
||||
## 二、后端配置
|
||||
|
||||
### 1. 更新配置文件
|
||||
|
||||
在 `application-dev.yml` 中添加配置:
|
||||
|
||||
```yaml
|
||||
wps365:
|
||||
# 应用ID(从WPS365开放平台获取)
|
||||
app-id: YOUR_APP_ID
|
||||
# 应用密钥(从WPS365开放平台获取)
|
||||
app-key: YOUR_APP_KEY
|
||||
# 授权回调地址
|
||||
redirect-uri: https://jarvis.van333.cn/wps365-callback
|
||||
# API基础地址
|
||||
api-base-url: https://open.wps.cn/api/v1
|
||||
# OAuth授权地址
|
||||
oauth-url: https://open.wps.cn/oauth2/v1/authorize
|
||||
# 获取Token地址
|
||||
token-url: https://open.wps.cn/oauth2/v1/token
|
||||
# 刷新Token地址
|
||||
refresh-token-url: https://open.wps.cn/oauth2/v1/token
|
||||
```
|
||||
|
||||
### 2. 确认授权范围(Scope)
|
||||
|
||||
当前代码中使用的授权范围:
|
||||
```java
|
||||
scope=file.readwrite,user.info
|
||||
```
|
||||
|
||||
如果需要更细粒度的权限控制,可以修改为:
|
||||
```java
|
||||
scope=file.read,ksheet:read,user.info // 只读权限
|
||||
// 或
|
||||
scope=file.readwrite,ksheet:readwrite,user.info // 读写权限
|
||||
```
|
||||
|
||||
## 三、使用流程
|
||||
|
||||
### 1. 用户授权
|
||||
|
||||
1. 调用 `/jarvis/wps365/authUrl` 获取授权URL
|
||||
2. 用户访问授权URL,同意授权
|
||||
3. WPS365回调到 `/wps365-callback`,自动保存Token
|
||||
|
||||
### 2. 获取文件列表
|
||||
|
||||
```javascript
|
||||
// 调用接口获取文件列表
|
||||
GET /jarvis/wps365/files?userId=xxx&page=1&pageSize=20
|
||||
```
|
||||
|
||||
### 3. 获取工作表列表
|
||||
|
||||
```javascript
|
||||
// 获取指定文件的工作表列表
|
||||
GET /jarvis/wps365/sheets?userId=xxx&fileToken=xxx
|
||||
```
|
||||
|
||||
### 4. 读取单元格数据
|
||||
|
||||
```javascript
|
||||
// 读取指定范围的单元格数据
|
||||
GET /jarvis/wps365/readCells?userId=xxx&fileToken=xxx&sheetIdx=0&range=A1:Z100
|
||||
```
|
||||
|
||||
**参数说明:**
|
||||
- `userId`: 用户ID(授权后获取)
|
||||
- `fileToken`: 文件Token(从文件列表中获取)
|
||||
- `sheetIdx`: 工作表索引(从0开始)
|
||||
- `range`: 单元格范围(如:A1:Z100,可选,不填则读取整个工作表)
|
||||
|
||||
## 四、常见问题
|
||||
|
||||
### Q1: 提示"权限不足"或"无权限访问"
|
||||
|
||||
**解决方案:**
|
||||
1. 检查WPS365开放平台的权限配置
|
||||
2. 确认已添加 `file.read` 和 `ksheet:read` 权限
|
||||
3. 重新授权(删除旧Token,重新获取授权)
|
||||
|
||||
### Q2: 无法读取自己创建的表格
|
||||
|
||||
**可能原因:**
|
||||
1. 文件Token不正确
|
||||
2. 工作表索引错误
|
||||
3. 用户对文件没有读取权限(即使是自己创建的,也需要授权给应用)
|
||||
|
||||
**解决方案:**
|
||||
1. 确认文件Token是从文件列表中正确获取的
|
||||
2. 使用 `/jarvis/wps365/sheets` 接口确认工作表索引
|
||||
3. 确保用户已授权应用访问该文件
|
||||
|
||||
### Q3: 读取返回空数据
|
||||
|
||||
**可能原因:**
|
||||
1. 指定的单元格范围没有数据
|
||||
2. 工作表索引错误
|
||||
3. API返回格式与预期不符
|
||||
|
||||
**解决方案:**
|
||||
1. 尝试读取更大的范围(如:A1:Z1000)
|
||||
2. 检查工作表索引是否正确
|
||||
3. 查看后端日志,确认API返回的具体内容
|
||||
|
||||
## 五、API接口说明
|
||||
|
||||
### 读取单元格数据接口
|
||||
|
||||
**接口地址:** `GET /jarvis/wps365/readCells`
|
||||
|
||||
**请求参数:**
|
||||
| 参数 | 类型 | 必填 | 说明 |
|
||||
|------|------|------|------|
|
||||
| userId | String | 是 | 用户ID |
|
||||
| fileToken | String | 是 | 文件Token |
|
||||
| sheetIdx | Integer | 否 | 工作表索引,默认0 |
|
||||
| range | String | 否 | 单元格范围,如:A1:B10 |
|
||||
|
||||
**返回示例:**
|
||||
```json
|
||||
{
|
||||
"code": 200,
|
||||
"msg": "读取单元格数据成功",
|
||||
"data": {
|
||||
"values": [
|
||||
["列1", "列2", "列3"],
|
||||
["数据1", "数据2", "数据3"],
|
||||
["数据4", "数据5", "数据6"]
|
||||
]
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
## 六、完整示例
|
||||
|
||||
### 前端调用示例
|
||||
|
||||
```javascript
|
||||
import {
|
||||
getWPS365AuthUrl,
|
||||
getWPS365FileList,
|
||||
getWPS365SheetList,
|
||||
readWPS365Cells
|
||||
} from '@/api/jarvis/wps365'
|
||||
|
||||
// 1. 获取授权URL
|
||||
const authResponse = await getWPS365AuthUrl()
|
||||
window.open(authResponse.data, '_blank')
|
||||
|
||||
// 2. 等待授权完成后,获取文件列表
|
||||
const fileListResponse = await getWPS365FileList({
|
||||
userId: 'your_user_id',
|
||||
page: 1,
|
||||
pageSize: 20
|
||||
})
|
||||
|
||||
// 3. 选择要读取的文件,获取工作表列表
|
||||
const fileToken = fileListResponse.data.files[0].file_token
|
||||
const sheetListResponse = await getWPS365SheetList('your_user_id', fileToken)
|
||||
|
||||
// 4. 读取第一个工作表的数据
|
||||
const dataResponse = await readWPS365Cells({
|
||||
userId: 'your_user_id',
|
||||
fileToken: fileToken,
|
||||
sheetIdx: 0,
|
||||
range: 'A1:Z100'
|
||||
})
|
||||
|
||||
console.log('表格数据:', dataResponse.data.values)
|
||||
```
|
||||
|
||||
## 七、注意事项
|
||||
|
||||
1. **权限范围**:确保在WPS365开放平台配置了正确的权限
|
||||
2. **文件Token**:使用fileToken而不是fileId来访问文件
|
||||
3. **工作表索引**:工作表索引从0开始,不是从1开始
|
||||
4. **单元格范围**:范围格式为 `A1:B10`,不区分大小写
|
||||
5. **Token有效期**:Token会过期,需要定期刷新或重新授权
|
||||
6. **数据量限制**:一次读取的数据量不要太大,建议分批读取
|
||||
|
||||
@@ -1,270 +0,0 @@
|
||||
# WPS365 在线表格API集成使用说明
|
||||
|
||||
## 概述
|
||||
|
||||
本功能实现了WPS365在线表格(KSheet)的完整API集成,支持用户授权、文档查看和编辑等功能。
|
||||
|
||||
## 功能特性
|
||||
|
||||
1. **OAuth用户授权**:支持WPS365标准的OAuth 2.0授权流程
|
||||
2. **Token管理**:自动保存和管理访问令牌,支持Token刷新
|
||||
3. **文件管理**:获取文件列表、文件信息
|
||||
4. **工作表管理**:获取工作表列表、创建数据表
|
||||
5. **单元格编辑**:支持读取和更新单元格数据,支持批量更新
|
||||
|
||||
## 配置说明
|
||||
|
||||
### 1. 在WPS365开放平台注册应用
|
||||
|
||||
1. 访问 [WPS365开放平台](https://open.wps.cn/)
|
||||
2. 注册成为服务商并创建应用
|
||||
3. 获取 `app_id` 和 `app_key`
|
||||
4. 配置授权回调地址(需要与配置文件中的 `redirect-uri` 一致)
|
||||
|
||||
### 1.1 配置应用权限(重要!)
|
||||
|
||||
在WPS365开放平台的应用配置中,需要确保开启以下权限:
|
||||
|
||||
#### 基础权限
|
||||
- **文件读取权限** (`file.read` 或 `file.readwrite`)
|
||||
- **用户信息权限** (`user.info`)
|
||||
|
||||
#### 在线表格(KSheet)相关权限
|
||||
根据图片中的应用能力配置页面,如果需要读取在线表格内容,建议:
|
||||
|
||||
1. **进入"应用能力"配置页面**
|
||||
- 在左侧导航栏选择"应用能力" > "应用能力"
|
||||
|
||||
2. **确保相关能力已开启**
|
||||
- 虽然图片中显示的是"多维表格"插件相关能力,但读取在线表格内容主要依赖:
|
||||
- **文件读取权限**(在"权限管理"中配置)
|
||||
- **API调用权限**(确保应用有调用OpenAPI的权限)
|
||||
|
||||
3. **权限管理配置**
|
||||
- 进入"开发配置" > "权限管理"
|
||||
- 确保添加了以下权限:
|
||||
- `ksheet:read` - 读取在线表格数据
|
||||
- `ksheet:write` - 写入在线表格数据(如果需要编辑)
|
||||
- `file:read` - 读取文件
|
||||
- `file:write` - 写入文件(如果需要编辑)
|
||||
|
||||
4. **事件与回调配置**
|
||||
- 进入"开发配置" > "事件与回调"
|
||||
- 配置回调地址:`https://your-domain.com/wps365-callback`
|
||||
- 确保回调地址验证通过(支持GET和POST请求)
|
||||
|
||||
### 2. 更新配置文件
|
||||
|
||||
编辑 `application-dev.yml`(或对应的环境配置文件),添加WPS365配置:
|
||||
|
||||
```yaml
|
||||
wps365:
|
||||
# 应用ID(从WPS365开放平台获取)
|
||||
app-id: YOUR_APP_ID
|
||||
# 应用密钥(从WPS365开放平台获取)
|
||||
app-key: YOUR_APP_KEY
|
||||
# 授权回调地址(需要在WPS365开放平台配置)
|
||||
# 注意:使用 /wps365-callback 路径,避免前端路由拦截
|
||||
redirect-uri: https://your-domain.com/wps365-callback
|
||||
# API基础地址(一般不需要修改)
|
||||
api-base-url: https://openapi.wps.cn/api/v1
|
||||
# OAuth授权地址(一般不需要修改)
|
||||
oauth-url: https://openapi.wps.cn/oauth2/auth
|
||||
# 获取Token地址(一般不需要修改)
|
||||
token-url: https://openapi.wps.cn/oauth2/token
|
||||
# 刷新Token地址(一般不需要修改)
|
||||
refresh-token-url: https://openapi.wps.cn/oauth2/token
|
||||
```
|
||||
|
||||
**重要提示**:
|
||||
- 回调地址使用 `/wps365-callback` 而不是 `/jarvis/wps365/oauth/callback`
|
||||
- 这样可以避免前端路由拦截,确保OAuth回调能正常访问
|
||||
- 在WPS365开放平台配置时,只需配置域名(如:`jarvis.van333.cn`),回调路径会自动使用配置中的完整URL
|
||||
|
||||
## API接口说明
|
||||
|
||||
### 1. 获取授权URL
|
||||
|
||||
**接口**: `GET /jarvis/wps365/authUrl`
|
||||
|
||||
**参数**:
|
||||
- `state` (可选): 状态参数,用于防止CSRF攻击
|
||||
|
||||
**返回**: 授权URL,用户需要访问此URL完成授权
|
||||
|
||||
**示例**:
|
||||
```javascript
|
||||
// 前端调用
|
||||
import { getWPS365AuthUrl } from '@/api/jarvis/wps365'
|
||||
|
||||
const response = await getWPS365AuthUrl()
|
||||
const authUrl = response.data
|
||||
// 打开授权页面
|
||||
window.open(authUrl, '_blank')
|
||||
```
|
||||
|
||||
### 2. OAuth回调处理
|
||||
|
||||
**接口**: `GET /wps365-callback`
|
||||
|
||||
**参数**:
|
||||
- `code`: 授权码(由WPS365回调时自动传入)
|
||||
- `state`: 状态参数(可选)
|
||||
- `error`: 错误码(授权失败时)
|
||||
- `error_description`: 错误描述(授权失败时)
|
||||
|
||||
**说明**:
|
||||
- 此接口处理WPS365的授权回调,自动获取并保存Token
|
||||
- 返回HTML页面,显示授权结果
|
||||
- 使用 `/wps365-callback` 路径避免前端路由拦截
|
||||
- 授权成功后会显示成功页面,3秒后自动关闭窗口
|
||||
|
||||
### 3. 获取Token状态
|
||||
|
||||
**接口**: `GET /jarvis/wps365/tokenStatus`
|
||||
|
||||
**参数**:
|
||||
- `userId`: 用户ID
|
||||
|
||||
**返回**: Token状态信息(是否授权、是否有效等)
|
||||
|
||||
### 4. 刷新Token
|
||||
|
||||
**接口**: `POST /jarvis/wps365/refreshToken`
|
||||
|
||||
**请求体**:
|
||||
```json
|
||||
{
|
||||
"refreshToken": "refresh_token_value"
|
||||
}
|
||||
```
|
||||
|
||||
### 5. 获取用户信息
|
||||
|
||||
**接口**: `GET /jarvis/wps365/userInfo`
|
||||
|
||||
**参数**:
|
||||
- `userId`: 用户ID
|
||||
|
||||
### 6. 获取文件列表
|
||||
|
||||
**接口**: `GET /jarvis/wps365/files`
|
||||
|
||||
**参数**:
|
||||
- `userId`: 用户ID
|
||||
- `page`: 页码(默认1)
|
||||
- `pageSize`: 每页数量(默认20)
|
||||
|
||||
### 7. 获取工作表列表
|
||||
|
||||
**接口**: `GET /jarvis/wps365/sheets`
|
||||
|
||||
**参数**:
|
||||
- `userId`: 用户ID
|
||||
- `fileToken`: 文件token
|
||||
|
||||
### 8. 读取单元格数据
|
||||
|
||||
**接口**: `GET /jarvis/wps365/readCells`
|
||||
|
||||
**参数**:
|
||||
- `userId`: 用户ID
|
||||
- `fileToken`: 文件token
|
||||
- `sheetIdx`: 工作表索引(从0开始)
|
||||
- `range`: 单元格范围(如:A1:B10,可选)
|
||||
|
||||
### 9. 更新单元格数据
|
||||
|
||||
**接口**: `POST /jarvis/wps365/updateCells`
|
||||
|
||||
**请求体**:
|
||||
```json
|
||||
{
|
||||
"userId": "user_id",
|
||||
"fileToken": "file_token",
|
||||
"sheetIdx": 0,
|
||||
"range": "A1:B2",
|
||||
"values": [
|
||||
["值1", "值2"],
|
||||
["值3", "值4"]
|
||||
]
|
||||
}
|
||||
```
|
||||
|
||||
### 10. 批量更新单元格数据
|
||||
|
||||
**接口**: `POST /jarvis/wps365/batchUpdateCells`
|
||||
|
||||
**请求体**:
|
||||
```json
|
||||
{
|
||||
"userId": "user_id",
|
||||
"fileToken": "file_token",
|
||||
"sheetIdx": 0,
|
||||
"updates": [
|
||||
{
|
||||
"range": "A1:B2",
|
||||
"values": [["值1", "值2"], ["值3", "值4"]]
|
||||
},
|
||||
{
|
||||
"range": "C1:D2",
|
||||
"values": [["值5", "值6"], ["值7", "值8"]]
|
||||
}
|
||||
]
|
||||
}
|
||||
```
|
||||
|
||||
## 使用流程
|
||||
|
||||
### 1. 用户授权流程
|
||||
|
||||
1. 前端调用 `/jarvis/wps365/authUrl` 获取授权URL
|
||||
2. 在新窗口打开授权URL,用户完成授权
|
||||
3. WPS365会回调到配置的 `redirect-uri`,自动处理授权码
|
||||
4. 系统自动获取并保存Token到Redis
|
||||
|
||||
### 2. 编辑文档流程
|
||||
|
||||
1. 调用 `/jarvis/wps365/files` 获取文件列表
|
||||
2. 选择要编辑的文件,调用 `/jarvis/wps365/sheets` 获取工作表列表
|
||||
3. 调用 `/jarvis/wps365/readCells` 读取现有数据
|
||||
4. 修改数据后,调用 `/jarvis/wps365/updateCells` 更新数据
|
||||
|
||||
### 3. Token刷新
|
||||
|
||||
- Token过期前,系统会自动尝试刷新
|
||||
- 也可以手动调用 `/jarvis/wps365/refreshToken` 刷新Token
|
||||
|
||||
## 注意事项
|
||||
|
||||
1. **用户权限**:只有文档的所有者或被授予编辑权限的用户才能编辑文档
|
||||
2. **Token管理**:Token存储在Redis中,有效期30天。过期后需要重新授权
|
||||
3. **API限制**:注意WPS365的API调用频率限制
|
||||
4. **文件Token**:WPS365使用 `file_token` 而不是文件ID,需要从文件列表中获取
|
||||
|
||||
## 前端页面
|
||||
|
||||
访问 `/jarvis/wps365` 可以打开WPS365管理页面,包含:
|
||||
- 授权状态显示
|
||||
- 用户信息查看
|
||||
- 文件列表浏览
|
||||
- 在线编辑表格功能
|
||||
|
||||
## 错误处理
|
||||
|
||||
- **未授权**:返回错误提示,引导用户完成授权
|
||||
- **Token过期**:自动尝试刷新Token,刷新失败则提示重新授权
|
||||
- **权限不足**:返回错误码10003,提示用户没有编辑权限
|
||||
|
||||
## 技术实现
|
||||
|
||||
- **后端**:Spring Boot + Redis(Token存储)
|
||||
- **前端**:Vue.js + Element UI
|
||||
- **HTTP客户端**:HttpURLConnection(不使用代理,直接连接)
|
||||
|
||||
## 参考文档
|
||||
|
||||
- [WPS365开放平台文档](https://open.wps.cn/)
|
||||
- [用户授权流程](https://open.wps.cn/documents/app-integration-dev/wps365/server/certification-authorization/user-authorization/flow)
|
||||
- [KSheet API文档](https://developer.kdocs.cn/server/ksheet/)
|
||||
|
||||
Reference in New Issue
Block a user