index.jsx 5.0 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178
  1. import React, { useState, useCallback, useRef } from 'react';
  2. import cx from 'classnames';
  3. import { Button, Checkbox, message } from 'antd';
  4. import { importUsers } from './service';
  5. import { useModel, history } from 'umi';
  6. import iconExcel from './icon-excel.svg';
  7. import iconErrorExcel from './icon-excel-error.svg';
  8. import styles from './index.less';
  9. const isExcel = (type) => {
  10. return (
  11. [
  12. 'text/csv',
  13. '.csv',
  14. 'application/vnd.ms-excel',
  15. 'application/vnd.openxmlformats-officedocument.spreadsheetml.sheet',
  16. ].indexOf(type) >= 0
  17. );
  18. };
  19. export default ({ onUploadDone }) => {
  20. const [draggingOver, setDraggingOver] = useState(false);
  21. const [fileInfo, setFileInfo] = useState({});
  22. const [autoSendActiveMsg, setAutoSendActiveMsg] = useState(true);
  23. const [errorInfo, setErrorInfo] = useState('');
  24. const [uploading, setUploading] = useState(false);
  25. const fileInputRef = useRef();
  26. /**
  27. * 0: 开始选择
  28. * 1: 文件选择之后,且符合规范
  29. * 2: 文件选择之后,不符合规范
  30. * 3: 文件上传失败
  31. */
  32. const [uploadState, setUploadState] = useState(0);
  33. const { initialState } = useModel('@@initialState');
  34. const handleFileSelected = useCallback((e) => {
  35. const file = e.target.files[0];
  36. if (!file) {
  37. setUploadState(3);
  38. }
  39. setFileInfo({
  40. file,
  41. name: file.name,
  42. size: `${Math.ceil(file.size / 1024)}K`,
  43. });
  44. if (!isExcel(file.type)) {
  45. setErrorInfo('不支持此类文件格式');
  46. setUploadState(2);
  47. } else if (file.size > 1024 * 1024 * 10) {
  48. setErrorInfo('文件大小不能超过 10MB');
  49. setUploadState(2);
  50. } else {
  51. setUploadState(1);
  52. }
  53. e.target.value = '';
  54. }, []);
  55. const beginUpload = useCallback(() => {
  56. setUploading(true);
  57. let params = {
  58. companyId: initialState?.currentUser?.companyId,
  59. };
  60. importUsers(fileInfo.file, params)
  61. .then((res) => {
  62. setUploading(false);
  63. if (res.key) {
  64. onUploadDone(res);
  65. } else {
  66. message.error(res.message);
  67. setUploadState(0);
  68. }
  69. })
  70. .catch(() => {
  71. // 文件上传失败
  72. setUploading(false);
  73. setUploadState(3);
  74. });
  75. }, [fileInfo, autoSendActiveMsg, onUploadDone]);
  76. return (
  77. <div
  78. className={cx(styles.c, {
  79. [styles.dragging]: draggingOver,
  80. })}
  81. onDragEnter={(e) => {
  82. e.preventDefault();
  83. e.stopPropagation();
  84. setDraggingOver(true);
  85. }}
  86. onDragOver={(e) => {
  87. setDraggingOver(true);
  88. e.preventDefault();
  89. e.stopPropagation();
  90. return false;
  91. }}
  92. onDragLeave={(e) => {
  93. e.preventDefault();
  94. e.stopPropagation();
  95. setDraggingOver(false);
  96. }}
  97. onDrop={(e) => {
  98. e.preventDefault();
  99. e.stopPropagation();
  100. setDraggingOver(false);
  101. handleFileSelected({
  102. target: {
  103. files: e.dataTransfer.files,
  104. },
  105. });
  106. }}
  107. >
  108. <input type="file" hidden ref={fileInputRef} onChange={(e) => handleFileSelected(e)} />
  109. <div className={styles.title}>
  110. <span>2&nbsp;/</span>
  111. 上传填写完后的表格文件
  112. </div>
  113. {uploadState === 0 && (
  114. <div className={styles.fileTrigger}>
  115. <img src={iconExcel} />
  116. <div>
  117. <span onClick={() => fileInputRef.current.click()}>点击选择文件</span>
  118. ,或将文件拖拽到此处
  119. </div>
  120. </div>
  121. )}
  122. {uploadState === 1 && (
  123. <div className={styles.fileInfo}>
  124. <img src={iconExcel} />
  125. <div>
  126. {fileInfo.name} ({fileInfo.size})&nbsp;&nbsp;
  127. <span onClick={() => fileInputRef.current.click()}>重新选择文件</span>
  128. </div>
  129. <section>
  130. <Button
  131. type="primary"
  132. size="large"
  133. style={{ margin: '30px 0 20px' }}
  134. loading={uploading}
  135. onClick={() => {
  136. beginUpload();
  137. }}
  138. >
  139. 开始上传
  140. </Button>
  141. <br />
  142. {/* <Checkbox checked={autoSendActiveMsg} onChange={e => setAutoSendActiveMsg(e.target.checked)}>导入后自动发送短信提醒其激活账号</Checkbox> */}
  143. </section>
  144. </div>
  145. )}
  146. {uploadState === 2 && (
  147. <div className={styles.fileError}>
  148. <img src={iconErrorExcel} />
  149. <div>
  150. {errorInfo},<span onClick={() => fileInputRef.current.click()}>重新选择文件</span>
  151. </div>
  152. </div>
  153. )}
  154. {uploadState === 3 && (
  155. <div className={styles.fileError}>
  156. <img src={iconErrorExcel} />
  157. <div>
  158. {fileInfo.name} ({fileInfo.size})
  159. </div>
  160. <div>
  161. 文件导入失败,请<span onClick={beginUpload}>再次上传</span>或
  162. <span onClick={() => fileInputRef.current.click()}>重新选择文件</span>
  163. </div>
  164. </div>
  165. )}
  166. </div>
  167. );
  168. };