|
@@ -1,119 +1,127 @@
|
|
|
-import { message, Space, Upload, Image } from "antd"
|
|
|
-import { PlusOutlined, LoadingOutlined } from "@ant-design/icons";
|
|
|
-import { RcFile } from "antd/lib/upload";
|
|
|
-import React, { useState } from "react";
|
|
|
-import './index.less'
|
|
|
-import { getBase64, getImgSizeProper } from "@/utils";
|
|
|
-import { getOssInfo } from "@/services/ant-design-pro/api";
|
|
|
-import { request } from "@umijs/max";
|
|
|
-
|
|
|
-interface Props {
|
|
|
- value?: string, // 图片地址
|
|
|
- maxCount?: number
|
|
|
- onChange?: (data: RcFile | string) => void,
|
|
|
- tooltip?: JSX.Element
|
|
|
- isUpload?: boolean, // 是否上传
|
|
|
- sizeData?: {
|
|
|
- width: number,
|
|
|
- height: number
|
|
|
- }
|
|
|
-}
|
|
|
-const UploadImg: React.FC<Props> = (props) => {
|
|
|
-
|
|
|
- /** 变量START */
|
|
|
- const { value, maxCount = 1, tooltip, sizeData, isUpload = false, onChange } = props
|
|
|
- const [imageFile, setImageFile] = useState<string>(value || '');
|
|
|
- const [loading, setLoading] = useState<boolean>(false)
|
|
|
- const [visible, setVisible] = useState<boolean>(false)
|
|
|
- /** 变量END */
|
|
|
-
|
|
|
- const beforeUpload = async (file: RcFile) => {
|
|
|
- const isJpgOrPng = file.type === 'image/jpeg' || file.type === 'image/png';
|
|
|
- if (!isJpgOrPng) {
|
|
|
- message.error('您只能上传JPG/PNG文件!');
|
|
|
- }
|
|
|
- const isLt2M = file.size / 1024 / 1024 < 2;
|
|
|
- if (!isLt2M) {
|
|
|
- message.error('图像必须小于2MB!');
|
|
|
- }
|
|
|
-
|
|
|
- if (sizeData) {
|
|
|
- let imgData: any = await getImgSizeProper(file)
|
|
|
- if (sizeData?.width !== imgData.width || sizeData?.height !== imgData.height) {
|
|
|
- message.error(`传入的图片大小不符, 图片大小${imgData.width}*${imgData.height}, 需要图片大小${sizeData.width}*${sizeData.height}`)
|
|
|
- return false
|
|
|
- }
|
|
|
- }
|
|
|
- return isJpgOrPng && isLt2M;
|
|
|
- };
|
|
|
-
|
|
|
- const uploadButton = (
|
|
|
- <div>
|
|
|
- {loading ? <LoadingOutlined /> : <PlusOutlined />}
|
|
|
- </div>
|
|
|
- );
|
|
|
-
|
|
|
- return <div className="myUpload">
|
|
|
- <Space align="start">
|
|
|
- <Upload
|
|
|
- name="avatar"
|
|
|
- listType="picture-card"
|
|
|
- accept='image/gif,image/jpeg,image/png,image/jpg'
|
|
|
- className="avatar-uploader"
|
|
|
- beforeUpload={beforeUpload}
|
|
|
- maxCount={maxCount}
|
|
|
- showUploadList={false}
|
|
|
- customRequest={(options: any) => {
|
|
|
- if (isUpload) { // 上传oss
|
|
|
- setLoading(true)
|
|
|
- getOssInfo({ type: 'image/jpeg', fileType: 'image' }).then(async res => {
|
|
|
- try {
|
|
|
- let formData = new FormData();
|
|
|
- Object.keys(res.data).forEach((key: string) => {
|
|
|
- if (key !== 'url') {
|
|
|
- formData.append(key, res.data[key])
|
|
|
- }
|
|
|
- })
|
|
|
- formData.append('file', options.file)
|
|
|
- let urlData = await request(res?.data?.ossUrl, { method: 'POST', data: formData })
|
|
|
- setLoading(false)
|
|
|
- setImageFile(urlData?.data?.url);
|
|
|
- if (urlData?.data?.url) {
|
|
|
- onChange && onChange(urlData?.data?.url)
|
|
|
- }
|
|
|
- } catch (error) {
|
|
|
- setLoading(false)
|
|
|
- }
|
|
|
- })
|
|
|
- } else {
|
|
|
- getBase64(options.file as RcFile, url => {
|
|
|
- setImageFile(url);
|
|
|
- })
|
|
|
- onChange && onChange(options.file)
|
|
|
- }
|
|
|
- }}
|
|
|
- >
|
|
|
- {imageFile ? <Image src={imageFile} preview={false} style={{ height: '85px' }} /> : uploadButton}
|
|
|
- </Upload>
|
|
|
- <div>{tooltip && tooltip}</div>
|
|
|
- {imageFile && <div className="look">
|
|
|
- <a onClick={() => setVisible(true)}>预览</a>
|
|
|
- <Image
|
|
|
- style={{ display: 'none' }}
|
|
|
- src={imageFile}
|
|
|
- preview={{
|
|
|
- visible,
|
|
|
- src: imageFile,
|
|
|
- onVisibleChange: value => {
|
|
|
- setVisible(value);
|
|
|
- },
|
|
|
- }}
|
|
|
- />
|
|
|
- </div>}
|
|
|
-
|
|
|
- </Space>
|
|
|
- </div>
|
|
|
-}
|
|
|
-
|
|
|
-
|
|
|
-export default React.memo(UploadImg)
|
|
|
+import { getOssInfo } from '@/services/ant-design-pro/api';
|
|
|
+import { getBase64, getImgSizeProper } from '@/utils';
|
|
|
+import { LoadingOutlined, PlusOutlined } from '@ant-design/icons';
|
|
|
+import { request } from '@umijs/max';
|
|
|
+import { Image, message, Space, Upload } from 'antd';
|
|
|
+import { RcFile } from 'antd/lib/upload';
|
|
|
+import React, { useState } from 'react';
|
|
|
+import './index.less';
|
|
|
+
|
|
|
+interface Props {
|
|
|
+ value?: string; // 图片地址
|
|
|
+ maxCount?: number;
|
|
|
+ onChange?: (data: RcFile | string) => void;
|
|
|
+ tooltip?: JSX.Element;
|
|
|
+ isUpload?: boolean; // 是否上传
|
|
|
+ sizeData?: {
|
|
|
+ width: number;
|
|
|
+ height: number;
|
|
|
+ };
|
|
|
+}
|
|
|
+const UploadImg: React.FC<Props> = (props) => {
|
|
|
+ /** 变量START */
|
|
|
+ const { value, maxCount = 1, tooltip, sizeData, isUpload = false, onChange } = props;
|
|
|
+ const [imageFile, setImageFile] = useState<string>(value || '');
|
|
|
+ const [loading, setLoading] = useState<boolean>(false);
|
|
|
+ const [visible, setVisible] = useState<boolean>(false);
|
|
|
+ /** 变量END */
|
|
|
+
|
|
|
+ const beforeUpload = async (file: RcFile) => {
|
|
|
+ const isJpgOrPng =
|
|
|
+ file.type === 'image/jpeg' || file.type === 'image/png' || file.type === 'image/jpg';
|
|
|
+ if (!isJpgOrPng) {
|
|
|
+ message.error('您只能上传JPG/PNG文件!');
|
|
|
+ }
|
|
|
+ const isLt2M = file.size / 1024 / 1024 < 2;
|
|
|
+ if (!isLt2M) {
|
|
|
+ message.error('图像必须小于2MB!');
|
|
|
+ }
|
|
|
+
|
|
|
+ if (sizeData) {
|
|
|
+ let imgData: any = await getImgSizeProper(file);
|
|
|
+ if (sizeData?.width !== imgData.width || sizeData?.height !== imgData.height) {
|
|
|
+ message.error(
|
|
|
+ `传入的图片大小不符, 图片大小${imgData.width}*${imgData.height}, 需要图片大小${sizeData.width}*${sizeData.height}`,
|
|
|
+ );
|
|
|
+ return false;
|
|
|
+ }
|
|
|
+ }
|
|
|
+ return isJpgOrPng && isLt2M;
|
|
|
+ };
|
|
|
+
|
|
|
+ const uploadButton = <div>{loading ? <LoadingOutlined /> : <PlusOutlined />}</div>;
|
|
|
+
|
|
|
+ return (
|
|
|
+ <div className="myUpload">
|
|
|
+ <Space align="start">
|
|
|
+ <Upload
|
|
|
+ name="avatar"
|
|
|
+ listType="picture-card"
|
|
|
+ accept="image/jpeg,image/png,image/jpg"
|
|
|
+ className="avatar-uploader"
|
|
|
+ beforeUpload={beforeUpload}
|
|
|
+ maxCount={maxCount}
|
|
|
+ showUploadList={false}
|
|
|
+ customRequest={(options: any) => {
|
|
|
+ if (isUpload) {
|
|
|
+ // 上传oss
|
|
|
+ setLoading(true);
|
|
|
+ getOssInfo({ type: 'image/jpeg', fileType: 'image' }).then(async (res) => {
|
|
|
+ try {
|
|
|
+ let formData = new FormData();
|
|
|
+ Object.keys(res.data).forEach((key: string) => {
|
|
|
+ if (key !== 'url') {
|
|
|
+ formData.append(key, res.data[key]);
|
|
|
+ }
|
|
|
+ });
|
|
|
+ formData.append('file', options.file);
|
|
|
+ let urlData = await request(res?.data?.ossUrl, {
|
|
|
+ method: 'POST',
|
|
|
+ data: formData,
|
|
|
+ });
|
|
|
+ setLoading(false);
|
|
|
+ setImageFile(urlData?.data?.url);
|
|
|
+ if (urlData?.data?.url) {
|
|
|
+ onChange && onChange(urlData?.data?.url);
|
|
|
+ }
|
|
|
+ } catch (error) {
|
|
|
+ setLoading(false);
|
|
|
+ }
|
|
|
+ });
|
|
|
+ } else {
|
|
|
+ getBase64(options.file as RcFile, (url) => {
|
|
|
+ setImageFile(url);
|
|
|
+ });
|
|
|
+ onChange && onChange(options.file);
|
|
|
+ }
|
|
|
+ }}
|
|
|
+ >
|
|
|
+ {imageFile ? (
|
|
|
+ <Image src={imageFile} preview={false} style={{ height: '85px' }} />
|
|
|
+ ) : (
|
|
|
+ uploadButton
|
|
|
+ )}
|
|
|
+ </Upload>
|
|
|
+ <div>{tooltip && tooltip}</div>
|
|
|
+ {imageFile && (
|
|
|
+ <div className="look">
|
|
|
+ <a onClick={() => setVisible(true)}>预览</a>
|
|
|
+ <Image
|
|
|
+ style={{ display: 'none' }}
|
|
|
+ src={imageFile}
|
|
|
+ preview={{
|
|
|
+ visible,
|
|
|
+ src: imageFile,
|
|
|
+ onVisibleChange: (value) => {
|
|
|
+ setVisible(value);
|
|
|
+ },
|
|
|
+ }}
|
|
|
+ />
|
|
|
+ </div>
|
|
|
+ )}
|
|
|
+ </Space>
|
|
|
+ </div>
|
|
|
+ );
|
|
|
+};
|
|
|
+
|
|
|
+export default React.memo(UploadImg);
|