| @@ -61,6 +61,26 @@ function showDoPickOpsButtons(row: getTicketReleaseTable): boolean { | |||||
| ); | ); | ||||
| } | } | ||||
| const isDev = process.env.NODE_ENV === "development"; | |||||
| function shouldLogTicketFilterDebug(): boolean { | |||||
| if (isDev) return true; | |||||
| if (typeof window === "undefined") return false; | |||||
| return (window as unknown as { __FG_TICKET_FILTER_DEBUG__?: boolean }).__FG_TICKET_FILTER_DEBUG__ === true; | |||||
| } | |||||
| /** | |||||
| * 後端 LocalDate 常序列化為 [year, month, day](month 為 1–12)。 | |||||
| * 不可使用 dayjs(array):會被當成 [年, 月索引 0–11, 日],導致月份錯一個月、篩選與畫面日期錯誤。 | |||||
| */ | |||||
| function requiredDeliveryDateToDayString(value: unknown): string { | |||||
| if (value == null) return ""; | |||||
| if (Array.isArray(value) && value.length >= 3 && value.every((x) => typeof x === "number")) { | |||||
| return arrayToDayjs(value as number[]).format("YYYY-MM-DD"); | |||||
| } | |||||
| return dayjs(value as string | number | Date).format("YYYY-MM-DD"); | |||||
| } | |||||
| const FGPickOrderTicketReleaseTable: React.FC = () => { | const FGPickOrderTicketReleaseTable: React.FC = () => { | ||||
| const { t } = useTranslation("ticketReleaseTable"); | const { t } = useTranslation("ticketReleaseTable"); | ||||
| const { data: session } = useSession() as { data: SessionWithTokens | null }; | const { data: session } = useSession() as { data: SessionWithTokens | null }; | ||||
| @@ -110,6 +130,24 @@ const FGPickOrderTicketReleaseTable: React.FC = () => { | |||||
| try { | try { | ||||
| const dayStr = queryDate.format("YYYY-MM-DD"); | const dayStr = queryDate.format("YYYY-MM-DD"); | ||||
| const result = await fetchTicketReleaseTable(dayStr, dayStr); | const result = await fetchTicketReleaseTable(dayStr, dayStr); | ||||
| if (shouldLogTicketFilterDebug() && Array.isArray(result) && result.length > 0) { | |||||
| const statusCounts = result.reduce<Record<string, number>>((acc, r) => { | |||||
| const k = String(r.ticketStatus ?? "(null)"); | |||||
| acc[k] = (acc[k] ?? 0) + 1; | |||||
| return acc; | |||||
| }, {}); | |||||
| console.log("[FGTicketReleaseTable] API rows:", result.length, "ticketStatus 分布:", statusCounts); | |||||
| console.table( | |||||
| result.slice(0, 5).map((r) => ({ | |||||
| ticketStatus: r.ticketStatus ?? "(null)", | |||||
| requiredDeliveryDate: r.requiredDeliveryDate, | |||||
| itemDate: r.requiredDeliveryDate | |||||
| ? requiredDeliveryDateToDayString(r.requiredDeliveryDate) | |||||
| : "", | |||||
| queryDay: dayStr, | |||||
| })), | |||||
| ); | |||||
| } | |||||
| setData(result); | setData(result); | ||||
| setLastDataRefreshTime(dayjs()); | setLastDataRefreshTime(dayjs()); | ||||
| } catch (error) { | } catch (error) { | ||||
| @@ -133,23 +171,42 @@ const FGPickOrderTicketReleaseTable: React.FC = () => { | |||||
| const dayStr = queryDate.format("YYYY-MM-DD"); | const dayStr = queryDate.format("YYYY-MM-DD"); | ||||
| const filteredData = useMemo(() => { | const filteredData = useMemo(() => { | ||||
| return data.filter((item) => { | |||||
| let dropFloor = 0; | |||||
| let dropDate = 0; | |||||
| let dropStatus = 0; | |||||
| const filtered: getTicketReleaseTable[] = []; | |||||
| for (const item of data) { | |||||
| if (selectedFloor && item.storeId !== selectedFloor) { | if (selectedFloor && item.storeId !== selectedFloor) { | ||||
| return false; | |||||
| dropFloor++; | |||||
| continue; | |||||
| } | } | ||||
| if (item.requiredDeliveryDate) { | if (item.requiredDeliveryDate) { | ||||
| const itemDate = dayjs(item.requiredDeliveryDate).format("YYYY-MM-DD"); | |||||
| const itemDate = requiredDeliveryDateToDayString(item.requiredDeliveryDate); | |||||
| if (itemDate !== dayStr) { | if (itemDate !== dayStr) { | ||||
| return false; | |||||
| dropDate++; | |||||
| continue; | |||||
| } | } | ||||
| } | } | ||||
| if (selectedStatus && item.ticketStatus?.toLowerCase() !== selectedStatus.toLowerCase()) { | if (selectedStatus && item.ticketStatus?.toLowerCase() !== selectedStatus.toLowerCase()) { | ||||
| return false; | |||||
| dropStatus++; | |||||
| continue; | |||||
| } | } | ||||
| return true; | |||||
| }); | |||||
| filtered.push(item); | |||||
| } | |||||
| if (shouldLogTicketFilterDebug()) { | |||||
| console.log("[FGTicketReleaseTable] filter:", { | |||||
| total: data.length, | |||||
| kept: filtered.length, | |||||
| dropFloor, | |||||
| dropDate, | |||||
| dropStatus, | |||||
| selectedFloor: selectedFloor || "(all)", | |||||
| selectedStatus: selectedStatus || "(all)", | |||||
| dayStr, | |||||
| }); | |||||
| } | |||||
| return filtered; | |||||
| }, [data, dayStr, selectedFloor, selectedStatus]); | }, [data, dayStr, selectedFloor, selectedStatus]); | ||||
| const handlePageChange = useCallback((event: unknown, newPage: number) => { | const handlePageChange = useCallback((event: unknown, newPage: number) => { | ||||
| setPaginationController((prev) => ({ | setPaginationController((prev) => ({ | ||||
| ...prev, | ...prev, | ||||
| @@ -360,7 +417,7 @@ const FGPickOrderTicketReleaseTable: React.FC = () => { | |||||
| <TableCell>{row.storeId || "-"}</TableCell> | <TableCell>{row.storeId || "-"}</TableCell> | ||||
| <TableCell> | <TableCell> | ||||
| {row.requiredDeliveryDate | {row.requiredDeliveryDate | ||||
| ? dayjs(row.requiredDeliveryDate).format("YYYY-MM-DD") | |||||
| ? requiredDeliveryDateToDayString(row.requiredDeliveryDate) | |||||
| : "-"} | : "-"} | ||||
| </TableCell> | </TableCell> | ||||