perf(core): 资产库改服务端懒加载分页(tab/筛选/计数走后端,不再前端取全量切片)

- api.ts 加 assetsPage(分页+tab/category/source/type/product/q/metadata 过滤)、
  assetSummary(tab 计数)、assetFacets(某 tab 真实存在的来源/类型/metadata 取值)。
- LibraryPage 不再吃全局 assets 全量数组:列表按页拉、tab 徽标走 summary、
  筛选下拉走 facets(「只列真有的」体验保留)、搜索去抖、上传/删除后刷新。
- App.tsx 不再向 LibraryPage 透传 assets。

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
This commit is contained in:
zyc
2026-06-17 18:10:05 +08:00
co-authored by Claude Opus 4.8
parent ce809b2d32
commit 59ab3c0404
3 changed files with 86 additions and 31 deletions
+24
View File
@@ -370,6 +370,30 @@ export const api = {
assets() {
return request<Paginated<Asset>>("/api/assets/");
},
// 服务端分页+过滤的资产列表(各页按需懒加载,不再前端取全量再切片)。
assetsPage(params: {
tab?: string; category?: string; source?: string; asset_type?: string;
product?: string; q?: string; ordering?: string; page?: number; pageSize?: number;
meta?: Record<string, string>;
} = {}) {
const qs = new URLSearchParams();
const { meta, pageSize, ...rest } = params;
for (const [k, v] of Object.entries(rest)) if (v !== undefined && v !== "" && v !== null) qs.set(k, String(v));
if (pageSize) qs.set("page_size", String(pageSize));
if (meta) for (const [k, v] of Object.entries(meta)) if (v) qs.set(`m_${k}`, v);
return request<Paginated<Asset>>(`/api/assets/?${qs.toString()}`);
},
// 资产库各 tab 计数(tab 徽标用,不必取全量)
assetSummary() {
return request<Record<string, number>>("/api/assets/summary/");
},
// 某 tab 下真实存在的筛选项(来源/类型/指定 metadata 键取值),供下拉「只列真有的」
assetFacets(tab?: string, metaKeys: string[] = []) {
const qs = new URLSearchParams();
if (tab) qs.set("tab", tab);
if (metaKeys.length) qs.set("meta_keys", metaKeys.join(","));
return request<{ sources: string[]; kinds: string[]; metadata: Record<string, string[]> }>(`/api/assets/facets/?${qs.toString()}`);
},
// 经后端同源代理取资产原始文件(TOS 未配 CORS,浏览器抽帧/解码必须同源)
async fetchAssetBlob(id: string): Promise<Blob> {
const token = getToken();