|
|
@@ -0,0 +1,600 @@
|
|
|
+<template>
|
|
|
+ <!-- 搜索 -->
|
|
|
+ <ContentWrap>
|
|
|
+ <el-form class="-mb-15px" :model="queryParams" ref="queryFormRef" :inline="true" label-width="80px">
|
|
|
+ <TenantSelect v-model="queryParams.tenantIds" placeholder="请选择机构名称" prop="tenantIds" />
|
|
|
+ <el-form-item label="长者姓名" prop="elderName">
|
|
|
+ <el-input
|
|
|
+ @keyup.enter="handleQuery"
|
|
|
+ v-model="queryParams.elderName"
|
|
|
+ placeholder="请输入长者姓名"
|
|
|
+ class="!w-200px"
|
|
|
+ clearable
|
|
|
+ />
|
|
|
+ </el-form-item>
|
|
|
+ <el-form-item label="执行日期" prop="execDate">
|
|
|
+ <el-date-picker
|
|
|
+ v-model="queryParams.execDate"
|
|
|
+ type="date"
|
|
|
+ value-format="YYYY-MM-DD"
|
|
|
+ format="YYYY-MM-DD"
|
|
|
+ placeholder="选择执行日期"
|
|
|
+ style="width: 180px"
|
|
|
+ />
|
|
|
+ </el-form-item>
|
|
|
+ <el-form-item label="医嘱类型" prop="orderType">
|
|
|
+ <el-select v-model="queryParams.orderType" placeholder="全部" clearable class="!w-160px">
|
|
|
+ <el-option label="长期医嘱" :value="1" />
|
|
|
+ <el-option label="临时医嘱" :value="2" />
|
|
|
+ </el-select>
|
|
|
+ </el-form-item>
|
|
|
+ <el-form-item label="状态" prop="status">
|
|
|
+ <el-select v-model="queryParams.status" placeholder="全部" clearable class="!w-160px">
|
|
|
+ <el-option label="待执行" :value="0" />
|
|
|
+ <el-option label="已执行" :value="1" />
|
|
|
+ <el-option label="已跳过" :value="2" />
|
|
|
+ </el-select>
|
|
|
+ </el-form-item>
|
|
|
+ <el-form-item>
|
|
|
+ <el-button @click="handleQuery">
|
|
|
+ <Icon icon="ep:search" class="mr-5px" /> 查询
|
|
|
+ </el-button>
|
|
|
+ <el-button @click="resetQuery">
|
|
|
+ <Icon icon="ep:refresh" class="mr-5px" /> 重置
|
|
|
+ </el-button>
|
|
|
+ <el-button type="primary" plain @click="openPrintDialog('all')">
|
|
|
+ <Icon icon="ep:printer" class="mr-5px" /> 打印执行单
|
|
|
+ </el-button>
|
|
|
+ </el-form-item>
|
|
|
+ </el-form>
|
|
|
+ </ContentWrap>
|
|
|
+
|
|
|
+ <!-- 列表 -->
|
|
|
+ <ContentWrap>
|
|
|
+ <el-table v-loading="loading" :data="pagedList" border stripe>
|
|
|
+ <el-table-column label="长者" prop="elderName" width="110" fixed />
|
|
|
+ <el-table-column label="床位" prop="bedName" width="120" />
|
|
|
+ <el-table-column label="类型" width="90" align="center">
|
|
|
+ <template #default="{ row }">
|
|
|
+ <el-tag :type="row.orderType === 1 ? 'primary' : 'warning'" size="small" effect="plain">
|
|
|
+ {{ row.orderType === 1 ? '长期' : '临时' }}
|
|
|
+ </el-tag>
|
|
|
+ </template>
|
|
|
+ </el-table-column>
|
|
|
+ <el-table-column label="医嘱内容" prop="orderContent" min-width="220" show-overflow-tooltip />
|
|
|
+ <el-table-column label="频次" width="90" align="center">
|
|
|
+ <template #default="{ row }">{{ freqCn(row.frequency) }}</template>
|
|
|
+ </el-table-column>
|
|
|
+ <el-table-column label="给药时间" width="90" align="center">
|
|
|
+ <template #default="{ row }">{{ timeCn(row.medTime) }}</template>
|
|
|
+ </el-table-column>
|
|
|
+ <el-table-column label="途径" width="90" align="center">
|
|
|
+ <template #default="{ row }">{{ routeCn(row.route) }}</template>
|
|
|
+ </el-table-column>
|
|
|
+ <el-table-column label="计划执行时间" prop="planTime" width="160" />
|
|
|
+ <el-table-column label="执行护士" prop="execNurseSign" width="100" />
|
|
|
+ <el-table-column label="实际执行时间" prop="execTime" width="160" />
|
|
|
+ <el-table-column label="状态" width="90" align="center">
|
|
|
+ <template #default="{ row }">
|
|
|
+ <el-tag :type="statusType(row.status)" size="small">{{ statusText(row.status) }}</el-tag>
|
|
|
+ </template>
|
|
|
+ </el-table-column>
|
|
|
+ <el-table-column label="操作" width="220" align="center" fixed="right">
|
|
|
+ <template #default="{ row }">
|
|
|
+ <el-button
|
|
|
+ v-if="row.status === 0"
|
|
|
+ link
|
|
|
+ type="primary"
|
|
|
+ @click="openExecute(row, false)"
|
|
|
+ v-hasPermi="['doctor-order-execute:execute']"
|
|
|
+ >执行</el-button
|
|
|
+ >
|
|
|
+ <el-button
|
|
|
+ v-if="row.status === 0"
|
|
|
+ link
|
|
|
+ type="danger"
|
|
|
+ @click="handleSkip(row)"
|
|
|
+ v-hasPermi="['doctor-order-execute:skip']"
|
|
|
+ >跳过</el-button
|
|
|
+ >
|
|
|
+ <el-button v-if="row.status !== 0" link type="primary" @click="openExecute(row, true)"
|
|
|
+ >查看</el-button
|
|
|
+ >
|
|
|
+ <el-button link type="warning" @click="openPrintDialog('single', row)" v-hasPermi="['doctor-order-execute:print']"
|
|
|
+ >打印</el-button
|
|
|
+ >
|
|
|
+ </template>
|
|
|
+ </el-table-column>
|
|
|
+ </el-table>
|
|
|
+
|
|
|
+ <Pagination
|
|
|
+ :total="total"
|
|
|
+ v-model:page="pageNo"
|
|
|
+ v-model:limit="pageSize"
|
|
|
+ @pagination="() => {}"
|
|
|
+ />
|
|
|
+ </ContentWrap>
|
|
|
+
|
|
|
+ <!-- 执行弹窗 -->
|
|
|
+ <ExecuteDialog ref="execRef" @success="buildRows" />
|
|
|
+
|
|
|
+ <!-- 跳过原因弹窗 -->
|
|
|
+ <el-dialog
|
|
|
+ v-model="skipVisible"
|
|
|
+ title="跳过执行"
|
|
|
+ width="500px"
|
|
|
+ :close-on-click-modal="false"
|
|
|
+ append-to-body
|
|
|
+ >
|
|
|
+ <el-alert
|
|
|
+ :title="`${skipRow.elderName || ''} · ${skipRow.bedName || ''}`"
|
|
|
+ :description="skipRow.orderContent || ''"
|
|
|
+ type="warning"
|
|
|
+ :closable="false"
|
|
|
+ class="mb-16px"
|
|
|
+ />
|
|
|
+ <el-form label-width="90px">
|
|
|
+ <el-form-item label="计划时间">{{ skipRow.planTime || '-' }}</el-form-item>
|
|
|
+ <el-form-item label="跳过原因" required>
|
|
|
+ <el-input
|
|
|
+ v-model="skipForm.remark"
|
|
|
+ type="textarea"
|
|
|
+ :rows="3"
|
|
|
+ maxlength="200"
|
|
|
+ show-word-limit
|
|
|
+ placeholder="请填写本次不执行的原因,如:长者外出 / 拒采 / 当日禁食转院…"
|
|
|
+ />
|
|
|
+ </el-form-item>
|
|
|
+ </el-form>
|
|
|
+ <template #footer>
|
|
|
+ <el-button @click="skipVisible = false">取消</el-button>
|
|
|
+ <el-button type="primary" :loading="skipping" @click="confirmSkip">确认跳过</el-button>
|
|
|
+ </template>
|
|
|
+ </el-dialog>
|
|
|
+
|
|
|
+ <!-- 打印弹窗:打印区在可见状态下由 v-print 克隆,避免离屏 div 导致空白页 -->
|
|
|
+ <el-dialog
|
|
|
+ v-model="printDialogVisible"
|
|
|
+ :title="printMode === 'all' ? '医嘱执行单' : '医嘱执行单(单条)'"
|
|
|
+ width="1080px"
|
|
|
+ append-to-body
|
|
|
+ :close-on-click-modal="false"
|
|
|
+ >
|
|
|
+ <!-- 汇总(当日全量) -->
|
|
|
+ <div v-if="printMode === 'all'" id="execPrintArea" class="exec-print" style="padding: 12px 16px; color: #000; background: #fff">
|
|
|
+ <div style="text-align: center; font-size: 20px; font-weight: bold; margin: 6px 0 18px">
|
|
|
+ 医嘱执行单
|
|
|
+ </div>
|
|
|
+ <div style="display: flex; justify-content: space-between; font-size: 14px; margin-bottom: 10px">
|
|
|
+ <span>机构:{{ tenantName }}</span>
|
|
|
+ <span>执行日期:{{ queryParams.execDate }}</span>
|
|
|
+ </div>
|
|
|
+ <table
|
|
|
+ border="1"
|
|
|
+ cellspacing="0"
|
|
|
+ cellpadding="6"
|
|
|
+ style="width: 100%; border-collapse: collapse; font-size: 14px"
|
|
|
+ >
|
|
|
+ <thead>
|
|
|
+ <tr>
|
|
|
+ <th>长者</th>
|
|
|
+ <th>床位</th>
|
|
|
+ <th>类型</th>
|
|
|
+ <th>医嘱内容</th>
|
|
|
+ <th>频次</th>
|
|
|
+ <th>给药时间</th>
|
|
|
+ <th>途径</th>
|
|
|
+ <th>计划时间</th>
|
|
|
+ <th>执行护士</th>
|
|
|
+ <th>实际时间</th>
|
|
|
+ <th>状态</th>
|
|
|
+ </tr>
|
|
|
+ </thead>
|
|
|
+ <tbody>
|
|
|
+ <tr v-for="(item, idx) in list" :key="idx">
|
|
|
+ <td>{{ item.elderName }}</td>
|
|
|
+ <td>{{ item.bedName }}</td>
|
|
|
+ <td>{{ item.orderType === 1 ? '长期' : '临时' }}</td>
|
|
|
+ <td>{{ item.orderContent }}</td>
|
|
|
+ <td>{{ freqCn(item.frequency) }}</td>
|
|
|
+ <td>{{ timeCn(item.medTime) }}</td>
|
|
|
+ <td>{{ routeCn(item.route) }}</td>
|
|
|
+ <td>{{ item.planTime }}</td>
|
|
|
+ <td>{{ item.execNurseSign }}</td>
|
|
|
+ <td>{{ item.execTime }}</td>
|
|
|
+ <td>{{ statusText(item.status) }}</td>
|
|
|
+ </tr>
|
|
|
+ </tbody>
|
|
|
+ </table>
|
|
|
+ </div>
|
|
|
+
|
|
|
+ <!-- 单条 -->
|
|
|
+ <div v-else id="singlePrintArea" class="exec-print" style="padding: 12px 16px; color: #000; background: #fff">
|
|
|
+ <div v-if="singlePrintRow">
|
|
|
+ <div style="text-align: center; font-size: 20px; font-weight: bold; margin: 6px 0 18px">
|
|
|
+ 医嘱执行单(单条)
|
|
|
+ </div>
|
|
|
+ <div
|
|
|
+ style="
|
|
|
+ display: grid;
|
|
|
+ grid-template-columns: repeat(2, 1fr);
|
|
|
+ gap: 4px 16px;
|
|
|
+ font-size: 14px;
|
|
|
+ margin-bottom: 14px;
|
|
|
+ line-height: 1.8;
|
|
|
+ "
|
|
|
+ >
|
|
|
+ <div><strong>长者:</strong>{{ singlePrintRow.elderName }}</div>
|
|
|
+ <div><strong>床位:</strong>{{ singlePrintRow.bedName }}</div>
|
|
|
+ <div><strong>类型:</strong>{{ singlePrintRow.orderType === 1 ? '长期医嘱' : '临时医嘱' }}</div>
|
|
|
+ <div><strong>状态:</strong>{{ statusText(singlePrintRow.status) }}</div>
|
|
|
+ <div><strong>频次:</strong>{{ freqCn(singlePrintRow.frequency) }}</div>
|
|
|
+ <div><strong>给药时间:</strong>{{ timeCn(singlePrintRow.medTime) }}</div>
|
|
|
+ <div><strong>途径:</strong>{{ routeCn(singlePrintRow.route) }}</div>
|
|
|
+ <div><strong>计划执行时间:</strong>{{ singlePrintRow.planTime }}</div>
|
|
|
+ <div><strong>实际执行时间:</strong>{{ singlePrintRow.execTime || '-' }}</div>
|
|
|
+ <div><strong>执行护士:</strong>{{ singlePrintRow.execNurseSign || '-' }}</div>
|
|
|
+ <div style="grid-column: 1 / -1"><strong>医嘱内容:</strong>{{ singlePrintRow.orderContent }}</div>
|
|
|
+ <div v-if="singlePrintRow.remark" style="grid-column: 1 / -1">
|
|
|
+ <strong>{{ singlePrintRow.status === 2 ? '跳过原因:' : '备注:' }}</strong
|
|
|
+ >{{ singlePrintRow.remark }}
|
|
|
+ </div>
|
|
|
+ </div>
|
|
|
+ <div
|
|
|
+ style="
|
|
|
+ margin-top: 40px;
|
|
|
+ display: flex;
|
|
|
+ justify-content: space-between;
|
|
|
+ font-size: 14px;
|
|
|
+ "
|
|
|
+ >
|
|
|
+ <span>执行护士签名:__________________</span>
|
|
|
+ <span>核对护士签名:__________________</span>
|
|
|
+ </div>
|
|
|
+ </div>
|
|
|
+ </div>
|
|
|
+
|
|
|
+ <template #footer>
|
|
|
+ <el-button @click="printDialogVisible = false">关闭</el-button>
|
|
|
+ <el-button v-if="printMode === 'all'" type="primary" v-print="printAll">打印</el-button>
|
|
|
+ <el-button v-else type="primary" v-print="printOne">打印</el-button>
|
|
|
+ </template>
|
|
|
+ </el-dialog>
|
|
|
+</template>
|
|
|
+
|
|
|
+<script lang="ts" setup>
|
|
|
+import { ref, reactive, computed } from 'vue'
|
|
|
+import { useMessage } from '@/hooks/web/useMessage'
|
|
|
+import { useUserStore } from '@/store/modules/user'
|
|
|
+import { formatDate } from '@/utils/formatTime'
|
|
|
+import {
|
|
|
+ getLongDoctorOrderPage,
|
|
|
+ getShortDoctorOrderPage,
|
|
|
+ getDoctorOrderExecutionPage,
|
|
|
+ executeDoctorOrder,
|
|
|
+ buildExecutionPlanTimes,
|
|
|
+ MED_FREQUENCY_OPTIONS,
|
|
|
+ MED_TIME_OPTIONS,
|
|
|
+ MED_ROUTE_OPTIONS,
|
|
|
+ getMedCn,
|
|
|
+ type DoctorOrderExecution
|
|
|
+} from '@/api/elderly/elder/bed-change'
|
|
|
+import ExecuteDialog from './ExecuteDialog.vue'
|
|
|
+
|
|
|
+defineOptions({ name: 'DoctorOrderExecute' })
|
|
|
+
|
|
|
+const message = useMessage()
|
|
|
+const userStore = useUserStore()
|
|
|
+const tenantName = computed(() => userStore.tenant?.name || '')
|
|
|
+
|
|
|
+/** v-print 配置(vue3-print-nb 期望传 {id, popTitle, ...} 对象,不是字符串选择器) */
|
|
|
+const printAll = {
|
|
|
+ id: 'execPrintArea',
|
|
|
+ popTitle: '医嘱执行单',
|
|
|
+ extraCss: '',
|
|
|
+ preview: false,
|
|
|
+ zIndex: 20002
|
|
|
+}
|
|
|
+const printOne = {
|
|
|
+ id: 'singlePrintArea',
|
|
|
+ popTitle: '医嘱执行单(单条)',
|
|
|
+ extraCss: '',
|
|
|
+ preview: false,
|
|
|
+ zIndex: 20002
|
|
|
+}
|
|
|
+/** 打印弹窗:可见状态下由 v-print 克隆,避免离屏 div 空白页 */
|
|
|
+const printDialogVisible = ref(false)
|
|
|
+const printMode = ref<'all' | 'single'>('all')
|
|
|
+const singlePrintRow = ref<any>(null)
|
|
|
+/** 打开打印弹窗:all=当日汇总,single=当前行 */
|
|
|
+const openPrintDialog = (mode: 'all' | 'single', row?: any) => {
|
|
|
+ printMode.value = mode
|
|
|
+ singlePrintRow.value = mode === 'single' ? { ...row } : null
|
|
|
+ printDialogVisible.value = true
|
|
|
+}
|
|
|
+
|
|
|
+const loading = ref(false)
|
|
|
+const list = ref<any[]>([])
|
|
|
+const pageNo = ref(1)
|
|
|
+const pageSize = ref(20)
|
|
|
+const total = computed(() => list.value.length)
|
|
|
+const pagedList = computed(() => {
|
|
|
+ const start = (pageNo.value - 1) * pageSize.value
|
|
|
+ return list.value.slice(start, start + pageSize.value)
|
|
|
+})
|
|
|
+
|
|
|
+const queryParams = reactive({
|
|
|
+ tenantIds: userStore.orgTenantId as any,
|
|
|
+ elderName: undefined as string | undefined,
|
|
|
+ execDate: formatDate(new Date(), 'YYYY-MM-DD'),
|
|
|
+ orderType: undefined as number | undefined,
|
|
|
+ status: undefined as number | undefined
|
|
|
+})
|
|
|
+const queryFormRef = ref()
|
|
|
+
|
|
|
+const freqCn = (v?: string) => getMedCn(MED_FREQUENCY_OPTIONS, v)
|
|
|
+const timeCn = (v?: string) => getMedCn(MED_TIME_OPTIONS, v)
|
|
|
+const routeCn = (v?: string) => getMedCn(MED_ROUTE_OPTIONS, v)
|
|
|
+const statusType = (s?: number) => (s === 1 ? 'success' : s === 2 ? 'info' : 'warning')
|
|
|
+const statusText = (s?: number) => (s === 1 ? '已执行' : s === 2 ? '已跳过' : '待执行')
|
|
|
+
|
|
|
+/** 构造一条执行行 */
|
|
|
+const makeRow = (orderType: number, e: any, planTime: string, vo: any) => ({
|
|
|
+ orderType,
|
|
|
+ orderEntryId: e.id,
|
|
|
+ elderId: vo.elderId,
|
|
|
+ elderName: vo.elderName,
|
|
|
+ bedName: vo.bedName,
|
|
|
+ orderContent: e.orderContent,
|
|
|
+ frequency: e.frequency,
|
|
|
+ medTime: e.medTime,
|
|
|
+ route: e.route,
|
|
|
+ planTime,
|
|
|
+ status: 0,
|
|
|
+ execTime: '',
|
|
|
+ execNurseSign: '',
|
|
|
+ remark: '',
|
|
|
+ tenantId: vo.tenantId
|
|
|
+})
|
|
|
+
|
|
|
+/** 聚合:长期(在用) + 临时(当日) → 按频次展开 → 合并已执行记录 */
|
|
|
+const buildRows = async () => {
|
|
|
+ loading.value = true
|
|
|
+ pageNo.value = 1
|
|
|
+ try {
|
|
|
+ const { tenantIds, execDate, elderName } = queryParams
|
|
|
+ // 1) 长期医嘱
|
|
|
+ let longOrders: any[] = []
|
|
|
+ try {
|
|
|
+ const lp = await getLongDoctorOrderPage({
|
|
|
+ pageNo: 1,
|
|
|
+ pageSize: 100,
|
|
|
+ tenantIds,
|
|
|
+ elderName: elderName || undefined
|
|
|
+ })
|
|
|
+ longOrders = lp.list || []
|
|
|
+ } catch (e) {
|
|
|
+ console.warn('[执行医嘱] 长期医嘱列表失败,使用测试数据', e)
|
|
|
+ longOrders = buildMockLong(execDate)
|
|
|
+ }
|
|
|
+ // 2) 临时医嘱
|
|
|
+ let shortOrders: any[] = []
|
|
|
+ try {
|
|
|
+ const sp = await getShortDoctorOrderPage({
|
|
|
+ pageNo: 1,
|
|
|
+ pageSize: 100,
|
|
|
+ tenantIds,
|
|
|
+ elderName: elderName || undefined
|
|
|
+ })
|
|
|
+ shortOrders = sp.list || []
|
|
|
+ } catch (e) {
|
|
|
+ console.warn('[执行医嘱] 临时医嘱列表失败,使用测试数据', e)
|
|
|
+ shortOrders = buildMockShort(execDate)
|
|
|
+ }
|
|
|
+
|
|
|
+ // 3) 展开执行行
|
|
|
+ const rows: any[] = []
|
|
|
+ longOrders.forEach((vo: any) => {
|
|
|
+ ;(vo.entries || []).forEach((e: any) => {
|
|
|
+ if (e.status !== 1) return // 仅在用医嘱需要执行
|
|
|
+ buildExecutionPlanTimes(e.frequency, e.medTime).forEach((t: string) => {
|
|
|
+ rows.push(makeRow(1, e, `${execDate} ${t}`, vo))
|
|
|
+ })
|
|
|
+ })
|
|
|
+ })
|
|
|
+ shortOrders.forEach((vo: any) => {
|
|
|
+ ;(vo.entries || []).forEach((e: any) => {
|
|
|
+ const plan = e.orderTime
|
|
|
+ if (!plan || plan.slice(0, 10) !== execDate) return
|
|
|
+ rows.push(makeRow(2, e, plan, vo))
|
|
|
+ })
|
|
|
+ })
|
|
|
+
|
|
|
+ // 4) 拉取已执行记录,合并标记
|
|
|
+ const execMap = new Map<string, any>()
|
|
|
+ try {
|
|
|
+ const ep = await getDoctorOrderExecutionPage({
|
|
|
+ pageNo: 1,
|
|
|
+ pageSize: 1000,
|
|
|
+ tenantIds,
|
|
|
+ planDate: execDate
|
|
|
+ })
|
|
|
+ ;(ep.list || []).forEach((r: any) => {
|
|
|
+ execMap.set(`${r.orderType}-${r.orderEntryId}-${r.planTime}`, r)
|
|
|
+ })
|
|
|
+ } catch (e) {
|
|
|
+ console.warn('[执行医嘱] 执行记录查询失败,全部按待执行展示', e)
|
|
|
+ }
|
|
|
+ rows.forEach((r) => {
|
|
|
+ const ex = execMap.get(`${r.orderType}-${r.orderEntryId}-${r.planTime}`)
|
|
|
+ if (ex) {
|
|
|
+ r.execId = ex.id
|
|
|
+ r.status = ex.status ?? 1
|
|
|
+ r.execTime = ex.execTime || ''
|
|
|
+ r.execNurseSign = ex.execNurseSign || ''
|
|
|
+ r.remark = ex.remark || ''
|
|
|
+ }
|
|
|
+ })
|
|
|
+
|
|
|
+ // 5) 筛选 + 排序
|
|
|
+ let filtered = rows
|
|
|
+ if (queryParams.orderType != null) {
|
|
|
+ filtered = filtered.filter((r) => r.orderType === queryParams.orderType)
|
|
|
+ }
|
|
|
+ if (queryParams.status != null) {
|
|
|
+ filtered = filtered.filter((r) => r.status === queryParams.status)
|
|
|
+ }
|
|
|
+ filtered.sort((a, b) => (a.planTime || '').localeCompare(b.planTime || ''))
|
|
|
+ list.value = filtered
|
|
|
+ } finally {
|
|
|
+ loading.value = false
|
|
|
+ }
|
|
|
+}
|
|
|
+
|
|
|
+/** 测试假数据:长期医嘱(在用条目,含多频次) */
|
|
|
+const buildMockLong = (execDate: string): any[] => [
|
|
|
+ {
|
|
|
+ id: 1001,
|
|
|
+ elderId: 801,
|
|
|
+ elderName: '张建国',
|
|
|
+ bedName: '1号楼-301-01',
|
|
|
+ tenantId: queryParams.tenantIds,
|
|
|
+ entries: [
|
|
|
+ {
|
|
|
+ id: 9001,
|
|
|
+ orderTime: `${execDate} 09:00:00`,
|
|
|
+ orderContent: '口服苯磺酸氨氯地平片 5mg',
|
|
|
+ frequency: 'qd',
|
|
|
+ medTime: 'am',
|
|
|
+ route: 'po',
|
|
|
+ status: 1,
|
|
|
+ statusText: '在用'
|
|
|
+ },
|
|
|
+ {
|
|
|
+ id: 9002,
|
|
|
+ orderTime: `${execDate} 09:00:00`,
|
|
|
+ orderContent: '二甲双胍缓释片 0.5g 早晚服用',
|
|
|
+ frequency: 'bid',
|
|
|
+ medTime: 'pc',
|
|
|
+ route: 'po',
|
|
|
+ status: 1,
|
|
|
+ statusText: '在用'
|
|
|
+ }
|
|
|
+ ]
|
|
|
+ },
|
|
|
+ {
|
|
|
+ id: 1002,
|
|
|
+ elderId: 802,
|
|
|
+ elderName: '刘秀英',
|
|
|
+ bedName: '2号楼-205-03',
|
|
|
+ tenantId: queryParams.tenantIds,
|
|
|
+ entries: [
|
|
|
+ {
|
|
|
+ id: 9003,
|
|
|
+ orderTime: `${execDate} 08:00:00`,
|
|
|
+ orderContent: '胰岛素皮下注射,餐前 15 分钟',
|
|
|
+ frequency: 'tid',
|
|
|
+ medTime: 'ac',
|
|
|
+ route: 'sc',
|
|
|
+ status: 1,
|
|
|
+ statusText: '在用'
|
|
|
+ }
|
|
|
+ ]
|
|
|
+ }
|
|
|
+]
|
|
|
+
|
|
|
+/** 测试假数据:临时医嘱(医嘱时间为当日) */
|
|
|
+const buildMockShort = (execDate: string): any[] => [
|
|
|
+ {
|
|
|
+ id: 2001,
|
|
|
+ elderId: 803,
|
|
|
+ elderName: '王德海',
|
|
|
+ bedName: '1号楼-402-02',
|
|
|
+ tenantId: queryParams.tenantIds,
|
|
|
+ entries: [
|
|
|
+ {
|
|
|
+ id: 9101,
|
|
|
+ orderTime: `${execDate} 10:30:00`,
|
|
|
+ orderContent: '血常规 + 生化全套(空腹采血)',
|
|
|
+ frequency: 'st',
|
|
|
+ medTime: 'st',
|
|
|
+ route: 'iv',
|
|
|
+ executeTime: '',
|
|
|
+ nurseSign: ''
|
|
|
+ }
|
|
|
+ ]
|
|
|
+ }
|
|
|
+]
|
|
|
+
|
|
|
+/** 查询 */
|
|
|
+const handleQuery = () => {
|
|
|
+ buildRows()
|
|
|
+}
|
|
|
+
|
|
|
+/** 重置 */
|
|
|
+const resetQuery = () => {
|
|
|
+ queryFormRef.value?.resetFields()
|
|
|
+ queryParams.elderName = undefined
|
|
|
+ queryParams.execDate = formatDate(new Date(), 'YYYY-MM-DD')
|
|
|
+ queryParams.orderType = undefined
|
|
|
+ queryParams.status = undefined
|
|
|
+ handleQuery()
|
|
|
+}
|
|
|
+
|
|
|
+/** 执行 / 查看 */
|
|
|
+const execRef = ref()
|
|
|
+const openExecute = (row: any, view: boolean) => {
|
|
|
+ execRef.value?.open(row, view)
|
|
|
+}
|
|
|
+
|
|
|
+/** 跳过:打开原因弹窗 */
|
|
|
+const skipVisible = ref(false)
|
|
|
+const skipRow = ref<any>({})
|
|
|
+const skipping = ref(false)
|
|
|
+const skipForm = reactive({ remark: '' })
|
|
|
+
|
|
|
+const handleSkip = (row: any) => {
|
|
|
+ skipRow.value = row
|
|
|
+ skipForm.remark = ''
|
|
|
+ skipVisible.value = true
|
|
|
+}
|
|
|
+
|
|
|
+/** 确认跳过:原因必填,写入一条 status=2 的执行记录 */
|
|
|
+const confirmSkip = async () => {
|
|
|
+ if (!skipForm.remark || !skipForm.remark.trim()) {
|
|
|
+ message.error('请填写跳过原因')
|
|
|
+ return
|
|
|
+ }
|
|
|
+ skipping.value = true
|
|
|
+ try {
|
|
|
+ const r = skipRow.value
|
|
|
+ const payload: DoctorOrderExecution = {
|
|
|
+ orderType: r.orderType,
|
|
|
+ orderEntryId: r.orderEntryId,
|
|
|
+ elderId: r.elderId,
|
|
|
+ elderName: r.elderName,
|
|
|
+ bedName: r.bedName,
|
|
|
+ orderContent: r.orderContent,
|
|
|
+ frequency: r.frequency,
|
|
|
+ medTime: r.medTime,
|
|
|
+ route: r.route,
|
|
|
+ planTime: r.planTime,
|
|
|
+ status: 2,
|
|
|
+ remark: skipForm.remark.trim(),
|
|
|
+ tenantId: r.tenantId
|
|
|
+ }
|
|
|
+ await executeDoctorOrder(payload)
|
|
|
+ message.success('已跳过')
|
|
|
+ skipVisible.value = false
|
|
|
+ buildRows()
|
|
|
+ } catch {
|
|
|
+ // 错误提示由请求拦截器统一处理
|
|
|
+ } finally {
|
|
|
+ skipping.value = false
|
|
|
+ }
|
|
|
+}
|
|
|
+
|
|
|
+onMounted(() => {
|
|
|
+ buildRows()
|
|
|
+})
|
|
|
+</script>
|