"use client"; import { useEffect, useState } from "react"; import {Sparkles } from "lucide-react"; import { listDigitalTwins, buildDigitalTwin, simulateTwin } from "@/lib/api-v2"; import { useCompanyScope } from "@/lib/company-scope"; import { PageContainer, Card, Badge } from "@/components/shared/PageContainer"; import { LoadingSpinner } from "@/components/shared/LoadingSpinner"; import { EmptyState } from "@/components/shared/EmptyState"; import { toast } from "sonner"; /** 数字孪生模型项。 */ interface DigitalTwinItem { accuracy_score?: number; } /** 模拟结果。 */ interface SimulationResult { projected_outcome: string; confidence?: number; } export default function DigitalTwinsPage() { const { companyId } = useCompanyScope(); const [items, setItems] = useState([]); const [isLoading, setIsLoading] = useState(true); const [companyData, setCompanyData] = useState(""); const [scenario, setScenario] = useState(""); const [simResult, setSimResult] = useState(null); useEffect(() => { if (!companyId) { // eslint-disable-next-line react-hooks/set-state-in-effect setItems([]); setIsLoading(false); return; } listDigitalTwins(companyId) .then((resp) => setItems((resp.data as DigitalTwinItem[]) ?? [])) .catch(() => setItems([])) .finally(() => setIsLoading(false)); }, [companyId]); const handleBuild = async () => { if (!companyData.trim()) { toast.error("请输入企业数据"); return; } try { const resp = await buildDigitalTwin(companyData); toast.success("数字孿生模型已构建"); setItems([resp.data as DigitalTwinItem, ...items]); } catch { toast.error("构建失败"); } }; const handleSimulate = async () => { if (!scenario.trim()) { toast.error("请输入场景描述"); return; } try { const resp = await simulateTwin({}, scenario); setSimResult(resp.data as SimulationResult); } catch { toast.error("模拟失败"); } }; return ( {!companyId ? ( ) : ( <>

构建数字孪生模型