index.tsx 8.2 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297
  1. import { useCallback, useRef, useState } from "react";
  2. import styles from "./index.module.scss";
  3. import { InboxOutlined } from "@ant-design/icons";
  4. import {
  5. Button,
  6. message,
  7. Modal,
  8. Popconfirm,
  9. Upload,
  10. UploadFile,
  11. UploadProps,
  12. } from "antd";
  13. import { EyeOutlined, DownloadOutlined } from "@ant-design/icons";
  14. import history from "@/utils/history";
  15. import React from "react";
  16. import { getTokenFu } from "@/utils/storage";
  17. import { MessageFu } from "@/utils/message";
  18. import { A1_APIOupFileIds, A1_APIremoveOut } from "@/store/action/A1Project";
  19. import { authFilesLookFu, urlChangeFu } from "@/utils/authFilesLook";
  20. const { Dragger } = Upload;
  21. const A1OtopBtnArr = [
  22. { id: 1, name: "上传文件夹" },
  23. { id: 2, name: "上传文件" },
  24. ];
  25. type props = {
  26. myUrl: string;
  27. fromData: any;
  28. nowLoc: string;
  29. upFileFu: () => void;
  30. closeFu: () => void;
  31. };
  32. function A1OupFile({ myUrl, fromData, nowLoc, closeFu, upFileFu }: props) {
  33. // 文件夹和文件的选择
  34. const [isFiles, setIsFiles] = useState(1);
  35. const [modal, contextHolder] = Modal.useModal();
  36. const [fileList, setFileList] = useState<UploadFile[]>([]);
  37. const timeRef = useRef(-1);
  38. const FileProps: UploadProps = {
  39. name: "file",
  40. multiple: true,
  41. action: myUrl,
  42. headers: {
  43. token: getTokenFu(),
  44. },
  45. // 支持上传文件夹
  46. directory: isFiles === 1,
  47. data: fromData,
  48. fileList,
  49. //不要前面的图标
  50. // iconRender: () => false,
  51. // 文件上传之前 -- 这里不用校验
  52. // beforeUpload(file, fileList) {
  53. // // console.log("文件上传之前-用于校验", file);
  54. // // if (file.name.includes("4dage")) {
  55. // // // console.log("校验不通过,不上传");
  56. // // message.error(`${file.name}不符合上传需求`);
  57. // // return Upload.LIST_IGNORE;
  58. // // }
  59. // },
  60. onChange(info) {
  61. setFileList([...info.fileList]);
  62. const { status } = info.file;
  63. if (status !== "uploading") {
  64. // 检查请求状态
  65. const response = info.file.response || {};
  66. if (response.code !== 0) {
  67. setFileList(info.fileList.filter((v) => v.uid !== info.file.uid));
  68. clearTimeout(timeRef.current);
  69. timeRef.current = window.setTimeout(() => {
  70. MessageFu.warning(response.msg);
  71. }, 200);
  72. }
  73. if (response.code === 5001 || response.code === 5002) {
  74. message.warning("登录失效!");
  75. history.push("/login");
  76. return false;
  77. }
  78. // console.log(info.file, info.fileList);
  79. }
  80. if (status === "done") {
  81. // message.success(`${info.file.name} 上传成功.`);
  82. } else if (status === "error") {
  83. message.error(`${info.file.name} 上传失败.`);
  84. // 去掉列表中的失败状态文件
  85. setFileList(info.fileList.filter((v) => v.uid !== info.file.uid));
  86. }
  87. },
  88. // onDrop(e) {
  89. // // console.log("拖动文件到上传区域", e.dataTransfer.files);
  90. // },
  91. // 点击删除
  92. async onRemove(info) {
  93. const promiseFu = new Promise((resolve: (value: boolean) => void) => {
  94. modal.confirm({
  95. title: "删除确认",
  96. content: "删除后无法恢复,是否删除?",
  97. okText: "删除",
  98. cancelText: "取消",
  99. async onOk() {
  100. if (info.percent === 100) {
  101. // console.log("-----还没有发请求删除", info);
  102. const id = info.response.data.id;
  103. // 已经上传完成,发请求删除
  104. const res = await A1_APIremoveOut(id);
  105. if (res.code === 0) {
  106. resolve(true);
  107. MessageFu.success("删除成功!");
  108. }
  109. } else {
  110. resolve(true);
  111. MessageFu.success("删除成功!");
  112. }
  113. },
  114. onCancel() {
  115. resolve(false);
  116. },
  117. });
  118. });
  119. return await promiseFu;
  120. },
  121. };
  122. // 点击确定
  123. const btnOkFu = useCallback(async () => {
  124. if (fileList.some((v) => v.percent !== 100))
  125. return message.warning("有文件未上传完成.");
  126. // 拿到 id集合
  127. const ids: number[] = [];
  128. fileList.forEach((v) => {
  129. ids.push(v.response.data.id);
  130. });
  131. const res = await A1_APIOupFileIds(ids.join(","));
  132. if (res.code === 0) {
  133. MessageFu.success("保存成功!");
  134. upFileFu();
  135. closeFu();
  136. }
  137. }, [closeFu, fileList, upFileFu]);
  138. // 点击取消 删除所有文件
  139. const clickCloseFu = useCallback(async () => {
  140. const arr: string[] = [];
  141. fileList.forEach((v) => {
  142. if (v.response && v.response.data) {
  143. arr.push(v.response.data.id);
  144. }
  145. });
  146. if (arr.length > 0) {
  147. const res = await A1_APIremoveOut(arr.join(","));
  148. if (res.code === 0) closeFu();
  149. } else closeFu();
  150. }, [closeFu, fileList]);
  151. // 点击按钮切换上传 文件夹 和 文件
  152. const changeFileType = useCallback((id: number) => {
  153. setIsFiles(id);
  154. setTimeout(() => {
  155. const dom: any = document.querySelector(
  156. ".ant-upload-wrapper .ant-upload input"
  157. )!;
  158. dom.click();
  159. }, 100);
  160. }, []);
  161. return (
  162. <Modal
  163. wrapClassName={styles.A1OupFile}
  164. destroyOnClose
  165. open={true}
  166. title={"上传文件 - " + nowLoc}
  167. footer={
  168. [] // 设置footer为空,去掉 取消 确定默认按钮
  169. }
  170. >
  171. <div className="A1OtopBtn">
  172. {A1OtopBtnArr.map((v) => (
  173. <div key={v.id}>
  174. <Button onClick={() => changeFileType(v.id)} type="primary">
  175. {v.name}
  176. </Button>
  177. </div>
  178. ))}
  179. </div>
  180. <div className="A1OMain">
  181. <Dragger {...FileProps}>
  182. <p className="ant-upload-drag-icon">
  183. <InboxOutlined rev={undefined} />
  184. </p>
  185. <br />
  186. <p className="ant-upload-text">
  187. 点击上传整个文件夹,或拖动多个文件至此上传
  188. </p>
  189. </Dragger>
  190. {/* 自定义 预览 下载 删除 */}
  191. <div className="myIncoBox">
  192. {fileList.map((v) => (
  193. <div className="myIncoRow" key={v.uid}>
  194. {v.percent === 100 && v.response && v.response.data ? (
  195. <>
  196. {authFilesLookFu(v.response.data.name) ? (
  197. <>
  198. {/* // 1.预览(name里面有常用的,浏览器能识别的 图片 音频 视频 模型) */}
  199. <div title="预览文件">
  200. <EyeOutlined
  201. rev={undefined}
  202. onClick={() =>
  203. authFilesLookFu(
  204. v.response.data.name,
  205. v.response.data.filePath
  206. )
  207. }
  208. />
  209. </div>
  210. </>
  211. ) : null}
  212. {/* // 2.下载 */}
  213. <div
  214. title="下载文件"
  215. onClick={() =>
  216. urlChangeFu(
  217. v.response.data.filePath,
  218. true,
  219. undefined,
  220. v.response.data.name
  221. )
  222. }
  223. >
  224. <DownloadOutlined rev={undefined} />
  225. </div>
  226. </>
  227. ) : (
  228. ""
  229. )}
  230. {/* 3.前面的序号 */}
  231. {/* <div className="mySortQ" hidden={fileList.length <= 1}>
  232. {i + 1}.
  233. </div> */}
  234. </div>
  235. ))}
  236. </div>
  237. </div>
  238. <div className="A1OUpBtn">
  239. <Popconfirm
  240. title="放弃编辑后,信息将不会保存!"
  241. okText="放弃"
  242. cancelText="取消"
  243. onConfirm={clickCloseFu}
  244. okButtonProps={{ loading: false }}
  245. >
  246. <Button>取消</Button>
  247. </Popconfirm>
  248. &emsp;
  249. <Button
  250. type="primary"
  251. onClick={btnOkFu}
  252. disabled={fileList.length <= 0}
  253. >
  254. 确定
  255. </Button>
  256. </div>
  257. {contextHolder}
  258. </Modal>
  259. );
  260. }
  261. const MemoA1OupFile = React.memo(A1OupFile);
  262. export default MemoA1OupFile;