index.tsx 3.7 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121
  1. import CropperImg from '@/components/CropperImg';
  2. import { useOss } from '@/Hook/useOss';
  3. import { PlusOutlined } from '@ant-design/icons';
  4. import { message, Upload } from 'antd';
  5. import { RcFile } from 'antd/es/upload';
  6. import dayjs from 'dayjs';
  7. import React, { useEffect, useState } from 'react';
  8. import styles from './index.less';
  9. type CompareType = '<' | '<=' | '>' | '>=' | '=' | '!=';
  10. interface Props {
  11. type?: any;
  12. value?: string;
  13. onChange?: (data: { value: string; file: RcFile; name: string }) => void;
  14. size?: { width: number; height: number; evalW: CompareType; evalH: CompareType; msg: string };
  15. // 是否裁剪
  16. isCropper?: boolean;
  17. isEdit?: boolean;
  18. }
  19. const UploadImg: React.FC<Props> = ({ value, onChange, size, type, isCropper, isEdit }) => {
  20. /********************************/
  21. const [visible, setVisible] = useState<boolean>(false);
  22. const [file, setFile] = useState<RcFile>();
  23. const ossUpload = useOss(true);
  24. const [imageUrl, setImageUrl] = useState<string>('');
  25. /********************************/
  26. useEffect(() => {
  27. setImageUrl(value || '');
  28. }, [value]);
  29. const uploadButton = (
  30. <div>
  31. <div style={{ height: 45, display: 'flex', justifyContent: 'center', alignItems: 'center' }}>
  32. {' '}
  33. <PlusOutlined/>
  34. </div>
  35. <div style={{ display: 'flex', flexFlow: 'column' }}>
  36. <span>上传图片</span>
  37. <span style={{ color: '#999', fontSize: 10 }}>
  38. {size?.width} * {size?.height}
  39. </span>
  40. </div>
  41. </div>
  42. );
  43. const upload = (file: RcFile) => {
  44. let name = dayjs().valueOf().toString();
  45. ossUpload.run(file, name).then((res: any) => {
  46. if (res?.data) {
  47. let [fileName, nameSuffix] = file.name.split('.');
  48. onChange?.(res.data.url);
  49. }
  50. });
  51. };
  52. return (
  53. <>
  54. <Upload
  55. name="avatar"
  56. listType="picture-card"
  57. accept="image/png,image/jpg,image/jpeg"
  58. action="#"
  59. showUploadList={false}
  60. customRequest={() => {}}
  61. className={imageUrl ? styles.upLoadTrue : ''}
  62. beforeUpload={(file: RcFile): any => {
  63. if (file.size > 10485760) {
  64. message.error('图片大小大于10M,请压缩在上传');
  65. return;
  66. }
  67. let img: any = new Image();
  68. let _URL = window.URL || window.webkitURL;
  69. img.onload = function (e: any) {
  70. if (
  71. (size?.width && eval(`${this.width} ${size.evalW} ${size?.width}`)) ||
  72. (size?.height && eval(`${this.height} ${size?.evalH} ${size?.height}`))
  73. ) {
  74. if (
  75. isCropper &&
  76. ((isEdit &&
  77. eval(`${this.width} >= ${size?.width}`) &&
  78. eval(`${this.height} >= ${size?.height}`)) ||
  79. !isEdit)
  80. ) {
  81. setFile(file);
  82. setVisible(true);
  83. } else {
  84. message.error(
  85. `传入的图片大小不符, 上传图片宽度${this.width}高度${this.height}, ${size?.msg}`,
  86. );
  87. }
  88. return;
  89. }
  90. upload(file);
  91. };
  92. img.src = _URL.createObjectURL(file);
  93. }}
  94. >
  95. {imageUrl ? <img src={imageUrl} alt="avatar" style={{ width: '100%' }} /> : uploadButton}
  96. </Upload>
  97. {/* 裁剪 */}
  98. {visible && (
  99. <CropperImg
  100. visible={visible}
  101. size={size}
  102. isEdit={isEdit}
  103. onClose={() => setVisible(false)}
  104. file={file}
  105. onChange={(fileList: any[], file: any) => {
  106. upload(file);
  107. setVisible(false);
  108. }}
  109. />
  110. )}
  111. </>
  112. );
  113. };
  114. export default React.memo(UploadImg);