2026-08-25.md 14 KB

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,...}])。 弹窗:<Dialog v-model="dialogVisible" :title> + 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;⑤频次展开逻辑若后端已有执行计划生成,前端应改为直接读执行表而非自行展开。