import { createContext, useContext, useState, useCallback, useMemo } from 'react'; import { menuItems, currentUser as defaultUser } from '@/lib/mock'; export type UserRole = 'admin' | 'dba' | 'developer' | 'guest'; export interface AuthUser { id: number; username: string; email: string; role: UserRole; roleName: string; avatar: string; } interface AuthContextType { user: AuthUser; isLoggedIn: boolean; login: (username: string, password: string) => Promise; logout: () => void; switchRole: (role: UserRole) => void; hasPermission: (menuId: string) => boolean; visibleMenuItems: typeof menuItems; isAdmin: boolean; isDBA: boolean; isDeveloper: boolean; isGuest: boolean; } const roleNameMap: Record = { admin: '超级管理员', dba: '数据库管理员', developer: '开发人员', guest: '访客', }; const routePermissionMap: Record = { dashboard: ['admin', 'dba', 'developer', 'guest'], mysql: ['admin', 'dba'], postgres: ['admin', 'dba'], redis: ['admin', 'dba'], mongo: ['admin', 'dba'], clickhouse: ['admin', 'dba'], tickets: ['admin', 'dba', 'developer'], queries: ['admin', 'dba', 'developer', 'guest'], roles: ['admin'], users: ['admin'], 'data-permission': ['admin', 'dba'], 'audit-rules': ['admin', 'dba'], workflow: ['admin', 'dba'], 'auto-task': ['admin'], announcement: ['admin'], 'config-platform': ['admin'], notifications: ['admin'], }; // 页面内操作权限 export const actionPermissionMap: Record = { 'ticket.create': ['admin', 'dba', 'developer'], 'ticket.approve': ['admin', 'dba'], 'ticket.execute': ['admin', 'dba'], 'ticket.rollback': ['admin', 'dba'], 'ticket.delete': ['admin'], 'query.create': ['admin', 'dba', 'developer'], 'query.export': ['admin', 'dba', 'developer'], 'instance.add': ['admin'], 'instance.edit': ['admin', 'dba'], 'instance.delete': ['admin'], 'user.manage': ['admin'], 'role.manage': ['admin'], 'rule.manage': ['admin', 'dba'], 'workflow.manage': ['admin', 'dba'], 'config.manage': ['admin'], 'announcement.manage': ['admin'], 'auto-task.manage': ['admin'], }; const AuthContext = createContext(null); export function AuthProvider({ children }: { children: React.ReactNode }) { const [user, setUser] = useState({ id: defaultUser.id, username: defaultUser.username, email: defaultUser.email, role: defaultUser.role, roleName: defaultUser.roleName, avatar: defaultUser.avatar, }); const [isLoggedIn, setIsLoggedIn] = useState(true); const login = useCallback(async (username: string, _password: string): Promise => { await new Promise(r => setTimeout(r, 800)); setIsLoggedIn(true); setUser({ id: 1, username, email: `${username}@company.com`, role: username === 'admin' ? 'admin' : username === 'dba' ? 'dba' : 'developer', roleName: username === 'admin' ? '超级管理员' : username === 'dba' ? '数据库管理员' : '开发人员', avatar: username.charAt(0).toUpperCase(), }); return true; }, []); const logout = useCallback(() => { setIsLoggedIn(false); }, []); const switchRole = useCallback((role: UserRole) => { setUser(prev => ({ ...prev, role, roleName: roleNameMap[role], username: role === 'admin' ? 'admin' : role === 'dba' ? 'zhangsan' : role === 'developer' ? 'wangwu' : 'visitor', email: `${role}@company.com`, avatar: role.charAt(0).toUpperCase(), })); }, []); const hasPermission = useCallback((menuId: string): boolean => { const allowedRoles = routePermissionMap[menuId]; if (!allowedRoles) return false; return allowedRoles.includes(user.role); }, [user.role]); const visibleMenuItems = useMemo(() => { return menuItems.filter(item => item.roles.includes(user.role)); }, [user.role]); const value = useMemo(() => ({ user, isLoggedIn, login, logout, switchRole, hasPermission, visibleMenuItems, isAdmin: user.role === 'admin', isDBA: user.role === 'dba', isDeveloper: user.role === 'developer', isGuest: user.role === 'guest', }), [user, isLoggedIn, login, logout, switchRole, hasPermission, visibleMenuItems]); return {children}; } export function useAuth(): AuthContextType { const ctx = useContext(AuthContext); if (!ctx) throw new Error('useAuth must be used within AuthProvider'); return ctx; } export function useActionPermission(action: string): boolean { const { user } = useAuth(); const allowedRoles = actionPermissionMap[action]; if (!allowedRoles) return false; return allowedRoles.includes(user.role); }