From 72d0e9a168fb55c52cab16929df26517248e1d23 Mon Sep 17 00:00:00 2001 From: admin <572701190@qq.com> Date: Mon, 18 May 2026 19:39:07 +0800 Subject: [PATCH] =?UTF-8?q?2026-05-18-19-37-10=20=E8=B0=83=E6=95=B4?= =?UTF-8?q?=E5=8E=9F=E5=A7=8B=E8=A7=86=E9=A2=91=E4=B8=8E=E7=BB=93=E6=9E=9C?= =?UTF-8?q?=E5=90=8C=E7=BA=A7=E5=88=86=E6=A0=8F?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- frontend/app.js | 8 ++- frontend/index.html | 73 +++++++++++++----------- frontend/styles.css | 51 +++++++++++++---- 工程分析/实现方案-2026-05-18-19-37-10.md | 26 +++++++++ 工程分析/测试方案-2026-05-18-19-37-10.md | 27 +++++++++ 工程分析/经验记录.md | 12 ++++ 工程分析/需求分析-2026-05-18-19-37-10.md | 22 +++++++ 7 files changed, 172 insertions(+), 47 deletions(-) create mode 100644 工程分析/实现方案-2026-05-18-19-37-10.md create mode 100644 工程分析/测试方案-2026-05-18-19-37-10.md create mode 100644 工程分析/需求分析-2026-05-18-19-37-10.md diff --git a/frontend/app.js b/frontend/app.js index 72c12a8..636df0d 100644 --- a/frontend/app.js +++ b/frontend/app.js @@ -28,6 +28,7 @@ const jobMeta = document.querySelector("#jobMeta"); const detailDialog = document.querySelector("#detailDialog"); const closeDialog = document.querySelector("#closeDialog"); const openSourceButton = document.querySelector("#openSourceButton"); +const sourcePaneTitle = document.querySelector("#sourcePaneTitle"); const sourceDialog = document.querySelector("#sourceDialog"); const closeSourceDialog = document.querySelector("#closeSourceDialog"); const sourceTitle = document.querySelector("#sourceTitle"); @@ -78,12 +79,14 @@ function renderPreview(file) { if (file.type.startsWith("video/")) { videoPreview.src = currentObjectUrl; videoPreview.hidden = false; - openSourceButton.textContent = "查看原始视频"; + openSourceButton.textContent = "放大查看"; + sourcePaneTitle.textContent = "查看原始视频"; sourceTitle.textContent = "原始视频"; } else { imagePreview.src = currentObjectUrl; imagePreview.hidden = false; - openSourceButton.textContent = "查看原始图像"; + openSourceButton.textContent = "放大查看"; + sourcePaneTitle.textContent = "查看原始图像"; sourceTitle.textContent = "原始图像"; } jobMeta.textContent = `已选择 ${file.name}`; @@ -229,6 +232,7 @@ function clearAll() { sourceVideo.removeAttribute("src"); sourceImage.removeAttribute("src"); openSourceButton.hidden = true; + sourcePaneTitle.textContent = "查看原始视频"; if (sourceDialog.open) sourceDialog.close(); previewEmpty.hidden = false; resultGrid.innerHTML = ""; diff --git a/frontend/index.html b/frontend/index.html index e7598d2..78a3c41 100644 --- a/frontend/index.html +++ b/frontend/index.html @@ -80,44 +80,51 @@
-
-
-

Live Workspace

-

预览与结果

-
-
- -
等待输入
-
-
+
+
+
+
+

Source Media

+

查看原始视频

+
+
+ +
等待输入
+
+
-
-
选择文件或加载样例后开始
- - -
+
+
选择文件或加载样例后开始
+ + +
+
- +
+
+
+

Live Workspace

+

预览与结果

+
+ 0 个结果 +
- + -
-
-

Result Frames

-

分割帧

-
- 0 个结果 + + +
运行分割后,这里会显示原帧、叠加图、掩膜和指标。
+
+
-
运行分割后,这里会显示原帧、叠加图、掩膜和指标。
-
diff --git a/frontend/styles.css b/frontend/styles.css index b8c407d..0a95d0b 100644 --- a/frontend/styles.css +++ b/frontend/styles.css @@ -62,10 +62,10 @@ button { .top-actions, .section-title, .field-head, -.viewer-head, .results-toolbar, .card-top, -.dialog-head { +.dialog-head, +.pane-head { display: flex; align-items: center; justify-content: space-between; @@ -363,7 +363,23 @@ input[type="range"] { padding: 16px; } -.viewer-head { +.viewer-split { + display: grid; + grid-template-columns: minmax(0, 1fr) minmax(0, 1fr); + gap: 14px; + align-items: start; +} + +.workspace-pane { + min-height: 690px; + padding: 14px; + border: 1px solid var(--line); + border-radius: 8px; + background: rgba(16, 20, 17, 0.58); +} + +.pane-head { + min-height: 48px; margin-bottom: 14px; } @@ -392,7 +408,7 @@ input[type="range"] { .preview-stage { display: grid; place-items: center; - min-height: 320px; + min-height: 590px; border: 1px solid var(--line); border-radius: 8px; background: @@ -414,7 +430,7 @@ input[type="range"] { #imagePreview { display: block; width: 100%; - max-height: 520px; + max-height: 590px; object-fit: contain; background: #050605; } @@ -459,7 +475,7 @@ input[type="range"] { .summary-strip { display: grid; - grid-template-columns: repeat(4, 1fr); + grid-template-columns: repeat(2, 1fr); gap: 1px; margin-top: 14px; overflow: hidden; @@ -486,12 +502,8 @@ input[type="range"] { font-size: 18px; } -.results-toolbar { - margin: 18px 0 12px; -} - .empty { - min-height: 180px; + min-height: 590px; display: grid; place-items: center; border: 1px solid var(--line); @@ -501,8 +513,10 @@ input[type="range"] { .result-grid { display: grid; - grid-template-columns: repeat(auto-fit, minmax(260px, 1fr)); + grid-template-columns: repeat(auto-fit, minmax(210px, 1fr)); gap: 12px; + max-height: 590px; + overflow: auto; } .result-card { @@ -668,4 +682,17 @@ dd { .detail-images { grid-template-columns: 1fr; } + + .viewer-split { + grid-template-columns: 1fr; + } + + .workspace-pane { + min-height: auto; + } + + .preview-stage, + .empty { + min-height: 320px; + } } diff --git a/工程分析/实现方案-2026-05-18-19-37-10.md b/工程分析/实现方案-2026-05-18-19-37-10.md new file mode 100644 index 0000000..f4cb582 --- /dev/null +++ b/工程分析/实现方案-2026-05-18-19-37-10.md @@ -0,0 +1,26 @@ +# 实现方案 + +开始时间:2026-05-18-19-37-10 + +## 修改内容 + +1. `frontend/index.html` + - 将 `viewer` 内部改为 `viewer-split`。 + - 左侧新增 `workspace-pane source-pane`,标题为“查看原始视频”。 + - 右侧新增 `workspace-pane result-pane`,标题为“预览与结果”。 + - 原始媒体预览控件移动到左侧面板。 + - 进度、摘要、结果帧移动到右侧面板。 + +2. `frontend/app.js` + - 增加 `sourcePaneTitle` 引用。 + - 根据加载文件类型切换左侧标题为“查看原始视频”或“查看原始图像”。 + - 原始媒体弹窗按钮改为“放大查看”。 + +3. `frontend/styles.css` + - 增加左右分栏布局。 + - 给左右面板独立边框、标题栏、内容高度。 + - 移动端改为单列上下堆叠。 + +## 设计说明 + +这个结构把“输入核对”和“算法输出”分开,符合医学影像工作台的使用习惯:先确认原始输入,再查看分割结果。 diff --git a/工程分析/测试方案-2026-05-18-19-37-10.md b/工程分析/测试方案-2026-05-18-19-37-10.md new file mode 100644 index 0000000..2c16012 --- /dev/null +++ b/工程分析/测试方案-2026-05-18-19-37-10.md @@ -0,0 +1,27 @@ +# 测试方案 + +开始时间:2026-05-18-19-37-10 + +## 自动化验证 + +- `pytest -q` +- `curl -s http://127.0.0.1:8001/api/health` +- `curl -s http://127.0.0.1:8001/api/samples` +- `git diff --check` +- Chrome headless 截图首页检查布局。 + +## 手工验证 + +1. 打开 `http://192.168.3.11:8001/`。 +2. 右侧应显示左右两个同级面板:左侧“查看原始视频”,右侧“预览与结果”。 +3. 点击“加载样例”,左侧显示原始视频播放器。 +4. 点击“运行分割”,右侧显示分割结果。 +5. 点击左侧“放大查看”,打开原始视频大弹窗。 + +## 执行结果 + +- `pytest -q`:通过,4 个测试全部通过。 +- `curl -s http://127.0.0.1:8001/api/health`:通过,返回 `status=ok`。 +- `curl -s http://127.0.0.1:8001/api/samples`:通过,样例视频和样例图像仍可获取。 +- `git diff --check`:通过,无空白格式错误。 +- Chrome headless 首页截图:通过,右侧工作区已拆成同级左右两栏,左侧为“查看原始视频”,右侧为“预览与结果”。 diff --git a/工程分析/经验记录.md b/工程分析/经验记录.md index 0a3f425..b247582 100644 --- a/工程分析/经验记录.md +++ b/工程分析/经验记录.md @@ -81,3 +81,15 @@ B. 产生问题原因:页面虽然已有内嵌预览区域,但缺少显式 C. 解决问题方案:在“预览与结果”标题区新增按文件类型切换文案的按钮;加载视频时显示“查看原始视频”,加载图像时显示“查看原始图像”;点击后打开原始媒体弹窗。 D. 后续如何避免问题:输入数据、处理中结果、最终结果应分别提供清晰入口,尤其是医学影像类工具需要让用户随时核对原始输入。 + +## 2026-05-18-19-37-10 原始视频与结果同级分栏 + +### 1. 原始媒体入口层级不符合用户预期 + +A. 具体问题:用户希望“查看原始视频”和“预览与结果”是同一级,而不是把原始视频查看作为“预览与结果”标题区里的按钮。 + +B. 产生问题原因:上一版将原始媒体查看入口作为辅助操作放在结果区标题右侧,信息架构上仍然偏向“结果主导”,不符合用户希望的左右对照工作流。 + +C. 解决问题方案:将右侧工作区拆成左右两个 `workspace-pane`:左侧固定展示原始视频/图像,右侧展示分割进度、摘要和结果帧;保留“放大查看”作为左侧面板内的辅助操作。 + +D. 后续如何避免问题:医学影像交互页面应优先考虑“原始输入”和“算法输出”并列对照,而不是把原始输入藏在结果区域的附属操作中。 diff --git a/工程分析/需求分析-2026-05-18-19-37-10.md b/工程分析/需求分析-2026-05-18-19-37-10.md new file mode 100644 index 0000000..bd8fe8b --- /dev/null +++ b/工程分析/需求分析-2026-05-18-19-37-10.md @@ -0,0 +1,22 @@ +# 需求分析 + +开始时间:2026-05-18-19-37-10 + +## 用户目标 + +用户希望“查看原始视频”和“预览与结果”成为同级区域,而不是“预览与结果”中的一个按钮。右侧工作区需要横向分为两半:左侧查看原始视频/图像,右侧展示预览与分割结果。 + +## 本轮目标 + +- 将右侧工作区拆成左右两个同级面板。 +- 左侧面板标题为“查看原始视频/图像”,负责原始输入预览。 +- 右侧面板标题为“预览与结果”,负责分割进度、统计摘要和结果帧。 +- 保留原始媒体大弹窗能力,入口放在左侧面板标题区。 +- 保持移动端自动上下堆叠。 + +## 验收标准 + +- 初始页面右侧区域左右分栏明确。 +- 加载样例后左侧显示原始视频播放器。 +- 分割后右侧显示结果摘要和结果帧。 +- 清空后左侧恢复未加载状态,右侧恢复未运行状态。