엔티티 조인컬럼 표시문제 수정
This commit is contained in:
parent
2327dbe35c
commit
fc5ffb03b2
|
|
@ -134,8 +134,8 @@ export class EntityJoinService {
|
|||
`🔧 기존 display_column 사용: ${column.column_name} → ${displayColumn}`
|
||||
);
|
||||
} else {
|
||||
// display_column이 "none"이거나 없는 경우 참조 테이블의 모든 컬럼 가져오기
|
||||
logger.info(`🔍 ${referenceTable}의 모든 컬럼 조회 중...`);
|
||||
// display_column이 "none"이거나 없는 경우 참조 테이블의 표시용 컬럼 자동 감지
|
||||
logger.info(`🔍 ${referenceTable}의 표시 컬럼 자동 감지 중...`);
|
||||
|
||||
// 참조 테이블의 모든 컬럼 이름 가져오기
|
||||
const tableColumnsResult = await query<{ column_name: string }>(
|
||||
|
|
@ -148,10 +148,34 @@ export class EntityJoinService {
|
|||
);
|
||||
|
||||
if (tableColumnsResult.length > 0) {
|
||||
displayColumns = tableColumnsResult.map((col) => col.column_name);
|
||||
const allColumns = tableColumnsResult.map((col) => col.column_name);
|
||||
|
||||
// 🆕 표시용 컬럼 자동 감지 (우선순위 순서)
|
||||
// 1. *_name 컬럼 (item_name, customer_name 등)
|
||||
// 2. name 컬럼
|
||||
// 3. label 컬럼
|
||||
// 4. title 컬럼
|
||||
// 5. 참조 컬럼 (referenceColumn)
|
||||
const nameColumn = allColumns.find(
|
||||
(col) => col.endsWith("_name") && col !== "company_name"
|
||||
);
|
||||
const simpleNameColumn = allColumns.find((col) => col === "name");
|
||||
const labelColumn = allColumns.find(
|
||||
(col) => col === "label" || col.endsWith("_label")
|
||||
);
|
||||
const titleColumn = allColumns.find((col) => col === "title");
|
||||
|
||||
// 우선순위에 따라 표시 컬럼 선택
|
||||
const displayColumn =
|
||||
nameColumn ||
|
||||
simpleNameColumn ||
|
||||
labelColumn ||
|
||||
titleColumn ||
|
||||
referenceColumn;
|
||||
displayColumns = [displayColumn];
|
||||
|
||||
logger.info(
|
||||
`✅ ${referenceTable}의 모든 컬럼 자동 포함 (${displayColumns.length}개):`,
|
||||
displayColumns.join(", ")
|
||||
`✅ ${referenceTable}의 표시 컬럼 자동 감지: ${displayColumn} (전체 ${allColumns.length}개 중)`
|
||||
);
|
||||
} else {
|
||||
// 테이블 컬럼을 못 찾으면 기본값 사용
|
||||
|
|
|
|||
|
|
@ -73,6 +73,67 @@ export const SplitPanelLayoutComponent: React.FC<SplitPanelLayoutComponentProps>
|
|||
return true;
|
||||
};
|
||||
|
||||
// 🆕 엔티티 조인 컬럼명 변환 헬퍼
|
||||
// "테이블명.컬럼명" 형식을 "원본컬럼_조인컬럼명" 형식으로 변환하여 데이터 접근
|
||||
const getEntityJoinValue = useCallback(
|
||||
(item: any, columnName: string, entityColumnMap?: Record<string, string>): any => {
|
||||
// 직접 매칭 시도
|
||||
if (item[columnName] !== undefined) {
|
||||
return item[columnName];
|
||||
}
|
||||
|
||||
// "테이블명.컬럼명" 형식인 경우 (예: item_info.item_name)
|
||||
if (columnName.includes(".")) {
|
||||
const [tableName, fieldName] = columnName.split(".");
|
||||
|
||||
// 🔍 디버깅: 첫 번째 아이템에서 키 목록 출력
|
||||
if (item && typeof item === "object") {
|
||||
const keys = Object.keys(item);
|
||||
const matchingKeys = keys.filter((k) => k.includes(fieldName));
|
||||
console.log(`🔍 getEntityJoinValue: columnName=${columnName}, fieldName=${fieldName}`);
|
||||
console.log(" 전체 키 목록:", keys);
|
||||
console.log(" 매칭 가능한 키들:", matchingKeys);
|
||||
}
|
||||
|
||||
// entityColumnMap에서 매핑 찾기 (예: item_info → item_code)
|
||||
if (entityColumnMap && entityColumnMap[tableName]) {
|
||||
const sourceColumn = entityColumnMap[tableName];
|
||||
const joinedColumnName = `${sourceColumn}_${fieldName}`;
|
||||
if (item[joinedColumnName] !== undefined) {
|
||||
return item[joinedColumnName];
|
||||
}
|
||||
}
|
||||
|
||||
// 모든 키에서 _fieldName으로 끝나는 것 찾기
|
||||
for (const key of Object.keys(item)) {
|
||||
if (key.endsWith(`_${fieldName}`)) {
|
||||
console.log(` ✅ 매칭됨: ${key} → ${item[key]}`);
|
||||
return item[key];
|
||||
}
|
||||
}
|
||||
|
||||
// 🆕 엔티티 조인 기본 패턴: 테이블명.컬럼명 → 소스컬럼_name
|
||||
// 예: item_info.item_name → item_code_name
|
||||
// tableName에서 소스 컬럼 추론 (item_info → item_code, customer_mng → customer_id 등)
|
||||
const inferredSourceColumn = tableName.replace("_info", "_code").replace("_mng", "_id");
|
||||
const defaultAliasKey = `${inferredSourceColumn}_name`;
|
||||
if (item[defaultAliasKey] !== undefined) {
|
||||
console.log(` ✅ 기본 별칭 매칭: ${defaultAliasKey} → ${item[defaultAliasKey]}`);
|
||||
return item[defaultAliasKey];
|
||||
}
|
||||
|
||||
// 테이블명_컬럼명 형식으로 시도
|
||||
const underscoreKey = `${tableName}_${fieldName}`;
|
||||
if (item[underscoreKey] !== undefined) {
|
||||
return item[underscoreKey];
|
||||
}
|
||||
}
|
||||
|
||||
return undefined;
|
||||
},
|
||||
[],
|
||||
);
|
||||
|
||||
// TableOptions Context
|
||||
const { registerTable, unregisterTable } = useTableOptions();
|
||||
const [leftFilters, setLeftFilters] = useState<TableFilter[]>([]);
|
||||
|
|
@ -1737,7 +1798,7 @@ export const SplitPanelLayoutComponent: React.FC<SplitPanelLayoutComponentProps>
|
|||
>
|
||||
{formatCellValue(
|
||||
col.name,
|
||||
item[col.name],
|
||||
getEntityJoinValue(item, col.name),
|
||||
leftCategoryMappings,
|
||||
col.format,
|
||||
)}
|
||||
|
|
@ -1796,7 +1857,12 @@ export const SplitPanelLayoutComponent: React.FC<SplitPanelLayoutComponentProps>
|
|||
className="px-3 py-2 text-sm whitespace-nowrap text-gray-900"
|
||||
style={{ textAlign: col.align || "left" }}
|
||||
>
|
||||
{formatCellValue(col.name, item[col.name], leftCategoryMappings, col.format)}
|
||||
{formatCellValue(
|
||||
col.name,
|
||||
getEntityJoinValue(item, col.name),
|
||||
leftCategoryMappings,
|
||||
col.format,
|
||||
)}
|
||||
</td>
|
||||
))}
|
||||
</tr>
|
||||
|
|
@ -2172,7 +2238,12 @@ export const SplitPanelLayoutComponent: React.FC<SplitPanelLayoutComponentProps>
|
|||
className="px-3 py-2 text-sm whitespace-nowrap text-gray-900"
|
||||
style={{ textAlign: col.align || "left" }}
|
||||
>
|
||||
{formatCellValue(col.name, item[col.name], rightCategoryMappings, col.format)}
|
||||
{formatCellValue(
|
||||
col.name,
|
||||
getEntityJoinValue(item, col.name),
|
||||
rightCategoryMappings,
|
||||
col.format,
|
||||
)}
|
||||
</td>
|
||||
))}
|
||||
{/* 수정 또는 삭제 버튼이 하나라도 활성화되어 있을 때만 작업 셀 표시 */}
|
||||
|
|
@ -2246,78 +2317,16 @@ export const SplitPanelLayoutComponent: React.FC<SplitPanelLayoutComponentProps>
|
|||
firstValues = rightColumns
|
||||
.slice(0, summaryCount)
|
||||
.map((col) => {
|
||||
// 🆕 엔티티 조인 컬럼 처리 (예: item_info.item_number → item_number 또는 item_id_name)
|
||||
let value = item[col.name];
|
||||
if (value === undefined && col.name.includes(".")) {
|
||||
const columnName = col.name.split(".").pop();
|
||||
// 1차: 컬럼명 그대로 (예: item_number)
|
||||
value = item[columnName || ""];
|
||||
// 2차: item_info.item_number → item_id_name 또는 item_id_item_number 형식 확인
|
||||
if (value === undefined) {
|
||||
const parts = col.name.split(".");
|
||||
if (parts.length === 2) {
|
||||
const refTable = parts[0]; // item_info
|
||||
const refColumn = parts[1]; // item_number 또는 item_name
|
||||
// FK 컬럼명 추론: item_info → item_id
|
||||
const fkColumn = refTable.replace("_info", "").replace("_mng", "") + "_id";
|
||||
|
||||
// 백엔드에서 반환하는 별칭 패턴:
|
||||
// 1) item_id_name (기본 referenceColumn)
|
||||
// 2) item_id_item_name (추가 컬럼)
|
||||
if (
|
||||
refColumn === refTable.replace("_info", "").replace("_mng", "") + "_number" ||
|
||||
refColumn === refTable.replace("_info", "").replace("_mng", "") + "_code"
|
||||
) {
|
||||
// 기본 참조 컬럼 (item_number, customer_code 등)
|
||||
const aliasKey = fkColumn + "_name";
|
||||
value = item[aliasKey];
|
||||
} else {
|
||||
// 추가 컬럼 (item_name, customer_name 등)
|
||||
const aliasKey = `${fkColumn}_${refColumn}`;
|
||||
value = item[aliasKey];
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
// 🆕 엔티티 조인 컬럼 처리 (getEntityJoinValue 사용)
|
||||
const value = getEntityJoinValue(item, col.name);
|
||||
return [col.name, value, col.label] as [string, any, string];
|
||||
})
|
||||
.filter(([_, value]) => value !== null && value !== undefined && value !== "");
|
||||
|
||||
allValues = rightColumns
|
||||
.map((col) => {
|
||||
// 🆕 엔티티 조인 컬럼 처리
|
||||
let value = item[col.name];
|
||||
if (value === undefined && col.name.includes(".")) {
|
||||
const columnName = col.name.split(".").pop();
|
||||
// 1차: 컬럼명 그대로
|
||||
value = item[columnName || ""];
|
||||
// 2차: {fk_column}_name 또는 {fk_column}_{ref_column} 형식 확인
|
||||
if (value === undefined) {
|
||||
const parts = col.name.split(".");
|
||||
if (parts.length === 2) {
|
||||
const refTable = parts[0]; // item_info
|
||||
const refColumn = parts[1]; // item_number 또는 item_name
|
||||
// FK 컬럼명 추론: item_info → item_id
|
||||
const fkColumn = refTable.replace("_info", "").replace("_mng", "") + "_id";
|
||||
|
||||
// 백엔드에서 반환하는 별칭 패턴:
|
||||
// 1) item_id_name (기본 referenceColumn)
|
||||
// 2) item_id_item_name (추가 컬럼)
|
||||
if (
|
||||
refColumn === refTable.replace("_info", "").replace("_mng", "") + "_number" ||
|
||||
refColumn === refTable.replace("_info", "").replace("_mng", "") + "_code"
|
||||
) {
|
||||
// 기본 참조 컬럼
|
||||
const aliasKey = fkColumn + "_name";
|
||||
value = item[aliasKey];
|
||||
} else {
|
||||
// 추가 컬럼
|
||||
const aliasKey = `${fkColumn}_${refColumn}`;
|
||||
value = item[aliasKey];
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
// 🆕 엔티티 조인 컬럼 처리 (getEntityJoinValue 사용)
|
||||
const value = getEntityJoinValue(item, col.name);
|
||||
return [col.name, value, col.label] as [string, any, string];
|
||||
})
|
||||
.filter(([_, value]) => value !== null && value !== undefined && value !== "");
|
||||
|
|
|
|||
Loading…
Reference in New Issue