From d13f5b8fa1ccd9aadc139333f98497f9916e1c8b Mon Sep 17 00:00:00 2001 From: attacker Date: Mon, 15 Jun 2026 16:06:04 +0800 Subject: [PATCH] =?UTF-8?q?refactor:=20=E6=B8=85=E7=90=86=E7=AB=99?= =?UTF-8?q?=E5=86=85=E5=AF=BC=E8=88=AA=E6=AD=BB=E4=BB=A3=E7=A0=81=20(?= =?UTF-8?q?=E5=88=A0=E9=99=A4=E5=AD=A4=E7=AB=8BNavigationPage=E7=BB=84?= =?UTF-8?q?=E4=BB=B6+navigationApi+=E5=AF=BC=E8=88=AAmock=E6=95=B0?= =?UTF-8?q?=E6=8D=AE)?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit - 删除 frontend/src/components/navigation/NavigationPage.tsx (359行, 菜单/路由移除后遗留的孤立组件) - 移除 services/api.ts 中 navigationApi (唯一消费者已删除) - 移除 mocks/modules/misc.ts 中 navigationGroups/navigationLinks 死数据 (252行) - 清理 mocks/data.ts barrel 中导航 re-export - 修正 cloud.ts 误导性注释 (站内导航→云平台/账号/区域/域名数据) - 后端 navigation.go 保留不动 (菜单已移除但后端代码保留) - tsc --noEmit 零错误 + npm run build 通过 --- .../components/navigation/NavigationPage.tsx | 359 ------------------ frontend/src/mocks/data.ts | 4 +- frontend/src/mocks/modules/cloud.ts | 2 +- frontend/src/mocks/modules/misc.ts | 252 ------------ frontend/src/services/api.ts | 31 -- 5 files changed, 2 insertions(+), 646 deletions(-) delete mode 100644 frontend/src/components/navigation/NavigationPage.tsx diff --git a/frontend/src/components/navigation/NavigationPage.tsx b/frontend/src/components/navigation/NavigationPage.tsx deleted file mode 100644 index 2b23cd4..0000000 --- a/frontend/src/components/navigation/NavigationPage.tsx +++ /dev/null @@ -1,359 +0,0 @@ -import { useState, useEffect } from 'react'; -import { Card, CardContent, CardHeader, CardTitle } from '@/components/ui/card'; -import { Input } from '@/components/ui/input'; -import { Button } from '@/components/ui/button'; -import { Badge } from '@/components/ui/badge'; -import { Loader2 } from 'lucide-react'; -import { - Search, - ExternalLink, - Plus, - Edit2, - Trash2, - Folder, - LayoutGrid, - List, - Star, - Settings -} from 'lucide-react'; -import { navigationApi } from '@/services/api'; - -interface NavLink { - id: string; - title: string; - url: string; - icon?: string; - description?: string; - group_id: string; - is_favorite?: boolean; - tags?: string[]; -} - -interface NavGroup { - id: string; - name: string; - icon?: string; - description?: string; - sort_order?: number; -} - -export function NavigationPage() { - const [searchQuery, setSearchQuery] = useState(''); - const [viewMode, setViewMode] = useState<'grid' | 'list'>('grid'); - const [selectedGroup, setSelectedGroup] = useState('all'); - const [showFavoritesOnly, setShowFavoritesOnly] = useState(false); - const [groups, setGroups] = useState([]); - const [links, setLinks] = useState([]); - const [loading, setLoading] = useState(true); - - const loadData = async () => { - try { - setLoading(true); - const [groupsData, linksData] = await Promise.all([ - navigationApi.getGroups(), - navigationApi.getLinks(), - ]); - setGroups(groupsData || []); - setLinks(linksData || []); - } catch (error) { - console.error('Failed to load navigation data:', error); - } finally { - setLoading(false); - } - }; - - useEffect(() => { - loadData(); - }, []); - - const handleToggleFavorite = async (id: string) => { - try { - await navigationApi.toggleFavorite(id); - loadData(); - } catch (error) { - console.error('Failed to toggle favorite:', error); - } - }; - - const handleDeleteLink = async (id: string) => { - try { - await navigationApi.deleteLink(id); - loadData(); - } catch (error) { - console.error('Failed to delete link:', error); - } - }; - - const filteredLinks = links.filter(link => { - const matchesSearch = (link.title || '').toLowerCase().includes(searchQuery.toLowerCase()) || - (link.description || '').toLowerCase().includes(searchQuery.toLowerCase()) || - (link.tags || []).some(tag => tag.toLowerCase().includes(searchQuery.toLowerCase())); - const matchesGroup = selectedGroup === 'all' || link.group_id === selectedGroup; - const matchesFavorite = !showFavoritesOnly || link.is_favorite; - return matchesSearch && matchesGroup && matchesFavorite; - }); - - const groupedLinks = groups.map(group => ({ - ...group, - links: filteredLinks.filter(link => link.group_id === group.id) - })).filter(group => group.links.length > 0); - - const stats = { - totalLinks: links.length, - totalGroups: groups.length, - favorites: links.filter(l => l.is_favorite).length, - }; - - return ( -
- {/* Header */} -
-
-

站内导航

-

管理内部系统和常用链接

-
-
- - -
-
- - {/* Stats */} -
- - -
-
-

链接总数

-

{stats.totalLinks}

-
-
- -
-
-
-
- - -
-
-

分组数

-

{stats.totalGroups}

-
-
- -
-
-
-
- - -
-
-

收藏

-

{stats.favorites}

-
-
- -
-
-
-
-
- - {/* Filters */} -
-
- - setSearchQuery(e.target.value)} - className="pl-10 bg-slate-800 border-slate-700 text-slate-100" - /> -
- - -
- - -
-
- - {loading ? ( -
- -
- ) : null} - - {/* Navigation Content */} -
- {selectedGroup === 'all' && !searchQuery && !showFavoritesOnly ? ( - // Grouped view - groupedLinks.map(group => ( -
-
- -

{group.name}

- - {group.links.length} - -
- {viewMode === 'grid' ? ( -
- {group.links.map(link => ( - - ))} -
- ) : ( -
- {group.links.map(link => ( - - ))} -
- )} -
- )) - ) : ( - // Flat view - viewMode === 'grid' ? ( -
- {filteredLinks.map(link => ( - - ))} -
- ) : ( -
- {filteredLinks.map(link => ( - - ))} -
- ) - )} -
-
- ); -} - -function NavLinkCard({ link, onToggleFavorite, onDelete }: { link: NavLink; onToggleFavorite: (id: string) => void; onDelete: (id: string) => void }) { - return ( - - -
-
-
- {(link.title || '').slice(0, 2)} -
-
-

{link.title}

-

{link.description}

-
-
-
- - -
-
-
-
- {(link.tags || []).map(tag => ( - - {tag} - - ))} -
- -
-
-
- ); -} - -function NavLinkRow({ link, onToggleFavorite, onDelete }: { link: NavLink; onToggleFavorite: (id: string) => void; onDelete: (id: string) => void }) { - return ( - - -
-
-
- {(link.title || '').slice(0, 2)} -
-
-

{link.title}

-

{link.description}

-
-
-
-
- {(link.tags || []).map(tag => ( - - {tag} - - ))} -
-
- - - -
-
-
-
-
- ); -} diff --git a/frontend/src/mocks/data.ts b/frontend/src/mocks/data.ts index f4b7df6..74b1a57 100644 --- a/frontend/src/mocks/data.ts +++ b/frontend/src/mocks/data.ts @@ -12,7 +12,7 @@ export * from './modules/monitor'; export * from './modules/misc'; // Aggregate mockData object (cross-module references) -import { sqlAuditRecords, sqlAuditRules, resourceModels, modelInstances, navigationGroups, navigationLinks } from './modules/misc'; +import { sqlAuditRecords, sqlAuditRules, resourceModels, modelInstances } from './modules/misc'; import { ansiblePlaybooks, ansibleJobs, ansibleInventories, cronJobsList, cronJobExecutions, scripts } from './modules/automation'; import { logMonitorEntries, logSources, traces, serviceMetrics, traceSpans, grafanaDashboards, datasources } from './modules/monitor'; import { alertCenterAlerts, alertCenterRules, notificationChannels, recentAlerts, alertEvents } from './modules/alerts'; @@ -75,6 +75,4 @@ export const mockData = { approvalFlows, approvalInstances, alertEvents, - navigationGroups, - navigationLinks, }; diff --git a/frontend/src/mocks/modules/cloud.ts b/frontend/src/mocks/modules/cloud.ts index 83f108f..9fc0a8d 100644 --- a/frontend/src/mocks/modules/cloud.ts +++ b/frontend/src/mocks/modules/cloud.ts @@ -279,7 +279,7 @@ export const platforms = [ }, ]; -// ==================== 站内导航数据 ==================== +// ==================== 云平台/账号/区域/域名数据 ==================== export const cloudProvidersList = [ { id: 'aliyun', name: '阿里云', icon: 'aliyun', regions: ['cn-beijing', 'cn-shanghai'] }, diff --git a/frontend/src/mocks/modules/misc.ts b/frontend/src/mocks/modules/misc.ts index e9daa5d..0ae30f4 100644 --- a/frontend/src/mocks/modules/misc.ts +++ b/frontend/src/mocks/modules/misc.ts @@ -132,258 +132,6 @@ export const modelInstances: ModelInstance[] = [ }, ]; -// ==================== 机房机柜数据 ==================== - -export const navigationGroups = [ - { - id: 'group-001', - name: '运维工具', - description: '日常运维常用工具', - linkCount: 5, - }, - { - id: 'group-002', - name: '监控告警', - description: '监控系统和告警平台', - linkCount: 4, - }, - { - id: 'group-003', - name: '开发工具', - description: '开发相关工具和平台', - linkCount: 6, - }, - { - id: 'group-004', - name: '文档知识库', - description: '技术文档和知识库', - linkCount: 3, - }, - { - id: 'group-005', - name: '云平台', - description: '各大云厂商控制台', - linkCount: 5, - }, -]; - -export const navigationLinks = [ - // 运维工具 - { - id: 'link-001', - name: 'Jenkins', - url: 'https://jenkins.company.com', - description: 'CI/CD流水线平台', - groupId: 'group-001', - isFavorite: true, - tags: ['CI/CD', 'DevOps'], - }, - { - id: 'link-002', - name: 'GitLab', - url: 'https://gitlab.company.com', - description: '代码仓库管理平台', - groupId: 'group-001', - isFavorite: true, - tags: ['Git', '代码仓库'], - }, - { - id: 'link-003', - name: 'Harbor', - url: 'https://harbor.company.com', - description: 'Docker镜像仓库', - groupId: 'group-001', - isFavorite: false, - tags: ['Docker', '镜像'], - }, - { - id: 'link-004', - name: 'Nexus', - url: 'https://nexus.company.com', - description: 'Maven/npm仓库', - groupId: 'group-001', - isFavorite: false, - tags: ['Maven', 'npm'], - }, - { - id: 'link-005', - name: 'Confluence', - url: 'https://confluence.company.com', - description: '团队协作文档平台', - groupId: 'group-001', - isFavorite: true, - tags: ['文档', 'Wiki'], - }, - // 监控告警 - { - id: 'link-006', - name: 'Prometheus', - url: 'https://prometheus.company.com', - description: '监控指标采集和查询', - groupId: 'group-002', - isFavorite: true, - tags: ['监控', '指标'], - }, - { - id: 'link-007', - name: 'Grafana', - url: 'https://grafana.company.com', - description: '可视化监控大盘', - groupId: 'group-002', - isFavorite: true, - tags: ['监控', '可视化'], - }, - { - id: 'link-008', - name: 'AlertManager', - url: 'https://alertmanager.company.com', - description: '告警管理和通知', - groupId: 'group-002', - isFavorite: false, - tags: ['告警', '通知'], - }, - { - id: 'link-009', - name: 'ELK Stack', - url: 'https://kibana.company.com', - description: '日志收集和分析平台', - groupId: 'group-002', - isFavorite: false, - tags: ['日志', 'ELK'], - }, - // 开发工具 - { - id: 'link-010', - name: 'Jira', - url: 'https://jira.company.com', - description: '项目管理和任务跟踪', - groupId: 'group-003', - isFavorite: true, - tags: ['项目管理', '敏捷'], - }, - { - id: 'link-011', - name: 'SonarQube', - url: 'https://sonarqube.company.com', - description: '代码质量分析平台', - groupId: 'group-003', - isFavorite: false, - tags: ['代码质量', '扫描'], - }, - { - id: 'link-012', - name: 'Nexus', - url: 'https://nexus.company.com', - description: '制品仓库管理', - groupId: 'group-003', - isFavorite: false, - tags: ['制品', '仓库'], - }, - { - id: 'link-013', - name: 'Swagger UI', - url: 'https://swagger.company.com', - description: 'API文档和测试', - groupId: 'group-003', - isFavorite: false, - tags: ['API', '文档'], - }, - { - id: 'link-014', - name: 'YApi', - url: 'https://yapi.company.com', - description: 'API接口管理平台', - groupId: 'group-003', - isFavorite: false, - tags: ['API', '接口管理'], - }, - { - id: 'link-015', - name: 'Postman', - url: 'https://web.postman.co', - description: 'API测试工具', - groupId: 'group-003', - isFavorite: true, - tags: ['API', '测试'], - }, - // 文档知识库 - { - id: 'link-016', - name: 'Confluence', - url: 'https://confluence.company.com', - description: '团队知识库', - groupId: 'group-004', - isFavorite: true, - tags: ['文档', '知识库'], - }, - { - id: 'link-017', - name: 'Notion', - url: 'https://notion.so', - description: '个人和团队笔记', - groupId: 'group-004', - isFavorite: true, - tags: ['笔记', '文档'], - }, - { - id: 'link-018', - name: '语雀', - url: 'https://yuque.com', - description: '阿里知识库平台', - groupId: 'group-004', - isFavorite: false, - tags: ['文档', '知识库'], - }, - // 云平台 - { - id: 'link-019', - name: '阿里云控制台', - url: 'https://ecs.console.aliyun.com', - description: '阿里云ECS管理', - groupId: 'group-005', - isFavorite: true, - tags: ['阿里云', 'ECS'], - }, - { - id: 'link-020', - name: '腾讯云控制台', - url: 'https://console.cloud.tencent.com', - description: '腾讯云CVM管理', - groupId: 'group-005', - isFavorite: false, - tags: ['腾讯云', 'CVM'], - }, - { - id: 'link-021', - name: 'AWS控制台', - url: 'https://console.aws.amazon.com', - description: 'AWS EC2管理', - groupId: 'group-005', - isFavorite: true, - tags: ['AWS', 'EC2'], - }, - { - id: 'link-022', - name: '华为云控制台', - url: 'https://console.huaweicloud.com', - description: '华为云ECS管理', - groupId: 'group-005', - isFavorite: false, - tags: ['华为云', 'ECS'], - }, - { - id: 'link-023', - name: 'Azure门户', - url: 'https://portal.azure.com', - description: 'Azure虚拟机管理', - groupId: 'group-005', - isFavorite: false, - tags: ['Azure', 'VM'], - }, -]; - - - // ============ SQL审计数据 ============ export const sqlAuditRecords = [ { diff --git a/frontend/src/services/api.ts b/frontend/src/services/api.ts index 345d5c8..6cfdbd2 100644 --- a/frontend/src/services/api.ts +++ b/frontend/src/services/api.ts @@ -376,37 +376,6 @@ export const approvalApi = { }, }; -// ==================== 导航管理 API ==================== -export const navigationApi = { - getGroups: async () => { - return http.get('/navigations/groups'); - }, - createGroup: async (data: any) => { - return http.post('/navigations/groups', data); - }, - updateGroup: async (id: number | string, data: any) => { - return http.put(`/navigations/groups/${id}`, data); - }, - deleteGroup: async (id: number | string) => { - return http.delete(`/navigations/groups/${id}`); - }, - getLinks: async () => { - return http.get('/navigations/links'); - }, - createLink: async (data: any) => { - return http.post('/navigations/links', data); - }, - updateLink: async (id: number | string, data: any) => { - return http.put(`/navigations/links/${id}`, data); - }, - deleteLink: async (id: number | string) => { - return http.delete(`/navigations/links/${id}`); - }, - toggleFavorite: async (id: number | string) => { - return http.post(`/navigations/links/${id}/favorite`); - }, -}; - // ==================== 云管理 API ==================== export const cloudApi = { getAccounts: async () => {