import { StoryTemplateEntity } from "../domain/Entities"; /** 模板角色接口 */ interface TemplateRole { /** 角色名 */ role_name: string; /** 照片URL */ photo_url: string; /** 声音URL */ voice_url: string; } import { TemplateStoryUseCase } from "../usecase/templateStoryUseCase"; import { getUploadToken, uploadToQiniu } from "@/api/common"; import { useState, useCallback, useMemo } from "react"; interface UseTemplateStoryService { /** 模板列表 */ templateStoryList: StoryTemplateEntity[]; /** 当前选中要使用的模板 */ selectedTemplate: StoryTemplateEntity | null; /** 当前选中的活跃角色索引 */ activeRoleIndex: number; /** 计算属性:当前活跃角色信息 */ activeRole: TemplateRole | null; /** 加载状态 */ isLoading: boolean; /** 获取模板列表函数 */ getTemplateStoryList: () => Promise; /** action 生成电影函数 */ actionStory: () => Promise; /** 设置选中的模板 */ setSelectedTemplate: (template: StoryTemplateEntity | null) => void; /** 设置活跃角色索引 */ setActiveRoleIndex: (index: number) => void; /** 设置当前活跃角色的图片URL */ setActiveRoleImage: (imageUrl: string) => void; /** 设置当前活跃角色的音频URL */ setActiveRoleAudio: (audioUrl: string) => void; } export const useTemplateStoryServiceHook = (): UseTemplateStoryService => { const [templateStoryList, setTemplateStoryList] = useState([]); const [selectedTemplate, setSelectedTemplate] = useState(null); const [activeRoleIndex, setActiveRoleIndex] = useState(0); const [isLoading, setIsLoading] = useState(false); /** 模板故事用例实例 */ const templateStoryUseCase = useMemo(() => new TemplateStoryUseCase(), []); /** 计算属性:当前活跃角色信息 */ const activeRole = useMemo(() => { if (!selectedTemplate || activeRoleIndex < 0 || activeRoleIndex >= selectedTemplate.storyRole.length) { return null; } return selectedTemplate.storyRole[activeRoleIndex]; }, [selectedTemplate, activeRoleIndex]); /** * 获取模板列表函数 */ const getTemplateStoryList = useCallback(async (): Promise => { try { setIsLoading(true); const templates = await templateStoryUseCase.getTemplateStoryList(); setTemplateStoryList(templates); } catch (err) { console.error('获取模板列表失败:', err); } finally { setIsLoading(false); } }, [templateStoryUseCase]); /** * action 生成电影函数 */ const actionStory = useCallback(async (): Promise => { if (!selectedTemplate) { throw new Error('请先选择一个故事模板'); } try { setIsLoading(true); const projectId = await templateStoryUseCase.actionStory(selectedTemplate); return projectId; } catch (err) { console.error('生成电影失败:', err); throw err; } finally { setIsLoading(false); } }, [selectedTemplate, templateStoryUseCase]); /** * 设置活跃角色索引 */ const handleSetActiveRoleIndex = useCallback((index: number): void => { setActiveRoleIndex(index); }, []); /** * 设置当前活跃角色的图片URL */ const setActiveRoleImage = useCallback((imageUrl: string): void => { if (!selectedTemplate || activeRoleIndex < 0 || activeRoleIndex >= selectedTemplate.storyRole.length) { return; } const updatedTemplate = { ...selectedTemplate, storyRole: selectedTemplate.storyRole.map((role, index) => index === activeRoleIndex ? { ...role, photo_url: imageUrl } : role ), }; setSelectedTemplate(updatedTemplate); }, [selectedTemplate, activeRoleIndex]); /** * 设置当前活跃角色的音频URL */ const setActiveRoleAudio = useCallback((audioUrl: string): void => { if (!selectedTemplate || activeRoleIndex < 0 || activeRoleIndex >= selectedTemplate.storyRole.length) { return; } const updatedTemplate = { ...selectedTemplate, storyRole: selectedTemplate.storyRole.map((role, index) => index === activeRoleIndex ? { ...role, voice_url: audioUrl } : role ), }; setSelectedTemplate(updatedTemplate); }, [selectedTemplate, activeRoleIndex]); return { templateStoryList, selectedTemplate, activeRoleIndex, activeRole, isLoading, getTemplateStoryList, actionStory, setSelectedTemplate, setActiveRoleIndex: handleSetActiveRoleIndex, setActiveRoleImage, setActiveRoleAudio, }; };