sa2kit 1.6.44 → 1.6.46

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 (267) hide show
  1. package/dist/AliyunOSSProvider-2FARPAQD.js +15 -0
  2. package/dist/{AliyunOSSProvider-HCNGDJL7.js.map → AliyunOSSProvider-2FARPAQD.js.map} +1 -1
  3. package/dist/AliyunOSSProvider-UMVGVBDJ.mjs +9 -0
  4. package/dist/{AliyunOSSProvider-4W47OFEK.mjs.map → AliyunOSSProvider-UMVGVBDJ.mjs.map} +1 -1
  5. package/dist/CollisionBalls-BpHufX3H.d.mts +41 -0
  6. package/dist/CollisionBalls-BpHufX3H.d.ts +41 -0
  7. package/dist/ConfigService-QR67WYNK.mjs +4 -0
  8. package/dist/{ConfigService-V6ZK273Z.mjs.map → ConfigService-QR67WYNK.mjs.map} +1 -1
  9. package/dist/{ConfigService-3DIC6C3Q.js → ConfigService-UYC6ZTCM.js} +3 -3
  10. package/dist/{ConfigService-3DIC6C3Q.js.map → ConfigService-UYC6ZTCM.js.map} +1 -1
  11. package/dist/GenericOrderManager-e4WizpNf.d.mts +28 -0
  12. package/dist/GenericOrderManager-e4WizpNf.d.ts +28 -0
  13. package/dist/LocalStorageProvider-JQF5WK5H.js +15 -0
  14. package/dist/{LocalStorageProvider-PP7MA5OT.js.map → LocalStorageProvider-JQF5WK5H.js.map} +1 -1
  15. package/dist/LocalStorageProvider-PYOHETJV.mjs +9 -0
  16. package/dist/{LocalStorageProvider-3RVPCQB3.mjs.map → LocalStorageProvider-PYOHETJV.mjs.map} +1 -1
  17. package/dist/PMXParser-RLBDO7YK.mjs +4 -0
  18. package/dist/{PMXParser-RNVQL76A.mjs.map → PMXParser-RLBDO7YK.mjs.map} +1 -1
  19. package/dist/{PMXParser-2VTA737I.js → PMXParser-XHNO2KNI.js} +3 -3
  20. package/dist/{PMXParser-2VTA737I.js.map → PMXParser-XHNO2KNI.js.map} +1 -1
  21. package/dist/UniversalFileService-RBV6EN5J.js +15 -0
  22. package/dist/UniversalFileService-RBV6EN5J.js.map +1 -0
  23. package/dist/UniversalFileService-TNYKO6JN.mjs +9 -0
  24. package/dist/UniversalFileService-TNYKO6JN.mjs.map +1 -0
  25. package/dist/analytics/index.js +1 -1
  26. package/dist/analytics/index.mjs +1 -1
  27. package/dist/analytics/server/index.js +1 -1
  28. package/dist/analytics/server/index.mjs +1 -1
  29. package/dist/api/index.js +1 -1
  30. package/dist/api/index.mjs +1 -1
  31. package/dist/audioDetection/index.js +1 -1
  32. package/dist/audioDetection/index.mjs +1 -1
  33. package/dist/auth/client/index.js +1 -1
  34. package/dist/auth/client/index.mjs +1 -1
  35. package/dist/auth/components/index.js +1 -1
  36. package/dist/auth/components/index.mjs +1 -1
  37. package/dist/auth/hooks/index.js +1 -1
  38. package/dist/auth/hooks/index.mjs +1 -1
  39. package/dist/auth/index.js +1 -1
  40. package/dist/auth/index.mjs +1 -1
  41. package/dist/auth/middleware/index.js +1 -1
  42. package/dist/auth/middleware/index.mjs +1 -1
  43. package/dist/auth/routes/index.js +1 -1
  44. package/dist/auth/routes/index.mjs +1 -1
  45. package/dist/auth/schema/index.js +1 -1
  46. package/dist/auth/schema/index.mjs +1 -1
  47. package/dist/auth/services/index.js +1 -1
  48. package/dist/auth/services/index.mjs +1 -1
  49. package/dist/calendar/index.js +12 -12
  50. package/dist/calendar/index.mjs +5 -5
  51. package/dist/calendar/routes/index.js +1 -1
  52. package/dist/calendar/routes/index.mjs +1 -1
  53. package/dist/calendar/server.js +1 -1
  54. package/dist/calendar/server.mjs +1 -1
  55. package/dist/chunk-2PS5PIXV.mjs +443 -0
  56. package/dist/chunk-2PS5PIXV.mjs.map +1 -0
  57. package/dist/chunk-35CXIK5Y.js +277 -0
  58. package/dist/chunk-35CXIK5Y.js.map +1 -0
  59. package/dist/{chunk-GMIUSZXC.mjs → chunk-3JW4X3AC.mjs} +3 -3
  60. package/dist/{chunk-GMIUSZXC.mjs.map → chunk-3JW4X3AC.mjs.map} +1 -1
  61. package/dist/chunk-3M6T5KVD.js +453 -0
  62. package/dist/chunk-3M6T5KVD.js.map +1 -0
  63. package/dist/chunk-3TNR6IMC.js +168 -0
  64. package/dist/chunk-3TNR6IMC.js.map +1 -0
  65. package/dist/chunk-4NFOSCM6.js +34 -0
  66. package/dist/chunk-4NFOSCM6.js.map +1 -0
  67. package/dist/{chunk-3NHAT7D4.mjs → chunk-4VJQZSPU.mjs} +4 -3
  68. package/dist/chunk-4VJQZSPU.mjs.map +1 -0
  69. package/dist/{chunk-SCDDMIF6.js → chunk-4XXIBWCO.js} +66 -66
  70. package/dist/{chunk-SCDDMIF6.js.map → chunk-4XXIBWCO.js.map} +1 -1
  71. package/dist/chunk-6AHYPPUP.js +344 -0
  72. package/dist/chunk-6AHYPPUP.js.map +1 -0
  73. package/dist/{chunk-EGJPS7OL.mjs → chunk-6BJ76BYC.mjs} +3 -3
  74. package/dist/{chunk-EGJPS7OL.mjs.map → chunk-6BJ76BYC.mjs.map} +1 -1
  75. package/dist/chunk-76V7EKBX.mjs +796 -0
  76. package/dist/chunk-76V7EKBX.mjs.map +1 -0
  77. package/dist/chunk-ACLOJXXE.js +195 -0
  78. package/dist/chunk-ACLOJXXE.js.map +1 -0
  79. package/dist/chunk-AEXPAH7Z.mjs +32 -0
  80. package/dist/chunk-AEXPAH7Z.mjs.map +1 -0
  81. package/dist/chunk-CFGX3EKK.js +560 -0
  82. package/dist/chunk-CFGX3EKK.js.map +1 -0
  83. package/dist/chunk-D2HXMGXS.js +46 -0
  84. package/dist/chunk-D2HXMGXS.js.map +1 -0
  85. package/dist/chunk-DM2GUVUH.js +1201 -0
  86. package/dist/chunk-DM2GUVUH.js.map +1 -0
  87. package/dist/{chunk-ZWQJSZEY.js → chunk-DVENFCQY.js} +5 -4
  88. package/dist/chunk-DVENFCQY.js.map +1 -0
  89. package/dist/chunk-EONPKLEJ.mjs +163 -0
  90. package/dist/chunk-EONPKLEJ.mjs.map +1 -0
  91. package/dist/{chunk-L47ZOYHL.js → chunk-EUIXQPPU.js} +4 -4
  92. package/dist/{chunk-L47ZOYHL.js.map → chunk-EUIXQPPU.js.map} +1 -1
  93. package/dist/chunk-K7WNCB4V.mjs +554 -0
  94. package/dist/chunk-K7WNCB4V.mjs.map +1 -0
  95. package/dist/chunk-L4ZYBFB2.mjs +44 -0
  96. package/dist/chunk-L4ZYBFB2.mjs.map +1 -0
  97. package/dist/chunk-M4HGHTIC.js +820 -0
  98. package/dist/chunk-M4HGHTIC.js.map +1 -0
  99. package/dist/{chunk-HHVDOIPV.js → chunk-MZKATHB7.js} +4 -4
  100. package/dist/{chunk-HHVDOIPV.js.map → chunk-MZKATHB7.js.map} +1 -1
  101. package/dist/{chunk-UKT3PLON.mjs → chunk-NXQVTAOP.mjs} +3 -3
  102. package/dist/{chunk-UKT3PLON.mjs.map → chunk-NXQVTAOP.mjs.map} +1 -1
  103. package/dist/chunk-OBIPI4GU.mjs +266 -0
  104. package/dist/chunk-OBIPI4GU.mjs.map +1 -0
  105. package/dist/chunk-PAX4S7QM.mjs +94 -0
  106. package/dist/chunk-PAX4S7QM.mjs.map +1 -0
  107. package/dist/chunk-PXWDQFWV.mjs +192 -0
  108. package/dist/chunk-PXWDQFWV.mjs.map +1 -0
  109. package/dist/chunk-QROLPPXP.mjs +5797 -0
  110. package/dist/chunk-QROLPPXP.mjs.map +1 -0
  111. package/dist/chunk-TGNUEULF.mjs +1158 -0
  112. package/dist/chunk-TGNUEULF.mjs.map +1 -0
  113. package/dist/chunk-VBQFVXOW.mjs +2772 -0
  114. package/dist/chunk-VBQFVXOW.mjs.map +1 -0
  115. package/dist/chunk-VLZ5N6XZ.js +5888 -0
  116. package/dist/chunk-VLZ5N6XZ.js.map +1 -0
  117. package/dist/chunk-VTGPHE4Z.mjs +322 -0
  118. package/dist/chunk-VTGPHE4Z.mjs.map +1 -0
  119. package/dist/chunk-WMJKH4XE.mjs +30 -0
  120. package/dist/{chunk-BJTO5JO5.mjs.map → chunk-WMJKH4XE.mjs.map} +1 -1
  121. package/dist/chunk-XYQMAF7H.js +96 -0
  122. package/dist/chunk-XYQMAF7H.js.map +1 -0
  123. package/dist/chunk-Z3G3IXEF.js +2814 -0
  124. package/dist/chunk-Z3G3IXEF.js.map +1 -0
  125. package/dist/chunk-Z6ZWNWWR.js +35 -0
  126. package/dist/{chunk-DGUM43GV.js.map → chunk-Z6ZWNWWR.js.map} +1 -1
  127. package/dist/components/index.d.mts +378 -0
  128. package/dist/components/index.d.ts +378 -0
  129. package/dist/components/index.js +414 -0
  130. package/dist/components/index.js.map +1 -0
  131. package/dist/components/index.mjs +9 -0
  132. package/dist/components/index.mjs.map +1 -0
  133. package/dist/config/index.js +1 -1
  134. package/dist/config/index.mjs +1 -1
  135. package/dist/config/server/index.js +1 -1
  136. package/dist/config/server/index.mjs +1 -1
  137. package/dist/fileService-O3W6YXCI.mjs +4 -0
  138. package/dist/fileService-O3W6YXCI.mjs.map +1 -0
  139. package/dist/fileService-YUDIYOAS.js +13 -0
  140. package/dist/fileService-YUDIYOAS.js.map +1 -0
  141. package/dist/i18n/index.js +7 -7
  142. package/dist/i18n/index.mjs +1 -1
  143. package/dist/imageCrop/index.js +1 -1
  144. package/dist/imageCrop/index.mjs +1 -1
  145. package/dist/index.d.mts +9 -580
  146. package/dist/index.d.ts +9 -580
  147. package/dist/index.js +297 -956
  148. package/dist/index.js.map +1 -1
  149. package/dist/index.mjs +103 -789
  150. package/dist/index.mjs.map +1 -1
  151. package/dist/logger/index.js +8 -8
  152. package/dist/logger/index.mjs +5 -2
  153. package/dist/mikuFireworks3D/index.js +1 -1
  154. package/dist/mikuFireworks3D/index.mjs +1 -1
  155. package/dist/mikuFireworks3D/server/index.js +1 -1
  156. package/dist/mikuFireworks3D/server/index.mjs +1 -1
  157. package/dist/mikuFusionGame/index.js +5 -5
  158. package/dist/mikuFusionGame/index.mjs +4 -4
  159. package/dist/mmd/admin/index.js +1 -1
  160. package/dist/mmd/admin/index.mjs +1 -1
  161. package/dist/mmd/index.js +2 -2
  162. package/dist/mmd/index.mjs +2 -2
  163. package/dist/mmd/server/index.js +1 -1
  164. package/dist/mmd/server/index.mjs +1 -1
  165. package/dist/music/index.js +1 -1
  166. package/dist/music/index.mjs +1 -1
  167. package/dist/music/server/index.js +1 -1
  168. package/dist/music/server/index.mjs +1 -1
  169. package/dist/navigation/index.d.mts +93 -0
  170. package/dist/navigation/index.d.ts +93 -0
  171. package/dist/navigation/index.js +29 -0
  172. package/dist/navigation/index.js.map +1 -0
  173. package/dist/navigation/index.mjs +4 -0
  174. package/dist/navigation/index.mjs.map +1 -0
  175. package/dist/popupConfig-BznThU1O.d.mts +330 -0
  176. package/dist/popupConfig-BznThU1O.d.ts +330 -0
  177. package/dist/portfolio/index.d.mts +57 -0
  178. package/dist/portfolio/index.d.ts +57 -0
  179. package/dist/portfolio/index.js +35 -0
  180. package/dist/portfolio/index.js.map +1 -0
  181. package/dist/portfolio/index.mjs +10 -0
  182. package/dist/portfolio/index.mjs.map +1 -0
  183. package/dist/request/index.js +1 -1
  184. package/dist/request/index.mjs +1 -1
  185. package/dist/showmasterpiece/index.d.mts +2524 -0
  186. package/dist/showmasterpiece/index.d.ts +2524 -0
  187. package/dist/showmasterpiece/index.js +9681 -0
  188. package/dist/showmasterpiece/index.js.map +1 -0
  189. package/dist/showmasterpiece/index.mjs +9631 -0
  190. package/dist/showmasterpiece/index.mjs.map +1 -0
  191. package/dist/showmasterpiece/migration/index.d.mts +120 -0
  192. package/dist/showmasterpiece/migration/index.d.ts +120 -0
  193. package/dist/showmasterpiece/migration/index.js +595 -0
  194. package/dist/showmasterpiece/migration/index.js.map +1 -0
  195. package/dist/showmasterpiece/migration/index.mjs +589 -0
  196. package/dist/showmasterpiece/migration/index.mjs.map +1 -0
  197. package/dist/showmasterpiece/scripts/index.d.mts +28 -0
  198. package/dist/showmasterpiece/scripts/index.d.ts +28 -0
  199. package/dist/showmasterpiece/scripts/index.js +327 -0
  200. package/dist/showmasterpiece/scripts/index.js.map +1 -0
  201. package/dist/showmasterpiece/scripts/index.mjs +325 -0
  202. package/dist/showmasterpiece/scripts/index.mjs.map +1 -0
  203. package/dist/showmasterpiece/server/index.d.mts +2698 -0
  204. package/dist/showmasterpiece/server/index.d.ts +2698 -0
  205. package/dist/showmasterpiece/server/index.js +179 -0
  206. package/dist/showmasterpiece/server/index.js.map +1 -0
  207. package/dist/showmasterpiece/server/index.mjs +6 -0
  208. package/dist/showmasterpiece/server/index.mjs.map +1 -0
  209. package/dist/storage/index.js +8 -8
  210. package/dist/storage/index.mjs +2 -2
  211. package/dist/testYourself/admin/index.js +1 -1
  212. package/dist/testYourself/admin/index.mjs +1 -1
  213. package/dist/testYourself/index.js +2 -2
  214. package/dist/testYourself/index.mjs +2 -2
  215. package/dist/testYourself/server/index.js +1 -1
  216. package/dist/testYourself/server/index.mjs +1 -1
  217. package/dist/universalExport/index.js +154 -1195
  218. package/dist/universalExport/index.js.map +1 -1
  219. package/dist/universalExport/index.mjs +2 -1157
  220. package/dist/universalExport/index.mjs.map +1 -1
  221. package/dist/universalExport/server/index.js +5 -3
  222. package/dist/universalExport/server/index.js.map +1 -1
  223. package/dist/universalExport/server/index.mjs +4 -2
  224. package/dist/universalExport/server/index.mjs.map +1 -1
  225. package/dist/universalFile/index.js +10 -7
  226. package/dist/universalFile/index.js.map +1 -1
  227. package/dist/universalFile/index.mjs +6 -2
  228. package/dist/universalFile/index.mjs.map +1 -1
  229. package/dist/universalFile/server/index.d.mts +592 -265
  230. package/dist/universalFile/server/index.d.ts +592 -265
  231. package/dist/universalFile/server/index.js +298 -5637
  232. package/dist/universalFile/server/index.js.map +1 -1
  233. package/dist/universalFile/server/index.mjs +8 -5559
  234. package/dist/universalFile/server/index.mjs.map +1 -1
  235. package/dist/utils/index.js +12 -12
  236. package/dist/utils/index.mjs +3 -3
  237. package/package.json +36 -1
  238. package/dist/AliyunOSSProvider-4W47OFEK.mjs +0 -6
  239. package/dist/AliyunOSSProvider-HCNGDJL7.js +0 -15
  240. package/dist/ConfigService-V6ZK273Z.mjs +0 -4
  241. package/dist/LocalStorageProvider-3RVPCQB3.mjs +0 -6
  242. package/dist/LocalStorageProvider-PP7MA5OT.js +0 -15
  243. package/dist/PMXParser-RNVQL76A.mjs +0 -4
  244. package/dist/chunk-25OFOKNF.js +0 -171
  245. package/dist/chunk-25OFOKNF.js.map +0 -1
  246. package/dist/chunk-3DXPQ4YV.mjs +0 -165
  247. package/dist/chunk-3DXPQ4YV.mjs.map +0 -1
  248. package/dist/chunk-3NHAT7D4.mjs.map +0 -1
  249. package/dist/chunk-BJTO5JO5.mjs +0 -10
  250. package/dist/chunk-CIVO4R6N.mjs +0 -37
  251. package/dist/chunk-CIVO4R6N.mjs.map +0 -1
  252. package/dist/chunk-DGUM43GV.js +0 -12
  253. package/dist/chunk-HDMIOOZY.mjs +0 -546
  254. package/dist/chunk-HDMIOOZY.mjs.map +0 -1
  255. package/dist/chunk-HJ6MH7J7.js +0 -552
  256. package/dist/chunk-HJ6MH7J7.js.map +0 -1
  257. package/dist/chunk-KH6RQ4J5.js +0 -28
  258. package/dist/chunk-KH6RQ4J5.js.map +0 -1
  259. package/dist/chunk-Q5EDCKQA.js +0 -336
  260. package/dist/chunk-Q5EDCKQA.js.map +0 -1
  261. package/dist/chunk-YOTQG4NP.mjs +0 -314
  262. package/dist/chunk-YOTQG4NP.mjs.map +0 -1
  263. package/dist/chunk-ZGVB35L2.mjs +0 -25
  264. package/dist/chunk-ZGVB35L2.mjs.map +0 -1
  265. package/dist/chunk-ZRAW3HXA.js +0 -43
  266. package/dist/chunk-ZRAW3HXA.js.map +0 -1
  267. package/dist/chunk-ZWQJSZEY.js.map +0 -1
@@ -0,0 +1,820 @@
1
+ 'use strict';
2
+
3
+ var chunkACLOJXXE_js = require('./chunk-ACLOJXXE.js');
4
+ var chunkD2HXMGXS_js = require('./chunk-D2HXMGXS.js');
5
+ var chunkZ6ZWNWWR_js = require('./chunk-Z6ZWNWWR.js');
6
+ var path2 = require('path');
7
+ var events = require('events');
8
+ var uuid = require('uuid');
9
+ var crypto = require('crypto');
10
+
11
+ function _interopNamespace(e) {
12
+ if (e && e.__esModule) return e;
13
+ var n = Object.create(null);
14
+ if (e) {
15
+ Object.keys(e).forEach(function (k) {
16
+ if (k !== 'default') {
17
+ var d = Object.getOwnPropertyDescriptor(e, k);
18
+ Object.defineProperty(n, k, d.get ? d : {
19
+ enumerable: true,
20
+ get: function () { return e[k]; }
21
+ });
22
+ }
23
+ });
24
+ }
25
+ n.default = e;
26
+ return Object.freeze(n);
27
+ }
28
+
29
+ var path2__namespace = /*#__PURE__*/_interopNamespace(path2);
30
+
31
+ function getMimeType(filename) {
32
+ const ext = path2__namespace.extname(filename).toLowerCase();
33
+ return MIME_TYPES[ext] || "application/octet-stream";
34
+ }
35
+ var MIME_TYPES;
36
+ var init_mime = chunkZ6ZWNWWR_js.__esm({
37
+ "src/universalFile/server/utils/mime.ts"() {
38
+ MIME_TYPES = {
39
+ // 图片
40
+ ".jpg": "image/jpeg",
41
+ ".jpeg": "image/jpeg",
42
+ ".png": "image/png",
43
+ ".gif": "image/gif",
44
+ ".webp": "image/webp",
45
+ ".svg": "image/svg+xml",
46
+ ".bmp": "image/bmp",
47
+ ".ico": "image/x-icon",
48
+ // 视频
49
+ ".mp4": "video/mp4",
50
+ ".avi": "video/x-msvideo",
51
+ ".mov": "video/quicktime",
52
+ ".wmv": "video/x-ms-wmv",
53
+ ".flv": "video/x-flv",
54
+ ".mkv": "video/x-matroska",
55
+ ".webm": "video/webm",
56
+ // 音频
57
+ ".mp3": "audio/mpeg",
58
+ ".wav": "audio/wav",
59
+ ".ogg": "audio/ogg",
60
+ ".m4a": "audio/mp4",
61
+ ".flac": "audio/flac",
62
+ ".aac": "audio/aac",
63
+ // 文档
64
+ ".pdf": "application/pdf",
65
+ ".doc": "application/msword",
66
+ ".docx": "application/vnd.openxmlformats-officedocument.wordprocessingml.document",
67
+ ".xls": "application/vnd.ms-excel",
68
+ ".xlsx": "application/vnd.openxmlformats-officedocument.spreadsheetml.sheet",
69
+ ".ppt": "application/vnd.ms-powerpoint",
70
+ ".pptx": "application/vnd.openxmlformats-officedocument.presentationml.presentation",
71
+ ".txt": "text/plain",
72
+ ".rtf": "application/rtf",
73
+ // 压缩文件
74
+ ".zip": "application/zip",
75
+ ".rar": "application/x-rar-compressed",
76
+ ".7z": "application/x-7z-compressed",
77
+ ".tar": "application/x-tar",
78
+ ".gz": "application/gzip",
79
+ // 代码文件
80
+ ".js": "application/javascript",
81
+ ".json": "application/json",
82
+ ".xml": "application/xml",
83
+ ".html": "text/html",
84
+ ".css": "text/css",
85
+ ".ts": "application/typescript",
86
+ // 其他
87
+ ".csv": "text/csv",
88
+ ".md": "text/markdown"
89
+ };
90
+ }
91
+ });
92
+ var logger; exports.UniversalFileService = void 0;
93
+ var init_UniversalFileService = chunkZ6ZWNWWR_js.__esm({
94
+ "src/universalFile/server/UniversalFileService.ts"() {
95
+ chunkACLOJXXE_js.init_logger();
96
+ init_mime();
97
+ chunkD2HXMGXS_js.init_types();
98
+ logger = chunkACLOJXXE_js.createLogger("UniversalFileService");
99
+ exports.UniversalFileService = class extends events.EventEmitter {
100
+ constructor(config) {
101
+ super();
102
+ this.storageProviders = /* @__PURE__ */ new Map();
103
+ this.cdnProviders = /* @__PURE__ */ new Map();
104
+ this.fileProcessors = /* @__PURE__ */ new Map();
105
+ this.uploadProgressMap = /* @__PURE__ */ new Map();
106
+ this.metadataCache = /* @__PURE__ */ new Map();
107
+ this.urlCache = /* @__PURE__ */ new Map();
108
+ this.processingQueue = [];
109
+ this.isProcessingQueueRunning = false;
110
+ this.config = config;
111
+ if (this.config.persistence?.enabled && this.config.persistence.repository) {
112
+ this.setupPersistenceListeners();
113
+ }
114
+ }
115
+ // ============= 持久化设置 =============
116
+ /**
117
+ * 设置数据库持久化监听器
118
+ *
119
+ * 当文件上传完成或删除时,自动触发数据库操作
120
+ */
121
+ setupPersistenceListeners() {
122
+ const { repository, autoPersist = true } = this.config.persistence;
123
+ if (!autoPersist) {
124
+ logger.info("\u2699\uFE0F [UniversalFileService] \u81EA\u52A8\u6301\u4E45\u5316\u5DF2\u7981\u7528");
125
+ return;
126
+ }
127
+ logger.info("\u2705 [UniversalFileService] \u5DF2\u542F\u7528\u6570\u636E\u5E93\u6301\u4E45\u5316\uFF0C\u81EA\u52A8\u76D1\u542C\u6587\u4EF6\u4E8B\u4EF6");
128
+ this.on("upload:complete", async (fileId, data) => {
129
+ try {
130
+ const metadata = data.metadata || data;
131
+ await repository.save(metadata);
132
+ logger.info("\u{1F4BE} [Persistence] \u6587\u4EF6\u5143\u6570\u636E\u5DF2\u81EA\u52A8\u4FDD\u5B58: " + fileId);
133
+ } catch (error) {
134
+ logger.error("\u274C [Persistence] \u4FDD\u5B58\u5931\u8D25: " + fileId, error);
135
+ }
136
+ });
137
+ this.on("file:deleted", async (fileId) => {
138
+ try {
139
+ await repository.delete(fileId);
140
+ logger.info("\u{1F5D1}\uFE0F [Persistence] \u6587\u4EF6\u5143\u6570\u636E\u5DF2\u81EA\u52A8\u5220\u9664: " + fileId);
141
+ } catch (error) {
142
+ logger.error("\u274C [Persistence] \u5220\u9664\u5931\u8D25: " + fileId, error);
143
+ }
144
+ });
145
+ this.on("files:batch-deleted", async (fileIds) => {
146
+ try {
147
+ await repository.batchDelete(fileIds);
148
+ logger.info("\u{1F5D1}\uFE0F [Persistence] \u6279\u91CF\u5220\u9664\u5143\u6570\u636E: " + fileIds.length + " \u4E2A\u6587\u4EF6");
149
+ } catch (error) {
150
+ logger.error(`\u274C [Persistence] \u6279\u91CF\u5220\u9664\u5931\u8D25`, error);
151
+ }
152
+ });
153
+ }
154
+ // ============= 初始化方法 =============
155
+ /**
156
+ * 初始化文件服务
157
+ */
158
+ async initialize() {
159
+ logger.info("\u{1F680} [UniversalFileService] \u5F00\u59CB\u521D\u59CB\u5316\u6587\u4EF6\u670D\u52A1...");
160
+ try {
161
+ await this.validateConfiguration();
162
+ await this.initializeStorageProviders();
163
+ await this.initializeCDNProviders();
164
+ await this.initializeFileProcessors();
165
+ logger.info("\u2705 [UniversalFileService] \u6587\u4EF6\u670D\u52A1\u521D\u59CB\u5316\u5B8C\u6210");
166
+ } catch (error) {
167
+ console.error("\u274C [UniversalFileService] \u6587\u4EF6\u670D\u52A1\u521D\u59CB\u5316\u5931\u8D25:", error);
168
+ throw error;
169
+ }
170
+ }
171
+ /**
172
+ * 重新初始化存储提供者(支持配置热更新)
173
+ */
174
+ async reinitializeStorageProviders() {
175
+ logger.info("\u{1F504} [UniversalFileService] \u91CD\u65B0\u521D\u59CB\u5316\u5B58\u50A8\u63D0\u4F9B\u8005...");
176
+ try {
177
+ for (const [type, provider] of this.storageProviders) {
178
+ if ("reinitialize" in provider) {
179
+ try {
180
+ logger.info("\u{1F504} [UniversalFileService] \u91CD\u65B0\u521D\u59CB\u5316\u5B58\u50A8\u63D0\u4F9B\u8005: " + type + "...");
181
+ const config = this.config.storageProviders?.[type];
182
+ if (config) {
183
+ await provider.reinitialize(config);
184
+ logger.info("\u2705 [UniversalFileService] \u5B58\u50A8\u63D0\u4F9B\u8005\u91CD\u65B0\u521D\u59CB\u5316\u5B8C\u6210: " + type);
185
+ } else {
186
+ logger.warn("\u26A0\uFE0F [UniversalFileService] \u5B58\u50A8\u63D0\u4F9B\u8005\u914D\u7F6E\u4E0D\u5B58\u5728: " + type);
187
+ }
188
+ } catch (error) {
189
+ logger.error("\u274C [UniversalFileService] \u5B58\u50A8\u63D0\u4F9B\u8005\u91CD\u65B0\u521D\u59CB\u5316\u5931\u8D25: " + type, error);
190
+ }
191
+ }
192
+ }
193
+ logger.info("\u2705 [UniversalFileService] \u5B58\u50A8\u63D0\u4F9B\u8005\u91CD\u65B0\u521D\u59CB\u5316\u5B8C\u6210");
194
+ } catch (error) {
195
+ console.error("\u274C [UniversalFileService] \u5B58\u50A8\u63D0\u4F9B\u8005\u91CD\u65B0\u521D\u59CB\u5316\u5931\u8D25:", error);
196
+ throw error;
197
+ }
198
+ }
199
+ /**
200
+ * 注册存储提供者
201
+ */
202
+ registerStorageProvider(provider) {
203
+ this.storageProviders.set(provider.type, provider);
204
+ logger.info("\u{1F4E6} [UniversalFileService] \u6CE8\u518C\u5B58\u50A8\u63D0\u4F9B\u8005: " + provider.type);
205
+ }
206
+ /**
207
+ * 注册CDN提供者
208
+ */
209
+ registerCDNProvider(provider) {
210
+ this.cdnProviders.set(provider.type, provider);
211
+ logger.info("\u{1F310} [UniversalFileService] \u6CE8\u518CCDN\u63D0\u4F9B\u8005: " + provider.type);
212
+ }
213
+ /**
214
+ * 注册文件处理器
215
+ */
216
+ registerFileProcessor(processor) {
217
+ this.fileProcessors.set(processor.type, processor);
218
+ logger.info("\u2699\uFE0F [UniversalFileService] \u6CE8\u518C\u6587\u4EF6\u5904\u7406\u5668: " + processor.type);
219
+ }
220
+ // ============= 核心文件操作方法 =============
221
+ /**
222
+ * 上传文件
223
+ */
224
+ async uploadFile(fileInfo, storageType, onProgress) {
225
+ const fileId = uuid.v4();
226
+ const startTime = Date.now();
227
+ logger.info("\u{1F4E4} [UniversalFileService] \u5F00\u59CB\u4E0A\u4F20\u6587\u4EF6: " + fileInfo.file.name + ", ID: " + fileId);
228
+ try {
229
+ await this.validateFile(fileInfo.file);
230
+ const progress = {
231
+ fileId,
232
+ status: "pending",
233
+ progress: 0,
234
+ uploadedBytes: 0,
235
+ totalBytes: fileInfo.file.size,
236
+ speed: 0,
237
+ remainingTime: 0
238
+ };
239
+ this.uploadProgressMap.set(fileId, progress);
240
+ this.emitFileEvent("upload:start", fileId, { fileName: fileInfo.file.name });
241
+ const metadata = await this.generateFileMetadata(fileId, fileInfo);
242
+ const selectedStorageType = storageType || this.config.defaultStorage;
243
+ let storageProvider = this.storageProviders.get(selectedStorageType);
244
+ if (!storageProvider) {
245
+ logger.info(
246
+ "\u26A0\uFE0F [UniversalFileService] \u5B58\u50A8\u63D0\u4F9B\u8005 " + selectedStorageType + " \u4E0D\u53EF\u7528\uFF0C\u5C1D\u8BD5\u4F7F\u7528OSS"
247
+ );
248
+ storageProvider = this.storageProviders.get("aliyun-oss");
249
+ if (!storageProvider) {
250
+ logger.info(`\u26A0\uFE0F [UniversalFileService] OSS\u4E0D\u53EF\u7528\uFF0C\u56DE\u9000\u5230\u672C\u5730\u5B58\u50A8`);
251
+ storageProvider = this.storageProviders.get("local");
252
+ }
253
+ }
254
+ if (!storageProvider) {
255
+ throw new chunkD2HXMGXS_js.StorageProviderError(`\u6CA1\u6709\u53EF\u7528\u7684\u5B58\u50A8\u63D0\u4F9B\u8005`);
256
+ }
257
+ const storagePath = this.generateStoragePath(metadata);
258
+ progress.status = "uploading";
259
+ progress.progress = 10;
260
+ this.uploadProgressMap.set(fileId, progress);
261
+ onProgress?.(progress);
262
+ this.emitFileEvent("upload:progress", fileId, { progress: progress.progress });
263
+ const uploadResult = await storageProvider.upload(fileInfo, storagePath);
264
+ if (!uploadResult.success) {
265
+ throw new chunkD2HXMGXS_js.FileUploadError("\u4E0A\u4F20\u5931\u8D25: " + uploadResult.error);
266
+ }
267
+ metadata.storagePath = uploadResult.path || storagePath;
268
+ metadata.storageProvider = selectedStorageType;
269
+ if (this.config.defaultCDN !== "none") {
270
+ const cdnProvider = this.cdnProviders.get(this.config.defaultCDN);
271
+ if (cdnProvider && uploadResult.url) {
272
+ metadata.cdnUrl = await cdnProvider.generateUrl(uploadResult.url);
273
+ }
274
+ }
275
+ progress.status = fileInfo.needsProcessing ? "processing" : "completed";
276
+ progress.progress = fileInfo.needsProcessing ? 70 : 100;
277
+ this.uploadProgressMap.set(fileId, progress);
278
+ onProgress?.(progress);
279
+ if (fileInfo.needsProcessing && fileInfo.processingOptions) {
280
+ await this.queueFileProcessing(metadata, fileInfo.processingOptions);
281
+ }
282
+ this.cacheMetadata(metadata);
283
+ progress.status = "completed";
284
+ progress.progress = 100;
285
+ this.uploadProgressMap.set(fileId, progress);
286
+ onProgress?.(progress);
287
+ const uploadTime = Date.now() - startTime;
288
+ logger.info("\u2705 [UniversalFileService] \u6587\u4EF6\u4E0A\u4F20\u5B8C\u6210: " + fileId + ", \u8017\u65F6: " + uploadTime + "ms");
289
+ this.emitFileEvent("upload:complete", fileId, {
290
+ fileName: fileInfo.file.name,
291
+ size: fileInfo.file.size,
292
+ uploadTime
293
+ });
294
+ return metadata;
295
+ } catch (error) {
296
+ console.error("\u274C [UniversalFileService] \u6587\u4EF6\u4E0A\u4F20\u5931\u8D25: " + fileId + ":", error);
297
+ const progress = this.uploadProgressMap.get(fileId);
298
+ if (progress) {
299
+ progress.status = "failed";
300
+ progress.error = error instanceof Error ? error.message : "\u4E0A\u4F20\u5931\u8D25";
301
+ this.uploadProgressMap.set(fileId, progress);
302
+ onProgress?.(progress);
303
+ }
304
+ this.emitFileEvent(
305
+ "upload:error",
306
+ fileId,
307
+ void 0,
308
+ error instanceof Error ? error.message : "\u4E0A\u4F20\u5931\u8D25"
309
+ );
310
+ throw error;
311
+ } finally {
312
+ setTimeout(
313
+ () => {
314
+ this.uploadProgressMap.delete(fileId);
315
+ },
316
+ 5 * 60 * 1e3
317
+ );
318
+ }
319
+ }
320
+ /**
321
+ * 下载文件
322
+ */
323
+ async downloadFile(fileId, userId) {
324
+ logger.info("\u{1F4E5} [UniversalFileService] \u5F00\u59CB\u4E0B\u8F7D\u6587\u4EF6: " + fileId);
325
+ try {
326
+ this.emitFileEvent("download:start", fileId);
327
+ const metadata = await this.getFileMetadata(fileId);
328
+ if (!metadata) {
329
+ throw new chunkD2HXMGXS_js.FileUploadError("\u6587\u4EF6\u4E0D\u5B58\u5728: " + fileId);
330
+ }
331
+ await this.checkFileAccess(metadata, userId);
332
+ const storageProvider = this.storageProviders.get(metadata.storageProvider);
333
+ if (!storageProvider) {
334
+ throw new chunkD2HXMGXS_js.StorageProviderError("\u5B58\u50A8\u63D0\u4F9B\u8005\u4E0D\u5B58\u5728: " + metadata.storageProvider);
335
+ }
336
+ const fileBuffer = await storageProvider.download(metadata.storagePath);
337
+ if (this.config.persistence?.enabled) {
338
+ await this.updateAccessStats(fileId);
339
+ }
340
+ logger.info("\u2705 [UniversalFileService] \u6587\u4EF6\u4E0B\u8F7D\u5B8C\u6210: " + fileId);
341
+ this.emitFileEvent("download:complete", fileId, { size: fileBuffer.length });
342
+ return fileBuffer;
343
+ } catch (error) {
344
+ console.error("\u274C [UniversalFileService] \u6587\u4EF6\u4E0B\u8F7D\u5931\u8D25: " + fileId + ":", error);
345
+ this.emitFileEvent("download:error", fileId, void 0, error instanceof Error ? error.message : "\u4E0B\u8F7D\u5931\u8D25");
346
+ throw error;
347
+ }
348
+ }
349
+ /**
350
+ * 删除文件
351
+ */
352
+ async deleteFile(fileId, userId) {
353
+ logger.info("\u{1F5D1}\uFE0F [UniversalFileService] \u5F00\u59CB\u5220\u9664\u6587\u4EF6: " + fileId);
354
+ try {
355
+ const metadata = await this.getFileMetadata(fileId);
356
+ if (!metadata) {
357
+ throw new chunkD2HXMGXS_js.FileUploadError("\u6587\u4EF6\u4E0D\u5B58\u5728: " + fileId);
358
+ }
359
+ await this.checkFileDeleteAccess(metadata, userId);
360
+ const storageProvider = this.storageProviders.get(metadata.storageProvider);
361
+ if (!storageProvider) {
362
+ throw new chunkD2HXMGXS_js.StorageProviderError("\u5B58\u50A8\u63D0\u4F9B\u8005\u4E0D\u5B58\u5728: " + metadata.storageProvider);
363
+ }
364
+ const deleteResult = await storageProvider.delete(metadata.storagePath);
365
+ if (!deleteResult.success) {
366
+ console.warn("\u26A0\uFE0F [UniversalFileService] \u5B58\u50A8\u6587\u4EF6\u5220\u9664\u5931\u8D25: " + deleteResult.error);
367
+ }
368
+ if (this.config.persistence?.enabled) {
369
+ await this.deleteFileMetadata(fileId);
370
+ }
371
+ this.clearMetadataCache(fileId);
372
+ logger.info("\u2705 [UniversalFileService] \u6587\u4EF6\u5220\u9664\u5B8C\u6210: " + fileId);
373
+ this.emitFileEvent("delete:complete", fileId);
374
+ this.emit("file:deleted", fileId);
375
+ } catch (error) {
376
+ console.error("\u274C [UniversalFileService] \u6587\u4EF6\u5220\u9664\u5931\u8D25: " + fileId + ":", error);
377
+ this.emitFileEvent("delete:error", fileId, void 0, error instanceof Error ? error.message : "\u5220\u9664\u5931\u8D25");
378
+ throw error;
379
+ }
380
+ }
381
+ /**
382
+ * 获取文件访问URL
383
+ */
384
+ async getFileUrl(fileId, userId, expiresIn) {
385
+ const cacheKey = fileId + "_" + (userId || "public") + "_" + (expiresIn || 0);
386
+ const cached = this.urlCache.get(cacheKey);
387
+ if (cached && cached.expires > Date.now()) {
388
+ return cached.url;
389
+ }
390
+ const metadata = await this.getFileMetadata(fileId);
391
+ if (!metadata) {
392
+ throw new chunkD2HXMGXS_js.FileUploadError("\u6587\u4EF6\u4E0D\u5B58\u5728: " + fileId);
393
+ }
394
+ await this.checkFileAccess(metadata, userId);
395
+ let url;
396
+ if (metadata.cdnUrl) {
397
+ url = metadata.cdnUrl;
398
+ } else {
399
+ const storageProvider = this.storageProviders.get(metadata.storageProvider);
400
+ if (!storageProvider) {
401
+ throw new chunkD2HXMGXS_js.StorageProviderError("\u5B58\u50A8\u63D0\u4F9B\u8005\u4E0D\u5B58\u5728: " + metadata.storageProvider);
402
+ }
403
+ url = await storageProvider.getAccessUrl(metadata.storagePath, expiresIn);
404
+ }
405
+ const cacheExpires = Date.now() + (this.config.cache?.urlTTL || 1800) * 1e3;
406
+ this.urlCache.set(cacheKey, { url, expires: cacheExpires });
407
+ return url;
408
+ }
409
+ /**
410
+ * 获取文件元数据
411
+ */
412
+ async getFileMetadata(fileId) {
413
+ const cached = this.metadataCache.get(fileId);
414
+ if (cached && cached.expires > Date.now()) {
415
+ return cached.data;
416
+ }
417
+ if (this.config.persistence?.enabled && this.config.persistence.repository) {
418
+ try {
419
+ const metadata = await this.config.persistence.repository.get(fileId);
420
+ if (metadata) {
421
+ this.cacheMetadata(metadata);
422
+ }
423
+ return metadata;
424
+ } catch (error) {
425
+ console.error("\u274C [UniversalFileService] \u67E5\u8BE2\u6587\u4EF6\u5143\u6570\u636E\u5931\u8D25:", error);
426
+ return null;
427
+ }
428
+ }
429
+ logger.warn("\u26A0\uFE0F [UniversalFileService] \u6301\u4E45\u5316\u672A\u542F\u7528,\u65E0\u6CD5\u67E5\u8BE2\u6587\u4EF6\u5143\u6570\u636E: " + fileId);
430
+ return null;
431
+ }
432
+ /**
433
+ * 查询文件列表
434
+ */
435
+ async queryFiles(options) {
436
+ if (!this.config.persistence?.enabled || !this.config.persistence.repository) {
437
+ logger.warn("\u26A0\uFE0F [UniversalFileService] \u6301\u4E45\u5316\u672A\u542F\u7528,\u65E0\u6CD5\u67E5\u8BE2\u6587\u4EF6\u5217\u8868");
438
+ return {
439
+ items: [],
440
+ total: 0,
441
+ page: options.page || 1,
442
+ pageSize: options.pageSize || 20,
443
+ totalPages: 0,
444
+ hasNext: false,
445
+ hasPrev: false
446
+ };
447
+ }
448
+ try {
449
+ const result = await this.config.persistence.repository.query(options);
450
+ const hasNext = result.page < result.totalPages;
451
+ const hasPrev = result.page > 1;
452
+ return {
453
+ ...result,
454
+ hasNext,
455
+ hasPrev
456
+ };
457
+ } catch (error) {
458
+ console.error("\u274C [UniversalFileService] \u67E5\u8BE2\u6587\u4EF6\u5217\u8868\u5931\u8D25:", error);
459
+ throw error;
460
+ }
461
+ }
462
+ /**
463
+ * 批量删除文件
464
+ */
465
+ async batchDeleteFiles(fileIds, userId) {
466
+ const result = {
467
+ successCount: 0,
468
+ failureCount: 0,
469
+ failures: []
470
+ };
471
+ for (const fileId of fileIds) {
472
+ try {
473
+ await this.deleteFile(fileId, userId);
474
+ result.successCount++;
475
+ } catch (error) {
476
+ result.failureCount++;
477
+ result.failures.push({
478
+ fileId,
479
+ error: error instanceof Error ? error.message : "\u5220\u9664\u5931\u8D25"
480
+ });
481
+ }
482
+ }
483
+ if (result.successCount > 0) {
484
+ this.emit("files:batch-deleted", fileIds.filter((_, i) => i < result.successCount));
485
+ }
486
+ return result;
487
+ }
488
+ /**
489
+ * 获取上传进度
490
+ */
491
+ getUploadProgress(fileId) {
492
+ return this.uploadProgressMap.get(fileId);
493
+ }
494
+ // ============= 事件处理方法 =============
495
+ /**
496
+ * 监听文件事件
497
+ */
498
+ onFileEvent(eventType, listener) {
499
+ this.on(eventType, listener);
500
+ }
501
+ /**
502
+ * 移除文件事件监听器
503
+ */
504
+ offFileEvent(eventType, listener) {
505
+ this.off(eventType, listener);
506
+ }
507
+ // ============= 私有方法 =============
508
+ /**
509
+ * 验证配置是否完整
510
+ */
511
+ async validateConfiguration() {
512
+ logger.info("\u{1F50D} [UniversalFileService] \u9A8C\u8BC1\u914D\u7F6E\u6587\u4EF6...");
513
+ if (!this.config) {
514
+ throw new Error("\u6587\u4EF6\u670D\u52A1\u914D\u7F6E\u4E3A\u7A7A");
515
+ }
516
+ if (!this.config.storage) {
517
+ throw new Error("\u5B58\u50A8\u914D\u7F6E\u4E3A\u7A7A");
518
+ }
519
+ if (this.config.storage.type === "aliyun-oss") {
520
+ const ossConfig = this.config.storage;
521
+ if (!ossConfig.accessKeyId || !ossConfig.accessKeySecret || !ossConfig.bucket || !ossConfig.region) {
522
+ logger.warn("\u26A0\uFE0F [UniversalFileService] OSS\u914D\u7F6E\u4E0D\u5B8C\u6574\uFF0C\u7B49\u5F85\u914D\u7F6E\u52A0\u8F7D...");
523
+ const maxRetries = 30;
524
+ const retryInterval = 1e3;
525
+ for (let i = 0; i < maxRetries; i++) {
526
+ await new Promise((resolve) => setTimeout(resolve, retryInterval));
527
+ const updatedConfig = this.config.storage;
528
+ if (updatedConfig.accessKeyId && updatedConfig.accessKeySecret && updatedConfig.bucket && updatedConfig.region) {
529
+ logger.info("\u2705 [UniversalFileService] OSS\u914D\u7F6E\u52A0\u8F7D\u5B8C\u6210");
530
+ break;
531
+ }
532
+ if (i === maxRetries - 1) {
533
+ throw new Error("OSS\u914D\u7F6E\u52A0\u8F7D\u8D85\u65F6\uFF1A\u7F3A\u5C11\u5FC5\u9700\u7684\u914D\u7F6E\u9879 (accessKeyId, accessKeySecret, bucket, region)");
534
+ }
535
+ logger.debug("\u7B49\u5F85OSS\u914D\u7F6E\u52A0\u8F7D\u4E2D... (" + (i + 1) + "/" + maxRetries + ")");
536
+ }
537
+ }
538
+ }
539
+ if (!this.config.defaultStorage) {
540
+ this.config.defaultStorage = this.config.storage.type;
541
+ }
542
+ logger.info("\u2705 [UniversalFileService] \u914D\u7F6E\u9A8C\u8BC1\u5B8C\u6210");
543
+ }
544
+ async initializeStorageProviders() {
545
+ logger.info("\u{1F4E6} [UniversalFileService] \u5F00\u59CB\u521D\u59CB\u5316\u5B58\u50A8\u63D0\u4F9B\u8005...");
546
+ if (this.storageProviders.size === 0) {
547
+ await this.registerDefaultStorageProviders();
548
+ }
549
+ if (this.config.storageProviders) {
550
+ for (const [type, config] of Object.entries(this.config.storageProviders)) {
551
+ if (config && config.enabled) {
552
+ const provider = this.storageProviders.get(type);
553
+ if (provider) {
554
+ try {
555
+ await provider.initialize(config);
556
+ logger.info("\u2705 [UniversalFileService] \u5B58\u50A8\u63D0\u4F9B\u8005\u521D\u59CB\u5316\u5B8C\u6210: " + type);
557
+ } catch (error) {
558
+ console.warn("\u26A0\uFE0F [UniversalFileService] \u5B58\u50A8\u63D0\u4F9B\u8005\u521D\u59CB\u5316\u5931\u8D25: " + type + ":", error);
559
+ }
560
+ } else {
561
+ console.warn("\u26A0\uFE0F [UniversalFileService] \u5B58\u50A8\u63D0\u4F9B\u8005\u672A\u6CE8\u518C: " + type);
562
+ }
563
+ }
564
+ }
565
+ }
566
+ }
567
+ async registerDefaultStorageProviders() {
568
+ logger.info("\u{1F4E6} [UniversalFileService] \u6CE8\u518C\u9ED8\u8BA4\u5B58\u50A8\u63D0\u4F9B\u8005...");
569
+ try {
570
+ if (this.config.storage) {
571
+ if (this.config.storage.type === "aliyun-oss" && this.config.storage.enabled) {
572
+ const { AliyunOSSProvider } = await import('./AliyunOSSProvider-2FARPAQD.js');
573
+ const ossProvider = new AliyunOSSProvider();
574
+ this.registerStorageProvider(ossProvider);
575
+ logger.info("\u2705 [UniversalFileService] \u963F\u91CC\u4E91OSS\u63D0\u4F9B\u8005\u6CE8\u518C\u6210\u529F");
576
+ } else if (this.config.storage.type === "local" && this.config.storage.enabled) {
577
+ const { LocalStorageProvider } = await import('./LocalStorageProvider-JQF5WK5H.js');
578
+ const localProvider = new LocalStorageProvider();
579
+ this.registerStorageProvider(localProvider);
580
+ logger.info("\u2705 [UniversalFileService] \u672C\u5730\u5B58\u50A8\u63D0\u4F9B\u8005\u6CE8\u518C\u6210\u529F");
581
+ }
582
+ }
583
+ if (this.storageProviders.size === 0) {
584
+ const { LocalStorageProvider } = await import('./LocalStorageProvider-JQF5WK5H.js');
585
+ const fallbackProvider = new LocalStorageProvider();
586
+ this.registerStorageProvider(fallbackProvider);
587
+ logger.info("\u2705 [UniversalFileService] \u5DF2\u6CE8\u518C\u5907\u7528\u672C\u5730\u5B58\u50A8\u63D0\u4F9B\u8005");
588
+ }
589
+ } catch (error) {
590
+ console.warn("\u26A0\uFE0F [UniversalFileService] \u6CE8\u518C\u9ED8\u8BA4\u5B58\u50A8\u63D0\u4F9B\u8005\u5931\u8D25:", error);
591
+ throw new Error("\u65E0\u6CD5\u521D\u59CB\u5316\u5B58\u50A8\u63D0\u4F9B\u8005");
592
+ }
593
+ }
594
+ async initializeCDNProviders() {
595
+ if (this.config.cdn && this.config.cdn.enabled) {
596
+ logger.info("\u2705 [UniversalFileService] CDN\u914D\u7F6E\u5DF2\u542F\u7528: " + this.config.cdn.type);
597
+ }
598
+ }
599
+ async initializeFileProcessors() {
600
+ for (const processor of Array.from(this.fileProcessors.values())) {
601
+ await processor.initialize();
602
+ logger.info("\u2705 [UniversalFileService] \u6587\u4EF6\u5904\u7406\u5668\u521D\u59CB\u5316\u5B8C\u6210: " + processor.type);
603
+ }
604
+ }
605
+ async validateFile(file) {
606
+ if (this.config.maxFileSize && file.size > this.config.maxFileSize) {
607
+ throw new chunkD2HXMGXS_js.FileUploadError("\u6587\u4EF6\u5927\u5C0F\u8D85\u8FC7\u9650\u5236: " + file.size + " > " + this.config.maxFileSize);
608
+ }
609
+ const mimeType = file.type || getMimeType(file.name);
610
+ if (this.config.allowedMimeTypes && this.config.allowedMimeTypes.length > 0 && !this.config.allowedMimeTypes.includes(mimeType)) {
611
+ throw new chunkD2HXMGXS_js.FileUploadError("\u4E0D\u652F\u6301\u7684\u6587\u4EF6\u7C7B\u578B: " + mimeType);
612
+ }
613
+ }
614
+ async generateFileMetadata(fileId, fileInfo) {
615
+ const now = /* @__PURE__ */ new Date();
616
+ const mimeType = fileInfo.file.type || getMimeType(fileInfo.file.name);
617
+ const extension = path2__namespace.extname(fileInfo.file.name).toLowerCase();
618
+ const hash = await this.generateFileHash(fileInfo.file);
619
+ return {
620
+ id: fileId,
621
+ originalName: fileInfo.file.name,
622
+ storageName: fileId + extension,
623
+ size: fileInfo.file.size,
624
+ mimeType,
625
+ extension,
626
+ hash,
627
+ uploadTime: now,
628
+ permission: fileInfo.permission || "public",
629
+ uploaderId: fileInfo.metadata?.uploadedBy || "system",
630
+ moduleId: fileInfo.moduleId,
631
+ businessId: fileInfo.businessId,
632
+ storageProvider: this.config.defaultStorage || "local",
633
+ storagePath: "",
634
+ accessCount: 0,
635
+ metadata: fileInfo.metadata || {}
636
+ };
637
+ }
638
+ generateStoragePath(metadata) {
639
+ const date = /* @__PURE__ */ new Date();
640
+ const year = date.getFullYear();
641
+ const month = String(date.getMonth() + 1).padStart(2, "0");
642
+ const day = String(date.getDate()).padStart(2, "0");
643
+ return metadata.moduleId + "/" + year + "/" + month + "/" + day + "/" + metadata.storageName;
644
+ }
645
+ async generateFileHash(file) {
646
+ const buffer = await file.arrayBuffer();
647
+ const hash = crypto.createHash("sha256");
648
+ hash.update(Buffer.from(buffer));
649
+ return hash.digest("hex");
650
+ }
651
+ async queueFileProcessing(metadata, options) {
652
+ if (!this.config.processors?.length || 0 > 0) {
653
+ return;
654
+ }
655
+ const processor = this.fileProcessors.get(options.type);
656
+ if (!processor) {
657
+ console.warn("\u26A0\uFE0F [UniversalFileService] \u6587\u4EF6\u5904\u7406\u5668\u4E0D\u5B58\u5728: " + options.type);
658
+ return;
659
+ }
660
+ if (this.processingQueue.length >= 1e3) {
661
+ throw new chunkD2HXMGXS_js.FileProcessingError("\u5904\u7406\u961F\u5217\u5DF2\u6EE1");
662
+ }
663
+ this.processingQueue.push({
664
+ fileId: metadata.id,
665
+ processor,
666
+ inputPath: metadata.storagePath,
667
+ outputPath: this.generateProcessedPath(metadata, options),
668
+ options
669
+ });
670
+ if (!this.isProcessingQueueRunning) {
671
+ this.processFileQueue();
672
+ }
673
+ }
674
+ generateProcessedPath(metadata, options) {
675
+ const basePath = metadata.storagePath;
676
+ const extension = path2__namespace.extname(basePath);
677
+ const basename = basePath.replace(extension, "");
678
+ return basename + "_processed" + extension;
679
+ }
680
+ async processFileQueue() {
681
+ if (this.isProcessingQueueRunning || this.processingQueue.length === 0) {
682
+ return;
683
+ }
684
+ this.isProcessingQueueRunning = true;
685
+ while (this.processingQueue.length > 0) {
686
+ const task = this.processingQueue.shift();
687
+ if (!task) break;
688
+ try {
689
+ this.emitFileEvent("processing:start", task.fileId);
690
+ const result = await task.processor.process(task.inputPath, task.outputPath, task.options);
691
+ if (result.success) {
692
+ this.emitFileEvent("processing:complete", task.fileId, result);
693
+ } else {
694
+ this.emitFileEvent("processing:error", task.fileId, void 0, result.error);
695
+ }
696
+ } catch (error) {
697
+ console.error("\u274C [UniversalFileService] \u6587\u4EF6\u5904\u7406\u5931\u8D25: " + task.fileId + ":", error);
698
+ this.emitFileEvent(
699
+ "processing:error",
700
+ task.fileId,
701
+ void 0,
702
+ error instanceof Error ? error.message : "\u5904\u7406\u5931\u8D25"
703
+ );
704
+ }
705
+ }
706
+ this.isProcessingQueueRunning = false;
707
+ }
708
+ cacheMetadata(metadata) {
709
+ const expires = Date.now() + (this.config.cache?.metadataTTL || 3600) * 1e3;
710
+ this.metadataCache.set(metadata.id, { data: metadata, expires });
711
+ }
712
+ clearMetadataCache(fileId) {
713
+ this.metadataCache.delete(fileId);
714
+ }
715
+ emitFileEvent(type, fileId, data, error) {
716
+ const event = {
717
+ type,
718
+ fileId,
719
+ timestamp: /* @__PURE__ */ new Date(),
720
+ data,
721
+ error
722
+ };
723
+ this.emit(type, event);
724
+ this.emit("*", event);
725
+ }
726
+ // ============= 数据库操作私有方法 =============
727
+ /**
728
+ * 保存文件元数据到数据库 (通过持久化仓储)
729
+ */
730
+ async saveFileMetadata(metadata) {
731
+ if (!this.config.persistence?.enabled || !this.config.persistence.repository) {
732
+ logger.warn("\u26A0\uFE0F [UniversalFileService] \u6301\u4E45\u5316\u672A\u542F\u7528,\u8DF3\u8FC7\u4FDD\u5B58\u5143\u6570\u636E");
733
+ return;
734
+ }
735
+ try {
736
+ await this.config.persistence.repository.save(metadata);
737
+ logger.info("\u{1F4BE} [UniversalFileService] \u6587\u4EF6\u5143\u6570\u636E\u4FDD\u5B58\u6210\u529F:", metadata.id);
738
+ } catch (error) {
739
+ console.error("\u274C [UniversalFileService] \u4FDD\u5B58\u6587\u4EF6\u5143\u6570\u636E\u5931\u8D25:", error);
740
+ throw new chunkD2HXMGXS_js.FileUploadError(
741
+ "\u4FDD\u5B58\u6587\u4EF6\u5143\u6570\u636E\u5931\u8D25: " + (error instanceof Error ? error.message : "\u672A\u77E5\u9519\u8BEF")
742
+ );
743
+ }
744
+ }
745
+ /**
746
+ * 从数据库删除文件元数据 (通过持久化仓储)
747
+ */
748
+ async deleteFileMetadata(fileId) {
749
+ if (!this.config.persistence?.enabled || !this.config.persistence.repository) {
750
+ return;
751
+ }
752
+ try {
753
+ await this.config.persistence.repository.delete(fileId);
754
+ logger.info("\u{1F5D1}\uFE0F [UniversalFileService] \u6587\u4EF6\u5143\u6570\u636E\u5220\u9664\u6210\u529F:", fileId);
755
+ } catch (error) {
756
+ console.error("\u274C [UniversalFileService] \u5220\u9664\u6587\u4EF6\u5143\u6570\u636E\u5931\u8D25:", error);
757
+ throw new chunkD2HXMGXS_js.FileUploadError(
758
+ "\u5220\u9664\u6587\u4EF6\u5143\u6570\u636E\u5931\u8D25: " + (error instanceof Error ? error.message : "\u672A\u77E5\u9519\u8BEF")
759
+ );
760
+ }
761
+ }
762
+ /**
763
+ * 更新访问统计
764
+ */
765
+ async updateAccessStats(fileId) {
766
+ logger.info("\u{1F4CA} [UniversalFileService] \u9700\u8981\u66F4\u65B0\u8BBF\u95EE\u7EDF\u8BA1:", fileId);
767
+ }
768
+ /**
769
+ * 检查文件访问权限
770
+ */
771
+ async checkFileAccess(metadata, userId) {
772
+ if (metadata.permission === "public") {
773
+ return;
774
+ }
775
+ if (metadata.permission === "private" && metadata.uploaderId !== userId) {
776
+ throw new chunkD2HXMGXS_js.FileUploadError("\u65E0\u6743\u9650\u8BBF\u95EE\u6B64\u6587\u4EF6");
777
+ }
778
+ if (metadata.permission === "authenticated" && !userId) {
779
+ throw new chunkD2HXMGXS_js.FileUploadError("\u9700\u8981\u767B\u5F55\u624D\u80FD\u8BBF\u95EE\u6B64\u6587\u4EF6");
780
+ }
781
+ }
782
+ /**
783
+ * 检查文件删除权限
784
+ */
785
+ async checkFileDeleteAccess(metadata, userId) {
786
+ if (metadata.uploaderId !== userId) {
787
+ throw new chunkD2HXMGXS_js.FileUploadError("\u65E0\u6743\u9650\u5220\u9664\u6B64\u6587\u4EF6");
788
+ }
789
+ }
790
+ /**
791
+ * 检查服务是否完全可用(包括存储提供者)
792
+ */
793
+ isFullyInitialized() {
794
+ const hasStorageProvider = Array.from(this.storageProviders.values()).some(
795
+ (provider) => provider.type === "aliyun-oss" || provider.type === "local"
796
+ );
797
+ return hasStorageProvider;
798
+ }
799
+ /**
800
+ * 等待服务完全初始化(带超时)
801
+ */
802
+ async waitForInitialization(timeoutMs = 3e4) {
803
+ const startTime = Date.now();
804
+ while (!this.isFullyInitialized()) {
805
+ if (Date.now() - startTime > timeoutMs) {
806
+ throw new Error("\u670D\u52A1\u521D\u59CB\u5316\u8D85\u65F6 (" + timeoutMs + "ms)");
807
+ }
808
+ await new Promise((resolve) => setTimeout(resolve, 100));
809
+ }
810
+ logger.info("\u2705 [UniversalFileService] \u670D\u52A1\u5B8C\u5168\u521D\u59CB\u5316\u5C31\u7EEA");
811
+ }
812
+ };
813
+ }
814
+ });
815
+
816
+ exports.getMimeType = getMimeType;
817
+ exports.init_UniversalFileService = init_UniversalFileService;
818
+ exports.init_mime = init_mime;
819
+ //# sourceMappingURL=chunk-M4HGHTIC.js.map
820
+ //# sourceMappingURL=chunk-M4HGHTIC.js.map