diff --git a/mini-program/src/pages/main/ScriptLibraryView.vue b/mini-program/src/pages/main/ScriptLibraryView.vue index 460e187..e6f3733 100644 --- a/mini-program/src/pages/main/ScriptLibraryView.vue +++ b/mini-program/src/pages/main/ScriptLibraryView.vue @@ -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 || '' diff --git a/mini-program/src/pages/main/ScriptView.vue b/mini-program/src/pages/main/ScriptView.vue index 6004a79..8f58be3 100644 --- a/mini-program/src/pages/main/ScriptView.vue +++ b/mini-program/src/pages/main/ScriptView.vue @@ -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() }