'use client' import { useEffect, useState } from 'react' import { User, LogOut, KeyRound } from 'lucide-react' import { DevPanel } from '@/app/(main)/dev/panel' import { ChangePasswordDialog } from '@/components/layout/change-password-dialog' import { UserProfileDialog } from '@/components/layout/user-profile-dialog' import { Button } from '@/components/ui/button' import { DropdownMenu, DropdownMenuContent, DropdownMenuItem, DropdownMenuLabel, DropdownMenuSeparator, DropdownMenuTrigger, } from '@/components/ui/dropdown-menu' import { Separator } from '@/components/ui/separator' import { SidebarTrigger } from '@/components/ui/sidebar' import { signOut } from 'next-auth/react' import { useRouter, usePathname } from 'next/navigation' import { useTheme } from 'next-themes' import { ThemeToggleButton, useThemeTransition } from '@/components/common/theme-toggle-button' import { getMenuTitle } from '@/constants/menu' import type { User as AppUser } from '@/types/user' import { useUserStore } from '@/lib/stores/userStore' import { toast } from 'sonner' import { trpc } from '@/lib/trpc' import { AdvancedSelect, SelectContent, SelectedName, SelectInput, SelectItemList, SelectPopover, SelectTrigger } from '@/components/common/advanced-select' import type { Dept } from '@prisma/client' interface HeaderProps { user?: AppUser } export function Header({ user }: HeaderProps) { const router = useRouter() const pathname = usePathname() const { theme, setTheme } = useTheme() const { startTransition } = useThemeTransition() const [isChangePasswordOpen, setIsChangePasswordOpen] = useState(false) const [isUserProfileOpen, setIsUserProfileOpen] = useState(false) const pageTitle = getMenuTitle(pathname, 2) // 只匹配到第二级菜单 // 从zustand store获取当前管理的院系信息 const { setCurrentManagedDept } = useUserStore() // 获取可管理的院系列表(包含当前管理的院系信息) const { data: managedDeptsData } = trpc.users.getManagedDepts.useQuery() // 本地状态管理 const [currentManagedDeptCode, setCurrentManagedDeptCode] = useState(null) const [managedDepts, setManagedDepts] = useState>([]) // 初始化数据 useEffect(() => { if (managedDeptsData && managedDeptsData.currentDept !== undefined) { setCurrentManagedDeptCode(managedDeptsData.currentDept) setManagedDepts(managedDeptsData.depts) // 更新store中的当前管理院系信息 const deptInfo = managedDeptsData.depts.find(dept => dept.code === managedDeptsData.currentDept) || null setCurrentManagedDept(deptInfo) } }, [managedDeptsData, setCurrentManagedDept]) // 切换管理院系 const switchManagedDeptMutation = trpc.users.switchManagedDept.useMutation({ onSuccess: (data) => { toast.success('切换管理院系成功') // 更新本地状态 setCurrentManagedDeptCode(data.deptCode) // 更新store中的当前管理院系信息 setCurrentManagedDept(managedDepts.find(dept => dept.code === data.deptCode) || null) }, onError: (error) => { toast.error(error.message || '切换管理院系失败') }, }) // 处理院系切换 const handleDeptChange = (deptCode: string | null) => { switchManagedDeptMutation.mutate({ deptCode }) } const handleThemeToggle = () => { startTransition(() => { setTheme(theme === 'dark' ? 'light' : 'dark') }) } const handleLogout = async () => { await signOut({ redirect: false }) router.push('/login') } // 如果没有用户信息,不显示Header(应该被中间件重定向) if (!user) { return null } return (

{pageTitle}

{/* 主题切换按钮 */} {/* 开发者工具按钮 - 仅开发环境 */} {process.env.NODE_ENV === 'development' && user.isSuperAdmin && } {/* 用户菜单 */} 我的账户 setIsUserProfileOpen(true)}> 个人资料 setIsChangePasswordOpen(true)}> 修改密码 角色 {user.isSuperAdmin ? '超级管理员' : (Array.isArray(user.roles) ? user.roles.join('、') : user.roles)} {/* 管理院系 - 根据可管理院系数量决定显示方式 */} {managedDepts.length > 0 && ( <> 管理院系 {managedDepts.length === 1 ? ( // 只有一个可管理院系时,直接显示院系名称 {managedDepts[0].fullName} ) : ( // 多个可管理院系时,显示下拉选择器
({ id: dept.code, name: dept.fullName, shortName: dept.name }))} disabled={switchManagedDeptMutation.isPending} filterFunction={(option, searchValue) => { const search = searchValue.toLowerCase() return option.id.includes(search) || option.name.toLowerCase().includes(search) || (option.shortName && option.shortName.toLowerCase().includes(search)) }} > {managedDepts.length > 5 && }
)} )} 退出登录
{/* 修改密码对话框 */} setIsChangePasswordOpen(false)} /> {/* 用户资料对话框 */} setIsUserProfileOpen(false)} />
) }