@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,617 @@
1
+ import React, { useEffect, useRef, useCallback, useState } from 'react';
2
+ import { Modal, Button, Space, message, Popconfirm, Tag } from 'antd';
3
+ import { SaveOutlined, FileExcelFilled, UploadOutlined, DeleteOutlined, CloseOutlined, CloudOutlined, CloudServerOutlined } from '@ant-design/icons';
4
+ import { UniverSheetsCorePreset } from '@univerjs/preset-sheets-core';
5
+ import UniverPresetSheetsCoreZhCN from '@univerjs/preset-sheets-core/locales/zh-CN';
6
+ import { createUniver, LocaleType, mergeLocales, Univer } from '@univerjs/presets';
7
+ import * as XLSX from 'xlsx';
8
+
9
+ import '@univerjs/preset-sheets-core/lib/index.css';
10
+ import { ArrowLeft } from 'lucide-react';
11
+ import { saveFile, loadFile, deleteFile } from '../IndexedDBUtils';
12
+ import { CacheUserInfo } from '../../../utils/CacheUserInfo';
13
+ import uiConfirm from '../../UIConfirm';
14
+
15
+ const SHEET_VALUE_CHANGE_COMMAND_IDS = new Set([
16
+ 'sheet.mutation.set-range-values',
17
+ 'sheet.mutation.move-range',
18
+ 'sheet.mutation.remove-worksheet-merge',
19
+ 'sheet.mutation.add-worksheet-merge',
20
+ 'sheet.mutation.reorder-range',
21
+ 'sheet.mutation.set-worksheet-default-style',
22
+ 'sheet.mutation.set-row-data',
23
+ 'sheet.mutation.set-col-data',
24
+ 'sheet.mutation.set-worksheet-range-theme-style',
25
+ 'sheet.mutation.remove-worksheet-range-theme-style',
26
+ ]);
27
+
28
+ interface ExcelEditorProps {
29
+ visible: boolean;
30
+ hiddenClose?: boolean; // 是否隐藏关闭按钮
31
+ isCreate?: boolean; // 是否为新建模式
32
+ onClose: () => void;
33
+ fileName: string;
34
+ onUpload?: (initialBlob:Blob|undefined, blob: Blob, fileName: string) => Promise<void>;
35
+ initialBlob?: Blob;
36
+ readOnly?: boolean;
37
+ uploadPercent?: number;
38
+ uploadSuccess?: boolean;
39
+ // ---- 新增:本地文件 / 离线模式支持 ----
40
+ isOffline?: boolean;
41
+ isLocalOnly?: boolean;
42
+ hasUnsyncedChanges?: boolean;
43
+ onSaveLocalBlob?: (blob: Blob, fileName: string, markUnsynced?: boolean) => Promise<void>;
44
+ }
45
+
46
+ export const ExcelEditor: React.FC<ExcelEditorProps> = ({ visible, hiddenClose = false, isCreate, onClose, fileName, onUpload, initialBlob, readOnly, uploadPercent, uploadSuccess, isOffline, isLocalOnly, hasUnsyncedChanges, onSaveLocalBlob }) => {
47
+ const containerRef = useRef<HTMLDivElement>(null);
48
+ const univerRef = useRef<Univer | null>(null);
49
+ const univerAPIRef = useRef<any>(null);
50
+ const saveTimerRef = useRef<NodeJS.Timeout | null>(null);
51
+ const [userId, setUserId] = useState<string | null>(null);
52
+ const [initialWorkbookData, setInitialWorkbookData] = useState<any>(null);
53
+ const [editorKey, setEditorKey] = useState(0);
54
+ const [hasLocalCache, setHasLocalCache] = useState(false);
55
+ const [hasUploaded, setHasUploaded] = useState(!isCreate);
56
+ const [loadingInitialBlob, setLoadingInitialBlob] = useState(false);
57
+ // 跟踪"标记为未同步"的调用是否已在本次编辑会话中执行过,避免每次编辑都写 IndexedDB
58
+ const markUnsyncedTriggeredRef = useRef(false);
59
+ // 跟踪编辑器是否已完成初始加载。编辑器初始化时会触发 CommandExecuted,需抑制以免误标"有修改未同步"。
60
+ const isEditorReadyRef = useRef(false);
61
+ // 跟踪当前差分上传的基准 blob(即服务器上最新的文件内容)。
62
+ // 上传成功后会更新为本次上传的 blob,确保下次差分基准与服务器一致。
63
+ const baseBlobRef = useRef<Blob | undefined>(initialBlob);
64
+
65
+ // 用 ref 跟踪这些"状态标记"属性,避免它们的变化(如保存/上传后更新标记)
66
+ // 触发 Univer 初始化 useEffect 重新执行,导致编辑器销毁重建、画面闪动。
67
+ const hasUnsyncedChangesRef = useRef(hasUnsyncedChanges);
68
+ const onSaveLocalBlobRef = useRef(onSaveLocalBlob);
69
+ hasUnsyncedChangesRef.current = hasUnsyncedChanges;
70
+ onSaveLocalBlobRef.current = onSaveLocalBlob;
71
+
72
+ // 获取当前登录用户
73
+ useEffect(() => {
74
+ if (visible) {
75
+ const getUserId = async () => {
76
+ try {
77
+ const userInfo = CacheUserInfo.currentLocalUser();
78
+ if (userInfo?.id) {
79
+ setUserId(userInfo.id);
80
+ } else {
81
+ setUserId(null);
82
+ }
83
+ } catch (error) {
84
+ console.error('获取用户信息失败:', error);
85
+ setUserId(null);
86
+ }
87
+ };
88
+ getUserId();
89
+ }
90
+ }, [visible]);
91
+
92
+ // 加载初始文件
93
+ useEffect(() => {
94
+ const loadInitialFile = async () => {
95
+ if (visible && userId) {
96
+ // 如果有传入的 initialBlob,优先加载它
97
+ if (initialBlob) {
98
+ try {
99
+ setLoadingInitialBlob(true);
100
+
101
+ // 需求3:彻底移除旧缓存检查。既然有了 initialBlob,直接加载
102
+ // 使用 XLSX 读取 blob 并转换为 Univer 格式
103
+ const arrayBuffer = await initialBlob.arrayBuffer();
104
+ const workbook = XLSX.read(arrayBuffer);
105
+
106
+ // 将 XLSX 格式转换为 Univer 工作簿格式
107
+ const univerWorkbookData: any = {
108
+ id: `workbook-${Date.now()}`, // 添加工作簿 ID
109
+ name: fileName,
110
+ sheets: {},
111
+ sheetOrder: [],
112
+ locale: 'zhCN',
113
+ appVersion: '0.10.2'
114
+ };
115
+
116
+ workbook.SheetNames.forEach((sheetName) => {
117
+ const worksheet = workbook.Sheets[sheetName];
118
+ const sheetId = `sheet-${Date.now()}-${sheetName}`; // 生成唯一的工作表 ID
119
+
120
+ // 使用 sheet_to_json 的 range 选项来获取所有单元格,包括空单元格
121
+ const jsonData = XLSX.utils.sheet_to_json(worksheet, {
122
+ header: 1,
123
+ defval: '', // 为空单元格提供默认值
124
+ raw: false // 获取格式化后的值
125
+ });
126
+
127
+ // 转换为 Univer 格式
128
+ univerWorkbookData.sheets[sheetId] = {
129
+ id: sheetId, // 添加工作表 ID
130
+ name: sheetName,
131
+ cellData: {},
132
+ rowData: {},
133
+ columnData: {},
134
+ rowCount: Math.max(jsonData.length, 100), // 设置合理的行数
135
+ columnCount: Math.max(...(jsonData as any[][]).map((row: any[]) => row?.length || 0), 20), // 设置合理的列数
136
+ defaultColumnWidth: 100,
137
+ defaultRowHeight: 25,
138
+ showGridlines: 1,
139
+ rowHeader: { width: 46 },
140
+ columnHeader: { height: 20 },
141
+ };
142
+
143
+ // 填充单元格数据(使用嵌套对象结构)
144
+ (jsonData as any[][]).forEach((row: any[], rowIndex: number) => {
145
+ if (!univerWorkbookData.sheets[sheetId].cellData[rowIndex]) {
146
+ univerWorkbookData.sheets[sheetId].cellData[rowIndex] = {};
147
+ }
148
+
149
+ row.forEach((cellValue: any, colIndex: number) => {
150
+ // 只保存非空值
151
+ if (cellValue !== undefined && cellValue !== null && cellValue !== '') {
152
+ univerWorkbookData.sheets[sheetId].cellData[rowIndex][colIndex] = {
153
+ v: cellValue,
154
+ };
155
+ }
156
+ });
157
+ });
158
+
159
+ univerWorkbookData.sheetOrder.push(sheetId);
160
+ });
161
+
162
+ setInitialWorkbookData(univerWorkbookData);
163
+ setEditorKey((prev) => prev + 1);
164
+ setHasLocalCache(false);
165
+ } catch (error) {
166
+ console.error('加载文件失败:', error);
167
+ message.error('加载文件失败');
168
+ setInitialWorkbookData(null);
169
+ setHasLocalCache(false);
170
+ } finally {
171
+ setLoadingInitialBlob(false);
172
+ }
173
+ } else if (isCreate && fileName && userId) {
174
+ // 需求3:新建模式下不再自动检查/加载旧的本地缓存
175
+ // 新建的本地文件会通过 initialBlob 从 localFiles store 传入内容
176
+ // 没有 initialBlob 时(兜底),直接创建空白工作簿(univer 初始化时自动创建)
177
+ try {
178
+ setInitialWorkbookData(null);
179
+ setHasLocalCache(false);
180
+ } catch (error) {
181
+ console.error('创建新工作簿失败:', error);
182
+ setInitialWorkbookData(null);
183
+ setHasLocalCache(false);
184
+ }
185
+ } else {
186
+ // 没有用户ID,重置状态
187
+ setInitialWorkbookData(null);
188
+ setHasLocalCache(false);
189
+ }
190
+ }
191
+ };
192
+
193
+ loadInitialFile();
194
+ }, [visible, fileName, userId, initialBlob, isCreate, readOnly]);
195
+
196
+ // 获取当前工作簿数据
197
+ const getWorkbookData = useCallback(() => {
198
+ if (!univerAPIRef.current) return null;
199
+ const workbook = univerAPIRef.current.getActiveWorkbook();
200
+ if (!workbook) return null;
201
+ return workbook.save(); // workbook.getSnapshot();
202
+ }, []);
203
+
204
+ // 提交正在编辑的单元格内容(在导出/保存前调用)
205
+ const commitCellEditor = useCallback(async (event?: React.MouseEvent<HTMLElement>): Promise<void> => {
206
+ // 阻止按钮获取焦点,避免编辑器在 endEditing 之前丢失焦点
207
+ if (event) {
208
+ event.preventDefault();
209
+ event.stopPropagation();
210
+ }
211
+
212
+ try {
213
+ const workbook = univerAPIRef.current?.getActiveWorkbook?.();
214
+ if (workbook && typeof (workbook as any).endEditingAsync === 'function') {
215
+ await (workbook as any).endEditingAsync(true);
216
+ console.log('[Excel] endEditingAsync(true) 完成');
217
+ } else if (workbook && typeof (workbook as any).endEditing === 'function') {
218
+ await (workbook as any).endEditing(true);
219
+ console.log('[Excel] endEditing(true) 完成');
220
+ }
221
+ } catch (err) {
222
+ console.warn('[Excel] 提交单元格编辑失败:', err);
223
+ }
224
+ }, []);
225
+
226
+ // 导出 Excel 文件为 Blob
227
+ const exportToBlob = useCallback(async (): Promise<Blob | null> => {
228
+ try {
229
+ if (!univerAPIRef.current) {
230
+ message.error('编辑器未初始化');
231
+ return null;
232
+ }
233
+
234
+ const workbook = univerAPIRef.current.getActiveWorkbook();
235
+ if (!workbook) {
236
+ message.error('没有可保存的工作簿');
237
+ return null;
238
+ }
239
+
240
+ // 提交正在编辑的单元格内容
241
+ await commitCellEditor();
242
+
243
+ // 使用 Univer API 获取快照数据
244
+ const snapshot = workbook.save();
245
+
246
+ // 将 Univer 快照数据转换为 XLSX 格式
247
+ const xlsxWorkbook = XLSX.utils.book_new();
248
+
249
+ // 遍历所有工作表
250
+ if (snapshot.sheets && snapshot.sheetOrder) {
251
+ snapshot.sheetOrder.forEach((sheetId: string) => {
252
+ const sheet = snapshot.sheets[sheetId];
253
+ if (!sheet) return;
254
+
255
+ const sheetName = sheet.name || '工作表';
256
+ const cellData = sheet.cellData || {};
257
+
258
+ // 转换单元格数据为二维数组
259
+ const data: any[][] = [];
260
+
261
+ // 遍历所有行
262
+ Object.keys(cellData).forEach((rowKey: string) => {
263
+ const rowIndex = parseInt(rowKey);
264
+ const row = cellData[rowKey];
265
+
266
+ // 确保数组有足够的行
267
+ while (data.length <= rowIndex) {
268
+ data.push([]);
269
+ }
270
+
271
+ // 遍历所有列
272
+ Object.keys(row).forEach((colKey: string) => {
273
+ const colIndex = parseInt(colKey);
274
+ const cell = row[colKey];
275
+
276
+ // 确保数组有足够的列
277
+ while (data[rowIndex].length <= colIndex) {
278
+ data[rowIndex].push('');
279
+ }
280
+
281
+ // 设置单元格值
282
+ data[rowIndex][colIndex] = cell?.v || '';
283
+ });
284
+ });
285
+
286
+ const worksheet = XLSX.utils.aoa_to_sheet(data);
287
+ XLSX.utils.book_append_sheet(xlsxWorkbook, worksheet, sheetName);
288
+ });
289
+ }
290
+
291
+ const excelBuffer = XLSX.write(xlsxWorkbook, { bookType: 'xlsx', type: 'array' });
292
+ return new Blob([excelBuffer], { type: 'application/vnd.openxmlformats-officedocument.spreadsheetml.sheet' });
293
+ } catch (error) {
294
+ console.error('导出 Excel 失败:', error);
295
+ return null;
296
+ }
297
+ }, []);
298
+
299
+ // 自动保存到 IndexedDB(防抖)+ 同步 localFiles store
300
+ const autoSaveToIndexedDB = useCallback(() => {
301
+ if (!fileName || !userId) return;
302
+
303
+ const data = getWorkbookData();
304
+ if (!data) return;
305
+
306
+ if (saveTimerRef.current) {
307
+ clearTimeout(saveTimerRef.current);
308
+ }
309
+
310
+ saveTimerRef.current = setTimeout(async () => {
311
+ try {
312
+ await saveFile(userId, fileName, 'xlsx', data);
313
+ setHasLocalCache(false);
314
+ // 同步更新 localFiles store,确保自动保存也持久化到 localFiles
315
+ const fn = onSaveLocalBlobRef.current;
316
+ if (fn) {
317
+ try {
318
+ const blob = await exportToBlob();
319
+ if (blob) {
320
+ await fn(blob, fileName, false);
321
+ }
322
+ } catch (err) {
323
+ console.warn('自动保存时同步 localFiles store 失败(不影响本地保存):', err);
324
+ }
325
+ }
326
+ } catch (error) {
327
+ console.error('自动保存到 IndexedDB 失败:', error);
328
+ }
329
+ }, 20000);
330
+ }, [fileName, userId, getWorkbookData, exportToBlob]);
331
+
332
+ // 初始化 Univer
333
+ useEffect(() => {
334
+ if (!visible || !containerRef.current) return;
335
+
336
+ // 清理之前的实例
337
+ if (univerAPIRef.current) {
338
+ univerAPIRef.current.dispose();
339
+ univerAPIRef.current = null;
340
+ univerRef.current = null;
341
+ }
342
+
343
+ // 创建 Univer 实例
344
+ const { univer, univerAPI } = createUniver({
345
+ locale: LocaleType.ZH_CN,
346
+ locales: {
347
+ [LocaleType.ZH_CN]: mergeLocales(UniverPresetSheetsCoreZhCN),
348
+ },
349
+ presets: [
350
+ UniverSheetsCorePreset({
351
+ container: containerRef.current,
352
+ }),
353
+ ],
354
+ });
355
+
356
+ univerRef.current = univer;
357
+ univerAPIRef.current = univerAPI;
358
+
359
+ // 创建或加载工作簿
360
+ if (initialWorkbookData) {
361
+ try {
362
+ univerAPI.createWorkbook(initialWorkbookData);
363
+ } catch (e) {
364
+ univerAPI.createWorkbook({ name: fileName });
365
+ }
366
+ } else {
367
+ univerAPI.createWorkbook({ name: fileName });
368
+ }
369
+
370
+ // 监听工作簿内容变化,只有真实编辑内容变化时才标记未保存并触发防抖保存。
371
+ const valueChangeDisposable = univerAPI.addEvent(univerAPI.Event.CommandExecuted, ({ id }: { id: string }) => {
372
+ if (readOnly || !SHEET_VALUE_CHANGE_COMMAND_IDS.has(id)) return;
373
+ // 抑制编辑器初始化期间触发的 CommandExecuted,避免误标"有修改未同步"
374
+ if (!isEditorReadyRef.current) return;
375
+
376
+ setHasLocalCache(true);
377
+ setHasUploaded(false);
378
+ autoSaveToIndexedDB();
379
+
380
+ // 首次编辑(且 hasUnsyncedChanges 目前为 false)时,立即标记未同步。
381
+ // 上传成功后 hasUnsyncedChanges 被清除,用户继续编辑后应立即重新显示"有未同步修改"。
382
+ if (!markUnsyncedTriggeredRef.current && !hasUnsyncedChangesRef.current && onSaveLocalBlobRef.current) {
383
+ markUnsyncedTriggeredRef.current = true;
384
+ const fn = onSaveLocalBlobRef.current;
385
+ (async () => {
386
+ try {
387
+ const blob = await exportToBlob();
388
+ if (blob) {
389
+ await fn(blob, fileName);
390
+ } else {
391
+ markUnsyncedTriggeredRef.current = false;
392
+ }
393
+ } catch (err) {
394
+ markUnsyncedTriggeredRef.current = false;
395
+ console.warn('编辑时立即标记未同步失败(不影响编辑,等待自动/手动保存即可):', err);
396
+ }
397
+ })();
398
+ }
399
+ });
400
+
401
+ return () => {
402
+ valueChangeDisposable.dispose();
403
+ if (univerAPIRef.current) {
404
+ univerAPIRef.current.dispose();
405
+ univerAPIRef.current = null;
406
+ univerRef.current = null;
407
+ }
408
+ };
409
+ }, [visible, fileName, initialWorkbookData, editorKey, autoSaveToIndexedDB, readOnly, exportToBlob]);
410
+
411
+ // 编辑器初始化后,延迟标记为"就绪",让初始化期间的 CommandExecuted 事件先过去
412
+ useEffect(() => {
413
+ if (!visible || loadingInitialBlob) return;
414
+ const timer = setTimeout(() => {
415
+ isEditorReadyRef.current = true;
416
+ }, 2000);
417
+ return () => {
418
+ clearTimeout(timer);
419
+ isEditorReadyRef.current = false;
420
+ };
421
+ }, [editorKey, visible, loadingInitialBlob]);
422
+
423
+ // initialBlob 变化时(文件切换/加载)重置差分基准
424
+ useEffect(() => {
425
+ baseBlobRef.current = initialBlob;
426
+ }, [initialBlob]);
427
+
428
+ // 保存到 IndexedDB
429
+ const handleSave = useCallback(async () => {
430
+ try {
431
+ const data = getWorkbookData();
432
+ if (!data) {
433
+ message.error('编辑器未初始化');
434
+ return;
435
+ }
436
+ if (!userId) {
437
+ message.error('无法获取用户信息');
438
+ return;
439
+ }
440
+
441
+ await saveFile(userId, fileName, 'xlsx', data);
442
+ setHasLocalCache(false);
443
+
444
+ // 通知父组件更新 localFiles store(需同时导出为 blob)
445
+ if (onSaveLocalBlob) {
446
+ try {
447
+ const blob = await exportToBlob();
448
+ if (blob) {
449
+ await onSaveLocalBlob(blob, fileName, false);
450
+ }
451
+ } catch (err) {
452
+ console.warn('同步本地文件内容到 localFiles store 失败(不影响本地保存):', err);
453
+ }
454
+ }
455
+
456
+ message.success('已保存到本地缓存');
457
+ } catch (error) {
458
+ console.error('保存到本地缓存失败:', error);
459
+ message.error('保存失败');
460
+ }
461
+ }, [fileName, userId, getWorkbookData, exportToBlob, onSaveLocalBlob]);
462
+
463
+ // 上传到服务器
464
+ const handleUpload = useCallback(async () => {
465
+ if (!onUpload) {
466
+ message.error('未提供上传功能');
467
+ return;
468
+ }
469
+ try {
470
+ const blob = await exportToBlob();
471
+ if (!blob) return;
472
+
473
+ // 使用 baseBlobRef 作为差分基准,而非 initialBlob。
474
+ // 上传成功后 baseBlobRef 会更新为本次上传的 blob,确保下次差分基准与服务端一致。
475
+ const baseBlob = baseBlobRef.current ?? initialBlob;
476
+ await onUpload(baseBlob, blob, fileName);
477
+
478
+ // 上传成功后更新差分基准,使下次上传的差分基准与服务器一致
479
+ baseBlobRef.current = blob;
480
+
481
+ // 上传成功后,清空本地缓存
482
+ if (userId) {
483
+ await deleteFile(userId, fileName, 'xlsx');
484
+ setHasLocalCache(false);
485
+ setHasUploaded(true);
486
+ }
487
+ // 上传成功后重置"立即标记未同步"触发器,使后续编辑可再次立即触发
488
+ markUnsyncedTriggeredRef.current = false;
489
+ } catch (error) {
490
+ console.error('上传失败:', error);
491
+ message.error('上传失败');
492
+ }
493
+ }, [fileName, onUpload, exportToBlob, userId, initialBlob]);
494
+
495
+ // Ctrl+S / Cmd+S 保存到本地缓存
496
+ useEffect(() => {
497
+ if (!visible) return;
498
+ const handleKeyDown = (e: KeyboardEvent) => {
499
+ if ((e.ctrlKey || e.metaKey) && e.key === 's') {
500
+ e.preventDefault();
501
+ handleSave();
502
+ }
503
+ };
504
+ window.addEventListener('keydown', handleKeyDown);
505
+ return () => window.removeEventListener('keydown', handleKeyDown);
506
+ }, [visible, handleSave]);
507
+
508
+ // 重置状态和清理定时器(当编辑器打开/关闭时)
509
+ useEffect(() => {
510
+ if (visible) {
511
+ setHasUploaded(!isCreate);
512
+ // 重置"立即标记未同步"触发器
513
+ markUnsyncedTriggeredRef.current = false;
514
+ // 清理之前的定时器
515
+ if (saveTimerRef.current) {
516
+ clearTimeout(saveTimerRef.current);
517
+ saveTimerRef.current = null;
518
+ }
519
+ }
520
+
521
+ // 组件卸载时清理定时器
522
+ return () => {
523
+ if (saveTimerRef.current) {
524
+ clearTimeout(saveTimerRef.current);
525
+ saveTimerRef.current = null;
526
+ }
527
+ };
528
+ }, [visible, isCreate]);
529
+
530
+ return (
531
+ <Modal
532
+ open={visible}
533
+ onCancel={onClose}
534
+ keyboard={false}
535
+ closeIcon={null}
536
+ footer={null}
537
+ style={{ top: 0, maxWidth: '100vw' }}
538
+ styles={{
539
+ body: {
540
+ height: '100dvh',
541
+ padding: 0,
542
+ },
543
+ }}
544
+ className="ant-modal-nopadding ant-modal-fullscreen"
545
+ transitionName='none'
546
+ >
547
+ <div className="h-full flex flex-col bg-white p-0 m-0">
548
+ {/* 工具栏 */}
549
+ <div className={`flex items-center justify-between px-4 py-2 pr-0 border-b flex-shrink-0 ${isOffline ? 'bg-orange-50 border-orange-200' : 'bg-gray-50 border-gray-200'}`}>
550
+ {/* 只读模式下直接关闭,不需要提示保存 */}
551
+ <span>&nbsp;</span>
552
+ {!readOnly && <span>&nbsp;</span>}
553
+ <div className="flex items-center gap-2 flex-wrap min-w-[40%]">
554
+ {!isOffline && isLocalOnly && (
555
+ <Tag icon={<CloudOutlined />} color="orange" style={{ margin: 0 }}>
556
+ 本地文件
557
+ </Tag>
558
+ )}
559
+ {!isOffline && !isLocalOnly && hasUnsyncedChanges && (
560
+ <Tag icon={<CloudOutlined />} color="warning" style={{ margin: 0 }}>
561
+ 有未同步修改
562
+ </Tag>
563
+ )}
564
+ {!isOffline && !isLocalOnly && !hasUnsyncedChanges && !onUpload ? (
565
+ <Tag icon={<CloudServerOutlined />} color="default" style={{ margin: 0 }}>
566
+ 同步完成
567
+ </Tag>
568
+ ) : null}
569
+ <FileExcelFilled className="text-green-600" />
570
+ <span className="text-sm font-medium">{hasLocalCache ? '*' : ''}{fileName}</span>
571
+ </div>
572
+ {!readOnly && !hiddenClose && (
573
+ <Space wrap={true} align="center" direction="horizontal">
574
+ {/* <Button icon={<DeleteOutlined />} onClick={handleClearCache}>
575
+ 清除缓存
576
+ </Button> */}
577
+ {onUpload && (
578
+ <Button type="text" style={{ paddingLeft: 4, paddingRight: 4 }} title="每次上传将保留一个历史版本,最多保留10个版本" icon={<UploadOutlined />} onMouseDown={commitCellEditor} onClick={handleUpload} disabled={uploadPercent !== undefined && uploadPercent < 1}>
579
+ {uploadPercent !== undefined && uploadPercent < 1 ? `上传中 ${Math.round(uploadPercent * 100)}%` : '上传'}
580
+ </Button>
581
+ )}
582
+ <Button type="primary" icon={<SaveOutlined />} onMouseDown={commitCellEditor} onClick={handleSave}>
583
+ 保存
584
+ </Button>
585
+ {(!readOnly && (hasLocalCache || !hasUploaded)) ?
586
+ (<Popconfirm
587
+ title="确定要退出吗?"
588
+ description={hasLocalCache?"修改未保存,确定要退出吗?": "修改未上传,确定要退出吗?"}
589
+ onConfirm={onClose}
590
+ okText="确定"
591
+ cancelText="取消"
592
+ >
593
+ <Button type="text" className="ml-3 mr-2" icon={<CloseOutlined className="w-6 h-6" />} />
594
+ </Popconfirm>) : (<CloseOutlined onClick={onClose} className='ml-3 mr-2 w-6 h-6'/>)}
595
+ </Space>
596
+ )}
597
+ {readOnly && !hiddenClose && (
598
+ <CloseOutlined onClick={onClose} className='ml-3 mr-2 w-6 h-6'/>)
599
+ }
600
+ {hiddenClose && <span>&nbsp;</span>}
601
+ </div>
602
+
603
+ {/* Univer 编辑器容器 */}
604
+ <div className="relative flex-1 min-h-0">
605
+ <div
606
+ key={editorKey}
607
+ ref={containerRef}
608
+ className="h-full univer-container overflow-hidden"
609
+ style={{ height: 'calc(100vh - 48px)' }}
610
+ />
611
+ </div>
612
+ </div>
613
+ </Modal>
614
+ );
615
+ };
616
+
617
+ export default ExcelEditor;
@@ -0,0 +1,24 @@
1
+ export interface ExcelEditorProps {
2
+ visible: boolean;
3
+ onClose: () => void;
4
+ fileName: string;
5
+ }
6
+
7
+ export interface ExcelCell {
8
+ value: string | number | boolean | null;
9
+ formula?: string;
10
+ }
11
+
12
+ export interface ExcelSheet {
13
+ name: string;
14
+ data: ExcelCell[][];
15
+ colWidths: number[];
16
+ rowHeights: number[];
17
+ }
18
+
19
+ export interface ExcelEditorState {
20
+ sheets: ExcelSheet[];
21
+ currentSheetIndex: number;
22
+ selectedCell: { row: number; col: number } | null;
23
+ selectedRange: { startRow: number; startCol: number; endRow: number; endCol: number } | null;
24
+ }