2025-11-26 14:56:13 +08:00
|
|
|
|
import React from 'react';
|
2025-11-27 17:29:23 +08:00
|
|
|
|
import { Modal, Spin, Button } from 'antd';
|
|
|
|
|
|
import { LoadingOutlined, StopOutlined } from '@ant-design/icons';
|
2025-11-26 14:56:13 +08:00
|
|
|
|
|
|
|
|
|
|
interface SSEProgressModalProps {
|
|
|
|
|
|
visible: boolean;
|
|
|
|
|
|
progress: number;
|
|
|
|
|
|
message: string;
|
|
|
|
|
|
title?: string;
|
|
|
|
|
|
showPercentage?: boolean;
|
|
|
|
|
|
showIcon?: boolean;
|
2025-11-27 17:29:23 +08:00
|
|
|
|
onCancel?: () => void;
|
|
|
|
|
|
cancelButtonText?: string;
|
2025-11-26 14:56:13 +08:00
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
/**
|
|
|
|
|
|
* 统一的SSE进度显示Modal组件
|
|
|
|
|
|
* 用于在Modal中显示AI生成进度,样式与SSELoadingOverlay保持一致
|
|
|
|
|
|
*/
|
|
|
|
|
|
export const SSEProgressModal: React.FC<SSEProgressModalProps> = ({
|
|
|
|
|
|
visible,
|
|
|
|
|
|
progress,
|
|
|
|
|
|
message,
|
|
|
|
|
|
title = 'AI生成中...',
|
|
|
|
|
|
showPercentage = true,
|
|
|
|
|
|
showIcon = true,
|
2025-11-27 17:29:23 +08:00
|
|
|
|
onCancel,
|
|
|
|
|
|
cancelButtonText = '取消任务',
|
2025-11-26 14:56:13 +08:00
|
|
|
|
}) => {
|
|
|
|
|
|
if (!visible) return null;
|
|
|
|
|
|
|
|
|
|
|
|
return (
|
|
|
|
|
|
<Modal
|
|
|
|
|
|
title={null}
|
|
|
|
|
|
open={visible}
|
|
|
|
|
|
footer={null}
|
|
|
|
|
|
closable={false}
|
|
|
|
|
|
centered
|
|
|
|
|
|
width={500}
|
|
|
|
|
|
maskClosable={false}
|
|
|
|
|
|
keyboard={false}
|
|
|
|
|
|
styles={{
|
|
|
|
|
|
body: {
|
|
|
|
|
|
padding: '40px 40px 32px',
|
|
|
|
|
|
}
|
|
|
|
|
|
}}
|
|
|
|
|
|
>
|
|
|
|
|
|
<div>
|
|
|
|
|
|
{/* 标题和图标 */}
|
|
|
|
|
|
{showIcon && (
|
|
|
|
|
|
<div style={{
|
|
|
|
|
|
textAlign: 'center',
|
|
|
|
|
|
marginBottom: 24
|
|
|
|
|
|
}}>
|
|
|
|
|
|
<Spin
|
|
|
|
|
|
indicator={<LoadingOutlined style={{ fontSize: 48, color: '#1890ff' }} spin />}
|
|
|
|
|
|
/>
|
|
|
|
|
|
<div style={{
|
|
|
|
|
|
fontSize: 20,
|
|
|
|
|
|
fontWeight: 'bold',
|
|
|
|
|
|
marginTop: 16,
|
|
|
|
|
|
color: '#262626'
|
|
|
|
|
|
}}>
|
|
|
|
|
|
{title}
|
|
|
|
|
|
</div>
|
|
|
|
|
|
</div>
|
|
|
|
|
|
)}
|
|
|
|
|
|
|
|
|
|
|
|
{/* 进度条 */}
|
|
|
|
|
|
<div style={{
|
|
|
|
|
|
marginBottom: showPercentage ? 16 : 24
|
|
|
|
|
|
}}>
|
|
|
|
|
|
<div style={{
|
|
|
|
|
|
height: 12,
|
|
|
|
|
|
background: '#f0f0f0',
|
|
|
|
|
|
borderRadius: 6,
|
|
|
|
|
|
overflow: 'hidden',
|
|
|
|
|
|
marginBottom: showPercentage ? 12 : 0
|
|
|
|
|
|
}}>
|
|
|
|
|
|
<div style={{
|
|
|
|
|
|
height: '100%',
|
|
|
|
|
|
background: progress === 100
|
|
|
|
|
|
? 'linear-gradient(90deg, #52c41a 0%, #73d13d 100%)'
|
|
|
|
|
|
: 'linear-gradient(90deg, #1890ff 0%, #40a9ff 100%)',
|
|
|
|
|
|
width: `${progress}%`,
|
|
|
|
|
|
transition: 'all 0.3s ease',
|
|
|
|
|
|
borderRadius: 6,
|
|
|
|
|
|
boxShadow: progress > 0 ? '0 0 10px rgba(24, 144, 255, 0.3)' : 'none'
|
|
|
|
|
|
}} />
|
|
|
|
|
|
</div>
|
|
|
|
|
|
|
|
|
|
|
|
{/* 进度百分比 */}
|
|
|
|
|
|
{showPercentage && (
|
|
|
|
|
|
<div style={{
|
|
|
|
|
|
textAlign: 'center',
|
|
|
|
|
|
fontSize: 32,
|
|
|
|
|
|
fontWeight: 'bold',
|
|
|
|
|
|
color: progress === 100 ? '#52c41a' : '#1890ff',
|
|
|
|
|
|
marginBottom: 8
|
|
|
|
|
|
}}>
|
|
|
|
|
|
{progress}%
|
|
|
|
|
|
</div>
|
|
|
|
|
|
)}
|
|
|
|
|
|
</div>
|
|
|
|
|
|
|
|
|
|
|
|
{/* 状态消息 */}
|
|
|
|
|
|
<div style={{
|
|
|
|
|
|
textAlign: 'center',
|
|
|
|
|
|
fontSize: 16,
|
|
|
|
|
|
color: '#595959',
|
|
|
|
|
|
minHeight: 24,
|
|
|
|
|
|
padding: '0 20px',
|
|
|
|
|
|
marginBottom: 16
|
|
|
|
|
|
}}>
|
|
|
|
|
|
{message || '准备生成...'}
|
|
|
|
|
|
</div>
|
|
|
|
|
|
|
|
|
|
|
|
{/* 提示文字 */}
|
|
|
|
|
|
<div style={{
|
|
|
|
|
|
textAlign: 'center',
|
|
|
|
|
|
fontSize: 13,
|
2025-11-27 17:29:23 +08:00
|
|
|
|
color: '#8c8c8c',
|
|
|
|
|
|
marginBottom: onCancel ? 16 : 0
|
2025-11-26 14:56:13 +08:00
|
|
|
|
}}>
|
|
|
|
|
|
请勿关闭页面,生成过程需要一定时间
|
|
|
|
|
|
</div>
|
2025-11-27 17:29:23 +08:00
|
|
|
|
|
|
|
|
|
|
{/* 取消按钮 */}
|
|
|
|
|
|
{onCancel && (
|
|
|
|
|
|
<div style={{
|
|
|
|
|
|
textAlign: 'center',
|
|
|
|
|
|
marginTop: 16
|
|
|
|
|
|
}}>
|
|
|
|
|
|
<Button
|
|
|
|
|
|
danger
|
|
|
|
|
|
size="large"
|
|
|
|
|
|
icon={<StopOutlined />}
|
|
|
|
|
|
onClick={onCancel}
|
|
|
|
|
|
>
|
|
|
|
|
|
{cancelButtonText}
|
|
|
|
|
|
</Button>
|
|
|
|
|
|
</div>
|
|
|
|
|
|
)}
|
2025-11-26 14:56:13 +08:00
|
|
|
|
</div>
|
|
|
|
|
|
</Modal>
|
|
|
|
|
|
);
|
|
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
|
|
export default SSEProgressModal;
|