zsqtony 70dda373a1
All checks were successful
Build and Push Docker Image / build (push) Successful in 3m46s
fix:限制上传内容大小
2025-10-11 13:32:20 +08:00

174 lines
4.7 KiB
TypeScript
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

import { MyProFormFieldProps } from '@/common';
import { Apis } from '@/gen/Apis';
import { PlusOutlined, UploadOutlined } from '@ant-design/icons';
import { Button, message, Modal, Upload, UploadFile, UploadProps } from 'antd';
import { RcFile } from 'antd/es/upload';
import axios from 'axios';
import { useSetState } from 'react-use';
import './MyUploadImages.scss';
type MyType = {
uploadType?: 'image' | 'video' | 'audio' | 'file';
max?: number;
size?: number;
} & UploadProps<any> &
MyProFormFieldProps<UploadFile[]>;
const getBase64 = (file: RcFile): Promise<string> =>
new Promise((resolve, reject) => {
const reader = new FileReader();
reader.readAsDataURL(file);
reader.onload = () => resolve(reader.result as string);
reader.onerror = (error) => reject(error);
});
export function MyUploadImages({
value,
onChange,
uploadType = 'image',
max = 1,
size = 10,
...rest
}: MyType) {
const [preview, setPreview] = useSetState<{
open: boolean;
image: string;
title: string;
}>({
open: false,
image: '',
title: '',
});
console.log('MyUploadImages');
const handleCancel = () => setPreview({ open: false });
const handlePreview = async (file: UploadFile) => {
if (!file.url && !file.preview) {
file.preview = await getBase64(file.originFileObj as RcFile);
}
setPreview({
open: true,
image: file.url || file.preview,
title: file.name || file.url!.substring(file.url!.lastIndexOf('/') + 1),
});
};
const handleChange: UploadProps['onChange'] = ({ fileList: newFileList }) => {
console.log('newFileList', newFileList);
const _newFileList: UploadFile<any>[] = newFileList.map((file) => {
if (!file.percent) return file;
return {
name: file.name,
status: file.status,
uid: file.uid,
url: file.response,
size: file.size ?? 0,
type: file.type ?? '',
};
});
onChange?.(_newFileList);
};
const uploadButton =
uploadType === 'image' ? (
<div>
<PlusOutlined />
</div>
) : (
<Button icon={<UploadOutlined />}></Button>
);
const customRequest = ({ file, onError, onProgress, onSuccess }: any) => {
Apis.Common.Auth.PreUpload({
filename: file.name,
alc: 'public-read',
})
.then(async (res) => {
try {
axios
.put(res.data.url, file, {
headers: res.data.headers,
onUploadProgress: ({ total, loaded }) => {
if (total)
onProgress(
{ percent: Math.round((loaded / total) * 100).toFixed(2) },
file,
);
},
})
.then(({ data: response }) => {
console.log('response', response);
if (response && response.errorMessage) {
onError(response, file);
} else {
// 确保URL正确处理
const fileUrl = res.data.url.split('?')[0];
console.log('文件上传成功URL:', fileUrl);
onSuccess(fileUrl, file);
}
})
.catch((error) => {
console.error('上传文件时出错:', error);
onError(error, file);
});
} catch (error) {
console.error('处理上传请求时出错:', error);
onError(error, file);
}
})
.catch((error) => {
console.error('获取预上传URL时出错:', error);
onError(error, file);
});
return {
abort() {
console.log('upload progress is aborted.');
},
};
};
const handleBeforeUpload = (file: any, fileList: any) => {
if (file?.size > 1024 * 1024 * size) {
message.error('文件大小不能超过10MB请选择重新上传');
return false;
}
console.log('beforeUpload', file, fileList);
};
return (
<>
<Upload
accept={
uploadType === 'image'
? 'image/*'
: uploadType === 'video'
? 'video/*'
: '*'
}
beforeUpload={handleBeforeUpload}
fileList={value}
listType={uploadType === 'image' ? 'picture-card' : 'text'}
onPreview={handlePreview}
onChange={handleChange}
customRequest={customRequest}
className="my-upload-images"
{...rest}
>
{!value?.length || (value && value.length < max) ? uploadButton : null}
</Upload>
<Modal
open={preview.open}
title={preview.title}
footer={null}
onCancel={handleCancel}
>
<img alt="preview" style={{ width: '100%' }} src={preview.image} />
</Modal>
</>
);
}