532 lines
13 KiB
Markdown
532 lines
13 KiB
Markdown
# API 文档 - 查询功能
|
||
|
||
## 元数据
|
||
- 需求编号:001-04
|
||
- 创建时间:2026-01-30
|
||
- 创建人:AI Assistant
|
||
- 版本号:v1.0.0
|
||
- 状态:已完成
|
||
|
||
## API 概述
|
||
|
||
查询功能 API 提供对 Salesforce 数据的查询能力,包括 SOQL 查询、查询所有记录(包括已删除的)、分页查询和 SOSL 搜索四个核心功能。所有接口都需要用户登录后才能访问。
|
||
|
||
### 基础信息
|
||
- **基础路径**:`/partner`
|
||
- **认证方式**:JWT Token(通过请求头传入)
|
||
- **权限要求**:已登录用户
|
||
- **数据格式**:JSON
|
||
|
||
### 功能列表
|
||
1. **Query** - 执行标准 SOQL 查询
|
||
2. **QueryAll** - 查询所有记录(包括已删除的)
|
||
3. **QueryMore** - 获取查询结果的下一页
|
||
4. **Search** - 执行 SOSL 搜索
|
||
|
||
## 接口列表
|
||
|
||
### 1. 执行 SOQL 查询
|
||
|
||
执行标准的 SOQL 查询语句,返回查询结果。
|
||
|
||
#### 基本信息
|
||
- **接口名称**:query
|
||
- **请求方式**:POST
|
||
- **请求路径**:`/partner/query`
|
||
- **权限要求**:`@PreAuthorize("@ss.hasLogin()")`
|
||
|
||
#### 请求参数
|
||
|
||
| 参数名 | 类型 | 必填 | 说明 | 示例 |
|
||
|--------|------|------|------|------|
|
||
| soql | String | 是 | SOQL 查询语句 | `SELECT Id, Name FROM Account LIMIT 10` |
|
||
| batchSize | Integer | 否 | 批次大小,默认 500,最大 2000 | 500 |
|
||
|
||
#### 请求示例
|
||
```json
|
||
{
|
||
"soql": "SELECT Id, Name, CreatedDate FROM Account WHERE Name LIKE '%Test%' LIMIT 10",
|
||
"batchSize": 500
|
||
}
|
||
```
|
||
|
||
#### 响应参数
|
||
|
||
| 参数名 | 类型 | 说明 |
|
||
|--------|------|------|
|
||
| code | Integer | 状态码(200 成功,其他失败) |
|
||
| msg | String | 提示信息 |
|
||
| data | Object | 查询结果 |
|
||
| data.records | List<Map> | 记录列表 |
|
||
| data.queryLocator | String | 查询定位器,用于 QueryMore 获取下一页 |
|
||
| data.done | Boolean | 是否完成(true 表示没有更多数据) |
|
||
| data.size | Integer | 记录数量 |
|
||
| data.success | Boolean | 是否成功 |
|
||
| data.errors | List | 错误信息列表 |
|
||
|
||
#### 成功响应示例
|
||
```json
|
||
{
|
||
"code": 200,
|
||
"msg": "操作成功",
|
||
"data": {
|
||
"records": [
|
||
{
|
||
"Id": "001D000001",
|
||
"Name": "Test Account 1",
|
||
"CreatedDate": "2026-01-15T10:30:00.000Z"
|
||
},
|
||
{
|
||
"Id": "001D000002",
|
||
"Name": "Test Account 2",
|
||
"CreatedDate": "2026-01-16T14:20:00.000Z"
|
||
}
|
||
],
|
||
"queryLocator": "01gD0000002J6ozIAC-2000",
|
||
"done": false,
|
||
"size": 2,
|
||
"success": true,
|
||
"errors": null
|
||
}
|
||
}
|
||
```
|
||
|
||
#### 失败响应示例
|
||
```json
|
||
{
|
||
"code": 500,
|
||
"msg": "查询失败: INVALID_FIELD: No such column 'InvalidField' on entity 'Account'",
|
||
"data": null
|
||
}
|
||
```
|
||
|
||
#### SOQL 语法说明
|
||
|
||
**支持的运算符**:
|
||
- `=` : 等于
|
||
- `!=` : 不等于
|
||
- `>` : 大于
|
||
- `>=` : 大于等于
|
||
- `<` : 小于
|
||
- `<=` : 小于等于
|
||
- `LIKE` : 模糊匹配(使用 `%` 作为通配符)
|
||
- `IN` : 在列表中
|
||
- `NOT IN` : 不在列表中
|
||
- `= NULL` : 为空
|
||
- `!= NULL` : 不为空
|
||
|
||
**支持的子句**:
|
||
- `WHERE` : 条件过滤
|
||
- `GROUP BY` : 分组
|
||
- `HAVING` : 分组过滤
|
||
- `ORDER BY` : 排序
|
||
- `LIMIT` : 限制返回记录数
|
||
- `OFFSET` : 跳过指定数量的记录
|
||
|
||
**注意事项**:
|
||
- 不支持 `SELECT *`,必须明确指定字段或使用 `FIELDS(ALL)`、`FIELDS(STANDARD)`、`FIELDS(CUSTOM)`
|
||
- 不支持 `BETWEEN` 运算符,请使用 `>=` 和 `<=` 组合代替
|
||
- 不支持 `JOIN`,使用关系查询(Relationship Queries)如 `Account.Name`
|
||
- 不支持 `UNION`,无法合并两个不相关的结果集
|
||
- 查询最多返回 50000 条记录
|
||
- `OFFSET` 上限为 2000,且必须与 `LIMIT` 一起使用
|
||
|
||
#### 关系查询示例
|
||
```json
|
||
{
|
||
"soql": "SELECT Id, Name, Account.Name, Account.Industry FROM Contact WHERE Account.Name LIKE '%Acme%'",
|
||
"batchSize": 500
|
||
}
|
||
```
|
||
|
||
#### 聚合查询示例
|
||
```json
|
||
{
|
||
"soql": "SELECT Industry, COUNT(Id) total FROM Account GROUP BY Industry HAVING COUNT(Id) > 5",
|
||
"batchSize": 500
|
||
}
|
||
```
|
||
|
||
---
|
||
|
||
### 2. 查询所有记录(包括已删除的)
|
||
|
||
执行 SOQL 查询,返回所有记录,包括已删除到回收站中的记录。
|
||
|
||
#### 基本信息
|
||
- **接口名称**:queryAll
|
||
- **请求方式**:POST
|
||
- **请求路径**:`/partner/queryAll`
|
||
- **权限要求**:`@PreAuthorize("@ss.hasLogin()")`
|
||
|
||
#### 请求参数
|
||
|
||
| 参数名 | 类型 | 必填 | 说明 | 示例 |
|
||
|--------|------|------|------|------|
|
||
| soql | String | 是 | SOQL 查询语句 | `SELECT Id, Name FROM Account LIMIT 10` |
|
||
| batchSize | Integer | 否 | 批次大小,默认 500,最大 2000 | 500 |
|
||
|
||
#### 请求示例
|
||
```json
|
||
{
|
||
"soql": "SELECT Id, Name, IsDeleted FROM Account WHERE Name LIKE '%Test%' LIMIT 10",
|
||
"batchSize": 500
|
||
}
|
||
```
|
||
|
||
#### 响应参数
|
||
|
||
| 参数名 | 类型 | 说明 |
|
||
|--------|------|------|
|
||
| code | Integer | 状态码(200 成功,其他失败) |
|
||
| msg | String | 提示信息 |
|
||
| data | Object | 查询结果(结构同 Query 接口) |
|
||
|
||
#### 成功响应示例
|
||
```json
|
||
{
|
||
"code": 200,
|
||
"msg": "操作成功",
|
||
"data": {
|
||
"records": [
|
||
{
|
||
"Id": "001D000001",
|
||
"Name": "Test Account 1",
|
||
"IsDeleted": false
|
||
},
|
||
{
|
||
"Id": "001D000002",
|
||
"Name": "Deleted Account",
|
||
"IsDeleted": true
|
||
}
|
||
],
|
||
"queryLocator": null,
|
||
"done": true,
|
||
"size": 2,
|
||
"success": true,
|
||
"errors": null
|
||
}
|
||
}
|
||
```
|
||
|
||
#### 适用场景
|
||
- 数据恢复:查找已删除的记录
|
||
- 数据审计:查看所有记录的历史状态
|
||
- 数据同步:确保数据同步的完整性
|
||
|
||
---
|
||
|
||
### 3. 获取查询结果的下一页
|
||
|
||
使用 QueryLocator 获取查询结果的下一页数据。
|
||
|
||
#### 基本信息
|
||
- **接口名称**:queryMore
|
||
- **请求方式**:POST
|
||
- **请求路径**:`/partner/queryMore`
|
||
- **权限要求**:`@PreAuthorize("@ss.hasLogin()")`
|
||
|
||
#### 请求参数
|
||
|
||
| 参数名 | 类型 | 必填 | 说明 | 示例 |
|
||
|--------|------|------|------|------|
|
||
| queryLocator | String | 是 | 查询定位器,从 Query 或 QueryAll 的结果中获取 | `01gD0000002J6ozIAC-2000` |
|
||
|
||
#### 请求示例
|
||
```json
|
||
{
|
||
"queryLocator": "01gD0000002J6ozIAC-2000"
|
||
}
|
||
```
|
||
|
||
#### 响应参数
|
||
|
||
| 参数名 | 类型 | 说明 |
|
||
|--------|------|------|
|
||
| code | Integer | 状态码(200 成功,其他失败) |
|
||
| msg | String | 提示信息 |
|
||
| data | Object | 查询结果(结构同 Query 接口) |
|
||
|
||
#### 成功响应示例
|
||
```json
|
||
{
|
||
"code": 200,
|
||
"msg": "操作成功",
|
||
"data": {
|
||
"records": [
|
||
{
|
||
"Id": "001D000003",
|
||
"Name": "Test Account 3"
|
||
},
|
||
{
|
||
"Id": "001D000004",
|
||
"Name": "Test Account 4"
|
||
}
|
||
],
|
||
"queryLocator": "01gD0000002J6ozIAC-4000",
|
||
"done": true,
|
||
"size": 2,
|
||
"success": true,
|
||
"errors": null
|
||
}
|
||
}
|
||
```
|
||
|
||
#### 分页流程说明
|
||
|
||
1. **首次查询**:调用 Query 或 QueryAll 接口,获取第一批数据
|
||
2. **检查是否完成**:查看响应中的 `done` 字段
|
||
- 如果 `done` 为 `true`,表示没有更多数据,分页结束
|
||
- 如果 `done` 为 `false`,表示还有更多数据,继续下一步
|
||
3. **获取下一页**:使用响应中的 `queryLocator` 调用 QueryMore 接口
|
||
4. **重复步骤 2-3**,直到 `done` 为 `true`
|
||
|
||
#### 注意事项
|
||
- **有效期限制**:queryLocator 通常有 15 分钟的有效期,过期后需要重新查询
|
||
- **并发限制**:同一 queryLocator 不支持并发访问
|
||
- **数据一致性**:分页查询期间,如果数据发生变化,可能导致数据重复或遗漏
|
||
|
||
---
|
||
|
||
### 4. 执行 SOSL 搜索
|
||
|
||
执行 SOSL 搜索语句,支持跨对象全文搜索。
|
||
|
||
#### 基本信息
|
||
- **接口名称**:search
|
||
- **请求方式**:POST
|
||
- **请求路径**:`/partner/search`
|
||
- **权限要求**:`@PreAuthorize("@ss.hasLogin()")`
|
||
|
||
#### 请求参数
|
||
|
||
| 参数名 | 类型 | 必填 | 说明 | 示例 |
|
||
|--------|------|------|------|------|
|
||
| sosl | String | 是 | SOSL 搜索语句 | `FIND {Acme} IN ALL FIELDS RETURNING Account(Id, Name), Contact(Id, Name)` |
|
||
|
||
#### 请求示例
|
||
```json
|
||
{
|
||
"sosl": "FIND {Acme} IN ALL FIELDS RETURNING Account(Id, Name, Industry), Contact(Id, FirstName, LastName, Email)"
|
||
}
|
||
```
|
||
|
||
#### 响应参数
|
||
|
||
| 参数名 | 类型 | 说明 |
|
||
|--------|------|------|
|
||
| code | Integer | 状态码(200 成功,其他失败) |
|
||
| msg | String | 提示信息 |
|
||
| data | Object | 搜索结果 |
|
||
| data.searchRecords | List | 搜索结果列表 |
|
||
| data.searchRecords[0].type | String | 记录类型(如 Account、Contact) |
|
||
| data.searchRecords[0].record | Map | 记录数据 |
|
||
| data.success | Boolean | 是否成功 |
|
||
| data.errors | List | 错误信息列表 |
|
||
|
||
#### 成功响应示例
|
||
```json
|
||
{
|
||
"code": 200,
|
||
"msg": "操作成功",
|
||
"data": {
|
||
"searchRecords": [
|
||
{
|
||
"type": "Account",
|
||
"record": {
|
||
"Id": "001D000001",
|
||
"Name": "Acme Corporation",
|
||
"Industry": "Technology"
|
||
}
|
||
},
|
||
{
|
||
"type": "Account",
|
||
"record": {
|
||
"Id": "001D000002",
|
||
"Name": "Acme Ltd",
|
||
"Industry": "Manufacturing"
|
||
}
|
||
},
|
||
{
|
||
"type": "Contact",
|
||
"record": {
|
||
"Id": "003D000001",
|
||
"FirstName": "John",
|
||
"LastName": "Acme",
|
||
"Email": "john@acme.com"
|
||
}
|
||
}
|
||
],
|
||
"success": true,
|
||
"errors": null
|
||
}
|
||
}
|
||
```
|
||
|
||
#### SOSL 语法说明
|
||
|
||
**基本语法**:
|
||
```sql
|
||
FIND {搜索关键词}
|
||
[IN 搜索范围]
|
||
[RETURNING 对象类型(字段列表)]
|
||
[WITH 过滤条件]
|
||
[LIMIT 结果限制]
|
||
```
|
||
|
||
**搜索范围**:
|
||
- `IN ALL FIELDS` - 在所有字段中搜索
|
||
- `IN NAME FIELDS` - 在名称字段中搜索
|
||
- `IN EMAIL FIELDS` - 在邮箱字段中搜索
|
||
- `IN PHONE FIELDS` - 在电话字段中搜索
|
||
- `IN SIDEBAR FIELDS` - 在侧边栏字段中搜索
|
||
|
||
**RETURNING 子句**:
|
||
- 指定要搜索的对象类型和返回的字段
|
||
- 支持多个对象类型,用逗号分隔
|
||
- 可以为每个对象类型指定 LIMIT
|
||
|
||
**搜索关键词**:
|
||
- 使用 `{}` 包裹搜索关键词
|
||
- 支持通配符 `*` 和 `?`
|
||
- 支持逻辑运算符 `AND`、`OR`、`NOT`
|
||
|
||
#### SOSL 示例
|
||
|
||
**基本搜索**:
|
||
```json
|
||
{
|
||
"sosl": "FIND {Acme} IN ALL FIELDS RETURNING Account(Id, Name), Contact(Id, Name)"
|
||
}
|
||
```
|
||
|
||
**模糊搜索**:
|
||
```json
|
||
{
|
||
"sosl": "FIND {Acme*} IN NAME FIELDS RETURNING Account(Id, Name), Contact(Id, FirstName, LastName)"
|
||
}
|
||
```
|
||
|
||
**多关键词搜索**:
|
||
```json
|
||
{
|
||
"sosl": "FIND {Acme OR Salesforce} IN ALL FIELDS RETURNING Account(Id, Name), Contact(Id, Name), Lead(Id, Name)"
|
||
}
|
||
```
|
||
|
||
**带限制的搜索**:
|
||
```json
|
||
{
|
||
"sosl": "FIND {Acme} IN ALL FIELDS RETURNING Account(Id, Name LIMIT 10), Contact(Id, Name LIMIT 10)"
|
||
}
|
||
```
|
||
|
||
---
|
||
|
||
## 错误码
|
||
|
||
### 系统错误码
|
||
|
||
| 错误码 | 说明 | 处理建议 |
|
||
|--------|------|----------|
|
||
| 200 | 成功 | 无需处理 |
|
||
| 401 | 未授权 | 检查是否已登录,Token 是否有效 |
|
||
| 403 | 禁止访问 | 检查用户权限 |
|
||
| 500 | 服务器内部错误 | 查看错误消息,检查 SOQL/SOSL 语法 |
|
||
|
||
### 业务错误码
|
||
|
||
| 错误码 | 说明 | 处理建议 |
|
||
|--------|------|----------|
|
||
| 1001 | SOQL 语法错误 | 检查 SOQL 语句语法,参考 Salesforce 文档 |
|
||
| 1002 | SOSL 语法错误 | 检查 SOSL 语句语法,参考 Salesforce 文档 |
|
||
| 1003 | 无效的批次大小 | 确保 batchSize 在 1-2000 范围内 |
|
||
| 1004 | 无效的查询定位器 | 确保 queryLocator 有效且未过期 |
|
||
| 1005 | 查询超时 | 优化查询条件,减少返回数据量 |
|
||
| 1006 | 超出查询限制 | 减少查询复杂度,避免超过 Salesforce 限制 |
|
||
|
||
### 常见错误消息
|
||
|
||
| 错误消息 | 说明 | 处理建议 |
|
||
|----------|------|----------|
|
||
| `INVALID_FIELD` | 无效的字段名 | 检查字段名是否正确,是否存在于对象中 |
|
||
| `INVALID_TYPE` | 无效的对象类型 | 检查对象类型名是否正确 |
|
||
| `MALFORMED_QUERY` | 查询格式错误 | 检查 SOQL/SOSL 语法 |
|
||
| `QUERY_TIMEOUT` | 查询超时 | 优化查询条件,添加 LIMIT |
|
||
| `TOO_MANY_QUERY_ROWS` | 查询返回记录过多 | 添加 LIMIT 限制返回记录数 |
|
||
| `INVALID_QUERY_LOCATOR` | 无效的查询定位器 | queryLocator 已过期,需要重新查询 |
|
||
|
||
---
|
||
|
||
## 相关文档
|
||
|
||
- [需求文档](../requirements/sub/2026-01-28-001-04-查询功能.md)
|
||
- [设计文档](../design/2026-01-30-004-查询功能-设计.md)
|
||
- [决策记录](../decisions/2026-01-30-004-ADR-查询功能技术选型.md)
|
||
- [提示词文档](../prompts/2026-01-30-004-prompt-查询功能.md)
|
||
- [变更日志](../changelog/2026-01-30-004-changelog.md)
|
||
- [复盘文档](../retros/2026-01-30-004-retro.md)
|
||
- [会话记录](../sessions/2026-01-28-001-session.md)
|
||
|
||
---
|
||
|
||
## 附录
|
||
|
||
### SOQL 快速参考
|
||
|
||
**基本查询**:
|
||
```sql
|
||
SELECT Id, Name FROM Account
|
||
```
|
||
|
||
**条件查询**:
|
||
```sql
|
||
SELECT Id, Name FROM Account WHERE Name LIKE '%Test%'
|
||
```
|
||
|
||
**排序**:
|
||
```sql
|
||
SELECT Id, Name FROM Account ORDER BY Name ASC
|
||
```
|
||
|
||
**限制返回数量**:
|
||
```sql
|
||
SELECT Id, Name FROM Account LIMIT 100
|
||
```
|
||
|
||
**分页**:
|
||
```sql
|
||
SELECT Id, Name FROM Account LIMIT 100 OFFSET 100
|
||
```
|
||
|
||
**关系查询**:
|
||
```sql
|
||
SELECT Id, Name, Account.Name FROM Contact
|
||
```
|
||
|
||
**聚合查询**:
|
||
```sql
|
||
SELECT Industry, COUNT(Id) FROM Account GROUP BY Industry
|
||
```
|
||
|
||
### SOSL 快速参考
|
||
|
||
**基本搜索**:
|
||
```sql
|
||
FIND {Acme} IN ALL FIELDS RETURNING Account(Id, Name)
|
||
```
|
||
|
||
**多对象搜索**:
|
||
```sql
|
||
FIND {Acme} IN ALL FIELDS RETURNING Account(Id, Name), Contact(Id, Name)
|
||
```
|
||
|
||
**模糊搜索**:
|
||
```sql
|
||
FIND {Acme*} IN NAME FIELDS RETURNING Account(Id, Name)
|
||
```
|
||
|
||
**带限制的搜索**:
|
||
```sql
|
||
FIND {Acme} IN ALL FIELDS RETURNING Account(Id, Name LIMIT 10)
|
||
``` |