- 「设置和更多」新增「智能体管理」「技能管理」入口,与定时任务管理同级; 独立的 AdminAgentsPage/AdminSkillsPage 复用 AgentCard/SkillRow, 管理员可查看并编辑/删除所有用户的智能体与技能。 - 后端 /api/agents、/api/skills 增加 ?admin=true 越权列表;agents 端 放宽 _get_editable_or_raise 让管理员可编辑/删除任意智能体;新增 list_all/update_any/delete_any(agents)与 list_all(skills)。 - 新增 AuthSyncWatcher:监听 localStorage["deerflow.auth"] 的 storage 事件,user_id 变化时自动 reload,修复多标签切换登录后老页面点击 「新对话」偶发 404 的问题。 - LLMErrorHandlingMiddleware 将 bad_response_status_code / JSON decode 等上游网关乱码识别为可重试的 upstream 类故障。 - 侧边栏「任务管理」改名为「定时任务」。 Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
74 lines
2.6 KiB
TypeScript
74 lines
2.6 KiB
TypeScript
import { useMemo } from "react";
|
|
import { Navigate, Route, Routes } from "react-router-dom";
|
|
import { ThemeProvider as NextThemesProvider } from "next-themes";
|
|
|
|
import { QueryClientProvider } from "@/components/query-client-provider";
|
|
import { AuthSyncWatcher } from "@/core/auth/sync";
|
|
import { I18nProvider } from "@/core/i18n/context";
|
|
import { detectLocale } from "@/core/i18n/locale";
|
|
import { ChatProvider } from "@/contexts/ChatContext";
|
|
import { ThemeProvider } from "@/contexts/ThemeContext";
|
|
|
|
import { HashRouter, useLocation } from "react-router-dom";
|
|
|
|
import LandingPage from "./pages/LandingPage";
|
|
import LoginPage from "./pages/LoginPage";
|
|
import PageRoutes from "./pages/PageRoutes";
|
|
import PublicScheduledTaskPage from "./pages/PublicScheduledTaskPage";
|
|
import PublicSharePage from "./pages/PublicSharePage";
|
|
import { NotFoundPage } from "./pages/NotFoundPage";
|
|
|
|
function AppProviders({ children }: { children: React.ReactNode }) {
|
|
const locale = useMemo(() => detectLocale(), []);
|
|
const location = useLocation();
|
|
const forcedTheme = location.pathname === "/landing" ? "light" : undefined;
|
|
|
|
return (
|
|
<NextThemesProvider
|
|
attribute="class"
|
|
storageKey="strategy-theme"
|
|
defaultTheme="light"
|
|
enableSystem={false}
|
|
disableTransitionOnChange
|
|
forcedTheme={forcedTheme}
|
|
>
|
|
{/* QueryClientProvider must wrap ThemeProvider because the custom
|
|
ThemeProvider reads the admin-configured default via useQuery. */}
|
|
<QueryClientProvider>
|
|
<I18nProvider initialLocale={locale}>
|
|
<ThemeProvider>
|
|
<ChatProvider>
|
|
<AuthSyncWatcher />
|
|
{children}
|
|
</ChatProvider>
|
|
</ThemeProvider>
|
|
</I18nProvider>
|
|
</QueryClientProvider>
|
|
</NextThemesProvider>
|
|
);
|
|
}
|
|
|
|
export function App() {
|
|
return (
|
|
<HashRouter>
|
|
<AppProviders>
|
|
<Routes>
|
|
<Route path="/" element={<Navigate to="/login" replace />} />
|
|
<Route path="/login" element={<LoginPage />} />
|
|
<Route path="/login/:username" element={<LoginPage />} />
|
|
<Route path="/landing" element={<LandingPage />} />
|
|
{/* Public read-only conversation viewer — no authentication. */}
|
|
<Route path="/share/:shareCode" element={<PublicSharePage />} />
|
|
{/* Public read-only scheduled-task runs viewer — no authentication. */}
|
|
<Route
|
|
path="/public/scheduled-tasks/:taskId"
|
|
element={<PublicScheduledTaskPage />}
|
|
/>
|
|
<Route path="/page/*" element={<PageRoutes />} />
|
|
<Route path="*" element={<NotFoundPage />} />
|
|
</Routes>
|
|
</AppProviders>
|
|
</HashRouter>
|
|
);
|
|
}
|