- 增强 DICOM/视频项目导入与演示数据:DICOM 按文件名自然顺序处理,导入后展示上传与解析任务进度,恢复演示出厂设置保留演示视频和演示 DICOM 项目,并补充 demo media seed 逻辑。 - 完善项目管理:项目支持重命名、删除、复制,删除使用站内确认弹窗,复制支持新项目重置和全内容复制,DICOM 项目不显示生成帧入口。 - 完善 GT Mask 与导出链路:只支持 8-bit maskid 图导入,非法/全背景图明确拒绝,尺寸自动适配,高精度 polygon 回显;统一导出默认当前帧,GT_label 使用 uint8 和真实 maskid,待分类 maskid 0 与背景一致。 - 完善分割工作区交互:新增画笔和橡皮擦并支持尺寸控制,移除创建点/线段入口,工具栏按类别分隔,AI 智能分割使用明确 AI 图标,取消黄色 seed point,清空/删除传播 mask 后同步清理空帧时间轴状态。 - 完善传播与时间轴:自动传播使用 SAM 2.1 权重任务,参考帧无遮罩时提示,传播历史按同一蓝色系递进变暗,删除/清空传播链时保留人工或独立 AI 标注来源。 - 完善模板库:新增头颈部 CT 分割默认模板,所有模板保留 maskid 0 待分类,支持鼠标复制模板、拖拽层级、JSON 批量导入预览、删除 label 和站内删除确认。 - 完善用户与高风险确认:用户改密码、删除用户、恢复演示出厂设置和清空人工/AI 标注帧均改为站内确认交互,避免浏览器原生 prompt/confirm。 - 补充前后端测试与文档:更新项目、模板、GT 导入、导出、传播、DICOM、用户管理等测试,并同步 README、AGENTS 和 doc 下实现/契约/测试计划文档。
7.6 KiB
7.6 KiB
当前实现地图
运行入口
前端入口
- React 挂载:
src/main.tsx - 根组件:
src/App.tsx - 前端服务:
server.ts - 默认访问:
http://localhost:3000
server.ts 的角色比较特殊:它既负责在开发模式下创建 Vite middleware,也在生产模式下服务 dist/。当前旧版 /api/login、/api/projects、/api/templates mock 已清理;前端业务 API 走 src/lib/api.ts 指向的 FastAPI。
后端入口
- FastAPI 应用:
backend/main.py - 默认访问:
http://localhost:8000 - API 文档:
http://localhost:8000/docs - 健康检查:
GET /health
后端启动时会通过 lifespan 执行:
- 创建数据库表。
- 检查 MinIO bucket。
- 测试 Redis。
- Seed 默认模板。
- 如果存在
demo_video_path和配置的demo_dicom_dirDICOM 序列,创建默认演示视频项目和演示 DICOM 项目,DICOM 按文件名自然顺序生成帧。
前端模块切换
App.tsx 使用 Zustand 中的 activeModule 做模块切换,没有使用路由库。
| activeModule | 组件 | 页面 |
|---|---|---|
dashboard |
Dashboard |
系统概况 |
projects |
ProjectLibrary |
项目库 |
workspace |
VideoWorkspace |
分割工作区 |
ai |
AISegmentation |
AI 智能分割页 |
templates |
TemplateRegistry |
模板库 |
admin |
UserAdmin |
管理员用户后台,仅 role=admin 可见 |
未登录时,App.tsx 直接渲染 Login。
全局状态
全局状态在 src/store/useStore.ts 中,主要包括:
- 登录状态:
isAuthenticated、token、currentUser - 项目:
projects、currentProject - 工作区:
activeModule、activeTool、frames、currentFrameIndex - 标注与 mask:
annotations、masks - 模板:
templates、activeTemplateId - UI:
isLoading、error
当前状态管理主要是前端内存状态;登录 token 会持久化到 localStorage,刷新后再通过 /api/auth/me 恢复当前用户。
数据流
登录
Login.tsx调用login()。src/lib/api.ts请求POST /api/auth/login。- FastAPI
backend/routers/auth.py查询users表并校验密码哈希。 - 前端把返回 JWT 写入 localStorage,并把用户资料写入 store。
- 后续业务请求带
Authorization: Bearer <token>,后端按当前用户过滤项目资源。 admin/annotator可调用写入类业务接口,viewer只能读取;/api/admin/*仅允许admin。
管理员用户管理
Sidebar.tsx仅对currentUser.role === 'admin'显示“用户管理”。UserAdmin.tsx调用GET/POST/PATCH/DELETE /api/admin/users完成用户新增、停用/启用、角色修改、改密码和删除无项目用户。UserAdmin.tsx调用GET /api/admin/audit-logs展示登录成功/失败以及用户管理操作审计。UserAdmin.tsx危险区“恢复演示出厂设置”需要浏览器确认和输入RESET_DEMO_FACTORY,随后调用POST /api/admin/demo-factory-reset。- 后端
backend/routers/admin.py会阻止管理员删除、停用或降级自己,并阻止删除仍拥有项目的用户;演示出厂重置会清空其它用户、项目帧、标注、任务和私有模板,重新创建演示视频项目和一个已按文件名自然顺序生成帧的演示 DICOM 项目。
项目与拆帧
ProjectLibrary.tsx调用getProjects()获取项目。- 上传视频时先
createProject(),再uploadMedia();导入视频不自动调用parseMedia()。 - 后端
media.py把原始文件上传到 MinIO。 - 用户在项目库点击“生成帧”并选择 FPS 后,
parseMedia()创建processing_tasks记录并投递 Celery worker。 - Celery worker 下载 MinIO 文件,调用
frame_parser.py拆帧。 - worker 把拆出的帧重新上传 MinIO,写入
frames表,并更新任务状态。 - 工作区只通过
GET /api/projects/{id}/frames获取预签名图片 URL;若项目有源视频但无帧,会提示先回项目库生成帧。 - Dashboard 可通过
POST /api/tasks/{id}/cancel取消 queued/running 任务,通过POST /api/tasks/{id}/retry重试 failed/cancelled 任务,并用GET /api/tasks/{id}查看失败详情。
工作区浏览
VideoWorkspace.tsx根据currentProject.id加载帧。CanvasArea.tsx用当前帧 URL 加载底图。FrameTimeline.tsx显示缩略图和当前帧索引。- 播放按钮会推进
currentFrameIndex,从而更新画布底图。
模板管理
TemplateRegistry.tsx调用模板 API。- 后端
templates.py把classes和rules打包进mapping_rulesJSON 字段。 OntologyInspector.tsx读取全局templates和activeTemplateId展示分类树。
后端数据模型
| 模型 | 表 | 用途 |
|---|---|---|
Project |
projects |
项目元数据,包含视频路径、缩略图、状态、fps |
Frame |
frames |
拆帧后的图片记录 |
Template |
templates |
模板、本体类别、颜色、z-index、mapping_rules |
Annotation |
annotations |
标注数据、点、bbox、mask_data |
Mask |
masks |
mask 文件元数据 |
当前主要风险点
- 前端 API/WS 地址虽然已支持环境变量和 hostname 推导,但部署时仍需要确认浏览器可访问
:8000后端。 - AI 当前启用 SAM 2.1 tiny/small/base+/large 点/框/interactive 路径;语义文本提示和 SAM 3 产品入口已禁用,
model=sam3会被后端拒绝。SAM 3 源码保留但不计入当前可用功能。 - 工作区顶部“分割结果导出”和保存状态按钮、左侧工具栏“导入 GT Mask”已接入统一导出、GT 多类别导入、标注新增和 dirty 标注更新;导入 GT Mask 仅支持 8-bit 二值/灰度 maskid 图和 8-bit RGB 三通道完全相同的
[X,X,X]maskid 图,未知 maskid 可由用户选择舍弃或导入为未定义类别,16-bit/uint16 GT_label 和普通彩色类别图会被拒绝,尺寸不同会自动最近邻拉伸到当前帧;GT 连通域会生成高精度 polygon,导入后和普通 mask 一样不显示黄色 seed point,并与普通 mask 共用拓扑统计、边缘平滑、编辑和保存链路。保存状态按钮会按待保存数量显示“保存 X 个改动”或“已全部保存”;统一导出可选择整体视频、特定范围帧或当前图片,并勾选分开 mask、GT_label 黑白图、Pro_label 彩色图和 Mix_label 原图叠加图;特定范围帧导出支持直接输入起止帧,也支持在播放进度条或视频处理进度条上点击/拖拽选择范围;Mix_label 支持默认 0.3 的透明度调节和首帧预览;后端统一导出 ZIP 固定包含 maskid/GT 像素值映射 JSON 与原始图片文件夹,GT_label 固定输出 8-bit uint8 PNG,像素值使用类别真实 maskid,其中maskid:0的“待分类”和背景同为 0,缺失 maskid 的旧标注才补下一个可用正整数,正整数 maskid 超出 1-255 会拒绝导出,并按客户命名规则输出分开 Mask、GT_label、Pro_label 和 Mix_label 文件夹;清空当前帧遮罩会删除对应后端标注。手工绘制、polygon 顶点拖动/删除、区域合并/去除和撤销重做已经落到前端 mask 数据结构。 - Dashboard 初始统计、队列和活动日志来自后端聚合接口;解析队列来自
processing_tasks,worker 进度通过 Redisseg:progress转发到 WebSocket。任务取消、重试和失败详情已接入前后端。 - 后端已接入 Bearer JWT 鉴权、当前用户项目隔离和角色权限;写入类业务接口要求
admin/annotator,管理员用户后台要求admin。当前审计覆盖登录和用户管理操作,全业务级审计仍可继续扩展。