Refactor UUID generation, remove unused logger and encryption utilities, and clean up request handling

- Updated `generateUUID` function for improved readability and performance.
- Deleted `logger.ts`, `other.ts`, `request.ts`, `storage.ts`, `tansParams.ts`, and `validate.ts` as they were no longer needed.
- Simplified TypeScript configuration by removing unnecessary paths and aliases.
- Enhanced Vite configuration for better project structure and maintainability.
This commit is contained in:
DEV_DSW
2026-04-17 15:38:08 +08:00
parent b1dea9a5c2
commit 79bea4f107
360 changed files with 14495 additions and 30856 deletions

101
src/router/auth-session.ts Normal file
View File

@@ -0,0 +1,101 @@
import Cookies from 'js-cookie';
export const TOKEN_STORAGE_KEYS = ['token', 'access_token', 'refresh_token'] as const;
const AUTH_LOGOUT_EVENT = 'zn:auth-logout';
export type AuthLogoutDetail = {
from?: string;
reason?: 'manual' | 'unauthorized';
};
function normalizeStoredToken(value: string | null): string | null {
if (!value) return null;
try {
const parsed = JSON.parse(value) as unknown;
return typeof parsed === 'string' ? parsed : value;
} catch {
return value;
}
}
function readCookie(name: string): string | null {
if (typeof document === 'undefined' || !document.cookie) return null;
const match = document.cookie.match(new RegExp(`(?:^|; )${name.replace(/[.*+?^${}()|[\]\\]/g, '\\$&')}=([^;]*)`));
return match ? decodeURIComponent(match[1]) : null;
}
export function readPersistedAuthToken(): string | null {
if (typeof window === 'undefined') return null;
const storageCandidates = [window.sessionStorage, window.localStorage];
for (const storage of storageCandidates) {
for (const key of TOKEN_STORAGE_KEYS) {
const value = normalizeStoredToken(storage.getItem(key));
if (value) return value;
}
}
for (const key of TOKEN_STORAGE_KEYS) {
const value = normalizeStoredToken(readCookie(key));
if (value) return value;
}
return null;
}
export function persistAuthTokens(accessToken: string, refreshToken?: string | null): void {
if (typeof window === 'undefined') return;
window.sessionStorage.setItem('token', JSON.stringify(accessToken));
Cookies.set('token', accessToken);
if (refreshToken) {
window.sessionStorage.setItem('refresh_token', JSON.stringify(refreshToken));
Cookies.set('refresh_token', refreshToken);
return;
}
window.sessionStorage.removeItem('refresh_token');
window.localStorage.removeItem('refresh_token');
Cookies.remove('refresh_token');
}
export function clearPersistedAuth(): void {
if (typeof window === 'undefined') return;
const storageCandidates = [window.sessionStorage, window.localStorage];
for (const storage of storageCandidates) {
for (const key of TOKEN_STORAGE_KEYS) {
storage.removeItem(key);
}
}
for (const key of TOKEN_STORAGE_KEYS) {
Cookies.remove(key);
}
}
export function logout(detail: AuthLogoutDetail = {}): void {
clearPersistedAuth();
if (typeof window === 'undefined') return;
window.dispatchEvent(new CustomEvent<AuthLogoutDetail>(AUTH_LOGOUT_EVENT, { detail }));
}
export function onAuthLogout(callback: (detail: AuthLogoutDetail) => void): () => void {
if (typeof window === 'undefined') {
return () => {};
}
const listener = (event: Event) => {
const customEvent = event as CustomEvent<AuthLogoutDetail>;
callback(customEvent.detail ?? {});
};
window.addEventListener(AUTH_LOGOUT_EVENT, listener);
return () => window.removeEventListener(AUTH_LOGOUT_EVENT, listener);
}

42
src/router/auth.tsx Normal file
View File

@@ -0,0 +1,42 @@
import { Navigate, Outlet, useLocation } from 'react-router-dom';
import { DEFAULT_PATH, normalizeWorkspacePath, type WorkspacePath } from './routes';
import { clearPersistedAuth, logout, readPersistedAuthToken } from './auth-session';
type AuthRedirectState = {
from?: string;
};
export function isAuthenticated(): boolean {
return Boolean(readPersistedAuthToken());
}
export { clearPersistedAuth, logout, readPersistedAuthToken };
export function resolveWorkspacePath(pathname?: string | null): WorkspacePath {
if (!pathname) return DEFAULT_PATH;
return normalizeWorkspacePath(pathname);
}
export function resolvePostLoginPath(state?: AuthRedirectState | null): WorkspacePath {
return resolveWorkspacePath(state?.from);
}
export function RequireAuth() {
const location = useLocation();
if (!isAuthenticated()) {
return <Navigate to="/login" replace state={{ from: location.pathname } satisfies AuthRedirectState} />;
}
return <Outlet />;
}
export function RedirectAuthenticated() {
const location = useLocation();
if (isAuthenticated()) {
return <Navigate to={resolvePostLoginPath(location.state as AuthRedirectState | null)} replace />;
}
return <Outlet />;
}

View File

@@ -1,70 +0,0 @@
import { createRouter, createMemoryHistory } from "vue-router";
const routes = [
{
path: '/',
redirect: '/home'
},
{
path: "/login",
component: () => import("@src/pages/login/index.vue"),
name: "Login",
meta: { requiresAuth: true },
},
{
path: "/home",
component: () => import("@src/pages/home/index.vue"),
name: "Home",
meta: { requiresAuth: true },
},
{
path: "/agents",
component: () => import("@src/pages/agents/index.vue"),
name: "Agents",
meta: { requiresAuth: true },
},
{
path: "/knowledge",
component: () => import("@src/pages/knowledge/index.vue"),
name: "Knowledge",
meta: { requiresAuth: true },
},
{
path: "/skills",
component: () => import("@src/pages/skills/index.vue"),
name: "Skills",
meta: { requiresAuth: true },
},
{
path: "/cron",
component: () => import("@src/pages/cron/index.vue"),
name: "Cron",
meta: { requiresAuth: true },
},
{
path: "/scripts",
component: () => import("@src/pages/scripts/index.vue"),
name: "Scripts",
meta: { requiresAuth: true },
},
{
path: "/setting",
component: () => import("@src/pages/setting/index.vue"),
name: "Setting",
meta: { requiresAuth: true },
},
];
const router = createRouter({
history: createMemoryHistory(),
routes,
scrollBehavior(_to: any, _from: any, savedPosition: any) {
if (savedPosition) {
return savedPosition
}
return { top: 0 }
},
});
export default router;

61
src/router/index.tsx Normal file
View File

@@ -0,0 +1,61 @@
import { useEffect } from 'react';
import { Navigate, Route, Routes, useLocation, useNavigate } from 'react-router-dom';
import MainLayout from '../components/layout/MainLayout';
import HomePage from '../pages/Home';
import LoginPage from '../pages/Login';
import AgentsPage from '../pages/Agents';
import SkillsPage from '../pages/Skills';
import CronPage from '../pages/Cron';
import ScriptsPage from '../pages/Scripts';
import SettingPage from '../pages/Setting';
import KnowledgePage from '../pages/Knowledge';
import { DEFAULT_PATH } from './routes';
import { RedirectAuthenticated, RequireAuth, isAuthenticated } from './auth';
import { onAuthLogout } from './auth-session';
function AuthLogoutRedirector() {
const location = useLocation();
const navigate = useNavigate();
useEffect(() => {
return onAuthLogout(({ from }) => {
const currentPath = location.pathname === '/login' ? undefined : location.pathname;
navigate('/login', {
replace: true,
state: { from: from ?? currentPath },
});
});
}, [location.pathname, navigate]);
return null;
}
export function AppRouter() {
const initialPath = isAuthenticated() ? DEFAULT_PATH : '/login';
return (
<>
<AuthLogoutRedirector />
<Routes>
<Route path="/" element={<Navigate to={initialPath} replace />} />
<Route element={<RedirectAuthenticated />}>
<Route path="/login" element={<LoginPage />} />
</Route>
<Route element={<RequireAuth />}>
<Route element={<MainLayout />}>
<Route path="/home" element={<HomePage />} />
<Route path="/agents" element={<AgentsPage />} />
<Route path="/skills" element={<SkillsPage />} />
<Route path="/cron" element={<CronPage />} />
<Route path="/scripts" element={<ScriptsPage />} />
<Route path="/setting" element={<SettingPage />} />
<Route path="/knowledge" element={<KnowledgePage />} />
</Route>
</Route>
<Route path="*" element={<Navigate to={initialPath} replace />} />
</Routes>
</>
);
}

44
src/router/routes.ts Normal file
View File

@@ -0,0 +1,44 @@
export type AppPath =
| '/home'
| '/agents'
| '/skills'
| '/cron'
| '/scripts'
| '/setting'
| '/knowledge'
| '/login';
export type WorkspacePath = Exclude<AppPath, '/login'>;
export type NavItem = {
path: WorkspacePath;
label: string;
description: string;
};
export const DEFAULT_PATH: WorkspacePath = '/home';
export const NAV_ITEMS: NavItem[] = [
{ path: '/home', label: '首页', description: '对话与首页入口' },
{ path: '/knowledge', label: '知识库', description: '知识库与内容管理' },
{ path: '/agents', label: '模型', description: '智能体与提供方' },
{ path: '/skills', label: '技能', description: '技能与能力集' },
{ path: '/cron', label: '定时任务', description: '计划与调度' },
{ path: '/scripts', label: '脚本', description: '脚本与自动化' },
{ path: '/setting', label: '设置', description: '应用配置' },
];
export function normalizeWorkspacePath(pathname: string): WorkspacePath {
switch (pathname) {
case '/knowledge':
case '/agents':
case '/skills':
case '/cron':
case '/scripts':
case '/setting':
return pathname;
case '/home':
default:
return DEFAULT_PATH;
}
}