/** * 上传队列面板 * 展示批量上传中每个文件的独立状态/进度;失败可重试、可移除、可清空已完成。 * 上传中的素材卡片同时也会出现在素材网格(后端 prepare 预建 asset), * 此面板用于展示真实传输进度与失败重试入口。 */ import React from "react" import { LoadingOutlined, CheckCircleFilled, CloseCircleFilled, ReloadOutlined, CloseOutlined, } from "@ant-design/icons" import type { UploadItem, UploadFailStage } from "../hooks/useAssetUpload" import { COMPLETE_RETRY_HINT } from "../hooks/useAssetUpload" export interface UploadQueuePanelProps { items: UploadItem[] onRetry: (tempId: string) => void onRemove: (tempId: string) => void onClearFinished: () => void } const STATUS_TEXT: Record = { preparing: "排队中…", uploading: "上传中", ingesting: "转码中…", done: "已完成", error: "上传失败", } /** 失败阶段中文名:让用户一眼看到失败发生在哪一步 */ const FAIL_STAGE_TEXT: Record = { prepare: "准备上传阶段", transfer: "文件传输阶段", complete: "确认入库阶段", } const UploadQueuePanel: React.FC = ({ items, onRetry, onRemove, onClearFinished, }) => { if (items.length === 0) return null const finishedCount = items.filter((it) => it.status === "done").length return (
上传任务({items.length} {finishedCount > 0 ? `,已完成 ${finishedCount}` : ""}) {finishedCount > 0 && ( )}
{items.map((it) => { const isActive = it.status === "preparing" || it.status === "uploading" const showProgress = it.status === "uploading" || it.status === "ingesting" return (
{it.status === "done" || it.duplicated ? ( ) : it.status === "error" ? ( ) : ( )}
{it.fileName}
{showProgress ? (
) : null}
{it.duplicated ? "素材已存在,已跳过" : STATUS_TEXT[it.status]} {it.status === "preparing" && it.hint ? `(${it.hint})` : ""} {it.status === "uploading" ? ` ${it.progress}%` : ""} {it.status === "error" && it.failedStage ? `(${FAIL_STAGE_TEXT[it.failedStage]})` : ""}
{it.status === "error" && it.error ? (
{it.error.split("\n").map((line, idx) => line === COMPLETE_RETRY_HINT ? (
{line}
) : (
{line}
), )}
) : null}
{it.status === "error" && ( )} {(it.status === "error" || it.status === "done") && !isActive && ( )}
) })}
) } export default UploadQueuePanel