Просмотр исходного кода

fix: 修复getById方法和JSON解析容错 - 支持三级大纲显示

MyFramework User 4 месяцев назад
Родитель
Сommit
46f53ad419

+ 37 - 0
server/check-book-fields.js

@@ -0,0 +1,37 @@
+const { PrismaClient } = require('@prisma/client');
+const prisma = new PrismaClient();
+
+async function checkBookFields() {
+  try {
+    const book = await prisma.book.findUnique({
+      where: { id: 1 }
+    });
+
+    console.log('📖 Book ID=1 字段检查:');
+    console.log(`  title: ${book.title}`);
+    console.log(`  bookScale: ${book.bookScale}`);
+    console.log(`  description: ${book.description}`);
+    console.log(`  targetAudience: ${book.targetAudience}`);
+    console.log(`  style: ${book.style}`);
+    console.log(`  status: ${book.status}`);
+    console.log('');
+
+    if (!book.bookScale) {
+      console.log('⚠️ bookScale为空,需要设置默认值');
+      await prisma.book.update({
+        where: { id: 1 },
+        data: {
+          bookScale: '标准教程'
+        }
+      });
+      console.log('✅ 已设置 bookScale = 标准教程');
+    }
+
+  } catch (error) {
+    console.error('错误:', error);
+  } finally {
+    await prisma.$disconnect();
+  }
+}
+
+checkBookFields();

+ 63 - 0
server/check-generation-status.js

@@ -0,0 +1,63 @@
+const { PrismaClient } = require('@prisma/client');
+const prisma = new PrismaClient();
+
+async function checkAndTriggerGeneration() {
+  try {
+    const book = await prisma.book.findUnique({
+      where: { id: 1 }
+    });
+
+    console.log('📖 书籍信息:');
+    console.log(`  ID: ${book.id}`);
+    console.log(`  标题: ${book.title}`);
+    console.log(`  状态: ${book.status}`);
+    console.log(`  进度: ${book.progress}%`);
+    console.log('');
+
+    // 检查大纲是否完整
+    const chapters = await prisma.bookChapter.findMany({
+      where: { bookId: 1 },
+      orderBy: [
+        { level: 'asc' },
+        { number: 'asc' }
+      ]
+    });
+
+    const level1 = chapters.filter(c => c.level === 1);
+    const level2 = chapters.filter(c => c.level === 2);
+    const level3 = chapters.filter(c => c.level === 3);
+
+    console.log('📊 大纲结构:');
+    console.log(`  章: ${level1.length}`);
+    console.log(`  节: ${level2.length}`);
+    console.log(`  小节: ${level3.length}`);
+    console.log('');
+
+    // 检查内容生成状态
+    const contentCompleted = level3.filter(c => c.contentStatus === 'completed').length;
+    const contentPending = level3.filter(c => c.contentStatus !== 'completed').length;
+
+    console.log('📝 内容生成状态:');
+    console.log(`  已完成: ${contentCompleted}`);
+    console.log(`  待生成: ${contentPending}`);
+    console.log('');
+
+    if (contentPending > 0) {
+      console.log('💡 建议操作:');
+      console.log('  需要通过API重新触发生成任务');
+      console.log('  由于大纲已完成,会跳过大钢生成阶段,直接进入内容生成');
+      console.log('');
+      console.log('  触发方式:');
+      console.log('  POST /api/book-generator/langgraph/books/1/generate');
+    } else {
+      console.log('✅ 所有内容已生成完成');
+    }
+
+  } catch (error) {
+    console.error('错误:', error);
+  } finally {
+    await prisma.$disconnect();
+  }
+}
+
+checkAndTriggerGeneration();

+ 52 - 0
server/reset-and-trigger.js

@@ -0,0 +1,52 @@
+const { PrismaClient } = require('@prisma/client');
+const http = require('http');
+
+async function resetAndTriggerGeneration() {
+  const prisma = new PrismaClient();
+  
+  try {
+    console.log('📝 步骤1: 重置书籍状态...');
+    
+    // 重置书籍状态
+    await prisma.book.update({
+      where: { id: 1 },
+      data: {
+        status: 'draft',
+        progress: 10,
+        errorMsg: null
+      }
+    });
+
+    console.log('✅ 状态已重置: draft, 10%');
+
+    // 重置所有章节的内容状态
+    const result = await prisma.bookChapter.updateMany({
+      where: {
+        bookId: 1,
+        level: 3  // 只重置小节的内容状态
+      },
+      data: {
+        contentStatus: null,
+        content: null,
+        wordCount: 0,
+        contentError: null
+      }
+    });
+
+    console.log(`✅ 已重置 ${result.count} 个小节的内容状态`);
+    console.log('');
+
+    console.log('🚀 步骤2: 触发内容生成...');
+    console.log('请手动调用以下API触发生成:');
+    console.log('  POST http://localhost:3000/api/book-generator/langgraph/books/1/generate');
+    console.log('');
+    console.log('或者在浏览器中访问前端页面点击"继续生成"按钮');
+
+  } catch (error) {
+    console.error('错误:', error);
+  } finally {
+    await prisma.$disconnect();
+  }
+}
+
+resetAndTriggerGeneration();

+ 21 - 4
server/src/modules/book-generator/book-generator.store.ts

@@ -53,6 +53,18 @@ function outlineChapterFromDb(dbChapter: any) {
 // ============ 存储类 ============
 // ============ 存储类 ============
 
 
 export class BookStore {
 export class BookStore {
+  /**
+   * 安全解析JSON
+   */
+  private safeParseJson(jsonStr: string | null): any[] {
+    if (!jsonStr) return [];
+    try {
+      return JSON.parse(jsonStr);
+    } catch {
+      return [];
+    }
+  }
+
   /**
   /**
    * 从数据库章节记录构建树形结构的outline
    * 从数据库章节记录构建树形结构的outline
    */
    */
@@ -73,7 +85,7 @@ export class BookStore {
           number: c.number,
           number: c.number,
           title: c.title,
           title: c.title,
           summary: c.summary || '',
           summary: c.summary || '',
-          keyPoints: c.keyPoints ? JSON.parse(c.keyPoints) : [],
+          keyPoints: this.safeParseJson(c.keyPoints),
           estimatedWords: c.estimatedWords,
           estimatedWords: c.estimatedWords,
           sections: []
           sections: []
         });
         });
@@ -82,7 +94,7 @@ export class BookStore {
           number: c.number,
           number: c.number,
           title: c.title,
           title: c.title,
           summary: c.summary || '',
           summary: c.summary || '',
-          keyPoints: c.keyPoints ? JSON.parse(c.keyPoints) : [],
+          keyPoints: this.safeParseJson(c.keyPoints),
           estimatedWords: c.estimatedWords,
           estimatedWords: c.estimatedWords,
           subsections: []
           subsections: []
         });
         });
@@ -104,7 +116,7 @@ export class BookStore {
             number: c.number,
             number: c.number,
             title: c.title,
             title: c.title,
             summary: c.summary || '',
             summary: c.summary || '',
-            keyPoints: c.keyPoints ? JSON.parse(c.keyPoints) : [],
+            keyPoints: this.safeParseJson(c.keyPoints),
             estimatedWords: c.estimatedWords
             estimatedWords: c.estimatedWords
           });
           });
         }
         }
@@ -173,7 +185,12 @@ export class BookStore {
     if (!book) return null;
     if (!book) return null;
     
     
     // 构建树形结构的outline(从数据库章节记录构建)
     // 构建树形结构的outline(从数据库章节记录构建)
-    const outline = this.buildOutlineFromChapters(book.chapters);
+    let outline: BookOutline | null = null;
+    try {
+      outline = this.buildOutlineFromChapters(book.chapters);
+    } catch (error) {
+      console.error('[BookStore] buildOutlineFromChapters 失败:', error);
+    }
     
     
     let result = this.toBook(book);
     let result = this.toBook(book);