feat: 生成进度弹窗增加片段状态列表
CI Build & Deploy Pipeline / Build Staging API Image (push) Has been skipped
CI Build & Deploy Pipeline / Build Staging Web Image (push) Has been skipped
CI Build & Deploy Pipeline / Build Staging Worker Image (push) Has been skipped
CI Build & Deploy Pipeline / Deploy Staging (Watchtower auto-deploy) (push) Has been skipped
CI Build & Deploy Pipeline / Build Production API Image (push) Has been skipped
CI Build & Deploy Pipeline / Build Production Web Image (push) Has been skipped
CI Build & Deploy Pipeline / Build Production Worker Image (push) Has been skipped
CI Build & Deploy Pipeline / Staging E2E Tests (push) Has been skipped
CI Build & Deploy Pipeline / Deploy Production (push) Has been skipped
CI Build & Deploy Pipeline / Staging API Integration Tests (push) Has been skipped
CI Build & Deploy Pipeline / Production Browser E2E (push) Has been skipped
CI/CD Pipeline / Validate Code Quality And Tests (push) Failing after 34s
CI/CD Pipeline / Frontend Lint (push) Failing after 33s
CI/CD Pipeline / Unit Tests (push) Has been cancelled
CI/CD Pipeline / Integration Tests (push) Has been cancelled

- 新增 genClipStatuses state 保存每个片段的处理状态
- 生成进度弹窗展示所有片段的实时状态(等待中/处理中/完成/失败)
- 处理中状态带呼吸动画效果
- 使用轮询已有的 clips 数据,无额外请求
This commit is contained in:
2026-07-16 11:06:24 +08:00
parent 87e739d42f
commit da07dbd1de
2 changed files with 103 additions and 1 deletions
@@ -6048,3 +6048,78 @@
color: #ef4444;
background: #fef2f2;
}
/* ═══ 生成进度 - 片段状态列表 ═══ */
.ep-gen-clip-list {
margin-top: 16px;
max-height: 200px;
overflow-y: auto;
border: 1px solid var(--border-color, #e5e7eb);
border-radius: 8px;
padding: 4px 0;
}
.ep-gen-clip-item {
display: flex;
align-items: center;
gap: 10px;
padding: 6px 12px;
font-size: 13px;
}
.ep-gen-clip-item + .ep-gen-clip-item {
border-top: 1px solid var(--border-color-light, #f3f4f6);
}
.ep-gen-clip-index {
width: 22px;
height: 22px;
display: flex;
align-items: center;
justify-content: center;
background: var(--bg-secondary, #f3f4f6);
border-radius: 4px;
font-size: 11px;
color: var(--text-secondary, #6b7280);
flex-shrink: 0;
}
.ep-gen-clip-name {
flex: 1;
overflow: hidden;
text-overflow: ellipsis;
white-space: nowrap;
color: var(--text-primary, #1f2937);
}
.ep-gen-clip-status {
flex-shrink: 0;
font-size: 12px;
font-weight: 500;
}
.ep-gen-clip-status.status-completed {
color: #10b981;
}
.ep-gen-clip-status.status-failed {
color: #ef4444;
}
.ep-gen-clip-status.status-processing {
color: #3b82f6;
animation: pulse 1.5s infinite;
}
.ep-gen-clip-status.status-pending,
.ep-gen-clip-status.status-queued {
color: #9ca3af;
}
@keyframes pulse {
0%, 100% { opacity: 1; }
50% { opacity: 0.5; }
}
@@ -278,6 +278,7 @@ const EditingPlanner: React.FC = () => {
const [genError, setGenError] = useState<string | null>(null);
const [genCancelled, setGenCancelled] = useState(false);
const [currentGenTaskId, setCurrentGenTaskId] = useState<string | null>(null);
const [genClipStatuses, setGenClipStatuses] = useState<ClipStatusItem[]>([]);
const genTimerRef = useRef<ReturnType<typeof setTimeout> | null>(null);
/* ── 播放 ── */
@@ -1084,6 +1085,7 @@ const EditingPlanner: React.FC = () => {
).length;
setGenDoneClips(done);
setGenTotalClips(total);
setGenClipStatuses(status.clips || []);
setGenProgress(total > 0 ? Math.round((done / total) * 100) : 5);
if (status.plan_status === "completed") {
@@ -1465,7 +1467,32 @@ const EditingPlanner: React.FC = () => {
<p style={{ marginTop: 8, color: "var(--text-secondary)" }}>
{genDoneClips}/{genTotalClips}
</p>
<p style={{ color: "var(--text-secondary)", fontSize: 12 }}>
{genClipStatuses.length > 0 && (
<div className="ep-gen-clip-list">
{genClipStatuses.map((clip, index) => (
<div key={clip.clip_id || index} className="ep-gen-clip-item">
<span className="ep-gen-clip-index">{index + 1}</span>
<span className="ep-gen-clip-name">
{clip.text_content
? clip.text_content.slice(0, 20)
: clip.clip_type || `片段${index + 1}`}
</span>
<span
className={`ep-gen-clip-status status-${clip.status}`}
>
{clip.status === "completed"
? "✓ 完成"
: clip.status === "failed"
? "✗ 失败"
: clip.status === "processing"
? "⟳ 处理中"
: "⏳ 等待中"}
</span>
</div>
))}
</div>
)}
<p style={{ color: "var(--text-secondary)", fontSize: 12, marginTop: 12 }}>
</p>
</div>