회사관리, 메뉴관리 수정,삭제 기능
This commit is contained in:
@@ -1,25 +1,22 @@
|
||||
import { useMultiLang } from "@/hooks/useMultiLang";
|
||||
import { apiClient } from "../api/client";
|
||||
|
||||
// 메뉴 관리 화면 다국어 키 상수
|
||||
export const MENU_MANAGEMENT_KEYS = {
|
||||
// 메뉴 타입 관련
|
||||
TITLE: "menu.management.title",
|
||||
DESCRIPTION: "menu.management.description",
|
||||
// 기본 정보
|
||||
TITLE: "title",
|
||||
DESCRIPTION: "description",
|
||||
MENU_TYPE_TITLE: "menu.type.title",
|
||||
ADMIN_MENU: "menu.management.admin",
|
||||
USER_MENU: "menu.management.user",
|
||||
ADMIN_DESCRIPTION: "menu.management.admin.description",
|
||||
USER_DESCRIPTION: "menu.management.user.description",
|
||||
MENU_TYPE_ADMIN: "menu.type.admin",
|
||||
MENU_TYPE_USER: "menu.type.user",
|
||||
ADMIN_MENU: "admin.menu",
|
||||
USER_MENU: "user.menu",
|
||||
ADMIN_DESCRIPTION: "admin.description",
|
||||
USER_DESCRIPTION: "user.description",
|
||||
LIST_TITLE: "list.title",
|
||||
LIST_TOTAL: "list.total",
|
||||
LIST_SEARCH_RESULT: "list.search.result",
|
||||
|
||||
// 메뉴 목록 관련
|
||||
LIST_TITLE: "menu.list.title",
|
||||
LIST_TOTAL: "menu.list.total",
|
||||
LIST_SEARCH_RESULT: "menu.list.search.result",
|
||||
|
||||
// 필터 및 검색 관련
|
||||
// 필터 관련
|
||||
FILTER_COMPANY: "filter.company",
|
||||
FILTER_COMPANY_ALL: "filter.company.all",
|
||||
FILTER_COMPANY_COMMON: "filter.company.common",
|
||||
@@ -43,7 +40,7 @@ export const MENU_MANAGEMENT_KEYS = {
|
||||
BUTTON_REGISTER: "button.register",
|
||||
BUTTON_MODIFY: "button.modify",
|
||||
|
||||
// 메뉴 폼 관련
|
||||
// 폼 관련
|
||||
FORM_MENU_TYPE: "form.menu.type",
|
||||
FORM_MENU_TYPE_ADMIN: "form.menu.type.admin",
|
||||
FORM_MENU_TYPE_USER: "form.menu.type.user",
|
||||
@@ -115,215 +112,172 @@ export const MENU_MANAGEMENT_KEYS = {
|
||||
UI_LANGUAGE: "ui.language",
|
||||
} as const;
|
||||
|
||||
// 다국어 텍스트 가져오기 함수
|
||||
export const useMenuManagementText = () => {
|
||||
const { getText } = useMultiLang({ companyCode: "*" });
|
||||
// 다국어 텍스트 캐시 (메모리 기반)
|
||||
const translationCache: Record<string, Record<string, string>> = {};
|
||||
|
||||
const getMenuText = async (key: string, params?: Record<string, string | number>): Promise<string> => {
|
||||
let text = await getText("MENU_MANAGEMENT", key);
|
||||
// 배치 조회를 위한 키 수집기
|
||||
const pendingKeys: Set<string> = new Set();
|
||||
let batchTimeout: NodeJS.Timeout | null = null;
|
||||
const BATCH_DELAY = 50; // 50ms 지연으로 배치 처리
|
||||
|
||||
// 파라미터 치환
|
||||
if (params) {
|
||||
Object.entries(params).forEach(([paramKey, paramValue]) => {
|
||||
text = text.replace(new RegExp(`\\{${paramKey}\\}`, "g"), paramValue.toString());
|
||||
});
|
||||
/**
|
||||
* 다국어 텍스트 배치 조회
|
||||
* 여러 키를 한번에 조회하여 API 호출 횟수를 대폭 줄임
|
||||
*/
|
||||
async function fetchBatchTranslations(
|
||||
keys: string[],
|
||||
companyCode: string = "*",
|
||||
menuCode: string = "MENU_MANAGEMENT",
|
||||
userLang: string = "KR",
|
||||
): Promise<Record<string, string>> {
|
||||
try {
|
||||
console.log(`🚀 배치 조회 시작: ${keys.length}개 키`);
|
||||
|
||||
const response = await apiClient.post(
|
||||
"/multilang/batch",
|
||||
{
|
||||
langKeys: keys,
|
||||
},
|
||||
{
|
||||
params: {
|
||||
companyCode,
|
||||
menuCode,
|
||||
userLang,
|
||||
},
|
||||
},
|
||||
);
|
||||
|
||||
if (response.data.success) {
|
||||
console.log(`✅ 배치 조회 성공: ${keys.length}개 키`);
|
||||
return response.data.data || {};
|
||||
} else {
|
||||
console.error("❌ 배치 조회 실패:", response.data.message);
|
||||
return {};
|
||||
}
|
||||
} catch (error) {
|
||||
console.error("❌ 배치 조회 오류:", error);
|
||||
return {};
|
||||
}
|
||||
}
|
||||
|
||||
return text;
|
||||
};
|
||||
|
||||
return {
|
||||
getMenuText,
|
||||
keys: MENU_MANAGEMENT_KEYS,
|
||||
};
|
||||
};
|
||||
|
||||
// 전역 번역 캐시
|
||||
let translationCache: Record<string, Record<string, string>> = {};
|
||||
|
||||
// 번역 캐시 설정 함수
|
||||
export const setTranslationCache = (lang: string, translations: Record<string, string>) => {
|
||||
translationCache[lang] = translations;
|
||||
};
|
||||
|
||||
// 번역 캐시 가져오기 함수
|
||||
export const getTranslationCache = (lang: string): Record<string, string> => {
|
||||
return translationCache[lang] || {};
|
||||
};
|
||||
|
||||
// 동기적 다국어 텍스트 가져오기 (캐시된 값 사용)
|
||||
export const getMenuTextSync = (key: string, params?: Record<string, any>): string => {
|
||||
// 전역 언어 상태 확인
|
||||
const userLang = (typeof window !== "undefined" && (window as any).__GLOBAL_USER_LANG) || "KR";
|
||||
|
||||
// 현재 언어가 한국어가 아니면 캐시에서 번역 텍스트 찾기
|
||||
if (userLang !== "KR") {
|
||||
// 1. 먼저 전역 캐시에서 찾기
|
||||
const cachedTranslations = getTranslationCache(userLang);
|
||||
if (cachedTranslations[key]) {
|
||||
let text = cachedTranslations[key];
|
||||
|
||||
// 파라미터 치환
|
||||
if (params) {
|
||||
Object.entries(params).forEach(([paramKey, paramValue]) => {
|
||||
text = text.replace(new RegExp(`\\{${paramKey}\\}`, "g"), paramValue.toString());
|
||||
});
|
||||
}
|
||||
|
||||
return text;
|
||||
}
|
||||
|
||||
// 2. 개별 캐시에서 찾기
|
||||
const individualCache = (typeof window !== "undefined" && (window as any).__TRANSLATION_CACHE) || {};
|
||||
const cacheKey = `MENU_MANAGEMENT.${key}`;
|
||||
if (individualCache[cacheKey]) {
|
||||
let text = individualCache[cacheKey];
|
||||
|
||||
// 파라미터 치환
|
||||
if (params) {
|
||||
Object.entries(params).forEach(([paramKey, paramValue]) => {
|
||||
text = text.replace(new RegExp(`\\{${paramKey}\\}`, "g"), paramValue.toString());
|
||||
});
|
||||
}
|
||||
|
||||
console.log(`✅ 개별 캐시에서 번역 사용:`, { key, result: text, userLang });
|
||||
return text;
|
||||
}
|
||||
|
||||
// 3. 캐시에 없으면 비동기적으로 로드 시도
|
||||
console.log(`⚠️ getMenuTextSync: 캐시에 번역이 없습니다. 키: ${key}, 언어: ${userLang}`);
|
||||
|
||||
// 비동기적으로 번역 로드 (백그라운드에서)
|
||||
if (typeof window !== "undefined") {
|
||||
const companyCode = "*";
|
||||
|
||||
apiClient
|
||||
.get(`/multilang/user-text/${companyCode}/MENU_MANAGEMENT/${key}?userLang=${userLang}`)
|
||||
.then((response) => {
|
||||
if (response.data.success && response.data.data) {
|
||||
// 개별 캐시에 저장
|
||||
const currentCache = (window as any).__TRANSLATION_CACHE || {};
|
||||
currentCache[cacheKey] = data.data;
|
||||
(window as any).__TRANSLATION_CACHE = currentCache;
|
||||
|
||||
// 전역 캐시에도 저장
|
||||
const globalCache = getTranslationCache(userLang);
|
||||
globalCache[key] = data.data;
|
||||
setTranslationCache(userLang, globalCache);
|
||||
|
||||
// 페이지 리렌더링을 위해 이벤트 발생
|
||||
window.dispatchEvent(
|
||||
new CustomEvent("translation-loaded", {
|
||||
detail: { key, text: data.data, userLang },
|
||||
}),
|
||||
);
|
||||
}
|
||||
})
|
||||
.catch((error) => {
|
||||
console.error(`❌ 백그라운드 번역 로드 실패:`, { key, error });
|
||||
});
|
||||
}
|
||||
|
||||
// 캐시에 없으면 기본 텍스트에서 찾기
|
||||
const defaultTexts: Record<string, string> = {
|
||||
[MENU_MANAGEMENT_KEYS.TITLE]: "메뉴 관리",
|
||||
[MENU_MANAGEMENT_KEYS.DESCRIPTION]: "시스템의 메뉴 구조와 권한을 관리합니다.",
|
||||
[MENU_MANAGEMENT_KEYS.MENU_TYPE_TITLE]: "메뉴 타입",
|
||||
[MENU_MANAGEMENT_KEYS.MENU_TYPE_ADMIN]: "관리자",
|
||||
[MENU_MANAGEMENT_KEYS.MENU_TYPE_USER]: "사용자",
|
||||
[MENU_MANAGEMENT_KEYS.ADMIN_MENU]: "관리자 메뉴",
|
||||
[MENU_MANAGEMENT_KEYS.USER_MENU]: "사용자 메뉴",
|
||||
[MENU_MANAGEMENT_KEYS.ADMIN_DESCRIPTION]: "시스템 관리 및 설정 메뉴",
|
||||
[MENU_MANAGEMENT_KEYS.USER_DESCRIPTION]: "일반 사용자 업무 메뉴",
|
||||
[MENU_MANAGEMENT_KEYS.BUTTON_ADD]: "추가",
|
||||
[MENU_MANAGEMENT_KEYS.BUTTON_ADD_TOP_LEVEL]: "최상위 메뉴 추가",
|
||||
[MENU_MANAGEMENT_KEYS.BUTTON_ADD_SUB]: "하위 메뉴 추가",
|
||||
[MENU_MANAGEMENT_KEYS.BUTTON_EDIT]: "수정",
|
||||
[MENU_MANAGEMENT_KEYS.BUTTON_DELETE]: "삭제",
|
||||
[MENU_MANAGEMENT_KEYS.BUTTON_DELETE_SELECTED]: "선택 삭제",
|
||||
[MENU_MANAGEMENT_KEYS.BUTTON_DELETE_SELECTED_COUNT]: "선택 삭제 ({count})",
|
||||
[MENU_MANAGEMENT_KEYS.BUTTON_DELETE_PROCESSING]: "삭제 중...",
|
||||
[MENU_MANAGEMENT_KEYS.BUTTON_CANCEL]: "취소",
|
||||
[MENU_MANAGEMENT_KEYS.BUTTON_SAVE]: "저장",
|
||||
[MENU_MANAGEMENT_KEYS.BUTTON_SAVE_PROCESSING]: "저장 중...",
|
||||
[MENU_MANAGEMENT_KEYS.BUTTON_REGISTER]: "등록",
|
||||
[MENU_MANAGEMENT_KEYS.BUTTON_MODIFY]: "수정",
|
||||
[MENU_MANAGEMENT_KEYS.FORM_MENU_TYPE]: "메뉴 타입",
|
||||
[MENU_MANAGEMENT_KEYS.FORM_MENU_TYPE_ADMIN]: "관리자",
|
||||
[MENU_MANAGEMENT_KEYS.FORM_MENU_TYPE_USER]: "사용자",
|
||||
[MENU_MANAGEMENT_KEYS.FORM_STATUS]: "상태",
|
||||
[MENU_MANAGEMENT_KEYS.FORM_STATUS_ACTIVE]: "활성화",
|
||||
[MENU_MANAGEMENT_KEYS.FORM_STATUS_INACTIVE]: "비활성화",
|
||||
[MENU_MANAGEMENT_KEYS.FORM_COMPANY]: "회사",
|
||||
[MENU_MANAGEMENT_KEYS.FORM_COMPANY_SELECT]: "회사를 선택하세요",
|
||||
[MENU_MANAGEMENT_KEYS.FORM_COMPANY_COMMON]: "공통",
|
||||
[MENU_MANAGEMENT_KEYS.FORM_COMPANY_SUBMENU_NOTE]: "하위 메뉴는 상위 메뉴와 동일한 회사를 가져야 합니다.",
|
||||
[MENU_MANAGEMENT_KEYS.FORM_MENU_NAME]: "메뉴명",
|
||||
[MENU_MANAGEMENT_KEYS.FORM_MENU_NAME_PLACEHOLDER]: "메뉴명을 입력하세요",
|
||||
[MENU_MANAGEMENT_KEYS.FORM_MENU_URL]: "URL",
|
||||
[MENU_MANAGEMENT_KEYS.FORM_MENU_URL_PLACEHOLDER]: "메뉴 URL을 입력하세요",
|
||||
[MENU_MANAGEMENT_KEYS.FORM_MENU_DESCRIPTION]: "설명",
|
||||
[MENU_MANAGEMENT_KEYS.FORM_MENU_DESCRIPTION_PLACEHOLDER]: "메뉴 설명을 입력하세요",
|
||||
[MENU_MANAGEMENT_KEYS.FORM_MENU_SEQUENCE]: "순서",
|
||||
[MENU_MANAGEMENT_KEYS.FORM_LANG_KEY]: "다국어 키",
|
||||
[MENU_MANAGEMENT_KEYS.FORM_LANG_KEY_SELECT]: "다국어 키를 선택하세요",
|
||||
[MENU_MANAGEMENT_KEYS.FORM_LANG_KEY_NONE]: "다국어 키 없음",
|
||||
[MENU_MANAGEMENT_KEYS.FORM_LANG_KEY_SEARCH]: "다국어 키 검색...",
|
||||
[MENU_MANAGEMENT_KEYS.FORM_LANG_KEY_SELECTED]: "선택된 키: {key} - {description}",
|
||||
[MENU_MANAGEMENT_KEYS.MODAL_MENU_REGISTER_TITLE]: "메뉴 등록",
|
||||
[MENU_MANAGEMENT_KEYS.MODAL_MENU_MODIFY_TITLE]: "메뉴 수정",
|
||||
[MENU_MANAGEMENT_KEYS.MODAL_DELETE_TITLE]: "메뉴 삭제",
|
||||
[MENU_MANAGEMENT_KEYS.MODAL_DELETE_DESCRIPTION]: "해당 메뉴를 삭제하시겠습니까? 이 작업은 되돌릴 수 없습니다.",
|
||||
[MENU_MANAGEMENT_KEYS.MODAL_DELETE_BATCH_DESCRIPTION]:
|
||||
"선택된 {count}개의 메뉴를 영구적으로 삭제하시겠습니까?\n\n⚠️ 주의: 상위 메뉴를 삭제하면 하위 메뉴들도 함께 삭제됩니다.\n이 작업은 되돌릴 수 없습니다.",
|
||||
[MENU_MANAGEMENT_KEYS.TABLE_HEADER_SELECT]: "선택",
|
||||
[MENU_MANAGEMENT_KEYS.TABLE_HEADER_MENU_NAME]: "메뉴명",
|
||||
[MENU_MANAGEMENT_KEYS.TABLE_HEADER_MENU_URL]: "URL",
|
||||
[MENU_MANAGEMENT_KEYS.TABLE_HEADER_MENU_TYPE]: "메뉴 타입",
|
||||
[MENU_MANAGEMENT_KEYS.TABLE_HEADER_STATUS]: "상태",
|
||||
[MENU_MANAGEMENT_KEYS.TABLE_HEADER_COMPANY]: "회사",
|
||||
[MENU_MANAGEMENT_KEYS.TABLE_HEADER_SEQUENCE]: "순서",
|
||||
[MENU_MANAGEMENT_KEYS.TABLE_HEADER_ACTIONS]: "작업",
|
||||
[MENU_MANAGEMENT_KEYS.STATUS_ACTIVE]: "활성화",
|
||||
[MENU_MANAGEMENT_KEYS.STATUS_INACTIVE]: "비활성화",
|
||||
[MENU_MANAGEMENT_KEYS.STATUS_UNSPECIFIED]: "미지정",
|
||||
[MENU_MANAGEMENT_KEYS.MESSAGE_LOADING]: "로딩 중...",
|
||||
[MENU_MANAGEMENT_KEYS.MESSAGE_MENU_DELETE_PROCESSING]: "메뉴 삭제 중...",
|
||||
[MENU_MANAGEMENT_KEYS.MESSAGE_MENU_SAVE_SUCCESS]: "메뉴가 저장되었습니다.",
|
||||
[MENU_MANAGEMENT_KEYS.MESSAGE_MENU_SAVE_FAILED]: "메뉴 저장에 실패했습니다.",
|
||||
[MENU_MANAGEMENT_KEYS.MESSAGE_MENU_DELETE_SUCCESS]: "메뉴가 삭제되었습니다.",
|
||||
[MENU_MANAGEMENT_KEYS.MESSAGE_MENU_DELETE_FAILED]: "메뉴 삭제에 실패했습니다.",
|
||||
[MENU_MANAGEMENT_KEYS.MESSAGE_MENU_DELETE_BATCH_SUCCESS]:
|
||||
"✅ {count}개의 메뉴(및 하위 메뉴)가 성공적으로 삭제되었습니다!",
|
||||
[MENU_MANAGEMENT_KEYS.MESSAGE_MENU_DELETE_BATCH_PARTIAL]: "⚠️ {success}개 삭제 성공, {failed}개 삭제 실패",
|
||||
[MENU_MANAGEMENT_KEYS.MESSAGE_MENU_STATUS_TOGGLE_SUCCESS]: "메뉴 상태가 변경되었습니다.",
|
||||
[MENU_MANAGEMENT_KEYS.MESSAGE_MENU_STATUS_TOGGLE_FAILED]: "메뉴 상태 변경에 실패했습니다.",
|
||||
[MENU_MANAGEMENT_KEYS.MESSAGE_VALIDATION_MENU_NAME_REQUIRED]: "메뉴명을 입력해주세요.",
|
||||
[MENU_MANAGEMENT_KEYS.MESSAGE_VALIDATION_COMPANY_REQUIRED]: "회사를 선택해주세요.",
|
||||
[MENU_MANAGEMENT_KEYS.MESSAGE_VALIDATION_SELECT_MENU_DELETE]: "삭제할 메뉴를 선택해주세요.",
|
||||
[MENU_MANAGEMENT_KEYS.MESSAGE_ERROR_LOAD_MENU_LIST]: "메뉴 목록을 불러오는데 실패했습니다.",
|
||||
[MENU_MANAGEMENT_KEYS.MESSAGE_ERROR_LOAD_MENU_INFO]: "메뉴 정보를 불러오는데 실패했습니다.",
|
||||
[MENU_MANAGEMENT_KEYS.MESSAGE_ERROR_LOAD_COMPANY_LIST]: "회사 목록을 불러오는데 실패했습니다.",
|
||||
[MENU_MANAGEMENT_KEYS.MESSAGE_ERROR_LOAD_LANG_KEY_LIST]: "다국어 키 목록을 불러오는데 실패했습니다.",
|
||||
[MENU_MANAGEMENT_KEYS.UI_EXPAND]: "펼치기",
|
||||
[MENU_MANAGEMENT_KEYS.UI_COLLAPSE]: "접기",
|
||||
[MENU_MANAGEMENT_KEYS.UI_MENU_COLLAPSE]: "메뉴 접기",
|
||||
[MENU_MANAGEMENT_KEYS.UI_LANGUAGE]: "언어",
|
||||
};
|
||||
|
||||
let text = defaultTexts[key] || key;
|
||||
|
||||
// 파라미터 치환
|
||||
if (params) {
|
||||
Object.entries(params).forEach(([paramKey, paramValue]) => {
|
||||
text = text.replace(new RegExp(`\\{${paramKey}\\}`, "g"), paramValue.toString());
|
||||
});
|
||||
}
|
||||
|
||||
return text;
|
||||
/**
|
||||
* 개별 다국어 텍스트 조회 (배치 처리)
|
||||
* 실제로는 배치로 처리되어 API 호출 횟수가 대폭 감소
|
||||
*/
|
||||
export async function getMultilangText(
|
||||
key: string,
|
||||
companyCode: string = "*",
|
||||
menuCode: string = "MENU_MANAGEMENT",
|
||||
userLang: string = "KR",
|
||||
): Promise<string> {
|
||||
// 1. 캐시에서 먼저 확인
|
||||
const cacheKey = `${userLang}_${companyCode}_${menuCode}`;
|
||||
if (translationCache[cacheKey]?.[key]) {
|
||||
return translationCache[cacheKey][key];
|
||||
}
|
||||
|
||||
// 한국어인 경우 기본 텍스트 반환
|
||||
// 2. 기본 텍스트에서 확인
|
||||
const defaultText = getDefaultText(key);
|
||||
if (defaultText) {
|
||||
return defaultText;
|
||||
}
|
||||
|
||||
// 3. 배치 처리에 추가
|
||||
pendingKeys.add(key);
|
||||
|
||||
// 4. 배치 타임아웃 설정
|
||||
if (batchTimeout) {
|
||||
clearTimeout(batchTimeout);
|
||||
}
|
||||
|
||||
return new Promise((resolve) => {
|
||||
batchTimeout = setTimeout(async () => {
|
||||
try {
|
||||
const keysToFetch = Array.from(pendingKeys);
|
||||
pendingKeys.clear();
|
||||
|
||||
if (keysToFetch.length > 0) {
|
||||
const translations = await fetchBatchTranslations(keysToFetch, companyCode, menuCode, userLang);
|
||||
|
||||
// 캐시에 저장
|
||||
if (!translationCache[cacheKey]) {
|
||||
translationCache[cacheKey] = {};
|
||||
}
|
||||
|
||||
Object.assign(translationCache[cacheKey], translations);
|
||||
|
||||
// 요청된 키에 대한 번역 반환
|
||||
if (translations[key]) {
|
||||
resolve(translations[key]);
|
||||
} else {
|
||||
resolve(defaultText || key);
|
||||
}
|
||||
} else {
|
||||
resolve(defaultText || key);
|
||||
}
|
||||
} catch (error) {
|
||||
console.error("❌ 배치 처리 오류:", error);
|
||||
resolve(defaultText || key);
|
||||
}
|
||||
}, BATCH_DELAY);
|
||||
});
|
||||
}
|
||||
|
||||
/**
|
||||
* 동기적 다국어 텍스트 조회 (캐시에서만)
|
||||
* UI 렌더링 시 즉시 사용
|
||||
*/
|
||||
export function getMultilangTextSync(
|
||||
key: string,
|
||||
companyCode: string = "*",
|
||||
menuCode: string = "MENU_MANAGEMENT",
|
||||
userLang: string = "KR",
|
||||
): string {
|
||||
// 1. 캐시에서 확인
|
||||
const cacheKey = `${userLang}_${companyCode}_${menuCode}`;
|
||||
if (translationCache[cacheKey]?.[key]) {
|
||||
return translationCache[cacheKey][key];
|
||||
}
|
||||
|
||||
// 2. 기본 텍스트에서 확인
|
||||
const defaultText = getDefaultText(key);
|
||||
if (defaultText) {
|
||||
return defaultText;
|
||||
}
|
||||
|
||||
// 3. 캐시에 없으면 비동기적으로 로드 (백그라운드)
|
||||
if (typeof window !== "undefined") {
|
||||
getMultilangText(key, companyCode, menuCode, userLang).then((text) => {
|
||||
// 페이지 리렌더링을 위해 이벤트 발생
|
||||
window.dispatchEvent(
|
||||
new CustomEvent("translation-loaded", {
|
||||
detail: { key, text, userLang },
|
||||
}),
|
||||
);
|
||||
});
|
||||
}
|
||||
|
||||
return defaultText || key;
|
||||
}
|
||||
|
||||
/**
|
||||
* 메뉴 관리 관련 다국어 텍스트 조회 (배치 처리)
|
||||
*/
|
||||
export async function getMenuText(key: string, userLang: string = "KR"): Promise<string> {
|
||||
return getMultilangText(key, "*", "MENU_MANAGEMENT", userLang);
|
||||
}
|
||||
|
||||
/**
|
||||
* 메뉴 관리 관련 다국어 텍스트 동기 조회
|
||||
*/
|
||||
export function getMenuTextSync(key: string, userLang: string = "KR"): string {
|
||||
return getMultilangTextSync(key, "*", "MENU_MANAGEMENT", userLang);
|
||||
}
|
||||
|
||||
/**
|
||||
* 기본 텍스트 반환 (한국어)
|
||||
*/
|
||||
function getDefaultText(key: string): string {
|
||||
const defaultTexts: Record<string, string> = {
|
||||
[MENU_MANAGEMENT_KEYS.TITLE]: "메뉴 관리",
|
||||
[MENU_MANAGEMENT_KEYS.DESCRIPTION]: "시스템의 메뉴 구조와 권한을 관리합니다.",
|
||||
@@ -334,16 +288,6 @@ export const getMenuTextSync = (key: string, params?: Record<string, any>): stri
|
||||
[MENU_MANAGEMENT_KEYS.USER_MENU]: "사용자 메뉴",
|
||||
[MENU_MANAGEMENT_KEYS.ADMIN_DESCRIPTION]: "시스템 관리 및 설정 메뉴",
|
||||
[MENU_MANAGEMENT_KEYS.USER_DESCRIPTION]: "일반 사용자 업무 메뉴",
|
||||
[MENU_MANAGEMENT_KEYS.LIST_TITLE]: "메뉴 목록",
|
||||
[MENU_MANAGEMENT_KEYS.LIST_TOTAL]: "총 {count}개의 메뉴가 있습니다.",
|
||||
[MENU_MANAGEMENT_KEYS.LIST_SEARCH_RESULT]: "검색 결과: {count}개",
|
||||
[MENU_MANAGEMENT_KEYS.FILTER_COMPANY]: "회사",
|
||||
[MENU_MANAGEMENT_KEYS.FILTER_COMPANY_ALL]: "전체 회사",
|
||||
[MENU_MANAGEMENT_KEYS.FILTER_COMPANY_COMMON]: "공통",
|
||||
[MENU_MANAGEMENT_KEYS.FILTER_COMPANY_SEARCH]: "회사명 검색...",
|
||||
[MENU_MANAGEMENT_KEYS.FILTER_SEARCH]: "검색어",
|
||||
[MENU_MANAGEMENT_KEYS.FILTER_SEARCH_PLACEHOLDER]: "메뉴명 또는 URL 검색",
|
||||
[MENU_MANAGEMENT_KEYS.FILTER_RESET]: "초기화",
|
||||
[MENU_MANAGEMENT_KEYS.BUTTON_ADD]: "추가",
|
||||
[MENU_MANAGEMENT_KEYS.BUTTON_ADD_TOP_LEVEL]: "최상위 메뉴 추가",
|
||||
[MENU_MANAGEMENT_KEYS.BUTTON_ADD_SUB]: "하위 메뉴 추가",
|
||||
@@ -396,38 +340,44 @@ export const getMenuTextSync = (key: string, params?: Record<string, any>): stri
|
||||
[MENU_MANAGEMENT_KEYS.STATUS_ACTIVE]: "활성화",
|
||||
[MENU_MANAGEMENT_KEYS.STATUS_INACTIVE]: "비활성화",
|
||||
[MENU_MANAGEMENT_KEYS.STATUS_UNSPECIFIED]: "미지정",
|
||||
[MENU_MANAGEMENT_KEYS.MESSAGE_LOADING]: "로딩 중...",
|
||||
[MENU_MANAGEMENT_KEYS.MESSAGE_MENU_DELETE_PROCESSING]: "메뉴 삭제 중...",
|
||||
[MENU_MANAGEMENT_KEYS.MESSAGE_MENU_SAVE_SUCCESS]: "메뉴가 저장되었습니다.",
|
||||
[MENU_MANAGEMENT_KEYS.MESSAGE_MENU_SAVE_FAILED]: "메뉴 저장에 실패했습니다.",
|
||||
[MENU_MANAGEMENT_KEYS.MESSAGE_MENU_DELETE_SUCCESS]: "메뉴가 삭제되었습니다.",
|
||||
[MENU_MANAGEMENT_KEYS.MESSAGE_MENU_DELETE_FAILED]: "메뉴 삭제에 실패했습니다.",
|
||||
[MENU_MANAGEMENT_KEYS.MESSAGE_MENU_DELETE_BATCH_SUCCESS]:
|
||||
"✅ {count}개의 메뉴(및 하위 메뉴)가 성공적으로 삭제되었습니다!",
|
||||
[MENU_MANAGEMENT_KEYS.MESSAGE_MENU_DELETE_BATCH_PARTIAL]: "⚠️ {success}개 삭제 성공, {failed}개 삭제 실패",
|
||||
[MENU_MANAGEMENT_KEYS.MESSAGE_MENU_STATUS_TOGGLE_SUCCESS]: "메뉴 상태가 변경되었습니다.",
|
||||
[MENU_MANAGEMENT_KEYS.MESSAGE_MENU_STATUS_TOGGLE_FAILED]: "메뉴 상태 변경에 실패했습니다.",
|
||||
[MENU_MANAGEMENT_KEYS.MESSAGE_VALIDATION_MENU_NAME_REQUIRED]: "메뉴명을 입력해주세요.",
|
||||
[MENU_MANAGEMENT_KEYS.MESSAGE_VALIDATION_COMPANY_REQUIRED]: "회사를 선택해주세요.",
|
||||
[MENU_MANAGEMENT_KEYS.MESSAGE_VALIDATION_SELECT_MENU_DELETE]: "삭제할 메뉴를 선택해주세요.",
|
||||
[MENU_MANAGEMENT_KEYS.MESSAGE_ERROR_LOAD_MENU_LIST]: "메뉴 목록을 불러오는데 실패했습니다.",
|
||||
[MENU_MANAGEMENT_KEYS.MESSAGE_ERROR_LOAD_MENU_INFO]: "메뉴 정보를 불러오는데 실패했습니다.",
|
||||
[MENU_MANAGEMENT_KEYS.MESSAGE_ERROR_LOAD_COMPANY_LIST]: "회사 목록을 불러오는데 실패했습니다.",
|
||||
[MENU_MANAGEMENT_KEYS.MESSAGE_ERROR_LOAD_LANG_KEY_LIST]: "다국어 키 목록을 불러오는데 실패했습니다.",
|
||||
[MENU_MANAGEMENT_KEYS.UI_EXPAND]: "펼치기",
|
||||
[MENU_MANAGEMENT_KEYS.UI_COLLAPSE]: "접기",
|
||||
[MENU_MANAGEMENT_KEYS.UI_MENU_COLLAPSE]: "메뉴 접기",
|
||||
[MENU_MANAGEMENT_KEYS.UI_LANGUAGE]: "언어",
|
||||
};
|
||||
|
||||
let text = defaultTexts[key] || key;
|
||||
return defaultTexts[key] || key;
|
||||
}
|
||||
|
||||
// 파라미터 치환
|
||||
if (params) {
|
||||
Object.entries(params).forEach(([paramKey, paramValue]) => {
|
||||
text = text.replace(new RegExp(`\\{${paramKey}\\}`, "g"), paramValue.toString());
|
||||
});
|
||||
}
|
||||
|
||||
return text;
|
||||
/**
|
||||
* 번역 캐시 설정 함수
|
||||
*/
|
||||
export const setTranslationCache = (lang: string, translations: Record<string, string>) => {
|
||||
translationCache[lang] = translations;
|
||||
};
|
||||
|
||||
/**
|
||||
* 번역 캐시 가져오기 함수
|
||||
*/
|
||||
export const getTranslationCache = (lang: string): Record<string, string> => {
|
||||
return translationCache[lang] || {};
|
||||
};
|
||||
|
||||
/**
|
||||
* 메뉴 관리 다국어 텍스트 훅 (기존 코드와 호환)
|
||||
*/
|
||||
export const useMenuManagementText = () => {
|
||||
const getMenuText = async (key: string, params?: Record<string, string | number>): Promise<string> => {
|
||||
let text = await getMultilangText(key, "*", "MENU_MANAGEMENT", "KR");
|
||||
|
||||
// 파라미터 치환
|
||||
if (params) {
|
||||
Object.entries(params).forEach(([paramKey, paramValue]) => {
|
||||
text = text.replace(new RegExp(`\\{${paramKey}\\}`, "g"), paramValue.toString());
|
||||
});
|
||||
}
|
||||
|
||||
return text;
|
||||
};
|
||||
|
||||
return {
|
||||
getMenuText,
|
||||
keys: MENU_MANAGEMENT_KEYS,
|
||||
};
|
||||
};
|
||||
|
||||
Reference in New Issue
Block a user