210 lines
6.3 KiB
Plaintext
210 lines
6.3 KiB
Plaintext
<template>
|
|
<view class="health-details">
|
|
<view class="header">
|
|
<text class="title">健康详情</text>
|
|
</view>
|
|
<view class="summary-section">
|
|
<view class="summary-item">
|
|
<text class="label">姓名:</text>
|
|
<text class="value">{{ elderInfo.name }}</text>
|
|
</view>
|
|
<view class="summary-item">
|
|
<text class="label">性别:</text>
|
|
<text class="value">{{ elderInfo.gender }}</text>
|
|
</view>
|
|
<view class="summary-item">
|
|
<text class="label">年龄:</text>
|
|
<text class="value">{{ getAge(elderInfo.birthday) }}</text>
|
|
</view>
|
|
<view class="summary-item">
|
|
<text class="label">房间号:</text>
|
|
<text class="value">{{ elderInfo.room_number }}</text>
|
|
</view>
|
|
</view>
|
|
<view class="vital-history-section">
|
|
<text class="section-title">生命体征历史</text>
|
|
<view v-if="vitalHistory.length > 0">
|
|
<view class="vital-row" v-for="vital in vitalHistory" :key="vital.id">
|
|
<text class="vital-date">{{ formatDateTime(vital.measured_at) }}</text>
|
|
<text class="vital-type">{{ getVitalLabel(vital.vital_type) }}</text>
|
|
<text class="vital-value">{{ getVitalValue(vital) }}</text>
|
|
<text class="vital-status" :class="vital.is_abnormal ? 'abnormal' : 'normal'">
|
|
{{ vital.is_abnormal ? '异常' : '正常' }}
|
|
</text>
|
|
</view>
|
|
</view>
|
|
<view v-else class="empty-state">
|
|
<text>暂无生命体征记录</text>
|
|
</view>
|
|
</view>
|
|
<view class="health-record-section">
|
|
<text class="section-title">健康档案</text>
|
|
<view v-if="healthRecords.length > 0">
|
|
<view class="record-row" v-for="record in healthRecords" :key="record.id">
|
|
<text class="record-date">{{ formatDate(record.record_date) }}</text>
|
|
<text class="record-type">{{ getRecordTypeText(record.record_type) }}</text>
|
|
<text class="record-summary">身高: {{ record.height_cm }}cm 体重: {{ record.weight_kg }}kg</text>
|
|
</view>
|
|
</view>
|
|
<view v-else class="empty-state">
|
|
<text>暂无健康档案</text>
|
|
</view>
|
|
</view>
|
|
<view class="alert-section">
|
|
<text class="section-title">健康预警</text>
|
|
<view v-if="alerts.length > 0">
|
|
<view class="alert-row" v-for="alert in alerts" :key="alert.id">
|
|
<text class="alert-title">{{ alert.title }}</text>
|
|
<text class="alert-severity" :class="getSeverityClass(alert.severity)">{{ getSeverityText(alert.severity) }}</text>
|
|
<text class="alert-time">{{ formatDateTime(alert.created_at) }}</text>
|
|
</view>
|
|
</view>
|
|
<view v-else class="empty-state">
|
|
<text>暂无健康预警</text>
|
|
</view>
|
|
</view>
|
|
</view>
|
|
</template>
|
|
|
|
<script setup lang="uts">
|
|
import { ref } from 'vue'
|
|
import supa from '@/components/supadb/aksupainstance.uts'
|
|
import { formatDate, formatDateTime, getAge, getRecordTypeText, getSeverityText, getSeverityClass } from '../types.uts'
|
|
import type { Elder, VitalSign, HealthAlert } from '../types.uts'
|
|
|
|
const elderInfo = ref<Elder>({
|
|
id: '',
|
|
name: '',
|
|
gender: '',
|
|
birthday: '',
|
|
room_number: '',
|
|
// ...可补充其它字段
|
|
})
|
|
const vitalHistory = ref<VitalSign[]>([])
|
|
const healthRecords = ref<any[]>([])
|
|
const alerts = ref<HealthAlert[]>([])
|
|
|
|
function getVitalLabel(type: string): string {
|
|
const labels = {
|
|
'heart_rate': '心率',
|
|
'blood_pressure': '血压',
|
|
'temperature': '体温',
|
|
'blood_sugar': '血糖',
|
|
'oxygen_saturation': '血氧'
|
|
}
|
|
return labels[type] || type
|
|
}
|
|
function getVitalValue(vital: VitalSign): string {
|
|
switch (vital.vital_type) {
|
|
case 'heart_rate': return vital.heart_rate ? vital.heart_rate + ' bpm' : '-'
|
|
case 'blood_pressure': return vital.systolic_pressure && vital.diastolic_pressure ? `${vital.systolic_pressure}/${vital.diastolic_pressure} mmHg` : '-'
|
|
case 'temperature': return vital.temperature ? vital.temperature + '°C' : '-'
|
|
case 'blood_sugar': return vital.glucose_level ? vital.glucose_level + ' mmol/L' : '-'
|
|
case 'oxygen_saturation': return vital.oxygen_saturation ? vital.oxygen_saturation + '%' : '-'
|
|
default: return '-'
|
|
}
|
|
}
|
|
|
|
onLoad(async(options: OnLoadOptions) => {
|
|
const elderId = options['id']
|
|
if (!elderId) return
|
|
// 获取老人基本信息
|
|
const elderRes = await supa.rpc('get_elder_info', { elder_id: elderId }).execute()
|
|
if (elderRes && elderRes.length > 0) elderInfo.value = elderRes[0]
|
|
// 获取生命体征历史
|
|
const vitalsRes = await supa.rpc('get_vital_history', { elder_id: elderId, limit: 20 }).execute()
|
|
if (vitalsRes) vitalHistory.value = vitalsRes
|
|
// 获取健康档案
|
|
const healthRes = await supa.rpc('get_health_records', { elder_id: elderId }).execute()
|
|
if (healthRes) healthRecords.value = healthRes
|
|
// 获取健康预警
|
|
const alertRes = await supa.rpc('get_health_alerts', { elder_id: elderId }).execute()
|
|
if (alertRes) alerts.value = alertRes
|
|
})
|
|
</script>
|
|
|
|
<style scoped>
|
|
.health-details {
|
|
padding: 40rpx;
|
|
background: #f8f9fa;
|
|
min-height: 100vh;
|
|
}
|
|
.header {
|
|
margin-bottom: 32rpx;
|
|
}
|
|
.title {
|
|
font-size: 44rpx;
|
|
font-weight: bold;
|
|
color: #333;
|
|
}
|
|
.summary-section {
|
|
background: #fff;
|
|
border-radius: 16rpx;
|
|
padding: 32rpx;
|
|
margin-bottom: 32rpx;
|
|
}
|
|
.summary-item {
|
|
display: flex;
|
|
flex-direction: row;
|
|
margin-bottom: 16rpx;
|
|
}
|
|
.label {
|
|
color: #666;
|
|
width: 120rpx;
|
|
}
|
|
.value {
|
|
color: #222;
|
|
font-weight: 500;
|
|
}
|
|
.vital-history-section, .health-record-section, .alert-section {
|
|
background: #fff;
|
|
border-radius: 16rpx;
|
|
padding: 32rpx;
|
|
margin-bottom: 32rpx;
|
|
}
|
|
.section-title {
|
|
font-size: 32rpx;
|
|
font-weight: bold;
|
|
color: #007AFF;
|
|
margin-bottom: 20rpx;
|
|
}
|
|
.vital-row, .record-row, .alert-row {
|
|
display: flex;
|
|
flex-direction: row;
|
|
align-items: center;
|
|
margin-bottom: 16rpx;
|
|
}
|
|
.vital-date, .record-date, .alert-time {
|
|
width: 180rpx;
|
|
color: #888;
|
|
font-size: 26rpx;
|
|
}
|
|
.vital-type, .record-type, .alert-title {
|
|
width: 120rpx;
|
|
color: #333;
|
|
font-size: 28rpx;
|
|
}
|
|
.vital-value, .record-summary {
|
|
flex: 1;
|
|
color: #222;
|
|
font-size: 28rpx;
|
|
}
|
|
.vital-status.normal {
|
|
color: #4caf50;
|
|
}
|
|
.vital-status.abnormal {
|
|
color: #f44336;
|
|
}
|
|
.alert-severity {
|
|
margin-left: 16rpx;
|
|
font-size: 26rpx;
|
|
padding: 4rpx 12rpx;
|
|
border-radius: 10rpx;
|
|
}
|
|
.empty-state {
|
|
color: #aaa;
|
|
text-align: center;
|
|
padding: 40rpx 0;
|
|
}
|
|
</style>
|