From 6a3a7b915d7cba60388f8ba63ce3395f7a68f5f0 Mon Sep 17 00:00:00 2001 From: kjs Date: Tue, 16 Sep 2025 15:52:37 +0900 Subject: [PATCH] =?UTF-8?q?=EC=BD=94=EB=93=9C=ED=83=80=EC=9E=85=20?= =?UTF-8?q?=EC=BD=94=EB=93=9C=EB=AA=85=EC=9C=BC=EB=A1=9C=20=EB=B3=B4?= =?UTF-8?q?=EC=9D=B4=EA=B2=8C=20=EC=88=98=EC=A0=95?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../table-list/TableListComponent.tsx | 95 ++++++++++++++++++- 1 file changed, 92 insertions(+), 3 deletions(-) diff --git a/frontend/lib/registry/components/table-list/TableListComponent.tsx b/frontend/lib/registry/components/table-list/TableListComponent.tsx index 109fd948..511a789b 100644 --- a/frontend/lib/registry/components/table-list/TableListComponent.tsx +++ b/frontend/lib/registry/components/table-list/TableListComponent.tsx @@ -5,6 +5,7 @@ import { ComponentRendererProps } from "@/types/component"; import { TableListConfig, ColumnConfig, TableDataResponse } from "./types"; import { tableTypeApi } from "@/lib/api/screen"; import { entityJoinApi } from "@/lib/api/entityJoin"; +import { commonCodeApi } from "@/lib/api/commonCode"; import { Button } from "@/components/ui/button"; import { Input } from "@/components/ui/input"; import { Table, TableBody, TableCell, TableHead, TableHeader, TableRow } from "@/components/ui/table"; @@ -99,6 +100,8 @@ export const TableListComponent: React.FC = ({ const [localPageSize, setLocalPageSize] = useState(tableConfig.pagination?.pageSize || 20); // 로컬 페이지 크기 상태 const [selectedSearchColumn, setSelectedSearchColumn] = useState(""); // 선택된 검색 컬럼 const [displayColumns, setDisplayColumns] = useState([]); // 🎯 표시할 컬럼 (Entity 조인 적용됨) + const [columnMeta, setColumnMeta] = useState>({}); // 🎯 컬럼 메타정보 (웹타입, 코드카테고리) + const [codeCache, setCodeCache] = useState>>({}); // 🎯 코드명 캐시 (categoryCode: {codeValue: codeName}) // 높이 계산 함수 const calculateOptimalHeight = () => { @@ -144,16 +147,66 @@ export const TableListComponent: React.FC = ({ // API 응답 구조 확인 및 컬럼 배열 추출 const columns = response.columns || response; const labels: Record = {}; + const meta: Record = {}; + columns.forEach((column: any) => { labels[column.columnName] = column.displayName || column.columnName; + // 🎯 웹타입과 코드카테고리 정보 저장 + meta[column.columnName] = { + webType: column.webType, + codeCategory: column.codeCategory, + }; }); + setColumnLabels(labels); + setColumnMeta(meta); console.log("🔍 컬럼 라벨 설정 완료:", labels); + console.log("🔍 컬럼 메타정보 설정 완료:", meta); } catch (error) { console.log("컬럼 라벨 정보를 가져올 수 없습니다:", error); } }; + // 🎯 코드 캐시 로드 함수 + const loadCodeCache = async (categoryCode: string): Promise => { + if (codeCache[categoryCode]) { + return; // 이미 캐시됨 + } + + try { + const response = await commonCodeApi.options.getOptions(categoryCode); + const codeMap: Record = {}; + + if (response.success && response.data) { + response.data.forEach((option: any) => { + // 🎯 대소문자 구분 없이 저장 (모두 대문자로 키 저장) + codeMap[option.value?.toUpperCase()] = option.label; + }); + } + + setCodeCache((prev) => ({ + ...prev, + [categoryCode]: codeMap, + })); + + console.log(`📋 코드 캐시 로드 완료 [${categoryCode}]:`, codeMap); + } catch (error) { + console.error(`❌ 코드 캐시 로드 실패 [${categoryCode}]:`, error); + } + }; + + // 🎯 코드값을 코드명으로 변환하는 함수 (대소문자 구분 없음) + const convertCodeToName = (categoryCode: string, codeValue: string): string => { + if (!categoryCode || !codeValue) return codeValue; + + const codes = codeCache[categoryCode]; + if (!codes) return codeValue; + + // 🎯 대소문자 구분 없이 검색 + const upperCodeValue = codeValue.toUpperCase(); + return codes[upperCodeValue] || codeValue; + }; + // 테이블 라벨명 가져오기 const fetchTableLabel = async () => { if (!tableConfig.selectedTable) return; @@ -260,6 +313,30 @@ export const TableListComponent: React.FC = ({ console.log("🔗 Entity 조인 없음"); } + // 🎯 코드 컬럼들의 캐시 미리 로드 + const codeColumns = Object.entries(columnMeta).filter( + ([_, meta]) => meta.webType === "code" && meta.codeCategory, + ); + + if (codeColumns.length > 0) { + console.log( + "📋 코드 컬럼 감지:", + codeColumns.map(([col, meta]) => `${col}(${meta.codeCategory})`), + ); + + // 필요한 코드 캐시들을 병렬로 로드 + const loadPromises = codeColumns.map(([_, meta]) => + meta.codeCategory ? loadCodeCache(meta.codeCategory) : Promise.resolve(), + ); + + try { + await Promise.all(loadPromises); + console.log("📋 모든 코드 캐시 로드 완료"); + } catch (error) { + console.error("❌ 코드 캐시 로드 중 오류:", error); + } + } + // 🎯 Entity 조인된 컬럼 처리 let processedColumns = [...(tableConfig.columns || [])]; @@ -398,10 +475,22 @@ export const TableListComponent: React.FC = ({ return displayColumns.filter((col) => col.visible).sort((a, b) => a.order - b.order); }, [displayColumns, tableConfig.columns]); - // 값 포맷팅 - const formatCellValue = (value: any, format?: string) => { + // 🎯 값 포맷팅 (코드 변환 포함) + const formatCellValue = (value: any, format?: string, columnName?: string) => { if (value === null || value === undefined) return ""; + // 🎯 코드 컬럼인 경우 코드명으로 변환 + if (columnName && columnMeta[columnName]?.webType === "code" && columnMeta[columnName]?.codeCategory) { + const categoryCode = columnMeta[columnName].codeCategory!; + const convertedValue = convertCodeToName(categoryCode, String(value)); + + if (convertedValue !== String(value)) { + console.log(`🔄 코드 변환: ${columnName}[${categoryCode}] ${value} → ${convertedValue}`); + } + + value = convertedValue; + } + switch (format) { case "number": return typeof value === "number" ? value.toLocaleString() : value; @@ -572,7 +661,7 @@ export const TableListComponent: React.FC = ({ > {visibleColumns.map((column) => ( - {formatCellValue(row[column.columnName], column.format)} + {formatCellValue(row[column.columnName], column.format, column.columnName)} ))}