import { View, Text } from '@tarojs/components'; import { useState } from 'react'; import Taro, { useDidShow } from '@tarojs/taro'; import { useAuthStore } from '../../stores/auth'; import { useHealthStore } from '../../stores/health'; import EmptyState from '../../components/EmptyState'; import Loading from '../../components/Loading'; import { trackPageView } from '@/services/analytics'; import * as appointmentApi from '@/services/appointment'; import * as followupApi from '@/services/followup'; import './index.scss'; interface UpcomingItem { id: string; title: string; subtitle: string; type: 'appointment' | 'followup'; } export default function Index() { const { user, currentPatient, restore: restoreAuth } = useAuthStore(); const { todaySummary, loading, refreshToday } = useHealthStore(); const [upcomingItems, setUpcomingItems] = useState([]); const [upcomingLoading, setUpcomingLoading] = useState(false); useDidShow(() => { restoreAuth(); refreshToday(); loadUpcoming(); trackPageView('home'); }); const loadUpcoming = async () => { const patientId = useAuthStore.getState().currentPatient?.id; if (!patientId) return; setUpcomingLoading(true); try { const items: UpcomingItem[] = []; const [apptRes, taskRes] = await Promise.allSettled([ appointmentApi.listAppointments(patientId, 1), followupApi.listTasks(patientId, 'pending'), ]); if (apptRes.status === 'fulfilled') { for (const a of apptRes.value.data.slice(0, 3)) { if (a.status === 'pending' || a.status === 'confirmed') { items.push({ id: a.id, title: `预约: ${a.appointment_date} ${a.start_time}`, subtitle: `${a.doctor_name || '医护'} · ${a.status === 'pending' ? '待确认' : '已确认'}`, type: 'appointment', }); } } } if (taskRes.status === 'fulfilled') { for (const t of taskRes.value.data.slice(0, 2)) { items.push({ id: t.id, title: `随访: ${t.task_type}`, subtitle: `${t.description?.slice(0, 30) || ''} · 截止 ${t.due_date}`, type: 'followup', }); } } setUpcomingItems(items); } catch { setUpcomingItems([]); } finally { setUpcomingLoading(false); } }; const hour = new Date().getHours(); const greeting = hour < 12 ? '早上好' : hour < 18 ? '下午好' : '晚上好'; const displayName = user?.display_name || currentPatient?.name || '访客'; const quickServices = [ { label: '预约挂号', icon: '📅', path: '/pages/appointment/create/index' }, { label: '健康录入', icon: '📊', path: '/pages/health/input/index' }, { label: '健康趋势', icon: '📈', path: '/pages/health/trend/index' }, { label: '资讯文章', icon: '📰', path: '/pages/article/index' }, { label: 'AI 报告', icon: '🤖', path: '/pages/ai-report/list/index' }, ]; const handleServiceClick = (path: string) => { // tabBar 页面必须使用 switchTab,其他页面用 navigateTo const isTabBar = ['pages/index/index', 'pages/health/index', 'pages/appointment/index', 'pages/article/index', 'pages/profile/index'] .some((p) => path.includes(p)); if (isTabBar) { Taro.switchTab({ url: path }); } else { Taro.navigateTo({ url: path }); } }; const healthItems = [ { label: '血压', value: todaySummary?.blood_pressure ? `${todaySummary.blood_pressure.systolic}/${todaySummary.blood_pressure.diastolic}` : '--/--', unit: 'mmHg', status: todaySummary?.blood_pressure?.status }, { label: '心率', value: todaySummary?.heart_rate ? `${todaySummary.heart_rate.value}` : '--', unit: 'bpm', status: todaySummary?.heart_rate?.status }, { label: '血糖', value: todaySummary?.blood_sugar ? `${todaySummary.blood_sugar.value}` : '--', unit: 'mmol/L', status: todaySummary?.blood_sugar?.status }, { label: '体重', value: todaySummary?.weight ? `${todaySummary.weight.value}` : '--', unit: 'kg', status: todaySummary?.weight?.status }, ]; const getStatusLabel = (status?: string) => { if (status === 'high') return '偏高 ▲'; if (status === 'low') return '偏低 ▼'; if (status === 'normal') return '正常'; return ''; }; return ( {greeting}, {displayName} {new Date().toLocaleDateString('zh-CN')} 今日健康 {loading && !todaySummary ? ( ) : ( {healthItems.map((item) => ( {item.label} {item.value} {item.unit} {item.status && {getStatusLabel(item.status)}} ))} )} 快捷服务 {quickServices.map((svc) => ( handleServiceClick(svc.path)}> {svc.icon} {svc.label} ))} 待办事项 {upcomingLoading ? ( ) : upcomingItems.length === 0 ? ( ) : ( {upcomingItems.map((item) => ( { if (item.type === 'appointment') { Taro.navigateTo({ url: `/pages/appointment/index` }); } else { Taro.navigateTo({ url: `/pages/followup/detail/index?id=${item.id}` }); } }} > {item.title} {item.subtitle} ))} )} ); }