권한, 사용자, 메뉴 등에 대한 기능 업데이트

This commit is contained in:
2026-01-10 16:54:06 +09:00
parent 134a68d9db
commit ef7914d5c6
34 changed files with 2678 additions and 650 deletions

View File

@@ -7,10 +7,23 @@ interface User {
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<User | null>(null)
const userMenus = ref<MenuItem[]>([])
const isLoading = ref(false)
export function useAuth() {
@@ -22,15 +35,37 @@ export function useAuth() {
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<void> {
try {
const response = await $fetch<{ menus: MenuItem[] }>('/api/auth/menu')
userMenus.value = response.menus
} catch (error) {
console.error('메뉴 조회 실패:', error)
userMenus.value = []
}
}
/**
* 이메일+이름으로 로그인
*/
@@ -40,6 +75,7 @@ export function useAuth() {
body: { email, name }
})
currentUser.value = response.user
await fetchUserMenus()
return response.user
}
@@ -52,6 +88,7 @@ export function useAuth() {
body: { employeeId }
})
currentUser.value = response.user
await fetchUserMenus()
return response.user
}
@@ -69,6 +106,7 @@ export function useAuth() {
async function logout(): Promise<void> {
await $fetch('/api/auth/logout', { method: 'POST' })
currentUser.value = null
userMenus.value = []
}
/**
@@ -76,14 +114,66 @@ export function useAuth() {
*/
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
logout,
hasRole,
hasMenuAccess,
hasPathAccess
}
}