import { ImageStoryEntity } from "../domain/Entities"; import { AIGenerateImageStory } from "@/api/movie_start"; import { MovieStartDTO, CharacterAnalysis } from "@/api/DTO/movie_start_dto"; /** * 图片故事用例 * 负责管理图片故事模式的业务逻辑,包括图片上传、AI分析和故事生成 */ export class ImageStoryUseCase { /** 当前图片故事数据 */ imageStory: Partial = { imageUrl: "", imageStory: "", storyType: "auto", }; /** 故事梗概 */ storyLogline: string = ""; /** 角色头像及名称数据 */ charactersAnalysis: CharacterAnalysis[] = []; /** 分类数据 */ potentialGenres: string[] = []; /** 是否正在分析图片 */ isAnalyzing: boolean = false; /** 是否正在上传 */ isUploading: boolean = false; constructor() {} /** * 获取当前图片故事数据 * @returns {Partial} 图片故事数据 */ getImageStory(): Partial { return { ...this.imageStory }; } /** * 获取故事梗概 * @returns {string} 故事梗概 */ getStoryLogline(): string { return this.storyLogline; } /** * 获取角色分析数据 * @returns {CharacterAnalysis[]} 角色分析数据 */ getCharactersAnalysis(): CharacterAnalysis[] { return [...this.charactersAnalysis]; } /** * 获取分类数据 * @returns {string[]} 分类数据 */ getPotentialGenres(): string[] { return [...this.potentialGenres]; } /** * 获取分析状态 * @returns {boolean} 是否正在分析 */ getAnalyzingStatus(): boolean { return this.isAnalyzing; } /** * 获取上传状态 * @returns {boolean} 是否正在上传 */ getUploadingStatus(): boolean { return this.isUploading; } /** * 设置图片故事数据 * @param {Partial} data - 要设置的图片故事数据 */ setImageStory(data: Partial): void { this.imageStory = { ...this.imageStory, ...data }; } /** * 重置图片故事数据 */ resetImageStory(): void { this.imageStory = { imageUrl: "", imageStory: "", storyType: "auto", }; this.storyLogline = ""; this.charactersAnalysis = []; this.potentialGenres = []; this.isAnalyzing = false; this.isUploading = false; } /** * 处理图片上传 * @param {string} imageUrl - 已上传的图片URL * @returns {Promise} */ async handleImageUpload(imageUrl: string): Promise { try { this.isUploading = false; // 图片已上传,设置上传状态为false this.isAnalyzing = true; // 设置上传后的图片URL this.setImageStory({ imageUrl }); // 调用AI分析接口 await this.analyzeImageWithAI(); } catch (error) { console.error("图片分析失败:", error); // 分析失败时清空图片URL this.setImageStory({ imageUrl: "" }); throw error; } finally { this.isAnalyzing = false; } } /** * 使用AI分析图片 * @returns {Promise} */ async analyzeImageWithAI(): Promise { try { // 调用AI分析接口 const response = await AIGenerateImageStory({ imageUrl: this.imageStory.imageUrl || "", user_text: this.imageStory.imageStory || "", }); if (response.successful && response.data) { // 解析并存储新的数据结构 this.parseAndStoreAnalysisData(response.data); // 组合成ImageStoryEntity this.composeImageStoryEntity(response.data); } else { throw new Error("AI分析失败"); } } catch (error) { console.error("AI分析失败:", error); throw error; } } /** * 解析并存储分析数据到类属性中 * @param {MovieStartDTO} data - AI分析返回的数据 */ parseAndStoreAnalysisData(data: MovieStartDTO): void { // 存储故事梗概 this.storyLogline = data.story_logline || ""; // 存储角色头像及名称数据 this.charactersAnalysis = data.characters_analysis || []; // 存储分类数据 this.potentialGenres = data.potential_genres || []; } /** * 组合成ImageStoryEntity * @param {MovieStartDTO} data - AI分析返回的数据 */ composeImageStoryEntity(data: MovieStartDTO): void { // 将角色数据转换为ImageStoryEntity需要的格式 const roleImage = data.characters_analysis?.map(character => ({ name: character.role_name, avatar_url: "", // 这里需要根据实际情况设置头像URL region: { x: character.region.x, y: character.region.y, width: character.region.width, height: character.region.height, } })) || []; // 更新ImageStoryEntity this.setImageStory({ imageAnalysis: data.story_logline || "", storyType: data.potential_genres?.[0] || "auto", // 使用第一个分类作为故事类型 roleImage, }); } /** * 更新故事类型 * @param {string} storyType - 新的故事类型 */ updateStoryType(storyType: string): void { this.setImageStory({ storyType }); } /** * 更新故事内容 * @param {string} storyContent - 新的故事内容 */ updateStoryContent(storyContent: string): void { this.setImageStory({ imageStory: storyContent }); } /** * 获取故事类型选项 * @returns {Array<{key: string, label: string}> 故事类型选项数组 */ getStoryTypeOptions(): Array<{ key: string; label: string }> { return [ { key: "auto", label: "Auto" }, { key: "adventure", label: "Adventure" }, { key: "romance", label: "Romance" }, { key: "mystery", label: "Mystery" }, { key: "fantasy", label: "Fantasy" }, { key: "comedy", label: "Comedy" }, ]; } /** * 处理角色数据,解析并存储到类属性中 * @param {CharacterAnalysis[]} characters - 角色分析数据 */ processCharacterData(characters: CharacterAnalysis[]): void { this.charactersAnalysis = characters.map(character => ({ ...character, region: { x: character.region.x, y: character.region.y, width: character.region.width, height: character.region.height, } })); } /** * 获取指定角色的区域坐标 * @param {string} characterName - 角色名称 * @returns {CharacterAnalysis['region'] | null} 角色区域坐标,如果未找到则返回null */ getCharacterRegion(characterName: string): CharacterAnalysis['region'] | null { const character = this.charactersAnalysis.find(char => char.role_name === characterName); return character ? character.region : null; } /** * 更新角色头像URL * @param {string} characterName - 角色名称 * @param {string} avatarUrl - 头像URL */ updateCharacterAvatar(characterName: string, avatarUrl: string): void { const character = this.charactersAnalysis.find(char => char.role_name === characterName); if (character) { // 更新角色头像URL(这里需要根据实际的数据结构来调整) // 由于CharacterAnalysis接口中没有avatar_url字段,这里只是示例 console.log(`更新角色 ${characterName} 的头像URL: ${avatarUrl}`); } } /** * 获取所有角色名称 * @returns {string[]} 角色名称数组 */ getAllCharacterNames(): string[] { return this.charactersAnalysis.map(char => char.role_name); } }