"use client"; import { useEffect, useState } from "react"; import { Brain, RefreshCw, Sparkles } from "lucide-react"; import { Badge } from "@/components/ui/badge"; import { Button } from "@/components/ui/button"; import { Card, CardContent, CardDescription, CardHeader, CardTitle } from "@/components/ui/card"; import { Dialog } from "@/components/ui/dialog"; import type { ElderAiAnalysisHistoryItem, ElderAiDataScope, ElderAiRecommendationPriority, ElderAiSeverity, } from "@/modules/ai/types"; import type { ApiResult } from "@/modules/core/server/api"; import { CARE_LEVEL_LABELS, ELDER_STATUS_LABELS } from "@/modules/elders/types"; import type { Elder } from "@/modules/elders/types"; type ElderAiAnalysisDialogProps = { elder: Elder | null; open: boolean; onClose: () => void; }; const riskLabels: Record = { low: "低", medium: "中", high: "高", critical: "紧急", unknown: "未知", }; const statusLabels: Record = { completed: "已完成", failed: "未完成", }; const severityLabels: Record = { info: "提示", warning: "关注", critical: "紧急", }; const recommendationPriorityLabels: Record = { low: "低", normal: "常规", high: "高", urgent: "紧急", }; const dataScopeLabels: Record = { elder: "基础档案", health: "健康数据", care: "护理服务", family: "家属服务", admission: "入住信息", facility: "床位设施", alert: "规则预警", incident: "安全事件", knowledge: "知识库", }; function severityVariant(severity: ElderAiSeverity): "danger" | "secondary" | "warning" { if (severity === "critical") { return "danger"; } if (severity === "warning") { return "warning"; } return "secondary"; } function recommendationVariant(priority: ElderAiRecommendationPriority): "danger" | "secondary" | "warning" { if (priority === "urgent") { return "danger"; } if (priority === "high") { return "warning"; } return "secondary"; } function formatDateTime(value: string): string { return new Date(value).toLocaleString("zh-CN"); } export function ElderAiAnalysisDialog({ elder, onClose, open }: ElderAiAnalysisDialogProps): React.ReactElement { const [history, setHistory] = useState([]); const [message, setMessage] = useState(""); const [isLoading, setIsLoading] = useState(false); const [isGenerating, setIsGenerating] = useState(false); async function loadHistory(target: Elder): Promise { setIsLoading(true); setMessage(""); const response = await fetch(`/api/ai/elders/${target.id}/analyses`); const result = (await response.json()) as ApiResult<{ history: ElderAiAnalysisHistoryItem[] }>; setIsLoading(false); if (!result.success) { setMessage(result.reason); return; } setHistory(result.history); } useEffect(() => { if (open && elder) { void loadHistory(elder); } }, [elder, open]); async function generate(): Promise { if (!elder) { return; } setIsGenerating(true); setMessage(""); const response = await fetch(`/api/ai/elders/${elder.id}/analyses`, { method: "POST" }); const result = (await response.json()) as ApiResult<{ analysis: ElderAiAnalysisHistoryItem }>; setIsGenerating(false); if (!result.success) { setMessage(result.reason); await loadHistory(elder); return; } setHistory((current) => [result.analysis, ...current]); setMessage(result.reason); } const latest = history[0]; const latestResult = latest && !latest.restricted ? latest.result : undefined; return ( {elder ? (

{elder.name}

{elder.age} 岁 · {CARE_LEVEL_LABELS[elder.careLevel]} · {ELDER_STATUS_LABELS[elder.status]} · {elder.room && elder.bed ? `${elder.room}-${elder.bed}` : "未绑定床位"}

{message ? (

{message}

) : null} {latestResult ? (
最新分析 {latest ? formatDateTime(latest.createdAt) : ""}
风险:{riskLabels[latestResult.overallRiskLevel] ?? latestResult.overallRiskLevel}

{latestResult.summary}

关键发现

{latestResult.keyFindings.map((finding, index) => (
{finding.category} {severityLabels[finding.severity]}

{finding.evidence}

))}

建议动作

{latestResult.recommendations.map((recommendation, index) => (
{recommendation.title} {recommendationPriorityLabels[recommendation.priority]}

{recommendation.rationale}

{recommendation.suggestedNextStep}

))}
{latestResult.dataGaps.length > 0 ? (

数据缺口

    {latestResult.dataGaps.map((gap) => (
  • {gap}
  • ))}
) : null}

引用来源

{latestResult.citations.map((citation) => (

[{citation.id}] {citation.title}

{citation.excerpt}

))}
) : latest ? (
最新记录 {formatDateTime(latest.createdAt)}
{latest.status === "failed" ? "生成失败" : "受限"}

{latest.restricted ? "当前角色缺少该分析所使用数据范围的读取权限。" : latest.errorReason ?? "暂无可展示分析。"}

{latest.status === "failed" ?

系统已保留必要的状态信息,可稍后重新更新分析。

: null}
) : ( {isLoading ? "正在加载分析历史" : "暂无智能分析历史"} )}

历史记录

{history.map((item) => (

{formatDateTime(item.createdAt)}

范围:{item.dataScopes.map((scope) => dataScopeLabels[scope]).join("、") || "-"}

{item.restricted ? 受限 : null} {statusLabels[item.status]}
))}
) : (
)}
); }