# 2026-08-25 工作记录 ## 长期医嘱单页面(long-doctor-order) 按截图新建 `src/views/elderly/elder/doctor-orders/long-doctor-order/` 三件套: - `columns.ts`:长期医嘱列表格列定义,复用 `reactive` + `type/dictArr/format/width` 约定,与 `src/views/elderly/elder/column.ts` 风格一致。 - `Form.vue`:Dialog 弹窗(60% 宽),基于 `selectElder` 自动联动填充姓名/性别/床号/护理等级(注意 Vue3 不推荐 `.sync`,要用 `v-model:propName`)。表单含医嘱内容、开始时间、医生签名、护士签名、停止时间、停止医生签名、停止护士签名、备注。`open(row, detail)` 回显详情。 - `index.vue`:参考 `bed-change/index.vue` 的标准结构(ContentWrap 筛选 + ContentWrap 列表(TabBarBtn + Table2 + Pagination)+ Form 弹窗引用),监听 `@edit`/`@del` 事件做编辑/删除。删除用 `message.confirm` 二次确认。 接口:`src/api/elderly/elder/bed-change/index.ts` 追加 5 个 CRUD + VO/Form 类型: - `getLongDoctorOrderPage / getLongDoctorOrder / createLongDoctorOrder / updateLongDoctorOrder / deleteLongDoctorOrder` - 路径:`elderly/longDoctorOrder/{page|get|create|update|delete}`,复用 `request.get/post/put/delete` 模式。 注意:列定义里 `gender` 用 `type:'1'` + `DICT_TYPE.SYSTEM_USER_SEX` 字典。**未引入 `status` 字典**(项目里估计没有 LONG_ORDER_STATUS),等后端落地后再加一列。 --- ## 临时医嘱单页面(short-doctor-order) 按截图实现 `src/views/elderly/elder/doctor-orders/short-doctor-order/`,四件套: - `columns.ts`:列表列(长者姓名/性别/床位号/护理等级/医嘱条数/最新医嘱时间/最新执行时间/创建时间),无状态列(临时医嘱一次性,无未开始/在用/已停止语义)。 - `Form.vue`:80% 宽 Dialog,上方长者 picker(`selectElder` 联动),下方 el-table 子表展示**多条医嘱条目**(每条 6 列:医嘱时间/医嘱内容/医生签名/执行时间/护士签名/备注),支持新增/删除条目,至少保留 1 条。`entries` 是数组,对应后端一对多结构。 - `Print.vue`:完全按截图渲染。**关键样式**:日/月 列表头用 `::before` 画斜线(`linear-gradient` 一条对角线),签名按「有数据显数据、无数据显横线」规则(`.sign-box.empty` 灰底文字),打印最少 6 行(不足补空行)。 - `index.vue`:与 long-doctor-order 同款结构(ContentWrap 筛选 + ContentWrap 列表 + Pagination + Form/Print 引用),操作列只保留 编辑/删除/打印(**没有停止/启用**,因为临时医嘱是一次性)。列表请求失败时填充 2 条测试假数据。 接口:`bed-change/index.ts` 追加 5 个 + 3 个类型: - `getShortDoctorOrderPage / getShortDoctorOrder / createShortDoctorOrder / updateShortDoctorOrder / deleteShortDoctorOrder` - 路径:`elderly/shortDoctorOrder/{page|get|create|update|delete}` - 类型:`ShortDoctorOrderVO`(含 `entries: ShortDoctorOrderEntry[]`)/ `ShortDoctorOrderForm` / `ShortDoctorOrderEntry`(每条单据子行字段)。 ## 通用发现 - yudao 风格打印:`v-print` 指令全局可用(`vue3-print-nb`),只需配置 `id/popTitle/preview/zIndex`。打印区域 ID 不要和其他医嘱单(`longOrderPrintArea`)冲突。 - el-table 子表 + el-date-picker 单元格内嵌:`el-date-picker` 加 `style="width: 100%"` 才不溢出。`el-form-item` 包外层 + 子列用 `template #default="{ row }"` 解构。 - 临时医嘱多 entry 提交 payload 用 `{elderId, entries: [...]}`,后端一对多时直接整个 list 传过去即可。 校验:ESLint 0 错误,vue-tsc 过滤 long-doctor-order/bed-change/index.ts 无报错。 ## 项目里标准的列表页结构(备查) `ContentWrap`(筛选 + 列表 + 分页) + `TabBarBtn @add` + `Table2`(自动渲染操作列:编辑/详情/撤销/删除,事件:edit/detail/del/cancel)+ `Pagination`。 列定义写在独立 `columns.ts` 用 `reactive([{label,field,type,format,...}])`。 弹窗:`` + `defineExpose({ open })`。 全局组件(无需 import):`ContentWrap / Dialog / TabBarBtn / Table2 / Pagination / Icon / TenantSelect`。 ## 长期医嘱单功能增强(同文件,追加) 按需求增量修改 long-doctor-order 三件套 + 接口: - **新增「未开始」状态**:状态语义 0=未开始 / 1=在用 / 2=已停止。筛选新增「未开始」选项;`getList` 预计算 `statusText`;`columns.ts` 加「状态」列(渲染 `statusText`,因无后端字典故不走 dict-tag)。 - **操作列新增 停止/启用 切换 + 打印 + 打开**:Table2 内置 编辑/删除/详情 用 `:show-edit-condition / :show-delete-condition / :show-detail-condition="()=>false"` 隐藏(避免权限串 `elder:*` 导致的重复/不可控),改在 `#next` 插槽自绘 编辑/删除/停止启用/打开/打印 按钮(用正确的 `v-hasPermi="['long-doctor-order:*']"`)。`op-width` 调到 340。 - `handleToggleStatus`:status==2(已停止)→显示「启用」置 1;否则→「停止」置 2;`message.confirm` 二次确认后调 `updateLongDoctorOrderStatus(id, status)`。 - `openDetail`→`Form.open(row,true)` 只读详情;`openPrint`→`Print.open(row)`。 - **新建 `Print.vue`**:Dialog 内 `#longOrderPrintArea` 渲染医嘱单详情(基本信息表 + 医嘱内容 + 签名区)。**签名规则**:有值显值、无值显横线(`.sign-box.empty` 仅 `border-bottom` + 浅色「(签名)」占位)供纸质签名。底部 `v-print="print"`(vue3-print-nb,已在 main.ts `app.use(Print)` 全局注册)触发打印。 - **Form.vue 详情增强**:detail 模式展示「医嘱状态」(只读);footer 加「打印」按钮→`Print.open({id})`。 - 接口追加:`updateLongDoctorOrderStatus(id,status)`(PUT `elderly/longDoctorOrder/updateStatus`)+ `LONG_ORDER_STATUS` / `LONG_ORDER_STATUS_OPTIONS` / `getLongDoctorOrderStatusText()` 常量。 校验:ESLint 0 错误;vue-tsc 过滤 long-doctor-order/bed-change/index.ts 无报错。 ⚠️ 待后端落地确认项:①`updateStatus` 接口 URL/参数名(`?id=&status=`);②新医嘱默认 status(建议后端置 0 未开始);③菜单 path + 权限码 `long-doctor-order:edit/delete/print`;④打印走 `v-print` 会克隆 `#longOrderPrintArea` 到 iframe 打印,遮罩层不会入纸。 --- ## 打印页时间格式化 + 签名去横线(长期/临时医嘱统一) 用户要求两个医嘱单打印页:**时间用标准格式化(没有就留空白)+ 表格里签名不需要横线**。 ### 长期医嘱 `long-doctor-order/Print.vue` - 表头 11 列 → 9 列(序号/医嘱时间/医嘱内容/医生签名/护士签名/停止时间/停止医生签名/停止护士签名/备注)。 - 去掉「医嘱时间/停止时间」的 colspan 2 + 对角线「日/月·时」表头,改单列直接显示完整时间。 - 新增 `formatFullTime(val)`:`YYYY-MM-DD HH:mm:ss` → 截到 `YYYY-MM-DD HH:mm`;空/`null`/`undefined`/`''` → 空串;数字时间戳按本地时区解析;其他兜底原样返回。替换原 `formatDateOnly`/`formatTimeOnly`。 - 签名单元格去掉 `.sign-box`(含 `border-bottom` 横线 + `.empty` 占位灰),直接 `{{ item.xxxSign || '' }}`。 - 删除 `.diag-cell` 斜线 CSS(`::before` linear-gradient)。 ### 临时医嘱 `short-doctor-order/Print.vue` - 表头 8 列 → 6 列(医嘱时间/医嘱/医生签名/执行时间/护士签名/备注)。 - 同样 `formatFullTime` 替换 `formatDateOnly`/`formatTimeOnly`,`orderTime` 与 `executeTime` 两个时间字段都用它。 - 签名去 `.sign-box` 横线,删除 `.diag-cell` 斜线 CSS。 ### 结论 两张打印单视觉风格现已一致:时间列单列标准 `YYYY-MM-DD HH:mm`,无值留空;签名只显文本不加横线。这是用户明确偏好(「有表格了就不需要横线」),后续新打印页默认沿用此风格。 --- ## 长期医嘱 Form.vue 子表新增「启用/停止医嘱」按钮 用户要求新增弹窗里子表操作列也显示「启用医嘱/停止医嘱」(此前只有已保存行 `row.id` 存在才显示)。 改动: - 操作列 180px → 220px。 - 启用/停止按钮显示条件 `v-if="row.id && !isDetail"` → `v-if="!isDetail"`(新增行也可见)。 - 文案/颜色按 `status`:`IN_USE(1)`→「停止医嘱」warning;`NOT_STARTED(0)`/`STOPPED(2)`→「启用医嘱」success。 - `emptyEntry()` 默认 `status: LONG_ORDER_STATUS.NOT_STARTED`(未开始),`statusText:'未开始'`。 - `togglingId` 判定加 `row.id !== undefined` 防止新增行 id=undefined 误判。 - 未保存行(无 id)点击仍走 `handleToggleEntryStatus` 原提示分支「新添加的条目请先保存后再启用/停止」。 ⚠️ 临时医嘱 `short-doctor-order/Form.vue` **未加**启停按钮(临时医嘱一次性,无此语义)。如要加「执行/作废」类按钮再单独处理。 --- ## 医嘱给药三要素(频次/时间/途径)下拉选择项 用户要求长期+临时医嘱,每条医嘱新增三个结构化选择项:给药频次、给药时间、给药途径,下拉项最右侧带中文临床场景提示。 ### API `bed-change/index.ts` - 新增 `MedOption` 接口(`value/label/cn/tip`)。 - 新增三套选项常量(长期/临时共用): - `MED_FREQUENCY_OPTIONS`:qd/bid/tid/qid/qn/qod/qw/biw/tiw/q2w/q3w/q4w/q8h/q6h/q4h(15 项)。 - `MED_TIME_OPTIONS`:ac/pc/hs/st/prn/sos/am/pm(8 项)。 - `MED_ROUTE_OPTIONS`:po/iv/ivgtt/im/sc/ih/igtt/inh/ext(9 项,ivgtt 含 iv drip 别名释义)。 - `label` = 「缩写 + 中文含义」(如下拉主显),`cn` = 中文含义,`tip` = 临床场景(hover 提示)。 - `LongDoctorOrderEntry` / `ShortDoctorOrderEntry` 各加 `frequency?`、`medTime?`、`route?`(均存缩写)。 ### 两个 `Form.vue`(长期/临时) - `emptyEntry()` 补 `frequency/medTime/route: ''`。 - 子表在「医嘱内容」列后插入三列 `el-select`(clearable + filterable),`v-model` 绑 `row.frequency/medTime/route`,`disabled=isDetail`。 - `el-option` 用 `:value`(缩写) + `:label`(缩写+中文) + `:title="o.tip"`(原生 hover tooltip 显示临床场景)。选框提交时 payload 自动带三字段。 ### 两个 `Print.vue`(长期/临时) - 导入三套常量 + 新增 `medLabel(options, val)` helper(缩写→`o.label`,空值返回空串)。 - 表头/表格在「医嘱内容」后加「频次/给药时间/途径」三列,单元格 `medLabel(...)` 显示中文文案;`paddedEntries` 补空字段。 - 长期打印 9→12 列;临时打印 6→9 列。 ### 结论 两种医嘱编辑时均可结构化选择给药三要素,打印页同步展示中文;选项字典集中在 API 一处维护。校验:ESLint 0 错误(5 文件)。 ⚠️ 待后端确认:①entry 新增三字段的库表列名/序列化(建议 frequency/med_time/route);②前端存的缩写需与后端字典一致;③如后端有独立给药字典接口,需替换本地常量。 --- ## 护士执行医嘱页面(execute-doctor-order)—— 新建 用户要开发护士"执行医嘱"功能,数据来源是前两个医嘱。已确认方案:**前端自动展开 + 按频次拆分多次**(护士只做"确认执行+签名",不手动新增执行记录)。 ### 设计决策 - 数据流转:**不新增独立录入**,页面读长期+临时医嘱接口,在前端按频次展开成"当日执行行",护士点「执行」→写一条执行记录。 - 长期医嘱只取 `status=1(在用)` 的 entry;临时医嘱取 `orderTime` 当日者,以医嘱时间为 planTime(一次性)。 - 执行记录需持久化(跨刷新可追溯):`getDoctorOrderExecutionPage(planDate)` 拉已执行,按 `${orderType}-${orderEntryId}-${planTime}` 合并标记行 status=已执行。 - 行操作:待执行→「执行」(弹窗填实际时间+签名) / 「跳过」(写 status=2);已执行/已跳过→「查看」。 ### API `bed-change/index.ts` 追加 - `DoctorOrderExecution` 接口(orderType/orderEntryId/elderId/elderName/bedName/orderContent/frequency/medTime/route/planTime/execTime/execNurseSign/status/remark/tenantId)。 - `EXEC_STATUS`(0待执行/1已执行/2已跳过) + `EXEC_STATUS_OPTIONS`。 - `getDoctorOrderExecutionPage(query)` GET `elderly/doctorOrderExecution/page`;`executeDoctorOrder(data)` POST `elderly/doctorOrderExecution/execute`;`skipDoctorOrderExecution(id)` PUT `elderly/doctorOrderExecution/skip`。 - `getMedCn(options, val)` 选项值→中文。 - `buildExecutionPlanTimes(frequency, medTime)`:频次→HH:mm 时点数组(日频次多时点;周/间隔频次给 1 个 09:00 代表点;medTime 对单时点微调 hs→21:00 等)。**前端启发式,真实排班以后端执行为准**。 ### 文件 - `execute-doctor-order/index.vue`:ContentWrap 筛选(机构/长者/执行日期默认今天/类型/状态)+ el-table 列表(合并展开)+ 客户端分页 Pagination + 打印执行单(`v-print="'#execPrintArea'"`,离屏克隆打印)+ ExecuteDialog 引用。列表失败各自 catch 用 `buildMockLong/buildMockShort` 兜底(含 bids/tid 多时点,验证展开)。 - `execute-doctor-order/ExecuteDialog.vue`:摘要描述 + 表单(实际执行时间默认 now、执行护士默认 `userStore.nickname`、备注),保存调 `executeDoctorOrder`。`defineExpose({open(row, view)})`。 校验:ESLint 0 错误(3 文件)。 ⚠️ 待后端确认:①执行记录表 `doctor_order_execution` 列名/序列化;②`execute` 接口入参(是否需传 elderId/orderContent 冗余或仅 orderEntryId+planTime+status+execTime+sign);③`page` 查询参数 `planDate` 命名;④权限码 `doctor-order-execute:execute`;⑤频次展开逻辑若后端已有执行计划生成,前端应改为直接读执行表而非自行展开。