From 27f062341e50b862425a18ba5621ce282c08a50b Mon Sep 17 00:00:00 2001 From: "CANCERYS\\kw093" Date: Sat, 11 Apr 2026 20:07:17 +0800 Subject: [PATCH] update truck X part --- src/app/api/do/actions.tsx | 24 +++++++- src/components/DoSearch/DoSearch.tsx | 6 ++ .../FinishedGoodFloorLanePanel.tsx | 3 + .../ReleasedDoPickOrderSelectModal.tsx | 55 +++++++++++-------- .../Jodetail/newJobPickExecution.tsx | 6 +- 5 files changed, 67 insertions(+), 27 deletions(-) diff --git a/src/app/api/do/actions.tsx b/src/app/api/do/actions.tsx index dd9c16b..76304b7 100644 --- a/src/app/api/do/actions.tsx +++ b/src/app/api/do/actions.tsx @@ -292,6 +292,12 @@ export const fetchDoDetail = cache(async (id: number) => { }); }); +/** 車線搜尋為「車線-X」時改走後端專用 API(只含推算車線為 null/空白之送貨單) */ +function isTruckLaneXSearch(truckLanceCode?: string): boolean { + const t = truckLanceCode?.trim().toLowerCase() ?? ""; + return t === "車線-x"; +} + export async function fetchDoSearch( code: string, shopName: string, @@ -322,7 +328,14 @@ export async function fetchDoSearch( requestBody.estimatedArrivalDate = null; } - const url = `${BASE_API_URL}/do/search-do-lite`; + const useUnassignedTruck = isTruckLaneXSearch(truckLanceCode); + if (useUnassignedTruck) { + delete requestBody.truckLanceCode; + } + + const url = useUnassignedTruck + ? `${BASE_API_URL}/do/search-do-lite-unassigned-truck` + : `${BASE_API_URL}/do/search-do-lite`; const data = await serverFetchJson(url, { method: "POST", @@ -460,7 +473,14 @@ export async function fetchAllDoSearch( requestBody.estimatedArrivalDate = null; } - const url = `${BASE_API_URL}/do/search-do-lite`; + const useUnassignedTruck = isTruckLaneXSearch(truckLanceCode); + if (useUnassignedTruck) { + delete requestBody.truckLanceCode; + } + + const url = useUnassignedTruck + ? `${BASE_API_URL}/do/search-do-lite-unassigned-truck` + : `${BASE_API_URL}/do/search-do-lite`; const data = await serverFetchJson(url, { method: "POST", diff --git a/src/components/DoSearch/DoSearch.tsx b/src/components/DoSearch/DoSearch.tsx index fa99cb0..ddfde5a 100644 --- a/src/components/DoSearch/DoSearch.tsx +++ b/src/components/DoSearch/DoSearch.tsx @@ -239,6 +239,12 @@ const DoSearch: React.FC = ({ filterArgs, searchQuery, onDeliveryOrderSea field: "truckLanceCode", headerName: t("Truck Lance Code"), flex: 1, + renderCell: (params) => { + const v = params.row.truckLanceCode; + if (v == null) return "車線-X"; + if (typeof v === "string" && v.trim() === "") return "車線-X"; + return v; + } }, { field: "orderDate", diff --git a/src/components/FinishedGoodSearch/FinishedGoodFloorLanePanel.tsx b/src/components/FinishedGoodSearch/FinishedGoodFloorLanePanel.tsx index 336f270..a91178e 100644 --- a/src/components/FinishedGoodSearch/FinishedGoodFloorLanePanel.tsx +++ b/src/components/FinishedGoodSearch/FinishedGoodFloorLanePanel.tsx @@ -670,6 +670,7 @@ const getDateLabel = (offset: number) => { variant="outlined" size="medium" onClick={() => { + setIsDefaultTruck(false); setSelectedStore("2/F"); setSelectedTruck(truck); setModalOpen(true); @@ -737,6 +738,7 @@ const getDateLabel = (offset: number) => { variant="outlined" size="medium" onClick={() => { + setIsDefaultTruck(false); setSelectedStore("4/F"); setSelectedTruck(truck); setModalOpen(true); @@ -802,6 +804,7 @@ const getDateLabel = (offset: number) => { storeId={selectedStore} truck={selectedTruck} isDefaultTruck={isDefaultTruck} + defaultDateScope={defaultDateScope} onClose={() => setModalOpen(false)} onAssigned={() => { loadSummaries(); diff --git a/src/components/FinishedGoodSearch/ReleasedDoPickOrderSelectModal.tsx b/src/components/FinishedGoodSearch/ReleasedDoPickOrderSelectModal.tsx index 01abc52..d08b6a7 100644 --- a/src/components/FinishedGoodSearch/ReleasedDoPickOrderSelectModal.tsx +++ b/src/components/FinishedGoodSearch/ReleasedDoPickOrderSelectModal.tsx @@ -23,12 +23,28 @@ import { assignByDoPickOrderId, type ReleasedDoPickOrderListItem, fetchReleasedDoPickOrdersForSelectionToday, + type PostPickOrderResponse, } from "@/app/api/pickOrder/actions"; import { useSession } from "next-auth/react"; import { SessionWithTokens } from "@/config/authConfig"; import Swal from "sweetalert2"; import dayjs from "dayjs"; -type DateScope = "today" | "before"; + +/** DO workbench 使用 workbench released API;Finished Good 不傳即可 */ +export type ReleasedDoPickListBridge = { + loadBeforeToday: ( + shopName?: string, + storeId?: string, + truck?: string + ) => Promise; + loadToday: ( + shopName?: string, + storeId?: string, + truck?: string + ) => Promise; + assignByListItemId: (userId: number, id: number) => Promise; +}; + interface Props { open: boolean; onClose: () => void; @@ -36,7 +52,9 @@ interface Props { storeId: string; truck: string; isDefaultTruck: boolean; + /** Truck X only: today → released-today; before → released (歷史未完工) */ defaultDateScope?: "today" | "before"; + listBridge?: ReleasedDoPickListBridge; } const ReleasedDoPickOrderSelectModal: React.FC = ({ @@ -46,11 +64,12 @@ const ReleasedDoPickOrderSelectModal: React.FC = ({ storeId, truck, isDefaultTruck, + defaultDateScope: defaultDateScopeProp = "today", + listBridge, }) => { const { t } = useTranslation("pickOrder"); const { data: session } = useSession() as { data: SessionWithTokens | null }; const currentUserId = session?.id ? parseInt(session.id) : undefined; - const [defaultDateScope, setDefaultDateScope] = useState<"today" | "before">("today"); const [list, setList] = useState([]); const [loading, setLoading] = useState(false); const [shopSearch, setShopSearch] = useState(""); @@ -60,27 +79,18 @@ const ReleasedDoPickOrderSelectModal: React.FC = ({ if (!open) return; setLoading(true); try { - let data: ReleasedDoPickOrderListItem[]; // ⭐ 先宣告 - + let data: ReleasedDoPickOrderListItem[]; + const loadReleased = listBridge?.loadBeforeToday ?? fetchReleasedDoPickOrdersForSelection; + const loadTodayFn = listBridge?.loadToday ?? fetchReleasedDoPickOrdersForSelectionToday; + if (isDefaultTruck) { - if (defaultDateScope === "today") { - // Truck X 今天 - data = await fetchReleasedDoPickOrdersForSelectionToday( - undefined, // shopName - undefined, // storeId - "車線-X" // truck - ); + if (defaultDateScopeProp === "today") { + data = await loadTodayFn(undefined, undefined, "車線-X"); } else { - // Truck X 以前(/released,server 內是 < today) - data = await fetchReleasedDoPickOrdersForSelection( - undefined, - undefined, - "車線-X" - ); + data = await loadReleased(undefined, undefined, "車線-X"); } } else { - // 一般車道 - data = await fetchReleasedDoPickOrdersForSelection( + data = await loadReleased( shopSearch.trim() || undefined, storeId, truck?.trim() || undefined @@ -94,7 +104,7 @@ const ReleasedDoPickOrderSelectModal: React.FC = ({ } finally { setLoading(false); } - }, [open, shopSearch, storeId, truck, isDefaultTruck, defaultDateScope]); + }, [open, shopSearch, storeId, truck, isDefaultTruck, defaultDateScopeProp, listBridge]); useEffect(() => { loadList(); @@ -131,7 +141,8 @@ const ReleasedDoPickOrderSelectModal: React.FC = ({ setIsAssigning(true); try { - const res = await assignByDoPickOrderId(currentUserId, item.id); + const assignFn = listBridge?.assignByListItemId ?? assignByDoPickOrderId; + const res = await assignFn(currentUserId, item.id); if (res?.code === "SUCCESS") { Swal.fire({ icon: "success", @@ -154,7 +165,7 @@ const ReleasedDoPickOrderSelectModal: React.FC = ({ setIsAssigning(false); } }, - [currentUserId, t, onAssigned, onClose] + [currentUserId, t, onAssigned, onClose, listBridge] ); return ( diff --git a/src/components/Jodetail/newJobPickExecution.tsx b/src/components/Jodetail/newJobPickExecution.tsx index e2fcfec..b271611 100644 --- a/src/components/Jodetail/newJobPickExecution.tsx +++ b/src/components/Jodetail/newJobPickExecution.tsx @@ -2979,7 +2979,7 @@ const sortedData = [...sourceData].sort((a, b) => { variant="outlined" size="small" onClick={() => handlePickExecutionForm(lot)} - /* + disabled={ lot.lotAvailability === "expired" || lot.stockOutLineStatus === "completed" || @@ -2988,8 +2988,8 @@ const sortedData = [...sourceData].sort((a, b) => { (Number(lot.stockOutLineId) > 0 && actionBusyBySolId[Number(lot.stockOutLineId)] === true) } - */ - disabled={true} + + //disabled={true} sx={{ fontSize: '0.7rem', py: 0.5,