# 同步单对象数据接口文档

## 1. 接口概述

### 1.1 接口名称
同步单对象数据到本地数据库

### 1.2 接口描述
该接口用于触发指定对象的单次数据同步操作，将Salesforce对象的数据同步到本地数据库。同步操作包括全量同步和增量同步两种模式，具体模式由对象的配置决定：
- **全量同步**：当对象的全量拉取时间（lastFullSyncDate）为空时，执行全量数据拉取，查询所有全量同步批次并使用多线程并行拉取
- **增量同步**：当对象的全量拉取时间不为空时，执行增量数据拉取，创建增量批次并拉取增量数据

### 1.3 接口地址
```
POST /integration/object/{id}/syncData
```

### 1.4 请求方式
POST

### 1.5 权限要求
需要 `integration:object:syncData` 权限

### 1.6 日志记录
- 操作类型：UPDATE（更新）
- 日志标题：对象同步控制

## 2. 请求参数

### 2.1 请求头
```
Content-Type: application/json
Authorization: Bearer {token}
```

### 2.2 路径参数

| 参数名 | 类型 | 是否必填 | 描述 | 示例值 |
|--------|------|----------|------|--------|
| id | Integer | 是 | 对象ID，用于标识需要同步的Salesforce对象 | 1 |

### 2.3 请求体
该接口无需请求体参数

### 2.4 请求示例

#### 2.4.1 cURL 示例
```bash
curl -X POST "http://localhost:8080/integration/object/1/syncData" \
  -H "Content-Type: application/json" \
  -H "Authorization: Bearer {your_token}"
```

#### 2.4.2 HTTP 示例
```http
POST /integration/object/1/syncData HTTP/1.1
Host: localhost:8080
Content-Type: application/json
Authorization: Bearer {your_token}
```

#### 2.4.3 JavaScript (fetch) 示例
```javascript
fetch('http://localhost:8080/integration/object/1/syncData', {
  method: 'POST',
  headers: {
    'Content-Type': 'application/json',
    'Authorization': 'Bearer {your_token}'
  }
})
  .then(response => response.json())
  .then(data => console.log(data))
  .catch(error => console.error('Error:', error));
```

## 3. 响应格式

### 3.1 响应结构
```json
{
  "code": 200,
  "msg": "操作成功",
  "data": {
    "success": true,
    "message": "全量数据拉取完成",
    "objectId": 1,
    "objectApi": "Account",
    "totalCount": 12345,
    "duration": 15234,
    "syncType": "full",
    "lastFullSyncDate": "2025-12-27T10:30:00",
    "totalBatchCount": 5,
    "successBatchCount": 5,
    "failedBatchCount": 0
  }
}
```

### 3.2 响应字段说明

#### 3.2.1 通用响应字段

| 字段名 | 类型 | 说明 |
|--------|------|------|
| code | Integer | 响应状态码，200表示成功，其他表示失败 |
| msg | String | 响应消息 |
| data | Object | 响应数据对象，失败时为null |

#### 3.2.2 业务数据字段（data对象）

| 字段名 | 类型 | 说明 |
|--------|------|------|
| success | Boolean | 操作是否成功，true表示成功，false表示失败 |
| message | String | 详细消息说明 |
| objectId | Integer | 对象ID |
| objectApi | String | 对象API名称 |
| totalCount | Integer | 同步的总记录数 |
| duration | Long | 同步耗时（毫秒） |
| syncType | String | 同步类型，"full"表示全量同步，"incremental"表示增量同步 |
| lastFullSyncDate | LocalDateTime | 最后全量同步时间 |
| lastSyncDate | LocalDateTime | 最后同步时间（增量同步时返回） |
| totalBatchCount | Integer | 总批次数量（全量同步时返回） |
| successBatchCount | Integer | 成功批次数量（全量同步时返回） |
| failedBatchCount | Integer | 失败批次数量（全量同步时返回） |

### 3.3 成功响应示例

#### 3.3.1 全量同步成功
```json
{
  "code": 200,
  "msg": "操作成功",
  "data": {
    "success": true,
    "message": "全量数据拉取完成",
    "objectId": 1,
    "objectApi": "Account",
    "totalCount": 12345,
    "duration": 15234,
    "syncType": "full",
    "lastFullSyncDate": "2025-12-27T10:30:00",
    "totalBatchCount": 5,
    "successBatchCount": 5,
    "failedBatchCount": 0
  }
}
```

#### 3.3.2 增量同步成功
```json
{
  "code": 200,
  "msg": "操作成功",
  "data": {
    "success": true,
    "message": "增量数据拉取成功",
    "objectId": 1,
    "objectApi": "Account",
    "totalCount": 234,
    "duration": 3456,
    "syncType": "incremental",
    "lastFullSyncDate": "2025-12-26T10:30:00",
    "lastSyncDate": "2025-12-27T10:30:00"
  }
}
```

#### 3.3.3 部分批次失败（全量同步）
```json
{
  "code": 200,
  "msg": "操作成功",
  "data": {
    "success": true,
    "message": "全量数据拉取完成",
    "objectId": 1,
    "objectApi": "Account",
    "totalCount": 10000,
    "duration": 12000,
    "syncType": "full",
    "lastFullSyncDate": "2025-12-27T10:30:00",
    "totalBatchCount": 5,
    "successBatchCount": 4,
    "failedBatchCount": 1
  }
}
```

### 3.4 失败响应示例

#### 3.4.1 对象ID为空
```json
{
  "code": 500,
  "msg": "对象ID不能为空",
  "data": null
}
```

#### 3.4.2 对象不存在
```json
{
  "code": 500,
  "msg": "对象不存在",
  "data": null
}
```

#### 3.4.3 对象API为空
```json
{
  "code": 500,
  "msg": "对象API不能为空",
  "data": null
}
```

#### 3.4.4 对象未启用同步
```json
{
  "code": 500,
  "msg": "对象未启用同步",
  "data": null
}
```

#### 3.4.5 没有找到全量同步批次
```json
{
  "code": 500,
  "msg": "没有找到全量同步批次",
  "data": null
}
```

#### 3.4.6 对象未启用增量更新
```json
{
  "code": 500,
  "msg": "对象未启用增量更新",
  "data": null
}
```

#### 3.4.7 无法获取Salesforce连接
```json
{
  "code": 500,
  "msg": "无法获取Salesforce连接",
  "data": null
}
```

#### 3.4.8 无法确定批次字段
```json
{
  "code": 500,
  "msg": "无法确定批次字段",
  "data": null
}
```

#### 3.4.9 同步异常
```json
{
  "code": 500,
  "msg": "同步对象数据时发生异常: Connection timeout",
  "data": null
}
```

## 4. 业务逻辑说明

### 4.1 处理流程

#### 4.1.1 全量同步流程
1. **参数校验**：检查对象ID是否为空
2. **对象查询**：根据对象ID查询对象配置信息
3. **对象验证**：
   - 检查对象是否存在
   - 检查对象API是否配置
   - 检查对象是否启用同步
4. **同步模式判断**：判断对象的全量拉取时间（lastFullSyncDate）是否为空
5. **全量同步执行**：
   - 查询所有 `syncType="FULL"` 的批次
   - 使用 `SalesforceExecutor` 线程池多线程并行拉取多个批次
   - 统计成功和失败的批次数量
   - 统计总同步记录数
6. **对象状态更新**：
   - 更新对象的 `lastFullSyncDate` 为当前时间
   - 更新对象的 `lastSyncDate` 为当前时间
   - 更新对象的 `totalRows` 为总记录数
   - 更新对象的 `syncStatus`（全部成功为true，否则为false）
7. **同步日志记录**：记录同步操作日志，包括操作类型、状态、执行时间等
8. **返回结果**：返回同步结果，包括成功状态、同步数量、耗时等信息

#### 4.1.2 增量同步流程
1. **参数校验**：检查对象ID是否为空
2. **对象查询**：根据对象ID查询对象配置信息
3. **对象验证**：
   - 检查对象是否存在
   - 检查对象API是否配置
   - 检查对象是否启用同步
4. **同步模式判断**：判断对象的全量拉取时间（lastFullSyncDate）是否为空
5. **增量同步执行**：
   - 检查对象是否启用增量更新（isIncremental）
   - 获取Salesforce连接
   - 获取对象字段列表
   - 确定批次字段（batchField）
   - 创建增量批次（syncType="INCREMENTAL"）
   - 设置批次的开始时间为上次全量同步时间，结束时间为当前时间
   - 调用批次同步服务拉取增量数据
6. **对象状态更新**：
   - 更新对象的 `lastSyncDate` 为当前时间
   - 更新对象的 `totalRows`（累加增量记录数）
   - 更新对象的 `syncStatus`
7. **同步日志记录**：记录同步操作日志，包括操作类型、状态、执行时间等
8. **返回结果**：返回同步结果，包括成功状态、同步数量、耗时等信息

### 4.2 同步模式判断规则

| 条件 | 同步模式 | 说明 |
|------|----------|------|
| lastFullSyncDate == null | 全量同步 | 对象首次同步，执行全量数据拉取 |
| lastFullSyncDate != null | 增量同步 | 对象已执行过全量同步，执行增量数据拉取 |

### 4.3 全量同步特性

#### 4.3.1 批次查询
- 查询条件：`api = objectApi` 且 `syncType = "FULL"`
- 返回所有匹配的全量同步批次

#### 4.3.2 多线程并行拉取
- 使用 `SalesforceExecutor` 线程池执行批次同步任务
- 每个批次作为一个独立的任务提交到线程池
- 使用 `CopyOnWriteArrayList` 线程安全集合存储批次同步结果
- 等待所有批次任务完成后统计结果

#### 4.3.3 结果统计
- **totalBatchCount**：总批次数量
- **successBatchCount**：成功批次数量
- **failedBatchCount**：失败批次数量
- **totalCount**：所有成功批次同步的记录数总和

### 4.4 增量同步特性

#### 4.4.1 增量更新检查
- 必须启用增量更新（isIncremental = true）
- 如果未启用增量更新，返回失败

#### 4.4.2 批次字段确定
1. 优先使用对象配置的 `batchField`
2. 如果未配置，使用 `dataiIntegrationFieldService.getDateField(objectApi)` 获取默认日期字段
3. 如果无法确定批次字段，返回失败

#### 4.4.3 增量批次创建
- `api`：对象API名称
- `label`：对象标签名称
- `batchField`：批次字段
- `syncType`：INCREMENTAL
- `syncStatus`：false
- `syncStartDate`：上次全量同步时间
- `syncEndDate`：当前时间
- `createTime`：当前时间
- `updateTime`：当前时间

#### 4.4.4 记录数累加
- 增量同步成功后，将增量记录数累加到对象的 `totalRows` 中
- 如果对象的 `totalRows` 为空，直接设置为增量记录数

### 4.5 同步日志记录

#### 4.5.1 日志字段
- `objectApi`：对象API名称
- `operationType`：操作类型（"全量同步" 或 "增量同步"）
- `operationStatus`：操作状态（"成功"、"失败" 或 "部分失败"）
- `errorMessage`：错误信息（失败时）
- `executionTime`：执行时间（秒）
- `deptId`：部门ID（从当前登录用户获取）

#### 4.5.2 日志记录时机
- 成功时：记录成功日志
- 失败时：记录失败日志，包含错误信息
- 异常时：记录异常日志，包含异常信息

## 5. 错误处理

### 5.1 常见错误码

| 错误码 | 说明 | 处理建议 |
|--------|------|----------|
| 401 | 未授权 | 检查token是否有效 |
| 403 | 权限不足 | 确认用户是否具有 `integration:object:syncData` 权限 |
| 500 | 服务器内部错误 | 查看服务器日志，检查具体错误信息 |

### 5.2 常见错误场景

#### 5.2.1 对象ID为空
```
错误信息：对象ID不能为空
原因：请求路径中的id参数未提供或为null
解决方案：确保请求路径中包含有效的对象ID
```

#### 5.2.2 对象不存在
```
错误信息：对象不存在
原因：根据提供的对象ID未查询到对应的对象配置
解决方案：检查对象ID是否正确，确认对象是否已创建
```

#### 5.2.3 对象API为空
```
错误信息：对象API不能为空
原因：对象的API字段为空或未配置
解决方案：检查对象配置，确保API字段已正确配置
```

#### 5.2.4 对象未启用同步
```
错误信息：对象未启用同步
原因：对象的isWork字段为false
解决方案：先调用更新对象启用同步状态接口，将isWork设置为true
```

#### 5.2.5 没有找到全量同步批次
```
错误信息：没有找到全量同步批次
原因：对象没有配置全量同步批次
解决方案：先为对象创建全量同步批次
```

#### 5.2.6 对象未启用增量更新
```
错误信息：对象未启用增量更新
原因：对象的isIncremental字段为false
解决方案：先调用更新对象增量更新状态接口，将isIncremental设置为true
```

#### 5.2.7 无法获取Salesforce连接
```
错误信息：无法获取Salesforce连接
原因：SOAP连接配置错误或网络问题
解决方案：检查SOAPConnectionFactory配置和网络连接
```

#### 5.2.8 无法确定批次字段
```
错误信息：无法确定批次字段
原因：对象未配置批次字段，且无法获取默认日期字段
解决方案：为对象配置批次字段，或确保对象包含日期字段
```

#### 5.2.9 同步异常
```
错误信息：同步对象数据时发生异常: {具体异常信息}
原因：同步过程中发生异常，如网络超时、数据格式错误等
解决方案：查看服务器日志，根据具体异常信息进行排查
```

### 5.3 错误处理机制

#### 5.3.1 参数校验
- 在方法开始时进行参数校验
- 校验失败立即返回错误信息

#### 5.3.2 异常捕获
- 使用try-catch捕获所有异常
- 异常发生时记录错误日志
- 更新对象的错误状态和错误信息
- 记录同步日志（操作状态为"失败"）

#### 5.3.3 状态回滚
- 异常发生时，将对象的syncStatus设置为false
- 记录错误信息到对象的errorMessage字段

## 6. 使用注意事项

### 6.1 性能考虑

#### 6.1.1 全量同步
- 全量同步会拉取所有批次的数据，数据量可能很大
- 使用多线程并行拉取，可以提高同步效率
- 建议在业务低峰期执行全量同步
- 监控同步耗时，避免超时

#### 6.1.2 增量同步
- 增量同步只拉取增量数据，数据量相对较小
- 增量同步的耗时取决于增量数据量
- 建议定期执行增量同步，保持数据最新

### 6.2 数据一致性

#### 6.2.1 批次同步
- 每个批次的同步是独立的
- 部分批次失败不影响其他批次
- 全量同步时，即使部分批次失败，成功的批次数据也会保存
- 建议检查failedBatchCount，必要时重新同步失败的批次

#### 6.2.2 对象状态
- 同步成功后，对象的同步状态（syncStatus）会更新
- 部分批次失败时，syncStatus会设置为false
- 增量同步失败时，不会影响已同步的数据

### 6.3 并发控制

#### 6.3.1 同一对象
- 不建议对同一对象同时发起多次同步请求
- 可能导致数据重复或状态不一致
- 建议等待前一次同步完成后再发起下一次同步

#### 6.3.2 不同对象
- 可以对不同对象同时发起同步请求
- 使用线程池控制并发数
- 监控线程池状态，避免资源耗尽

### 6.4 监控建议

#### 6.4.1 同步状态监控
- 监控对象的syncStatus字段
- 监控对象的errorMessage字段
- 定期检查同步日志

#### 6.4.2 性能监控
- 监控同步耗时（duration）
- 监控同步记录数（totalCount）
- 监控批次成功率（successBatchCount / totalBatchCount）

#### 6.4.3 异常监控
- 监控同步异常日志
- 监控失败批次数量
- 及时处理异常情况

### 6.5 最佳实践

#### 6.5.1 首次同步
- 首次同步时，确保对象已配置全量同步批次
- 确保对象已启用同步（isWork = true）
- 在业务低峰期执行首次同步

#### 6.5.2 定期同步
- 建议定期执行增量同步
- 根据业务需求确定同步频率
- 监控增量数据量，调整同步策略

#### 6.5.3 错误处理
- 同步失败时，检查错误信息
- 根据错误类型采取相应措施
- 必要时重新执行同步

#### 6.5.4 日志管理
- 定期检查同步日志
- 分析同步趋势和异常情况
- 优化同步策略

## 7. 相关接口

### 7.1 查询对象同步控制列表
```
GET /integration/object/list
```

### 7.2 获取对象同步控制详细信息
```
GET /integration/object/{id}
```

### 7.3 获取对象同步统计信息
```
GET /integration/object/{id}/statistics
```

### 7.4 变更对象启用同步状态
```
PUT /integration/object/{id}/workStatus?isWork=true
```

### 7.5 变更对象增量更新状态
```
PUT /integration/object/{id}/incrementalStatus?isIncremental=true
```

### 7.6 创建对象表结构
```
POST /integration/object/{id}/createStructure
```

### 7.7 获取对象依赖关系
```
GET /integration/object/{id}/dependencies
```

### 7.8 同步批次数据
```
POST /integration/batch/{id}/syncData
```

## 8. 附录

### 8.1 对象同步控制表结构（DataiIntegrationObject）

| 字段名 | 类型 | 说明 |
|--------|------|------|
| id | Integer | 主键ID |
| api | String | 对象API名称 |
| label | String | 对象标签名称 |
| isWork | Boolean | 是否启用同步 |
| isIncremental | Boolean | 是否启用增量更新 |
| batchField | String | 批次字段 |
| lastFullSyncDate | LocalDateTime | 最后全量同步时间 |
| lastSyncDate | LocalDateTime | 最后同步时间 |
| totalRows | Integer | 总记录数 |
| syncStatus | Boolean | 同步状态 |
| errorMessage | String | 错误信息 |
| createTime | Date | 创建时间 |
| updateTime | Date | 更新时间 |
| createBy | String | 创建人 |
| updateBy | String | 更新人 |

### 8.2 批次同步表结构（DataiIntegrationBatch）

| 字段名 | 类型 | 说明 |
|--------|------|------|
| id | Integer | 主键ID |
| api | String | 对象API名称 |
| label | String | 对象标签名称 |
| batchField | String | 批次字段 |
| syncType | String | 同步类型（FULL/INCREMENTAL） |
| syncStatus | Boolean | 同步状态 |
| syncStartDate | LocalDateTime | 同步开始时间 |
| syncEndDate | LocalDateTime | 同步结束时间 |
| createTime | Date | 创建时间 |
| updateTime | Date | 更新时间 |

### 8.3 同步日志表结构（DataiIntegrationSyncLog）

| 字段名 | 类型 | 说明 |
|--------|------|------|
| id | Long | 主键ID |
| objectApi | String | 对象API名称 |
| operationType | String | 操作类型 |
| operationStatus | String | 操作状态 |
| errorMessage | String | 错误信息 |
| executionTime | BigDecimal | 执行时间（秒） |
| deptId | Long | 部门ID |
| createTime | Date | 创建时间 |

### 8.4 SalesforceExecutor 线程池配置

| 配置项 | 默认值 | 说明 |
|--------|--------|------|
| corePoolSize | CPU核心数 | 核心线程数 |
| maxPoolSize | CPU核心数 * 2 | 最大线程数 |
| keepAliveTime | 60秒 | 线程存活时间 |
| queueCapacity | 100 | 队列容量 |
| allowCoreThreadTimeout | false | 是否允许核心线程超时 |

### 8.5 版本历史

| 版本 | 日期 | 说明 |
|------|------|------|
| 1.0 | 2025-12-27 | 初始版本 |

### 8.6 联系方式
如有问题，请联系技术支持团队。

---

**文档生成时间**：2025-12-27
**最后更新时间**：2025-12-27
**文档版本**：1.0
