fix(logs): 恢复 POST /logs/histogram(直方图 404)+ 系统设置改为侧栏五分页
=== 1. 修复 /analysis 与 /logs 直方图 404(我上一轮 patch 的误伤)===
现象:分析页直接报 "API endpoint not found";日志查询页直方图不显示。
根因:37e2f0f 里一次模糊匹配的 patch 把
logs.POST("/histogram", logsCtrl.Histogram)
改成了
logs.GET("/histogram", logsCtrl.Histogram)
前端 logsApi.histogram 一直用 POST(body 带 sourceId/query/start/end),
于是 POST /logs/histogram 全部 404。访问日志实证:
POST /api/v1/logs/histogram → 404 ×7
这类"方法写错"编译期查不出来,go build / tsc 都是绿的。
修法:同时注册 POST(前端用)与 GET(curl 调试用)。
新增 backend/routers/router_test.go 守门:
TestCriticalRoutes 断言 19 条关键路由的 method+path 组合都存在
TestHistogramAcceptsPost 单独断言 histogram 必须同时有 POST 与 GET
以后再把 POST 写成 GET,测试会直接红。
=== 2. 系统设置放回侧栏,改成 5 个顶层 tab ===
按使用反馈调整:
系统设置(侧栏一个入口)
├ 通用配置 /settings ← tab 起点
├ 用户管理 /users
├ 审计日志 /audit
├ LDAP 接入 /settings/ldap ← 新拆分
└ 默认镜像源 /settings/registry ← 新拆分
为什么拆:原来 /settings 页面内部已有 4 个 tab(通用/告警通知/LDAP/镜像源),
如果侧栏再加一层 tab 就是"两层 tab",点两下才知道自己在哪。现在扁平化成单层。
配套改动:
- 新增 pages/settings/ldap.tsx、registry.tsx(各自只渲染一块内容)
- settings 主页去掉内层 Tabs,只留通用配置(外观/语言/改密码/关于)
- 上一版把设置放到了右上角齿轮,现在移除齿轮入口
- 菜单文案:settings 页标题 系统设置 → 通用配置;新增 LDAP 接入 / 默认镜像源
- 删除设置页副标题「通用配置、告警通知、LDAP 接入与默认镜像源」(用户要求去掉)
- 删除 settings 里已不存在的 tabs.notify 文案
(注意 settings.notify.* 这些 key 仍被告警页的 NotifySection 用着,保留)
=== 3. 告警通知已不在系统设置里 ===
它在上一轮就搬到了「日志告警 → 通知通道」tab,
本次顺带把系统设置里遗留的 tab 文案一并清掉,避免出现"看似有两处配置入口"。
=== 实测 ===
POST /api/v1/logs/histogram → 200(修复前 404)
go test ./... 全绿(含新增的 routers 包)
tsc -b --force 通过
This commit is contained in:
1 parent
8bea331183
commit
6d6e17745c
11 files changed
+150
-54
No files matched your search
@@ -17,6 +17,8 @@ import {
|
||||
BarChart3,
|
||||
History,
|
||||
Boxes,
|
||||
ShieldCheck,
|
||||
Container,
|
||||
} from 'lucide-react';
|
||||
import type { AppRoute, MenuItem, RouteMeta } from '@/types/router';
|
||||
|
||||
@@ -28,6 +30,8 @@ const Storage = lazy(() => import('@/pages/storage'));
|
||||
const Deployments = lazy(() => import('@/pages/deployments'));
|
||||
const Collectors = lazy(() => import('@/pages/collectors'));
|
||||
const SettingsPage = lazy(() => import('@/pages/settings'));
|
||||
const LdapPage = lazy(() => import('@/pages/settings/ldap'));
|
||||
const RegistryPage = lazy(() => import('@/pages/settings/registry'));
|
||||
const NotFound = lazy(() => import('@/pages/not-found'));
|
||||
const WizardPage = lazy(() => import('@/pages/wizard'));
|
||||
const LogsPage = lazy(() => import('@/pages/logs'));
|
||||
@@ -76,14 +80,23 @@ export const routes: AppRoute[] = [
|
||||
{
|
||||
path: '/users', component: UsersPage, auth: true,
|
||||
meta: {
|
||||
title: 'menu.users', icon: UsersRound, order: 8, adminOnly: true,
|
||||
// 系统设置(tab 起点)/ 用户管理 / 审计日志 同属「系统设置」分组,
|
||||
// 侧栏只占一个入口,页面内用 tab 切换。
|
||||
title: 'menu.users', icon: UsersRound, order: 9, adminOnly: true,
|
||||
groupKey: 'system',
|
||||
},
|
||||
},
|
||||
{ path: '/audit', component: AuditPage, auth: true, meta: { title: 'menu.audit', icon: History, order: 10, adminOnly: true, groupKey: 'system' } },
|
||||
{ path: '/settings/ldap', component: LdapPage, auth: true, meta: { title: 'menu.ldap', icon: ShieldCheck, order: 11, adminOnly: true, groupKey: 'system' } },
|
||||
{ path: '/settings/registry', component: RegistryPage, auth: true, meta: { title: 'menu.registry', icon: Container, order: 12, adminOnly: true, groupKey: 'system' } },
|
||||
// 系统设置放回侧栏,并作为「系统设置」分组的 tab 起点(order 最小 = 排在第一个)
|
||||
{
|
||||
path: '/settings', component: SettingsPage, auth: true,
|
||||
meta: {
|
||||
title: 'menu.settings', icon: Settings, order: 8, adminOnly: true,
|
||||
group: { key: 'system', label: 'menu.groups.system', icon: Settings, order: 8 },
|
||||
},
|
||||
},
|
||||
{ path: '/audit', component: AuditPage, auth: true, meta: { title: 'menu.audit', icon: History, order: 13, adminOnly: true, groupKey: 'system' } },
|
||||
// 系统设置从侧栏移到右上角齿轮入口:属于低频平台配置,
|
||||
// 和「用户/审计」这类日常安全管理不是一类东西,混在一个分组里太乱。
|
||||
{ path: '/settings', component: SettingsPage, auth: true, meta: { title: 'menu.settings', icon: Settings, order: 12, adminOnly: true, hideInMenu: true } },
|
||||
{ path: '*', component: NotFound, auth: false, meta: { title: 'menu.notFound', hideInMenu: true } },
|
||||
];
|
||||
|
||||
|
||||
Reference in new issue
Block a user