sa2kit 1.6.57 → 1.6.59

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 (147) hide show
  1. package/dist/AliyunOSSProvider-KSYW2IOG.js +15 -0
  2. package/dist/{AliyunOSSProvider-2FARPAQD.js.map → AliyunOSSProvider-KSYW2IOG.js.map} +1 -1
  3. package/dist/AliyunOSSProvider-TBK3G7YK.mjs +6 -0
  4. package/dist/{AliyunOSSProvider-UMVGVBDJ.mjs.map → AliyunOSSProvider-TBK3G7YK.mjs.map} +1 -1
  5. package/dist/LocalStorageProvider-2DGYRQAB.mjs +6 -0
  6. package/dist/{LocalStorageProvider-PYOHETJV.mjs.map → LocalStorageProvider-2DGYRQAB.mjs.map} +1 -1
  7. package/dist/LocalStorageProvider-SSRW3ZJW.js +15 -0
  8. package/dist/{LocalStorageProvider-JQF5WK5H.js.map → LocalStorageProvider-SSRW3ZJW.js.map} +1 -1
  9. package/dist/UniversalFileService-336GFY6N.mjs +6 -0
  10. package/dist/{UniversalFileService-TNYKO6JN.mjs.map → UniversalFileService-336GFY6N.mjs.map} +1 -1
  11. package/dist/UniversalFileService-J6ET6KZK.js +15 -0
  12. package/dist/{UniversalFileService-RBV6EN5J.js.map → UniversalFileService-J6ET6KZK.js.map} +1 -1
  13. package/dist/calendar/index.js +11 -11
  14. package/dist/calendar/index.mjs +4 -4
  15. package/dist/chunk-25OFOKNF.js +171 -0
  16. package/dist/chunk-25OFOKNF.js.map +1 -0
  17. package/dist/chunk-3DXPQ4YV.mjs +165 -0
  18. package/dist/chunk-3DXPQ4YV.mjs.map +1 -0
  19. package/dist/{chunk-4VJQZSPU.mjs → chunk-3NHAT7D4.mjs} +3 -4
  20. package/dist/chunk-3NHAT7D4.mjs.map +1 -0
  21. package/dist/{chunk-3JW4X3AC.mjs → chunk-622Y6LTH.mjs} +3 -3
  22. package/dist/{chunk-3JW4X3AC.mjs.map → chunk-622Y6LTH.mjs.map} +1 -1
  23. package/dist/{chunk-HYZ5C6FY.mjs → chunk-7CMGQX3S.mjs} +1199 -1995
  24. package/dist/chunk-7CMGQX3S.mjs.map +1 -0
  25. package/dist/chunk-CIVO4R6N.mjs +37 -0
  26. package/dist/chunk-CIVO4R6N.mjs.map +1 -0
  27. package/dist/{chunk-6BJ76BYC.mjs → chunk-EGJPS7OL.mjs} +3 -3
  28. package/dist/{chunk-6BJ76BYC.mjs.map → chunk-EGJPS7OL.mjs.map} +1 -1
  29. package/dist/{chunk-UR5TU4MW.mjs → chunk-FVDPGX6A.mjs} +3 -3
  30. package/dist/{chunk-UR5TU4MW.mjs.map → chunk-FVDPGX6A.mjs.map} +1 -1
  31. package/dist/chunk-HDMIOOZY.mjs +546 -0
  32. package/dist/chunk-HDMIOOZY.mjs.map +1 -0
  33. package/dist/{chunk-MZKATHB7.js → chunk-HHVDOIPV.js} +4 -4
  34. package/dist/{chunk-MZKATHB7.js.map → chunk-HHVDOIPV.js.map} +1 -1
  35. package/dist/chunk-HJ6MH7J7.js +552 -0
  36. package/dist/chunk-HJ6MH7J7.js.map +1 -0
  37. package/dist/chunk-KH6RQ4J5.js +28 -0
  38. package/dist/chunk-KH6RQ4J5.js.map +1 -0
  39. package/dist/{chunk-53WLQ22S.js → chunk-LJGJPAQ4.js} +6 -6
  40. package/dist/{chunk-53WLQ22S.js.map → chunk-LJGJPAQ4.js.map} +1 -1
  41. package/dist/{chunk-35CXIK5Y.js → chunk-NCOXT7SK.js} +11 -11
  42. package/dist/{chunk-35CXIK5Y.js.map → chunk-NCOXT7SK.js.map} +1 -1
  43. package/dist/chunk-NZZZUMMX.mjs +784 -0
  44. package/dist/chunk-NZZZUMMX.mjs.map +1 -0
  45. package/dist/{chunk-OBIPI4GU.mjs → chunk-OFYBMMWT.mjs} +4 -4
  46. package/dist/{chunk-OBIPI4GU.mjs.map → chunk-OFYBMMWT.mjs.map} +1 -1
  47. package/dist/chunk-Q5EDCKQA.js +336 -0
  48. package/dist/chunk-Q5EDCKQA.js.map +1 -0
  49. package/dist/{chunk-U7AQC2Z7.js → chunk-SKCMZYSQ.js} +1203 -2001
  50. package/dist/chunk-SKCMZYSQ.js.map +1 -0
  51. package/dist/{chunk-6NMIKAE7.mjs → chunk-SNBILYSH.mjs} +5 -5
  52. package/dist/{chunk-6NMIKAE7.mjs.map → chunk-SNBILYSH.mjs.map} +1 -1
  53. package/dist/{chunk-IPY26RQH.js → chunk-UVHPCLP6.js} +5 -5
  54. package/dist/{chunk-IPY26RQH.js.map → chunk-UVHPCLP6.js.map} +1 -1
  55. package/dist/{chunk-V6BXO6ZS.mjs → chunk-UZB4IO3T.mjs} +835 -38
  56. package/dist/chunk-UZB4IO3T.mjs.map +1 -0
  57. package/dist/{chunk-W2NCOORK.js → chunk-WK3HTUID.js} +951 -145
  58. package/dist/chunk-WK3HTUID.js.map +1 -0
  59. package/dist/chunk-YMS6BPXS.js +807 -0
  60. package/dist/chunk-YMS6BPXS.js.map +1 -0
  61. package/dist/chunk-YOTQG4NP.mjs +314 -0
  62. package/dist/chunk-YOTQG4NP.mjs.map +1 -0
  63. package/dist/chunk-ZGVB35L2.mjs +25 -0
  64. package/dist/chunk-ZGVB35L2.mjs.map +1 -0
  65. package/dist/chunk-ZRAW3HXA.js +43 -0
  66. package/dist/chunk-ZRAW3HXA.js.map +1 -0
  67. package/dist/{chunk-4XXIBWCO.js → chunk-ZRWED7Q6.js} +66 -66
  68. package/dist/{chunk-4XXIBWCO.js.map → chunk-ZRWED7Q6.js.map} +1 -1
  69. package/dist/{chunk-DVENFCQY.js → chunk-ZWQJSZEY.js} +4 -5
  70. package/dist/chunk-ZWQJSZEY.js.map +1 -0
  71. package/dist/components/index.js +104 -104
  72. package/dist/components/index.mjs +4 -4
  73. package/dist/index.js +146 -148
  74. package/dist/index.js.map +1 -1
  75. package/dist/index.mjs +8 -11
  76. package/dist/index.mjs.map +1 -1
  77. package/dist/logger/index.js +7 -7
  78. package/dist/logger/index.mjs +1 -4
  79. package/dist/mikuFusionGame/index.js +4 -4
  80. package/dist/mikuFusionGame/index.mjs +3 -3
  81. package/dist/portfolio/index.js +10 -10
  82. package/dist/portfolio/index.mjs +5 -5
  83. package/dist/showmasterpiece/db/index.js +42 -42
  84. package/dist/showmasterpiece/db/index.mjs +1 -1
  85. package/dist/showmasterpiece/index.js +143 -144
  86. package/dist/showmasterpiece/index.js.map +1 -1
  87. package/dist/showmasterpiece/index.mjs +7 -9
  88. package/dist/showmasterpiece/index.mjs.map +1 -1
  89. package/dist/showmasterpiece/logic/index.d.mts +10 -1
  90. package/dist/showmasterpiece/logic/index.d.ts +10 -1
  91. package/dist/showmasterpiece/logic/index.js +19 -19
  92. package/dist/showmasterpiece/logic/index.mjs +2 -2
  93. package/dist/showmasterpiece/server/index.js +42 -42
  94. package/dist/showmasterpiece/server/index.mjs +1 -1
  95. package/dist/showmasterpiece/ui/web/index.js +34 -34
  96. package/dist/showmasterpiece/ui/web/index.mjs +6 -6
  97. package/dist/universalExport/server/index.js +2 -4
  98. package/dist/universalExport/server/index.js.map +1 -1
  99. package/dist/universalExport/server/index.mjs +1 -3
  100. package/dist/universalExport/server/index.mjs.map +1 -1
  101. package/dist/universalFile/index.js +6 -9
  102. package/dist/universalFile/index.js.map +1 -1
  103. package/dist/universalFile/index.mjs +1 -5
  104. package/dist/universalFile/index.mjs.map +1 -1
  105. package/dist/universalFile/server/index.js +31 -64
  106. package/dist/universalFile/server/index.js.map +1 -1
  107. package/dist/universalFile/server/index.mjs +7 -42
  108. package/dist/universalFile/server/index.mjs.map +1 -1
  109. package/dist/utils/index.js +11 -11
  110. package/dist/utils/index.mjs +2 -2
  111. package/package.json +1 -1
  112. package/dist/AliyunOSSProvider-2FARPAQD.js +0 -15
  113. package/dist/AliyunOSSProvider-UMVGVBDJ.mjs +0 -9
  114. package/dist/LocalStorageProvider-JQF5WK5H.js +0 -15
  115. package/dist/LocalStorageProvider-PYOHETJV.mjs +0 -9
  116. package/dist/UniversalFileService-RBV6EN5J.js +0 -15
  117. package/dist/UniversalFileService-TNYKO6JN.mjs +0 -9
  118. package/dist/chunk-4NFOSCM6.js +0 -34
  119. package/dist/chunk-4NFOSCM6.js.map +0 -1
  120. package/dist/chunk-4VJQZSPU.mjs.map +0 -1
  121. package/dist/chunk-6AHYPPUP.js +0 -344
  122. package/dist/chunk-6AHYPPUP.js.map +0 -1
  123. package/dist/chunk-76V7EKBX.mjs +0 -796
  124. package/dist/chunk-76V7EKBX.mjs.map +0 -1
  125. package/dist/chunk-ACLOJXXE.js +0 -195
  126. package/dist/chunk-ACLOJXXE.js.map +0 -1
  127. package/dist/chunk-AEXPAH7Z.mjs +0 -32
  128. package/dist/chunk-AEXPAH7Z.mjs.map +0 -1
  129. package/dist/chunk-CFGX3EKK.js +0 -560
  130. package/dist/chunk-CFGX3EKK.js.map +0 -1
  131. package/dist/chunk-D2HXMGXS.js +0 -46
  132. package/dist/chunk-D2HXMGXS.js.map +0 -1
  133. package/dist/chunk-DVENFCQY.js.map +0 -1
  134. package/dist/chunk-HYZ5C6FY.mjs.map +0 -1
  135. package/dist/chunk-K7WNCB4V.mjs +0 -554
  136. package/dist/chunk-K7WNCB4V.mjs.map +0 -1
  137. package/dist/chunk-L4ZYBFB2.mjs +0 -44
  138. package/dist/chunk-L4ZYBFB2.mjs.map +0 -1
  139. package/dist/chunk-M4HGHTIC.js +0 -820
  140. package/dist/chunk-M4HGHTIC.js.map +0 -1
  141. package/dist/chunk-PXWDQFWV.mjs +0 -192
  142. package/dist/chunk-PXWDQFWV.mjs.map +0 -1
  143. package/dist/chunk-U7AQC2Z7.js.map +0 -1
  144. package/dist/chunk-V6BXO6ZS.mjs.map +0 -1
  145. package/dist/chunk-VTGPHE4Z.mjs +0 -322
  146. package/dist/chunk-VTGPHE4Z.mjs.map +0 -1
  147. package/dist/chunk-W2NCOORK.js.map +0 -1
@@ -1,820 +0,0 @@
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