feat: 结果页添加帧预览、GIF动画和导出选项
- 后端: GetAssets 返回素材级别 metadata,区分 frame/preview/spritesheet 类型 - 后端: 上传时区分素材类型标签,GIF URL 独立追踪 - 前端: 结果详情页默认展示拆分后的单帧网格 - 前端: 添加动作帧 GIF 预览弹窗 - 前端: 添加导出下拉菜单(整张精灵表/自动切分帧) - 前端: 失败任务展示错误信息和重试次数
This commit is contained in:
@@ -79,26 +79,41 @@ export default function ResultPage() {
|
||||
)
|
||||
}
|
||||
|
||||
return (
|
||||
<div className="container page-enter" style={{ paddingTop: 24, paddingBottom: 40 }}>
|
||||
<div style={{ display: 'flex', justifyContent: 'space-between', alignItems: 'center', marginBottom: 24 }}>
|
||||
<div style={{ display: 'flex', alignItems: 'center', gap: 16 }}>
|
||||
<Link
|
||||
to={`/projects/${projectId}`}
|
||||
style={{ fontSize: 13, color: 'var(--text-secondary)' }}
|
||||
>
|
||||
if (task.status === 'failed') {
|
||||
return (
|
||||
<div className="container page-enter" style={{ paddingTop: 40 }}>
|
||||
<div style={{ display: 'flex', alignItems: 'center', gap: 16, marginBottom: 24 }}>
|
||||
<Link to={`/projects/${projectId}`} style={{ fontSize: 13, color: 'var(--text-secondary)' }}>
|
||||
← 返回工程
|
||||
</Link>
|
||||
<h1 style={{ fontSize: 22 }}>生成结果</h1>
|
||||
<h1 style={{ fontSize: 22 }}>生成失败</h1>
|
||||
</div>
|
||||
{assets.length > 0 && (
|
||||
<button
|
||||
className="btn-primary"
|
||||
onClick={() => downloadAssets(assets)}
|
||||
style={{ padding: '8px 20px', fontSize: 13 }}
|
||||
>
|
||||
下载全部素材
|
||||
</button>
|
||||
<div className="card" style={{ textAlign: 'center', padding: 40 }}>
|
||||
<p style={{ color: 'var(--error)', marginBottom: 8 }}>
|
||||
{task.error || '未知错误'}
|
||||
</p>
|
||||
<p style={{ fontSize: 13, color: 'var(--text-secondary)' }}>
|
||||
重试次数: {task.retryCount ?? 0}
|
||||
</p>
|
||||
</div>
|
||||
</div>
|
||||
)
|
||||
}
|
||||
|
||||
return (
|
||||
<div className="container page-enter" style={{ paddingTop: 24, paddingBottom: 40 }}>
|
||||
<div style={{ marginBottom: 24 }}>
|
||||
<Link
|
||||
to={`/projects/${projectId}`}
|
||||
style={{ fontSize: 13, color: 'var(--text-secondary)' }}
|
||||
>
|
||||
← 返回工程
|
||||
</Link>
|
||||
<h1 style={{ fontSize: 22, marginTop: 8 }}>生成结果</h1>
|
||||
{task.prompt && (
|
||||
<p style={{ fontSize: 13, color: 'var(--text-secondary)', marginTop: 4 }}>
|
||||
提示词: {task.prompt}
|
||||
</p>
|
||||
)}
|
||||
</div>
|
||||
|
||||
@@ -108,22 +123,3 @@ export default function ResultPage() {
|
||||
</div>
|
||||
)
|
||||
}
|
||||
|
||||
async function downloadAssets(assets: Asset[]) {
|
||||
for (const a of assets) {
|
||||
try {
|
||||
const res = await fetch(a.url)
|
||||
const blob = await res.blob()
|
||||
const blobUrl = URL.createObjectURL(blob)
|
||||
const link = document.createElement('a')
|
||||
link.href = blobUrl
|
||||
link.download = `${a.id}.${a.format}`
|
||||
document.body.appendChild(link)
|
||||
link.click()
|
||||
document.body.removeChild(link)
|
||||
URL.revokeObjectURL(blobUrl)
|
||||
} catch {
|
||||
window.open(a.url, '_blank')
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user