fix(records): TeamAssetsPage 重新编辑 prompt 丢失 — VideoDetailModal fallback 补 editorHtml

根因(4 层叠加):
1. TeamAssetsPage 没传 onReEdit prop 给 VideoDetailModal → 走 modal 内部 fallback
2. fallback 只 setPrompt(task.prompt),没设 editorHtml
3. PromptInput 是 contenteditable,渲染依据是 editorHtml,不是 prompt
4. assetVideoToTask 把 editorHtml 显式置 '' → fallback 拿到的就是空串

修法:fallback 跟 store/generation.ts:reEdit 对齐,
用 useInputBarStore.setState 一次性批量灌入所有字段,
关键补 editorHtml: task.editorHtml || task.prompt || '',
让 PromptInput 渲染 + rebuildMentionSpans 走完整路径
(原文 + assetMentions 重建带缩略图的 @ 标签)。

附带顺手补:
- mode 用 switchMode 而不是 setMode(switchMode 会清 keyframe 状态)
- assetMentions: task.assetMentions || []
- references 用 setState 批量传(原代码用 setState 又用 setX 混用,不一致)

影响范围:
- 团管 /team/assets → 任意视频 → "重新编辑" → /app prompt 文本框有内容 ✓
- 超管 /admin/assets → 同上 ✓
- 用户 /user-assets → reEdit 走的是另一条路(generation.ts:reEdit),不受影响

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
This commit is contained in:
seaislee1209 2026-05-12 18:24:28 +08:00
parent 6ee5c8ffdb
commit 11c1cdf8cc

View File

@ -212,29 +212,34 @@ export function VideoDetailModal({ task, onClose, onReEdit, onRegenerate, onDele
onReEdit(task.id); onReEdit(task.id);
onClose(); onClose();
} else { } else {
// Fallback: load task into input bar and navigate to generation page // Fallback (asset page → reEdit): 跟 store/generation.ts:reEdit 对齐,
// 用 setState 一次性批量灌入所有相关字段。
// 关键 bug 修复:之前只 setPrompt 不写 editorHtml,PromptInput 渲染 editorHtml,
// 所以编辑器是空的(只回填了图片素材)。
const store = useInputBarStore.getState(); const store = useInputBarStore.getState();
store.reset(); store.reset();
store.setPrompt(task.prompt || ''); if (task.mode && store.mode !== task.mode) {
if (task.mode) store.setMode(task.mode as 'universal' | 'keyframe'); store.switchMode(task.mode as 'universal' | 'keyframe');
if (task.model) store.setModel(task.model as 'seedance_2.0' | 'seedance_2.0_fast'); }
if (task.aspectRatio) store.setAspectRatio(task.aspectRatio as any); const refs = (task.references || [])
if (task.duration) store.setDuration(task.duration); .filter(r => r.previewUrl && !r.isAssetRef)
if (task.resolution) store.setResolution(task.resolution); .map(r => ({
// Load references from task (exclude asset library refs — they restore via @mentions in editorHtml)
if (task.references && task.references.length > 0) {
const refs = task.references.filter(r => r.previewUrl && !r.isAssetRef).map(r => ({
id: r.id, id: r.id,
file: null as unknown as File,
previewUrl: r.previewUrl,
type: r.type as 'image' | 'video' | 'audio', type: r.type as 'image' | 'video' | 'audio',
previewUrl: r.previewUrl,
label: r.label, label: r.label,
tosUrl: r.previewUrl, tosUrl: r.previewUrl,
})); }));
if (refs.length > 0) { useInputBarStore.setState({
useInputBarStore.setState({ references: refs }); prompt: task.prompt || '',
} editorHtml: task.editorHtml || task.prompt || '',
} model: (task.model as 'seedance_2.0' | 'seedance_2.0_fast') || 'seedance_2.0',
aspectRatio: (task.aspectRatio as any) || '16:9',
duration: task.duration ?? 5,
resolution: task.resolution || '720p',
references: refs,
assetMentions: task.assetMentions || [],
});
onClose(); onClose();
navigate('/app'); navigate('/app');
} }