From f75ebfac88582cbf1e8c39662a35ebd0b41e8bbf Mon Sep 17 00:00:00 2001 From: Momentry Studio Date: Fri, 9 Oct 2026 16:25:26 +0800 Subject: [PATCH] =?UTF-8?q?fix:=20=E4=BF=AE=E5=A4=8D=20Face=20Filter=20UI?= =?UTF-8?q?=20=E5=8F=82=E6=95=B0=E6=8C=81=E4=B9=85=E5=8C=96=E5=88=B0?= =?UTF-8?q?=E5=90=8E=E7=AB=AF=E6=95=B0=E6=8D=AE=E5=BA=93?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit 问题: - UI Filter Rules (min_confidence, min_bbox_size 等) 修改后只保存到 localStorage - 不会持久化到后端数据库,导致刷新页面或换浏览器后设置丢失 修复: - updateRules() 函数现在会调用 markSingleFrameSettingsModified() - 触发 500ms debounce 的 auto-save 到后端 API - 保存完整的 FaceFilterSettings (包括 ui_filter_rules, processing_thresholds, trace_settings) 变更: 1. src/composables/useFaceFilter.ts - updateRules() 新增调用 markSingleFrameSettingsModified() - 确保 UI Filter Rules 修改后自动保存到后端 2. docs/FACE_FILTER_PERSISTENCE_TEST_GUIDE.md - 完整的测试指南 - 包含调试方法和后端 API 要求 持久化流程: - FaceFilterPanel 打开 → loadSingleFrameSettings() 从后端加载 - 用户修改参数 → updateRules() → markSingleFrameSettingsModified() → auto-save - 500ms debounce → saveSingleFrameSettings() → PUT /api/v1/file-profile 测试: - ✅ TypeScript 编译通过 - ⏳ 需要验证后端 API 支持 测试文件: 020.mp4 (UUID: b496a68800f90770aa7246c877f38985) --- docs/FACE_FILTER_PERSISTENCE_TEST_GUIDE.md | 304 +++++++++++++++++++++ src/composables/useFaceFilter.ts | 1 + 2 files changed, 305 insertions(+) create mode 100644 docs/FACE_FILTER_PERSISTENCE_TEST_GUIDE.md diff --git a/docs/FACE_FILTER_PERSISTENCE_TEST_GUIDE.md b/docs/FACE_FILTER_PERSISTENCE_TEST_GUIDE.md new file mode 100644 index 0000000..c2b35a1 --- /dev/null +++ b/docs/FACE_FILTER_PERSISTENCE_TEST_GUIDE.md @@ -0,0 +1,304 @@ +# Face Filter 持久化功能测试指南 + +**日期**: 2026-10-09 +**修复版本**: commit 8789770 + 持久化修复 + +--- + +## 问题描述 + +用户报告:Face Filter 参数改动后没有成功持久化到后端数据库。 + +## 修复内容 + +### 1. UI Filter Rules 持久化修复 + +**文件**: `/Users/accusys/momentry_studio/src/composables/useFaceFilter.ts` + +**修改**: +```typescript +function updateRules(newRules: Partial) { + settings.value.ui_filter_rules = { ...settings.value.ui_filter_rules, ...newRules }; + applyLocalFilter(); + savePreferences(); // 保存到 localStorage + markSingleFrameSettingsModified(); // 新增:触发 auto-save 到后端 +} +``` + +**说明**: 之前只保存到 localStorage,现在会触发 auto-save 到后端数据库。 + +--- + +## 持久化流程 + +### 完整流程 + +1. **打开 FaceFilterPanel** + - 用户点击 "🔍 Face Filter" 按钮打开面板 + - `watch(showPanel)` 触发 `loadSingleFrameSettings(fileUuid)` + - 从后端 API `/api/v1/file-profile?file_uuid={uuid}` 加载该文件的设置 + - 设置 `currentFileUuid.value = fileUuid` + +2. **修改 UI Filter Rules** + - 用户修改 `min_confidence`, `min_bbox_size`, `source`, `backend_status` + - 触发 `@change="onRuleChange"` + - 调用 `updateRules(settings.value.ui_filter_rules)` + - `updateRules()` 内部调用 `markSingleFrameSettingsModified()` + - 500ms debounce 后调用 `saveSingleFrameSettings(currentFileUuid)` + - 发送 PUT 请求到 `/api/v1/file-profile` + +3. **修改 Trace Settings** + - 用户修改 `VLM Processing`, `Face Groups` 等选项 + - 触发 `@change="markModified"` + - 调用 `markSingleFrameSettingsModified()` + - 500ms debounce 后保存到后端 + +4. **保存成功** + - `settingsModified.value = false` + - 显示 "✓ Auto-saved" + - 发送 `settings-updated` 事件 + +--- + +## 测试步骤 + +### 测试文件 +- 文件名: 020.mp4 +- UUID: b496a68800f90770aa7246c877f38985 +- Face 数量: 162 + +### 测试场景 1: UI Filter Rules 持久化 + +1. **打开 FaceFilterPanel** + - 点击 "🔍 Face Filter" 按钮打开面板 + - 等待加载完成 + +2. **修改 UI Filter Rules** + - 修改 `Min Confidence` 从 0.5 改为 0.8 + - 观察:底部显示 "⏳ Saving..." + - 等待 500ms 后显示 "✓ Auto-saved" + +3. **刷新页面** + - 刷新浏览器(F5 或 Cmd+R) + - 重新打开 FaceFilterPanel + - **验证**: `Min Confidence` 应该仍然是 0.8 + +4. **检查后端数据** + - 使用 API 工具(Postman/curl)查询: + ``` + GET /api/v1/file-profile?file_uuid=b496a68800f90770aa7246c877f38985 + ``` + - 验证返回的 `face_filter.ui_filter_rules.min_confidence` 是否为 0.8 + +### 测试场景 2: Trace Settings 持久化 + +1. **修改 Trace Settings** + - 取消勾选 "VLM Processing" + - 观察:底部显示 "⏳ Saving..." + - 等待 500ms 后显示 "✓ Auto-saved" + +2. **刷新页面** + - 刷新浏览器 + - 重新打开 FaceFilterPanel + - **验证**: "VLM Processing" 应该仍然未勾选 + +3. **检查后端数据** + - API 查询: + ``` + GET /api/v1/file-profile?file_uuid=b496a68800f90770aa7246c877f38985 + ``` + - 验证 `face_filter.trace_settings.single_frame_trace_vlm_enabled` 是否为 false + +### 测试场景 3: 跨浏览器持久化 + +1. **在浏览器 A 修改设置** + - 打开 Chrome + - 修改 `Min Confidence` 为 0.9 + - 等待 "✓ Auto-saved" + +2. **在浏览器 B 验证** + - 打开 Firefox 或 Safari + - 访问同一个文件 + - 打开 FaceFilterPanel + - **验证**: `Min Confidence` 应该是 0.9(从后端加载) + +--- + +## 调试方法 + +### 1. 浏览器 Console + +打开开发者工具 Console,观察以下日志: + +```javascript +// 成功加载 +// (没有错误) + +// 保存失败 +console.error('Auto-save failed for single frame settings'); +console.error('Failed to save single frame settings:', err); +``` + +### 2. Network 面板 + +观察 API 请求: + +``` +GET /api/v1/file-profile?file_uuid={uuid} // 加载设置 +PUT /api/v1/file-profile // 保存设置 +``` + +**请求体示例**: +```json +{ + "file_uuid": "b496a68800f90770aa7246c877f38985", + "face_filter": { + "version": "1.0", + "ui_filter_rules": { + "min_confidence": 0.8, + "min_bbox_size": 80, + "source": "all", + "backend_status": "accept" + }, + "processing_thresholds": { + "min_confidence": 0.8, + "min_bbox_size": 80 + }, + "trace_settings": { + "single_frame_trace_vlm_enabled": true, + "single_frame_trace_group_enabled": true, + "single_frame_trace_unassigned_enabled": true, + "single_trace_group_filter_enabled": true + } + } +} +``` + +### 3. Vue DevTools + +检查 `settings` 响应式变量的值: +- `settings.value.ui_filter_rules.min_confidence` +- `settings.value.trace_settings.single_frame_trace_vlm_enabled` +- `settingsModified.value` (应该为 false 保存成功后) + +--- + +## 可能的问题 + +### 问题 1: 后端 API 返回格式不对 + +**症状**: FaceFilterPanel 打开后设置不正确 + +**检查**: +```bash +curl http://localhost:3002/api/v1/file-profile?file_uuid=b496a68800f90770aa7246c877f38985 +``` + +**预期格式**: +```json +{ + "file_uuid": "b496a68800f90770aa7246c877f38985", + "face_filter": { + "ui_filter_rules": { ... }, + "processing_thresholds": { ... }, + "trace_settings": { ... } + } +} +``` + +**解决方案**: 确保 Core API 已更新到支持三段式结构的版本 + +### 问题 2: 后端 API 不接受新格式 + +**症状**: 保存失败,Console 显示错误 + +**检查**: Network 面板中的 PUT 请求返回状态码 + +**解决方案**: +- 检查 Core API 的 `/api/v1/file-profile` PUT 端点是否支持新格式 +- 确保 Rust 端的 `FaceFilterSettings` 结构与 TypeScript 端一致 + +### 问题 3: localStorage 干扰 + +**症状**: 设置被意外覆盖 + +**调试**: +```javascript +// 在 Console 中执行 +localStorage.getItem('momentry_face_filter_preferences') +``` + +**清理**: +```javascript +localStorage.removeItem('momentry_face_filter_preferences') +``` + +--- + +## 后端 API 要求 + +### Core API 需要支持 + +1. **GET `/api/v1/file-profile?file_uuid={uuid}`** + - 返回完整的 `FaceFilterSettings`(三段式结构) + - 如果该文件没有设置,返回默认值 + +2. **PUT `/api/v1/file-profile`** + - 接受完整的 `FaceFilterSettings`(三段式结构) + - 保存到数据库 + - 返回成功状态 + +### Rust 端结构要求 + +确保 `FaceFilterSettings` 结构定义如下: + +```rust +pub struct FaceFilterSettings { + pub version: Option, + pub ui_filter_rules: UiFilterRules, + pub processing_thresholds: ProcessingThresholds, + pub trace_settings: TraceSettings, +} + +pub struct UiFilterRules { + pub min_confidence: f32, // 0.0-1.0 + pub max_confidence: Option, + pub min_bbox_size: u32, + pub max_bbox_size: Option, + pub source: Option, + pub backend_status: Option, +} + +pub struct ProcessingThresholds { + pub min_confidence: f32, + pub max_confidence: Option, + pub min_bbox_size: u32, + pub max_bbox_size: Option, +} + +pub struct TraceSettings { + pub single_frame_trace_vlm_enabled: bool, + pub single_frame_trace_group_enabled: bool, + pub single_frame_trace_unassigned_enabled: bool, + pub single_trace_group_filter_enabled: bool, +} +``` + +--- + +## 验证清单 + +- [ ] UI Filter Rules 修改后显示 "✓ Auto-saved" +- [ ] Trace Settings 修改后显示 "✓ Auto-saved" +- [ ] 刷新页面后设置保留 +- [ ] 跨浏览器设置保留 +- [ ] 后端 API 返回正确格式 +- [ ] 后端 API 保存成功 +- [ ] Console 无错误日志 +- [ ] Network 请求成功 (200 OK) + +--- + +**测试负责人**: Studio Team +**Core API 支持**: Core Team +**最后更新**: 2026-10-09 \ No newline at end of file diff --git a/src/composables/useFaceFilter.ts b/src/composables/useFaceFilter.ts index 592d893..6056404 100644 --- a/src/composables/useFaceFilter.ts +++ b/src/composables/useFaceFilter.ts @@ -307,6 +307,7 @@ function updateRules(newRules: Partial) { settings.value.ui_filter_rules = { ...settings.value.ui_filter_rules, ...newRules }; applyLocalFilter(); savePreferences(); + markSingleFrameSettingsModified(); } // Change mode and re-filter