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,