| @@ -294,117 +294,47 @@ const PoSearch: React.FC<Props> = ({ | |||
| if (typeof v === "string" && (v as string).trim() === "") return; | |||
| cleanedQuery[k] = String(v); | |||
| }); | |||
| try { | |||
| const baseListResp = await clientAuthFetch( | |||
| `${NEXT_PUBLIC_API_URL}/po/list?${new URLSearchParams(cleanedQuery).toString()}`, | |||
| { method: "GET" }, | |||
| ); | |||
| if (!baseListResp.ok) { | |||
| throw new Error(`PO list fetch failed: ${baseListResp.status}`); | |||
| } | |||
| const res = await baseListResp.json(); | |||
| if (!res) return; | |||
| const records: PoResult[] = res.records ?? []; | |||
| const searchedCodeRaw = (filterArgs as any)?.code; | |||
| const searchedCode = | |||
| typeof searchedCodeRaw === "string" ? searchedCodeRaw.trim() : ""; | |||
| const isM18PoCode = | |||
| searchedCode.length > 14 && | |||
| (searchedCode.startsWith("PP") || searchedCode.startsWith("PF")); | |||
| const hasLocalPending = records.some( | |||
| (row) => String(row.status ?? "").toLowerCase() === "pending", | |||
| ); | |||
| const shouldLookupMissing = records.length === 0 && isM18PoCode; | |||
| const shouldRefreshPending = hasLocalPending && isM18PoCode; | |||
| if ( | |||
| (!shouldLookupMissing && !shouldRefreshPending) || | |||
| autoSyncInProgressRef.current | |||
| ) { | |||
| setFilteredPo(records); | |||
| setTotalCount(res.total); | |||
| return; | |||
| } | |||
| if (shouldRefreshPending) { | |||
| setFilteredPo(records); | |||
| setTotalCount(res.total); | |||
| if (isM18PoCode) { | |||
| cleanedQuery.refreshFromM18 = "true"; | |||
| setIsM18LookupLoading(true); | |||
| setAutoSyncStatus("載入中..."); | |||
| } | |||
| try { | |||
| autoSyncInProgressRef.current = true; | |||
| setIsM18LookupLoading(shouldLookupMissing); | |||
| setAutoSyncStatus( | |||
| shouldLookupMissing | |||
| ? "正在從M18找尋PO..." | |||
| : "正在檢查M18是否有更新...", | |||
| ); | |||
| const syncResp = await clientAuthFetch( | |||
| `${NEXT_PUBLIC_API_URL}/m18/test/po-by-code?code=${encodeURIComponent( | |||
| searchedCode, | |||
| )}&ifNewer=true`, | |||
| const baseListResp = await clientAuthFetch( | |||
| `${NEXT_PUBLIC_API_URL}/po/list?${new URLSearchParams(cleanedQuery).toString()}`, | |||
| { method: "GET" }, | |||
| ); | |||
| if (!syncResp.ok) { | |||
| throw new Error(`M18 sync failed: ${syncResp.status}`); | |||
| } | |||
| let syncJson: any = null; | |||
| try { | |||
| syncJson = await syncResp.json(); | |||
| } catch { | |||
| // Some endpoints may respond with plain text | |||
| const txt = await syncResp.text(); | |||
| syncJson = { raw: txt }; | |||
| } | |||
| const syncOk = Boolean(syncJson?.totalSuccess && syncJson.totalSuccess > 0); | |||
| const skippedIfNewer = String(syncJson?.query ?? "").includes( | |||
| "skipped (ifNewer)", | |||
| ); | |||
| if (syncOk) { | |||
| setAutoSyncStatus( | |||
| shouldLookupMissing ? "成功找到PO" : "已從M18更新PO", | |||
| ); | |||
| const listResp = await clientAuthFetch( | |||
| `${NEXT_PUBLIC_API_URL}/po/list?${new URLSearchParams( | |||
| cleanedQuery, | |||
| ).toString()}`, | |||
| { method: "GET" }, | |||
| ); | |||
| if (listResp.ok) { | |||
| const listJson = await listResp.json(); | |||
| setFilteredPo(listJson.records ?? []); | |||
| setTotalCount(listJson.total ?? 0); | |||
| setAutoSyncStatus( | |||
| shouldLookupMissing ? "成功找到PO" : "已從M18更新PO", | |||
| ); | |||
| return; | |||
| } | |||
| setAutoSyncStatus(shouldLookupMissing ? "找不到PO" : null); | |||
| } else if (skippedIfNewer || shouldRefreshPending) { | |||
| setAutoSyncStatus(null); | |||
| } else { | |||
| setAutoSyncStatus("找不到PO"); | |||
| if (!baseListResp.ok) { | |||
| throw new Error(`PO list fetch failed: ${baseListResp.status}`); | |||
| } | |||
| const res = await baseListResp.json(); | |||
| if (!res) return; | |||
| const records: PoResult[] = res.records ?? []; | |||
| setFilteredPo(records); | |||
| setTotalCount(res.total ?? 0); | |||
| if (isM18PoCode) { | |||
| const refreshAction = baseListResp.headers.get("X-M18-Po-Refresh"); | |||
| if (refreshAction === "synced") { | |||
| setAutoSyncStatus(records.length > 0 ? "已從M18同步PO" : "找不到PO"); | |||
| } else { | |||
| setAutoSyncStatus(null); | |||
| } | |||
| } | |||
| } catch (e) { | |||
| console.error("Auto sync error:", e); | |||
| setAutoSyncStatus(shouldLookupMissing ? "找不到PO" : null); | |||
| setFilteredPo(records); | |||
| setTotalCount(res.total ?? 0); | |||
| console.error("PO list fetch error:", e); | |||
| if (isM18PoCode) setAutoSyncStatus("找不到PO"); | |||
| } finally { | |||
| setIsM18LookupLoading(false); | |||
| autoSyncInProgressRef.current = false; | |||
| } | |||
| } catch (e) { | |||
| console.error("PO list fetch error:", e); | |||
| } | |||
| }, | |||
| [], | |||
| ); | |||
| @@ -501,7 +431,7 @@ const PoSearch: React.FC<Props> = ({ | |||
| > | |||
| <CircularProgress color="inherit" /> | |||
| <Typography variant="body1"> | |||
| {autoSyncStatus || "正在從M18找尋PO..."} | |||
| {autoSyncStatus || "載入中..."} | |||
| </Typography> | |||
| </Backdrop> | |||
| </> | |||