@zjlab-fe/data-hub-ui 0.21.6 → 0.22.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (226) hide show
  1. package/dist/types/components/tip-tap/extensions/index.d.ts +1 -1
  2. package/es/assets/cardImg.png.js +3 -0
  3. package/es/assets/closeBtn.png.js +3 -0
  4. package/es/assets/icon-tag-header.png.js +3 -0
  5. package/es/assets/source.png.js +3 -0
  6. package/es/components/FileUploader/FileUploadModal.js +24 -0
  7. package/es/components/FileUploader/FileUploader.js +20 -0
  8. package/es/components/FileUploader/FileUploaderImpl/FileUploader.js +34 -0
  9. package/es/components/FileUploader/FileUploaderImpl/FileUploaderContextProvider.js +46 -0
  10. package/es/components/FileUploader/FileUploaderImpl/FileUploaderFileReceiver.css.js +36 -0
  11. package/es/components/FileUploader/FileUploaderImpl/FileUploaderFileReceiver.js +57 -0
  12. package/es/components/FileUploader/FileUploaderImpl/FileUploaderFileReceiverContainer.js +24 -0
  13. package/es/components/FileUploader/FileUploaderImpl/FileUploaderFileReceiverDesc.js +9 -0
  14. package/es/components/FileUploader/FileUploaderImpl/FileUploaderList.js +46 -0
  15. package/es/components/FileUploader/FileUploaderImpl/FileUploaderListItem.js +46 -0
  16. package/es/components/FileUploader/FileUploaderImpl/FileUploaderListItemFail.js +21 -0
  17. package/es/components/FileUploader/FileUploaderImpl/FileUploaderListItemPaused.js +20 -0
  18. package/es/components/FileUploader/FileUploaderImpl/FileUploaderListItemUploading.js +43 -0
  19. package/es/components/FileUploader/FileUploaderImpl/FileUploaderlListItemFinished.js +32 -0
  20. package/es/components/FileUploader/Locale/translations.js +52 -0
  21. package/es/components/FileUploader/Locale/useTranslate.js +16 -0
  22. package/es/components/FileUploader/UploadStoreProvider/UploadStoreProvider.js +31 -0
  23. package/es/components/FileUploader/UploadStoreProvider/uploadStoreReducer.js +62 -0
  24. package/es/components/FileUploader/UploadStoreProvider/useOnFileAllUploaded.js +31 -0
  25. package/es/components/FileUploader/UploadStoreProvider/useSaveUnfinishedUploads.js +42 -0
  26. package/es/components/FileUploader/UploadStoreProvider/useSetupMergingEvent.js +45 -0
  27. package/es/components/FileUploader/hooks/useCancelUpload.js +40 -0
  28. package/es/components/FileUploader/hooks/useCurrentFile.js +61 -0
  29. package/es/components/FileUploader/hooks/useCurrentFileOnUploading.js +52 -0
  30. package/es/components/FileUploader/hooks/useCurrentFileSetupAndBackUp.js +39 -0
  31. package/es/components/FileUploader/hooks/useFormatFiles.js +64 -0
  32. package/es/components/FileUploader/hooks/useFormatFilesFindDuplicates.js +75 -0
  33. package/es/components/FileUploader/hooks/useFormatFilesRemoveDuplicates.js +21 -0
  34. package/es/components/FileUploader/hooks/useHandleChunkCompletion.js +31 -0
  35. package/es/components/FileUploader/hooks/useOnMounted.js +24 -0
  36. package/es/components/FileUploader/hooks/useOnMountedResumeUnfinished.js +58 -0
  37. package/es/components/FileUploader/hooks/useRetryUpload.js +33 -0
  38. package/es/components/FileUploader/hooks/useUploadChunk.js +46 -0
  39. package/es/components/FileUploader/icons/CloseFilled.js +7 -0
  40. package/es/components/FileUploader/icons/UnkownFileIcon.js +7 -0
  41. package/es/components/FileUploader/icons/UploadIcon.js +7 -0
  42. package/es/components/FileUploader/index.css.js +532 -0
  43. package/es/components/FileUploader/index.js +23 -0
  44. package/es/components/FileUploader/types.js +13 -0
  45. package/es/components/FileUploader/utils/calcDisplaySize.js +20 -0
  46. package/es/components/FileUploader/utils/checkExpiryTime.js +15 -0
  47. package/es/components/FileUploader/utils/createFileToUpload.js +60 -0
  48. package/es/components/FileUploader/utils/fileDB/addFilesToIndexdb.js +14 -0
  49. package/es/components/FileUploader/utils/fileDB/deleteFileInStore.js +18 -0
  50. package/es/components/FileUploader/utils/fileDB/deleteObjectStore.js +25 -0
  51. package/es/components/FileUploader/utils/fileDB/index.js +77 -0
  52. package/es/components/FileUploader/utils/fileDB/openDBAndRetrieveData.js +90 -0
  53. package/es/components/FileUploader/utils/fileDB/retrieveExistingData.js +49 -0
  54. package/es/components/FileUploader/utils/modalConfig.css.js +20 -0
  55. package/es/components/FileUploader/utils/modalConfig.js +32 -0
  56. package/es/components/FileUploader/utils/retrieveAllFiles.js +70 -0
  57. package/es/components/FileUploader/utils/splitFileIntoChunk.js +15 -0
  58. package/es/components/SDK-modal/document-link.js +8 -0
  59. package/es/components/SDK-modal/index.js +25 -0
  60. package/es/components/SDK-modal/index.module.scss.js +49 -0
  61. package/es/components/SDK-modal/inner-modal.js +59 -0
  62. package/es/components/SDK-modal/locale/translations.js +17 -0
  63. package/es/components/apply-perm-modal/index.js +53 -0
  64. package/es/components/apply-perm-modal/index.module.scss.js +96 -0
  65. package/es/components/auth-tag/index.js +23 -0
  66. package/es/components/bench-card/index.js +20 -0
  67. package/es/components/bench-card/index.module.scss.js +48 -0
  68. package/es/components/confirm-again/index.js +15 -0
  69. package/es/components/confirm-again/index.scss.js +37 -0
  70. package/es/components/copy/index.js +41 -0
  71. package/es/components/copy/index.module.scss.js +15 -0
  72. package/es/components/corpus-card/index.js +88 -0
  73. package/es/components/corpus-card/index.module.scss.js +171 -0
  74. package/es/components/feature-card/classNames.js +72 -0
  75. package/es/components/feature-card/components.js +48 -0
  76. package/es/components/feature-card/context.js +13 -0
  77. package/es/components/feature-card/index.css.js +655 -0
  78. package/es/components/feature-card/index.js +48 -0
  79. package/es/components/file-preview/data-table/index.js +94 -0
  80. package/es/components/file-preview/data-table/index.module.scss.js +54 -0
  81. package/es/components/file-preview/excel-preview/index.js +132 -0
  82. package/es/components/file-preview/excel-preview/index.module.scss.js +11 -0
  83. package/es/components/file-preview/excel-preview/utils.js +46 -0
  84. package/es/components/file-preview/img-preview/index.js +18 -0
  85. package/es/components/file-preview/img-preview/index.module.scss.js +17 -0
  86. package/es/components/file-preview/index.js +124 -0
  87. package/es/components/file-preview/index.module.scss.js +32 -0
  88. package/es/components/file-preview/json-preview/index.js +166 -0
  89. package/es/components/file-preview/markdown-preview/index.js +53 -0
  90. package/es/components/file-preview/markdown-preview/index.module.scss.js +1055 -0
  91. package/es/components/file-preview/parquet-preview/index.js +54 -0
  92. package/es/components/file-preview/pdf-preview/index.js +215 -0
  93. package/es/components/file-preview/pdf-preview/index.module.scss.js +16 -0
  94. package/es/components/file-preview/table-preview/index.js +43 -0
  95. package/es/components/file-preview/table-preview/index.module.scss.js +11 -0
  96. package/es/components/file-preview/txt-preview/index.js +24 -0
  97. package/es/components/file-preview/util.js +94 -0
  98. package/es/components/file-uploader/components/circle-progress.css.js +39 -0
  99. package/es/components/file-uploader/components/circle-progress.js +12 -0
  100. package/es/components/file-uploader/components/hooks/use-drop-zone.js +74 -0
  101. package/es/components/file-uploader/components/hooks/use-file-validation.js +52 -0
  102. package/es/components/file-uploader/components/icons.js +19 -0
  103. package/es/components/file-uploader/components/theme.css.js +64 -0
  104. package/es/components/file-uploader/components/uploader-drop-zone.css.js +66 -0
  105. package/es/components/file-uploader/components/uploader-drop-zone.js +74 -0
  106. package/es/components/file-uploader/components/uploader-file-item.css.js +186 -0
  107. package/es/components/file-uploader/components/uploader-file-item.js +63 -0
  108. package/es/components/file-uploader/components/uploader-file-list.css.js +43 -0
  109. package/es/components/file-uploader/components/uploader-file-list.js +27 -0
  110. package/es/components/file-uploader/components/uploader.css.js +20 -0
  111. package/es/components/file-uploader/components/uploader.js +51 -0
  112. package/es/components/file-uploader/components/uploading-status.css.js +52 -0
  113. package/es/components/file-uploader/components/uploading-status.js +54 -0
  114. package/es/components/file-uploader/components/utils/directory-reader.js +65 -0
  115. package/es/components/file-uploader/constants.js +31 -0
  116. package/es/components/file-uploader/context/action-registry.js +69 -0
  117. package/es/components/file-uploader/context/file-state-store.js +83 -0
  118. package/es/components/file-uploader/context/handler-registry.js +119 -0
  119. package/es/components/file-uploader/context/upload-context.js +36 -0
  120. package/es/components/file-uploader/context/upload-provider.js +77 -0
  121. package/es/components/file-uploader/context/upload-reducer.js +21 -0
  122. package/es/components/file-uploader/context/use-upload-engine.js +440 -0
  123. package/es/components/file-uploader/engine/queue-callbacks.js +257 -0
  124. package/es/components/file-uploader/engine/queue-manager.js +195 -0
  125. package/es/components/file-uploader/engine/queue-uploader.js +25 -0
  126. package/es/components/file-uploader/hooks/use-upload.js +327 -0
  127. package/es/components/file-uploader/utils/chunk-handlers.js +66 -0
  128. package/es/components/file-uploader/utils/ensure-handlers.js +53 -0
  129. package/es/components/file-uploader/utils/error-handler.js +84 -0
  130. package/es/components/file-uploader/utils/upload-controllers.js +43 -0
  131. package/es/components/file-uploader/utils/upload-handler.js +68 -0
  132. package/es/components/file-uploader/utils/validate-handlers.js +16 -0
  133. package/es/components/floating-label-input/index.js +46 -0
  134. package/es/components/floating-label-input/index.module.scss.js +30 -0
  135. package/es/components/floating-layer/index.js +15 -0
  136. package/es/components/floating-layer/index.scss.js +31 -0
  137. package/es/components/header/index.js +10 -0
  138. package/es/components/header/index.module.scss.js +16 -0
  139. package/es/components/input-tag/index.js +65 -0
  140. package/es/components/menu/index.js +96 -0
  141. package/es/components/menu/index.module.scss.js +188 -0
  142. package/es/components/model-card/index.js +20 -0
  143. package/es/components/model-card/index.module.scss.js +116 -0
  144. package/es/components/notion-editor/code-block/index.js +18 -0
  145. package/es/components/notion-editor/code-block/languageDetector.js +134 -0
  146. package/es/components/notion-editor/code-block/languages.js +42 -0
  147. package/es/components/notion-editor/index.js +258 -0
  148. package/es/components/notion-editor/index.scss.js +421 -0
  149. package/es/components/notion-editor/parseMarkdown.js +184 -0
  150. package/es/components/operator-chain/components/AddButton.js +20 -0
  151. package/es/components/operator-chain/components/IOCard.js +8 -0
  152. package/es/components/operator-chain/components/SingleCard.js +12 -0
  153. package/es/components/operator-chain/components/VirtualDropdown.js +56 -0
  154. package/es/components/operator-chain/index.js +83 -0
  155. package/es/components/operator-chain/index.module.scss.js +232 -0
  156. package/es/components/permission-editor/index.js +9 -0
  157. package/es/components/permission-editor/permissionEditModal/index.js +37 -0
  158. package/es/components/permission-editor/permissionEditor/index.js +253 -0
  159. package/es/components/permission-editor/permissionEditor/index.module.scss.js +22 -0
  160. package/es/components/permission-editor/permissionViewPopover/index.js +9 -0
  161. package/es/components/popover-select/index.js +42 -0
  162. package/es/components/popover-select/index.module.scss.js +22 -0
  163. package/es/components/radio-card/index.js +24 -0
  164. package/es/components/radio-card/index.scss.js +58 -0
  165. package/es/components/section-heading/classNames.js +22 -0
  166. package/es/components/section-heading/components.js +27 -0
  167. package/es/components/section-heading/context.js +13 -0
  168. package/es/components/section-heading/index.css.js +648 -0
  169. package/es/components/section-heading/index.js +37 -0
  170. package/es/components/status-tag/index.js +31 -0
  171. package/es/components/tag-group-filter/dataSizeFilter.js +100 -0
  172. package/es/components/tag-group-filter/index.js +53 -0
  173. package/es/components/tag-group-filter/index.module.scss.js +134 -0
  174. package/es/components/tag-group-filter/tagFilter.js +19 -0
  175. package/es/components/tag-view/index.js +138 -0
  176. package/es/components/tag-view/index.module.scss.js +56 -0
  177. package/es/components/tag-view/useSize.js +41 -0
  178. package/es/components/tip-tap/bubble-menu.js +47 -0
  179. package/es/components/tip-tap/editor.js +34 -0
  180. package/es/components/tip-tap/extensions/index.js +133 -0
  181. package/es/components/tip-tap/extensions/markdown-paste.js +148 -0
  182. package/es/components/tip-tap/icons/index.js +29 -0
  183. package/es/components/tip-tap/reader.js +15 -0
  184. package/es/components/tip-tap/styles/editor.css.js +863 -0
  185. package/es/components/tip-tap/toolbar/components/color-picker.js +76 -0
  186. package/es/components/tip-tap/toolbar/components/heading-dropdown.js +44 -0
  187. package/es/components/tip-tap/toolbar/components/image-button.js +26 -0
  188. package/es/components/tip-tap/toolbar/components/link-button.js +107 -0
  189. package/es/components/tip-tap/toolbar/components/table-button.js +37 -0
  190. package/es/components/tip-tap/toolbar/components/toolbar-button.js +7 -0
  191. package/es/components/tip-tap/toolbar/index.js +39 -0
  192. package/es/components/uploadDrawer/UploadStoreProvider.js +61 -0
  193. package/es/components/uploadDrawer/fileUploadDrawer.js +66 -0
  194. package/es/components/uploadDrawer/fileUploadDrawerFileDragger.js +71 -0
  195. package/es/components/uploadDrawer/fileUploadDrawerList.js +54 -0
  196. package/es/components/uploadDrawer/fileUploadDrawerListProgressButton.js +54 -0
  197. package/es/components/uploadDrawer/hooks/useCancelUpload.js +37 -0
  198. package/es/components/uploadDrawer/hooks/useFilterFiles.js +107 -0
  199. package/es/components/uploadDrawer/hooks/useFinishUpload.js +33 -0
  200. package/es/components/uploadDrawer/hooks/useFormatFiles.js +54 -0
  201. package/es/components/uploadDrawer/hooks/useProgressButtonRef.js +22 -0
  202. package/es/components/uploadDrawer/hooks/useRemoveFilesInUploadQueue.js +21 -0
  203. package/es/components/uploadDrawer/hooks/useResumeUnfinishedUploads.js +52 -0
  204. package/es/components/uploadDrawer/hooks/useRetryUpload.js +35 -0
  205. package/es/components/uploadDrawer/hooks/useSaveUnfinishedUploads.js +42 -0
  206. package/es/components/uploadDrawer/hooks/useSetupUpload.js +80 -0
  207. package/es/components/uploadDrawer/hooks/useUploadFileToOSS.js +23 -0
  208. package/es/components/uploadDrawer/index.css.js +511 -0
  209. package/es/components/uploadDrawer/index.js +43 -0
  210. package/es/components/uploadDrawer/utils/calcDisplaySize.js +19 -0
  211. package/es/components/uploadDrawer/utils/constant.js +16 -0
  212. package/es/components/uploadDrawer/utils/createFileToUpload.js +51 -0
  213. package/es/components/uploadDrawer/utils/fileDB/deleteFileInStore.js +28 -0
  214. package/es/components/uploadDrawer/utils/fileDB/deleteObjectStore.js +28 -0
  215. package/es/components/uploadDrawer/utils/fileDB/handleAddFilesToDB.js +37 -0
  216. package/es/components/uploadDrawer/utils/fileDB/index.js +9 -0
  217. package/es/components/uploadDrawer/utils/fileDB/openDB.js +111 -0
  218. package/es/components/uploadDrawer/utils/retrieveAllFiles.js +110 -0
  219. package/es/components/uploadDrawer/utils/shouldCreateNewFile.js +13 -0
  220. package/es/components/uploadDrawer/utils/splitFileIntoChunk.js +15 -0
  221. package/es/index.js +42 -1
  222. package/es/lib/utils.js +8 -0
  223. package/lib/index.js +1 -1
  224. package/package.json +164 -154
  225. package/rollup.es.config.mjs +177 -0
  226. package/tsconfig.rollup.json +7 -0
@@ -0,0 +1,54 @@
1
+ import { jsx, Fragment } from 'react/jsx-runtime';
2
+ import { CheckOutlined, LoadingOutlined, CloseOutlined, PauseOutlined } from '@ant-design/icons';
3
+ import { Button, Progress } from 'antd';
4
+ import { useState } from 'react';
5
+ import { FILE_UPLOAD_STATUS } from './utils/constant.js';
6
+ import 'tslib';
7
+ import { useProgressButtonRef } from './hooks/useProgressButtonRef.js';
8
+
9
+ // 进度条样式属性
10
+ const progressStyleProps = {
11
+ size: 32,
12
+ strokeWidth: 12,
13
+ type: 'circle',
14
+ strokeLinecap: 'butt',
15
+ };
16
+ function FileUploadDrawerListProgressButton({ percent, status, onClick, }) {
17
+ // 使用自定义 hook 获取按钮引用和悬停状态
18
+ const { progressButtonRef, buttonInHover } = useProgressButtonRef();
19
+ // 状态用于跟踪是否正在取消上传
20
+ const [isCanceling, setIsCanceling] = useState(false);
21
+ // 根据不同的上传状态渲染不同的组件
22
+ if (status === FILE_UPLOAD_STATUS.FINISHED) {
23
+ // 上传完成时显示绿色对勾
24
+ return jsx(CheckOutlined, { className: "text-green-600 text-2xl h-8" });
25
+ }
26
+ if (status === FILE_UPLOAD_STATUS.FAILED) {
27
+ // 上传失败时显示红色叉号或加载图标
28
+ return (jsx(Fragment, { children: isCanceling ? (jsx(LoadingOutlined, { className: "text-red-600 text-2xl h-8" })) : (jsx(CloseOutlined, { className: "text-red-600 text-2xl h-8", onClick: () => {
29
+ onClick();
30
+ setIsCanceling(true);
31
+ } })) }));
32
+ }
33
+ // 默认情况下显示进度按钮
34
+ return (jsx(Button, { type: "text", shape: "circle", disabled: isCanceling, ref: progressButtonRef, title: status === FILE_UPLOAD_STATUS.PAUSED ? '继续下载' : '取消下载', onClick: () => {
35
+ onClick();
36
+ if (status === FILE_UPLOAD_STATUS.UPLOADING) {
37
+ setIsCanceling(true);
38
+ }
39
+ }, children: jsx(Progress, Object.assign({ percent: percent }, progressStyleProps, { strokeColor: isCanceling ? '#f0a020' : '#19a1fe', format: progressInner })) }));
40
+ // 根据不同状态渲染进度条内部的图标
41
+ function progressInner() {
42
+ if (status === FILE_UPLOAD_STATUS.PAUSED) {
43
+ return jsx(PauseOutlined, {});
44
+ }
45
+ if (isCanceling) {
46
+ return jsx(LoadingOutlined, { className: "text-yellow-500" });
47
+ }
48
+ if (buttonInHover) {
49
+ return jsx(CloseOutlined, {});
50
+ }
51
+ }
52
+ }
53
+
54
+ export { FileUploadDrawerListProgressButton as default };
@@ -0,0 +1,37 @@
1
+ import { __awaiter } from 'tslib';
2
+ import { FILE_UPLOAD_STATUS } from '../utils/constant.js';
3
+ import { deleteFileInStore } from '../utils/fileDB/deleteFileInStore.js';
4
+ import { useContext } from 'react';
5
+ import { UploadStoreDispatchContext } from '../UploadStoreProvider.js';
6
+ import { App } from 'antd';
7
+ import { FileUploadDrawerContext } from '../index.js';
8
+
9
+ function useCancelUpload() {
10
+ const { message } = App.useApp();
11
+ const { identifier, onCancelUpload } = useContext(FileUploadDrawerContext);
12
+ const uploadsDispatch = useContext(UploadStoreDispatchContext);
13
+ return function cancelUpload(file) {
14
+ return __awaiter(this, void 0, void 0, function* () {
15
+ const { fileName, uploadId } = file;
16
+ if (!uploadId) {
17
+ deleteFile(file);
18
+ return;
19
+ }
20
+ const result = yield onCancelUpload(fileName, uploadId);
21
+ if (result.status) {
22
+ deleteFile(file);
23
+ }
24
+ else {
25
+ message.error(result.reason || '取消失败');
26
+ }
27
+ });
28
+ };
29
+ function deleteFile(file) {
30
+ file.fileStatus = FILE_UPLOAD_STATUS.CANCELED;
31
+ deleteFileInStore(String(identifier), file.fileName);
32
+ Object.values(file.cancelControllers).forEach((cc) => cc.abort());
33
+ uploadsDispatch({ type: 'remove_file', identifier, file });
34
+ }
35
+ }
36
+
37
+ export { useCancelUpload };
@@ -0,0 +1,107 @@
1
+ import { __awaiter } from 'tslib';
2
+ import { App } from 'antd';
3
+ import { useContext } from 'react';
4
+ import { GB } from '../utils/constant.js';
5
+ import { calcDisplaySize } from '../utils/calcDisplaySize.js';
6
+ import { UploadStoreContext } from '../UploadStoreProvider.js';
7
+ import { FileUploadDrawerContext } from '../index.js';
8
+
9
+ /**
10
+ * useFilterFiles hook用于过滤上传文件
11
+ * 主要功能:
12
+ * 1. 检查文件大小是否超过限制
13
+ * 2. 检查是否有重复文件名
14
+ */
15
+ function useFilterFiles() {
16
+ const { message, modal } = App.useApp();
17
+ const uploadStore = useContext(UploadStoreContext);
18
+ const { identifier, maxSizePerFile = 10 * GB, uploadHistory = [], root, } = useContext(FileUploadDrawerContext);
19
+ return function filterFiles(files) {
20
+ return __awaiter(this, void 0, void 0, function* () {
21
+ // 获取超过大小限制的文件
22
+ const oversizedFiles = getOversizedFiles(files);
23
+ // 检查重复文件并询问用户是否覆盖
24
+ const [shouldOverwrite, duplicateFiles] = yield checkForDuplicates(files);
25
+ // 添加注释说明函数的返回值
26
+ // 返回值是一个元组,包含两个 Set:
27
+ // 1. 第一个 Set 包含需要移除的文件名(超大文件或用户选择不覆盖的重复文件)
28
+ // 2. 第二个 Set 包含用户选择覆盖的重复文件名
29
+ return shouldOverwrite
30
+ ? [new Set(oversizedFiles), new Set(duplicateFiles)]
31
+ : [new Set([...oversizedFiles, ...duplicateFiles]), new Set()];
32
+ });
33
+ };
34
+ /**
35
+ * 检查文件大小并返回超过限制的文件名列表
36
+ */
37
+ function getOversizedFiles(files) {
38
+ const oversizedFiles = files.filter((file) => file.size > maxSizePerFile).map((file) => file.name);
39
+ if (oversizedFiles.length) {
40
+ const maxSizeDisplay = calcDisplaySize(maxSizePerFile);
41
+ message.warning(`以下文件大小超过${maxSizeDisplay}:${oversizedFiles.join(', ')}`);
42
+ }
43
+ return oversizedFiles;
44
+ }
45
+ /**
46
+ * 检查重复文件并询问用户是否覆盖
47
+ * @returns [是否覆盖, 重复文件名列表]
48
+ */
49
+ function checkForDuplicates(files) {
50
+ return __awaiter(this, void 0, void 0, function* () {
51
+ const duplicateFiles = [
52
+ ...checkForDuplicatesInUploads(files, uploadStore[identifier], root),
53
+ ...checkForDuplicatesInUploadHistory(files, uploadHistory),
54
+ ];
55
+ // duplicateFiles 现在包含了所有重复的文件或文件夹的名称
56
+ if (duplicateFiles.length) {
57
+ const userChoice = yield modal.confirm({
58
+ title: '发现同名文件,是否覆盖?',
59
+ okText: '覆盖',
60
+ cancelText: '取消',
61
+ });
62
+ return [userChoice, duplicateFiles];
63
+ }
64
+ return [true, []];
65
+ });
66
+ }
67
+ }
68
+ function checkForDuplicatesInUploads(files, uploads, root) {
69
+ // 获取已存在的文件名集合
70
+ const existingFiles = new Set(uploads.map((f) => f.fileName));
71
+ // 检查新上传的文件是否与现有文件重名
72
+ const duplicateFiles = files
73
+ .filter((file) => {
74
+ const fileName = root ? `${root}${file.name}` : file.name;
75
+ return existingFiles.has(fileName);
76
+ })
77
+ .map((file) => file.name); // 最后,我们只保留重复文件的名称
78
+ return duplicateFiles;
79
+ }
80
+ function checkForDuplicatesInUploadHistory(files, uploadHistory) {
81
+ // const existingFiles = new Map<string, boolean>(uploadHistory.map(f => ([f.fileName, f.isFolder || false] as const)));
82
+ // 检查新上传的文件是否与现有文件重名
83
+ const duplicateFiles = files
84
+ .filter((file) => {
85
+ var _a;
86
+ // 判断当前文件是否为文件夹
87
+ // 如果文件名中包含 '/', 则认为它是一个文件夹
88
+ const isNewFileFolder = file.name.includes('/');
89
+ // 获取文件或文件夹的第一级名称
90
+ // 例如,对于 "folder/file.txt",我们只取 "folder"
91
+ const topLevelName = file.name.split('/')[0];
92
+ // 检查这个名称在已存在的文件列表中是否为文件夹
93
+ // existingFiles 是一个 Map,键是文件名,值是布尔值(true 表示文件夹,false 表示文件)
94
+ const isExistingFileFolder = (_a = uploadHistory.find((v) => v.fileName === topLevelName)) === null || _a === void 0 ? void 0 : _a.isFolder;
95
+ // 比较新文件和已存在文件的类型(文件夹或非文件夹)是否相同
96
+ if (isNewFileFolder === isExistingFileFolder) {
97
+ // 如果类型相同(都是文件夹或都不是文件夹),则认为是重复的
98
+ return true;
99
+ }
100
+ // 如果类型不同,则不是重复的
101
+ return false;
102
+ })
103
+ .map((file) => file.name); // 最后,我们只保留重复文件的名称
104
+ return duplicateFiles;
105
+ }
106
+
107
+ export { useFilterFiles };
@@ -0,0 +1,33 @@
1
+ import { __awaiter } from 'tslib';
2
+ import { useContext, useCallback } from 'react';
3
+ import { FILE_UPLOAD_STATUS } from '../utils/constant.js';
4
+ import { UploadStoreDispatchContext } from '../UploadStoreProvider.js';
5
+ import { FileUploadDrawerContext } from '../index.js';
6
+
7
+ function useFinishUpload() {
8
+ const { identifier, onAllPartDone } = useContext(FileUploadDrawerContext);
9
+ const uploadsDispatch = useContext(UploadStoreDispatchContext);
10
+ return useCallback((file) => __awaiter(this, void 0, void 0, function* () {
11
+ try {
12
+ const { fileName, uploadId } = file;
13
+ if (file.failSeq.length === 0) {
14
+ const result = yield onAllPartDone(fileName, uploadId);
15
+ if (!result.status) {
16
+ throw new Error(result.reason);
17
+ }
18
+ file.fileStatus = FILE_UPLOAD_STATUS.FINISHED;
19
+ }
20
+ else {
21
+ throw new Error('partial failed');
22
+ }
23
+ }
24
+ catch (e) {
25
+ file.fileStatus = FILE_UPLOAD_STATUS.FAILED;
26
+ }
27
+ finally {
28
+ uploadsDispatch({ type: 'edit_file', identifier, file });
29
+ }
30
+ }), [identifier, onAllPartDone, uploadsDispatch]);
31
+ }
32
+
33
+ export { useFinishUpload };
@@ -0,0 +1,54 @@
1
+ import { __awaiter } from 'tslib';
2
+ import { App } from 'antd';
3
+ import { useContext } from 'react';
4
+ import '../utils/constant.js';
5
+ import { createFileToUpload } from '../utils/createFileToUpload.js';
6
+ import { handleAddFilesToDB } from '../utils/fileDB/handleAddFilesToDB.js';
7
+ import { useFilterFiles } from './useFilterFiles.js';
8
+ import { useRemoveFilesInUploadQueue } from './useRemoveFilesInUploadQueue.js';
9
+ import { UploadStoreDispatchContext } from '../UploadStoreProvider.js';
10
+ import { FileUploadDrawerContext } from '../index.js';
11
+
12
+ function useFormatFiles() {
13
+ const { message } = App.useApp();
14
+ const { identifier, root, getUploadUrls } = useContext(FileUploadDrawerContext);
15
+ const uploadsDispatch = useContext(UploadStoreDispatchContext);
16
+ const filterFiles = useFilterFiles();
17
+ const removeFilesInUploadQueue = useRemoveFilesInUploadQueue();
18
+ return function formatFiles(allFiles) {
19
+ return __awaiter(this, void 0, void 0, function* () {
20
+ const filesToUpload = yield processFiles(allFiles);
21
+ const uploadableFiles = yield createUploadableFiles(filesToUpload);
22
+ updateUploadQueue(uploadableFiles);
23
+ handleAddFilesToDB(identifier, uploadableFiles);
24
+ if (uploadableFiles.length < filesToUpload.length) {
25
+ message.info('部分文件获取上传地址失败');
26
+ }
27
+ });
28
+ };
29
+ function processFiles(files) {
30
+ return __awaiter(this, void 0, void 0, function* () {
31
+ const fileMap = new Map(files.map((f) => [f.name, f]));
32
+ const [filesToRemove, duplicateFiles] = yield filterFiles(files);
33
+ filesToRemove.forEach((name) => fileMap.delete(name));
34
+ removeFilesInUploadQueue(duplicateFiles);
35
+ return Array.from(fileMap.values());
36
+ });
37
+ }
38
+ function createUploadableFiles(files) {
39
+ return __awaiter(this, void 0, void 0, function* () {
40
+ const promises = files.map((file) => createFileToUpload(file, root, getUploadUrls));
41
+ const results = yield Promise.allSettled(promises);
42
+ return results
43
+ .filter((r) => r.status === 'fulfilled')
44
+ .map((f) => f.value);
45
+ });
46
+ }
47
+ function updateUploadQueue(files) {
48
+ files.forEach((file) => {
49
+ uploadsDispatch({ type: 'add_file', identifier, file });
50
+ });
51
+ }
52
+ }
53
+
54
+ export { useFormatFiles };
@@ -0,0 +1,22 @@
1
+ import { useRef, useState, useEffect } from 'react';
2
+
3
+ function useProgressButtonRef() {
4
+ const progressButtonRef = useRef(null);
5
+ const [buttonInHover, setButtonInHover] = useState(false);
6
+ useEffect(() => {
7
+ const button = progressButtonRef.current;
8
+ if (!button)
9
+ return;
10
+ const inHover = () => setButtonInHover(true);
11
+ const outHover = () => setButtonInHover(false);
12
+ button.addEventListener('mouseenter', inHover);
13
+ button.addEventListener('mouseleave', outHover);
14
+ return () => {
15
+ button.removeEventListener('mouseenter', inHover);
16
+ button.removeEventListener('mouseleave', outHover);
17
+ };
18
+ }, []);
19
+ return { progressButtonRef, buttonInHover };
20
+ }
21
+
22
+ export { useProgressButtonRef };
@@ -0,0 +1,21 @@
1
+ import { useContext } from 'react';
2
+ import { UploadStoreContext } from '../UploadStoreProvider.js';
3
+ import { useCancelUpload } from './useCancelUpload.js';
4
+ import { FileUploadDrawerContext } from '../index.js';
5
+
6
+ function useRemoveFilesInUploadQueue() {
7
+ const uploadStore = useContext(UploadStoreContext);
8
+ const { identifier } = useContext(FileUploadDrawerContext);
9
+ const cancelUpload = useCancelUpload();
10
+ return function removeFilesInUploadQueue(duplicationOfName) {
11
+ const fileList = uploadStore[identifier];
12
+ for (const fileName of duplicationOfName) {
13
+ const upload = fileList.find((f) => f.fileName === fileName);
14
+ if (upload) {
15
+ cancelUpload(upload);
16
+ }
17
+ }
18
+ };
19
+ }
20
+
21
+ export { useRemoveFilesInUploadQueue };
@@ -0,0 +1,52 @@
1
+ import { __awaiter } from 'tslib';
2
+ import { useContext, useCallback } from 'react';
3
+ import { App } from 'antd';
4
+ import { UploadStoreDispatchContext } from '../UploadStoreProvider.js';
5
+ import { FILE_UPLOAD_STATUS } from '../utils/constant.js';
6
+ import { openDB } from '../utils/fileDB/openDB.js';
7
+ import { useRetryUpload } from './useRetryUpload.js';
8
+
9
+ function useResumeUnfinishedUploads(identifier) {
10
+ const { message, modal } = App.useApp();
11
+ const setUploadStore = useContext(UploadStoreDispatchContext);
12
+ const retryUpload = useRetryUpload();
13
+ return useCallback(() => __awaiter(this, void 0, void 0, function* () {
14
+ // 重新加载未完成的上传文件
15
+ const unfinishedFiles = yield reloadSaveData(identifier);
16
+ // 将未完成的文件添加到上传状态中
17
+ setUploadStore({ type: 'add_files', identifier, files: unfinishedFiles });
18
+ if (unfinishedFiles.length) {
19
+ // 如果有未完成的文件,显示确认对话框
20
+ modal.confirm({
21
+ title: '提示',
22
+ content: '检测到未完成上传任务,是否继续上传?',
23
+ onOk() {
24
+ // 用户确认继续上传,重试每个未完成的文件
25
+ unfinishedFiles.forEach(retryUpload);
26
+ },
27
+ onCancel() {
28
+ // 用户取消,显示提示信息
29
+ message.info('点击上传按钮手动继续');
30
+ },
31
+ });
32
+ }
33
+ }), [identifier, setUploadStore, retryUpload, modal, message]);
34
+ function reloadSaveData(identifier) {
35
+ return __awaiter(this, void 0, void 0, function* () {
36
+ // 从数据库获取文件信息
37
+ const filesFromDB = yield openDB(identifier);
38
+ // 从本地存储获取上传进度信息
39
+ const uploadsProgress = JSON.parse(localStorage.getItem(identifier) || '[]');
40
+ // 合并数据库文件信息和上传进度信息
41
+ const mergedSaveData = uploadsProgress.map((progressItem) => {
42
+ const matchingFile = filesFromDB.find((file) => file.fileName === progressItem.fileName);
43
+ return Object.assign(Object.assign(Object.assign({}, matchingFile), progressItem), { fileStatus: FILE_UPLOAD_STATUS.PAUSED });
44
+ });
45
+ // 清除本地存储中的数据
46
+ localStorage.removeItem(identifier);
47
+ return mergedSaveData;
48
+ });
49
+ }
50
+ }
51
+
52
+ export { useResumeUnfinishedUploads };
@@ -0,0 +1,35 @@
1
+ import { __awaiter } from 'tslib';
2
+ import { checkExpiryTime } from '../utils/shouldCreateNewFile.js';
3
+ import { NEW, FILE_UPLOAD_STATUS } from '../utils/constant.js';
4
+ import { createFileToUpload } from '../utils/createFileToUpload.js';
5
+ import { useContext, useCallback } from 'react';
6
+ import { UploadStoreDispatchContext } from '../UploadStoreProvider.js';
7
+ import { FileUploadDrawerContext } from '../index.js';
8
+
9
+ /**
10
+ * 自定义钩子函数,用于重试文件上传
11
+ */
12
+ function useRetryUpload() {
13
+ // 从上下文中获取必要的值和函数
14
+ const { identifier, root, getUploadUrls } = useContext(FileUploadDrawerContext);
15
+ const uploadsDispatch = useContext(UploadStoreDispatchContext);
16
+ // 使用 useCallback 优化性能
17
+ return useCallback((file) => __awaiter(this, void 0, void 0, function* () {
18
+ // 检查上传时间是否过期,决定是重新上传还是继续上传
19
+ const isUploadExpired = checkExpiryTime(file) === NEW;
20
+ if (isUploadExpired) {
21
+ // 如果上传时间已过期,创建新的文件上传对象
22
+ const newFile = yield createFileToUpload(file.raw, root, getUploadUrls);
23
+ // 更新上传状态
24
+ uploadsDispatch({ type: 'edit_file', identifier, file: newFile });
25
+ }
26
+ else {
27
+ // 如果上传时间未过期,更新现有文件的状态以继续上传
28
+ const updatedFile = Object.assign(Object.assign({}, file), { fileStatus: FILE_UPLOAD_STATUS.INIT, uploadUrls: [...file.failSeq, ...file.uploadUrls], failSeq: [], cancelControllers: {} });
29
+ // 更新上传状态
30
+ uploadsDispatch({ type: 'edit_file', identifier, file: updatedFile });
31
+ }
32
+ }), [identifier, root, getUploadUrls, uploadsDispatch]); // 依赖数组
33
+ }
34
+
35
+ export { useRetryUpload };
@@ -0,0 +1,42 @@
1
+ import { useEffect } from 'react';
2
+ import { FILE_UPLOAD_STATUS } from '../utils/constant.js';
3
+ import 'tslib';
4
+ import { deleteObjectStore } from '../utils/fileDB/deleteObjectStore.js';
5
+
6
+ function useSaveUnfinishedUploads(uploadStore) {
7
+ useEffect(() => {
8
+ window.addEventListener('beforeunload', saveUnfinishedUploads);
9
+ return () => {
10
+ window.removeEventListener('beforeunload', saveUnfinishedUploads);
11
+ };
12
+ function saveUnfinishedUploads() {
13
+ const emptyUploadKeys = [];
14
+ for (const [key, uploads] of Object.entries(uploadStore)) {
15
+ const unfinishedUploads = uploads.filter((upload) => upload.fileStatus !== FILE_UPLOAD_STATUS.FINISHED);
16
+ if (unfinishedUploads.length) {
17
+ localStorage.setItem(key, JSON.stringify(formatUnfinishedUploads(unfinishedUploads)));
18
+ }
19
+ else {
20
+ emptyUploadKeys.push(key);
21
+ }
22
+ }
23
+ if (emptyUploadKeys.length) {
24
+ deleteObjectStore(emptyUploadKeys);
25
+ }
26
+ }
27
+ }, [uploadStore]);
28
+ }
29
+ function formatUnfinishedUploads(uploads) {
30
+ return uploads.map(({ completeSeq, uploadId, uploadStatus, uploadUrls, percentage, fileName, failSeq }) => {
31
+ return {
32
+ fileName,
33
+ uploadId,
34
+ completeSeq,
35
+ uploadStatus,
36
+ percentage,
37
+ uploadUrls: [...uploadUrls, ...failSeq],
38
+ };
39
+ });
40
+ }
41
+
42
+ export { useSaveUnfinishedUploads };
@@ -0,0 +1,80 @@
1
+ import { __awaiter } from 'tslib';
2
+ import { useContext, useCallback } from 'react';
3
+ import axios from 'axios';
4
+ import { FILE_UPLOAD_STATUS } from '../utils/constant.js';
5
+ import { splitFileIntoChunk } from '../utils/splitFileIntoChunk.js';
6
+ import { UploadStoreDispatchContext } from '../UploadStoreProvider.js';
7
+ import { FileUploadDrawerContext } from '../index.js';
8
+
9
+ function useSetupUpload() {
10
+ const { identifier, onOnePartDone } = useContext(FileUploadDrawerContext);
11
+ const uploadsDispatch = useContext(UploadStoreDispatchContext);
12
+ const handleUploadProgress = useCallback((e, file, partNum) => {
13
+ if (file.fileStatus === FILE_UPLOAD_STATUS.UPLOADING) {
14
+ file.uploadStatus[partNum] = Number(e.progress);
15
+ file.percentage = file.uploadStatus.reduce((acc, curr) => acc + curr) * (100 / file.partCount);
16
+ uploadsDispatch({ type: 'edit_file', identifier, file });
17
+ }
18
+ }, [identifier, uploadsDispatch]);
19
+ const uploadChunk = useCallback((urlInfo, chunk, file) => __awaiter(this, void 0, void 0, function* () {
20
+ const axiosInstance = axios.create({});
21
+ yield axiosInstance.put(urlInfo.uploadUrl, chunk, {
22
+ signal: file.cancelControllers[urlInfo.partNum].signal,
23
+ withCredentials: false,
24
+ timeout: 60 * 10 * 3 * 1000,
25
+ headers: { 'Content-Type': 'application/octet-stream' },
26
+ onUploadProgress: throttled((e) => handleUploadProgress(e, file, urlInfo.partNum)),
27
+ });
28
+ }), [handleUploadProgress]);
29
+ const handlePartCompletion = useCallback((file, urlInfo) => __awaiter(this, void 0, void 0, function* () {
30
+ const { fileName, uploadId } = file;
31
+ const result = yield onOnePartDone(fileName, uploadId, urlInfo.partNum);
32
+ if (!result.status) {
33
+ throw new Error(result.reason);
34
+ }
35
+ updateFileStatus(file, urlInfo, 'complete');
36
+ }), [onOnePartDone]);
37
+ const putFile = useCallback((urlInfo, chunk, file) => __awaiter(this, void 0, void 0, function* () {
38
+ try {
39
+ yield uploadChunk(urlInfo, chunk, file);
40
+ yield handlePartCompletion(file, urlInfo);
41
+ return file.fileStatus;
42
+ }
43
+ catch (e) {
44
+ updateFileStatus(file, urlInfo, 'fail');
45
+ return file.fileStatus;
46
+ }
47
+ }), [uploadChunk, handlePartCompletion]);
48
+ const setupUpload = useCallback((file) => __awaiter(this, void 0, void 0, function* () {
49
+ file.fileStatus = FILE_UPLOAD_STATUS.UPLOADING;
50
+ uploadsDispatch({ type: 'edit_file', identifier, file });
51
+ const chunks = splitFileIntoChunk(file);
52
+ for (const { url, chunk } of chunks) {
53
+ file.cancelControllers[url.partNum] = new AbortController();
54
+ const newFileStatus = yield putFile(url, chunk, file);
55
+ if (newFileStatus === FILE_UPLOAD_STATUS.CANCELED) {
56
+ return false;
57
+ }
58
+ uploadsDispatch({ type: 'edit_file', identifier, file });
59
+ }
60
+ }), [identifier, uploadsDispatch, putFile]);
61
+ return setupUpload;
62
+ }
63
+ function throttled(fn, delay = 1000) {
64
+ let timer = null;
65
+ return function (arg) {
66
+ if (!timer) {
67
+ timer = setTimeout(() => {
68
+ fn(arg);
69
+ timer = null;
70
+ }, delay);
71
+ }
72
+ };
73
+ }
74
+ function updateFileStatus(file, urlInfo, status) {
75
+ const urlIndex = file.uploadUrls.findIndex((u) => u === urlInfo);
76
+ file.uploadUrls.splice(urlIndex, 1);
77
+ file[status === 'complete' ? 'completeSeq' : 'failSeq'].push(urlInfo);
78
+ }
79
+
80
+ export { useSetupUpload };
@@ -0,0 +1,23 @@
1
+ import { __awaiter } from 'tslib';
2
+ import { useCallback } from 'react';
3
+ import { FILE_UPLOAD_STATUS } from '../utils/constant.js';
4
+ import { useSetupUpload } from './useSetupUpload.js';
5
+ import { useFinishUpload } from './useFinishUpload.js';
6
+
7
+ function useUploadFileToOSS() {
8
+ const setupUpload = useSetupUpload();
9
+ const finishUpload = useFinishUpload();
10
+ const uploadFileToOSS = useCallback((file, onSuccess) => __awaiter(this, void 0, void 0, function* () {
11
+ yield setupUpload(file);
12
+ if (file.fileStatus === FILE_UPLOAD_STATUS.CANCELED) {
13
+ return;
14
+ }
15
+ yield finishUpload(file);
16
+ if (file.fileStatus === FILE_UPLOAD_STATUS.FINISHED) {
17
+ onSuccess && onSuccess(file);
18
+ }
19
+ }), [setupUpload, finishUpload]);
20
+ return uploadFileToOSS;
21
+ }
22
+
23
+ export { useUploadFileToOSS };