import { post, streamJsonPost } from "./request"; import { ProjectTypeEnum } from "@/app/model/enums"; import { ApiResponse } from "@/api/common"; import { BASE_URL } from "./constants"; import { AITextEntity, RoleEntity, SceneEntity, VideoSegmentEntity, TagEntity, } from "@/app/service/domain/Entities"; import { ContentItem, LensType, ScriptSlice, } from "@/app/service/domain/valueObject"; // API 响应类型 interface BaseApiResponse { code: number; successful: boolean; message: string; data: T; } // 剧集详情数据类型 interface EpisodeDetail { project_id: string; name: string; status: "running" | "completed"; step: "sketch" | "character" | "video" | "music" | "final_video"; last_message: string; data: TaskData | null; mode: "auto" | "manual"; resolution: "1080p" | "4k"; } // 任务数据类型 interface TaskData { sketch?: Array<{ url: string; script: string; bg_rgb: string[]; }>; roles?: Array<{ name: string; url: string; sound: string; soundDescription: string; roleDescription: string; }>; videos?: Array<{ url: string; script: string; audio: string; }>; music?: Array<{ url: string; script: string; name: string; duration: string; totalDuration: string; isLooped: boolean; }>; final?: { url: string; }; } // 流式数据类型 export interface StreamData { category: "sketch" | "character" | "video" | "music" | "final_video"; message: string; data: T; status: "running" | "completed"; total?: number; completed?: number; all_completed?: boolean; } // 场景/分镜头数据结构 export interface Scene { id: string; name: string; description: string; plot: string; dialogue: string; narration: string; imageUrl?: string; } // 角色数据结构 export interface Character { name: string; desc: string; } // 剧本到分镜头提示词模型 export interface ScenePrompts { scenes: Scene[]; // 分场景列表 characters?: Character[]; // 角色列表 summary?: string; // 剧情概要 scene?: string; // 场景描述 atmosphere?: string; // 氛围描述 episode_id?: number; // 剧集ID total_shots?: string; // 总镜头数 } // 剧本转分镜头请求接口 export interface ScriptToSceneRequest { script: string; episode_id: number; script_id: number; project_type: ProjectTypeEnum.SCRIPT_TO_VIDEO; } // 视频转分镜头请求接口 export interface VideoToSceneRequest { video_url: string; episode_id: number; script_id: number; project_type: ProjectTypeEnum.VIDEO_TO_VIDEO; } // 转换分镜头请求类型 export type ConvertScenePromptRequest = | ScriptToSceneRequest | VideoToSceneRequest; // 转换分镜头响应接口 export type ConvertScenePromptResponse = BaseApiResponse; /** * 将剧本或视频转换为分镜头提示词 * @param request - 请求参数,根据 project_type 自动判断是剧本还是视频模式 * @returns Promise */ export const convertScenePrompt = async ( request: ConvertScenePromptRequest ): Promise => { // return post('/video_flow/convert-scene-prompts', request); return new Promise((resolve) => { setTimeout(() => { resolve({ code: 0, message: "success", data: { scenes: [], characters: [], summary: "", scene: "", atmosphere: "", episode_id: 0, total_shots: "", }, successful: true, }); }, 0); }); }; /** * 剧本转分镜头提示词 * @param script - 剧本内容 * @returns Promise */ export const convertScriptToScene = async ( script: string, episode_id: number, script_id: number ): Promise => { return convertScenePrompt({ script, episode_id, script_id, project_type: ProjectTypeEnum.SCRIPT_TO_VIDEO, }); }; /** * 视频转分镜头提示词 * @param video_url - 视频链接 * @returns Promise */ export const convertVideoToScene = async ( video_url: string, episode_id: number, script_id: number ): Promise => { return convertScenePrompt({ video_url, episode_id, script_id, project_type: ProjectTypeEnum.VIDEO_TO_VIDEO, }); }; // 新-获取剧集详情 export const detailScriptEpisodeNew = async (data: { project_id: string; }): Promise> => { return post>("/movie/get_movie_project_detail", data); }; // 获取 title 接口 export const getScriptTitle = async (data: { project_id: string; }): Promise> => { return post>("/movie/get_movie_project_description", data); }; // 获取 数据 全量(需轮询) export const getRunningStreamData = async (data: { project_id: string; }): Promise> => { return post>("/movie/get_status", data); }; // 获取 脚本 接口 export const getScriptTags = async (data: { project_id: string; }): Promise => { return post("/movie/text_to_script_tags", data); }; // 获取 loading-场景 接口 export const getSceneJson = async (data: { project_id: string; }): Promise> => { return post("/movie/scene_json", data); }; // 获取 loading-分镜 接口 export const getShotSketchJson = async (data: { project_id: string; }): Promise> => { return post("/movie/shot_sketch_json", data); }; // 获取 loading-视频 接口 export const getVideoJson = async (data: { project_id: string; }): Promise> => { return post("/movie/video_json", data); }; /** * 重新生成角色 * @param request - 重新生成角色请求参数 * @returns Promise> */ export const regenerateRole = async (request: { /** 角色提示词 */ prompt: string; /** 标签类型列表 */ tagTypes: (number | string)[]; /** 角色ID(可选,如果重新生成现有角色) */ roleId?: string; }): Promise> => { return post>("/movie/regenerate_role", request); }; /** * 应用角色到分镜 * @param request - 应用角色请求参数 * @returns Promise> */ export const applyRoleToShots = async (request: { /** 角色ID */ roleId: string; /** 分镜ID列表 */ shotIds: string[]; }): Promise> => { return post>("/movie/apply_role_to_shots", request); }; /** * 获取角色应用到的分镜列表 * @param request - 获取角色分镜列表请求参数 * @returns Promise> */ export const getRoleShots = async (request: { /** 角色ID */ roleId: string; }): Promise< ApiResponse<{ /** 分镜列表 */ shots: VideoSegmentEntity[]; /** 已应用的分镜ID列表 */ appliedShotIds: string[]; }> > => { return post>("/movie/get_role_shots", request); }; /** * 获取角色列表 * @param request - 获取角色列表请求参数 * @returns Promise> */ export const getRoleList = async (request: { /** 项目ID */ projectId: string; }): Promise> => { return post>("/movie/get_role_list", request); }; /** * 获取角色数据 * @param request - 获取角色数据请求参数 * @returns Promise> */ export const getRoleData = async (request: { /** 角色ID */ roleId: string; }): Promise< ApiResponse<{ /** AI文本数据 */ text: AITextEntity; /** 标签列表 */ tags: TagEntity[]; }> > => { return post>("/movie/get_role_data", request); }; /** * 获取用户角色库 * @returns Promise> */ export const getUserRoleLibrary = async (): Promise< ApiResponse > => { return post>("/movie/get_user_role_library", {}); }; /** * 替换角色 * @param request - 替换角色请求参数 * @returns Promise> */ export const replaceRole = async (request: { /** 当前角色ID */ currentRoleId: string; /** 替换的角色ID */ replaceRoleId: string; }): Promise> => { return post>("/movie/replace_role", request); }; /** * 修改标签 * @param request - 修改标签请求参数 * @returns Promise> */ export const updateTag = async (request: { /** 标签ID */ tagId: string; /** 新的标签内容 */ content: string | number; }): Promise> => { return post>("/movie/update_tag", request); }; /** * 修改文案 * @param request - 修改文案请求参数 * @returns Promise> */ export const updateText = async (request: { /** 文案ID */ textId: string; /** 新的文案内容 */ content: string; }): Promise> => { return post>("/movie/update_text", request); }; /** * 重新生成场景 * @param request - 重新生成场景请求参数 * @returns Promise> */ export const regenerateScene = async (request: { /** 场景提示词 */ prompt: string; /** 标签类型列表 */ tagTypes: (number | string)[]; /** 场景ID(可选,如果重新生成现有场景) */ sceneId?: string; }): Promise> => { return post>("/movie/regenerate_scene", request); }; /** * 应用场景到分镜 * @param request - 应用场景请求参数 * @returns Promise> */ export const applySceneToShots = async (request: { /** 场景ID */ sceneId: string; /** 分镜ID列表 */ shotIds: string[]; }): Promise> => { return post>("/movie/apply_scene_to_shots", request); }; /** * 获取场景数据 * @param request - 获取场景数据请求参数 * @returns Promise> */ export const getSceneData = async (request: { /** 场景ID */ sceneId: string; }): Promise< ApiResponse<{ /** AI文本数据 */ text: AITextEntity; /** 标签列表 */ tags: TagEntity[]; }> > => { return post>("/movie/get_scene_data", request); }; /** * 获取场景列表 * @param request - 获取场景列表请求参数 * @returns Promise> */ export const getSceneList = async (request: { /** 项目ID */ projectId: string; }): Promise> => { return post>("/movie/get_scene_list", request); }; /** * 获取场景应用到的分镜列表 * @param request - 获取场景分镜列表请求参数 * @returns Promise> */ export const getSceneShots = async (request: { /** 场景ID */ sceneId: string; }): Promise< ApiResponse<{ /** 分镜列表 */ shots: VideoSegmentEntity[]; /** 已应用的分镜ID列表 */ appliedShotIds: string[]; }> > => { return post>("/movie/get_scene_shots", request); }; /** * 获取分镜关联的角色信息列表 * @param request - 获取分镜角色信息请求参数 * @returns Promise> */ export const getShotRoles = async (request: { /** 分镜ID */ shotId: string; }): Promise> => { return post>("/movie/get_shot_roles", request); }; /** * 获取分镜关联的场景信息列表 * @param request - 获取分镜场景信息请求参数 * @returns Promise> */ export const getShotScenes = async (request: { /** 分镜ID */ shotId: string; }): Promise> => { return post>("/movie/get_shot_scenes", request); }; /** * 获取分镜详细数据 * @param request - 获取分镜数据请求参数 * @returns Promise> */ export const getShotData = async (request: { /** 分镜ID */ shotId: string; }): Promise< ApiResponse<{ /** AI文本数据 */ text: AITextEntity; /** 标签列表 */ tags: TagEntity[]; }> > => { return post>("/movie/get_shot_data", request); }; /** * 重新生成分镜 * @param request - 重新生成分镜请求参数 * @returns Promise> */ export const regenerateShot = async (request: { /** 分镜ID */ shotId?: string; /** 镜头描述 */ shotPrompt?: LensType[]; /** 对话内容 */ dialogueContent?: ContentItem[]; /** 角色ID替换参数,格式为{oldId:string,newId:string}[] */ roleReplaceParams?: { oldId: string; newId: string }[]; /** 场景ID替换参数,格式为{oldId:string,newId:string}[] */ sceneReplaceParams?: { oldId: string; newId: string }[]; }): Promise> => { return post>("/movie/regenerate_shot", request); }; /** * 修改分镜对话内容 * @param request - 修改分镜对话内容请求参数 * @returns Promise> */ export const updateShotContent = async (request: { /** 分镜ID */ shotId: string; /** 新的对话内容,ContentItem数量和ID顺序不能变,只能修改content字段 */ content: Array<{ /** 角色ID */ roleId: string; /** 对话内容 */ content: string; }>; }): Promise> => { return post>("/movie/update_shot_content", request); }; /** * 获取分镜列表 * @param request - 获取分镜列表请求参数 * @returns Promise> */ export const getShotList = async (request: { /** 项目ID */ projectId: string; }): Promise> => { return post>("/movie/get_shot_list", request); }; /** * 替换分镜角色 * @param request - 替换分镜角色请求参数 * @returns Promise> */ export const replaceShotRole = async (request: { /** 分镜ID */ shotId: string; /** 旧角色ID */ oldRoleId: string; /** 新角色ID */ newRoleId: string; }): Promise> => { return post>("/movie/replace_shot_role", request); }; /** * 获取分镜视频剧本内容 * @param request - 获取分镜视频剧本请求参数 * @returns Promise> */ export const getShotVideoScript = async (request: { /** 分镜ID */ shotId: string; }): Promise> => { return post>("/movie/get_shot_video_script", request); }; /** * AI生成剧本流式接口 * @param request - AI生成剧本请求参数 * @returns Promise> */ export const generateScriptStream = ( request: { /** 剧本提示词 */ text: string; }, onData: (data: any) => void ): Promise => { return new Promise((resolve, reject) => { streamJsonPost("/text_to_script/generate_script_stream", request, (data) => { switch(data.status) { case 'streaming': onData(data.content); break; case 'completed': console.log('生成完成:', data.message); return; case 'error': console.error('生成失败:', data.message); return; } }) }) }; /** * 应用剧本 * @param request - 应用剧本请求参数 * @returns Promise> */ export const applyScriptToShot = async (request: { /** 项目ID */ projectId: string; /** 剧本*/ scriptText: string; }): Promise> => { return post>("/movie/apply_script_to_shot", request); }; /** * 获取项目剧本数据 * @param request 请求参数 */ export const getProjectScript = async (request: { /** 项目ID */ projectId: string; }): Promise< ApiResponse<{ /** 用户提示词 */ prompt: string; /** 生成的剧本文本 */ scriptText: string; }> > => { return post< ApiResponse<{ prompt: string; scriptText: string; }> >("/movie/get_project_script", request); }; /** * 保存剧本 * @param request 保存剧本请求参数 * @returns Promise> */ export const saveScript = async (request: { /** 项目ID */ projectId: string; /** 剧本文本 */ scriptText: string; }): Promise> => { return post>("/movie/save_script", request); }; /** * 创建项目 * @param request 创建项目请求参数 * @returns Promise> */ export const createProject = async (request: { /** 用户提示词 */ userPrompt: string; /** 剧本内容 */ scriptContent: string; }): Promise< ApiResponse<{ /** 项目ID */ projectId: string; }> > => { return post< ApiResponse<{ projectId: string; }> >("/movie/create_project", request); };