datai/datai-scenes/datai-scene-salesforce/docs/api-docs/2026-02-06-003-06-api.md

576 lines
15 KiB
Markdown
Raw Permalink Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

# API 文档 - 检索操作
## 元数据
- 需求编号003-06
- 创建时间2026-02-06
- 创建人AI Assistant
- 状态:已完成
- 版本v1.0.0
## API 概述
本文档描述了 Salesforce Metadata API 检索操作相关的 REST API 接口,包括元数据检索请求提交、状态轮询、状态检查和历史查询功能。
### 核心功能
1. **提交检索请求**:向 Salesforce 提交元数据检索请求,返回异步操作 ID
2. **轮询检索状态**:循环检查检索状态直到完成或超时
3. **单次状态检查**:单次检查检索状态,返回当前状态
4. **检索历史查询**:查询检索操作的历史记录
5. **检索记录查询**:根据 asyncId 查询具体的检索记录
### 技术栈
- Spring Boot 2.7.x
- Spring Security权限控制
- MyBatis Plus数据持久化
- Salesforce Metadata API
### 基础路径
```
/salesforce/metadata/retrieve
```
## 接口列表
### 接口 1提交检索请求
#### 功能描述
向 Salesforce 提交元数据检索请求。检索操作是异步的,提交后会立即返回一个异步操作 IDasyncId客户端需要使用这个 ID 轮询检索状态或查询结果。
#### 请求方式
`POST`
#### 请求路径
```
/salesforce/metadata/retrieve
```
#### 权限要求
- 权限标识:`salesforce:metadata:retrieve`
- 使用 `@PreAuthorize("@ss.hasPermi('salesforce:metadata:retrieve')")` 控制
#### 请求参数
##### 请求体参数JSON
| 参数名 | 类型 | 必填 | 说明 | 示例 |
|--------|------|------|------|------|
| apiVersion | Double | 是 | API 版本 | `59.0` |
| singlePackage | Boolean | 否 | 是否为单个包,默认 false | `false` |
| unpackaged | Object | 条件 | 未打包的元数据类型列表(与 packageNames 二选一) | 见下方示例 |
| packageNames | String[] | 条件 | 包名称列表(与 unpackaged 二选一) | `["MyPackage"]` |
| specificFiles | String[] | 否 | 特定文件列表 | `["package.xml"]` |
##### Unpackaged 对象结构
| 参数名 | 类型 | 必填 | 说明 | 示例 |
|--------|------|------|------|------|
| types | Array | 是 | 元数据类型列表 | 见下方示例 |
##### PackageTypeMember 对象结构
| 参数名 | 类型 | 必填 | 说明 | 示例 |
|--------|------|------|------|------|
| name | String | 是 | 元数据类型名称 | `"CustomObject"` |
| members | String[] | 是 | 成员列表,`*` 表示所有 | `["*"]` |
#### 请求示例
##### 示例 1检索所有 CustomObject
```json
POST /salesforce/metadata/retrieve
Content-Type: application/json
{
"apiVersion": 59.0,
"singlePackage": false,
"unpackaged": {
"types": [
{
"name": "CustomObject",
"members": ["*"]
}
]
}
}
```
##### 示例 2检索特定包
```json
POST /salesforce/metadata/retrieve
Content-Type: application/json
{
"apiVersion": 59.0,
"singlePackage": true,
"packageNames": ["MyManagedPackage"]
}
```
##### 示例 3检索多种元数据类型
```json
POST /salesforce/metadata/retrieve
Content-Type: application/json
{
"apiVersion": 59.0,
"unpackaged": {
"types": [
{
"name": "CustomObject",
"members": ["Account", "Contact"]
},
{
"name": "ApexClass",
"members": ["MyClass", "MyTestClass"]
},
{
"name": "ApexTrigger",
"members": ["*"]
}
]
}
}
```
#### 响应参数
##### 成功响应HTTP 200
| 参数名 | 类型 | 说明 | 示例 |
|--------|------|------|------|
| code | Integer | 状态码200 表示成功 | `200` |
| msg | String | 提示信息 | `"操作成功"` |
| data | Object | 异步结果对象 | 见下方说明 |
##### AsyncResult 对象
| 参数名 | 类型 | 说明 | 示例 |
|--------|------|------|------|
| id | String | 异步操作 ID | `"09Sxx0000000001EAA"` |
| done | Boolean | 是否完成 | `false` |
| state | String | 状态Queued、InProgress、Completed、Error | `"Queued"` |
#### 成功响应示例
```json
{
"code": 200,
"msg": "操作成功",
"data": {
"id": "09Sxx0000000001EAA",
"done": false,
"state": "Queued"
}
}
```
#### 错误响应示例
```json
{
"code": 500,
"msg": "检索元数据失败: 连接超时",
"data": null
}
```
---
### 接口 2轮询检索状态
#### 功能描述
轮询检索状态直到完成或超时。此接口会循环检查检索状态,直到检索完成(成功或失败)或达到超时时间。适用于需要等待检索完成的场景。
#### 请求方式
`GET`
#### 请求路径
```
/salesforce/metadata/retrieve/status/{asyncId}
```
#### 权限要求
- 权限标识:`salesforce:metadata:retrieve`
#### 请求参数
##### 路径参数
| 参数名 | 类型 | 必填 | 说明 | 示例 |
|--------|------|------|------|------|
| asyncId | String | 是 | 异步操作 ID | `"09Sxx0000000001EAA"` |
##### 查询参数
| 参数名 | 类型 | 必填 | 说明 | 示例 |
|--------|------|------|------|------|
| interval | Long | 否 | 轮询间隔(毫秒),默认 5000 | `5000` |
| timeout | Long | 否 | 超时时间(毫秒),默认 3000005分钟 | `300000` |
#### 请求示例
```
GET /salesforce/metadata/retrieve/status/09Sxx0000000001EAA?interval=5000&timeout=300000
```
#### 响应参数
##### 成功响应HTTP 200
| 参数名 | 类型 | 说明 | 示例 |
|--------|------|------|------|
| code | Integer | 状态码200 表示成功 | `200` |
| msg | String | 提示信息 | `"操作成功"` |
| data | Object | 检索结果对象 | 见下方说明 |
##### RetrieveResultVo 对象
| 参数名 | 类型 | 说明 | 示例 |
|--------|------|------|------|
| asyncId | String | 异步操作 ID | `"09Sxx0000000001EAA"` |
| status | String | 检索状态 | `"Succeeded"` |
| success | Boolean | 是否成功 | `true` |
| zipFile | String | ZIP 文件数据Base64 编码) | `"UEsDBBQ..."` |
| errorMessage | String | 错误消息(失败时) | `null` |
| messages | Array | 检索消息列表 | 见下方说明 |
| completedTime | Date | 完成时间 | `"2026-02-06T10:30:00"` |
| done | Boolean | 是否完成 | `true` |
##### RetrieveMessageVo 对象
| 参数名 | 类型 | 说明 | 示例 |
|--------|------|------|------|
| fileName | String | 文件名 | `"objects/Account.object"` |
| problem | String | 问题描述 | `"Entity is not found"` |
| problemType | String | 问题类型 | `"Warning"` |
#### 成功响应示例
```json
{
"code": 200,
"msg": "操作成功",
"data": {
"asyncId": "09Sxx0000000001EAA",
"status": "Succeeded",
"success": true,
"zipFile": "UEsDBBQACAAI...",
"errorMessage": null,
"messages": [],
"completedTime": "2026-02-06T10:30:00",
"done": true
}
}
```
#### 超时响应示例
```json
{
"code": 500,
"msg": "检索操作超时",
"data": null
}
```
---
### 接口 3单次检查状态
#### 功能描述
单次检查检索状态,立即返回当前状态。适用于前端主动轮询的场景,由前端控制轮询间隔。
#### 请求方式
`GET`
#### 请求路径
```
/salesforce/metadata/retrieve/check/{asyncId}
```
#### 权限要求
- 权限标识:`salesforce:metadata:retrieve`
#### 请求参数
##### 路径参数
| 参数名 | 类型 | 必填 | 说明 | 示例 |
|--------|------|------|------|------|
| asyncId | String | 是 | 异步操作 ID | `"09Sxx0000000001EAA"` |
#### 请求示例
```
GET /salesforce/metadata/retrieve/check/09Sxx0000000001EAA
```
#### 响应参数
##### 成功响应HTTP 200
与"轮询检索状态"接口的响应参数相同,但只返回当前状态,不会等待完成。
#### 进行中响应示例
```json
{
"code": 200,
"msg": "操作成功",
"data": {
"asyncId": "09Sxx0000000001EAA",
"status": "InProgress",
"success": null,
"zipFile": null,
"errorMessage": null,
"messages": [],
"completedTime": null,
"done": false
}
}
```
#### 已完成响应示例
```json
{
"code": 200,
"msg": "操作成功",
"data": {
"asyncId": "09Sxx0000000001EAA",
"status": "Succeeded",
"success": true,
"zipFile": "UEsDBBQACAAI...",
"errorMessage": null,
"messages": [],
"completedTime": "2026-02-06T10:30:00",
"done": true
}
}
```
---
### 接口 4获取检索历史
#### 功能描述
获取检索操作的历史记录列表。返回最近的检索记录,支持限制返回数量。
#### 请求方式
`GET`
#### 请求路径
```
/salesforce/metadata/retrieve/history
```
#### 权限要求
- 权限标识:`salesforce:metadata:retrieve`
#### 请求参数
##### 查询参数
| 参数名 | 类型 | 必填 | 说明 | 示例 |
|--------|------|------|------|------|
| limit | Integer | 否 | 返回数量限制,默认 50最大 100 | `50` |
#### 请求示例
```
GET /salesforce/metadata/retrieve/history?limit=20
```
#### 响应参数
##### 成功响应HTTP 200
| 参数名 | 类型 | 说明 | 示例 |
|--------|------|------|------|
| code | Integer | 状态码200 表示成功 | `200` |
| msg | String | 提示信息 | `"操作成功"` |
| data | Array | 检索历史列表 | 见下方说明 |
##### DataiMetadataRetrieve 对象
| 参数名 | 类型 | 说明 | 示例 |
|--------|------|------|------|
| id | Long | 记录 ID | `1` |
| asyncId | String | 异步操作 ID | `"09Sxx0000000001EAA"` |
| status | String | 检索状态 | `"Succeeded"` |
| done | Boolean | 是否完成 | `true` |
| message | String | 消息 | `"Retrieve completed successfully"` |
| errorMessage | String | 错误消息 | `null` |
| retrieveTime | Date | 检索时间 | `"2026-02-06T10:30:00"` |
| updateTime | Date | 更新时间 | `"2026-02-06T10:30:00"` |
| userId | Long | 用户 ID | `1` |
| createBy | String | 创建者 | `"admin"` |
| createTime | Date | 创建时间 | `"2026-02-06T10:25:00"` |
#### 成功响应示例
```json
{
"code": 200,
"msg": "操作成功",
"data": [
{
"id": 1,
"asyncId": "09Sxx0000000001EAA",
"status": "Succeeded",
"done": true,
"message": "Retrieve completed successfully",
"errorMessage": null,
"retrieveTime": "2026-02-06T10:30:00",
"updateTime": "2026-02-06T10:30:00",
"userId": 1,
"createBy": "admin",
"createTime": "2026-02-06T10:25:00"
},
{
"id": 2,
"asyncId": "09Sxx0000000002EAA",
"status": "Failed",
"done": true,
"message": null,
"errorMessage": "Invalid API version",
"retrieveTime": "2026-02-06T10:20:00",
"updateTime": "2026-02-06T10:20:00",
"userId": 1,
"createBy": "admin",
"createTime": "2026-02-06T10:15:00"
}
]
}
```
---
### 接口 5查询检索记录
#### 功能描述
根据 asyncId 查询具体的检索记录。用于获取某个特定检索操作的详细信息。
#### 请求方式
`GET`
#### 请求路径
```
/salesforce/metadata/retrieve/record/{asyncId}
```
#### 权限要求
- 权限标识:`salesforce:metadata:retrieve`
#### 请求参数
##### 路径参数
| 参数名 | 类型 | 必填 | 说明 | 示例 |
|--------|------|------|------|------|
| asyncId | String | 是 | 异步操作 ID | `"09Sxx0000000001EAA"` |
#### 请求示例
```
GET /salesforce/metadata/retrieve/record/09Sxx0000000001EAA
```
#### 响应参数
##### 成功响应HTTP 200
与"获取检索历史"接口中的单个对象结构相同。
#### 成功响应示例
```json
{
"code": 200,
"msg": "操作成功",
"data": {
"id": 1,
"asyncId": "09Sxx0000000001EAA",
"status": "Succeeded",
"done": true,
"message": "Retrieve completed successfully",
"errorMessage": null,
"retrieveTime": "2026-02-06T10:30:00",
"updateTime": "2026-02-06T10:30:00",
"userId": 1,
"createBy": "admin",
"createTime": "2026-02-06T10:25:00"
}
}
```
#### 记录不存在响应示例
```json
{
"code": 200,
"msg": "操作成功",
"data": null
}
```
---
## 错误码
### 业务错误码
| 错误码 | 说明 | 处理建议 |
|--------|------|----------|
| RETRIEVE_001 | 获取 MetadataConnection 失败 | 检查 Salesforce 连接配置 |
| RETRIEVE_002 | 检索元数据操作失败 | 检查请求参数和 API 版本 |
| RETRIEVE_003 | 检索操作超时 | 增加超时时间或稍后重试 |
| RETRIEVE_004 | 检查检索状态失败 | 检查 asyncId 是否正确 |
| RETRIEVE_005 | 获取检索历史失败 | 检查数据库连接 |
| RETRIEVE_006 | 根据 asyncId 查询检索记录失败 | 检查 asyncId 是否正确 |
| RETRIEVE_007 | 请求参数不能为空 | 检查请求体是否为空 |
| RETRIEVE_008 | API 版本不能为空 | 检查 apiVersion 字段 |
| RETRIEVE_009 | 未打包的元数据类型列表不能为空 | 检查 unpackaged.types 字段 |
| RETRIEVE_010 | 检索元数据失败 | 查看详细错误信息 |
### HTTP 状态码
| 状态码 | 说明 |
|--------|------|
| 200 | 请求成功 |
| 400 | 请求参数错误 |
| 401 | 未授权,需要登录 |
| 403 | 禁止访问,权限不足 |
| 500 | 服务器内部错误 |
---
## 使用流程
### 典型使用场景 1简单检索并等待结果
```
1. 调用 POST /salesforce/metadata/retrieve 提交检索请求
2. 获取返回的 asyncId
3. 调用 GET /salesforce/metadata/retrieve/status/{asyncId} 轮询状态
4. 等待返回结果(包含 ZIP 文件 Base64 数据)
5. 前端解码 Base64 并下载 ZIP 文件
```
### 典型使用场景 2前端主动轮询
```
1. 调用 POST /salesforce/metadata/retrieve 提交检索请求
2. 获取返回的 asyncId
3. 前端使用定时器,每隔 5 秒调用 GET /salesforce/metadata/retrieve/check/{asyncId}
4. 检查返回的 done 字段,为 true 时表示完成
5. 如果成功,获取 ZIP 文件数据;如果失败,显示错误信息
```
### 典型使用场景 3查询历史记录
```
1. 调用 GET /salesforce/metadata/retrieve/history 获取检索历史列表
2. 用户选择某条历史记录
3. 调用 GET /salesforce/metadata/retrieve/record/{asyncId} 获取详细信息
4. 显示检索状态和结果
```
---
## 注意事项
### 1. 异步操作特性
- 检索操作是异步的,提交请求后立即返回 asyncId
- 需要使用 asyncId 轮询或查询状态
- 检索时间取决于元数据数量和复杂度,可能需要几秒到几分钟
### 2. ZIP 文件处理
- ZIP 文件内容以 Base64 编码返回
- 不在数据库中存储 ZIP 文件内容
- 对于大文件,建议设置合理的超时时间
### 3. 超时控制
- 轮询接口默认超时时间为 5 分钟
- 可以通过 timeout 参数调整超时时间
- 超时后会抛出异常,需要客户端处理
### 4. 权限控制
- 所有接口都需要 `salesforce:metadata:retrieve` 权限
- 使用 Spring Security 的 `@PreAuthorize` 注解控制
- 确保用户有权限访问目标 Salesforce 组织的元数据
---
## 相关文档
- [需求文档](../requirements/sub/2026-01-28-003-06-检索操作.md)
- [设计文档](../design/2026-02-03-003-06-检索操作-设计.md)
- [决策记录](../decisions/2026-02-03-003-06-ADR-检索操作技术选型.md)
- [变更日志](../changelog/2026-02-06-003-06-changelog.md)
- [复盘文档](../retros/2026-02-06-003-06-retro.md)
- [会话记录](../sessions/2026-02-03-003-06-session.md)