按截图新建 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 / deleteLongDoctorOrderelderly/longDoctorOrder/{page|get|create|update|delete},复用 request.get/post/put/delete 模式。注意:列定义里 gender 用 type:'1' + DICT_TYPE.SYSTEM_USER_SEX 字典。未引入 status 字典(项目里估计没有 LONG_ORDER_STATUS),等后端落地后再加一列。
按截图实现 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 / deleteShortDoctorOrderelderly/shortDoctorOrder/{page|get|create|update|delete}ShortDoctorOrderVO(含 entries: ShortDoctorOrderEntry[])/ ShortDoctorOrderForm / ShortDoctorOrderEntry(每条单据子行字段)。v-print 指令全局可用(vue3-print-nb),只需配置 id/popTitle/preview/zIndex。打印区域 ID 不要和其他医嘱单(longOrderPrintArea)冲突。el-date-picker 加 style="width: 100%" 才不溢出。el-form-item 包外层 + 子列用 template #default="{ row }" 解构。{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 三件套 + 接口:
getList 预计算 statusText;columns.ts 加「状态」列(渲染 statusText,因无后端字典故不走 dict-tag)。: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) 全局注册)触发打印。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.vueformatFullTime(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.vueformatFullTime 替换 formatDateOnly/formatTimeOnly,orderTime 与 executeTime 两个时间字段都用它。.sign-box 横线,删除 .diag-cell 斜线 CSS。两张打印单视觉风格现已一致:时间列单列标准 YYYY-MM-DD HH:mm,无值留空;签名只显文本不加横线。这是用户明确偏好(「有表格了就不需要横线」),后续新打印页默认沿用此风格。
用户要求新增弹窗里子表操作列也显示「启用医嘱/停止医嘱」(此前只有已保存行 row.id 存在才显示)。
改动:
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 误判。handleToggleEntryStatus 原提示分支「新添加的条目请先保存后再启用/停止」。⚠️ 临时医嘱 short-doctor-order/Form.vue 未加启停按钮(临时医嘱一次性,无此语义)。如要加「执行/作废」类按钮再单独处理。
用户要求长期+临时医嘱,每条医嘱新增三个结构化选择项:给药频次、给药时间、给药途径,下拉项最右侧带中文临床场景提示。
bed-change/index.tsMedOption 接口(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 补空字段。两种医嘱编辑时均可结构化选择给药三要素,打印页同步展示中文;选项字典集中在 API 一处维护。校验:ESLint 0 错误(5 文件)。
⚠️ 待后端确认:①entry 新增三字段的库表列名/序列化(建议 frequency/med_time/route);②前端存的缩写需与后端字典一致;③如后端有独立给药字典接口,需替换本地常量。
用户要开发护士"执行医嘱"功能,数据来源是前两个医嘱。已确认方案:前端自动展开 + 按频次拆分多次(护士只做"确认执行+签名",不手动新增执行记录)。
status=1(在用) 的 entry;临时医嘱取 orderTime 当日者,以医嘱时间为 planTime(一次性)。getDoctorOrderExecutionPage(planDate) 拉已执行,按 ${orderType}-${orderEntryId}-${planTime} 合并标记行 status=已执行。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;⑤频次展开逻辑若后端已有执行计划生成,前端应改为直接读执行表而非自行展开。