35 KiB
管理端“诊单列表”视觉规格(源码基准)
审计日期:2026-08-10
唯一业务页面基准:D:/web/zyt/admin/src/views/tcm/diagnosis/index.vue
方法:只读检查 Vue 模板、同文件 scoped SCSS、直接挂载组件、全局样式、主题生成逻辑和当前锁定的 Element Plus 源码;未启动浏览器、未改业务源码。
1. 结论摘要
- 该页面没有页面内标题、说明文案或独立标题栏。路由内容从一张无边框、无阴影的筛选卡直接开始;“新增诊单”等主操作位于第二张列表卡顶部,而不是页面标题旁。证据:
index.vue:2-154。 - 页面是“浅灰页面底 + 两张白卡”的高密度后台列表。外层路由容器提供左右
8px、上下16px的留白;筛选卡和列表卡之间为12px。证据:D:/web/zyt/admin/src/layout/default/components/main.vue:2-10、index.vue:154、D:/web/zyt/admin/tailwind.config.js:103-113。 - 顶部不是常规 tabs,而是可换行的圆角文字 chip:6 个日期入口,再接“待预约 / 已完成 / 待分配医助”,计数是文字后面的普通半透明数字,不是独立 badge。当天默认选中。证据:
index.vue:6-70,964-976,2174-2182,2222-2317。 - 表格声明列的最小总宽约为 1403px;右侧固定“视频旁观”
120px与“操作”340px,合计460px。窄于该宽度时由 Element Table 横向滚动,右侧两列保持 fixed。证据:index.vue:191-342。 - 表格使用斑马纹;普通偶数行是
#FAFAFA,普通悬停是#F8F8F8。未确认、未挂号行还声明了左侧语义色和横向渐变,但静态渐变写在tr,斑马纹及 fixed cell 的td背景可能遮住它;两类行的 hover 渐变直接写在td,表现更稳定。证据:index.vue:2723-2735、Element Plustable.scss:560-588,665-668。 - 空态不是
el-empty插画,而是表格默认的 60px 高“暂无数据”文本区;加载态是覆盖表格的半透明蒙层和42px主色环。证据:Element Plustable.scss:52-70、loading.scss:19-73、中文 localezh-cn.mjs:137。
2. 源码证据层级
| 层级 | 文件 | 本规格使用内容 |
|---|---|---|
| 页面模板与局部样式 | D:/web/zyt/admin/src/views/tcm/diagnosis/index.vue:1-2766 |
DOM 次序、列宽、状态类、局部尺寸和颜色 |
| 路由内容容器 | D:/web/zyt/admin/src/layout/default/components/main.vue:1-12 |
页面底色、外层滚动、px-2 py-4 |
| 共享组件 | D:/web/zyt/admin/src/components/pagination/index.vue:1-50;D:/web/zyt/admin/src/components/daterange-picker/index.vue:1-49 |
分页布局、页容量、日期范围控件行为 |
| 项目全局样式 | D:/web/zyt/admin/src/styles/index.scss:1-5、var.css:1-49、element.scss:58-68,106-115,140-151,177-201、public.scss:1-3 |
全局字体、颜色、表格、输入焦点、移动分页 |
| 项目主题 | D:/web/zyt/admin/src/config/setting.ts:1-15、src/utils/theme.ts:3-75、src/App.vue:25-34 |
默认主色、明暗主题色派生、运行时覆盖 |
| Tailwind token | D:/web/zyt/admin/tailwind.config.js:5-155 |
字体族、颜色映射、间距值 |
| UI 框架 | D:/web/zyt/admin/pnpm-lock.yaml:47-49,2412-2415;node_modules/element-plus/theme-chalk/src/** |
当前锁定 Element Plus 2.13.7 的默认组件尺寸 |
package.json:27 写的是兼容范围 ^2.9.4,当前 lock 与已安装源码均为 2.13.7;本规格的框架默认尺寸以锁文件和当前安装源码为准。
3. 页面骨架与 ASCII wireframe
3.1 宽屏主态
主内容滚动区,#F6F6F6;左右 8,上下 16
┌────────────────────────────────────────────────────────────────────────────────────────────┐
│ 筛选卡 #FFF / r4 / 无边框无阴影;内边距 12V × 16H │
│ [昨天挂号 n] [前天挂号 n] [当天挂号 n] [明天挂号 n] [后天挂号 n] [全部 n] │
│ [待预约 n] [已完成 n] [待分配医助 n] [患者姓名 / 手机号 160] [查询 32h] │
│ ──────────────────────────────────────────────────────────────────────────────────────── │
│ 挂号:[全部] [已挂号] [未挂号] │ 确认:[全部] [已确认] [未确认] 更多筛选⌄ │
│ · · · 展开时:诊断类型 / 证型 / 医助 / 最近挂号日期 / 最近指派日期 / 渠道 / 重置 · · · │
└────────────────────────────────────────────────────────────────────────────────────────────┘
12px
┌────────────────────────────────────────────────────────────────────────────────────────────┐
│ [新增诊单] [批量指派医助] [批量取消指派] 已选 n 条(按需显示) │
├────┬──────┬──────┬───────────┬──────────────┬──────┬────────┬──────┬──────┬──────────┬──────┬────────────────────┤
│ □ │ ID │ 患者 │ 性别/年龄 │ 挂号 │ 确认 │ 复诊 │ 助理 │ 开方 │未服务天数│旁观* │ 操作* │
├────┼──────┼──────┼───────────┼──────────────┼──────┼────────┼──────┼──────┼──────────┼──────┼────────────────────┤
│ □ │123 NEW│张三 │ 男 · 42岁 │[待问诊] 医生 │未确认│日期/医生│医助 │已开方│ 8 │进入 │查看 诊单 开方 … 更多│
│ │ │ │ │时间 / 渠道 │ │ │ │ │ │ │ │
├────┴──────┴──────┴───────────┴──────────────┴──────┴────────┴──────┴──────┴──────────┴──────┴────────────────────┤
│ 共 n 条 [15条/页] [<] 1 2 … [>] 前往 [ ] 页 │
└────────────────────────────────────────────────────────────────────────────────────────────┘
* 右侧固定列,共 460px
3.2 结构说明
- 外层
main是整页垂直滚动容器;诊单表没有本页固定高度或纵向虚拟滚动,15 条数据会把页面自然撑高。证据:layout/default/components/main.vue:2-11、index.vue:179-190。 - 两张卡都使用
shadow="never"与!border-none;保留 Element Card 的白底、裁切和4px圆角。框架默认:Element Pluscard.scss:9-17、common/var.scss:1226-1235。 - 页面根节点只设
min-height:100%、页面底色和水平居中;不设自身宽度、最大宽度或 padding。证据:index.vue:2200-2206。 - 顶部全局 header、面包屑和多页签属于应用壳,不在
index.vue中;它们是否出现受全局 setting 控制,不能当作本页标题复刻。
4. 可复刻的基础 token
4.1 字体与基础尺寸
| 项 | 源码确定值 | 证据 |
|---|---|---|
| 字体族 | PingFang SC, Arial, Hiragino Sans GB, Microsoft YaHei, sans-serif |
tailwind.config.js:79-81、var.css:2 |
| body / Element base | 14px |
public.scss:1-3、var.css:16 |
| small / extra-small | 13px / 12px |
var.css:17-18 |
| 默认控件高度 | 32px |
Element Plus common/var.scss:233-241 |
| small 控件高度 | 24px |
同上 |
| 默认圆角 | 4px |
Element Plus base.css:1 |
| 卡片圆角 | 4px |
Element Plus common/var.scss:1227-1234 |
字体栅格的真实像素高度仍受 Windows 缩放、浏览器 DPR 与首个可用字体影响;页面 chip 没有固定 height/line-height,只能精确复刻 padding,不能仅凭源码承诺最终外框高度。
4.2 亮色主题
项目在 App.vue mount 时用 setting 重写 Element 语义色。默认主色不是 Element 原生蓝,而是 #4A5DFF。主题派生算法见 src/utils/theme.ts:3-18,29-37,55-74。
| token | 默认运行值 | 使用处 |
|---|---|---|
--el-color-primary |
#4A5DFF |
active chip、主按钮、链接、loading |
| primary light-3 / 5 / 7 / 8 / 9 | #808EFF / #A5AEFF / #C9CEFF / #DBDFFF / #EDEFFF |
hover、focus、轻底色 |
| primary dark-2 | #3B4ACC |
active 状态;页面另有硬编码近似值 #3A4ACC |
| success | #67C23A |
已完成 chip、已确认、成功按钮 |
| warning | #E6A23C |
待分配、未确认、警示行 |
| danger | #F56C6C |
NEW、删除/取消 |
| info | #909399 |
待预约、完成预约、次要态 |
| page / card | #F6F6F6 / #FFFFFF |
页面底 / 卡片与普通行 |
| primary / regular / secondary text | #333333 / #666666 / #999999 |
标题信息 / 常规 / 辅助 |
| placeholder / disabled | #A8ABB2 / #C0C4CC |
空值、禁用 |
| border / light / lighter | #DCDFE6 / #E4E7ED / #EBEEF5 |
控件、卡线、行分隔 |
| fill / light / lighter | #F0F2F5 / #F8F8F8 / #FAFAFA |
hover、表头、斑马纹 |
| loading mask | rgba(255,255,255,.5) |
表格加载蒙层 |
证据:src/config/setting.ts:9-14、src/styles/var.css:9-43。主色的派生结果使用项目同一 css-color-function 算法计算;不是页面硬编码。warning/info 的页面渐变使用 --el-color-*-rgb,其当前框架默认分别为 230,162,60 和 144,147,153(Element Plus base.css:1)。
4.3 暗色与运行时主题边界
.dark下页面底为#0A0A0A、普通背景#1D2124、overlay#1D1E1F,主/常规/次要文字为#E5EAF3 / #CFD3DC / #A3A6AD,lighter border 为#363637。证据:src/styles/dark.css:1-31。App.vue根据useDark()调用主题生成器,主色仍可保持#4A5DFF,但 light-* 在暗色下改用 shade 算法。证据:src/App.vue:29-34、src/utils/theme.ts:12-18,55-77。- setting 会从本地缓存覆盖默认颜色,因此某个真实账号的主色/语义色可能不同。证据:
src/stores/modules/setting.ts:12-50,65-77。上表是无用户自定义时的确定基线。 - 页面内硬编码的
#4A5DFF、#3A4ACC与rgba(74,93,255,...)不会随自定义主题变化,因而自定义主题下会出现两套蓝色。证据:index.vue:2522-2529,2556-2559,2596-2599。
5. 顶部筛选卡
5.1 卡与第一行
筛选卡 body padding 为 12px 16px。第一行 .filter-main 是单行 flex:垂直居中、两端对齐、组间 16px、下边距 8px;自身没有 flex-wrap。左侧 .date-chips 才可换行,chip 间距 6px。证据:index.vue:3-76,2208-2225。
| 元素 | 几何/排版 | 默认/交互颜色 | 证据 |
|---|---|---|---|
| 普通日期 chip | padding 6px 12px;14px/500;r6;transition .2s |
常规 #666 + #F8F8F8;hover #F0F2F5;active 白字 + 主色 |
index.vue:2227-2250 |
| chip 计数 | 与标题相隔 4px;normal style;opacity .8 |
跟随父 chip | index.vue:23-24,2237-2241 |
| 待预约 | 普通 chip 外再有左 margin 8px |
info / info-light-9;active info 实色 | index.vue:26-32,2253-2265 |
| 已完成 | 左 margin 8px |
success / success-light-9;active success 实色 | index.vue:33-39,2268-2280 |
| 待分配医助 | 权限控制;外容器可换行、gap 8px、左 margin 8px |
warning / warning-light-9;active warning 实色 | index.vue:40-70,2283-2308 |
| 待分配月份 | default 月选择器;宽 128px |
Element 默认输入态 | index.vue:51-60,2310-2312 |
| 待分配宽搜索 | default 输入;宽 220px,最大 42vw |
Element 默认输入态 | index.vue:61-69,2314-2317 |
| 主搜索 | default 输入宽 160px |
placeholder“患者姓名 / 手机号” | index.vue:72-75,2320-2326 |
| 查询 | primary default button;高 32px,14px,r4 |
白字/主色底 | index.vue:74、Element Plus button.scss:22-43,76-82 |
日期 chip 的实际顺序是:昨天、前天、当天、明天、后天、全部,不是按自然日期升序;随后才是 3 个业务 chip。证据:index.vue:964-976。页面挂载时直接选中当天并请求列表;各 chip 计数延后到 idle(不支持时延后约 120ms)获取,所以首帧可能只有标签、稍后才出现数字。证据:index.vue:1046-1095,2174-2182。
5.2 第二行快捷筛选
- 第二行上方有
1px solid #EBEEF5;自身padding-top:8px、margin-top:8px、水平 gap6px、垂直居中。证据:index.vue:78-102,2329-2335。 - “挂号:”“确认:”为
13px #999,label 后额外2px。每组都是“全部 / 已… / 未…”。证据:index.vue:79-97,2337-2341。 - 小 chip 最终 padding 是
.chip-sm的4px 10px,13px、r4、透明底;hover/active 用主色文字与 primary-light-9,active 权重 500。证据:index.vue:2343-2366。 - 两组之间为
1×14px的 lighter 分隔线,左右 margin4px。证据:index.vue:2368-2373。 - “更多筛选”是 primary/link/small 按钮,左 margin
8px;展开时 ArrowDown 旋转180°,文字变“收起”。源码没有为该旋转指定独立 transition。证据:index.vue:98-101,2375-2380。
5.3 展开筛选区
展开区使用 v-show,所以是即时显隐而非折叠动画。它为可换行 flex,gap 10px,上 margin/padding 各 8px,顶部是 1px dashed #EBEEF5。证据:index.vue:104-151,2384-2391。
控件从左到右:
- 诊断类型 select(small,
24px高); - 证型 select(small);
- 医助 select(small,可搜索);
- 最近挂号日期范围(共享
DaterangePicker,260px宽、最大 100%,未传 size,故 default32px高); - 最近指派日期范围(同上);
- 最近挂号渠道(small,可搜索,宽
170px); - 重置(small button,
24px高)。
证据:index.vue:104-150,2393-2405;共享日期组件只是透传一个 el-date-picker,见 components/daterange-picker/index.vue:1-11,15-31。因此展开区客观上混有 24px 与 32px 两种控件高度。前三个 select 没有本页固定宽度;Element Select 自身是 width:100% 的可收缩 flex item,最终每行宽度依赖可用空间与浏览器 flex 计算,源码不能给出一个稳定像素值。
6. 列表卡操作栏
- 列表卡距筛选卡
12px,body padding 清零。证据:index.vue:154,2408-2412、Tailwind spacingtailwind.config.js:103-113。 - 操作栏为左右两端布局,padding
10px 16px,底边1px #EBEEF5;未固定高度。default button 高32px,故无换行时栏高至少约52px。证据:index.vue:155-177,2414-2429。 - 左侧依权限显示:primary“新增诊单”、success“批量指派医助”、warning/plain“批量取消指派”。后两者按选中状态禁用。右侧仅在选中数量大于 0 时显示
13px #999的“已选 n 条”。证据:index.vue:157-176。 .list-actions声明gap:8px,但 Element 默认还有.el-button + .el-button { margin-left:12px },此处没有清零。因此相邻按钮的实际起点间空白通常是 20px(8+12),而不是设计者表面写下的 8px。证据:index.vue:2421-2424、Element Plusbutton.scss:72-74。
7. 表格规格
7.1 外框与表头
- 表格外围 padding
10px 16px 0;表格宽度 100%,默认 fixed layout、无竖边框;行之间由1px #EBEEF5底边分隔。证据:index.vue:178-190,2432-2434、Element Plustable.scss:11-20,188-195,217-235。 - 表头底
#F8F8F8、13px/600、文字#666。默认 cell 水平 padding12px,行高23px,纵向 padding8px,所以单行表头的理论最小高度约 39px(23+16,不含亚像素/边线差异)。证据:index.vue:2710-2716、Element Plustable.scss:156-195、common/var.scss:1014-1031。 - 表头“未服务天数”有双态排序箭头,顺序只允许 descending → ascending;激活箭头使用主色。证据:
index.vue:297-304、Element Plustable.scss:548-552。
7.2 列宽与内容
| 次序 | 列 | 声明宽度 | 对齐/固定 | 主要视觉内容 |
|---|---|---|---|---|
| 1 | 选择 | 48px |
center | header 全选 + 行 checkbox |
| 2 | ID | min 70px |
left | ID 为 14px/600;未读指派时附 small/dark/danger NEW |
| 3 | 患者 | min 60px |
left | 患者名 14px/600;头像模板已注释,不显示 |
| 4 | 性别 / 年龄 | 100px |
left | 男 · 42岁,继承表格 14px |
| 5 | 挂号 | min 175px |
left | 预约状态 badge、医生、时间、可取消链接、最近渠道;无则“未挂号” |
| 6 | 确认 | 88px |
center | 13px 已确认/未确认文字 |
| 7 | 复诊 | min 120px |
left | 时间、医生、可选“处方已作废” tag;无则“无” |
| 8 | 助理 | 100px |
left | 13px 次要文字,溢出 tooltip |
| 9 | 开方 | 72px |
center | 13px 已开方/未开方 |
| 10 | 未服务天数 | 110px |
center | 13px/600 tabular number,按天数绿/橙/红;可有健康打卡 tooltip |
| 11 | 视频旁观 | 120px |
center / right fixed | small link 或 12px 次要状态 |
| 12 | 操作 | 340px |
left / right fixed | 5 个 small/link 主动作 + click dropdown |
证据:index.vue:191-406。声明宽度/最小宽度合计约 1403px;min-width 列在更宽窗口可继续分配余量。右固定区域为 120+340=460px,Element 会在滚动边缘加 fixed-column 阴影;阴影值来自框架 common/var.scss:981-1000。
7.3 行高与密度
- 本页再次把 body cell 设为
padding:8px 0,cell 内层保留 Element 的水平12px与23pxline-height。纯单行内容的最小行高约 39px。证据:index.vue:2720-2722、Element Plustable.scss:188-195。 - 挂号 cell 有
min-height:36px、内 padding4px 8px、r6,所以含该列的常规数据行通常至少约 52px(cell 36 + table 上下 16);实际由内容较高者决定。证据:index.vue:2485-2489。 - 同一诊单多条预约时,每一后续预约额外带
8pxtop margin、8pxtop padding 和1px dashed #EBEEF5,行高会显著增加,不是固定行高。证据:index.vue:227-247,2490-2494。 - 操作区允许换行;链接数量受权限与记录状态影响,所以操作列也可能增高整行。证据:
index.vue:344-403,2683-2688。
7.4 斑马、hover 与业务高亮
| 状态 | 静态 | hover | 判定优先级 |
|---|---|---|---|
| 普通奇数行 | 白 #FFF |
#F8F8F8 |
无业务类 |
| 普通偶数行 | #FAFAFA |
#F8F8F8 |
stripe |
| 未确认 | 预期左侧 3px #E6A23C;从左到右 warning RGB .06 → transparent |
warning RGB .10 → transparent,直接覆盖 td |
第一优先 |
| 已确认但未挂号 | 预期左侧 3px #909399;info RGB .04 → transparent |
info RGB .08 → transparent,直接覆盖 td |
第二优先 |
判定函数先检查“是否确认”,只有已确认才检查“是否挂号”,所以一行不会同时得到两个业务类。证据:index.vue:1313-1337。页面声明见 index.vue:2723-2735;斑马和 hover 框架规则见 Element Plus table.scss:560-588,665-668。
实现时必须区分“源码意图”和“浏览器可见结果”:
- 静态业务渐变在
tr,而偶数斑马行和 fixed cell 的背景落在td;不透明td会遮住下面的tr渐变。 - 业务 hover 选择器直接命中
td且带!important,因此 hover 更可靠。 border-left施加在tr,在border-collapse:separate的 table 中具体像素绘制还受浏览器表格格式化上下文影响。
PySide 复刻应按“意图”直接给每个可见 cell/row delegate 绘背景和 3px 左条,避免复现 CSS 遮挡缺陷;若目标是截图逐像素一致,则需先用指定 Chromium、固定数据测一张运行态截图。
7.5 单元格内部视觉
患者与 ID
.patient-name为 14px/600、#333、line-height1.3。ID 与患者列都复用该样式。证据:index.vue:194-212,2461-2470。- 32×32、r8、主色渐变的头像 CSS 存在,但患者模板已注释,不参与实际页面。证据:
index.vue:207,2447-2459。 NEW是 small (20px高)、danger、dark tag:白字、danger 实色底;字体 12px、r4。证据:index.vue:198、Element Plustag.scss:66-87,142-165、common/var.scss:1110-1138。
挂号块
- 每个预约 badge:11px/600、padding
2px 6px、r4、下 margin2px;医生 14px/600#333;时间 12px、上 margin2px。证据:index.vue:2496-2519。 - 活跃预约 badge 为
#3A4ACC/rgba(74,93,255,.15),时间硬编码#4A5DFF;整块为 135° 蓝色渐变.12 → .06,边rgba(74,93,255,.3)。证据:index.vue:2522-2531,2556-2559。 - 已完成预约用 info-dark-2 / info-light-7;爽约用 warning-dark-2 / warning-light-7。整块也分别换成 info 或 warning 透明渐变。证据:
index.vue:2533-2569。 - 最近渠道为上 margin
6px、12px、line-height1.35、#999;未挂号为 13px#A8ABB2。证据:index.vue:2571-2581。
语义文字与 tag
- 已确认:13px/500 success;未确认:13px/600 warning。证据:
index.vue:2584-2594。 - 已开方:13px/500、硬编码
#4A5DFF;未开方:13px#A8ABB2。证据:index.vue:2596-2605。 - 复诊时间 13px/500
#333,医生 12px#999,纵向 gap4px、line-height1.35;“处方已作废”是 small/plain/info tag。证据:index.vue:268-285,2651-2676。 - 未服务天数:最小
28px、13px/600、等宽数字;空值灰#A8ABB2/400,<=2绿#16A34A,3-6橙#EA580C,>=7红#DC2626。证据:index.vue:305-316,1319-1329,2607-2632。 - 视频旁观为 12px、line-height
1.4,左右 padding2px;不可进入时是#999。证据:index.vue:318-341,2690-2704。
8. 按钮、dropdown、tooltip
8.1 操作列链接
直接动作依次为:查看(primary)、诊单(primary)、开方/查看处方(primary)、预约(success)、补全身份证(warning),最后是 info“更多”。权限会移除部分按钮。证据:index.vue:345-403。
- 均为
size="small"、link:12px,透明边/底,padding2px,高度 auto;hover 使用各语义色的 light-3。证据:Element Plusbutton.scss:223-248、element.scss:113-127。 .action-cell设 flex-wrap +gap:4px;但相邻.el-button + .el-button仍有12px左 margin,因此连续按钮间通常是 16px(4+12)。dropdown 外壳与前一按钮之间只有 flex gap4px。证据:index.vue:2683-2688、Element Plusbutton.scss:72-74。- 340px 操作列不足时允许链接换行;没有强制单行或省略号。
8.2 “更多”菜单
- click 触发、
bottom-end对齐。菜单项按权限/状态可包含:指派、取消指派、视频二维码、二维码、取消挂号、挂号日志、创建订单、删除。证据:index.vue:379-403。 - Element 默认 dropdown item 为 14px、line-height
22px、padding5px 16px,故普通项约32px高;菜单上下净 padding 约5px,r4、overlay 白底,popper 有 light border 与 shadow。hover 为 fill-light + primary。证据:Element Plusdropdown.scss:7-24,42-70,137-176。 - 删除项有 divided 顶线,文字由
.text-danger强制为 danger。证据:index.vue:400,2706-2708。 - tooltip 使用 Element 默认 popper:12px、line-height
20px、padding5px 11px;实际位置由视口碰撞计算,不能从源码固定。
9. 分页、空态与加载态
9.1 分页
- 列表默认
page=1, size=15;共享组件页容量选项为[15,20,30,40]。证据:src/hooks/usePaging.ts:14-34、components/pagination/index.vue:18-28。 - 布局固定为
total, sizes, prev, pager, next, jumper,最多显示 5 个 pager,单页也不隐藏。证据:components/pagination/index.vue:3-14,24-28。 - 容器右对齐,padding
10px 16px 16px。默认分页按钮32×32px(最小宽),14px,r2,项组间 gap token16px;active 仅主色文字 + bold,并未启用 background 模式。证据:index.vue:408-410,2436-2440、Element Pluscommon/var.scss:1034-1057、pagination.scss:5-67。 - page-size select 框架宽
128px,jumper 输入56px。证据:Element Pluspagination.scss:73-75,118-150。 - 视口
<=768px时,全局 CSS 隐藏 size selector 与 jumper,仍保留 total、prev、pager、next。证据:src/styles/element.scss:177-184。
9.2 空态
页面没有提供 table #empty slot,也没有在主列表使用 el-empty。因此空列表为:
- sticky empty block,min-height
60px; - 居中纯文本“暂无数据”;
- 文字
#999,line-height60px,宽 50%; - 表头、底线和分页仍存在。
证据:index.vue:179-190、Element Plus table.scss:52-70、src/App.vue:5,25-28、Element 中文 locale zh-cn.mjs:137。
9.3 加载
v-loading="pager.loading"直接挂表格;普通请求开始时 loading=true,完成后 false。证据:index.vue:179-184、src/hooks/usePaging.ts:35-72。- 蒙层绝对覆盖 table,z-index 2000,亮色为
rgba(255,255,255,.5);中央环42px,主色描边2px,2 秒旋转、1.5 秒 dash 动画。证据:src/styles/var.css:41-43、Element Plusloading.scss:19-73,85-103、common/var.scss:1340-1349。 - 页面每 20 秒静默刷新列表和计数;标签页不可见时跳过,静默刷新不打开 loading,因此不会周期性白闪。证据:
index.vue:1098-1105,2182-2195、src/hooks/usePaging.ts:36-42,64-71。 - 首次
pager.loading初值是 false,但 mount 后立即调用getLists(),正常网络下会很快进入蒙层;能否肉眼看到取决于响应时长。
10. 响应式与滚动行为
index.vue的 scoped 样式没有 media query。页面级响应式主要来自 flex-wrap、宽度上限、Element Table 横向滚动及全局分页规则。- body 被全局设为
min-width:375px、overflow:hidden;应用主内容通过el-scrollbar承担页面滚动。证据:src/styles/public.scss:1-3、layout/default/components/main.vue:2-11。 - 第一筛选行本身不换行。左侧日期 chip 可换行,但右侧 160px 搜索 + 32px 查询按钮仍与左侧同一 flex 行;在极窄内容宽度下可能压缩、增高左侧或溢出,源码没有把搜索行堆到下一行的断点。
- 待分配容器可换行,宽搜索最多
42vw;展开筛选区可换行,两个日期范围各为260px且max-width:100%。证据:index.vue:2298-2317,2384-2405。 - 表格 min 总宽约 1403px。Element Table 内部提供横向 scrollbar;右侧 460px fixed 区保持可见,导致很窄时可见的左侧业务列空间进一步减少。
- 外层应用在窄屏会折叠侧栏,但那是壳层行为,不改变本页筛选/表格 DOM。证据:
src/App.vue:36-53。 - dark mode 有完整全局变量,但页面的硬编码蓝/绿/橙/红不会自适应;其亮度对比应另做暗色运行态验收。
11. 直接挂载的覆盖层(不占主页面静态布局)
主列表下方常驻挂载多个异步组件或 dialog/drawer;关闭时不占主页面空间,操作后覆盖在页面之上:
| 入口 | 覆盖层 | 关键尺寸 | 证据 |
|---|---|---|---|
| 新增/诊单 | edit.vue 诊单 drawer |
60% |
index.vue:414、edit.vue:1-10 |
| 详情组件 | detail.vue popup |
800px |
index.vue:415、detail.vue:1-10 |
| 开方/处方 | tcm-prescription drawer |
1200px |
index.vue:416、components/tcm-prescription/index.vue:1-8 |
| 预约 | appointment.vue drawer |
60% |
index.vue:417、appointment.vue:1-10 |
| 视频旁观 | AssistantWatchCall dialog | 760px;视频 grid min 220px |
index.vue:418-422、AssistantWatchCallDialog.vue:1-19,242-284 |
| 挂号日志 | drawer | 460px |
index.vue:424-447 |
| 小程序二维码 | dialog | 400px;二维码 256×256 |
index.vue:449-481 |
| 指派医助 | dialog | 500px |
index.vue:483-531 |
| 创建订单 | dialog | 600px |
index.vue:533-587 |
| 补全身份证 | dialog | 400px |
index.vue:589-615 |
| 企微记录 | drawer | 600px |
index.vue:617-722 |
这些覆盖层说明“操作按钮点击后”的页面层级,但其完整内部视觉不应混入诊单 index 主页面的静态复刻范围。
12. PySide 映射建议
12.1 页面与筛选
| Vue/CSS 意图 | PySide 建议 | 复刻要点 |
|---|---|---|
外层 el-scrollbar + 两张 card |
QScrollArea → 单一 QWidget/QVBoxLayout;卡用 QFrame |
viewport #F6F6F6;外 margin 16V/8H;卡 r4、白底、无 border/shadow;卡间 12 |
| date chips | 自定义 FlowLayout + checkable QToolButton |
padding 6×12、r6、gap6;计数拼接为同一 label,保持源码顺序 |
| 业务色 chip | 同一 button class 加 dynamic property | pending_booking/info、completed/success、pending/warning;active 白字实底 |
| 第一行搜索 | QHBoxLayout 右侧固定 QLineEdit(160) + QPushButton |
高 32、gap8;若追求源码一致,不自行添加窄屏 stack |
| 第二行筛选 | QHBoxLayout/FlowLayout + QToolButton |
top line、上下 8;13px;active primary-light-9 |
| 更多筛选 | 可显隐 QWidget + FlowLayout |
无动画;top dashed border;gap10;small 控件 24,日期范围 32 |
Qt 没有内建通用 FlowLayout,建议采用 Qt 示例式 FlowLayout,并把 chip 的 sizeHint() 包含字体宽度、左右 12/10px padding;不要用固定总宽,否则计数从一位变三位时会截断。
12.2 表格
- 使用
QTableView + QAbstractTableModel,不要堆 15 行 QWidget。列的 initial/min widths 按本规格表设置;表头高建议从39px起,常规 row 从52px起,并由 delegatesizeHint()为多预约/操作换行增高。 - 选择列用 check-state delegate;ID/患者、确认、复诊、开方、未服务天数分别用专用 delegate 绘文字和 tag,避免嵌套控件带来的滚动性能问题。
- 挂号列用一个复合 delegate:r6 的状态背景、11px badge、14px/600 医生、12px 时间、多预约虚线分隔。可点击“取消挂号”若必须嵌入,可在命中区域处理 mouse event,而不是每格常驻 QPushButton。
- 两个右固定列可用同步滚动的双
QTableView:主表隐藏最后两列,右表只显示 120/340 两列,共宽 460;共享 model、selection model、vertical scrollbar 与 row height。单一 QTableView 无 Element 的 sticky fixed-column 等价物。 - 行背景应在 delegate 对每个 cell 绘制:普通白/
#FAFAFA,hover#F8F8F8;业务行覆盖渐变并在第一可见 cell 绘 3px 语义条。不要把渐变只画在 viewport 底层,否则会重现 HTMLtd遮挡问题。 - 操作列优先使用 delegate + 命中区域或常驻
QWidget行容器;若用按钮,链接样式为 12px、2px padding、无背景/边框,并预留源码实际的较大按钮间距。 - 横向滚动时保持右表固定;表头与 body 必须共用列宽。多预约行要同步两张表的 row height。
12.3 dropdown、分页、空态、加载
- “更多”使用
QMenu,item 高约 32、左右 padding16、14px;按权限/状态动态构建,删除项前addSeparator()且 danger 文本。 - 分页建议自定义
PaginationBar:total、15/20/30/40 combo、prev、最多 5 页、next、jump;高度32,容器右对齐并保留10T/16H/16B。窗口内容宽度 <=768 时隐藏 combo 与 jump。 - 空态在
QTableView.viewport()中央放一个透明QLabel("暂无数据"),有效高度 60;不要用大插画。仍显示 header 和分页。 - 加载态用覆盖 table rect 的半透明 widget:亮色
rgba(255,255,255,.5),中央约 42px 主色 spinner。新请求显示;20 秒静默刷新不显示。 - 用 generation/request id 丢弃过期异步响应,并只在当前请求结束时关闭 overlay;这不是 Vue 当前
latestOnly:false的视觉保证,但能避免 PySide 快速筛选时旧响应造成闪回。
12.4 主题与字体
- 定义集中 token,而不是把
#4A5DFF散落在 QSS;但为了忠实,挂号块与“已开方”目前应保留硬编码蓝,或在设计确认后统一为 theme primary。 - Windows 上首选“Microsoft YaHei UI”还是源码的“Microsoft YaHei”会改变字宽;逐像素复刻应显式用
Microsoft YaHei,14px CSS 大致映射为 Qt pixelSize 14,而不是 pointSize 14。 - Qt 的 devicePixelRatio 与 CSS px 不同。截图验收需固定 Windows 缩放(建议 100%)、字体、窗口内容宽度和主题。
13. 能从源码确定 / 不能从源码确定
可以确定
- DOM 顺序、无页面内标题、两张卡、每个筛选和操作入口;
- 页面局部 padding/gap/宽度、列声明宽度、固定列、颜色、字体大小/字重;
- 日期 chip 的顺序与当天默认态;
- 表格 stripe、业务类判定优先级、语义文本与预约块状态;
- 共享分页的页容量、布局、空态文案、loading 结构;
- 默认亮/暗 token 及运行时主题派生方式;
- 权限或数据条件控制哪些按钮/tag 出现。
仅运行态可最终确定
- 最终换行和行高:取决于 viewport、数据长度、按钮权限、预约条数、字体回退、DPR;chip 和多数 row 都没有固定 height。
- 实际主题色:setting 存在本地缓存,账号可改主色及语义色;dark 状态也来自浏览器存储/系统偏好。
- 业务行静态渐变是否完整可见:受
tr背景、striped/fixedtd背景与 Chromium table paint 顺序影响;源码只能确定规则叠加关系。 - fixed-column 阴影和 scrollbar 尺寸:由 Chromium/Element 的滚动状态、平台 scrollbar 策略决定。
- tooltip/dropdown 的最终坐标:popper 会做视口碰撞与翻转。
- 加载态停留时间和计数出现时间:由 API 延迟、idle callback 调度决定;静默轮询通常无蒙层。
- 应用壳标题/面包屑/多页签:由路由菜单、setting 和权限生成,不是
index.vue的页面内视觉。
若后续要求“像素级截图一致”,应在固定 Element Plus 2.13.7 + Chromium 版本 + 100% Windows 缩放 + 默认亮色主题 + 固定权限/样本数据 下补一轮运行态测量;本文件已经给出源码能够保证的全部静态约束与明确边界。