Ver Fonte

Merge branch 'master' of http://47.107.245.0:3000/xiongxing/kyj-yanglao-web-new

unknown há 1 dia atrás
pai
commit
5cfc598514

+ 18 - 1
src/api/elderly/nursing/index.ts

@@ -397,4 +397,21 @@ export const exportElderlyItemsRoundExcel = (params: Recordable) => {
     url: 'elderly-items-round/exportExcel',
     params
   })
-}
+}
+
+// =================安全检查日志================
+/** 安全检查日志(长者维度分页) */
+export const getElderlySafeCheckElderPage = (params: Recordable) => {
+  return request.get({
+    url: '/elderly-safe-check/page',
+    params
+  })
+}
+
+/** 安全检查日志记录分页(详情弹窗列表) */
+export const getElderlySafeCheckRecordPage = (params: Recordable) => {
+  return request.get({
+    url: '/elderly-safe-check/page-record',
+    params
+  })
+}

+ 1 - 1
src/main.ts

@@ -51,7 +51,7 @@ import { Flex } from 'ant-design-vue'
 import 'ant-design-vue/dist/reset.css'
 import fetchPlugin from './config/axios/fetch';
 //版本号
-export const MAIN_VERSION = '4.4.7'
+export const MAIN_VERSION = '4.4.8'
 
 // 创建实例
 const setupAll = async () => {

+ 4 - 2
src/views/elderly/apply/nine-precautions/MMSE/index.vue

@@ -183,7 +183,8 @@ let queryParams = reactive({
   pageSize: 10,
   elderName: '',
   assessor: '',
-  assessorDate: getCurrentMonthRange(),
+  // assessorDate: getCurrentMonthRange(),
+  assessDate: [],
   tenantIds: userStore.orgTenantId
 })
 const queryFormRef = ref() // 搜索的表单
@@ -252,7 +253,8 @@ const resetQuery = () => {
   queryParams.elderName = ''
   queryParams.assessor = ''
   queryParams.tenantIds = userStore.orgTenantId
-  queryParams.assessorDate= getCurrentMonthRange()
+  // queryParams.assessorDate= getCurrentMonthRange()
+  queryParams.assessDate = []
   queryFormRef.value.resetFields()
   handleQuery()
 }

+ 4 - 2
src/views/elderly/apply/nine-precautions/asphyxiation-by-choking/index.vue

@@ -166,7 +166,8 @@ let queryParams = reactive({
   pageSize: 10,
   elderName: '',
   assessor: '',
-  assessDate: getCurrentMonthRange(),
+  // assessDate: getCurrentMonthRange(),
+  assessDate: [],
   tenantIds: userStore.orgTenantId
 })
 const queryFormRef = ref()
@@ -203,7 +204,8 @@ const resetQuery = () => {
   queryParams.elderName = ''
   queryParams.assessor = ''
   queryParams.tenantIds = userStore.orgTenantId
-  queryParams.assessDate = getCurrentMonthRange()
+  // queryParams.assessDate = getCurrentMonthRange()
+  queryParams.assessDate = []
   queryFormRef.value.resetFields()
   handleQuery()
 }

+ 4 - 2
src/views/elderly/apply/nine-precautions/attack/index.vue

@@ -195,7 +195,8 @@ let queryParams = reactive({
   pageSize: 10,
   elderName: '',
   assessor: '',
-  assessDate: getCurrentMonthRange(),
+  // assessDate: getCurrentMonthRange(),
+  assessDate: [],
   tenantIds: userStore.orgTenantId
 })
 const queryFormRef = ref() // 搜索的表单
@@ -262,7 +263,8 @@ const resetQuery = () => {
   queryParams.elderName = ''
   queryParams.assessor = ''
   queryParams.tenantIds = userStore.orgTenantId
-  queryParams.assessDate= getCurrentMonthRange()
+  // queryParams.assessDate= getCurrentMonthRange()
+  queryParams.assessDate = []
   queryFormRef.value.resetFields()
   handleQuery()
 }

+ 4 - 2
src/views/elderly/apply/nine-precautions/commit-suicide/index.vue

@@ -182,7 +182,8 @@ let queryParams = reactive({
   pageSize: 10,
   elderName: '',
   assessor: '',
-  assessDate: getCurrentMonthRange(),
+  // assessDate: getCurrentMonthRange(),
+  assessDate: [],
   tenantIds: userStore.orgTenantId
 })
 const queryFormRef = ref() // 搜索的表单
@@ -249,7 +250,8 @@ const resetQuery = () => {
   queryParams.elderName = ''
   queryParams.assessor = ''
   queryParams.tenantIds = userStore.orgTenantId
-  queryParams.assessDate= getCurrentMonthRange()
+  // queryParams.assessDate= getCurrentMonthRange()
+  queryParams.assessDate = []
   queryFormRef.value.resetFields()
   handleQuery()
 }

+ 4 - 2
src/views/elderly/apply/nine-precautions/communication/index.vue

@@ -182,7 +182,8 @@ let queryParams = reactive({
   pageSize: 10,
   elderName: '',
   assessor: '',
-  assessDate: getCurrentMonthRange(),
+  // assessDate: getCurrentMonthRange(),
+  assessDate: [],
   tenantIds: userStore.orgTenantId
 })
 const queryFormRef = ref() // 搜索的表单
@@ -251,7 +252,8 @@ const resetQuery = () => {
   queryParams.elderName = ''
   queryParams.assessor = ''
   queryParams.tenantIds = userStore.orgTenantId
-  queryParams.assessDate= getCurrentMonthRange()
+  // queryParams.assessDate= getCurrentMonthRange()
+  queryParams.assessDate = []
   queryFormRef.value.resetFields()
   handleQuery()
 }

+ 4 - 2
src/views/elderly/apply/nine-precautions/daily-life/index.vue

@@ -167,7 +167,8 @@ let queryParams = reactive({
   pageSize: 10,
   elderName: '',
   assessor: '',
-  assessDate: getCurrentMonthRange(),
+  // assessDate: getCurrentMonthRange(),
+  assessDate: [],
   tenantIds: userStore.orgTenantId
 })
 const queryFormRef = ref()
@@ -204,7 +205,8 @@ const resetQuery = () => {
   queryParams.elderName = ''
   queryParams.assessor = ''
   queryParams.tenantIds = userStore.orgTenantId
-  queryParams.assessDate = getCurrentMonthRange()
+  // queryParams.assessDate = getCurrentMonthRange()
+  queryParams.assessDate = []
   queryFormRef.value.resetFields()
   handleQuery()
 }

+ 4 - 2
src/views/elderly/apply/nine-precautions/empyrosis/index.vue

@@ -167,7 +167,8 @@ let queryParams = reactive({
   pageSize: 10,
   elderName: '',
   assessor: '',
-  assessDate: getCurrentMonthRange(),
+  // assessDate: getCurrentMonthRange(),
+  assessDate: [],
   tenantIds: userStore.orgTenantId
 })
 const queryFormRef = ref()
@@ -204,7 +205,8 @@ const resetQuery = () => {
   queryParams.elderName = ''
   queryParams.assessor = ''
   queryParams.tenantIds = userStore.orgTenantId
-  queryParams.assessDate = getCurrentMonthRange()
+  // queryParams.assessDate = getCurrentMonthRange()
+  queryParams.assessDate = []
   queryFormRef.value.resetFields()
   handleQuery()
 }

+ 4 - 2
src/views/elderly/apply/nine-precautions/equilibrium/index.vue

@@ -167,7 +167,8 @@ let queryParams = reactive({
   pageSize: 10,
   elderName: '',
   assessor: '',
-  assessDate: getCurrentMonthRange(),
+  // assessDate: getCurrentMonthRange(),
+  assessDate: [],
   tenantIds: userStore.orgTenantId
 })
 const queryFormRef = ref()
@@ -204,7 +205,8 @@ const resetQuery = () => {
   queryParams.elderName = ''
   queryParams.assessor = ''
   queryParams.tenantIds = userStore.orgTenantId
-  queryParams.assessDate = getCurrentMonthRange()
+  // queryParams.assessDate = getCurrentMonthRange()
+  queryParams.assessDate = []
   queryFormRef.value.resetFields()
   handleQuery()
 }

+ 4 - 2
src/views/elderly/apply/nine-precautions/fall-down/index.vue

@@ -167,7 +167,8 @@ let queryParams = reactive({
   pageSize: 10,
   elderName: '',
   assessor: '',
-  assessDate: getCurrentMonthRange(),
+  // assessDate: getCurrentMonthRange(),
+  assessDate: [],
   tenantIds: userStore.orgTenantId
 })
 const queryFormRef = ref()
@@ -204,7 +205,8 @@ const resetQuery = () => {
   queryParams.elderName = ''
   queryParams.assessor = ''
   queryParams.tenantIds = userStore.orgTenantId
-  queryParams.assessDate = getCurrentMonthRange()
+  // queryParams.assessDate = getCurrentMonthRange()
+  queryParams.assessDate = []
   queryFormRef.value.resetFields()
   handleQuery()
 }

+ 4 - 2
src/views/elderly/apply/nine-precautions/fall-prevention-measures/index.vue

@@ -167,7 +167,8 @@ let queryParams = reactive({
   pageSize: 10,
   elderName: '',
   assessor: '',
-  assessDate: getCurrentMonthRange(),
+  // assessDate: getCurrentMonthRange(),
+  assessDate: [],
   tenantIds: userStore.orgTenantId
 })
 const queryFormRef = ref()
@@ -204,7 +205,8 @@ const resetQuery = () => {
   queryParams.elderName = ''
   queryParams.assessor = ''
   queryParams.tenantIds = userStore.orgTenantId
-  queryParams.assessDate = getCurrentMonthRange()
+  // queryParams.assessDate = getCurrentMonthRange()
+  queryParams.assessDate = []
   queryFormRef.value.resetFields()
   handleQuery()
 }

+ 4 - 2
src/views/elderly/apply/nine-precautions/nutritional-risk/index.vue

@@ -20,7 +20,8 @@ let queryParams = reactive({
   pageSize: 10,
   elderName: '',
   assessor: '',
-  assessDate: getCurrentMonthRange(),
+  // assessDate: getCurrentMonthRange(),
+  assessDate: [],
   tenantIds: userStore.orgTenantId
 })
 const queryFormRef = ref()
@@ -52,7 +53,8 @@ const resetQuery = () => {
   queryFormRef.value.resetFields()
   queryParams.elderName = ''
   queryParams.assessor = ''
-  queryParams.assessDate = getCurrentMonthRange()
+  // queryParams.assessDate = getCurrentMonthRange()
+  queryParams.assessDate = []
   handleQuery()
 }
 

+ 4 - 2
src/views/elderly/apply/nine-precautions/pressure-sores/index.vue

@@ -167,7 +167,8 @@ let queryParams = reactive({
   pageSize: 10,
   elderName: '',
   assessor: '',
-  assessDate: getCurrentMonthRange(),
+  // assessDate: getCurrentMonthRange(),
+  assessDate: [],
   tenantIds: userStore.orgTenantId
 })
 const queryFormRef = ref()
@@ -204,7 +205,8 @@ const resetQuery = () => {
   queryParams.elderName = ''
   queryParams.assessor = ''
   queryParams.tenantIds = userStore.orgTenantId
-  queryParams.assessDate = getCurrentMonthRange()
+  // queryParams.assessDate = getCurrentMonthRange()
+  queryParams.assessDate = []
   queryFormRef.value.resetFields()
   handleQuery()
 }

+ 4 - 2
src/views/elderly/apply/nine-precautions/wander-away/index.vue

@@ -167,7 +167,8 @@ let queryParams = reactive({
   pageSize: 10,
   elderName: '',
   assessor: '',
-  assessDate: getCurrentMonthRange(),
+  // assessDate: getCurrentMonthRange(),
+  assessDate: [],
   tenantIds: userStore.orgTenantId
 })
 const queryFormRef = ref()
@@ -204,7 +205,8 @@ const resetQuery = () => {
   queryParams.elderName = ''
   queryParams.assessor = ''
   queryParams.tenantIds = userStore.orgTenantId
-  queryParams.assessDate = getCurrentMonthRange()
+  // queryParams.assessDate = getCurrentMonthRange()
+  queryParams.assessDate = []
   queryFormRef.value.resetFields()
   handleQuery()
 }

+ 408 - 0
src/views/elderly/nursing/safety-check-log/index.vue

@@ -0,0 +1,408 @@
+<template>
+  <ContentWrap>
+    <el-form
+      class="-mb-15px"
+      :model="queryParams"
+      ref="queryFormRef"
+      :inline="true"
+      label-width="80px"
+    >
+      <el-form-item prop="tenantIds">
+        <TenantSelect v-model="queryParams.tenantIds" placeholder="请选择机构名称" prop="tenantIds" />
+      </el-form-item>
+      <el-form-item label="长者名称" prop="elderName">
+        <TgInput @keyup.enter="handleQuery" v-model="queryParams.elderName" class="!w-160px" />
+      </el-form-item>
+      <el-form-item label="检查日期" prop="checkDate">
+        <el-date-picker
+          v-model="queryParams.checkDate"
+          type="daterange"
+          range-separator="至"
+          start-placeholder="开始日期"
+          end-placeholder="结束日期"
+          value-format="YYYY-MM-DD"
+          clearable
+          class="!w-280px"
+        />
+      </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-form-item>
+    </el-form>
+  </ContentWrap>
+
+  <ContentWrap>
+    <Table2 v-loading="loading" :list="list" :columns="columns" :queryParams="queryParams">
+      <template #pre="{ scope }">
+        <el-button link type="primary" @click="openDetail(scope)">查看</el-button>
+      </template>
+    </Table2>
+
+    <Pagination
+      :total="total"
+      v-model:page="queryParams.pageNo"
+      v-model:limit="queryParams.pageSize"
+      @pagination="getList"
+    />
+
+    <Dialog
+      v-model="detailVisible"
+      width="90%"
+      title="安全检查日志详情"
+      class="form-tag-dialog"
+      scroll
+      @close="closeDetail"
+    >
+      <div v-loading="detailLoading">
+        <div class="info-title">长者信息</div>
+        <div class="info-wrap mb-15px">
+          <el-row :gutter="20">
+            <el-col :span="8" :xs="24" class="header-item">长者姓名:{{ detailHeader.elderName || '-' }}</el-col>
+            <el-col :span="8" :xs="24" class="header-item">房间号:{{ detailHeader.roomName || '-' }}</el-col>
+            <el-col :span="8" :xs="24" class="header-item">床位号:{{ detailHeader.bedName || '-' }}</el-col>
+          </el-row>
+        </div>
+
+        <div class="info-title">历史记录查询</div>
+        <el-form class="detail-query-form mb-15px" :inline="true" @submit.prevent>
+          <el-form-item label="检查日期">
+            <el-date-picker
+              v-model="detailCheckDateRange"
+              type="daterange"
+              range-separator="至"
+              start-placeholder="开始日期"
+              end-placeholder="结束日期"
+              value-format="YYYY-MM-DD"
+              clearable
+              class="!w-280px"
+            />
+          </el-form-item>
+          <el-form-item>
+            <el-button type="primary" :loading="detailLoading" @click="handleDetailQuery">查询</el-button>
+          </el-form-item>
+        </el-form>
+
+        <el-table :data="detailRecords" max-height="58vh">
+          <el-table-column type="expand">
+            <template #default="scope">
+              <div class="expand-wrap">
+                <div class="expand-title">安全检查明细</div>
+                <el-descriptions :column="4" border size="small" class="mb-10px" label-width="130px">
+                  <el-descriptions-item label="被检查人签字">
+                    {{ scope.row.beCheckSign || '-' }}
+                  </el-descriptions-item>
+                  <el-descriptions-item label="长者自带电器设备">
+                    {{ scope.row.elderSelfEquipment || '-' }}
+                  </el-descriptions-item>
+                  <el-descriptions-item label="存在问题及整改要求">
+                    {{ scope.row.safeRemark || '-' }}
+                  </el-descriptions-item>
+                  <el-descriptions-item label="其他">
+                    {{ scope.row.other || '-' }}
+                  </el-descriptions-item>
+                </el-descriptions>
+
+                <el-table :data="scope.row.items || []" size="small" class="inner-table">
+                  <el-table-column label="检查项" prop="label" min-width="220" show-overflow-tooltip />
+                  <el-table-column label="结果" prop="status" width="96" align="center">
+                    <template #default="s">
+                      <el-tag v-if="Number(s.row.status) === 1" type="success" size="small">无问题</el-tag>
+                      <el-tag v-else-if="Number(s.row.status) === 0" type="danger" size="small">有问题</el-tag>
+                      <span v-else>-</span>
+                    </template>
+                  </el-table-column>
+                </el-table>
+              </div>
+            </template>
+          </el-table-column>
+
+          <el-table-column label="检查时间" prop="checkTime" min-width="160" show-overflow-tooltip>
+            <template #default="scope">
+              {{ formatBackendDateTime(scope.row.checkTime, 'YYYY-MM-DD HH:mm') || '-' }}
+            </template>
+          </el-table-column>
+
+          <el-table-column label="状态" prop="overallStatus" align="center">
+            <template #default="scope">
+              <el-tag v-if="Number(scope.row.overallStatus) === 1" type="success" size="small">正常</el-tag>
+              <el-tag v-else-if="Number(scope.row.overallStatus) === 0" type="danger" size="small">异常</el-tag>
+              <span v-else>-</span>
+            </template>
+          </el-table-column>
+
+          <el-table-column label="异常项数" prop="failCount" align="center" />
+          <el-table-column label="记录人" prop="recorder" show-overflow-tooltip />
+          <!-- <el-table-column label="问题与要求" prop="question" min-width="180" show-overflow-tooltip /> -->
+          <el-table-column label="被检查人签字" prop="beCheckSign" show-overflow-tooltip />
+          <el-table-column label="创建时间" prop="createTime" min-width="160" show-overflow-tooltip>
+            <template #default="scope">
+              {{ formatBackendDateTime(scope.row.createTime, 'YYYY-MM-DD HH:mm') || '-' }}
+            </template>
+          </el-table-column>
+        </el-table>
+
+        <div v-if="detailTotal > 0" class="flex justify-end">
+          <Pagination
+            :total="detailTotal"
+            v-model:page="detailPageNo"
+            v-model:limit="detailPageSize"
+            @pagination="onDetailPagination"
+          />
+        </div>
+      </div>
+
+      <template #footer>
+        <el-button @click="closeDetail">关闭</el-button>
+      </template>
+    </Dialog>
+  </ContentWrap>
+</template>
+<script setup lang="ts">
+import { formatBackendDateTime } from '@/utils/formatTime'
+import dayjs from 'dayjs'
+import { useUserStore } from '@/store/modules/user'
+import { getElderlySafeCheckElderPage, getElderlySafeCheckRecordPage } from '@/api/elderly/nursing'
+
+defineOptions({ name: 'SafetyCheckLog' })
+
+type SafetyChecklistItem = {
+  key?: string
+  label?: string
+  status?: number | string
+}
+
+type SafetyCheckElderRow = {
+  elderId: number | string
+  elderName: string
+  roomName: string
+  bedName: string
+}
+
+type ElderlySafeCheckRespVO = {
+  id?: number | string
+  elderId?: number | string
+  elderName?: string
+  roomName?: string
+  bedName?: string
+  safeSituation?: string
+  safeRemark?: string
+  elderSelfEquipment?: string
+  question?: string
+  beCheckSign?: string
+  failCount?: number | string
+  creator?: string
+  createTime?: number | string
+}
+
+type SafetyCheckDetailRow = ElderlySafeCheckRespVO & {
+  checkTime?: number | string
+  items?: SafetyChecklistItem[]
+  other?: string
+  overallStatus: 0 | 1
+}
+
+const userStore = useUserStore()
+const message = useMessage()
+
+const columns = reactive([
+  { label: '长者姓名', field: 'elderName' },
+  { label: '房间号', field: 'roomName' },
+  { label: '床位号', field: 'bedName' }
+])
+
+const queryParams = reactive({
+  pageNo: 1,
+  pageSize: 10,
+  elderName: '',
+  checkDate: undefined as string[] | undefined,
+  tenantIds: userStore.orgTenantId
+})
+
+const loading = ref(true)
+const total = ref(0)
+const list = ref<SafetyCheckElderRow[]>([])
+const queryFormRef = ref()
+
+function buildPageParams() {
+  const p = { ...queryParams } as Recordable
+  if (!p.elderName) delete p.elderName
+  const cd = p.checkDate as string[] | undefined
+  if (!Array.isArray(cd) || cd.length < 2 || !cd[0] || !cd[1]) {
+    delete p.checkDate
+  }
+  return p
+}
+
+const handleQuery = () => {
+  queryParams.pageNo = 1
+  getList()
+}
+
+const resetQuery = () => {
+  queryFormRef.value?.resetFields?.()
+  handleQuery()
+}
+
+const getList = async () => {
+  loading.value = true
+  try {
+    const data = await getElderlySafeCheckElderPage(buildPageParams())
+    list.value = (data?.list ?? []) as SafetyCheckElderRow[]
+    total.value = Number(data?.total ?? 0)
+  } finally {
+    loading.value = false
+  }
+}
+
+const detailVisible = ref(false)
+const detailLoading = ref(false)
+const detailHeader = reactive({
+  elderId: undefined as number | string | undefined,
+  elderName: '',
+  roomName: '',
+  bedName: ''
+})
+
+const detailCheckDateRange = ref<string[] | undefined>(undefined)
+const detailRecords = ref<SafetyCheckDetailRow[]>([])
+const detailPageNo = ref(1)
+const detailPageSize = ref(10)
+const detailTotal = ref(0)
+
+function createDetailDefaultDateRange(): string[] {
+  const start = dayjs().startOf('month')
+  const end = dayjs().endOf('month')
+  return [start.format('YYYY-MM-DD'), end.format('YYYY-MM-DD')]
+}
+
+function safeParseJson<T>(raw: unknown): T | undefined {
+  if (raw == null || raw === '') return undefined
+  if (typeof raw === 'object') return raw as T
+  const s = String(raw)
+  try {
+    return JSON.parse(s) as T
+  } catch {
+    return undefined
+  }
+}
+
+function parseSafeSituation(raw: unknown): { checkTime?: number | string; items: SafetyChecklistItem[]; other?: string } {
+  const parsed = safeParseJson<any>(raw) ?? {}
+  const items = Array.isArray(parsed.items) ? (parsed.items as SafetyChecklistItem[]) : []
+  return { checkTime: parsed.checkTime, items, other: parsed.other }
+}
+
+function computeOverallStatusByFailCountAndItems(failCount: unknown, items: SafetyChecklistItem[]): 0 | 1 {
+  if (failCount !== undefined && failCount !== null && failCount !== '') {
+    const n = Number(failCount)
+    if (!Number.isNaN(n)) return n > 0 ? 0 : 1
+  }
+  return items.some((x) => Number((x as any)?.status) === 0) ? 0 : 1
+}
+
+async function fetchDetailList() {
+  if (detailHeader.elderId == null) return
+  detailLoading.value = true
+  try {
+    const params: Recordable = {
+      tenantIds: queryParams.tenantIds,
+      elderId: detailHeader.elderId,
+      pageNo: detailPageNo.value,
+      pageSize: detailPageSize.value
+    }
+    const cd = detailCheckDateRange.value
+    if (Array.isArray(cd) && cd.length >= 2 && cd[0] && cd[1]) {
+      params.checkDate = [cd[0], cd[1]]
+    }
+    const data = await getElderlySafeCheckRecordPage(params)
+    detailTotal.value = Number(data?.total ?? 0)
+    const rawList = (data?.list ?? []) as ElderlySafeCheckRespVO[]
+    detailRecords.value = rawList.map((r) => {
+      const parsed = parseSafeSituation(r.safeSituation)
+      return {
+        ...r,
+        checkTime: parsed.checkTime,
+        items: parsed.items,
+        other: parsed.other,
+        overallStatus: computeOverallStatusByFailCountAndItems(r.failCount, parsed.items)
+      } as SafetyCheckDetailRow
+    })
+  } finally {
+    detailLoading.value = false
+  }
+}
+
+function onDetailPagination() {
+  fetchDetailList()
+}
+
+function handleDetailQuery() {
+  detailPageNo.value = 1
+  fetchDetailList()
+}
+
+function resetDetailHeader() {
+  detailHeader.elderId = undefined
+  detailHeader.elderName = ''
+  detailHeader.roomName = ''
+  detailHeader.bedName = ''
+}
+
+function openDetail(row: SafetyCheckElderRow) {
+  if (!row?.elderId && row?.elderId !== 0) {
+    message.warning('该行缺少长者 id,无法查询详情')
+    return
+  }
+  detailVisible.value = true
+  detailPageNo.value = 1
+  detailPageSize.value = 10
+  detailCheckDateRange.value = createDetailDefaultDateRange()
+  detailRecords.value = []
+
+  detailHeader.elderId = row.elderId
+  detailHeader.elderName = row.elderName || ''
+  detailHeader.roomName = row.roomName || ''
+  detailHeader.bedName = row.bedName || ''
+
+  fetchDetailList()
+}
+
+function closeDetail() {
+  detailVisible.value = false
+  resetDetailHeader()
+  detailCheckDateRange.value = undefined
+  detailRecords.value = []
+  detailTotal.value = 0
+  detailPageNo.value = 1
+  detailPageSize.value = 10
+}
+
+onMounted(() => {
+  getList()
+})
+</script>
+
+<style lang="scss" scoped>
+.info-title {
+  margin-bottom: 8px;
+  font-weight: 600;
+  color: var(--el-text-color-primary);
+}
+.header-item {
+  margin-bottom: 6px;
+  font-size: 14px;
+  color: var(--el-text-color-regular);
+}
+.expand-wrap {
+  padding: 10px 10px 6px;
+}
+.expand-title {
+  margin-bottom: 8px;
+  font-weight: 600;
+  color: var(--el-text-color-primary);
+}
+.inner-table {
+  width: 100%;
+}
+</style>