From 688d9884ca98b50d04ac78fc1f6e28e034a519c0 Mon Sep 17 00:00:00 2001
From: dujinkim <dujin.kim@dtsolution.co.kr>
Date: Wed, 3 Sep 2025 12:44:32 +0000
Subject: (대표님) rfq-last 작업, vendorDocu 스키마 변경, 벤더 문서 관련 변경
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit

---
 lib/rfq-last/table/rfq-table-columns.tsx | 1206 +++++++++++++++++++++---------
 1 file changed, 858 insertions(+), 348 deletions(-)

(limited to 'lib/rfq-last/table/rfq-table-columns.tsx')

diff --git a/lib/rfq-last/table/rfq-table-columns.tsx b/lib/rfq-last/table/rfq-table-columns.tsx
index 3fac8881..1b523adc 100644
--- a/lib/rfq-last/table/rfq-table-columns.tsx
+++ b/lib/rfq-last/table/rfq-table-columns.tsx
@@ -5,7 +5,7 @@ import { type ColumnDef } from "@tanstack/react-table";
 import { Checkbox } from "@/components/ui/checkbox";
 import { Badge } from "@/components/ui/badge";
 import { Button } from "@/components/ui/button";
-import { Eye, FileText, Send, Package, Users, ChevronRight } from "lucide-react";
+import { Eye, FileText, Send, Lock, LockOpen } from "lucide-react";
 import {
   Tooltip,
   TooltipContent,
@@ -17,10 +17,14 @@ import { RfqsLastView } from "@/db/schema";
 import { DataTableRowAction } from "@/types/table";
 import { format } from "date-fns";
 import { ko } from "date-fns/locale";
+import { useRouter } from "next/navigation";
+
+type NextRouter = ReturnType<typeof useRouter>;
 
 interface GetColumnsProps {
   setRowAction: React.Dispatch<React.SetStateAction<DataTableRowAction<RfqsLastView> | null>>;
-  rfqCategory?: "all" | "general" | "itb" | "rfq";
+  rfqCategory?: "general" | "itb" | "rfq";
+  router: NextRouter;
 }
 
 // RFQ 상태별 색상
@@ -38,408 +42,914 @@ const getStatusBadgeVariant = (status: string) => {
   }
 };
 
-// 시리즈 배지
-const getSeriesBadge = (series: string | null) => {
-  if (!series) return null;
-  
-  const label = series === "SS" ? "시리즈 통합" : series === "II" ? "품목 통합" : series;
-  const variant = series === "SS" ? "default" : series === "II" ? "secondary" : "outline";
-  
-  return <Badge variant={variant} className="text-xs">{label}</Badge>;
-};
-
 export function getRfqColumns({
   setRowAction,
-  rfqCategory = "all"
+  rfqCategory = "itb",
+  router
 }: GetColumnsProps): ColumnDef<RfqsLastView>[] {
-  
-  const baseColumns: ColumnDef<RfqsLastView>[] = [
-    // ═══════════════════════════════════════════════════════════════
-    // 선택 및 기본 정보
-    // ═══════════════════════════════════════════════════════════════
-
-    // Checkbox
-    {
-      id: "select",
-      header: ({ table }) => (
-        <Checkbox
-          checked={table.getIsAllPageRowsSelected() || (table.getIsSomePageRowsSelected() && "indeterminate")}
-          onCheckedChange={(v) => table.toggleAllPageRowsSelected(!!v)}
-          aria-label="select all"
-          className="translate-y-0.5"
-        />
-      ),
-      cell: ({ row }) => (
-        <Checkbox
-          checked={row.getIsSelected()}
-          onCheckedChange={(v) => row.toggleSelected(!!v)}
-          aria-label="select row"
-          className="translate-y-0.5"
-        />
-      ),
-      size: 40,
-      enableSorting: false,
-      enableHiding: false,
-    },
-
-    // RFQ 코드
-    {
-      accessorKey: "rfqCode",
-      header: ({ column }) => <DataTableColumnHeaderSimple column={column} title="RFQ 코드" />,
-      cell: ({ row }) => {
-        const rfqSealed = row.original.rfqSealedYn;
-        return (
-          <div className="flex items-center gap-1">
-            <span className="font-mono font-medium">{row.original.rfqCode}</span>
-            {rfqSealed && (
-              <Badge variant="destructive" className="text-xs">봉인</Badge>
-            )}
-          </div>
-        );
-      },
-      size: 140,
-    },
-
-    // 상태
-    {
-      accessorKey: "status",
-      header: ({ column }) => <DataTableColumnHeaderSimple column={column} title="상태" />,
-      cell: ({ row }) => (
-        <Badge variant={getStatusBadgeVariant(row.original.status)}>
-          {row.original.status}
-        </Badge>
-      ),
-      size: 120,
-    },
-
-    // ═══════════════════════════════════════════════════════════════
-    // 일반견적 필드 (rfqCategory가 'general' 또는 'all'일 때만)
-    // ═══════════════════════════════════════════════════════════════
-    ...(rfqCategory === "general" || rfqCategory === "all" ? [
-      {
-        id: "rfqType",
-        accessorKey: "rfqType",
-        header: ({ column }) => <DataTableColumnHeaderSimple column={column} title="견적 유형" />,
-        cell: ({ row }) => row.original.rfqType || "-",
+
+  // ═══════════════════════════════════════════════════════════════
+  // ITB 컬럼 정의
+  // ═══════════════════════════════════════════════════════════════
+  if (rfqCategory === "itb") {
+    return [
+      // Checkbox
+      {
+        id: "select",
+        header: ({ table }) => (
+          <Checkbox
+            checked={table.getIsAllPageRowsSelected() || (table.getIsSomePageRowsSelected() && "indeterminate")}
+            onCheckedChange={(v) => table.toggleAllPageRowsSelected(!!v)}
+            aria-label="select all"
+            className="translate-y-0.5"
+          />
+        ),
+        cell: ({ row }) => (
+          <Checkbox
+            checked={row.getIsSelected()}
+            onCheckedChange={(v) => row.toggleSelected(!!v)}
+            aria-label="select row"
+            className="translate-y-0.5"
+          />
+        ),
+        size: 40,
+        enableSorting: false,
+        enableHiding: false,
+      },
+
+      // ITB No.
+      {
+        accessorKey: "rfqCode",
+        header: ({ column }) => <DataTableColumnHeaderSimple column={column} title="ITB No." />,
+        cell: ({ row }) => (
+          <span className="font-mono font-medium">{row.original.rfqCode}</span>
+        ),
+        size: 120,
+      },
+
+      // 상세 (액션 버튼) - 수정됨
+      {
+        id: "detail",
+        header: "상세",
+        cell: ({ row }) => (
+          <Button
+            variant="ghost"
+            size="icon"
+            className="h-8 w-8"
+            onClick={() => router.push(`/evcp/rfq-last/${row.original.id}`)}
+          >
+            <Eye className="h-4 w-4" />
+          </Button>
+        ),
+        size: 60,
+      },
+
+      // 견적상태
+      {
+        accessorKey: "status",
+        header: ({ column }) => <DataTableColumnHeaderSimple column={column} title="견적상태" />,
+        cell: ({ row }) => (
+          <Badge variant={getStatusBadgeVariant(row.original.status)}>
+            {row.original.status}
+          </Badge>
+        ),
+        size: 120,
+      },
+
+      // 견적 밀봉
+      {
+        accessorKey: "rfqSealedYn",
+        header: ({ column }) => <DataTableColumnHeaderSimple column={column} title="견적 밀봉" />,
+        cell: ({ row }) => {
+          const isSealed = row.original.rfqSealedYn;
+          return (
+            <div className="flex justify-center">
+              {isSealed ? (
+                <Lock className="h-4 w-4 text-red-500" />
+              ) : (
+                <LockOpen className="h-4 w-4 text-gray-400" />
+              )}
+            </div>
+          );
+        },
+        size: 80,
+      },
+
+      // 구매담당자
+      {
+        accessorKey: "picUserName",
+        header: ({ column }) => <DataTableColumnHeaderSimple column={column} title="구매담당자" />,
+        cell: ({ row }) => row.original.picUserName || row.original.picName || "-",
         size: 100,
       },
+
+      // 프로젝트 (프로젝트명)
       {
-        id: "rfqTitle",
-        accessorKey: "rfqTitle",
-        header: ({ column }) => <DataTableColumnHeaderSimple column={column} title="견적 제목" />,
+        accessorKey: "projectName",
+        header: ({ column }) => <DataTableColumnHeaderSimple column={column} title="프로젝트 (프로젝트명)" />,
         cell: ({ row }) => (
-          <div className="max-w-[200px] truncate" title={row.original.rfqTitle || ""}>
-            {row.original.rfqTitle || "-"}
+          <div className="flex flex-col">
+            <span className="font-mono text-xs text-muted-foreground">
+              {row.original.projectCode}
+            </span>
+            <span className="max-w-[200px] truncate" title={row.original.projectName || ""}>
+              {row.original.projectName || "-"}
+            </span>
           </div>
         ),
-        size: 200,
+        size: 220,
+      },
+
+      // 선급
+      {
+        accessorKey: "classNo",
+        header: ({ column }) => <DataTableColumnHeaderSimple column={column} title="선급" />,
+        cell: ({ row }) => row.original.classNo || "-",
+        size: 80,
+      },
+
+      // PKG No. (PKG명)
+      {
+        accessorKey: "packageName",
+        header: ({ column }) => <DataTableColumnHeaderSimple column={column} title="PKG No. (PKG명)" />,
+        cell: ({ row }) => (
+          <div className="flex flex-col">
+            <span className="font-mono text-xs text-muted-foreground">
+              {row.original.packageNo}
+            </span>
+            <span className="max-w-[150px] truncate" title={row.original.packageName || ""}>
+              {row.original.packageName || "-"}
+            </span>
+          </div>
+        ),
+        size: 180,
+      },
+
+      // 자재그룹 (자재그룹명)
+      {
+        accessorKey: "itemName",
+        header: ({ column }) => <DataTableColumnHeaderSimple column={column} title="자재그룹 (자재그룹명)" />,
+        cell: ({ row }) => (
+          <div className="flex flex-col">
+            <span className="font-mono text-xs text-muted-foreground">
+              {row.original.itemCode}
+            </span>
+            <span className="max-w-[150px] truncate" title={row.original.itemName || ""}>
+              {row.original.itemName || "-"}
+            </span>
+          </div>
+        ),
+        size: 180,
+      },
+
+      // SM Code
+      {
+        accessorKey: "smCode",
+        header: ({ column }) => <DataTableColumnHeaderSimple column={column} title="SM Code" />,
+        cell: ({ row }) => row.original.smCode || "-",
+        size: 80,
+      },
+
+      // 견적문서 - 수정됨
+      {
+        id: "rfqDocument",
+        header: ({ column }) => <DataTableColumnHeaderSimple column={column} title="견적문서" />,
+        cell: ({ row }) => (
+          <Button 
+            variant="ghost" 
+            size="sm"
+            onClick={() => setRowAction({ row, type: "attachment" })}
+          >
+            <FileText className="h-4 w-4" />
+          </Button>
+        ),
+        size: 80,
+      },
+
+      // 견적생성일
+      {
+        accessorKey: "createdAt",
+        header: ({ column }) => <DataTableColumnHeaderSimple column={column} title="견적생성일" />,
+        cell: ({ row }) => {
+          const date = row.original.createdAt;
+          return date ? format(new Date(date), "yyyy-MM-dd") : "-";
+        },
+        size: 100,
+      },
+
+      // 견적발송일
+      {
+        accessorKey: "rfqSendDate",
+        header: ({ column }) => <DataTableColumnHeaderSimple column={column} title="견적발송일" />,
+        cell: ({ row }) => {
+          const date = row.original.rfqSendDate;
+          return date ? format(new Date(date), "yyyy-MM-dd") : "-";
+        },
+        size: 100,
+      },
+
+      // 견적마감일
+      {
+        accessorKey: "dueDate",
+        header: ({ column }) => <DataTableColumnHeaderSimple column={column} title="견적마감일" />,
+        cell: ({ row }) => {
+          const date = row.original.dueDate;
+          if (!date) return "-";
+          
+          const now = new Date();
+          const dueDate = new Date(date);
+          const isOverdue = now > dueDate;
+          
+          return (
+            <span className={`text-sm ${isOverdue ? "text-red-600 font-medium" : ""}`}>
+              {format(dueDate, "yyyy-MM-dd")}
+            </span>
+          );
+        },
+        size: 100,
+      },
+
+      // 설계담당자
+      {
+        accessorKey: "engPicName",
+        header: ({ column }) => <DataTableColumnHeaderSimple column={column} title="설계담당자" />,
+        cell: ({ row }) => row.original.engPicName || "-",
+        size: 100,
       },
-    ] as ColumnDef<RfqsLastView>[] : []),
 
-    // ═══════════════════════════════════════════════════════════════
-    // ITB 필드 (rfqCategory가 'itb' 또는 'all'일 때만)
-    // ═══════════════════════════════════════════════════════════════
-    ...(rfqCategory === "itb" || rfqCategory === "all" ? [
+      // 프로젝트 Company
       {
-        id: "projectCompany",
         accessorKey: "projectCompany",
-        header: ({ column }) => <DataTableColumnHeaderSimple column={column} title="프로젝트 회사" />,
+        header: ({ column }) => <DataTableColumnHeaderSimple column={column} title="프로젝트 Company" />,
         cell: ({ row }) => row.original.projectCompany || "-",
         size: 120,
       },
+
+      // TBE 결과접수
+      {
+        accessorKey: "tbeResultReceived",
+        header: ({ column }) => <DataTableColumnHeaderSimple column={column} title="TBE 결과접수" />,
+        cell: ({ row }) => {
+          const received = row.original.quotationReceivedCount || 0;
+          const total = row.original.vendorCount || 0;
+          return `${received}/${total}`;
+        },
+        size: 100,
+      },
+
+      // 프로젝트 Flag
       {
-        id: "projectFlag",
         accessorKey: "projectFlag",
-        header: ({ column }) => <DataTableColumnHeaderSimple column={column} title="프로젝트 플래그" />,
+        header: ({ column }) => <DataTableColumnHeaderSimple column={column} title="프로젝트 Flag" />,
         cell: ({ row }) => row.original.projectFlag || "-",
         size: 100,
       },
+
+      // 프로젝트 Site
       {
-        id: "projectSite",
         accessorKey: "projectSite",
-        header: ({ column }) => <DataTableColumnHeaderSimple column={column} title="프로젝트 사이트" />,
+        header: ({ column }) => <DataTableColumnHeaderSimple column={column} title="프로젝트 Site" />,
         cell: ({ row }) => row.original.projectSite || "-",
+        size: 100,
+      },
+
+      // 최종수정일
+      {
+        accessorKey: "updatedAt",
+        header: ({ column }) => <DataTableColumnHeaderSimple column={column} title="최종수정일" />,
+        cell: ({ row }) => {
+          const date = row.original.updatedAt;
+          return date ? format(new Date(date), "yyyy-MM-dd HH:mm") : "-";
+        },
         size: 120,
       },
+
+      // 최종수정자
       {
-        id: "smCode",
-        accessorKey: "smCode",
-        header: ({ column }) => <DataTableColumnHeaderSimple column={column} title="SM 코드" />,
-        cell: ({ row }) => row.original.smCode || "-",
-        size: 80,
+        accessorKey: "updatedByUserName",
+        header: ({ column }) => <DataTableColumnHeaderSimple column={column} title="최종수정자" />,
+        cell: ({ row }) => row.original.updatedByUserName || "-",
+        size: 100,
       },
-    ] as ColumnDef<RfqsLastView>[] : []),
 
-    // ═══════════════════════════════════════════════════════════════
-    // RFQ(PR) 필드 (rfqCategory가 'rfq' 또는 'all'일 때만)
-    // ═══════════════════════════════════════════════════════════════
-    ...(rfqCategory === "rfq" || rfqCategory === "all" ? [
+      // 비고
       {
-        id: "prNumber",
-        accessorKey: "prNumber",
-        header: ({ column }) => <DataTableColumnHeaderSimple column={column} title="PR 번호" />,
+        accessorKey: "remark",
+        header: ({ column }) => <DataTableColumnHeaderSimple column={column} title="비고" />,
+        cell: ({ row }) => row.original.remark || "-",
+        size: 150,
+      },
+    ];
+  }
+
+  // ═══════════════════════════════════════════════════════════════
+  // RFQ 컬럼 정의
+  // ═══════════════════════════════════════════════════════════════
+  if (rfqCategory === "rfq") {
+    return [
+      // Checkbox
+      {
+        id: "select",
+        header: ({ table }) => (
+          <Checkbox
+            checked={table.getIsAllPageRowsSelected() || (table.getIsSomePageRowsSelected() && "indeterminate")}
+            onCheckedChange={(v) => table.toggleAllPageRowsSelected(!!v)}
+            aria-label="select all"
+            className="translate-y-0.5"
+          />
+        ),
         cell: ({ row }) => (
-          <span className="font-mono text-sm">{row.original.prNumber || "-"}</span>
+          <Checkbox
+            checked={row.getIsSelected()}
+            onCheckedChange={(v) => row.toggleSelected(!!v)}
+            aria-label="select row"
+            className="translate-y-0.5"
+          />
+        ),
+        size: 40,
+        enableSorting: false,
+        enableHiding: false,
+      },
+
+      // RFQ No.
+      {
+        accessorKey: "rfqCode",
+        header: ({ column }) => <DataTableColumnHeaderSimple column={column} title="RFQ No." />,
+        cell: ({ row }) => (
+          <span className="font-mono font-medium">{row.original.rfqCode}</span>
         ),
         size: 120,
       },
+
+      // 상세 - 수정됨
       {
-        id: "prIssueDate",
-        accessorKey: "prIssueDate",
-        header: ({ column }) => <DataTableColumnHeaderSimple column={column} title="PR 발행일" />,
+        id: "detail",
+        header: "상세",
+        cell: ({ row }) => (
+          <Button
+            variant="ghost"
+            size="icon"
+            className="h-8 w-8"
+            onClick={() => router.push(`/evcp/rfq-last/${row.original.id}`)}
+          >
+            <Eye className="h-4 w-4" />
+          </Button>
+        ),
+        size: 60,
+      },
+
+      // 견적상태
+      {
+        accessorKey: "status",
+        header: ({ column }) => <DataTableColumnHeaderSimple column={column} title="견적상태" />,
+        cell: ({ row }) => (
+          <Badge variant={getStatusBadgeVariant(row.original.status)}>
+            {row.original.status}
+          </Badge>
+        ),
+        size: 120,
+      },
+
+      // 견적 밀봉
+      {
+        accessorKey: "rfqSealedYn",
+        header: ({ column }) => <DataTableColumnHeaderSimple column={column} title="견적 밀봉" />,
         cell: ({ row }) => {
-          const date = row.original.prIssueDate;
-          return date ? format(new Date(date), "yyyy-MM-dd") : "-";
+          const isSealed = row.original.rfqSealedYn;
+          return (
+            <div className="flex justify-center">
+              {isSealed ? (
+                <Lock className="h-4 w-4 text-red-500" />
+              ) : (
+                <LockOpen className="h-4 w-4 text-gray-400" />
+              )}
+            </div>
+          );
         },
+        size: 80,
+      },
+
+      // 구매담당자
+      {
+        accessorKey: "picUserName",
+        header: ({ column }) => <DataTableColumnHeaderSimple column={column} title="구매담당자" />,
+        cell: ({ row }) => row.original.picUserName || row.original.picName || "-",
         size: 100,
       },
+
+      // 프로젝트 (프로젝트명)
+      {
+        accessorKey: "projectName",
+        header: ({ column }) => <DataTableColumnHeaderSimple column={column} title="프로젝트 (프로젝트명)" />,
+        cell: ({ row }) => (
+          <div className="flex flex-col">
+            <span className="font-mono text-xs text-muted-foreground">
+              {row.original.projectCode}
+            </span>
+            <span className="max-w-[200px] truncate" title={row.original.projectName || ""}>
+              {row.original.projectName || "-"}
+            </span>
+          </div>
+        ),
+        size: 220,
+      },
+
+      // 시리즈
       {
-        id: "series",
         accessorKey: "series",
         header: ({ column }) => <DataTableColumnHeaderSimple column={column} title="시리즈" />,
-        cell: ({ row }) => getSeriesBadge(row.original.series),
+        cell: ({ row }) => {
+          const series = row.original.series;
+          if (!series) return "-";
+          const label = series === "SS" ? "시리즈 통합" : series === "II" ? "품목 통합" : series;
+          return <Badge variant="outline">{label}</Badge>;
+        },
         size: 100,
       },
-    ] as ColumnDef<RfqsLastView>[] : []),
-
-    // ═══════════════════════════════════════════════════════════════
-    // 공통 프로젝트 정보
-    // ═══════════════════════════════════════════════════════════════
-    {
-      header: "프로젝트 정보",
-      columns: [
-        {
-          accessorKey: "projectCode",
-          header: ({ column }) => <DataTableColumnHeaderSimple column={column} title="프로젝트 코드" />,
-          cell: ({ row }) => (
-            <span className="font-mono text-sm">{row.original.projectCode || "-"}</span>
-          ),
-          size: 120,
-        },
-        {
-          accessorKey: "projectName",
-          header: ({ column }) => <DataTableColumnHeaderSimple column={column} title="프로젝트명" />,
-          cell: ({ row }) => (
-            <div className="max-w-[200px] truncate" title={row.original.projectName || ""}>
-              {row.original.projectName || "-"}
-            </div>
-          ),
-          size: 200,
-        },
-      ]
-    },
-
-    // ═══════════════════════════════════════════════════════════════
-    // 품목 정보
-    // ═══════════════════════════════════════════════════════════════
-    {
-      header: "품목 정보",
-      columns: [
-        {
-          accessorKey: "itemCode",
-          header: ({ column }) => <DataTableColumnHeaderSimple column={column} title="자재코드" />,
-          cell: ({ row }) => (
-            <span className="font-mono text-sm">{row.original.itemCode || "-"}</span>
-          ),
-          size: 100,
-        },
-        {
-          accessorKey: "itemName",
-          header: ({ column }) => <DataTableColumnHeaderSimple column={column} title="자재명" />,
-          cell: ({ row }) => (
-            <div className="max-w-[200px] truncate" title={row.original.itemName || ""}>
+
+      // 선급
+      {
+        accessorKey: "classNo",
+        header: ({ column }) => <DataTableColumnHeaderSimple column={column} title="선급" />,
+        cell: ({ row }) => row.original.classNo || "-",
+        size: 80,
+      },
+
+      // PKG No. (PKG명)
+      {
+        accessorKey: "packageName",
+        header: ({ column }) => <DataTableColumnHeaderSimple column={column} title="PKG No. (PKG명)" />,
+        cell: ({ row }) => (
+          <div className="flex flex-col">
+            <span className="font-mono text-xs text-muted-foreground">
+              {row.original.packageNo}
+            </span>
+            <span className="max-w-[150px] truncate" title={row.original.packageName || ""}>
+              {row.original.packageName || "-"}
+            </span>
+          </div>
+        ),
+        size: 180,
+      },
+
+      // 자재그룹 (자재그룹명)
+      {
+        accessorKey: "itemName",
+        header: ({ column }) => <DataTableColumnHeaderSimple column={column} title="자재그룹 (자재그룹명)" />,
+        cell: ({ row }) => (
+          <div className="flex flex-col">
+            <span className="font-mono text-xs text-muted-foreground">
+              {row.original.itemCode}
+            </span>
+            <span className="max-w-[150px] truncate" title={row.original.itemName || ""}>
               {row.original.itemName || "-"}
-            </div>
-          ),
-          size: 200,
-        },
-        {
-          accessorKey: "packageNo",
-          header: ({ column }) => <DataTableColumnHeaderSimple column={column} title="패키지 번호" />,
-          cell: ({ row }) => row.original.packageNo || "-",
-          size: 100,
+            </span>
+          </div>
+        ),
+        size: 180,
+      },
+
+      // 자재코드
+      {
+        accessorKey: "itemCode",
+        header: ({ column }) => <DataTableColumnHeaderSimple column={column} title="자재코드" />,
+        cell: ({ row }) => (
+          <span className="font-mono text-sm">{row.original.itemCode || "-"}</span>
+        ),
+        size: 100,
+      },
+
+      // 견적문서 - 수정됨
+      {
+        id: "rfqDocument",
+        header: ({ column }) => <DataTableColumnHeaderSimple column={column} title="견적문서" />,
+        cell: ({ row }) => (
+          <Button 
+            variant="ghost" 
+            size="sm"
+            onClick={() => setRowAction({ row, type: "attachment" })}
+          >
+            <FileText className="h-4 w-4" />
+          </Button>
+        ),
+        size: 80,
+      },
+
+      // PR건수 - 수정됨
+      {
+        accessorKey: "prItemsCount",
+        header: ({ column }) => <DataTableColumnHeaderSimple column={column} title="PR건수" />,
+        cell: ({ row }) => (
+          <Button
+            variant="ghost"
+            size="sm"
+            className="font-mono text-sm p-1 h-auto"
+            onClick={() => setRowAction({ row, type: "items" })}
+          >
+            {row.original.prItemsCount || 0}
+          </Button>
+        ),
+        size: 80,
+      },
+
+      // 견적생성일
+      {
+        accessorKey: "createdAt",
+        header: ({ column }) => <DataTableColumnHeaderSimple column={column} title="견적생성일" />,
+        cell: ({ row }) => {
+          const date = row.original.createdAt;
+          return date ? format(new Date(date), "yyyy-MM-dd") : "-";
         },
-        {
-          accessorKey: "packageName",
-          header: ({ column }) => <DataTableColumnHeaderSimple column={column} title="패키지명" />,
-          cell: ({ row }) => (
-            <div className="max-w-[200px] truncate" title={row.original.packageName || ""}>
-              {row.original.packageName || "-"}
-            </div>
-          ),
-          size: 200,
+        size: 100,
+      },
+
+      // 견적발송일
+      {
+        accessorKey: "rfqSendDate",
+        header: ({ column }) => <DataTableColumnHeaderSimple column={column} title="견적발송일" />,
+        cell: ({ row }) => {
+          const date = row.original.rfqSendDate;
+          return date ? format(new Date(date), "yyyy-MM-dd") : "-";
         },
-      ]
-    },
-
-    // ═══════════════════════════════════════════════════════════════
-    // 담당자 정보
-    // ═══════════════════════════════════════════════════════════════
-    {
-      header: "담당자",
-      columns: [
-        {
-          accessorKey: "picUserName",
-          header: ({ column }) => <DataTableColumnHeaderSimple column={column} title="구매담당자" />,
-          cell: ({ row }) => row.original.picUserName || row.original.picName || "-",
-          size: 100,
+        size: 100,
+      },
+
+      // 견적마감일
+      {
+        accessorKey: "dueDate",
+        header: ({ column }) => <DataTableColumnHeaderSimple column={column} title="견적마감일" />,
+        cell: ({ row }) => {
+          const date = row.original.dueDate;
+          if (!date) return "-";
+          
+          const now = new Date();
+          const dueDate = new Date(date);
+          const isOverdue = now > dueDate;
+          
+          return (
+            <span className={`text-sm ${isOverdue ? "text-red-600 font-medium" : ""}`}>
+              {format(dueDate, "yyyy-MM-dd")}
+            </span>
+          );
         },
-        {
-          accessorKey: "engPicName",
-          header: ({ column }) => <DataTableColumnHeaderSimple column={column} title="엔지니어링 담당" />,
-          cell: ({ row }) => row.original.engPicName || "-",
-          size: 120,
+        size: 100,
+      },
+
+      // 설계담당자
+      {
+        accessorKey: "engPicName",
+        header: ({ column }) => <DataTableColumnHeaderSimple column={column} title="설계담당자" />,
+        cell: ({ row }) => row.original.engPicName || "-",
+        size: 100,
+      },
+
+      // TBE 결과접수
+      {
+        accessorKey: "tbeResultReceived",
+        header: ({ column }) => <DataTableColumnHeaderSimple column={column} title="TBE 결과접수" />,
+        cell: ({ row }) => {
+          const received = row.original.quotationReceivedCount || 0;
+          const total = row.original.vendorCount || 0;
+          return `${received}/${total}`;
         },
-      ]
-    },
-
-    // ═══════════════════════════════════════════════════════════════
-    // 일정 정보
-    // ═══════════════════════════════════════════════════════════════
-    {
-      header: "일정",
-      columns: [
-        {
-          accessorKey: "rfqSendDate",
-          header: ({ column }) => <DataTableColumnHeaderSimple column={column} title="발송일" />,
-          cell: ({ row }) => {
-            const date = row.original.rfqSendDate;
-            return date ? (
-              <div className="flex items-center gap-1">
-                <Send className="h-3 w-3 text-muted-foreground" />
-                <span className="text-sm">
-                  {format(new Date(date), "MM-dd", { locale: ko })}
-                </span>
-              </div>
-            ) : "-";
-          },
-          size: 90,
+        size: 100,
+      },
+
+      // 대표 PR No.
+      {
+        accessorKey: "prNumber",
+        header: ({ column }) => <DataTableColumnHeaderSimple column={column} title="대표 PR No." />,
+        cell: ({ row }) => (
+          <span className="font-mono text-sm">{row.original.prNumber || "-"}</span>
+        ),
+        size: 120,
+      },
+
+      // PR발행일
+      {
+        accessorKey: "prIssueDate",
+        header: ({ column }) => <DataTableColumnHeaderSimple column={column} title="PR발행일" />,
+        cell: ({ row }) => {
+          const date = row.original.prIssueDate;
+          return date ? format(new Date(date), "yyyy-MM-dd") : "-";
         },
-        {
-          accessorKey: "dueDate",
-          header: ({ column }) => <DataTableColumnHeaderSimple column={column} title="마감일" />,
-          cell: ({ row }) => {
-            const date = row.original.dueDate;
-            if (!date) return "-";
-            
-            const now = new Date();
-            const dueDate = new Date(date);
-            const isOverdue = now > dueDate;
-            
-            return (
-              <span className={`text-sm ${isOverdue ? "text-red-600 font-medium" : ""}`}>
-                {format(dueDate, "MM-dd", { locale: ko })}
-              </span>
-            );
-          },
-          size: 90,
+        size: 100,
+      },
+
+      // 최종수정일
+      {
+        accessorKey: "updatedAt",
+        header: ({ column }) => <DataTableColumnHeaderSimple column={column} title="최종수정일" />,
+        cell: ({ row }) => {
+          const date = row.original.updatedAt;
+          return date ? format(new Date(date), "yyyy-MM-dd HH:mm") : "-";
         },
-      ]
-    },
-
-    // ═══════════════════════════════════════════════════════════════
-    // 벤더 및 견적 현황
-    // ═══════════════════════════════════════════════════════════════
-    {
-      header: "견적 현황",
-      columns: [
-        {
-          accessorKey: "vendorCount",
-          header: ({ column }) => <DataTableColumnHeaderSimple column={column} title="업체수" />,
-          cell: ({ row }) => (
-            <div className="flex items-center gap-1">
-              <Users className="h-3 w-3 text-muted-foreground" />
-              <span className="font-medium">{row.original.vendorCount || 0}</span>
+        size: 120,
+      },
+
+      // 최종수정자
+      {
+        accessorKey: "updatedByUserName",
+        header: ({ column }) => <DataTableColumnHeaderSimple column={column} title="최종수정자" />,
+        cell: ({ row }) => row.original.updatedByUserName || "-",
+        size: 100,
+      },
+
+      // 비고
+      {
+        accessorKey: "remark",
+        header: ({ column }) => <DataTableColumnHeaderSimple column={column} title="비고" />,
+        cell: ({ row }) => row.original.remark || "-",
+        size: 150,
+      },
+    ];
+  }
+
+  // ═══════════════════════════════════════════════════════════════
+  // 일반견적 컬럼 정의
+  // ═══════════════════════════════════════════════════════════════
+  if (rfqCategory === "general") {
+    return [
+      // Checkbox
+      {
+        id: "select",
+        header: ({ table }) => (
+          <Checkbox
+            checked={table.getIsAllPageRowsSelected() || (table.getIsSomePageRowsSelected() && "indeterminate")}
+            onCheckedChange={(v) => table.toggleAllPageRowsSelected(!!v)}
+            aria-label="select all"
+            className="translate-y-0.5"
+          />
+        ),
+        cell: ({ row }) => (
+          <Checkbox
+            checked={row.getIsSelected()}
+            onCheckedChange={(v) => row.toggleSelected(!!v)}
+            aria-label="select row"
+            className="translate-y-0.5"
+          />
+        ),
+        size: 40,
+        enableSorting: false,
+        enableHiding: false,
+      },
+
+      // 견적 No.
+      {
+        accessorKey: "rfqCode",
+        header: ({ column }) => <DataTableColumnHeaderSimple column={column} title="견적 No." />,
+        cell: ({ row }) => (
+          <span className="font-mono font-medium">{row.original.rfqCode}</span>
+        ),
+        size: 120,
+      },
+
+      // 상세 - 수정됨
+      {
+        id: "detail",
+        header: "상세",
+        cell: ({ row }) => (
+          <Button
+            variant="ghost"
+            size="icon"
+            className="h-8 w-8"
+            onClick={() => router.push(`/evcp/rfq-last/${row.original.id}`)}
+          >
+            <Eye className="h-4 w-4" />
+          </Button>
+        ),
+        size: 60,
+      },
+
+      // 견적상태
+      {
+        accessorKey: "status",
+        header: ({ column }) => <DataTableColumnHeaderSimple column={column} title="견적상태" />,
+        cell: ({ row }) => (
+          <Badge variant={getStatusBadgeVariant(row.original.status)}>
+            {row.original.status}
+          </Badge>
+        ),
+        size: 120,
+      },
+
+      // 견적 밀봉
+      {
+        accessorKey: "rfqSealedYn",
+        header: ({ column }) => <DataTableColumnHeaderSimple column={column} title="견적 밀봉" />,
+        cell: ({ row }) => {
+          const isSealed = row.original.rfqSealedYn;
+          return (
+            <div className="flex justify-center">
+              {isSealed ? (
+                <Lock className="h-4 w-4 text-red-500" />
+              ) : (
+                <LockOpen className="h-4 w-4 text-gray-400" />
+              )}
             </div>
-          ),
-          size: 80,
-        },
-        {
-          accessorKey: "shortListedVendorCount",
-          header: ({ column }) => <DataTableColumnHeaderSimple column={column} title="Short List" />,
-          cell: ({ row }) => {
-            const count = row.original.shortListedVendorCount || 0;
-            return count > 0 ? (
-              <Badge variant="default" className="font-mono">
-                {count}
-              </Badge>
-            ) : "-";
-          },
-          size: 90,
+          );
         },
-        {
-          accessorKey: "quotationReceivedCount",
-          header: ({ column }) => <DataTableColumnHeaderSimple column={column} title="견적접수" />,
-          cell: ({ row }) => {
-            const received = row.original.quotationReceivedCount || 0;
-            const total = row.original.vendorCount || 0;
-            
-            return (
-              <div className="flex items-center gap-1">
-                <FileText className="h-3 w-3 text-muted-foreground" />
-                <span className={`text-sm ${received === total && total > 0 ? "text-green-600 font-medium" : ""}`}>
-                  {received}/{total}
-                </span>
-              </div>
-            );
-          },
-          size: 90,
+        size: 80,
+      },
+
+      // 견적종류
+      {
+        accessorKey: "rfqType",
+        header: ({ column }) => <DataTableColumnHeaderSimple column={column} title="견적종류" />,
+        cell: ({ row }) => row.original.rfqType || "-",
+        size: 100,
+      },
+
+      // 프로젝트 (프로젝트명)
+      {
+        accessorKey: "projectName",
+        header: ({ column }) => <DataTableColumnHeaderSimple column={column} title="프로젝트 (프로젝트명)" />,
+        cell: ({ row }) => (
+          <div className="flex flex-col">
+            <span className="font-mono text-xs text-muted-foreground">
+              {row.original.projectCode}
+            </span>
+            <span className="max-w-[200px] truncate" title={row.original.projectName || ""}>
+              {row.original.projectName || "-"}
+            </span>
+          </div>
+        ),
+        size: 220,
+      },
+
+      // 시리즈
+      {
+        accessorKey: "series",
+        header: ({ column }) => <DataTableColumnHeaderSimple column={column} title="시리즈" />,
+        cell: ({ row }) => {
+          const series = row.original.series;
+          if (!series) return "-";
+          const label = series === "SS" ? "시리즈 통합" : series === "II" ? "품목 통합" : series;
+          return <Badge variant="outline">{label}</Badge>;
         },
-      ]
-    },
-
-    // PR Items 정보
-    {
-      accessorKey: "prItemsCount",
-      header: ({ column }) => <DataTableColumnHeaderSimple column={column} title="PR Items" />,
-      cell: ({ row }) => {
-        const prItems = row.original.prItemsCount || 0;
-        const majorItems = row.original.majorItemsCount || 0;
-        
-        return (
-          <div className="flex flex-col gap-0.5">
-            <span className="text-sm font-medium">{prItems}개</span>
-            {majorItems > 0 && (
-              <Badge variant="secondary" className="text-xs">
-                주요 {majorItems}
-              </Badge>
-            )}
+        size: 100,
+      },
+
+      // 선급
+      {
+        accessorKey: "classNo",
+        header: ({ column }) => <DataTableColumnHeaderSimple column={column} title="선급" />,
+        cell: ({ row }) => row.original.classNo || "-",
+        size: 80,
+      },
+
+      // 견적명
+      {
+        accessorKey: "rfqTitle",
+        header: ({ column }) => <DataTableColumnHeaderSimple column={column} title="견적명" />,
+        cell: ({ row }) => (
+          <div className="max-w-[200px] truncate" title={row.original.rfqTitle || ""}>
+            {row.original.rfqTitle || "-"}
           </div>
-        );
-      },
-      size: 90,
-    },
-
-    // 액션
-    {
-      id: "actions",
-      header: "액션",
-      enableHiding: false,
-      size: 80,
-      minSize: 80,
-      cell: ({ row }) => {
-        return (
-          <div className="flex items-center gap-1">
-            <TooltipProvider>
-              <Tooltip>
-                <TooltipTrigger asChild>
-                  <Button
-                    variant="ghost"
-                    size="icon"
-                    className="h-8 w-8"
-                    onClick={() => setRowAction({ row, type: "view" })}
-                  >
-                    <Eye className="h-4 w-4" />
-                  </Button>
-                </TooltipTrigger>
-                <TooltipContent>상세보기</TooltipContent>
-              </Tooltip>
-            </TooltipProvider>
+        ),
+        size: 200,
+      },
+
+      // 자재그룹 (자재그룹명)
+      {
+        accessorKey: "itemName",
+        header: ({ column }) => <DataTableColumnHeaderSimple column={column} title="자재그룹 (자재그룹명)" />,
+        cell: ({ row }) => (
+          <div className="flex flex-col">
+            <span className="font-mono text-xs text-muted-foreground">
+              {row.original.itemCode}
+            </span>
+            <span className="max-w-[150px] truncate" title={row.original.itemName || ""}>
+              {row.original.itemName || "-"}
+            </span>
           </div>
-        );
+        ),
+        size: 180,
+      },
+
+      // 자재코드
+      {
+        accessorKey: "itemCode",
+        header: ({ column }) => <DataTableColumnHeaderSimple column={column} title="자재코드" />,
+        cell: ({ row }) => (
+          <span className="font-mono text-sm">{row.original.itemCode || "-"}</span>
+        ),
+        size: 100,
       },
-    },
-  ];
 
-  return baseColumns;
+      // 견적 자료 - 수정됨
+      {
+        id: "rfqDocument",
+        header: ({ column }) => <DataTableColumnHeaderSimple column={column} title="견적 자료" />,
+        cell: ({ row }) => (
+          <Button 
+            variant="ghost" 
+            size="sm"
+            onClick={() => setRowAction({ row, type: "attachment" })}
+          >
+            <FileText className="h-4 w-4" />
+          </Button>
+        ),
+        size: 80,
+      },
+
+      // 견적품목수 - 수정됨
+      {
+        accessorKey: "prItemsCount",
+        header: ({ column }) => <DataTableColumnHeaderSimple column={column} title="견적품목수" />,
+        cell: ({ row }) => (
+          <Button
+            variant="ghost"
+            size="sm"
+            className="font-mono text-sm p-1 h-auto"
+            onClick={() => setRowAction({ row, type: "items" })}
+          >
+            {row.original.prItemsCount || 0}
+          </Button>
+        ),
+        size: 90,
+      },
+
+      // 견적생성일
+      {
+        accessorKey: "createdAt",
+        header: ({ column }) => <DataTableColumnHeaderSimple column={column} title="견적생성일" />,
+        cell: ({ row }) => {
+          const date = row.original.createdAt;
+          return date ? format(new Date(date), "yyyy-MM-dd") : "-";
+        },
+        size: 100,
+      },
+
+      // 견적발송일
+      {
+        accessorKey: "rfqSendDate",
+        header: ({ column }) => <DataTableColumnHeaderSimple column={column} title="견적발송일" />,
+        cell: ({ row }) => {
+          const date = row.original.rfqSendDate;
+          return date ? format(new Date(date), "yyyy-MM-dd") : "-";
+        },
+        size: 100,
+      },
+
+      // 견적마감일
+      {
+        accessorKey: "dueDate",
+        header: ({ column }) => <DataTableColumnHeaderSimple column={column} title="견적마감일" />,
+        cell: ({ row }) => {
+          const date = row.original.dueDate;
+          if (!date) return "-";
+          
+          const now = new Date();
+          const dueDate = new Date(date);
+          const isOverdue = now > dueDate;
+          
+          return (
+            <span className={`text-sm ${isOverdue ? "text-red-600 font-medium" : ""}`}>
+              {format(dueDate, "yyyy-MM-dd")}
+            </span>
+          );
+        },
+        size: 100,
+      },
+
+      // 구매담당자
+      {
+        accessorKey: "picUserName",
+        header: ({ column }) => <DataTableColumnHeaderSimple column={column} title="구매담당자" />,
+        cell: ({ row }) => row.original.picUserName || row.original.picName || "-",
+        size: 100,
+      },
+
+      // 최종수정일
+      {
+        accessorKey: "updatedAt",
+        header: ({ column }) => <DataTableColumnHeaderSimple column={column} title="최종수정일" />,
+        cell: ({ row }) => {
+          const date = row.original.updatedAt;
+          return date ? format(new Date(date), "yyyy-MM-dd HH:mm") : "-";
+        },
+        size: 120,
+      },
+
+      // 최종수정자
+      {
+        accessorKey: "updatedByUserName",
+        header: ({ column }) => <DataTableColumnHeaderSimple column={column} title="최종수정자" />,
+        cell: ({ row }) => row.original.updatedByUserName || "-",
+        size: 100,
+      },
+
+      // 비고
+      {
+        accessorKey: "remark",
+        header: ({ column }) => <DataTableColumnHeaderSimple column={column} title="비고" />,
+        cell: ({ row }) => row.original.remark || "-",
+        size: 150,
+      },
+    ];
+  }
+
+  // 기본값 (fallback)
+  return [];
 }
\ No newline at end of file
-- 
cgit v1.2.3

