363 lines
7.9 KiB
TypeScript
363 lines
7.9 KiB
TypeScript
/**
|
|
* 다국어 관리 API 클라이언트
|
|
* 카테고리, 키 자동 생성, 오버라이드 등 확장 기능 포함
|
|
*/
|
|
|
|
import { apiClient } from "./client";
|
|
|
|
// =====================================================
|
|
// 타입 정의
|
|
// =====================================================
|
|
|
|
export interface Language {
|
|
langCode: string;
|
|
langName: string;
|
|
langNative: string;
|
|
isActive: string;
|
|
sortOrder?: number;
|
|
}
|
|
|
|
export interface LangCategory {
|
|
categoryId: number;
|
|
categoryCode: string;
|
|
categoryName: string;
|
|
parentId?: number | null;
|
|
level: number;
|
|
keyPrefix: string;
|
|
description?: string;
|
|
sortOrder: number;
|
|
isActive: string;
|
|
children?: LangCategory[];
|
|
}
|
|
|
|
export interface LangKey {
|
|
keyId?: number;
|
|
companyCode: string;
|
|
menuName?: string;
|
|
langKey: string;
|
|
description?: string;
|
|
isActive: string;
|
|
categoryId?: number;
|
|
keyMeaning?: string;
|
|
usageNote?: string;
|
|
baseKeyId?: number;
|
|
createdDate?: Date;
|
|
}
|
|
|
|
export interface LangText {
|
|
textId?: number;
|
|
keyId: number;
|
|
langCode: string;
|
|
langText: string;
|
|
isActive: string;
|
|
}
|
|
|
|
export interface GenerateKeyRequest {
|
|
companyCode: string;
|
|
categoryId: number;
|
|
keyMeaning: string;
|
|
usageNote?: string;
|
|
texts: Array<{
|
|
langCode: string;
|
|
langText: string;
|
|
}>;
|
|
}
|
|
|
|
export interface CreateOverrideKeyRequest {
|
|
companyCode: string;
|
|
baseKeyId: number;
|
|
texts: Array<{
|
|
langCode: string;
|
|
langText: string;
|
|
}>;
|
|
}
|
|
|
|
export interface KeyPreview {
|
|
langKey: string;
|
|
exists: boolean;
|
|
isOverride: boolean;
|
|
baseKeyId?: number;
|
|
}
|
|
|
|
export interface ApiResponse<T> {
|
|
success: boolean;
|
|
message?: string;
|
|
data?: T;
|
|
error?: {
|
|
code: string;
|
|
details?: any;
|
|
};
|
|
}
|
|
|
|
// =====================================================
|
|
// 카테고리 관련 API
|
|
// =====================================================
|
|
|
|
/**
|
|
* 카테고리 트리 조회
|
|
*/
|
|
export async function getCategories(): Promise<ApiResponse<LangCategory[]>> {
|
|
try {
|
|
const response = await apiClient.get("/multilang/categories");
|
|
return response.data;
|
|
} catch (error: any) {
|
|
return {
|
|
success: false,
|
|
error: {
|
|
code: "CATEGORY_FETCH_ERROR",
|
|
details: error.message,
|
|
},
|
|
};
|
|
}
|
|
}
|
|
|
|
/**
|
|
* 카테고리 상세 조회
|
|
*/
|
|
export async function getCategoryById(categoryId: number): Promise<ApiResponse<LangCategory>> {
|
|
try {
|
|
const response = await apiClient.get(`/multilang/categories/${categoryId}`);
|
|
return response.data;
|
|
} catch (error: any) {
|
|
return {
|
|
success: false,
|
|
error: {
|
|
code: "CATEGORY_FETCH_ERROR",
|
|
details: error.message,
|
|
},
|
|
};
|
|
}
|
|
}
|
|
|
|
/**
|
|
* 카테고리 경로 조회 (부모 포함)
|
|
*/
|
|
export async function getCategoryPath(categoryId: number): Promise<ApiResponse<LangCategory[]>> {
|
|
try {
|
|
const response = await apiClient.get(`/multilang/categories/${categoryId}/path`);
|
|
return response.data;
|
|
} catch (error: any) {
|
|
return {
|
|
success: false,
|
|
error: {
|
|
code: "CATEGORY_PATH_ERROR",
|
|
details: error.message,
|
|
},
|
|
};
|
|
}
|
|
}
|
|
|
|
// =====================================================
|
|
// 언어 관련 API
|
|
// =====================================================
|
|
|
|
/**
|
|
* 언어 목록 조회
|
|
*/
|
|
export async function getLanguages(): Promise<ApiResponse<Language[]>> {
|
|
try {
|
|
const response = await apiClient.get("/multilang/languages");
|
|
return response.data;
|
|
} catch (error: any) {
|
|
return {
|
|
success: false,
|
|
error: {
|
|
code: "LANGUAGE_FETCH_ERROR",
|
|
details: error.message,
|
|
},
|
|
};
|
|
}
|
|
}
|
|
|
|
// =====================================================
|
|
// 키 관련 API
|
|
// =====================================================
|
|
|
|
/**
|
|
* 다국어 키 목록 조회
|
|
*/
|
|
export async function getLangKeys(params?: {
|
|
companyCode?: string;
|
|
menuCode?: string;
|
|
categoryId?: number;
|
|
searchText?: string;
|
|
}): Promise<ApiResponse<LangKey[]>> {
|
|
try {
|
|
const queryParams = new URLSearchParams();
|
|
if (params?.companyCode) queryParams.append("companyCode", params.companyCode);
|
|
if (params?.menuCode) queryParams.append("menuCode", params.menuCode);
|
|
if (params?.categoryId) queryParams.append("categoryId", params.categoryId.toString());
|
|
if (params?.searchText) queryParams.append("searchText", params.searchText);
|
|
|
|
const url = `/multilang/keys${queryParams.toString() ? `?${queryParams.toString()}` : ""}`;
|
|
const response = await apiClient.get(url);
|
|
return response.data;
|
|
} catch (error: any) {
|
|
return {
|
|
success: false,
|
|
error: {
|
|
code: "KEYS_FETCH_ERROR",
|
|
details: error.message,
|
|
},
|
|
};
|
|
}
|
|
}
|
|
|
|
/**
|
|
* 키의 텍스트 조회
|
|
*/
|
|
export async function getLangTexts(keyId: number): Promise<ApiResponse<LangText[]>> {
|
|
try {
|
|
const response = await apiClient.get(`/multilang/keys/${keyId}/texts`);
|
|
return response.data;
|
|
} catch (error: any) {
|
|
return {
|
|
success: false,
|
|
error: {
|
|
code: "TEXTS_FETCH_ERROR",
|
|
details: error.message,
|
|
},
|
|
};
|
|
}
|
|
}
|
|
|
|
/**
|
|
* 키 자동 생성
|
|
*/
|
|
export async function generateKey(data: GenerateKeyRequest): Promise<ApiResponse<number>> {
|
|
try {
|
|
const response = await apiClient.post("/multilang/keys/generate", data);
|
|
return response.data;
|
|
} catch (error: any) {
|
|
return {
|
|
success: false,
|
|
error: {
|
|
code: "KEY_GENERATE_ERROR",
|
|
details: error.response?.data?.error?.details || error.message,
|
|
},
|
|
};
|
|
}
|
|
}
|
|
|
|
/**
|
|
* 키 미리보기
|
|
*/
|
|
export async function previewKey(
|
|
categoryId: number,
|
|
keyMeaning: string,
|
|
companyCode: string
|
|
): Promise<ApiResponse<KeyPreview>> {
|
|
try {
|
|
const response = await apiClient.post("/multilang/keys/preview", {
|
|
categoryId,
|
|
keyMeaning,
|
|
companyCode,
|
|
});
|
|
return response.data;
|
|
} catch (error: any) {
|
|
return {
|
|
success: false,
|
|
error: {
|
|
code: "KEY_PREVIEW_ERROR",
|
|
details: error.message,
|
|
},
|
|
};
|
|
}
|
|
}
|
|
|
|
/**
|
|
* 오버라이드 키 생성
|
|
*/
|
|
export async function createOverrideKey(
|
|
data: CreateOverrideKeyRequest
|
|
): Promise<ApiResponse<number>> {
|
|
try {
|
|
const response = await apiClient.post("/multilang/keys/override", data);
|
|
return response.data;
|
|
} catch (error: any) {
|
|
return {
|
|
success: false,
|
|
error: {
|
|
code: "OVERRIDE_CREATE_ERROR",
|
|
details: error.response?.data?.error?.details || error.message,
|
|
},
|
|
};
|
|
}
|
|
}
|
|
|
|
/**
|
|
* 회사별 오버라이드 키 목록 조회
|
|
*/
|
|
export async function getOverrideKeys(companyCode: string): Promise<ApiResponse<LangKey[]>> {
|
|
try {
|
|
const response = await apiClient.get(`/multilang/keys/overrides/${companyCode}`);
|
|
return response.data;
|
|
} catch (error: any) {
|
|
return {
|
|
success: false,
|
|
error: {
|
|
code: "OVERRIDE_KEYS_FETCH_ERROR",
|
|
details: error.message,
|
|
},
|
|
};
|
|
}
|
|
}
|
|
|
|
/**
|
|
* 키 텍스트 저장
|
|
*/
|
|
export async function saveLangTexts(
|
|
keyId: number,
|
|
texts: Array<{ langCode: string; langText: string }>
|
|
): Promise<ApiResponse<string>> {
|
|
try {
|
|
const response = await apiClient.post(`/multilang/keys/${keyId}/texts`, { texts });
|
|
return response.data;
|
|
} catch (error: any) {
|
|
return {
|
|
success: false,
|
|
error: {
|
|
code: "TEXTS_SAVE_ERROR",
|
|
details: error.message,
|
|
},
|
|
};
|
|
}
|
|
}
|
|
|
|
/**
|
|
* 키 삭제
|
|
*/
|
|
export async function deleteLangKey(keyId: number): Promise<ApiResponse<string>> {
|
|
try {
|
|
const response = await apiClient.delete(`/multilang/keys/${keyId}`);
|
|
return response.data;
|
|
} catch (error: any) {
|
|
return {
|
|
success: false,
|
|
error: {
|
|
code: "KEY_DELETE_ERROR",
|
|
details: error.message,
|
|
},
|
|
};
|
|
}
|
|
}
|
|
|
|
/**
|
|
* 키 상태 토글
|
|
*/
|
|
export async function toggleLangKey(keyId: number): Promise<ApiResponse<string>> {
|
|
try {
|
|
const response = await apiClient.put(`/multilang/keys/${keyId}/toggle`);
|
|
return response.data;
|
|
} catch (error: any) {
|
|
return {
|
|
success: false,
|
|
error: {
|
|
code: "KEY_TOGGLE_ERROR",
|
|
details: error.message,
|
|
},
|
|
};
|
|
}
|
|
}
|
|
|