import { ShotEntity, RoleEntity, SceneEntity, AITextEntity, TagEntity } from '../domain/Entities'; import { ShotItem, RoleItem, SceneItem, TextItem, TagItem } from '../domain/Item'; import { getShotRoles, getShotScenes, getShotData, regenerateShot, updateShotContent } from '@/api/video_flow'; /** * 分镜编辑用例 * 负责分镜内容的初始化、修改和优化 */ export class ShotEditUseCase { constructor(private shotItem: ShotItem) { } /** * 获取分镜关联的角色信息列表 * @description 获取当前分镜可以使用的角色列表 * @returns Promise 角色信息列表 * @throws {Error} 当API调用失败时抛出错误 */ async getShotRoles(): Promise { const shotId = this.shotItem.entity.id; if (!shotId) { throw new Error('分镜ID不存在,无法获取角色信息'); } const response = await getShotRoles({ shotId: shotId }); if (response.successful) { return response.data; } else { throw new Error(`获取分镜角色信息失败: ${response.message}`); } } /** * 获取分镜关联的场景信息列表 * @description 获取当前分镜可以使用的场景列表 * @returns Promise 场景信息列表 * @throws {Error} 当API调用失败时抛出错误 */ async getShotScenes(): Promise { const shotId = this.shotItem.entity.id; if (!shotId) { throw new Error('分镜ID不存在,无法获取场景信息'); } const response = await getShotScenes({ shotId: shotId }); if (response.successful) { return response.data; } else { throw new Error(`获取分镜场景信息失败: ${response.message}`); } } /** * 重新获取当前分镜信息 * @description 从服务器重新获取当前分镜的详细数据,并更新当前实体 * @returns Promise<{ text: AITextEntity; tags: TagEntity[] }> 分镜相关的AI文本和标签数据 * @throws {Error} 当API调用失败时抛出错误 */ async refreshShotData(): Promise<{ text: AITextEntity; tags: TagEntity[] }> { const shotId = this.shotItem.entity.id; if (!shotId) { throw new Error('分镜ID不存在,无法获取分镜数据'); } const response = await getShotData({ shotId: shotId }); if (response.successful) { // 更新当前分镜的实体数据 const { text, tags } = response.data; // 更新分镜实体中的相关字段 const updatedShotEntity = { ...this.shotItem.entity, generateTextId: text.id, // 更新AI文本ID tagIds: tags.map((tag: TagEntity) => tag.id), // 更新标签ID列表 updatedAt: Date.now(), // 更新时间戳 }; // 更新当前UseCase中的实体 this.shotItem.setEntity(updatedShotEntity); // 检查状态是否需要更新为视频状态 this.checkAndUpdateVideoStatus(updatedShotEntity); return response.data; } else { throw new Error(`获取分镜数据失败: ${response.message}`); } } /** * 重新生成当前分镜 * @description 使用镜头、对话内容、角色ID替换参数、场景ID替换参数重新生成分镜 * @param shotPrompt 镜头描述 * @param dialogueContent 对话内容 * @param roleReplaceParams 角色ID替换参数,格式为{oldId:string,newId:string}[] * @param sceneReplaceParams 场景ID替换参数,格式为{oldId:string,newId:string}[] * @returns Promise 重新生成的分镜实体 * @throws {Error} 当API调用失败时抛出错误 */ async regenerateShot( shotPrompt: string, dialogueContent: string, roleReplaceParams: { oldId: string; newId: string }[], sceneReplaceParams: { oldId: string; newId: string }[] ): Promise { const shotId = this.shotItem.entity.id; if (!shotId) { throw new Error('分镜ID不存在,无法重新生成分镜'); } // 调用重新生成分镜接口 const response = await regenerateShot({ shotId: shotId, shotPrompt: shotPrompt, dialogueContent: dialogueContent, roleReplaceParams: roleReplaceParams, sceneReplaceParams: sceneReplaceParams, }); if (response.successful) { const shotEntity = response.data; this.shotItem.setEntity(shotEntity); // 检查状态是否需要更新为视频状态 this.checkAndUpdateVideoStatus(shotEntity); return shotEntity; } else { throw new Error(`重新生成分镜失败: ${response.message}`); } } /** * 修改分镜对话内容 * @description 更新分镜的对话内容,ContentItem数量和ID顺序不能变,只能修改content字段 * @param newContent 新的对话内容数组 * @returns Promise 修改后的分镜实体 * @throws {Error} 当API调用失败时抛出错误 */ async updateShotContent(newContent: Array<{ roleId: string; content: string }>): Promise { const shotId = this.shotItem.entity.id; if (!shotId) { throw new Error('分镜ID不存在,无法修改对话内容'); } // 验证ContentItem数量和ID顺序 const currentContent = this.shotItem.entity.content; if (newContent.length !== currentContent.length) { throw new Error('ContentItem数量不能改变'); } // 验证角色ID顺序 for (let i = 0; i < newContent.length; i++) { if (newContent[i].roleId !== currentContent[i].roleId) { throw new Error('ContentItem的roleId顺序不能改变'); } } const response = await updateShotContent({ shotId: shotId, content: newContent, }); if (response.successful) { const shotEntity = response.data; this.shotItem.setEntity(shotEntity); // 检查状态是否需要更新为视频状态 this.checkAndUpdateVideoStatus(shotEntity); return shotEntity; } else { throw new Error(`修改分镜对话内容失败: ${response.message}`); } } /** * 检查并更新视频状态 * @description 当分镜状态变为视频加载中或完成时,调用updateToVideoStatus * @param shotEntity 分镜实体 */ private checkAndUpdateVideoStatus(shotEntity: ShotEntity): void { // 当状态为视频加载中或完成时,更新为视频状态 if (shotEntity.status === 1 || shotEntity.status === 2) { // videoLoading 或 finished this.shotItem.updateToVideoStatus(); } } }