# API 文档 - 批量操作 ## 元数据 - 需求编号:001-03 - 创建时间:2026-01-30 - 创建人:AI Assistant - 版本号:v1.0.0 - 模块:datai-salesforce-partner ## API 概述 批量操作 API 提供对 Salesforce 记录进行批量操作的能力,支持批量创建、批量更新、批量删除、批量 Upsert 四个核心操作。 ### 核心特性 - 支持最多 1000 条记录 - 自动分批处理(每批最多 200 条) - 支持部分失败情况 - 提供详细的成功/失败统计 - 支持 AllOrNoneHeader 控制 - 使用 DisableFeedTrackingHeader 提高性能 - 批次间休眠时间可配置 ### 基础信息 - **Base URL**:`/partner/batch` - **认证方式**:JWT Token(通过 Authorization Header 传递) - **权限要求**:需要登录权限(`@PreAuthorize("@ss.hasLogin()")`) - **Content-Type**:`application/json` ## 接口列表 ### 1. 批量创建记录 #### 接口说明 批量创建 Salesforce 记录,支持最多 1000 条记录,自动分批处理(每批最多 200 条)。 #### 请求信息 - **请求方式**:POST - **请求路径**:`/partner/batch/create` - **权限要求**:`@ss.hasLogin()` #### 请求参数 **Body 参数**: | 参数名 | 类型 | 必填 | 说明 | 示例 | |--------|------|------|------|------| | objectType | String | 是 | 对象类型 | "Account" | | records | List> | 是 | 记录列表,最多 1000 条 | [{"Name": "Test Account"}] | | allOrNone | Boolean | 否 | 是否全部成功或全部失败,默认 false | false | | sleepTime | Long | 否 | 批次间休眠时间(毫秒),默认 100 | 100 | #### 响应参数 **成功响应**(HTTP 200): | 参数名 | 类型 | 说明 | 示例 | |--------|------|------|------| | code | Integer | 状态码 | 200 | | msg | String | 提示信息 | "批量创建成功" | | data | Object | 响应数据 | - | | data.success | Boolean | 是否全部成功 | true | | data.successCount | Integer | 成功数量 | 100 | | data.failureCount | Integer | 失败数量 | 0 | | data.totalCount | Integer | 总数量 | 100 | | data.results | List | 结果列表 | - | | data.results[].success | Boolean | 单项是否成功 | true | | data.results[].id | String | 记录 ID | "001xx000003GWFjAAO" | | data.results[].errors | List | 错误列表 | [] | | data.results[].index | Integer | 索引 | 0 | **失败响应**(HTTP 200,业务失败): | 参数名 | 类型 | 说明 | 示例 | |--------|------|------|------| | code | Integer | 状态码 | 200 | | msg | String | 提示信息 | "批量创建部分失败" | | data | Object | 响应数据(包含失败详情) | - | **错误响应**(HTTP 500): | 参数名 | 类型 | 说明 | 示例 | |--------|------|------|------| | code | Integer | 状态码 | 500 | | msg | String | 错误信息 | "批量创建记录失败: ..." | #### 请求示例 ```json { "objectType": "Account", "records": [ { "Name": "Test Account 1", "BillingCity": "San Francisco" }, { "Name": "Test Account 2", "BillingCity": "New York" } ], "allOrNone": false, "sleepTime": 100 } ``` #### 响应示例 **成功示例**: ```json { "code": 200, "msg": "批量创建成功", "data": { "success": true, "successCount": 2, "failureCount": 0, "totalCount": 2, "results": [ { "success": true, "id": "001xx000003GWFjAAO", "errors": [], "index": 0 }, { "success": true, "id": "001xx000003GWFkAAP", "errors": [], "index": 1 } ] } } ``` **部分失败示例**: ```json { "code": 200, "msg": "批量创建部分失败", "data": { "success": false, "successCount": 1, "failureCount": 1, "totalCount": 2, "results": [ { "success": true, "id": "001xx000003GWFjAAO", "errors": [], "index": 0 }, { "success": false, "id": null, "errors": [ { "statusCode": "REQUIRED_FIELD_MISSING", "message": "Required fields are missing: [Name]", "fields": ["Name"] } ], "index": 1 } ] } } ``` --- ### 2. 批量更新记录 #### 接口说明 批量更新 Salesforce 记录,支持最多 1000 条记录,自动分批处理(每批最多 200 条)。每条记录必须包含 `id` 字段。 #### 请求信息 - **请求方式**:POST - **请求路径**:`/partner/batch/update` - **权限要求**:`@ss.hasLogin()` #### 请求参数 **Body 参数**: | 参数名 | 类型 | 必填 | 说明 | 示例 | |--------|------|------|------|------| | objectType | String | 是 | 对象类型 | "Account" | | records | List> | 是 | 记录列表,每条记录必须包含 id,最多 1000 条 | [{"id": "001xx...", "Name": "Updated"}] | | allOrNone | Boolean | 否 | 是否全部成功或全部失败,默认 false | false | | sleepTime | Long | 否 | 批次间休眠时间(毫秒),默认 100 | 100 | #### 响应参数 **成功响应**(HTTP 200): | 参数名 | 类型 | 说明 | 示例 | |--------|------|------|------| | code | Integer | 状态码 | 200 | | msg | String | 提示信息 | "批量更新成功" | | data | Object | 响应数据 | - | | data.success | Boolean | 是否全部成功 | true | | data.successCount | Integer | 成功数量 | 100 | | data.failureCount | Integer | 失败数量 | 0 | | data.totalCount | Integer | 总数量 | 100 | | data.results | List | 结果列表 | - | | data.results[].success | Boolean | 单项是否成功 | true | | data.results[].id | String | 记录 ID | "001xx000003GWFjAAO" | | data.results[].errors | List | 错误列表 | [] | | data.results[].index | Integer | 索引 | 0 | #### 请求示例 ```json { "objectType": "Account", "records": [ { "id": "001xx000003GWFjAAO", "Name": "Updated Account 1", "BillingCity": "Los Angeles" }, { "id": "001xx000003GWFkAAP", "Name": "Updated Account 2", "BillingCity": "Chicago" } ], "allOrNone": false, "sleepTime": 100 } ``` #### 响应示例 **成功示例**: ```json { "code": 200, "msg": "批量更新成功", "data": { "success": true, "successCount": 2, "failureCount": 0, "totalCount": 2, "results": [ { "success": true, "id": "001xx000003GWFjAAO", "errors": [], "index": 0 }, { "success": true, "id": "001xx000003GWFkAAP", "errors": [], "index": 1 } ] } } ``` --- ### 3. 批量删除记录 #### 接口说明 批量删除 Salesforce 记录,支持最多 1000 条记录,自动分批处理(每批最多 200 条)。 #### 请求信息 - **请求方式**:POST - **请求路径**:`/partner/batch/delete` - **权限要求**:`@ss.hasLogin()` #### 请求参数 **Body 参数**: | 参数名 | 类型 | 必填 | 说明 | 示例 | |--------|------|------|------|------| | objectType | String | 是 | 对象类型 | "Account" | | ids | List | 是 | 记录 ID 列表,最多 1000 条 | ["001xx...", "001xx..."] | | allOrNone | Boolean | 否 | 是否全部成功或全部失败,默认 false | false | | sleepTime | Long | 否 | 批次间休眠时间(毫秒),默认 100 | 100 | #### 响应参数 **成功响应**(HTTP 200): | 参数名 | 类型 | 说明 | 示例 | |--------|------|------|------| | code | Integer | 状态码 | 200 | | msg | String | 提示信息 | "批量删除成功" | | data | Object | 响应数据 | - | | data.success | Boolean | 是否全部成功 | true | | data.successCount | Integer | 成功数量 | 100 | | data.failureCount | Integer | 失败数量 | 0 | | data.totalCount | Integer | 总数量 | 100 | | data.results | List | 结果列表 | - | | data.results[].success | Boolean | 单项是否成功 | true | | data.results[].id | String | 记录 ID | "001xx000003GWFjAAO" | | data.results[].errors | List | 错误列表 | [] | | data.results[].index | Integer | 索引 | 0 | #### 请求示例 ```json { "objectType": "Account", "ids": [ "001xx000003GWFjAAO", "001xx000003GWFkAAP" ], "allOrNone": false, "sleepTime": 100 } ``` #### 响应示例 **成功示例**: ```json { "code": 200, "msg": "批量删除成功", "data": { "success": true, "successCount": 2, "failureCount": 0, "totalCount": 2, "results": [ { "success": true, "id": "001xx000003GWFjAAO", "errors": [], "index": 0 }, { "success": true, "id": "001xx000003GWFkAAP", "errors": [], "index": 1 } ] } } ``` --- ### 4. 批量 Upsert 记录 #### 接口说明 批量 Upsert(更新或插入)Salesforce 记录,支持最多 1000 条记录,自动分批处理(每批最多 200 条)。根据指定的外部 ID 字段,如果记录存在则更新,不存在则创建。 #### 请求信息 - **请求方式**:POST - **请求路径**:`/partner/batch/upsert` - **权限要求**:`@ss.hasLogin()` #### 请求参数 **Body 参数**: | 参数名 | 类型 | 必填 | 说明 | 示例 | |--------|------|------|------|------| | objectType | String | 是 | 对象类型 | "Account" | | externalIdField | String | 是 | 外部 ID 字段 | "ExternalId__c" | | records | List> | 是 | 记录列表,每条记录必须包含外部 ID 字段,最多 1000 条 | [{"ExternalId__c": "EXT001", "Name": "Test"}] | | allOrNone | Boolean | 否 | 是否全部成功或全部失败,默认 false | false | | sleepTime | Long | 否 | 批次间休眠时间(毫秒),默认 100 | 100 | #### 响应参数 **成功响应**(HTTP 200): | 参数名 | 类型 | 说明 | 示例 | |--------|------|------|------| | code | Integer | 状态码 | 200 | | msg | String | 提示信息 | "批量 Upsert 成功" | | data | Object | 响应数据 | - | | data.success | Boolean | 是否全部成功 | true | | data.successCount | Integer | 成功数量 | 100 | | data.failureCount | Integer | 失败数量 | 0 | | data.createdCount | Integer | 创建数量 | 50 | | data.updatedCount | Integer | 更新数量 | 50 | | data.totalCount | Integer | 总数量 | 100 | | data.results | List | 结果列表 | - | | data.results[].success | Boolean | 单项是否成功 | true | | data.results[].id | String | 记录 ID | "001xx000003GWFjAAO" | | data.results[].created | Boolean | 是否创建(true 创建,false 更新) | true | | data.results[].errors | List | 错误列表 | [] | | data.results[].index | Integer | 索引 | 0 | #### 请求示例 ```json { "objectType": "Account", "externalIdField": "ExternalId__c", "records": [ { "ExternalId__c": "EXT001", "Name": "Upsert Account 1", "BillingCity": "Seattle" }, { "ExternalId__c": "EXT002", "Name": "Upsert Account 2", "BillingCity": "Boston" } ], "allOrNone": false, "sleepTime": 100 } ``` #### 响应示例 **成功示例**: ```json { "code": 200, "msg": "批量 Upsert 成功", "data": { "success": true, "successCount": 2, "failureCount": 0, "createdCount": 1, "updatedCount": 1, "totalCount": 2, "results": [ { "success": true, "id": "001xx000003GWFjAAO", "created": true, "errors": [], "index": 0 }, { "success": true, "id": "001xx000003GWFkAAP", "created": false, "errors": [], "index": 1 } ] } } ``` --- ## 错误码 ### 系统错误码 | 错误码 | 错误消息 | 说明 | 解决方案 | |--------|----------|------|----------| | 200 | 操作成功 | 请求处理成功 | - | | 500 | 操作失败 | 服务器内部错误 | 检查服务器日志,联系管理员 | | 401 | 未授权 | 用户未登录或 Token 无效 | 重新登录获取 Token | | 403 | 禁止访问 | 用户没有权限执行该操作 | 检查用户权限配置 | ### 业务错误码 | 错误码 | 错误消息 | 说明 | 解决方案 | |--------|----------|------|----------| | INVALID_OBJECT_TYPE | 无效的对象类型 | 对象类型不存在或无权限访问 | 检查对象类型名称是否正确 | | INVALID_RECORD_ID | 无效的记录 ID | 记录 ID 格式不正确或记录不存在 | 检查记录 ID 是否正确 | | INVALID_FIELD_NAME | 无效的字段名称 | 字段名称不存在或无权限访问 | 检查字段名称是否正确 | | INVALID_FIELD_VALUE | 无效的字段值 | 字段值不符合要求 | 检查字段值是否符合要求 | | MISSING_REQUIRED_FIELD | 缺少必填字段 | 缺少必填字段的值 | 补充必填字段的值 | | MISSING_RECORD_ID | 缺少记录 ID | Update 操作必须提供记录 ID | 在记录中添加 id 字段 | | MISSING_EXTERNAL_ID | 缺少外部 ID | Upsert 操作必须提供外部 ID 字段 | 在记录中添加外部 ID 字段 | | DUPLICATE_VALUE | 重复值 | 字段值已存在,违反唯一性约束 | 检查字段值是否重复 | | RECORD_LOCKED | 记录已锁定 | 记录被其他用户锁定 | 等待其他用户释放锁定 | | INSUFFICIENT_PERMISSIONS | 权限不足 | 当前用户没有执行该操作的权限 | 检查用户权限配置 | | ENTITY_IS_DELETED | 记录已删除 | 记录已被删除 | 检查记录是否存在 | | BATCH_SIZE_EXCEEDED | 批量大小超出限制 | 单次批量操作最多支持 1000 条记录 | 减少记录数量 | | OPERATION_FAILED | 操作失败 | 操作执行失败 | 检查错误详情 | ### Salesforce API 错误码 | 错误码 | 说明 | |--------|------| | REQUIRED_FIELD_MISSING | 缺少必填字段 | | INVALID_FIELD | 无效字段 | | INVALID_ID_FIELD | 无效 ID 字段 | | INVALID_CROSS_REFERENCE_KEY | 无效交叉引用键 | | DUPLICATE_VALUE | 重复值 | | ENTITY_IS_LOCKED | 实体已锁定 | | INSUFFICIENT_ACCESS_OR_READONLY | 权限不足或只读 | | INVALID_OPERATION | 无效操作 | | STORAGE_LIMIT_EXCEEDED | 存储限制超出 | | SYSTEM_UNAVAILABLE | 系统不可用 | ## 限制与约束 ### 数量限制 - 单次请求最多支持 1000 条记录 - 每批最多 200 条记录 - 超出限制将返回 BATCH_SIZE_EXCEEDED 错误 ### 性能限制 - 批次间默认休眠 100ms - 可根据实际情况调整休眠时间 - 建议使用 DisableFeedTrackingHeader 提高性能 ### 权限要求 - 需要登录权限(`@ss.hasLogin()`) - 需要有相应对象的读写权限 - 需要有相应字段的访问权限 ## 最佳实践 ### 1. 分批处理 对于大规模数据操作,建议使用自动分批处理功能: - 单次请求最多 1000 条记录 - 系统会自动分批处理(每批 200 条) - 建议设置适当的批次间休眠时间,避免 API 限流 ### 2. 错误处理 - 建议设置 `allOrNone` 为 `false`,允许部分失败 - 检查返回结果中的 `success` 字段,判断是否全部成功 - 对于失败的记录,可以查看 `results` 中的错误详情 ### 3. 性能优化 - 使用 `DisableFeedTrackingHeader` 提高性能(已默认启用) - 设置适当的 `sleepTime`,避免 API 限流 - 避免在高峰期进行大规模批量操作 ### 4. Upsert 使用 - 确保外部 ID 字段在对象中已定义 - 确保每条记录都包含外部 ID 字段的值 - 可以使用 `created` 字段判断记录是创建还是更新 ## 相关文档 - [需求文档](../requirements/sub/2026-01-28-001-03-批量操作.md) - 批量操作需求文档 - [设计文档](../design/2026-01-30-003-批量操作-设计.md) - 批量操作设计文档 - [决策记录](../decisions/2026-01-30-003-ADR-批量操作技术选型.md) - 批量操作技术选型决策记录 - [变更日志](../changelog/2026-01-30-003-changelog.md) - 批量操作变更日志 - [复盘文档](../retros/2026-01-30-003-retro.md) - 批量操作复盘文档 - [会话记录](../sessions/2026-01-28-001-session.md) - 会话记录