374 lines
35 KiB
Markdown
374 lines
35 KiB
Markdown
# 管理端“诊单列表”视觉规格(源码基准)
|
||
|
||
> 审计日期:2026-08-10
|
||
> 唯一业务页面基准:`D:/web/zyt/admin/src/views/tcm/diagnosis/index.vue`
|
||
> 方法:只读检查 Vue 模板、同文件 scoped SCSS、直接挂载组件、全局样式、主题生成逻辑和当前锁定的 Element Plus 源码;未启动浏览器、未改业务源码。
|
||
|
||
## 1. 结论摘要
|
||
|
||
1. 该页面**没有页面内标题、说明文案或独立标题栏**。路由内容从一张无边框、无阴影的筛选卡直接开始;“新增诊单”等主操作位于第二张列表卡顶部,而不是页面标题旁。证据:`index.vue:2-154`。
|
||
2. 页面是“浅灰页面底 + 两张白卡”的高密度后台列表。外层路由容器提供左右 `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`。
|
||
3. 顶部不是常规 tabs,而是可换行的圆角文字 chip:6 个日期入口,再接“待预约 / 已完成 / 待分配医助”,计数是文字后面的普通半透明数字,不是独立 badge。当天默认选中。证据:`index.vue:6-70,964-976,2174-2182,2222-2317`。
|
||
4. 表格声明列的最小总宽约为 **1403px**;右侧固定“视频旁观” `120px` 与“操作” `340px`,合计 `460px`。窄于该宽度时由 Element Table 横向滚动,右侧两列保持 fixed。证据:`index.vue:191-342`。
|
||
5. 表格使用斑马纹;普通偶数行是 `#FAFAFA`,普通悬停是 `#F8F8F8`。未确认、未挂号行还声明了左侧语义色和横向渐变,但静态渐变写在 `tr`,斑马纹及 fixed cell 的 `td` 背景可能遮住它;两类行的 hover 渐变直接写在 `td`,表现更稳定。证据:`index.vue:2723-2735`、Element Plus `table.scss:560-588,665-668`。
|
||
6. 空态不是 `el-empty` 插画,而是表格默认的 **60px 高“暂无数据”文本区**;加载态是覆盖表格的半透明蒙层和 `42px` 主色环。证据:Element Plus `table.scss:52-70`、`loading.scss:19-73`、中文 locale `zh-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 宽屏主态
|
||
|
||
```text
|
||
主内容滚动区,#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 Plus `card.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`、水平 gap `6px`、垂直居中。证据:`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 分隔线,左右 margin `4px`。证据:`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`。
|
||
|
||
控件从左到右:
|
||
|
||
1. 诊断类型 select(small,`24px` 高);
|
||
2. 证型 select(small);
|
||
3. 医助 select(small,可搜索);
|
||
4. 最近挂号日期范围(共享 `DaterangePicker`,`260px` 宽、最大 100%,未传 size,故 default `32px` 高);
|
||
5. 最近指派日期范围(同上);
|
||
6. 最近挂号渠道(small,可搜索,宽 `170px`);
|
||
7. 重置(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 spacing `tailwind.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 Plus `button.scss:72-74`。
|
||
|
||
## 7. 表格规格
|
||
|
||
### 7.1 外框与表头
|
||
|
||
- 表格外围 padding `10px 16px 0`;表格宽度 100%,默认 fixed layout、无竖边框;行之间由 `1px #EBEEF5` 底边分隔。证据:`index.vue:178-190,2432-2434`、Element Plus `table.scss:11-20,188-195,217-235`。
|
||
- 表头底 `#F8F8F8`、13px/600、文字 `#666`。默认 cell 水平 padding `12px`,行高 `23px`,纵向 padding `8px`,所以单行表头的理论最小高度约 **39px**(23+16,不含亚像素/边线差异)。证据:`index.vue:2710-2716`、Element Plus `table.scss:156-195`、`common/var.scss:1014-1031`。
|
||
- 表头“未服务天数”有双态排序箭头,顺序只允许 descending → ascending;激活箭头使用主色。证据:`index.vue:297-304`、Element Plus `table.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` 与 `23px` line-height。纯单行内容的最小行高约 **39px**。证据:`index.vue:2720-2722`、Element Plus `table.scss:188-195`。
|
||
- 挂号 cell 有 `min-height:36px`、内 padding `4px 8px`、r6,所以含该列的常规数据行通常至少约 **52px**(cell 36 + table 上下 16);实际由内容较高者决定。证据:`index.vue:2485-2489`。
|
||
- 同一诊单多条预约时,每一后续预约额外带 `8px` top margin、`8px` top 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-height `1.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 Plus `tag.scss:66-87,142-165`、`common/var.scss:1110-1138`。
|
||
|
||
#### 挂号块
|
||
|
||
- 每个预约 badge:11px/600、padding `2px 6px`、r4、下 margin `2px`;医生 14px/600 `#333`;时间 12px、上 margin `2px`。证据:`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-height `1.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`,纵向 gap `4px`、line-height `1.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`,左右 padding `2px`;不可进入时是 `#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,透明边/底,padding `2px`,高度 auto;hover 使用各语义色的 light-3。证据:Element Plus `button.scss:223-248`、`element.scss:113-127`。
|
||
- `.action-cell` 设 flex-wrap + `gap:4px`;但相邻 `.el-button + .el-button` 仍有 `12px` 左 margin,因此连续按钮间通常是 **16px(4+12)**。dropdown 外壳与前一按钮之间只有 flex gap `4px`。证据:`index.vue:2683-2688`、Element Plus `button.scss:72-74`。
|
||
- 340px 操作列不足时允许链接换行;没有强制单行或省略号。
|
||
|
||
### 8.2 “更多”菜单
|
||
|
||
- click 触发、`bottom-end` 对齐。菜单项按权限/状态可包含:指派、取消指派、视频二维码、二维码、取消挂号、挂号日志、创建订单、删除。证据:`index.vue:379-403`。
|
||
- Element 默认 dropdown item 为 14px、line-height `22px`、padding `5px 16px`,故普通项约 `32px` 高;菜单上下净 padding 约 `5px`,r4、overlay 白底,popper 有 light border 与 shadow。hover 为 fill-light + primary。证据:Element Plus `dropdown.scss:7-24,42-70,137-176`。
|
||
- 删除项有 divided 顶线,文字由 `.text-danger` 强制为 danger。证据:`index.vue:400,2706-2708`。
|
||
- tooltip 使用 Element 默认 popper:12px、line-height `20px`、padding `5px 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 token `16px`;active 仅主色文字 + bold,并未启用 background 模式。证据:`index.vue:408-410,2436-2440`、Element Plus `common/var.scss:1034-1057`、`pagination.scss:5-67`。
|
||
- page-size select 框架宽 `128px`,jumper 输入 `56px`。证据:Element Plus `pagination.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-height `60px`,宽 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 Plus `loading.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. 响应式与滚动行为
|
||
|
||
1. `index.vue` 的 scoped 样式**没有 media query**。页面级响应式主要来自 flex-wrap、宽度上限、Element Table 横向滚动及全局分页规则。
|
||
2. body 被全局设为 `min-width:375px`、`overflow:hidden`;应用主内容通过 `el-scrollbar` 承担页面滚动。证据:`src/styles/public.scss:1-3`、`layout/default/components/main.vue:2-11`。
|
||
3. 第一筛选行本身不换行。左侧日期 chip 可换行,但右侧 160px 搜索 + 32px 查询按钮仍与左侧同一 flex 行;在极窄内容宽度下可能压缩、增高左侧或溢出,源码没有把搜索行堆到下一行的断点。
|
||
4. 待分配容器可换行,宽搜索最多 `42vw`;展开筛选区可换行,两个日期范围各为 `260px` 且 `max-width:100%`。证据:`index.vue:2298-2317,2384-2405`。
|
||
5. 表格 min 总宽约 1403px。Element Table 内部提供横向 scrollbar;右侧 460px fixed 区保持可见,导致很窄时可见的左侧业务列空间进一步减少。
|
||
6. 外层应用在窄屏会折叠侧栏,但那是壳层行为,不改变本页筛选/表格 DOM。证据:`src/App.vue:36-53`。
|
||
7. 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` 起,并由 delegate `sizeHint()` 为多预约/操作换行增高。
|
||
- 选择列用 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 底层,否则会重现 HTML `td` 遮挡问题。
|
||
- 操作列优先使用 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 出现。
|
||
|
||
### 仅运行态可最终确定
|
||
|
||
1. **最终换行和行高**:取决于 viewport、数据长度、按钮权限、预约条数、字体回退、DPR;chip 和多数 row 都没有固定 height。
|
||
2. **实际主题色**:setting 存在本地缓存,账号可改主色及语义色;dark 状态也来自浏览器存储/系统偏好。
|
||
3. **业务行静态渐变是否完整可见**:受 `tr` 背景、striped/fixed `td` 背景与 Chromium table paint 顺序影响;源码只能确定规则叠加关系。
|
||
4. **fixed-column 阴影和 scrollbar 尺寸**:由 Chromium/Element 的滚动状态、平台 scrollbar 策略决定。
|
||
5. **tooltip/dropdown 的最终坐标**:popper 会做视口碰撞与翻转。
|
||
6. **加载态停留时间和计数出现时间**:由 API 延迟、idle callback 调度决定;静默轮询通常无蒙层。
|
||
7. **应用壳标题/面包屑/多页签**:由路由菜单、setting 和权限生成,不是 `index.vue` 的页面内视觉。
|
||
|
||
若后续要求“像素级截图一致”,应在固定 `Element Plus 2.13.7 + Chromium 版本 + 100% Windows 缩放 + 默认亮色主题 + 固定权限/样本数据` 下补一轮运行态测量;本文件已经给出源码能够保证的全部静态约束与明确边界。
|