zoukankan      html  css  js  c++  java
  • 整个组件功能代码-->图片压缩上传&&axios封装

    // 项目中上传图片组件 and其它功能
    import React, { useState, useRef } from 'react';
    import { QrcodeOutlined } from '@ant-design/icons';
    import '@ant-design/compatible/assets/index.css';
    import { Modal, Button, message } from 'antd';
    import { useObserver } from 'mobx-react';
    import { useHistory, useLocation } from 'react-router-dom';
    // eslint-disable-next-line @typescript-eslint/ban-ts-ignore
    // @ts-ignore
    import QRCode from 'qrcode';
    import ajax from '@/lib/axios';
    import { Wrapper, SuccessWrapper, UploadImgWrapper } from './link-qrcode-style';
    
    interface IProps {
      merchantId: string;
      branchName: string;
      merchantName: string;
      personInCharge: string;
    }
    
    const LinkQrCode = (props: IProps) => {
      const [showConfirmModal, setShowConfirmModal] = useState<boolean>(false);
      const [showSuccessModal, setShowSuccessModal] = useState<boolean>(false);
      const [showUploadModal, setShowUploadModal] = useState<boolean>(false);
      const [uploadButtonLoading, setUploadButtonLoading] = useState<boolean>(false);
      const [confirmButtonLoading, setConfirmButtonLoading] = useState<boolean>(false);
      const [qrCodeUrl, setQrCodeUrl] = useState<string>('');
      const [qrDecode, setQrDecode] = useState<string>('');
      const [uploadImgUrl, setUploadImgUrl] = useState<string>('');
      const [canvasToBlob, setCanvasToBlob] = useState<any>({});
      const history = useHistory();
      const location = useLocation();
      const fileInputRef = useRef<HTMLInputElement>(null);
      // const ua = navigator.userAgent.toLowerCase();
      // const isIos = ua.indexOf('iphone') !== -1 || ua.indexOf('ipad') !== -1;
    
      const uploadFileValidate = async () => {
        try {
          const makeBoundary = function() {
            return '----JQBoundary' + btoa(Math.random().toString()).substr(0, 12);
          };
          const boundary = makeBoundary();
          const formData = new FormData();
        
    // 这里需要注意,formdata.append()括号里参数的名称是根据后端定的,不是固定的.
    后端需要什么字端,就append什么字段,如果需要多个字段,就写多个append()
          formData.append('qrcodeImage', canvasToBlob);
          const {
            data: { data },
          } = await ajax.post('/qrcode/validate', formData, {
         
    // 请求后端上传接口的方法中,参数直接是上面封装的formdata即可,不需要其它。
    // 另外请求默认的content-type是application/json,上传文件接口这里需要自己定义content-type:multipart/form-data。
    定义了content-type之后需要手动添加boundary,否则会报错。
            headers: { 'Content-Type': `multipart/form-data; boundary=${boundary}` },
          });
          setUploadButtonLoading(false);
          setShowUploadModal(false);
          if (data) {
            setQrDecode(data);
            setShowConfirmModal(true);
          } else {
            Modal.error({
              content: "Sorry, we can't process this picture, please make sure you use a clear picture of valid QR code.",
              onOk() {
                const to = `${location.pathname}${location.search}`;
                history.push(to);
              },
            });
          }
        } catch (e) {
          message.error(e.message);
        }
      };
    
      const qrCodeUploadedHandler = (imageFile: object, fileImageUrl: string) => {
        const canvas = document.createElement('canvas');
        const context = canvas.getContext('2d') as any;
        const img = new Image();
        img.src = fileImageUrl;
        img.onload = () => {
          const originWidth = img.width;
          const originHeight = img.height;
          const maxWidth = 1280;
          const maxHeight = 768;
          let targetWidth = originWidth;
          let targetHeight = originHeight;
          if (originWidth > maxWidth || originHeight > maxHeight) {
            if (originWidth / originHeight > maxWidth / maxHeight) {
              // 更宽,按照宽度限定尺寸
              targetWidth = maxWidth;
              targetHeight = Math.round(maxWidth * (originHeight / originWidth));
            } else {
              targetHeight = maxHeight;
              targetWidth = Math.round(maxHeight * (originWidth / originHeight));
            }
          }
          // canvas对图片进行缩放
          canvas.width = targetWidth;
          canvas.height = targetHeight;
          // 清除画布
          context.clearRect(0, 0, targetWidth, targetHeight);
          // 图片压缩
          context.drawImage(img, 0, 0, targetWidth, targetHeight);
          canvas.toBlob(
            blob => {
              // const newImage = new File([blob as any], (imageFile as any).name, { type: (imageFile as any).type });
              setCanvasToBlob(blob);
            },
            'image/jpeg',
            0.7,
          );
        };
        img.onerror = () => console.error('Upload file of image format please.');
      };
    
      const handleUploadButton = (e: React.MouseEvent) => {
        e.preventDefault();
        setUploadButtonLoading(true);
        uploadFileValidate();
      };
    
      const handleFileChange = (e: any) => {
        const file = e.target.files[0];
        if (file !== undefined) {
          const fr = new FileReader();
          fr.readAsDataURL(file);
          fr.addEventListener('load', () => {
            setUploadImgUrl(fr.result as string); //base64
            qrCodeUploadedHandler(file, fr.result as string);
            setShowUploadModal(true);
          });
        } else {
          setUploadImgUrl('');
        }
      };
    
      const backToListPage = () => {
        const to = `${location.pathname}${location.search}`;
        history.push(to);
      };
    
      const handleLinkButton = (e: React.MouseEvent) => {
        e.preventDefault();
        if (!!fileInputRef) {
          (fileInputRef as any).current.click();
        }
      };
    
      const handleConfirmLink = async (e: React.MouseEvent) => {
        e.preventDefault();
        setConfirmButtonLoading(true);
        try {
          const {
            data: { data },
          } = await ajax.post('/qrcode/bind', { qrcode: qrDecode, bindObjectId: props.merchantId });
          if (data.length > 0) {
            try {
              const codeUrl = await QRCode.toDataURL(data[0]);
              setQrCodeUrl(codeUrl);
            } catch (err) {
              console.error(err);
            }
            setConfirmButtonLoading(false);
            setShowConfirmModal(false);
            setShowSuccessModal(true);
          }
        } catch (e) {
          message.error(e.message);
        }
      };
    
      const handleConfirmModalCancel = (e: React.MouseEvent) => {
        e.preventDefault();
        setShowConfirmModal(false);
        backToListPage();
      };
    
      const handleSuccessModalCancel = (e: React.MouseEvent) => {
        e.preventDefault();
        setShowSuccessModal(false);
        backToListPage();
      };
    
      return useObserver(() => (
        <>
          <div>
            <Button onClick={handleLinkButton} style={{  '100%', marginTop: 5 }} type="default" size="small">
              <QrcodeOutlined />
              Link QR code
            </Button>
            <input
              type="file"
              name="cover"
              accept="image/*"
              ref={fileInputRef}
              style={{  0, height: 0 }}
              onChange={handleFileChange}
            />
          </div>
          <Modal
            destroyOnClose={true}
            title="Confirm Information"
            visible={showConfirmModal}
            style={{ top: 20 }}
            width={'80%'}
            maskClosable={false}
            footer={[
              <Button
                type="primary"
                key="confirm"
                style={{ fontSize: '30px', height: '60px' }}
                loading={confirmButtonLoading}
                htmlType="button"
                onClick={handleConfirmLink}>
                Confirm
              </Button>,
              <Button
                key="cancel"
                htmlType="button"
                style={{ fontSize: '30px', height: '60px' }}
                onClick={handleConfirmModalCancel}>
                Cancel
              </Button>,
            ]}
            onCancel={handleConfirmModalCancel}>
            <Wrapper>
              <p>
                {/* eslint-disable-next-line react/no-unescaped-entities */}
                You're linking the QR code you scaned to the following merchant. Please check the merchant information
                throughly.
              </p>
              <div className="confirm-information">
                <div className="confirm-information-item">
                  <span>Merchant ID:</span>
                  <p>{props.merchantId}</p>
                </div>
                <div className="confirm-information-item">
                  <span>Branch Name:</span>
                  <p>{props.branchName}</p>
                </div>
                <div className="confirm-information-item">
                  <span>Merchant Name:</span>
                  <p>{props.merchantName}</p>
                </div>
                <div className="confirm-information-item">
                  <span>Person in Charge:</span>
                  <p>{props.personInCharge}</p>
                </div>
              </div>
            </Wrapper>
          </Modal>
          <Modal
            destroyOnClose={true}
            visible={showSuccessModal}
            style={{ top: 20 }}
            width={'50%'}
            maskClosable={false}
            footer={null}
            onCancel={handleSuccessModalCancel}>
            <SuccessWrapper>
              <p className="top-tip">QR code has been successfully linked!</p>
              <div className="branch-name">
                <span>Branch Name:</span>
                <p>{props.branchName}</p>
              </div>
              <div className="qr-code">
                <span>QR Code:</span>
                <img src={qrCodeUrl} alt="图片加载失败" />
              </div>
            </SuccessWrapper>
          </Modal>
          <Modal
            destroyOnClose={true}
            visible={showUploadModal}
            style={{ top: 20, textAlign: 'center' }}
            width={'80%'}
            maskClosable={false}
            closable={false}
            footer={null}>
            <UploadImgWrapper>
              <img id="img" src={uploadImgUrl} style={{  '90%' }} alt="" />
            </UploadImgWrapper>
            <Button
              type="primary"
              key="confirm"
              loading={uploadButtonLoading}
              size="large"
              htmlType="button"
              style={{ margin: '20px',  '90%', fontSize: '30px', height: '60px' }}
              onClick={handleUploadButton}>
              UPLOAD
            </Button>
          </Modal>
        </>
      ));
    };
    
    export default LinkQrCode;
    // axios封装
    import axios, { AxiosError, AxiosRequestConfig, AxiosResponse, Canceler } from 'axios';
    import Cookies from 'js-cookie';
    import { message } from 'antd';
    
    export let cancel!: Canceler;
    export const ROUTE_CHANGE = 'ROUTE_CHANGE';
    
    export const handleError = (e: AxiosError) => {
      message.error(`CODE: ${e.code}
     MESSAGE: ${e.message}`);
    };
    
    const requestInterceptor = (config: AxiosRequestConfig) => {
      const acceptLanguages = [...navigator.languages];
    // config.headers['Authorization'] = xxx,这种方式写法只会重写
    // headers中Authorization字段,不会重写整个headers.
    // 如果config.headers= {xxx},每次请求的headers都会被重写成这里定义
    // 的,会导致你在调请求方法时手动指定的headers失效。
      config.headers['Authorization'] = Cookies.get('token');
      config.headers['Accept-Language'] = acceptLanguages.join(',');
      return config;
    };
    
    const responseInterceptor = (res: AxiosResponse) => {
      if (res.data.code !== 'SUCCESS') {
        throw {
          isAxiosError: false,
          request: res.request,
          name: res.data.code,
          config: res.config,
          code: res.data.code,
          message: res.data.message,
          response: res,
        } as AxiosError;
      } else {
        return res;
      }
    };
    
    const ajax = axios.create({
      baseURL: '/api',
      timeout: 60000,
    });
    
    ajax.interceptors.response.use(responseInterceptor);
    ajax.interceptors.request.use(requestInterceptor);
    
    export default ajax;
    // AxiosRequestConfig  ===> ts
    export interface AxiosTransformer {
      (data: any, headers?: any): any;
    }
    
    export interface AxiosAdapter {
      (config: AxiosRequestConfig): AxiosPromise<any>;
    }
    
    export interface AxiosBasicCredentials {
      username: string;
      password: string;
    }
    
    export interface AxiosProxyConfig {
      host: string;
      port: number;
      auth?: {
        username: string;
        password:string;
      };
      protocol?: string;
    }
    
    export type Method =
      | 'get' | 'GET'
      | 'delete' | 'DELETE'
      | 'head' | 'HEAD'
      | 'options' | 'OPTIONS'
      | 'post' | 'POST'
      | 'put' | 'PUT'
      | 'patch' | 'PATCH'
      | 'link' | 'LINK'
      | 'unlink' | 'UNLINK'
    
    export type ResponseType = 
      | 'arraybuffer' 
      | 'blob' 
      | 'document' 
      | 'json' 
      | 'text' 
      | 'stream'
    
    export interface AxiosRequestConfig {
      url?: string;
      method?: Method;
      baseURL?: string;
      transformRequest?: AxiosTransformer | AxiosTransformer[];
      transformResponse?: AxiosTransformer | AxiosTransformer[];
      headers?: any;
      params?: any;
      paramsSerializer?: (params: any) => string;
      data?: any;
      timeout?: number;
      timeoutErrorMessage?: string;
      withCredentials?: boolean;
      adapter?: AxiosAdapter;
      auth?: AxiosBasicCredentials;
      responseType?: ResponseType;
      xsrfCookieName?: string;
      xsrfHeaderName?: string;
      onUploadProgress?: (progressEvent: any) => void;
      onDownloadProgress?: (progressEvent: any) => void;
      maxContentLength?: number;
      validateStatus?: (status: number) => boolean;
      maxRedirects?: number;
      socketPath?: string | null;
      httpAgent?: any;
      httpsAgent?: any;
      proxy?: AxiosProxyConfig | false;
      cancelToken?: CancelToken;
    }
    
    export interface AxiosResponse<T = any>  {
      data: T;
      status: number;
      statusText: string;
      headers: any;
      config: AxiosRequestConfig;
      request?: any;
    }
    
    export interface AxiosError<T = any> extends Error {
      config: AxiosRequestConfig;
      code?: string;
      request?: any;
      response?: AxiosResponse<T>;
      isAxiosError: boolean;
      toJSON: () => object;
    }
    
    export interface AxiosPromise<T = any> extends Promise<AxiosResponse<T>> {
    }
    
    export interface CancelStatic {
      new (message?: string): Cancel;
    }
    
    export interface Cancel {
      message: string;
    }
    
    export interface Canceler {
      (message?: string): void;
    }
    
    export interface CancelTokenStatic {
      new (executor: (cancel: Canceler) => void): CancelToken;
      source(): CancelTokenSource;
    }
    
    export interface CancelToken {
      promise: Promise<Cancel>;
      reason?: Cancel;
      throwIfRequested(): void;
    }
    
    export interface CancelTokenSource {
      token: CancelToken;
      cancel: Canceler;
    }
    
    export interface AxiosInterceptorManager<V> {
      use(onFulfilled?: (value: V) => V | Promise<V>, onRejected?: (error: any) => any): number;
      eject(id: number): void;
    }
    
    export interface AxiosInstance {
      (config: AxiosRequestConfig): AxiosPromise;
      (url: string, config?: AxiosRequestConfig): AxiosPromise;
      defaults: AxiosRequestConfig;
      interceptors: {
        request: AxiosInterceptorManager<AxiosRequestConfig>;
        response: AxiosInterceptorManager<AxiosResponse>;
      };
      getUri(config?: AxiosRequestConfig): string;
      request<T = any, R = AxiosResponse<T>> (config: AxiosRequestConfig): Promise<R>;
      get<T = any, R = AxiosResponse<T>>(url: string, config?: AxiosRequestConfig): Promise<R>;
      delete<T = any, R = AxiosResponse<T>>(url: string, config?: AxiosRequestConfig): Promise<R>;
      head<T = any, R = AxiosResponse<T>>(url: string, config?: AxiosRequestConfig): Promise<R>;
      options<T = any, R = AxiosResponse<T>>(url: string, config?: AxiosRequestConfig): Promise<R>;
      post<T = any, R = AxiosResponse<T>>(url: string, data?: any, config?: AxiosRequestConfig): Promise<R>;
      put<T = any, R = AxiosResponse<T>>(url: string, data?: any, config?: AxiosRequestConfig): Promise<R>;
      patch<T = any, R = AxiosResponse<T>>(url: string, data?: any, config?: AxiosRequestConfig): Promise<R>;
    }
    
    export interface AxiosStatic extends AxiosInstance {
      create(config?: AxiosRequestConfig): AxiosInstance;
      Cancel: CancelStatic;
      CancelToken: CancelTokenStatic;
      isCancel(value: any): boolean;
      all<T>(values: (T | Promise<T>)[]): Promise<T[]>;
      spread<T, R>(callback: (...args: T[]) => R): (array: T[]) => R;
    }
    
    declare const Axios: AxiosStatic;
    
    export default Axios;
  • 相关阅读:
    Mybatis 原始dao CRUD方法
    JQuery的焦点事件focus() 与按键事件keydown() 及js判断当前页面是否为顶级页面 子页面刷新将顶级页面刷新 window.top.location
    使用actionerror做失败登录验证
    Java项目中的下载 与 上传
    shiro框架 4种授权方式 说明
    javascript 中数组的创建 添加 与将数组转换成字符串 页面三种提交请求的方式
    序列化表单为json对象,datagrid带额外参提交一次查询 后台用Spring data JPA 实现带条件的分页查询 多表关联查询
    Spring data JPA 理解(默认查询 自定义查询 分页查询)及no session 三种处理方法
    orcal 数据库 maven架构 ssh框架 的全注解环境模版 maven中央仓库批量删除lastupdated文件后依然是lastupdated解决方法 mirror aliyun中央仓库
    EasyUI加zTree使用解析 easyui修改操作的表单回显方法 验证框提交表单前验证 datagrid的load方法
  • 原文地址:https://www.cnblogs.com/chenbeibei520/p/12551970.html
Copyright © 2011-2022 走看看