style: reformat useSmartMatch.ts with repo prettier config (#1899 #1900)
CI/CD Pipeline / Dedup Check - skip PR tests when covered by push pipeline (pull_request) Has been cancelled
CI/CD Pipeline / Validate - Style (pull_request) Has been cancelled
CI/CD Pipeline / Validate - Security (pull_request) Has been cancelled
CI/CD Pipeline / Validate - Python (mypy + alembic) (pull_request) Has been cancelled
CI/CD Pipeline / Unit Tests (pull_request) Has been cancelled
CI/CD Pipeline / Integration Tests (pull_request) Has been cancelled
CI/CD Pipeline / Frontend Lint (pull_request) Has been cancelled
CI/CD Pipeline / Frontend Unit Tests (pull_request) Has been cancelled
CI/CD Pipeline / PR Build API Image (pull_request) Has been cancelled
CI/CD Pipeline / PR Build Web Image (pull_request) Has been cancelled
CI/CD Pipeline / PR Build Worker Image (pull_request) Has been cancelled
CI/CD Pipeline / Build Staging Web Image (pull_request) Has been cancelled
CI/CD Pipeline / Check if frontend-only change (pull_request) Successful in 1s
CI/CD Pipeline / Build Staging API Image (pull_request) Has been cancelled
CI/CD Pipeline / Check push changed paths (pull_request) Has been skipped
CI/CD Pipeline / Build Staging Worker Image (pull_request) Has been cancelled
CI/CD Pipeline / Retag skipped Staging API Image (pull_request) Has been cancelled
CI/CD Pipeline / Retag skipped Staging Web Image (pull_request) Has been cancelled
CI/CD Pipeline / Retag skipped Staging Worker Image (pull_request) Has been cancelled
CI/CD Pipeline / Deploy Staging (Watchtower auto-deploy) (pull_request) Has been cancelled
CI/CD Pipeline / Staging E2E Tests (pull_request) Has been cancelled
CI/CD Pipeline / Staging API Integration Tests (pull_request) Has been cancelled
CI/CD Pipeline / Build Production API Image (pull_request) Has been cancelled
CI/CD Pipeline / Build Production Web Image (pull_request) Has been cancelled
CI/CD Pipeline / Build Production Worker Image (pull_request) Has been cancelled
CI/CD Pipeline / Deploy Production (pull_request) Has been cancelled
CI/CD Pipeline / Production Browser E2E (pull_request) Has been cancelled
CI/CD Pipeline / ACR Image Cleanup (pull_request) Has been cancelled
CI/CD Pipeline / Canary Release to Production (pull_request) Has been cancelled
CI/CD Pipeline / CI Gate (pull_request) Has been cancelled
AI Code Review / AI Code Review (pull_request) Has been cancelled
PR Automation / Auto Approve on CI Green (pull_request) Has been cancelled
PR Automation / Auto Merge on CI Green + Approved (pull_request) Has been cancelled
Preview Deploy / Deploy Preview Environment (pull_request) Has been cancelled

This commit is contained in:
2026-09-14 21:37:36 +08:00
parent ad8dda8e36
commit 712e381ec6
@@ -1,32 +1,32 @@
import { useState, useCallback } from "react";
import { message } from "antd";
import type { AssetItem } from "@/api/assets";
import { smartMatchAssets, isAssetUsable } from "@/api/assets";
import { useState, useCallback } from "react"
import { message } from "antd"
import type { AssetItem } from "@/api/assets"
import { smartMatchAssets, isAssetUsable } from "@/api/assets"
interface UseSmartMatchOptions {
libraryId: string;
materials: { items: AssetItem[]; total: number };
onSmartSelectedIdsChange: (ids: string[]) => void;
libraryId: string
materials: { items: AssetItem[]; total: number }
onSmartSelectedIdsChange: (ids: string[]) => void
/** 片段数量(#1899) */
clipCount: number;
clipCount: number
}
/** 默认 limit(拿不到目标时长时的兜底上限) */
const DEFAULT_LIMIT = 30;
const DEFAULT_LIMIT = 30
/**
* 候选池放大倍数:批量 N 个变体独立选片、跨变体 20% 区间避让需要
* 足够大的素材池才能保证 N 条成片素材排布互不相同。
*/
const ASSET_POOL_MULTIPLIER = 3;
const ASSET_POOL_MULTIPLIER = 3
/**
* 根据片段数量计算智能匹配候选素材数量上限(#1899)。
* 候选池 = clipCount × 倍数;结果钳制到 [1, 200] 区间。
*/
export function computeLimitFromClipCount(clipCount: number): number {
if (clipCount <= 0) return DEFAULT_LIMIT;
const limit = clipCount * ASSET_POOL_MULTIPLIER;
return Math.max(1, Math.min(limit, 200));
if (clipCount <= 0) return DEFAULT_LIMIT
const limit = clipCount * ASSET_POOL_MULTIPLIER
return Math.max(1, Math.min(limit, 200))
}
/**
@@ -38,62 +38,58 @@ export function useSmartMatch({
onSmartSelectedIdsChange,
clipCount,
}: UseSmartMatchOptions) {
const [smartMatching, setSmartMatching] = useState(false);
const [hasMatched, setHasMatched] = useState(false);
const [smartMatching, setSmartMatching] = useState(false)
const [hasMatched, setHasMatched] = useState(false)
const handleSmartMatch = useCallback(async () => {
if (!libraryId) {
message.warning("请先选择视频库");
return;
message.warning("请先选择视频库")
return
}
const usableItems = materials.items.filter(isAssetUsable);
const usableItems = materials.items.filter(isAssetUsable)
if (usableItems.length === 0) {
message.warning(
materials.items.length === 0
? "当前视频库暂无素材"
: "素材可能已用尽,请先上传新素材",
);
return;
materials.items.length === 0 ? "当前视频库暂无素材" : "素材可能已用尽,请先上传新素材",
)
return
}
setSmartMatching(true);
setSmartMatching(true)
try {
const limit = computeLimitFromClipCount(clipCount);
const limit = computeLimitFromClipCount(clipCount)
const result = await smartMatchAssets(libraryId, limit);
const matched = (result.items ?? []).filter(
(a) => !!a?.id && isAssetUsable(a),
);
const matchedIds = matched.map((a: AssetItem) => a.id);
const result = await smartMatchAssets(libraryId, limit)
const matched = (result.items ?? []).filter((a) => !!a?.id && isAssetUsable(a))
const matchedIds = matched.map((a: AssetItem) => a.id)
if (matchedIds.length > 0) {
onSmartSelectedIdsChange(matchedIds);
setHasMatched(true);
message.success(`AI 已为你选择 ${matchedIds.length} 个素材`);
onSmartSelectedIdsChange(matchedIds)
setHasMatched(true)
message.success(`AI 已为你选择 ${matchedIds.length} 个素材`)
} else {
onSmartSelectedIdsChange(usableItems.map((a) => a.id));
setHasMatched(true);
message.info("AI 暂未找到匹配素材,已全选当前库素材");
onSmartSelectedIdsChange(usableItems.map((a) => a.id))
setHasMatched(true)
message.info("AI 暂未找到匹配素材,已全选当前库素材")
}
} catch {
onSmartSelectedIdsChange(usableItems.map((a) => a.id));
setHasMatched(true);
message.info("已为你全选当前库素材(智能匹配功能即将上线)");
onSmartSelectedIdsChange(usableItems.map((a) => a.id))
setHasMatched(true)
message.info("已为你全选当前库素材(智能匹配功能即将上线)")
} finally {
setSmartMatching(false);
setSmartMatching(false)
}
}, [libraryId, materials.items, onSmartSelectedIdsChange, clipCount]);
}, [libraryId, materials.items, onSmartSelectedIdsChange, clipCount])
const handleRefreshMatch = useCallback(async () => {
await handleSmartMatch();
}, [handleSmartMatch]);
await handleSmartMatch()
}, [handleSmartMatch])
return {
smartMatching,
hasMatched,
handleSmartMatch,
handleRefreshMatch,
};
}
}