@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,182 @@
1
+ 'use strict';
2
+
3
+ /**
4
+ * Copyright (c) 2025 SPACECORE Co.,Ltd. All Rights Reserved.
5
+ * Author: brian.li
6
+ * Date: 2025-06-21 11:43
7
+ * Desc: 视图切换缓存工具类 - 支持Dexie缓存各页面UIViewToggle的选择
8
+ *
9
+ * @example 使用方法
10
+ *
11
+ * // 1. 获取页面的视图模式
12
+ * import { getViewMode, setViewMode, CacheViewToggleInfo } from './CacheViewToggleInfo';
13
+ * const viewMode = await getViewMode('user-management');
14
+ * console.log(viewMode); // 'table' | 'grid' | null
15
+ *
16
+ * // 2. 设置页面的视图模式
17
+ * await setViewMode('user-management', 'grid');
18
+ *
19
+ * // 3. 清除页面视图模式缓存
20
+ * import { clearViewModeCache, clearAllViewModeCache } from './CacheViewToggleInfo';
21
+ * await clearViewModeCache('user-management');
22
+ * await clearAllViewModeCache();
23
+ */
24
+
25
+ import Dexie, { Table } from 'dexie';
26
+
27
+ /** 视图模式缓存数据结构 */
28
+ interface ViewModeCache {
29
+ pageKey: string;
30
+ viewMode: string;
31
+ timestamp: number;
32
+ }
33
+
34
+ /** Dexie 数据库类 */
35
+ class ViewToggleDatabase extends Dexie {
36
+ viewModeCache!: Table<ViewModeCache, string>;
37
+
38
+ constructor() {
39
+ super('ViewToggleDB');
40
+ this.version(1).stores({
41
+ viewModeCache: 'pageKey, timestamp'
42
+ });
43
+ }
44
+ }
45
+
46
+ /** 单例数据库实例 */
47
+ const db = new ViewToggleDatabase();
48
+
49
+ /**
50
+ * 从缓存获取指定页面的视图模式
51
+ * @param pageKey 页面标识(如路由路径)
52
+ * @returns 缓存的视图模式或null
53
+ */
54
+ const getFromCache = async (pageKey: string): Promise<string | null> => {
55
+ try {
56
+ const cached = await db.viewModeCache.get(pageKey);
57
+ if (cached) {
58
+ return cached.viewMode;
59
+ }
60
+ return null;
61
+ } catch (error) {
62
+ console.error('读取视图模式缓存失败:', error);
63
+ return null;
64
+ }
65
+ };
66
+
67
+ /**
68
+ * 设置页面视图模式到缓存
69
+ * @param pageKey 页面标识
70
+ * @param viewMode 视图模式值
71
+ */
72
+ const setToCache = async (pageKey: string, viewMode: string): Promise<void> => {
73
+ try {
74
+ await db.viewModeCache.put({
75
+ pageKey,
76
+ viewMode,
77
+ timestamp: Date.now()
78
+ });
79
+ } catch (error) {
80
+ console.error('写入视图模式缓存失败:', error);
81
+ }
82
+ };
83
+
84
+ /**
85
+ * 清除指定页面的视图模式缓存
86
+ * @param pageKey 页面标识
87
+ */
88
+ const clearCache = async (pageKey: string): Promise<void> => {
89
+ try {
90
+ await db.viewModeCache.delete(pageKey);
91
+ } catch (error) {
92
+ console.error('清除视图模式缓存失败:', error);
93
+ }
94
+ };
95
+
96
+ /**
97
+ * 清除所有视图模式缓存
98
+ */
99
+ const clearAllCache = async (): Promise<void> => {
100
+ try {
101
+ await db.viewModeCache.clear();
102
+ } catch (error) {
103
+ console.error('清除所有视图模式缓存失败:', error);
104
+ }
105
+ };
106
+
107
+ /**
108
+ * 获取指定页面的视图模式
109
+ * @param pageKey 页面标识(如路由路径)
110
+ * @returns 视图模式值或null
111
+ */
112
+ const getViewMode = async (pageKey: string): Promise<string | null> => {
113
+ return await getFromCache(pageKey);
114
+ };
115
+
116
+ /**
117
+ * 设置指定页面的视图模式
118
+ * @param pageKey 页面标识(如路由路径)
119
+ * @param viewMode 视图模式值
120
+ */
121
+ const setViewMode = async (pageKey: string, viewMode: string): Promise<void> => {
122
+ await setToCache(pageKey, viewMode);
123
+ };
124
+
125
+ /**
126
+ * 清除指定页面的视图模式缓存
127
+ * @param pageKey 页面标识
128
+ */
129
+ const clearViewModeCache = async (pageKey: string): Promise<void> => {
130
+ await clearCache(pageKey);
131
+ };
132
+
133
+ /**
134
+ * 清除所有视图模式缓存
135
+ */
136
+ const clearAllViewModeCache = async (): Promise<void> => {
137
+ await clearAllCache();
138
+ };
139
+
140
+ /**
141
+ * 获取所有缓存的页面视图模式
142
+ * @returns 所有缓存的页面视图模式
143
+ */
144
+ const getAllCachedViewModes = async (): Promise<ViewModeCache[]> => {
145
+ try {
146
+ return await db.viewModeCache.toArray();
147
+ } catch (error) {
148
+ console.error('获取所有视图模式缓存失败:', error);
149
+ return [];
150
+ }
151
+ };
152
+
153
+ export const CacheViewToggleInfo = {
154
+ /**
155
+ * 获取指定页面的视图模式
156
+ * @param pageKey 页面标识(如路由路径)
157
+ * @returns 视图模式值或null
158
+ */
159
+ getViewMode,
160
+ /**
161
+ * 设置指定页面的视图模式
162
+ * @param pageKey 页面标识(如路由路径)
163
+ * @param viewMode 视图模式值
164
+ */
165
+ setViewMode,
166
+ /**
167
+ * 清除指定页面的视图模式缓存
168
+ * @param pageKey 页面标识
169
+ */
170
+ clearViewModeCache,
171
+ /**
172
+ * 清除所有视图模式缓存
173
+ */
174
+ clearAllViewModeCache,
175
+ /**
176
+ * 获取所有缓存的页面视图模式
177
+ * @returns 所有缓存的页面视图模式
178
+ */
179
+ getAllCachedViewModes
180
+ };
181
+
182
+ export { getViewMode, setViewMode, clearViewModeCache, clearAllViewModeCache };
@@ -0,0 +1,268 @@
1
+ 'use strict';
2
+
3
+ /**
4
+ * Copyright (c) 2026 SPACECORE Co.,Ltd. All Rights Reserved.
5
+ * Author: GitHub Copilot
6
+ * Desc: 用户消息 content 字段统一封装工具
7
+ *
8
+ * 由于 user_message 表只保留 title + content 两列,业务类型/关联ID/跳转等
9
+ * 信息统一序列化为 JSON 字符串写入 content,前端解析后分类展示与跳转。
10
+ */
11
+
12
+ /** 消息大类 */
13
+ export type MessageType = 'project' | 'approval' | 'knowledge' | 'todo' | 'crm';
14
+
15
+ /** 项目子类型 */
16
+ export type ProjectBizType =
17
+ | 'file_add'
18
+ | 'file_update'
19
+ | 'file_delete'
20
+ | 'contract_add'
21
+ | 'contract_delete'
22
+ | 'contract_update'
23
+ | 'detail'
24
+ | 'member_add'
25
+ | 'member_remove'
26
+ | 'member_role_change'
27
+ | 'file_download';
28
+
29
+ /** 审批子类型 */
30
+ export type ApprovalBizType =
31
+ | 'submit'
32
+ | 'approve'
33
+ | 'reject'
34
+ | 'cancel'
35
+ | 'deal';
36
+
37
+ /** 知识库子类型 */
38
+ export type KnowledgeBizType = 'kb_new';
39
+
40
+ /** 待办子类型 */
41
+ export type TodoBizType = 'task_assign' | 'task_remind';
42
+
43
+ /** CRM 子类型 */
44
+ export type CrmBizType = 'customer_transfer_in' | 'customer_transfer_out';
45
+
46
+ /** 全部业务子类型 */
47
+ export type MessageBizType = ProjectBizType | ApprovalBizType | KnowledgeBizType | TodoBizType | CrmBizType;
48
+
49
+ /** content 字段结构定义 */
50
+ export interface MessageContent {
51
+ /** 消息大类 */
52
+ type: MessageType;
53
+ /** 业务子类型 */
54
+ bizType: MessageBizType;
55
+ /** 关联业务主键(项目ID/审批实例ID/知识文章ID) */
56
+ id: string;
57
+ /** 人话描述,前端可直接展示 */
58
+ text: string;
59
+ /** 下载地址(相对文件根路径,file_download 成功时存在) */
60
+ url?: string;
61
+ /** 下载文件名 */
62
+ fileName?: string;
63
+ /** 打包任务 ID */
64
+ jobId?: string;
65
+ /** 下载地址过期时间戳(毫秒) */
66
+ expireAt?: number;
67
+ }
68
+
69
+ /** 消息大类展示名称 */
70
+ export const MESSAGE_TYPE_LABELS: Record<MessageType, string> = {
71
+ project: '项目动态',
72
+ approval: '审批动态',
73
+ knowledge: '知识库',
74
+ todo: '待办任务',
75
+ crm: '客户管理',
76
+ };
77
+
78
+ /** 项目类业务子类型展示名称 */
79
+ export const PROJECT_BIZ_LABELS: Record<ProjectBizType, string> = {
80
+ file_add: '文件新增',
81
+ file_update: '文件更新',
82
+ file_delete: '文件删除',
83
+ contract_add: '合同新增',
84
+ contract_delete: '合同删除',
85
+ contract_update: '合同更新',
86
+ detail: '详情更新',
87
+ member_add: '成员加入',
88
+ member_remove: '成员移除',
89
+ member_role_change: '角色变更',
90
+ file_download: '文件下载',
91
+ };
92
+
93
+ /** 审批类业务子类型展示名称 */
94
+ export const APPROVAL_BIZ_LABELS: Record<ApprovalBizType, string> = {
95
+ submit: '审批提交',
96
+ approve: '审批通过',
97
+ reject: '审批驳回',
98
+ cancel: '审批撤销',
99
+ deal: '产物更新',
100
+ };
101
+
102
+ /** 知识库类业务子类型展示名称 */
103
+ export const KNOWLEDGE_BIZ_LABELS: Record<KnowledgeBizType, string> = {
104
+ kb_new: '新增知识',
105
+ };
106
+
107
+ /** 待办类业务子类型展示名称 */
108
+ export const TODO_BIZ_LABELS: Record<TodoBizType, string> = {
109
+ task_assign: '任务指派',
110
+ task_remind: '到期提醒',
111
+ };
112
+
113
+ /** CRM 类业务子类型展示名称 */
114
+ export const CRM_BIZ_LABELS: Record<CrmBizType, string> = {
115
+ customer_transfer_in: '客户移交(接收)',
116
+ customer_transfer_out: '客户移交(移交出)',
117
+ };
118
+
119
+ /** 项目类 bizType 到项目详情页 tab 的映射 */
120
+ const PROJECT_BIZ_TAB_MAP: Partial<Record<ProjectBizType, string>> = {
121
+ file_add: 'files',
122
+ file_update: 'files',
123
+ file_delete: 'files',
124
+ contract_add: 'contracts',
125
+ contract_update: 'contracts',
126
+ contract_delete: 'contracts',
127
+ detail: 'detail',
128
+ member_add: 'members',
129
+ member_remove: 'members',
130
+ member_role_change: 'members',
131
+ };
132
+
133
+ export class MessageContentUtils {
134
+ /**
135
+ * 构造消息 content JSON 字符串
136
+ * @param type 消息大类
137
+ * @param bizType 业务子类型
138
+ * @param id 关联业务主键
139
+ * @param text 人话描述
140
+ * @returns 序列化后的 JSON 字符串
141
+ */
142
+ static buildContent(
143
+ type: MessageType,
144
+ bizType: MessageBizType,
145
+ id: string,
146
+ text: string,
147
+ ): string {
148
+ const content: MessageContent = { type, bizType, id: id || '', text: text || '' };
149
+ return JSON.stringify(content);
150
+ }
151
+
152
+ /**
153
+ * 解析消息 content JSON 字符串
154
+ * @param content content 字段
155
+ * @returns 解析后的结构,解析失败返回 null
156
+ */
157
+ static parseContent(content: string): MessageContent | null {
158
+ if (!content) {
159
+ return null;
160
+ }
161
+ try {
162
+ const obj = JSON.parse(content);
163
+ if (
164
+ obj &&
165
+ typeof obj.type === 'string' &&
166
+ typeof obj.bizType === 'string' &&
167
+ typeof obj.id === 'string'
168
+ ) {
169
+ const parsed: MessageContent = {
170
+ type: obj.type as MessageType,
171
+ bizType: obj.bizType as MessageBizType,
172
+ id: obj.id,
173
+ text: typeof obj.text === 'string' ? obj.text : '',
174
+ };
175
+ if (typeof obj.url === 'string') {
176
+ parsed.url = obj.url;
177
+ }
178
+ if (typeof obj.fileName === 'string') {
179
+ parsed.fileName = obj.fileName;
180
+ }
181
+ if (typeof obj.jobId === 'string') {
182
+ parsed.jobId = obj.jobId;
183
+ }
184
+ if (typeof obj.expireAt === 'number') {
185
+ parsed.expireAt = obj.expireAt;
186
+ }
187
+ return parsed;
188
+ }
189
+ return null;
190
+ } catch (e) {
191
+ return null;
192
+ }
193
+ }
194
+
195
+ /** 判断是否为受支持的消息大类 */
196
+ static isMessageType(type: string): type is MessageType {
197
+ return Object.prototype.hasOwnProperty.call(MESSAGE_TYPE_LABELS, type);
198
+ }
199
+
200
+ /** 获取消息大类展示名称,未知类型降级为「系统消息」 */
201
+ static getTypeLabel(type: string): string {
202
+ return MESSAGE_TYPE_LABELS[type as MessageType] || '系统消息';
203
+ }
204
+
205
+ /** 获取业务子类型展示名称,未知子类型返回空串 */
206
+ static getBizTypeLabel(type: string, bizType: string): string {
207
+ switch (type) {
208
+ case 'project':
209
+ return PROJECT_BIZ_LABELS[bizType as ProjectBizType] || '';
210
+ case 'approval':
211
+ return APPROVAL_BIZ_LABELS[bizType as ApprovalBizType] || '';
212
+ case 'knowledge':
213
+ return KNOWLEDGE_BIZ_LABELS[bizType as KnowledgeBizType] || '';
214
+ case 'todo':
215
+ return TODO_BIZ_LABELS[bizType as TodoBizType] || '';
216
+ case 'crm':
217
+ return CRM_BIZ_LABELS[bizType as CrmBizType] || '';
218
+ default:
219
+ return '';
220
+ }
221
+ }
222
+
223
+ /**
224
+ * 获取消息正文:优先展示后端下发的人话 text,
225
+ * text 缺失时降级为业务子类型名称。
226
+ */
227
+ static getDisplayText(content: MessageContent | null | undefined): string {
228
+ if (!content) {
229
+ return '';
230
+ }
231
+ return content.text || MessageContentUtils.getBizTypeLabel(content.type, content.bizType);
232
+ }
233
+
234
+ /**
235
+ * 获取消息关联业务页面的跳转路由(含查询参数)。
236
+ * project -> /project?id=xxx&tab=files|contracts|members|detail
237
+ * approval -> /approval?instanceId=xxx
238
+ * knowledge -> /knowledge?id=xxx
239
+ * todo -> /todo?todoId=xxx(待办页读取参数后自动打开任务抽屉)
240
+ * 未知类型或缺少关联ID时返回 null。
241
+ */
242
+ static getJumpRoute(content: MessageContent | null | undefined): string | null {
243
+ if (!content || !content.id) {
244
+ return null;
245
+ }
246
+ const id = encodeURIComponent(content.id);
247
+ switch (content.type) {
248
+ case 'project': {
249
+ // 文件夹打包下载通知不跳转,由消息中心直接触发下载
250
+ if (content.bizType === 'file_download') {
251
+ return null;
252
+ }
253
+ const tab = PROJECT_BIZ_TAB_MAP[content.bizType as ProjectBizType];
254
+ return `/project?id=${id}${tab ? `&tab=${tab}` : ''}`;
255
+ }
256
+ case 'approval':
257
+ return `/approval?instanceId=${id}`;
258
+ case 'knowledge':
259
+ return `/knowledge?id=${id}`;
260
+ case 'todo':
261
+ return `/todo?todoId=${id}`;
262
+ case 'crm':
263
+ return `/crm?id=${id}`;
264
+ default:
265
+ return null;
266
+ }
267
+ }
268
+ }
@@ -0,0 +1,70 @@
1
+ /**
2
+ * 复制文本到剪贴板。
3
+ * 优先尝试 navigator.clipboard(HTTPS/localhost 安全上下文可用),
4
+ * 若不可用或调用失败(如部分移动端 webview 权限/手势问题),自动回退到 document.execCommand('copy')。
5
+ */
6
+ export async function copyToClipboard(text: string): Promise<void> {
7
+ // 1. 优先尝试 Clipboard API。注意:即使存在也可能 reject,因此失败需继续走兜底。
8
+ if (navigator.clipboard && typeof navigator.clipboard.writeText === 'function') {
9
+ try {
10
+ await navigator.clipboard.writeText(text);
11
+ return;
12
+ } catch {
13
+ // 忽略,进入 execCommand 兜底
14
+ }
15
+ }
16
+
17
+ // 2. 兜底:临时 textarea + execCommand('copy'),兼容 HTTP 内网及 iOS/Android 移动端
18
+ const succeeded = copyViaExecCommand(text);
19
+ if (!succeeded) {
20
+ throw new Error('复制到剪贴板失败');
21
+ }
22
+ }
23
+
24
+ function copyViaExecCommand(text: string): boolean {
25
+ const textarea = document.createElement('textarea');
26
+ textarea.value = text;
27
+ // iOS 下 readonly 会阻止选中,先设为可编辑;复制后再恢复
28
+ textarea.setAttribute('contenteditable', 'true');
29
+ // 隐藏元素,避免影响页面布局与滚动(不能用 display:none,否则无法选中)
30
+ textarea.style.position = 'fixed';
31
+ textarea.style.top = '0';
32
+ textarea.style.left = '0';
33
+ textarea.style.width = '1px';
34
+ textarea.style.height = '1px';
35
+ textarea.style.padding = '0';
36
+ textarea.style.border = 'none';
37
+ textarea.style.outline = 'none';
38
+ textarea.style.boxShadow = 'none';
39
+ textarea.style.background = 'transparent';
40
+ textarea.style.opacity = '0';
41
+ document.body.appendChild(textarea);
42
+
43
+ const isIOS = /ipad|iphone|ipod/i.test(navigator.userAgent);
44
+ let succeeded = false;
45
+
46
+ try {
47
+ if (isIOS) {
48
+ // iOS Safari:需用 Range 选中 contenteditable 元素
49
+ const selection = document.getSelection();
50
+ const range = document.createRange();
51
+ range.selectNodeContents(textarea);
52
+ selection?.removeAllRanges();
53
+ selection?.addRange(range);
54
+ textarea.setSelectionRange(0, text.length);
55
+ } else {
56
+ // 其他平台:focus + select
57
+ textarea.focus();
58
+ textarea.select();
59
+ textarea.setSelectionRange(0, text.length);
60
+ }
61
+
62
+ succeeded = document.execCommand('copy');
63
+ } catch {
64
+ succeeded = false;
65
+ } finally {
66
+ document.body.removeChild(textarea);
67
+ }
68
+
69
+ return succeeded;
70
+ }
@@ -0,0 +1,19 @@
1
+ // 公司邮箱域名来自前端环境变量,多个域名用逗号分隔。
2
+ const companyEmailRules = (import.meta.env.VITE_COMPANY_EMAIL_DOMAINS || '')
3
+ .split(',')
4
+ .map((rule: string) => rule.trim().toLowerCase().replace(/^@/, ''))
5
+ .filter(Boolean);
6
+
7
+ const normalizeEmail = (email?: string) => (email || '').trim().toLowerCase();
8
+
9
+ export const getCompanyEmailRuleText = () => companyEmailRules.join('、');
10
+
11
+ export const isCompanyEmail = (email?: string) => {
12
+ const normalizedEmail = normalizeEmail(email);
13
+ const domain = normalizedEmail.split('@')[1];
14
+
15
+ // 兼容两种配置:完整邮箱地址或邮箱域名。
16
+ return companyEmailRules.some((rule: string) => (
17
+ rule.includes('@') ? rule === normalizedEmail : Boolean(domain && rule === domain)
18
+ ));
19
+ };
@@ -0,0 +1,59 @@
1
+ 'use strict'
2
+
3
+ /**
4
+ * Copyright (c) 2021 bpui All Rights Reserved.
5
+ * Author: brian.li
6
+ * Date: 2021-08-25 14:24
7
+ * Desc:
8
+ */
9
+
10
+ /**
11
+ * @descs 禁止浏览器调试.
12
+ */
13
+ export function forbidDebugger() {
14
+ const check = function() {
15
+ function doCheck(a:number) {
16
+ if (('' + a / a)['length'] !== 1 || a % 20 === 0) {
17
+ ;(function() {}['constructor']('debugger')())
18
+ } else {
19
+ ;(function() {}['constructor']('debugger')())
20
+ }
21
+ doCheck(++a)
22
+ }
23
+ try {
24
+ doCheck(0)
25
+ } catch (err) { ; }
26
+ }
27
+
28
+ const checkDebuggerWindow = function() {
29
+ const thresholdW = 160 // 打开控制台的宽或高阈值
30
+ const thresholdH = 160 + 200 // 打开控制台的宽或高阈值
31
+ if (
32
+ window.outerWidth - window.innerWidth > thresholdW ||
33
+ window.outerHeight - window.innerHeight > thresholdH
34
+ ) {
35
+ window.close()
36
+ ;(window.location as any) = 'about:blank'
37
+ }
38
+ }
39
+
40
+ setInterval(function() {
41
+ if (!__debug) {
42
+ checkDebuggerWindow()
43
+ check()
44
+ }
45
+ }, 5000)
46
+
47
+ if (!__debug) {
48
+ checkDebuggerWindow()
49
+ check()
50
+
51
+ // f12.
52
+ window.onkeydown = window.onkeyup = window.onkeypress = function (event) {
53
+ if (event.keyCode === 123) {
54
+ event.preventDefault()
55
+ window.event.returnValue = false
56
+ }
57
+ }
58
+ }
59
+ }
@@ -0,0 +1,94 @@
1
+ /**
2
+ * e.g. 2026/04/17
3
+ * @param date
4
+ * @returns
5
+ */
6
+
7
+ const initalDate = 0; // new Date('1970-01-01T08:00:00.000Z').getTime();
8
+
9
+ export const formatDate = (date: Date | string): string => {
10
+ if (!date) return '无';
11
+ if (typeof date === 'string') {
12
+ date = new Date(date);
13
+ }
14
+
15
+ if (date.getTime() == initalDate) {
16
+ return '无';
17
+ }
18
+
19
+ if (isNaN(date.getTime())) {
20
+ return '无';
21
+ }
22
+
23
+
24
+ return date.toLocaleDateString('zh-CN', {
25
+ year: 'numeric',
26
+ month: '2-digit',
27
+ day: 'numeric'
28
+ });
29
+ };
30
+
31
+ /**
32
+ * e.g. 2026/04/17 20:41
33
+ * @param date
34
+ * @returns
35
+ */
36
+ export const formatDatetime = (date: Date|string): string => {
37
+ if (!date) return '无';
38
+ if (typeof date === 'string') {
39
+ date = new Date(date);
40
+ }
41
+
42
+ if (date.getTime() == initalDate) {
43
+ return '无';
44
+ }
45
+
46
+ if (isNaN(date.getTime())) {
47
+ return '无';
48
+ }
49
+
50
+
51
+ return date.toLocaleDateString('zh-CN', {
52
+ year: 'numeric',
53
+ month: '2-digit',
54
+ day: 'numeric',
55
+ hour: '2-digit',
56
+ minute: '2-digit'
57
+ });
58
+ };
59
+
60
+ export const formatCurrency = (amount: number): string => {
61
+ return new Intl.NumberFormat('zh-CN', {
62
+ style: 'currency',
63
+ currency: 'CNY'
64
+ }).format(amount);
65
+ };
66
+
67
+ /**
68
+ * 返回文件大小
69
+ */
70
+ export const formatDisksize = (filesize: number): string => {
71
+ if (!filesize) return '0 KB';
72
+
73
+ filesize = (filesize / 1024);
74
+ if (filesize < 1024) {
75
+ if (filesize.toFixed(1).endsWith('.0')) {
76
+ return filesize.toFixed(2) + ' KB';
77
+ }
78
+ return filesize.toFixed(1) + ' KB';
79
+ }
80
+
81
+ filesize = (filesize / 1024);
82
+ if (filesize < 1024) {
83
+ if (filesize.toFixed(1).endsWith('.0')) {
84
+ return filesize.toFixed(2) + ' MB';
85
+ }
86
+ return filesize.toFixed(1) + ' MB';
87
+ }
88
+
89
+ filesize = (filesize / 1024);
90
+ if (filesize.toFixed(1).endsWith('.0')) {
91
+ return filesize.toFixed(2) + ' GB';
92
+ }
93
+ return filesize.toFixed(1) + ' GB';
94
+ };