import { View, Text, Swiper, SwiperItem } from '@tarojs/components'; import { useState, useCallback } from 'react'; import Taro, { useDidShow, usePullDownRefresh } from '@tarojs/taro'; import { useAuthStore } from '../../stores/auth'; import { useUIStore } from '../../stores/ui'; import { useHealthStore } from '../../stores/health'; import ProgressRing from '../../components/ProgressRing'; import Loading from '../../components/Loading'; import { trackPageView } from '@/services/analytics'; import * as appointmentApi from '@/services/appointment'; import * as followupApi from '@/services/followup'; import { listPendingSuggestions, type AiSuggestionItem } from '@/services/ai-analysis'; import { notificationService } from '@/services/notification'; import * as articleApi from '@/services/article'; import './index.scss'; interface ReminderItem { id: string; text: string; type: 'ai' | 'appointment' | 'followup'; tag: string; } // ─── 访客首页 ─── const CAROUSEL_SLIDES = [ { id: 'slide-1', title: '专业血透中心', desc: '三甲级医护团队全程守护' }, { id: 'slide-2', title: '智慧健康管理', desc: 'AI 驱动个性化健康方案' }, { id: 'slide-3', title: '温馨就医环境', desc: '舒适安全的治疗体验' }, ]; function GuestHome({ modeClass }: { modeClass: string }) { const [articles, setArticles] = useState([]); const [loading, setLoading] = useState(false); useDidShow(() => { loadArticles(); trackPageView('guest-home'); }); const loadArticles = async () => { setLoading(true); try { const res = await articleApi.listArticles({ page: 1, page_size: 4 }); setArticles(res.data || []); } catch { // 文章加载失败不阻塞 } finally { setLoading(false); } }; return ( {/* 轮播图 */} {CAROUSEL_SLIDES.map((slide) => ( {slide.title} {slide.desc} ))} {/* 健康资讯 */} 健康资讯 {loading ? ( ) : articles.length > 0 ? ( {articles.map((a) => ( Taro.navigateTo({ url: `/pages/article/detail/index?id=${a.id}` })} > {a.title} {a.summary && {a.summary}} ))} ) : ( 暂无文章 )} {/* 底部登录引导 */} 登录后即可使用完整健康管理服务 Taro.navigateTo({ url: '/pages/login/index' })} > 立即登录 ); } // ─── 登录后首页 ─── function HomeDashboard({ modeClass }: { modeClass: string }) { const { user, currentPatient } = useAuthStore(); const { todaySummary, loading, refreshToday } = useHealthStore(); const [reminders, setReminders] = useState([]); const [unreadCount, setUnreadCount] = useState(0); const [remindersLoading, setRemindersLoading] = useState(false); useDidShow(() => { refreshToday(); loadReminders(); loadUnread(); trackPageView('home'); }); usePullDownRefresh(() => { Promise.all([refreshToday(true), loadReminders(), loadUnread()]).finally(() => { Taro.stopPullDownRefresh(); }); }); const loadUnread = async () => { try { const res = await notificationService.getUnreadCount() as { data?: { count?: number } | number }; const d = res.data; setUnreadCount(typeof d === 'object' && d ? (d.count ?? 0) : 0); } catch { // ignore } }; const loadReminders = async () => { const patientId = useAuthStore.getState().currentPatient?.id; if (!patientId) return; setRemindersLoading(true); try { const items: ReminderItem[] = []; const [apptRes, taskRes, suggestRes] = await Promise.allSettled([ appointmentApi.listAppointments(patientId, 1), followupApi.listTasks(patientId, 'pending'), listPendingSuggestions(), ]); if (suggestRes.status === 'fulfilled') { for (const s of suggestRes.value.data.slice(0, 1)) { items.push({ id: s.id, text: buildSuggestionText(s), type: 'ai', tag: 'AI 建议' }); } } if (apptRes.status === 'fulfilled') { for (const a of apptRes.value.data.slice(0, 1)) { if (a.status === 'pending' || a.status === 'confirmed') { items.push({ id: a.id, text: `${a.appointment_date} ${a.start_time} — ${a.doctor_name || '医护'} ${a.department || '门诊'}`, type: 'appointment', tag: '预约', }); } } } if (taskRes.status === 'fulfilled') { for (const t of taskRes.value.data.slice(0, 1)) { items.push({ id: t.id, text: `${t.follow_up_type} · 截止 ${t.planned_date}`, type: 'followup', tag: '随访', }); } } setReminders(items.slice(0, 3)); } catch { setReminders([]); } finally { setRemindersLoading(false); } }; const hour = new Date().getHours(); const greeting = hour < 12 ? '上午好' : hour < 18 ? '下午好' : '晚上好'; const displayName = user?.display_name || currentPatient?.name || '访客'; const summary = todaySummary || {}; const indicators = [!!summary.blood_pressure, !!summary.heart_rate, !!summary.blood_sugar, !!summary.weight]; const completedCount = indicators.filter(Boolean).length; const progressPercent = Math.round((completedCount / 4) * 100); const indicatorCapsules = [ { label: '血压', done: !!summary.blood_pressure }, { label: '心率', done: !!summary.heart_rate }, { label: '血糖', done: !!summary.blood_sugar }, { label: '体重', done: !!summary.weight }, ]; const healthItems = [ { label: '血压', value: summary.blood_pressure ? `${summary.blood_pressure.systolic}/${summary.blood_pressure.diastolic}` : '—', unit: 'mmHg', status: summary.blood_pressure?.status, indicator: 'systolic_bp_morning' }, { label: '心率', value: summary.heart_rate ? `${summary.heart_rate.value}` : '—', unit: 'bpm', status: summary.heart_rate?.status, indicator: 'heart_rate' }, { label: '血糖', value: summary.blood_sugar ? `${summary.blood_sugar.value}` : '—', unit: 'mmol/L', status: summary.blood_sugar?.status, indicator: 'blood_sugar' }, { label: '体重', value: summary.weight ? `${summary.weight.value}` : '—', unit: 'kg', status: summary.weight?.status, indicator: 'weight' }, ]; const getStatusTag = (status?: string) => { if (status === 'high' || status === 'low') return { label: status === 'high' ? '偏高' : '偏低', cls: 'tag-warn' }; if (status === 'normal') return { label: '正常', cls: 'tag-ok' }; return null; }; return ( {/* 问候区 */} {greeting},{displayName} {new Date().toLocaleDateString('zh-CN', { month: 'long', day: 'numeric', weekday: 'short' })} Taro.switchTab({ url: '/pages/messages/index' })}> {unreadCount > 0 && } {/* 今日体征进度 */} Taro.switchTab({ url: '/pages/health/index' })}> {completedCount === 4 ? '今日体征已全部记录' : completedCount === 0 ? '今日尚未记录体征' : `今日已记录 ${completedCount}/4 项`} {indicatorCapsules.map((cap) => ( {cap.done ? '✓ ' : ''}{cap.label} ))} {/* 体征 2x2 */} 今日体征 {loading && !todaySummary ? ( ) : ( {healthItems.map((item) => { const tag = getStatusTag(item.status); return ( Taro.navigateTo({ url: `/pages/pkg-health/trend/index?indicator=${item.indicator}` })} > {item.label} {item.value} {item.unit} {tag && {tag.label}} {!item.status && 未记录} ); })} )} {/* 智能提醒卡片 */} {!remindersLoading && reminders.length > 0 && ( 智能提醒 {reminders.length} 条待处理 {reminders.map((r, i) => ( 0 ? 'reminder-item-border' : ''}`} onClick={() => { if (r.type === 'appointment') Taro.navigateTo({ url: '/pages/appointment/index' }); else if (r.type === 'followup') Taro.navigateTo({ url: `/pages/followup/detail/index?id=${r.id}` }); }} > {r.tag} {r.text} ))} )} {/* 快捷操作 */} Taro.switchTab({ url: '/pages/health/index' })}> 记录体征 Taro.navigateTo({ url: '/pages/appointment/create/index' })}> 预约挂号 ); } // ─── 首页入口:根据登录状态切换 ─── export default function Index() { const user = useAuthStore((s) => s.user); const mode = useUIStore((s) => s.mode); const modeClass = mode === 'elder' ? 'elder-mode' : ''; if (!user) { return ; } return ; } function buildSuggestionText(s: AiSuggestionItem): string { const riskMap: Record = { high: '高风险', medium: '中风险', low: '低风险' }; const typeMap: Record = { vital_sign_anomaly: '体征异常', lab_result_anomaly: '化验异常', medication_adherence: '用药提醒', lifestyle: '生活建议', }; const risk = riskMap[s.risk_level] || ''; const type = typeMap[s.suggestion_type] || '健康建议'; return `${type}:发现${risk}指标,建议关注`; }