修复培训:对齐电子班牌V2模型并清理演示页面
This commit is contained in:
1 parent
e65870ac6e
commit
20694559d7
9 files changed
+788
-303
No files matched your search
@@ -0,0 +1,110 @@
|
||||
# RailwaySystem Electronic Board Demo-Safe Cleanup (V2 闭环版) 实施报告
|
||||
|
||||
## 1. 任务背景与集成基线
|
||||
|
||||
本任务目标为 **RailwaySystem Electronic Board Demo-Safe Cleanup**:
|
||||
1. **基线对齐**:切换至正式受控集成分支 `integration/delivery-cicd-20260914` (commit `c763cb691c4a48a0a01339de83731a99ed9311e6`),在新分支 `fix/demo-electronic-board-cleanup-v2` 下开发。
|
||||
2. **结构对齐**:与已在数据库执行的 Database V2 (`public.train_electronic_board`) 真实物理结构完全对齐;
|
||||
3. **界面清洁**:前端管理页面彻底消除裸露的数据库表名、列名、主键 ID 及枚举裸数值;
|
||||
4. **生命周期写保护**:
|
||||
- `boardStatus` / `lastHeartbeat` 均为设备运行只读字段;
|
||||
- 前端表单中彻底删除 `boardStatus` 与 `lastHeartbeat`,避免管理员人工篡改;
|
||||
- 后端新增时显式初始化 `boardStatus = 0`(离线);
|
||||
- 后端编辑时写保护:强制置空防篡改,保留数据库原值;
|
||||
5. **boardId 闭环**:前端不传 `boardId`,后端 Service 自动生成唯一 UUID,实现 INSERT 与 GET 闭环;
|
||||
6. **逻辑删除**:DELETE 操作统一使用 `UPDATE ... SET del_flag = '2'` 软删除,所有查询(包含教室聚合)强制排除 `del_flag = '2'`;
|
||||
7. **教室聚合无回归**:完全保持 CG-05 裁决的轻量 `ClassroomBoardSummaryVO` 契约,既有聚合行为 100% 正常;
|
||||
8. **不伪造能力**:不伪造不存在的设备心跳上报、不伪造协议/MQTT、不添加假“在线心跳模拟”按钮。
|
||||
|
||||
---
|
||||
|
||||
## 2. 真实数据库 V2 结构验证 (Kingbase 元数据)
|
||||
|
||||
通过直连 Kingbase 只读查询 `information_schema.columns`、`information_schema.table_constraints`、`information_schema.key_column_usage`,确认当前 `public.train_electronic_board` 的实际元数据如下:
|
||||
|
||||
### 2.1 真实列清单与约束
|
||||
|
||||
| 列名 | 数据类型 | 允许空 | 默认值 | 约束类型 | 说明 |
|
||||
|:---|:---|:---|:---|:---|:---|
|
||||
| `board_id` | character varying(64) | NO | 无 | PRIMARY KEY (`pk_train_electronic_board`) | 班牌设备主键 UUID |
|
||||
| `board_sn` | character varying(64) | NO | 无 | UNIQUE (`uq_train_electronic_board_sn`) | 设备硬件唯一序列号 |
|
||||
| `board_name` | character varying(100) | NO | 无 | - | 设备名称 (V2 迁移脚本新增) |
|
||||
| `bind_classroom_id`| character varying(64) | YES | NULL | FOREIGN KEY (`fk_electronic_board_classroom`) | 关联教室主键,外键关联 `train_classroom_info.class_room_id` |
|
||||
| `board_ip` | character varying(45) | YES | NULL | - | 设备当前 IP 地址 |
|
||||
| `api_endpoint` | character varying(255) | YES | NULL | - | 设备通信/推流端点 URL |
|
||||
| `support_checkin_type` | character varying(50) | YES | 'CARD,FACE' | - | 支持签到方式 (CARD, FACE, QR) |
|
||||
| `board_status` | smallint | YES | 1 | - | 状态 (0 离线, 1 在线) |
|
||||
| `last_heartbeat` | timestamp without time zone | YES | NULL | - | 最近心跳时间 |
|
||||
| `remark` | character varying(500) | YES | NULL | - | 备注信息 |
|
||||
| `create_by` | character varying(64) | YES | '' | - | 创建人账号 |
|
||||
| `create_time` | timestamp without time zone | YES | clock_timestamp() | - | 创建时间 |
|
||||
| `update_by` | character varying(64) | YES | '' | - | 修改人账号 |
|
||||
| `update_time` | timestamp without time zone | YES | clock_timestamp() | - | 修改时间 |
|
||||
| `del_flag` | character(1) | YES | '0' | - | 逻辑删除标志 ('0' 存在, '2' 删除) |
|
||||
|
||||
### 2.2 确认已物理删除的旧字段
|
||||
- ❌ `bind_plan_id`
|
||||
- ❌ `board_content`
|
||||
- ❌ `board_playmode`
|
||||
- ❌ `create_user`
|
||||
|
||||
---
|
||||
|
||||
## 3. 后端最小兼容整改明细
|
||||
|
||||
### 3.1 实体模型对齐 (`TrainElectronicBoard.java`)
|
||||
- 剔除 `bindPlanId`、`boardContent`、`boardPlaymode`、`createUser`。
|
||||
- 补充 `boardName`、`apiEndpoint`、`delFlag`。
|
||||
- 标注 `@JsonFormat(pattern = "yyyy-MM-dd HH:mm:ss")`。
|
||||
|
||||
### 3.2 映射器对齐与逻辑删除 (`TrainElectronicBoardMapper.xml`)
|
||||
- 彻底剔除不存在的旧列,加入 `board_name` 与 `api_endpoint`。
|
||||
- 查询 `selectTrainElectronicBoardList` 与 `selectTrainElectronicBoardByBoardId` 均强制带上 `where del_flag = '0'`。
|
||||
- 逻辑删除:
|
||||
```sql
|
||||
<update id="deleteTrainElectronicBoardByBoardId" parameterType="String">
|
||||
update train_electronic_board
|
||||
set del_flag = '2',
|
||||
update_time = clock_timestamp()
|
||||
where board_id = #{boardId}
|
||||
</update>
|
||||
```
|
||||
|
||||
### 3.3 业务服务层写保护与主键闭环 (`TrainElectronicBoardServiceImpl.java`)
|
||||
- **boardId 生成位置**:在 `insertTrainElectronicBoard` 中:
|
||||
```java
|
||||
if (StringUtils.isEmpty(trainElectronicBoard.getBoardId())) {
|
||||
trainElectronicBoard.setBoardId(IdUtils.fastSimpleUUID());
|
||||
}
|
||||
trainElectronicBoard.setBoardStatus(0); // 显式初始化为离线
|
||||
```
|
||||
- **boardStatus / lastHeartbeat 写保护位置**:在 `updateTrainElectronicBoard` 中:
|
||||
```java
|
||||
trainElectronicBoard.setBoardStatus(null);
|
||||
trainElectronicBoard.setLastHeartbeat(null);
|
||||
```
|
||||
|
||||
### 3.4 控制器与接口兼容 (`TrainElectronicBoardController.java`)
|
||||
- 路由基路径:`@RequestMapping("/train/board")`。
|
||||
- 权限保持系统正式权限:`@ss.hasPermi('system:board:...')`。
|
||||
|
||||
---
|
||||
|
||||
## 4. 前端表单与列表重构 (`build_ui/src/views/train/board/index.vue`)
|
||||
- **表单彻底删除 boardStatus / lastHeartbeat**:仅录入设备名称*、硬件序列号*、安装教室、设备IP、通信端点、签到支持方式复选组、备注。
|
||||
- **列表优雅展示**:安装教室根据 ID 映射显示 `roomName`;状态 Tag 化(绿标签“在线”/灰标签“离线”);心跳空显示“—”。
|
||||
|
||||
---
|
||||
|
||||
## 5. KingbaseES 9 步最小 Smoke Test 实测结果
|
||||
|
||||
在直连真实 KingbaseES 测试(`BoardSmokeTest.java`)中执行全部 9 项测试,结果全绿:
|
||||
1. **新增 Board(不传 boardId)**:Service 生成 UUID 并成功执行 INSERT。
|
||||
2. **查询 Board**:验证存在,初始 `board_status` 为 0(离线),`last_heartbeat` 为 NULL。
|
||||
3. **修改业务字段**:名称与 IP 成功更新。
|
||||
4. **确认写保护**:修改无法人为篡改 `boardStatus` 与 `lastHeartbeat`,DB 原值完好。
|
||||
5. **删除 Board**:执行软删除 UPDATE。
|
||||
6. **DB 物理验证**:底层行记录仍存在,`del_flag` 成功标记为 `'2'`。
|
||||
7. **业务 list 验证**:业务 list 查询自动排除,已不再返回该设备。
|
||||
8. **新增绑定教室 Board**:成功插入绑定测试教室的班牌。
|
||||
9. **Classroom 聚合验证**:通过 `ClassroomBoardSummaryVO` 聚合查询成功回显该班牌,既有聚合行为 100% 无回归!
|
||||
Reference in new issue
Block a user