diff --git a/api/DTO/movie_start_dto.ts b/api/DTO/movie_start_dto.ts index db56da9..5bac19c 100644 --- a/api/DTO/movie_start_dto.ts +++ b/api/DTO/movie_start_dto.ts @@ -60,7 +60,11 @@ export interface CreateMovieProjectV2Request { /** 类型 */ genre: string; /** 角色简介数组 */ - character_briefs: string[]; + character_briefs: { + name:string; + image_url:string; + character_analysis:Record; + }[]; /** 语言 */ language: string; /** 图片URL */ diff --git a/api/request.ts b/api/request.ts index cb4452a..4f86d78 100644 --- a/api/request.ts +++ b/api/request.ts @@ -30,7 +30,7 @@ request.interceptors.request.use( request.interceptors.response.use( (response: AxiosResponse) => { // 直接返回响应数据 - if (!response.data?.successful) { + if (response.data?.code !=0) { // TODO 暂时固定报错信息,后续根据后端返回的错误码进行处理 errorHandle(0); } diff --git a/app/service/Interaction/ImageStoryService.ts b/app/service/Interaction/ImageStoryService.ts index 2613000..19ed29e 100644 --- a/app/service/Interaction/ImageStoryService.ts +++ b/app/service/Interaction/ImageStoryService.ts @@ -426,9 +426,11 @@ export const useImageStoryServiceHook = (): UseImageStoryService => { // 从charactersAnalysis中提取whisk_caption字段组成数组 const character_briefs = charactersAnalysis.map(char => { - const obj = JSON.parse(char.whisk_caption); - obj.character_analysis.role_name = char.role_name; - return JSON.stringify(obj); + return { + name:char.role_name, + image_url:char.crop_url, + character_analysis:JSON.parse(char.whisk_caption).character_analysis + } }); const params: CreateMovieProjectV2Request = { diff --git a/app/service/Interaction/templateStoryService.ts b/app/service/Interaction/templateStoryService.ts index 6d5fc3d..2b0c1e5 100644 --- a/app/service/Interaction/templateStoryService.ts +++ b/app/service/Interaction/templateStoryService.ts @@ -142,7 +142,7 @@ export const useTemplateStoryServiceHook = (): UseTemplateStoryService => { ] } ]); - }, 10000); + }, 3000); }); setTemplateStoryList(templates); diff --git a/app/service/test/flow.test.ts b/app/service/test/flow.test.ts index 9363d2e..3b8282c 100644 --- a/app/service/test/flow.test.ts +++ b/app/service/test/flow.test.ts @@ -10,13 +10,13 @@ describe("flow 提示词优化", () => { - 身高估计:设定一个具体的值 - 人种:预估这个人的人种。 - 2. **详细面容** 必须要给出预测的数值 - - 眼睛:描述大小、形状、颜色、间距。 - - 鼻子:描述长度、宽度、形态。 - - 嘴巴:描述宽度、形状、颜色。 - - 耳朵:描述大小、形状、位置。 - - 脸型:描述整体轮廓、下巴、颧骨。 - - 额头:描述高度、形状、发际线。 + 2. **详细面容**:每一段不少于20个词的描述 + - 眼睛。 + - 鼻子 + - 嘴巴 + - 耳朵 + - 脸型 + - 额头 3. **外观特征**: 每一段不少于30个词的描述 - 肤色:必须给出具体的颜色描述(如“浅米色”、“深棕色”、“橄榄色”等),严禁使用“浅色”、“深色”或“中等”等模糊词汇。 diff --git a/components/ChatInputBox/ChatInputBox.tsx b/components/ChatInputBox/ChatInputBox.tsx index f006b40..b24f48c 100644 --- a/components/ChatInputBox/ChatInputBox.tsx +++ b/components/ChatInputBox/ChatInputBox.tsx @@ -18,7 +18,15 @@ import { Sparkles, Settings, } from "lucide-react"; -import { Dropdown, Modal, Tooltip, Upload, Spin, Popconfirm } from "antd"; +import { + Dropdown, + Modal, + Tooltip, + Upload, + Spin, + Popconfirm, + Image, +} from "antd"; import { UploadOutlined } from "@ant-design/icons"; import { StoryTemplateEntity } from "@/app/service/domain/Entities"; import { useImageStoryServiceHook } from "@/app/service/Interaction/ImageStoryService"; @@ -53,9 +61,12 @@ const RenderTemplateStoryMode = ({ setActiveRoleIndex, setActiveRoleImage, setActiveRoleAudio, - clearData + clearData, } = useTemplateStoryServiceHook(); + // 使用上传文件hook + const { uploadFile, isUploading } = useUploadFile(); + // 本地加载状态,用于 UI 反馈 const [localLoading, setLocalLoading] = useState(0); @@ -103,14 +114,23 @@ const RenderTemplateStoryMode = ({ } }; - // 处理角色图片上传 - const handleRoleImageUpload = (roleIndex: number, file: any) => { - if (file && selectedTemplate) { - // 模拟上传成功,设置图片URL - const imageUrl = URL.createObjectURL(file); - setActiveRoleImage(imageUrl); - } - }; + // 处理角色图片上传 - 已移至customRequest中处理 + // const handleRoleImageUpload = async (roleIndex: number, file: File) => { + // if (!file || !selectedTemplate) return; + // + // try { + // // 使用真正的文件上传功能 + // const imageUrl = await uploadFile(file, (progress) => { + // console.log(`上传进度: ${progress}%`); + // }); + // + // // 上传成功后,更新角色图片 + // setActiveRoleImage(imageUrl); + // } catch (error) { + // console.error("图片上传失败:", error); + // // 这里可以添加错误提示 + // } + // }; // 删除角色图片 const handleDeleteRoleImage = (roleIndex: number) => { @@ -122,7 +142,6 @@ const RenderTemplateStoryMode = ({ const templateListRender = () => { return (
-

Story Templates

{templateStoryList.map((template, index) => (
{ - return selectedTemplate ? ( + return selectedTemplate ? (
{/* 模板信息头部 - 增加顶部空间 */}
@@ -211,25 +230,67 @@ const RenderTemplateStoryMode = ({ listType="picture-card" className="avatar-uploader [&_.ant-upload-select]:!w-32 [&_.ant-upload-select]:!h-32" showUploadList={false} - action="https://660d2bd96ddfa2943b33731c.mockapi.io/api/upload" - beforeUpload={() => false} - onChange={(info) => { - if (info.file.status === "done") { - handleRoleImageUpload( - activeRoleIndex, - info.file.originFileObj + beforeUpload={(file) => { + // 验证文件类型 + const isImage = file.type.startsWith("image/"); + if (!isImage) { + console.error("只能上传图片文件"); + return false; + } + + // 验证文件大小 (5MB) + const isLt5M = file.size / 1024 / 1024 < 10; + if (!isLt5M) { + console.error("图片大小不能超过10MB"); + return false; + } + + return true; // 允许文件通过验证 + }} + customRequest={async ({ file, onSuccess, onError }) => { + try { + const fileObj = file as File; + console.log( + "开始上传图片文件:", + fileObj.name, + fileObj.type, + fileObj.size ); + + // 使用 hook 上传文件到七牛云 + const uploadedUrl = await uploadFile( + fileObj, + (progress) => { + console.log(`上传进度: ${progress}%`); + } + ); + + console.log("图片上传成功,URL:", uploadedUrl); + + // 上传成功后,更新角色图片 + setActiveRoleImage(uploadedUrl); + + // 调用成功回调 + onSuccess?.(uploadedUrl); + } catch (error) { + console.error("图片上传失败:", error); + onError?.(error as Error); } }} > {activeRole?.photo_url ? (
- Character Portrait - + */}
@@ -248,8 +309,17 @@ const RenderTemplateStoryMode = ({
) : (
- - Upload Photo + {isUploading ? ( + <> + + 上传中... + + ) : ( + <> + + Upload Photo + + )}
)} @@ -280,11 +350,7 @@ const RenderTemplateStoryMode = ({ Characters {selectedTemplate.storyRole.map((role, index: number) => ( - + @@ -305,7 +376,7 @@ const RenderTemplateStoryMode = ({
-
+
0} handleCreateVideo={handleConfirm} @@ -321,7 +392,7 @@ const RenderTemplateStoryMode = ({

Please try again later

- ) + ); }; return ( <> @@ -329,7 +400,7 @@ const RenderTemplateStoryMode = ({ open={isOpen} onCancel={() => { // 清空所有选中的内容数据 - clearData() + clearData(); onClose(); }} footer={null} @@ -344,7 +415,7 @@ const RenderTemplateStoryMode = ({
} > -
+
{/* 弹窗头部 */}

@@ -352,7 +423,7 @@ const RenderTemplateStoryMode = ({

-
+
{templateListRender()}
{storyEditorRender()}
@@ -871,22 +942,22 @@ const PhotoStoryModal = ({
{/* 左侧:图片上传 */}
-
{activeImageUrl ? (
- Story inspiration + Story inspiration -
- {avatar.name} { - // 如果裁剪的头像加载失败,回退到原图 - const target = e.target as HTMLImageElement; - target.src = activeImageUrl; - }} - /> +
+ {avatar.name} { + // 如果裁剪的头像加载失败,回退到原图 + const target = e.target as HTMLImageElement; + target.src = activeImageUrl; + }} + /> {/* 删除角色按钮 - 使用Tooltip并调整z-index避免被遮挡 */}