feat: Implement BOM Excel upload and download functionality

- Added endpoints for uploading BOM data from Excel and downloading BOM data in Excel format.
- Developed the `createBomFromExcel` function to handle Excel uploads, including validation and error handling.
- Implemented the `downloadBomExcelData` function to retrieve BOM data for Excel downloads.
- Created a new `BomExcelUploadModal` component for the frontend to facilitate Excel file uploads.
- Updated BOM routes to include new Excel upload and download routes, enhancing BOM management capabilities.
This commit is contained in:
kjs
2026-02-27 07:50:22 +09:00
parent d50f705c44
commit 929b68299a
10 changed files with 1299 additions and 20 deletions

View File

@@ -20,6 +20,7 @@ import {
Trash2,
Settings,
Move,
FileSpreadsheet,
} from "lucide-react";
import { dataApi } from "@/lib/api/data";
import { entityJoinApi } from "@/lib/api/entityJoin";
@@ -43,6 +44,7 @@ import { useSplitPanel } from "./SplitPanelContext";
import { DynamicComponentRenderer } from "@/lib/registry/DynamicComponentRenderer";
import { PanelInlineComponent } from "./types";
import { cn } from "@/lib/utils";
import { BomExcelUploadModal } from "../v2-bom-tree/BomExcelUploadModal";
export interface SplitPanelLayoutComponentProps extends ComponentRendererProps {
// 추가 props
@@ -500,6 +502,7 @@ export const SplitPanelLayoutComponent: React.FC<SplitPanelLayoutComponentProps>
const [showAddModal, setShowAddModal] = useState(false);
const [addModalPanel, setAddModalPanel] = useState<"left" | "right" | "left-item" | null>(null);
const [addModalFormData, setAddModalFormData] = useState<Record<string, any>>({});
const [bomExcelUploadOpen, setBomExcelUploadOpen] = useState(false);
// 수정 모달 상태
const [showEditModal, setShowEditModal] = useState(false);
@@ -3010,12 +3013,20 @@ export const SplitPanelLayoutComponent: React.FC<SplitPanelLayoutComponentProps>
<CardTitle className="text-base font-semibold">
{componentConfig.leftPanel?.title || "좌측 패널"}
</CardTitle>
{!isDesignMode && componentConfig.leftPanel?.showAdd && (
<Button size="sm" variant="outline" onClick={() => handleAddClick("left")}>
<Plus className="mr-1 h-4 w-4" />
</Button>
)}
<div className="flex items-center gap-1">
{!isDesignMode && (componentConfig.leftPanel as any)?.showBomExcelUpload && (
<Button size="sm" variant="outline" onClick={() => setBomExcelUploadOpen(true)}>
<FileSpreadsheet className="mr-1 h-4 w-4" />
</Button>
)}
{!isDesignMode && componentConfig.leftPanel?.showAdd && (
<Button size="sm" variant="outline" onClick={() => handleAddClick("left")}>
<Plus className="mr-1 h-4 w-4" />
</Button>
)}
</div>
</div>
</CardHeader>
{componentConfig.leftPanel?.showSearch && (
@@ -5070,6 +5081,16 @@ export const SplitPanelLayoutComponent: React.FC<SplitPanelLayoutComponentProps>
</DialogFooter>
</DialogContent>
</Dialog>
{(componentConfig.leftPanel as any)?.showBomExcelUpload && (
<BomExcelUploadModal
open={bomExcelUploadOpen}
onOpenChange={setBomExcelUploadOpen}
onSuccess={() => {
loadLeftData();
}}
/>
)}
</div>
);
};