前后端七牛集成打通

puxiaoshuai 2024-6-25 174 6/25

前后端七牛集成打通

项目背景

图片或者文件的上传在项目中很常用,我想白嫖。七牛云作为中国领先的云服务提供商之一,其OSS服务以其高性能、高可靠性和易用性而受到广泛欢迎。他们的服务可以帮助个人和企业存储、管理和传输数据,同时提供高速、可靠的内容分发服务。七牛云还提供了丰富的开发者工具和API,方便开发者构建基于云端的应用程序和服务。

1.为什么选择七牛云

https://blog.csdn.net/m0_53127626/article/details/136040982

假设你注册好了账号,以及在空间上传了一个图片或者文件,下一步

2.自定义 CDN 加速域名

前后端七牛集成打通

为空间绑定自定义 CDN 加速域名,通过 CDN 边缘节点缓存数据,提高存储空间内的文件访问响应速度。

具体操作步骤:  https://developer.qiniu.com/fusion/kb/1322/how-to-configure-cname-domain-name

服务端集成

npm install qiniu

服务端代码

import { Injectable } from '@nestjs/common';
import { ConfigService } from '@nestjs/config';
import * as qiniu from 'qiniu';
@Injectable()
export class QiniuService {
  constructor(private configService: ConfigService) {}

  async createQiNiuToken() {
    const accessKey = this.configService.get('QINIU_ACCESS_KEY'); //该key的定义在 .env文件中
    const secretKey = this.configService.get('QINIU_SECRET_KEY');
    const bucket = this.configService.get('QINIU_BUCKET');
    const options = {
      scope: bucket,
      expires: 7200, // 2h
    };
    const mac = new qiniu.auth.digest.Mac(accessKey, secretKey);
    const putPolicy = new qiniu.rs.PutPolicy(options);
    const uploadToken = putPolicy.uploadToken(mac);
    return {
      data: uploadToken,
    };
  }
}

客户端集成

npm i qiniu-js

客户端代码

使用 umi.js

1.定义接口情况

export async function getQiniuToken() {
  return request<BaseResponse<any>>('/api/xxxxx', {
    method: 'GET',
    headers: {
      'Content-Type': 'application/x-www-form-urlencoded',
    },
  });
}

2.图片上传组件

import { ProFormUploadButton } from '@ant-design/pro-components';
import { useModel } from '@umijs/max';
import { message } from 'antd';
import * as qiniu from 'qiniu-js';
import React, { useEffect, useState } from 'react';
import { DOMAIN } from '../../utils/constants';

interface Iprops {
  token: string;
  callback: (url: string) => void;
  currentFile?: { status: string; url: string };
}
interface IFile {
  file: any;
  fileList: [];
}

const UploadToQiniu: React.FC<Iprops> = (props) => {
  const [fileList, setFileList] = useState([]);
  const [isCanUpdate, setIsCanUpdate] = useState(false);
  useEffect(() => {
    if (props.currentFile?.url) {
      setFileList([props.currentFile]);
    }
  }, []);

  const { refreshToken } = useModel('qiniuModel');
  const handleUpload = (file: IFile) => {
    setFileList(file.fileList);
    if(!isCanUpdate) {
      setFileList([])
    }
    if (file.fileList.length === 0) {
      return;
    }
    if (file.file.status !== 'done') {
      return;
    }
    const fileName = file.file.name;
    //wiki https://developer.qiniu.com/kodo/1283/javascript#usage
    const putExtra = {
      fname: '',
      params: {},
      // mimeType: ['image/png', 'image/jpeg', 'image/gif',"application/pdf"],
    };
    const config = {
      useCdnDomain: true,
      region: qiniu.region.z2, //华南
    };
    const key = `${Date.now()}-${fileName}`;
    const observable = qiniu.upload(
      file.file.originFileObj,
      key,
      props.token,
      putExtra,
      config,
    );
    const observer = {
      next(res: any) {},
      error(err: any) {
        setFileList([]);
        message.error('图片上传凭证已失效,请重新图片上传');
        refreshToken();
      },
      complete(res: any) {
        props.callback(DOMAIN + res.key);
      },
    };
    observable.subscribe(observer);
  };
  //为什么没触发 https://github.com/ant-design/pro-components/issues/2903
  const beforeUpload = (file: any) => {
    setIsCanUpdate(false);
    const isAllowType = file.type.includes("image") || file.type === 'application/pdf' ;
    if (!isAllowType) {
      message.error('只允许上传图片和pdf文件');
    }
    const isLt10M = file.size / 1024 / 1024 < 5;
    if (!isLt10M) {
      message.error('文件最大允许5M');
    }
    const isAllow =  isAllowType && isLt10M;
    isAllow && setIsCanUpdate(true);
    return isAllow
  };
  //wiki https://procomponents.ant.design/components/field-set#proformtext-demo-upload
  return (
    <ProFormUploadButton
      accept="image/jpeg,image/jpg,image/png,.pdf"
      onChange={handleUpload}
      fileList={fileList}
      listType="text"
      {...props}
      fieldProps={{
        beforeUpload:(file:any) => beforeUpload(file)
      }}
      
    />
  );
};

export default UploadToQiniu;

3.使用

<UploadToQiniu
    width="md"
    name="contract_pic"
    label="附件"
    max={1}
    token={qiNiuToken}
    callback={hanleQiniuhash}
/>

如上就是七牛上传图片的基本使用

- THE END -
Tag:

puxiaoshuai

6月25日15:04

最后修改:2024年6月25日
0

非特殊说明,本博所有文章均为博主原创。