fix: 修复 Face Filter UI 参数持久化到后端数据库
问题: - 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)
This commit is contained in:
304
docs/FACE_FILTER_PERSISTENCE_TEST_GUIDE.md
Normal file
304
docs/FACE_FILTER_PERSISTENCE_TEST_GUIDE.md
Normal file
@@ -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<UiFilterRules>) {
|
||||
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<String>,
|
||||
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<f32>,
|
||||
pub min_bbox_size: u32,
|
||||
pub max_bbox_size: Option<u32>,
|
||||
pub source: Option<String>,
|
||||
pub backend_status: Option<String>,
|
||||
}
|
||||
|
||||
pub struct ProcessingThresholds {
|
||||
pub min_confidence: f32,
|
||||
pub max_confidence: Option<f32>,
|
||||
pub min_bbox_size: u32,
|
||||
pub max_bbox_size: Option<u32>,
|
||||
}
|
||||
|
||||
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
|
||||
@@ -307,6 +307,7 @@ function updateRules(newRules: Partial<UiFilterRules>) {
|
||||
settings.value.ui_filter_rules = { ...settings.value.ui_filter_rules, ...newRules };
|
||||
applyLocalFilter();
|
||||
savePreferences();
|
||||
markSingleFrameSettingsModified();
|
||||
}
|
||||
|
||||
// Change mode and re-filter
|
||||
|
||||
Reference in New Issue
Block a user