diff --git a/apps/web/src/api/assets.ts b/apps/web/src/api/assets.ts old mode 100644 new mode 100755 index 987590a79..55dd6706c --- a/apps/web/src/api/assets.ts +++ b/apps/web/src/api/assets.ts @@ -390,6 +390,25 @@ export interface BatchOperationResult { failure_count: number; } +/** 统一批量操作结果归一化,防御后端字段缺失或格式不一致 */ +const normalizeBatchResult = ( + raw: Record, +): BatchOperationResult => { + const succeeded = Array.isArray(raw.succeeded) + ? (raw.succeeded as string[]) + : []; + const failed = Array.isArray(raw.failed) ? (raw.failed as string[]) : []; + const success_count = + typeof raw.success_count === "number" + ? raw.success_count + : succeeded.length; + const failure_count = + typeof raw.failure_count === "number" ? raw.failure_count : failed.length; + const total = + typeof raw.total === "number" ? raw.total : success_count + failure_count; + return { succeeded, failed, total, success_count, failure_count }; +}; + /** 批量删除素材 */ export const batchDeleteAssets = async ( assetIds: string[], @@ -397,7 +416,7 @@ export const batchDeleteAssets = async ( const response = await apiClient.post("/assets/batch-delete", { asset_ids: assetIds, }); - return response.data; + return normalizeBatchResult((response.data || {}) as Record); }; /** 批量打标签 */ @@ -407,7 +426,7 @@ export const batchTagAssets = async (data: { mode: "add" | "replace"; }): Promise => { const response = await apiClient.post("/assets/batch-tag", data); - return response.data; + return normalizeBatchResult((response.data || {}) as Record); }; /** 批量改分类 */ @@ -416,7 +435,7 @@ export const batchClassifyAssets = async (data: { category: string; }): Promise => { const response = await apiClient.post("/assets/batch-classify", data); - return response.data; + return normalizeBatchResult((response.data || {}) as Record); }; /** 批量智能标记 */ @@ -425,5 +444,5 @@ export const batchMarkAssets = async (data: { smart_view: "recommended" | "caution" | "high_risk"; }): Promise => { const response = await apiClient.post("/assets/batch-mark", data); - return response.data; + return normalizeBatchResult((response.data || {}) as Record); }; diff --git a/apps/web/src/pages/assets/AssetLibrary.tsx b/apps/web/src/pages/assets/AssetLibrary.tsx old mode 100644 new mode 100755 index d10f881c3..35555cd9d --- a/apps/web/src/pages/assets/AssetLibrary.tsx +++ b/apps/web/src/pages/assets/AssetLibrary.tsx @@ -355,7 +355,10 @@ const AssetLibrary: React.FC = () => { staleTime: 60_000, }); - const libraries = useMemo(() => apiLibraries.map(mapLibrary), [apiLibraries]); + const libraries = useMemo( + () => (Array.isArray(apiLibraries) ? apiLibraries : []).map(mapLibrary), + [apiLibraries], + ); /* ── 当前选中的素材库 ── */ const [activeLibId, setActiveLibId] = useState(""); @@ -377,7 +380,10 @@ const AssetLibrary: React.FC = () => { staleTime: 30_000, }); - const assets = useMemo(() => apiAssets.map(mapAsset), [apiAssets]); + const assets = useMemo( + () => (Array.isArray(apiAssets) ? apiAssets : []).map(mapAsset), + [apiAssets], + ); /* ── Mutations ── */ const createLibMutation = useMutation({