2348800e68
Build & Deploy to K8s / build-and-deploy (push) Successful in 9m22s
카테고리/캐스케이딩 시스템 (B/C/D) 전부 폐기:
- BE: mapper/Service/Controller 9세트 삭제 (cascading*, categoryTree, tableCategoryValue, categoryValueCascading, codeMerge)
- FE: 페이지 3 + API 8 + hooks 2 + 폐기 컴포넌트 6 삭제, 14곳 의존성 정리
- DB: 12 테이블 DROP, TABLE_TYPE_COLUMNS.CODE_CATEGORY → CODE_INFO rename
신설 commonCode 마스터-디테일:
- code_info: 1레벨 그룹 마스터
- code_detail: 2~∞ depth 재귀 트리 (parent_detail_id self-FK, depth 자동 계산)
- API: /api/common-codes/{info,detail}
- CodeCategoryFormModal/Panel → CodeInfoFormModal/Panel rename
- code_category 컬럼명 전부 code_info 로 치환 (mapper/Java/FE)
- 옛 commonCode API URL (/categories/...) → getCodeOptions 어댑터 + /detail?code_info=... 전환
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
203 lines
6.9 KiB
TypeScript
203 lines
6.9 KiB
TypeScript
import { apiClient } from "./client";
|
|
import type {
|
|
CodeInfo,
|
|
CodeDetail,
|
|
ApiResponse,
|
|
GetCodeInfoListQuery,
|
|
GetCodeDetailListQuery,
|
|
DuplicateCheckResult,
|
|
} from "@/types/commonCode";
|
|
|
|
/**
|
|
* 공통코드 API 클라이언트 (마스터-디테일 구조)
|
|
*
|
|
* code_info — 그룹 마스터
|
|
* code_detail — 트리 노드 (depth 2 시작, 무한 depth)
|
|
*
|
|
* 백엔드 계약 (BE Agent 가 만드는 것):
|
|
* /api/common-codes/info/...
|
|
* /api/common-codes/detail/...
|
|
*
|
|
* 응답 포맷:
|
|
* 목록: { success, data: [...], total: N, message }
|
|
* 단건/CRUD: { success, data: {...}, message }
|
|
*/
|
|
|
|
/* ───────────────────────── code_info (그룹 마스터) ───────────────────────── */
|
|
|
|
/** 그룹 목록 (페이징/검색) */
|
|
export async function getCodeInfoList(
|
|
params?: GetCodeInfoListQuery,
|
|
): Promise<ApiResponse<CodeInfo[]>> {
|
|
const search = new URLSearchParams();
|
|
if (params?.search) search.append("search", params.search);
|
|
if (params?.is_active !== undefined) search.append("is_active", params.is_active.toString());
|
|
if (params?.page !== undefined) search.append("page", params.page.toString());
|
|
if (params?.size !== undefined) search.append("size", params.size.toString());
|
|
|
|
const qs = search.toString();
|
|
const url = `/common-codes/info${qs ? `?${qs}` : ""}`;
|
|
const response = await apiClient.get(url);
|
|
return response.data;
|
|
}
|
|
|
|
/** 그룹 단건 */
|
|
export async function getCodeInfoInfo(codeInfo: string): Promise<ApiResponse<CodeInfo>> {
|
|
const response = await apiClient.get(`/common-codes/info/${encodeURIComponent(codeInfo)}`);
|
|
return response.data;
|
|
}
|
|
|
|
/** 그룹 생성 */
|
|
export async function createCodeInfo(data: Record<string, any>): Promise<ApiResponse<CodeInfo>> {
|
|
const response = await apiClient.post("/common-codes/info", data);
|
|
return response.data;
|
|
}
|
|
|
|
/** 그룹 수정 */
|
|
export async function updateCodeInfo(
|
|
codeInfo: string,
|
|
data: Record<string, any>,
|
|
): Promise<ApiResponse<CodeInfo>> {
|
|
const response = await apiClient.put(
|
|
`/common-codes/info/${encodeURIComponent(codeInfo)}`,
|
|
data,
|
|
);
|
|
return response.data;
|
|
}
|
|
|
|
/** 그룹 삭제 (CASCADE) */
|
|
export async function deleteCodeInfo(codeInfo: string): Promise<ApiResponse> {
|
|
const response = await apiClient.delete(`/common-codes/info/${encodeURIComponent(codeInfo)}`);
|
|
return response.data;
|
|
}
|
|
|
|
/** 그룹 중복 체크 */
|
|
export async function checkCodeInfoDuplicate(
|
|
field: "code_info" | "code_name" | "code_name_eng",
|
|
value: string,
|
|
excludeCode?: string,
|
|
): Promise<ApiResponse<DuplicateCheckResult>> {
|
|
const search = new URLSearchParams();
|
|
search.append("field", field);
|
|
search.append("value", value);
|
|
if (excludeCode) search.append("excludeCode", excludeCode);
|
|
const response = await apiClient.get(`/common-codes/info/check-duplicate?${search}`);
|
|
return response.data;
|
|
}
|
|
|
|
/* ───────────────────────── code_detail (디테일 트리) ───────────────────────── */
|
|
|
|
/** 그룹의 전체 디테일 트리 (depth+sort_order 평탄화 리스트) */
|
|
export async function getCodeDetailTree(
|
|
params: GetCodeDetailListQuery,
|
|
): Promise<ApiResponse<CodeDetail[]>> {
|
|
const search = new URLSearchParams();
|
|
search.append("code_info", params.code_info);
|
|
if (params.search) search.append("search", params.search);
|
|
if (params.is_active !== undefined) search.append("is_active", params.is_active.toString());
|
|
|
|
const response = await apiClient.get(`/common-codes/detail?${search}`);
|
|
return response.data;
|
|
}
|
|
|
|
/** 디테일 단건 */
|
|
export async function getCodeDetailInfo(
|
|
codeDetailId: number | string,
|
|
): Promise<ApiResponse<CodeDetail>> {
|
|
const response = await apiClient.get(`/common-codes/detail/${codeDetailId}`);
|
|
return response.data;
|
|
}
|
|
|
|
/** 디테일 생성 */
|
|
export async function createCodeDetail(
|
|
data: Record<string, any>,
|
|
): Promise<ApiResponse<CodeDetail>> {
|
|
const response = await apiClient.post("/common-codes/detail", data);
|
|
return response.data;
|
|
}
|
|
|
|
/** 디테일 수정 */
|
|
export async function updateCodeDetail(
|
|
codeDetailId: number | string,
|
|
data: Record<string, any>,
|
|
): Promise<ApiResponse<CodeDetail>> {
|
|
const response = await apiClient.put(`/common-codes/detail/${codeDetailId}`, data);
|
|
return response.data;
|
|
}
|
|
|
|
/** 디테일 삭제 (CASCADE) */
|
|
export async function deleteCodeDetail(codeDetailId: number | string): Promise<ApiResponse> {
|
|
const response = await apiClient.delete(`/common-codes/detail/${codeDetailId}`);
|
|
return response.data;
|
|
}
|
|
|
|
/** 디테일 중복 체크 (그룹 + 필드 단위) */
|
|
export async function checkCodeDetailDuplicate(
|
|
codeInfo: string,
|
|
field: "code_value" | "code_name" | "code_name_eng",
|
|
value: string,
|
|
excludeId?: number | string,
|
|
): Promise<ApiResponse<DuplicateCheckResult>> {
|
|
const search = new URLSearchParams();
|
|
search.append("code_info", codeInfo);
|
|
search.append("field", field);
|
|
search.append("value", value);
|
|
if (excludeId !== undefined && excludeId !== null && excludeId !== "") {
|
|
search.append("excludeId", String(excludeId));
|
|
}
|
|
const response = await apiClient.get(`/common-codes/detail/check-duplicate?${search}`);
|
|
return response.data;
|
|
}
|
|
|
|
/* ───────────────────────── compat: 화면관리/캐시에서 사용 ───────────────────────── */
|
|
|
|
/**
|
|
* 그룹의 활성 디테일 옵션 (label/value)
|
|
* 기존 `commonCodeApi.options.getOptions(categoryCode)` 의 대체.
|
|
*/
|
|
export async function getCodeOptions(
|
|
codeInfo: string,
|
|
): Promise<ApiResponse<Array<{ value: string; label: string; depth?: number; parent_detail_id?: number | null }>>> {
|
|
const tree = await getCodeDetailTree({ code_info: codeInfo, is_active: true });
|
|
const options = (tree.data || []).map((row) => ({
|
|
value: row.code_value,
|
|
label: row.code_name || row.code_value,
|
|
depth: row.depth,
|
|
parent_detail_id: row.parent_detail_id ?? null,
|
|
}));
|
|
return {
|
|
success: tree.success,
|
|
data: options,
|
|
message: tree.message,
|
|
total: options.length,
|
|
};
|
|
}
|
|
|
|
/**
|
|
* 호환 객체. 기존 코드가 `commonCodeApi.codes.getList(category, ...)` 등으로 부르고 있어
|
|
* 깨끗한 1안 마이그레이션 동안 임시로 노출. 새 코드는 위 함수들을 직접 import.
|
|
*
|
|
* NOTE: 사용처가 점진적으로 제거되면 이 객체도 삭제.
|
|
*/
|
|
export const commonCodeApi = {
|
|
info: {
|
|
getList: getCodeInfoList,
|
|
get: getCodeInfoInfo,
|
|
create: createCodeInfo,
|
|
update: updateCodeInfo,
|
|
delete: deleteCodeInfo,
|
|
checkDuplicate: checkCodeInfoDuplicate,
|
|
},
|
|
detail: {
|
|
getTree: getCodeDetailTree,
|
|
get: getCodeDetailInfo,
|
|
create: createCodeDetail,
|
|
update: updateCodeDetail,
|
|
delete: deleteCodeDetail,
|
|
checkDuplicate: checkCodeDetailDuplicate,
|
|
},
|
|
options: {
|
|
getOptions: getCodeOptions,
|
|
},
|
|
};
|