@spacecorexdev/core 0.0.2 → 0.0.5

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 (345) hide show
  1. package/package.json +20 -38
  2. package/public/cmaps/78-EUC-H.bcmap +0 -0
  3. package/public/cmaps/78-EUC-V.bcmap +0 -0
  4. package/public/cmaps/78-H.bcmap +0 -0
  5. package/public/cmaps/78-RKSJ-H.bcmap +0 -0
  6. package/public/cmaps/78-RKSJ-V.bcmap +0 -0
  7. package/public/cmaps/78-V.bcmap +0 -0
  8. package/public/cmaps/78ms-RKSJ-H.bcmap +0 -0
  9. package/public/cmaps/78ms-RKSJ-V.bcmap +0 -0
  10. package/public/cmaps/83pv-RKSJ-H.bcmap +0 -0
  11. package/public/cmaps/90ms-RKSJ-H.bcmap +0 -0
  12. package/public/cmaps/90ms-RKSJ-V.bcmap +0 -0
  13. package/public/cmaps/90msp-RKSJ-H.bcmap +0 -0
  14. package/public/cmaps/90msp-RKSJ-V.bcmap +0 -0
  15. package/public/cmaps/90pv-RKSJ-H.bcmap +0 -0
  16. package/public/cmaps/90pv-RKSJ-V.bcmap +0 -0
  17. package/public/cmaps/Add-H.bcmap +0 -0
  18. package/public/cmaps/Add-RKSJ-H.bcmap +0 -0
  19. package/public/cmaps/Add-RKSJ-V.bcmap +0 -0
  20. package/public/cmaps/Add-V.bcmap +0 -0
  21. package/public/cmaps/Adobe-CNS1-0.bcmap +0 -0
  22. package/public/cmaps/Adobe-CNS1-1.bcmap +0 -0
  23. package/public/cmaps/Adobe-CNS1-2.bcmap +0 -0
  24. package/public/cmaps/Adobe-CNS1-3.bcmap +0 -0
  25. package/public/cmaps/Adobe-CNS1-4.bcmap +0 -0
  26. package/public/cmaps/Adobe-CNS1-5.bcmap +0 -0
  27. package/public/cmaps/Adobe-CNS1-6.bcmap +0 -0
  28. package/public/cmaps/Adobe-CNS1-UCS2.bcmap +0 -0
  29. package/public/cmaps/Adobe-GB1-0.bcmap +0 -0
  30. package/public/cmaps/Adobe-GB1-1.bcmap +0 -0
  31. package/public/cmaps/Adobe-GB1-2.bcmap +0 -0
  32. package/public/cmaps/Adobe-GB1-3.bcmap +0 -0
  33. package/public/cmaps/Adobe-GB1-4.bcmap +0 -0
  34. package/public/cmaps/Adobe-GB1-5.bcmap +0 -0
  35. package/public/cmaps/Adobe-GB1-UCS2.bcmap +0 -0
  36. package/public/cmaps/Adobe-Japan1-0.bcmap +0 -0
  37. package/public/cmaps/Adobe-Japan1-1.bcmap +0 -0
  38. package/public/cmaps/Adobe-Japan1-2.bcmap +0 -0
  39. package/public/cmaps/Adobe-Japan1-3.bcmap +0 -0
  40. package/public/cmaps/Adobe-Japan1-4.bcmap +0 -0
  41. package/public/cmaps/Adobe-Japan1-5.bcmap +0 -0
  42. package/public/cmaps/Adobe-Japan1-6.bcmap +0 -0
  43. package/public/cmaps/Adobe-Japan1-UCS2.bcmap +0 -0
  44. package/public/cmaps/Adobe-Korea1-0.bcmap +0 -0
  45. package/public/cmaps/Adobe-Korea1-1.bcmap +0 -0
  46. package/public/cmaps/Adobe-Korea1-2.bcmap +0 -0
  47. package/public/cmaps/Adobe-Korea1-UCS2.bcmap +0 -0
  48. package/public/cmaps/B5-H.bcmap +0 -0
  49. package/public/cmaps/B5-V.bcmap +0 -0
  50. package/public/cmaps/B5pc-H.bcmap +0 -0
  51. package/public/cmaps/B5pc-V.bcmap +0 -0
  52. package/public/cmaps/CNS-EUC-H.bcmap +0 -0
  53. package/public/cmaps/CNS-EUC-V.bcmap +0 -0
  54. package/public/cmaps/CNS1-H.bcmap +0 -0
  55. package/public/cmaps/CNS1-V.bcmap +0 -0
  56. package/public/cmaps/CNS2-H.bcmap +0 -0
  57. package/public/cmaps/CNS2-V.bcmap +3 -0
  58. package/public/cmaps/ETHK-B5-H.bcmap +0 -0
  59. package/public/cmaps/ETHK-B5-V.bcmap +0 -0
  60. package/public/cmaps/ETen-B5-H.bcmap +0 -0
  61. package/public/cmaps/ETen-B5-V.bcmap +0 -0
  62. package/public/cmaps/ETenms-B5-H.bcmap +3 -0
  63. package/public/cmaps/ETenms-B5-V.bcmap +0 -0
  64. package/public/cmaps/EUC-H.bcmap +0 -0
  65. package/public/cmaps/EUC-V.bcmap +0 -0
  66. package/public/cmaps/Ext-H.bcmap +0 -0
  67. package/public/cmaps/Ext-RKSJ-H.bcmap +0 -0
  68. package/public/cmaps/Ext-RKSJ-V.bcmap +0 -0
  69. package/public/cmaps/Ext-V.bcmap +0 -0
  70. package/public/cmaps/GB-EUC-H.bcmap +0 -0
  71. package/public/cmaps/GB-EUC-V.bcmap +0 -0
  72. package/public/cmaps/GB-H.bcmap +4 -0
  73. package/public/cmaps/GB-V.bcmap +0 -0
  74. package/public/cmaps/GBK-EUC-H.bcmap +0 -0
  75. package/public/cmaps/GBK-EUC-V.bcmap +0 -0
  76. package/public/cmaps/GBK2K-H.bcmap +0 -0
  77. package/public/cmaps/GBK2K-V.bcmap +0 -0
  78. package/public/cmaps/GBKp-EUC-H.bcmap +0 -0
  79. package/public/cmaps/GBKp-EUC-V.bcmap +0 -0
  80. package/public/cmaps/GBT-EUC-H.bcmap +0 -0
  81. package/public/cmaps/GBT-EUC-V.bcmap +0 -0
  82. package/public/cmaps/GBT-H.bcmap +0 -0
  83. package/public/cmaps/GBT-V.bcmap +0 -0
  84. package/public/cmaps/GBTpc-EUC-H.bcmap +0 -0
  85. package/public/cmaps/GBTpc-EUC-V.bcmap +0 -0
  86. package/public/cmaps/GBpc-EUC-H.bcmap +0 -0
  87. package/public/cmaps/GBpc-EUC-V.bcmap +0 -0
  88. package/public/cmaps/H.bcmap +0 -0
  89. package/public/cmaps/HKdla-B5-H.bcmap +0 -0
  90. package/public/cmaps/HKdla-B5-V.bcmap +0 -0
  91. package/public/cmaps/HKdlb-B5-H.bcmap +0 -0
  92. package/public/cmaps/HKdlb-B5-V.bcmap +0 -0
  93. package/public/cmaps/HKgccs-B5-H.bcmap +0 -0
  94. package/public/cmaps/HKgccs-B5-V.bcmap +0 -0
  95. package/public/cmaps/HKm314-B5-H.bcmap +0 -0
  96. package/public/cmaps/HKm314-B5-V.bcmap +0 -0
  97. package/public/cmaps/HKm471-B5-H.bcmap +0 -0
  98. package/public/cmaps/HKm471-B5-V.bcmap +0 -0
  99. package/public/cmaps/HKscs-B5-H.bcmap +0 -0
  100. package/public/cmaps/HKscs-B5-V.bcmap +0 -0
  101. package/public/cmaps/Hankaku.bcmap +0 -0
  102. package/public/cmaps/Hiragana.bcmap +0 -0
  103. package/public/cmaps/KSC-EUC-H.bcmap +0 -0
  104. package/public/cmaps/KSC-EUC-V.bcmap +0 -0
  105. package/public/cmaps/KSC-H.bcmap +0 -0
  106. package/public/cmaps/KSC-Johab-H.bcmap +0 -0
  107. package/public/cmaps/KSC-Johab-V.bcmap +0 -0
  108. package/public/cmaps/KSC-V.bcmap +0 -0
  109. package/public/cmaps/KSCms-UHC-H.bcmap +0 -0
  110. package/public/cmaps/KSCms-UHC-HW-H.bcmap +0 -0
  111. package/public/cmaps/KSCms-UHC-HW-V.bcmap +0 -0
  112. package/public/cmaps/KSCms-UHC-V.bcmap +0 -0
  113. package/public/cmaps/KSCpc-EUC-H.bcmap +0 -0
  114. package/public/cmaps/KSCpc-EUC-V.bcmap +0 -0
  115. package/public/cmaps/Katakana.bcmap +0 -0
  116. package/public/cmaps/LICENSE +36 -0
  117. package/public/cmaps/NWP-H.bcmap +0 -0
  118. package/public/cmaps/NWP-V.bcmap +0 -0
  119. package/public/cmaps/RKSJ-H.bcmap +0 -0
  120. package/public/cmaps/RKSJ-V.bcmap +0 -0
  121. package/public/cmaps/Roman.bcmap +0 -0
  122. package/public/cmaps/UniCNS-UCS2-H.bcmap +0 -0
  123. package/public/cmaps/UniCNS-UCS2-V.bcmap +0 -0
  124. package/public/cmaps/UniCNS-UTF16-H.bcmap +0 -0
  125. package/public/cmaps/UniCNS-UTF16-V.bcmap +0 -0
  126. package/public/cmaps/UniCNS-UTF32-H.bcmap +0 -0
  127. package/public/cmaps/UniCNS-UTF32-V.bcmap +0 -0
  128. package/public/cmaps/UniCNS-UTF8-H.bcmap +0 -0
  129. package/public/cmaps/UniCNS-UTF8-V.bcmap +0 -0
  130. package/public/cmaps/UniGB-UCS2-H.bcmap +0 -0
  131. package/public/cmaps/UniGB-UCS2-V.bcmap +0 -0
  132. package/public/cmaps/UniGB-UTF16-H.bcmap +0 -0
  133. package/public/cmaps/UniGB-UTF16-V.bcmap +0 -0
  134. package/public/cmaps/UniGB-UTF32-H.bcmap +0 -0
  135. package/public/cmaps/UniGB-UTF32-V.bcmap +0 -0
  136. package/public/cmaps/UniGB-UTF8-H.bcmap +0 -0
  137. package/public/cmaps/UniGB-UTF8-V.bcmap +0 -0
  138. package/public/cmaps/UniJIS-UCS2-H.bcmap +0 -0
  139. package/public/cmaps/UniJIS-UCS2-HW-H.bcmap +0 -0
  140. package/public/cmaps/UniJIS-UCS2-HW-V.bcmap +0 -0
  141. package/public/cmaps/UniJIS-UCS2-V.bcmap +0 -0
  142. package/public/cmaps/UniJIS-UTF16-H.bcmap +0 -0
  143. package/public/cmaps/UniJIS-UTF16-V.bcmap +0 -0
  144. package/public/cmaps/UniJIS-UTF32-H.bcmap +0 -0
  145. package/public/cmaps/UniJIS-UTF32-V.bcmap +0 -0
  146. package/public/cmaps/UniJIS-UTF8-H.bcmap +0 -0
  147. package/public/cmaps/UniJIS-UTF8-V.bcmap +0 -0
  148. package/public/cmaps/UniJIS2004-UTF16-H.bcmap +0 -0
  149. package/public/cmaps/UniJIS2004-UTF16-V.bcmap +0 -0
  150. package/public/cmaps/UniJIS2004-UTF32-H.bcmap +0 -0
  151. package/public/cmaps/UniJIS2004-UTF32-V.bcmap +0 -0
  152. package/public/cmaps/UniJIS2004-UTF8-H.bcmap +0 -0
  153. package/public/cmaps/UniJIS2004-UTF8-V.bcmap +0 -0
  154. package/public/cmaps/UniJISPro-UCS2-HW-V.bcmap +0 -0
  155. package/public/cmaps/UniJISPro-UCS2-V.bcmap +0 -0
  156. package/public/cmaps/UniJISPro-UTF8-V.bcmap +0 -0
  157. package/public/cmaps/UniJISX0213-UTF32-H.bcmap +0 -0
  158. package/public/cmaps/UniJISX0213-UTF32-V.bcmap +0 -0
  159. package/public/cmaps/UniJISX02132004-UTF32-H.bcmap +0 -0
  160. package/public/cmaps/UniJISX02132004-UTF32-V.bcmap +0 -0
  161. package/public/cmaps/UniKS-UCS2-H.bcmap +0 -0
  162. package/public/cmaps/UniKS-UCS2-V.bcmap +0 -0
  163. package/public/cmaps/UniKS-UTF16-H.bcmap +0 -0
  164. package/public/cmaps/UniKS-UTF16-V.bcmap +0 -0
  165. package/public/cmaps/UniKS-UTF32-H.bcmap +0 -0
  166. package/public/cmaps/UniKS-UTF32-V.bcmap +0 -0
  167. package/public/cmaps/UniKS-UTF8-H.bcmap +0 -0
  168. package/public/cmaps/UniKS-UTF8-V.bcmap +0 -0
  169. package/public/cmaps/V.bcmap +0 -0
  170. package/public/cmaps/WP-Symbol.bcmap +0 -0
  171. package/public/polyfills/polyfills.js +802 -0
  172. package/public/vendor/docx/docx.worker.js +5 -0
  173. package/public/vendor/docx/jszip.min.js +13 -0
  174. package/public/vendor/libarchive/libarchive.wasm +0 -0
  175. package/public/vendor/libarchive/worker-bundle.js +6 -0
  176. package/public/vendor/pptx/pptx.worker.js +26 -0
  177. package/public/wasm/cad/0.8.2/dwfv-render.wasm +0 -0
  178. package/public/wasm/cad/0.8.2/dwg-worker.js +24 -0
  179. package/public/wasm/cad/0.8.2/dwg-worker.js.map +1 -0
  180. package/public/wasm/cad/0.8.2/libredwg-web.js +2 -0
  181. package/public/wasm/cad/0.8.2/libredwg-web.wasm +0 -0
  182. package/public/wasm/cad/dwfv-render.wasm +0 -0
  183. package/public/wasm/cad/dwg-worker.js +24 -0
  184. package/public/wasm/cad/dwg-worker.js.map +1 -0
  185. package/public/wasm/cad/libredwg-web.js +2 -0
  186. package/public/wasm/cad/libredwg-web.wasm +0 -0
  187. package/public/wasm/data/sql-wasm.wasm +0 -0
  188. package/public/wasm/hdiff.wasm +0 -0
  189. package/public/wasm/model/LICENSE.occt-import-js.txt +504 -0
  190. package/public/wasm/model/LICENSE.occt.txt +502 -0
  191. package/public/wasm/model/occt-import-js.js +19 -0
  192. package/public/wasm/model/occt-import-js.wasm +0 -0
  193. package/public/wasm/model/occt-worker.js +83 -0
  194. package/public/wasm/typst/fonts/DejaVuSansMono-Bold.ttf +0 -0
  195. package/public/wasm/typst/fonts/DejaVuSansMono-BoldOblique.ttf +0 -0
  196. package/public/wasm/typst/fonts/DejaVuSansMono-Oblique.ttf +0 -0
  197. package/public/wasm/typst/fonts/DejaVuSansMono.ttf +0 -0
  198. package/public/wasm/typst/fonts/LibertinusSerif-Bold.otf +0 -0
  199. package/public/wasm/typst/fonts/LibertinusSerif-BoldItalic.otf +0 -0
  200. package/public/wasm/typst/fonts/LibertinusSerif-Italic.otf +0 -0
  201. package/public/wasm/typst/fonts/LibertinusSerif-Regular.otf +0 -0
  202. package/public/wasm/typst/fonts/LibertinusSerif-Semibold.otf +0 -0
  203. package/public/wasm/typst/fonts/LibertinusSerif-SemiboldItalic.otf +0 -0
  204. package/public/wasm/typst/fonts/NewCM10-Bold.otf +0 -0
  205. package/public/wasm/typst/fonts/NewCM10-BoldItalic.otf +0 -0
  206. package/public/wasm/typst/fonts/NewCM10-Italic.otf +0 -0
  207. package/public/wasm/typst/fonts/NewCM10-Regular.otf +0 -0
  208. package/public/wasm/typst/fonts/NewCMMath-Bold.otf +0 -0
  209. package/public/wasm/typst/fonts/NewCMMath-Book.otf +0 -0
  210. package/public/wasm/typst/fonts/NewCMMath-Regular.otf +0 -0
  211. package/public/wasm/typst/fonts/README.md +7 -0
  212. package/public/wasm/typst/typst_ts_renderer_bg.wasm +0 -0
  213. package/public/wasm/typst/typst_ts_web_compiler_bg.wasm +0 -0
  214. package/scripts/patch-docx-grid.cjs +412 -0
  215. package/src/api/_base.ts +243 -0
  216. package/src/api/index.ts +17 -0
  217. package/src/api/project.ts +1345 -0
  218. package/src/api/user.ts +1174 -0
  219. package/src/contract.ts +50 -0
  220. package/src/hooks/index.ts +2 -0
  221. package/{dist/hooks/index.js → src/hooks/useLongPress.ts} +53 -49
  222. package/src/hooks/useOnlineStatus.ts +22 -0
  223. package/src/index.ts +14 -0
  224. package/src/types/id.ts +2 -0
  225. package/src/types/index.ts +5 -0
  226. package/src/types/project/base.ts +63 -0
  227. package/src/types/project/contract.ts +79 -0
  228. package/src/types/project/contractStatus.tsx +15 -0
  229. package/src/types/project/index.ts +5 -0
  230. package/src/types/project/member.ts +46 -0
  231. package/src/types/project/progress.ts +43 -0
  232. package/src/types/projectRole.ts +17 -0
  233. package/src/types/theme.ts +1 -0
  234. package/src/types/user/index.ts +1 -0
  235. package/src/types/user/role.ts +7 -0
  236. package/src/ui/CommentTimeline/index.tsx +330 -0
  237. package/src/ui/FileManager/FileContextMenu.tsx +628 -0
  238. package/src/ui/FileManager/FileGridView.tsx +529 -0
  239. package/src/ui/FileManager/FileTableView.tsx +405 -0
  240. package/src/ui/FileManager/FileToolbar.tsx +119 -0
  241. package/src/ui/FileManager/FileVersionHistoryModal.tsx +175 -0
  242. package/src/ui/FileManager/MoveCopyToProjectModal.tsx +119 -0
  243. package/src/ui/FileManager/ShareToWechatModal.tsx +419 -0
  244. package/src/ui/FileManager/hooks/useFileManagerActions.ts +2532 -0
  245. package/src/ui/FileManager/hooks/useFileManagerState.ts +419 -0
  246. package/src/ui/FileManager/index.tsx +580 -0
  247. package/src/ui/FileManager/projectFileManagerApi.ts +57 -0
  248. package/src/ui/FileManager/types.ts +184 -0
  249. package/src/ui/FileManager/utils/fileDeltaWorker.ts +193 -0
  250. package/src/ui/FileManager/utils/fileTree.ts +178 -0
  251. package/src/ui/FileManager/utils/fileUpload.ts +714 -0
  252. package/src/ui/FileManager/utils/fileUtils.ts +65 -0
  253. package/src/ui/InvoiceRecordsList/index.tsx +813 -0
  254. package/src/ui/MyFileSelectorModal.tsx +261 -0
  255. package/src/ui/ProjectSelector/index.tsx +472 -0
  256. package/src/ui/ProjectSelector/projectCache.ts +40 -0
  257. package/src/ui/RoleSelector/index.tsx +473 -0
  258. package/src/ui/RoleSelector/roleCache.ts +40 -0
  259. package/src/ui/UIAlert.tsx +399 -0
  260. package/src/ui/UIAlertExample.tsx +129 -0
  261. package/src/ui/UIConfirm.tsx +335 -0
  262. package/src/ui/UIConfirmExample.tsx +165 -0
  263. package/src/ui/UIDatePicker.tsx +146 -0
  264. package/src/ui/UIDateRangePicker.tsx +38 -0
  265. package/src/ui/UIFilePreview/ExcelEditor/index.tsx +617 -0
  266. package/src/ui/UIFilePreview/ExcelEditor/types.ts +24 -0
  267. package/src/ui/UIFilePreview/ExportDropdown.css +85 -0
  268. package/src/ui/UIFilePreview/ExportDropdown.tsx +109 -0
  269. package/src/ui/UIFilePreview/IndexedDBUtils.ts +564 -0
  270. package/src/ui/UIFilePreview/MarkdownEditor/exportMarkdownPdf.ts +576 -0
  271. package/src/ui/UIFilePreview/MarkdownEditor/index.tsx +677 -0
  272. package/src/ui/UIFilePreview/MarkdownEditor/markdownEditor.css +1005 -0
  273. package/src/ui/UIFilePreview/MarkdownEditor/types.ts +15 -0
  274. package/src/ui/UIFilePreview/PPTXEditor/index.tsx +602 -0
  275. package/src/ui/UIFilePreview/RichDocEditor/exportRDocMarkdown.ts +77 -0
  276. package/src/ui/UIFilePreview/RichDocEditor/exportRDocPdf.ts +374 -0
  277. package/src/ui/UIFilePreview/RichDocEditor/index.tsx +730 -0
  278. package/src/ui/UIFilePreview/RichDocEditor/richdoc-editor.css +59 -0
  279. package/src/ui/UIFilePreview/UIFilePreview.tsx +611 -0
  280. package/src/ui/UIFilePreview/WordEditor/index.tsx +3933 -0
  281. package/src/ui/UIFilePreview/WordEditor/style.ts +1213 -0
  282. package/src/ui/UIFilePreview/WordEditor/word-editor.css +999 -0
  283. package/src/ui/UIFilePreview/filePreview.css +193 -0
  284. package/src/ui/UIFilePreview/filetypes/archive.tsx +66 -0
  285. package/src/ui/UIFilePreview/filetypes/cad.tsx +287 -0
  286. package/src/ui/UIFilePreview/filetypes/excel.tsx +355 -0
  287. package/src/ui/UIFilePreview/filetypes/image.tsx +20 -0
  288. package/src/ui/UIFilePreview/filetypes/imageLoader.ts +63 -0
  289. package/src/ui/UIFilePreview/filetypes/pdf.tsx +156 -0
  290. package/src/ui/UIFilePreview/filetypes/ppt.tsx +535 -0
  291. package/src/ui/UIFilePreview/filetypes/pptExportPdf.ts +523 -0
  292. package/src/ui/UIFilePreview/filetypes/video.tsx +482 -0
  293. package/src/ui/UIFilePreview/filetypes/word.tsx +245 -0
  294. package/src/ui/UIFilePreview/filetypes/wordExportMarkdown.ts +86 -0
  295. package/src/ui/UIFilePreview/filetypes/wordExportPdf.tsx +427 -0
  296. package/src/ui/UIFilePreview/index.ts +35 -0
  297. package/src/ui/UIFilePreview/pdfPagination.ts +143 -0
  298. package/src/ui/UIFilePreview/previewUtils.tsx +531 -0
  299. package/src/ui/UIFileUpload.tsx +382 -0
  300. package/src/ui/UIImageUpload.tsx +195 -0
  301. package/src/ui/UILoading.tsx +255 -0
  302. package/src/ui/UILoadingExample.tsx +139 -0
  303. package/src/ui/UISelect.tsx +105 -0
  304. package/src/ui/UIToast.tsx +381 -0
  305. package/src/ui/UIToastExample.tsx +69 -0
  306. package/src/ui/UIToastSingle.tsx +279 -0
  307. package/src/ui/UIViewToggle.tsx +64 -0
  308. package/src/ui/UserSelector/index.tsx +583 -0
  309. package/src/ui/index.ts +84 -0
  310. package/src/ui/upload/image.ts +135 -0
  311. package/src/ui/upload/index.ts +73 -0
  312. package/src/ui/upload/submitFile.ts +106 -0
  313. package/src/ui/upload/submitForm.ts +124 -0
  314. package/src/ui/upload/upload.err.ts +15 -0
  315. package/src/ui/upload/upload.ts +250 -0
  316. package/src/utils/CacheDepartmentInfo.ts +372 -0
  317. package/src/utils/CacheFileContent.ts +315 -0
  318. package/src/utils/CachePermissionInfo.ts +235 -0
  319. package/src/utils/CacheRoleInfo.ts +303 -0
  320. package/src/utils/CacheUserInfo.ts +818 -0
  321. package/src/utils/CacheViewToggleInfo.ts +182 -0
  322. package/src/utils/MessageContentUtils.ts +268 -0
  323. package/src/utils/clipboard.ts +70 -0
  324. package/src/utils/companyEmail.ts +19 -0
  325. package/src/utils/forbidDebugger.ts +59 -0
  326. package/src/utils/formatters.ts +94 -0
  327. package/src/utils/htmlUtils.tsx +59 -0
  328. package/src/utils/index.ts +18 -0
  329. package/src/utils/keyboard.ts +114 -0
  330. package/src/utils/mammothApi.ts +16 -0
  331. package/src/utils/polyfills.ts +928 -0
  332. package/src/utils/regex.ts +14 -0
  333. package/src/utils/storage.ts +95 -0
  334. package/src/utils/workerBootstrap.ts +87 -0
  335. package/dist/api/index.js +0 -1553
  336. package/dist/contract.js +0 -5
  337. package/dist/index.js +0 -4492
  338. package/dist/types/index.js +0 -49
  339. package/dist/ui/index.css +0 -1876
  340. package/dist/ui/index.js +0 -22245
  341. package/dist/utils/index.js +0 -4296
  342. /package/{dist → src}/styles/ant-modal.css +0 -0
  343. /package/{dist → src}/styles/ant-spin.css +0 -0
  344. /package/{dist → src}/styles/ant-table.css +0 -0
  345. /package/{dist → src}/styles/index.css +0 -0
@@ -0,0 +1,580 @@
1
+ import React, { useEffect, useRef, useMemo } from 'react';
2
+ import { useSearchParams } from 'react-router-dom';
3
+ import { Card, Modal, Input, Checkbox, Button, Spin } from 'antd';
4
+ import { ProjectRole, ProjectFile, FileManagerApi, FileManagerFeatures, FileSortBy } from './types';
5
+ import { ArrowLeftOutlined } from '@ant-design/icons';
6
+ import { projectFileManagerApi } from './projectFileManagerApi';
7
+ import { UIFilePreview } from '../UIFilePreview/index';
8
+ import { useEffectResize } from '../../utils/htmlUtils';
9
+ import { getViewMode, setViewMode as saveViewMode } from '../../utils/CacheViewToggleInfo';
10
+ import { buildFileTree, sortFiles } from './utils/fileTree';
11
+ import { FileTableView } from './FileTableView';
12
+ import { FileGridView } from './FileGridView';
13
+ import { FileToolbar } from './FileToolbar';
14
+ import { FileContextMenu } from './FileContextMenu';
15
+ import { MoveCopyToProjectModal } from './MoveCopyToProjectModal';
16
+ import { FileVersionHistoryModal } from './FileVersionHistoryModal';
17
+ import { ShareToWechatModal } from './ShareToWechatModal';
18
+ import { useFileManagerState } from './hooks/useFileManagerState';
19
+ import { useFileManagerActions } from './hooks/useFileManagerActions';
20
+
21
+ const PAGE_KEY = 'file-manager';
22
+ const FILE_DESCS_MAX_LENGTH = 255;
23
+
24
+ /** 在文件树中按 id 查找节点 */
25
+ const findNodeInTree = (items: ProjectFile[], id: string): ProjectFile | undefined => {
26
+ for (const item of items) {
27
+ if (item.id === id) return item;
28
+ if (item.children && item.children.length > 0) {
29
+ const found = findNodeInTree(item.children, id);
30
+ if (found) return found;
31
+ }
32
+ }
33
+ return undefined;
34
+ };
35
+
36
+ interface FileManagerProps {
37
+ projectId: string;
38
+ fileId?: string | null;
39
+ currentUserRole: ProjectRole | null;
40
+ /** 当前文件 tab 是否处于激活状态:重新激活时刷新文件列表(例如在合同 tab 新建合同后切回) */
41
+ isActive?: boolean;
42
+ className?: string;
43
+ /** 数据接口适配器,缺省为项目文件 API(CRM 等场景注入自定义实现) */
44
+ api?: FileManagerApi;
45
+ /** 功能开关,缺省全部开启(合同、跨项目移动复制、微信分享、版本历史、外部预览链接) */
46
+ features?: FileManagerFeatures;
47
+ }
48
+
49
+ export const FileManager: React.FC<FileManagerProps> = ({
50
+ projectId,
51
+ currentUserRole,
52
+ isActive = true,
53
+ className,
54
+ api: apiProp,
55
+ features: featuresProp,
56
+ }) => {
57
+ const [searchParams, setSearchParams] = useSearchParams();
58
+ const [state, actions] = useFileManagerState();
59
+
60
+ // 数据接口与功能开关:解析缺省值并计算各功能入口是否可用
61
+ const resolvedApi = apiProp || projectFileManagerApi;
62
+ const features = useMemo(() => featuresProp || {}, [featuresProp]);
63
+ const enableContracts = features.contracts !== false;
64
+ const enableMoveCopyToProject = features.moveCopyToProject !== false;
65
+ const enableShareToWechat = features.shareToWechat !== false;
66
+ const enableVersionHistory = features.versionHistory !== false;
67
+ const enableExternalLink = features.externalLink !== false;
68
+ const hasTempAccessToken = !!resolvedApi.generateTempAccessToken;
69
+ const hasCopyFileToProject = !!resolvedApi.copyFileToProject;
70
+
71
+ const hookOptions = useMemo(() => ({ api: resolvedApi, features }), [resolvedApi, features]);
72
+ // 预览时按当前适配器查询文件详情(CRM 场景走 /api/crm/file/detail,而非项目文件接口)
73
+ const fetchFileDetail = useMemo(
74
+ () => (fileId: string) => resolvedApi.getDetail(fileId),
75
+ [resolvedApi],
76
+ );
77
+ const fileManagerActions = useFileManagerActions(projectId, currentUserRole, state, actions, hookOptions);
78
+ const fileManagerActionsRef = useRef(fileManagerActions);
79
+ fileManagerActionsRef.current = fileManagerActions;
80
+
81
+ const currentFileId = searchParams.get('fileid');
82
+ const dragUploadProgressPercent = state.dragUploadPercent === undefined ? 0 : Math.min(100, Math.round(state.dragUploadPercent * 100));
83
+
84
+ useEffect(() => {
85
+ const { initUserRole, loadFiles } = fileManagerActionsRef.current;
86
+ initUserRole();
87
+ loadFiles();
88
+ }, [projectId]);
89
+
90
+ // 从其他 tab(如合同 tab)切回文件视图时刷新列表,确保新建/变更的合同文件夹能及时显示
91
+ const isActiveRef = useRef(isActive);
92
+ useEffect(() => {
93
+ if (isActive && !isActiveRef.current) {
94
+ fileManagerActionsRef.current.loadFiles();
95
+ }
96
+ isActiveRef.current = isActive;
97
+ }, [isActive]);
98
+
99
+ useEffect(() => {
100
+ if (currentFileId && state.files.length > 0) {
101
+ const file = state.files.find(f => f.id === currentFileId);
102
+ if (file && file.fileType !== 'folder') {
103
+ actions.setPreviewFileName(file.fileName);
104
+ actions.setPreviewUrl(file.fileResourcePath);
105
+ actions.setPreviewVisible(true);
106
+ }
107
+ }
108
+ }, [currentFileId, state.files]);
109
+
110
+ // 当 URL 中无 fileid 时关闭预览(如用户后退导航)。
111
+ // 仅依赖 currentFileId,不依赖 state.previewVisible —— 否则 handlePreview
112
+ // 设置 previewVisible=true 后,若 setSearchParams 尚未同步到 currentFileId,
113
+ // 此 effect 会把 previewVisible 重置为 false,导致首次请求被 abort。
114
+ const previewVisibleRef = useRef(state.previewVisible);
115
+ previewVisibleRef.current = state.previewVisible;
116
+ useEffect(() => {
117
+ if (!currentFileId && previewVisibleRef.current) {
118
+ actions.setPreviewVisible(false);
119
+ actions.setPreviewUrl(null);
120
+ actions.setPreviewingFile(null);
121
+ }
122
+ // eslint-disable-next-line react-hooks/exhaustive-deps
123
+ }, [currentFileId]);
124
+
125
+ useEffectResize(() => {
126
+ actions.setSmallView(true);
127
+ actions.setViewMode('grid');
128
+ }, () => {
129
+ actions.setSmallView(false);
130
+ actions.setViewMode('table');
131
+ }, 500);
132
+
133
+ useEffect(() => {
134
+ const loadCachedViewMode = async () => {
135
+ const cached = await getViewMode(PAGE_KEY);
136
+ if (cached && (cached === 'grid' || cached === 'table')) {
137
+ actions.setViewMode(cached);
138
+ }
139
+ };
140
+ loadCachedViewMode();
141
+ }, []);
142
+
143
+ // 排序切换处理:相同字段切换顺序,不同字段设为升序
144
+ const handleSortByChange = (by: FileSortBy) => {
145
+ if (by === state.sortBy) {
146
+ actions.setSortOrder(state.sortOrder === 'asc' ? 'desc' : 'asc');
147
+ } else {
148
+ actions.setSortBy(by);
149
+ actions.setSortOrder('asc');
150
+ }
151
+ };
152
+
153
+ const handleSortOrderToggle = () => {
154
+ actions.setSortOrder(state.sortOrder === 'asc' ? 'desc' : 'asc');
155
+ };
156
+
157
+ // grid 视图目录导航:当前所在目录节点(用于顶部返回上级按钮)
158
+ const currentGridFolder = state.viewMode === 'grid' && state.selectedFolderId
159
+ ? findNodeInTree(state.fileTreeData, state.selectedFolderId)
160
+ : undefined;
161
+
162
+ const handleGridBack = () => {
163
+ actions.setSelectedFolderId(currentGridFolder?.parentId || null);
164
+ };
165
+
166
+ useEffect(() => {
167
+ if (state.viewMode === 'grid') {
168
+ actions.setExpandedRowKeys([]);
169
+ } else {
170
+ actions.setFileTreeData(buildFileTree(sortFiles(state.files)));
171
+ }
172
+ }, [state.viewMode, state.files]);
173
+
174
+ useEffect(() => {
175
+ const handleClick = () => {
176
+ if (state.contextMenuVisible) {
177
+ actions.setContextMenuVisible(false);
178
+ actions.setContextMenuRecord(null);
179
+ }
180
+ };
181
+ document.addEventListener('click', handleClick);
182
+ return () => {
183
+ document.removeEventListener('click', handleClick);
184
+ };
185
+ }, [state.contextMenuVisible]);
186
+
187
+ const handleClosePreview = () => {
188
+ actions.setUploadPercent(undefined);
189
+ actions.setPreviewFileName(null);
190
+ actions.setUploadSuccess(undefined);
191
+ if (state.previewVisible) {
192
+ actions.setPreviewVisible(false);
193
+ actions.setPreviewingFile(null);
194
+ setSearchParams(prev => {
195
+ const newParams = new URLSearchParams(prev);
196
+ newParams.delete('fileid');
197
+ return newParams;
198
+ }, { replace: true });
199
+ } else if (state.editorVisible) {
200
+ actions.setEditorVisible(false);
201
+ actions.setEditingFile(null);
202
+ } else if (state.creatorVisible) {
203
+ actions.setCreatorVisible(false);
204
+ actions.setCreatingFileName('');
205
+ actions.setCreatingFileType(null);
206
+ }
207
+ };
208
+
209
+ return (
210
+ <Card
211
+ className={className}
212
+ styles={{
213
+ body: { padding: 0 },
214
+ header: { paddingLeft: state.smallView ? 16 : 0, paddingRight: state.smallView ? 16 : 0 },
215
+ extra: { margin: 0, marginLeft: 'auto', marginRight: state.smallView ? 0 : '8px' },
216
+ }}
217
+ title={currentGridFolder ? (
218
+ <Button
219
+ type="text"
220
+ size="small"
221
+ icon={<ArrowLeftOutlined />}
222
+ onClick={handleGridBack}
223
+ title="返回上级目录"
224
+ style={{ marginLeft: state.smallView ? 0 : 16 }}
225
+ />
226
+ ) : undefined}
227
+ extra={
228
+ <FileToolbar
229
+ currentUserRole={currentUserRole}
230
+ viewMode={state.viewMode}
231
+ onToggleViewMode={(mode) => { actions.setViewMode(mode); saveViewMode(PAGE_KEY, mode); }}
232
+ onCreateFolder={fileManagerActions.handleCreateFolder}
233
+ onCreateMarkdown={fileManagerActions.handleCreateMarkdown}
234
+ onCreateRdoc={fileManagerActions.handleCreateRdoc}
235
+ onCreateExcel={fileManagerActions.handleCreateExcel}
236
+ onCreateWord={fileManagerActions.handleCreateWord}
237
+ onUploadFiles={fileManagerActions.uploadFiles}
238
+ />
239
+ }
240
+ >
241
+ <div
242
+ className={`flex justify-center items-center rounded border ${state.rootDragOver ? 'border-blue-500 bg-blue-50' : 'border-dashed border-gray-300 bg-white'}`}
243
+ style={{
244
+ opacity: state.dragSourceId ? 1 : 0,
245
+ textAlign: 'center',
246
+ zIndex: 40,
247
+ position: 'absolute',
248
+ height: '40px',
249
+ left: 0,
250
+ right: 0,
251
+ margin: 'auto',
252
+ transition: 'all 0.2s',
253
+ borderWidth: '2px',
254
+ pointerEvents: state.dragSourceId ? 'auto' : 'none',
255
+ }}
256
+ onDragOver={fileManagerActions.handleRootDragOver}
257
+ onDragLeave={fileManagerActions.handleRootDragLeave}
258
+ onDrop={fileManagerActions.handleRootDrop}
259
+ >
260
+ 移动到根目录
261
+ </div>
262
+
263
+ <div
264
+ className="relative"
265
+ onDragEnter={fileManagerActions.handleExternalDragEnter}
266
+ onDragOver={fileManagerActions.handleExternalDragOver}
267
+ onDragLeave={fileManagerActions.handleExternalDragLeave}
268
+ onDrop={fileManagerActions.handleExternalDrop}
269
+ >
270
+ {state.dragUploadPercent !== undefined && (
271
+ <Button
272
+ className="absolute right-3 top-3 z-50 shadow-md"
273
+ type={state.dragUploadSuccess === false ? 'default' : 'primary'}
274
+ danger={state.dragUploadSuccess === false}
275
+ loading={state.dragUploadSuccess !== false && dragUploadProgressPercent < 100}
276
+ disabled
277
+ >
278
+ {state.dragUploadSuccess === false
279
+ ? '拖拽上传失败'
280
+ : dragUploadProgressPercent >= 100
281
+ ? '拖拽上传完成'
282
+ : `拖拽上传中 ${dragUploadProgressPercent}%`}
283
+ {state.dragUploadingFileName ? `:${state.dragUploadingFileName}` : ''}
284
+ </Button>
285
+ )}
286
+
287
+ {state.isExternalDragOver && (
288
+ <div
289
+ className="absolute inset-0 z-50 flex flex-col items-center justify-center bg-blue-500/10 border-2 border-blue-500 border-dashed rounded m-2"
290
+ style={{ pointerEvents: 'none' }}
291
+ >
292
+ <div className="text-blue-600 text-lg font-medium">释放以上传文件</div>
293
+ <div className="text-blue-400 text-sm mt-1">
294
+ {state.selectedFolderId
295
+ ? `上传到当前文件夹`
296
+ : '上传到根目录'}
297
+ </div>
298
+ </div>
299
+ )}
300
+
301
+ <Spin spinning={state.loading}>
302
+ <div className="min-h-[400px]">
303
+ {state.viewMode === 'table' ? (
304
+ <FileTableView
305
+ dataSource={state.fileTreeData}
306
+ expandedRowKeys={state.expandedRowKeys}
307
+ selectedFolderId={state.selectedFolderId}
308
+ dragOverId={state.dragOverId}
309
+ dragSourceId={state.dragSourceId}
310
+ smallView={state.smallView}
311
+ isFolderExpanded={fileManagerActions.isFolderExpanded}
312
+ onExpand={fileManagerActions.handleExpand}
313
+ onPreview={fileManagerActions.handlePreview}
314
+ onDownload={fileManagerActions.handleDownload}
315
+ onDownloadFolder={state.isManager ? fileManagerActions.handleDownloadFolder : undefined}
316
+ onCopyLink={enableExternalLink ? fileManagerActions.handleCopyLink : undefined}
317
+ onRename={fileManagerActions.handleRename}
318
+ onEditDescs={fileManagerActions.handleEditDescs}
319
+ onDelete={fileManagerActions.handleDelete}
320
+ onEdit={fileManagerActions.handleEditFile}
321
+ onGenerateTempLink={hasTempAccessToken ? fileManagerActions.handleGenerateTempLink : undefined}
322
+ onMove={fileManagerActions.handleMove}
323
+ onDragStart={fileManagerActions.handleDragStart}
324
+ onDragEnd={fileManagerActions.handleDragEnd}
325
+ onDragOver={fileManagerActions.handleDragOver}
326
+ onDragLeave={fileManagerActions.handleDragLeave}
327
+ onDrop={fileManagerActions.handleDrop}
328
+ onRowContextMenu={fileManagerActions.handleContextMenu}
329
+ onMoveToProject={enableMoveCopyToProject ? fileManagerActions.handleMoveToProject : undefined}
330
+ onCopyToProject={enableMoveCopyToProject ? fileManagerActions.handleCopyToProject : undefined}
331
+ onCopyToSelf={hasCopyFileToProject ? fileManagerActions.handleCopyToSelf : undefined}
332
+ onViewVersionHistory={enableVersionHistory ? fileManagerActions.handleViewVersionHistory : undefined}
333
+ onJumpToContract={enableContracts ? fileManagerActions.handleJumpToContract : undefined}
334
+ sortBy={state.sortBy}
335
+ sortOrder={state.sortOrder}
336
+ onSortByChange={handleSortByChange}
337
+ />
338
+ ) : (
339
+ <FileGridView
340
+ dataSource={state.fileTreeData}
341
+ selectedFolderId={state.selectedFolderId}
342
+ dragOverId={state.dragOverId}
343
+ dragSourceId={state.dragSourceId}
344
+ isFolderExpanded={fileManagerActions.isFolderExpanded}
345
+ smallView={state.smallView}
346
+ onPreview={fileManagerActions.handlePreview}
347
+ onDownload={fileManagerActions.handleDownload}
348
+ onDownloadFolder={state.isManager ? fileManagerActions.handleDownloadFolder : undefined}
349
+ onCopyLink={enableExternalLink ? fileManagerActions.handleCopyLink : undefined}
350
+ onRename={fileManagerActions.handleRename}
351
+ onEditDescs={fileManagerActions.handleEditDescs}
352
+ onDelete={fileManagerActions.handleDelete}
353
+ onEdit={fileManagerActions.handleEditFile}
354
+ onGenerateTempLink={hasTempAccessToken ? fileManagerActions.handleGenerateTempLink : undefined}
355
+ onFolderChange={actions.setSelectedFolderId}
356
+ onMove={fileManagerActions.handleMove}
357
+ onDragStart={fileManagerActions.handleDragStart}
358
+ onDragEnd={fileManagerActions.handleDragEnd}
359
+ onDragOver={fileManagerActions.handleDragOver}
360
+ onDragLeave={fileManagerActions.handleDragLeave}
361
+ onDrop={fileManagerActions.handleDrop}
362
+ onRowContextMenu={fileManagerActions.handleContextMenu}
363
+ onMoveToProject={enableMoveCopyToProject ? fileManagerActions.handleMoveToProject : undefined}
364
+ onCopyToProject={enableMoveCopyToProject ? fileManagerActions.handleCopyToProject : undefined}
365
+ onCopyToSelf={hasCopyFileToProject ? fileManagerActions.handleCopyToSelf : undefined}
366
+ onViewVersionHistory={enableVersionHistory ? fileManagerActions.handleViewVersionHistory : undefined}
367
+ onJumpToContract={enableContracts ? fileManagerActions.handleJumpToContract : undefined}
368
+ sortBy={state.sortBy}
369
+ sortOrder={state.sortOrder}
370
+ onSortByChange={handleSortByChange}
371
+ onSortOrderToggle={handleSortOrderToggle}
372
+ />
373
+ )}
374
+ </div>
375
+ </Spin>
376
+ </div>
377
+
378
+ <Modal
379
+ className='ant-modal-nofull'
380
+ title="新建文件夹"
381
+ open={state.createFolderVisible}
382
+ onOk={() => fileManagerActions.handleCreateFolderConfirm(state.newFolderName, state.newFolderDescs, state.isEncryptedFolder)}
383
+ onCancel={() => actions.setCreateFolderVisible(false)}
384
+ okText="创建"
385
+ cancelText="取消"
386
+ >
387
+ <Input
388
+ placeholder="请输入文件夹名称"
389
+ value={state.newFolderName}
390
+ onChange={(event) => actions.setNewFolderName(event.target.value)}
391
+ />
392
+ <Input.TextArea
393
+ className="mt-3"
394
+ placeholder="请输入备注(可选)"
395
+ value={state.newFolderDescs}
396
+ autoSize={{ minRows: 3, maxRows: 6 }}
397
+ maxLength={FILE_DESCS_MAX_LENGTH}
398
+ showCount
399
+ style={{ marginBottom: 24 }}
400
+ onChange={(event) => actions.setNewFolderDescs(event.target.value)}
401
+ />
402
+
403
+ {state.isManager && <Checkbox className="mt-2" checked={state.isEncryptedFolder} onChange={(e) => actions.setIsEncryptedFolder(e.target.checked)}>加密文件夹<span className="text-sm text-gray-500 font-thin">(仅对管理员可见)</span></Checkbox>}
404
+ </Modal>
405
+
406
+ <Modal
407
+ className='ant-modal-nofull'
408
+ title="新建文件"
409
+ open={state.createFileVisible}
410
+ onOk={() => fileManagerActions.handleCreateFileConfirm(state.newFileName, state.pendingFileType)}
411
+ onCancel={() => actions.setCreateFileVisible(false)}
412
+ okText="创建"
413
+ cancelText="取消"
414
+ >
415
+ <Input
416
+ placeholder="请输入文件名称"
417
+ value={state.newFileName}
418
+ onChange={(event) => actions.setNewFileName(event.target.value)}
419
+ onPressEnter={() => fileManagerActions.handleCreateFileConfirm(state.newFileName, state.pendingFileType)}
420
+ autoFocus
421
+ />
422
+ </Modal>
423
+
424
+ <Modal
425
+ title="编辑备注"
426
+ className='ant-modal-nofull'
427
+ open={state.descsVisible}
428
+ onOk={() => fileManagerActions.handleDescsConfirm(state.descsFileId, state.descsValue)}
429
+ onCancel={() => {
430
+ actions.setDescsVisible(false);
431
+ actions.setDescsFileId(null);
432
+ actions.setDescsValue('');
433
+ }}
434
+ okText="保存"
435
+ cancelText="取消"
436
+ >
437
+ <Input.TextArea
438
+ placeholder="请输入备注"
439
+ value={state.descsValue}
440
+ autoSize={{ minRows: 4, maxRows: 8 }}
441
+ maxLength={FILE_DESCS_MAX_LENGTH}
442
+ showCount
443
+ style={{ marginBottom: 24 }}
444
+ onChange={(event) => actions.setDescsValue(event.target.value)}
445
+ />
446
+ </Modal>
447
+
448
+ <Modal
449
+ title="重命名"
450
+ className='ant-modal-nofull'
451
+ open={state.renameVisible}
452
+ onOk={() => fileManagerActions.handleRenameConfirm(state.renameFileId, state.renameFileName)}
453
+ onCancel={() => actions.setRenameVisible(false)}
454
+ okText="确定"
455
+ cancelText="取消"
456
+ >
457
+ <Input
458
+ placeholder="请输入新名称"
459
+ value={state.renameFileName}
460
+ onChange={(event) => actions.setRenameFileName(event.target.value)}
461
+ onPressEnter={() => fileManagerActions.handleRenameConfirm(state.renameFileId, state.renameFileName)}
462
+ />
463
+ </Modal>
464
+
465
+ {(() => {
466
+ // previewFile 优先取 previewingFile(handlePreview 同步设置),
467
+ // 避免 setSearchParams 异步更新 currentFileId 时首次渲染取到旧文件。
468
+ const previewFile = state.editingFile || state.previewingFile || (currentFileId ? state.files.find(f => f.id === currentFileId) : undefined);
469
+ const isOffline = !state.isOnline;
470
+ // 本地文件 / 未同步修改 → 可编辑模式需要上传回调;离线时服务器文件禁用上传按钮
471
+ const shouldHideUpload = isOffline && !state.previewIsLocalOnly;
472
+ const editingOrCreating = state.editorVisible || state.creatorVisible;
473
+ const effectiveLocalId = state.previewLocalId || previewFile?.localId;
474
+
475
+ return (
476
+ <UIFilePreview
477
+ fileUrl={state.previewVisible ? state.previewUrl : (state.editingFile?.fileResourcePath || null)}
478
+ visible={state.previewVisible || state.editorVisible || state.creatorVisible}
479
+ editable={editingOrCreating}
480
+ isCreate={state.creatorVisible || !!state.previewIsLocalOnly}
481
+ fileName={state.editingFile?.fileName || state.creatingFileName || state.previewFileName || undefined}
482
+ uploadPercent={state.uploadPercent}
483
+ uploadSuccess={state.uploadSuccess}
484
+ onClose={handleClosePreview}
485
+ onUploadBlob={!shouldHideUpload
486
+ ? (state.editorVisible
487
+ ? async (initialBlob, blob, fileName) => fileManagerActions.handleUploadBlob(state.editingFile, initialBlob, blob, fileName)
488
+ : (state.creatorVisible
489
+ ? async (initialBlob, blob, fileName) => fileManagerActions.handleCreateUploadBlob(initialBlob, blob, fileName)
490
+ : undefined))
491
+ : undefined}
492
+ onUploadMarkdown={!shouldHideUpload
493
+ ? (state.editorVisible
494
+ ? async (oldContent, content, fileName) => fileManagerActions.handleUploadMarkdown(state.editingFile, oldContent, content, fileName)
495
+ : (state.creatorVisible
496
+ ? async (oldContent, content, fileName) => fileManagerActions.handleCreateUploadMarkdown(oldContent, content, fileName)
497
+ : undefined))
498
+ : undefined}
499
+ onSaveLocalBlob={(blob, fileName, markUnsynced) => fileManagerActions.handleSaveLocalBlob(effectiveLocalId, blob, fileName, markUnsynced)}
500
+ onSaveLocalMarkdown={(content, fileName, markUnsynced) => fileManagerActions.handleSaveLocalMarkdown(effectiveLocalId, content, fileName, markUnsynced)}
501
+ fileId={previewFile?.isContractLink ? undefined : previewFile?.id}
502
+ localId={effectiveLocalId}
503
+ isLocalOnly={state.previewIsLocalOnly || !!previewFile?.isLocalOnly}
504
+ hasUnsyncedChanges={state.previewHasUnsyncedChanges || !!previewFile?.hasUnsyncedChanges}
505
+ isOffline={isOffline}
506
+ crc32={state.previewCrc32}
507
+ fetchFileDetail={fetchFileDetail}
508
+ onCacheSaved={fileManagerActions.handleCacheSaved}
509
+ />
510
+ );
511
+ })()}
512
+
513
+ {state.contextMenuVisible && state.contextMenuRecord && (
514
+ <FileContextMenu
515
+ record={state.contextMenuRecord}
516
+ onPreview={fileManagerActions.handlePreview}
517
+ onDownload={fileManagerActions.handleDownload}
518
+ onDownloadFolder={state.isManager ? fileManagerActions.handleDownloadFolder : undefined}
519
+ onCopyLink={enableExternalLink ? fileManagerActions.handleCopyLink : undefined}
520
+ onRename={fileManagerActions.handleRename}
521
+ onEditDescs={fileManagerActions.handleEditDescs}
522
+ onDelete={fileManagerActions.handleDelete}
523
+ onEdit={fileManagerActions.handleEditFile}
524
+ onGenerateTempLink={hasTempAccessToken ? fileManagerActions.handleGenerateTempLink : undefined}
525
+ onMoveToProject={enableMoveCopyToProject ? fileManagerActions.handleMoveToProject : undefined}
526
+ onCopyToProject={enableMoveCopyToProject ? fileManagerActions.handleCopyToProject : undefined}
527
+ onCopyToSelf={hasCopyFileToProject ? fileManagerActions.handleCopyToSelf : undefined}
528
+ onViewVersionHistory={enableVersionHistory ? fileManagerActions.handleViewVersionHistory : undefined}
529
+ onJumpToContract={enableContracts ? fileManagerActions.handleJumpToContract : undefined}
530
+ onCreateContract={enableContracts ? fileManagerActions.handleCreateContract : undefined}
531
+ onShareToWechat={enableShareToWechat ? fileManagerActions.handleShareToWechat : undefined}
532
+ onClearCache={fileManagerActions.handleClearCache}
533
+ onOpenInNewWindow={enableExternalLink ? fileManagerActions.handleOpenInNewWindow : undefined}
534
+ isAdminOrOwner={state.isManager}
535
+ open={true}
536
+ position={state.contextMenuPosition}
537
+ />
538
+ )}
539
+
540
+ {enableMoveCopyToProject && (
541
+ <MoveCopyToProjectModal
542
+ visible={state.moveCopyModalVisible}
543
+ fileIds={state.moveCopyFiles.map(f => f.id)}
544
+ files={state.moveCopyFiles.map(f => ({ fileName: f.fileName, fileType: f.fileType }))}
545
+ currentProjectId={projectId}
546
+ mode={state.moveCopyMode}
547
+ onCancel={() => {
548
+ actions.setMoveCopyModalVisible(false);
549
+ actions.setMoveCopyFiles([]);
550
+ }}
551
+ onSuccess={fileManagerActions.handleMoveCopySuccess}
552
+ />
553
+ )}
554
+
555
+ {enableVersionHistory && (
556
+ <FileVersionHistoryModal
557
+ visible={state.versionHistoryModalVisible}
558
+ file={state.versionHistoryFile}
559
+ onClose={() => {
560
+ actions.setVersionHistoryModalVisible(false);
561
+ actions.setVersionHistoryFile(null);
562
+ }}
563
+ />
564
+ )}
565
+
566
+ {enableShareToWechat && (
567
+ <ShareToWechatModal
568
+ visible={state.shareToWechatVisible}
569
+ file={state.shareToWechatFile}
570
+ onFileCached={fileManagerActions.handleCacheSaved}
571
+ onClose={() => {
572
+ actions.setShareToWechatVisible(false);
573
+ actions.setShareToWechatFile(null);
574
+ }}
575
+ />
576
+ )}
577
+
578
+ </Card>
579
+ );
580
+ };
@@ -0,0 +1,57 @@
1
+ import { API } from '../../api/index';
2
+ import { ResponseCode } from '../../api/_base';
3
+ import { CacheUserInfo } from '../../utils/CacheUserInfo';
4
+ import { FileManagerApi, ProjectFile, ProjectRole } from './types';
5
+
6
+ /**
7
+ * 项目文件场景的默认 FileManagerApi 实现:包装 API.project.*。
8
+ * FileManager 未传入自定义 api 时使用。
9
+ */
10
+ export const projectFileManagerApi: FileManagerApi = {
11
+ listFiles: (scopeId) =>
12
+ API.project.file.listFiles({ projectId: scopeId }) as Promise<{
13
+ code: number;
14
+ message?: string;
15
+ data?: ProjectFile[];
16
+ }>,
17
+ getDetail: (fileId) =>
18
+ API.project.file.getDetail({ fileId }) as Promise<{
19
+ code: number;
20
+ message?: string;
21
+ data?: ProjectFile;
22
+ }>,
23
+ addFile: (scopeId, data) => API.project.file.addFile({ projectId: scopeId }, data),
24
+ removeFile: (fileId) => API.project.file.removeFile({ fileId }),
25
+ moveFile: (scopeId, data) => API.project.file.moveFile({ projectId: scopeId }, data),
26
+ updateFileDescs: (data) => API.project.file.updateFileDescs(data),
27
+ updateFile: (data) => API.project.file.updateFile(data),
28
+ updateFileDelta: (data) => API.project.file.updateFileDelta(data),
29
+ copyFileToProject: (scopeId, fileId) =>
30
+ API.project.file.copyFileToProject({ projectId: scopeId, fileId }),
31
+ generateTempAccessToken: (fileId, expireSeconds) =>
32
+ API.project.file.generateTempAccessToken({ fileId, expireSeconds }),
33
+ downloadFolder: (scopeId, folderPath, folderName) =>
34
+ API.project.file.folderDownload(
35
+ { projectId: scopeId },
36
+ { folderPath, folderName },
37
+ ) as Promise<{ code: number; message?: string; data?: { jobId: string } }>,
38
+ getFolderDownloadStatus: (jobId) =>
39
+ API.project.file.folderDownloadStatus({ jobId }) as Promise<{
40
+ code: number;
41
+ message?: string;
42
+ data?: import('./types').FolderDownloadJobStatus;
43
+ }>,
44
+ resolveIsManager: async (scopeId) => {
45
+ const user = await CacheUserInfo.getUserInfo({ forceRefresh: true });
46
+ const projectRes = await API.project.project.getProjectMembers({ projectId: scopeId });
47
+ if (projectRes.code == ResponseCode.SUCCESS) {
48
+ const ret = projectRes.data?.find(
49
+ (value) =>
50
+ value.userId == user?.id &&
51
+ (value.role == ProjectRole.MANAGER || value.role == ProjectRole.OWNER),
52
+ );
53
+ return !!ret;
54
+ }
55
+ return false;
56
+ },
57
+ };