import { useState, useEffect, useCallback } from "react"; import { Routes, Route, useNavigate, useLocation, Navigate } from "react-router-dom"; import { Layout, Menu, Button, Spin, Tag, Tooltip } from "antd"; import { HomeOutlined, ApartmentOutlined, SettingOutlined, LogoutOutlined, MenuFoldOutlined, MenuUnfoldOutlined, ProjectOutlined, DatabaseOutlined, ApiOutlined, } from "@ant-design/icons"; import AdminLogin from "./AdminLogin"; import AdminLoginV2 from "./AdminLoginV2"; import Brand from "./Brand"; import { getProjectContext, whoami, type KgProjectContext } from "./api"; import ProjectContextBar from "./ProjectContextBar"; import ProjectLanding from "./ProjectLanding"; import DataCenterPanel from "./panels/data-platform/DataCenterPanel"; // Plaza panels (STEP 02) import PlazaOverview from "./panels/plaza/PlazaOverview"; import GraphCanvas from "./panels/plaza/GraphCanvas"; import ProjectUserExperiencePanel from "./panels/plaza/ProjectUserExperiencePanel"; // Schema viewer for schemas created from the graph center. import OntologySchemaPanel from "./panels/modeling/OntologySchemaPanel"; // System panels import UserManagement from "./panels/system/UserManagement"; import InterfaceCenterPanel from "./panels/system/InterfaceCenterPanel"; const { Sider, Content } = Layout; const MENU_ITEMS = [ { key: "/projects", icon: , label: "图谱中心" }, { key: "/data", icon: , label: "数据中心" }, { key: "/plaza", icon: , label: "知识广场", children: [ { key: "/plaza/overview", label: "数据大屏" }, { key: "/plaza/user", label: "业务问答" }, { key: "/plaza/graph", label: "图谱浏览器" }, ]}, { key: "/modeling", icon: , label: "本体建模", children: [ { key: "/modeling/schema", label: "本体 Schema" }, ]}, { key: "/system", icon: , label: "系统", children: [ { key: "/system/interfaces", icon: , label: "接口中心" }, { key: "/system/users", label: "用户管理" }, ]}, ]; export default function App() { const [authed, setAuthed] = useState(false); const [checking, setChecking] = useState(true); const [collapsed, setCollapsed] = useState(false); const [roles, setRoles] = useState([]); const [projectContext, setProjectContextState] = useState(getProjectContext()); const navigate = useNavigate(); const location = useLocation(); const checkAuth = useCallback(async () => { const token = localStorage.getItem("token"); if (!token) { setChecking(false); return; } try { const { data } = await whoami(); setRoles(Array.isArray(data?.roles) ? data.roles : []); setAuthed(true); } catch { localStorage.removeItem("token"); setRoles([]); } setChecking(false); }, []); useEffect(() => { checkAuth(); }, [checkAuth]); useEffect(() => { const onChange = () => setProjectContextState(getProjectContext()); window.addEventListener("znkg-project-context", onChange); return () => window.removeEventListener("znkg-project-context", onChange); }, []); const handleLogout = () => { localStorage.removeItem("token"); setRoles([]); setAuthed(false); navigate("/admin/login"); }; if (checking) return ; if (!authed) { return ( { setAuthed(true); void checkAuth(); navigate("/admin/projects"); }} />} /> { setAuthed(true); void checkAuth(); navigate("/admin/projects"); }} />} /> } /> ); } const onMenuClick = ({ key }: { key: string }) => { if (key === "/data") { window.open("/admin/data", "_blank", "noopener,noreferrer"); return; } navigate(`/admin${key}`); }; const selectedKey = location.pathname.replace("/admin", "") || "/projects"; const openKeys = [selectedKey.split("/").slice(0, 2).join("/")]; const showProjectContextBar = location.pathname === "/admin/projects"; const showDataCenterWorkbench = location.pathname === "/admin/data"; const isDataManager = roles.includes("admin"); const visibleMenuItems = isDataManager ? MENU_ITEMS : MENU_ITEMS.filter((item) => item.key !== "/system"); return ( {!showDataCenterWorkbench && ( {!collapsed && } : } onClick={() => setCollapsed(!collapsed)} /> {!collapsed && ( {projectContext.graphName && {projectContext.graphName}} )} } onClick={handleLogout}> {!collapsed && "退出"} )} {showProjectContextBar && } } /> } /> {/* Plaza */} } /> } /> } /> {/* Schema viewer */} } /> {/* System */} : } /> : } /> navigate("/admin/projects")} />} /> } /> ); }