From 0f0ae08b7efe478402f2eaf1bf2f5dfd6bc6e543 Mon Sep 17 00:00:00 2001 From: Peanut Date: Sun, 26 Jul 2026 11:53:20 +0800 Subject: [PATCH] =?UTF-8?q?feat:=20=E5=89=8D=E7=AB=AF=20store=20=E5=A2=9E?= =?UTF-8?q?=E5=8A=A0=20sessionMeta=20=E7=8A=B6=E6=80=81=20+=20ScriptView?= =?UTF-8?q?=20=E5=A2=9E=E5=BC=BA=20originalQuery=20=E5=85=9C=E5=BA=95?= =?UTF-8?q?=E5=92=8C=E5=8F=AF=E9=9D=A0=E5=88=B7=E6=96=B0?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- mini-program/src/pages/main/ScriptView.vue | 61 +++++++++++++++++++--- mini-program/src/stores/app.js | 33 ++++++++++++ 2 files changed, 88 insertions(+), 6 deletions(-) diff --git a/mini-program/src/pages/main/ScriptView.vue b/mini-program/src/pages/main/ScriptView.vue index 35c35ee..6004a79 100644 --- a/mini-program/src/pages/main/ScriptView.vue +++ b/mini-program/src/pages/main/ScriptView.vue @@ -1649,6 +1649,19 @@ const runGeneration = async ({ prompt, displayText, source = 'text', saveTheme } novelSessionId.value = '' firstQuery.value = text // 记住首次心愿,用于后续 followup 保存剧本 console.log('[ScriptView] 设置 firstQuery:', { length: text.length }) + + // 把原始心愿保存到 store,供 followup 时透传给后端(避免 originalQuery 丢失导致不保存) + if (store.setSessionMeta) { + store.setSessionMeta({ + sessionId: '', // 后续在 status 事件中更新 + scriptId: '', + conversationId: '', + originalQuery: text, + style: 'career', + length: 'short' + }) + } + pendingNextResponse.value = true // 标记等待下一个 assistant 响应 resumeableSessionId.value = '' outlineFeedback.value = '' @@ -1689,13 +1702,23 @@ const runGeneration = async ({ prompt, displayText, source = 'text', saveTheme } } } -const handleShortNovelEvent = (event) => { +const handleShortNovelEvent = async (event) => { const { type, session_id, payload = {} } = event const timestamp = Date.now() console.log('[ScriptView] 收到事件:', { type, session_id, timestamp }) - if (session_id) novelSessionId.value = session_id + if (session_id) { + novelSessionId.value = session_id + // 把外部 short-novel-service 返回的 session_id 同步到 store,供 followup 透传 + if (store.setSessionMeta && store.getSessionMeta) { + const meta = store.getSessionMeta() + if (meta) { + meta.sessionId = session_id + store.setSessionMeta(meta) + } + } + } switch (type) { case 'status': @@ -1751,8 +1774,25 @@ const handleShortNovelEvent = (event) => { generationStatus.value = 'idle' pendingNextResponse.value = false persistResultMessages() - // 从后端刷新剧本列表,确保新生成的短篇出现在历史中(非阻塞) - store.fetchScripts() + + // 把 scriptId/conversationId 同步到 store,便于详情页/历史页查最新剧本 + if (store.setSessionMeta && store.getSessionMeta) { + const meta = store.getSessionMeta() + if (meta) { + meta.scriptId = scriptId.value + meta.conversationId = conversationId.value + store.setSessionMeta(meta) + } + } + + // 可靠刷新剧本列表:使用 await 确保后端返回后再继续,避免列表中看不到最新剧本 + try { + await store.fetchScripts() + console.log('[ScriptView] novel_done 后剧本列表刷新成功') + } catch (e) { + console.error('[ScriptView] novel_done 后剧本列表刷新失败:', e) + uni.showToast({ title: '列表刷新失败,请手动刷新', icon: 'none' }) + } break } case 'error': @@ -1781,15 +1821,24 @@ const submitClarification = (answer) => { } pendingNextResponse.value = true // 标记等待下一个 assistant 响应 answeringClarification.value = true + + // originalQuery 兜底:优先 firstQuery,缺失时从 store 获取,避免 followup 时 originalQuery 为空导致不保存 + const effectiveOriginalQuery = firstQuery.value || (store.getSessionMeta && store.getSessionMeta()?.originalQuery) || '' + if (!effectiveOriginalQuery) { + uni.showToast({ title: '原始心愿已丢失,请重新开始', icon: 'none' }) + answeringClarification.value = false + return + } + console.log('[ScriptView] submitClarification:', { sessionId: novelSessionId.value, - originalQueryLength: firstQuery.value?.length + originalQueryLength: effectiveOriginalQuery.length }) currentStreamTask.value = followupStream({ sessionId: novelSessionId.value, action: 'answer_clarification', payload: { answer }, // 后端仍收 value - originalQuery: firstQuery.value, // 首次心愿文本,用于后续 novel_done 保存 + originalQuery: effectiveOriginalQuery, // 首次心愿文本,用于后续 novel_done 保存 onEvent: handleShortNovelEvent, onError: (errMsg) => markGenerationFailed(errMsg) }) diff --git a/mini-program/src/stores/app.js b/mini-program/src/stores/app.js index 8d835d2..9a3fa8c 100644 --- a/mini-program/src/stores/app.js +++ b/mini-program/src/stores/app.js @@ -16,6 +16,8 @@ const state = reactive({ inspirationRecommendations: [], paths: [], currentPath: null, + // 当前心愿实现的 session 元数据(用于 followup 时传递 originalQuery 兜底) + currentSessionMeta: null, registrationData: { nickname: '', gender: '', @@ -264,6 +266,34 @@ const fetchScripts = async () => { } } +/** + * 设置当前心愿实现的 session 元数据 + * 用于在后续 followup 调用中透传 originalQuery/style/length + * + * @param {{ sessionId?: string, scriptId?: string, conversationId?: string, originalQuery: string, style?: string, length?: string }} meta + */ +const setSessionMeta = (meta) => { + if (!meta || !meta.originalQuery) { + return + } + state.currentSessionMeta = { ...meta, updatedAt: Date.now() } +} + +/** + * 获取当前心愿实现的 session 元数据 + * @returns {object|null} + */ +const getSessionMeta = () => { + return state.currentSessionMeta +} + +/** + * 清除当前 session 元数据 + */ +const clearSessionMeta = () => { + state.currentSessionMeta = null +} + const createScript = async (scriptData) => { try { const res = await epicScriptService.createScript(scriptData) @@ -495,6 +525,9 @@ export const useAppStore = () => { createScript, updateScript, deleteScript, + setSessionMeta, + getSessionMeta, + clearSessionMeta, fetchInspirationRecommendations, fetchRandomInspirations, generateScriptFromInspiration,