"use strict"; /** * 书籍生成模块 - Prisma 数据库存储 */ Object.defineProperty(exports, "__esModule", { value: true }); exports.bookStore = exports.BookStore = void 0; const models_1 = require("../../models"); const tts_service_1 = require("../tts/tts.service"); // ============ 类型转换 ============ function parseOutlineJson(jsonStr) { if (!jsonStr) return null; try { return JSON.parse(jsonStr); } catch { return null; } } function chaptersFromDb(dbChapters, bookId) { return dbChapters.map((c) => ({ id: String(c.id), bookId: String(c.bookId), number: c.number, title: c.title, content: c.content || '', wordCount: c.wordCount, status: c.status, summary: c.summary || undefined, generatedAt: c.generatedAt || undefined, error: c.errorMsg || undefined, audioUrl: c.audioUrl || undefined, audioDuration: c.audioDuration || 0, videoUrl: c.videoUrl || undefined, videoDuration: c.videoDuration || undefined, })); } function outlineChapterFromDb(dbChapter) { return { number: dbChapter.number, title: dbChapter.title, summary: dbChapter.summary || '', keyPoints: dbChapter.keyPoints ? JSON.parse(dbChapter.keyPoints) : [], estimatedWords: dbChapter.estimatedWords, }; } // ============ 存储类 ============ class BookStore { /** * 创建书籍 */ async create(data) { const book = await models_1.prisma.book.create({ data: { userId: data.userId, title: data.title, subtitle: data.subtitle, description: data.description, targetAudience: data.targetAudience || '通用', style: data.style || '专业严谨', totalChapters: data.totalChapters || 10, status: 'draft', progress: 0, isPublished: false, // 预发布:等书籍完成后再发布 }, include: { chapters: true }, }); return this.toBook(book); } /** * 获取书籍 */ async getById(id) { const book = await models_1.prisma.book.findUnique({ where: { id: parseInt(id) }, include: { chapters: { orderBy: { number: 'asc' } } }, }); return book ? this.toBook(book) : null; } /** * 获取用户的所有书籍 */ async getAllByUser(userId) { const books = await models_1.prisma.book.findMany({ where: userId ? { userId } : {}, include: { chapters: true }, orderBy: { createdAt: 'desc' }, }); return books.map((b) => this.toBook(b)); } /** * 更新书籍 */ async update(id, data) { const book = await models_1.prisma.book.update({ where: { id: parseInt(id) }, data: { ...data, updatedAt: new Date(), }, include: { chapters: { orderBy: { number: 'asc' } } }, }); return this.toBook(book); } /** * 删除书籍 */ async delete(id) { try { await models_1.prisma.book.delete({ where: { id: parseInt(id) } }); return true; } catch { return false; } } /** * 创建章节 */ async createChapter(data) { await models_1.prisma.bookChapter.create({ data: { bookId: parseInt(data.bookId), number: data.number, title: data.title, summary: data.summary, keyPoints: data.keyPoints ? JSON.stringify(data.keyPoints) : null, estimatedWords: data.estimatedWords || 1000, status: 'pending', }, }); } /** * 批量创建章节 */ async createChapters(bookId, chapters) { await models_1.prisma.bookChapter.createMany({ data: chapters.map((c) => ({ bookId: parseInt(bookId), number: c.number, title: c.title, summary: c.summary, keyPoints: c.keyPoints ? JSON.stringify(c.keyPoints) : null, estimatedWords: c.estimatedWords || 1000, status: 'pending', })), }); } /** * 更新章节内容 */ async updateChapter(bookId, chapterNumber, data) { const chapter = await models_1.prisma.bookChapter.findFirst({ where: { bookId: parseInt(bookId), number: chapterNumber, }, }); if (!chapter) return null; const updated = await models_1.prisma.bookChapter.update({ where: { id: chapter.id }, data: { ...data, generatedAt: data.content ? new Date() : undefined, }, }); return { id: String(updated.id), bookId: String(updated.bookId), number: updated.number, title: updated.title, content: updated.content || '', wordCount: updated.wordCount, status: updated.status, summary: updated.summary || undefined, generatedAt: updated.generatedAt || undefined, error: updated.errorMsg || undefined, }; } /** * 获取书籍的章节 */ async getChapters(bookId) { const chapters = await models_1.prisma.bookChapter.findMany({ where: { bookId: parseInt(bookId) }, orderBy: { number: 'asc' }, }); return chaptersFromDb(chapters, parseInt(bookId)); } /** * 统计书籍完成章节数 */ async countCompletedChapters(bookId) { return models_1.prisma.bookChapter.count({ where: { bookId: parseInt(bookId), status: 'completed', }, }); } /** * 发布书籍(将 isPublished 设为 true) */ async publishAlbum(bookId) { await models_1.prisma.book.update({ where: { id: parseInt(bookId) }, data: { isPublished: true }, }); } /** * 为书籍章节生成音频并关联(更新 BookChapter.audioUrl) */ async generateChapterAudio(bookId, chapterNumber, userId) { const chapter = await models_1.prisma.bookChapter.findFirst({ where: { bookId: parseInt(bookId), number: chapterNumber }, include: { book: true }, }); if (!chapter || !chapter.content) { return null; } // 生成音频(异步模式,通过回调更新章节) const result = await (0, tts_service_1.generateAudio)(userId ? String(userId) : String(chapter.book?.userId || '0'), chapter.content, 'default', { speed: 1.0, pitch: 0, volume: 50 }, async (audioUrl, duration) => { // 音频生成完成后更新章节 await models_1.prisma.bookChapter.update({ where: { id: chapter.id }, data: { audioUrl, audioDuration: duration, }, }); console.log(`✅ 章节${chapterNumber}音频生成完成:`, audioUrl); }); return { audioUrl: result.audioUrl, // 初始为空字符串,实际URL通过回调更新 }; } /** * 转换数据库模型到 Book 类型 */ toBook(dbBook) { const outline = parseOutlineJson(dbBook.outlineJson); return { id: String(dbBook.id), title: dbBook.title, subtitle: dbBook.subtitle || undefined, description: dbBook.description, targetAudience: dbBook.targetAudience, style: dbBook.style, totalChapters: dbBook.totalChapters, estimatedWords: dbBook.estimatedWords, status: dbBook.status, progress: dbBook.progress, chapters: chaptersFromDb(dbBook.chapters, dbBook.id), outline: outline || undefined, metadata: { foreword: dbBook.foreword || undefined, afterword: dbBook.afterword || undefined, }, error: dbBook.errorMsg || undefined, createdAt: dbBook.createdAt, updatedAt: dbBook.updatedAt, }; } } exports.BookStore = BookStore; // 导出单例 exports.bookStore = new BookStore();