All checks were successful
Build and Push Docker Image / build (push) Successful in 3m46s
174 lines
4.7 KiB
TypeScript
174 lines
4.7 KiB
TypeScript
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>
|
||
</>
|
||
);
|
||
}
|