import { useState, useCallback } from 'react'; import { View, Text } from '@tarojs/components'; import Taro, { useReachBottom } from '@tarojs/taro'; import { safeNavigateTo } from '@/utils/navigate'; import { usePageData } from '@/hooks/usePageData'; import { useAuthStore } from '@/stores/auth'; import { listConsultations, ConsultationSession } from '@/services/consultation'; import PageShell from '@/components/ui/PageShell'; import ContentCard from '@/components/ui/ContentCard'; import StatusTag from '@/components/ui/StatusTag'; import LoadingCard from '@/components/ui/LoadingCard'; import EmptyState from '@/components/EmptyState'; import ErrorState from '@/components/ErrorState'; import Loading from '@/components/Loading'; import GuestGuard from '@/components/GuestGuard'; import { useElderClass } from '../../hooks/useElderClass'; import './index.scss'; /** 读取当前页面 URL 中的查询参数 */ function getQueryParams(): Record { try { const instance = Taro.getCurrentInstance(); const params = instance?.router?.params; if (!params) return {}; const result: Record = {}; for (const [key, value] of Object.entries(params)) { if (typeof value === 'string') { result[key] = value; } } return result; } catch (err) { console.warn('[consultation] 解析查询参数失败:', err); return {}; } } function formatTime(iso: string): string { if (!iso) return ''; const d = new Date(iso); const now = new Date(); const diffMin = Math.floor((now.getTime() - d.getTime()) / 60000); if (diffMin < 1) return '刚刚'; if (diffMin < 60) return `${diffMin}分钟前`; const diffHour = Math.floor(diffMin / 60); if (diffHour < 24) return `${diffHour}小时前`; const diffDay = Math.floor(diffHour / 24); if (diffDay < 7) return `${diffDay}天前`; const m = String(d.getMonth() + 1).padStart(2, '0'); const day = String(d.getDate()).padStart(2, '0'); return `${m}-${day}`; } /** 咨询状态到 StatusTag status 的映射 */ function getConsultStatus(status: string): string { if (status === 'active') return 'active'; if (status === 'pending') return 'pending'; if (status === 'closed') return 'completed'; if (status === 'cancelled') return 'cancelled'; return status; } const STATUS_LABEL_MAP: Record = { active: '进行中', pending: '等待接诊', closed: '已结束', cancelled: '已取消', }; export default function Consultation() { const user = useAuthStore((s) => s.user); const [sessions, setSessions] = useState([]); const [loading, setLoading] = useState(true); const [error, setError] = useState(''); const modeClass = useElderClass(); const [page, setPage] = useState(1); const [total, setTotal] = useState(0); // Alert context: when navigated from an alert page const [alertContext, setAlertContext] = useState<{ alertId: string; alertTitle: string } | null>(null); const loadSessions = useCallback(async (pageNum: number, isRefresh = false) => { if (isRefresh) setLoading(true); setError(''); try { const resp = await listConsultations({ page: pageNum, page_size: 20 }); const list = resp.data || []; if (isRefresh) { setSessions(list); } else { setSessions((prev) => [...prev, ...list]); } setTotal(resp.total || 0); setPage(pageNum); } catch (err) { console.warn('[consultation] 加载会话列表失败:', err); if (isRefresh) { setSessions([]); setTotal(0); } setError('加载失败,请稍后重试'); Taro.showToast({ title: '加载失败,下拉重试', icon: 'none' }); } finally { setLoading(false); } }, []); usePageData( useCallback(async () => { Taro.setNavigationBarTitle({ title: '在线咨询' }); // Read alert context from URL query params const params = getQueryParams(); if (params.context === 'alert' && params.alert_id) { setAlertContext({ alertId: params.alert_id, alertTitle: params.alert_title ? decodeURIComponent(params.alert_title) : '健康告警', }); } if (!user) return; await loadSessions(1, true); }, [user, loadSessions]), { throttleMs: 10000, enablePullDown: true }, ); useReachBottom(() => { if (!loading && sessions.length < total) { loadSessions(page + 1); } }); const handleTapSession = (session: ConsultationSession) => { safeNavigateTo(`/pages/pkg-consultation/detail/index?id=${session.id}`); }; if (!user) { return ( ); } if (loading && sessions.length === 0) { return ; } if (error && sessions.length === 0) { return ( loadSessions(1, true)} /> ); } return ( {/* 副标题 */} 随时随地,连接专业医生 {/* Alert context banner */} {alertContext && ( 来自告警: {alertContext.alertTitle} )} {/* 发起咨询按钮 */} safeNavigateTo('/pages/consultation/create/index')} > 发起咨询 {/* 会话列表 */} {sessions.length === 0 ? ( ) : ( {sessions.map((session) => { const initial = (session.subject || '咨').charAt(0); const isClosed = session.status === 'closed' || session.status === 'cancelled'; return ( handleTapSession(session)} > {initial} {session.doctor_name || session.subject || '在线咨询'} {session.last_message_at ? formatTime(session.last_message_at) : formatTime(session.created_at)} {STATUS_LABEL_MAP[session.status] || session.status} {session.last_message || '暂无消息'} {session.unread_count_patient > 0 && ( {session.unread_count_patient > 99 ? '99+' : session.unread_count_patient} )} ); })} )} {loading && sessions.length > 0 && } ); }