feat: Enhance Excel upload functionality with automatic numbering column detection
- Implemented automatic detection of numbering columns in the Excel upload modal, improving user experience by streamlining the upload process. - Updated the master-detail Excel upload configuration to reflect changes in how numbering rules are applied, ensuring consistency across uploads. - Refactored related components to remove deprecated properties and improve clarity in the configuration settings. - Enhanced error handling and logging for better debugging during the upload process.
This commit is contained in:
@@ -4984,7 +4984,7 @@ export class ButtonActionExecutor {
|
||||
// visible이 true인 컬럼만 추출
|
||||
visibleColumns = columns.filter((col: any) => col.visible !== false).map((col: any) => col.columnName);
|
||||
|
||||
// 🎯 column_labels 테이블에서 실제 라벨 가져오기
|
||||
// column_labels 테이블에서 실제 라벨 가져오기
|
||||
try {
|
||||
const columnsResponse = await apiClient.get(`/table-management/tables/${context.tableName}/columns`, {
|
||||
params: { page: 1, size: 9999 },
|
||||
@@ -5021,19 +5021,77 @@ export class ButtonActionExecutor {
|
||||
}
|
||||
});
|
||||
}
|
||||
} else {
|
||||
console.warn("⚠️ 화면 레이아웃에서 테이블 리스트 컴포넌트를 찾을 수 없습니다.");
|
||||
}
|
||||
}
|
||||
} catch (error) {
|
||||
console.error("❌ 화면 레이아웃 조회 실패:", error);
|
||||
}
|
||||
|
||||
// 🎨 카테고리 값들 조회 (한 번만)
|
||||
// Fallback: 레이아웃에서 컬럼 정보를 못 가져온 경우, table_type_columns에서 직접 조회
|
||||
// 시스템 컬럼 제외 + 라벨 적용으로 raw 컬럼명 노출 방지
|
||||
const SYSTEM_COLUMNS = ["id", "company_code", "created_date", "updated_date", "writer"];
|
||||
if ((!visibleColumns || visibleColumns.length === 0) && context.tableName && dataToExport.length > 0) {
|
||||
console.log("⚠️ 레이아웃에서 컬럼 설정을 찾지 못함 → table_type_columns에서 fallback 조회");
|
||||
try {
|
||||
const { apiClient } = await import("@/lib/api/client");
|
||||
const columnsResponse = await apiClient.get(`/table-management/tables/${context.tableName}/columns`, {
|
||||
params: { page: 1, size: 9999 },
|
||||
});
|
||||
|
||||
if (columnsResponse.data?.success && columnsResponse.data?.data) {
|
||||
let columnData = columnsResponse.data.data;
|
||||
if (columnData.columns && Array.isArray(columnData.columns)) {
|
||||
columnData = columnData.columns;
|
||||
}
|
||||
|
||||
if (Array.isArray(columnData) && columnData.length > 0) {
|
||||
// visible이 false가 아닌 컬럼만 + 시스템 컬럼 제외
|
||||
const filteredCols = columnData.filter((col: any) => {
|
||||
const colName = (col.column_name || col.columnName || "").toLowerCase();
|
||||
if (SYSTEM_COLUMNS.includes(colName)) return false;
|
||||
if (col.isVisible === false || col.is_visible === false) return false;
|
||||
return true;
|
||||
});
|
||||
|
||||
visibleColumns = filteredCols.map((col: any) => col.column_name || col.columnName);
|
||||
columnLabels = {};
|
||||
filteredCols.forEach((col: any) => {
|
||||
const colName = col.column_name || col.columnName;
|
||||
const labelValue = col.column_label || col.label || col.displayName || colName;
|
||||
if (colName) {
|
||||
columnLabels![colName] = labelValue;
|
||||
}
|
||||
});
|
||||
|
||||
console.log(`✅ Fallback 컬럼 ${visibleColumns.length}개 로드 완료`);
|
||||
}
|
||||
}
|
||||
} catch (fallbackError) {
|
||||
console.error("❌ Fallback 컬럼 조회 실패:", fallbackError);
|
||||
}
|
||||
}
|
||||
|
||||
// 최종 안전장치: 여전히 컬럼 정보가 없으면 데이터의 키에서 시스템 컬럼만 제외
|
||||
if ((!visibleColumns || visibleColumns.length === 0) && dataToExport.length > 0) {
|
||||
console.log("⚠️ 최종 fallback: 데이터 키에서 시스템 컬럼 제외");
|
||||
const allKeys = Object.keys(dataToExport[0]);
|
||||
visibleColumns = allKeys.filter((key) => {
|
||||
const lowerKey = key.toLowerCase();
|
||||
// 시스템 컬럼 제외
|
||||
if (SYSTEM_COLUMNS.includes(lowerKey)) return false;
|
||||
// _name, _label 등 조인된 보조 필드 제외
|
||||
if (lowerKey.endsWith("_name") || lowerKey.endsWith("_label") || lowerKey.endsWith("_value_label")) return false;
|
||||
return true;
|
||||
});
|
||||
// 라벨이 없으므로 최소한 column_labels 비워두지 않음 (컬럼명 그대로 표시되지만 시스템 컬럼은 제외됨)
|
||||
if (!columnLabels) {
|
||||
columnLabels = {};
|
||||
}
|
||||
}
|
||||
|
||||
// 카테고리 값들 조회 (한 번만)
|
||||
const categoryMap: Record<string, Record<string, string>> = {};
|
||||
let categoryColumns: string[] = [];
|
||||
|
||||
// 백엔드에서 카테고리 컬럼 정보 가져오기
|
||||
if (context.tableName) {
|
||||
try {
|
||||
const { getCategoryColumns, getCategoryValues } = await import("@/lib/api/tableCategoryValue");
|
||||
@@ -5072,7 +5130,7 @@ export class ButtonActionExecutor {
|
||||
}
|
||||
}
|
||||
|
||||
// 🎨 컬럼 필터링 및 라벨 적용 (항상 실행)
|
||||
// 컬럼 필터링 및 라벨 적용
|
||||
if (visibleColumns && visibleColumns.length > 0 && dataToExport.length > 0) {
|
||||
dataToExport = dataToExport.map((row: any) => {
|
||||
const filteredRow: Record<string, any> = {};
|
||||
@@ -5165,6 +5223,8 @@ export class ButtonActionExecutor {
|
||||
? config.excelAfterUploadFlows
|
||||
: config.masterDetailExcel?.afterUploadFlows;
|
||||
|
||||
// masterDetailExcel 설정이 명시적으로 있을 때만 간단 모드 (디테일만 업로드)
|
||||
// 설정이 없으면 기본 모드 (마스터+디테일 둘 다 업로드)
|
||||
if (config.masterDetailExcel) {
|
||||
masterDetailExcelConfig = {
|
||||
...config.masterDetailExcel,
|
||||
@@ -5173,25 +5233,13 @@ export class ButtonActionExecutor {
|
||||
detailTable: relationResponse.data.detailTable,
|
||||
masterKeyColumn: relationResponse.data.masterKeyColumn,
|
||||
detailFkColumn: relationResponse.data.detailFkColumn,
|
||||
// 채번 규칙 ID 추가 (excelNumberingRuleId를 numberingRuleId로 매핑)
|
||||
numberingRuleId: config.masterDetailExcel.numberingRuleId || config.excelNumberingRuleId,
|
||||
// 업로드 후 제어 설정 (통합: excelAfterUploadFlows 우선)
|
||||
afterUploadFlows,
|
||||
};
|
||||
} else {
|
||||
// 버튼 설정이 없으면 분할 패널 정보만 사용
|
||||
masterDetailExcelConfig = {
|
||||
masterTable: relationResponse.data.masterTable,
|
||||
detailTable: relationResponse.data.detailTable,
|
||||
masterKeyColumn: relationResponse.data.masterKeyColumn,
|
||||
detailFkColumn: relationResponse.data.detailFkColumn,
|
||||
simpleMode: true, // 기본값으로 간단 모드 사용
|
||||
// 채번 규칙 ID 추가 (excelNumberingRuleId 사용)
|
||||
numberingRuleId: config.excelNumberingRuleId,
|
||||
// 채번은 ExcelUploadModal에서 마스터 테이블 기반 자동 감지
|
||||
// 업로드 후 제어 설정 (통합: excelAfterUploadFlows 우선)
|
||||
afterUploadFlows,
|
||||
};
|
||||
}
|
||||
// masterDetailExcel 설정 없으면 masterDetailExcelConfig는 undefined 유지
|
||||
// → ExcelUploadModal에서 기본 모드로 동작 (마스터+디테일 둘 다 매핑/업로드)
|
||||
}
|
||||
}
|
||||
|
||||
@@ -5233,9 +5281,7 @@ export class ButtonActionExecutor {
|
||||
isMasterDetail,
|
||||
masterDetailRelation,
|
||||
masterDetailExcelConfig,
|
||||
// 🆕 단일 테이블 채번 설정
|
||||
numberingRuleId: config.excelNumberingRuleId,
|
||||
numberingTargetColumn: config.excelNumberingTargetColumn,
|
||||
// 채번은 ExcelUploadModal에서 테이블 타입 관리 기반 자동 감지
|
||||
// 🆕 업로드 후 제어 실행 설정
|
||||
afterUploadFlows: config.excelAfterUploadFlows,
|
||||
onSuccess: () => {
|
||||
|
||||
Reference in New Issue
Block a user