838 lines
17 KiB
Plaintext
838 lines
17 KiB
Plaintext
<template>
|
||
<scroll-view class="care-records-container">
|
||
<!-- Header with Filter -->
|
||
<view class="records-header">
|
||
<text class="header-title">护理记录</text>
|
||
<text class="header-subtitle">{{ elderInfo.name }}的详细护理历史</text>
|
||
<view class="filter-bar">
|
||
<picker class="filter-picker" mode="selector" :value="selectedTimeFilter" :range="timeFilterLabels" @change="onTimeFilterChange">
|
||
<view class="picker-item">
|
||
<text class="picker-text">{{ timeFilterLabels[selectedTimeFilter] }}</text>
|
||
<text class="picker-arrow">▼</text>
|
||
</view>
|
||
</picker>
|
||
<picker class="filter-picker" mode="selector" :value="selectedTypeFilter" :range="typeFilterLabels" @change="onTypeFilterChange">
|
||
<view class="picker-item">
|
||
<text class="picker-text">{{ typeFilterLabels[selectedTypeFilter] }}</text>
|
||
<text class="picker-arrow">▼</text>
|
||
</view>
|
||
</picker>
|
||
</view>
|
||
</view>
|
||
|
||
<!-- Records Summary -->
|
||
<view class="summary-cards">
|
||
<view class="summary-card">
|
||
<text class="summary-number">{{ recordsSummary.total }}</text>
|
||
<text class="summary-label">总记录数</text>
|
||
</view>
|
||
<view class="summary-card">
|
||
<text class="summary-number">{{ recordsSummary.today }}</text>
|
||
<text class="summary-label">今日记录</text>
|
||
</view>
|
||
<view class="summary-card">
|
||
<text class="summary-number">{{ recordsSummary.this_week }}</text>
|
||
<text class="summary-label">本周记录</text>
|
||
</view>
|
||
</view>
|
||
|
||
<!-- Records Timeline -->
|
||
<view v-if="filteredRecords.length > 0" class="records-timeline">
|
||
<view v-for="(dateGroup, dateKey) in groupedRecords" :key="dateKey" class="date-group">
|
||
<view class="date-header">
|
||
<text class="date-text">{{ formatDateHeader(dateKey) }}</text>
|
||
<text class="date-count">{{ dateGroup.length }}条记录</text>
|
||
</view>
|
||
|
||
<view v-for="record in dateGroup" :key="record.id" class="record-item" :class="getRecordTypeClass(record.type)">
|
||
<view class="record-timeline-marker" :class="getRecordTypeClass(record.type)"></view>
|
||
<view class="record-content-wrapper">
|
||
<view class="record-header">
|
||
<text class="record-type">{{ getCareRecordTypeText(record.type) }}</text>
|
||
<text class="record-time">{{ formatTime(record.created_at) }}</text>
|
||
</view>
|
||
<view class="record-content">
|
||
<text class="record-notes">{{ record.notes }}</text>
|
||
<view class="record-details" v-if="record.details">
|
||
<view class="detail-item" v-for="(value, key) in parseRecordDetails(record.details)" :key="key">
|
||
<text class="detail-label">{{ getDetailLabel(key) }}:</text>
|
||
<text class="detail-value">{{ value }}</text>
|
||
</view>
|
||
</view>
|
||
</view>
|
||
<view class="record-footer">
|
||
<text class="record-caregiver">护理员:{{ record.caregiver_name }}</text>
|
||
<view class="record-actions">
|
||
<button class="action-btn" @tap="viewRecordDetail(record)" v-if="record.type === 'vital_signs'">
|
||
<text class="btn-text">查看详情</text>
|
||
</button>
|
||
</view>
|
||
</view>
|
||
</view>
|
||
</view>
|
||
</view>
|
||
</view>
|
||
|
||
<!-- Empty State -->
|
||
<view v-else class="empty-records">
|
||
<text class="empty-icon">📋</text>
|
||
<text class="empty-title">暂无护理记录</text>
|
||
<text class="empty-subtitle">选择不同的筛选条件查看记录</text>
|
||
</view>
|
||
|
||
<!-- Record Detail Modal -->
|
||
<view class="record-modal" v-if="showRecordDetail" @tap="hideRecordDetail">
|
||
<view class="modal-content" @tap.stop>
|
||
<view class="modal-header">
|
||
<text class="modal-title">{{ getCareRecordTypeText(selectedRecord.type) }}</text>
|
||
<button class="close-btn" @tap="hideRecordDetail">
|
||
<text class="close-icon">×</text>
|
||
</button>
|
||
</view>
|
||
<view class="modal-body">
|
||
<view class="detail-section">
|
||
<text class="section-title">基本信息</text>
|
||
<view class="detail-row">
|
||
<text class="detail-label">记录时间:</text>
|
||
<text class="detail-value">{{ formatDateTime(selectedRecord.created_at) }}</text>
|
||
</view>
|
||
<view class="detail-row">
|
||
<text class="detail-label">护理员:</text>
|
||
<text class="detail-value">{{ selectedRecord.caregiver_name }}</text>
|
||
</view>
|
||
</view>
|
||
|
||
<view class="detail-section" v-if="selectedRecord.type === 'vital_signs'">
|
||
<text class="section-title">生命体征</text>
|
||
<view class="vitals-grid" v-if="selectedRecord.vital_signs">
|
||
<view class="vital-item" v-for="vital in selectedRecord.vital_signs" :key="vital.type">
|
||
<text class="vital-label">{{ getVitalLabel(vital.type) }}</text>
|
||
<text class="vital-value">{{ vital.value }}{{ getVitalUnit(vital.type) }}</text>
|
||
<text class="vital-status" :class="vital.status">{{ getStatusText(vital.status) }}</text>
|
||
</view>
|
||
</view>
|
||
</view>
|
||
|
||
<view class="detail-section" v-if="selectedRecord.notes">
|
||
<text class="section-title">护理记录</text>
|
||
<text class="notes-content">{{ selectedRecord.notes }}</text>
|
||
</view>
|
||
</view>
|
||
</view>
|
||
</view>
|
||
</scroll-view>
|
||
</template>
|
||
|
||
<style scoped>
|
||
.care-records-container {
|
||
min-height: 100vh;
|
||
background-color: #f8f9fa;
|
||
}
|
||
|
||
.records-header {
|
||
background: white;
|
||
padding: 40rpx;
|
||
border-bottom: 1rpx solid #eee;
|
||
}
|
||
|
||
.header-title {
|
||
font-size: 44rpx;
|
||
font-weight: bold;
|
||
color: #333;
|
||
display: block;
|
||
margin-bottom: 8rpx;
|
||
}
|
||
|
||
.header-subtitle {
|
||
font-size: 28rpx;
|
||
color: #666;
|
||
display: block;
|
||
margin-bottom: 30rpx;
|
||
}
|
||
|
||
.filter-bar {
|
||
display: flex;
|
||
gap: 20rpx;
|
||
}
|
||
|
||
.filter-picker {
|
||
flex: 1;
|
||
}
|
||
|
||
.picker-item {
|
||
display: flex;
|
||
align-items: center;
|
||
justify-content: space-between;
|
||
padding: 20rpx;
|
||
background: #f8f9fa;
|
||
border-radius: 12rpx;
|
||
border: 1rpx solid #ddd;
|
||
}
|
||
|
||
.picker-text {
|
||
font-size: 28rpx;
|
||
color: #333;
|
||
}
|
||
|
||
.picker-arrow {
|
||
font-size: 24rpx;
|
||
color: #666;
|
||
}
|
||
|
||
.summary-cards {
|
||
display: flex;
|
||
padding: 40rpx;
|
||
gap: 20rpx;
|
||
}
|
||
|
||
.summary-card {
|
||
flex: 1;
|
||
background: white;
|
||
padding: 30rpx;
|
||
border-radius: 16rpx;
|
||
text-align: center;
|
||
box-shadow: 0 4rpx 12rpx rgba(0,0,0,0.05);
|
||
}
|
||
|
||
.summary-number {
|
||
font-size: 48rpx;
|
||
font-weight: bold;
|
||
color: #007AFF;
|
||
display: block;
|
||
margin-bottom: 8rpx;
|
||
}
|
||
|
||
.summary-label {
|
||
font-size: 26rpx;
|
||
color: #666;
|
||
display: block;
|
||
}
|
||
|
||
.records-timeline {
|
||
padding: 0 40rpx 40rpx;
|
||
}
|
||
|
||
.date-group {
|
||
margin-bottom: 40rpx;
|
||
}
|
||
|
||
.date-header {
|
||
display: flex;
|
||
align-items: center;
|
||
justify-content: space-between;
|
||
margin-bottom: 20rpx;
|
||
padding: 20rpx;
|
||
background: white;
|
||
border-radius: 12rpx;
|
||
}
|
||
|
||
.date-text {
|
||
font-size: 32rpx;
|
||
font-weight: 600;
|
||
color: #333;
|
||
}
|
||
|
||
.date-count {
|
||
font-size: 24rpx;
|
||
color: #666;
|
||
background: #f0f0f0;
|
||
padding: 6rpx 12rpx;
|
||
border-radius: 12rpx;
|
||
}
|
||
|
||
.record-item {
|
||
display: flex;
|
||
margin-bottom: 20rpx;
|
||
position: relative;
|
||
}
|
||
|
||
.record-timeline-marker {
|
||
width: 24rpx;
|
||
height: 24rpx;
|
||
border-radius: 12rpx;
|
||
margin-right: 20rpx;
|
||
margin-top: 20rpx;
|
||
flex-shrink: 0;
|
||
}
|
||
|
||
.record-timeline-marker.vital_signs {
|
||
background: #ff6b6b;
|
||
}
|
||
|
||
.record-timeline-marker.medication {
|
||
background: #4ecdc4;
|
||
}
|
||
|
||
.record-timeline-marker.nursing {
|
||
background: #45b7d1;
|
||
}
|
||
|
||
.record-timeline-marker.meal {
|
||
background: #f9ca24;
|
||
}
|
||
|
||
.record-timeline-marker.activity {
|
||
background: #6c5ce7;
|
||
}
|
||
|
||
.record-timeline-marker.incident {
|
||
background: #fd79a8;
|
||
}
|
||
|
||
.record-content-wrapper {
|
||
flex: 1;
|
||
background: white;
|
||
border-radius: 16rpx;
|
||
padding: 24rpx;
|
||
box-shadow: 0 4rpx 12rpx rgba(0,0,0,0.05);
|
||
}
|
||
|
||
.record-header {
|
||
display: flex;
|
||
align-items: center;
|
||
justify-content: space-between;
|
||
margin-bottom: 16rpx;
|
||
}
|
||
|
||
.record-type {
|
||
font-size: 30rpx;
|
||
font-weight: 600;
|
||
color: #333;
|
||
}
|
||
|
||
.record-time {
|
||
font-size: 26rpx;
|
||
color: #666;
|
||
}
|
||
|
||
.record-content {
|
||
margin-bottom: 16rpx;
|
||
}
|
||
|
||
.record-notes {
|
||
font-size: 28rpx;
|
||
color: #333;
|
||
line-height: 1.6;
|
||
display: block;
|
||
margin-bottom: 12rpx;
|
||
}
|
||
|
||
.record-details {
|
||
background: #f8f9fa;
|
||
padding: 16rpx;
|
||
border-radius: 8rpx;
|
||
}
|
||
|
||
.detail-item {
|
||
display: flex;
|
||
margin-bottom: 8rpx;
|
||
}
|
||
|
||
.detail-item:last-child {
|
||
margin-bottom: 0;
|
||
}
|
||
|
||
.detail-label {
|
||
width: 160rpx;
|
||
font-size: 26rpx;
|
||
color: #666;
|
||
flex-shrink: 0;
|
||
}
|
||
|
||
.detail-value {
|
||
font-size: 26rpx;
|
||
color: #333;
|
||
flex: 1;
|
||
}
|
||
|
||
.record-footer {
|
||
display: flex;
|
||
align-items: center;
|
||
justify-content: space-between;
|
||
padding-top: 16rpx;
|
||
border-top: 1rpx solid #f0f0f0;
|
||
}
|
||
|
||
.record-caregiver {
|
||
font-size: 24rpx;
|
||
color: #666;
|
||
}
|
||
|
||
.record-actions {
|
||
display: flex;
|
||
gap: 12rpx;
|
||
}
|
||
|
||
.action-btn {
|
||
padding: 12rpx 20rpx;
|
||
background: #007AFF;
|
||
color: white;
|
||
border-radius: 16rpx;
|
||
border: none;
|
||
font-size: 24rpx;
|
||
}
|
||
|
||
.empty-records {
|
||
padding: 120rpx 40rpx;
|
||
text-align: center;
|
||
}
|
||
|
||
.empty-icon {
|
||
font-size: 120rpx;
|
||
display: block;
|
||
margin-bottom: 30rpx;
|
||
opacity: 0.3;
|
||
}
|
||
|
||
.empty-title {
|
||
font-size: 36rpx;
|
||
color: #333;
|
||
display: block;
|
||
margin-bottom: 12rpx;
|
||
font-weight: 600;
|
||
}
|
||
|
||
.empty-subtitle {
|
||
font-size: 28rpx;
|
||
color: #666;
|
||
display: block;
|
||
}
|
||
|
||
.record-modal {
|
||
position: fixed;
|
||
top: 0;
|
||
left: 0;
|
||
right: 0;
|
||
bottom: 0;
|
||
background: rgba(0,0,0,0.5);
|
||
display: flex;
|
||
align-items: center;
|
||
justify-content: center;
|
||
z-index: 1000;
|
||
}
|
||
|
||
.modal-content {
|
||
background: white;
|
||
border-radius: 24rpx;
|
||
width: 90%;
|
||
max-width: 800rpx;
|
||
max-height: 80%;
|
||
overflow: hidden;
|
||
}
|
||
|
||
.modal-header {
|
||
display: flex;
|
||
align-items: center;
|
||
justify-content: space-between;
|
||
padding: 30rpx 40rpx;
|
||
border-bottom: 1rpx solid #eee;
|
||
}
|
||
|
||
.modal-title {
|
||
font-size: 36rpx;
|
||
font-weight: bold;
|
||
color: #333;
|
||
}
|
||
|
||
.close-btn {
|
||
width: 60rpx;
|
||
height: 60rpx;
|
||
border-radius: 30rpx;
|
||
background: #f0f0f0;
|
||
border: none;
|
||
display: flex;
|
||
align-items: center;
|
||
justify-content: center;
|
||
}
|
||
|
||
.close-icon {
|
||
font-size: 40rpx;
|
||
color: #666;
|
||
}
|
||
|
||
.modal-body {
|
||
padding: 40rpx;
|
||
max-height: 600rpx;
|
||
overflow-y: auto;
|
||
}
|
||
|
||
.detail-section {
|
||
margin-bottom: 40rpx;
|
||
}
|
||
|
||
.detail-section:last-child {
|
||
margin-bottom: 0;
|
||
}
|
||
|
||
.section-title {
|
||
font-size: 32rpx;
|
||
font-weight: 600;
|
||
color: #333;
|
||
display: block;
|
||
margin-bottom: 20rpx;
|
||
}
|
||
|
||
.detail-row {
|
||
display: flex;
|
||
margin-bottom: 16rpx;
|
||
}
|
||
|
||
.detail-row:last-child {
|
||
margin-bottom: 0;
|
||
}
|
||
|
||
.vitals-grid {
|
||
display: flex;
|
||
flex-wrap: wrap;
|
||
gap: 20rpx;
|
||
}
|
||
|
||
.vital-item {
|
||
flex: 1;
|
||
min-width: 200rpx;
|
||
background: #f8f9fa;
|
||
padding: 24rpx;
|
||
border-radius: 12rpx;
|
||
text-align: center;
|
||
}
|
||
|
||
.vital-label {
|
||
font-size: 26rpx;
|
||
color: #666;
|
||
display: block;
|
||
margin-bottom: 8rpx;
|
||
}
|
||
|
||
.vital-value {
|
||
font-size: 32rpx;
|
||
font-weight: bold;
|
||
color: #333;
|
||
display: block;
|
||
margin-bottom: 8rpx;
|
||
}
|
||
|
||
.vital-status {
|
||
font-size: 24rpx;
|
||
padding: 4rpx 8rpx;
|
||
border-radius: 8rpx;
|
||
display: inline-block;
|
||
}
|
||
|
||
.vital-status.normal {
|
||
background: #e8f5e8;
|
||
color: #4caf50;
|
||
}
|
||
|
||
.vital-status.warning {
|
||
background: #fff3e0;
|
||
color: #ff9800;
|
||
}
|
||
|
||
.vital-status.danger {
|
||
background: #ffebee;
|
||
color: #f44336;
|
||
}
|
||
|
||
.notes-content {
|
||
font-size: 28rpx;
|
||
color: #333;
|
||
line-height: 1.6;
|
||
background: #f8f9fa;
|
||
padding: 20rpx;
|
||
border-radius: 12rpx;
|
||
}
|
||
</style>
|
||
|
||
<script setup lang="uts">
|
||
import { ref, computed, onMounted } from 'vue'
|
||
import { formatDate, formatTime, formatDateTime, getStatusText } from '../types.uts'
|
||
import type { ElderInfo, CareRecord, HealthVitals } from '../types.uts'
|
||
|
||
// 数据状态
|
||
const elderInfo = ref<ElderInfo>({
|
||
id: '',
|
||
name: '',
|
||
age: 0,
|
||
gender: 'male',
|
||
room_number: '',
|
||
bed_number: '',
|
||
admission_date: '',
|
||
health_status: 'stable',
|
||
care_level: 1,
|
||
emergency_contact: '',
|
||
profile_picture: '',
|
||
family_contact: ''
|
||
})
|
||
|
||
const allRecords = ref<CareRecord[]>([])
|
||
const recordsSummary = ref({
|
||
total: 0,
|
||
today: 0,
|
||
this_week: 0
|
||
})
|
||
|
||
const selectedTimeFilter = ref(0)
|
||
const selectedTypeFilter = ref(0)
|
||
const showRecordDetail = ref(false)
|
||
const selectedRecord = ref<CareRecord>({
|
||
id: '',
|
||
elder_id: '',
|
||
type: 'nursing',
|
||
notes: '',
|
||
created_at: '',
|
||
caregiver_id: '',
|
||
caregiver_name: '',
|
||
details: null,
|
||
vital_signs: null
|
||
})
|
||
|
||
// 筛选选项
|
||
const timeFilters = [
|
||
{ label: '全部', value: 'all' },
|
||
{ label: '今天', value: 'today' },
|
||
{ label: '本周', value: 'week' },
|
||
{ label: '本月', value: 'month' }
|
||
]
|
||
|
||
const typeFilters = [
|
||
{ label: '全部类型', value: 'all' },
|
||
{ label: '生命体征', value: 'vital_signs' },
|
||
{ label: '用药记录', value: 'medication' },
|
||
{ label: '护理服务', value: 'nursing' },
|
||
{ label: '用餐记录', value: 'meal' },
|
||
{ label: '活动记录', value: 'activity' },
|
||
{ label: '事件记录', value: 'incident' }
|
||
]
|
||
|
||
const timeFilterLabels = computed(() => timeFilters.map(f => f.label))
|
||
const typeFilterLabels = computed(() => typeFilters.map(f => f.label))
|
||
|
||
// 筛选记录
|
||
const filteredRecords = computed(() => {
|
||
let records = [...allRecords.value]
|
||
|
||
// 时间筛选
|
||
const timeFilter = timeFilters[selectedTimeFilter.value]
|
||
if (timeFilter.value !== 'all') {
|
||
const now = new Date()
|
||
const today = new Date(now.getFullYear(), now.getMonth(), now.getDate())
|
||
|
||
records = records.filter(record => {
|
||
const recordDate = new Date(record.created_at)
|
||
|
||
switch (timeFilter.value) {
|
||
case 'today':
|
||
return recordDate >= today
|
||
case 'week':
|
||
const weekStart = new Date(today)
|
||
weekStart.setDate(today.getDate() - today.getDay())
|
||
return recordDate >= weekStart
|
||
case 'month':
|
||
const monthStart = new Date(today.getFullYear(), today.getMonth(), 1)
|
||
return recordDate >= monthStart
|
||
default:
|
||
return true
|
||
}
|
||
})
|
||
}
|
||
|
||
// 类型筛选
|
||
const typeFilter = typeFilters[selectedTypeFilter.value]
|
||
if (typeFilter.value !== 'all') {
|
||
records = records.filter(record => record.type === typeFilter.value)
|
||
}
|
||
|
||
return records
|
||
})
|
||
|
||
// 按日期分组记录
|
||
const groupedRecords = computed(() => {
|
||
const groups: Record<string, CareRecord[]> = {}
|
||
|
||
filteredRecords.value.forEach(record => {
|
||
const date = new Date(record.created_at).toISOString().split('T')[0]
|
||
if (!groups[date]) {
|
||
groups[date] = []
|
||
}
|
||
groups[date].push(record)
|
||
})
|
||
|
||
// 按日期排序
|
||
const sortedGroups: Record<string, CareRecord[]> = {}
|
||
Object.keys(groups)
|
||
.sort((a, b) => new Date(b).getTime() - new Date(a).getTime())
|
||
.forEach(date => {
|
||
// 每组内按时间排序
|
||
sortedGroups[date] = groups[date].sort((a, b) =>
|
||
new Date(b.created_at).getTime() - new Date(a.created_at).getTime()
|
||
)
|
||
})
|
||
|
||
return sortedGroups
|
||
})
|
||
|
||
// 辅助函数
|
||
function getCareRecordTypeText(type: string): string {
|
||
const typeMap = {
|
||
'vital_signs': '生命体征',
|
||
'medication': '用药记录',
|
||
'nursing': '护理服务',
|
||
'meal': '用餐记录',
|
||
'activity': '活动记录',
|
||
'incident': '事件记录'
|
||
}
|
||
return typeMap[type] || type
|
||
}
|
||
|
||
function getRecordTypeClass(type: string): string {
|
||
return type
|
||
}
|
||
|
||
function getVitalLabel(type: string): string {
|
||
const labels = {
|
||
'heart_rate': '心率',
|
||
'blood_pressure': '血压',
|
||
'temperature': '体温',
|
||
'blood_sugar': '血糖',
|
||
'oxygen_saturation': '血氧'
|
||
}
|
||
return labels[type] || type
|
||
}
|
||
|
||
function getVitalUnit(type: string): string {
|
||
const units = {
|
||
'heart_rate': 'bpm',
|
||
'blood_pressure': 'mmHg',
|
||
'temperature': '°C',
|
||
'blood_sugar': 'mmol/L',
|
||
'oxygen_saturation': '%'
|
||
}
|
||
return units[type] || ''
|
||
}
|
||
|
||
function formatDateHeader(dateStr: string): string {
|
||
const date = new Date(dateStr)
|
||
const today = new Date()
|
||
const yesterday = new Date(today)
|
||
yesterday.setDate(today.getDate() - 1)
|
||
|
||
if (date.toDateString() === today.toDateString()) {
|
||
return '今天'
|
||
} else if (date.toDateString() === yesterday.toDateString()) {
|
||
return '昨天'
|
||
} else {
|
||
return formatDate(dateStr)
|
||
}
|
||
}
|
||
|
||
function parseRecordDetails(details: string | null): Record<string, string> {
|
||
if (!details) return {}
|
||
|
||
try {
|
||
return JSON.parse(details)
|
||
} catch {
|
||
return {}
|
||
}
|
||
}
|
||
|
||
function getDetailLabel(key: string): string {
|
||
const labels = {
|
||
'duration': '持续时间',
|
||
'dosage': '剂量',
|
||
'location': '位置',
|
||
'temperature': '温度',
|
||
'amount': '数量',
|
||
'notes': '备注'
|
||
}
|
||
return labels[key] || key
|
||
}
|
||
|
||
// 事件处理
|
||
function onTimeFilterChange(e: any) {
|
||
selectedTimeFilter.value = e.detail.value
|
||
}
|
||
|
||
function onTypeFilterChange(e: any) {
|
||
selectedTypeFilter.value = e.detail.value
|
||
}
|
||
|
||
function viewRecordDetail(record: CareRecord) {
|
||
selectedRecord.value = record
|
||
showRecordDetail.value = true
|
||
}
|
||
|
||
function hideRecordDetail() {
|
||
showRecordDetail.value = false
|
||
}
|
||
|
||
// 数据加载
|
||
async function loadElderInfo() {
|
||
try {
|
||
const pages = getCurrentPages()
|
||
const currentPage = pages[pages.length - 1]
|
||
const elderId = currentPage.$route.query?.elder_id as string
|
||
|
||
if (!elderId) {
|
||
uni.showToast({
|
||
title: '缺少老人ID',
|
||
icon: 'error'
|
||
})
|
||
return
|
||
}
|
||
|
||
const supa = (globalThis as any).supa
|
||
const result = await supa.executeAs('get_elder_info', {
|
||
elder_id: elderId
|
||
})
|
||
|
||
if (result && result.length > 0) {
|
||
elderInfo.value = result[0]
|
||
}
|
||
} catch (error) {
|
||
console.error('加载老人信息失败:', error)
|
||
}
|
||
}
|
||
|
||
async function loadCareRecords() {
|
||
try {
|
||
const supa = (globalThis as any).supa
|
||
const result = await supa.executeAs('get_elder_care_records', {
|
||
elder_id: elderInfo.value.id,
|
||
limit: 100
|
||
})
|
||
|
||
if (result && result.length > 0) {
|
||
allRecords.value = result
|
||
}
|
||
} catch (error) {
|
||
console.error('加载护理记录失败:', error)
|
||
}
|
||
}
|
||
|
||
async function loadRecordsSummary() {
|
||
try {
|
||
const supa = (globalThis as any).supa
|
||
const result = await supa.executeAs('get_care_records_summary', {
|
||
elder_id: elderInfo.value.id
|
||
})
|
||
|
||
if (result && result.length > 0) {
|
||
recordsSummary.value = result[0]
|
||
}
|
||
} catch (error) {
|
||
console.error('加载记录统计失败:', error)
|
||
}
|
||
}
|
||
|
||
// 初始化
|
||
onMounted(async () => {
|
||
await loadElderInfo()
|
||
if (elderInfo.value.id) {
|
||
await Promise.all([
|
||
loadCareRecords(),
|
||
loadRecordsSummary()
|
||
])
|
||
}
|
||
})
|
||
</script>
|