feat: 修复仪表盘数据管线 — 补充应用发布种子数据 + 修复limit参数解析 + LDAP认证集成 + User类型完善

后端改进:
- 修复 dashboard/recent-alerts 的 limit 参数解析 (原代码错误地将数字解析为日期)
- 为 dashboard/recent-releases 添加 limit 参数解析支持
- 新增 generateAppReleases 种子数据生成函数 (10条应用发布记录)
- 修复 AlertEvent 的 rule_name/rule_id/severity 数据一致性
- 添加 go-ldap/ldap/v3 依赖并集成 LDAP 认证处理器
- 添加 seed.go 自动种子数据初始化 (admin用户+LDAP配置)
- User model 添加 AuthSource/LDAPConfig 字段

前端改进:
- 修复 User 类型定义以匹配后端 API (real_name/is_admin/auth_source等)
- 修复 Header.tsx 的 real_name 属性引用导致 TypeScript 编译错误
- 统一 API 服务层、暗色主题样式、组件联调优化

验证:
- go build ./... 编译通过
- npm run build 构建通过
- 仪表盘发布历史、告警消息等区域数据正常展示
- 健康检查 /health 正常
This commit is contained in:
attacker committed 2026-06-14 02:11:10 +08:00
1 parent 97c4207ff8
commit ff0b268984
39 files changed
+4283 -1878

No files matched your search

+49 -4
View File
@@ -1,7 +1,7 @@
import { useState } from 'react';
import { NavLink } from 'react-router-dom';
import { cn } from '@/lib/utils';
import { useThemeStore, useTabStore, useNotificationStore } from '@/store';
import { useThemeStore, useTabStore, useNotificationStore, useUserStore } from '@/store';
import { Button } from '@/components/ui/button';
import { Input } from '@/components/ui/input';
import { Badge } from '@/components/ui/badge';
@@ -31,15 +31,27 @@ import {
Rocket,
Server,
Cloud,
Palette,
Check,
} from 'lucide-react';
import { formatDistanceToNow } from '@/lib/utils';
import { useTheme, THEME_OPTIONS } from '@/hooks/useTheme';
export function Header() {
const { sidebarCollapsed, toggleSidebar } = useThemeStore();
const { tabs, activeTab, removeTab, setActiveTab } = useTabStore();
const { notifications, unreadCount, markAsRead, markAllAsRead } = useNotificationStore();
const { user, logout } = useUserStore();
const { theme, setTheme } = useTheme();
const [searchValue, setSearchValue] = useState('');
const handleLogout = () => {
logout();
window.location.href = '/login';
};
const displayName = user?.real_name || user?.username || '管理员';
const getNotificationIcon = (type: string) => {
switch (type) {
case 'error':
@@ -101,6 +113,39 @@ export function Header() {
{/* Right: Actions */}
<div className="flex items-center gap-2">
{/* Theme Switcher */}
<DropdownMenu>
<DropdownMenuTrigger asChild>
<Button variant="ghost" size="icon" className="h-8 w-8 text-slate-400 hover:text-slate-100">
<Palette className="h-4 w-4" />
</Button>
</DropdownMenuTrigger>
<DropdownMenuContent align="end" className="w-56 bg-slate-800 border-slate-700">
<DropdownMenuLabel className="text-slate-300">主题切换</DropdownMenuLabel>
<DropdownMenuSeparator className="bg-slate-700" />
{THEME_OPTIONS.map((option) => (
<DropdownMenuItem
key={option.id}
className={cn(
'flex items-center gap-2 cursor-pointer focus:bg-slate-700 focus:text-slate-100',
theme === option.id ? 'text-slate-100' : 'text-slate-300'
)}
onClick={() => setTheme(option.id)}
>
<span
className="w-3 h-3 rounded-full shrink-0 ring-2 ring-slate-900"
style={{ backgroundColor: option.primaryColor }}
/>
<div className="flex-1 min-w-0">
<span className="text-sm font-medium">{option.name}</span>
<span className="block text-xs text-slate-500 truncate">{option.description}</span>
</div>
{theme === option.id && <Check className="h-4 w-4 text-blue-400 shrink-0" />}
</DropdownMenuItem>
))}
</DropdownMenuContent>
</DropdownMenu>
{/* Create New */}
<DropdownMenu>
<DropdownMenuTrigger asChild>
@@ -201,9 +246,9 @@ export function Header() {
<DropdownMenuTrigger asChild>
<Button variant="ghost" className="h-8 gap-2 px-2 text-slate-300 hover:text-slate-100">
<div className="w-6 h-6 rounded-full bg-blue-600 flex items-center justify-center text-white text-xs font-medium">
管
{displayName.charAt(0)}
</div>
<span className="hidden md:inline text-sm">管理员</span>
<span className="hidden md:inline text-sm">{displayName}</span>
</Button>
</DropdownMenuTrigger>
<DropdownMenuContent align="end" className="w-48 bg-slate-800 border-slate-700">
@@ -218,7 +263,7 @@ export function Header() {
账号设置
</DropdownMenuItem>
<DropdownMenuSeparator className="bg-slate-700" />
<DropdownMenuItem className="text-red-400 focus:bg-slate-700 focus:text-red-400">
<DropdownMenuItem className="text-red-400 focus:bg-slate-700 focus:text-red-400" onClick={handleLogout}>
<LogOut className="h-4 w-4 mr-2" />
退出登录
</DropdownMenuItem>