在后台系统中,经常要上传图片吧
我这里用的是 阿里云 oss
因为还是很便宜的。
想要用的,去阿里云注册 个账号开通就行,充个几毛钱,够用你好久的
前端
import React from 'react';
import { Upload, message } from 'antd';
import { InboxOutlined } from '@ant-design/icons';
import { request } from '@umijs/max';
import { UploadProps } from 'antd/lib/upload/interface';
import { useIntl } from '@umijs/max';
interface MyUploadProps {
onFileUpload: (url: string) => void;
accept?: string; // 使accept属性可选
defaultFileList?: any;
multiple?: boolean;
}
const MyUpload: React.FC<MyUploadProps> = ({ onFileUpload, accept, defaultFileList, multiple }) => {
const intl = useIntl();
// 定义默认的accept值
const defaultAccept = '.png,.jpeg,.jpg,.gif';
const customRequest = async (options: any) => {
const { onSuccess, onError } = options;
const formData = new FormData();
if (Array.isArray(options.file)) {
options.file.forEach((file: any) => {
formData.append('file', file);
});
} else {
formData.append('file', options.file);
}
try {
const response = await request<{ success: boolean; data: any }>('/upload', {
method: 'POST',
data: formData,
requestType: 'form',
});
console.log('response:', response);
if (response.success) {
message.success('上传成功');
if (onSuccess) {
onSuccess(response);
}
const httpUrl = response.data.signedURL; // 假设返回的signedURL就在data字段中
onFileUpload(httpUrl);
} else {
message.error('上传失败');
if (onError) {
onError(new Error('上传失败'));
}
}
} catch (error) {
message.error('上传异常');
if (onError) {
onError(new Error('上传异常'));
}
}
};
const props: UploadProps = {
name: 'file',
multiple: multiple,
customRequest,
showUploadList: true,
onChange(info) {
if (info.file.status !== 'uploading') {
console.log(info.file, info.fileList);
}
if (info.file.status === 'done') {
message.success(`${info.file.name} 文件上传成功`);
} else if (info.file.status === 'error') {
message.error(`${info.file.name} 文件上传失败`);
}
},
};
return (
<Upload.Dragger
{...props}
listType="picture"
showUploadList={{ showRemoveIcon: true }}
multiple={multiple}
accept={accept || defaultAccept}
maxCount={multiple ? undefined : 1}
defaultFileList={defaultFileList}
style={{ width: 328 }}
>
<p className="ant-upload-drag-icon">
<InboxOutlined />
</p>
<p className="ant-upload-text">{intl.formatMessage({ id: 'upload.text' })}</p>
<p className="ant-upload-hint">{intl.formatMessage({ id: 'upload.hint' })}</p>
</Upload.Dragger>
);
};
export default MyUpload;
组件我都封装好了,后面可以直接用。
比如
<ProForm.Item required label={intl.formatMessage({ id: 'platform.image' })} name="image">
<MyUpload
accept="image/*"
onFileUpload={(data: any) => {
console.log('Uploaded resource URL:', data);
setImageUrl(data); // Assuming 'data' is an array of objects with a 'title' property
}}
defaultFileList={defaultFileList}
/>
</ProForm.Item>
后端
export const uploadFileToOSS = handleAsync(async (req: CustomRequest, res: Response) => {
const file = req.file;
if (!file) {
res.status(400);
throw new Error('No file provided');
}
const filePath = file.path; // This now points to the /tmp directory
const ossPath = `taskOssUploads/${file.filename}`;
// Read the file from /tmp directory
const fileContent = fs.readFileSync(filePath);
// Upload the file content to OSS
await ossClient.put(ossPath, fileContent);
// Optionally, delete the file from /tmp directory after uploading
fs.unlinkSync(filePath);
// Generate a signed URL with read permission (valid for 1 hour)
const signedURL = await generateSignedUrlForOSS(ossPath);
res.json({
success: true,
data: { signedURL, file: ossPath },
});
});
路由地址是这样的:
app.post('/api/upload', handleFileUpload, uploadFileToOSS);
export const uploadFileToS3 = handleAsync(async (req: CustomRequest, res: Response) => {
const file = req.file;
if (!file) {
res.status(400);
throw new Error('No file provided');
}
const bucketName = process.env.AWS_BUCKET_NAME;
const key = `taskS3Uploads/${file.filename}`;
const fileContent = fs.readFileSync(file.path);
// Upload parameters for S3
const params = {
Bucket: bucketName,
Key: key,
Body: fileContent,
ContentType: file.mimetype,
};
// Upload file to S3
await s3.upload(params).promise();
// Use the utility function to generate a signed URL
const signedURL = await generateSignedUrlForS3(key);
// Optionally, remove the file from temporary storage
fs.unlinkSync(file.path);
// Respond with the signed URL
res.json({
success: true,
message: 'File uploaded successfully',
data: { signedURL, file: key },
});
});