Files
xuetang/app/research/diagnosis_python_visual_gap.md
T
2026-09-08 11:40:15 +08:00

548 lines
43 KiB
Markdown
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
# Python 医生工作站诊单视觉 / 交互差异审计
> 审计日期:2026-08-10
> 结论:**OPEN — 当前实现不具备与管理端诊单主链做截图级验收的条件。** 主要差异不是局部颜色或间距,而是索引页层级、表格固定列、只读/编辑形态和预约选择器的组件架构不同。
> 约束:本轮只读检查业务源码;只新增本审计文档,未修改 Python、Vue、接口、payload、权限、状态门槛或业务流程。
> 环境说明:项目提示的 `D:/web/zyt/app/.trellis/` 当前不存在,因此没有可补读的 Trellis 工作流或包级规格。
## 1. 范围与事实源
当前 Python 审计范围:
- `D:/web/zyt/app/src/doctor_workstation/ui/theme.py`
- `D:/web/zyt/app/src/doctor_workstation/ui/widgets.py`
- `D:/web/zyt/app/src/doctor_workstation/ui/shell.py`
- `D:/web/zyt/app/src/doctor_workstation/ui/pages/consultations.py`
- `D:/web/zyt/app/src/doctor_workstation/ui/dialogs/diagnosis.py`
- `D:/web/zyt/app/src/doctor_workstation/ui/pages/patients.py``_AppointmentDialog` 及其入口
管理端唯一视觉事实源:
- `D:/web/zyt/admin/src/views/tcm/diagnosis/index.vue`
- `D:/web/zyt/admin/src/views/tcm/diagnosis/edit.vue`
- `D:/web/zyt/admin/src/views/tcm/diagnosis/readonly.vue`
- `D:/web/zyt/admin/src/views/tcm/diagnosis/appointment.vue`
- 上述页面直接渲染的 diagnosis components、`NoteTimeline.vue` 以及直接生效的全局样式
研究基线:
- `D:/web/zyt/app/research/diagnosis_index_visual_spec.md:1-373`
- `D:/web/zyt/app/research/diagnosis_detail_visual_spec.md:1-565`
明确排除:其他角色页面、小程序、企微运营、二维码、视频观看弹窗、未被三主视图引用的旧 Blood/Diet/Exercise/Tracking 组件,以及任何业务接口改造。本报告提到权限时,只描述入口或 Tab 的可见状态,不重新设计权限规则。
## 2. 总体判定
| 领域 | 当前状态 | 阻断截图复刻的根因 |
|---|---|---|
| 全局主题与密度 | OPEN | Qt 是暖灰绿、13 px、36 px 控件;管理端诊单基线是冷灰白、14 px、32 px 控件,索引主色为 `#4A5DFF` |
| 诊单索引 | OPEN | 多出页面标题;筛选永久四行;单表无右固定列;行操作、复合单元格、分页、空态和 loading 架构不同 |
| 诊单只读 / 编辑 | OPEN | 独立 readonly 与 drawer viewOnly 被合并成同一个居中 `QDialog`;Tabs、字段布局和内容主链大量不等价 |
| 预约 | OPEN | 60% 右 Drawer 被固定 540×560 Dialog 取代;医生、日期、时段网格全部降级为 ComboBox |
| 1024×640 | OPEN | 880×680 诊单 Dialog 请求高度超过外窗;索引页无页面级滚动且高级筛选常驻,表格可见高度过低 |
| 1440×900 | OPEN | 索引仍缺固定 460 px 右区;详情/预约保持固定宽度,无法随视口保持 60% 比例 |
必须先完成四项结构改造,再做颜色和像素微调:
1. 诊单索引改回“无页面标题 + 两张平卡 + 折叠筛选”。
2. 诊单表使用专用 model/delegate,并实现右侧 `120 + 340 = 460 px` 固定区域。
3. 将独立 readonly 页面与 edit/viewOnly Drawer 拆成两个视觉形态。
4. 将预约恢复为右侧 Drawer,并恢复医生 radio、日期按钮、时段卡片网格及完整状态。
## 3. 基础 token 与壳层差异
### G-01 [阻断] 字体、颜色、控件与圆角是另一套设计系统
管理端诊单索引基线为 `PingFang SC, Arial, Hiragino Sans GB, Microsoft YaHei`、基础 14 px、页面 `#F6F6F6`、卡片 `#FFFFFF`、主/常规/次要文字 `#333/#666/#999`、默认控件 32 px、small 24 px、索引主色 `#4A5DFF`、卡片 r4。证据:
- `D:/web/zyt/admin/src/config/setting.ts:1-14`
- `D:/web/zyt/admin/src/styles/var.css:1-43`
- `D:/web/zyt/app/research/diagnosis_index_visual_spec.md:65-101`
当前 Qt 为 Microsoft YaHei UI 优先、基础 13 px、画布/表面 `#F4F3EF/#FCFBF8`、墨绿/青绿 `#17382F/#168579`、按钮和输入最小 36 px/r9、卡片 r16。状态色也全部偏成低饱和绿褐色。证据:
- `D:/web/zyt/app/src/doctor_workstation/ui/theme.py:13-33`
- `D:/web/zyt/app/src/doctor_workstation/ui/theme.py:36-84`
- `D:/web/zyt/app/src/doctor_workstation/ui/theme.py:87-175`
- `D:/web/zyt/app/src/doctor_workstation/ui/theme.py:233-250`
可见后果:同一页面的字宽、首屏密度、按钮高度、卡片轮廓、语义色和表格行数均不同;仅替换主色不能修复。
建议边界:在 `D:/web/zyt/app/src/doctor_workstation/ui/theme.py:13-275` 增加以 `#DiagnosisIndex``#DiagnosisDrawer``#DiagnosisReadonly``#AppointmentDrawer` 为根的局部 token/QSS。除非另立全工作站换肤任务,不应直接改写共享 `Card``QPushButton``QTableWidget` 的全局规则。
### G-02 [高] 壳层占宽与页面滚动模型不同
当前 Shell 最小 1024×640,侧栏固定 216 px、顶栏固定 68 pxworkspace 的 `QStackedWidget` 本身没有页面滚动容器:
- `D:/web/zyt/app/src/doctor_workstation/ui/shell.py:306-325`
- `D:/web/zyt/app/src/doctor_workstation/ui/shell.py:329-423`
管理端默认侧栏宽 183 px,navbar 50 px,默认还可显示 40 px multiple tabs;路由内容由 `el-scrollbar` 承担整页纵向滚动,页面外留白为 8 px 水平 / 16 px 垂直:
- `D:/web/zyt/admin/src/config/setting.ts:1-6`
- `D:/web/zyt/admin/src/styles/var.css:4-10`
- `D:/web/zyt/admin/src/layout/default/components/header/multiple-tabs.vue:65`
- `D:/web/zyt/admin/src/layout/default/components/main.vue:2-11`
当前诊单页又额外使用 24 px 水平边距,因此两档窗口下的静态内容宽约为:
| 外窗 | 当前 workspace | 当前页面内容宽 | 管理端默认路由内容宽(约) | 差值 |
|---|---:|---:|---:|---:|
| 1024×640 | 808 | 760 | 824 | -64 px |
| 1440×900 | 1224 | 1176 | 1240 | -64 px |
建议边界:索引页自行增加页面级滚动及 8/16 外留白;不要为了修诊单页直接改变全工作站 216/68 壳。若最终验收要求连管理端壳一起复刻,应另行冻结侧栏、navbar、multiple tabs 的 setting 后再改 `ShellWindow`
### G-03 [高] hover、checked、focus、read-only 状态不完整
- 日期和业务入口都是 checkable ghost `QPushButton`,但 QSS 没有 `QPushButton[variant="ghost"]:checked`;active 态没有确定的可见反馈。当前:`D:/web/zyt/app/src/doctor_workstation/ui/theme.py:87-118``D:/web/zyt/app/src/doctor_workstation/ui/pages/consultations.py:495-528,776-799`;基准:`D:/web/zyt/admin/src/views/tcm/diagnosis/index.vue:2227-2308`
- Qt 输入 focus 直接把 1 px 边改为 2 px 青绿实线,存在内部尺寸跳动;管理端是 primary-light 的 2 px 外环。当前:`D:/web/zyt/app/src/doctor_workstation/ui/theme.py:140-154`;基准:`D:/web/zyt/admin/src/styles/element.scss:140-175`
- 按钮、Tab、radio、checkbox 没有统一的键盘 focus ring;表格还显式 `outline:0`。当前:`D:/web/zyt/app/src/doctor_workstation/ui/theme.py:87-138,164-186,208-220`
- read-only `QPlainTextEdit` 没有独立 QSS,仍呈白底可编辑外观;只定义了部分 `:disabled`。当前:`D:/web/zyt/app/src/doctor_workstation/ui/theme.py:140-155``D:/web/zyt/app/src/doctor_workstation/ui/dialogs/diagnosis.py:685-689`
- 表格没有显式 item hover 规则;管理端普通 hover 是 `#F8F8F8`,业务行还有语义渐变。当前:`D:/web/zyt/app/src/doctor_workstation/ui/theme.py:177-197`;基准:`D:/web/zyt/admin/src/views/tcm/diagnosis/index.vue:2723-2735`
建议边界:为诊单专用 chip、输入、Tab、表格 delegate 增加状态规则;保留键盘可达性,不必复刻 HTML `span` 不可聚焦的缺陷。focus 不应通过改变边框占位宽度实现。
### G-04 [中] 共享组件的视觉契约与诊单基线不同
- `PageHeader` 固定生成标题/副标题层级:`D:/web/zyt/app/src/doctor_workstation/ui/widgets.py:331-365`
- `EmptyState` 是 30 px 圆圈 + 16 px 标题 + 说明 + 44 px 垂直留白:`D:/web/zyt/app/src/doctor_workstation/ui/widgets.py:388-420`
- `BusyOverlay` 是文字 + 140 px 横向 progress,非 42 px 环形 spinner`D:/web/zyt/app/src/doctor_workstation/ui/widgets.py:489-514``D:/web/zyt/app/src/doctor_workstation/ui/theme.py:230-231,271`
- `SortableTable` 是单选、全列本地排序、纯文本 item、末列 stretch`D:/web/zyt/app/src/doctor_workstation/ui/widgets.py:535-575`
- `Pager` 只有 total、上一页、页码分数、下一页:`D:/web/zyt/app/src/doctor_workstation/ui/widgets.py:585-627`
建议边界:新增诊单专用组件,不要破坏性修改这些被患者、订单、接诊页共享的类。
## 4. 诊单索引页差异
### I-01 [阻断] 页面层级、留白和卡片形态错误
管理端页面内没有标题或说明;路由内容直接从无边框、无阴影、r4 的筛选白卡开始,第二张列表卡相距 12 px。新增诊单在列表卡工具栏:
- `D:/web/zyt/admin/src/views/tcm/diagnosis/index.vue:2-177`
- `D:/web/zyt/admin/src/views/tcm/diagnosis/index.vue:2200-2211,2408-2434`
当前页面先放 25 px `PageHeader("问诊列表", …)`,并把新增按钮放在标题右侧;外边距 24/20/24、间距 14。两张卡是有边框的暖白 r16,表格自身再加 r12,形成“卡中卡”:
- `D:/web/zyt/app/src/doctor_workstation/ui/pages/consultations.py:464-587`
- `D:/web/zyt/app/src/doctor_workstation/ui/pages/consultations.py:590-674`
- `D:/web/zyt/app/src/doctor_workstation/ui/theme.py:54-84,177-197`
建议边界:只在 `ConsultationsPage.__init__` 移除页面内 `PageHeader`,将 add 入口移入列表工具栏;保留 Shell topbar。诊单两卡使用局部 objectName/QSS。
### I-02 [阻断] 日期 / 业务 chip 顺序、文案、换行和语义态不同
管理端顺序严格是“昨天挂号、前天挂号、当天挂号、明天挂号、后天挂号、全部”,随后是待预约/已完成/待分配医助;左侧 chips 可换行,计数是同行半透明文字。三种业务 chip 分别用 info/success/warning
- `D:/web/zyt/admin/src/views/tcm/diagnosis/index.vue:6-70`
- `D:/web/zyt/admin/src/views/tcm/diagnosis/index.vue:964-970`
- `D:/web/zyt/admin/src/views/tcm/diagnosis/index.vue:2222-2317`
当前顺序是“前天、昨天、今天、明天、后天、全部”,缺“挂号”文案;九个按钮放在不可换行的 `QHBoxLayout`,全部是通用 ghost,无业务色和明确 checked 态:
- `D:/web/zyt/app/src/doctor_workstation/ui/pages/consultations.py:483-530`
- `D:/web/zyt/app/src/doctor_workstation/ui/pages/consultations.py:776-799`
在 1024 档,按钮加入两三位计数后可能在约 760 px 内容宽内被挤压或裁字。
建议边界:增加诊单局部 `FlowLayout` 和带 dynamic property 的 chip;沿用现有 `_choose_*``_update_quick_buttons()`,只换视图装配和文案。
### I-03 [阻断] 筛选的两层结构被永久四行网格取代
管理端:第一行右侧是固定 160 px 搜索 + 32 px primary 查询;第二行是“挂号/确认”小 chips 和“更多筛选”;高级区默认隐藏,点击后即时显隐,使用虚线上边界和可换行布局:
- `D:/web/zyt/admin/src/views/tcm/diagnosis/index.vue:72-151`
- `D:/web/zyt/admin/src/views/tcm/diagnosis/index.vue:2320-2405`
当前:关键词、挂号、确认和所有高级条件永久铺成四行等宽 `QGridLayout`;查询/重置在最后一行。挂号/确认变成 ComboBox;最近日期范围被拆成四个独立 `QDateEdit`;还常驻一个管理端通过表头表达的“未服务排序”下拉:
- `D:/web/zyt/app/src/doctor_workstation/ui/pages/consultations.py:532-586`
- `D:/web/zyt/app/src/doctor_workstation/ui/pages/consultations.py:683-721`
当前还缺待分配模式选中后显示的月份 128 px 和宽搜索 220 px / max 42vw;管理端证据为 `D:/web/zyt/admin/src/views/tcm/diagnosis/index.vue:40-70,2298-2317`
建议边界:重建筛选视图,但保留 `_search()``_filters()`、日期校验和现有请求字段。是否补待分配月份/宽搜索涉及现有请求参数,超出本视觉报告授权;在业务层确认前先预留容器,不自行发明接口字段。
### I-04 [阻断] 列表工具栏与选择模型不等价
管理端列表栏无“诊单记录”标题;左侧是新增、批量指派、批量取消指派,右侧按需显示“已选 n 条”。表格首列为 48 px checkbox 多选:
- `D:/web/zyt/admin/src/views/tcm/diagnosis/index.vue:154-191`
- `D:/web/zyt/admin/src/views/tcm/diagnosis/index.vue:2414-2429`
当前工具栏是标题 + 总数摘要 + 查看/诊单/开方/作废/视频/删除/刷新等全局按钮;表格无 checkbox,使用整行单选,加载后自动选第一行并出现青绿选择底:
- `D:/web/zyt/app/src/doctor_workstation/ui/pages/consultations.py:590-640`
- `D:/web/zyt/app/src/doctor_workstation/ui/pages/consultations.py:938-946`
- `D:/web/zyt/app/src/doctor_workstation/ui/pages/consultations.py:1085-1112`
- `D:/web/zyt/app/src/doctor_workstation/ui/widgets.py:541-549`
建议边界:视图层改为 checkbox check-state;不要用整行 selection 代替多选。批量动作若当前业务方法不存在,本轮只应建立视觉容器和禁用态,不得伪造 mutation。
### I-05 [阻断] 表格列、固定区、排序和行操作架构不同
管理端列顺序与宽度为:选择 48、ID min70、患者 min60、性别年龄 100、挂号 min175、确认 88、复诊 min120、助理 100、开方 72、未服务 110、视频旁观 120 fixed、操作 340 fixed。声明最小总宽约 1403 px,右固定区共 460 px
- `D:/web/zyt/admin/src/views/tcm/diagnosis/index.vue:191-406`
- `D:/web/zyt/app/research/diagnosis_index_visual_spec.md:169-186`
当前列约 1392 px,但无选择/操作列,额外有医生 90、作废 74;挂号 300、未服务 180、视频 90。所有列随单一 `QTableWidget` 一起滚动,末列还会 stretch:
- `D:/web/zyt/app/src/doctor_workstation/ui/pages/consultations.py:646-663`
- `D:/web/zyt/app/src/doctor_workstation/ui/widgets.py:535-552`
管理端只允许“未服务天数”走 descending → ascending 的自定义排序;当前全部表头都可做客户端排序,并另设排序 ComboBox:
- 基准:`D:/web/zyt/admin/src/views/tcm/diagnosis/index.vue:297-304`
- 当前:`D:/web/zyt/app/src/doctor_workstation/ui/widgets.py:543-549``D:/web/zyt/app/src/doctor_workstation/ui/pages/consultations.py:560-570`
管理端每行右侧有查看、诊单、开方/查看处方、预约、补全身份证和“更多”菜单;当前把少量动作集中在列表栏,行内没有动作命中区:
- 基准:`D:/web/zyt/admin/src/views/tcm/diagnosis/index.vue:342-403`
- 当前:`D:/web/zyt/app/src/doctor_workstation/ui/pages/consultations.py:605-639`
建议边界:新增 `DiagnosisTableModel`、专用 delegates 和同步的双 `QTableView`;右表只显示 120/340 两列,共享 model、selection、垂直滚动与 row height。不要把固定列能力硬塞进通用 `SortableTable`
### I-06 [阻断] 复合单元格、语义色、hover 和密度全部降级为纯文本
当前 `SortableTable.set_rows()` 只创建 `QTableWidgetItem(text)`;格式化函数也只拼接字符串:
- `D:/web/zyt/app/src/doctor_workstation/ui/widgets.py:554-575`
- `D:/web/zyt/app/src/doctor_workstation/ui/pages/consultations.py:233-322`
由此缺失:
- ID/患者 14 px/600`NEW` 20 px danger tag。
- 挂号块的 11 px badge、14 px/600 医生、12 px 时间、状态渐变、多预约虚线、取消挂号链接和最近渠道。
- 已确认/未确认、已开方/未开方、处方作废 tag。
- 未服务 null/`<=2`/`36`/`>=7` 的灰/绿/橙/红,以及健康打卡 tooltip。
- 普通白/#FAFAFA 斑马、#F8F8F8 hover、未确认/未挂号的 3 px 左条和渐变。
- 行级视频入口和 340 px 动作链接区。
管理端证据:
- `D:/web/zyt/admin/src/views/tcm/diagnosis/index.vue:193-406`
- `D:/web/zyt/admin/src/views/tcm/diagnosis/index.vue:2442-2735`
当前表格头是 12 px/700、`#EEF1EE`alternate 为暖灰 `#F6F7F4`;基准表头为 13 px/600、`#F8F8F8`,普通预约行约 52 px。当前只调用 `resizeRowsToContents()`,无 39/52 px 基线:
- 当前:`D:/web/zyt/app/src/doctor_workstation/ui/theme.py:177-197``D:/web/zyt/app/src/doctor_workstation/ui/pages/consultations.py:938-940`
- 基准:`D:/web/zyt/app/research/diagnosis_index_visual_spec.md:163-212`
建议边界:复合绘制与 `sizeHint()` 均放在诊单 delegates;不要给每格常驻 QWidget。行样本必须覆盖多预约和动作换行,且双表 row height 同步。
### I-07 [高] 分页、空态、loading、error 的布局契约不同
分页基线为 total、15/20/30/40 size、prev、最多 5 个数字页、next、jumper,按钮 32 px;当前只有 total、上一页、`1/N`、下一页,按钮最小 36 px
- 基准:`D:/web/zyt/app/research/diagnosis_index_visual_spec.md:254-262`
- 当前:`D:/web/zyt/app/src/doctor_workstation/ui/widgets.py:585-627`
空态基线保留表头和分页,仅在 table body 显示约 60 px 高的“暂无数据”。当前切换整个 `content_stack` 到大型 `EmptyState`,表头与分页同时消失:
- 基准:`D:/web/zyt/app/research/diagnosis_index_visual_spec.md:264-273`
- 当前:`D:/web/zyt/app/src/doctor_workstation/ui/pages/consultations.py:642-673``D:/web/zyt/app/src/doctor_workstation/ui/widgets.py:388-420`
loading 基线只覆盖表格,亮色 `rgba(255,255,255,.5)` + 42 px 主色环;20 秒静默刷新不闪。当前普通加载在两卡之间插入 MessageBanner,并禁用刷新,没有 table overlay;共享 `BusyOverlay` 的形态也不匹配:
- 基准:`D:/web/zyt/app/research/diagnosis_index_visual_spec.md:275-280`
- 当前:`D:/web/zyt/app/src/doctor_workstation/ui/pages/consultations.py:901-956``D:/web/zyt/app/src/doctor_workstation/ui/widgets.py:489-514`
错误当前只显示全宽 Banner,原表/旧数据仍在;管理端主表没有独立 error 插画。建议保留错误消息但不得让 Banner 插入造成卡片整体跳位。
建议边界:新增诊单专用 PaginationBar、table viewport empty label 和 table-only overlay;保持现有 generation、silent refresh 与错误传递逻辑不变。
### I-08 [高] 页面纵向滚动与少量数据高度不同
管理端表格没有本页固定高度;15 行自然撑高并由路由 `el-scrollbar` 滚整页。当前列表卡以 stretch=1 填满余高,表格内部滚动;一行数据时会留下大块空白,15 行时筛选和工具栏固定在窗口而不是随页面滚动:
- 基准:`D:/web/zyt/admin/src/layout/default/components/main.vue:2-11``D:/web/zyt/admin/src/views/tcm/diagnosis/index.vue:179-190`
- 当前:`D:/web/zyt/app/src/doctor_workstation/ui/pages/consultations.py:642-674`
建议边界:诊单页使用单一 `QScrollArea` 承载两卡,表格按 header + 实际 rows + pagination 给自然高度;不要改其他页面的内部表滚动策略。
## 5. 诊单只读 / 编辑差异
### D-01 [阻断] 两种只读形态被合并为一个居中 Dialog
管理端有两个不可互换的只读形态:
1. `readonly.vue`:独立单列页面,无 Tabs,Hero 后按顺序纵向展示摘要、病例、日常记录、备注、订单、视频、聊天、指派、挂号。
2. `edit.vue``viewOnly`:仍是 60% 右 Drawer + Tabs + disabled 表单,只隐藏保存。
证据:
- `D:/web/zyt/admin/src/views/tcm/diagnosis/readonly.vue:1-149`
- `D:/web/zyt/admin/src/views/tcm/diagnosis/edit.vue:1-84,766-781`
- `D:/web/zyt/app/research/diagnosis_detail_visual_spec.md:75-152,156-194`
当前所有查看/编辑都调用同一个 `DiagnosisDialog.open_for()`;只通过 `setReadOnly` 和保存按钮显隐切模式:
- `D:/web/zyt/app/src/doctor_workstation/ui/dialogs/diagnosis.py:245-288`
- `D:/web/zyt/app/src/doctor_workstation/ui/dialogs/diagnosis.py:426-464`
- `D:/web/zyt/app/src/doctor_workstation/ui/pages/consultations.py:1113-1129`
- `D:/web/zyt/app/src/doctor_workstation/ui/pages/patients.py:2142-2151`
建议边界:保留 `open_for()`、saved signal、现有 load bundle 和数据快照;仅拆视图为 `DiagnosisReadonlyView``DiagnosisDrawerView`,由入口决定呈现形态。不得通过给现有 QDialog 换皮来声称两种基线都已覆盖。
### D-02 [阻断] Drawer 几何与 Header/Body/Footer 三段壳缺失
编辑/viewOnly 基线为 RTL 右 Drawer、宽视口 60%、全高;header 为白到 `#F8FAFC` 渐变和底线,body `#F8FAFC`,footer 独立白底、上边线,按钮右对齐、40 px/r10:
- `D:/web/zyt/admin/src/views/tcm/diagnosis/edit.vue:3-10`
- `D:/web/zyt/admin/src/views/tcm/diagnosis/edit.vue:1670-1745`
- `D:/web/zyt/admin/src/views/tcm/diagnosis/edit.vue:1776-1864`
当前是居中系统 `QDialog`,请求 880×680、最小 680×520,统一暖灰画布,四周 20/18;标题 25 px。按钮栏虽在 Tabs 外,能保持不随首 Tab 滚动,但没有 footer frame、边线和确定按钮顺序:
- `D:/web/zyt/app/src/doctor_workstation/ui/dialogs/diagnosis.py:245-288`
- `D:/web/zyt/app/src/doctor_workstation/ui/theme.py:44-46,54-58,87-104`
当前 mode 文案/颜色也不同:后台只读 info、编辑 warning、新建 success;当前只读 neutral、可编辑 success,且标题是“患者信息详情/编辑患者病历”:`D:/web/zyt/app/src/doctor_workstation/ui/dialogs/diagnosis.py:256-266,441-447`
建议边界:在主窗之上实现遮罩 + 右贴边 panel,按外窗宽度计算 60%;只让 body 滚动,header/footer 固定。保留 QDialog 作为临时承载会继续出现系统标题栏和居中几何差异。
### D-03 [阻断] Tabs 样式、顺序、权限可见性和内容主链不等价
管理端顺序:病历、医生备注、日常记录、处方、业务订单、视频录制回放、聊天、指派、挂号;“跟踪备注”已注释,不渲染。Tabs 为可横滚文本导航,4 px scrollbaractive 3 px 底条:
- `D:/web/zyt/admin/src/views/tcm/diagnosis/edit.vue:55-759`
- `D:/web/zyt/admin/src/views/tcm/diagnosis/edit.vue:1798-1858`
当前只有患者与病历、医生备注、挂号记录、指派记录、可选患者订单;挂号先于指派,日常记录/待办、处方、视频、聊天均缺失。除订单外,Tab 没按对应权限移除:
- `D:/web/zyt/app/src/doctor_workstation/ui/dialogs/diagnosis.py:271-279`
- `D:/web/zyt/app/src/doctor_workstation/ui/dialogs/diagnosis.py:479-525`
当前全局 Tab 是青绿填充 pill、r9、36 px,无 3 px active indicator`D:/web/zyt/app/src/doctor_workstation/ui/theme.py:208-220`
建议边界:用诊单局部 `QTabBar + QStackedWidget` 或可横滚 TabBar;按既有 canonical permissions 移除入口,当前 Tab 失权时回病历。不要加入已注释 TrackingNote,也不要重复增加旧 Blood/Diet/Exercise Tabs。
### D-04 [阻断] 编辑表单被统一成单列大文本框,字段顺序也偏离真实模板
当前 `_DIAGNOSIS_FIELDS` 将全部字段装成单列 `QFormLayout + QPlainTextEdit`,每项 4682 px;没有 160 px label、栅格、分组标题或语义控件:
- `D:/web/zyt/app/src/doctor_workstation/ui/dialogs/diagnosis.py:49-102`
- `D:/web/zyt/app/src/doctor_workstation/ui/dialogs/diagnosis.py:331-346`
管理端是 12 px 表单、160 px label、32 px input/select/date/number、radio/check-button、24/12/8 栅格、18 px 项间距,以及横线夹胶囊的分组标题:
- `D:/web/zyt/admin/src/views/tcm/diagnosis/edit.vue:57-632`
- `D:/web/zyt/admin/src/views/tcm/diagnosis/edit.vue:1476-1667`
当前与后台真实模板的具体偏差:
- 缺少/不等价:诊单ID表单行、状态、渠道、统计端就诊卡、当地诊断日期、糖尿病病史、口腔感觉、其他补充、病史补充。
- “当前用药”被放在末尾;后台“在用药物”位于生命体征区。
- 当前显示后台模板未渲染的证型、糖尿病类型、自由文本主诉/现病史/症状、食欲、舌象、舌苔、脉象、临床诊断、治则、处方、处方意见、医嘱。
- 类别项都变成自由文本,失去 radio/check/select 的密度和状态。
真实后台字段次序见 `D:/web/zyt/app/research/diagnosis_detail_visual_spec.md:221-255`
患者基本信息锁定时,当前只设 read-only,没有后台 warning Alert
- 当前:`D:/web/zyt/app/src/doctor_workstation/ui/dialogs/diagnosis.py:659-689`
- 基准:`D:/web/zyt/admin/src/views/tcm/diagnosis/edit.vue:71-84`
建议边界:只重建 `DiagnosisDialog` 的表单装配和 scoped QSS,保留字段值转换、校验、保存入口及隐私遮罩。严格按后台实际渲染字段,不把脚本模型中但模板未显示的字段继续呈现。
### D-05 [阻断] 独立 readonly 的 Hero、卡片流和病例网格完全缺失
readonly 基线:16 px 页面边距/卡间距;可换行浅蓝 Hero 带返回、患者名、性别年龄、未服务绿橙红 badge;白卡 r14、18 px padding、标题前 3×16 蓝条;患者摘要按确定顺序,病例按 4/3 列分组键值展示:
- `D:/web/zyt/admin/src/views/tcm/diagnosis/readonly.vue:1-149`
- `D:/web/zyt/admin/src/views/tcm/diagnosis/readonly.vue:257-405`
- `D:/web/zyt/app/research/diagnosis_detail_visual_spec.md:75-152`
当前没有返回、Hero、未服务 badge 或纵向卡片流。摘要是两列九项,额外含身份证/血压/血糖,却缺地区、预约状态、是否开方和备注;病例仍是单列可编辑形态:
- `D:/web/zyt/app/src/doctor_workstation/ui/dialogs/diagnosis.py:290-349`
- `D:/web/zyt/app/src/doctor_workstation/ui/dialogs/diagnosis.py:574-700`
建议边界:单独实现只读卡片 view;不要把 disabled 编辑表单当作独立 readonly。1440 档保留后台 4/3 列;1024 档若主动降列,应在验收中标注为桌面可用性增强,而不是声称 Vue 原实现已有响应式。
### D-06 [高] 备注、订单、历史表和关联内容被降级或缺失
- 医生备注:后台是时间轴、64×64 缩略图、文件 chip、编辑动作;当前仅三列“时间/医生/内容”。基准 `D:/web/zyt/admin/src/views/patient/reception/components/NoteTimeline.vue:1-436`;当前 `D:/web/zyt/app/src/doctor_workstation/ui/dialogs/diagnosis.py:351-364`
- 日常记录/待办:后台有日期筛选、矩阵、趋势、toolbar 和待办;当前整个 Tab 缺失。基准 `D:/web/zyt/admin/src/views/tcm/diagnosis/components/DailyMatrix.vue:1-1260``D:/web/zyt/admin/src/views/tcm/diagnosis/components/DiagnosisTodoList.vue:1-319`
- 处方历史:后台七列并有编辑态开方入口;当前缺失。基准 `D:/web/zyt/admin/src/views/tcm/diagnosis/components/CaseRecordList.vue:1-106`
- 业务订单:后台有就诊序号工具栏、九列、Tag/红金额、固定详情;当前八列为订单号/处方/收货人/手机/金额/发货/状态/创建,无工具栏和详情动作。当前 `D:/web/zyt/app/src/doctor_workstation/ui/dialogs/diagnosis.py:393-424,764-787`;基准 `D:/web/zyt/admin/src/views/tcm/diagnosis/components/PatientOrderList.vue:7-148,252-276`
- 指派历史:后台九列;当前六列且继承只是纯文本。当前 `D:/web/zyt/app/src/doctor_workstation/ui/dialogs/diagnosis.py:378-390,748-762`;基准 `D:/web/zyt/admin/src/views/tcm/diagnosis/components/AssignLogPanel.vue:1-43`
- 挂号历史:后台十二列和多个状态 Tag;当前七列。当前 `D:/web/zyt/app/src/doctor_workstation/ui/dialogs/diagnosis.py:370-390,731-746`;基准 `D:/web/zyt/admin/src/views/tcm/diagnosis/components/AppointmentRecordPanel.vue:1-75`
- 视频与聊天:当前完全缺失。基准 `D:/web/zyt/admin/src/views/tcm/diagnosis/components/CallRecordPanel.vue:1-214``D:/web/zyt/admin/src/views/tcm/diagnosis/components/ImChatRecordPanel.vue:1-293`
当前所有表格最终都只创建纯文本 `QTableWidgetItem``D:/web/zyt/app/src/doctor_workstation/ui/dialogs/diagnosis.py:711-716`
建议边界:按当前主视图可达组件增加局部 model/delegate;不把不可达旧组件或观看弹窗混入。缺失内容若尚无当前 repository 数据来源,应明确保持 OPEN,不能用静态假数据冒充视觉完成。
### D-07 [高] loading、empty、error、保存与隐私锁定状态不足
- 打开详情时只显示 MessageBanner,种子内容继续可见;没有 readonly 页面级 overlay/skeleton`D:/web/zyt/app/src/doctor_workstation/ui/dialogs/diagnosis.py:452-464`
- 加载失败只改 Banner,后台独立 readonly 应在 Hero 下显示错误 Empty:当前 `D:/web/zyt/app/src/doctor_workstation/ui/dialogs/diagnosis.py:570-573`;基准 `D:/web/zyt/admin/src/views/tcm/diagnosis/readonly.vue:31-36`
- 清空表格只是 `setRowCount(0)`,没有“暂无…”状态:`D:/web/zyt/app/src/doctor_workstation/ui/dialogs/diagnosis.py:702-709`
- 订单翻页仍用全局 Banner,未遮住对应 Tab 内容:`D:/web/zyt/app/src/doctor_workstation/ui/dialogs/diagnosis.py:789-827`
- 保存只禁用按钮并显示 Banner,没有按钮 loading 动画或字段级 danger`D:/web/zyt/app/src/doctor_workstation/ui/dialogs/diagnosis.py:829-917`
- 隐私/业务锁定只有只读控件,无 warning Alert,且 read-only 控件视觉仍像可编辑白框:`D:/web/zyt/app/src/doctor_workstation/ui/dialogs/diagnosis.py:659-689``D:/web/zyt/app/src/doctor_workstation/ui/theme.py:140-155`
建议边界:为每个内容区域提供局部 overlay/empty/error;保留 seed-first、generation 和异常处理。错误样式不能改变业务成功/失败判定。
## 6. 预约差异
### A-01 [阻断] 预约 Drawer 被固定居中 Dialog 取代
基线为 RTL 右 Drawer、外窗 60% 宽、全高、遮罩点击不能关闭、独立 footer;表单 label 100 px
- `D:/web/zyt/admin/src/views/tcm/diagnosis/appointment.vue:2-19,185-198`
当前是居中 540×560 模态 QDialog、20/18 内边距、系统标题栏、默认 QFormLayout label 宽;内容顶部还额外放 25 px 患者名和“患者号仅用于视频”说明:
- `D:/web/zyt/app/src/doctor_workstation/ui/pages/patients.py:219-299`
建议边界:保留 `_AppointmentDialog` 的异步查询、状态字段、`payload()``accept()`;只把承载层替换为右贴边 panel,并将 Header/Body/Footer 分离。不要改 `PatientsPage._book_appointment()` 的业务调用:`D:/web/zyt/app/src/doctor_workstation/ui/pages/patients.py:2208-2224`
### A-02 [阻断] 字段顺序和控件类型不等价
后台严格顺序是:上次就诊、预约方式、预约类型、当前患者、渠道、条件性自媒体补充、医生 radio、日期按钮、时段矩阵、备注:
- `D:/web/zyt/admin/src/views/tcm/diagnosis/appointment.vue:20-181`
当前缺上次就诊、预约方式和当前患者;预约类型是 ComboBox,医生/日期/号源也全是 ComboBox
- `D:/web/zyt/app/src/doctor_workstation/ui/pages/patients.py:247-285`
渠道基线宽 100%、最大 360 px;当前随 QFormLayout 拉伸,没有最大宽。`channel_source_detail` 创建后默认可见,初始化信号又被 `_setting` 拦截,因此首帧/默认渠道可能错误显示“渠道补充”;只有后续用户 change 才显隐:
- 当前:`D:/web/zyt/app/src/doctor_workstation/ui/pages/patients.py:260-268,345-402,587-594`
- 基准:`D:/web/zyt/admin/src/views/tcm/diagnosis/appointment.vue:62-75,741-750`
建议边界:按真实顺序重建表单控件;沿用当前字段与校验,不改变 payload key。条件控件在初始渲染时就必须正确隐藏。
### A-03 [阻断] 日期和时段的所有可见状态都被下拉框吞掉
后台医生为可换行 radio;日期按钮 min 130×40、r8、14 pxhover 上移 2 px并有阴影;时段容器为 `#F8F9FA`、16 px padding,网格 cell min 110×70,显式展示可约、不可约、hover、selected 和刷新 loading
- `D:/web/zyt/admin/src/views/tcm/diagnosis/appointment.vue:77-171`
- `D:/web/zyt/admin/src/views/tcm/diagnosis/appointment.vue:752-921`
当前只将医生、日期、可用号源放进 ComboBox;`_apply_slots()` 直接过滤不可约、quota<=0 和当天过去时段,因此不可约卡、状态标签、slot hover、selected 渐变和刷新入口均无法呈现:
- `D:/web/zyt/app/src/doctor_workstation/ui/pages/patients.py:269-280`
- `D:/web/zyt/app/src/doctor_workstation/ui/pages/patients.py:534-574`
建议边界:以服务端原始 slot 列表驱动局部 Flow/Grid;业务上不可提交的时段保留为 disabled card。当前的未来日期限制、过期判定和 submit gate 保持不变。
### A-04 [高] loading、空态、重复预约、hover/focus 状态不足
- 后台未选医生/无排班在时间区显示 Empty;当前只是 ComboBox placeholder + Banner:基准 `D:/web/zyt/admin/src/views/tcm/diagnosis/appointment.vue:100-171`;当前 `D:/web/zyt/app/src/doctor_workstation/ui/pages/patients.py:410-493`
- 后台 `v-loading` 覆盖预约 body;当前所有阶段复用表单下方 MessageBanner,没有区域 overlay:基准 `D:/web/zyt/admin/src/views/tcm/diagnosis/appointment.vue:10`;当前 `D:/web/zyt/app/src/doctor_workstation/ui/pages/patients.py:286-299,439-448,521-532`
- 当天冲突基线在顶部持续显示 warning,切其他日期显示 info;当前只计算今日 blocking 并通过提交禁用/accept 文案表达,没有持续的 warning/info 双态:当前 `D:/web/zyt/app/src/doctor_workstation/ui/pages/patients.py:319-402,600-643`;基准 `D:/web/zyt/admin/src/views/tcm/diagnosis/appointment.vue:10-18,359-386`
- 后台 available hover、disabled opacity、selected 蓝渐变和 slot refresh loading 当前均不存在。
- 当前 generic focus 仍是青绿 2 px 实边,radio/date/slot 的 focus-visible 不存在。
建议边界:增加预约 body overlay、时间区 empty、顶部冲突 alert、按钮/卡片 hover/pressed/focus;保留现有 `_today_blocking` 与 submit complete 判定。
### A-05 [高] 预约响应式和滚动安全不足
基线预约 Drawer 自身没有 <=768 media query,但内部医生、日期、slot 可换行,body 是 Drawer 可滚区域。当前固定 540×560 且无 `QScrollArea`;恢复完整 slot 网格后若继续用当前容器,1024×640 必然裁掉内容或 footer。
建议边界:桌面保持 60% 比例;当可用内容宽不足时再做全宽/单列增强,并明确这是 PySide 可用性增强。body 独立滚动,footer 永远留在可视区。
## 7. 两档窗口的确定性差异
### 1024×640
| 视图 | 管理端基线 | 当前源码请求 | 必须验收的风险 |
|---|---|---|---|
| 索引 | 页面内容可整体纵向滚;表宽约1403,右460固定 | 内容约760;高级筛选四行常驻;单表约1392且无固定列 | chip 计数裁字、表格高度仅剩少数行、动作不可见、空/loading移位 |
| edit/viewOnly | 右贴边约614 px、全高、固定 footer | 居中880×680,最小680×520 | 请求高度已超过640;系统窗口可能裁剪/强制缩放,footer不可作为稳定截图基线 |
| appointment | 右贴边约614 px、全高 | 居中540×560 | 宽度偏小且大量留白;恢复slot后无滚动会裁内容 |
| standalone readonly | 页面流、16px边距、无Tabs | 880px模态Tabs | 模式、层级和宽度均不可比较 |
### 1440×900
| 视图 | 管理端基线 | 当前 | 必须验收的风险 |
|---|---|---|---|
| 索引 | 内容宽约1240;仍可能横滚,右460固定 | 内容约1176;横滚约248px且无固定列 | 视频/操作随滚动消失;少量数据时列表卡被拉出大空白 |
| edit/viewOnly | 右贴边约864 px | 居中880×680 | 宽度偶然接近,但方向、全高、三段壳仍错误 |
| appointment | 右贴边约864 px | 居中540×560 | 明显过窄,无法呈现日期/slot网格密度 |
| standalone readonly | 宽页面流,病例4/3列 | 固定880px单列表单 | 信息密度和卡片层级完全不同 |
注:Element Drawer 的 60% 按外窗 viewport 计算,因此上表为约 614/864 px;不按 Python 扣除侧栏后的 workspace 计算。
## 8. 建议改动边界(按文件 / 类)
| 目标 | 允许的视觉改造 | 必须保持不动 |
|---|---|---|
| `D:/web/zyt/app/src/doctor_workstation/ui/theme.py:13-275` | 新增诊单局部 token、scoped QSS、checked/focus/read-only/overlay/delegate 状态 | 不全局换肤其他页面;不改变业务状态含义 |
| `D:/web/zyt/app/src/doctor_workstation/ui/widgets.py:331-627` | 新增 FlowLayout、DiagnosisPaginationBar、局部 loading/empty、专用 model/delegate/固定表辅助 | 不破坏现有 PageHeader、EmptyState、SortableTable、Pager 的调用方 |
| `D:/web/zyt/app/src/doctor_workstation/ui/shell.py:306-423` | 仅当全壳明确纳入验收时调整;可提供 drawer host/overlay host | 不以改壳宽度掩盖诊单页布局问题 |
| `D:/web/zyt/app/src/doctor_workstation/ui/pages/consultations.py:464-674` | 重建索引层级、筛选、工具栏、表格绑定、页面滚动 | 保留 repository 调用、过滤语义、权限判断、generation、mutation、视频门槛 |
| `D:/web/zyt/app/src/doctor_workstation/ui/pages/consultations.py:901-956` | 将普通 loading/error 映射到 table-only overlay/状态层 | 20秒 silent refresh 继续不闪;不改请求时序 |
| `D:/web/zyt/app/src/doctor_workstation/ui/dialogs/diagnosis.py:208-424` | 拆 readonly/drawer 视图,重建 header/tabs/form/cards/tables | 保留 `open_for` 契约、saved signal、隐私可见性和已有数据加载 |
| `D:/web/zyt/app/src/doctor_workstation/ui/dialogs/diagnosis.py:426-917` | 把加载/错误/锁定/保存映射到局部视觉状态 | 不改 endpoint、payload、字段校验、generation、防过期响应 |
| `D:/web/zyt/app/src/doctor_workstation/ui/pages/patients.py:219-646` | 把预约改成 Drawer、radio/date/slot grid、overlay/empty/alert | 保留排班来源、日期/过期过滤、冲突门槛、submit gate、`payload()` |
| `D:/web/zyt/app/src/doctor_workstation/ui/pages/patients.py:2208-2224` | 仅替换打开的视觉容器 | 不改预约保存调用与 mutation reconcile |
推荐实施顺序:
1. 建 scoped token 与 drawer/table 基础组件。
2. 重建 index 层级、筛选、固定列和 states。
3. 拆 readonly 与 edit/viewOnly,先完成壳和病历主 Tab。
4. 补当前可达的 notes/orders/histories;数据源不存在的主链保持显式 OPEN。
5. 重建 appointment 卡片式选择器。
6. 最后做两档截图的字号、间距和颜色微调。
## 9. 截图验收前置条件
所有截图固定:Windows 缩放 100%、默认亮色、同一 Qt 字体回退、同一权限集合、相同样本数据、无本地主题覆盖。运行态字体/DPR、tooltip/dropdown 坐标和 scrollbar 像素应记录环境,不应以静态源码推断绝对像素。
索引样本至少包含:`NEW`、双预约、已完成预约、爽约、未确认、已确认未挂号、处方作废、unserved=`null/2/5/8`、可进入/不可进入视频。
详情样本至少包含:患者基本信息可编辑/锁定、全部权限/裁减权限、备注含图片和文件、订单有/无数据、挂号/指派有/无数据、加载失败。
预约样本至少包含:未选医生、无排班、可约、不可约、当天过去时段、选中、今日冲突、其他日期 info、渠道需要/不需要补充、loading/error。
## 10. 截图验收矩阵
| ID | 窗口 | 状态 / 操作 | 必须同时看见 | 关键判定 |
|---|---|---|---|---|
| IDX-01 | 1024×640 | 默认15条、筛选收起、横滚最左 | 无页面内标题;两张平卡;两行筛选;表头、分页 | chips 不裁字;搜索完整;默认当天 active;至少能正常纵向滚整页 |
| IDX-02 | 1024×640 | 横滚到最右 | 左表发生横滚;视频120+操作340仍贴右 | 固定区不移动;双表 header/body/row height 无错位 |
| IDX-03 | 1024×640 | 更多筛选展开 | 虚线分隔、高级控件可换行、表格仍可达 | 显隐无动画;24/32px混合高度按源码;页面整体可滚 |
| IDX-04 | 1024×640 | 四类 chip active + 键盘 focus | 当天/待预约/已完成/待分配各自语义色 | 计数为同行文字;focus清晰且无几何跳动 |
| IDX-05 | 1024×640 | 普通、未确认、未挂号 hover | 斑马、#F8F8F8 hover、3px语义条/渐变 | fixed区背景连续;hover不被 selection 色覆盖 |
| IDX-06 | 1024×640 | 慢请求 loading | 原表尺寸保持、table-only 半透明层、42px spinner | 筛选/卡位置不跳;无全宽 banner 插入 |
| IDX-07 | 1024×640 | 空结果 | 表头、60px“暂无数据”、分页 | 无大圆圈插画;pager不消失 |
| IDX-08 | 1440×900 | 默认15条 | 完整两卡、自然表高、完整分页 | 少量数据不拉出大空白;15条由整页滚动承载 |
| IDX-09 | 1440×900 | 多预约 + 操作换行 | 预约 badge/渐变/虚线、340px操作链接 | 行高由内容增长;左右固定表同步 |
| IDX-10 | 两档 | tooltip / 更多菜单 | 助理溢出、未服务、视频 tooltipbottom-end菜单 | tooltip只在语义命中区;删除前分隔且danger |
| DET-01 | 1024×640 | edit 基本 Tab | 右侧约614px全高 Drawer、header、横滚Tabs、固定footer | body单独滚;footer不裁;label160px;无系统标题栏 |
| DET-02 | 1024×640 | viewOnly + 患者锁定 | info badge、disabled表单、warning Alert、关闭按钮 | 无保存;read-only外观不似可编辑;隐私字段无泄漏 |
| DET-03 | 1440×900 | edit 全权限 | 右侧约864px、Tab正确顺序、24/12/8栅格 | 无TrackingNoteactive底条3px;表单字段顺序与§4.5一致 |
| DET-04 | 两档 | 独立 readonly | 无Tabs/模态;返回+Hero+摘要+病例+权限卡片 | 1024可用;1440病例保持4/3列;未服务三色正确 |
| DET-05 | 两档 | 详情 loading/error/empty | overlayHero下错误Empty;各表局部空态 | 不残留错误seederror不导致footer/tab位移 |
| DET-06 | 1440×900 | 备注/订单/指派/挂号 | 时间轴图片/文件;订单工具栏/详情;完整列/Tag | 表头顺序、状态色、固定动作列与管理端一致 |
| APT-01 | 1024×640 | 初始 loading / 未选医生 | 右侧约614px Drawer、body overlay、时间区Empty、固定footer | label100pxfooter可见;渠道补充默认正确隐藏 |
| APT-02 | 1024×640 | 无排班 | 医生radio、时间区“暂无排班”Empty | 不用ComboBox placeholder冒充空态 |
| APT-03 | 1024×640 | 可约/不可约/hover/selected | 日期130×40slot最小110×70;刷新 | 不可约仍显示但禁用;hover抬升;selected蓝渐变 |
| APT-04 | 两档 | 今日冲突 / 其他日期重复 | 顶部warning切info、确认disabled/available | 状态随所选日期切换;不只在点击提交后提示 |
| APT-05 | 1440×900 | 完整预约表单 | 右侧约864px、医生和日期自然换行、slot多列 | 不保持540px窄窗;body滚动,footer固定 |
| A11Y-01 | 两档 | 仅键盘遍历 | chip/input/select/radio/checkbox/table/button均有focus | 顺序可预测;focus对比足够;无控件尺寸抖动 |
## 11. 发布门槛
以下任一项仍存在即不能标记视觉对齐完成:
- 索引页仍有第二个页面标题,或高级筛选默认常驻。
- 表格仍是单个纯文本 `QTableWidget`,右侧 460 px 不固定。
- 空态仍替换掉表头/分页,或普通加载仍插入全宽 Banner。
- 只读与 viewOnly 仍复用同一个居中 Tabs Dialog。
- 编辑/预约仍不是 60% 右贴边、全高、固定 footer 的 Drawer。
- 病历仍由一串同形态 `QPlainTextEdit` 组成。
- 医生、日期和时段仍以 ComboBox 代替 radio/button/grid。
- 1024×640 下任何 footer、搜索、chip 或表格固定区被裁剪。
- 1440×900 下预约仍固定 540 px,或详情仍只有固定 880 px 居中模态形态。
- hover/focus/loading/empty/error/disabled/selected 任一规定状态没有独立截图证据。
本报告只定义视觉和交互呈现的修复边界。所有 repository、endpoint、payload、权限 code、状态门槛和 mutation reconcile 均应原样保留,并在实现后另走现有业务回归测试。