Your Name 9a2e1afe56
All checks were successful
Build and Push Docker Image / build (push) Successful in 5m10s
feat:初始化
2026-01-08 16:35:06 +08:00

176 lines
4.8 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;
accept?: string;
} & 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,
accept = '*',
...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/*'
: accept
}
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>
</>
);
}