P2-14 模型管理简化: - 上传新模型:模态框上传 → 存盘 → SHA256 入库 → 可选自动分发 - 设备兼容性矩阵:根据 Edge /v1/capabilities 区分缺失 vs 不适用 - 版本管理:从固定 auto 改为文件修改时间戳 - 更新全部智能过滤:只推送缺失/不一致的设备 P2-15 人脸库优化: - Build 产出自动注册为标准资源,接入 Resource Task 分发系统 - 人脸库页面增加设备同步状态矩阵 + 批量同步按钮 - 人员搜索过滤 - 人脸质量评分反馈(构建诊断信息 + 通过率展示) 新增:通道部署页每台设备显示配置同步状态(对比 config_versions 与 Edge config SHA256) 文档:产品化改进计划、实施跟踪、模型与人脸库改进方案
175 lines
6.9 KiB
Markdown
175 lines
6.9 KiB
Markdown
# 模型管理 & 人脸库管理 改进实施方案
|
||
|
||
> 关联文档:[产品化改进计划](./产品化改进计划.md) → P2-14 / P2-15
|
||
> 跟踪状态:[实施跟踪](./实施跟踪.md)
|
||
|
||
## 改造原则
|
||
|
||
最小侵入,最大复用。人脸库的核心问题是"基建已就绪但没接上",不重写已有逻辑,而是**连通断点**。
|
||
|
||
---
|
||
|
||
## 一、人脸库管理(P2-15)
|
||
|
||
### 问题回顾
|
||
|
||
| 现有能力 | 问题 |
|
||
|----------|------|
|
||
| 人员 CRUD、照片管理 | ✅ 正常 |
|
||
| Python Build 脚本生成 face_gallery.db | ✅ 正常 |
|
||
| 产出落到 `resources/standard_resources/face_gallery/` | ✅ 已就位 |
|
||
| Resource Task 系统(`resource_sync_all`/`resource_sync_one`) | ✅ 已就位 |
|
||
| ResourceStatusBoard 对比矩阵 | ✅ 已就位 |
|
||
| 从人脸库页面触发批量同步 | ❌ 缺失 |
|
||
| 查看设备上人脸库版本/状态 | ❌ 缺失 |
|
||
| 搜索过滤人员 | ❌ 缺失 |
|
||
|
||
### 改动清单
|
||
|
||
#### 1.1 人脸库页面增加"同步到设备"区域
|
||
|
||
**文件**: `internal/web/ui/templates/face_gallery.html`
|
||
|
||
在人脸库页面底部新增一个卡片区域:
|
||
- 显示当前 `face_gallery.db` 构建状态(最后构建时间、人数、照片数)
|
||
- 显示设备同步状态矩阵(复用 `ResourceStatusBoard`,筛选 `resource_type=face_gallery`)
|
||
- "同步到全部设备"按钮 → 创建 `resource_sync_all` 任务
|
||
- 单设备"同步"按钮 → 创建 `resource_sync_one` 任务
|
||
|
||
**后端改动**:
|
||
- `pageFaceGallery` handler 增加:查询 `standard_resources` 中 `resource_type=face_gallery` 的记录、构建 `ResourceStatusBoard`
|
||
- 新增 `actionFaceGallerySync` handler:接收 `device_id[]`,调用 `taskSvc.CreateTask("resource_sync_all", deviceIDs, payload)`
|
||
|
||
#### 1.2 Build 后自动注册为标准资源
|
||
|
||
**文件**: `internal/web/ui.go` - `actionFaceGalleryBuild`
|
||
|
||
现有 Build 后只返回消息,需要增加:
|
||
1. Build 成功后扫描 `resources/standard_resources/face_gallery/` 目录
|
||
2. 调用 `resourceSvc.SyncStandardResourcesFromDirectory()` 或其局部逻辑
|
||
3. 将 `face_gallery.db` 的 SHA256/hash/size 写入 `standard_resources` 表
|
||
|
||
这样 Build 完后,Resource 分发系统就能自动感知到新版本。
|
||
|
||
**实现要点**:
|
||
```go
|
||
// actionFaceGalleryBuild 中,build 成功后:
|
||
hash, size := hashFile(outputDB)
|
||
resourcesRepo.Save(StandardResourceRecord{
|
||
Name: "face_gallery", ResourceType: "face_gallery",
|
||
SHA256: hash, SizeBytes: size,
|
||
FilePath: outputDB,
|
||
})
|
||
```
|
||
|
||
#### 1.3 人员搜索与过滤
|
||
|
||
**文件**: `internal/storage/face_gallery_repo.go` + `face_gallery.html`
|
||
|
||
- `FaceGalleryRepo` 新增 `SearchPersons(keyword string) ([]PersonRecord, error)`
|
||
- 模板增加搜索框,输入关键词实时过滤人员列表(前端 JS 过滤即可,数据量小)
|
||
|
||
#### 1.4 人脸质量评分展示
|
||
|
||
**文件**: `internal/service/face_gallery_builder.go` + `face_gallery.html`
|
||
|
||
- Build 脚本的输出中解析每张照片的 quality score(如果 build_gallery.py 有输出的话)
|
||
- 在人员详情编辑弹窗中,每张照片旁显示质量标签(高/中/低)
|
||
|
||
如果 `build_gallery.py` 当前不输出质量分,则作为可选项推迟。
|
||
|
||
---
|
||
|
||
## 二、模型管理(P2-14)
|
||
|
||
### 问题回顾
|
||
|
||
| 现有能力 | 问题 |
|
||
|----------|------|
|
||
| 目录扫描同步到 DB | ✅ 正常 |
|
||
| ModelStatusBoard 对比矩阵 | ✅ 正常 |
|
||
| Task 系统批量同步 | ✅ 正常 |
|
||
| "更新全部模型"按钮 | ✅ 已就位 |
|
||
| **上传新模型** UI | ❌ 按钮存在但无功能 |
|
||
| 模型版本管理 | ❌ 版本字段固定为 "auto" |
|
||
| 设备兼容性检查 | ❌ 不做区分,所有模型对所有设备 |
|
||
|
||
### 改动清单
|
||
|
||
#### 2.1 "上传新模型"功能实现
|
||
|
||
**文件**: `internal/web/ui/templates/models.html` + `internal/web/ui.go`
|
||
|
||
- 点击"上传新模型"弹出模态框
|
||
- 表单:模型名、模型类型(下拉选择)、描述、文件选择(.rknn)
|
||
- 上传后:
|
||
1. 保存文件到 `models/standard_models/{filename}`
|
||
2. 计算 SHA256
|
||
3. 写入 `standard_models` 表
|
||
4. 可选:立即分发到所有在线设备(checkbox)
|
||
|
||
**新增 handler**: `POST /ui/models/upload`
|
||
```go
|
||
func (u *UI) actionModelUpload(w http.ResponseWriter, r *http.Request) {
|
||
// multipart form: name, model_type, description, file
|
||
// 1. Save file to models/standard_models/
|
||
// 2. Hash + save to standard_models table
|
||
// 3. Optional: create model_sync_all task
|
||
}
|
||
```
|
||
|
||
**路由注册**: 在 `Routes()` 中添加 `r.Post("/models/upload", u.actionModelUpload)`
|
||
|
||
#### 2.2 模型版本管理
|
||
|
||
**文件**: `internal/storage/models_repo.go` + `internal/service/model_management.go` + `models.html`
|
||
|
||
- `StandardModelRecord.Version` 字段从固定 "auto" 改为基于文件修改时间的语义化版本(如 `2026-07-17-v1`)
|
||
- 上传时允许用户指定版本号(可留空自动生成)
|
||
- 模板中已有版本列,展示即可
|
||
|
||
#### 2.3 设备兼容性矩阵
|
||
|
||
**文件**: `internal/service/model_management.go` + `models.html`
|
||
|
||
当前 `ModelStatusBoard` 对所有设备检查所有模型。改进:
|
||
- `BuildModelStatusBoard` 接收可选的设备 capability 信息
|
||
- 如果设备不支持人脸识别(没有 face_recognition capability),则 `face_recognition` 类型的模型标记为 "N/A" 而非 "缺失"
|
||
- 矩阵中增加灰色 "N/A" pill,区别于红色的 "缺失"
|
||
|
||
**实现要点**:
|
||
- 在 `pageModels` 中查询设备 `/v1/capabilities`,缓存到 map
|
||
- 传给 `BuildModelStatusBoard` 一个新参数 `deviceCapabilities map[string][]string`
|
||
- Cell 增加第三种状态 `"na"` → 灰色 pill "不适用"
|
||
|
||
#### 2.4 "更新全部模型"增强
|
||
|
||
当前已有此功能,只做小优化:
|
||
- 改为只更新需要更新的设备(缺失或不一致的),而不是全量推送
|
||
- 这在前端层面做过滤:只提交 `status != "ok"` 的设备 ID
|
||
|
||
---
|
||
|
||
## 三、实施顺序
|
||
|
||
```
|
||
第1步:人脸库 - Build后自动注册为标准资源 (1.2) ← ✅ 已完成
|
||
第2步:人脸库 - 同步到设备区域 (1.1) ← 页面UI接入Task系统
|
||
第3步:人脸库 - 人员搜索过滤 (1.3) ← 交互优化
|
||
第4步:模型管理 - 上传新模型功能 (2.1) ← 补全核心功能
|
||
第5步:模型管理 - 设备兼容性矩阵 (2.3) ← 展示优化
|
||
第6步:模型管理 - 版本管理 (2.2) ← 锦上添花
|
||
第7步:人脸库 - 质量评分展示 (1.4) ← 可选
|
||
```
|
||
|
||
## 四、涉及文件一览
|
||
|
||
| 文件 | 改动类型 |
|
||
|------|----------|
|
||
| `internal/web/ui.go` | 新增/修改 handlers,增加 face gallery sync + model upload |
|
||
| `internal/web/ui/templates/face_gallery.html` | 增加同步区域、搜索框、质量展示 |
|
||
| `internal/web/ui/templates/models.html` | 实现上传模态框、兼容性显示 |
|
||
| `internal/storage/face_gallery_repo.go` | 新增 `SearchPersons` |
|
||
| `internal/service/model_management.go` | `BuildModelStatusBoard` 支持 capability 过滤 |
|
||
| `internal/service/face_gallery_builder.go` | 可选:解析质量分 |
|