refactor(frontend): P1-P2 架构统一 — utils/hooks/api 模块化

P1:
- utils/storage.ts、theme.ts、validate.ts + index 统一出口
- request/store/useTheme 接入 storage;清零 confirm/alert
- PipelineManager、TerminalAuditTab 拆分子模块(<700行红线)

P2:
- api/monitor、api/deploy 子目录化
- hooks/api 扩展:servers/pipelines/alerts/audit/sessionCommands
- PipelineManager、AuditOperationsTab 接入 TanStack Query
This commit is contained in:
Logan.Li committed 2026-06-26 00:18:14 +08:00
1 parent d19a03d427
commit f45e203e21
196 files changed
+3228 -2018

No files matched your search

+64
View File
@@ -0,0 +1,64 @@
// 主题常量与持久化 — 供 useTheme / ThemeProvider 使用 // Logan.Li
import { getItem, setItem, STORAGE_KEYS } from './storage';
export type Theme =
| 'ocean-deep'
| 'light-professional'
| 'midnight-purple'
| 'pine-green'
| 'orange-vitality';
export interface ThemeOption {
id: Theme;
name: string;
description: string;
isDark: boolean;
primaryColor: string;
}
export const THEME_OPTIONS: ThemeOption[] = [
{ id: 'ocean-deep', name: '深海蓝', description: '专业稳重的深蓝色调', isDark: true, primaryColor: '#3b82f6' },
{ id: 'light-professional', name: '明亮白', description: '清爽干净的浅色主题', isDark: false, primaryColor: '#2563eb' },
{ id: 'midnight-purple', name: '午夜紫', description: '神秘优雅的紫色调', isDark: true, primaryColor: '#a855f7' },
{ id: 'pine-green', name: '松林绿', description: '自然清新的绿色主题', isDark: true, primaryColor: '#22c55e' },
{ id: 'orange-vitality', name: '活力橙', description: '温暖活力的橙色主题', isDark: true, primaryColor: '#f97316' },
];
export const THEME_ORDER: Theme[] = THEME_OPTIONS.map((o) => o.id);
export const DEFAULT_THEME: Theme = 'ocean-deep';
/** 兼容旧版 dark/light 主题名 // Logan.Li */
export function migrateLegacyTheme(value: string | null): Theme | null {
if (value === 'dark') return 'ocean-deep';
if (value === 'light') return 'light-professional';
return null;
}
export function getInitialTheme(): Theme {
if (typeof window === 'undefined') return DEFAULT_THEME;
const stored = getItem(STORAGE_KEYS.theme);
const migrated = migrateLegacyTheme(stored);
if (migrated) {
setItem(STORAGE_KEYS.theme, migrated);
return migrated;
}
if (stored && THEME_ORDER.includes(stored as Theme)) {
return stored as Theme;
}
return DEFAULT_THEME;
}
export function persistTheme(theme: Theme): void {
setItem(STORAGE_KEYS.theme, theme);
}
export function applyThemeToDocument(theme: Theme): void {
if (typeof document === 'undefined') return;
document.documentElement.setAttribute('data-theme', theme);
}
export function getNextTheme(current: Theme): Theme {
const idx = THEME_ORDER.indexOf(current);
return THEME_ORDER[(idx + 1) % THEME_ORDER.length];
}