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 章标题)
|
||||
* 数据来源: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 beats = script?.plotJson?.stages?.outline?.beats
|
||||
|| script?.plotJson?.fullPayload?.outline?.beats
|
||||
|| script?.plotJson?.outline?.beats
|
||||
if (!Array.isArray(beats) || beats.length === 0) return ''
|
||||
const parts = beats.slice(0, 2).map((beat, i) => {
|
||||
const title = beat.title || ''
|
||||
|
||||
@@ -1455,45 +1455,73 @@ const openScriptChat = async (payload = {}) => {
|
||||
await loadMessages()
|
||||
}
|
||||
|
||||
// 将历史剧本数据转换为统一对话消息格式,填充 resultMessages
|
||||
const novelContent = currentResult.value?.content || currentResult.value?.plotJson?.fullContent || ''
|
||||
const wishTheme = currentResult.value?.theme || currentResult.value?.title || ''
|
||||
|
||||
// 1. 用户心愿作为首条 user 消息
|
||||
if (wishTheme) {
|
||||
resultMessages.value.push({
|
||||
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 => {
|
||||
// 从后端 messages 重建统一对话消息流,复刻生成时的 chat-bubble 展示
|
||||
// 不再重复 push wishTheme/novelContent(messages 中已包含)
|
||||
const messagesList = messages.value || []
|
||||
messagesList.forEach(m => {
|
||||
if (m.type === 'clarification_question') {
|
||||
let card = {}
|
||||
try { card = JSON.parse(m.content || '{}') } catch (e) { card = {} }
|
||||
resultMessages.value.push({
|
||||
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',
|
||||
content: m.content || '',
|
||||
pending: false,
|
||||
@@ -1501,12 +1529,13 @@ const openScriptChat = async (payload = {}) => {
|
||||
submitted: false,
|
||||
confirmed: false
|
||||
})
|
||||
})
|
||||
}
|
||||
}
|
||||
// 跳过 system 类型(不展示)
|
||||
})
|
||||
|
||||
analytics.track('script_chat_open_from_library', {
|
||||
script_id: script.id,
|
||||
has_history: messages.value.length > 0
|
||||
has_history: messagesList.length > 0
|
||||
}, { eventType: 'script', pagePath })
|
||||
scrollResultToLatest()
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user