Files
xiaoxia-saas/apps/web/src/pages/generate/hooks/step2-materials/useSmartMatch.ts
T

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,
}
}