분할패널 수정동작 수정
This commit is contained in:
parent
cded99d644
commit
eb61506acd
|
|
@ -775,7 +775,8 @@ export async function getTableData(
|
|||
const userField = autoFilter?.userField || "companyCode";
|
||||
const userValue = (req.user as any)[userField];
|
||||
|
||||
if (userValue) {
|
||||
// 🆕 최고 관리자(company_code = '*')는 모든 회사 데이터 조회 가능
|
||||
if (userValue && userValue !== "*") {
|
||||
enhancedSearch[filterColumn] = userValue;
|
||||
|
||||
logger.info("🔍 현재 사용자 필터 적용:", {
|
||||
|
|
@ -784,6 +785,10 @@ export async function getTableData(
|
|||
userValue,
|
||||
tableName,
|
||||
});
|
||||
} else if (userValue === "*") {
|
||||
logger.info("🔓 최고 관리자 - 회사 필터 미적용 (모든 회사 데이터 조회)", {
|
||||
tableName,
|
||||
});
|
||||
} else {
|
||||
logger.warn("⚠️ 사용자 정보 필드 값 없음:", {
|
||||
userField,
|
||||
|
|
@ -792,6 +797,9 @@ export async function getTableData(
|
|||
}
|
||||
}
|
||||
|
||||
// 🆕 최종 검색 조건 로그
|
||||
logger.info(`🔍 최종 검색 조건 (enhancedSearch):`, JSON.stringify(enhancedSearch));
|
||||
|
||||
// 데이터 조회
|
||||
const result = await tableManagementService.getTableData(tableName, {
|
||||
page: parseInt(page),
|
||||
|
|
|
|||
|
|
@ -816,14 +816,23 @@ export function TableSectionRenderer({
|
|||
// 이미 초기화되었으면 스킵
|
||||
if (initialDataLoadedRef.current) return;
|
||||
|
||||
const tableSectionKey = `_tableSection_${sectionId}`;
|
||||
const tableSectionKey = `__tableSection_${sectionId}`;
|
||||
const initialData = formData[tableSectionKey];
|
||||
|
||||
console.log("[TableSectionRenderer] 초기 데이터 확인:", {
|
||||
sectionId,
|
||||
tableSectionKey,
|
||||
hasInitialData: !!initialData,
|
||||
initialDataLength: Array.isArray(initialData) ? initialData.length : 0,
|
||||
formDataKeys: Object.keys(formData).filter(k => k.startsWith("__tableSection_")),
|
||||
});
|
||||
|
||||
if (Array.isArray(initialData) && initialData.length > 0) {
|
||||
// console.log("[TableSectionRenderer] 초기 데이터 로드:", {
|
||||
// sectionId,
|
||||
// itemCount: initialData.length,
|
||||
// });
|
||||
console.log("[TableSectionRenderer] 초기 데이터 로드:", {
|
||||
sectionId,
|
||||
itemCount: initialData.length,
|
||||
firstItem: initialData[0],
|
||||
});
|
||||
setTableData(initialData);
|
||||
initialDataLoadedRef.current = true;
|
||||
|
||||
|
|
|
|||
|
|
@ -588,6 +588,225 @@ export function UniversalFormModalComponent({
|
|||
}
|
||||
}
|
||||
|
||||
// 🆕 테이블 섹션(type: "table") 디테일 데이터 로드 (마스터-디테일 구조)
|
||||
// 수정 모드일 때 디테일 테이블에서 데이터 가져오기
|
||||
if (effectiveInitialData) {
|
||||
console.log("[initializeForm] 테이블 섹션 디테일 로드 시작", {
|
||||
sectionsCount: config.sections.length,
|
||||
effectiveInitialDataKeys: Object.keys(effectiveInitialData),
|
||||
});
|
||||
|
||||
for (const section of config.sections) {
|
||||
if (section.type !== "table" || !section.tableConfig) {
|
||||
continue;
|
||||
}
|
||||
|
||||
const tableConfig = section.tableConfig;
|
||||
const editConfig = tableConfig.editConfig;
|
||||
const saveConfig = tableConfig.saveConfig;
|
||||
|
||||
console.log(`[initializeForm] 테이블 섹션 ${section.id} 검사:`, {
|
||||
hasEditConfig: !!editConfig,
|
||||
loadOnEdit: editConfig?.loadOnEdit,
|
||||
hasSaveConfig: !!saveConfig,
|
||||
targetTable: saveConfig?.targetTable,
|
||||
linkColumn: editConfig?.linkColumn,
|
||||
});
|
||||
|
||||
// 수정 모드 로드 설정 확인 (기본값: true)
|
||||
if (editConfig?.loadOnEdit === false) {
|
||||
console.log(`[initializeForm] 테이블 섹션 ${section.id}: loadOnEdit=false, 스킵`);
|
||||
continue;
|
||||
}
|
||||
|
||||
// 디테일 테이블과 연결 정보 확인
|
||||
const detailTable = saveConfig?.targetTable;
|
||||
let linkColumn = editConfig?.linkColumn;
|
||||
|
||||
if (!detailTable) {
|
||||
console.log(`[initializeForm] 테이블 섹션 ${section.id}: saveConfig.targetTable 미설정, 스킵`);
|
||||
continue;
|
||||
}
|
||||
|
||||
// linkColumn이 설정되지 않았으면, 디테일 테이블 컬럼 정보 조회하여 자동 감지
|
||||
if (!linkColumn?.masterField || !linkColumn?.detailField) {
|
||||
try {
|
||||
// 마스터 테이블명 확인 (saveConfig에서)
|
||||
// 1. customApiSave.multiTable.mainTable.tableName (다중 테이블 저장)
|
||||
// 2. saveConfig.tableName (단일 테이블 저장)
|
||||
const masterTable = config.saveConfig?.customApiSave?.multiTable?.mainTable?.tableName
|
||||
|| config.saveConfig?.tableName;
|
||||
|
||||
// 디테일 테이블의 컬럼 목록 조회
|
||||
const columnsResponse = await apiClient.get(`/table-management/tables/${detailTable}/columns`);
|
||||
|
||||
if (columnsResponse.data?.success && columnsResponse.data?.data) {
|
||||
// API 응답 구조: { success, data: { columns: [...], total, page, ... } }
|
||||
const columnsArray = columnsResponse.data.data.columns || columnsResponse.data.data || [];
|
||||
const detailColumnsData = Array.isArray(columnsArray) ? columnsArray : [];
|
||||
const detailColumns = detailColumnsData.map((col: any) => col.column_name || col.columnName);
|
||||
const masterKeys = Object.keys(effectiveInitialData);
|
||||
|
||||
console.log(`[initializeForm] 테이블 섹션 ${section.id}: 연결 필드 자동 감지`, {
|
||||
masterTable,
|
||||
detailTable,
|
||||
detailColumnsCount: detailColumnsData.length,
|
||||
});
|
||||
|
||||
// 방법 1: 엔티티 관계 기반 감지 (정확)
|
||||
// 디테일 테이블에서 마스터 테이블을 참조하는 엔티티 컬럼 찾기
|
||||
if (masterTable) {
|
||||
for (const col of detailColumnsData) {
|
||||
const colName = col.column_name || col.columnName;
|
||||
const inputType = col.input_type || col.inputType;
|
||||
|
||||
// 엔티티 타입 컬럼 확인
|
||||
if (inputType === "entity") {
|
||||
// reference_table 또는 detail_settings에서 참조 테이블 확인
|
||||
let refTable = col.reference_table || col.referenceTable;
|
||||
|
||||
// detail_settings에서 referenceTable 확인
|
||||
if (!refTable && col.detail_settings) {
|
||||
try {
|
||||
const settings = typeof col.detail_settings === "string"
|
||||
? JSON.parse(col.detail_settings)
|
||||
: col.detail_settings;
|
||||
refTable = settings.referenceTable;
|
||||
} catch {
|
||||
// JSON 파싱 실패 무시
|
||||
}
|
||||
}
|
||||
|
||||
// 마스터 테이블을 참조하는 컬럼 발견
|
||||
if (refTable === masterTable) {
|
||||
// 참조 컬럼 확인 (마스터 테이블의 어떤 컬럼을 참조하는지)
|
||||
let refColumn = col.reference_column || col.referenceColumn;
|
||||
if (!refColumn && col.detail_settings) {
|
||||
try {
|
||||
const settings = typeof col.detail_settings === "string"
|
||||
? JSON.parse(col.detail_settings)
|
||||
: col.detail_settings;
|
||||
refColumn = settings.referenceColumn;
|
||||
} catch {
|
||||
// JSON 파싱 실패 무시
|
||||
}
|
||||
}
|
||||
|
||||
// 마스터 데이터에 해당 컬럼 값이 있는지 확인
|
||||
if (refColumn && effectiveInitialData[refColumn]) {
|
||||
console.log(`[initializeForm] 테이블 섹션 ${section.id}: 엔티티 관계 감지 - ${colName} → ${masterTable}.${refColumn}`);
|
||||
linkColumn = { masterField: refColumn, detailField: colName };
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// 방법 2: 공통 컬럼 패턴 기반 감지 (폴백)
|
||||
// 엔티티 관계가 없으면 공통 컬럼명 패턴으로 찾기
|
||||
if (!linkColumn) {
|
||||
const priorityPatterns = ["_no", "_number", "_code", "_id"];
|
||||
|
||||
for (const pattern of priorityPatterns) {
|
||||
for (const masterKey of masterKeys) {
|
||||
if (masterKey.endsWith(pattern) &&
|
||||
detailColumns.includes(masterKey) &&
|
||||
effectiveInitialData[masterKey] &&
|
||||
masterKey !== "id" && masterKey !== "company_code") {
|
||||
console.log(`[initializeForm] 테이블 섹션 ${section.id}: 공통 컬럼 패턴 감지 - ${masterKey}`);
|
||||
linkColumn = { masterField: masterKey, detailField: masterKey };
|
||||
break;
|
||||
}
|
||||
}
|
||||
if (linkColumn) break;
|
||||
}
|
||||
}
|
||||
|
||||
// 방법 3: 일반 공통 컬럼 (마지막 폴백)
|
||||
if (!linkColumn) {
|
||||
for (const masterKey of masterKeys) {
|
||||
if (detailColumns.includes(masterKey) &&
|
||||
effectiveInitialData[masterKey] &&
|
||||
masterKey !== "id" && masterKey !== "company_code" &&
|
||||
!masterKey.startsWith("__")) {
|
||||
console.log(`[initializeForm] 테이블 섹션 ${section.id}: 공통 컬럼 감지 - ${masterKey}`);
|
||||
linkColumn = { masterField: masterKey, detailField: masterKey };
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
} catch (error) {
|
||||
console.warn(`[initializeForm] 테이블 섹션 ${section.id}: 컬럼 정보 조회 실패`, error);
|
||||
}
|
||||
}
|
||||
|
||||
if (!linkColumn?.masterField || !linkColumn?.detailField) {
|
||||
console.log(`[initializeForm] 테이블 섹션 ${section.id}: linkColumn 미설정 및 자동 감지 실패, 스킵`);
|
||||
continue;
|
||||
}
|
||||
|
||||
// 마스터 테이블의 연결 필드 값 가져오기
|
||||
const masterValue = effectiveInitialData[linkColumn.masterField];
|
||||
if (!masterValue) {
|
||||
console.log(`[initializeForm] 테이블 섹션 ${section.id}: masterField(${linkColumn.masterField}) 값 없음, 스킵`);
|
||||
continue;
|
||||
}
|
||||
|
||||
try {
|
||||
console.log(`[initializeForm] 테이블 섹션 ${section.id}: 디테일 데이터 로드 시작`, {
|
||||
detailTable,
|
||||
linkColumn,
|
||||
masterValue,
|
||||
});
|
||||
|
||||
// 디테일 테이블에서 데이터 조회
|
||||
// operator: "equals"를 사용하여 정확히 일치하는 값만 검색 (엔티티 타입 컬럼에서 중요)
|
||||
const searchCondition: Record<string, any> = {
|
||||
[linkColumn.detailField]: { value: masterValue, operator: "equals" },
|
||||
};
|
||||
|
||||
console.log(`[initializeForm] 테이블 섹션 ${section.id}: API 요청 - URL: /table-management/tables/${detailTable}/data`);
|
||||
console.log(`[initializeForm] 테이블 섹션 ${section.id}: API 요청 - search:`, JSON.stringify(searchCondition));
|
||||
|
||||
const response = await apiClient.post(`/table-management/tables/${detailTable}/data`, {
|
||||
search: searchCondition, // filters가 아닌 search로 전달
|
||||
page: 1,
|
||||
size: 1000, // pageSize가 아닌 size로 전달
|
||||
autoFilter: { enabled: true }, // 멀티테넌시 필터 적용
|
||||
});
|
||||
|
||||
console.log(`[initializeForm] 테이블 섹션 ${section.id}: API 응답 - success: ${response.data?.success}, total: ${response.data?.data?.total}, dataLength: ${response.data?.data?.data?.length}`);
|
||||
|
||||
if (response.data?.success) {
|
||||
// 다양한 응답 구조 처리
|
||||
let items: any[] = [];
|
||||
const data = response.data.data;
|
||||
|
||||
if (Array.isArray(data)) {
|
||||
items = data;
|
||||
} else if (data?.items && Array.isArray(data.items)) {
|
||||
items = data.items;
|
||||
} else if (data?.rows && Array.isArray(data.rows)) {
|
||||
items = data.rows;
|
||||
} else if (data?.data && Array.isArray(data.data)) {
|
||||
items = data.data;
|
||||
}
|
||||
|
||||
console.log(`[initializeForm] 테이블 섹션 ${section.id}: ${items.length}건 로드됨`, items);
|
||||
|
||||
// 테이블 섹션 데이터를 formData에 저장 (TableSectionRenderer에서 사용)
|
||||
const tableSectionKey = `__tableSection_${section.id}`;
|
||||
newFormData[tableSectionKey] = items;
|
||||
console.log(`[initializeForm] 테이블 섹션 ${section.id}: formData[${tableSectionKey}]에 저장됨`);
|
||||
}
|
||||
} catch (error) {
|
||||
console.error(`[initializeForm] 테이블 섹션 ${section.id}: 디테일 데이터 로드 실패`, error);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
setFormData(newFormData);
|
||||
setRepeatSections(newRepeatSections);
|
||||
setCollapsedSections(newCollapsed);
|
||||
|
|
|
|||
Loading…
Reference in New Issue