fastbee/docs/knowledge-base/06_1-platform-intergration-design.md
2026-05-29 09:53:48 +08:00

1014 lines
34 KiB
Markdown
Raw Permalink Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

# 平台对接需求与技术设计
## 1. 背景
需求目录 `docs/platform/` 中目前包含 DCP 雨量计、倾角、静力水准、轴力计接口文档。DCP 是当前优先落地的平台,但平台对接能力不能只服务一个平台、一个租户。平台一旦完成接入,后续其他租户应复用同一套平台定义、接口定义、流程编排、适配器和推送执行能力;租户只需要维护自己的第三方账号/用户、项目、设备、字段映射和推送任务。
当前 FastBee 已具备以下基础能力:
- 设备、产品、物模型:设备通过 `iot_device` 管理,物模型通过产品和设备编号查询。
- 设备上报处理:设备数据解析后进入原有入库和规则处理链路。
- 历史数据查询:数据中心接口支持按设备、时间窗口和物模型标识符查询历史数据。
- 数据桥接:现有 `bridge`、`iot_script`、`iot_script_bridge` 支持 HTTP、MQTT、数据库桥接。
- 定时任务:系统已有 Quartz 任务体系,可复用为定时推送和补偿任务触发器。
- 多租户:IoT 主要业务表已有 `tenant_id`、`tenant_name` 约定,平台对接也应按租户隔离业务映射和推送数据。
因此推荐建设系统级 **平台对接 / iPaaS Connector** 能力:平台基础接入可复用,租户业务映射可隔离,DCP 等复杂平台通过专用适配器补充规则。
## 2. 核心目标
平台对接需要同时满足“平台共用”和“租户隔离”:
- 平台接入人员只需维护一次第三方平台模板:认证方式、接口、字段、流程、适配器。
- 多个租户可启用同一个平台模板,不重复配置接口和流程。
- 每个租户维护自己的第三方账号/用户授权、项目映射、设备绑定、字段映射和推送任务。
- 设备上报后按租户和设备绑定匹配推送目标,生成推送记录并异步执行。
- 支持定时推送和按时间范围补推,复用现有历史数据查询能力。
- 支持幂等、失败重试、手动重推、推送日志和审计。
- DCP 这类平台保留专用适配器,处理 token、项目、测点、设备、传感器、雨量递增等平台规则。
- DCP 必须遵守 **一个测点对应一个 FastBee 设备**,不能将测点设计为平台级或产品级共享资源。
## 3. 分层模型
平台对接按三层拆分:
```text
平台模板层(全局/系统级,可复用)
-> 平台定义、接口定义、字段定义、流程编排、适配器
租户接入层(租户级,隔离)
-> 租户平台实例、第三方账号/用户、项目映射、资源映射、设备绑定、字段映射、推送任务
执行审计层(租户级,隔离)
-> 推送记录 outbox、推送尝试日志、重试、重推、补偿
```
### 3.1 平台模板层
平台模板层由平台管理员维护,配置一次、多租户复用。
包含:
- 第三方平台类型,例如 DCP、通用 HTTP、通用 MQTT、通用数据库。
- 认证方式,例如无认证、固定 Token、Basic、Bearer、OAuth2、自定义 Token 接口。
- 接口定义,例如获取用户、获取项目、创建测点、创建设备、绑定传感器、推送数据。
- 接口字段定义,用于页面展示和字段映射。
- 流程编排,例如“获取用户 -> 获取项目 -> 确保测点 -> 确保设备 -> 推送数据”。
- 适配器编码,例如 `genericHttp`、`dcp`。
### 3.2 租户接入层
租户接入层由租户管理员或实施人员维护。
包含:
- 租户启用哪个平台模板。
- 租户自己的第三方账号、token、clientId/clientSecret 等授权配置。
- 租户第三方用户和项目映射。
- FastBee 设备与第三方资源的绑定。
- FastBee 物模型字段与第三方接口字段的映射。
- 实时/定时推送任务和补推策略。
同一个平台模板下,不同租户的数据必须隔离:授权配置、项目、用户、资源映射、设备绑定、推送记录都必须带 `tenant_id`。
### 3.3 执行审计层
执行审计层面向运行时。
```text
设备上报 / Quartz 定时任务 / 手动补推
-> 标准上报快照 PlatformReport
-> 按 tenant_id + device_id 匹配启用绑定
-> 加载租户平台实例和流程
-> 字段映射与数据转换
-> 资源检查/懒加载
-> 生成推送记录 iot_platform_push_record
-> worker 异步执行
-> 写推送尝试日志 iot_platform_push_attempt
```
## 4. 与现有系统功能的关系
| 现有能力 | 复用方式 |
| --- | --- |
| 设备管理 `iot_device` | 设备绑定引用 `device_id`、`serial_number`、`product_id`、`tenant_id`。 |
| 产品物模型 | 绑定页面通过现有物模型接口展示字段,字段映射使用物模型 `identifier`。 |
| 设备实时上报链路 | 在原有数据处理完成后发布平台推送事件,不改变协议解析逻辑。 |
| 数据中心历史查询 | 定时推送和手动补推按设备、时间窗口、identifier 取历史数据。 |
| 规则引擎和数据桥接 | 保留给轻量 HTTP/MQTT/DB 转发;平台对接面向多步骤、多租户、可重推场景。 |
| Quartz 定时任务 | 平台推送任务可复用 sys_job/Quartz 触发。 |
| Redis/Redisson | 缓存 token,资源创建时做并发锁。 |
| 若依权限体系 | 继续使用菜单、角色、`@PreAuthorize` 权限控制。 |
现有数据桥接仍保留。它适合“固定 URL + 固定模板 + 脚本触发”的轻量转发;平台对接用于第三方平台长期集成,需要多租户账号、项目、设备映射、流程编排、资源幂等、失败重试和审计。
## 5. 前端功能设计
一级菜单:**平台对接**。
建议菜单:
```text
平台对接
平台模板
接口配置
流程编排
租户接入
设备绑定
推送任务
推送记录
```
### 5.1 平台模板
平台模板是系统级可复用配置。
主要字段:
| 字段 | 说明 |
| --- | --- |
| 平台名称 | 用户可读名称,例如 DCP。 |
| 平台编码 | 全局唯一,例如 `DCP`。 |
| 平台类型 | DCP、GENERIC_HTTP、GENERIC_MQTT、GENERIC_DB。 |
| 适配器编码 | dcp、genericHttp 等。 |
| 基础地址模板 | 可作为租户实例默认 baseUrl。 |
| 认证方式 | OAuth2、自定义 Token、固定 Token 等。 |
| 默认请求配置 | 超时、重试、Content-Type 等。 |
| 启用状态 | 启用、停用。 |
### 5.2 接口配置
接口配置属于平台模板,可被所有租户复用。
接口类型:
| 类型 | 说明 |
| --- | --- |
| TOKEN | 获取或刷新 token。 |
| QUERY | 查询第三方基础数据,如用户、项目。 |
| RESOURCE_CREATE | 创建外部资源,如测点、设备、传感器。 |
| RESOURCE_BIND | 绑定外部资源。 |
| PUSH | 推送设备数据。 |
配置项:
- 请求方法:GET、POST、PUT、DELETE。
- URL 模板:支持 `${变量}`。
- Header、Query、Body 模板。
- Content-Type。
- 成功条件:HTTP 状态码、响应 JSONPath。
- 响应变量提取:例如 `$.id -> pointId`。
- 超时和重试策略。
### 5.3 接口字段
接口字段用于设备绑定页面右侧展示,帮助租户配置字段映射。
| 字段 | 说明 |
| --- | --- |
| 接口 | 所属接口。 |
| 方向 | REQUEST、RESPONSE。 |
| 字段路径 | JSONPath 或表单字段名。 |
| 字段名称 | 展示名称。 |
| 数据类型 | string、number、boolean、array、object。 |
| 是否必填 | 是否必填。 |
| 默认值 | 默认值。 |
| 示例值 | 示例值。 |
### 5.4 流程编排
流程属于平台模板,用于将多个接口和适配器方法组成可复用业务流程。
示例:DCP 数据推送流程。
```text
获取/刷新 token
-> 获取用户 userId
-> 获取/选择项目 projectId
-> 确保测点 pointId
-> 确保设备 dcpDeviceId
-> 确保传感器/附属资源
-> 构造 payload
-> 推送数据
```
流程步骤类型:
| 步骤类型 | 说明 |
| --- | --- |
| API | 调用平台接口配置。 |
| ADAPTER | 调用专用适配器方法。 |
| CONDITION | 条件判断。 |
| TRANSFORM | 数据转换。 |
流程模板可以被多个租户复用;步骤执行时使用当前租户的授权配置、项目映射、设备绑定和资源映射。
### 5.5 租户接入
租户接入表示某个租户启用某个平台模板。
主要字段:
| 字段 | 说明 |
| --- | --- |
| 租户 | 当前租户。 |
| 平台模板 | 选择 DCP 等平台模板。 |
| 实例名称 | 租户内展示名。 |
| baseUrl | 可覆盖模板默认地址。 |
| 授权配置 | 租户自己的账号、clientId、secret、token 等。 |
| 默认第三方用户 | DCP userId 或其他平台用户。 |
| 默认项目 | DCP projectId 或其他平台项目。 |
| 启用状态 | 启用、停用。 |
租户接入配置完成后,该租户才能建立设备绑定、推送任务和资源映射。
### 5.6 设备绑定
设备绑定是租户级配置。
绑定内容:
```text
租户平台实例 + FastBee 设备 + 平台流程 + 第三方用户/项目 + 字段映射 + 推送模式
```
绑定页面左侧使用现有 FastBee 产品、设备、物模型;右侧使用平台模板的接口字段和租户的第三方用户/项目/资源。
绑定支持:新增、修改、启用、停用、解绑、初始化资源、查看资源映射、查看推送记录。
DCP 绑定规则:
```text
FastBee 一个设备 = DCP 一个测点 = DCP 一个设备资源
```
DCP 的 `pointId`、`dcpDeviceId`、sensor/module/virtual 等必须按租户设备绑定保存,不能平台级共享。
### 5.7 字段映射
字段映射按设备绑定维护,也可以支持从平台模板复制默认映射。
映射来源:
| 来源类型 | 说明 |
| --- | --- |
| THING_MODEL | 物模型字段,例如 rainfall。 |
| SYSTEM | 系统字段,例如 serialNumber、deviceName、reportTime。 |
| CONSTANT | 常量。 |
| RESOURCE | 外部资源映射,例如 pointId、dcpDeviceId。 |
| JSONPATH | 从 rawPayload 中取值。 |
| EXPRESSION | 受限表达式,后续增强。 |
第一阶段转换能力建议支持:直接映射、时间格式化、单位换算、数值倍率、枚举转换、默认值。表达式必须受限,不能执行任意代码。
### 5.8 推送任务与推送记录
推送任务是租户级配置,支持:
- 实时推送:设备上报后生成推送记录。
- 定时推送:按 Quartz/sys_job 触发,从历史数据按窗口生成推送记录。
- 手动补推:按设备和时间范围生成推送记录。
推送记录展示业务层面的推送状态:
- 按租户、平台、流程、设备、状态、时间筛选。
- 查看最终 payload、幂等 key、请求响应、错误信息。
- 失败重推、批量重推、成功记录强制重推。
## 6. 标准上报快照
字段映射不要直接依赖原始 MQTT/HTTP payload。系统应先把设备数据整理成统一快照。
```json
{
"tenantId": 1,
"productId": 10,
"deviceId": 1001,
"serialNumber": "ABC001",
"deviceName": "雨量计-001",
"reportTime": "2026-05-27 10:00:00",
"sourceRefId": "device_log_id_or_history_id",
"values": {
"rainfall": {
"value": 12.3,
"unit": "mm",
"ts": "2026-05-27 10:00:00"
},
"temperature": {
"value": 22.1,
"unit": "℃",
"ts": "2026-05-27 10:00:00"
}
},
"rawPayload": {}
}
```
`values` 的 key 使用物模型 `identifier`,便于复用现有物模型和历史数据查询能力。
## 7. DCP 适配设计
DCP 通过平台模板 + 流程编排 + 专用适配器落地。
### 7.1 DCP 平台模板
DCP 平台模板包含:
- token 接口:`POST /connect/token`。
- 用户接口:获取 userId。
- 项目接口:按 userId 获取项目。
- 资源接口:创建测点、创建设备、创建/绑定传感器等。
- 推送接口:雨量、倾角、静力水准、轴力计数据推送。
- DCP 专用适配器:处理 token 缓存、资源幂等、payload 构造、特殊规则。
这些配置由系统维护一次,所有租户复用。
### 7.2 DCP 租户映射
每个租户需要维护自己的 DCP 映射:
```text
租户
-> DCP 租户平台实例
-> DCP 账号/用户 userId
-> DCP 项目 projectId
-> FastBee 设备绑定 DCP 测点 pointId
-> FastBee 设备绑定 DCP 设备 dcpDeviceId
-> 设备附属 sensor/module/virtual
```
同一个 DCP 平台模板下,不同租户可以使用不同 DCP 账号、用户和项目。资源映射必须按 `tenant_id` 隔离。
### 7.3 DCP 一测点一设备约束
DCP 资源映射必须按“一测点一设备”建模:
```text
FastBee Device(serialNumber)
-> DCP Project(projectId)
-> DCP Point(pointId)
-> DCP Device(dcpDeviceId)
-> DCP Sensor/Module/Virtual(按设备类型可选)
```
规则:
- `PROJECT` 可以是租户平台实例级默认资源,也可以绑定级覆盖。
- `USER`、`PROJECT` 是租户级或绑定级映射,不是全局共享。
- `POINT` 必须是设备级资源,一个 FastBee 设备对应一个 DCP 测点。
- `DEVICE` 必须是设备级资源,一个 FastBee 设备对应一个 DCP 设备资源。
- `SENSOR`、`MODULE`、`VIRTUAL` 是设备附属资源,按绑定保存。
- 静力水准 payload 中可包含多条 `sensorData`,但仍归属同一个 FastBee 设备对应的 DCP 测点和 DCP 设备下。
### 7.4 DCP 运行流程
```text
设备上报或定时任务
-> 匹配租户 DCP 设备绑定
-> 加载租户 DCP 授权配置
-> 获取/刷新 token
-> 加载 userId/projectId 映射
-> 加载 pointId/dcpDeviceId/sensor 映射
-> 资源缺失时按流程懒加载或手动初始化
-> 构造对应设备类型 payload
-> 调用 DCP 数据接口
-> 写推送记录和尝试日志
```
资源创建必须幂等。并发上报同一设备时,使用 Redis/Redisson 锁:
```text
platform:dcp:resource:{tenantId}:{tenantChannelId}:{serialNumber}
```
### 7.5 DCP 特殊规则
- 雨量 `value` 为累计降雨量,DCP 要求新值大于历史值。系统使用绑定的 `last_success_value` 或资源扩展字段记录最近成功值;不满足时记录为 `SKIPPED`,不反复重试。
- 倾角需要同一时间的 x、y、z 和温度,必须按一次设备快照组包,不能拆成多个单字段推送。
- 静力水准的 `sensorData` 可包含多条传感器数据,但这些数据属于同一个 FastBee 设备对应的 DCP 设备资源。
- 轴力计按独立设备类型处理,字段映射和 payload 由 `DcpPlatformAdapter` 中对应 builder 负责。
- DCP token 缓存在 Redis,key 建议:`platform:dcp:token:{tenantId}:{tenantChannelId}`。
- 401 或 token 过期时刷新 token 后重试一次,再失败则记录错误。
## 8. 表设计
表名前缀使用 `iot_platform_`,避免和现有 `iot_social_platform` 混淆。
### 8.1 表清单
| 表名 | 层级 | 说明 |
| --- | --- | --- |
| `iot_platform_template` | 平台模板层 | 平台模板,全局可复用。 |
| `iot_platform_api` | 平台模板层 | 第三方接口定义。 |
| `iot_platform_api_field` | 平台模板层 | 接口字段定义。 |
| `iot_platform_flow` | 平台模板层 | 流程模板。 |
| `iot_platform_flow_step` | 平台模板层 | 流程步骤。 |
| `iot_platform_tenant_channel` | 租户接入层 | 租户启用的平台实例和授权配置。 |
| `iot_platform_resource_mapping` | 租户接入层 | 用户、项目、测点、设备、传感器等资源映射。 |
| `iot_platform_binding` | 租户接入层 | FastBee 设备与平台流程/项目/资源绑定。 |
| `iot_platform_field_mapping` | 租户接入层 | 绑定级字段映射。 |
| `iot_platform_push_task` | 租户接入层 | 定时推送任务。 |
| `iot_platform_task_binding` | 租户接入层 | 推送任务与绑定关系。 |
| `iot_platform_push_record` | 执行审计层 | 推送记录,兼 outbox。 |
| `iot_platform_push_attempt` | 执行审计层 | 每次推送尝试日志。 |
### 8.2 iot_platform_template
平台模板,全局可复用。
| 字段 | 类型 | 说明 |
| --- | --- | --- |
| id | bigint | 主键 |
| platform_code | varchar(64) | 平台编码,全局唯一 |
| platform_name | varchar(128) | 平台名称 |
| platform_type | varchar(32) | DCP、GENERIC_HTTP、GENERIC_MQTT、GENERIC_DB |
| adapter_code | varchar(64) | dcp、genericHttp 等 |
| base_url_template | varchar(512) | 默认基础地址模板 |
| auth_type | varchar(32) | 认证类型 |
| auth_schema | json | 授权配置字段定义,用于租户填写 |
| request_config | json | 默认超时、重试、TLS 等 |
| status | tinyint | 0停用,1启用 |
| create_time | datetime | 创建时间 |
| update_time | datetime | 更新时间 |
| remark | varchar(500) | 备注 |
建议索引:
```text
uk_platform_code(platform_code)
idx_platform_type(platform_type)
```
### 8.3 iot_platform_api
第三方接口定义,属于平台模板。
| 字段 | 类型 | 说明 |
| --- | --- | --- |
| id | bigint | 主键 |
| template_id | bigint | 平台模板 id |
| api_code | varchar(64) | 接口编码 |
| api_name | varchar(128) | 接口名称 |
| api_type | varchar(32) | TOKEN、QUERY、PUSH、RESOURCE_CREATE、RESOURCE_BIND |
| method | varchar(16) | GET、POST、PUT、DELETE |
| path_template | varchar(512) | URL 路径模板 |
| content_type | varchar(64) | application/json、form-urlencoded |
| header_template | json | Header 模板 |
| query_template | json | Query 模板 |
| body_template | json | Body 模板 |
| success_condition | json | 成功条件 |
| response_mapping | json | 响应变量提取规则 |
| retry_policy | json | 接口级重试策略 |
| timeout_ms | int | 超时时间 |
| status | tinyint | 0停用,1启用 |
| create_time | datetime | 创建时间 |
| update_time | datetime | 更新时间 |
建议索引:
```text
uk_template_api_code(template_id, api_code)
idx_template_api_type(template_id, api_type)
```
### 8.4 iot_platform_api_field
接口字段定义,用于页面展示和字段映射。
| 字段 | 类型 | 说明 |
| --- | --- | --- |
| id | bigint | 主键 |
| api_id | bigint | 接口 id |
| direction | varchar(16) | REQUEST、RESPONSE |
| field_path | varchar(256) | JSONPath 或表单字段名 |
| field_name | varchar(128) | 字段名称 |
| data_type | varchar(32) | string、number、boolean、array、object |
| required | tinyint | 是否必填 |
| default_value | varchar(512) | 默认值 |
| example_value | varchar(512) | 示例值 |
| description | varchar(500) | 说明 |
| sort_order | int | 排序 |
建议索引:
```text
idx_api_direction(api_id, direction)
```
### 8.5 iot_platform_flow
流程模板,属于平台模板。
| 字段 | 类型 | 说明 |
| --- | --- | --- |
| id | bigint | 主键 |
| template_id | bigint | 平台模板 id |
| flow_code | varchar(64) | 流程编码 |
| flow_name | varchar(128) | 流程名称 |
| flow_type | varchar(32) | PUSH、QUERY、RESOURCE_SYNC |
| adapter_code | varchar(64) | 可覆盖平台适配器 |
| status | tinyint | 0停用,1启用 |
| create_time | datetime | 创建时间 |
| update_time | datetime | 更新时间 |
| remark | varchar(500) | 备注 |
建议索引:
```text
uk_template_flow_code(template_id, flow_code)
```
### 8.6 iot_platform_flow_step
流程步骤。
| 字段 | 类型 | 说明 |
| --- | --- | --- |
| id | bigint | 主键 |
| flow_id | bigint | 流程 id |
| step_code | varchar(64) | 步骤编码 |
| step_name | varchar(128) | 步骤名称 |
| step_type | varchar(32) | API、ADAPTER、CONDITION、TRANSFORM |
| api_id | bigint | API 步骤引用接口 id |
| adapter_method | varchar(128) | 适配器方法,例如 ensurePoint |
| input_mapping | json | 步骤入参映射 |
| output_mapping | json | 步骤输出变量映射 |
| condition_expr | varchar(512) | 执行条件 |
| on_fail | varchar(32) | STOP、SKIP、RETRY |
| sort_order | int | 执行顺序 |
| status | tinyint | 0停用,1启用 |
建议索引:
```text
idx_flow_sort(flow_id, sort_order)
```
### 8.7 iot_platform_tenant_channel
租户启用平台模板后的平台实例。授权配置、baseUrl、默认用户/项目属于租户级。
| 字段 | 类型 | 说明 |
| --- | --- | --- |
| id | bigint | 主键 |
| tenant_id | bigint | 租户 id |
| tenant_name | varchar(64) | 租户名称 |
| template_id | bigint | 平台模板 id |
| channel_code | varchar(64) | 租户内平台实例编码 |
| channel_name | varchar(128) | 租户内平台实例名称 |
| base_url | varchar(512) | 实际基础地址 |
| auth_config | json | 租户授权配置,敏感值加密 |
| default_user_id | varchar(128) | 默认第三方用户 id |
| default_project_id | varchar(128) | 默认第三方项目 id |
| config_json | json | 租户级扩展配置 |
| status | tinyint | 0停用,1启用 |
| del_flag | char(1) | 0正常,2删除 |
| create_by | varchar(64) | 创建者 |
| create_time | datetime | 创建时间 |
| update_by | varchar(64) | 更新者 |
| update_time | datetime | 更新时间 |
| remark | varchar(500) | 备注 |
建议索引:
```text
uk_tenant_channel_code(tenant_id, channel_code, del_flag)
idx_tenant_template(tenant_id, template_id)
```
### 8.8 iot_platform_resource_mapping
外部资源映射,租户级隔离。DCP 的 user、project、point、device、sensor 等都保存在这里。
| 字段 | 类型 | 说明 |
| --- | --- | --- |
| id | bigint | 主键 |
| tenant_id | bigint | 租户 id |
| tenant_channel_id | bigint | 租户平台实例 id |
| binding_id | bigint | 绑定 id,用户/项目可为空 |
| resource_scope | varchar(32) | TENANT、PROJECT、DEVICE、BINDING |
| resource_type | varchar(64) | USER、PROJECT、POINT、DEVICE、SENSOR、MODULE、VIRTUAL |
| local_key | varchar(128) | 本地唯一键,设备级使用 serialNumber |
| external_id | varchar(128) | 外部资源 id |
| external_code | varchar(128) | 外部资源编码 |
| external_name | varchar(128) | 外部资源名称 |
| resource_payload | json | 外部资源详情 |
| status | tinyint | 0失效,1有效 |
| create_time | datetime | 创建时间 |
| update_time | datetime | 更新时间 |
建议索引:
```text
uk_resource(tenant_channel_id, binding_id, resource_type, local_key)
idx_resource_tenant_type(tenant_id, tenant_channel_id, resource_type)
idx_external_id(tenant_channel_id, resource_type, external_id)
```
### 8.9 iot_platform_binding
设备绑定,租户级配置。
| 字段 | 类型 | 说明 |
| --- | --- | --- |
| id | bigint | 主键 |
| tenant_id | bigint | 租户 id |
| tenant_channel_id | bigint | 租户平台实例 id |
| flow_id | bigint | 平台流程 id |
| product_id | bigint | 产品 id |
| product_name | varchar(128) | 产品名称冗余 |
| device_id | bigint | FastBee 设备 id |
| device_name | varchar(128) | FastBee 设备名称 |
| serial_number | varchar(64) | FastBee 设备编号 |
| external_user_id | varchar(128) | 绑定级第三方用户 id,可为空 |
| external_project_id | varchar(128) | 绑定级第三方项目 id,可为空 |
| external_device_type | varchar(32) | 第三方设备类型,例如 DCP RAIN、INCLINO |
| binding_name | varchar(128) | 绑定名称 |
| push_mode | varchar(16) | REALTIME、SCHEDULED、BOTH |
| config_json | json | 绑定级配置 |
| last_success_time | datetime | 最近成功推送时间 |
| last_success_value | varchar(128) | 最近成功值,雨量递增等场景使用 |
| status | tinyint | 0停用,1启用 |
| del_flag | char(1) | 0正常,2删除 |
| create_time | datetime | 创建时间 |
| update_time | datetime | 更新时间 |
建议索引:
```text
idx_binding_device(tenant_id, product_id, serial_number)
idx_binding_channel_flow(tenant_channel_id, flow_id)
uk_binding(tenant_channel_id, flow_id, serial_number, del_flag)
```
### 8.10 iot_platform_field_mapping
字段映射,按绑定维护。
| 字段 | 类型 | 说明 |
| --- | --- | --- |
| id | bigint | 主键 |
| tenant_id | bigint | 租户 id |
| binding_id | bigint | 绑定 id |
| target_path | varchar(256) | 外部目标字段路径 |
| target_name | varchar(128) | 外部字段名称 |
| source_type | varchar(32) | THING_MODEL、SYSTEM、CONSTANT、JSONPATH、EXPRESSION、RESOURCE |
| source_key | varchar(256) | 物模型 identifier、系统字段、表达式等 |
| source_name | varchar(128) | 内部字段名称 |
| transform_type | varchar(32) | DIRECT、DATE_FORMAT、UNIT_CONVERT、ENUM、NUMBER_SCALE、TEMPLATE、EXPRESSION |
| transform_config | json | 转换配置 |
| default_value | varchar(512) | 默认值 |
| required | tinyint | 是否必填 |
| sort_order | int | 排序 |
| status | tinyint | 0停用,1启用 |
建议索引:
```text
idx_mapping_binding(binding_id)
```
### 8.11 iot_platform_push_task
定时推送任务,租户级。
| 字段 | 类型 | 说明 |
| --- | --- | --- |
| id | bigint | 主键 |
| tenant_id | bigint | 租户 id |
| tenant_channel_id | bigint | 租户平台实例 id |
| flow_id | bigint | 流程 id |
| task_name | varchar(128) | 任务名称 |
| cron_expression | varchar(128) | Cron 表达式 |
| window_type | varchar(32) | LAST_SUCCESS、RECENT_MINUTES、CUSTOM |
| window_config | json | 时间窗口配置 |
| batch_size | int | 批次大小 |
| max_retry | int | 最大重试次数 |
| status | tinyint | 0停用,1启用 |
| last_run_time | datetime | 最近执行时间 |
| next_run_time | datetime | 下次执行时间 |
| create_time | datetime | 创建时间 |
| update_time | datetime | 更新时间 |
### 8.12 iot_platform_task_binding
定时任务与设备绑定关系。
| 字段 | 类型 | 说明 |
| --- | --- | --- |
| id | bigint | 主键 |
| task_id | bigint | 任务 id |
| binding_id | bigint | 绑定 id |
| status | tinyint | 0停用,1启用 |
建议索引:
```text
uk_task_binding(task_id, binding_id)
```
### 8.13 iot_platform_push_record
推送记录,租户级 outbox。
| 字段 | 类型 | 说明 |
| --- | --- | --- |
| id | bigint | 主键 |
| tenant_id | bigint | 租户 id |
| tenant_channel_id | bigint | 租户平台实例 id |
| flow_id | bigint | 流程 id |
| binding_id | bigint | 绑定 id |
| task_id | bigint | 定时任务 id,实时推送为空 |
| push_mode | varchar(16) | REALTIME、SCHEDULED、MANUAL |
| source_device_id | bigint | FastBee 设备 id |
| serial_number | varchar(64) | FastBee 设备编号 |
| source_ref_id | varchar(128) | 来源日志或历史数据 id |
| source_time | datetime | 数据时间 |
| time_window_start | datetime | 批量窗口开始 |
| time_window_end | datetime | 批量窗口结束 |
| request_payload | json | 待推送 payload |
| payload_hash | varchar(64) | payload 哈希 |
| idempotency_key | varchar(128) | 幂等 key |
| status | varchar(32) | PENDING、PROCESSING、SUCCESS、FAILED、RETRY_WAIT、SKIPPED、CANCELLED |
| retry_count | int | 已重试次数 |
| max_retry | int | 最大重试次数 |
| next_retry_time | datetime | 下次重试时间 |
| last_error | varchar(1000) | 最近错误 |
| locked_by | varchar(64) | worker 锁 |
| locked_time | datetime | 锁定时间 |
| success_time | datetime | 成功时间 |
| create_time | datetime | 创建时间 |
| update_time | datetime | 更新时间 |
建议索引:
```text
uk_idempotency(idempotency_key)
idx_record_poll(status, next_retry_time)
idx_record_device(tenant_channel_id, serial_number, source_time)
idx_record_binding(binding_id, source_time)
```
### 8.14 iot_platform_push_attempt
推送尝试日志。
| 字段 | 类型 | 说明 |
| --- | --- | --- |
| id | bigint | 主键 |
| tenant_id | bigint | 租户 id |
| record_id | bigint | 推送记录 id |
| attempt_no | int | 第几次尝试 |
| request_url | varchar(1024) | 请求地址 |
| request_headers | json | 请求头,敏感信息脱敏 |
| request_payload | json | 请求体 |
| response_status | int | HTTP 状态码 |
| response_body | mediumtext | 响应内容 |
| success | tinyint | 是否成功 |
| error_msg | varchar(1000) | 错误信息 |
| duration_ms | int | 耗时 |
| create_time | datetime | 创建时间 |
建议索引:
```text
idx_attempt_record(record_id, attempt_no)
idx_attempt_tenant(tenant_id, create_time)
```
## 9. 技术实现建议
### 9.1 模块与包
后端先放在现有 IoT 服务和 open-api 中:
```text
fastbee-open-api/src/main/java/com/fastbee/controller/platform
fastbee-service/fastbee-iot-service/src/main/java/com/fastbee/iot/platform
fastbee-service/fastbee-iot-service/src/main/resources/mapper/iot/platform
```
前端目录:
```text
yack-web/src/views/iot/platformConnect
yack-web/src/api/iot/platformConnect.js
```
权限前缀建议使用 `iot:platformConnect`,避免和现有第三方登录 `iot:platform` 混淆。
### 9.2 核心接口
```java
public interface PlatformAdapter {
String adapterCode();
void beforeExecute(PlatformContext context);
void ensureResources(PlatformContext context);
Object buildPayload(PlatformContext context);
PushResult push(PlatformContext context, Object payload);
}
```
```java
public interface PlatformFlowExecutor {
PushResult execute(Long tenantChannelId, Long flowId, PlatformReport report, Long bindingId);
}
```
```java
public interface PlatformPushRecordService {
void createRealtimeRecords(PlatformReport report);
void createScheduledRecords(Long taskId, Date beginTime, Date endTime);
void retry(Long recordId, boolean force);
void retryBatch(List<Long> recordIds, boolean force);
}
```
### 9.3 实时推送接入点
设备上报原流程保持不变,在设备数据入库或规则处理附近增加平台推送事件:
```text
设备数据解析
-> 原有设备日志/历史数据处理
-> 构造 PlatformReport
-> PlatformPushRecordService.createRealtimeRecords(report)
-> 匹配 tenant_id + device_id 的启用绑定
-> 生成 PENDING 推送记录
-> worker 异步执行流程
```
如果短期不改主链路,也可先通过现有规则引擎脚本触发平台推送服务,作为过渡方案。
### 9.4 定时推送
优先复用 Quartz/sys_job:
```text
Quartz 触发
-> 读取 iot_platform_push_task
-> 根据 window_type 计算时间窗口
-> 查询任务关联绑定
-> 调用现有历史数据服务按设备取数
-> 构造 PlatformReport
-> 批量生成推送记录
-> worker 执行流程
```
不建议第一阶段新增独立调度框架。
### 9.5 worker 处理
worker 轮询:
```text
status in (PENDING, RETRY_WAIT)
and next_retry_time <= now
```
抢占记录时使用数据库乐观更新,避免多实例重复消费:
```sql
UPDATE iot_platform_push_record
SET status = 'PROCESSING', locked_by = ?, locked_time = NOW()
WHERE id = ?
AND status IN ('PENDING', 'RETRY_WAIT')
```
处理结果:成功写 `SUCCESS`,可重试失败写 `RETRY_WAIT`,超过次数写 `FAILED`,业务跳过写 `SKIPPED`。
## 10. 幂等与重推
### 10.1 推送记录幂等
实时数据优先使用原始日志 id:
```text
tenantChannelId + flowId + bindingId + pushMode + sourceRefId + payloadHash
```
没有 `sourceRefId` 时使用:
```text
tenantChannelId + flowId + bindingId + pushMode + sourceTime + payloadHash
```
定时窗口使用:
```text
tenantChannelId + flowId + bindingId + windowStart + windowEnd + sourceTime + payloadHash
```
`idempotency_key` 必须唯一。
### 10.2 外部资源幂等
资源创建前先查 `iot_platform_resource_mapping`。
DCP 设备级资源必须按 `tenantChannelId + bindingId + serialNumber + resourceType` 唯一。
```text
查 mapping
-> 存在则复用
-> 不存在则加 Redis 锁
-> 再查一次
-> 调第三方创建接口或适配器方法
-> 保存 mapping
```
DCP 锁 key:
```text
platform:dcp:resource:{tenantId}:{tenantChannelId}:{serialNumber}
```
### 10.3 手动重推
- 失败记录重推:原记录状态重置为 `PENDING`,保留历史 attempt。
- 成功记录强制重推:新建 `MANUAL` 记录,幂等 key 追加手动批次号。
- 按设备时间范围补推:查询历史数据后生成新的 `MANUAL` 推送记录。
## 11. 权限建议
权限前缀:`iot:platformConnect`。
```text
iot:platformConnect:template:list/query/add/edit/remove
iot:platformConnect:api:list/add/edit/remove
iot:platformConnect:flow:list/add/edit/remove
iot:platformConnect:tenantChannel:list/query/add/edit/remove
iot:platformConnect:binding:list/query/add/edit/unbind/initResource
iot:platformConnect:task:list/add/edit/remove
iot:platformConnect:record:list/query/retry
```
平台模板、接口、流程建议仅平台管理员可维护;租户管理员主要维护租户接入、设备绑定、推送任务和推送记录。
## 12. 实施计划
### 阶段一:平台模板与租户接入骨架
- 新增平台模板、接口、字段、流程、流程步骤表。
- 新增租户平台实例表。
- 建立 DCP 平台模板和 DCP 基础流程。
- 实现租户级授权配置和默认用户/项目映射。
### 阶段二:设备绑定与 DCP 资源映射
- 新增设备绑定、字段映射、资源映射页面和接口。
- 实现 DCP 一设备一测点、一设备一 DCP 设备资源建模。
- 实现 DCP token、userId、projectId、pointId、dcpDeviceId、sensor/module/virtual 资源初始化。
### 阶段三:推送执行与审计
- 新增推送记录和推送尝试日志。
- 实现实时推送记录生成。
- 实现 worker、重试、幂等和手动重推。
- 支持雨量计实时推送闭环。
### 阶段四:补齐 DCP 设备类型与定时补偿
- 倾角 payload 组包。
- 静力水准 sensorData 配置和组包。
- 轴力计 payload 组包。
- 雨量递增校验和 `SKIPPED` 状态。
- 接入 Quartz/sys_job 定时推送和按时间范围补推。
### 阶段五:通用平台增强
- 通用 HTTP 平台模板。
- 接口调试。
- 模板导入导出。
- MQTT/DB 适配器按需扩展。
- 日志归档和敏感信息脱敏策略。
## 13. 风险与约束
- 平台模板是共享基础能力,租户授权、项目、设备绑定、推送记录必须按 `tenant_id` 隔离。
- DCP 一测点一设备是核心建模约束,不能把测点设计成产品级或平台级共享资源。
- 实时推送必须异步,不影响设备上报吞吐。
- token、密码、请求头等敏感信息需要加密保存和脱敏展示。
- 推送日志增长较快,需要后续增加归档或清理策略。
- 字段映射表达式必须受限,不能执行任意代码。
- 定时补推要限制窗口、批次大小和并发数,避免压垮第三方平台。
- 雨量累计值不递增时应跳过并记录原因,不应无限重试。
## 14. 结论
平台对接应定位为可复用的 iPaaS/Connector 能力,而不是单个平台的硬编码适配。
推荐模型:
```text
平台模板(共享)
-> 接口配置(共享)
-> 流程编排(共享)
-> 适配器(共享)
-> 租户平台实例(租户级)
-> 用户/项目/资源映射(租户级)
-> 设备绑定和字段映射(租户级)
-> 推送任务、推送记录、推送日志(租户级)
```
DCP 是第一批落地模板和适配器,必须保留“一测点一设备”的资源约束;其他租户复用 DCP 平台模板后,只需配置自己的 DCP 账号、用户、项目、设备绑定、字段映射和推送策略。