# API 文档 - 删除操作 ## 元数据 - 需求编号:003-05 - 创建时间:2026-02-06 - 创建人:AI Assistant - 状态:已完成 - 版本:v1.0.0 ## API 概述 本文档描述了 Salesforce Metadata API 删除操作相关的 REST API 接口,包括元数据删除、批量删除和删除历史查询功能。 ### 核心功能 1. **元数据删除**:根据元数据类型和完整名称删除单个或多个元数据 2. **批量删除**:支持批量删除不同类型的元数据,自动分批处理(每批 10 个) 3. **删除历史查询**:查询删除操作的历史记录 ### 技术栈 - Spring Boot 2.7.x - Spring Security(权限控制) - MyBatis Plus(数据持久化) - Salesforce Metadata API ### 基础路径 ``` /salesforce/metadata/delete ``` ## 接口列表 ### 接口 1:删除元数据 #### 功能描述 根据元数据类型和完整名称列表删除元数据。支持一次删除多个同类型的元数据(最多 10 个,超过会自动分批处理)。 #### 请求方式 `POST` #### 请求路径 ``` /salesforce/metadata/delete/{type} ``` #### 权限要求 - 权限标识:`salesforce:metadata:delete` - 使用 `@PreAuthorize("@ss.hasPermi('salesforce:metadata:delete')")` 控制 #### 请求参数 ##### 路径参数 | 参数名 | 类型 | 必填 | 说明 | 示例 | |--------|------|------|------|------| | type | String | 是 | 元数据类型 | `CustomObject`、`ApexClass`、`ApexTrigger` | ##### 请求体参数 | 参数名 | 类型 | 必填 | 说明 | 示例 | |--------|------|------|------|------| | fullNames | String[] | 是 | 元数据完整名称列表 | `["MyCustomObject__c", "AnotherObject__c"]` | #### 请求示例 ```json POST /salesforce/metadata/delete/CustomObject Content-Type: application/json ["MyCustomObject__c", "AnotherObject__c"] ``` #### 响应参数 ##### 成功响应(HTTP 200) | 参数名 | 类型 | 说明 | 示例 | |--------|------|------|------| | code | Integer | 状态码,200 表示成功 | `200` | | msg | String | 提示信息 | `"操作成功"` | | data | Array | 删除结果列表 | 见下方示例 | ##### 删除结果对象(DeleteResultVo) | 参数名 | 类型 | 说明 | 示例 | |--------|------|------|------| | fullName | String | 元数据完整名称 | `"MyCustomObject__c"` | | success | Boolean | 是否删除成功 | `true` | | errors | Array | 错误消息数组(失败时) | `["Entity is not found"]` | #### 成功响应示例 ```json { "code": 200, "msg": "操作成功", "data": [ { "fullName": "MyCustomObject__c", "success": true, "errors": null }, { "fullName": "AnotherObject__c", "success": false, "errors": ["Entity is not found"] } ] } ``` #### 失败响应示例 ```json { "code": 500, "msg": "Salesforce 连接失败: Connection refused" } ``` --- ### 接口 2:批量删除元数据 #### 功能描述 批量删除不同类型的元数据。支持一次提交多个删除请求,每个请求包含元数据类型和完整名称列表。系统会自动对每个请求进行分批处理(每批 10 个)。 #### 请求方式 `POST` #### 请求路径 ``` /salesforce/metadata/delete/batch ``` #### 权限要求 - 权限标识:`salesforce:metadata:delete` - 使用 `@PreAuthorize("@ss.hasPermi('salesforce:metadata:delete')")` 控制 #### 请求参数 ##### 请求体参数(DeleteRequest 数组) | 参数名 | 类型 | 必填 | 说明 | 示例 | |--------|------|------|------|------| | type | String | 是 | 元数据类型 | `CustomObject`、`ApexClass` | | fullNames | String[] | 是 | 元数据完整名称列表 | `["Object1__c", "Object2__c"]` | #### 请求示例 ```json POST /salesforce/metadata/delete/batch Content-Type: application/json [ { "type": "CustomObject", "fullNames": ["MyCustomObject__c", "AnotherObject__c"] }, { "type": "ApexClass", "fullNames": ["MyApexClass", "AnotherClass"] } ] ``` #### 响应参数 ##### 成功响应(HTTP 200) | 参数名 | 类型 | 说明 | 示例 | |--------|------|------|------| | code | Integer | 状态码,200 表示成功 | `200` | | msg | String | 提示信息 | `"批量删除完成,成功 3 个,失败 1 个"` | | data | Object | 批量删除结果 | 见下方示例 | ##### 批量删除结果对象 | 参数名 | 类型 | 说明 | 示例 | |--------|------|------|------| | totalCount | Integer | 总删除数量 | `4` | | successCount | Integer | 成功数量 | `3` | | failureCount | Integer | 失败数量 | `1` | | results | Array | 详细删除结果列表 | DeleteResultVo 数组 | #### 成功响应示例 ```json { "code": 200, "msg": "批量删除完成,成功 3 个,失败 1 个", "data": { "totalCount": 4, "successCount": 3, "failureCount": 1, "results": [ { "fullName": "MyCustomObject__c", "success": true, "errors": null }, { "fullName": "AnotherObject__c", "success": false, "errors": ["Entity is not found"] }, { "fullName": "MyApexClass", "success": true, "errors": null }, { "fullName": "AnotherClass", "success": true, "errors": null } ] } } ``` #### 失败响应示例 ```json { "code": 500, "msg": "批量删除失败: 参数校验失败" } ``` --- ### 接口 3:获取删除历史 #### 功能描述 查询元数据删除操作的历史记录,支持限制返回数量。 #### 请求方式 `GET` #### 请求路径 ``` /salesforce/metadata/delete/history ``` #### 权限要求 - 权限标识:`salesforce:metadata:delete:query` - 使用 `@PreAuthorize("@ss.hasPermi('salesforce:metadata:delete:query')")` 控制 #### 请求参数 ##### 查询参数 | 参数名 | 类型 | 必填 | 说明 | 默认值 | 范围 | |--------|------|------|------|--------|------| | limit | Integer | 否 | 返回记录数量限制 | `10` | 1-100 | #### 请求示例 ``` GET /salesforce/metadata/delete/history?limit=20 ``` #### 响应参数 ##### 成功响应(HTTP 200) | 参数名 | 类型 | 说明 | 示例 | |--------|------|------|------| | code | Integer | 状态码,200 表示成功 | `200` | | msg | String | 提示信息 | `"操作成功"` | | data | Array | 删除历史记录列表 | 见下方示例 | ##### 删除历史记录对象(DataiMetadataDelete) | 参数名 | 类型 | 说明 | 示例 | |--------|------|------|------| | id | Long | 记录 ID | `1` | | metadataType | String | 元数据类型 | `CustomObject` | | fullName | String | 元数据完整名称 | `MyCustomObject__c` | | success | Integer | 是否成功(0-否,1-是) | `1` | | errorMessage | String | 错误消息(失败时) | `null` | | deleteTime | Date | 删除时间 | `2026-02-06 10:30:00` | | userId | Long | 操作用户 ID | `1` | | createBy | String | 创建者 | `admin` | | createTime | Date | 创建时间 | `2026-02-06 10:30:00` | #### 成功响应示例 ```json { "code": 200, "msg": "操作成功", "data": [ { "id": 1, "metadataType": "CustomObject", "fullName": "MyCustomObject__c", "success": 1, "errorMessage": null, "deleteTime": "2026-02-06 10:30:00", "userId": 1, "createBy": "admin", "createTime": "2026-02-06 10:30:00" }, { "id": 2, "metadataType": "ApexClass", "fullName": "MyApexClass", "success": 0, "errorMessage": "Entity is not found", "deleteTime": "2026-02-06 10:35:00", "userId": 1, "createBy": "admin", "createTime": "2026-02-06 10:35:00" } ] } ``` #### 失败响应示例 ```json { "code": 500, "msg": "获取删除历史失败" } ``` --- ## 错误码 ### 系统错误码 | 错误码 | 说明 | 场景 | |--------|------|------| | 200 | 操作成功 | 请求处理成功 | | 500 | 操作失败 | 服务器内部错误 | | 401 | 未授权 | 用户未登录或 Token 过期 | | 403 | 禁止访问 | 用户没有权限 | | 404 | 资源不存在 | 请求的资源不存在 | ### 业务错误码 | 错误码 | 说明 | 场景 | 解决方案 | |--------|------|------|----------| | DELETE_001 | Salesforce 连接失败 | 连接 Salesforce 时发生异常 | 检查网络连接和 Salesforce 配置 | | DELETE_002 | 删除元数据失败 | 调用 Salesforce API 删除失败 | 检查元数据是否存在,查看错误详情 | | DELETE_003 | 批量删除失败 | 批量删除过程中发生错误 | 检查请求参数,查看具体错误信息 | | DELETE_004 | 参数校验失败 | 请求参数不符合要求 | 检查参数是否为空,格式是否正确 | --- ## 数据模型 ### DeleteRequest(删除请求) ```java @Data @Schema(description = "删除请求") public class DeleteRequest implements Serializable { private static final long serialVersionUID = 1L; @NotBlank(message = "元数据类型不能为空") @Schema(description = "元数据类型", required = true, example = "CustomObject") private String type; @NotEmpty(message = "元数据名称列表不能为空") @Schema(description = "元数据完整名称列表", required = true, example = "[\"MyCustomObject__c\", \"AnotherObject__c\"]") private String[] fullNames; } ``` ### DeleteResultVo(删除结果) ```java @Data @Schema(description = "删除结果") public class DeleteResultVo implements Serializable { private static final long serialVersionUID = 1L; @Schema(description = "元数据完整名称", example = "MyCustomObject__c") private String fullName; @Schema(description = "是否删除成功", example = "true") private boolean success; @Schema(description = "错误消息数组", example = "[\"Entity is not found\"]") private String[] errors; } ``` ### DataiMetadataDelete(删除历史实体) ```java @Data public class DataiMetadataDelete implements Serializable { private static final long serialVersionUID = 1L; private Long id; private String metadataType; private String fullName; private Integer success; private String errorMessage; private Date deleteTime; private Long userId; private String createBy; private Date createTime; private String updateBy; private Date updateTime; private Integer delFlag; } ``` --- ## 调用示例 ### JavaScript 调用示例 #### 单个删除 ```javascript const response = await fetch('/salesforce/metadata/delete/CustomObject', { method: 'POST', headers: { 'Content-Type': 'application/json', 'Authorization': 'Bearer ' + token }, body: JSON.stringify(['MyCustomObject__c']) }); const result = await response.json(); console.log(result); ``` #### 批量删除 ```javascript const response = await fetch('/salesforce/metadata/delete/batch', { method: 'POST', headers: { 'Content-Type': 'application/json', 'Authorization': 'Bearer ' + token }, body: JSON.stringify([ { type: 'CustomObject', fullNames: ['Object1__c', 'Object2__c'] }, { type: 'ApexClass', fullNames: ['Class1', 'Class2'] } ]) }); const result = await response.json(); console.log(result); ``` #### 查询历史 ```javascript const response = await fetch('/salesforce/metadata/delete/history?limit=10', { method: 'GET', headers: { 'Authorization': 'Bearer ' + token } }); const result = await response.json(); console.log(result); ``` ### Java 调用示例 #### 单个删除 ```java @RestController public class DeleteExample { @Autowired private RestTemplate restTemplate; public void deleteMetadata() { String url = "http://localhost:8080/salesforce/metadata/delete/CustomObject"; HttpHeaders headers = new HttpHeaders(); headers.setContentType(MediaType.APPLICATION_JSON); headers.setBearerAuth(token); String[] fullNames = {"MyCustomObject__c"}; HttpEntity entity = new HttpEntity<>(fullNames, headers); ResponseEntity response = restTemplate.exchange( url, HttpMethod.POST, entity, AjaxResult.class); System.out.println(response.getBody()); } } ``` --- ## 注意事项 ### 1. 权限控制 - 所有接口都需要有效的 JWT Token - 删除操作需要 `salesforce:metadata:delete` 权限 - 历史查询需要 `salesforce:metadata:delete:query` 权限 ### 2. 分批处理 - Salesforce Metadata API 每次最多删除 10 个元数据 - 系统会自动对超过 10 个的请求进行分批处理 - 分批处理是串行执行,单个失败不影响其他批次 ### 3. 异步日志 - 删除操作的历史记录是异步写入数据库的 - 可能会有短暂的延迟(通常 < 1 秒) - 不影响主业务流程的响应时间 ### 4. 错误处理 - 建议客户端对所有可能的错误码进行处理 - 对于批量删除,建议检查每个结果的 success 字段 - 对于失败的删除,可以根据 errors 字段进行针对性处理 ### 5. 性能考虑 - 批量删除时,如果数量很大,可能需要较长时间 - 建议客户端设置合理的超时时间(如 60 秒) - 对于超大量删除,建议分批调用接口 --- ## 相关文档 - [需求文档](../requirements/sub/2026-01-28-003-05-删除操作.md) - [设计文档](../design/2026-02-03-003-05-删除操作-设计.md) - [决策记录](../decisions/2026-02-03-003-05-ADR-删除操作技术选型.md) - [变更日志](../changelog/2026-02-06-003-05-changelog.md) - [复盘文档](../retros/2026-02-06-003-05-retro.md) - [会话记录](../sessions/2026-02-03-003-05-session.md)