Commit Graph

4 Commits

Author SHA1 Message Date
ericwyuan
2c5bf950c5 feat: 事件时间轴缩略帧 + 人物管理头像 + 人物合并硬规则校验
## 新架构:Oracle 集中计算 + NAS 代理展示

### Oracle 端 (fam-edge)
- 新增 frame_service: ffmpeg 视频抽帧 + VLM 人物定位裁剪头像(磁盘缓存)
- 新增 /api/oracle/frame: 按 video_id+ts 抽帧返回 jpeg(带 token)
- 新增 /api/oracle/avatar: 按 label 生成人物头像(VLM 定位人物 + 兜底整帧居中)
- 新增 person_identifier: 人物身份识别模块
- Gemini 适配器支持 flash/flash-lite 双模型切换,429 自动降级
- frame_service VLM 全模型 429 时进入 10 分钟熔断,避免每次请求白打配额
- 兜底头像不落缓存,配额恢复后自动重试 VLM 精确定位

### 人物合并硬规则校验(框架级修复)
- person_service: LLM 合并结果落库前加硬冲突检测
  - 性别冲突 → 绝不合并
  - 年龄档跨未成年/成年 → 绝不合并(防止把爷爷/宝宝并进同一人)
- oracle_db: upsert_person 入口剥离括号后缀(人物A(别名:人物B) → 人物A),消灭垃圾人物行
- 修复 set_canonical 丢弃 source 参数的 bug(旧代码硬编码 'manual' 导致错误合并被永久固化)
- get_events_for_label: 只提取该身份组的特征文本,头像定位更精准

### NAS 端 (fam-core)
- 新增 img_proxy: /api/proxy/frame 和 /api/proxy/avatar 代理 Oracle 图片
- app.py 注册 img_bp 蓝图
- oracle_sync / db_layer / member_manager 同步人物表

### UI 端 (fam-ui)
- 事件时间轴: 每条事件卡片加时间点缩略帧
- 人物管理: 每人卡片加头像(150x150 圆角)
- parse_persons: 剥离括号备注,与 Oracle 归一化一致
- 新增 EventItem 组件、Timeline 页改造
- Chat / ServiceStatus 页相应调整

### 数据库
- scripts/ddl.sql: 同步表结构更新
- Oracle people 表: features_json / display_uid / source 字段完善
2026-08-23 00:13:56 +08:00
ericwyuan
4cf4fc4bc2 [功能] 人物管理按运动视频重设计 - 人物卡新增「运动片段」区块(缩略图/时间/摘要/事件数,点击跳时间轴定位); 新增 GET /api/ui/people/clips 后端接口(按 label/canonical_name 查关联运动片段,含 first_ts/clip_events); Timeline 支持 ?video= 定位 2026-08-22 12:55:30 +08:00
ericwyuan
22df28f2d3 feat(fam-ui): 各页面加载状态 - 数据到达前不再是空白/半截页面
新增 Spinner 组件,接入时间轴/AI对话历史/人物管理/统计图表/模型统计/
服务状态 6 个页面。People.vue 特殊处理:命名或合并后触发的刷新不重新
显示整页 Spinner(此时列表已有数据,会闪一下丢失滚动位置),只有首次
加载(列表为空)才转圈。ServiceStatus.vue 同理,手动点刷新只变按钮文
字,不重新蒙一层 Spinner。
2026-08-22 07:19:32 +08:00
ericwyuan
7579782daf refactor(fam-ui): 重构第三阶段 - Streamlit 换成 Vue3+Vite+Tailwind 完全重写
范围变更:原计划是给 Streamlit 界面做视觉美化,用户中途要求换新框架完全重新实现。
最终方案:Vue 3 + Vite + Tailwind CSS v4,本地 npm run build 出静态文件,NAS 不装
Node.js,由 fam-core 的 Flask 直接提供(send_from_directory),原来独立跑在 :8501
的 Streamlit 进程整个退休,前端和 API 合并到 fam-core 的 :8000 一个进程。

fam-core 新增只读 API(ui_api.py):全部包装 db_layer.py 里已有的查询函数,没有
新写查询逻辑(除了下面两处真实缺口)。新增 static_app.py 做 SPA 静态文件服务
(assets 直出 + 非 API 路径回退 index.html 供前端路由接管),app.py 注册顺序上
必须排在其他 /api/* 蓝图之后。

顺带补的两个功能缺口(旧 Streamlit 版本自己绕开 db_layer 写了裸 SQL 才有的功能,
db_layer 本身不支持):
- get_chat_history 补 offset 参数(分页)
- 新增 get_attention_events(统计图表页"关注事件"表格)

fam-ui 完全重写为 Vue 3 项目:7 个页面 1:1 迁移功能(事件时间轴/AI对话/对话历史/
人物管理/统计图表/模型统计/服务状态),深色主题设计系统(Inter+JetBrains Mono
字体、蓝紫渐变强调色、语义色 token)。用本地 npm run dev 代理到真实 NAS 数据做
了完整联调,过程中发现并修了两个真 bug:
- URLSearchParams 把 undefined 转成字符串 "undefined" 传给后端,导致日期筛选失效
- MariaDB SUM() 返回 Decimal,Flask 默认序列化成字符串,前端字符串拼接出乱码数字
  (ui_api.py::_ser 统一转 int/float 修复)

移动端 H5 补了响应式:原来的固定宽度侧边栏 + flex-wrap 导航在手机宽度下会把每个
按钮挤到文字逐字换行;改成 lg 以上桌面侧边栏、lg 以下移动端顶栏 + 横向可滑动导航
胶囊;人物管理页命名表单(输入框+命名按钮+合并下拉)在窄屏下改为纵向堆叠。

已部署 NAS 并验证:curl 确认 index.html/assets/深层路由/API 路由全部 200;
Browser 工具在桌面宽度和手机宽度下把 7 个页面点了一遍(含真实提问一次 AI 对话、
人物头像/事件缩略图加载、命名合并表单),旧 Streamlit 进程已停止。

Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
2026-08-22 06:48:25 +08:00