/** * 인증 상태 관리 composable */ interface User { employeeId: number employeeName: string employeeEmail: string employeePosition: string | null roles?: string[] // 권한 코드 배열 추가 } interface MenuItem { menuId: number menuCode: string menuName: string menuPath: string | null menuIcon: string | null parentMenuId: number | null sortOrder: number children: MenuItem[] } // 전역 상태 const currentUser = ref(null) const userMenus = ref([]) const isLoading = ref(false) export function useAuth() { /** * 현재 로그인 사용자 조회 */ async function fetchCurrentUser(): Promise { try { isLoading.value = true const response = await $fetch<{ user: User | null }>('/api/auth/current-user') currentUser.value = response.user // 로그인된 경우 메뉴 정보도 가져오기 if (response.user) { await fetchUserMenus() } else { userMenus.value = [] } return response.user } catch (error) { currentUser.value = null userMenus.value = [] return null } finally { isLoading.value = false } } /** * 사용자 메뉴 조회 */ async function fetchUserMenus(): Promise { try { const response = await $fetch<{ menus: MenuItem[] }>('/api/auth/menu') userMenus.value = response.menus } catch (error) { console.error('메뉴 조회 실패:', error) userMenus.value = [] } } /** * 이메일+이름으로 로그인 */ async function login(email: string, name: string): Promise { const response = await $fetch<{ user: User }>('/api/auth/login', { method: 'POST', body: { email, name } }) currentUser.value = response.user await fetchUserMenus() return response.user } /** * 기존 사용자 선택 로그인 */ async function selectUser(employeeId: number): Promise { const response = await $fetch<{ user: User }>('/api/auth/select-user', { method: 'POST', body: { employeeId } }) currentUser.value = response.user await fetchUserMenus() return response.user } /** * 최근 로그인 사용자 목록 */ async function getRecentUsers(): Promise { const response = await $fetch<{ users: User[] }>('/api/auth/recent-users') return response.users } /** * 로그아웃 */ async function logout(): Promise { await $fetch('/api/auth/logout', { method: 'POST' }) currentUser.value = null userMenus.value = [] } /** * 로그인 여부 확인 */ const isLoggedIn = computed(() => currentUser.value !== null) /** * 특정 권한 보유 여부 확인 */ function hasRole(roleCode: string): boolean { return currentUser.value?.roles?.includes(roleCode) ?? false } /** * 특정 메뉴 접근 가능 여부 확인 */ function hasMenuAccess(menuCode: string): boolean { const findMenu = (menus: MenuItem[]): boolean => { for (const menu of menus) { if (menu.menuCode === menuCode) return true if (menu.children && findMenu(menu.children)) return true } return false } return findMenu(userMenus.value) } /** * 특정 경로 접근 가능 여부 확인 */ function hasPathAccess(path: string): boolean { const findPath = (menus: MenuItem[]): boolean => { for (const menu of menus) { if (menu.menuPath && path.startsWith(menu.menuPath)) return true if (menu.children && findPath(menu.children)) return true } return false } return findPath(userMenus.value) } /** * 관리자 여부 (ROLE_ADMIN) */ const isAdmin = computed(() => hasRole('ROLE_ADMIN')) /** * 매니저 이상 여부 (ROLE_MANAGER 또는 ROLE_ADMIN) */ const isManager = computed(() => hasRole('ROLE_MANAGER') || hasRole('ROLE_ADMIN')) return { currentUser: readonly(currentUser), userMenus: readonly(userMenus), isLoading: readonly(isLoading), isLoggedIn, isAdmin, isManager, fetchCurrentUser, fetchUserMenus, login, selectUser, getRecentUsers, logout, hasRole, hasMenuAccess, hasPathAccess } }