diff --git a/apps/web/src/pages/products/hooks/useProductList/index.ts b/apps/web/src/pages/products/hooks/useProductList/index.ts index 1452a46e5..6729bca21 100644 --- a/apps/web/src/pages/products/hooks/useProductList/index.ts +++ b/apps/web/src/pages/products/hooks/useProductList/index.ts @@ -1,28 +1,53 @@ import { useMemo } from "react" -import { useQuery } from "@tanstack/react-query" +import { useInfiniteQuery } from "@tanstack/react-query" import { getProducts, type ProductItem as ApiProductItem } from "@/api/products" import { mapApiProduct } from "../../utils" +import type { ProductItem } from "../../types" import { useProductFiltering } from "./useProductFiltering" import { useBatchSelection } from "./useBatchSelection" export type { Filters } from "./useProductFiltering" +const PAGE_SIZE = 20 + export const useProductList = () => { - /* ── 获取成品列表 ── */ + /* ── 无限滚动获取成品列表(每页 20 条) ── */ const { - data: apiProducts = [], + data, isLoading, + isFetchingNextPage, isError, error, + hasNextPage, + fetchNextPage, refetch, - } = useQuery({ + } = useInfiniteQuery< + { + items: ApiProductItem[] + total: number + page: number + page_size: number + }, + Error + >({ queryKey: ["products"], - queryFn: () => getProducts(), + queryFn: async ({ pageParam = 1 }) => + getProducts({ page: pageParam as number, page_size: PAGE_SIZE }), + initialPageParam: 1, + getNextPageParam: (lastPage) => { + const loadedCount = lastPage.page * lastPage.page_size + return loadedCount < lastPage.total ? lastPage.page + 1 : undefined + }, staleTime: 30_000, }) - // 映射为前端类型,按创建时间倒序排列,防御非数组返回 - const products = useMemo( + // 将所有页拼接为一维数组,再做前端映射+排序 + const apiProducts = useMemo(() => { + if (!data?.pages) return [] + return data.pages.flatMap((p) => p.items) + }, [data]) + + const products = useMemo( () => (Array.isArray(apiProducts) ? apiProducts : []).map(mapApiProduct).sort((a, b) => { if (!a.date || a.date === "—") return 1 @@ -65,8 +90,11 @@ export const useProductList = () => { products, filteredProducts, isLoading, + isFetchingNextPage, isError, error, + hasNextPage, + fetchNextPage, refetch, // 筛选 searchText,