fix(mobile): 优化患者列表 - 分页加载+搜索+数据格式适配
This commit is contained in:
@@ -1,52 +1,79 @@
|
||||
<template>
|
||||
<div class="patient-list">
|
||||
<div class="search-bar"><input v-model="searchText" placeholder="搜索患者姓名/床号..." class="search-input" /></div>
|
||||
<div v-if="loading" class="loading">加载中...</div>
|
||||
<div v-for="p in displayPatients" :key="p.id" class="patient-card" @click="$router.push(`/mobile/patient-detail/${p.id}`)">
|
||||
<div class="patient-avatar" :class="'level-' + p.nursingLevel">{{ p.name?.charAt(0) }}</div>
|
||||
<div class="search-bar">
|
||||
<input v-model="searchText" placeholder="搜索患者姓名/床号..." class="search-input" @input="onSearch" />
|
||||
</div>
|
||||
<div v-if="loading" class="loading">
|
||||
<div class="loading-spinner"></div>
|
||||
<span>加载中...</span>
|
||||
</div>
|
||||
<div v-for="p in patients" :key="p.patientId || p.id" class="patient-card" @click="goDetail(p)">
|
||||
<div class="patient-avatar" :class="'level-' + (p.nursingLevel || 3)">{{ (p.patientName || p.name || '?').charAt(0) }}</div>
|
||||
<div class="patient-info">
|
||||
<div class="patient-name">{{ p.name }} <span class="bed">{{ p.bedNo }}床</span></div>
|
||||
<div class="patient-diag">{{ p.diagnosis || '暂无诊断' }}</div>
|
||||
<div class="patient-tags"><span class="tag" :class="'level-' + p.nursingLevel">{{ p.nursingLevel }}级护理</span><span v-if="p.gender" class="tag">{{ p.gender }}</span></div>
|
||||
<div class="patient-name">{{ p.patientName || p.name || '未知患者' }} <span class="bed">{{ p.bedNo || p.locationName || '' }}</span></div>
|
||||
<div class="patient-diag">{{ p.primaryDiagnosisName || p.diagnosis || '暂无诊断' }}</div>
|
||||
<div class="patient-tags">
|
||||
<span class="tag" :class="'level-' + (p.nursingLevel || 3)">{{ (p.nursingLevel || 3) }}级护理</span>
|
||||
<span v-if="p.gender" class="tag">{{ p.gender }}</span>
|
||||
<span v-if="p.age" class="tag">{{ p.age }}岁</span>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div v-if="!loading && displayPatients.length === 0" class="empty">暂无患者</div>
|
||||
<div v-if="!loading && patients.length === 0" class="empty">暂无患者</div>
|
||||
<div v-if="!loading && hasMore" class="load-more" @click="loadMore">加载更多</div>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script setup>
|
||||
import { ref, onMounted, computed } from 'vue'
|
||||
import { ref, onMounted } from 'vue'
|
||||
import { useRouter } from 'vue-router'
|
||||
import { ElMessage } from 'element-plus'
|
||||
import { nursingApi } from '../api'
|
||||
|
||||
const router = useRouter()
|
||||
const patients = ref([])
|
||||
const loading = ref(false)
|
||||
const searchText = ref('')
|
||||
const displayPatients = computed(() => searchText.value ? patients.value.filter(p => p.name?.includes(searchText.value) || p.bedNo?.includes(searchText.value)) : patients.value)
|
||||
const pageNo = ref(1)
|
||||
const pageSize = 20
|
||||
const hasMore = ref(true)
|
||||
|
||||
const loadPatients = async () => {
|
||||
const loadPatients = async (reset = false) => {
|
||||
if (reset) { pageNo.value = 1; patients.value = []; hasMore.value = true }
|
||||
loading.value = true
|
||||
try {
|
||||
const res = await nursingApi.getPatientList({})
|
||||
patients.value = res.data?.list || res.data?.records || res.data?.rows || res.data || []
|
||||
} catch (e) { ElMessage.error('加载患者列表失败') } finally { loading.value = false }
|
||||
const params = { pageNo: pageNo.value, pageSize: pageSize }
|
||||
if (searchText.value) params.searchKey = searchText.value
|
||||
const res = await nursingApi.getPatientList(params)
|
||||
const list = res.data?.list || res.data?.records || res.data?.rows || res.data || []
|
||||
if (reset) { patients.value = list } else { patients.value.push(...list) }
|
||||
hasMore.value = list.length >= pageSize
|
||||
} catch (e) { console.error('加载失败:', e) } finally { loading.value = false }
|
||||
}
|
||||
|
||||
onMounted(loadPatients)
|
||||
const onSearch = () => { loadPatients(true) }
|
||||
const loadMore = () => { pageNo.value++; loadPatients(false) }
|
||||
const goDetail = (p) => { router.push(`/mobile/patient-detail/${p.patientId || p.id}`) }
|
||||
|
||||
onMounted(() => loadPatients(true))
|
||||
</script>
|
||||
|
||||
<style scoped>
|
||||
.search-bar { padding: 8px 0; }
|
||||
.search-input { width: 100%; padding: 10px 16px; border: 1px solid #ddd; border-radius: 20px; font-size: 15px; outline: none; background: #fff; }
|
||||
.search-input:focus { border-color: #1890ff; }
|
||||
.loading { text-align: center; padding: 20px; color: #999; }
|
||||
.loading { text-align: center; padding: 20px; color: #999; display: flex; align-items: center; justify-content: center; gap: 8px; }
|
||||
.loading-spinner { width: 20px; height: 20px; border: 2px solid #1890ff; border-top-color: transparent; border-radius: 50%; animation: spin 0.8s linear infinite; }
|
||||
@keyframes spin { to { transform: rotate(360deg); } }
|
||||
.patient-card { background: #fff; border-radius: 8px; padding: 12px; margin-bottom: 8px; display: flex; align-items: center; gap: 12px; box-shadow: 0 1px 3px rgba(0,0,0,0.08); }
|
||||
.patient-avatar { width: 44px; height: 44px; border-radius: 50%; display: flex; align-items: center; justify-content: center; font-size: 18px; font-weight: 600; color: #fff; }
|
||||
.patient-avatar { width: 44px; height: 44px; border-radius: 50%; display: flex; align-items: center; justify-content: center; font-size: 18px; font-weight: 600; color: #fff; flex-shrink: 0; }
|
||||
.level-1 { background: #f5222d; } .level-2 { background: #fa8c16; } .level-3 { background: #52c41a; }
|
||||
.patient-name { font-weight: 600; font-size: 15px; }
|
||||
.bed { color: #999; font-size: 13px; }
|
||||
.patient-diag { color: #666; font-size: 13px; margin: 2px 0; }
|
||||
.patient-tags { display: flex; gap: 6px; }
|
||||
.tag { font-size: 11px; padding: 2px 6px; border-radius: 4px; }
|
||||
.patient-info { flex: 1; min-width: 0; }
|
||||
.patient-name { font-weight: 600; font-size: 15px; white-space: nowrap; overflow: hidden; text-overflow: ellipsis; }
|
||||
.bed { color: #999; font-size: 13px; margin-left: 4px; }
|
||||
.patient-diag { color: #666; font-size: 13px; margin: 2px 0; white-space: nowrap; overflow: hidden; text-overflow: ellipsis; }
|
||||
.patient-tags { display: flex; gap: 6px; flex-wrap: wrap; }
|
||||
.tag { font-size: 11px; padding: 2px 6px; border-radius: 4px; background: #f5f5f5; }
|
||||
.load-more { text-align: center; padding: 12px; color: #1890ff; font-size: 14px; cursor: pointer; }
|
||||
.empty { text-align: center; padding: 40px; color: #999; }
|
||||
</style>
|
||||
|
||||
Reference in New Issue
Block a user