# 标注功能重构方案(细化版) > 状态:设计稿,未改代码。确认后再进入实施。 > 本版调整:标注改为“段记录 + 15 分钟色块显示”;PKS 单击整小时、连续小时合并;双击弹窗改类型/看算法属性/改起止/删除;不设正常段;时间轴汇总所有子图。 ## 1. 目标与范围 ### 目标 - 标注对象:**wave_file 传感器数据** 和 **PKS 数据**。 - 显示单位:**15 分钟色块**。 - 存储单位:**标签段**(起止时间对齐 15 分钟;wave 与 PKS 人工标注均按整小时)。 - 算法标签(振动/油压/温度)进入统一表,页面可看、可改。 - 人工标签与算法标签共存,人工优先。 - 后续可导出给训练。 ### 不做 - 不改模型算法。 - 不改 `tag-manual`。 - 不改 `compressor_alarm`。 - 暂不删除 `wave_annotation`,最后迁移。 - **不做“正常”段**:正常样本由后续训练算法生成。 ### 取消 “预训练记录”整套:前端记录/删除按钮、`/api/pretrain-records`、`pretrain_service.py`、`backend/预训练之文件头.csv`、`pretrainCounts`。 --- ## 2. 核心模型 ### 2.1 目标与通道 ``` 标注目标 = 目标类型 + 通道 + 标签段(start_time, end_time) ``` | 目标类型 | 通道 channel_key | target_key | |---|---|---| | `wave_file` | `wave:{device_part}|{device_point}` | `wave:{wave_file_id}` | | `pks` | `pks:{unit}:{device_code}:{metric_key}` | 同 channel_key | - wave:15 分钟一个文件,槽与文件一一对应。 - PKS:每个全场点位(如 `YSJ_11`)一个独立通道、独立标注行。 - 不同子图 = 不同通道 = 独立标签记录,单独操作。 ### 2.2 段记录与 15 分钟显示 - 一条标签记录 = 一个连续时间段 `[start_time, end_time)`。 - `start_time/end_time` 对齐 15 分钟;PKS 人工标注默认整小时。 - 页面按 15 分钟切成色块显示;一条段记录可覆盖多个色块。 - 相邻同类型段 **合并为一条记录**;不同类型重叠时拒绝并提示。 ### 2.3 标签级别 只保留异常级别,与现有算法一致: ``` 轻微 / 异常 / 严重异常 ``` `label_subtype` 存振动侧、温度部位、方向等;`features_json` 存算法原始属性。 --- ## 3. 页面交互 ### 3.1 标注行 每个子图上方一行,高度约一行文本(18–20px): ``` ┌──────────── 子图标题 ────────────┐ │ 异常 │ [异常][异常][ ][轻微][轻微] │ ← 左侧显示当前设置的类 ├──────────────────────────────────┤ │ 波形子图 │ └──────────────────────────────────┘ ``` - 每格 = 15 分钟。 - 有标签:按级别着色,块内显示类型文本,单行、超出隐藏。 - 无标签:浅灰空块。 - 无数据(停机/缺文件):空白且不可点。 - 颜色:轻微=黄,异常=橙,严重异常=红。 - 标注行左侧标题只显示“当前被设置的类”,不显示复杂信息。 ### 3.2 单击 - 单击空白 15 分钟块:新增标注,默认类型 `异常`(可改)。 - **wave 与 PKS 一致**:单击任一块 → 自动选中所在**整小时**(4 个块)。 - 连续小时再次单击 → 若类型相同,**合并成一条记录**。 - 同一通道内,不同类型不允许重叠或相邻;不同通道互不影响。 ### 3.3 双击弹窗 双击任意块打开弹窗,内容: 1. 类型选择:轻微 / 异常 / 严重异常。 2. 起止时间:可编辑,**按小时设置**(wave 与 PKS 都默认整小时)。 3. 算法原始属性:以只读 JSON 展示,例如: ``` 机组、批次、周期编号、压力阶段、开始小时、结束小时、 持续自然小时数、有效运行小时数、周期基线油压、正常波动带、 阶段开始小时油压、阶段结束小时油压、阶段最低小时油压、 阶段开始/结束相对周期基线变化、阶段最大连续下降有效小时数、 阶段低报警小时数、阶段低低报警小时数、是否形成确认等级、阶段触发依据 ``` 4. 备注(可编辑)。 5. **删除按钮**:删除整条段记录。 保存后: - 改类型 → 更新段记录。 - 改起止 → 重新计算合并/拆分。 - 人工修改后 `origin=manual`,算法重复导入不覆盖。 ### 3.4 展示 - 波形半透明色块保持现状,覆盖整个标签段。 - 时间轴“标注”行:**汇总所有子图**;任一道有标签即着色,颜色取最高级别。 - 时间轴 tooltip 只简单表达“有标注”,不列通道明细。 - 增加颜色图例。 --- ## 4. 数据表 ```sql CREATE TABLE IF NOT EXISTS compressor_label ( id BIGINT UNSIGNED NOT NULL AUTO_INCREMENT, source_type VARCHAR(32) NOT NULL COMMENT 'vibration/oil_pressure/temperature/pressure_wave/pks_manual', origin VARCHAR(16) NOT NULL DEFAULT 'manual' COMMENT 'algorithm/manual/imported', target_type VARCHAR(16) NOT NULL COMMENT 'wave_file/pks', target_id BIGINT UNSIGNED NULL COMMENT 'wave_file.id', target_key VARCHAR(200) NOT NULL COMMENT 'wave:{id} / pks:{unit}:{code}:{metric}', channel_key VARCHAR(200) NOT NULL COMMENT '子图通道键', segment_key VARCHAR(128) NULL COMMENT '算法原始段分组键', unit VARCHAR(16) NOT NULL, device_code VARCHAR(64) NULL, device_part VARCHAR(200) NULL, device_point VARCHAR(200) NULL COMMENT 'wave 点位', metric_key VARCHAR(64) NULL COMMENT 'PKS: YSJ_11', metric_label VARCHAR(200) NULL COMMENT 'PKS: 链轮端振动', start_time DATETIME NOT NULL COMMENT '标签段起点,15min/小时对齐', end_time DATETIME NOT NULL COMMENT '标签段终点(不含)', algorithm_start DATETIME NULL COMMENT '算法原始段起点', algorithm_end DATETIME NULL COMMENT '算法原始段终点', label_type VARCHAR(32) NOT NULL COMMENT '轻微/异常/严重异常', label_subtype VARCHAR(64) NULL, severity TINYINT NULL, confirm_status VARCHAR(16) NOT NULL DEFAULT '未确认', usable_for_train TINYINT(1) NOT NULL DEFAULT 1, source_file VARCHAR(500) NULL, source_row VARCHAR(64) NULL, algorithm_version VARCHAR(64) NULL, features_json MEDIUMTEXT NULL COMMENT '算法原始属性', note VARCHAR(1000) NULL, created_by VARCHAR(64) NULL, updated_by VARCHAR(64) NULL, created_at DATETIME NOT NULL DEFAULT CURRENT_TIMESTAMP, updated_at DATETIME NOT NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP, deleted_at DATETIME NULL, PRIMARY KEY (id), KEY idx_target_time (target_key, start_time, end_time), KEY idx_channel_time (channel_key, start_time), KEY idx_segment (segment_key), KEY idx_unit_time (unit, start_time), KEY idx_source (source_type, origin) ) ENGINE = InnoDB DEFAULT CHARSET = utf8mb4 COMMENT = '统一训练标签表'; ``` 说明: - 不做 `(target_key, slot_start)` 唯一键,因为要支持跨多槽的段和合并。 - 段重叠/相邻的合并与冲突在服务层处理。 - 同通道同时间段只保留一条有效记录。 - 算法段导入时也按段存,显示时展开为 15 分钟块。 ### 合并/冲突规则 ``` 新增或修改时,取同 target_key(同一子图通道)下与 [start,end) 重叠或相邻的记录: - 类型相同(重叠或相邻) -> 合并为一条,start=min, end=max - 类型不同(重叠或相邻) -> 拒绝,提示先修改/删除相邻记录 - 不同 target_key/通道互不影响,各自独立 ``` ### 算法导入覆盖 ``` 不存在 -> 插入 origin=manual -> 跳过 origin=algorithm -> 更新 ``` --- ## 5. 算法标签接入 算法不动,新增转存程序: ``` 读取 CSV -> 生成段记录 -> UPSERT compressor_label ``` | 来源 | source_type | metric_key | label_type | 时间 | |---|---|---|---|---| | 振动异常段.csv | vibration | 链轮端→YSJ_11,联轴器端→YSJ_10 | 振动阶段 | 开始/结束小时 | | 润滑油压力小时阶段段.csv | oil_pressure | 7/8/9 号机→YSJ_5 | 压力阶段 | 开始/结束小时 | | 温度异常段.csv | temperature | 阶段点位 YSJ_n → YSJ{unit}_n | 温度阶段 | 开始/结束小时 | 字段映射: - `label_subtype`:振动侧 / 温度部位 / 方向 / 特征类型。 - `confirm_status`:由“是否形成确认等级”映射。 - `source_row`:周期编号。 - `features_json`:整行原样 JSON。 - `segment_key`:来源 + 周期编号 + 起止时间。 正常样本不导入、不生成。 --- ## 6. 接口 ``` GET /api/labels?target_type=&unit=&device_code=&metric_key=&start=&end= GET /api/labels?wave_file_ids=... POST /api/labels 新增(自动合并) PUT /api/labels/{id} 改类型/起止/备注(自动合并或拆分) DELETE /api/labels/{id} 删除段 ``` 返回: ```json { "id": 12, "targetType": "pks", "targetKey": "pks:7:7#:YSJ_11", "startTime": "2026-02-10T10:00:00", "endTime": "2026-02-10T12:00:00", "labelType": "异常", "labelSubtype": "链轮端", "origin": "algorithm", "confirmStatus": "已确认", "features": { "...": "算法原始属性" } } ``` --- ## 7. 时间轴 - 汇总所有子图/通道。 - 每个时间槽:任一道有标签 → 标记。 - 颜色取该槽内最高级别(严重异常 > 异常 > 轻微)。 - tooltip 只显示“有标注”,不列通道明细。 - 语义不变,只改数据来源和着色逻辑。 --- ## 8. 分期 ### Phase 0:确认本设计 ### Phase 1:清理预训练记录 前端按钮/状态、后端接口/service/CSV/`pretrainCounts`。不动 `wave_annotation`。 ### Phase 2:新表 + 算法标签只读 建表、转存三张 CSV、查询接口、标注行只读展示。 ### Phase 3:人工标注 单击新增/整小时选择/连续合并;双击弹窗改类型、起止、看算法 JSON、删除;先 wave 后 PKS。 ### Phase 4:训练导出与迁移(暂缓,用户指示先不做) 导出 `usable_for_train=1`;迁移 `wave_annotation`;下线老逻辑。 --- ## 8.1 测试记录(2026-11-08) 使用 Playwright + Chrome 对 Phase 1–3 做了界面回归: - Phase 1:窗口文件表只剩“定位”,无“记录/删除”;页面无“预训练”;`/api/pretrain-records` 返回 404。 - Phase 2:算法标签在子图标注行按 15 分钟块显示;时间轴“标注”行汇总着色。 - Phase 3: - 单击空白整点块 → POST 创建 `异常`,成功。 - 双击已有标签 → 弹窗,类型、起止、点位、备注正常回显。 - 改类型保存 → PUT,弹窗关闭,重开类型正确。 - 改起止时间 + 备注保存 → PUT,重开值正确。 - 删除 → 二次确认 → DELETE,弹窗关闭。 - 同类型相邻单击 → 合并为一条段记录。 - 不同类型相邻保存 → 400,界面提示“同一子图内不同类型不能重叠或相邻”。 - 双击算法标签 → 显示只读算法属性 JSON(机组、周期编号、压力阶段、基线油压、触发依据等)。 - 测试产生的临时人工标签已清理,库内保留 182 条算法标签。 --- ## 9. 已确认 1. wave 单击也选中整小时。 2. 同一通道内,不同类型不允许重叠或相邻并存;不同通道各自独立。 3. 时间轴 tooltip 只表达“有标注”,不显示通道明细。 --- ## 10. 注意 - 段记录跨多槽,显示时展开;不要按槽存重复行。 - 人工修改与算法导入要隔离,避免覆盖。 - 新旧标注并存期只显示一套,避免重复。 - ECharts 标注行需随缩放重绘,事件绑定在 graphic 上。