From cf2ffb0194de536f31571830c67b292a87679768 Mon Sep 17 00:00:00 2001 From: Vickey <891607480@qq.com> Date: Sat, 23 May 2026 08:20:48 +0800 Subject: [PATCH] docs: update thing-model design with Phase 1 implementation plan --- docs/design/thing-model.md | 117 ++++++++++++++++++++++++++++--------- 1 file changed, 89 insertions(+), 28 deletions(-) diff --git a/docs/design/thing-model.md b/docs/design/thing-model.md index 76cc612c5..c754e8c89 100644 --- a/docs/design/thing-model.md +++ b/docs/design/thing-model.md @@ -7,6 +7,23 @@ title: 物模型设计方案 本文是物模型改造初版设计,用于先统一概念和边界,再进入接口、表结构和代码实现。这里的"物模型"用于说明行业语义,不要求把 DC3 的领域名词改成通用物模型名词。 +> **实施状态**:Phase 1 开工在即;Phase 2-4 为后续迭代。各章节 `[DONE]` / `[TODO]` 标记实际进度。 + +--- + +## 0. 实施进度总览 + +| 阶段 | 内容 | 状态 | 说明 | +|------|------|------|------| +| Phase 1 | Device 加 `profile_id`,移除 ProfileBind | [TODO] | 28 文件改动,核心重构 | +| Phase 1 | 数据迁移(多 Profile → 单 Profile) | 不做 | 已决策:新设备走新逻辑,老设备兼容过渡 | +| Phase 2 | `dc3_command` / `dc3_command_param` 表 | [TODO] | 纯增量,无风险 | +| Phase 2 | `dc3_event` / `dc3_event_param` 表 | [TODO] | 纯增量,无风险 | +| Phase 3 | 指令调用链路 + 事件上报链路 | [TODO] | 依赖 Phase 2 完成 | +| Phase 4 | Web UI + 导入导出 + 文档 | [TODO] | 产品化收尾 | + +--- + ## 设计结论 基于现有 `Profile` 扩展指令和事件是合理的。当前 `Profile` 已经承担"设备模板 / 产品模型"的角色:`Point` 通过 `profile_id` @@ -42,7 +59,7 @@ DC3 保留自己的领域语言:`Profile` 就是 DC3 对一类设备能力模 | 属性值 | `PointValue` | 运行态采集数据,归属 `device_id + point_id` | | 设备归属能力模型 | `Device.profile_id` | 设备只能归属一个 `Profile`,不再维护多对多绑定 | | 服务 | `Command` | DC3 的动作型指令能力;Point 读写由 `rw_flag` 和现有读写链路表达,不进入 `dc3_command` | -| 事件 | `Event` + 运行态事件记录 | 新增 `Profile` 级事件定义;已有 `DeviceEvent` / `DriverEvent` 主要是平台运行态事件记录 | +| 事件 | `Event` + 运行态事件记录 | 新增 `Profile` 级事件定义;已有设备/驱动告警由 `dc3_entity_alarm` 承载,是运行态记录而非模型定义 | ## 目标 @@ -57,6 +74,7 @@ DC3 保留自己的领域语言:`Profile` 就是 DC3 对一类设备能力模 - 初版不重命名数据库、接口和页面中的 `Profile`、`Point` 概念。 - 初版不一次性覆盖复杂 TSL 标准,只实现 DC3 当前驱动和数据流能闭环的最小物模型。 +- 不做历史数据迁移。新建设备直接走 `profile_id`;已有设备通过兼容路径(bind 和 `profile_id` 并存过渡期)逐步切换。 ## 领域模型 @@ -80,6 +98,8 @@ Runtime `Profile` 继续作为 DC3 的设备能力模型根对象。业务层、接口和前端仍使用 `Profile` 作为主概念;文档可以说明它覆盖物模型能力,但不把它改名为物模型。 +当前字段已具备:`profile_code`、`profile_name`、`profile_type_flag`、`profile_share_flag`、`version`、`profile_ext`、`enable_flag`、`tenant_id`。 + 建议约束: - `profile_code` 在同租户下保持唯一,并作为物模型编码。 @@ -89,7 +109,7 @@ Runtime ### Point -`Point` 作为 DC3 的点位概念,不建议新建 `Property` 表替代它。当前字段已经覆盖属性的核心定义: +`Point` 作为 DC3 的点位概念,不建议新建 `Property` 表替代它。当前已有 `profile_id` 归属。字段已经覆盖属性的核心定义: | 字段 | 能力含义 | |---------------------------|---------------------| @@ -108,7 +128,7 @@ Runtime - 设备的 Point 集合只来自自身 `profile_id` 指向的 `Profile`。 - `point_ext` 中可放点位约束,如 `min`、`max`、`enum`、`step`、`reportMode`。 -### Command +### Command [TODO] 物模型语义里的服务在 DC3 中统一表达为 `Command`。这里的 `Command` 只描述读写 Point 之外的动作型能力,例如重启、校准、切换模式、下发配置。指令定义属于 `Profile`,指令执行属于 `Device`。 @@ -120,7 +140,7 @@ Runtime | `READ` | `Point.rw_flag` 包含读能力 | 读取指定 `device_id + point_id` 的点位值 | | `WRITE` | `Point.rw_flag` 包含写能力 | 向指定 `device_id + point_id` 写入目标值 | -Point 读写不在 `dc3_command` 中重复建模,由 `Point.rw_flag` 和现有 `PointValueCommand` 链路表达。新增 `Command` 只用于描述读写 +Point 读写不在 `dc3_command` 中重复建模,由 `Point.rw_flag` 和现有 `PointCommand` 链路表达。新增 `Command` 只用于描述读写 Point 之外的自定义指令能力,并通过 `profile_id` 归属到 `Profile`。 建议新增定义表: @@ -167,7 +187,7 @@ Point 之外的自定义指令能力,并通过 `profile_id` 归属到 `Profile 4. 驱动执行后返回结果;同步指令等待结果,异步指令只记录受理状态。 5. 指令调用记录写入数据中心,便于追踪、重试和审计。 -### Event +### Event [TODO] 事件表示设备主动上报或平台根据数据规则识别出的业务事件,例如故障、告警、模式切换、工况变化。事件定义属于 `Profile`,事件实例属于 `Device`。 @@ -195,18 +215,17 @@ Point 之外的自定义指令能力,并通过 `profile_id` 归属到 `Profile ### Event 与现有运行态事件的边界 -当前系统已经有 `dc3_device_event` 和 `dc3_driver_event`,但它们更接近平台运行态事件记录,不等同于 `Profile` 下的模型事件定义。 +当前系统已通过 `dc3_entity_alarm` 统一承载设备/驱动的运行态告警记录(`EntityAlarmDO`,含 `alarm_type_flag`、`alarm_source_flag`、`alarm_level_flag`)。 +原 `dc3_device_event` / `dc3_driver_event` 已合并到 `dc3_entity_alarm` 中。 | 现有事件 | 当前定位 | 是否属于 `dc3_event` 定义范围 | |------------------------------|--------------------|--------------------------------------------------------------| -| `dc3_driver_event` | 驱动在线、离线、告警等平台运行态事件 | 否,驱动不是设备模型实例,不归属 `Profile` | -| `dc3_device_event` 心跳/状态派生事件 | 设备在线、离线、故障等平台运行态事件 | 默认否,属于平台状态链路 | -| `dc3_device_event` 业务告警/故障事件 | 设备侧业务事件运行记录 | 可作为模型事件实例基础,但需要补充 `event_id` 或 `event_code` 与 `dc3_event` 关联 | +| `dc3_entity_alarm` 状态超时告警 | 驱动/设备在线、离线、故障等平台运行态记录 | 否,属于平台状态链路,不归属 `Profile` | +| `dc3_entity_alarm` 规则告警 | 规则引擎触发的告警记录 | 否,属于规则引擎链路 | +| `dc3_entity_alarm` 设备上报告警 | 设备侧业务告警运行记录 | 可作为模型事件实例基础,但需要补充 `event_id` 或 `event_code` 与 `dc3_event` 关联 | -设备状态和驱动状态当前不依赖 Redis,而是由 `dc3_entity_state` 维护持久化状态租约;心跳续租,状态翻转或 -租约过期时再派生告警事件记录。因此,在线/离线状态不建议建成 `Profile` 下的通用 `dc3_event` 定义,避免把平台生命周期和设备业务能力混在一起。 - -现有 `dc3_device_event` 可作为模型事件运行记录的基础,但建议补充 `event_id` 或 `event_code`,否则只能记录告警类型,无法和模型事件定义稳定关联。 +设备状态和驱动状态由 `dc3_entity_state` 维护持久化状态租约;心跳续租,状态翻转或租约过期时再派生告警事件记录到 `dc3_entity_alarm`。 +因此,在线/离线状态不建议建成 `Profile` 下的通用 `dc3_event` 定义,避免把平台生命周期和设备业务能力混在一起。 ## API 与模块落点 @@ -223,43 +242,85 @@ Point 之外的自定义指令能力,并通过 `profile_id` 归属到 `Profile ## 兼容策略 - 现有 Profile、Point API 保持命名不变,不为了贴合物模型术语新增同义别名接口。 -- 旧设备和旧模板需要先完成 `dc3_profile_bind -> dc3_device.profile_id` 的关系迁移,默认只有 Point 能力。 -- 自定义指令、事件新增表独立演进,不影响 `PointValue` 采集链路和现有读写指令。 -- 迁移后设备能力视图只来自单个 `Profile`,不再存在多模型能力聚合和编码冲突问题。 +- 新建设备直接写 `profile_id`;已有设备可留空,通过兼容路径(bind 查询)过渡。 +- 自定义指令、事件新增表独立演进,不影响 `PointValue` 采集链路和现有 `PointCommand` 读写链路。 - 租户、启停、逻辑删除、版本字段遵循现有 `Profile / Point` 模式。 ## 待确认问题 - 自定义指令结果是否需要强同步回传;若需要,命令通道要补充关联 ID 和响应队列。 -- 事件运行记录是扩展现有 `dc3_device_event`,还是新建更通用的事件实例表;无论哪种方式,`dc3_driver_event` 都应继续保持平台运行态事件定位。 +- 事件运行记录是扩展现有 `dc3_entity_alarm`,还是新建更通用的事件实例表。 - 参数类型是否复用 `PointTypeFlagEnum`,还是抽象为通用 `ValueTypeEnum`。 -- 已存在多 `Profile` 绑定数据时,是要求用户人工选择主 `Profile`,还是迁移脚本按规则选择一个并输出审计报告。 +- ~~已存在多 `Profile` 绑定数据时的迁移策略~~ — 已决策:不做数据迁移,新设备走新逻辑,老设备兼容过渡。 ## 分阶段落地 -### 第一阶段:设备与物模型单归属 +### 第一阶段:设备与物模型单归属 [TODO] -- 在 `Device` 增加 `profile_id`,把设备与物模型关系固化为多对一。 -- 将 `dc3_profile_bind` 中的有效绑定迁移到 `dc3_device.profile_id`。 -- 清理 `ProfileBind` 的 DO/BO/VO、Mapper、Service、Controller、Facade、gRPC 契约和前端入口。 -- 调整设备、点位、状态、导入导出、Dashboard、Agentic 工具中依赖 `ProfileBind` 的查询逻辑。 -- 对历史上绑定了多个 `Profile` 的设备生成迁移清单,确认唯一目标 `Profile` 后再执行迁移。 +**范围**:28 个文件,12 个类删除,16 个类修改。 -### 第二阶段:模型定义闭环 +**DDL**: +```sql +ALTER TABLE dc3_device ADD COLUMN profile_id BIGINT; +CREATE INDEX idx_device_profile ON dc3_device (tenant_id, profile_id) WHERE deleted = 0; +``` -- 保留 `Profile` 和 `Point`,新增自定义指令、事件定义表。 +**代码改动清单**: + +| 操作 | 文件 | 说明 | +|------|------|------| +| DELETE | `ProfileBindDO.java` | 模型类 | +| DELETE | `ProfileBindBO.java` | 业务对象 | +| DELETE | `ProfileBindVO.java` | 视图对象 | +| DELETE | `ProfileBindQuery.java` | 查询对象 | +| DELETE | `ProfileBindBuilder.java` | 构建器 | +| DELETE | `ProfileBindMapper.java` | Mapper 接口 | +| DELETE | `ProfileBindMapper.xml` | Mapper XML | +| DELETE | `ProfileBindManager.java` | Manager 接口 | +| DELETE | `ProfileBindManagerImpl.java` | Manager 实现 | +| DELETE | `ProfileBindService.java` | Service 接口 | +| DELETE | `ProfileBindServiceImpl.java` | Service 实现 | +| DELETE | `ProfileBindingRow.java` | Dashboard DTO | +| MODIFY | `DeviceDO.java` | 加 `profile_id` 字段 | +| MODIFY | `DeviceBO.java` | `Set profileIds` → `Long profileId` | +| MODIFY | `DeviceVO.java` | 同上 | +| MODIFY | `DeviceBuilder.java` | 适配新字段 | +| MODIFY | `DeviceServiceImpl.java` | 移除所有 bind 调用,直接读写 `profile_id` | +| MODIFY | `DeviceMapper.xml` | `selectPageWithProfile` 去掉 INNER JOIN | +| MODIFY | `ProfileServiceImpl.java` | `listByDeviceId()` 改用 `device.profile_id` | +| MODIFY | `PointServiceImpl.java` | device↔profile 解析改用 `device.profile_id` | +| MODIFY | `DriverServiceImpl.java` | `listDeviceIdsByProfileId` 查 `dc3_device.profile_id` | +| MODIFY | `TopicServiceImpl.java` | 点位解析链路 | +| MODIFY | `PointAttributeConfigServiceImpl.java` | bind 校验 → profile_id 校验 | +| MODIFY | `DashboardServiceImpl.java` | 拓扑图数据源 | +| MODIFY | `DashboardMapper.xml` | 拓扑 SQL | +| MODIFY | `ImportDeviceServiceImpl.java` | `importProfileBind` → 设 `profile_id` | +| MODIFY | `driver/entity/bo/DeviceBO.java` | `profileIds` → `profileId` | +| MODIFY | `driver/entity/builder/DeviceBuilder.java` | 适配 | +| MODIFY | `driver/job/DriverReadScheduleJob.java` | `getProfileIds()` → `getProfileId()` | + +**出口标准**: +- `dc3_device` 有 `profile_id` 列 +- `DeviceDO` / `DeviceBO` / `DeviceVO` 使用 `profileId` 单值 +- ProfileBind 全链路物理删除 +- Device/Point/Driver/Topic/Dashboard 服务不再引用 `dc3_profile_bind` +- 现有测试通过 + +### 第二阶段:模型定义闭环 [TODO] + +- 保留 `Profile` 和 `Point`,新增 `dc3_command`、`dc3_command_param`、`dc3_event`、`dc3_event_param` 四张表。 - Manager 提供自定义指令、事件 CRUD、分页、按 `profile_id` 查询。 - Profile 详情聚合返回 Point、指令、事件。 - 增加同一 `Profile` 下 `point_code`、`command_code`、`event_code` 唯一校验。 -### 第三阶段:运行链路闭环 +### 第三阶段:运行链路闭环 [TODO] - Data Center 扩展指令调用 API 和调用记录。 - Driver SDK 扩展自定义指令 DTO。 - Data Center 事件上报 API 支持按 `event_code` 关联模型定义。 - 虚拟驱动先实现一条示例自定义指令和一条示例事件,作为协议驱动参考。 -### 第四阶段:产品化体验 +### 第四阶段:产品化体验 [TODO] - Web UI 保留 Profile 管理入口,在 Profile 详情中补齐 Point、指令、事件能力视图。 - Point、指令、事件统一展示为设备能力视图。