fix:修复 ScriptView 详情面板重复展示及列表预览行数据路径
- ScriptView.openScriptChat 移除重复 push wishTheme/novelContent,改为从 messages 真实数据按 type 映射为 chat-bubble(与 ScriptDetailView.rebuildResultMessages 一致) - ScriptLibraryView.getOutlinePreview 增加多路径探测(plotJson.stages.outline.beats / fullPayload.outline.beats / plotJson.outline.beats),兼容老剧本数据
This commit is contained in:
@@ -255,10 +255,15 @@ const getInitial = (script) => (script.title || '剧').slice(0, 1)
|
|||||||
|
|
||||||
/**
|
/**
|
||||||
* 获取大纲预览文本(前 2 章标题)
|
* 获取大纲预览文本(前 2 章标题)
|
||||||
* 数据来源:script.plotJson.stages.outline.beats
|
* 数据来源按优先级探测:
|
||||||
|
* 1. plotJson.stages.outline.beats(Task 1-5 部署后新生成的小说)
|
||||||
|
* 2. plotJson.fullPayload.outline.beats(兼容老剧本可能的 fullPayload 结构)
|
||||||
|
* 3. 直接 plotJson.outline.beats(兜底)
|
||||||
*/
|
*/
|
||||||
const getOutlinePreview = (script) => {
|
const getOutlinePreview = (script) => {
|
||||||
const beats = script?.plotJson?.stages?.outline?.beats
|
const beats = script?.plotJson?.stages?.outline?.beats
|
||||||
|
|| script?.plotJson?.fullPayload?.outline?.beats
|
||||||
|
|| script?.plotJson?.outline?.beats
|
||||||
if (!Array.isArray(beats) || beats.length === 0) return ''
|
if (!Array.isArray(beats) || beats.length === 0) return ''
|
||||||
const parts = beats.slice(0, 2).map((beat, i) => {
|
const parts = beats.slice(0, 2).map((beat, i) => {
|
||||||
const title = beat.title || ''
|
const title = beat.title || ''
|
||||||
|
|||||||
@@ -1455,45 +1455,73 @@ const openScriptChat = async (payload = {}) => {
|
|||||||
await loadMessages()
|
await loadMessages()
|
||||||
}
|
}
|
||||||
|
|
||||||
// 将历史剧本数据转换为统一对话消息格式,填充 resultMessages
|
// 从后端 messages 重建统一对话消息流,复刻生成时的 chat-bubble 展示
|
||||||
const novelContent = currentResult.value?.content || currentResult.value?.plotJson?.fullContent || ''
|
// 不再重复 push wishTheme/novelContent(messages 中已包含)
|
||||||
const wishTheme = currentResult.value?.theme || currentResult.value?.title || ''
|
const messagesList = messages.value || []
|
||||||
|
messagesList.forEach(m => {
|
||||||
// 1. 用户心愿作为首条 user 消息
|
if (m.type === 'clarification_question') {
|
||||||
if (wishTheme) {
|
let card = {}
|
||||||
resultMessages.value.push({
|
try { card = JSON.parse(m.content || '{}') } catch (e) { card = {} }
|
||||||
id: `loaded-wish-${Date.now()}`,
|
|
||||||
role: 'user',
|
|
||||||
kind: 'text',
|
|
||||||
content: wishTheme,
|
|
||||||
pending: false,
|
|
||||||
time: formatMessageTime(),
|
|
||||||
submitted: false,
|
|
||||||
confirmed: false
|
|
||||||
})
|
|
||||||
}
|
|
||||||
|
|
||||||
// 2. 当前小说正文作为 AI novel 消息(已完成态)
|
|
||||||
if (novelContent) {
|
|
||||||
resultMessages.value.push({
|
|
||||||
id: `loaded-novel-${Date.now()}`,
|
|
||||||
role: 'assistant',
|
|
||||||
kind: 'novel',
|
|
||||||
content: novelContent,
|
|
||||||
pending: false,
|
|
||||||
time: formatMessageTime(),
|
|
||||||
submitted: false,
|
|
||||||
confirmed: false
|
|
||||||
})
|
|
||||||
}
|
|
||||||
|
|
||||||
// 3. 对话历史中除首条外的其他消息追加到对话流
|
|
||||||
// (首条通常是与 wishTheme 重复的用户消息,跳过避免重复)
|
|
||||||
if (messages.value.length > 0) {
|
|
||||||
messages.value.slice(1).forEach(m => {
|
|
||||||
resultMessages.value.push({
|
resultMessages.value.push({
|
||||||
id: m.id || createMessageId(),
|
id: m.id || createMessageId(),
|
||||||
role: m.sender === 'user' ? 'user' : 'assistant',
|
role: 'assistant',
|
||||||
|
kind: 'card',
|
||||||
|
content: '',
|
||||||
|
card,
|
||||||
|
answer: '',
|
||||||
|
pending: false,
|
||||||
|
time: formatMessageTime(),
|
||||||
|
submitted: true,
|
||||||
|
confirmed: true
|
||||||
|
})
|
||||||
|
} else if (m.type === 'clarification_answer') {
|
||||||
|
// 把答案合并到上一条 card 消息的 answer 字段
|
||||||
|
const lastCard = [...resultMessages.value].reverse().find(x => x.kind === 'card')
|
||||||
|
if (lastCard) {
|
||||||
|
lastCard.answer = m.content || '未回答'
|
||||||
|
lastCard.submitted = true
|
||||||
|
} else {
|
||||||
|
// 无对应 question,作为独立 user 消息
|
||||||
|
resultMessages.value.push({
|
||||||
|
id: m.id || createMessageId(),
|
||||||
|
role: 'user',
|
||||||
|
kind: 'text',
|
||||||
|
content: m.content || '',
|
||||||
|
pending: false,
|
||||||
|
time: formatMessageTime(),
|
||||||
|
submitted: false,
|
||||||
|
confirmed: false
|
||||||
|
})
|
||||||
|
}
|
||||||
|
} else if (m.type === 'outline') {
|
||||||
|
let outline = {}
|
||||||
|
try { outline = JSON.parse(m.content || '{}') } catch (e) { outline = {} }
|
||||||
|
resultMessages.value.push({
|
||||||
|
id: m.id || createMessageId(),
|
||||||
|
role: 'assistant',
|
||||||
|
kind: 'outline',
|
||||||
|
content: '',
|
||||||
|
outline,
|
||||||
|
pending: false,
|
||||||
|
time: formatMessageTime(),
|
||||||
|
submitted: false,
|
||||||
|
confirmed: true
|
||||||
|
})
|
||||||
|
} else if (m.type === 'script') {
|
||||||
|
resultMessages.value.push({
|
||||||
|
id: m.id || createMessageId(),
|
||||||
|
role: 'assistant',
|
||||||
|
kind: 'novel',
|
||||||
|
content: m.content || '',
|
||||||
|
pending: false,
|
||||||
|
time: formatMessageTime(),
|
||||||
|
submitted: false,
|
||||||
|
confirmed: true
|
||||||
|
})
|
||||||
|
} else if (m.type === 'chat' && m.sender === 'user') {
|
||||||
|
resultMessages.value.push({
|
||||||
|
id: m.id || createMessageId(),
|
||||||
|
role: 'user',
|
||||||
kind: 'text',
|
kind: 'text',
|
||||||
content: m.content || '',
|
content: m.content || '',
|
||||||
pending: false,
|
pending: false,
|
||||||
@@ -1501,12 +1529,13 @@ const openScriptChat = async (payload = {}) => {
|
|||||||
submitted: false,
|
submitted: false,
|
||||||
confirmed: false
|
confirmed: false
|
||||||
})
|
})
|
||||||
})
|
}
|
||||||
}
|
// 跳过 system 类型(不展示)
|
||||||
|
})
|
||||||
|
|
||||||
analytics.track('script_chat_open_from_library', {
|
analytics.track('script_chat_open_from_library', {
|
||||||
script_id: script.id,
|
script_id: script.id,
|
||||||
has_history: messages.value.length > 0
|
has_history: messagesList.length > 0
|
||||||
}, { eventType: 'script', pagePath })
|
}, { eventType: 'script', pagePath })
|
||||||
scrollResultToLatest()
|
scrollResultToLatest()
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user