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);
|
||||
|
||||
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);
|
||||
setSelectedTemplate(templates[0]);
|
||||
@ -237,7 +246,7 @@ export const useTemplateStoryServiceHook = (): UseTemplateStoryService => {
|
||||
setIsLoading(true);
|
||||
|
||||
const params: CreateMovieProjectV3Request = {
|
||||
script: selectedTemplate?.generateText || "",
|
||||
script: selectedTemplate?.freeInputItem?.free_input_text || selectedTemplate?.generateText || "",
|
||||
category: selectedTemplate?.category || "",
|
||||
user_id,
|
||||
mode,
|
||||
|
||||
@ -172,4 +172,13 @@ export interface StoryTemplateEntity {
|
||||
/** 道具照片URL */
|
||||
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";
|
||||
|
||||
/**模板故事模式弹窗组件 */
|
||||
/**
|
||||
* 防抖函数
|
||||
* @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 = ({
|
||||
isTemplateCreating,
|
||||
setIsTemplateCreating,
|
||||
@ -93,6 +111,22 @@ const RenderTemplateStoryMode = ({
|
||||
clearData,
|
||||
} = 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
|
||||
const { uploadFile, isUploading } = useUploadFile();
|
||||
// 本地加载状态,用于 UI 反馈
|
||||
@ -258,6 +292,7 @@ const RenderTemplateStoryMode = ({
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
{/* 角色配置区域 */}
|
||||
{selectedTemplate?.storyRole &&
|
||||
selectedTemplate.storyRole.length > 0 && (
|
||||
@ -755,7 +790,38 @@ const RenderTemplateStoryMode = ({
|
||||
</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
|
||||
isCreating={isTemplateCreating || localLoading > 0}
|
||||
handleCreateVideo={handleConfirm}
|
||||
|
||||
@ -427,6 +427,7 @@ export const MediaViewer = React.memo(function MediaViewer({
|
||||
|
||||
// 渲染视频内容
|
||||
const renderVideoContent = (onGotoCut: () => void) => {
|
||||
if (!taskObject.videos.data[currentSketchIndex]) return null;
|
||||
const urls = taskObject.videos.data[currentSketchIndex]?.urls ? taskObject.videos.data[currentSketchIndex]?.urls.join(',') : '';
|
||||
return (
|
||||
<div
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user