좌측 패널에 매핑한 컬럼 나오도록 구현

This commit is contained in:
dohyeons 2025-11-07 11:51:44 +09:00
parent 03bce9d643
commit 25740c499d
4 changed files with 86 additions and 9 deletions

View File

@ -51,21 +51,26 @@ router.get(
}
}
// 회사 코드 추출 (멀티테넌시 필터링)
const userCompany = req.user?.companyCode;
console.log(`🔗 조인 데이터 조회:`, {
leftTable,
rightTable,
leftColumn,
rightColumn,
leftValue,
userCompany,
});
// 조인 데이터 조회
// 조인 데이터 조회 (회사 코드 전달)
const result = await dataService.getJoinedData(
leftTable as string,
rightTable as string,
leftColumn as string,
rightColumn as string,
leftValue as string
leftValue as string,
userCompany
);
if (!result.success) {

View File

@ -409,7 +409,8 @@ class DataService {
rightTable: string,
leftColumn: string,
rightColumn: string,
leftValue?: string | number
leftValue?: string | number,
userCompany?: string
): Promise<ServiceResponse<any[]>> {
try {
// 왼쪽 테이블 접근 검증
@ -425,18 +426,42 @@ class DataService {
}
let queryText = `
SELECT r.*
SELECT DISTINCT r.*
FROM "${rightTable}" r
INNER JOIN "${leftTable}" l
ON l."${leftColumn}" = r."${rightColumn}"
`;
const values: any[] = [];
const whereConditions: string[] = [];
let paramIndex = 1;
// 좌측 값 필터링
if (leftValue !== undefined && leftValue !== null) {
queryText += ` WHERE l."${leftColumn}" = $1`;
whereConditions.push(`l."${leftColumn}" = $${paramIndex}`);
values.push(leftValue);
paramIndex++;
}
// 우측 테이블 회사별 필터링 (company_code 컬럼이 있는 경우)
if (userCompany && userCompany !== "*") {
const hasCompanyCode = await this.checkColumnExists(rightTable, "company_code");
if (hasCompanyCode) {
whereConditions.push(`r.company_code = $${paramIndex}`);
values.push(userCompany);
paramIndex++;
console.log(`🏢 우측 패널 회사별 필터링 적용: ${rightTable}.company_code = ${userCompany}`);
}
}
// WHERE 절 추가
if (whereConditions.length > 0) {
queryText += ` WHERE ${whereConditions.join(" AND ")}`;
}
console.log("🔍 조인 쿼리 실행:", queryText);
console.log("📊 조인 쿼리 파라미터:", values);
const result = await query<any>(queryText, values);
return {

View File

@ -373,10 +373,56 @@ export const SplitPanelLayoutComponent: React.FC<SplitPanelLayoutComponentProps>
const itemId = item.id || item.ID || item[Object.keys(item)[0]] || index;
const isSelected =
selectedLeftItem && (selectedLeftItem.id === itemId || selectedLeftItem === item);
// 첫 번째 2-3개 필드를 표시
const keys = Object.keys(item).filter((k) => k !== "id" && k !== "ID");
const displayTitle = item[keys[0]] || item.name || item.title || `항목 ${index + 1}`;
const displaySubtitle = keys[1] ? item[keys[1]] : null;
// 조인에 사용하는 leftColumn을 필수로 표시
const leftColumn = componentConfig.rightPanel?.relation?.leftColumn;
let displayFields: { label: string; value: any }[] = [];
// 디버그 로그
if (index === 0) {
console.log("🔍 좌측 패널 표시 로직:");
console.log(" - leftColumn (조인 키):", leftColumn);
console.log(" - item keys:", Object.keys(item));
}
if (leftColumn) {
// 조인 모드: leftColumn 값을 첫 번째로 표시 (필수)
displayFields.push({
label: leftColumn,
value: item[leftColumn],
});
// 추가로 다른 의미있는 필드 1-2개 표시 (name, title 등)
const additionalKeys = Object.keys(item).filter(
(k) => k !== "id" && k !== "ID" && k !== leftColumn &&
(k.includes("name") || k.includes("title") || k.includes("desc"))
);
if (additionalKeys.length > 0) {
displayFields.push({
label: additionalKeys[0],
value: item[additionalKeys[0]],
});
}
if (index === 0) {
console.log(" ✅ 조인 키 기반 표시:", displayFields);
}
} else {
// 상세 모드 또는 설정 없음: 자동으로 첫 2개 필드 표시
const keys = Object.keys(item).filter((k) => k !== "id" && k !== "ID");
displayFields = keys.slice(0, 2).map((key) => ({
label: key,
value: item[key],
}));
if (index === 0) {
console.log(" ⚠️ 조인 키 없음, 자동 선택:", displayFields);
}
}
const displayTitle = displayFields[0]?.value || item.name || item.title || `항목 ${index + 1}`;
const displaySubtitle = displayFields[1]?.value || null;
return (
<div

View File

@ -268,6 +268,7 @@ export const SplitPanelLayoutConfigPanel: React.FC<SplitPanelLayoutConfigPanelPr
onCheckedChange={(checked) => updateLeftPanel({ showAdd: checked })}
/>
</div>
</div>
{/* 우측 패널 설정 */}