import { useCallback, useEffect, useState } from 'react'; import { apiClient, errorMessage, AiRecommendations, ModelInfo, parseUtc, } from '../services/api'; import './Recommendations.css'; const PRIORITY_LABEL: Record = { high: '高', medium: '中', low: '低', }; function Recommendations() { const [models, setModels] = useState([]); const [selected, setSelected] = useState(''); const [result, setResult] = useState(null); const [loading, setLoading] = useState(true); const [error, setError] = useState(''); const [regenerating, setRegenerating] = useState(false); const load = useCallback(async (model?: string, refresh?: boolean) => { setLoading(true); setRegenerating(Boolean(refresh || model)); setError(''); try { setResult(await apiClient.getAiRecommendations(model || undefined, refresh)); } catch (err: any) { setError(errorMessage(err, '获取建议失败')); } finally { setLoading(false); setRegenerating(false); } }, []); useEffect(() => { const init = async () => { try { const list = await apiClient.getModels(); setModels(list); setSelected(list.find((m) => m.default && m.configured)?.id ?? ''); } catch { // The model list is a convenience; recommendations still work without it. } load(); }; init(); }, [load]); const configured = models.filter((m) => m.configured); const meta = result?.meta; return (

健康建议

基于你的历史数据生成,可切换不同的大模型

{regenerating && (
正在请求大模型重新分析,通常需要 1-3 分钟(推理模型会先推演再作答)。 期间可以离开本页,结果会被缓存下来。
)} {configured.length === 0 && models.length > 0 && (
尚未配置任何模型密钥。在 backend/.env 中填入 GEMINI_API_KEYNVIDIA_API_KEY 即可启用 AI 建议; 在此之前下面显示的是规则引擎的结果。
)} {error &&
{error}
} {meta && (
{meta.source === 'ai' ? ( <> AI 生成 · 模型 {meta.model} {meta.upstream && `(上游 ${meta.upstream})`} {' · '}分析了 {meta.days} 天数据 {meta.cached && ( · 缓存结果 {meta.generatedAt && `,生成于 ${parseUtc(meta.generatedAt)?.toLocaleString('zh-CN')}`} )} {meta.fallbackFrom && meta.fallbackFrom.length > 0 && ( ({meta.fallbackFrom.join('、')} 失败后自动切换) )} ) : ( <> 规则引擎 {meta.reason && · {meta.reason}} )}
)} {loading && !result &&
正在分析…
}
{result?.recommendations.map((rec) => (
{rec.category} {PRIORITY_LABEL[rec.priority] ?? rec.priority}

{rec.recommendation}

{rec.basedOn.length > 0 && (
依据:{rec.basedOn.join('、')}
)}
))}

以上内容由数据分析生成,不构成医疗建议。如有健康问题请咨询专业医师。

); } export default Recommendations;