推进,样式更新完成

This commit is contained in:
海龙 2025-08-26 15:52:08 +08:00
parent 5fe8c76efa
commit 0133cc0798

View File

@ -83,6 +83,8 @@ const RenderTemplateStoryMode = ({
const { uploadFile, isUploading } = useUploadFile(); const { uploadFile, isUploading } = useUploadFile();
// 本地加载状态,用于 UI 反馈 // 本地加载状态,用于 UI 反馈
const [localLoading, setLocalLoading] = useState(0); const [localLoading, setLocalLoading] = useState(0);
// 控制输入框显示状态
const [inputVisible, setInputVisible] = useState<{ [key: string]: boolean }>({});
const router = useRouter(); const router = useRouter();
// 组件挂载时获取模板列表 // 组件挂载时获取模板列表
useEffect(() => { useEffect(() => {
@ -91,6 +93,23 @@ const RenderTemplateStoryMode = ({
} }
}, [isOpen, getTemplateStoryList]); }, [isOpen, getTemplateStoryList]);
// 监听点击外部区域关闭输入框
useEffect(() => {
const handleClickOutside = (event: MouseEvent) => {
const target = event.target as Element;
// 检查是否点击了输入框相关的元素
if (!target.closest('.ant-tooltip') && !target.closest('[data-alt*="field-ai-button"]')) {
// 关闭所有打开的输入框
setInputVisible({});
}
};
document.addEventListener('mousedown', handleClickOutside);
return () => {
document.removeEventListener('mousedown', handleClickOutside);
};
}, []);
// 处理模板选择 // 处理模板选择
const handleTemplateSelect = (template: StoryTemplateEntity) => { const handleTemplateSelect = (template: StoryTemplateEntity) => {
setSelectedTemplate(template); setSelectedTemplate(template);
@ -251,13 +270,13 @@ const RenderTemplateStoryMode = ({
{/* AI生成按钮 */} {/* AI生成按钮 */}
<ActionButton <ActionButton
isCreating={false} isCreating={false}
handleCreateVideo={() => handleCreateVideo={() => {
handleFieldBlur( handleFieldBlur(
field.field_name, field.field_name,
field.value || "" field.value || ""
) );
} setInputVisible(prev => ({ ...prev, [field.field_name]: false }));
}}
icon={<Sparkles className="w-4 h-4" />} icon={<Sparkles className="w-4 h-4" />}
width="w-8" width="w-8"
height="h-8" height="h-8"
@ -269,7 +288,9 @@ const RenderTemplateStoryMode = ({
classNames={{ classNames={{
root: "max-w-none", root: "max-w-none",
}} }}
trigger="focus" open={inputVisible[field.field_name]}
onOpenChange={(visible) => setInputVisible(prev => ({ ...prev, [field.field_name]: visible }))}
trigger="contextMenu"
styles={{ root: { zIndex: 1000 } }} styles={{ root: { zIndex: 1000 } }}
> >
{/* 图片 */} {/* 图片 */}
@ -301,52 +322,66 @@ const RenderTemplateStoryMode = ({
</span> </span>
</div> </div>
{/* 上传按钮 - 右上角 */} {/* 按钮组 - 右上角 */}
<Upload <div className="absolute -top-8 left-[1.2rem] flex gap-3 opacity-0 group-hover:opacity-100 transition-all duration-200">
name="fieldImage" {/* AI生成按钮 */}
showUploadList={false} <Tooltip title="AI generate image" placement="top">
beforeUpload={(file) => {
const isImage = file.type.startsWith("image/");
if (!isImage) {
console.error("只能上传图片文件");
return false;
}
const isLt5M = file.size / 1024 / 1024 < 5;
if (!isLt5M) {
console.error("图片大小不能超过5MB");
return false;
}
return true;
}}
customRequest={async ({ file, onSuccess, onError }) => {
try {
const fileObj = file as File;
const uploadedUrl = await uploadFile(
fileObj,
(progress) => {
console.log(`上传进度: ${progress}%`);
}
);
await AvatarAndAnalyzeFeatures(
uploadedUrl,
field.field_name
);
onSuccess?.(uploadedUrl);
} catch (error) {
console.error("字段图片上传失败:", error);
onError?.(error as Error);
}
}}
>
<Tooltip title="upload your image" placement="top">
<button <button
data-alt={`field-upload-button-${index}`} data-alt={`field-ai-button-${index}`}
className="absolute -top-1 -right-1 w-6 h-6 bg-blue-500 hover:bg-blue-600 text-white rounded-full flex items-center justify-center transition-all duration-200 opacity-0 group-hover:opacity-100 hover:scale-110 shadow-lg" onClick={() => setInputVisible(prev => ({ ...prev, [field.field_name]: !prev[field.field_name] }))}
className="w-6 h-6 bg-purple-500 hover:bg-purple-600 text-white rounded-full flex items-center justify-center transition-all duration-200 hover:scale-110 shadow-lg"
> >
<UploadOutlined className="w-3.5 h-3.5" /> <Sparkles className="w-3.5 h-3.5" />
</button> </button>
</Tooltip> </Tooltip>
</Upload>
{/* 上传按钮 */}
<Upload
name="fieldImage"
showUploadList={false}
beforeUpload={(file) => {
const isImage = file.type.startsWith("image/");
if (!isImage) {
console.error("只能上传图片文件");
return false;
}
const isLt5M = file.size / 1024 / 1024 < 5;
if (!isLt5M) {
console.error("图片大小不能超过5MB");
return false;
}
return true;
}}
customRequest={async ({ file, onSuccess, onError }) => {
try {
const fileObj = file as File;
const uploadedUrl = await uploadFile(
fileObj,
(progress) => {
console.log(`上传进度: ${progress}%`);
}
);
await AvatarAndAnalyzeFeatures(
uploadedUrl,
field.field_name
);
onSuccess?.(uploadedUrl);
} catch (error) {
console.error("字段图片上传失败:", error);
onError?.(error as Error);
}
}}
>
<Tooltip title="upload your image" placement="top">
<button
data-alt={`field-upload-button-${index}`}
className="w-6 h-6 bg-blue-500 hover:bg-blue-600 text-white rounded-full flex items-center justify-center transition-all duration-200 hover:scale-110 shadow-lg"
>
<UploadOutlined className="w-3.5 h-3.5" />
</button>
</Tooltip>
</Upload>
</div>
</div> </div>
</div> </div>
))} ))}