世界上最伟大的投资就是投资自己的教育

首页Ant Design Pro
随风 · 练气

【图文并茂】ant design pro 如何使用 Upload.Dragger 对接阿里云 oss 上传组件(包含后端)

随风发布于704 次阅读


在后台系统中,经常要上传图片吧

我这里用的是 阿里云 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 },
  });
});

本站文章均为原创内容,如需转载请注明出处,谢谢。

0 条回复
暂无回复~~
喜欢
统计信息
    学员: 29980
    视频数量: 1996
    文章数量: 526

© 汕尾市求知科技有限公司 | Rails365 Gitlab | 知乎 | b 站 | csdn

粤公网安备 44152102000088号粤公网安备 44152102000088号 | 粤ICP备19038915号

Top