From 7d7d5356ff1bbc0f9b407151568dc68be40f67d2 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=EA=B6=8C=ED=98=81=EC=84=B1?= Date: Sat, 21 Feb 2026 08:56:44 +0900 Subject: [PATCH] =?UTF-8?q?feat(WEB):=20=EC=88=98=EC=A3=BC=20Bulk=20Delete?= =?UTF-8?q?=20+=20Revert=20Force=20=ED=94=84=EB=A1=A0=ED=8A=B8=EC=97=94?= =?UTF-8?q?=EB=93=9C=20=EC=97=B0=EB=8F=99?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit - deleteOrders: for 루프 단건 삭제 → DELETE /api/v1/orders/bulk 단일 호출로 전환 - deleteOrders: force 옵션 추가 (개발환경 물리 삭제용) - revertProductionOrder: force/reason 파라미터 추가 - 수주 상세: 되돌리기 다이얼로그에 사유 Textarea 추가 - 수주 상세: 개발환경 전용 "완전삭제 (DEV)" 버튼 추가 - 수주 목록: 개발환경 전용 selectionActions "완전삭제 (DEV)" 버튼 추가 --- .../order-management-sales/[id]/page.tsx | 70 ++++++++++++++++--- .../sales/order-management-sales/page.tsx | 62 ++++++++++++++++ src/components/orders/actions.ts | 61 +++++++++------- 3 files changed, 158 insertions(+), 35 deletions(-) diff --git a/src/app/[locale]/(protected)/sales/order-management-sales/[id]/page.tsx b/src/app/[locale]/(protected)/sales/order-management-sales/[id]/page.tsx index 8bc53653..a897ca5d 100644 --- a/src/app/[locale]/(protected)/sales/order-management-sales/[id]/page.tsx +++ b/src/app/[locale]/(protected)/sales/order-management-sales/[id]/page.tsx @@ -149,6 +149,9 @@ export default function OrderDetailPage() { const [isConfirming, setIsConfirming] = useState(false); const [isRevertDialogOpen, setIsRevertDialogOpen] = useState(false); const [isReverting, setIsReverting] = useState(false); + const [revertReason, setRevertReason] = useState(""); + const [isForceReverting, setIsForceReverting] = useState(false); + const isDev = process.env.NODE_ENV !== 'production'; const [isRevertConfirmDialogOpen, setIsRevertConfirmDialogOpen] = useState(false); const [isRevertingConfirm, setIsRevertingConfirm] = useState(false); const [isDeleteDialogOpen, setIsDeleteDialogOpen] = useState(false); @@ -322,6 +325,7 @@ export default function OrderDetailPage() { // 생산지시 되돌리기 const handleRevertProduction = () => { + setRevertReason(""); setIsRevertDialogOpen(true); }; @@ -329,7 +333,9 @@ export default function OrderDetailPage() { if (order) { setIsReverting(true); try { - const result = await revertProductionOrder(order.id); + const result = await revertProductionOrder(order.id, { + reason: revertReason || undefined, + }); if (result.success && result.data) { setOrder(result.data.order); const { deletedCounts } = result.data; @@ -349,6 +355,28 @@ export default function OrderDetailPage() { } }; + // 생산지시 완전삭제 (force=true, 개발환경 전용) + const handleForceRevertProduction = async () => { + if (order) { + setIsForceReverting(true); + try { + const result = await revertProductionOrder(order.id, { force: true }); + if (result.success && result.data) { + setOrder(result.data.order); + toast.success("생산지시가 완전삭제되었습니다. (물리 삭제)"); + setIsRevertDialogOpen(false); + } else { + toast.error(result.error || "완전삭제에 실패했습니다."); + } + } catch (error) { + console.error("Error force reverting production order:", error); + toast.error("완전삭제 중 오류가 발생했습니다."); + } finally { + setIsForceReverting(false); + } + } + }; + // 수주확정 되돌리기 const handleRevertConfirmation = () => { setIsRevertConfirmDialogOpen(true); @@ -1046,6 +1074,17 @@ export default function OrderDetailPage() { + {/* 되돌리기 사유 */} +
+ +