diff --git a/docs/camera_code改造测试报告.md b/docs/camera_code改造测试报告.md new file mode 100644 index 000000000..1f28813aa --- /dev/null +++ b/docs/camera_code改造测试报告.md @@ -0,0 +1,546 @@ +# camera_code 改造测试报告 + +## 一、测试概述 + +**测试目标**: 验证 camera_code 全链路改造的功能完整性和数据一致性 + +**测试时间**: 2026-02-13 + +**改造范围**: +- 后端:数据库、StreamProxy模块、AIoT模块 +- 前端:摄像头管理、ROI配置、API调用 + +**测试环境要求**: +- MySQL 5.7+ +- Redis 6.0+ +- ZLMediaKit 流媒体服务器 +- 前端开发环境(Node.js 18+) +- 后端 Java 环境(JDK 17+) + +--- + +## 二、测试准备 + +### 2.1 数据库迁移验证 + +**脚本位置**: `C:\workspace\wvp-platform\数据库\aiot\迁移-添加camera_code字段.sql` + +**执行步骤**: +```bash +# 1. 进入SQL脚本目录 +cd C:\workspace\wvp-platform\数据库\aiot + +# 2. 执行迁移脚本(需要MySQL客户端) +mysql -h localhost -u root -p your_database < 迁移-添加camera_code字段.sql +``` + +**预期结果**: +1. ✅ `wvp_stream_proxy` 表新增 `camera_code` 字段 +2. ✅ 现有数据自动生成 `camera_code`(格式:`cam_xxxxxxxxxxxx`) +3. ✅ `camera_code` 字段设置为 NOT NULL 和 UNIQUE 约束 +4. ✅ `wvp_ai_roi` 表的 `camera_id` 字段更新为对应的 `camera_code` +5. ✅ 验证查询显示无重复、无格式错误 + +**验证SQL**: +```sql +-- 检查字段是否添加成功 +SHOW COLUMNS FROM wvp_stream_proxy LIKE 'camera_code'; + +-- 检查唯一索引 +SHOW INDEX FROM wvp_stream_proxy WHERE Key_name = 'uk_camera_code'; + +-- 检查数据完整性(应返回0) +SELECT COUNT(*) FROM wvp_stream_proxy WHERE camera_code IS NULL; + +-- 检查格式正确性(应返回0) +SELECT COUNT(*) FROM wvp_stream_proxy +WHERE camera_code NOT REGEXP '^cam_[a-f0-9]{12}$'; + +-- 检查ROI表迁移情况 +SELECT COUNT(*) FROM wvp_ai_roi r +LEFT JOIN wvp_stream_proxy sp ON r.camera_id = sp.camera_code +WHERE sp.camera_code IS NULL; +``` + +--- + +## 三、功能测试用例 + +### 3.1 新增摄像头 - camera_code 自动生成 + +**测试目的**: 验证创建摄像头时 camera_code 自动生成逻辑 + +**前置条件**: +- 系统正常运行 +- 流媒体服务器在线 + +**测试步骤**: +1. 访问前端摄像头管理页面 +2. 点击"新增摄像头"按钮 +3. 填写摄像头信息: + - 名称:测试摄像头001 + - 拉流地址:rtsp://example.com/test/stream1 + - 超时时间:默认 + - 注意:**不需要手动填写 app 字段**(系统自动生成) +4. 提交保存 + +**预期结果**: +1. ✅ 摄像头创建成功 +2. ✅ 系统自动生成 `camera_code`(格式:`cam_xxxxxxxxxxxx`) +3. ✅ `app` 字段自动设置为与 `camera_code` 相同 +4. ✅ `stream` 字段为系统生成的唯一标识 +5. ✅ 数据库 `wvp_stream_proxy` 表中插入新记录 + +**验证SQL**: +```sql +SELECT id, camera_code, app, stream, name, src_url +FROM wvp_stream_proxy +WHERE name = '测试摄像头001'; +``` + +**重点检查**: +- `camera_code` 格式符合 `^cam_[a-f0-9]{12}$` +- `app` = `camera_code` +- `camera_code` 在全表唯一 + +--- + +### 3.2 ROI 截图功能 - cameraCode 参数 + +**测试目的**: 验证 ROI 截图接口改用 cameraCode 参数 + +**前置条件**: +- 摄像头已创建并在线推流 +- 流媒体服务器正常 + +**测试步骤**: +1. 访问 ROI 配置页面 +2. 选择已创建的摄像头 +3. 点击"获取截图"按钮 +4. 观察网络请求(F12开发者工具) + +**预期结果**: +1. ✅ 请求 URL:`/api/ai/roi/snap?cameraCode=cam_xxxxxxxxxxxx` +2. ✅ 使用 `cameraCode` 参数(而非旧的 `app`/`stream`) +3. ✅ 后端通过 `cameraCode` 查询 `StreamProxy` 对象 +4. ✅ 获取到正确的 `app` 和 `stream` 值 +5. ✅ 调用 ZLM 截图接口成功,返回图片数据 + +**验证方法**: +```javascript +// 浏览器控制台查看请求 +// Network > Headers > Request URL +// 应包含 cameraCode=cam_xxxxxxxxxxxx +``` + +**错误处理测试**: +- 使用不存在的 `cameraCode` → 返回 404 Not Found +- 流媒体服务器离线 → 返回 503 Service Unavailable + +--- + +### 3.3 配置推送到 Redis - camera_code 字段 + +**测试目的**: 验证配置推送使用 camera_code 查询和生成配置 + +**前置条件**: +- Redis 服务正常 +- ROI 已配置并绑定算法 +- Edge 设备在线 + +**测试步骤**: +1. 访问配置管理页面 +2. 创建或更新 ROI 配置 +3. 绑定算法模板 +4. 执行"配置推送"操作 +5. 检查 Redis 中的配置数据 + +**预期结果**: +1. ✅ 配置构建时使用 `camera_code` 查询 `StreamProxy` +2. ✅ 优先使用 `StreamProxy.srcUrl` 作为 `rtsp_url` +3. ✅ Redis 配置中包含 `camera_code` 字段 +4. ✅ 保留 `camera_id` 字段向后兼容(值为 `app/stream`) +5. ✅ StreamProxy 不存在时降级使用 MediaServer 构建 URL + +**验证命令**: +```bash +# 连接 Redis 检查配置 +redis-cli + +# 查看配置 key +KEYS aiot:edge:config:* + +# 查看具体配置内容 +GET aiot:edge:config:{edge_device_id} + +# 检查配置 JSON 中的字段 +# 应包含: +# - camera_code: "cam_xxxxxxxxxxxx" +# - camera_id: "app/stream" (向后兼容) +# - rtsp_url: 优先来自 StreamProxy.srcUrl +``` + +**配置示例**: +```json +{ + "cameras": [ + { + "camera_code": "cam_a1b2c3d4e5f6", + "camera_id": "cam_a1b2c3d4e5f6/stream_12345", + "rtsp_url": "rtsp://example.com/test/stream1", + "rois": [ + { + "roi_id": "roi_001", + "coordinates": [...], + "algorithms": [...] + } + ] + } + ] +} +``` + +--- + +### 3.4 前端展示和交互 + +**测试目的**: 验证前端页面正确使用 camera_code + +**测试用例 3.4.1 - 摄像头管理页面**: + +**测试步骤**: +1. 访问摄像头管理页面 +2. 查看摄像头列表 +3. 新增/编辑摄像头 + +**预期结果**: +1. ✅ 列表正确显示 `cameraCode` 字段 +2. ✅ 新增表单**隐藏** `app` 输入框(自动生成) +3. ✅ API 调用使用新的 `cameraCode` 字段 +4. ✅ 数据保存后正确回显 + +**测试用例 3.4.2 - ROI 配置页面**: + +**测试步骤**: +1. 访问 ROI 配置页面 +2. 选择摄像头 +3. 获取截图 +4. 配置 ROI 区域 + +**预期结果**: +1. ✅ 摄像头选择器显示 `cameraCode` 和名称 +2. ✅ 截图请求使用 `cameraCode` 参数 +3. ✅ ROI 保存时关联正确的 `cameraCode` +4. ✅ 配置查询使用 `cameraCode` 匹配 + +--- + +## 四、数据一致性测试 + +### 4.1 迁移数据验证 + +**测试目的**: 确保历史数据正确迁移 + +**验证SQL**: +```sql +-- 1. 检查所有 camera_code 都已生成 +SELECT COUNT(*) AS total, + COUNT(camera_code) AS has_code +FROM wvp_stream_proxy; +-- total 应等于 has_code + +-- 2. 检查 camera_code 格式 +SELECT id, camera_code +FROM wvp_stream_proxy +WHERE camera_code NOT REGEXP '^cam_[a-f0-9]{12}$'; +-- 应返回空 + +-- 3. 检查唯一性 +SELECT camera_code, COUNT(*) AS cnt +FROM wvp_stream_proxy +GROUP BY camera_code +HAVING cnt > 1; +-- 应返回空 + +-- 4. 检查 ROI 表关联 +SELECT r.roi_id, r.camera_id, r.name +FROM wvp_ai_roi r +LEFT JOIN wvp_stream_proxy sp ON r.camera_id = sp.camera_code +WHERE sp.camera_code IS NULL; +-- 应返回空(所有 ROI 都能找到对应的 camera_code) +``` + +### 4.2 新旧数据兼容性 + +**测试场景**: 系统同时存在迁移的旧数据和新创建的数据 + +**验证点**: +1. ✅ 旧数据的 `camera_code` 格式正确 +2. ✅ 新数据的 `camera_code` 与旧数据不冲突 +3. ✅ ROI 查询同时支持新旧数据 +4. ✅ 配置推送对新旧数据处理一致 + +--- + +## 五、异常测试 + +### 5.1 camera_code 重复冲突 + +**测试目的**: 验证重试机制 + +**模拟方法**: +- 理论上 UUID 生成的12位哈希极低概率重复 +- 系统已实现最多3次重试机制 + +**预期结果**: +- ✅ 第一次冲突时自动重试 +- ✅ 3次都冲突则抛出异常 +- ✅ 错误日志记录详细信息 + +### 5.2 StreamProxy 不存在 + +**测试场景**: 使用无效的 cameraCode 调用接口 + +**测试步骤**: +1. 调用截图接口:`/api/ai/roi/snap?cameraCode=cam_invalid123` +2. 调用配置推送时 ROI 关联了不存在的 camera_code + +**预期结果**: +- ✅ 截图接口返回 404 Not Found +- ✅ 配置推送时跳过该摄像头或使用降级逻辑 +- ✅ 错误日志记录 + +### 5.3 数据库迁移失败回滚 + +**测试场景**: 迁移脚本执行失败 + +**可能原因**: +- 数据库权限不足 +- 表不存在 +- 字段已存在 + +**验证方法**: +```sql +-- 检查迁移是否完成 +SHOW COLUMNS FROM wvp_stream_proxy LIKE 'camera_code'; + +-- 如果失败,检查错误日志 +SHOW ENGINE INNODB STATUS; +``` + +--- + +## 六、性能测试 + +### 6.1 camera_code 生成性能 + +**测试方法**: 批量创建摄像头 + +**测试步骤**: +1. 使用脚本批量调用新增摄像头接口 +2. 创建 100 个摄像头 +3. 记录平均响应时间 + +**预期结果**: +- ✅ 单次生成 camera_code 耗时 < 5ms +- ✅ 数据库唯一索引查询性能正常 +- ✅ 重试机制不影响整体性能 + +### 6.2 查询性能 + +**测试SQL**: +```sql +-- 1. 按 camera_code 查询(应使用唯一索引) +EXPLAIN SELECT * FROM wvp_stream_proxy WHERE camera_code = 'cam_a1b2c3d4e5f6'; +-- type: const 或 eq_ref + +-- 2. ROI 关联查询 +EXPLAIN SELECT r.*, sp.name, sp.src_url +FROM wvp_ai_roi r +INNER JOIN wvp_stream_proxy sp ON r.camera_id = sp.camera_code +WHERE sp.camera_code = 'cam_a1b2c3d4e5f6'; +-- 应使用索引 +``` + +--- + +## 七、集成测试场景 + +### 场景1: 完整业务流程 + +**流程步骤**: +1. 新增摄像头(自动生成 camera_code) +2. 创建 ROI 区域(关联 camera_code) +3. 绑定算法模板 +4. 获取截图验证(使用 cameraCode 参数) +5. 推送配置到 Redis(包含 camera_code) +6. Edge 设备消费配置 + +**验证点**: +- ✅ 每个步骤数据传递正确 +- ✅ camera_code 作为全局唯一标识贯穿全流程 +- ✅ 前后端数据一致 + +### 场景2: 多摄像头配置 + +**测试步骤**: +1. 创建 5 个摄像头 +2. 为每个摄像头配置 2-3 个 ROI +3. 绑定不同算法 +4. 批量推送配置 + +**验证点**: +- ✅ 所有 camera_code 唯一 +- ✅ ROI 正确关联到对应摄像头 +- ✅ Redis 配置结构正确 +- ✅ 无数据混乱 + +--- + +## 八、回归测试 + +### 8.1 旧功能验证 + +**测试项**: +- ✅ 摄像头列表查询 +- ✅ 摄像头编辑/删除 +- ✅ 流媒体代理功能 +- ✅ 国标设备对接 +- ✅ 录像管理 + +**预期**: 所有旧功能正常工作,不受 camera_code 改造影响 + +### 8.2 API 兼容性 + +**验证点**: +- ✅ 新接口正确处理 cameraCode +- ✅ 旧接口(如果有)仍可用或有明确废弃提示 +- ✅ 响应数据结构兼容 + +--- + +## 九、测试总结 + +### 9.1 测试清单 + +| 测试项 | 优先级 | 状态 | 备注 | +|--------|--------|------|------| +| 数据库迁移脚本执行 | P0 | ⏳待测 | 需要MySQL环境 | +| camera_code 自动生成 | P0 | ⏳待测 | 核心功能 | +| camera_code 唯一性 | P0 | ⏳待测 | 数据完整性 | +| ROI 截图接口 cameraCode 参数 | P0 | ⏳待测 | API改造 | +| 配置推送 camera_code 字段 | P0 | ⏳待测 | Redis配置 | +| 前端摄像头管理页面 | P1 | ⏳待测 | UI交互 | +| 前端 ROI 配置页面 | P1 | ⏳待测 | UI交互 | +| 数据一致性验证 | P0 | ⏳待测 | 迁移验证 | +| 异常处理测试 | P1 | ⏳待测 | 容错机制 | +| 性能测试 | P2 | ⏳待测 | 非阻塞 | + +### 9.2 风险评估 + +**高风险项**: +1. 数据库迁移失败 → **建议先备份数据库** +2. 历史数据 camera_code 生成冲突 → 已有重试机制 +3. ROI 表 camera_id 更新不完整 → 迁移脚本有验证SQL + +**缓解措施**: +- 在测试环境先完整执行一遍 +- 准备回滚方案 +- 监控生产环境日志 + +### 9.3 建议测试顺序 + +1. **第一阶段(核心功能)**: + - 数据库迁移 + - camera_code 自动生成 + - 数据一致性验证 + +2. **第二阶段(接口改造)**: + - ROI 截图接口 + - 配置推送功能 + - API 调用验证 + +3. **第三阶段(前端集成)**: + - 摄像头管理页面 + - ROI 配置页面 + - 端到端流程测试 + +4. **第四阶段(回归测试)**: + - 旧功能验证 + - 性能测试 + - 异常场景 + +### 9.4 部署前检查项 + +- [ ] 数据库迁移脚本在测试环境验证通过 +- [ ] 所有 P0 测试用例通过 +- [ ] 前后端代码已同步部署 +- [ ] Redis 配置结构兼容旧版本(向后兼容) +- [ ] 回滚方案准备就绪 +- [ ] 监控告警配置完成 + +--- + +## 十、附录 + +### 附录A: 相关代码文件清单 + +**后端文件**: +- `StreamProxy.java` - 新增 cameraCode 字段 +- `StreamProxyMapper.java` - 新增 selectByCameraCode 查询 +- `StreamProxyProvider.java` - SQL 生成逻辑 +- `StreamProxyServiceImpl.java` - 自动生成和查询实现 +- `IStreamProxyService.java` - 接口声明 +- `AiRoiController.java` - snap 接口改造 +- `AiRedisConfigServiceImpl.java` - 配置推送改造 + +**前端文件**: +- `apps/web-antd/src/api/aiot/device/index.ts` - API 类型定义 +- `apps/web-antd/src/views/aiot/device/camera/index.vue` - 摄像头管理页面 +- `apps/web-antd/src/views/aiot/device/roi/index.vue` - ROI 配置页面 +- `apps/web-antd/src/views/aiot/device/roi/components/*.vue` - ROI 子组件 + +**数据库文件**: +- `数据库/aiot/迁移-添加camera_code字段.sql` - 迁移脚本 + +### 附录B: Git 提交记录 + +``` +450afb811 feat(aiot): 配置推送使用camera_code查询StreamProxy +6d1e1d0bc feat(aiot): snap接口改用cameraCode参数查询StreamProxy +3792a3061 feat(streamProxy): 实现camera_code自动生成和查询逻辑 +754677e11 feat(streamProxy): Service接口新增getStreamProxyByCameraCode方法 +2b61113ba feat(streamProxy): Provider增加camera_code的SQL处理 +2e89c2a62 feat(streamProxy): Mapper新增selectByCameraCode查询方法 +b542432dc feat(streamProxy): StreamProxy增加cameraCode字段 +0c8037726 fix(aiot): 迁移脚本增加camera_code格式验证 +731291217 feat(aiot): 添加camera_code字段迁移脚本 +ac345a472 feat(aiot): ROI配置页面改用cameraCode参数和截图调用 +4bbc4b16d feat(aiot): 摄像头管理页面改用cameraCode,隐藏app输入 +2583ed533 feat(aiot): Camera接口增加cameraCode字段,getSnapUrl改用cameraCode +``` + +### 附录C: 测试数据示例 + +**摄像头测试数据**: +```sql +INSERT INTO wvp_stream_proxy (camera_code, app, stream, name, src_url, timeout, enable) +VALUES +('cam_test1234567', 'cam_test1234567', 'stream_001', '测试摄像头001', 'rtsp://example.com/test1', 30, 1), +('cam_test7654321', 'cam_test7654321', 'stream_002', '测试摄像头002', 'rtsp://example.com/test2', 30, 1); +``` + +**ROI 测试数据**: +```sql +INSERT INTO wvp_ai_roi (roi_id, camera_id, name, points) +VALUES +('roi_001', 'cam_test1234567', 'ROI区域1', '[[0,0],[100,0],[100,100],[0,100]]'), +('roi_002', 'cam_test1234567', 'ROI区域2', '[[200,200],[300,200],[300,300],[200,300]]'); +``` + +--- + +**文档版本**: v1.0 +**创建时间**: 2026-02-13 +**创建人**: AI开发团队 +**审核状态**: 待审核