diff --git a/api/video_flow.ts b/api/video_flow.ts index 864b443..218f41e 100644 --- a/api/video_flow.ts +++ b/api/video_flow.ts @@ -738,6 +738,8 @@ export const createMovieProjectV1 = async (request: { resolution: "720p" | "1080p" | "4k"; /** 语言 */ language: string; + /** 视频时长 */ + video_duration: string; }) => { return post Promise; /** 设置任何属性 */ setAnyAttribute: any; @@ -158,7 +159,8 @@ export const useScriptService = (): UseScriptService => { userId: string, mode: "automatic" | "manual", resolution: string, - language: string + language: string, + video_duration: string ): Promise => { try { setLoading(true); @@ -169,7 +171,8 @@ export const useScriptService = (): UseScriptService => { userId, mode as "automatic" | "manual", resolution as "720p" | "1080p" | "4k", - language + language, + video_duration ); setProjectId(projectData.project_id); diff --git a/app/service/adapter/textToShot.ts b/app/service/adapter/textToShot.ts index 5dd57ca..b9c8111 100644 --- a/app/service/adapter/textToShot.ts +++ b/app/service/adapter/textToShot.ts @@ -60,10 +60,10 @@ export class TextToShotAdapter { let currentText = text; // 按角色名称长度降序排序,避免短名称匹配到长名称的一部分 - // 既要兼容 首字母大写 其余小写、还要兼容 全部大写 + // 既要兼容 每个单词 首字母大写 其余小写、还要兼容 全部大写 const sortedRoles = [...roles].sort((a, b) => b.name.length - a.name.length).map(role => ({ ...role, - name: role.name.charAt(0).toUpperCase() + role.name.slice(1).toLowerCase() + name: role.name.split(' ').map(word => word.charAt(0).toUpperCase() + word.slice(1).toLowerCase()).join(' ') })).concat([...roles].map(role => ({ ...role, name: role.name.toUpperCase() @@ -257,14 +257,16 @@ export class TextToShotAdapter { if (shotData.shotDescContent.length > 0) { // 合并所有描述段落的文本内容 shotData.shotDescContent.forEach(paragraph => { - paragraph.content.forEach(node => { - if (node.type === 'text') { - currentScript += node.text; - } - if (node.type === 'characterToken') { - currentScript += node.attrs.name; - } - }); + if (paragraph.content) { + paragraph.content.forEach(node => { + if (node.type === 'text') { + currentScript += node.text; + } + if (node.type === 'characterToken') { + currentScript += node.attrs.name; + } + }); + } }); } diff --git a/app/service/test/Script.test.ts b/app/service/test/Script.test.ts index 7bf3e22..81b0bbe 100644 --- a/app/service/test/Script.test.ts +++ b/app/service/test/Script.test.ts @@ -40,7 +40,8 @@ describe("ScriptService 业务逻辑测试", () => { "user123", "automatic", "720p", - "en" + "en", + "10" ); expect(createRes.project_id).toBeDefined(); projectId = createRes.project_id; diff --git a/app/service/usecase/ScriptEditUseCase.ts b/app/service/usecase/ScriptEditUseCase.ts index dc5b5b0..76877b7 100644 --- a/app/service/usecase/ScriptEditUseCase.ts +++ b/app/service/usecase/ScriptEditUseCase.ts @@ -126,7 +126,8 @@ export class ScriptEditUseCase { userId: string , mode: "automatic" | "manual" = "automatic", resolution: "720p" | "1080p" | "4k" = "720p", - language: string + language: string, + video_duration: string ) { try { // 调用创建项目API @@ -136,6 +137,7 @@ export class ScriptEditUseCase { mode, resolution, language, + video_duration, }); if (!response.successful) { diff --git a/components/ai-suggestion-bar.tsx b/components/ai-suggestion-bar.tsx index ecb8211..05418d5 100644 --- a/components/ai-suggestion-bar.tsx +++ b/components/ai-suggestion-bar.tsx @@ -7,7 +7,7 @@ interface AISuggestionBarProps { suggestions: string[]; onSuggestionClick: (suggestion: string) => void; onSubmit: (text: string) => void; - onFocus: () => void; + onClick: () => void; placeholder?: string; } @@ -15,7 +15,7 @@ export function AISuggestionBar({ suggestions, onSuggestionClick, onSubmit, - onFocus, + onClick, placeholder = "输入你的想法,或点击预设词条获取 AI 建议..." }: AISuggestionBarProps) { const [inputText, setInputText] = useState(''); @@ -89,7 +89,7 @@ export function AISuggestionBar({ -
+
{/* 智能预设词条 英文 */} {showSuggestions && !isCollapsed && ( @@ -179,7 +179,6 @@ export function AISuggestionBar({ if (isCollapsed) { toggleCollapse(); } - onFocus(); }} onBlur={() => setIsFocused(false)} placeholder={isCollapsed ? "点击展开..." : placeholder} diff --git a/components/common/ChatInputBox.tsx b/components/common/ChatInputBox.tsx index aca6f60..60b574e 100644 --- a/components/common/ChatInputBox.tsx +++ b/components/common/ChatInputBox.tsx @@ -30,10 +30,15 @@ import { AudioRecorder } from "./AudioRecorder"; import { useTemplateStoryServiceHook } from "@/app/service/Interaction/templateStoryService"; import { createScriptEpisodeNew } from "@/api/script_episode"; import { useRouter } from "next/navigation"; +<<<<<<< HEAD import { EditorContent, useEditor } from "@tiptap/react"; import StarterKit from "@tiptap/starter-kit"; import { HighlightTextExtension } from "@/components/ui/main-editor/HighlightText"; import Placeholder from "@tiptap/extension-placeholder"; +import { createMovieProjectV1 } from "@/api/video_flow"; +======= +import { createMovieProjectV1 } from "@/api/video_flow"; +>>>>>>> 3a713f988f2a1b9f322258e14c192470d879eee5 // 自定义音频播放器样式 const customAudioPlayerStyles = ` @@ -548,8 +553,8 @@ export function ChatInputBox() { }; // 调用创建剧集API - const episodeResponse = await createScriptEpisodeNew(episodeData); - console.log("episodeResponse", episodeResponse); + const episodeResponse = await createMovieProjectV1(episodeData); + console.log('episodeResponse', episodeResponse); if (episodeResponse.code !== 0) { console.error(`创建剧集失败: ${episodeResponse.message}`); alert(`创建剧集失败: ${episodeResponse.message}`); diff --git a/components/pages/style/work-flow.css b/components/pages/style/work-flow.css index de416bb..6f02097 100644 --- a/components/pages/style/work-flow.css +++ b/components/pages/style/work-flow.css @@ -159,6 +159,10 @@ display: flex; overflow: hidden; min-height: 0; + + display: grid; + grid-auto-rows: auto; + justify-content: center; } .videoContainer-qteKNi { flex: 1; @@ -166,13 +170,14 @@ display: flex; position: relative; justify-content: center; + + width: max-content; } .heroVideo-FIzuK1 { object-fit: cover; object-position: center; background-color: #0003; border-radius: 8px; - width: 100%; height: 100%; } .container-kIPoeH { diff --git a/components/pages/work-flow.tsx b/components/pages/work-flow.tsx index 4712df5..991adbf 100644 --- a/components/pages/work-flow.tsx +++ b/components/pages/work-flow.tsx @@ -21,7 +21,6 @@ const WorkFlow = React.memo(function WorkFlow() { console.log("init-WorkFlow"); return () => console.log("unmount-WorkFlow"); }, []); - const containerRef = useRef(null); const [isEditModalOpen, setIsEditModalOpen] = React.useState(false); const [activeEditTab, setActiveEditTab] = React.useState('1'); @@ -92,102 +91,98 @@ const WorkFlow = React.memo(function WorkFlow() { return (
-
-
-
-
-
- - - -
+
+
+
+
+ + +
-
-
- {dataLoadError ? ( +
+
+
+ {dataLoadError ? ( + - - -

数据加载失败

-
- -

- {dataLoadError} -

- - retryLoadData?.()} - whileHover={{ scale: 1.05 }} - whileTap={{ scale: 0.95 }} - > - - 重试加载 - + +

数据加载失败

- ) : isLoading ? ( - - ) : ( -
- - - -
- )} -
- {taskObject.currentStage !== 'final_video' && taskObject.currentStage !== 'script' && ( -
+ +

+ {dataLoadError} +

+ + retryLoadData?.()} + whileHover={{ scale: 1.05 }} + whileTap={{ scale: 0.95 }} + > + + 重试加载 + + + ) : isLoading ? ( + + ) : ( +
-
)} -
+ {taskObject.currentStage !== 'final_video' && taskObject.currentStage !== 'script' && ( +
+ +
+ )} +
@@ -202,7 +197,7 @@ const WorkFlow = React.memo(function WorkFlow() { tooltip={isPauseWorkFlow ? "Play" : "Pause"} onClick={() => setIsPauseWorkFlow(!isPauseWorkFlow)} /> - { mode !== 'automatic' && ( + { !mode.includes('auto') && ( setIsPauseWorkFlow(true)} + onClick={() => setIsPauseWorkFlow(true)} placeholder="Please input your ideas, or click the predefined tags to receive AI advice..." /> diff --git a/components/pages/work-flow/media-viewer.tsx b/components/pages/work-flow/media-viewer.tsx index 27d4c89..b6aa3f0 100644 --- a/components/pages/work-flow/media-viewer.tsx +++ b/components/pages/work-flow/media-viewer.tsx @@ -137,7 +137,7 @@ export const MediaViewer = React.memo(function MediaViewer({ return (