566 lines
42 KiB
Markdown
566 lines
42 KiB
Markdown
# 诊单详情 / 编辑 / 预约视觉规格(后台源码基准)
|
||
|
||
## 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`):
|
||
|
||
```text
|
||
┌─────────────────────────────────────────────────────────────────────┐
|
||
│ ← 返回 诊单只读详情 张三 男 · 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`)。字段顺序是:
|
||
|
||
1. 姓名。
|
||
2. 脱敏手机 · 性别 · 年龄。
|
||
3. 身高 / 体重 · 地区。
|
||
4. 预约日期时间 · 时段。
|
||
5. 医生 / 医助。
|
||
6. 预约状态 · 是否已开方。
|
||
7. 备注(有值才显示)。
|
||
|
||
顺序由 `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`)。
|
||
|
||
```text
|
||
桌面(右侧 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`,body `10px 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 gap `8px 16px`,checkbox `8px 10px`。
|
||
- 分组标题外边距 18/14 px,文字 13 px、水平内边距 10 px。
|
||
|
||
```text
|
||
移动端(<=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`)。
|
||
|
||
```text
|
||
┌───────────────────────────────────────────────────────────────┐
|
||
│ 预约面诊 × │
|
||
├───────────────────────────────────────────────────────────────┤
|
||
│ [今日重复预约警告 / 其他日期提示,条件显示] │
|
||
│ 上次面诊 2026-08-01 10:30 │
|
||
│ 预约方式 (●) 按时间预约 │
|
||
│ 预约类型 (●) 视频面诊 │
|
||
│ 预约患者 (●) 当前患者 │
|
||
│ 渠道来源 [请选择 ▼] │
|
||
│ 自媒体详情 [请选择 ▼] ← 仅自媒体渠道 │
|
||
│ 预约医生 ( ) 医生A ( ) 医生B ... │
|
||
│ 预约时间 [08月10日 周一] [08月11日 周二] ... │
|
||
│ ┌───────────────────────────────────────────┐ │
|
||
│ │ 可预约时段 [刷新] │ │
|
||
│ │ [09:00 可约] [09:30 已满] [10:00 可约] ...│ │
|
||
│ └───────────────────────────────────────────┘ │
|
||
│ 备注 [_________________________________________] │
|
||
├───────────────────────────────────────────────────────────────┤
|
||
│ [取消] [确认预约] │
|
||
└───────────────────────────────────────────────────────────────┘
|
||
```
|
||
|
||
字段顺序严格为(`appointment.vue:21-181`):
|
||
|
||
1. 上次面诊(文本)。
|
||
2. 预约方式(当前只呈现按时间预约)。
|
||
3. 预约类型(视频)。
|
||
4. 预约患者(当前患者)。
|
||
5. 渠道来源(必填 select)。
|
||
6. 自媒体详情(渠道命中自媒体白名单时必填)。
|
||
7. 预约医生(radio 列表)。
|
||
8. 预约时间:先日期按钮,后可预约时段矩阵。
|
||
9. 备注(textarea,2 行)。
|
||
10. 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`)。编辑态顺序为:
|
||
|
||
1. 患者信息:姓名 / 性别 / 年龄三等分,电话 / 门诊号两等分。
|
||
2. 诊断信息:面象 / 舌象两等分,临床诊断整行 2 行 textarea;舌象详情和脉象详情在模板中被注释(`index.vue:11-76`)。
|
||
3. 中药处方 RP:药材总数与锁定提示;添加主方、添加辅方、处方库导入、粘贴导入;处方价格;主方卡片网格;辅方卡片网格(`index.vue:78-216`)。
|
||
4. 用法信息:处方类型、主方用法、条件性辅方用法、剂数、剂量单位、用法、服用时间、服用方式、忌口、其他说明、医师、是否共享、医师签名(`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`:
|
||
|
||
1. 订单号,min 200。
|
||
2. 全局就诊序号,96。
|
||
3. 数量统计,96,Tag。
|
||
4. 金额,120,右对齐红字。
|
||
5. 医生,110。
|
||
6. 医助,110。
|
||
7. 履约状态,110,Tag。
|
||
8. 创建时间,min 170。
|
||
9. 详情,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`)。内容顺序为:
|
||
|
||
1. 金额概览:总金额、已付总额、退款金额、需代收、已付笔数;响应式 2 / 3 / 5 列(`PrescriptionOrderDetailDrawer.vue:154-197`)。
|
||
2. 两栏主区:左侧处方详情,右侧未关联收款与关联收款;收款表顺序为 ID、单号、类型、金额、状态、方式(readonly 隐藏)、创建人、创建时间(`PrescriptionOrderDetailDrawer.vue:200-545`)。
|
||
3. 履约与收货信息:3 列 descriptions,label 宽 120 px(`PrescriptionOrderDetailDrawer.vue:551-680,1782-1785`)。
|
||
4. 物流轨迹与操作日志(有数据/开启附加加载时)(`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 推荐常量(来自源码,不是重新设计)
|
||
|
||
```text
|
||
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 顺序装配:
|
||
|
||
```text
|
||
编辑病历:
|
||
诊单ID
|
||
→ 姓名 / 身份证
|
||
→ 手机 / 性别
|
||
→ 年龄
|
||
→ [生命体征] 婚姻 / 身高 / 体重
|
||
→ 地区 / 高压 / 低压
|
||
→ 空腹血糖
|
||
→ 诊断类型
|
||
→ 状态 / 渠道
|
||
→ 统计端就诊卡
|
||
→ 在用药物
|
||
→ [主诉] 当地诊断日期 / 糖尿病病史
|
||
→ 当地医院诊断结果
|
||
→ 当地医院名称
|
||
→ [现病史] 口腔 → 饮水 → 体重变化 → 脂肪肝 → 饮食
|
||
→ 肢体 → 睡眠 → 眼睛 → 头部 → 出汗 → 皮肤 → 小便 → 大便 → 腰肾
|
||
→ 其他补充
|
||
→ [既往史] 既往史
|
||
→ [其他病史] 外伤 / 手术 / 过敏 → 家族 / 妊娠
|
||
→ [诊断信息] 病史补充
|
||
|
||
预约:
|
||
上次面诊 → 预约方式 → 预约类型 → 预约患者 → 渠道来源
|
||
→ [条件] 自媒体详情 → 预约医生 → 日期 → 时段 → 备注
|
||
```
|
||
|
||
---
|
||
|
||
## 9. 验收清单
|
||
|
||
1. 独立 readonly 是纵向卡片流,不出现 Tabs;抽屉 viewOnly 才是 Tabs + disabled 表单。
|
||
2. 编辑 Drawer 桌面 60%,<=768 等效状态下全宽;预约 Drawer 源码没有该响应式覆盖,需明确属于适配增强。
|
||
3. 编辑桌面 label 160 px,预约 label 100 px;编辑移动端 label 在控件上方。
|
||
4. 编辑的 body 独立滚动,footer 始终可见;实现中没有把按钮放到滚动区末尾。
|
||
5. Tab 顺序与 canonical permission 一致;“跟踪备注”不渲染。
|
||
6. 编辑病历字段严格按 §4.5;不把脚本中未渲染字段自行加入。
|
||
7. 只读病例按 4/3 列网格及 §3.4 顺序;小窗若做降列,需视为桌面端增强而非源码既有行为。
|
||
8. 预约状态至少覆盖:未选医生、无排班、可约、不可约、选中、当天冲突、其他日期提示、loading。
|
||
9. 订单、备注、视频、聊天、指派历史、挂号历史的列顺序/动作显隐与 §6 一致。
|
||
10. 所有表格提供 loading、empty、error;权限失去时移除入口并将当前页回退到可见页。
|
||
|
||
以上规格记录的是当前后台源码的可见事实;PySide 可为桌面小窗增加降列和全宽适配,但不得改变字段顺序、权限门槛、状态语义或主操作位置。
|