import { useState, useMemo } from "react" import { useQuery } from "@tanstack/react-query" import { getAssetLibraries, getAssets, type AssetLibraryItem, type AssetItem as ApiAssetItem, } from "@/api/assets" import { mapLibrary, mapAsset, type AssetItem, type LibraryItem } from "../types" /** * 素材库数据 Hook * 封装视频库列表、素材列表的数据查询,以及筛选、搜索状态管理 */ export function useAssetsData() { /* ── 视频库列表查询 ── */ const { data: apiLibraries = [], isLoading: libLoading } = useQuery({ queryKey: ["asset-libraries"], queryFn: getAssetLibraries, staleTime: 60_000, }) const libraries: LibraryItem[] = useMemo( () => (Array.isArray(apiLibraries) ? apiLibraries : []) .map(mapLibrary) .filter((lib) => lib.kind === "video"), [apiLibraries], ) /* ── 当前选中的视频库 ── */ const [activeLibId, setActiveLibId] = useState("") // 当库列表加载完成后,自动选中第一个 const effectiveLibId = activeLibId || libraries[0]?.id || "" /* ── 当前库的素材列表查询 ── */ const { data: apiAssets = { items: [], total: 0 }, isLoading: assetsLoading, isError: assetsError, error: assetsErrorObj, refetch: refetchAssets, } = useQuery<{ items: ApiAssetItem[]; total: number }, Error>({ queryKey: ["assets", effectiveLibId], queryFn: () => getAssets(effectiveLibId, { // 拉取所有非删除状态的素材,让用户上传后立刻能看到"处理中"的素材 status: "ready,uploading,ingesting,processing,pending,error,failed", }), enabled: !!effectiveLibId, staleTime: 30_000, }) const assets: AssetItem[] = useMemo( () => (Array.isArray(apiAssets?.items) ? apiAssets.items : []).map(mapAsset), [apiAssets], ) /* ── 筛选状态 ── */ const [searchText, setSearchText] = useState("") const [filterType, setFilterType] = useState("all") const [filterTime, setFilterTime] = useState("all") /* ── 筛选后的素材列表 ── */ const filteredAssets = useMemo(() => { let list = assets /* 按素材类型过滤 */ if (filterType !== "all") { list = list.filter((a) => a.kind === filterType) } /* 按时间筛选 */ if (filterTime !== "all") { const now = new Date() list = list.filter((a) => { const d = new Date(a.createdAt) const diffDays = (now.getTime() - d.getTime()) / (1000 * 60 * 60 * 24) if (filterTime === "today") return diffDays < 1 if (filterTime === "week") return diffDays < 7 if (filterTime === "month") return diffDays < 30 return true }) } /* 搜索 */ if (searchText.trim()) { const q = searchText.trim().toLowerCase() list = list.filter((a) => a.name.toLowerCase().includes(q)) } return list }, [assets, filterType, filterTime, searchText]) return { // 视频库 libraries, libLoading, activeLibId, setActiveLibId, effectiveLibId, // 素材列表 assets, assetsLoading, assetsError, assetsErrorObj, refetchAssets, // 筛选 searchText, setSearchText, filterType, setFilterType, filterTime, setFilterTime, filteredAssets, } }