929 lines
21 KiB
Plaintext
929 lines
21 KiB
Plaintext
<template>
|
||
<view class="elder-dashboard">
|
||
<!-- 头部欢迎区域 -->
|
||
<view class="header-section">
|
||
<view class="welcome-card">
|
||
<text class="welcome-text">{{ greeting }},{{ elderInfo.name }}</text>
|
||
<text class="weather-info">今天天气:{{ weatherInfo.description }}</text>
|
||
<text class="date-info">{{ formatDate(new Date()) }}</text>
|
||
</view>
|
||
</view>
|
||
|
||
<!-- 健康状态卡片 -->
|
||
<view class="health-section">
|
||
<view class="section-title">
|
||
<text class="title-text">我的健康</text>
|
||
<button class="view-all-btn" @tap="goToHealthDetails">
|
||
<text class="btn-text">查看详情</text>
|
||
</button>
|
||
</view>
|
||
<view class="health-cards">
|
||
<view class="health-card" v-for="vital in vitals" :key="vital.type">
|
||
<text class="health-icon">{{ getVitalIcon(vital.type) }}</text>
|
||
<text class="health-label">{{ getVitalLabel(vital.type) }}</text>
|
||
<text class="health-value">{{ vital.value }}{{ getVitalUnit(vital.type) }}</text>
|
||
<text class="health-status" :class="vital.status">{{ getStatusText(vital.status) }}</text>
|
||
</view>
|
||
</view>
|
||
</view>
|
||
|
||
<!-- 今日活动 -->
|
||
<view class="activity-section">
|
||
<view class="section-title">
|
||
<text class="title-text">今日活动</text>
|
||
<text class="activity-count">{{ todayActivities.length }}项</text>
|
||
</view>
|
||
<view class="activity-list" v-if="todayActivities.length > 0">
|
||
<view class="activity-item" v-for="activity in todayActivities" :key="activity.id">
|
||
<view class="activity-time">
|
||
<text class="time-text">{{ formatTime(activity.scheduled_time) }}</text>
|
||
</view>
|
||
<view class="activity-info">
|
||
<text class="activity-name">{{ activity.title }}</text>
|
||
<text class="activity-location">{{ activity.location }}</text>
|
||
</view>
|
||
<view class="activity-status" :class="activity.status">
|
||
<text class="status-text">{{ getActivityStatusText(activity.status) }}</text>
|
||
</view>
|
||
</view>
|
||
</view>
|
||
<view class="empty-state" v-else>
|
||
<text class="empty-text">今天没有安排活动</text>
|
||
</view>
|
||
</view>
|
||
|
||
<!-- 用药提醒 -->
|
||
<view class="medication-section">
|
||
<view class="section-title">
|
||
<text class="title-text">用药提醒</text>
|
||
<view class="medication-alert" v-if="upcomingMedications.length > 0">
|
||
<text class="alert-text">{{ upcomingMedications.length }}个即将到期</text>
|
||
</view>
|
||
</view>
|
||
<view class="medication-list" v-if="todayMedications.length > 0">
|
||
<view class="medication-item" v-for="medication in todayMedications" :key="medication.id">
|
||
<view class="medication-time">
|
||
<text class="time-text">{{ formatTime(medication.scheduled_time) }}</text>
|
||
</view>
|
||
<view class="medication-info">
|
||
<text class="medication-name">{{ medication.medication_name }}</text>
|
||
<text class="medication-dosage">{{ medication.dosage }}</text>
|
||
</view>
|
||
<view class="medication-actions">
|
||
<button class="action-btn taken" @tap="markMedicationTaken(medication.id)" v-if="medication.status !== 'taken'">
|
||
<text class="btn-text">已服用</text>
|
||
</button>
|
||
<view class="taken-indicator" v-else>
|
||
<text class="taken-text">✓ 已服用</text>
|
||
</view>
|
||
</view>
|
||
</view>
|
||
</view>
|
||
<view class="empty-state" v-else>
|
||
<text class="empty-text">今天没有用药安排</text>
|
||
</view>
|
||
</view>
|
||
|
||
<!-- 护理服务 -->
|
||
<view class="care-section">
|
||
<view class="section-title">
|
||
<text class="title-text">护理服务</text>
|
||
</view>
|
||
<view class="care-summary">
|
||
<view class="care-card" @tap="goToCareRecords">
|
||
<text class="care-icon">👩⚕️</text>
|
||
<text class="care-label">护理员</text>
|
||
<text class="care-value">{{ caregiverInfo.name }}</text>
|
||
<text class="care-status">在线</text>
|
||
</view>
|
||
<view class="care-card" @tap="goToServiceRequests">
|
||
<text class="care-icon">🔔</text>
|
||
<text class="care-label">服务请求</text>
|
||
<text class="care-value">{{ pendingRequests }}</text>
|
||
<text class="care-status">待处理</text>
|
||
</view>
|
||
</view>
|
||
</view>
|
||
|
||
<!-- 快捷操作 -->
|
||
<view class="quick-actions">
|
||
<view class="section-title">
|
||
<text class="title-text">快捷操作</text>
|
||
</view>
|
||
<view class="action-grid">
|
||
<view class="action-item" @tap="callEmergency">
|
||
<text class="action-icon">🚨</text>
|
||
<text class="action-label">紧急呼叫</text>
|
||
</view>
|
||
<view class="action-item" @tap="callNurse">
|
||
<text class="action-icon">🔔</text>
|
||
<text class="action-label">呼叫护理员</text>
|
||
</view>
|
||
<view class="action-item" @tap="viewMenu">
|
||
<text class="action-icon">🍽️</text>
|
||
<text class="action-label">今日菜单</text>
|
||
</view>
|
||
<view class="action-item" @tap="contactFamily">
|
||
<text class="action-icon">📞</text>
|
||
<text class="action-label">联系家人</text>
|
||
</view>
|
||
</view>
|
||
</view>
|
||
|
||
<!-- 紧急呼叫悬浮按钮 -->
|
||
<view class="emergency-fab" @tap="showEmergencyOptions">
|
||
<text class="fab-icon">🚨</text>
|
||
</view>
|
||
|
||
<!-- 紧急呼叫选项弹窗 -->
|
||
<view class="emergency-modal" v-if="showEmergencyModal" @tap="hideEmergencyOptions">
|
||
<view class="modal-content" @tap.stop>
|
||
<text class="modal-title">紧急呼叫</text>
|
||
<view class="emergency-options">
|
||
<button class="emergency-btn medical" @tap="callMedicalEmergency">
|
||
<text class="btn-text">医疗急救</text>
|
||
</button>
|
||
<button class="emergency-btn nurse" @tap="callNurseEmergency">
|
||
<text class="btn-text">护理员</text>
|
||
</button>
|
||
<button class="emergency-btn family" @tap="callFamilyEmergency">
|
||
<text class="btn-text">联系家人</text>
|
||
</button>
|
||
</view>
|
||
<button class="cancel-btn" @tap="hideEmergencyOptions">
|
||
<text class="btn-text">取消</text>
|
||
</button>
|
||
</view>
|
||
</view>
|
||
</view>
|
||
</template>
|
||
|
||
<script setup lang="uts">
|
||
import { ref, computed, onMounted } from 'vue'
|
||
import supa from '@/components/supadb/aksupainstance.uts'
|
||
import { state, getCurrentUserId } from '@/utils/store.uts'
|
||
|
||
import { formatDate, formatTime, getStatusText, getActivityStatusText } from '../types.uts'
|
||
import type { Elder, VitalSign, Activity, Medication, CaregiverInfo } from '../types.uts'
|
||
|
||
// 数据状态
|
||
const elderInfo = ref<Elder>({
|
||
id: '',
|
||
name: '',
|
||
age: 0,
|
||
gender: 'male',
|
||
room_number: '',
|
||
bed_number: '',
|
||
admission_date: '',
|
||
health_status: 'stable',
|
||
care_level: 1,
|
||
emergency_contact: '',
|
||
profile_picture: '',
|
||
family_contact: '',
|
||
status: 'normal',
|
||
|
||
})
|
||
|
||
const vitals = ref<VitalSign[]>([])
|
||
const todayActivities = ref<Activity[]>([])
|
||
const todayMedications = ref<Medication[]>([])
|
||
const caregiverInfo = ref<CaregiverInfo>({
|
||
id: '',
|
||
employee_id:'',
|
||
name: '',
|
||
phone: '',
|
||
department: '',
|
||
specialization: '',
|
||
shift: 'day'
|
||
})
|
||
|
||
const weatherInfo = ref({
|
||
description: '晴朗',
|
||
temperature: 22,
|
||
humidity: 65
|
||
})
|
||
|
||
const pendingRequests = ref(0)
|
||
const showEmergencyModal = ref(false)
|
||
|
||
// 计算属性
|
||
const greeting = computed(() => {
|
||
const hour = new Date().getHours()
|
||
if (hour < 12) return '早上好'
|
||
if (hour < 18) return '下午好'
|
||
return '晚上好'
|
||
})
|
||
|
||
const upcomingMedications = computed(() => {
|
||
const now = new Date()
|
||
const oneHour = 60 * 60 * 1000
|
||
return todayMedications.value.filter(med => {
|
||
const scheduledTime = new Date(med.scheduled_time)
|
||
return scheduledTime.getTime() - now.getTime() <= oneHour && scheduledTime.getTime() > now.getTime()
|
||
})
|
||
})
|
||
|
||
// 辅助函数
|
||
function getVitalIcon(type: string): string {
|
||
const icons = {
|
||
'heart_rate': '❤️',
|
||
'blood_pressure': '🩸',
|
||
'temperature': '🌡️',
|
||
'blood_sugar': '🍯',
|
||
'oxygen_saturation': '🫁'
|
||
}
|
||
return icons[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 goToHealthDetails() {
|
||
uni.navigateTo({
|
||
url: '/pages/ec/elder/health-details'
|
||
})
|
||
}
|
||
|
||
function goToCareRecords() {
|
||
uni.navigateTo({
|
||
url: '/pages/ec/elder/care-records'
|
||
})
|
||
}
|
||
|
||
function goToServiceRequests() {
|
||
uni.navigateTo({
|
||
url: '/pages/ec/elder/service-requests'
|
||
})
|
||
}
|
||
|
||
async function markMedicationTaken(medicationId: string) {
|
||
try {
|
||
const { error } = await supa
|
||
.from('ec_medications')
|
||
.update({ status: 'taken', updated_at: new Date().toISOString() })
|
||
.eq('id', medicationId)
|
||
.execute()
|
||
if (!error) {
|
||
const index = todayMedications.value.findIndex(med => med.id === medicationId)
|
||
if (index !== -1) {
|
||
todayMedications.value[index].status = 'taken'
|
||
}
|
||
uni.showToast({
|
||
title: '已标记为已服用',
|
||
icon: 'success'
|
||
})
|
||
} else {
|
||
throw error
|
||
}
|
||
} catch (error) {
|
||
console.error('标记用药失败:', error)
|
||
uni.showToast({
|
||
title: '操作失败',
|
||
icon: 'error'
|
||
})
|
||
}
|
||
}
|
||
|
||
function showEmergencyOptions() {
|
||
showEmergencyModal.value = true
|
||
}
|
||
|
||
function hideEmergencyOptions() {
|
||
showEmergencyModal.value = false
|
||
}
|
||
|
||
async function callEmergency() {
|
||
try {
|
||
console.log(elderInfo.value.id)
|
||
await supa
|
||
.from('ec_service_requests')
|
||
.insert({
|
||
elder_id: elderInfo.value.id,
|
||
type: 'emergency_call',
|
||
priority:'normal',
|
||
description: '老人主动发起紧急呼叫',
|
||
created_at: new Date().toISOString()
|
||
})
|
||
.execute()
|
||
uni.showToast({
|
||
title: '紧急呼叫已发送',
|
||
icon: 'success'
|
||
})
|
||
} catch (error) {
|
||
console.error('紧急呼叫失败:', error)
|
||
uni.showToast({
|
||
title: '呼叫失败',
|
||
icon: 'error'
|
||
})
|
||
}
|
||
}
|
||
|
||
async function callMedicalEmergency() {
|
||
hideEmergencyOptions()
|
||
try {
|
||
await supa
|
||
.from('ec_service_requests')
|
||
.insert({
|
||
elder_id: elderInfo.value.id,
|
||
type: 'medical',
|
||
description: '医疗急救',
|
||
created_at: new Date().toISOString()
|
||
})
|
||
.execute()
|
||
uni.showToast({
|
||
title: '医疗急救已呼叫',
|
||
icon: 'success'
|
||
})
|
||
} catch (error) {
|
||
console.error('医疗急救呼叫失败:', error)
|
||
}
|
||
}
|
||
|
||
async function callNurse() {
|
||
hideEmergencyOptions()
|
||
try {
|
||
await supa
|
||
.from('ec_service_requests')
|
||
.insert({
|
||
elder_id: elderInfo.value.id,
|
||
type: 'nurse_call',
|
||
priority: 'high',
|
||
description: '老人呼叫护理员',
|
||
status: 'pending',
|
||
created_at: new Date().toISOString()
|
||
})
|
||
.execute()
|
||
uni.showToast({
|
||
title: '护理员呼叫已发送',
|
||
icon: 'success'
|
||
})
|
||
} catch (error) {
|
||
console.error('呼叫护理员失败:', error)
|
||
}
|
||
}
|
||
|
||
function viewMenu() {
|
||
uni.navigateTo({
|
||
url: '/pages/ec/elder/daily-menu'
|
||
})
|
||
}
|
||
|
||
async function contactFamily() {
|
||
if (elderInfo.value.family_contact) {
|
||
uni.makePhoneCall({
|
||
phoneNumber: elderInfo.value.family_contact
|
||
})
|
||
} else {
|
||
uni.showToast({
|
||
title: '未设置家属联系方式',
|
||
icon: 'none'
|
||
})
|
||
}
|
||
}
|
||
|
||
// 数据加载
|
||
async function loadElderInfo() {
|
||
try {
|
||
const user = await supa.auth.getUser()
|
||
if (user?.data?.user?.id) {
|
||
const { data, error } = await supa
|
||
.from('ec_elders')
|
||
.select('*')
|
||
.or(`id.eq.${user.data.user.id},user_id.eq.${user.data.user.id}`)
|
||
.limit(1)
|
||
.single()
|
||
.executeAs<Elder>()
|
||
if (!error && data) {
|
||
elderInfo.value = data
|
||
}
|
||
}
|
||
} catch (error) {
|
||
console.error('加载老人信息失败:', error)
|
||
}
|
||
}
|
||
|
||
async function loadVitalSign() {
|
||
try {
|
||
const { data, error } = await supa
|
||
.from('ec_vital_signs')
|
||
.select('*')
|
||
.eq('elder_id', elderInfo.value.id)
|
||
.order('measured_at', { ascending: false })
|
||
.limit(3)
|
||
.executeAs<VitalSign[]>()
|
||
if (!error && data) {
|
||
vitals.value = data
|
||
}
|
||
} catch (error) {
|
||
console.error('加载健康数据失败:', error)
|
||
}
|
||
}
|
||
|
||
async function loadTodayActivities() {
|
||
try {
|
||
// 第一步:先查询老人报名的活动ID列表
|
||
const participationRes = await supa.from('ec_activity_participations')
|
||
.select('activity_id')
|
||
.eq('elder_id', elderInfo.value.id)
|
||
.eq('participation_status', 'registered')
|
||
.executeAs<UTSJSONObject[]>()
|
||
|
||
if (participationRes.error != null) {
|
||
console.error('加载活动参与情况失败:', participationRes.error)
|
||
return
|
||
}
|
||
|
||
const activityIds = participationRes.data?.map((item):string => item['activity_id'] as string) ?? []
|
||
|
||
if (activityIds.length == 0) {
|
||
todayActivities.value = []
|
||
return
|
||
}
|
||
|
||
// 第二步:根据ID列表查询活动详情
|
||
const today = new Date().toISOString().split('T')[0]
|
||
const { data, error } = await supa
|
||
.from('ec_activities')
|
||
.select('*')
|
||
.in('id', activityIds)
|
||
.gte('start_time', `${today} 00:00:00`)
|
||
.lte('start_time', `${today} 23:59:59`)
|
||
.order('start_time', { ascending: true })
|
||
.executeAs<Activity[]>()
|
||
if (!error && data) {
|
||
todayActivities.value = data
|
||
}
|
||
} catch (error) {
|
||
console.error('加载今日活动失败:', error)
|
||
}
|
||
}
|
||
|
||
async function loadTodayMedications() {
|
||
try {
|
||
const today = new Date().toISOString().split('T')[0]
|
||
const { data, error } = await supa
|
||
.from('ec_medications')
|
||
.select('*')
|
||
.eq('elder_id', elderInfo.value.id)
|
||
.or(`start_date.lte.${today},start_date.is.null`)
|
||
.or(`end_date.gte.${today},end_date.is.null`)
|
||
.order('medication_name', { ascending: true })
|
||
.executeAs<Medication[]>()
|
||
if (!error && data) {
|
||
todayMedications.value = data
|
||
}
|
||
} catch (error) {
|
||
console.error('加载用药信息失败:', error)
|
||
}
|
||
}
|
||
|
||
async function loadCaregiverInfo() {
|
||
try {
|
||
const { data, error } = await supa
|
||
.from('ec_caregivers')
|
||
.select('*')
|
||
.eq('id', elderInfo.value.caregiver_id)
|
||
.limit(1)
|
||
.single()
|
||
.executeAs<CaregiverInfo>()
|
||
if (!error && data) {
|
||
caregiverInfo.value = data
|
||
}
|
||
} catch (error) {
|
||
console.error('加载护理员信息失败:', error)
|
||
}
|
||
}
|
||
|
||
async function loadPendingRequests() {
|
||
try {
|
||
const { data, error } = await supa
|
||
.from('ec_service_requests')
|
||
.select('id')
|
||
.eq('elder_id', elderInfo.value.id)
|
||
.eq('status', 'pending')
|
||
.executeAs<any[]>()
|
||
if (!error && data) {
|
||
pendingRequests.value = data.length
|
||
}
|
||
} catch (error) {
|
||
console.error('加载待处理请求数失败:', error)
|
||
}
|
||
}
|
||
|
||
// // 初始化
|
||
// onMounted(async () => {
|
||
// await loadElderInfo()
|
||
// if (elderInfo.value.id) {
|
||
// await Promise.all([
|
||
// loadVitalSign(),
|
||
// loadTodayActivities(),
|
||
// loadTodayMedications(),
|
||
// loadCaregiverInfo(),
|
||
// loadPendingRequests()
|
||
// ])
|
||
// }
|
||
// })
|
||
onLoad(async(options: OnLoadOptions) => {
|
||
elderInfo.value.id = options['id'] ?? getCurrentUserId()
|
||
|
||
if (elderInfo.value.id !='' ) {
|
||
await Promise.all([
|
||
loadVitalSign(),
|
||
loadTodayActivities(),
|
||
loadTodayMedications(),
|
||
loadCaregiverInfo(),
|
||
loadPendingRequests()
|
||
])
|
||
}
|
||
})
|
||
</script>
|
||
|
||
<style scoped>
|
||
|
||
.elder-dashboard {
|
||
padding: 40rpx;
|
||
background-color: #f8f9fa;
|
||
min-height: 100vh;
|
||
}
|
||
.header-section {
|
||
margin-bottom: 40rpx;
|
||
}
|
||
.welcome-card {
|
||
background: linear-gradient(135deg, #667eea 0%, #764ba2 100%);
|
||
padding: 40rpx;
|
||
border-radius: 24rpx;
|
||
color: white;
|
||
}
|
||
.welcome-text {
|
||
font-size: 48rpx;
|
||
font-weight: bold;
|
||
display: block;
|
||
margin-bottom: 12rpx;
|
||
}
|
||
.weather-info {
|
||
font-size: 32rpx;
|
||
display: block;
|
||
margin-bottom: 8rpx;
|
||
opacity: 0.9;
|
||
}
|
||
.date-info {
|
||
font-size: 28rpx;
|
||
display: block;
|
||
opacity: 0.8;
|
||
}
|
||
.section-title {
|
||
display: flex;
|
||
flex-direction: row;
|
||
align-items: center;
|
||
justify-content: space-between;
|
||
margin-bottom: 24rpx;
|
||
}
|
||
.title-text {
|
||
font-size: 36rpx;
|
||
font-weight: bold;
|
||
color: #333;
|
||
}
|
||
.view-all-btn {
|
||
background: #007AFF;
|
||
color: white;
|
||
padding: 16rpx 24rpx;
|
||
border-radius: 20rpx;
|
||
border: none;
|
||
font-size: 24rpx;
|
||
}
|
||
.activity-count {
|
||
background: #ff6b6b;
|
||
color: white;
|
||
padding: 8rpx 16rpx;
|
||
border-radius: 16rpx;
|
||
font-size: 24rpx;
|
||
}
|
||
.health-section {
|
||
margin-bottom: 40rpx;
|
||
}
|
||
.health-cards {
|
||
display: flex;
|
||
flex-direction: row;
|
||
margin-bottom: 20rpx;
|
||
}
|
||
.health-card {
|
||
flex: 1;
|
||
min-width: 200rpx;
|
||
background: white;
|
||
padding: 30rpx;
|
||
border-radius: 16rpx;
|
||
text-align: center;
|
||
margin-right: 20rpx;
|
||
}
|
||
.health-card.is-last {
|
||
margin-right: 0;
|
||
}
|
||
.health-icon {
|
||
font-size: 48rpx;
|
||
display: block;
|
||
margin-bottom: 12rpx;
|
||
}
|
||
.health-label {
|
||
font-size: 28rpx;
|
||
color: #666;
|
||
display: block;
|
||
margin-bottom: 8rpx;
|
||
}
|
||
.health-value {
|
||
font-size: 32rpx;
|
||
font-weight: bold;
|
||
color: #333;
|
||
display: block;
|
||
margin-bottom: 12rpx;
|
||
}
|
||
.health-status {
|
||
font-size: 24rpx;
|
||
padding: 6rpx 12rpx;
|
||
border-radius: 12rpx;
|
||
display: inline-block;
|
||
}
|
||
.health-status.is-normal {
|
||
background: #e8f5e8;
|
||
color: #4caf50;
|
||
}
|
||
.health-status.is-warning {
|
||
background: #fff3e0;
|
||
color: #ff9800;
|
||
}
|
||
.health-status.is-danger {
|
||
background: #ffebee;
|
||
color: #f44336;
|
||
}
|
||
.activity-section,
|
||
.medication-section,
|
||
.care-section {
|
||
margin-bottom: 40rpx;
|
||
}
|
||
.activity-list,
|
||
.medication-list {
|
||
background: white;
|
||
border-radius: 16rpx;
|
||
overflow: hidden;
|
||
}
|
||
.activity-item,
|
||
.medication-item {
|
||
display: flex;
|
||
flex-direction: row;
|
||
align-items: center;
|
||
padding: 24rpx;
|
||
border-bottom: 1rpx solid #f0f0f0;
|
||
}
|
||
.activity-item.is-last,
|
||
.medication-item.is-last {
|
||
border-bottom: none;
|
||
}
|
||
.activity-time,
|
||
.medication-time {
|
||
width: 140rpx;
|
||
flex-shrink: 0;
|
||
}
|
||
.time-text {
|
||
font-size: 28rpx;
|
||
color: #007AFF;
|
||
font-weight: 600;
|
||
}
|
||
.activity-info,
|
||
.medication-info {
|
||
flex: 1;
|
||
margin-left: 20rpx;
|
||
}
|
||
.activity-name,
|
||
.medication-name {
|
||
font-size: 32rpx;
|
||
color: #333;
|
||
display: block;
|
||
margin-bottom: 4rpx;
|
||
}
|
||
.activity-location,
|
||
.medication-dosage {
|
||
font-size: 26rpx;
|
||
color: #666;
|
||
display: block;
|
||
}
|
||
.activity-status,
|
||
.medication-actions {
|
||
flex-shrink: 0;
|
||
}
|
||
.activity-status {
|
||
padding: 8rpx 16rpx;
|
||
border-radius: 12rpx;
|
||
font-size: 24rpx;
|
||
}
|
||
.activity-status.is-pending {
|
||
background: #fff3e0;
|
||
color: #ff9800;
|
||
}
|
||
.activity-status.is-completed {
|
||
background: #e8f5e8;
|
||
color: #4caf50;
|
||
}
|
||
.medication-alert {
|
||
background: #ff6b6b;
|
||
color: white;
|
||
padding: 8rpx 16rpx;
|
||
border-radius: 16rpx;
|
||
font-size: 24rpx;
|
||
}
|
||
.action-btn {
|
||
padding: 12rpx 20rpx;
|
||
border-radius: 16rpx;
|
||
border: none;
|
||
font-size: 24rpx;
|
||
}
|
||
.action-btn.is-taken {
|
||
background: #4caf50;
|
||
color: white;
|
||
}
|
||
.taken-indicator {
|
||
padding: 12rpx 20rpx;
|
||
}
|
||
.taken-text {
|
||
color: #4caf50;
|
||
font-size: 24rpx;
|
||
}
|
||
.care-summary {
|
||
display: flex;
|
||
flex-direction: row;
|
||
margin-bottom: 20rpx;
|
||
}
|
||
.care-card {
|
||
flex: 1;
|
||
background: white;
|
||
padding: 30rpx;
|
||
border-radius: 16rpx;
|
||
text-align: center;
|
||
margin-right: 20rpx;
|
||
}
|
||
.care-card.is-last {
|
||
margin-right: 0;
|
||
}
|
||
.care-icon {
|
||
font-size: 48rpx;
|
||
display: block;
|
||
margin-bottom: 12rpx;
|
||
}
|
||
.care-label {
|
||
font-size: 28rpx;
|
||
color: #666;
|
||
display: block;
|
||
margin-bottom: 8rpx;
|
||
}
|
||
.care-value {
|
||
font-size: 32rpx;
|
||
font-weight: bold;
|
||
color: #333;
|
||
display: block;
|
||
margin-bottom: 12rpx;
|
||
}
|
||
.care-status {
|
||
font-size: 24rpx;
|
||
color: #4caf50;
|
||
background: #e8f5e8;
|
||
padding: 6rpx 12rpx;
|
||
border-radius: 12rpx;
|
||
display: inline-block;
|
||
}
|
||
.quick-actions {
|
||
margin-bottom: 40rpx;
|
||
}
|
||
.action-grid {
|
||
display: flex;
|
||
flex-direction: row;
|
||
flex-wrap: wrap;
|
||
}
|
||
.action-item {
|
||
flex: 1;
|
||
min-width: 150rpx;
|
||
background: white;
|
||
padding: 30rpx;
|
||
border-radius: 16rpx;
|
||
text-align: center;
|
||
margin-right: 20rpx;
|
||
margin-bottom: 20rpx;
|
||
}
|
||
.action-item.is-last {
|
||
margin-right: 0;
|
||
}
|
||
.action-icon {
|
||
font-size: 48rpx;
|
||
display: block;
|
||
margin-bottom: 12rpx;
|
||
}
|
||
.action-label {
|
||
font-size: 28rpx;
|
||
color: #333;
|
||
display: block;
|
||
}
|
||
.empty-state {
|
||
background: white;
|
||
padding: 60rpx;
|
||
border-radius: 16rpx;
|
||
text-align: center;
|
||
}
|
||
.empty-text {
|
||
font-size: 30rpx;
|
||
color: #999;
|
||
}
|
||
.emergency-fab {
|
||
position: fixed;
|
||
right: 40rpx;
|
||
bottom: 40rpx;
|
||
width: 120rpx;
|
||
height: 120rpx;
|
||
background: #ff4444;
|
||
border-radius: 60rpx;
|
||
display: flex;
|
||
align-items: center;
|
||
justify-content: center;
|
||
z-index: 100;
|
||
}
|
||
.fab-icon {
|
||
font-size: 48rpx;
|
||
color: white;
|
||
}
|
||
.emergency-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;
|
||
padding: 40rpx;
|
||
border-radius: 24rpx;
|
||
width: 600rpx;
|
||
max-width: 90%;
|
||
}
|
||
.modal-title {
|
||
font-size: 36rpx;
|
||
font-weight: bold;
|
||
text-align: center;
|
||
margin-bottom: 30rpx;
|
||
color: #333;
|
||
}
|
||
.emergency-options {
|
||
margin-bottom: 30rpx;
|
||
}
|
||
.emergency-btn {
|
||
width: 100%;
|
||
padding: 30rpx;
|
||
border-radius: 16rpx;
|
||
border: none;
|
||
margin-bottom: 20rpx;
|
||
font-size: 32rpx;
|
||
font-weight: 600;
|
||
}
|
||
.emergency-btn.is-medical {
|
||
background: #ff4444;
|
||
color: white;
|
||
}
|
||
.emergency-btn.is-nurse {
|
||
background: #007AFF;
|
||
color: white;
|
||
}
|
||
.emergency-btn.is-family {
|
||
background: #4caf50;
|
||
color: white;
|
||
}
|
||
.cancel-btn {
|
||
width: 100%;
|
||
padding: 24rpx;
|
||
border-radius: 16rpx;
|
||
border: 1rpx solid #ddd;
|
||
background: white;
|
||
color: #666;
|
||
font-size: 30rpx;
|
||
}
|
||
</style>
|