diff --git a/mini-program/src/pages/main/ScriptView.vue b/mini-program/src/pages/main/ScriptView.vue
index c90e9ba..4c65ff0 100644
--- a/mini-program/src/pages/main/ScriptView.vue
+++ b/mini-program/src/pages/main/ScriptView.vue
@@ -173,7 +173,8 @@
{{ generationCopy }}
{{ generationSubcopy }}
-
+
+
@@ -346,6 +347,7 @@ const generationScrollTarget = ref('')
const generationScrollTop = ref(0)
const generationAutoFollow = ref(true)
const generationDisplayText = ref('')
+const resumeableSessionId = ref('')
const lastGenerationPrompt = ref('')
const lastSubmitSource = ref('text')
const lastGenerationRevision = ref(false)
@@ -1641,7 +1643,9 @@ const runGeneration = async ({ prompt, displayText, source = 'text', saveTheme }
novelOutline.value = null
clarificationCard.value = null
novelSessionId.value = ''
+ resumeableSessionId.value = ''
outlineFeedback.value = ''
+ generationDisplayText.value = display
generationScrollTarget.value = ''
generationScrollTop.value = 0
generationScrollAnchor.value = 'generation-stream-anchor-a'
@@ -1709,7 +1713,13 @@ const handleShortNovelEvent = (event) => {
viewMode.value = 'chat'
break
case 'error':
- markGenerationFailed(payload.message || '生成失败')
+ // 识别每日限制错误,保存 session_id 供"继续创作"使用
+ if (payload.code === 'DAILY_GENERATION_IN_PROGRESS' && session_id) {
+ resumeableSessionId.value = session_id
+ markGenerationFailed(payload.message || '今天已有未完成的创作,可点击继续创作恢复')
+ } else {
+ markGenerationFailed(payload.message || '生成失败')
+ }
break
}
}
@@ -1748,6 +1758,42 @@ const modifyOutline = (feedback) => {
})
}
+const resumeSession = () => {
+ if (!resumeableSessionId.value || generating.value) return
+ novelSessionId.value = resumeableSessionId.value
+ resumeableSessionId.value = ''
+ generating.value = true
+ streamContent.value = ''
+ novelFullText.value = ''
+ generationStatus.value = 'waiting'
+ generationError.value = ''
+ generationDisplayText.value = '继续之前的创作'
+ streamWriter.reset()
+ startGenerationFeedback()
+ viewState.value = 'generating'
+ keepGenerationAtBottom()
+
+ try {
+ currentStreamTask.value = followupStream({
+ sessionId: novelSessionId.value,
+ action: 'retry',
+ payload: null,
+ onEvent: handleShortNovelEvent,
+ onError: (msg) => {
+ markGenerationFailed(msg)
+ analytics.track('script_generate_fail', {
+ source: 'resume',
+ error: msg
+ }, { eventType: 'script', pagePath })
+ }
+ })
+ } catch (error) {
+ markGenerationFailed(error.message || '恢复失败')
+ } finally {
+ generating.value = false
+ }
+}
+
const submitWish = async (source = 'text') => {
const text = wishText.value.trim()
if (!text || generating.value) return