Sfoglia il codice sorgente

fix: 全量重新生成前清理旧章节树,避免扩缩后残留孤儿数据

deleteAllChapters 同时清理关联的 TtsTask 和 PlaylistItem,
reset totalChapters/progress 确保状态一致。

Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
MyFramework User 3 mesi fa
parent
commit
8e5e7ebcfa

+ 19 - 0
server/src/modules/book-generator/book-generator.store.ts

@@ -636,6 +636,25 @@ export class BookStore {
     }
     }
   }
   }
 
 
+  /**
+   * 删除书籍的所有章节(全量重新生成前清理旧数据)
+   */
+  async deleteAllChapters(bookId: string): Promise<number> {
+    const bookIdNum = parseInt(bookId);
+    // 先删子节点再删章,避免外键依赖
+    const { count: deletedPlaylistItems } = await prisma.playlistItem.deleteMany({
+      where: { chapter: { bookId: bookIdNum } },
+    });
+    const { count: deletedTtsTasks } = await prisma.ttsTask.deleteMany({
+      where: { chapter: { bookId: bookIdNum } },
+    });
+    const { count: deletedChapters } = await prisma.bookChapter.deleteMany({
+      where: { bookId: bookIdNum },
+    });
+    console.log(`[Store] 清理书籍${bookId}旧数据: ${deletedChapters}章, ${deletedTtsTasks}个TTS任务, ${deletedPlaylistItems}个播放列表项`);
+    return deletedChapters;
+  }
+
   /**
   /**
    * 创建章节
    * 创建章节
    */
    */

+ 3 - 1
server/src/modules/book-generator/langgraph-controller.ts

@@ -992,7 +992,9 @@ router.post('/books/:id/generate', optionalAuth, async (ctx: Context) => {
     }
     }
 
 
     // 异步生成(跳过队列,开发环境下队列不可靠)
     // 异步生成(跳过队列,开发环境下队列不可靠)
-    await bookStore.update(bookId, { genStage: 'outlining' });
+    // 先清理旧章节,避免扩缩后残留孤儿数据
+    await bookStore.deleteAllChapters(bookId);
+    await bookStore.update(bookId, { genStage: 'outlining', totalChapters: 0, progress: 0 });
 
 
     langGraphGenerator.generate(bookId, book.description, bookScale, genLevel, userId)
     langGraphGenerator.generate(bookId, book.description, bookScale, genLevel, userId)
       .then(() => {
       .then(() => {