feat: 完善堡垒机与 Agent 智能运维能力
- 支持 Windows Agent 构建、安装脚本和统一上报协议 - 增强 RDP 剪贴板、虚拟盘和文件传输能力 - 新增 AIOps 上下文工具、告警 RCA trace 落库和回放接口 - 重构 docs 模块文档并补充终端、堡垒机、监控、AI Agent 设计
This commit is contained in:
1 parent
a9513c2056
commit
e0d652d211
169 files changed
+12192
-9116
No files matched your search
+87
-24
@@ -1,8 +1,8 @@
|
||||
import { create } from 'zustand';
|
||||
import { persist } from 'zustand/middleware';
|
||||
import type { User } from '@/types';
|
||||
import { removeItem, STORAGE_KEYS } from '@/utils/storage';
|
||||
import i18n from '@/i18n';
|
||||
import { create } from "zustand";
|
||||
import { persist } from "zustand/middleware";
|
||||
import type { User } from "@/types";
|
||||
import { removeItem, STORAGE_KEYS } from "@/utils/storage";
|
||||
import i18n from "@/i18n";
|
||||
|
||||
// 主题状态
|
||||
interface ThemeState {
|
||||
@@ -12,11 +12,12 @@ interface ThemeState {
|
||||
|
||||
export const useThemeStore = create<ThemeState>((set) => ({
|
||||
sidebarCollapsed: false,
|
||||
toggleSidebar: () => set((state) => ({ sidebarCollapsed: !state.sidebarCollapsed })),
|
||||
toggleSidebar: () =>
|
||||
set((state) => ({ sidebarCollapsed: !state.sidebarCollapsed })),
|
||||
}));
|
||||
|
||||
// 语言状态(i18n — U3 国际化)
|
||||
type AppLanguage = 'zh-CN' | 'en-US';
|
||||
type AppLanguage = "zh-CN" | "en-US";
|
||||
|
||||
interface LanguageState {
|
||||
language: AppLanguage;
|
||||
@@ -26,21 +27,63 @@ interface LanguageState {
|
||||
export const useLanguageStore = create<LanguageState>()(
|
||||
persist(
|
||||
(set) => ({
|
||||
language: 'zh-CN' as AppLanguage,
|
||||
language: "zh-CN" as AppLanguage,
|
||||
setLanguage: (lang) => {
|
||||
// 同步切换 i18next 实例
|
||||
import('@/i18n').then(({ default: i18n }) => {
|
||||
i18n.changeLanguage(lang);
|
||||
}).catch(() => { /* i18n not yet loaded */ });
|
||||
import("@/i18n")
|
||||
.then(({ default: i18n }) => {
|
||||
i18n.changeLanguage(lang);
|
||||
})
|
||||
.catch(() => {
|
||||
/* i18n not yet loaded */
|
||||
});
|
||||
set({ language: lang });
|
||||
},
|
||||
}),
|
||||
{
|
||||
name: 'language-storage',
|
||||
name: "language-storage",
|
||||
},
|
||||
),
|
||||
);
|
||||
|
||||
// 会话安全策略:用于 RDP/SSH/POD 等远程会话的水印、剪贴板和文件管控。 // Logan.Li
|
||||
interface SessionSecurityState {
|
||||
watermarkEnabled: boolean;
|
||||
recordEnabled: boolean;
|
||||
clipboardEnabled: boolean;
|
||||
fileUploadEnabled: boolean;
|
||||
fileDownloadEnabled: boolean;
|
||||
commandPolicyEnabled: boolean;
|
||||
approvalRequired: boolean;
|
||||
setWatermarkEnabled: (enabled: boolean) => void;
|
||||
setPolicy: (
|
||||
policy: Partial<
|
||||
Omit<SessionSecurityState, "setWatermarkEnabled" | "setPolicy">
|
||||
>,
|
||||
) => void;
|
||||
}
|
||||
|
||||
export const useSessionSecurityStore = create<SessionSecurityState>()(
|
||||
persist(
|
||||
(set) => ({
|
||||
watermarkEnabled: true,
|
||||
recordEnabled: true,
|
||||
clipboardEnabled: true,
|
||||
fileUploadEnabled: true,
|
||||
fileDownloadEnabled: true,
|
||||
commandPolicyEnabled: false,
|
||||
approvalRequired: false,
|
||||
setWatermarkEnabled: (watermarkEnabled) => set({ watermarkEnabled }),
|
||||
setPolicy: (policy) => set(policy),
|
||||
}),
|
||||
{
|
||||
name: "session-security-storage",
|
||||
},
|
||||
),
|
||||
);
|
||||
|
||||
export const useSessionWatermarkStore = useSessionSecurityStore;
|
||||
|
||||
// 用户状态
|
||||
interface UserState {
|
||||
user: User | null;
|
||||
@@ -62,21 +105,32 @@ export const useUserStore = create<UserState>()(
|
||||
user: null as User | null,
|
||||
token: null as string | null,
|
||||
isAuthenticated: false,
|
||||
theme: 'ocean-deep',
|
||||
theme: "ocean-deep",
|
||||
permissions: null as string[] | null,
|
||||
setUser: (user) => set({ user }),
|
||||
setToken: (token) => set({ token }),
|
||||
setPermissions: (permissions) => set({ permissions }),
|
||||
login: (user, token, permissions) => set({ user, token, isAuthenticated: true, permissions: permissions ?? null }),
|
||||
login: (user, token, permissions) =>
|
||||
set({
|
||||
user,
|
||||
token,
|
||||
isAuthenticated: true,
|
||||
permissions: permissions ?? null,
|
||||
}),
|
||||
logout: () => {
|
||||
removeItem(STORAGE_KEYS.token);
|
||||
set({ user: null as User | null, token: null as string | null, isAuthenticated: false, permissions: null });
|
||||
set({
|
||||
user: null as User | null,
|
||||
token: null as string | null,
|
||||
isAuthenticated: false,
|
||||
permissions: null,
|
||||
});
|
||||
},
|
||||
}),
|
||||
{
|
||||
name: 'user-storage',
|
||||
}
|
||||
)
|
||||
name: "user-storage",
|
||||
},
|
||||
),
|
||||
);
|
||||
|
||||
// 菜单状态
|
||||
@@ -88,7 +142,7 @@ interface MenuState {
|
||||
}
|
||||
|
||||
export const useMenuStore = create<MenuState>((set) => ({
|
||||
activeMenu: 'dashboard',
|
||||
activeMenu: "dashboard",
|
||||
openMenus: [],
|
||||
setActiveMenu: (menu) => set({ activeMenu: menu }),
|
||||
toggleMenu: (menu) =>
|
||||
@@ -116,8 +170,15 @@ interface TabState {
|
||||
}
|
||||
|
||||
export const useTabStore = create<TabState>((set) => ({
|
||||
tabs: [{ id: 'dashboard', title: i18n.t('monitor.dashboard.custom.typeGauge'), path: '/', closable: false }],
|
||||
activeTab: 'dashboard',
|
||||
tabs: [
|
||||
{
|
||||
id: "dashboard",
|
||||
title: i18n.t("monitor.dashboard.custom.typeGauge"),
|
||||
path: "/",
|
||||
closable: false,
|
||||
},
|
||||
],
|
||||
activeTab: "dashboard",
|
||||
addTab: (tab) =>
|
||||
set((state) => {
|
||||
const exists = state.tabs.find((t) => t.id === tab.id);
|
||||
@@ -140,7 +201,7 @@ export const useTabStore = create<TabState>((set) => ({
|
||||
// 通知状态
|
||||
interface Notification {
|
||||
id: string;
|
||||
type: 'info' | 'success' | 'warning' | 'error';
|
||||
type: "info" | "success" | "warning" | "error";
|
||||
title: string;
|
||||
message: string;
|
||||
timestamp: number;
|
||||
@@ -150,7 +211,9 @@ interface Notification {
|
||||
interface NotificationState {
|
||||
notifications: Notification[];
|
||||
unreadCount: number;
|
||||
addNotification: (notification: Omit<Notification, 'id' | 'timestamp' | 'read'>) => void;
|
||||
addNotification: (
|
||||
notification: Omit<Notification, "id" | "timestamp" | "read">,
|
||||
) => void;
|
||||
markAsRead: (id: string) => void;
|
||||
markAllAsRead: () => void;
|
||||
removeNotification: (id: string) => void;
|
||||
@@ -178,7 +241,7 @@ export const useNotificationStore = create<NotificationState>((set) => ({
|
||||
if (notification && !notification.read) {
|
||||
return {
|
||||
notifications: state.notifications.map((n) =>
|
||||
n.id === id ? { ...n, read: true } : n
|
||||
n.id === id ? { ...n, read: true } : n,
|
||||
),
|
||||
unreadCount: Math.max(0, state.unreadCount - 1),
|
||||
};
|
||||
|
||||
Reference in new issue
Block a user