42 KiB
诊单详情 / 编辑 / 预约视觉规格(后台源码基准)
1. 范围与判读原则
本规格只以 D:/web/zyt/admin 当前源码为事实源,覆盖:
- 三个主视图:
src/views/tcm/diagnosis/edit.vue、readonly.vue、appointment.vue。 - 三个主视图直接渲染的诊单组件:患者摘要、病例、日常记录、医生备注、处方/病例记录、业务订单、视频、聊天、医助指派历史、挂号历史、待办。
- 备注视图直接引用的
src/views/patient/reception/components/NoteTimeline.vue。 - 直接生效的全局样式入口、Element Plus 变量和 Tailwind 尺寸映射。
颜色、尺寸若由当前文件明确声明,标为“显式”;若控件仅沿用 Element Plus,则标为“继承”。项目使用 Element Plus ^2.9.4 与 Tailwind CSS ^3.4.17(package.json:27,64)。全局样式入口为 main.ts:1-3,依次加载 element.scss、dark.css、var.css、tailwind.css、public.scss(src/styles/index.scss:1-5)。因此不能把浏览器/Element 默认值误写成某个业务组件的局部规格。
关键结论:系统实际上有两种“只读详情”。
readonly.vue是独立、卡片化、纵向详情页;edit.vue在viewOnly模式下则仍是右侧抽屉和 Tab 结构,只禁用编辑控件。两者不能用同一个线框替代。
2. 全局视觉基础
2.1 字体与字号
字体栈由 Tailwind 配置明确为 PingFang SC, Arial, Hiragino Sans GB, Microsoft YaHei, sans-serif(tailwind.config.js:79-80),并赋给 --el-font-family(src/styles/var.css:1-3)。基础字号如下(src/styles/var.css:11-18):
| 语义 | 实际字号 |
|---|---|
| extra large | 18 px |
| large | 16 px |
| medium | 15 px |
| base | 14 px |
| small | 13 px |
| extra small | 12 px |
业务层进一步压缩:编辑抽屉根节点和表单文字为 12 px(edit.vue:1476-1504,1532-1556);只读病例键值为 12.5 px(components/PatientCaseCard.vue:307-341);聊天气泡为 14 px(components/ImChatRecordPanel.vue:260-286)。
2.2 全局颜色与表面
以下均为项目显式变量(src/styles/var.css:20-40):
| 用途 | 色值 |
|---|---|
| 页面底 | #f6f6f6 |
| 普通/浮层底 | #ffffff |
| 主文字 | #333333 |
| 常规文字 | #666666 |
| 次要文字 | #999999 |
| placeholder | #a8abb2 |
| disabled | #c0c4cc |
| border / light / lighter | #dcdfe6 / #e4e7ed / #ebeef5 |
| extra-light border | #f2f2f2 |
| fill / light / lighter | #f0f2f5 / #f8f8f8 / #fafafa |
| extra-light fill | #fafcff |
Element 语义主色未在这些诊单文件中改写,局部引用 var(--el-color-primary) 或显式 #409eff。继承的 Element Plus 2.9.4 常规控件高度为 32 px(small 24 px、large 40 px);但编辑抽屉底部按钮被局部覆盖为最小 40 px,移动端最小 44 px(edit.vue:1732-1740,1905-1913)。
2.3 间距基线和全局行为
Tailwind 间距映射是 4 px 基线:1=4、2=8、2.5=10、3=12、3.5=14、4=16、5=20、6=24(tailwind.config.js:103-125)。业务文件里的 8/10/12/14/16/18/20/24 px 与该节奏一致。
直接影响这些页面的全局规则:
- Dialog 居中,最大宽
calc(100vw - 30px),圆角 5 px(src/styles/element.scss:11-27)。 - 全局 Drawer 主内边距变量为 16 px,Header 内边距
13px 16px、下边框 1 px lighter;预约 Drawer 没有重写这些值,编辑 Drawer 则只额外重写背景与边框(src/styles/element.scss:46-56)。 - 全局表格字号 14 px、表头主文字色、表头字重 400、表头底
#f8f8f8(src/styles/element.scss:58-68;src/styles/var.css:10)。因此编辑根节点的 12 px 不应错误地传成所有表格单元字号。 - Input、Select、Textarea 聚焦时出现 2 px primary-light 外环,radio/checkbox active 也有 2 px 外环;校验错误时切换 danger-light 外环(
src/styles/element.scss:140-175)。 - Tabs 底线全局压至 1 px(
src/styles/element.scss:131-133)。 - 消息与通知层级为 9999(
src/styles/element.scss:1-9)。 - 小于等于 768 px 时分页隐藏页码跳转与 page-size 选择器(
src/styles/element.scss:177-183)。 - Tailwind 会导入 base/components/utilities(
src/styles/tailwind.css:1-3),但 Element 按钮背景、focus、hover 被重新还原为 Element 变量,避免被 Tailwind reset 覆盖(src/styles/element.scss:186-200)。 body为 14 px 主文字、overflow:hidden、最小宽 375 px;页面/Drawer 自己承担滚动(src/styles/public.scss:1-3)。全局.form-tips为 12 px secondary、行高 24 px、上间距 4 px(src/styles/public.scss:4-6)。
暗色主题另有一套直接全局变量:页面/表面为 #0a0a0a / #1d2124 / #1d1e1f,主/常规/次要文字为 #e5eaf3 / #cfd3dc / #a3a6ad,边框从 #636466 到 #2b2b2c,遮罩为 rgba(0,0,0,.8)(src/styles/dark.css:1-31)。不过三个诊单主视图及卡片大量显式写入白底、浅蓝渐变和 slate 色,不能完整随暗色变量切换;本规格后续均按源码默认浅色态记录,暗色不能视为已完整适配。
3. 独立只读详情页 readonly.vue
3.1 页面骨架
源码结构是单列滚动页,不使用 Tabs(readonly.vue:1-149):
┌─────────────────────────────────────────────────────────────────────┐
│ ← 返回 诊单只读详情 张三 男 · 42岁 [未服务 3天] │
├─────────────────────────────────────────────────────────────────────┤
│ [患者信息摘要 PatientInfoCard] │
├─────────────────────────────────────────────────────────────────────┤
│ [患者病例 PatientCaseCard] │
├─────────────────────────────────────────────────────────────────────┤
│ [日常记录 DailyMatrix] 按权限可见 │
├─────────────────────────────────────────────────────────────────────┤
│ [医生备注/舌象/报告 NoteTimeline] │
├─────────────────────────────────────────────────────────────────────┤
│ [业务订单 PatientOrderList] 按权限可见 │
├─────────────────────────────────────────────────────────────────────┤
│ [视频录制回放 CallRecordPanel] 按权限可见 │
├─────────────────────────────────────────────────────────────────────┤
│ [聊天 ImChatRecordPanel] 按权限可见 │
├─────────────────────────────────────────────────────────────────────┤
│ [指派医助记录 AssignLogPanel] 按权限可见 │
├─────────────────────────────────────────────────────────────────────┤
│ [挂号记录 AppointmentRecordPanel] 按权限可见 │
└─────────────────────────────────────────────────────────────────────┘
渲染顺序严格来自 readonly.vue:39-146;异常时在 hero 下方显示错误空态(readonly.vue:31-36)。页面根容器垂直间距 16 px、内边距 16 px(readonly.vue:269-273)。
3.2 顶部 Hero
Hero 是可换行的左右布局:display:flex; justify-content:space-between; flex-wrap:wrap; gap:12px,内边距 12px 16px,圆角 12 px,边框 #dde7ff,背景为 #f5f8ff → #eef3ff 的浅蓝渐变(readonly.vue:275-285)。
- 页面标题:16 px / 700(
readonly.vue:286-303)。 - 患者姓名:18 px / 700;性别年龄 13 px(
readonly.vue:305-320)。 - 未服务状态胶囊:12 px / 600,内边距
4px 10px,999 px 全圆角(readonly.vue:323-330)。 - 状态色:正常绿
#16a34a/ 边框#bbf7d0;提醒橙#ea580c/#fed7aa;严重红#dc2626/#fecaca(readonly.vue:332-355)。从未记录时使用 Element placeholder 灰。
3.3 卡片规格
通用详情卡为白底、1 px #e6ebf2 边框、14 px 圆角、18 px 内边距、14 px 内部纵向间距和轻阴影(readonly.vue:364-373)。卡片标题 15 px / 700,标题前为 3 × 16 px 蓝色标记(readonly.vue:375-396)。DailyMatrix 外层额外 16 px 内边距以对齐矩阵(readonly.vue:398-405)。错误空态卡保持 14 px 圆角并有 40 px 纵向内边距(readonly.vue:357-362)。
患者摘要内部是浅蓝 Hero 卡:圆角 12 px,内边距 16px 18px,行距 6 px;患者名 22 px / 700,其余信息 13 px、行高 1.7(components/PatientInfoCard.vue:78-123)。字段顺序是:
- 姓名。
- 脱敏手机 · 性别 · 年龄。
- 身高 / 体重 · 地区。
- 预约日期时间 · 时段。
- 医生 / 医助。
- 预约状态 · 是否已开方。
- 备注(有值才显示)。
顺序由 components/PatientInfoCard.vue:6-25 确定。
3.4 病例字段顺序与网格
病例卡以分组标题 + 网格键值展示;组间 gap:10px,除首组外顶部 12 px 内边距并有 dashed 分隔线(components/PatientCaseCard.vue:258-269)。分组标题 13 px / 600、蓝色,前有 4 px 圆点(components/PatientCaseCard.vue:271-287)。网格横向间距 16 px、纵向 8 px,并提供 1/2/3/4 等分列(components/PatientCaseCard.vue:289-305)。键值字号 12.5 px、行高 1.55,label 最小宽 58 px;label 为 #6b7280,value 为 #1f2937 / 500,空值为 #c0c4cc(components/PatientCaseCard.vue:307-341)。
只读病例的真实字段顺序(components/PatientCaseCard.vue:8-124):
| 分组 | 列数 | 顺序 |
|---|---|---|
| 基本信息 | 4 | 诊单ID、姓名、身份证、手机、性别、年龄、婚姻、地区 |
| 生命体征 | 4 | 身高、体重、高压、低压、诊断类型、空腹血糖、在用药物(多行) |
| 主诉 | 4 | 当地诊断日期、糖尿病病史、当地医院、当地医院诊断结果 |
| 现病史 | 3 | 口腔、饮水、体重变化、脂肪肝、饮食(跨2列)、肢体、睡眠、眼、头、出汗、皮肤、小便、大便、腰肾、其他补充(跨3列、多行) |
| 既往史 | 1 | 既往史(整行) |
| 其他病史 | 混合 | 外伤、手术、过敏、家族、妊娠 |
| 补充与意见 | 1 | 病史补充(有值才显示)、处方意见 |
超标指标采用 #dc2626、700 字重并带上箭头(components/PatientCaseCard.vue:343-358)。处方意见为 13 px、12px 14px 内边距、8 px 圆角、左侧 3 px 蓝条(components/PatientCaseCard.vue:360-368)。
3.5 响应式事实
readonly.vue 自身没有 media query;Hero 仅通过 flex-wrap 避免左右信息互相挤压。PatientCaseCard.vue 也没有窄屏降列规则,所以 4 列病例网格不会自动变成 1 列。实现 PySide 时不能把“可换行 Hero”误判为整页已经完整响应式。
4. 编辑 / 抽屉只读 edit.vue
4.1 框架与模式
右侧 Drawer 宽度固定为视口的 60%,方向 RTL;只读时 z-index 4000,编辑/新增时 1500(edit.vue:2-10)。抽屉有三种标识:只读 info、新建 success、编辑 warning,标题下显示“患者名 · 诊单ID”(edit.vue:11-54,859-863)。
桌面(右侧 60% Drawer)
┌───────────────────────────────────────────────────────────────┐
│ 编辑诊单 [编辑] 患者名 · #123 │ Header
├───────────────────────────────────────────────────────────────┤
│ 病历 │ 医生备注 │ 日常记录 │ 处方 │ 业务订单 │ 视频 │ ... → │ Tabs
├───────────────────────────────────────────────────────────────┤
│ │
│ [锁定提示 / 隐私提示,按条件] │
│ 诊单ID [_____________________________] │
│ 姓名 [____________] 身份证 [____________] │
│ │
│ ──────────────── 生命体征 ──────────────── │
│ 婚姻 [____] 身高 [____] 体重 [____] │ Scroll body
│ ... │
│ ──────────────── 现病史 ───────────────── │
│ [可换行 radio / checkbox 组] │
│ │
├───────────────────────────────────────────────────────────────┤
│ [取消/关闭] [保存] │ Footer slot
└───────────────────────────────────────────────────────────────┘
viewOnly 模式没有切换到独立详情卡,而是给病历 fieldset 禁用输入,并隐藏保存;锁定患者信息时显示 warning alert(edit.vue:57-84,766-781)。
4.2 Header、Tabs、Footer
- Header 背景
#fff → #f8fafc,底边 1 px#e2e8f0(edit.vue:1776-1785)。标题 18 px / 600 /#0f172a,行高 1.3;副标题 13 px(edit.vue:1670-1717)。 - Body 背景
#f8fafc(edit.vue:1787-1790)。 - Tabs 横向滚动,滚动条 4 px;nav 使用
max-content且最小宽 100%,tab 水平内边距 14 px,常态#64748b/ 500,激活态为 Element primary / 600,激活条 3 px(edit.vue:1798-1858)。 - Footer 最终生效样式为白底、上边框 1 px
#e2e8f0,内容右对齐、gap 12 px、内边距14px 20px 18px(edit.vue:1719-1730,1860-1864)。按钮最小高 40 px、水平内边距 20 px、600 字重、圆角 10 px(edit.vue:1732-1740)。
这里没有 CSS position: sticky。底部操作之所以视觉上固定,是因为它使用 Element Drawer 的独立 footer slot,位于可滚动 body 之外(模板 edit.vue:766-781;结构样式 edit.vue:1792-1796)。PySide 应以固定底栏实现,而不是在滚动内容末尾放按钮。
4.3 Tab 顺序、权限与内容
Tab 的准确顺序和门槛(edit.vue:55-759):
| 序号 | Tab | 条件 | 内容组件 |
|---|---|---|---|
| 1 | 病历 | 始终 | 内联表单 |
| 2 | 医生备注 | 始终 | NoteTimeline |
| — | 跟踪备注 | 已注释,不渲染 | 原拟 TrackingNoteTimeline(edit.vue:644-654) |
| 3 | 日常记录 | tcm.diagnosis/dailyRecord |
DailyMatrix |
| 4 | 处方 | tcm.diagnosis/chufang |
CaseRecordList |
| 5 | 业务订单 | tcm.diagnosis/patientOrders |
PatientOrderList |
| 6 | 视频录制回放 | tcm.diagnosis/huifang |
CallRecordPanel |
| 7 | 聊天 | tcm.diagnosis/chat |
ImChatRecordPanel |
| 8 | 指派医助记录 | tcm.diagnosis/assign 或 tcm.diagnosis/detail |
AssignLogPanel |
| 9 | 挂号记录 | doctor.appointment/lists |
AppointmentRecordPanel |
权限变化后若当前 Tab 失权,代码会主动回到 basic(edit.vue:883-913)。除病历外的大部分 Tab 为 lazy 内容,首次选中才加载。
4.4 病历表单布局、标签和控件
桌面表单 label width 为 160 px(edit.vue:61-63)。根字号、label、输入/textarea/radio/checkbox/button 均显式为 12 px;label 为 500 / #606266(edit.vue:1476-1504,1532-1556)。表单项底部间距 18 px(edit.vue:1528-1530)。输入、选择、日期、数字框圆角 10 px(edit.vue:1645-1667);普通输入高度沿用 Element 32 px。
分组标题的上/下外边距为 28/22 px;中间文字 14 px / 600 / #0f172a、7px 16px 内边距、999 px 胶囊圆角,两侧 1 px #e2e8f0 横线(edit.vue:1506-1525)。单选紧凑组换行、gap 12 px;复选组 gap 12px 16px;普通 radio/checkbox 右、下间距分别 16/8 px(edit.vue:1558-1604)。帮助文本 12 px、#909399、行高 1.5、顶部 4 px(edit.vue:1606-1611)。
4.5 编辑表单的真实字段顺序
以下只列实际渲染字段,不把 formData 中未渲染的属性当作 UI(模板 edit.vue:57-632):
| 区段 | 栅格 | 字段顺序与控件 |
|---|---|---|
| 顶部 | 24 | 诊单ID(只读) |
| 基本身份 | 12 + 12 | 姓名;身份证 |
| 联系信息 | 12 + 12 | 手机;性别 |
| 年龄 | 12 | 年龄 |
| 生命体征 | 8 + 8 + 8 | 婚姻;身高;体重 |
| 8 + 8 + 8 | 地区;高压;低压 | |
| 8 | 空腹血糖 | |
| 12 | 诊断类型 | |
| 12 + 12 | 状态;渠道 | |
| 12 | 统计端就诊卡 | |
| 12 | 在用药物,textarea,3 行,maxlength 2000 | |
| 主诉 | 12 + 12 | 当地诊断日期;糖尿病病史 |
| 24 | 当地医院诊断结果(check buttons) | |
| 24 | 当地医院名称 | |
| 现病史 | 24 | 口腔感觉(check buttons) |
| 24 | 每日饮水量(radio buttons) | |
| 24 | 近月体重变化(radio buttons) | |
| 24 | 脂肪肝(radio buttons) | |
| 24 | 饮食(check buttons) | |
| 24 × 9 | 肢体、睡眠、眼睛、头部、出汗、皮肤、小便、大便、腰肾 | |
| 24 | 其他补充,textarea,3 行 | |
| 既往史 | 24 | 既往史(check buttons) |
| 其他病史 | 8 + 8 + 8 | 外伤;手术;过敏 |
| 12 + 12 | 家族;妊娠 | |
| 诊断信息 | 24 | 病史补充,textarea,2 行 |
具体模板行:顶部/身份 edit.vue:86-194;生命体征 edit.vue:199-368;主诉 edit.vue:369-412;现病史 edit.vue:414-549;既往史 edit.vue:552-564;其他病史 edit.vue:567-613;诊断信息 edit.vue:616-629。
当前模板没有显示 syndrome_type、diabetes_type、舌象、脉象、治则、医嘱等字段,即便脚本模型中存在,也不应擅自加入视觉复刻。
4.6 移动端
小于等于 768 px 时(edit.vue:1876-2004):
- Drawer 变为 100vw;header
12px 14px,body10px 12px。 - Footer 改为纵向、按钮全宽,gap 10 px,内边距
12px 14px + safe-area,按钮最小 44 px。 - 标题 17 px;Tab 高/行高 44 px、字号 13 px、水平内边距 12 px。
- label 改到控件上方:100% 宽、左对齐、下间距 6 px;表单项底部 14 px。
- 所有
el-col强制 100%,数字框 100%;radio gap8px 16px,checkbox8px 10px。 - 分组标题外边距 18/14 px,文字 13 px、水平内边距 10 px。
移动端(<=768)
┌──────────────────────┐
│ 标题 [状态] × │
│ 患者 · 诊单ID │
├──────────────────────┤
│ ← 可横向滚动 Tabs → │
├──────────────────────┤
│ 姓名 │
│ [__________________] │
│ 身份证 │
│ [__________________] │
│ ... 全部单列 ... │
├──────────────────────┤
│ [取消/关闭 全宽] │
│ [保存 全宽,44px+] │
└──────────────────────┘
5. 预约抽屉 appointment.vue
5.1 骨架与字段顺序
预约同样是 RTL 右侧 Drawer,宽 60%,z-index 2000,且点击遮罩不能关闭(appointment.vue:2-9)。表单 label width 为 100 px(appointment.vue:19)。
┌───────────────────────────────────────────────────────────────┐
│ 预约面诊 × │
├───────────────────────────────────────────────────────────────┤
│ [今日重复预约警告 / 其他日期提示,条件显示] │
│ 上次面诊 2026-08-01 10:30 │
│ 预约方式 (●) 按时间预约 │
│ 预约类型 (●) 视频面诊 │
│ 预约患者 (●) 当前患者 │
│ 渠道来源 [请选择 ▼] │
│ 自媒体详情 [请选择 ▼] ← 仅自媒体渠道 │
│ 预约医生 ( ) 医生A ( ) 医生B ... │
│ 预约时间 [08月10日 周一] [08月11日 周二] ... │
│ ┌───────────────────────────────────────────┐ │
│ │ 可预约时段 [刷新] │ │
│ │ [09:00 可约] [09:30 已满] [10:00 可约] ...│ │
│ └───────────────────────────────────────────┘ │
│ 备注 [_________________________________________] │
├───────────────────────────────────────────────────────────────┤
│ [取消] [确认预约] │
└───────────────────────────────────────────────────────────────┘
字段顺序严格为(appointment.vue:21-181):
- 上次面诊(文本)。
- 预约方式(当前只呈现按时间预约)。
- 预约类型(视频)。
- 预约患者(当前患者)。
- 渠道来源(必填 select)。
- 自媒体详情(渠道命中自媒体白名单时必填)。
- 预约医生(radio 列表)。
- 预约时间:先日期按钮,后可预约时段矩阵。
- 备注(textarea,2 行)。
- Footer:取消、确认预约。
5.2 尺寸、颜色与交互状态
- 渠道控件宽 100%、最大宽 360 px(
appointment.vue:741-750)。 - 医生/单选组可换行,gap 12 px(
appointment.vue:752-765,911-921)。 - 日期按钮 flex-wrap、gap 10 px、最小宽 130 px、高 40 px、字号 14 px、圆角 8 px;hover 上移 2 px并加阴影(
appointment.vue:771-789)。 - 时段容器底
#f8f9fa、圆角 8 px、内边距 16 px;标题 15 px / 600 /#303133(appointment.vue:791-808)。 - 时段网格
auto-fill minmax(110px,1fr)、gap 10 px、最大高 450 px并滚动,滚动条宽 6 px(appointment.vue:810-830)。 - 时段卡白底,2 px
#e4e7ed边框、8 px 圆角、最小高 70 px、水平内边距 8 px;时间 15 px / 600 /#303133,状态 12 px /#909399(appointment.vue:831-862)。 - 可约 hover:
#409eff边框、#ecf5ff底、上移并加阴影(appointment.vue:864-873)。 - 不可约:
#f5f7fa底、opacity 0.6、文字#c0c4cc(appointment.vue:875-894)。 - 选中:
#409eff → #66b1ff渐变、白字和阴影(appointment.vue:896-909)。 - Footer 右对齐、gap 12 px、上下内边距 12 px(
appointment.vue:923-928)。
状态逻辑是视觉的一部分:未选医生时显示“请先选择医生”,无排班显示空态;日期只来自当前及未来有效排班(appointment.vue:299-326);当天过去时段禁用(appointment.vue:328-357);当天已有预约显示 warning,其他日期重复信息为 info(appointment.vue:359-375)。提交按钮只有医生、日期、时间、渠道以及条件性渠道详情齐全,且不存在当天冲突时才可用(appointment.vue:377-386)。
5.3 响应式事实
appointment.vue 没有移动端 media query。内部医生、日期和 slot 网格会换行,但 Drawer 在窄屏仍保持 60% 视口宽。这是后台源码的真实缺口;PySide 若要求窗口缩小时可用,应保留桌面 60% 的视觉比例,同时设置合理最小内容宽并在不足时切到全宽/单列,而不声称这是 Vue 原实现已有行为。
6. 备注、日常记录、处方/订单与历史关联区
6.1 医生备注 / 舌象 / 报告
编辑 Drawer 和独立只读页均使用 NoteTimeline(edit.vue:633-643; readonly.vue:56-72)。编辑态顶部按权限显示“新增备注、选择舌象、选择报告”;只读态隐藏这些操作(src/views/patient/reception/components/NoteTimeline.vue:1-123)。
视觉规格(NoteTimeline.vue:272-436):
- 顶部动作行 gap 12 px、底部分隔线。
- 时间轴左内边距 22 px,轴线 2 px
#ebeef5;节点 10 px、#409eff,外圈#ecf5ff。 - 日期 13 px / 600 /
#303133,等宽数字;正文 12.5 px /#606266/ 1.6 行高。 - 舌象缩略图
64 × 64 px、圆角 6 px、带边框;删除为红色动作。 - 报告文件 chip 为
6px 10px、圆角 6 px、12 px primary 字,最大宽 180 px。 - 上传格
90 × 90 px、1 px dashed#dcdfe6、圆角 6 px、12 px;hover 转 primary。 - 新增备注 Dialog 宽 480 px,textarea 4 行、maxlength 500。
TrackingNoteTimeline 当前并未进入可见 Tab:edit.vue:644-654 将整段注释。不能在复刻中把它当作现存“跟踪备注”页签。
6.2 日常记录、趋势与待办
DailyMatrix 顶部提供最近 7 天 / 30 天 / 自定义日期和日期范围;右侧有本人记录图例、编辑动作与血糖血压/饮食/运动/备注/刷新按钮,readonly 仅保留刷新(components/DailyMatrix.vue:1-129)。矩阵的指标顺序为:空腹、餐后2小时、其他血糖、血压、西药、胰岛素、早餐、午餐、晚餐、运动、跟踪备注(components/DailyMatrix.vue:410-485)。固定指标列 120 px,日期列最小 100 px。
- 根内边距 16 px;toolbar 换行、gap 12 px、下间距 12 px(
DailyMatrix.vue:1090-1105)。 - 趋势卡上间距 16 px、内边距
16px 18px、圆角 10 px,图表高 280 px(DailyMatrix.vue:1124-1158)。 - 超标红
#dc2626/ 700;本人记录用紫色浅底,徽章#6d28d9 / #ede9fe / #ddd6fe(DailyMatrix.vue:1182-1225)。 - <=768 px 时根内边距 12 px,图表内边距 12 px、高 240 px(
DailyMatrix.vue:1240-1260)。
待办区域位于 DailyMatrix 下方,标题 14 px / 600。表格字段依次为提醒时间、内容、状态、创建人、推送时间、错误信息、操作;toolbar 可筛全部/待推送/已推送/失败/已取消(components/DiagnosisTodoList.vue:1-112)。新增 Dialog 宽 520 px、label 100 px,字段顺序为提醒时间、内容(4 行/500 字)、提醒人;toolbar 换行、gap 8 px、下间距 12 px,分页右对齐(DiagnosisTodoList.vue:291-319)。
6.3 处方 / 病例历史
CaseRecordList 顶部编辑态显示小号 primary“开方”,只读时隐藏。表格字段顺序:就诊日期(120)、就诊编号(120)、诊断(min 160)、处方摘要(min 180)、医生(90)、状态(140)、操作(120 固定右侧);根内边距 20 px(components/CaseRecordList.vue:1-39,103-106)。
点击“开方”进入直接依赖的全局 @/components/tcm-prescription/index.vue,不是在诊单 Tab 内原地编辑:它另开 1200 px Drawer、禁止点遮罩关闭,表单 label 100 px(src/components/tcm-prescription/index.vue:1-10)。编辑态顺序为:
- 患者信息:姓名 / 性别 / 年龄三等分,电话 / 门诊号两等分。
- 诊断信息:面象 / 舌象两等分,临床诊断整行 2 行 textarea;舌象详情和脉象详情在模板中被注释(
index.vue:11-76)。 - 中药处方 RP:药材总数与锁定提示;添加主方、添加辅方、处方库导入、粘贴导入;处方价格;主方卡片网格;辅方卡片网格(
index.vue:78-216)。 - 用法信息:处方类型、主方用法、条件性辅方用法、剂数、剂量单位、用法、服用时间、服用方式、忌口、其他说明、医师、是否共享、医师签名(
index.vue:217-531)。
信息分区间距 20 px、内边距 16 px、底 #f5f7fa、圆角 6 px;标题 15 px / 600 / #303133(index.vue:2500-2516)。RP toolbar 可换行,gap 12px 20px、内边距 14px 16px、圆角 10 px、lighter 边框;标题 16 px、说明/锁定文字 12 px。药材编辑区桌面固定 4 列、gap 12 px,卡片白底、10 px 内边距、6 px 圆角;仅在 <=960 px 时让操作按钮行占满,没有把 4 列药材网格降列(index.vue:2522-2690)。签名区最大宽 600 px、1 px #dcdfe6、圆角 4 px(index.vue:2694-2711)。
保存后同一 Drawer 切换为处方预览:Tab 为“药房联 / 处方联”,上方工具条与作废/审核驳回状态,主体是 A4 210 × 297 mm 白纸,8mm 10mm 内边距、13 px 字号、28 px / 700 标题(index.vue:536-754,2714-2782)。患者信息是 4 列表格,药材是 2 列,底部医师/类型/天数/剂量为网格(index.vue:2807-2966,2990-3035)。未保存编辑态才提供 Drawer footer(index.vue:899-905)。
6.4 业务订单
订单 Tab/卡片顶部先显示“全局就诊序号偏移”工具条:label、tooltip、0–20 数字框(宽 120 px)、保存按钮(components/PatientOrderList.vue:7-42)。工具条换行、12px 14px 内边距、1 px lighter 边框、8 px 圆角、light fill(PatientOrderList.vue:252-276)。
订单表为 bordered + striped,字段顺序和列宽来自 PatientOrderList.vue:44-106:
- 订单号,min 200。
- 全局就诊序号,96。
- 数量统计,96,Tag。
- 金额,120,右对齐红字。
- 医生,110。
- 医助,110。
- 履约状态,110,Tag。
- 创建时间,min 170。
- 详情,100,固定右侧。
默认 page size 为 10,底部带分页,点击详情打开只读订单详情(PatientOrderList.vue:108-148)。
订单详情复用 PrescriptionOrderDetailDrawer 的 readonly 受限版,而不是订单页内展开(PatientOrderList.vue:113-124)。该共享 Drawer 宽 80%,Header 16px 24px,标题 18 px / 600,订单号与药房单号用圆角 Tag;加载态为 12 行 skeleton,body 水平内边距 24 px并独立纵向滚动(src/views/consumer/prescription/components/PrescriptionOrderDetailDrawer.vue:13-50,1752-1757)。内容顺序为:
- 金额概览:总金额、已付总额、退款金额、需代收、已付笔数;响应式 2 / 3 / 5 列(
PrescriptionOrderDetailDrawer.vue:154-197)。 - 两栏主区:左侧处方详情,右侧未关联收款与关联收款;收款表顺序为 ID、单号、类型、金额、状态、方式(readonly 隐藏)、创建人、创建时间(
PrescriptionOrderDetailDrawer.vue:200-545)。 - 履约与收货信息:3 列 descriptions,label 宽 120 px(
PrescriptionOrderDetailDrawer.vue:551-680,1782-1785)。 - 物流轨迹与操作日志(有数据/开启附加加载时)(
PrescriptionOrderDetailDrawer.vue:683-824)。
readonly 明确隐藏顶部告警、流程步骤、挂号关联、内部成本、药材明细、收款方式和外部物流更新等完整版内容,但金额概览、主辅方用量/服法和基础详情仍共享(PrescriptionOrderDetailDrawer.vue:2-11)。面板统一 8 px 圆角,Header 14px 16px、Body 16 px(PrescriptionOrderDetailDrawer.vue:1759-1780)。
6.5 视频、聊天与历史表
视频录制回放。 CallRecordPanel 编辑态有上传 toolbar;字段为播放(min 320)、开始时间 170、结束时间 170、通话类型 100、房间 180、时长 110、状态 90、录制 100、上传 180(仅编辑)(components/CallRecordPanel.vue:1-74)。空态内边距 28px 12px,标题 14 px、说明 12 px / 1.6(CallRecordPanel.vue:188-214)。内嵌视频最大高 180 px、圆角 4 px、黑底;播放覆盖层为 rgba(0,0,0,.62)、白色 12 px(components/RecordingVideoPlayer.vue:322-359)。
聊天。 顶部 info alert + 同步/刷新 toolbar,消息区最大高 min(60vh,520px)、gap 16 px。单条最大宽 88%;患者消息靠左、灰底,医生消息靠右、primary 浅底;meta 12 px,气泡 14 px、1.5 行高、10px 12px 内边距、8 px 圆角;图片最大 240 × 200 px(components/ImChatRecordPanel.vue:1-70,200-293)。
医助指派历史。 字段依次为时间 175、原医助 min 120、新医助 min 120、继承 72 Tag、快照订单创建人 min 130、快照创建时间 190、操作人 110、账号 120、IP 130(components/AssignLogPanel.vue:1-43)。
挂号历史。 字段依次为 ID 72、状态 100 Tag、患者 min 150(姓名+手机堆叠)、医生 110、医助 110、预约时间 min 130(日期+时段堆叠)、预约类型 100、渠道 110、确认 92、处方 80、备注 min 100、创建时间 165(components/AppointmentRecordPanel.vue:1-75)。堆叠单元垂直 gap 2 px、行高 1.35(AppointmentRecordPanel.vue:172-178)。
6.6 components/ 全目录的可达性边界
三主视图的实际 import 清单见 edit.vue:787-805 与 readonly.vue:151-167。为避免把目录中保留组件误认成当前详情功能,本次也核了其余文件:
| 组件 | 三主视图当前可达性 | 结论 |
|---|---|---|
PatientInfoCard、PatientCaseCard |
readonly 直接使用 | 当前只读摘要/病例 |
DailyMatrix、CaseRecordList、PatientOrderList、CallRecordPanel、ImChatRecordPanel、AssignLogPanel、AppointmentRecordPanel |
edit/readonly 直接使用(依页面和权限而异) | 当前主链 |
RecordingPlaybackBlock → RecordingVideoPlayer |
CallRecordPanel 间接使用 | 当前视频主链(CallRecordPanel.vue:32,78; RecordingPlaybackBlock.vue:5,35) |
DiagnosisTodoList |
DailyMatrix 间接使用 | 当前日常记录主链 |
TrackingNoteTimeline |
edit 有 import,但模板区整段注释 | 当前不可见(edit.vue:644-654,803) |
BloodRecordList |
未被三主视图 import | 旧/独立颗粒列表;其能力已由 DailyMatrix 内置 600 px 血糖血压 Dialog 承接(BloodRecordList.vue:1-170; DailyMatrix.vue:131-185) |
DietRecordList |
未被三主视图 import | 旧/独立列表;当前 DailyMatrix 内置 800 px 饮食 Dialog(DietRecordList.vue:1-112; DailyMatrix.vue:187-227) |
ExerciseRecordList |
未被三主视图 import | 旧/独立列表;当前 DailyMatrix 内置 600 px 运动 Dialog(ExerciseRecordList.vue:1-86; DailyMatrix.vue:229-260) |
TrackingMatrix |
未被三主视图 import | 非当前矩阵;当前入口明确 import DailyMatrix(edit.vue:796; readonly.vue:161) |
AssistantWatchCallDialog |
未被三主视图 import | 旁路观看 Dialog,不属于诊单详情/编辑/预约;自身是 auto-fill、最小 280 px 的观看网格,gap 12 px(AssistantWatchCallDialog.vue:1-19,242-282) |
因此 PySide 对齐应以“当前可达主链”为实现范围,不能因为同目录存在旧颗粒列表而重复增加血糖、饮食、运动 Tab,也不能把观看 Dialog 或 TrackingMatrix 插入诊单详情。
7. 加载、空态、错误和权限状态
| 场景 | 后台表现 | 源码 |
|---|---|---|
| 独立详情加载 | 页面级 loading | readonly.vue:1-2 |
| 独立详情失败 | Hero 下方错误空态卡 | readonly.vue:31-36 |
| 无未服务记录 | Hero 灰色“从未记录”状态 | readonly.vue:323-355 |
| 抽屉只读 | 状态 badge + disabled fieldset + 无保存 | edit.vue:11-54,57-84,766-781 |
| 患者隐私锁定 | warning Alert,身份字段不可改 | edit.vue:71-84 |
| Tab 失权 | 隐藏 Tab;当前失权时回 basic | edit.vue:655-759,883-913 |
| 预约未选医生 | 时间区提示先选医生 | appointment.vue:100-171 |
| 无排班/无时段 | 时间区空态 | appointment.vue:100-171 |
| 当天已有预约 | warning 且禁止确认 | appointment.vue:10-18,359-386 |
| 其他日期已有预约 | info 提示,不等同当天阻断 | appointment.vue:359-375 |
| 表格无数据 | 各组件 Element empty/自定义空态 | PatientOrderList.vue:1-6; CallRecordPanel.vue:55-74 |
操作权限应控制“是否渲染/是否可编辑”,而不是只把无权按钮做成 disabled;这正是 Tab 通过 v-if 实现的模式。
8. PySide6 组件映射
8.1 结构映射
| Vue / Element 结构 | PySide6 建议 | 必须保留的视觉行为 |
|---|---|---|
el-drawer 右侧抽屉 |
模态 QDialog + 右侧面板,或主窗口上的遮罩 QFrame + 固定宽面板 |
桌面约 60% 宽;edit 在窄屏切全宽;Header/Body/Footer 三段分离 |
| Drawer body | QScrollArea + body widget |
只让 body 滚动,footer 不随滚动 |
| Drawer footer slot | 独立 QFrame + QHBoxLayout |
上边框、白底、固定在底部;不要放进 ScrollArea |
el-tabs |
QTabWidget / 自定义 QTabBar + QStackedWidget |
可横向滚动、3 px active indicator、按 canonical permission 移除页签 |
el-form + el-row/el-col |
QFormLayout 套 QGridLayout |
桌面 160 px 编辑标签 / 100 px 预约标签;窄屏改上标签单列 |
| input/select/date/input-number | QLineEdit、QComboBox、QDateEdit、QSpinBox/QDoubleSpinBox |
常规高 32 px、圆角 10 px;footer 按钮 40/44 px |
| radio/checkbox button groups | QButtonGroup + 可换行 FlowLayout |
12 px 字号,组间 12–16 px;小窗必须换行 |
| textarea | QTextEdit/QPlainTextEdit |
2/3/4 行按源码用途设置 minimumHeight,而非无限增高 |
| alert / empty | QFrame + QLabel / 统一 EmptyState |
warning/info/error 色语义与文案位置一致 |
| card | QFrame |
白底、1 px #e6ebf2、14 px radius、18 px padding |
| table | QTableView + QAbstractTableModel |
stripe、固定/最小列宽、状态 QStyledItemDelegate tag、右侧动作列 |
| timeline | QListView 或纵向 QWidget 列表 + paintEvent 轴线 |
22 px 左缩进、2 px 轴、10 px node,图片缩略图 64 px |
| appointment slot grid | QScrollArea + FlowLayout / QGridLayout 动态列 |
cell min 110 × 70;选中/禁用/可用状态显式 |
| loading | overlay QFrame + spinner/文字 |
遮住当前内容但保留布局尺寸,异步返回后解除 |
8.2 推荐常量(来自源码,不是重新设计)
FONT_FAMILY = "PingFang SC, Arial, Hiragino Sans GB, Microsoft YaHei"
FONT_BASE = 14
FONT_FORM = 12
CONTROL_HEIGHT = 32
FOOTER_BUTTON_HEIGHT = 40 # <=768 对应布局时 44
CARD_RADIUS = 14
CARD_PADDING = 18
CONTROL_RADIUS = 10
PANEL_GAP = 16
BORDER = #e6ebf2
BODY_BG = #f8fafc
PAGE_BG = #f6f6f6
TEXT_PRIMARY = #333333
TEXT_REGULAR = #666666
TEXT_MUTED = #999999
PRIMARY = #409eff # 继承 Element 语义主色
READONLY_ACCENT = #2563eb
READONLY_ACCENT_STRONG = #1d4ed8
8.3 PySide 字段装配顺序
为避免实现时按数据模型字母序排字段,应按以下 UI 顺序装配:
编辑病历:
诊单ID
→ 姓名 / 身份证
→ 手机 / 性别
→ 年龄
→ [生命体征] 婚姻 / 身高 / 体重
→ 地区 / 高压 / 低压
→ 空腹血糖
→ 诊断类型
→ 状态 / 渠道
→ 统计端就诊卡
→ 在用药物
→ [主诉] 当地诊断日期 / 糖尿病病史
→ 当地医院诊断结果
→ 当地医院名称
→ [现病史] 口腔 → 饮水 → 体重变化 → 脂肪肝 → 饮食
→ 肢体 → 睡眠 → 眼睛 → 头部 → 出汗 → 皮肤 → 小便 → 大便 → 腰肾
→ 其他补充
→ [既往史] 既往史
→ [其他病史] 外伤 / 手术 / 过敏 → 家族 / 妊娠
→ [诊断信息] 病史补充
预约:
上次面诊 → 预约方式 → 预约类型 → 预约患者 → 渠道来源
→ [条件] 自媒体详情 → 预约医生 → 日期 → 时段 → 备注
9. 验收清单
- 独立 readonly 是纵向卡片流,不出现 Tabs;抽屉 viewOnly 才是 Tabs + disabled 表单。
- 编辑 Drawer 桌面 60%,<=768 等效状态下全宽;预约 Drawer 源码没有该响应式覆盖,需明确属于适配增强。
- 编辑桌面 label 160 px,预约 label 100 px;编辑移动端 label 在控件上方。
- 编辑的 body 独立滚动,footer 始终可见;实现中没有把按钮放到滚动区末尾。
- Tab 顺序与 canonical permission 一致;“跟踪备注”不渲染。
- 编辑病历字段严格按 §4.5;不把脚本中未渲染字段自行加入。
- 只读病例按 4/3 列网格及 §3.4 顺序;小窗若做降列,需视为桌面端增强而非源码既有行为。
- 预约状态至少覆盖:未选医生、无排班、可约、不可约、选中、当天冲突、其他日期提示、loading。
- 订单、备注、视频、聊天、指派历史、挂号历史的列顺序/动作显隐与 §6 一致。
- 所有表格提供 loading、empty、error;权限失去时移除入口并将当前页回退到可见页。
以上规格记录的是当前后台源码的可见事实;PySide 可为桌面小窗增加降列和全宽适配,但不得改变字段顺序、权限门槛、状态语义或主操作位置。