feat(core): Wave 4 pipeline 视觉签名(纯视觉/rule 3 合规)

- 脚本助手头补 model mono 签名「· {模型名}」(品牌签名,用 S2 的 .mono-11 工具类)
- 阶段4 视频卡 meta 补三段「{N}s · {分辨率} · ~¥0.45」(分辨率取 timeline.resolution)
- 阶段4 queue-bar 补 Seedance 预估「约 15 秒」
- 阶段5 时间轴 zoom 范围 100-300 → 50-200(对齐 V1)
未碰脚本 agent/生成/轮询任何业务逻辑,只改文案/范围。tsc 0 · build 0。

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
This commit is contained in:
seaislee1209
2026-06-19 13:08:25 +08:00
co-authored by Claude Opus 4.8
parent 946e0169cd
commit 09e67a5893
+4 -3
View File
@@ -2324,6 +2324,7 @@ export function PipelinePage(props: {
<div className="pane-h">
<div className="ai-avatar">AI</div>
<strong></strong>
<span className="muted-2 mono-11" style={{ marginLeft: "8px" }}>· {activeModelName}</span>
<span className="spacer"></span>
<button className="btn btn-ghost btn-sm" type="button" id="chat-clear-btn" disabled={!chatText && chatAttachments.length === 0 && chatMsgs.length === 0} onClick={clearChat}></button>
</div>
@@ -2881,7 +2882,7 @@ export function PipelinePage(props: {
<div className="queue-bar">
<div>
<div style={{ fontSize: "14px", fontWeight: 600 }}> · {segDone} / {segments.length} </div>
<div className="muted-2 mono" style={{ fontSize: "12px", marginTop: "3px", letterSpacing: ".02em" }}>// 每场 Seedance 生成 · {statusText}</div>
<div className="muted-2 mono" style={{ fontSize: "12px", marginTop: "3px", letterSpacing: ".02em" }}>// 每场 Seedance 约 15 秒 · {statusText}</div>
</div>
<div className="bar-wrap"><span style={{ width: `${pct}%` }}></span></div>
<span className="muted mono" style={{ fontSize: "12px" }}>{pct}%</span>
@@ -2915,7 +2916,7 @@ export function PipelinePage(props: {
</strong>
<span className={`pill ${tone}`}><span className="dot"></span>{statusLabel(seg.status)}</span>
</div>
<div className="video-meta">{seg.target_duration_seconds}s{seg.error_message ? ` · ${seg.error_message}` : ""}</div>
<div className="video-meta">{seg.target_duration_seconds}s · {timeline?.resolution || "1080×1920"} · ~¥0.45{seg.error_message ? ` · ${seg.error_message}` : ""}</div>
<div className="video-actions">
<button className="btn btn-ghost btn-sm" type="button" data-vstop disabled={loading || busy} onClick={() => onSubmitVideo(seg.id, `${videoPrompt}${seg.sort_order + 1} 段,时长 ${seg.target_duration_seconds}`)}>{busy ? "生成中…" : "重跑"}</button>
<button className="btn btn-ghost btn-sm" type="button" data-vstop disabled={loading} onClick={() => triggerVideoUpload(seg.id)}></button>
@@ -3187,7 +3188,7 @@ export function PipelinePage(props: {
<button className="tl-action" type="button" title="复制选中片段" disabled={!edClips.length} onClick={() => edCopyClip(selectedClip)}><svg viewBox="0 0 24 24" fill="none" stroke="currentColor" strokeWidth="1.5" strokeLinecap="round" strokeLinejoin="round"><rect x="9" y="9" width="13" height="13" rx="2" /><path d="M5 15H4a2 2 0 0 1-2-2V4a2 2 0 0 1 2-2h9a2 2 0 0 1 2 2v1" /></svg></button>
<button className="tl-action danger" type="button" title="删除选中片段" disabled={edClips.length <= 1} onClick={() => edDeleteClip(selectedClip)}><svg viewBox="0 0 24 24" fill="none" stroke="currentColor" strokeWidth="1.5" strokeLinecap="round" strokeLinejoin="round"><path d="M3 6h18" /><path d="M8 6V4a2 2 0 0 1 2-2h4a2 2 0 0 1 2 2v2" /><path d="M19 6l-1.5 14a2 2 0 0 1-2 1.8H8.5a2 2 0 0 1-2-1.8L5 6" /></svg></button>
<span className="spacer"></span>
<div className="tl-zoom"><span className="lbl">// zoom {edZoom}%</span><input type="range" min={100} max={300} value={edZoom} onChange={(e) => setEdZoom(Number(e.target.value))} /></div>
<div className="tl-zoom"><span className="lbl">// zoom {edZoom}%</span><input type="range" min={50} max={200} value={edZoom} onChange={(e) => setEdZoom(Number(e.target.value))} /></div>
</div>
<div style={{ width: `${edZoom}%`, minWidth: "100%" }}>