fix(前端): 文字修改+优化
parent
46263f8d0d
commit
b88b020c3b
|
@ -49,7 +49,7 @@ export default defineConfig({
|
|||
// changeOrigin: true,
|
||||
},
|
||||
'/api/files': {
|
||||
target: 'http://10.100.51.85:8112',
|
||||
target: 'http://10.100.51.85:8113',
|
||||
},
|
||||
},
|
||||
});
|
||||
|
|
|
@ -87,19 +87,19 @@ const MainLayout: React.FC = () => {
|
|||
collapsed={collapsed}
|
||||
className="main-sider"
|
||||
>
|
||||
<div className="logo">{!collapsed && <span>VDI管理平台</span>}</div>
|
||||
<div className="logo">{!collapsed && <span>Nex管理平台</span>}</div>
|
||||
<Menu
|
||||
theme="dark"
|
||||
mode="inline"
|
||||
selectedKeys={[selectedKey]}
|
||||
onClick={handleMenuClick}
|
||||
>
|
||||
<Menu.Item key="userList" icon={<AppstoreOutlined />}>
|
||||
用户
|
||||
</Menu.Item>
|
||||
<Menu.Item key="terminal" icon={<AppstoreOutlined />}>
|
||||
终端
|
||||
</Menu.Item>
|
||||
<Menu.Item key="userList" icon={<AppstoreOutlined />}>
|
||||
用户
|
||||
</Menu.Item>
|
||||
<Menu.Item key="images" icon={<AppstoreOutlined />}>
|
||||
镜像列表
|
||||
</Menu.Item>
|
||||
|
|
|
@ -76,37 +76,25 @@ const ImportModal: React.FC<IMAGES.ImportModalProps> = ({
|
|||
// 上传镜像时间相关
|
||||
const [elapsedTime, setElapsedTime] = useState<number>(0); // 上传时间
|
||||
const timerRef = useRef<NodeJS.Timeout | null>(null);
|
||||
|
||||
// const [uploadCompleted, _setUploadCompleted] = useState(false);
|
||||
// const uploadCompletedRef = useRef(false);
|
||||
|
||||
// const setUploadCompleted = (value: boolean) => {
|
||||
// uploadCompletedRef.current = value;
|
||||
// _setUploadCompleted(value);
|
||||
// };
|
||||
// 上传完成状态
|
||||
const uploadCompletedRef = useRef(false);
|
||||
// 手动取消状态
|
||||
const isManualCancel = useRef(false); // 是否手动取消上传
|
||||
|
||||
// 处理页面刷新/关闭
|
||||
// useEffect(() => {
|
||||
// const handleBeforeUnload = (e: BeforeUnloadEvent) => {
|
||||
// if (isUploading && !uploadCompletedRef.current) {
|
||||
// e.preventDefault();
|
||||
// e.returnValue = '镜像正在上传中,确定要离开吗?';
|
||||
useEffect(() => {
|
||||
const handleBeforeUnload = (e: BeforeUnloadEvent) => {
|
||||
if (isUploading && !uploadCompletedRef.current) {
|
||||
e.preventDefault();
|
||||
e.returnValue = '镜像正在上传中,确定要离开吗?';
|
||||
return e.returnValue;
|
||||
|
||||
// // 使用 sendBeacon 发送取消请求
|
||||
// const params = new URLSearchParams();
|
||||
// params.append('file_id', fileId.current);
|
||||
// const blob = new Blob([params.toString()], {
|
||||
// type: 'application/x-www-form-urlencoded',
|
||||
// });
|
||||
// navigator.sendBeacon('/api/cancel-upload', blob);
|
||||
}
|
||||
};
|
||||
|
||||
// return e.returnValue;
|
||||
// }
|
||||
// };
|
||||
|
||||
// window.addEventListener('beforeunload', handleBeforeUnload);
|
||||
// return () => window.removeEventListener('beforeunload', handleBeforeUnload);
|
||||
// }, [isUploading]);
|
||||
window.addEventListener('beforeunload', handleBeforeUnload);
|
||||
return () => window.removeEventListener('beforeunload', handleBeforeUnload);
|
||||
}, [isUploading]);
|
||||
|
||||
// 计时器清理(仅组件卸载时执行)
|
||||
useEffect(() => {
|
||||
|
@ -117,30 +105,14 @@ const ImportModal: React.FC<IMAGES.ImportModalProps> = ({
|
|||
};
|
||||
}, []);
|
||||
|
||||
// // 上传取消逻辑(依赖 isUploading 和 uploadCompletedRef)
|
||||
// useEffect(() => {
|
||||
// return () => {
|
||||
// if (isUploading && !uploadCompletedRef.current && fileId.current) {
|
||||
// const params = new URLSearchParams();
|
||||
// params.append('file_id', fileId.current);
|
||||
// cancelUploadImagesAPI(params).then((res) => {
|
||||
// if (res.code === CODE) {
|
||||
// message.success('上传已取消');
|
||||
// } else {
|
||||
// message.error('取消上传失败');
|
||||
// }
|
||||
// });
|
||||
// }
|
||||
// };
|
||||
// }, [isUploading]); // 保留原有依赖
|
||||
|
||||
// 添加重置状态函数
|
||||
const resetState = () => {
|
||||
// setUploadCompleted(false); // 重置上传完成状态
|
||||
setUploadProgress(0);
|
||||
setIsUploading(false);
|
||||
setUploadStatus(READY);
|
||||
setUploadMessage('');
|
||||
uploadCompletedRef.current = false; // 重置上传完成状态
|
||||
isManualCancel.current = false; // 重置手动取消状态
|
||||
completedChunks.current = 0;
|
||||
totalChunks.current = 0;
|
||||
fileId.current = '';
|
||||
|
@ -162,13 +134,6 @@ const ImportModal: React.FC<IMAGES.ImportModalProps> = ({
|
|||
}
|
||||
};
|
||||
|
||||
// 当弹窗关闭时重置状态
|
||||
useEffect(() => {
|
||||
if (!visible) {
|
||||
resetState();
|
||||
}
|
||||
}, [visible]);
|
||||
|
||||
// 4. 上传单个分片
|
||||
const uploadChunk = async (
|
||||
chunk: Blob,
|
||||
|
@ -206,8 +171,9 @@ const ImportModal: React.FC<IMAGES.ImportModalProps> = ({
|
|||
// 根据后端返回的状态进行判断
|
||||
if (response.success) {
|
||||
if (response.status === 'completed') {
|
||||
uploadCompletedRef.current = true; // 设置上传完成状态
|
||||
isManualCancel.current = false; // 重置手动取消状态
|
||||
// 文件上传完成,设置进度为100%
|
||||
// setUploadCompleted(true); // 标记上传完成
|
||||
setUploadProgress(100); // 这里已经正确设置了100%
|
||||
setIsUploading(false);
|
||||
setUploadStatus(SUCCESS);
|
||||
|
@ -297,8 +263,11 @@ const ImportModal: React.FC<IMAGES.ImportModalProps> = ({
|
|||
hasError = true; // 设置错误标记
|
||||
setIsUploading(false);
|
||||
setUploadStatus(ERROR);
|
||||
setUploadMessage(result.message || '文件上传失败,请重试');
|
||||
message.error(result.message ||'文件上传失败');
|
||||
// 只有当不是用户取消时才显示错误消息
|
||||
if (!isManualCancel.current) {
|
||||
setUploadMessage(result.message || '文件上传失败');
|
||||
message.error(result.message || '文件上传失败');
|
||||
}
|
||||
|
||||
// 中止其他正在进行的上传
|
||||
if (abortController.current) {
|
||||
|
@ -326,6 +295,8 @@ const ImportModal: React.FC<IMAGES.ImportModalProps> = ({
|
|||
// 2. 开始上传
|
||||
const startUpload = async (file: File) => {
|
||||
try {
|
||||
isManualCancel.current=false;
|
||||
uploadCompletedRef.current = false;
|
||||
setIsUploading(true);
|
||||
setUploadStatus(UPLOADING);
|
||||
setUploadMessage('正在准备上传...');
|
||||
|
@ -421,12 +392,17 @@ const ImportModal: React.FC<IMAGES.ImportModalProps> = ({
|
|||
|
||||
// 取消上传
|
||||
const cancelUpload = async () => {
|
||||
// 先更新 ref 再更新 state
|
||||
// uploadCompletedRef.current = true;
|
||||
// _setUploadCompleted(true);
|
||||
if (abortController.current) {
|
||||
abortController.current.abort();
|
||||
abortController.current = null;
|
||||
// 1. 立即标记状态
|
||||
isManualCancel.current = true;
|
||||
uploadCompletedRef.current = true; // 标记完成(阻止 beforeunload)
|
||||
|
||||
// 2. 清空上传队列(阻止新请求)
|
||||
uploadQueue.current = [];
|
||||
// 3. 中止所有进行中的请求
|
||||
const oldController = abortController.current;
|
||||
abortController.current = new AbortController(); // 新建控制器
|
||||
if (oldController) {
|
||||
oldController.abort(); // 中止旧请求
|
||||
}
|
||||
// 如果有正在上传的文件,调用后端取消上传API
|
||||
if (fileId.current) {
|
||||
|
@ -458,11 +434,10 @@ const ImportModal: React.FC<IMAGES.ImportModalProps> = ({
|
|||
<Alert
|
||||
message="重要提示"
|
||||
description={
|
||||
<div style={{ color: "rgb(237, 41, 31)" }}>
|
||||
<div>1. 文件上传后需要组装,需要时间,请耐心等待。</div>
|
||||
<div>
|
||||
2. 文件上传中请勿刷新或者离开页面,否则会导致文件上传失败。
|
||||
</div>
|
||||
<div style={{ color: 'rgb(237, 41, 31)' }}>
|
||||
<div>1. 上传过程中刷新或离开将导致上传中断。</div>
|
||||
<div>2. 大文件上传可能需要较长时间,建议保持网络稳定。</div>
|
||||
<div>3. 最后阶段需要校验文件完整性,请耐心等待。</div>
|
||||
</div>
|
||||
}
|
||||
type="warning"
|
||||
|
@ -530,31 +505,25 @@ const ImportModal: React.FC<IMAGES.ImportModalProps> = ({
|
|||
</div>
|
||||
);
|
||||
|
||||
const handleCancel = () => {
|
||||
if (isUploading) {
|
||||
cancelUpload().finally(() => {
|
||||
resetState(); // 确保取消完成后再重置
|
||||
onCancel();
|
||||
});
|
||||
} else {
|
||||
resetState();
|
||||
onCancel();
|
||||
}
|
||||
};
|
||||
|
||||
return (
|
||||
<Modal
|
||||
title="导入镜像"
|
||||
open={visible}
|
||||
onCancel={() => {
|
||||
if (isUploading) {
|
||||
cancelUpload();
|
||||
} else {
|
||||
// 如果不是上传状态,直接重置状态
|
||||
resetState();
|
||||
}
|
||||
onCancel();
|
||||
}}
|
||||
onCancel={handleCancel}
|
||||
footer={[
|
||||
<Button
|
||||
key="close"
|
||||
onClick={() => {
|
||||
if (isUploading) {
|
||||
cancelUpload();
|
||||
} else {
|
||||
resetState();
|
||||
}
|
||||
onCancel();
|
||||
}}
|
||||
>
|
||||
<Button key="close" onClick={handleCancel}>
|
||||
关闭
|
||||
</Button>,
|
||||
]}
|
||||
|
|
|
@ -195,7 +195,7 @@ const ImageList: React.FC = () => {
|
|||
key: 'bt_path',
|
||||
title: 'BT路径',
|
||||
dataIndex: 'bt_path',
|
||||
width: 250,
|
||||
width: 180,
|
||||
defaultVisible: true,
|
||||
ellipsis: true,
|
||||
render: (text: string) => text ? <Tooltip title={text} placement="topLeft">{text}</Tooltip>:'--'
|
||||
|
@ -224,7 +224,7 @@ const ImageList: React.FC = () => {
|
|||
key: 'image_status',
|
||||
title: '镜像状态',
|
||||
dataIndex: 'image_status',
|
||||
width: 80,
|
||||
width: 90,
|
||||
render: (text: number) => (text ? getStatusTag(text) : '--'),
|
||||
defaultVisible: true,
|
||||
},
|
||||
|
@ -232,7 +232,7 @@ const ImageList: React.FC = () => {
|
|||
key: 'create_time',
|
||||
title: '创建时间',
|
||||
dataIndex: 'create_time',
|
||||
width: 180,
|
||||
width: 160,
|
||||
render: (text: string) =>
|
||||
text ? (
|
||||
<Tooltip title={dayjs(text).format('YYYY-MM-DD HH:mm:ss')}>
|
||||
|
@ -247,7 +247,7 @@ const ImageList: React.FC = () => {
|
|||
{
|
||||
key: 'action',
|
||||
title: '操作',
|
||||
width: 100,
|
||||
width: 90,
|
||||
fixed: 'right' as 'right',
|
||||
render: (_: any, record: IMAGES.ImageItem) => (
|
||||
<Space size="small">
|
||||
|
|
|
@ -42,7 +42,7 @@ const LoginPage: React.FC = () => {
|
|||
<SafetyCertificateOutlined className="logo-icon" />
|
||||
<h1 className="brand-title">紫光汇智</h1>
|
||||
</div>
|
||||
<div className="brand-subtitle">VDI 虚拟桌面管理平台</div>
|
||||
<div className="brand-subtitle">Nex管理平台</div>
|
||||
<div className="brand-description">
|
||||
<p>专业的虚拟桌面基础设施解决方案</p>
|
||||
<p>提供安全、高效、灵活的桌面云服务</p>
|
||||
|
@ -69,7 +69,7 @@ const LoginPage: React.FC = () => {
|
|||
<div className="login-form-container">
|
||||
<div className="login-header">
|
||||
<h2 className="login-title">系统登录</h2>
|
||||
<p className="login-subtitle">欢迎使用VDI管理平台</p>
|
||||
<p className="login-subtitle">欢迎使用Nex管理平台</p>
|
||||
</div>
|
||||
|
||||
<Form
|
||||
|
|
Loading…
Reference in New Issue