forked from 77media/video-flow
mock 百科全书模版 支持输入
This commit is contained in:
parent
9c5d064bd7
commit
260ce49cda
@ -68,6 +68,15 @@ export const useTemplateStoryServiceHook = (): UseTemplateStoryService => {
|
|||||||
setIsLoading(true);
|
setIsLoading(true);
|
||||||
|
|
||||||
const templates = await templateStoryUseCase.getTemplateStoryList();
|
const templates = await templateStoryUseCase.getTemplateStoryList();
|
||||||
|
templates.forEach(template => {
|
||||||
|
if (template.template_id === '69') {
|
||||||
|
template.freeInputItem = {
|
||||||
|
user_tips: "How is coffee made?",
|
||||||
|
constraints: "",
|
||||||
|
free_input_text: ""
|
||||||
|
};
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
setTemplateStoryList(templates);
|
setTemplateStoryList(templates);
|
||||||
setSelectedTemplate(templates[0]);
|
setSelectedTemplate(templates[0]);
|
||||||
@ -237,7 +246,7 @@ export const useTemplateStoryServiceHook = (): UseTemplateStoryService => {
|
|||||||
setIsLoading(true);
|
setIsLoading(true);
|
||||||
|
|
||||||
const params: CreateMovieProjectV3Request = {
|
const params: CreateMovieProjectV3Request = {
|
||||||
script: selectedTemplate?.generateText || "",
|
script: selectedTemplate?.freeInputItem?.free_input_text || selectedTemplate?.generateText || "",
|
||||||
category: selectedTemplate?.category || "",
|
category: selectedTemplate?.category || "",
|
||||||
user_id,
|
user_id,
|
||||||
mode,
|
mode,
|
||||||
|
|||||||
@ -172,4 +172,13 @@ export interface StoryTemplateEntity {
|
|||||||
/** 道具照片URL */
|
/** 道具照片URL */
|
||||||
photo_url: string;
|
photo_url: string;
|
||||||
}[];
|
}[];
|
||||||
|
/** 自由输入文字 */
|
||||||
|
freeInputItem?: {
|
||||||
|
/** 用户提示,提示给用户需要输入什么内容 */
|
||||||
|
user_tips: string;
|
||||||
|
/** 约束,可选,用于传给ai,让ai去拦截用户不符合约束的输入内容 */
|
||||||
|
constraints: string;
|
||||||
|
/** 自由输入文字 */
|
||||||
|
free_input_text: string;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@ -46,6 +46,24 @@ import { HighlightEditor } from "../common/HighlightEditor";
|
|||||||
import GlobalLoad from "../common/GlobalLoad";
|
import GlobalLoad from "../common/GlobalLoad";
|
||||||
|
|
||||||
/**模板故事模式弹窗组件 */
|
/**模板故事模式弹窗组件 */
|
||||||
|
/**
|
||||||
|
* 防抖函数
|
||||||
|
* @param {Function} func - 需要防抖的函数
|
||||||
|
* @param {number} wait - 等待时间(ms)
|
||||||
|
* @returns {Function} - 防抖后的函数
|
||||||
|
*/
|
||||||
|
const debounce = (func: Function, wait: number) => {
|
||||||
|
let timeout: NodeJS.Timeout;
|
||||||
|
return function executedFunction(...args: any[]) {
|
||||||
|
const later = () => {
|
||||||
|
clearTimeout(timeout);
|
||||||
|
func(...args);
|
||||||
|
};
|
||||||
|
clearTimeout(timeout);
|
||||||
|
timeout = setTimeout(later, wait);
|
||||||
|
};
|
||||||
|
};
|
||||||
|
|
||||||
const RenderTemplateStoryMode = ({
|
const RenderTemplateStoryMode = ({
|
||||||
isTemplateCreating,
|
isTemplateCreating,
|
||||||
setIsTemplateCreating,
|
setIsTemplateCreating,
|
||||||
@ -93,6 +111,22 @@ const RenderTemplateStoryMode = ({
|
|||||||
clearData,
|
clearData,
|
||||||
} = useTemplateStoryServiceHook();
|
} = useTemplateStoryServiceHook();
|
||||||
|
|
||||||
|
// 防抖处理的输入更新函数
|
||||||
|
const debouncedUpdateInput = debounce((value: string) => {
|
||||||
|
// 过滤特殊字符
|
||||||
|
const sanitizedValue = value.replace(/[<>]/g, '');
|
||||||
|
// 更新输入值
|
||||||
|
if (!selectedTemplate?.freeInputItem) return;
|
||||||
|
const updatedTemplate: StoryTemplateEntity = {
|
||||||
|
...selectedTemplate,
|
||||||
|
freeInputItem: {
|
||||||
|
...selectedTemplate.freeInputItem,
|
||||||
|
free_input_text: sanitizedValue
|
||||||
|
}
|
||||||
|
};
|
||||||
|
setSelectedTemplate(updatedTemplate);
|
||||||
|
}, 300); // 300ms 的防抖延迟
|
||||||
|
|
||||||
// 使用上传文件hook
|
// 使用上传文件hook
|
||||||
const { uploadFile, isUploading } = useUploadFile();
|
const { uploadFile, isUploading } = useUploadFile();
|
||||||
// 本地加载状态,用于 UI 反馈
|
// 本地加载状态,用于 UI 反馈
|
||||||
@ -258,6 +292,7 @@ const RenderTemplateStoryMode = ({
|
|||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
{/* 角色配置区域 */}
|
{/* 角色配置区域 */}
|
||||||
{selectedTemplate?.storyRole &&
|
{selectedTemplate?.storyRole &&
|
||||||
selectedTemplate.storyRole.length > 0 && (
|
selectedTemplate.storyRole.length > 0 && (
|
||||||
@ -755,7 +790,38 @@ const RenderTemplateStoryMode = ({
|
|||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div> */}
|
</div> */}
|
||||||
<div className=" absolute -bottom-8 right-0">
|
<div className=" absolute -bottom-8 right-0 w-full flex items-center justify-end gap-2">
|
||||||
|
{/** 自由输入文字 */}
|
||||||
|
{(selectedTemplate?.freeInputItem) && (
|
||||||
|
<div className="py-2 flex-1">
|
||||||
|
<input
|
||||||
|
type="text"
|
||||||
|
value={selectedTemplate?.freeInputItem?.free_input_text}
|
||||||
|
placeholder="How is coffee made?"
|
||||||
|
className="w-full px-3 py-2 pr-16 bg-white/0 border border-white/10 rounded-lg text-white placeholder-gray-400 focus:outline-none focus:border-blue-500 focus:ring-1 focus:ring-blue-500/30 transition-all duration-200 text-sm"
|
||||||
|
onChange={(e) => {
|
||||||
|
const value = e.target.value;
|
||||||
|
// 限制输入长度为500字符
|
||||||
|
if (value.length > 500) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
// 立即更新UI显示
|
||||||
|
if (!selectedTemplate?.freeInputItem) return;
|
||||||
|
const updatedTemplate: StoryTemplateEntity = {
|
||||||
|
...selectedTemplate,
|
||||||
|
freeInputItem: {
|
||||||
|
...selectedTemplate.freeInputItem,
|
||||||
|
free_input_text: value
|
||||||
|
}
|
||||||
|
};
|
||||||
|
setSelectedTemplate(updatedTemplate);
|
||||||
|
// 使用防抖函数处理实际的状态更新
|
||||||
|
debouncedUpdateInput(value);
|
||||||
|
}}
|
||||||
|
maxLength={500}
|
||||||
|
/>
|
||||||
|
</div>
|
||||||
|
)}
|
||||||
<ActionButton
|
<ActionButton
|
||||||
isCreating={isTemplateCreating || localLoading > 0}
|
isCreating={isTemplateCreating || localLoading > 0}
|
||||||
handleCreateVideo={handleConfirm}
|
handleCreateVideo={handleConfirm}
|
||||||
|
|||||||
@ -427,6 +427,7 @@ export const MediaViewer = React.memo(function MediaViewer({
|
|||||||
|
|
||||||
// 渲染视频内容
|
// 渲染视频内容
|
||||||
const renderVideoContent = (onGotoCut: () => void) => {
|
const renderVideoContent = (onGotoCut: () => void) => {
|
||||||
|
if (!taskObject.videos.data[currentSketchIndex]) return null;
|
||||||
const urls = taskObject.videos.data[currentSketchIndex]?.urls ? taskObject.videos.data[currentSketchIndex]?.urls.join(',') : '';
|
const urls = taskObject.videos.data[currentSketchIndex]?.urls ? taskObject.videos.data[currentSketchIndex]?.urls.join(',') : '';
|
||||||
return (
|
return (
|
||||||
<div
|
<div
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user