datai/datai-scenes/datai-scene-salesforce/docs/design/2026-01-30-002-CRUD操作-设计.md

13 KiB
Raw Permalink Blame History

设计文档

元数据

  • 需求编号001
  • 子需求编号001-02
  • 创建时间2026-01-30
  • 创建人AI Assistant
  • 状态:已完成(代码已实现)

设计概述

基于 Spring Boot 和若依框架,实现 Salesforce Partner API 的 CRUD 操作功能,包括 Create、Retrieve、Update、Delete、Upsert、Merge 六个核心操作。通过 PartnerConnectionFactory 获取 PartnerConnection 实例,利用连接缓存和自动 Session 有效性检查,提供 RESTful API 接口,支持单个和批量操作,正确处理各种异常情况。

架构设计

系统架构

graph TB
    A[前端应用] --> B[PartnerCrudController]
    B --> C[IPartnerCrudService]
    C --> D[PartnerCrudServiceImpl]
    D --> E[PartnerConnectionFactory]
    E --> F[AbstractConnectionFactory]
    F --> G[SessionManager]
    F --> H[PartnerConnection]
    H --> I[Salesforce API]
    D --> J[异常处理]
    D --> K[数据转换]

模块架构

datai-salesforce-partner/
├── controller/
│   └── PartnerCrudController.java          # REST API 控制器
├── service/
│   ├── IPartnerCrudService.java            # 服务接口
│   └── impl/
│       └── PartnerCrudServiceImpl.java      # 服务实现
├── model/
│   ├── dto/
│   │   ├── CreateRecordDto.java           # 创建记录 DTO
│   │   ├── UpdateRecordDto.java           # 更新记录 DTO
│   │   ├── DeleteRecordDto.java           # 删除记录 DTO
│   │   ├── UpsertRecordDto.java          # Upsert 记录 DTO
│   │   └── MergeRecordDto.java           # 合并记录 DTO
│   └── vo/
│       ├── RecordResultVo.java            # 记录结果 VO
│       ├── RetrieveResultVo.java          # 检索结果 VO
│       └── ErrorVo.java                 # 错误信息 VO
└── util/
    └── SObjectConverter.java             # SObject 转换工具类

数据流设计

创建记录流程

  1. 前端调用 POST /api/partner/crud/create 接口
  2. Controller 接收请求参数CreateRecordDto
  3. Controller 调用 Service 层的 create 方法
  4. Service 层通过 PartnerConnectionFactory 获取 PartnerConnection 实例
  5. Service 层将 Map<String, Object> 转换为 SObject 对象
  6. Service 层调用 PartnerConnection.create(SObject[]) 方法
  7. Service 层处理返回结果SaveResult[]
  8. Service 层返回 RecordResultVo
  9. Controller 返回统一的响应格式AjaxResult

检索记录流程

  1. 前端调用 GET /api/partner/crud/retrieve 接口
  2. Controller 接收请求参数objectType、id、fieldNames
  3. Controller 调用 Service 层的 retrieve 方法
  4. Service 层通过 PartnerConnectionFactory 获取 PartnerConnection 实例
  5. Service 层调用 PartnerConnection.retrieve(String, String[], String[]) 方法
  6. Service 层处理返回结果SObject
  7. Service 层返回 RetrieveResultVo
  8. Controller 返回统一的响应格式AjaxResult

技术方案

技术选型

技术组件 版本 选择理由
Spring Boot 3.x 项目基础框架,提供依赖注入、自动配置等功能
Spring Security 6.x 提供认证和授权功能,集成若依权限系统
若依框架 最新 项目基础框架,提供统一的异常处理、响应格式等
Salesforce Partner API partner.jar Salesforce 官方 Java 客户端,提供完整的 CRUD 操作
Lombok 最新 简化 Java 代码,减少样板代码
Swagger 3.x 自动生成 API 文档,方便前端调用

核心算法设计

SObject 转换算法

  1. 创建 SObject 对象
  2. 设置对象类型setType
  3. 遍历 Map<String, Object>设置字段值setField
  4. 处理特殊数据类型(日期、布尔值、数字等)
  5. 处理子对象关系setSObjectField
  6. 处理字段清空setFieldsToNull

批量操作算法

  1. 遍历记录列表,转换为 SObject 数组
  2. 调用 PartnerConnection 的批量方法
  3. 遍历返回结果数组,处理每个结果
  4. 收集所有错误信息
  5. 返回批量结果列表

集成方案

与 Salesforce API 集成

  1. 通过 PartnerConnectionFactory 获取 PartnerConnection 实例
  2. 使用 PartnerConnection 的 CRUD 方法执行操作
  3. 处理返回结果SaveResult、DeleteResult、UpsertResult、MergeResult
  4. 捕获并转换异常ConnectionException、ApiFault

与若依框架集成

  1. 使用若依的统一响应格式AjaxResult
  2. 使用若依的异常处理机制
  3. 使用若依的权限控制(@PreAuthorize
  4. 使用若依的参数验证(@Validated

数据模型

数据库表设计

不涉及数据库表,所有数据均来自 Salesforce API。

实体类设计

DTO 类

  1. CreateRecordDto:创建记录请求参数

    • objectType对象类型String必填
    • fields字段值Map<String, Object>,必填)
    • records批量创建记录列表List<Map<String, Object>>,可选)
  2. UpdateRecordDto:更新记录请求参数

    • objectType对象类型String必填
    • id:记录 IDString必填
    • fields字段值Map<String, Object>,必填)
    • records批量更新记录列表List可选
  3. DeleteRecordDto:删除记录请求参数

    • objectType对象类型String必填
    • id:记录 IDString必填
    • ids:批量删除记录 ID 列表List可选
  4. UpsertRecordDtoUpsert 记录请求参数

    • objectType对象类型String必填
    • externalIdField:外部 ID 字段String必填
    • fields字段值Map<String, Object>,必填)
    • records:批量 Upsert 记录列表List<Map<String, Object>>,可选)
  5. MergeRecordDto:合并记录请求参数

    • objectType对象类型String必填
    • masterRecordId:主记录 IDString必填
    • recordToMergeIds:要合并的记录 ID 列表List必填

VO 类

  1. RecordResultVo:记录操作结果

    • id:记录 IDString
    • success是否成功boolean
    • errors错误信息列表List
  2. RetrieveResultVo:检索结果

    • sObject记录对象Map<String, Object>
    • success是否成功boolean
    • errors错误信息列表List
  3. ErrorVo:错误信息

    • statusCode状态代码String
    • message错误消息String
    • fields相关字段列表List

接口设计

RESTful API 设计

1. 创建记录

接口POST /api/partner/crud/create

功能:创建新的 Salesforce 记录,支持批量创建

请求参数

{
  "objectType": "Account",
  "fields": {
    "Name": "Test Account",
    "BillingCity": "San Francisco"
  }
}

批量创建请求参数

{
  "objectType": "Account",
  "records": [
    {"Name": "Account 1", "BillingCity": "San Francisco"},
    {"Name": "Account 2", "BillingCity": "New York"}
  ]
}

响应示例

{
  "code": 200,
  "msg": "创建成功",
  "data": {
    "id": "001xx000003DHb2AAG",
    "success": true,
    "errors": []
  }
}

2. 检索单个记录

接口GET /api/partner/crud/retrieve

功能:根据 ID 检索单个 Salesforce 记录

请求参数

  • objectType:对象类型(必填)
  • id:记录 ID必填
  • fieldNames:字段名称列表(可选,多个字段用逗号分隔)

响应示例

{
  "code": 200,
  "msg": "检索成功",
  "data": {
    "sObject": {
      "Id": "001xx000003DHb2AAG",
      "Name": "Test Account",
      "BillingCity": "San Francisco"
    },
    "success": true,
    "errors": []
  }
}

3. 更新记录

接口PUT /api/partner/crud/update

功能:更新现有的 Salesforce 记录,支持批量更新

请求参数

{
  "objectType": "Account",
  "id": "001xx000003DHb2AAG",
  "fields": {
    "BillingCity": "New York"
  }
}

批量更新请求参数

{
  "objectType": "Account",
  "records": [
    {"id": "001xx000003DHb2AAG", "fields": {"BillingCity": "New York"}},
    {"id": "001xx000003DHb3AAH", "fields": {"BillingCity": "Los Angeles"}}
  ]
}

响应示例

{
  "code": 200,
  "msg": "更新成功",
  "data": {
    "success": true,
    "errors": []
  }
}

4. 删除记录

接口DELETE /api/partner/crud/delete

功能:删除 Salesforce 记录,支持批量删除

请求参数

  • objectType:对象类型(必填)
  • id:记录 ID必填

批量删除请求参数

{
  "objectType": "Account",
  "ids": [
    "001xx000003DHb2AAG",
    "001xx000003DHb3AAH"
  ]
}

响应示例

{
  "code": 200,
  "msg": "删除成功",
  "data": {
    "success": true,
    "errors": []
  }
}

5. 更新或插入记录

接口POST /api/partner/crud/upsert

功能:根据外部 ID 更新或插入 Salesforce 记录,支持批量 Upsert

请求参数

{
  "objectType": "Account",
  "externalIdField": "ExternalId__c",
  "fields": {
    "ExternalId__c": "EXT-001",
    "Name": "Test Account"
  }
}

批量 Upsert 请求参数

{
  "objectType": "Account",
  "externalIdField": "ExternalId__c",
  "records": [
    {"ExternalId__c": "EXT-001", "Name": "Account 1"},
    {"ExternalId__c": "EXT-002", "Name": "Account 2"}
  ]
}

响应示例

{
  "code": 200,
  "msg": "Upsert 成功",
  "data": {
    "id": "001xx000003DHb2AAG",
    "created": true,
    "success": true,
    "errors": []
  }
}

6. 合并记录

接口POST /api/partner/crud/merge

功能:合并多个 Salesforce 记录

请求参数

{
  "objectType": "Account",
  "masterRecordId": "001xx000003DHb2AAG",
  "recordToMergeIds": [
    "001xx000003DHb3AAH",
    "001xx000003DHb4AAI"
  ]
}

响应示例

{
  "code": 200,
  "msg": "合并成功",
  "data": {
    "success": true,
    "errors": []
  }
}

接口权限设计

所有接口均需要用户登录认证:

  • @PreAuthorize("@ss.hasLogin()")

接口文档设计

使用 Swagger 3.x 自动生成 API 文档,提供:

  • 接口功能描述
  • 请求参数说明
  • 响应参数说明
  • 请求示例
  • 响应示例

实现要点

关键实现逻辑

Service 层实现

  1. 使用 @Autowired 注入 PartnerConnectionFactory
  2. 实现 CRUD 操作方法
  3. 通过 partnerConnectionFactory.getConnection("source") 获取 PartnerConnection 实例
  4. 使用 PartnerConnection 的 CRUD 方法执行操作
  5. 处理返回结果SaveResult、DeleteResult、UpsertResult、MergeResult
  6. 捕获并转换异常

Controller 层实现

  1. 使用 @RestController@RequestMapping 注解
  2. 使用 @PreAuthorize("@ss.hasLogin()") 进行权限控制
  3. 使用 @Validated 进行参数验证
  4. 使用 @RequestBody@RequestParam 接收参数
  5. 使用 AjaxResult.success()AjaxResult.error() 返回统一响应格式
  6. 使用 @Operation@Tag 注解生成 Swagger 文档

异常处理

异常捕获

  1. 捕获 ConnectionException 并转换为 SalesforceAuthException
  2. 捕获 ApiFault 并转换为 SalesforceOperationException
  3. 捕获其他异常并转换为 DataAccessException

异常处理

  1. 使用 datai-salesforce-common 模块的异常类
  2. 返回友好的错误消息(中文)
  3. 记录详细的错误日志(使用 @Slf4j

错误码转换

  • INVALID_FIELD → "字段不存在或无效"
  • INVALID_ID → "记录 ID 无效"
  • INVALID_OPERATION → "操作无效"
  • DUPLICATE_VALUE → "值重复"
  • ENTITY_IS_DELETED → "记录已删除"
  • INSUFFICIENT_ACCESS → "权限不足"

性能优化

  1. 连接缓存:使用 PartnerConnectionFactory 提供的连接缓存,避免重复创建连接
  2. 自动 Session 有效性检查:使用 AbstractConnectionFactory 提供的自动 Session 有效性检查,过期时自动重新获取
  3. 批量操作支持批量操作Create、Update、Delete、Upsert减少网络往返次数
  4. 合理使用事务:根据业务需求,合理使用事务(暂不考虑)

安全设计

  1. HTTPS 加密传输:所有 API 调用使用 HTTPS 加密传输
  2. 权限控制:使用 @PreAuthorize("@ss.hasLogin()") 进行权限控制
  3. 参数验证:使用 @Validated@NotBlank 等注解进行参数验证
  4. 防注入:使用 PartnerConnection 的参数化查询,防止 SQL 注入
  5. 敏感信息保护不在日志中记录敏感信息如密码、Token

相关文档