index.tsx 3.0 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100
  1. import { message, Upload } from 'antd';
  2. import { useEffect, useState } from 'react';
  3. import { LoadingOutlined, PlusOutlined } from '@ant-design/icons';
  4. import SystemConst from '@/utils/const';
  5. import Token from '@/utils/token';
  6. import type { UploadChangeParam } from 'antd/lib/upload/interface';
  7. import type { RcFile } from 'antd/es/upload';
  8. import './index.less';
  9. interface UploadImageProps {
  10. onChange?: (url: string) => void;
  11. value?: string;
  12. disabled?: boolean;
  13. /**
  14. * 图片格式类型,默认 'image/jpeg', 'image/png'
  15. */
  16. types?: string[];
  17. /**
  18. * 图片大小限制, 单位 M,默认 4 M
  19. */
  20. size?: number;
  21. }
  22. export default ({ onChange, value, ...extraProps }: UploadImageProps) => {
  23. const [values, setValues] = useState(value || '');
  24. const [loading, setLoading] = useState<boolean>(false);
  25. const imageTypes = extraProps.types ? extraProps.types : ['image/jpeg', 'image/png'];
  26. useEffect(() => {
  27. setValues(value || '');
  28. }, [value]);
  29. const handleChange = (info: UploadChangeParam) => {
  30. if (info.file.status === 'uploading') {
  31. setLoading(true);
  32. }
  33. if (info.file.status === 'done') {
  34. info.file.url = info.file.response?.result;
  35. setLoading(false);
  36. setValues(info.file.response?.result);
  37. if (onChange) {
  38. onChange(info.file.response?.result);
  39. }
  40. }
  41. };
  42. const beforeUpload = (file: RcFile) => {
  43. const isType = imageTypes.includes(file.type);
  44. if (!isType) {
  45. message.error(`图片格式错误,必须是${imageTypes.toString()}格式`);
  46. return false;
  47. }
  48. const isSize = file.size / 1024 / 1024 < (extraProps.size || 4);
  49. if (!isSize) {
  50. message.error(`图片大小必须小于${extraProps.size || 4}M`);
  51. }
  52. return isType && isSize;
  53. };
  54. return (
  55. <div className={'upload-image-warp'}>
  56. <div className={'upload-image-border'}>
  57. <Upload
  58. action={`/${SystemConst.API_BASE}/file/static`}
  59. headers={{
  60. 'X-Access-Token': Token.get(),
  61. }}
  62. showUploadList={false}
  63. onChange={handleChange}
  64. beforeUpload={beforeUpload}
  65. {...extraProps}
  66. >
  67. <div className={'upload-image-content'}>
  68. {values ? (
  69. <>
  70. {/*<img width={120} height={120} src={values} />*/}
  71. <div className={'upload-image'} style={{ backgroundImage: `url(${values})` }} />
  72. <div className={'upload-image-mask'}>点击修改</div>
  73. </>
  74. ) : (
  75. <>
  76. {loading ? (
  77. <LoadingOutlined style={{ fontSize: 28 }} />
  78. ) : (
  79. <PlusOutlined style={{ fontSize: 28 }} />
  80. )}
  81. <div>点击上传图片</div>
  82. </>
  83. )}
  84. </div>
  85. </Upload>
  86. {values && loading ? (
  87. <div className={'upload-loading-mask'}>
  88. {loading ? <LoadingOutlined style={{ fontSize: 28 }} /> : null}
  89. </div>
  90. ) : null}
  91. </div>
  92. </div>
  93. );
  94. };