6437b96e54
CI/CD Pipeline / Canary Release to Production (push) Has been skipped
CI/CD Pipeline / Check if frontend-only change (push) Has been skipped
CI/CD Pipeline / Validate - Code Quality (push) Failing after 3m17s
CI/CD Pipeline / Validate - Type Check (mypy) (push) Successful in 1m8s
CI/CD Pipeline / Validate - Migration (alembic) (push) Successful in 1m20s
CI/CD Pipeline / Unit Tests (push) Failing after 5m11s
CI/CD Pipeline / Integration Tests (push) Successful in 3m7s
CI/CD Pipeline / Frontend Lint (push) Successful in 55s
CI/CD Pipeline / Frontend Unit Tests (push) Successful in 2m8s
CI/CD Pipeline / PR Build API Image (push) Has been skipped
CI/CD Pipeline / PR Build Web Image (push) Has been skipped
CI/CD Pipeline / PR Build Worker Image (push) Has been skipped
CI/CD Pipeline / Build Staging API Image (push) Successful in 13m32s
CI/CD Pipeline / Build Staging Web Image (push) Successful in 2m27s
CI/CD Pipeline / Build Staging Worker Image (push) Successful in 5m42s
CI/CD Pipeline / Deploy Staging (Watchtower auto-deploy) (push) Successful in 1m33s
CI/CD Pipeline / Staging E2E Tests (push) Successful in 8m18s
CI/CD Pipeline / Staging API Integration Tests (push) Successful in 11m0s
CI/CD Pipeline / Build Production API Image (push) Has been skipped
CI/CD Pipeline / Build Production Web Image (push) Has been skipped
CI/CD Pipeline / Build Production Worker Image (push) Has been skipped
CI/CD Pipeline / Deploy Production (push) Has been skipped
CI/CD Pipeline / Production Browser E2E (push) Has been skipped
CI/CD Pipeline / ACR Image Cleanup (push) Failing after 28s
Co-authored-by: xiaoxia <dev@xiaoxiajianji.com> Co-committed-by: xiaoxia <dev@xiaoxiajianji.com>
66 lines
2.0 KiB
TypeScript
66 lines
2.0 KiB
TypeScript
import { useState, useCallback } from "react"
|
||
import { useQueryClient } from "@tanstack/react-query"
|
||
import { message } from "antd"
|
||
import { uploadAssetDirect } from "@/api/assets"
|
||
import { MAX_FILE_SIZE, LARGE_FILE_THRESHOLD } from "../constants"
|
||
|
||
/**
|
||
* 素材上传 Hook
|
||
* 封装上传状态、进度管理和上传逻辑
|
||
*/
|
||
interface UseAssetUploadProps {
|
||
effectiveLibId: string
|
||
}
|
||
|
||
export function useAssetUpload({ effectiveLibId }: UseAssetUploadProps) {
|
||
const queryClient = useQueryClient()
|
||
|
||
const [uploading, setUploading] = useState(false)
|
||
const [uploadProgress, setUploadProgress] = useState(0)
|
||
|
||
const handleUpload = useCallback(
|
||
async (file: File) => {
|
||
if (file.size > MAX_FILE_SIZE) {
|
||
message.error(`文件 "${file.name}" 超过 2GB 限制`)
|
||
return
|
||
}
|
||
if (!effectiveLibId) {
|
||
message.warning("请先选择或创建一个视频库")
|
||
return
|
||
}
|
||
|
||
setUploading(true)
|
||
setUploadProgress(0)
|
||
try {
|
||
if (file.size > LARGE_FILE_THRESHOLD) {
|
||
message.info(`大文件 "${file.name}" 将使用直传上传`)
|
||
}
|
||
await uploadAssetDirect({
|
||
file,
|
||
library_id: effectiveLibId,
|
||
onProgress: (pct) => setUploadProgress(pct),
|
||
})
|
||
message.success(`"${file.name}" 上传成功`)
|
||
queryClient.invalidateQueries({ queryKey: ["assets"] })
|
||
queryClient.invalidateQueries({ queryKey: ["asset-libraries"] })
|
||
} catch (err: unknown) {
|
||
const detail = err instanceof Error ? err.message : ""
|
||
console.error("[handleUpload] 上传失败:", err)
|
||
message.error(`"${file.name}" 上传失败${detail ? `:${detail}` : ""}`)
|
||
// 错误时延迟关闭弹窗,让用户能看到错误提示
|
||
await new Promise((r) => setTimeout(r, 1500))
|
||
} finally {
|
||
setUploading(false)
|
||
setUploadProgress(0)
|
||
}
|
||
},
|
||
[effectiveLibId, queryClient],
|
||
)
|
||
|
||
return {
|
||
uploading,
|
||
uploadProgress,
|
||
handleUpload,
|
||
}
|
||
}
|