856 lines
19 KiB
Plaintext
856 lines
19 KiB
Plaintext
<!-- 养老管理系统 - 护理员仪表板 (简化版) -->
|
||
<template>
|
||
<view class="caregiver-dashboard">
|
||
<view class="header">
|
||
<text class="title">护理工作台</text>
|
||
<text class="welcome">{{ caregiverName }},{{ currentTime }}</text>
|
||
</view>
|
||
|
||
<!-- 今日工作概览 -->
|
||
<view class="today-overview">
|
||
<view class="overview-card">
|
||
<view class="card-icon">📋</view>
|
||
<view class="card-content">
|
||
<text class="card-number">{{ todayStats.total_tasks }}</text>
|
||
<text class="card-label">今日任务</text>
|
||
<view class="card-status">
|
||
<text class="status-text">{{ todayStats.completed_tasks }}/{{ todayStats.total_tasks }}</text>
|
||
</view>
|
||
</view>
|
||
|
||
</view>
|
||
|
||
<view class="overview-card">
|
||
<view class="card-icon">👥</view>
|
||
<view class="card-content">
|
||
<text class="card-number">{{ todayStats.assigned_elders }}</text>
|
||
<text class="card-label">负责老人</text>
|
||
</view>
|
||
</view>
|
||
|
||
<view class="overview-card">
|
||
<view class="card-icon">⚠️</view>
|
||
<view class="card-content">
|
||
<text class="card-number">{{ todayStats.urgent_tasks }}</text>
|
||
<text class="card-label">紧急任务</text>
|
||
</view>
|
||
<view class="card-alert" v-if="todayStats.urgent_tasks > 0">
|
||
<text class="alert-text">需处理</text>
|
||
</view>
|
||
</view>
|
||
</view>
|
||
|
||
<!-- 待处理任务 -->
|
||
<view class="pending-tasks-section">
|
||
<view class="section-header">
|
||
<text class="section-title">待处理任务</text>
|
||
<text class="section-more" @click="viewAllTasks">查看全部</text>
|
||
</view>
|
||
<view class="tasks-list">
|
||
<view v-for="task in pendingTasks" :key="task.id" class="task-item" :class="getTaskPriorityClass(task.priority)" @click="startTask(task)">
|
||
<view class="task-main">
|
||
<view class="task-info">
|
||
<text class="task-name">{{ task.task_name }}</text>
|
||
<text class="task-elder">{{ task.elder_name }}</text>
|
||
<text class="task-time">{{ formatTime(task.scheduled_time) }}</text>
|
||
</view>
|
||
<view class="task-priority">
|
||
<view class="priority-badge" :class="task.priority">
|
||
<text class="priority-text">{{ getPriorityText(task.priority) }}</text>
|
||
</view>
|
||
</view>
|
||
</view>
|
||
<view class="task-actions">
|
||
<button class="task-btn start" @click.stop="startTask(task)">开始</button>
|
||
<button class="task-btn detail" @click.stop="viewTaskDetail(task)">详情</button>
|
||
</view>
|
||
</view>
|
||
</view>
|
||
</view>
|
||
|
||
<!-- 负责的老人 -->
|
||
<view class="assigned-elders-section">
|
||
<view class="section-header">
|
||
<text class="section-title">我负责的老人</text>
|
||
<text class="section-more" @click="viewAllElders">查看全部</text>
|
||
</view>
|
||
<view class="elders-list">
|
||
<view v-for="elder in assignedElders" :key="elder.id" class="elder-item" @click="viewElderDetail(elder)">
|
||
<view class="elder-avatar">
|
||
<image class="avatar-image" :src="elder.profile_picture ?? ''" mode="aspectFill"
|
||
v-if="elder.profile_picture !== null" />
|
||
<text class="avatar-fallback" v-else>{{ elder.name.charAt(0) }}</text>
|
||
</view>
|
||
<view class="elder-info">
|
||
<text class="elder-name">{{ elder.name }}</text>
|
||
<text class="elder-room">{{ elder.room_number }}{{ elder.bed_number }}</text>
|
||
<text class="elder-care-level">{{ getCareLevelText(elder.care_level) }}</text>
|
||
</view>
|
||
<view class="elder-status">
|
||
<view class="health-indicator" :class="getHealthStatusClass(elder.health_status)">
|
||
<text class="health-text">{{ getHealthStatusText(elder.health_status) }}</text>
|
||
</view>
|
||
<view class="alert-count" v-if="getElderAlertCount(elder.id) > 0">
|
||
<text class="alert-number">{{ getElderAlertCount(elder.id) }}</text>
|
||
</view>
|
||
</view>
|
||
</view>
|
||
</view>
|
||
</view>
|
||
|
||
<!-- 最近完成的任务 -->
|
||
<view class="completed-tasks-section">
|
||
<view class="section-header">
|
||
<text class="section-title">最近完成</text>
|
||
<text class="section-more" @click="viewCompletedTasks">查看更多</text>
|
||
</view>
|
||
<view class="completed-list">
|
||
<view v-for="task in completedTasks" :key="task.id" class="completed-item">
|
||
<view class="completed-icon">✅</view>
|
||
<view class="completed-info">
|
||
<text class="completed-name">{{ task.task_name }}</text>
|
||
<text class="completed-elder">{{ task.elder_name }}</text>
|
||
<text class="completed-time">{{ formatDateTime(task.scheduled_time) }}</text>
|
||
</view>
|
||
<view class="completed-status">
|
||
<text class="status-text">已完成</text>
|
||
</view>
|
||
</view>
|
||
</view>
|
||
</view>
|
||
|
||
<!-- 快速操作 -->
|
||
<view class="quick-actions">
|
||
<view class="action-item" @click="quickReport">
|
||
<view class="action-icon">📝</view>
|
||
<text class="action-text">快速记录</text>
|
||
</view>
|
||
<view class="action-item" @click="emergencyCall">
|
||
<view class="action-icon">🚨</view>
|
||
<text class="action-text">紧急呼叫</text>
|
||
</view>
|
||
<view class="action-item" @click="healthCheck">
|
||
<view class="action-icon">💊</view>
|
||
<text class="action-text">健康检查</text>
|
||
</view>
|
||
</view>
|
||
</view>
|
||
</template>
|
||
|
||
<script setup lang="uts">
|
||
import { ref, onMounted } from 'vue'
|
||
import supa from '@/components/supadb/aksupainstance.uts'
|
||
import type { Elder, CareTask } from '../types.uts'
|
||
import { formatDateTime, formatTime,getPriorityText, getCareLevelText, getHealthStatusText, getHealthStatusClass, getTaskPriorityClass } from '../types.uts'
|
||
import { state, getCurrentUserId } from '@/utils/store.uts'
|
||
import type { UserProfile, UserStats } from '@/pages/user/types.uts'
|
||
|
||
const profile =ref<UserProfile>(state.userProfile)
|
||
// 响应式数据
|
||
const caregiverName = ref<string>('护理员')
|
||
const currentTime = ref<string>('')
|
||
|
||
// 今日统计
|
||
const todayStats = ref({
|
||
total_tasks: 0,
|
||
completed_tasks: 0,
|
||
assigned_elders: 0,
|
||
urgent_tasks: 0
|
||
})
|
||
|
||
// 数据列表
|
||
const pendingTasks = ref<Array<CareTask>>([])
|
||
const assignedElders = ref<Array<Elder>>([])
|
||
const completedTasks = ref<Array<CareTask>>([])
|
||
const elderAlerts = ref<Map<string, number>>(new Map())
|
||
|
||
// 更新当前时间
|
||
const updateCurrentTime = () => {
|
||
const now = new Date()
|
||
const hours = now.getHours().toString().padStart(2, '0')
|
||
const minutes = now.getMinutes().toString().padStart(2, '0')
|
||
currentTime.value = `今天 ${hours}:${minutes}`
|
||
}
|
||
|
||
// 获取今天的时间范围
|
||
const getTodayRange = () => {
|
||
const today = new Date()
|
||
const start = new Date(today.getFullYear(), today.getMonth(), today.getDate())
|
||
const end = new Date(today.getFullYear(), today.getMonth(), today.getDate() + 1)
|
||
return {
|
||
start: start.toISOString(),
|
||
end: end.toISOString()
|
||
}
|
||
}
|
||
|
||
// 加载今日统计
|
||
const loadTodayStats = async () => {
|
||
try {
|
||
const { start, end } = getTodayRange()
|
||
const currentUserId = profile.value.id
|
||
// 加载今日任务统计
|
||
const tasksResult = await supa
|
||
.from('ec_care_tasks')
|
||
.select('*', { count: 'exact' })
|
||
.eq('assigned_to', currentUserId)
|
||
.gte('scheduled_time', start)
|
||
.lt('scheduled_time', end)
|
||
.executeAs<Array<CareTask>>()
|
||
if (tasksResult.error === null) {
|
||
todayStats.value.total_tasks = tasksResult.count ?? 0
|
||
// 计算已完成任务数
|
||
const completedCount = tasksResult.data?.filter(task => task.status === 'completed').length ?? 0
|
||
todayStats.value.completed_tasks = completedCount
|
||
// 计算紧急任务数
|
||
const urgentCount = tasksResult.data?.filter(task => task.priority === 'urgent' && task.status !== 'completed').length ?? 0
|
||
todayStats.value.urgent_tasks = urgentCount
|
||
}
|
||
// 通过任务表统计负责老人数量
|
||
const eldersResult = await supa
|
||
.from('ec_care_tasks')
|
||
.select('elder_id')
|
||
.eq('assigned_to', currentUserId)
|
||
.executeAs<Array<{ elder_id: string }>>()
|
||
if (eldersResult.error === null && eldersResult.data !== null) {
|
||
const uniqueElderIds = Array.from(new Set(eldersResult.data.map(e => e.elder_id)))
|
||
todayStats.value.assigned_elders = uniqueElderIds.length
|
||
}
|
||
} catch (error) {
|
||
console.error('加载统计数据失败:', error)
|
||
}
|
||
}
|
||
|
||
// 加载待处理任务
|
||
const loadPendingTasks = async () => {
|
||
try {
|
||
const currentUserId = profile.value.id
|
||
|
||
const result = await supa
|
||
.from('ec_care_tasks')
|
||
.select(`
|
||
id,
|
||
task_name,
|
||
elder_name,
|
||
scheduled_time,
|
||
status,
|
||
priority
|
||
`)
|
||
.eq('assigned_to', currentUserId)
|
||
.eq('status', 'pending')
|
||
.order('scheduled_time', { ascending: true })
|
||
.limit(5)
|
||
.executeAs<Array<CareTask>>()
|
||
|
||
if (result.error === null && result.data !== null) {
|
||
pendingTasks.value = result.data
|
||
}
|
||
} catch (error) {
|
||
console.error('加载待处理任务失败:', error)
|
||
}
|
||
}
|
||
|
||
// 加载负责的老人
|
||
const loadAssignedElders = async () => {
|
||
try {
|
||
const currentUserId = profile.value.id
|
||
// 先查找当前护理员负责的所有老人ID
|
||
const taskResult = await supa
|
||
.from('ec_care_tasks')
|
||
.select('elder_id')
|
||
.eq('assigned_to', currentUserId)
|
||
.executeAs<Array<{ elder_id: string }>>()
|
||
|
||
if (taskResult.error === null && taskResult.data !== null) {
|
||
const uniqueElderIds = Array.from(new Set(taskResult.data.map(e => e.elder_id)))
|
||
if (uniqueElderIds.length === 0) {
|
||
assignedElders.value = []
|
||
return
|
||
}
|
||
// 查询老人信息
|
||
const eldersResult = await supa
|
||
.from('ec_elders')
|
||
.select(`
|
||
id,
|
||
name,
|
||
room_number,
|
||
bed_number,
|
||
health_status,
|
||
care_level,
|
||
profile_picture
|
||
`)
|
||
.in('id', uniqueElderIds)
|
||
.eq('status', 'active')
|
||
.limit(6)
|
||
.executeAs<Array<Elder>>()
|
||
|
||
if (eldersResult.error === null && eldersResult.data !== null) {
|
||
assignedElders.value = eldersResult.data
|
||
// 加载每个老人的告警数量
|
||
loadElderAlerts()
|
||
}
|
||
}
|
||
} catch (error) {
|
||
console.error('加载负责老人失败:', error)
|
||
}
|
||
}
|
||
|
||
// 加载最近完成的任务
|
||
const loadCompletedTasks = async () => {
|
||
try {
|
||
const currentUserId = profile.value.id
|
||
|
||
const result = await supa
|
||
.from('ec_care_tasks')
|
||
.select(`
|
||
id,
|
||
task_name,
|
||
elder_name,
|
||
scheduled_time,
|
||
status
|
||
`)
|
||
.eq('assigned_to', currentUserId)
|
||
.eq('status', 'completed')
|
||
.order('updated_at', { ascending: false })
|
||
.limit(3)
|
||
.executeAs<Array<CareTask>>()
|
||
|
||
if (result.error === null && result.data !== null) {
|
||
completedTasks.value = result.data
|
||
}
|
||
} catch (error) {
|
||
console.error('加载完成任务失败:', error)
|
||
}
|
||
}
|
||
|
||
// 加载老人告警数量
|
||
const loadElderAlerts = async () => {
|
||
try {
|
||
for (let i: Int = 0; i < assignedElders.value.length; i++) {
|
||
const elder = assignedElders.value[i]
|
||
const alertsResult = await supa
|
||
.from('ec_health_alerts')
|
||
.select('*', { count: 'exact' })
|
||
.eq('elder_id', elder.id)
|
||
.eq('status', 'active')
|
||
.executeAs<Array<any>>()
|
||
|
||
if (alertsResult.error === null) {
|
||
elderAlerts.value.set(elder.id, alertsResult.count ?? 0)
|
||
}
|
||
}
|
||
} catch (error) {
|
||
console.error('加载告警数据失败:', error)
|
||
}
|
||
}
|
||
|
||
// 获取老人告警数量
|
||
const getElderAlertCount = (elderId: string): number => {
|
||
return elderAlerts.value.get(elderId) ?? 0
|
||
}
|
||
|
||
|
||
|
||
// 开始任务
|
||
const startTask = async (task: CareTask) => {
|
||
try {
|
||
await supa
|
||
.from('ec_care_tasks')
|
||
.update({
|
||
status: 'in_progress',
|
||
start_time: new Date().toISOString()
|
||
})
|
||
.eq('id', task.id)
|
||
.executeAs<any>()
|
||
|
||
uni.navigateTo({
|
||
url: `/pages/ec/tasks/execute?id=${task.id}`
|
||
})
|
||
} catch (error) {
|
||
console.error('开始任务失败:', error)
|
||
uni.showToast({
|
||
title: '操作失败',
|
||
icon: 'error'
|
||
})
|
||
}
|
||
}
|
||
|
||
// 查看任务详情
|
||
const viewTaskDetail = (task: CareTask) => {
|
||
uni.navigateTo({
|
||
url: `/pages/ec/tasks/detail?id=${task.id}`
|
||
})
|
||
}
|
||
|
||
// 查看老人详情
|
||
const viewElderDetail = (elder: Elder) => {
|
||
uni.navigateTo({
|
||
url: `/pages/ec/elders/detail?id=${elder.id}`
|
||
})
|
||
}
|
||
|
||
// 导航函数
|
||
const viewAllTasks = () => {
|
||
uni.navigateTo({
|
||
url: '/pages/ec/tasks/my-tasks'
|
||
})
|
||
}
|
||
|
||
const viewAllElders = () => {
|
||
uni.navigateTo({
|
||
url: '/pages/ec/caregiver/my-elders'
|
||
})
|
||
}
|
||
|
||
const viewCompletedTasks = () => {
|
||
uni.navigateTo({
|
||
url: '/pages/ec/tasks/completed'
|
||
})
|
||
}
|
||
|
||
// 快速操作
|
||
const quickReport = () => {
|
||
uni.navigateTo({
|
||
url: '/pages/ec/reports/quick-add'
|
||
})
|
||
}
|
||
|
||
const emergencyCall = () => {
|
||
uni.makePhoneCall({
|
||
phoneNumber: '120'
|
||
})
|
||
}
|
||
|
||
const healthCheck = () => {
|
||
uni.navigateTo({
|
||
url: '/pages/ec/health/quick-check'
|
||
})
|
||
}
|
||
|
||
|
||
|
||
onLoad(async(options: OnLoadOptions) => {
|
||
profile.value.id = options['id'] ?? getCurrentUserId()
|
||
|
||
if (profile.value.id !='' ) {
|
||
loadTodayStats()
|
||
loadPendingTasks()
|
||
loadAssignedElders()
|
||
loadCompletedTasks()
|
||
|
||
// 定时更新时间
|
||
setInterval(() => {
|
||
updateCurrentTime()
|
||
}, 60000)
|
||
}
|
||
})
|
||
</script>
|
||
|
||
<style scoped>
|
||
.caregiver-dashboard {
|
||
display: flex;
|
||
flex-direction: column;
|
||
min-height: 100vh;
|
||
background-color: #f5f5f5;
|
||
padding: 20px;
|
||
}
|
||
|
||
.header {
|
||
display: flex;
|
||
flex-direction: row;
|
||
justify-content: space-between;
|
||
align-items: center;
|
||
margin-bottom: 20px;
|
||
}
|
||
|
||
.title {
|
||
font-size: 24px;
|
||
font-weight: bold;
|
||
color: #333;
|
||
}
|
||
|
||
.welcome {
|
||
font-size: 14px;
|
||
color: #666;
|
||
}
|
||
|
||
/* 今日概览 */
|
||
.today-overview {
|
||
display: flex;
|
||
flex-direction: row;
|
||
margin-bottom: 20px;
|
||
}
|
||
|
||
.overview-card {
|
||
flex: 1;
|
||
background-color: #fff;
|
||
border-radius: 8px;
|
||
padding: 15px;
|
||
margin-right: 10px;
|
||
box-shadow: 0 2px 4px rgba(0,0,0,0.1);
|
||
display: flex;
|
||
flex-direction: row;
|
||
align-items: center;
|
||
}
|
||
|
||
.overview-card:last-child {
|
||
margin-right: 0;
|
||
}
|
||
|
||
.card-icon {
|
||
font-size: 24px;
|
||
margin-right: 10px;
|
||
}
|
||
|
||
.card-content {
|
||
flex: 1;
|
||
display: flex;
|
||
flex-direction: column;
|
||
}
|
||
|
||
.card-number {
|
||
font-size: 20px;
|
||
font-weight: bold;
|
||
color: #333;
|
||
}
|
||
|
||
.card-label {
|
||
font-size: 12px;
|
||
color: #666;
|
||
}
|
||
|
||
.card-status {
|
||
display: flex;
|
||
align-items: center;
|
||
}
|
||
|
||
.status-text {
|
||
font-size: 12px;
|
||
color: #1890ff;
|
||
}
|
||
|
||
.card-alert {
|
||
display: flex;
|
||
align-items: center;
|
||
}
|
||
|
||
.alert-text {
|
||
font-size: 12px;
|
||
color: #ff4d4f;
|
||
background-color: #fff2f0;
|
||
padding: 2px 6px;
|
||
border-radius: 4px;
|
||
}
|
||
|
||
/* 通用列表样式 */
|
||
.pending-tasks-section,
|
||
.assigned-elders-section,
|
||
.completed-tasks-section {
|
||
background-color: #fff;
|
||
border-radius: 8px;
|
||
padding: 15px;
|
||
margin-bottom: 15px;
|
||
box-shadow: 0 2px 4px rgba(0,0,0,0.1);
|
||
}
|
||
|
||
.section-header {
|
||
display: flex;
|
||
flex-direction: row;
|
||
justify-content: space-between;
|
||
align-items: center;
|
||
margin-bottom: 15px;
|
||
}
|
||
|
||
.section-title {
|
||
font-size: 16px;
|
||
font-weight: bold;
|
||
color: #333;
|
||
}
|
||
|
||
.section-more {
|
||
font-size: 14px;
|
||
color: #1890ff;
|
||
}
|
||
|
||
/* 任务列表 */
|
||
.task-item {
|
||
display: flex;
|
||
flex-direction: column;
|
||
padding: 12px;
|
||
border-radius: 6px;
|
||
margin-bottom: 8px;
|
||
border-left: 3px solid #d9d9d9;
|
||
}
|
||
|
||
.task-item.priority-urgent {
|
||
border-left-color: #ff4d4f;
|
||
background-color: #fff2f0;
|
||
}
|
||
|
||
.task-item.priority-high {
|
||
border-left-color: #fa8c16;
|
||
background-color: #fff7e6;
|
||
}
|
||
|
||
.task-item.priority-normal {
|
||
border-left-color: #1890ff;
|
||
background-color: #f0f9ff;
|
||
}
|
||
|
||
.task-main {
|
||
display: flex;
|
||
flex-direction: row;
|
||
align-items: center;
|
||
margin-bottom: 8px;
|
||
}
|
||
|
||
.task-info {
|
||
flex: 1;
|
||
display: flex;
|
||
flex-direction: column;
|
||
}
|
||
|
||
.task-name {
|
||
font-size: 14px;
|
||
font-weight: bold;
|
||
color: #333;
|
||
margin-bottom: 3px;
|
||
}
|
||
|
||
.task-elder {
|
||
font-size: 12px;
|
||
color: #666;
|
||
margin-bottom: 2px;
|
||
}
|
||
|
||
.task-time {
|
||
font-size: 12px;
|
||
color: #999;
|
||
}
|
||
|
||
.priority-badge {
|
||
padding: 2px 6px;
|
||
border-radius: 4px;
|
||
font-size: 10px;
|
||
}
|
||
|
||
.priority-badge.urgent {
|
||
background-color: #ff4d4f;
|
||
color: #fff;
|
||
}
|
||
|
||
.priority-badge.high {
|
||
background-color: #fa8c16;
|
||
color: #fff;
|
||
}
|
||
|
||
.priority-badge.normal {
|
||
background-color: #1890ff;
|
||
color: #fff;
|
||
}
|
||
|
||
.task-actions {
|
||
display: flex;
|
||
flex-direction: row;
|
||
justify-content: flex-end;
|
||
}
|
||
|
||
.task-btn {
|
||
padding: 4px 12px;
|
||
border-radius: 4px;
|
||
border: none;
|
||
font-size: 12px;
|
||
margin-left: 8px;
|
||
}
|
||
|
||
.task-btn.start {
|
||
background-color: #52c41a;
|
||
color: #fff;
|
||
}
|
||
|
||
.task-btn.detail {
|
||
background-color: #1890ff;
|
||
color: #fff;
|
||
}
|
||
|
||
/* 老人列表 */
|
||
.elder-item {
|
||
display: flex;
|
||
flex-direction: row;
|
||
align-items: center;
|
||
padding: 12px;
|
||
border-bottom: 1px solid #f0f0f0;
|
||
}
|
||
|
||
.elder-item:last-child {
|
||
border-bottom: none;
|
||
}
|
||
|
||
.elder-avatar {
|
||
width: 40px;
|
||
height: 40px;
|
||
border-radius: 20px;
|
||
margin-right: 12px;
|
||
overflow: hidden;
|
||
background-color: #f0f0f0;
|
||
display: flex;
|
||
align-items: center;
|
||
justify-content: center;
|
||
}
|
||
|
||
.avatar-image {
|
||
width: 100%;
|
||
height: 100%;
|
||
}
|
||
|
||
.avatar-fallback {
|
||
font-size: 16px;
|
||
color: #666;
|
||
}
|
||
|
||
.elder-info {
|
||
flex: 1;
|
||
display: flex;
|
||
flex-direction: column;
|
||
}
|
||
|
||
.elder-name {
|
||
font-size: 14px;
|
||
font-weight: bold;
|
||
color: #333;
|
||
margin-bottom: 3px;
|
||
}
|
||
|
||
.elder-room {
|
||
font-size: 12px;
|
||
color: #666;
|
||
margin-bottom: 2px;
|
||
}
|
||
|
||
.elder-care-level {
|
||
font-size: 12px;
|
||
color: #1890ff;
|
||
}
|
||
|
||
.elder-status {
|
||
display: flex;
|
||
flex-direction: column;
|
||
align-items: flex-end;
|
||
}
|
||
|
||
.health-indicator {
|
||
padding: 2px 6px;
|
||
border-radius: 4px;
|
||
font-size: 10px;
|
||
margin-bottom: 4px;
|
||
}
|
||
|
||
.health-excellent {
|
||
background-color: #f6ffed;
|
||
color: #52c41a;
|
||
}
|
||
|
||
.health-good {
|
||
background-color: #e6f7ff;
|
||
color: #1890ff;
|
||
}
|
||
|
||
.health-fair {
|
||
background-color: #fff7e6;
|
||
color: #d48806;
|
||
}
|
||
|
||
.health-poor {
|
||
background-color: #fff2f0;
|
||
color: #ff4d4f;
|
||
}
|
||
|
||
.alert-count {
|
||
background-color: #ff4d4f;
|
||
color: #fff;
|
||
border-radius: 10px;
|
||
width: 20px;
|
||
height: 20px;
|
||
display: flex;
|
||
align-items: center;
|
||
justify-content: center;
|
||
}
|
||
|
||
.alert-number {
|
||
font-size: 10px;
|
||
}
|
||
|
||
/* 完成列表 */
|
||
.completed-item {
|
||
display: flex;
|
||
flex-direction: row;
|
||
align-items: center;
|
||
padding: 10px;
|
||
border-bottom: 1px solid #f0f0f0;
|
||
}
|
||
|
||
.completed-item:last-child {
|
||
border-bottom: none;
|
||
}
|
||
|
||
.completed-icon {
|
||
margin-right: 12px;
|
||
font-size: 16px;
|
||
}
|
||
|
||
.completed-info {
|
||
flex: 1;
|
||
display: flex;
|
||
flex-direction: column;
|
||
}
|
||
|
||
.completed-name {
|
||
font-size: 14px;
|
||
color: #333;
|
||
margin-bottom: 3px;
|
||
}
|
||
|
||
.completed-elder {
|
||
font-size: 12px;
|
||
color: #666;
|
||
margin-bottom: 2px;
|
||
}
|
||
|
||
.completed-time {
|
||
font-size: 12px;
|
||
color: #999;
|
||
}
|
||
|
||
.completed-status .status-text {
|
||
font-size: 12px;
|
||
color: #52c41a;
|
||
}
|
||
|
||
/* 快速操作 */
|
||
.quick-actions {
|
||
display: flex;
|
||
flex-direction: row;
|
||
justify-content: space-around;
|
||
background-color: #fff;
|
||
border-radius: 8px;
|
||
padding: 15px;
|
||
box-shadow: 0 2px 4px rgba(0,0,0,0.1);
|
||
}
|
||
|
||
.action-item {
|
||
display: flex;
|
||
flex-direction: column;
|
||
align-items: center;
|
||
padding: 10px;
|
||
}
|
||
|
||
.action-icon {
|
||
font-size: 24px;
|
||
margin-bottom: 5px;
|
||
}
|
||
|
||
.action-text {
|
||
font-size: 12px;
|
||
color: #666;
|
||
}
|
||
</style>
|