[리소스 권한 작업중]
This commit is contained in:
@@ -89,10 +89,10 @@ onMounted(async () => {
|
|||||||
await permissionStore.fetchPermissions();
|
await permissionStore.fetchPermissions();
|
||||||
});
|
});
|
||||||
|
|
||||||
// 권한이 있는 메뉴들만 필터링
|
// 권한이 있는 페이지그룹들만 필터링
|
||||||
const availableMenus = computed(() => {
|
const availableMenus = computed(() => {
|
||||||
return permissionStore.permissions.resources.menus.filter(menu => {
|
return permissionStore.permissions.resources.pageGroups.filter(pageGroup => {
|
||||||
return permissionStore.hasMenuPermission(menu.code);
|
return permissionStore.hasPageGroupPermission(pageGroup.code);
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|
||||||
|
|||||||
@@ -10,9 +10,9 @@ export const usePermission = () => {
|
|||||||
hasPagePermission: (page: string) =>
|
hasPagePermission: (page: string) =>
|
||||||
permissionsStore.hasPagePermission(page),
|
permissionsStore.hasPagePermission(page),
|
||||||
|
|
||||||
// 메뉴 권한 체크
|
// 페이지그룹 권한 체크
|
||||||
hasMenuPermission: (menu: string) =>
|
hasPageGroupPermission: (pageGroup: string) =>
|
||||||
permissionsStore.hasMenuPermission(menu),
|
permissionsStore.hasPageGroupPermission(pageGroup),
|
||||||
|
|
||||||
// 컴포넌트 권한 체크
|
// 컴포넌트 권한 체크
|
||||||
hasComponentPermission: (component: string) =>
|
hasComponentPermission: (component: string) =>
|
||||||
@@ -21,16 +21,18 @@ export const usePermission = () => {
|
|||||||
// 여러 권한 중 하나라도 있는지 체크
|
// 여러 권한 중 하나라도 있는지 체크
|
||||||
hasAnyPagePermission: (pages: string[]) =>
|
hasAnyPagePermission: (pages: string[]) =>
|
||||||
permissionsStore.hasAnyPagePermission(pages),
|
permissionsStore.hasAnyPagePermission(pages),
|
||||||
hasAnyMenuPermission: (menus: string[]) =>
|
hasAnyPageGroupPermission: (pageGroups: string[]) =>
|
||||||
permissionsStore.hasAnyMenuPermission(menus),
|
permissionsStore.hasAnyPageGroupPermission(pageGroups),
|
||||||
hasAnyComponentPermission: (components: string[]) =>
|
hasAnyComponentPermission: (components: string[]) =>
|
||||||
permissionsStore.hasAnyComponentPermission(components),
|
permissionsStore.hasAnyComponentPermission(components),
|
||||||
|
|
||||||
// 모든 권한이 있는지 체크
|
// 모든 권한이 있는지 체크
|
||||||
hasAllPagePermissions: (pages: string[]) =>
|
hasAllPagePermissions: (pages: string[]) =>
|
||||||
pages.every(page => permissionsStore.hasPagePermission(page)),
|
pages.every(page => permissionsStore.hasPagePermission(page)),
|
||||||
hasAllMenuPermissions: (menus: string[]) =>
|
hasAllPageGroupPermissions: (pageGroups: string[]) =>
|
||||||
menus.every(menu => permissionsStore.hasMenuPermission(menu)),
|
pageGroups.every(pageGroup =>
|
||||||
|
permissionsStore.hasPageGroupPermission(pageGroup)
|
||||||
|
),
|
||||||
hasAllComponentPermissions: (components: string[]) =>
|
hasAllComponentPermissions: (components: string[]) =>
|
||||||
components.every(component =>
|
components.every(component =>
|
||||||
permissionsStore.hasComponentPermission(component)
|
permissionsStore.hasComponentPermission(component)
|
||||||
|
|||||||
@@ -26,12 +26,13 @@ watch(activeMenu, newValue => {
|
|||||||
const subMenus = computed(() => {
|
const subMenus = computed(() => {
|
||||||
if (activeMenu.value === "HOME") return [];
|
if (activeMenu.value === "HOME") return [];
|
||||||
|
|
||||||
// 활성 메뉴의 코드 찾기 (M01, M02 등)
|
// 활성 메뉴의 코드 찾기 (PG01, PG02 등)
|
||||||
const activeMenuCode = activeMenu.value;
|
const activeMenuCode = activeMenu.value;
|
||||||
|
|
||||||
// 해당 메뉴의 하위 페이지들 필터링
|
// 해당 페이지그룹의 하위 페이지들 필터링 (menu_yn이 "Y"인 것만)
|
||||||
return permissionStore.permissions.resources.pages
|
return permissionStore.permissions.resources.pages
|
||||||
.filter(page => page.parentCode === activeMenuCode)
|
.filter(page => page.parentCode === activeMenuCode)
|
||||||
|
.filter(page => page.menuYn === "Y") // 메뉴에 표시할 페이지만
|
||||||
.filter(page => permissionStore.hasPagePermission(page.path || ""))
|
.filter(page => permissionStore.hasPagePermission(page.path || ""))
|
||||||
.sort((a, b) => a.sortOrder - b.sortOrder)
|
.sort((a, b) => a.sortOrder - b.sortOrder)
|
||||||
.map(page => ({
|
.map(page => ({
|
||||||
|
|||||||
@@ -105,16 +105,18 @@
|
|||||||
</span>
|
</span>
|
||||||
</p>
|
</p>
|
||||||
<p>
|
<p>
|
||||||
<strong>관리자 메뉴 권한(M01):</strong>
|
<strong>테스트 페이지그룹 권한(PG01):</strong>
|
||||||
<span
|
<span
|
||||||
:class="
|
:class="
|
||||||
permission.hasMenuPermission('M01')
|
permission.hasPageGroupPermission('PG01')
|
||||||
? 'text-green-600'
|
? 'text-green-600'
|
||||||
: 'text-red-600'
|
: 'text-red-600'
|
||||||
"
|
"
|
||||||
>
|
>
|
||||||
{{
|
{{
|
||||||
permission.hasMenuPermission("M01") ? "있음" : "없음"
|
permission.hasPageGroupPermission("PG01")
|
||||||
|
? "있음"
|
||||||
|
: "없음"
|
||||||
}}
|
}}
|
||||||
</span>
|
</span>
|
||||||
</p>
|
</p>
|
||||||
@@ -214,7 +216,7 @@
|
|||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<!-- 메뉴 권한 테스트 -->
|
<!-- 페이지그룹 권한 테스트 -->
|
||||||
<div class="bg-white rounded-lg shadow-md p-6">
|
<div class="bg-white rounded-lg shadow-md p-6">
|
||||||
<div class="flex items-center mb-4">
|
<div class="flex items-center mb-4">
|
||||||
<div
|
<div
|
||||||
@@ -223,58 +225,34 @@
|
|||||||
<span class="text-white font-bold text-sm">3</span>
|
<span class="text-white font-bold text-sm">3</span>
|
||||||
</div>
|
</div>
|
||||||
<h3 class="text-xl font-semibold text-gray-900">
|
<h3 class="text-xl font-semibold text-gray-900">
|
||||||
메뉴 권한 테스트
|
페이지그룹 권한 테스트
|
||||||
</h3>
|
</h3>
|
||||||
</div>
|
</div>
|
||||||
<p class="text-gray-600 mb-4">
|
<p class="text-gray-600 mb-4">
|
||||||
메뉴 권한에 따라 메뉴가 표시되거나 숨겨지는 것을 확인합니다.
|
페이지그룹 권한에 따라 메뉴가 표시되거나 숨겨지는 것을 확인합니다.
|
||||||
</p>
|
</p>
|
||||||
<div class="space-y-3">
|
<div class="space-y-3">
|
||||||
<div class="flex items-center space-x-2">
|
<div class="flex items-center space-x-2">
|
||||||
<div
|
<div
|
||||||
v-if="permission.hasMenuPermission('M01')"
|
v-if="permission.hasPageGroupPermission('PG01')"
|
||||||
class="bg-blue-100 text-blue-800 px-3 py-1 rounded text-sm"
|
class="bg-blue-100 text-blue-800 px-3 py-1 rounded text-sm"
|
||||||
>
|
>
|
||||||
관리자 메뉴
|
테스트 페이지그룹
|
||||||
</div>
|
</div>
|
||||||
<span v-else class="text-gray-400 text-sm"
|
<span v-else class="text-gray-400 text-sm"
|
||||||
>관리자 메뉴 (권한 없음)</span
|
>테스트 페이지그룹 (권한 없음)</span
|
||||||
>
|
>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<div class="flex items-center space-x-2">
|
<div class="flex items-center space-x-2">
|
||||||
<div
|
<div
|
||||||
v-if="permission.hasMenuPermission('M02')"
|
v-if="permission.hasPageGroupPermission('PG02')"
|
||||||
class="bg-green-100 text-green-800 px-3 py-1 rounded text-sm"
|
class="bg-green-100 text-green-800 px-3 py-1 rounded text-sm"
|
||||||
>
|
>
|
||||||
사용자 메뉴
|
관리자 페이지그룹
|
||||||
</div>
|
</div>
|
||||||
<span v-else class="text-gray-400 text-sm"
|
<span v-else class="text-gray-400 text-sm"
|
||||||
>사용자 메뉴 (권한 없음)</span
|
>관리자 페이지그룹 (권한 없음)</span
|
||||||
>
|
|
||||||
</div>
|
|
||||||
|
|
||||||
<div class="flex items-center space-x-2">
|
|
||||||
<div
|
|
||||||
v-if="permission.hasMenuPermission('M03')"
|
|
||||||
class="bg-purple-100 text-purple-800 px-3 py-1 rounded text-sm"
|
|
||||||
>
|
|
||||||
설정 메뉴
|
|
||||||
</div>
|
|
||||||
<span v-else class="text-gray-400 text-sm"
|
|
||||||
>설정 메뉴 (권한 없음)</span
|
|
||||||
>
|
|
||||||
</div>
|
|
||||||
|
|
||||||
<div class="flex items-center space-x-2">
|
|
||||||
<div
|
|
||||||
v-if="permission.hasMenuPermission('M04')"
|
|
||||||
class="bg-yellow-100 text-yellow-800 px-3 py-1 rounded text-sm"
|
|
||||||
>
|
|
||||||
보고서 메뉴
|
|
||||||
</div>
|
|
||||||
<span v-else class="text-gray-400 text-sm"
|
|
||||||
>보고서 메뉴 (권한 없음)</span
|
|
||||||
>
|
>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
@@ -324,21 +302,21 @@
|
|||||||
|
|
||||||
<div class="p-3 bg-gray-50 rounded border">
|
<div class="p-3 bg-gray-50 rounded border">
|
||||||
<h4 class="font-medium text-gray-900 mb-2 text-sm">
|
<h4 class="font-medium text-gray-900 mb-2 text-sm">
|
||||||
메뉴 권한 체크:
|
페이지그룹 권한 체크:
|
||||||
</h4>
|
</h4>
|
||||||
<p class="text-xs text-gray-600 mb-1">
|
<p class="text-xs text-gray-600 mb-1">
|
||||||
<code>hasMenuPermission('M000001')</code>
|
<code>hasPageGroupPermission('PG01')</code>
|
||||||
</p>
|
</p>
|
||||||
<p
|
<p
|
||||||
class="text-sm font-semibold"
|
class="text-sm font-semibold"
|
||||||
:class="
|
:class="
|
||||||
permission.hasMenuPermission('M000001')
|
permission.hasPageGroupPermission('PG01')
|
||||||
? 'text-green-600'
|
? 'text-green-600'
|
||||||
: 'text-red-600'
|
: 'text-red-600'
|
||||||
"
|
"
|
||||||
>
|
>
|
||||||
{{
|
{{
|
||||||
permission.hasMenuPermission("M000001") ? "true" : "false"
|
permission.hasPageGroupPermission("PG01") ? "true" : "false"
|
||||||
}}
|
}}
|
||||||
</p>
|
</p>
|
||||||
</div>
|
</div>
|
||||||
@@ -500,17 +478,21 @@
|
|||||||
</ul>
|
</ul>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<!-- 메뉴 권한 -->
|
<!-- 페이지그룹 권한 -->
|
||||||
<div class="bg-green-50 p-4 rounded-lg">
|
<div class="bg-green-50 p-4 rounded-lg">
|
||||||
<h4 class="text-lg font-semibold mb-3 text-green-800">메뉴 권한</h4>
|
<h4 class="text-lg font-semibold mb-3 text-green-800">
|
||||||
|
페이지그룹 권한
|
||||||
|
</h4>
|
||||||
<ul class="space-y-1">
|
<ul class="space-y-1">
|
||||||
<li
|
<li
|
||||||
v-for="menu in permission.permissions.resources.menus"
|
v-for="pageGroup in permission.permissions.resources.pageGroups"
|
||||||
:key="menu.oid"
|
:key="pageGroup.oid"
|
||||||
class="text-sm bg-white p-2 rounded border"
|
class="text-sm bg-white p-2 rounded border"
|
||||||
>
|
>
|
||||||
<div class="font-medium">{{ menu.name }} ({{ menu.code }})</div>
|
<div class="font-medium">
|
||||||
<div class="text-gray-600">{{ menu.description }}</div>
|
{{ pageGroup.name }} ({{ pageGroup.code }})
|
||||||
|
</div>
|
||||||
|
<div class="text-gray-600">{{ pageGroup.description }}</div>
|
||||||
</li>
|
</li>
|
||||||
</ul>
|
</ul>
|
||||||
</div>
|
</div>
|
||||||
@@ -553,8 +535,8 @@
|
|||||||
권한이 없으면 홈으로 리다이렉트됩니다.
|
권한이 없으면 홈으로 리다이렉트됩니다.
|
||||||
</p>
|
</p>
|
||||||
<p>
|
<p>
|
||||||
<strong>메뉴 권한:</strong> 메뉴 표시 여부를 제어합니다. 권한이
|
<strong>페이지그룹 권한:</strong> 페이지그룹 표시 여부를 제어합니다.
|
||||||
없으면 메뉴가 숨겨집니다.
|
권한이 없으면 페이지그룹이 숨겨집니다.
|
||||||
</p>
|
</p>
|
||||||
<p>
|
<p>
|
||||||
<strong>컴포넌트 권한:</strong> 버튼 등 UI 컴포넌트의 표시 여부를
|
<strong>컴포넌트 권한:</strong> 버튼 등 UI 컴포넌트의 표시 여부를
|
||||||
|
|||||||
@@ -7,7 +7,7 @@ export const usePermissionsStore = defineStore(
|
|||||||
// 권한 데이터 상태
|
// 권한 데이터 상태
|
||||||
const permissions = ref<UserPermissions>({
|
const permissions = ref<UserPermissions>({
|
||||||
resources: {
|
resources: {
|
||||||
menus: [],
|
pageGroups: [],
|
||||||
pages: [],
|
pages: [],
|
||||||
components: [],
|
components: [],
|
||||||
},
|
},
|
||||||
@@ -48,7 +48,7 @@ export const usePermissionsStore = defineStore(
|
|||||||
|
|
||||||
permissions.value = {
|
permissions.value = {
|
||||||
resources: {
|
resources: {
|
||||||
menus: [...MOCK_PERMISSIONS.resources.menus],
|
pageGroups: [...MOCK_PERMISSIONS.resources.pageGroups],
|
||||||
pages: [...MOCK_PERMISSIONS.resources.pages],
|
pages: [...MOCK_PERMISSIONS.resources.pages],
|
||||||
components: [...MOCK_PERMISSIONS.resources.components],
|
components: [...MOCK_PERMISSIONS.resources.components],
|
||||||
},
|
},
|
||||||
@@ -70,8 +70,10 @@ export const usePermissionsStore = defineStore(
|
|||||||
.filter(Boolean) as string[];
|
.filter(Boolean) as string[];
|
||||||
};
|
};
|
||||||
|
|
||||||
const getMenuCodes = (): string[] => {
|
const getPageGroupCodes = (): string[] => {
|
||||||
return permissions.value.resources.menus.map(menu => menu.code);
|
return permissions.value.resources.pageGroups.map(
|
||||||
|
pageGroup => pageGroup.code
|
||||||
|
);
|
||||||
};
|
};
|
||||||
|
|
||||||
const getComponentCodes = (): string[] => {
|
const getComponentCodes = (): string[] => {
|
||||||
@@ -85,8 +87,8 @@ export const usePermissionsStore = defineStore(
|
|||||||
return getPagePaths().includes(page);
|
return getPagePaths().includes(page);
|
||||||
};
|
};
|
||||||
|
|
||||||
const hasMenuPermission = (menu: string): boolean => {
|
const hasPageGroupPermission = (pageGroup: string): boolean => {
|
||||||
return getMenuCodes().includes(menu);
|
return getPageGroupCodes().includes(pageGroup);
|
||||||
};
|
};
|
||||||
|
|
||||||
const hasComponentPermission = (component: string): boolean => {
|
const hasComponentPermission = (component: string): boolean => {
|
||||||
@@ -98,8 +100,8 @@ export const usePermissionsStore = defineStore(
|
|||||||
return pages.some(page => hasPagePermission(page));
|
return pages.some(page => hasPagePermission(page));
|
||||||
};
|
};
|
||||||
|
|
||||||
const hasAnyMenuPermission = (menus: string[]): boolean => {
|
const hasAnyPageGroupPermission = (pageGroups: string[]): boolean => {
|
||||||
return menus.some(menu => hasMenuPermission(menu));
|
return pageGroups.some(pageGroup => hasPageGroupPermission(pageGroup));
|
||||||
};
|
};
|
||||||
|
|
||||||
const hasAnyComponentPermission = (components: string[]): boolean => {
|
const hasAnyComponentPermission = (components: string[]): boolean => {
|
||||||
@@ -134,14 +136,14 @@ export const usePermissionsStore = defineStore(
|
|||||||
|
|
||||||
const findResourceByCode = (
|
const findResourceByCode = (
|
||||||
resources: {
|
resources: {
|
||||||
menus: Resource[];
|
pageGroups: Resource[];
|
||||||
pages: Resource[];
|
pages: Resource[];
|
||||||
components: Resource[];
|
components: Resource[];
|
||||||
},
|
},
|
||||||
code: string
|
code: string
|
||||||
): Resource | undefined => {
|
): Resource | undefined => {
|
||||||
const allResources = [
|
const allResources = [
|
||||||
...resources.menus,
|
...resources.pageGroups,
|
||||||
...resources.pages,
|
...resources.pages,
|
||||||
...resources.components,
|
...resources.components,
|
||||||
];
|
];
|
||||||
@@ -149,7 +151,7 @@ export const usePermissionsStore = defineStore(
|
|||||||
if (resource.code === code) return resource;
|
if (resource.code === code) return resource;
|
||||||
if (resource.children) {
|
if (resource.children) {
|
||||||
const found = findResourceByCode(
|
const found = findResourceByCode(
|
||||||
{ menus: [], pages: [], components: resource.children },
|
{ pageGroups: [], pages: [], components: resource.children },
|
||||||
code
|
code
|
||||||
);
|
);
|
||||||
if (found) return found;
|
if (found) return found;
|
||||||
@@ -160,14 +162,14 @@ export const usePermissionsStore = defineStore(
|
|||||||
|
|
||||||
const findResourceByPath = (
|
const findResourceByPath = (
|
||||||
resources: {
|
resources: {
|
||||||
menus: Resource[];
|
pageGroups: Resource[];
|
||||||
pages: Resource[];
|
pages: Resource[];
|
||||||
components: Resource[];
|
components: Resource[];
|
||||||
},
|
},
|
||||||
path: string
|
path: string
|
||||||
): Resource | undefined => {
|
): Resource | undefined => {
|
||||||
const allResources = [
|
const allResources = [
|
||||||
...resources.menus,
|
...resources.pageGroups,
|
||||||
...resources.pages,
|
...resources.pages,
|
||||||
...resources.components,
|
...resources.components,
|
||||||
];
|
];
|
||||||
@@ -175,7 +177,7 @@ export const usePermissionsStore = defineStore(
|
|||||||
if (resource.path === path) return resource;
|
if (resource.path === path) return resource;
|
||||||
if (resource.children) {
|
if (resource.children) {
|
||||||
const found = findResourceByPath(
|
const found = findResourceByPath(
|
||||||
{ menus: [], pages: [], components: resource.children },
|
{ pageGroups: [], pages: [], components: resource.children },
|
||||||
path
|
path
|
||||||
);
|
);
|
||||||
if (found) return found;
|
if (found) return found;
|
||||||
@@ -188,7 +190,7 @@ export const usePermissionsStore = defineStore(
|
|||||||
const clearPermissions = () => {
|
const clearPermissions = () => {
|
||||||
permissions.value = {
|
permissions.value = {
|
||||||
resources: {
|
resources: {
|
||||||
menus: [],
|
pageGroups: [],
|
||||||
pages: [],
|
pages: [],
|
||||||
components: [],
|
components: [],
|
||||||
},
|
},
|
||||||
@@ -206,15 +208,15 @@ export const usePermissionsStore = defineStore(
|
|||||||
|
|
||||||
// 기존 호환성 함수들
|
// 기존 호환성 함수들
|
||||||
hasPagePermission,
|
hasPagePermission,
|
||||||
hasMenuPermission,
|
hasPageGroupPermission,
|
||||||
hasComponentPermission,
|
hasComponentPermission,
|
||||||
hasAnyPagePermission,
|
hasAnyPagePermission,
|
||||||
hasAnyMenuPermission,
|
hasAnyPageGroupPermission,
|
||||||
hasAnyComponentPermission,
|
hasAnyComponentPermission,
|
||||||
|
|
||||||
// 헬퍼 함수들
|
// 헬퍼 함수들
|
||||||
getPagePaths,
|
getPagePaths,
|
||||||
getMenuCodes,
|
getPageGroupCodes,
|
||||||
getComponentCodes,
|
getComponentCodes,
|
||||||
|
|
||||||
// 새로운 계층 구조 권한 체크 함수들
|
// 새로운 계층 구조 권한 체크 함수들
|
||||||
|
|||||||
@@ -1,27 +1,28 @@
|
|||||||
/**
|
/**
|
||||||
* 권한 시스템 타입 정의
|
* 권한 시스템 타입 정의
|
||||||
*
|
*
|
||||||
* 2자리 계층 코드 시스템을 사용하여 메뉴 > 페이지 > 컴포넌트 계층 구조를 표현합니다.
|
* 2자리 계층 코드 시스템을 사용하여 페이지그룹 > 페이지 > 컴포넌트 계층 구조를 표현합니다.
|
||||||
*
|
*
|
||||||
* 코드 규칙:
|
* 코드 규칙:
|
||||||
* - 메뉴: M01, M02, M03, M04...
|
* - 페이지그룹: PG01, PG02, PG03, PG04...
|
||||||
* - 페이지: P0101 (M01 하위), P0201 (M02 하위), P0501 (독립 페이지)...
|
* - 페이지: P0101 (PG01 하위), P0201 (PG02 하위), P0501 (독립 페이지)...
|
||||||
* - 컴포넌트: C010101 (P0101 하위), C010102 (P0101 하위)...
|
* - 컴포넌트: C010101 (P0101 하위), C010102 (P0101 하위)...
|
||||||
*/
|
*/
|
||||||
|
|
||||||
// 리소스 타입 정의 (메뉴, 페이지, 컴포넌트)
|
// 리소스 타입 정의 (페이지그룹, 페이지, 컴포넌트)
|
||||||
export type ResourceType = "menu" | "page" | "component";
|
export type ResourceType = "PAGE_GROUP" | "PAGE" | "COMPONENT";
|
||||||
|
|
||||||
// 개별 리소스 객체 (계층 구조 지원)
|
// 개별 리소스 객체 (계층 구조 지원)
|
||||||
export interface Resource {
|
export interface Resource {
|
||||||
oid: number; // OID (고유 식별자)
|
oid: number; // OID (고유 식별자)
|
||||||
code: string; // 2자리 계층 코드 (M01, P0101, C010101)
|
code: string; // 2자리 계층 코드 (PG01, P0101, C010101)
|
||||||
name: string; // 리소스 이름
|
name: string; // 리소스 이름
|
||||||
parentCode?: string; // 부모 리소스 코드 (계층 구조)
|
parentCode?: string; // 부모 리소스 코드 (계층 구조)
|
||||||
type: ResourceType; // 리소스 타입
|
type: ResourceType; // 리소스 타입
|
||||||
path?: string; // 페이지 경로 (페이지 타입만)
|
path?: string; // 페이지 경로 (PAGE 타입만)
|
||||||
sortOrder: number; // 정렬 순서
|
sortOrder: number; // 정렬 순서
|
||||||
description?: string; // 리소스 설명
|
description?: string; // 리소스 설명
|
||||||
|
menuYn?: string; // 메뉴 여부 (char(1))
|
||||||
componentType?: string; // 컴포넌트 세부 타입 (버튼, 그리드 등)
|
componentType?: string; // 컴포넌트 세부 타입 (버튼, 그리드 등)
|
||||||
children?: Resource[]; // 자식 리소스들 (계층 구조)
|
children?: Resource[]; // 자식 리소스들 (계층 구조)
|
||||||
}
|
}
|
||||||
@@ -29,7 +30,7 @@ export interface Resource {
|
|||||||
// 사용자 권한 구조 (계층적 리소스 관리)
|
// 사용자 권한 구조 (계층적 리소스 관리)
|
||||||
export interface UserPermissions {
|
export interface UserPermissions {
|
||||||
resources: {
|
resources: {
|
||||||
menus: Resource[]; // 메뉴 리소스들 (M01, M02...)
|
pageGroups: Resource[]; // 페이지그룹 리소스들 (PG01, PG02...)
|
||||||
pages: Resource[]; // 페이지 리소스들 (P0101, P0201...)
|
pages: Resource[]; // 페이지 리소스들 (P0101, P0201...)
|
||||||
components: Resource[]; // 컴포넌트 리소스들 (C010101, C010102...)
|
components: Resource[]; // 컴포넌트 리소스들 (C010101, C010102...)
|
||||||
};
|
};
|
||||||
@@ -39,7 +40,7 @@ export interface UserPermissions {
|
|||||||
export interface PermissionCheckResult {
|
export interface PermissionCheckResult {
|
||||||
// 기존 호환성 함수들 (경로/코드 기반)
|
// 기존 호환성 함수들 (경로/코드 기반)
|
||||||
hasPagePermission: (page: string) => boolean; // 페이지 경로로 권한 체크
|
hasPagePermission: (page: string) => boolean; // 페이지 경로로 권한 체크
|
||||||
hasMenuPermission: (menu: string) => boolean; // 메뉴 코드로 권한 체크
|
hasPageGroupPermission: (pageGroup: string) => boolean; // 페이지그룹 코드로 권한 체크
|
||||||
hasComponentPermission: (component: string) => boolean; // 컴포넌트 코드로 권한 체크
|
hasComponentPermission: (component: string) => boolean; // 컴포넌트 코드로 권한 체크
|
||||||
|
|
||||||
// 계층 구조를 고려한 권한 체크 함수들
|
// 계층 구조를 고려한 권한 체크 함수들
|
||||||
@@ -52,7 +53,7 @@ export interface PermissionCheckResult {
|
|||||||
// 권한 종류별 상수 (기존 호환성 유지용)
|
// 권한 종류별 상수 (기존 호환성 유지용)
|
||||||
export const PERMISSION_TYPES = {
|
export const PERMISSION_TYPES = {
|
||||||
PAGE: "pagePermissions",
|
PAGE: "pagePermissions",
|
||||||
MENU: "menuPermissions",
|
PAGE_GROUP: "pageGroupPermissions",
|
||||||
COMPONENT: "componentPermissions",
|
COMPONENT: "componentPermissions",
|
||||||
} as const;
|
} as const;
|
||||||
|
|
||||||
@@ -62,218 +63,291 @@ export const PERMISSION_TYPES = {
|
|||||||
* 2자리 계층 코드 시스템을 사용한 실제 권한 데이터 예시입니다.
|
* 2자리 계층 코드 시스템을 사용한 실제 권한 데이터 예시입니다.
|
||||||
*
|
*
|
||||||
* 계층 구조:
|
* 계층 구조:
|
||||||
* - M01 (관리자 메뉴) > P0101~P0105 (관리자 페이지들) > C010101~C010106 (컴포넌트들)
|
* - PG01 (테스트 페이지그룹) > P0101~P0115 (테스트 페이지들) > C010101~C010106 (컴포넌트들)
|
||||||
* - M02 (사용자 메뉴) > P0201~P0202 (사용자 페이지들)
|
* - PG02 (관리자 페이지그룹) > P0201~P0203 (관리자 페이지들)
|
||||||
* - P0501~P0504 (독립 페이지들: 홈, 로그인, 회원가입, 소개)
|
* - P0501~P0504 (독립 페이지들: 홈, 로그인, 회원가입, 소개)
|
||||||
* - P0601~P0602 (테스트 페이지들)
|
* - P0601~P0602 (테스트 페이지들)
|
||||||
* - P0701 (팝업 페이지들)
|
* - P0701 (팝업 페이지들)
|
||||||
*/
|
*/
|
||||||
export const MOCK_PERMISSIONS: UserPermissions = {
|
export const MOCK_PERMISSIONS: UserPermissions = {
|
||||||
resources: {
|
resources: {
|
||||||
// 메뉴 리소스들 (최상위 레벨)
|
// 페이지그룹 리소스들 (최상위 레벨)
|
||||||
menus: [
|
pageGroups: [
|
||||||
{
|
{
|
||||||
oid: 1,
|
oid: 1,
|
||||||
code: "M01",
|
code: "PG01",
|
||||||
name: "테스트 메뉴",
|
name: "테스트",
|
||||||
type: "menu",
|
type: "PAGE_GROUP",
|
||||||
sortOrder: 1,
|
sortOrder: 1,
|
||||||
description: "테스트 관련 메뉴",
|
description: "테스트 관련 페이지그룹",
|
||||||
|
menuYn: "Y",
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
oid: 2,
|
oid: 2,
|
||||||
code: "M02",
|
code: "PG02",
|
||||||
name: "관리자 메뉴",
|
name: "관리자",
|
||||||
type: "menu",
|
type: "PAGE_GROUP",
|
||||||
sortOrder: 2,
|
sortOrder: 2,
|
||||||
description: "관리자 전용 메뉴",
|
description: "관리자 전용 페이지그룹",
|
||||||
|
menuYn: "Y",
|
||||||
|
},
|
||||||
|
{
|
||||||
|
oid: 3,
|
||||||
|
code: "PG03",
|
||||||
|
name: "공통 팝업",
|
||||||
|
type: "PAGE_GROUP",
|
||||||
|
sortOrder: 2,
|
||||||
|
description: "공통 팝업 페이지그룹",
|
||||||
|
menuYn: "N",
|
||||||
},
|
},
|
||||||
],
|
],
|
||||||
|
|
||||||
// 페이지 리소스들 (화면 메뉴 구성에 맞춤)
|
// 페이지 리소스들 (화면 메뉴 구성에 맞춤)
|
||||||
pages: [
|
pages: [
|
||||||
// 테스트 메뉴 하위 페이지들 (M01 > P0101~P0115)
|
// 테스트 페이지그룹 하위 페이지들 (PG01 > P0101~P0115)
|
||||||
{
|
{
|
||||||
oid: 5,
|
oid: 5,
|
||||||
code: "P0101",
|
code: "P0101",
|
||||||
name: "테스트",
|
name: "테스트",
|
||||||
type: "page",
|
type: "PAGE",
|
||||||
path: "/test",
|
path: "/test",
|
||||||
parentCode: "M01",
|
parentCode: "PG01",
|
||||||
sortOrder: 1,
|
sortOrder: 1,
|
||||||
description: "기본 테스트 페이지",
|
description: "기본 테스트 페이지",
|
||||||
|
menuYn: "Y",
|
||||||
|
},
|
||||||
|
{
|
||||||
|
oid: 50,
|
||||||
|
code: "P010101",
|
||||||
|
name: "테스트 등록 팝업",
|
||||||
|
type: "PAGE",
|
||||||
|
path: "/test/registerPopup",
|
||||||
|
parentCode: "P0101",
|
||||||
|
sortOrder: 1,
|
||||||
|
description: "기본 테스트 페이지",
|
||||||
|
menuYn: "Y",
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
oid: 6,
|
oid: 6,
|
||||||
code: "P0102",
|
code: "P0102",
|
||||||
name: "ivg",
|
name: "ivg",
|
||||||
type: "page",
|
type: "PAGE",
|
||||||
path: "/test/igv",
|
path: "/test/igv",
|
||||||
parentCode: "M01",
|
parentCode: "PG01",
|
||||||
sortOrder: 2,
|
sortOrder: 2,
|
||||||
description: "IGV 테스트 페이지",
|
description: "IGV 테스트 페이지",
|
||||||
|
menuYn: "Y",
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
oid: 7,
|
oid: 7,
|
||||||
code: "P0103",
|
code: "P0103",
|
||||||
name: "ivg2",
|
name: "ivg2",
|
||||||
type: "page",
|
type: "PAGE",
|
||||||
path: "/test/igv2",
|
path: "/test/igv2",
|
||||||
parentCode: "M01",
|
parentCode: "PG01",
|
||||||
sortOrder: 3,
|
sortOrder: 3,
|
||||||
description: "IGV2 테스트 페이지",
|
description: "IGV2 테스트 페이지",
|
||||||
|
menuYn: "Y",
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
oid: 8,
|
oid: 8,
|
||||||
code: "P0104",
|
code: "P0104",
|
||||||
name: "pathway",
|
name: "pathway",
|
||||||
type: "page",
|
type: "PAGE",
|
||||||
path: "/test/pathway",
|
path: "/test/pathway",
|
||||||
parentCode: "M01",
|
parentCode: "PG01",
|
||||||
sortOrder: 4,
|
sortOrder: 4,
|
||||||
description: "경로 분석 페이지",
|
description: "경로 분석 페이지",
|
||||||
|
menuYn: "Y",
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
oid: 9,
|
oid: 9,
|
||||||
code: "P0105",
|
code: "P0105",
|
||||||
name: "pathway2",
|
name: "pathway2",
|
||||||
type: "page",
|
type: "PAGE",
|
||||||
path: "/test/pathway2",
|
path: "/test/pathway2",
|
||||||
parentCode: "M01",
|
parentCode: "PG01",
|
||||||
sortOrder: 5,
|
sortOrder: 5,
|
||||||
description: "경로 분석 페이지 2",
|
description: "경로 분석 페이지 2",
|
||||||
|
menuYn: "Y",
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
oid: 10,
|
oid: 10,
|
||||||
code: "P0106",
|
code: "P0106",
|
||||||
name: "pathway3",
|
name: "pathway3",
|
||||||
type: "page",
|
type: "PAGE",
|
||||||
path: "/test/pathway3",
|
path: "/test/pathway3",
|
||||||
parentCode: "M01",
|
parentCode: "PG01",
|
||||||
sortOrder: 6,
|
sortOrder: 6,
|
||||||
description: "경로 분석 페이지 3",
|
description: "경로 분석 페이지 3",
|
||||||
|
menuYn: "Y",
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
oid: 11,
|
oid: 11,
|
||||||
code: "P0107",
|
code: "P0107",
|
||||||
name: "pathway4",
|
name: "pathway4",
|
||||||
type: "page",
|
type: "PAGE",
|
||||||
path: "/test/pathway4",
|
path: "/test/pathway4",
|
||||||
parentCode: "M01",
|
parentCode: "PG01",
|
||||||
sortOrder: 7,
|
sortOrder: 7,
|
||||||
description: "경로 분석 페이지 4",
|
description: "경로 분석 페이지 4",
|
||||||
|
menuYn: "Y",
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
oid: 12,
|
oid: 12,
|
||||||
code: "P0108",
|
code: "P0108",
|
||||||
name: "pathwayjson",
|
name: "pathwayjson",
|
||||||
type: "page",
|
type: "PAGE",
|
||||||
path: "/test/pathwayJson",
|
path: "/test/pathwayJson",
|
||||||
parentCode: "M01",
|
parentCode: "PG01",
|
||||||
sortOrder: 8,
|
sortOrder: 8,
|
||||||
description: "경로 분석 JSON 페이지",
|
description: "경로 분석 JSON 페이지",
|
||||||
|
menuYn: "Y",
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
oid: 13,
|
oid: 13,
|
||||||
code: "P0109",
|
code: "P0109",
|
||||||
name: "배양그래프",
|
name: "배양그래프",
|
||||||
type: "page",
|
type: "PAGE",
|
||||||
path: "/test/culture-graph",
|
path: "/test/culture-graph",
|
||||||
parentCode: "M01",
|
parentCode: "PG01",
|
||||||
sortOrder: 9,
|
sortOrder: 9,
|
||||||
description: "배양 그래프 페이지",
|
description: "배양 그래프 페이지",
|
||||||
|
menuYn: "Y",
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
oid: 14,
|
oid: 14,
|
||||||
code: "P0110",
|
code: "P0110",
|
||||||
name: "배양그래프 멀티",
|
name: "배양그래프 멀티",
|
||||||
type: "page",
|
type: "PAGE",
|
||||||
path: "/test/culture-graph-multi",
|
path: "/test/culture-graph-multi",
|
||||||
parentCode: "M01",
|
parentCode: "PG01",
|
||||||
sortOrder: 10,
|
sortOrder: 10,
|
||||||
description: "배양 그래프 멀티 페이지",
|
description: "배양 그래프 멀티 페이지",
|
||||||
|
menuYn: "Y",
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
oid: 15,
|
oid: 15,
|
||||||
code: "P0111",
|
code: "P0111",
|
||||||
name: "배양그래프 탭",
|
name: "배양그래프 탭",
|
||||||
type: "page",
|
type: "PAGE",
|
||||||
path: "/test/culture-graph-tab",
|
path: "/test/culture-graph-tab",
|
||||||
parentCode: "M01",
|
parentCode: "PG01",
|
||||||
sortOrder: 11,
|
sortOrder: 11,
|
||||||
description: "배양 그래프 탭 페이지",
|
description: "배양 그래프 탭 페이지",
|
||||||
|
menuYn: "Y",
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
oid: 16,
|
oid: 16,
|
||||||
code: "P0112",
|
code: "P0112",
|
||||||
name: "tui-grid",
|
name: "tui-grid",
|
||||||
type: "page",
|
type: "PAGE",
|
||||||
path: "/tui",
|
path: "/tui",
|
||||||
parentCode: "M01",
|
parentCode: "PG01",
|
||||||
sortOrder: 12,
|
sortOrder: 12,
|
||||||
description: "TUI 그리드 페이지",
|
description: "TUI 그리드 페이지",
|
||||||
|
menuYn: "Y",
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
oid: 17,
|
oid: 17,
|
||||||
code: "P0113",
|
code: "P0113",
|
||||||
name: "리소스",
|
name: "리소스",
|
||||||
type: "page",
|
type: "PAGE",
|
||||||
path: "/admin/resource",
|
path: "/admin/resource",
|
||||||
parentCode: "M01",
|
parentCode: "PG01",
|
||||||
sortOrder: 13,
|
sortOrder: 13,
|
||||||
description: "리소스 관리 페이지",
|
description: "리소스 관리 페이지",
|
||||||
|
menuYn: "Y",
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
oid: 18,
|
oid: 18,
|
||||||
code: "P0114",
|
code: "P0114",
|
||||||
name: "sample",
|
name: "sample",
|
||||||
type: "page",
|
type: "PAGE",
|
||||||
path: "/sampleList",
|
path: "/sampleList",
|
||||||
parentCode: "M01",
|
parentCode: "PG01",
|
||||||
sortOrder: 14,
|
sortOrder: 14,
|
||||||
description: "샘플 목록 페이지",
|
description: "샘플 목록 페이지",
|
||||||
|
menuYn: "Y",
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
oid: 19,
|
oid: 19,
|
||||||
code: "P0115",
|
code: "P0115",
|
||||||
name: "공용 기능 테스트",
|
name: "공용 기능 테스트",
|
||||||
type: "page",
|
type: "PAGE",
|
||||||
path: "/test/common-test",
|
path: "/test/common-test",
|
||||||
parentCode: "M01",
|
parentCode: "PG01",
|
||||||
sortOrder: 15,
|
sortOrder: 15,
|
||||||
description: "공용 기능 테스트 페이지",
|
description: "공용 기능 테스트 페이지",
|
||||||
|
menuYn: "Y",
|
||||||
|
},
|
||||||
|
{
|
||||||
|
oid: 25,
|
||||||
|
code: "P0116",
|
||||||
|
name: "등록",
|
||||||
|
type: "PAGE",
|
||||||
|
path: "/test/register",
|
||||||
|
parentCode: "PG01",
|
||||||
|
sortOrder: 16,
|
||||||
|
description: "테스트 등록 페이지",
|
||||||
|
menuYn: "N",
|
||||||
},
|
},
|
||||||
|
|
||||||
// 관리자 메뉴 하위 페이지들 (M02 > P0201~P0203)
|
// 관리자 페이지그룹 하위 페이지들 (PG02 > P0201~P0203)
|
||||||
{
|
{
|
||||||
oid: 20,
|
oid: 20,
|
||||||
code: "P0201",
|
code: "P0201",
|
||||||
name: "접속기록",
|
name: "접속기록",
|
||||||
type: "page",
|
type: "PAGE",
|
||||||
path: "/admin/logs",
|
path: "/admin/logs",
|
||||||
parentCode: "M02",
|
parentCode: "PG02",
|
||||||
sortOrder: 1,
|
sortOrder: 1,
|
||||||
description: "사용자 접속 기록 관리",
|
description: "사용자 접속 기록 관리",
|
||||||
|
menuYn: "Y",
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
oid: 21,
|
oid: 21,
|
||||||
code: "P0202",
|
code: "P0202",
|
||||||
name: "공통코드",
|
name: "공통코드",
|
||||||
type: "page",
|
type: "PAGE",
|
||||||
path: "/admin/codes",
|
path: "/admin/codes",
|
||||||
parentCode: "M02",
|
parentCode: "PG02",
|
||||||
sortOrder: 2,
|
sortOrder: 2,
|
||||||
description: "공통 코드 관리",
|
description: "공통 코드 관리",
|
||||||
|
menuYn: "Y",
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
oid: 22,
|
oid: 22,
|
||||||
code: "P0203",
|
code: "P0203",
|
||||||
name: "프로그램",
|
name: "프로그램",
|
||||||
type: "page",
|
type: "PAGE",
|
||||||
path: "/admin/programs",
|
path: "/admin/programs",
|
||||||
parentCode: "M02",
|
parentCode: "PG02",
|
||||||
sortOrder: 3,
|
sortOrder: 3,
|
||||||
description: "프로그램 관리",
|
description: "프로그램 관리",
|
||||||
|
menuYn: "Y",
|
||||||
|
},
|
||||||
|
{
|
||||||
|
oid: 26,
|
||||||
|
code: "P0204",
|
||||||
|
name: "등록",
|
||||||
|
type: "PAGE",
|
||||||
|
path: "/admin/register",
|
||||||
|
parentCode: "PG02",
|
||||||
|
sortOrder: 4,
|
||||||
|
description: "관리자 등록 페이지",
|
||||||
|
menuYn: "N",
|
||||||
|
},
|
||||||
|
{
|
||||||
|
oid: 27,
|
||||||
|
code: "P0301",
|
||||||
|
name: "부서 조회 팝업",
|
||||||
|
type: "PAGE",
|
||||||
|
path: "/test/departmentPopup",
|
||||||
|
parentCode: "PG03",
|
||||||
|
sortOrder: 1,
|
||||||
|
description: "부서 조회 팝업",
|
||||||
|
menuYn: "N",
|
||||||
},
|
},
|
||||||
],
|
],
|
||||||
|
|
||||||
@@ -284,8 +358,7 @@ export const MOCK_PERMISSIONS: UserPermissions = {
|
|||||||
oid: 19,
|
oid: 19,
|
||||||
code: "C010101",
|
code: "C010101",
|
||||||
name: "삭제 버튼",
|
name: "삭제 버튼",
|
||||||
type: "component",
|
type: "COMPONENT",
|
||||||
componentType: "button",
|
|
||||||
parentCode: "P0101",
|
parentCode: "P0101",
|
||||||
sortOrder: 1,
|
sortOrder: 1,
|
||||||
description: "테스트 삭제 버튼",
|
description: "테스트 삭제 버튼",
|
||||||
@@ -294,8 +367,7 @@ export const MOCK_PERMISSIONS: UserPermissions = {
|
|||||||
oid: 20,
|
oid: 20,
|
||||||
code: "C010102",
|
code: "C010102",
|
||||||
name: "수정 버튼",
|
name: "수정 버튼",
|
||||||
type: "component",
|
type: "COMPONENT",
|
||||||
componentType: "button",
|
|
||||||
parentCode: "P0101",
|
parentCode: "P0101",
|
||||||
sortOrder: 2,
|
sortOrder: 2,
|
||||||
description: "테스트 수정 버튼",
|
description: "테스트 수정 버튼",
|
||||||
@@ -304,8 +376,7 @@ export const MOCK_PERMISSIONS: UserPermissions = {
|
|||||||
oid: 21,
|
oid: 21,
|
||||||
code: "C010103",
|
code: "C010103",
|
||||||
name: "내보내기 버튼",
|
name: "내보내기 버튼",
|
||||||
type: "component",
|
type: "COMPONENT",
|
||||||
componentType: "button",
|
|
||||||
parentCode: "P0101",
|
parentCode: "P0101",
|
||||||
sortOrder: 3,
|
sortOrder: 3,
|
||||||
description: "테스트 내보내기 버튼",
|
description: "테스트 내보내기 버튼",
|
||||||
@@ -314,8 +385,7 @@ export const MOCK_PERMISSIONS: UserPermissions = {
|
|||||||
oid: 22,
|
oid: 22,
|
||||||
code: "C010104",
|
code: "C010104",
|
||||||
name: "가져오기 버튼",
|
name: "가져오기 버튼",
|
||||||
type: "component",
|
type: "COMPONENT",
|
||||||
componentType: "button",
|
|
||||||
parentCode: "P0101",
|
parentCode: "P0101",
|
||||||
sortOrder: 4,
|
sortOrder: 4,
|
||||||
description: "테스트 가져오기 버튼",
|
description: "테스트 가져오기 버튼",
|
||||||
@@ -324,8 +394,7 @@ export const MOCK_PERMISSIONS: UserPermissions = {
|
|||||||
oid: 23,
|
oid: 23,
|
||||||
code: "C010105",
|
code: "C010105",
|
||||||
name: "생성 버튼",
|
name: "생성 버튼",
|
||||||
type: "component",
|
type: "COMPONENT",
|
||||||
componentType: "button",
|
|
||||||
parentCode: "P0101",
|
parentCode: "P0101",
|
||||||
sortOrder: 5,
|
sortOrder: 5,
|
||||||
description: "테스트 생성 버튼",
|
description: "테스트 생성 버튼",
|
||||||
@@ -334,8 +403,7 @@ export const MOCK_PERMISSIONS: UserPermissions = {
|
|||||||
oid: 24,
|
oid: 24,
|
||||||
code: "C010106",
|
code: "C010106",
|
||||||
name: "보기 버튼",
|
name: "보기 버튼",
|
||||||
type: "component",
|
type: "COMPONENT",
|
||||||
componentType: "button",
|
|
||||||
parentCode: "P0101",
|
parentCode: "P0101",
|
||||||
sortOrder: 6,
|
sortOrder: 6,
|
||||||
description: "테스트 상세보기 버튼",
|
description: "테스트 상세보기 버튼",
|
||||||
|
|||||||
Reference in New Issue
Block a user