318 lines
7.5 KiB
TypeScript
318 lines
7.5 KiB
TypeScript
|
|
/**
|
||
|
|
* 다단계 계층 (Hierarchy) API 클라이언트
|
||
|
|
*/
|
||
|
|
|
||
|
|
import { apiClient } from "./client";
|
||
|
|
|
||
|
|
// =====================================================
|
||
|
|
// 타입 정의
|
||
|
|
// =====================================================
|
||
|
|
|
||
|
|
export interface HierarchyLevel {
|
||
|
|
levelId?: number;
|
||
|
|
groupCode: string;
|
||
|
|
companyCode?: string;
|
||
|
|
levelOrder: number;
|
||
|
|
levelName: string;
|
||
|
|
levelCode?: string;
|
||
|
|
tableName: string;
|
||
|
|
valueColumn: string;
|
||
|
|
labelColumn: string;
|
||
|
|
parentKeyColumn?: string;
|
||
|
|
filterColumn?: string;
|
||
|
|
filterValue?: string;
|
||
|
|
orderColumn?: string;
|
||
|
|
orderDirection?: string;
|
||
|
|
placeholder?: string;
|
||
|
|
isRequired?: string;
|
||
|
|
isSearchable?: string;
|
||
|
|
isActive?: string;
|
||
|
|
createdDate?: string;
|
||
|
|
updatedDate?: string;
|
||
|
|
}
|
||
|
|
|
||
|
|
export interface HierarchyGroup {
|
||
|
|
groupId?: number;
|
||
|
|
groupCode: string;
|
||
|
|
groupName: string;
|
||
|
|
description?: string;
|
||
|
|
hierarchyType: "MULTI_TABLE" | "SELF_REFERENCE" | "BOM" | "TREE";
|
||
|
|
maxLevels?: number;
|
||
|
|
isFixedLevels?: string;
|
||
|
|
// Self-reference 설정
|
||
|
|
selfRefTable?: string;
|
||
|
|
selfRefIdColumn?: string;
|
||
|
|
selfRefParentColumn?: string;
|
||
|
|
selfRefValueColumn?: string;
|
||
|
|
selfRefLabelColumn?: string;
|
||
|
|
selfRefLevelColumn?: string;
|
||
|
|
selfRefOrderColumn?: string;
|
||
|
|
// BOM 설정
|
||
|
|
bomTable?: string;
|
||
|
|
bomParentColumn?: string;
|
||
|
|
bomChildColumn?: string;
|
||
|
|
bomItemTable?: string;
|
||
|
|
bomItemIdColumn?: string;
|
||
|
|
bomItemLabelColumn?: string;
|
||
|
|
bomQtyColumn?: string;
|
||
|
|
bomLevelColumn?: string;
|
||
|
|
// 메시지
|
||
|
|
emptyMessage?: string;
|
||
|
|
noOptionsMessage?: string;
|
||
|
|
loadingMessage?: string;
|
||
|
|
// 메타
|
||
|
|
companyCode?: string;
|
||
|
|
isActive?: string;
|
||
|
|
createdBy?: string;
|
||
|
|
createdDate?: string;
|
||
|
|
updatedBy?: string;
|
||
|
|
updatedDate?: string;
|
||
|
|
// 조회 시 포함
|
||
|
|
levels?: HierarchyLevel[];
|
||
|
|
levelCount?: number;
|
||
|
|
}
|
||
|
|
|
||
|
|
// 계층 타입
|
||
|
|
export const HIERARCHY_TYPES = [
|
||
|
|
{ value: "MULTI_TABLE", label: "다중 테이블 (국가>도시>구)" },
|
||
|
|
{ value: "SELF_REFERENCE", label: "자기 참조 (조직도)" },
|
||
|
|
{ value: "BOM", label: "BOM (부품 구조)" },
|
||
|
|
{ value: "TREE", label: "트리 (카테고리)" },
|
||
|
|
];
|
||
|
|
|
||
|
|
// =====================================================
|
||
|
|
// API 함수
|
||
|
|
// =====================================================
|
||
|
|
|
||
|
|
/**
|
||
|
|
* 계층 그룹 목록 조회
|
||
|
|
*/
|
||
|
|
export async function getHierarchyGroups(params?: {
|
||
|
|
isActive?: string;
|
||
|
|
hierarchyType?: string;
|
||
|
|
}): Promise<{
|
||
|
|
success: boolean;
|
||
|
|
data?: HierarchyGroup[];
|
||
|
|
error?: string;
|
||
|
|
}> {
|
||
|
|
try {
|
||
|
|
const searchParams = new URLSearchParams();
|
||
|
|
if (params?.isActive) searchParams.append("isActive", params.isActive);
|
||
|
|
if (params?.hierarchyType) searchParams.append("hierarchyType", params.hierarchyType);
|
||
|
|
|
||
|
|
const response = await apiClient.get(`/cascading-hierarchy?${searchParams.toString()}`);
|
||
|
|
return response.data;
|
||
|
|
} catch (error: any) {
|
||
|
|
console.error("계층 그룹 목록 조회 실패:", error);
|
||
|
|
return {
|
||
|
|
success: false,
|
||
|
|
error: error.response?.data?.message || error.message,
|
||
|
|
};
|
||
|
|
}
|
||
|
|
}
|
||
|
|
|
||
|
|
/**
|
||
|
|
* 계층 그룹 상세 조회 (레벨 포함)
|
||
|
|
*/
|
||
|
|
export async function getHierarchyGroupDetail(groupCode: string): Promise<{
|
||
|
|
success: boolean;
|
||
|
|
data?: HierarchyGroup;
|
||
|
|
error?: string;
|
||
|
|
}> {
|
||
|
|
try {
|
||
|
|
const response = await apiClient.get(`/cascading-hierarchy/${groupCode}`);
|
||
|
|
return response.data;
|
||
|
|
} catch (error: any) {
|
||
|
|
console.error("계층 그룹 상세 조회 실패:", error);
|
||
|
|
return {
|
||
|
|
success: false,
|
||
|
|
error: error.response?.data?.message || error.message,
|
||
|
|
};
|
||
|
|
}
|
||
|
|
}
|
||
|
|
|
||
|
|
/**
|
||
|
|
* 계층 그룹 생성
|
||
|
|
*/
|
||
|
|
export async function createHierarchyGroup(
|
||
|
|
data: Omit<HierarchyGroup, "groupId"> & { levels?: Partial<HierarchyLevel>[] }
|
||
|
|
): Promise<{
|
||
|
|
success: boolean;
|
||
|
|
data?: HierarchyGroup;
|
||
|
|
message?: string;
|
||
|
|
error?: string;
|
||
|
|
}> {
|
||
|
|
try {
|
||
|
|
const response = await apiClient.post("/cascading-hierarchy", data);
|
||
|
|
return response.data;
|
||
|
|
} catch (error: any) {
|
||
|
|
console.error("계층 그룹 생성 실패:", error);
|
||
|
|
return {
|
||
|
|
success: false,
|
||
|
|
error: error.response?.data?.message || error.message,
|
||
|
|
};
|
||
|
|
}
|
||
|
|
}
|
||
|
|
|
||
|
|
/**
|
||
|
|
* 계층 그룹 수정
|
||
|
|
*/
|
||
|
|
export async function updateHierarchyGroup(
|
||
|
|
groupCode: string,
|
||
|
|
data: Partial<HierarchyGroup>
|
||
|
|
): Promise<{
|
||
|
|
success: boolean;
|
||
|
|
data?: HierarchyGroup;
|
||
|
|
message?: string;
|
||
|
|
error?: string;
|
||
|
|
}> {
|
||
|
|
try {
|
||
|
|
const response = await apiClient.put(`/cascading-hierarchy/${groupCode}`, data);
|
||
|
|
return response.data;
|
||
|
|
} catch (error: any) {
|
||
|
|
console.error("계층 그룹 수정 실패:", error);
|
||
|
|
return {
|
||
|
|
success: false,
|
||
|
|
error: error.response?.data?.message || error.message,
|
||
|
|
};
|
||
|
|
}
|
||
|
|
}
|
||
|
|
|
||
|
|
/**
|
||
|
|
* 계층 그룹 삭제
|
||
|
|
*/
|
||
|
|
export async function deleteHierarchyGroup(groupCode: string): Promise<{
|
||
|
|
success: boolean;
|
||
|
|
message?: string;
|
||
|
|
error?: string;
|
||
|
|
}> {
|
||
|
|
try {
|
||
|
|
const response = await apiClient.delete(`/cascading-hierarchy/${groupCode}`);
|
||
|
|
return response.data;
|
||
|
|
} catch (error: any) {
|
||
|
|
console.error("계층 그룹 삭제 실패:", error);
|
||
|
|
return {
|
||
|
|
success: false,
|
||
|
|
error: error.response?.data?.message || error.message,
|
||
|
|
};
|
||
|
|
}
|
||
|
|
}
|
||
|
|
|
||
|
|
/**
|
||
|
|
* 레벨 추가
|
||
|
|
*/
|
||
|
|
export async function addLevel(
|
||
|
|
groupCode: string,
|
||
|
|
data: Partial<HierarchyLevel>
|
||
|
|
): Promise<{
|
||
|
|
success: boolean;
|
||
|
|
data?: HierarchyLevel;
|
||
|
|
message?: string;
|
||
|
|
error?: string;
|
||
|
|
}> {
|
||
|
|
try {
|
||
|
|
const response = await apiClient.post(`/cascading-hierarchy/${groupCode}/levels`, data);
|
||
|
|
return response.data;
|
||
|
|
} catch (error: any) {
|
||
|
|
console.error("레벨 추가 실패:", error);
|
||
|
|
return {
|
||
|
|
success: false,
|
||
|
|
error: error.response?.data?.message || error.message,
|
||
|
|
};
|
||
|
|
}
|
||
|
|
}
|
||
|
|
|
||
|
|
/**
|
||
|
|
* 레벨 수정
|
||
|
|
*/
|
||
|
|
export async function updateLevel(
|
||
|
|
levelId: number,
|
||
|
|
data: Partial<HierarchyLevel>
|
||
|
|
): Promise<{
|
||
|
|
success: boolean;
|
||
|
|
data?: HierarchyLevel;
|
||
|
|
message?: string;
|
||
|
|
error?: string;
|
||
|
|
}> {
|
||
|
|
try {
|
||
|
|
const response = await apiClient.put(`/cascading-hierarchy/levels/${levelId}`, data);
|
||
|
|
return response.data;
|
||
|
|
} catch (error: any) {
|
||
|
|
console.error("레벨 수정 실패:", error);
|
||
|
|
return {
|
||
|
|
success: false,
|
||
|
|
error: error.response?.data?.message || error.message,
|
||
|
|
};
|
||
|
|
}
|
||
|
|
}
|
||
|
|
|
||
|
|
/**
|
||
|
|
* 레벨 삭제
|
||
|
|
*/
|
||
|
|
export async function deleteLevel(levelId: number): Promise<{
|
||
|
|
success: boolean;
|
||
|
|
message?: string;
|
||
|
|
error?: string;
|
||
|
|
}> {
|
||
|
|
try {
|
||
|
|
const response = await apiClient.delete(`/cascading-hierarchy/levels/${levelId}`);
|
||
|
|
return response.data;
|
||
|
|
} catch (error: any) {
|
||
|
|
console.error("레벨 삭제 실패:", error);
|
||
|
|
return {
|
||
|
|
success: false,
|
||
|
|
error: error.response?.data?.message || error.message,
|
||
|
|
};
|
||
|
|
}
|
||
|
|
}
|
||
|
|
|
||
|
|
/**
|
||
|
|
* 특정 레벨의 옵션 조회
|
||
|
|
*/
|
||
|
|
export async function getLevelOptions(
|
||
|
|
groupCode: string,
|
||
|
|
levelOrder: number,
|
||
|
|
parentValue?: string
|
||
|
|
): Promise<{
|
||
|
|
success: boolean;
|
||
|
|
data?: Array<{ value: string; label: string }>;
|
||
|
|
levelInfo?: {
|
||
|
|
levelId: number;
|
||
|
|
levelName: string;
|
||
|
|
placeholder: string;
|
||
|
|
isRequired: string;
|
||
|
|
isSearchable: string;
|
||
|
|
};
|
||
|
|
error?: string;
|
||
|
|
}> {
|
||
|
|
try {
|
||
|
|
const params = new URLSearchParams();
|
||
|
|
if (parentValue) params.append("parentValue", parentValue);
|
||
|
|
|
||
|
|
const response = await apiClient.get(
|
||
|
|
`/cascading-hierarchy/${groupCode}/options/${levelOrder}?${params.toString()}`
|
||
|
|
);
|
||
|
|
return response.data;
|
||
|
|
} catch (error: any) {
|
||
|
|
console.error("레벨 옵션 조회 실패:", error);
|
||
|
|
return {
|
||
|
|
success: false,
|
||
|
|
error: error.response?.data?.message || error.message,
|
||
|
|
};
|
||
|
|
}
|
||
|
|
}
|
||
|
|
|
||
|
|
// 편의를 위한 네임스페이스 export
|
||
|
|
export const hierarchyApi = {
|
||
|
|
getGroups: getHierarchyGroups,
|
||
|
|
getDetail: getHierarchyGroupDetail,
|
||
|
|
createGroup: createHierarchyGroup,
|
||
|
|
updateGroup: updateHierarchyGroup,
|
||
|
|
deleteGroup: deleteHierarchyGroup,
|
||
|
|
addLevel,
|
||
|
|
updateLevel,
|
||
|
|
deleteLevel,
|
||
|
|
getLevelOptions,
|
||
|
|
};
|
||
|
|
|