103 lines
3.2 KiB
TypeScript
Executable File
103 lines
3.2 KiB
TypeScript
Executable File
import { useState, useCallback } from "react"
|
|
import { message } from "antd"
|
|
import type { AssetItem } from "@/api/assets"
|
|
import { smartMatchAssets, getAssets } from "@/api/assets"
|
|
|
|
interface UseSmartMatchOptions {
|
|
libraryId: string
|
|
materials: { items: AssetItem[]; total: number }
|
|
smartSelectedIds: string[]
|
|
onSmartSelectedIdsChange: (ids: string[]) => void
|
|
}
|
|
|
|
/**
|
|
* 智能素材匹配 Hook(Q5 简化版)
|
|
* 用户不手动选素材时,一键调用后端 AI 选素材
|
|
* 后端统一选素材逻辑后续完善,当前先走前端流程简化
|
|
*/
|
|
export function useSmartMatch({
|
|
libraryId,
|
|
materials,
|
|
smartSelectedIds,
|
|
onSmartSelectedIdsChange,
|
|
}: UseSmartMatchOptions) {
|
|
const [smartMatching, setSmartMatching] = useState(false)
|
|
const [hasMatched, setHasMatched] = useState(false)
|
|
|
|
/* ── 一键智能匹配 ── */
|
|
const handleSmartMatch = useCallback(async () => {
|
|
if (materials.items.length === 0) {
|
|
message.warning("当前视频库暂无素材")
|
|
return
|
|
}
|
|
|
|
setSmartMatching(true)
|
|
|
|
try {
|
|
// 调用后端智能匹配 API
|
|
const result = await smartMatchAssets(libraryId)
|
|
const matchedIds = result.items.map((a: AssetItem) => a.id)
|
|
|
|
if (matchedIds.length > 0) {
|
|
onSmartSelectedIdsChange(matchedIds)
|
|
setHasMatched(true)
|
|
message.success(`AI 已为你选择 ${matchedIds.length} 个素材`)
|
|
} else {
|
|
// 后端返回空结果,回退到全选
|
|
onSmartSelectedIdsChange(materials.items.map((a) => a.id))
|
|
setHasMatched(true)
|
|
message.info("AI 暂未找到匹配素材,已全选当前库素材")
|
|
}
|
|
} catch {
|
|
// 后端 API 尚未就绪时,回退到全选当前库素材
|
|
onSmartSelectedIdsChange(materials.items.map((a) => a.id))
|
|
setHasMatched(true)
|
|
message.info("已为你全选当前库素材(智能匹配功能即将上线)")
|
|
} finally {
|
|
setSmartMatching(false)
|
|
}
|
|
}, [libraryId, materials.items, onSmartSelectedIdsChange])
|
|
|
|
const handleRefreshMatch = useCallback(async () => {
|
|
// 换一批 = 重新触发智能匹配
|
|
await handleSmartMatch()
|
|
}, [handleSmartMatch])
|
|
|
|
const handleSelectAllMatched = useCallback(() => {
|
|
onSmartSelectedIdsChange(materials.items.map((a) => a.id))
|
|
}, [materials.items, onSmartSelectedIdsChange])
|
|
|
|
const handleClearSmartSelect = useCallback(() => {
|
|
onSmartSelectedIdsChange([])
|
|
}, [onSmartSelectedIdsChange])
|
|
|
|
const handleToggleSmartSelect = useCallback(
|
|
(assetId: string) => {
|
|
onSmartSelectedIdsChange(
|
|
smartSelectedIds.includes(assetId)
|
|
? smartSelectedIds.filter((id) => id !== assetId)
|
|
: [...smartSelectedIds, assetId],
|
|
)
|
|
},
|
|
[smartSelectedIds, onSmartSelectedIdsChange],
|
|
)
|
|
|
|
/* ── 计算已选素材总时长 ── */
|
|
const smartSelectedTotalDuration = materials.items
|
|
.filter((a) => smartSelectedIds.includes(a.id))
|
|
.reduce((sum, a) => sum + (a.duration || 0), 0)
|
|
|
|
return {
|
|
smartMatching,
|
|
hasMatched,
|
|
smartSelectedIds,
|
|
handleSmartMatch,
|
|
handleToggleSmartSelect,
|
|
handleRefreshMatch,
|
|
handleSelectAllMatched,
|
|
handleClearSmartSelect,
|
|
smartSelectedTotalDuration,
|
|
}
|
|
}
|
|
|