/** * 故事数据管理器 */ import { get, post } from '../utils/http'; export default class StoryManager { constructor() { this.storyList = []; this.currentStory = null; this.currentNodeKey = 'start'; this.categories = []; this.pathHistory = []; // 记录用户走过的路径 } /** * 加载故事列表 */ async loadStoryList(options = {}) { try { this.storyList = await get('/stories', options); return this.storyList; } catch (error) { console.error('加载故事列表失败:', error); return []; } } /** * 加载热门故事 */ async loadHotStories(limit = 10) { try { return await get('/stories/hot', { limit }); } catch (error) { console.error('加载热门故事失败:', error); return []; } } /** * 加载分类列表 */ async loadCategories() { try { this.categories = await get('/stories/categories'); return this.categories; } catch (error) { console.error('加载分类失败:', error); return []; } } /** * 加载故事详情 */ async loadStoryDetail(storyId) { try { this.currentStory = await get(`/stories/${storyId}`); this.currentNodeKey = 'start'; this.pathHistory = []; // 重置路径历史 // 记录游玩次数 await post(`/stories/${storyId}/play`); return this.currentStory; } catch (error) { console.error('加载故事详情失败:', error); return null; } } /** * 获取当前节点 */ getCurrentNode() { if (!this.currentStory || !this.currentStory.nodes) return null; return this.currentStory.nodes[this.currentNodeKey]; } /** * 选择选项,前进到下一个节点 */ selectChoice(choiceIndex) { const currentNode = this.getCurrentNode(); if (!currentNode || !currentNode.choices || !currentNode.choices[choiceIndex]) { return null; } const choice = currentNode.choices[choiceIndex]; // 记录路径历史 this.pathHistory.push({ nodeKey: this.currentNodeKey, content: currentNode.content, choice: choice.text }); this.currentNodeKey = choice.nextNodeKey; return this.getCurrentNode(); } /** * 检查当前节点是否为结局 */ isEnding() { const currentNode = this.getCurrentNode(); return currentNode && currentNode.is_ending; } /** * 获取结局信息 */ getEndingInfo() { const currentNode = this.getCurrentNode(); if (!currentNode || !currentNode.is_ending) return null; return { name: currentNode.ending_name, score: currentNode.ending_score, type: currentNode.ending_type, content: currentNode.content }; } /** * 重置故事进度 */ resetStory() { this.currentNodeKey = 'start'; } /** * 点赞故事 */ async likeStory(like = true) { if (!this.currentStory) return; await post(`/stories/${this.currentStory.id}/like`, { like }); } /** * AI改写结局 */ async rewriteEnding(storyId, ending, prompt) { try { const result = await post(`/stories/${storyId}/rewrite`, { ending_name: ending?.name, ending_content: ending?.content, prompt: prompt }, { timeout: 60000 }); return result; } catch (error) { console.error('AI改写失败:', error?.errMsg || error?.message || JSON.stringify(error)); return null; } } /** * AI改写中间章节,生成新的剧情分支 * @returns {Object|null} 成功返回新节点,失败返回 null(不改变当前状态) */ async rewriteBranch(storyId, prompt, userId) { try { const currentNode = this.getCurrentNode(); const result = await post(`/stories/${storyId}/rewrite-branch`, { userId: userId, currentNodeKey: this.currentNodeKey, pathHistory: this.pathHistory, currentContent: currentNode?.content || '', prompt: prompt }, { timeout: 300000 }); // 5分钟超时,AI生成需要较长时间 // 检查是否有有效的 nodes if (result && result.nodes) { // AI 成功,将新分支合并到当前故事中 Object.assign(this.currentStory.nodes, result.nodes); // 跳转到新分支的入口节点 this.currentNodeKey = result.entryNodeKey || 'branch_1'; return this.getCurrentNode(); } // AI 失败,返回 null console.log('AI服务不可用:', result?.error || '未知错误'); return null; } catch (error) { console.error('AI改写分支失败:', error?.errMsg || error?.message || JSON.stringify(error)); return null; } } /** * AI续写故事 */ async continueStory(storyId, prompt) { try { const result = await post(`/stories/${storyId}/continue`, { current_node_key: this.currentNodeKey, prompt: prompt }); return result; } catch (error) { console.error('AI续写失败:', error); return null; } } /** * AI创作新故事 */ async createStory(params) { try { const result = await post('/stories/ai-create', { genre: params.genre, keywords: params.keywords, protagonist: params.protagonist, conflict: params.conflict }); return result; } catch (error) { console.error('AI创作失败:', error); return null; } } }