- {t('themeCard.autoHint', {
- start: String(DAY_START_HOUR).padStart(2, '0'),
- end: String(DAY_END_HOUR).padStart(2, '0'),
- })}
-
- )}
)
})
diff --git a/frontend/src/pages/settings/index.tsx b/frontend/src/pages/settings/index.tsx
index 29150f0..ebfbc8c 100644
--- a/frontend/src/pages/settings/index.tsx
+++ b/frontend/src/pages/settings/index.tsx
@@ -12,6 +12,7 @@ import { toast } from 'sonner'
import { PageContainer } from '@/components/PageContainer'
import { ThemeSection } from './components/ThemeSection'
import { RetentionSection } from './components/RetentionSection'
+import { LicenseSection } from './components/LicenseSection'
import { LanguageSection } from '@/i18n/LanguageSection'
import { Palette } from 'lucide-react'
@@ -69,6 +70,7 @@ const SettingsPage = memo(function SettingsPage() {
return (
+
{/* 不再有内层 tab:LDAP / 镜像源 已拆成独立路由,
由左侧「系统设置」分组的顶层 tab 切换(单层 tab 更好理解)。 */}
diff --git a/frontend/src/router/routes.tsx b/frontend/src/router/routes.tsx
index c767f67..7c5a9ee 100644
--- a/frontend/src/router/routes.tsx
+++ b/frontend/src/router/routes.tsx
@@ -71,14 +71,14 @@ export const routes: AppRoute[] = [
// ── 日志查询 / 日志分析:高频入口,保持独立菜单项(不折叠)──
{ path: '/logs', component: LogsPage, auth: true, meta: { title: 'menu.logs', icon: ScrollText, order: 5 } },
- { path: '/analysis', component: AnalysisPage, auth: true, meta: { title: 'menu.analysis', icon: BarChart3, order: 6, adminOnly: true } },
+ { path: '/analysis', component: AnalysisPage, auth: true, meta: { title: 'menu.analysis', icon: BarChart3, order: 6, adminOnly: true, proOnly: true } },
// 智能运维:AI 日志分析。紧跟日志分析,便于"先看统计、再问 AI"的动线
- { path: '/aiops', component: AiopsPage, auth: true, meta: { title: 'menu.aiops', icon: Sparkles, order: 6, adminOnly: true } },
+ { path: '/aiops', component: AiopsPage, auth: true, meta: { title: 'menu.aiops', icon: Sparkles, order: 6, adminOnly: true, proOnly: true } },
// ── 告警:独立入口(要盯的,不能被折叠) ──
// 告警仅管理员:普通用户按「查询授权」只看指定的日志(菜单只剩日志查询)。
// 告警规则涉及阈值/通知通道等平台级配置,不属于日志查询者的职责。
- { path: '/alerts', component: AlertsPage, auth: true, meta: { title: 'menu.alerts', icon: BellRing, order: 7, adminOnly: true } },
+ { path: '/alerts', component: AlertsPage, auth: true, meta: { title: 'menu.alerts', icon: BellRing, order: 7, adminOnly: true, proOnly: true } },
// ── 系统管理(用户 / 审计 / 设置):低频管理动作 ──
{
@@ -90,7 +90,7 @@ export const routes: AppRoute[] = [
groupKey: 'system',
},
},
- { path: '/audit', component: AuditPage, auth: true, meta: { title: 'menu.audit', icon: History, order: 10, adminOnly: true, groupKey: 'system' } },
+ { path: '/audit', component: AuditPage, auth: true, meta: { title: 'menu.audit', icon: History, order: 10, adminOnly: true, groupKey: 'system', proOnly: true } },
{ 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 最小 = 排在第一个)
@@ -136,6 +136,7 @@ export const menuItems: MenuItem[] = (() => {
icon: group.icon ?? route.meta.icon,
label: group.label,
adminOnly: route.meta.adminOnly,
+ proOnly: route.meta.proOnly,
groupKey: group.key,
});
continue;
@@ -145,6 +146,7 @@ export const menuItems: MenuItem[] = (() => {
icon: route.meta.icon,
label: route.meta.title,
adminOnly: route.meta.adminOnly,
+ proOnly: route.meta.proOnly,
});
}
return items;
diff --git a/frontend/src/types/router.ts b/frontend/src/types/router.ts
index ab405e0..ba90dd3 100644
--- a/frontend/src/types/router.ts
+++ b/frontend/src/types/router.ts
@@ -13,7 +13,9 @@ export interface RouteMeta {
/** 不出现在菜单中(登录页、404 等) */
hideInMenu?: boolean;
/** 仅管理员可见/可访问(菜单过滤 + 页面内守卫,后端 AdminAuth 兜底) */
- adminOnly?: boolean;
+ adminOnly?: boolean
+ /** Pro 授权功能:免费版菜单带锁标,页面渲染升级引导 */
+ proOnly?: boolean;
/**
* 菜单分组:同组的多个页面在侧边栏只占【一个】入口,
* 页面内用顶部 tab 切换(避免 13 个菜单把侧栏塞满)。
@@ -44,7 +46,9 @@ export interface MenuItem {
icon?: LucideIcon;
label: string;
/** 仅管理员可见(Layout 按 getUser().role 过滤) */
- adminOnly?: boolean;
+ adminOnly?: boolean
+ /** Pro 功能:免费版菜单显示锁标(仍可进入看升级引导) */
+ proOnly?: boolean
/**
* 若该项是分组的代表入口,记录分组标识。
* 侧栏高亮据此判断:当前路由属于该分组时整项高亮,