sa2kit 1.6.50 → 1.6.57
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.
- package/dist/booking-BXtkG2ns.d.mts +386 -0
- package/dist/booking-BXtkG2ns.d.ts +386 -0
- package/dist/bookingAdminService-B2QDjSHJ.d.ts +193 -0
- package/dist/bookingAdminService-Dmg7dC6V.d.mts +193 -0
- package/dist/cart-CcZ7rQyG.d.mts +176 -0
- package/dist/cart-D3o67Q3H.d.ts +176 -0
- package/dist/chunk-53WLQ22S.js +119 -0
- package/dist/chunk-53WLQ22S.js.map +1 -0
- package/dist/{chunk-SHY424RZ.mjs → chunk-6NMIKAE7.mjs} +3 -3
- package/dist/{chunk-SHY424RZ.mjs.map → chunk-6NMIKAE7.mjs.map} +1 -1
- package/dist/chunk-ANKVXRPY.mjs +30 -0
- package/dist/chunk-ANKVXRPY.mjs.map +1 -0
- package/dist/{chunk-IZOIVYOW.js → chunk-DENROXAE.js} +2 -2
- package/dist/{chunk-IZOIVYOW.js.map → chunk-DENROXAE.js.map} +1 -1
- package/dist/chunk-HYZ5C6FY.mjs +3522 -0
- package/dist/chunk-HYZ5C6FY.mjs.map +1 -0
- package/dist/{chunk-7JN25DJB.js → chunk-IPY26RQH.js} +11 -11
- package/dist/{chunk-7JN25DJB.js.map → chunk-IPY26RQH.js.map} +1 -1
- package/dist/{chunk-GFVAIT6Y.mjs → chunk-MFG2Y6UR.mjs} +2 -2
- package/dist/{chunk-GFVAIT6Y.mjs.map → chunk-MFG2Y6UR.mjs.map} +1 -1
- package/dist/chunk-TJZDPOO7.js +34 -0
- package/dist/chunk-TJZDPOO7.js.map +1 -0
- package/dist/chunk-U7AQC2Z7.js +3542 -0
- package/dist/chunk-U7AQC2Z7.js.map +1 -0
- package/dist/chunk-UR5TU4MW.mjs +113 -0
- package/dist/chunk-UR5TU4MW.mjs.map +1 -0
- package/dist/chunk-V6BXO6ZS.mjs +6107 -0
- package/dist/chunk-V6BXO6ZS.mjs.map +1 -0
- package/dist/chunk-W2NCOORK.js +6138 -0
- package/dist/chunk-W2NCOORK.js.map +1 -0
- package/dist/iflytek/index.d.mts +109 -0
- package/dist/iflytek/index.d.ts +109 -0
- package/dist/iflytek/index.js +365 -0
- package/dist/iflytek/index.js.map +1 -0
- package/dist/iflytek/index.mjs +362 -0
- package/dist/iflytek/index.mjs.map +1 -0
- package/dist/iflytek/server.d.mts +59 -0
- package/dist/iflytek/server.d.ts +59 -0
- package/dist/iflytek/server.js +281 -0
- package/dist/iflytek/server.js.map +1 -0
- package/dist/iflytek/server.mjs +274 -0
- package/dist/iflytek/server.mjs.map +1 -0
- package/dist/showmasterpiece/db/index.d.mts +3028 -0
- package/dist/showmasterpiece/db/index.d.ts +3028 -0
- package/dist/showmasterpiece/db/index.js +179 -0
- package/dist/showmasterpiece/db/index.js.map +1 -0
- package/dist/showmasterpiece/db/index.mjs +6 -0
- package/dist/showmasterpiece/db/index.mjs.map +1 -0
- package/dist/showmasterpiece/index.d.mts +10 -1729
- package/dist/showmasterpiece/index.d.ts +10 -1729
- package/dist/showmasterpiece/index.js +435 -9654
- package/dist/showmasterpiece/index.js.map +1 -1
- package/dist/showmasterpiece/index.mjs +9 -9628
- package/dist/showmasterpiece/index.mjs.map +1 -1
- package/dist/showmasterpiece/logic/index.d.mts +372 -0
- package/dist/showmasterpiece/logic/index.d.ts +372 -0
- package/dist/showmasterpiece/logic/index.js +91 -0
- package/dist/showmasterpiece/logic/index.js.map +1 -0
- package/dist/showmasterpiece/logic/index.mjs +6 -0
- package/dist/showmasterpiece/logic/index.mjs.map +1 -0
- package/dist/showmasterpiece/server/index.d.mts +3 -2704
- package/dist/showmasterpiece/server/index.d.ts +3 -2704
- package/dist/showmasterpiece/server/index.js +43 -43
- package/dist/showmasterpiece/server/index.mjs +2 -2
- package/dist/showmasterpiece/ui/miniapp/index.d.mts +86 -0
- package/dist/showmasterpiece/ui/miniapp/index.d.ts +86 -0
- package/dist/showmasterpiece/ui/miniapp/index.js +196 -0
- package/dist/showmasterpiece/ui/miniapp/index.js.map +1 -0
- package/dist/showmasterpiece/ui/miniapp/index.mjs +183 -0
- package/dist/showmasterpiece/ui/miniapp/index.mjs.map +1 -0
- package/dist/showmasterpiece/ui/web/index.d.mts +600 -0
- package/dist/showmasterpiece/ui/web/index.d.ts +600 -0
- package/dist/showmasterpiece/ui/web/index.js +131 -0
- package/dist/showmasterpiece/ui/web/index.js.map +1 -0
- package/dist/showmasterpiece/ui/web/index.mjs +14 -0
- package/dist/showmasterpiece/ui/web/index.mjs.map +1 -0
- package/dist/types-C4bbgHHW.d.mts +100 -0
- package/dist/types-C4bbgHHW.d.ts +100 -0
- package/dist/universalFile/server/index.js +5882 -288
- package/dist/universalFile/server/index.js.map +1 -1
- package/dist/universalFile/server/index.mjs +5796 -5
- package/dist/universalFile/server/index.mjs.map +1 -1
- package/package.json +45 -4
- package/dist/chunk-QROLPPXP.mjs +0 -5797
- package/dist/chunk-QROLPPXP.mjs.map +0 -1
- package/dist/chunk-VLZ5N6XZ.js +0 -5888
- package/dist/chunk-VLZ5N6XZ.js.map +0 -1
- package/dist/popupConfig-BznThU1O.d.mts +0 -330
- package/dist/popupConfig-BznThU1O.d.ts +0 -330
- package/dist/showmasterpiece/migration/index.d.mts +0 -120
- package/dist/showmasterpiece/migration/index.d.ts +0 -120
- package/dist/showmasterpiece/migration/index.js +0 -595
- package/dist/showmasterpiece/migration/index.js.map +0 -1
- package/dist/showmasterpiece/migration/index.mjs +0 -589
- package/dist/showmasterpiece/migration/index.mjs.map +0 -1
- package/dist/showmasterpiece/scripts/index.d.mts +0 -28
- package/dist/showmasterpiece/scripts/index.d.ts +0 -28
- package/dist/showmasterpiece/scripts/index.js +0 -327
- package/dist/showmasterpiece/scripts/index.js.map +0 -1
- package/dist/showmasterpiece/scripts/index.mjs +0 -325
- package/dist/showmasterpiece/scripts/index.mjs.map +0 -1
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"sources":["../src/universalFile/server/factory.ts","../src/universalFile/server/presets.ts","../src/universalFile/server/validation.ts","../src/universalFile/server/providers/index.ts","../src/universalFile/server/providers/AliyunCDNProvider.ts","../src/universalFile/server/providers/CdnCacheStrategy.ts","../src/universalFile/server/processors/ImageProcessor.ts","../src/universalFile/server/processors/AudioProcessor.ts","../src/universalFile/server/processors/VideoProcessor.ts","../src/universalFile/server/processors/ProcessingQueue.ts","../src/universalFile/server/index.ts","../src/universalFile/server/cache/CacheManager.ts","../src/universalFile/server/monitoring/PerformanceMonitor.ts","../src/universalFile/server/cdn/CdnCacheStrategy.ts","../src/universalFile/server/types/api.ts","../src/universalFile/server/errors/ApiError.ts","../src/universalFile/server/persistence/drizzle-repository.ts","../src/universalFile/server/adapters/drizzleAdapter.ts","../src/universalFile/server/db/middleware/queryOptimizer.ts","../src/universalFile/server/drizzle-schemas/postgres.ts","../src/universalFile/server/db/services/fileDbService.ts","../src/universalFile/server/config-manager.ts","../src/universalFile/server/service-helpers.ts","../src/universalFile/server/config-helpers.ts"],"names":["init_LocalStorageProvider","init_AliyunOSSProvider","init_logger","init_types","createLogger","CDNProviderError","__require","timestamp","createHash","CacheStrategyType","logger","existsSync","path","fs","text","path2","path3","EventEmitter","init_mime","init_UniversalFileService","LRUCache","CdnCacheStrategy","ApiErrorCode","NextResponse","eq","sql","and","desc","fileStorageProviders","options","like","asc","pgTable","serial","varchar","json","boolean","integer","bigint","index","uuid","relations","uuidv4","UniversalFileService"],"mappings":"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","file":"chunk-VLZ5N6XZ.js","sourcesContent":["/**\n * UniversalFile Service 工厂函数\n * 提供简化的服务初始化方式\n */\n\nimport type {\n UniversalFileServiceConfig,\n StorageConfig,\n LocalStorageConfig,\n AliyunOSSConfig,\n} from './types';\n\n/**\n * 创建文件服务配置(带智能默认值)\n */\nexport function createFileServiceConfig(\n options: Partial<UniversalFileServiceConfig> & {\n storage: StorageConfig | 'local';\n }\n): UniversalFileServiceConfig {\n // 处理简化的 storage 配置\n let storage: StorageConfig;\n\n if (options.storage === 'local') {\n storage = {\n type: 'local',\n enabled: true,\n rootPath: process.env.UPLOAD_DIR || './uploads',\n baseUrl: process.env.BASE_URL || 'http://localhost:3000',\n } as LocalStorageConfig;\n } else {\n storage = options.storage;\n }\n\n return {\n storage,\n cdn: options.cdn,\n cache: options.cache || {\n enabled: false,\n },\n processors: options.processors || [],\n db: options.db,\n maxFileSize: options.maxFileSize || 10 * 1024 * 1024, // 10MB\n allowedMimeTypes: options.allowedMimeTypes || [\n 'image/*',\n 'video/*',\n 'audio/*',\n 'application/pdf',\n ],\n enableMonitoring: options.enableMonitoring !== false,\n };\n}\n\n/**\n * 创建文件服务实例(简化版)\n *\n * @example\n * ```typescript\n * // 最简配置 - 使用本地存储\n * const service = createUniversalFileService({ storage: 'local' });\n *\n * // 标准配置 - 使用阿里云 OSS\n * const service = createUniversalFileService({\n * storage: {\n * type: 'aliyun-oss',\n * config: {\n * accessKeyId: process.env.OSS_KEY!,\n * accessKeySecret: process.env.OSS_SECRET!,\n * bucket: process.env.OSS_BUCKET!,\n * region: process.env.OSS_REGION!,\n * },\n * },\n * db: drizzleDb,\n * });\n * ```\n */\nexport function createUniversalFileService(\n options: Partial<UniversalFileServiceConfig> & {\n storage: StorageConfig | 'local';\n }\n) {\n const config = createFileServiceConfig(options);\n\n // 注意:实际的 UniversalFileService 将在后续 Phase 迁移\n // 这里先返回一个占位对象,包含基本的类型信息\n console.warn(\n '⚠️ UniversalFileService 的完整实现将在后续 Phase 中迁移到 Sa2kit。\\n' +\n ' 当前版本仅包含类型定义和配置工厂函数。\\n' +\n ' 请暂时继续从 LyricNote 的 lib/universalFile 导入服务类。'\n );\n\n return {\n config,\n // 占位方法\n async upload() {\n throw new Error('UniversalFileService 尚未完全迁移,请从 LyricNote 导入');\n },\n async download() {\n throw new Error('UniversalFileService 尚未完全迁移,请从 LyricNote 导入');\n },\n };\n}\n\n/**\n * 从环境变量创建配置(便利函数)\n *\n * @example\n * ```typescript\n * // .env\n * // STORAGE_TYPE=aliyun-oss\n * // OSS_ACCESS_KEY_ID=xxx\n * // OSS_ACCESS_KEY_SECRET=xxx\n * // OSS_BUCKET=my-bucket\n * // OSS_REGION=oss-cn-hangzhou\n *\n * const service = createFileServiceFromEnv();\n * ```\n */\nexport function createFileServiceFromEnv(db?: any) {\n const storageType = process.env.STORAGE_TYPE || 'local';\n\n let storage: StorageConfig;\n\n switch (storageType) {\n case 'local':\n storage = {\n type: 'local',\n enabled: true,\n rootPath: process.env.UPLOAD_DIR || './uploads',\n baseUrl: process.env.BASE_URL || 'http://localhost:3000',\n } as LocalStorageConfig;\n break;\n\n case 'aliyun-oss':\n if (!process.env.OSS_ACCESS_KEY_ID || !process.env.OSS_ACCESS_KEY_SECRET) {\n throw new Error('Missing required OSS environment variables');\n }\n storage = {\n type: 'aliyun-oss',\n enabled: true,\n accessKeyId: process.env.OSS_ACCESS_KEY_ID,\n accessKeySecret: process.env.OSS_ACCESS_KEY_SECRET,\n bucket: process.env.OSS_BUCKET!,\n region: process.env.OSS_REGION || 'oss-cn-hangzhou',\n } as AliyunOSSConfig;\n break;\n\n default:\n throw new Error('Unsupported storage type: ' + (storageType));\n }\n\n return createUniversalFileService({\n storage,\n db,\n });\n}\n\n","/**\n * UniversalFile 预设配置\n * 提供常见场景的开箱即用配置\n */\n\nimport type { StorageConfig, LocalStorageConfig, AliyunOSSConfig } from './types';\n\n/**\n * 本地开发环境预设\n */\nexport function createLocalDevPreset(baseUrl = 'http://localhost:3000'): StorageConfig {\n return {\n type: 'local',\n enabled: true,\n rootPath: './uploads',\n baseUrl,\n } as LocalStorageConfig;\n}\n\n/**\n * 生产环境 OSS 预设\n */\nexport function createAliyunOSSPreset(config: {\n accessKeyId: string;\n accessKeySecret: string;\n bucket: string;\n region?: string;\n}): StorageConfig {\n return {\n type: 'aliyun-oss',\n enabled: true,\n accessKeyId: config.accessKeyId,\n accessKeySecret: config.accessKeySecret,\n bucket: config.bucket,\n region: config.region || 'oss-cn-hangzhou',\n } as AliyunOSSConfig;\n}\n\n/**\n * 智能预设:根据环境自动选择\n */\nexport function createSmartPreset(): StorageConfig {\n const isProduction = process.env.NODE_ENV === 'production';\n\n if (isProduction && process.env.OSS_ACCESS_KEY_ID) {\n // 生产环境且配置了 OSS\n return createAliyunOSSPreset({\n accessKeyId: process.env.OSS_ACCESS_KEY_ID,\n accessKeySecret: process.env.OSS_ACCESS_KEY_SECRET!,\n bucket: process.env.OSS_BUCKET!,\n region: process.env.OSS_REGION,\n });\n }\n\n // 默认使用本地存储\n return createLocalDevPreset(process.env.BASE_URL);\n}\n\n/**\n * 图片服务预设(针对图片处理优化)\n */\nexport function createImageServicePreset(storage: StorageConfig) {\n return {\n storage,\n maxFileSize: 5 * 1024 * 1024, // 5MB\n allowedMimeTypes: [\n 'image/jpeg',\n 'image/png',\n 'image/webp',\n 'image/gif',\n ],\n };\n}\n\n/**\n * 视频服务预设(针对大文件优化)\n */\nexport function createVideoServicePreset(storage: StorageConfig) {\n return {\n storage,\n maxFileSize: 100 * 1024 * 1024, // 100MB\n allowedMimeTypes: [\n 'video/mp4',\n 'video/webm',\n 'video/quicktime',\n ],\n enableStreaming: true,\n };\n}\n\n/**\n * 文档服务预设\n */\nexport function createDocumentServicePreset(storage: StorageConfig) {\n return {\n storage,\n maxFileSize: 20 * 1024 * 1024, // 20MB\n allowedMimeTypes: [\n 'application/pdf',\n 'application/msword',\n 'application/vnd.openxmlformats-officedocument.wordprocessingml.document',\n 'application/vnd.ms-excel',\n 'application/vnd.openxmlformats-officedocument.spreadsheetml.sheet',\n ],\n };\n}\n\n","/**\n * UniversalFile 配置验证\n */\n\nimport type { UniversalFileServiceConfig, StorageConfig } from './types';\n\nexport class ConfigValidationError extends Error {\n constructor(message: string, public field: string) {\n super(message);\n this.name = 'ConfigValidationError';\n }\n}\n\n/**\n * 验证存储配置\n */\nexport function validateStorageConfig(storage: StorageConfig): void {\n if (!storage.type) {\n throw new ConfigValidationError('Storage type is required', 'storage.type');\n }\n\n switch (storage.type) {\n case 'local': {\n const config = storage as any;\n if (!config.rootPath) {\n throw new ConfigValidationError(\n 'rootPath is required for local storage',\n 'storage.rootPath'\n );\n }\n if (!config.baseUrl) {\n throw new ConfigValidationError(\n 'baseUrl is required for local storage',\n 'storage.baseUrl'\n );\n }\n break;\n }\n\n case 'aliyun-oss': {\n const config = storage as any;\n if (!config.accessKeyId) {\n throw new ConfigValidationError(\n 'accessKeyId is required for Aliyun OSS',\n 'storage.accessKeyId'\n );\n }\n if (!config.accessKeySecret) {\n throw new ConfigValidationError(\n 'accessKeySecret is required for Aliyun OSS',\n 'storage.accessKeySecret'\n );\n }\n if (!config.bucket) {\n throw new ConfigValidationError(\n 'bucket is required for Aliyun OSS',\n 'storage.bucket'\n );\n }\n break;\n }\n\n default:\n throw new ConfigValidationError(\n 'Unsupported storage type: ' + (storage.type),\n 'storage.type'\n );\n }\n}\n\n/**\n * 验证完整的服务配置\n */\nexport function validateServiceConfig(config: UniversalFileServiceConfig): void {\n // 验证存储配置\n if (!config.storage) {\n throw new ConfigValidationError('Storage config is required', 'storage');\n }\n validateStorageConfig(config.storage);\n\n // 验证文件大小限制\n if (config.maxFileSize && config.maxFileSize <= 0) {\n throw new ConfigValidationError(\n 'maxFileSize must be greater than 0',\n 'maxFileSize'\n );\n }\n\n // 验证 MIME 类型\n if (config.allowedMimeTypes && config.allowedMimeTypes.length === 0) {\n throw new ConfigValidationError(\n 'allowedMimeTypes must not be empty',\n 'allowedMimeTypes'\n );\n }\n}\n\n/**\n * 验证环境变量\n */\nexport function validateEnvironment(requiredVars: string[]): void {\n const missing: string[] = [];\n\n for (const varName of requiredVars) {\n if (!process.env[varName]) {\n missing.push(varName);\n }\n }\n\n if (missing.length > 0) {\n throw new ConfigValidationError(\n 'Missing required environment variables: ' + (missing.join(', ')),\n 'environment'\n );\n }\n}\n\n/**\n * 获取环境变量所需的变量列表(根据存储类型)\n */\nexport function getRequiredEnvVars(storageType: string): string[] {\n switch (storageType) {\n case 'local':\n return ['UPLOAD_DIR', 'BASE_URL'];\n case 'aliyun-oss':\n return [\n 'OSS_ACCESS_KEY_ID',\n 'OSS_ACCESS_KEY_SECRET',\n 'OSS_BUCKET',\n 'OSS_REGION',\n ];\n default:\n return [];\n }\n}\n\n","/**\n * Universal File Providers\n * 导出所有的存储和CDN提供者\n */\n\n// Storage Providers\nexport { LocalStorageProvider } from './LocalStorageProvider';\nexport { AliyunOSSProvider } from './AliyunOSSProvider';\n\n// CDN Providers\nexport { AliyunCDNProvider } from './AliyunCDNProvider';\n\n// Cache Strategy\nexport { CdnCacheStrategy, CacheStrategyType, cdnCacheStrategy } from './CdnCacheStrategy';\n\n","/**\n * 阿里云CDN提供者实现\n */\n\nimport { createHash } from 'crypto';\nimport { createLogger } from '../../../logger';\n\nimport type { ICDNProvider, CDNConfig, AliyunCDNConfig, CDNResult, CDNType } from '../types';\n\nimport { CDNProviderError } from '../types';\n\nconst logger = createLogger('AliyunCDNProvider');\n\n// 定义阿里云CDN SDK类型 (简化版本)\ninterface AliyunCDNClient {\n refreshObjectCaches(params: any): Promise<any>;\n pushObjectCache(params: any): Promise<any>;\n describeRefreshTasks(params: any): Promise<any>;\n describePushTasks(params: any): Promise<any>;\n describeDomainConfigs(params: any): Promise<any>;\n describeCdnDomainLogs(params: any): Promise<any>;\n describeDomainRealTimeData(params: any): Promise<any>;\n}\n\n/**\n * 阿里云CDN提供者\n */\nexport class AliyunCDNProvider implements ICDNProvider {\n readonly type: CDNType = 'aliyun-cdn';\n\n private config: AliyunCDNConfig | null = null;\n private client: AliyunCDNClient | null = null;\n private isInitialized = false;\n\n /**\n * 初始化CDN提供者\n */\n async initialize(config: CDNConfig): Promise<void> {\n if (config.type !== 'aliyun-cdn') {\n throw new CDNProviderError('配置类型不匹配:期望 aliyun-cdn');\n }\n\n this.config = config as AliyunCDNConfig;\n\n logger.info('🌐 [AliyunCDNProvider] 初始化阿里云CDN,域名: ' + (this.config.domain));\n\n try {\n // 验证必需的配置项\n this.validateConfig();\n\n // 注意:这里需要安装阿里云CDN SDK\n // npm install @alicloud/cdn20180510\n try {\n const CDN = require('@alicloud/cdn20180510');\n const OpenApi = require('@alicloud/openapi-client');\n\n const cdnConfig = new OpenApi.Config({\n accessKeyId: this.config.accessKeyId,\n accessKeySecret: this.config.accessKeySecret,\n endpoint: 'cdn.aliyuncs.com',\n });\n\n this.client = new CDN.default(cdnConfig);\n } catch (sdkError) {\n logger.warn('⚠️ [AliyunCDNProvider] 阿里云CDN SDK未安装,使用模拟模式');\n // 创建模拟客户端用于开发测试\n this.client = this.createMockClient();\n }\n\n // 测试连接\n await this.testConnection();\n\n this.isInitialized = true;\n logger.info('✅ [AliyunCDNProvider] 阿里云CDN初始化完成');\n } catch (error) {\n logger.error('❌ [AliyunCDNProvider] 阿里云CDN初始化失败:', error);\n throw new CDNProviderError(\n '阿里云CDN初始化失败: ' + (error instanceof Error ? error.message : '未知错误')\n );\n }\n }\n\n /**\n * 生成CDN URL\n */\n async generateUrl(originalUrl: string): Promise<string> {\n this.ensureInitialized();\n\n logger.info('🔗 [AliyunCDNProvider] 生成CDN URL: ' + (originalUrl));\n\n try {\n // 解析原始URL\n const url = new URL(originalUrl);\n\n // 替换域名为CDN域名\n const cdnUrl = (url.protocol) + '//' + (this.config!.domain) + (url.pathname) + (url.search) + (url.hash);\n\n logger.info('✅ [AliyunCDNProvider] CDN URL生成完成: ' + (cdnUrl));\n\n return cdnUrl;\n } catch (error) {\n logger.error('❌ [AliyunCDNProvider] CDN URL生成失败: ' + (originalUrl) + ':', error);\n throw new CDNProviderError(\n 'CDN URL生成失败: ' + (error instanceof Error ? error.message : '未知错误')\n );\n }\n }\n\n /**\n * 刷新缓存\n */\n async refreshCache(urls: string[]): Promise<CDNResult> {\n this.ensureInitialized();\n\n logger.info('🔄 [AliyunCDNProvider] 开始刷新CDN缓存,URL数量: ' + (urls.length));\n\n try {\n // 将URL转换为CDN URL\n const cdnUrls = await Promise.all(urls.map((url) => this.generateUrl(url)));\n\n // 调用阿里云CDN API刷新缓存\n const result = await this.client!.refreshObjectCaches({\n domainName: this.config!.domain,\n objectPath: cdnUrls.join('\\n'),\n objectType: 'File', // File 或 Directory\n });\n\n logger.info(\n '✅ [AliyunCDNProvider] CDN缓存刷新完成,任务ID: ' + (result.RefreshTaskId || 'unknown')\n );\n\n return {\n success: true,\n data: {\n taskId: result.RefreshTaskId,\n requestId: result.RequestId,\n urls: cdnUrls,\n },\n };\n } catch (error) {\n logger.error(`❌ [AliyunCDNProvider] CDN缓存刷新失败:`, error);\n\n return {\n success: false,\n error: 'CDN缓存刷新失败: ' + (error instanceof Error ? error.message : '未知错误'),\n };\n }\n }\n\n /**\n * 预热缓存\n */\n async preheatCache(urls: string[]): Promise<CDNResult> {\n this.ensureInitialized();\n\n logger.info('🔥 [AliyunCDNProvider] 开始预热CDN缓存,URL数量: ' + (urls.length));\n\n try {\n // 将URL转换为CDN URL\n const cdnUrls = await Promise.all(urls.map((url) => this.generateUrl(url)));\n\n // 调用阿里云CDN API预热缓存\n const result = await this.client!.pushObjectCache({\n domainName: this.config!.domain,\n objectPath: cdnUrls.join('\\n'),\n area: 'domestic', // domestic, overseas, global\n });\n\n logger.info(\n '✅ [AliyunCDNProvider] CDN缓存预热完成,任务ID: ' + (result.PushTaskId || 'unknown')\n );\n\n return {\n success: true,\n data: {\n taskId: result.PushTaskId,\n requestId: result.RequestId,\n urls: cdnUrls,\n },\n };\n } catch (error) {\n logger.error(`❌ [AliyunCDNProvider] CDN缓存预热失败:`, error);\n\n return {\n success: false,\n error: 'CDN缓存预热失败: ' + (error instanceof Error ? error.message : '未知错误'),\n };\n }\n }\n\n /**\n * 获取访问统计\n */\n async getAccessStats(startTime: Date, endTime: Date): Promise<CDNResult> {\n this.ensureInitialized();\n\n logger.info(\n '📊 [AliyunCDNProvider] 获取CDN访问统计: ' + (startTime.toISOString()) + ' - ' + (endTime.toISOString())\n );\n\n try {\n // 格式化时间\n const formatTime = (date: Date) => date.toISOString().slice(0, 19).replace('T', ' ') + 'Z';\n\n // 调用阿里云CDN API获取实时数据\n const result = await this.client!.describeDomainRealTimeData({\n domainName: this.config!.domain,\n startTime: formatTime(startTime),\n endTime: formatTime(endTime),\n field: 'bps,qps', // 带宽和QPS\n });\n\n logger.info(`✅ [AliyunCDNProvider] CDN访问统计获取完成`);\n\n return {\n success: true,\n data: {\n requestId: result.RequestId,\n dataInterval: result.DataInterval,\n realTimeData: result.RealTimeData,\n domain: this.config!.domain,\n startTime: startTime.toISOString(),\n endTime: endTime.toISOString(),\n },\n };\n } catch (error) {\n logger.error(`❌ [AliyunCDNProvider] CDN访问统计获取失败:`, error);\n\n return {\n success: false,\n error: 'CDN访问统计获取失败: ' + (error instanceof Error ? error.message : '未知错误'),\n };\n }\n }\n\n // ============= 高级功能 =============\n\n /**\n * 生成防盗链签名URL\n */\n async generateSignedUrl(\n originalUrl: string,\n expiresIn: number = 3600,\n authKey?: string\n ): Promise<string> {\n this.ensureInitialized();\n\n logger.info('🔐 [AliyunCDNProvider] 生成防盗链签名URL: ' + (originalUrl));\n\n try {\n const cdnUrl = await this.generateUrl(originalUrl);\n\n // 如果没有提供authKey,直接返回CDN URL\n if (!authKey) {\n logger.info(`⚠️ [AliyunCDNProvider] 未提供authKey,返回普通CDN URL`);\n return cdnUrl;\n }\n\n // 生成防盗链签名\n const parsedUrl = new URL(cdnUrl);\n const timestamp = Math.floor(Date.now() / 1000) + expiresIn;\n\n // 阿里云CDN防盗链签名算法\n // signString = \"path-timestamp-rand-uid-authKey\"\n const signString = (parsedUrl.pathname) + '-' + (timestamp) + '-0-0-' + (authKey);\n const authValue = createHash('md5').update(signString).digest('hex');\n\n // 构建签名URL\n const signedUrl = (cdnUrl) + '?auth_key=' + (timestamp) + '-0-0-' + (authValue);\n\n logger.info(`✅ [AliyunCDNProvider] 防盗链签名URL生成完成`);\n\n return signedUrl;\n } catch (error) {\n logger.error('❌ [AliyunCDNProvider] 防盗链签名URL生成失败: ' + (originalUrl) + ':', error);\n throw new CDNProviderError(\n '防盗链签名URL生成失败: ' + (error instanceof Error ? error.message : '未知错误')\n );\n }\n }\n\n /**\n * 查询刷新任务状态\n */\n async getRefreshTaskStatus(taskId: string): Promise<CDNResult> {\n this.ensureInitialized();\n\n try {\n const result = await this.client!.describeRefreshTasks({\n taskId,\n });\n\n return {\n success: true,\n data: {\n tasks: result.Tasks,\n requestId: result.RequestId,\n },\n };\n } catch (error) {\n return {\n success: false,\n error: '查询刷新任务状态失败: ' + (error instanceof Error ? error.message : '未知错误'),\n };\n }\n }\n\n /**\n * 查询预热任务状态\n */\n async getPreheatTaskStatus(taskId: string): Promise<CDNResult> {\n this.ensureInitialized();\n\n try {\n const result = await this.client!.describePushTasks({\n taskId,\n });\n\n return {\n success: true,\n data: {\n tasks: result.Tasks,\n requestId: result.RequestId,\n },\n };\n } catch (error) {\n return {\n success: false,\n error: '查询预热任务状态失败: ' + (error instanceof Error ? error.message : '未知错误'),\n };\n }\n }\n\n /**\n * 获取域名配置\n */\n async getDomainConfig(): Promise<CDNResult> {\n this.ensureInitialized();\n\n try {\n const result = await this.client!.describeDomainConfigs({\n domainName: this.config!.domain,\n });\n\n return {\n success: true,\n data: {\n domainConfigs: result.DomainConfigs,\n requestId: result.RequestId,\n },\n };\n } catch (error) {\n return {\n success: false,\n error: '获取域名配置失败: ' + (error instanceof Error ? error.message : '未知错误'),\n };\n }\n }\n\n /**\n * 优化URL (添加图像处理参数等)\n */\n async optimizeUrl(\n originalUrl: string,\n options: {\n imageQuality?: number;\n imageFormat?: 'webp' | 'jpg' | 'png';\n imageResize?: { width?: number; height?: number };\n enableGzip?: boolean;\n } = {}\n ): Promise<string> {\n this.ensureInitialized();\n\n try {\n const cdnUrl = await this.generateUrl(originalUrl);\n const url = new URL(cdnUrl);\n\n // 添加阿里云CDN图像处理参数\n const params = new URLSearchParams(url.search);\n\n if (options.imageQuality) {\n params.set('x-oss-process', 'image/quality,q_' + (options.imageQuality));\n }\n\n if (options.imageFormat) {\n const formatParam = params.get('x-oss-process') || 'image';\n params.set('x-oss-process', (formatParam) + '/format,' + (options.imageFormat));\n }\n\n if (options.imageResize) {\n const resizeParam = params.get('x-oss-process') || 'image';\n let resize = 'resize';\n if (options.imageResize.width) resize += ',w_' + (options.imageResize.width);\n if (options.imageResize.height) resize += ',h_' + (options.imageResize.height);\n params.set('x-oss-process', (resizeParam) + '/' + (resize));\n }\n\n url.search = params.toString();\n\n return url.toString();\n } catch (error) {\n logger.error('❌ [AliyunCDNProvider] URL优化失败: ' + (originalUrl) + ':', error);\n // 如果优化失败,返回原始CDN URL\n return this.generateUrl(originalUrl);\n }\n }\n\n // ============= 私有方法 =============\n\n /**\n * 确保已初始化\n */\n private ensureInitialized(): void {\n if (!this.isInitialized || !this.client || !this.config) {\n throw new CDNProviderError('CDN提供者未初始化');\n }\n }\n\n /**\n * 验证配置\n */\n private validateConfig(): void {\n if (!this.config) {\n throw new CDNProviderError('CDN配置为空');\n }\n\n const required = ['domain', 'accessKeyId', 'accessKeySecret'];\n const missing = required.filter((key) => !this.config![key as keyof AliyunCDNConfig]);\n\n if (missing.length > 0) {\n throw new CDNProviderError('CDN配置缺少必需项: ' + (missing.join(', ')));\n }\n\n // 验证域名格式\n if (!this.isValidDomain(this.config.domain)) {\n throw new CDNProviderError('无效的CDN域名: ' + (this.config.domain));\n }\n }\n\n /**\n * 验证域名格式\n */\n private isValidDomain(domain: string): boolean {\n // 简单的域名格式验证\n const domainRegex =\n /^[a-zA-Z0-9]([a-zA-Z0-9-]{0,61}[a-zA-Z0-9])?(\\.[a-zA-Z0-9]([a-zA-Z0-9-]{0,61}[a-zA-Z0-9])?)*$/;\n return domainRegex.test(domain);\n }\n\n /**\n * 测试连接\n */\n private async testConnection(): Promise<void> {\n try {\n // 尝试获取域名配置来测试连接\n await this.getDomainConfig();\n logger.info(`✅ [AliyunCDNProvider] CDN连接测试成功`);\n } catch (error) {\n logger.warn(`⚠️ [AliyunCDNProvider] CDN连接测试失败,可能是权限问题:`, error);\n // 不抛出错误,因为可能是权限限制\n }\n }\n\n /**\n * 创建模拟客户端(用于开发测试)\n */\n private createMockClient(): AliyunCDNClient {\n logger.info('🧪 [AliyunCDNProvider] 创建模拟CDN客户端');\n\n return {\n async refreshObjectCaches(params: any) {\n logger.info('🔄 [MockCDN] 模拟刷新缓存:', params);\n return {\n RefreshTaskId: 'mock-refresh-' + (Date.now()),\n RequestId: 'mock-request-' + (Date.now()),\n };\n },\n\n async pushObjectCache(params: any) {\n logger.info('🔥 [MockCDN] 模拟预热缓存:', params);\n return {\n PushTaskId: 'mock-push-' + (Date.now()),\n RequestId: 'mock-request-' + (Date.now()),\n };\n },\n\n async describeRefreshTasks(params: any) {\n logger.info('📋 [MockCDN] 模拟查询刷新任务:', params);\n return {\n Tasks: {\n Task: [\n {\n TaskId: params.taskId,\n Status: 'Complete',\n Process: '100%',\n CreateTime: new Date().toISOString(),\n },\n ],\n },\n RequestId: 'mock-request-' + (Date.now()),\n };\n },\n\n async describePushTasks(params: any) {\n logger.info('📋 [MockCDN] 模拟查询预热任务:', params);\n return {\n Tasks: {\n Task: [\n {\n TaskId: params.taskId,\n Status: 'Complete',\n Process: '100%',\n CreateTime: new Date().toISOString(),\n },\n ],\n },\n RequestId: 'mock-request-' + (Date.now()),\n };\n },\n\n async describeDomainConfigs(params: any) {\n logger.info('⚙️ [MockCDN] 模拟获取域名配置:', params);\n return {\n DomainConfigs: {\n DomainConfig: [\n {\n FunctionName: 'cache',\n ConfigId: 'mock-config-id',\n Status: 'success',\n },\n ],\n },\n RequestId: 'mock-request-' + (Date.now()),\n };\n },\n\n async describeCdnDomainLogs(params: any) {\n logger.info('📊 [MockCDN] 模拟获取日志:', params);\n return {\n DomainLogDetails: {\n DomainLogDetail: [],\n },\n RequestId: 'mock-request-' + (Date.now()),\n };\n },\n\n async describeDomainRealTimeData(params: any) {\n logger.info('📈 [MockCDN] 模拟获取实时数据:', params);\n return {\n RealTimeData: {\n UsageData: [\n {\n TimeStamp: new Date().toISOString(),\n Value: Math.random() * 1000,\n },\n ],\n },\n DataInterval: '60',\n RequestId: 'mock-request-' + (Date.now()),\n };\n },\n };\n }\n\n /**\n * 批量刷新缓存(带进度回调)\n */\n async batchRefreshCache(\n urls: string[],\n batchSize: number = 20,\n onProgress?: (completed: number, total: number) => void\n ): Promise<CDNResult> {\n this.ensureInitialized();\n\n logger.info(\n '🔄 [AliyunCDNProvider] 开始批量刷新缓存,总URL数: ' + (urls.length) + ',批次大小: ' + (batchSize)\n );\n\n try {\n const results = [];\n let completed = 0;\n\n // 分批处理\n for (let i = 0; i < urls.length; i += batchSize) {\n const batch = urls.slice(i, i + batchSize);\n const batchResult = await this.refreshCache(batch);\n results.push(batchResult);\n\n completed += batch.length;\n if (onProgress) {\n onProgress(completed, urls.length);\n }\n\n // 避免API限流,每批次间隔1秒\n if (i + batchSize < urls.length) {\n await new Promise((resolve) => setTimeout(resolve, 1000));\n }\n }\n\n const successCount = results.filter((r) => r.success).length;\n logger.info('✅ [AliyunCDNProvider] 批量刷新完成,成功: ' + (successCount) + '/' + (results.length));\n\n return {\n success: successCount === results.length,\n data: {\n totalBatches: results.length,\n successBatches: successCount,\n results,\n },\n };\n } catch (error) {\n logger.error(`❌ [AliyunCDNProvider] 批量刷新失败:`, error);\n\n return {\n success: false,\n error: '批量刷新失败: ' + (error instanceof Error ? error.message : '未知错误'),\n };\n }\n }\n}\n\n","/**\n * CDN缓存策略管理\n * 优化静态资源缓存策略和预热机制\n */\n\n/**\n * 缓存策略类型\n */\nexport enum CacheStrategyType {\n /** 图片资源 */\n IMAGE = 'image',\n /** 视频资源 */\n VIDEO = 'video',\n /** 音频资源 */\n AUDIO = 'audio',\n /** 文档资源 */\n DOCUMENT = 'document',\n /** 压缩包 */\n ARCHIVE = 'archive',\n /** 静态资源 */\n STATIC = 'static',\n /** 其他 */\n OTHER = 'other',\n}\n\n/**\n * 缓存策略配置\n */\ninterface CacheStrategyConfig {\n /** 缓存策略类型 */\n type: CacheStrategyType;\n /** 缓存时间(秒) */\n ttl: number;\n /** 是否启用浏览器缓存 */\n browserCache: boolean;\n /** 浏览器缓存时间(秒) */\n browserCacheTtl: number;\n /** 是否启用CDN缓存 */\n cdnCache: boolean;\n /** CDN缓存时间(秒) */\n cdnCacheTtl: number;\n /** 是否启用预热 */\n enableWarmup: boolean;\n /** 缓存控制头 */\n cacheControl: string;\n /** 允许的文件类型 */\n allowedMimeTypes: string[];\n /** 文件大小限制(字节) */\n maxFileSize?: number;\n}\n\n/**\n * 缓存统计信息\n */\ninterface CacheStats {\n /** 命中次数 */\n hits: number;\n /** 未命中次数 */\n misses: number;\n /** 命中率 */\n hitRate: number;\n /** 总请求数 */\n totalRequests: number;\n /** 缓存大小估算 */\n estimatedSize: number;\n /** 节省的带宽(字节) */\n bandwidthSaved: number;\n}\n\n/**\n * CDN缓存策略管理器\n */\nexport class CdnCacheStrategy {\n private strategies: Map<CacheStrategyType, CacheStrategyConfig> = new Map();\n private stats: Map<CacheStrategyType, CacheStats> = new Map();\n\n constructor() {\n this.initializeDefaultStrategies();\n }\n\n /**\n * 初始化默认缓存策略\n */\n private initializeDefaultStrategies(): void {\n // 图片缓存策略\n this.strategies.set(CacheStrategyType.IMAGE, {\n type: CacheStrategyType.IMAGE,\n ttl: 30 * 24 * 3600, // 30天\n browserCache: true,\n browserCacheTtl: 7 * 24 * 3600, // 7天\n cdnCache: true,\n cdnCacheTtl: 30 * 24 * 3600, // 30天\n enableWarmup: true,\n cacheControl: 'public, max-age=604800, s-maxage=2592000',\n allowedMimeTypes: ['image/jpeg', 'image/png', 'image/gif', 'image/webp', 'image/svg+xml'],\n maxFileSize: 50 * 1024 * 1024, // 50MB\n });\n\n // 视频缓存策略\n this.strategies.set(CacheStrategyType.VIDEO, {\n type: CacheStrategyType.VIDEO,\n ttl: 7 * 24 * 3600, // 7天\n browserCache: true,\n browserCacheTtl: 24 * 3600, // 1天\n cdnCache: true,\n cdnCacheTtl: 7 * 24 * 3600, // 7天\n enableWarmup: false, // 视频文件通常较大,不预热\n cacheControl: 'public, max-age=86400, s-maxage=604800',\n allowedMimeTypes: ['video/mp4', 'video/avi', 'video/mov', 'video/wmv', 'video/webm'],\n maxFileSize: 500 * 1024 * 1024, // 500MB\n });\n\n // 音频缓存策略\n this.strategies.set(CacheStrategyType.AUDIO, {\n type: CacheStrategyType.AUDIO,\n ttl: 14 * 24 * 3600, // 14天\n browserCache: true,\n browserCacheTtl: 3 * 24 * 3600, // 3天\n cdnCache: true,\n cdnCacheTtl: 14 * 24 * 3600, // 14天\n enableWarmup: true,\n cacheControl: 'public, max-age=259200, s-maxage=1209600',\n allowedMimeTypes: ['audio/mpeg', 'audio/wav', 'audio/ogg', 'audio/m4a', 'audio/flac'],\n maxFileSize: 100 * 1024 * 1024, // 100MB\n });\n\n // 文档缓存策略\n this.strategies.set(CacheStrategyType.DOCUMENT, {\n type: CacheStrategyType.DOCUMENT,\n ttl: 24 * 3600, // 1天\n browserCache: true,\n browserCacheTtl: 3600, // 1小时\n cdnCache: true,\n cdnCacheTtl: 24 * 3600, // 1天\n enableWarmup: false,\n cacheControl: 'public, max-age=3600, s-maxage=86400',\n allowedMimeTypes: [\n 'application/pdf',\n 'application/msword',\n 'application/vnd.openxmlformats-officedocument.wordprocessingml.document',\n 'application/vnd.ms-excel',\n 'application/vnd.openxmlformats-officedocument.spreadsheetml.sheet',\n 'text/plain',\n 'text/csv',\n ],\n maxFileSize: 50 * 1024 * 1024, // 50MB\n });\n\n // 压缩包缓存策略\n this.strategies.set(CacheStrategyType.ARCHIVE, {\n type: CacheStrategyType.ARCHIVE,\n ttl: 24 * 3600, // 1天\n browserCache: true,\n browserCacheTtl: 1800, // 30分钟\n cdnCache: true,\n cdnCacheTtl: 24 * 3600, // 1天\n enableWarmup: false,\n cacheControl: 'public, max-age=1800, s-maxage=86400',\n allowedMimeTypes: [\n 'application/zip',\n 'application/x-rar-compressed',\n 'application/x-7z-compressed',\n 'application/gzip',\n 'application/x-tar',\n ],\n maxFileSize: 100 * 1024 * 1024, // 100MB\n });\n\n // 静态资源缓存策略\n this.strategies.set(CacheStrategyType.STATIC, {\n type: CacheStrategyType.STATIC,\n ttl: 365 * 24 * 3600, // 1年\n browserCache: true,\n browserCacheTtl: 30 * 24 * 3600, // 30天\n cdnCache: true,\n cdnCacheTtl: 365 * 24 * 3600, // 1年\n enableWarmup: true,\n cacheControl: 'public, max-age=2592000, s-maxage=31536000, immutable',\n allowedMimeTypes: [\n 'text/css',\n 'application/javascript',\n 'application/json',\n 'font/woff',\n 'font/woff2',\n 'font/ttf',\n ],\n maxFileSize: 10 * 1024 * 1024, // 10MB\n });\n\n // 其他文件缓存策略\n this.strategies.set(CacheStrategyType.OTHER, {\n type: CacheStrategyType.OTHER,\n ttl: 3600, // 1小时\n browserCache: true,\n browserCacheTtl: 300, // 5分钟\n cdnCache: false,\n cdnCacheTtl: 0,\n enableWarmup: false,\n cacheControl: 'public, max-age=300',\n allowedMimeTypes: [],\n maxFileSize: 10 * 1024 * 1024, // 10MB\n });\n\n // 初始化统计信息\n for (const type of Object.values(CacheStrategyType)) {\n this.stats.set(type, {\n hits: 0,\n misses: 0,\n hitRate: 0,\n totalRequests: 0,\n estimatedSize: 0,\n bandwidthSaved: 0,\n });\n }\n }\n\n /**\n * 根据MIME类型获取缓存策略\n */\n getStrategyByMimeType(mimeType: string): CacheStrategyConfig {\n for (const [_type, strategy] of this.strategies.entries()) {\n if (strategy.allowedMimeTypes.includes(mimeType)) {\n return strategy;\n }\n }\n\n // 根据MIME类型推断策略\n if (mimeType.startsWith('image/')) {\n return this.strategies.get(CacheStrategyType.IMAGE)!;\n } else if (mimeType.startsWith('video/')) {\n return this.strategies.get(CacheStrategyType.VIDEO)!;\n } else if (mimeType.startsWith('audio/')) {\n return this.strategies.get(CacheStrategyType.AUDIO)!;\n } else if (\n mimeType.includes('pdf') ||\n mimeType.includes('document') ||\n mimeType.includes('word') ||\n mimeType.includes('excel')\n ) {\n return this.strategies.get(CacheStrategyType.DOCUMENT)!;\n } else if (\n mimeType.includes('zip') ||\n mimeType.includes('compressed') ||\n mimeType.includes('archive')\n ) {\n return this.strategies.get(CacheStrategyType.ARCHIVE)!;\n }\n\n return this.strategies.get(CacheStrategyType.OTHER)!;\n }\n\n /**\n * 生成缓存控制头\n */\n generateCacheHeaders(mimeType: string, fileSize?: number): Record<string, string> {\n const strategy = this.getStrategyByMimeType(mimeType);\n\n // 检查文件大小限制\n if (fileSize && strategy.maxFileSize && fileSize > strategy.maxFileSize) {\n // 大文件使用更短的缓存时间\n return {\n 'Cache-Control': 'public, max-age=300', // 5分钟\n Expires: new Date(Date.now() + 300 * 1000).toUTCString(),\n };\n }\n\n const headers: Record<string, string> = {\n 'Cache-Control': strategy.cacheControl,\n Expires: new Date(Date.now() + strategy.browserCacheTtl * 1000).toUTCString(),\n };\n\n // 添加ETag用于缓存验证\n if (strategy.browserCache) {\n headers['ETag'] = '\"' + (Date.now()) + '\"';\n }\n\n // 添加Last-Modified头\n headers['Last-Modified'] = new Date().toUTCString();\n\n // 为静态资源添加不可变标记\n if (strategy.type === CacheStrategyType.STATIC) {\n headers['Cache-Control'] += ', immutable';\n }\n\n return headers;\n }\n\n /**\n * 检查是否需要缓存预热\n */\n shouldWarmupCache(mimeType: string): boolean {\n const strategy = this.getStrategyByMimeType(mimeType);\n return strategy.enableWarmup;\n }\n\n /**\n * 记录缓存命中\n */\n recordCacheHit(mimeType: string, fileSize: number = 0): void {\n const strategy = this.getStrategyByMimeType(mimeType);\n const stats = this.stats.get(strategy.type);\n\n if (stats) {\n stats.hits++;\n stats.totalRequests++;\n stats.bandwidthSaved += fileSize;\n stats.hitRate = (stats.hits / stats.totalRequests) * 100;\n }\n }\n\n /**\n * 记录缓存未命中\n */\n recordCacheMiss(mimeType: string, fileSize: number = 0): void {\n const strategy = this.getStrategyByMimeType(mimeType);\n const stats = this.stats.get(strategy.type);\n\n if (stats) {\n stats.misses++;\n stats.totalRequests++;\n stats.estimatedSize += fileSize;\n stats.hitRate = (stats.hits / stats.totalRequests) * 100;\n }\n }\n\n /**\n * 获取缓存统计信息\n */\n getCacheStats(): Map<CacheStrategyType, CacheStats> {\n return new Map(this.stats);\n }\n\n /**\n * 获取总体缓存统计\n */\n getOverallStats(): CacheStats {\n const overall: CacheStats = {\n hits: 0,\n misses: 0,\n hitRate: 0,\n totalRequests: 0,\n estimatedSize: 0,\n bandwidthSaved: 0,\n };\n\n for (const stats of this.stats.values()) {\n overall.hits += stats.hits;\n overall.misses += stats.misses;\n overall.totalRequests += stats.totalRequests;\n overall.estimatedSize += stats.estimatedSize;\n overall.bandwidthSaved += stats.bandwidthSaved;\n }\n\n overall.hitRate = overall.totalRequests > 0 ? (overall.hits / overall.totalRequests) * 100 : 0;\n\n return overall;\n }\n\n /**\n * 生成缓存优化建议\n */\n generateOptimizationSuggestions(): Array<{\n type: CacheStrategyType;\n issue: string;\n suggestion: string;\n severity: 'low' | 'medium' | 'high';\n }> {\n const suggestions: Array<{\n type: CacheStrategyType;\n issue: string;\n suggestion: string;\n severity: 'low' | 'medium' | 'high';\n }> = [];\n\n for (const [type, stats] of this.stats.entries()) {\n if (stats.totalRequests > 100) {\n // 只对有足够请求量的资源类型分析\n // 命中率过低\n if (stats.hitRate < 60) {\n suggestions.push({\n type,\n issue: (type) + '类型文件缓存命中率过低 (' + (stats.hitRate.toFixed(1)) + '%)',\n suggestion: '考虑增加缓存时间或启用预热机制',\n severity: stats.hitRate < 30 ? 'high' : 'medium',\n });\n }\n\n // 缓存大小过大\n if (stats.estimatedSize > 1024 * 1024 * 1024) {\n // 1GB\n suggestions.push({\n type,\n issue: (type) + '类型文件缓存占用空间过大 (' + ((stats.estimatedSize / 1024 / 1024 / 1024).toFixed(2)) + 'GB)',\n suggestion: '考虑减少缓存时间或优化文件压缩',\n severity: 'medium',\n });\n }\n }\n }\n\n return suggestions;\n }\n\n /**\n * 更新缓存策略\n */\n updateStrategy(type: CacheStrategyType, config: Partial<CacheStrategyConfig>): void {\n const currentStrategy = this.strategies.get(type);\n if (currentStrategy) {\n this.strategies.set(type, { ...currentStrategy, ...config });\n }\n }\n\n /**\n * 重置统计信息\n */\n resetStats(): void {\n for (const type of Object.values(CacheStrategyType)) {\n this.stats.set(type, {\n hits: 0,\n misses: 0,\n hitRate: 0,\n totalRequests: 0,\n estimatedSize: 0,\n bandwidthSaved: 0,\n });\n }\n }\n}\n\n/**\n * 单例CDN缓存策略管理器\n */\nexport const cdnCacheStrategy = new CdnCacheStrategy();\n\n","/**\n * 图片处理器实现\n * 支持压缩、裁剪、水印、格式转换等功能\n */\n\nimport * as path from 'path';\nimport { promises as fs } from 'fs';\nimport { existsSync } from 'fs';\nimport { createLogger } from '../../../logger';\n\nimport type {\n IFileProcessor,\n ProcessorType,\n ProcessingOptions,\n ProcessingResult,\n} from '../types';\n\nimport type { ImageProcessingOptions } from '../../types';\n\nconst logger = createLogger('ImageProcessor');\n\n// 图片处理相关类型定义\ninterface ImageMetadata {\n format: string;\n width: number;\n height: number;\n channels: number;\n density: number;\n hasAlpha: boolean;\n orientation?: number;\n}\n\n/**\n * 图片处理器\n * 使用Sharp库进行高性能图片处理\n */\nexport class ImageProcessor implements IFileProcessor {\n readonly type: ProcessorType = 'image';\n\n private sharp: any = null;\n private isInitialized = false;\n\n /**\n * 初始化图片处理器\n */\n async initialize(): Promise<void> {\n logger.info('🖼️ [ImageProcessor] 初始化图片处理器...');\n\n try {\n // 尝试加载Sharp库\n try {\n this.sharp = require('sharp');\n logger.info('✅ [ImageProcessor] Sharp库加载成功');\n } catch (error) {\n console.warn('⚠️ [ImageProcessor] Sharp库未安装,使用模拟模式');\n // 创建模拟Sharp对象\n this.sharp = this.createMockSharp();\n }\n\n this.isInitialized = true;\n logger.info('✅ [ImageProcessor] 图片处理器初始化完成');\n } catch (error) {\n console.error('❌ [ImageProcessor] 图片处理器初始化失败:', error);\n throw error;\n }\n }\n\n /**\n * 处理图片文件\n */\n async process(\n inputPath: string,\n outputPath: string,\n options: ProcessingOptions\n ): Promise<ProcessingResult> {\n this.ensureInitialized();\n\n if (options.type !== 'image') {\n throw new Error('处理选项类型不匹配:期望 image');\n }\n\n const imageOptions = options as ImageProcessingOptions;\n const startTime = Date.now();\n\n logger.info('🖼️ [ImageProcessor] 开始处理图片: ' + (inputPath));\n\n try {\n // 检查输入文件是否存在\n if (!existsSync(inputPath)) {\n throw new Error('输入文件不存在: ' + (inputPath));\n }\n\n // 确保输出目录存在\n const outputDir = path.dirname(outputPath);\n await fs.mkdir(outputDir, { recursive: true });\n\n // 获取图片元数据\n const metadata = await this.getImageMetadata(inputPath);\n logger.info(\n '📊 [ImageProcessor] 图片信息: ' + (metadata.width) + 'x' + (metadata.height) + ', 格式: ' + (metadata.format)\n );\n\n // 创建Sharp处理实例\n let sharpInstance = this.sharp(inputPath);\n\n // 应用图片处理操作\n sharpInstance = await this.applyImageOperations(sharpInstance, imageOptions);\n\n // 确定输出格式\n const outputFormat = this.determineOutputFormat(outputPath, imageOptions.format);\n\n // 应用输出格式和质量设置\n sharpInstance = this.applyOutputSettings(sharpInstance, outputFormat, imageOptions.quality);\n\n // 执行处理并保存\n const info = await sharpInstance.toFile(outputPath);\n\n // 生成缩略图(如果需要)\n let thumbnailPath: string | undefined;\n if (this.shouldGenerateThumbnail(imageOptions)) {\n thumbnailPath = await this.generateThumbnail(inputPath, outputPath, imageOptions);\n }\n\n const processingTime = Date.now() - startTime;\n logger.info('✅ [ImageProcessor] 图片处理完成: ' + (outputPath) + ', 耗时: ' + (processingTime) + 'ms');\n\n return {\n success: true,\n processedPath: outputPath,\n processedSize: info.size,\n thumbnailPath,\n processingTime,\n data: {\n originalSize: (await fs.stat(inputPath)).size,\n processedSize: info.size,\n compressionRatio:\n ((await fs.stat(inputPath)).size - info.size) / (await fs.stat(inputPath)).size,\n dimensions: {\n original: { width: metadata.width, height: metadata.height },\n processed: { width: info.width, height: info.height },\n },\n format: {\n original: metadata.format,\n processed: outputFormat,\n },\n },\n };\n } catch (error) {\n console.error('❌ [ImageProcessor] 图片处理失败: ' + (inputPath) + ':', error);\n\n return {\n success: false,\n error: '图片处理失败: ' + (error instanceof Error ? error.message : '未知错误'),\n processingTime: Date.now() - startTime,\n };\n }\n }\n\n /**\n * 检查文件是否支持处理\n */\n supports(mimeType: string): boolean {\n const supportedTypes = [\n 'image/jpeg',\n 'image/jpg',\n 'image/png',\n 'image/webp',\n 'image/avif',\n 'image/gif',\n 'image/tiff',\n 'image/bmp',\n ];\n\n return supportedTypes.includes(mimeType.toLowerCase());\n }\n\n /**\n * 获取图片文件信息\n */\n async getFileInfo(filePath: string): Promise<Record<string, any>> {\n this.ensureInitialized();\n\n try {\n const metadata = await this.getImageMetadata(filePath);\n const stats = await fs.stat(filePath);\n\n return {\n dimensions: {\n width: metadata.width,\n height: metadata.height,\n },\n format: metadata.format,\n channels: metadata.channels,\n hasAlpha: metadata.hasAlpha,\n density: metadata.density,\n orientation: metadata.orientation,\n fileSize: stats.size,\n aspectRatio: metadata.width / metadata.height,\n megapixels: (metadata.width * metadata.height) / 1000000,\n };\n } catch (error) {\n console.error('❌ [ImageProcessor] 获取图片信息失败: ' + (filePath) + ':', error);\n throw error;\n }\n }\n\n // ============= 私有方法 =============\n\n /**\n * 确保处理器已初始化\n */\n private ensureInitialized(): void {\n if (!this.isInitialized || !this.sharp) {\n throw new Error('图片处理器未初始化');\n }\n }\n\n /**\n * 获取图片元数据\n */\n private async getImageMetadata(filePath: string): Promise<ImageMetadata> {\n try {\n const metadata = await this.sharp(filePath).metadata();\n\n return {\n format: metadata.format || 'unknown',\n width: metadata.width || 0,\n height: metadata.height || 0,\n channels: metadata.channels || 3,\n density: metadata.density || 72,\n hasAlpha: metadata.hasAlpha || false,\n orientation: metadata.orientation,\n };\n } catch (error) {\n console.error('❌ [ImageProcessor] 获取图片元数据失败: ' + (filePath) + ':', error);\n throw new Error('无法读取图片元数据: ' + (error instanceof Error ? error.message : '未知错误'));\n }\n }\n\n /**\n * 应用图片处理操作\n */\n private async applyImageOperations(\n sharpInstance: any,\n options: ImageProcessingOptions\n ): Promise<any> {\n // 调整尺寸\n if (options.width || options.height) {\n const resizeOptions: any = {\n width: options.width,\n height: options.height,\n fit: 'inside', // 保持纵横比\n withoutEnlargement: true, // 不放大小图片\n };\n\n sharpInstance = sharpInstance.resize(resizeOptions);\n logger.info(\n '🔧 [ImageProcessor] 应用尺寸调整: ' + (options.width || 'auto') + 'x' + (options.height || 'auto')\n );\n }\n\n // 旋转和翻转(基于EXIF方向信息)\n sharpInstance = sharpInstance.rotate();\n\n // 添加水印\n if (options.watermark && options.watermarkOptions) {\n sharpInstance = await this.applyWatermark(sharpInstance, options.watermarkOptions);\n }\n\n return sharpInstance;\n }\n\n /**\n * 应用水印\n */\n private async applyWatermark(\n sharpInstance: any,\n watermarkOptions: NonNullable<ImageProcessingOptions['watermarkOptions']>\n ): Promise<any> {\n try {\n if (watermarkOptions.text) {\n // 文字水印\n logger.info('💧 [ImageProcessor] 应用文字水印: ' + (watermarkOptions.text));\n\n // 创建文字水印SVG\n const textSvg = this.createTextWatermarkSvg(\n watermarkOptions.text,\n watermarkOptions.opacity || 0.5\n );\n\n const textBuffer = Buffer.from(textSvg);\n\n sharpInstance = sharpInstance.composite([\n {\n input: textBuffer,\n gravity: this.getWatermarkGravity(watermarkOptions.position || 'bottom-right'),\n },\n ]);\n } else if (watermarkOptions.image && existsSync(watermarkOptions.image)) {\n // 图片水印\n logger.info('💧 [ImageProcessor] 应用图片水印: ' + (watermarkOptions.image));\n\n let watermarkBuffer = await fs.readFile(watermarkOptions.image);\n\n // 调整水印透明度\n if (watermarkOptions.opacity && watermarkOptions.opacity < 1) {\n const watermarkSharp = this.sharp(watermarkBuffer)\n .png()\n .modulate({ brightness: 1, saturation: 1, alpha: watermarkOptions.opacity });\n watermarkBuffer = await watermarkSharp.toBuffer();\n }\n\n sharpInstance = sharpInstance.composite([\n {\n input: watermarkBuffer,\n gravity: this.getWatermarkGravity(watermarkOptions.position || 'bottom-right'),\n },\n ]);\n }\n\n return sharpInstance;\n } catch (error) {\n console.warn(`⚠️ [ImageProcessor] 水印应用失败,跳过水印:`, error);\n return sharpInstance;\n }\n }\n\n /**\n * 创建文字水印SVG\n */\n private createTextWatermarkSvg(text: string, opacity: number): string {\n const fontSize = 24;\n const padding = 10;\n\n return `<svg width=\"200\" height=\"50\" xmlns=\"http://www.w3.org/2000/svg\">\n <text\n x=\"${padding}\"\n y=\"${fontSize + padding}\"\n font-family=\"Arial, sans-serif\"\n font-size=\"${fontSize}\"\n fill=\"white\"\n fill-opacity=\"${opacity}\"\n stroke=\"black\"\n stroke-width=\"1\"\n stroke-opacity=\"${opacity * 0.8}\"\n >\n ${text}\n </text>\n </svg>`.trim();\n }\n\n /**\n * 获取水印位置对应的gravity值\n */\n private getWatermarkGravity(position: string): string {\n const gravityMap: Record<string, string> = {\n 'top-left': 'northwest',\n 'top-right': 'northeast',\n 'bottom-left': 'southwest',\n 'bottom-right': 'southeast',\n center: 'center',\n };\n\n return gravityMap[position] || 'southeast';\n }\n\n /**\n * 确定输出格式\n */\n private determineOutputFormat(\n outputPath: string,\n requestedFormat?: ImageProcessingOptions['format']\n ): string {\n if (requestedFormat) {\n return requestedFormat;\n }\n\n const ext = path.extname(outputPath).toLowerCase();\n const formatMap: Record<string, string> = {\n '.jpg': 'jpeg',\n '.jpeg': 'jpeg',\n '.png': 'png',\n '.webp': 'webp',\n '.avif': 'avif',\n };\n\n return formatMap[ext] || 'jpeg';\n }\n\n /**\n * 应用输出设置\n */\n private applyOutputSettings(sharpInstance: any, format: string, quality?: number): any {\n const defaultQuality = 80;\n const finalQuality = quality || defaultQuality;\n\n switch (format) {\n case 'jpeg':\n return sharpInstance.jpeg({\n quality: finalQuality,\n progressive: true,\n mozjpeg: true,\n });\n\n case 'png':\n return sharpInstance.png({\n quality: finalQuality,\n progressive: true,\n compressionLevel: 6,\n });\n\n case 'webp':\n return sharpInstance.webp({\n quality: finalQuality,\n effort: 4,\n });\n\n case 'avif':\n return sharpInstance.avif({\n quality: finalQuality,\n effort: 4,\n });\n\n default:\n return sharpInstance.jpeg({ quality: finalQuality });\n }\n }\n\n /**\n * 是否需要生成缩略图\n */\n private shouldGenerateThumbnail(options: ImageProcessingOptions): boolean {\n // 如果明确设置了尺寸且尺寸较小,可能不需要缩略图\n const isSmallImage =\n (options.width && options.width <= 300) || (options.height && options.height <= 300);\n\n return !isSmallImage;\n }\n\n /**\n * 生成缩略图\n */\n private async generateThumbnail(\n inputPath: string,\n outputPath: string,\n _options: ImageProcessingOptions\n ): Promise<string> {\n try {\n const thumbnailPath = this.getThumbnailPath(outputPath);\n const thumbnailSize = 200; // 缩略图固定尺寸\n\n await this.sharp(inputPath)\n .resize({\n width: thumbnailSize,\n height: thumbnailSize,\n fit: 'cover',\n position: 'center',\n })\n .jpeg({ quality: 70 })\n .toFile(thumbnailPath);\n\n logger.info('🖼️ [ImageProcessor] 缩略图生成完成: ' + (thumbnailPath));\n\n return thumbnailPath;\n } catch (error) {\n console.warn(`⚠️ [ImageProcessor] 缩略图生成失败:`, error);\n throw error;\n }\n }\n\n /**\n * 获取缩略图路径\n */\n private getThumbnailPath(originalPath: string): string {\n const ext = path.extname(originalPath);\n const basePath = originalPath.replace(ext, '');\n return (basePath) + '_thumb' + (ext);\n }\n\n /**\n * 创建模拟Sharp对象(开发测试用)\n */\n private createMockSharp(): any {\n logger.info('🧪 [ImageProcessor] 创建模拟Sharp处理器');\n\n const mockSharp = (input: string) => {\n logger.info('🧪 [MockSharp] 处理图片: ' + (input));\n\n return {\n metadata: async () => ({\n format: 'jpeg',\n width: 1920,\n height: 1080,\n channels: 3,\n density: 72,\n hasAlpha: false,\n }),\n\n resize: (options: any) => {\n logger.info(`🧪 [MockSharp] 调整尺寸:`, options);\n return mockSharp(input);\n },\n\n rotate: () => {\n logger.info(`🧪 [MockSharp] 自动旋转`);\n return mockSharp(input);\n },\n\n composite: (operations: any[]) => {\n logger.info(`🧪 [MockSharp] 合成操作:`, operations.length);\n return mockSharp(input);\n },\n\n jpeg: (options: any) => {\n logger.info(`🧪 [MockSharp] JPEG输出:`, options);\n return mockSharp(input);\n },\n\n png: (options: any) => {\n logger.info(`🧪 [MockSharp] PNG输出:`, options);\n return mockSharp(input);\n },\n\n webp: (options: any) => {\n logger.info(`🧪 [MockSharp] WebP输出:`, options);\n return mockSharp(input);\n },\n\n avif: (options: any) => {\n logger.info(`🧪 [MockSharp] AVIF输出:`, options);\n return mockSharp(input);\n },\n\n toFile: async (outputPath: string) => {\n logger.info('🧪 [MockSharp] 保存到文件: ' + (outputPath));\n\n // 创建一个模拟的输出文件\n const outputDir = path.dirname(outputPath);\n await fs.mkdir(outputDir, { recursive: true });\n await fs.writeFile(outputPath, 'Mock processed image from ' + (input));\n\n return {\n format: 'jpeg',\n width: 800,\n height: 600,\n channels: 3,\n premultiplied: false,\n size: 1024 * 50, // 50KB\n };\n },\n\n toBuffer: async () => {\n logger.info(`🧪 [MockSharp] 转换为Buffer`);\n return Buffer.from('Mock image buffer');\n },\n };\n };\n\n return mockSharp;\n }\n\n /**\n * 批量图片处理\n */\n async batchProcess(\n inputPaths: string[],\n outputDir: string,\n options: ImageProcessingOptions,\n onProgress?: (completed: number, total: number) => void\n ): Promise<ProcessingResult[]> {\n this.ensureInitialized();\n\n logger.info('🖼️ [ImageProcessor] 开始批量处理 ' + (inputPaths.length) + ' 张图片');\n\n const results: ProcessingResult[] = [];\n\n for (let i = 0; i < inputPaths.length; i++) {\n const inputPath = inputPaths[i]!;\n const fileName = path.basename(inputPath);\n const outputPath = path.join(outputDir, fileName);\n\n try {\n const result = await this.process(inputPath, outputPath, options);\n results.push(result);\n\n if (onProgress) {\n onProgress(i + 1, inputPaths.length);\n }\n } catch (error) {\n console.error('❌ [ImageProcessor] 批量处理失败: ' + (inputPath) + ':', error);\n results.push({\n success: false,\n error: '处理失败: ' + (error instanceof Error ? error.message : '未知错误'),\n });\n }\n }\n\n const successCount = results.filter((r) => r.success).length;\n logger.info('✅ [ImageProcessor] 批量处理完成,成功: ' + (successCount) + '/' + (inputPaths.length));\n\n return results;\n }\n}\n","/**\n * 音频处理器实现\n * 支持格式转换、压缩、音质调整等功能\n */\n\nimport * as path from 'path';\nimport { promises as fs } from 'fs';\nimport { existsSync } from 'fs';\nimport { createLogger } from '../../../logger';\n\n\nimport type {\n IFileProcessor,\n ProcessorType,\n ProcessingOptions,\n ProcessingResult,\n} from '../types';\n\nimport type { AudioProcessingOptions } from '../../types';\n\nconst logger = createLogger('AudioProcessor');\n\n// 音频处理相关类型定义\ninterface AudioMetadata {\n format: string;\n duration: number;\n bitrate: number;\n sampleRate: number;\n channels: number;\n codec: string;\n size: number;\n}\n\n/**\n * 音频处理器\n * 使用FFmpeg进行音频处理\n */\nexport class AudioProcessor implements IFileProcessor {\n readonly type: ProcessorType = 'audio';\n\n private ffmpeg: any = null;\n private isInitialized = false;\n\n /**\n * 初始化音频处理器\n */\n async initialize(): Promise<void> {\n logger.info('🎵 [AudioProcessor] 初始化音频处理器...');\n\n try {\n // 尝试加载FFmpeg库\n try {\n this.ffmpeg = require('fluent-ffmpeg');\n logger.info('✅ [AudioProcessor] FFmpeg库加载成功');\n } catch (error) {\n console.warn('⚠️ [AudioProcessor] FFmpeg库未安装,使用模拟模式');\n // 创建模拟FFmpeg对象\n this.ffmpeg = this.createMockFFmpeg();\n }\n\n this.isInitialized = true;\n logger.info('✅ [AudioProcessor] 音频处理器初始化完成');\n } catch (error) {\n console.error('❌ [AudioProcessor] 音频处理器初始化失败:', error);\n throw error;\n }\n }\n\n /**\n * 处理音频文件\n */\n async process(\n inputPath: string,\n outputPath: string,\n options: ProcessingOptions\n ): Promise<ProcessingResult> {\n this.ensureInitialized();\n\n if (options.type !== 'audio') {\n throw new Error('处理选项类型不匹配:期望 audio');\n }\n\n const audioOptions = options as AudioProcessingOptions;\n const startTime = Date.now();\n\n logger.info('🎵 [AudioProcessor] 开始处理音频: ' + (inputPath));\n\n try {\n // 检查输入文件是否存在\n if (!existsSync(inputPath)) {\n throw new Error('输入文件不存在: ' + (inputPath));\n }\n\n // 确保输出目录存在\n const outputDir = path.dirname(outputPath);\n await fs.mkdir(outputDir, { recursive: true });\n\n // 获取音频元数据\n const metadata = await this.getAudioMetadata(inputPath);\n logger.info(\n '📊 [AudioProcessor] 音频信息: ' + (this.formatDuration(metadata.duration)) + ', ' + (metadata.bitrate) + 'kbps, ' + (metadata.sampleRate) + 'Hz'\n );\n\n // 确定输出格式\n const outputFormat = this.determineOutputFormat(outputPath, audioOptions.format);\n\n // 执行音频处理\n await this.processAudio(inputPath, outputPath, audioOptions, outputFormat);\n\n // 获取处理后的文件信息\n const processedStats = await fs.stat(outputPath);\n const processingTime = Date.now() - startTime;\n\n logger.info('✅ [AudioProcessor] 音频处理完成: ' + (outputPath) + ', 耗时: ' + (processingTime) + 'ms');\n\n return {\n success: true,\n processedPath: outputPath,\n processedSize: processedStats.size,\n processingTime,\n data: {\n originalSize: metadata.size,\n processedSize: processedStats.size,\n compressionRatio: (metadata.size - processedStats.size) / metadata.size,\n duration: metadata.duration,\n originalFormat: metadata.format,\n processedFormat: outputFormat,\n originalBitrate: metadata.bitrate,\n processedBitrate: audioOptions.bitrate || metadata.bitrate,\n sampleRate: audioOptions.sampleRate || metadata.sampleRate,\n channels: audioOptions.channels || metadata.channels,\n },\n };\n } catch (error) {\n console.error('❌ [AudioProcessor] 音频处理失败: ' + (inputPath) + ':', error);\n\n return {\n success: false,\n error: '音频处理失败: ' + (error instanceof Error ? error.message : '未知错误'),\n processingTime: Date.now() - startTime,\n };\n }\n }\n\n /**\n * 检查文件是否支持处理\n */\n supports(mimeType: string): boolean {\n const supportedTypes = [\n 'audio/mpeg',\n 'audio/mp3',\n 'audio/wav',\n 'audio/wave',\n 'audio/x-wav',\n 'audio/ogg',\n 'audio/vorbis',\n 'audio/aac',\n 'audio/x-aac',\n 'audio/mp4',\n 'audio/m4a',\n 'audio/flac',\n 'audio/x-flac',\n 'audio/webm',\n 'audio/opus',\n ];\n\n return supportedTypes.includes(mimeType.toLowerCase());\n }\n\n /**\n * 获取音频文件信息\n */\n async getFileInfo(filePath: string): Promise<Record<string, any>> {\n this.ensureInitialized();\n\n try {\n const metadata = await this.getAudioMetadata(filePath);\n\n return {\n duration: metadata.duration,\n durationFormatted: this.formatDuration(metadata.duration),\n bitrate: metadata.bitrate,\n sampleRate: metadata.sampleRate,\n channels: metadata.channels,\n channelsDescription: this.getChannelsDescription(metadata.channels),\n format: metadata.format,\n codec: metadata.codec,\n fileSize: metadata.size,\n quality: this.getQualityDescription(metadata.bitrate, metadata.sampleRate),\n };\n } catch (error) {\n console.error('❌ [AudioProcessor] 获取音频信息失败: ' + (filePath) + ':', error);\n throw error;\n }\n }\n\n // ============= 私有方法 =============\n\n /**\n * 确保处理器已初始化\n */\n private ensureInitialized(): void {\n if (!this.isInitialized || !this.ffmpeg) {\n throw new Error('音频处理器未初始化');\n }\n }\n\n /**\n * 获取音频元数据\n */\n private async getAudioMetadata(filePath: string): Promise<AudioMetadata> {\n return new Promise((resolve, reject) => {\n try {\n this.ffmpeg.ffprobe(filePath, (err: any, metadata: any) => {\n if (err) {\n console.error('❌ [AudioProcessor] 获取音频元数据失败: ' + (filePath) + ':', err);\n reject(new Error('无法读取音频元数据: ' + (err.message)));\n return;\n }\n\n const audioStream = metadata.streams?.find(\n (stream: any) => stream.codec_type === 'audio'\n );\n if (!audioStream) {\n reject(new Error('文件中未找到音频流'));\n return;\n }\n\n const result: AudioMetadata = {\n format: metadata.format?.format_name || 'unknown',\n duration: parseFloat(metadata.format?.duration || '0'),\n bitrate: parseInt(audioStream.bit_rate || '0') / 1000, // 转换为kbps\n sampleRate: parseInt(audioStream.sample_rate || '0'),\n channels: parseInt(audioStream.channels || '0'),\n codec: audioStream.codec_name || 'unknown',\n size: parseInt(metadata.format?.size || '0'),\n };\n\n resolve(result);\n });\n } catch (error) {\n reject(error);\n }\n });\n }\n\n /**\n * 执行音频处理\n */\n private async processAudio(\n inputPath: string,\n outputPath: string,\n options: AudioProcessingOptions,\n outputFormat: string\n ): Promise<void> {\n return new Promise((resolve, reject) => {\n try {\n let command = this.ffmpeg(inputPath);\n\n // 设置音频编解码器\n command = this.setAudioCodec(command, outputFormat);\n\n // 设置比特率\n if (options.bitrate) {\n command = command.audioBitrate(options.bitrate);\n logger.info('🔧 [AudioProcessor] 设置比特率: ' + (options.bitrate) + 'kbps');\n }\n\n // 设置采样率\n if (options.sampleRate) {\n command = command.audioFrequency(options.sampleRate);\n logger.info('🔧 [AudioProcessor] 设置采样率: ' + (options.sampleRate) + 'Hz');\n }\n\n // 设置声道数\n if (options.channels) {\n command = command.audioChannels(options.channels);\n logger.info('🔧 [AudioProcessor] 设置声道数: ' + (options.channels));\n }\n\n // 设置输出格式\n command = command.format(outputFormat);\n\n // 添加进度监听\n command.on('progress', (progress: any) => {\n if (progress.percent) {\n logger.info('🎵 [AudioProcessor] 处理进度: ' + (Math.round(progress.percent)) + '%');\n }\n });\n\n // 添加错误监听\n command.on('error', (err: any) => {\n console.error(`❌ [AudioProcessor] FFmpeg处理错误:`, err);\n reject(new Error('音频处理失败: ' + (err.message)));\n });\n\n // 添加完成监听\n command.on('end', () => {\n logger.info('✅ [AudioProcessor] FFmpeg处理完成: ' + (outputPath));\n resolve();\n });\n\n // 开始处理\n command.save(outputPath);\n } catch (error) {\n reject(error);\n }\n });\n }\n\n /**\n * 设置音频编解码器\n */\n private setAudioCodec(command: any, format: string): any {\n switch (format) {\n case 'mp3':\n return command.audioCodec('libmp3lame');\n case 'aac':\n return command.audioCodec('aac');\n case 'ogg':\n return command.audioCodec('libvorbis');\n case 'wav':\n return command.audioCodec('pcm_s16le');\n default:\n return command;\n }\n }\n\n /**\n * 确定输出格式\n */\n private determineOutputFormat(\n outputPath: string,\n requestedFormat?: AudioProcessingOptions['format']\n ): string {\n if (requestedFormat) {\n return requestedFormat;\n }\n\n const ext = path.extname(outputPath).toLowerCase();\n const formatMap: Record<string, string> = {\n '.mp3': 'mp3',\n '.wav': 'wav',\n '.ogg': 'ogg',\n '.aac': 'aac',\n '.m4a': 'aac',\n };\n\n return formatMap[ext] || 'mp3';\n }\n\n /**\n * 格式化时长显示\n */\n private formatDuration(seconds: number): string {\n const minutes = Math.floor(seconds / 60);\n const remainingSeconds = Math.floor(seconds % 60);\n return (minutes) + ':' + (remainingSeconds.toString().padStart(2, '0'));\n }\n\n /**\n * 获取声道描述\n */\n private getChannelsDescription(channels: number): string {\n switch (channels) {\n case 1:\n return '单声道';\n case 2:\n return '立体声';\n case 6:\n return '5.1环绕声';\n case 8:\n return '7.1环绕声';\n default:\n return (channels) + '声道';\n }\n }\n\n /**\n * 获取音质描述\n */\n private getQualityDescription(bitrate: number, sampleRate: number): string {\n if (bitrate >= 320 && sampleRate >= 44100) {\n return '高音质';\n } else if (bitrate >= 192 && sampleRate >= 44100) {\n return '标准音质';\n } else if (bitrate >= 128) {\n return '一般音质';\n } else {\n return '低音质';\n }\n }\n\n /**\n * 创建模拟FFmpeg对象(开发测试用)\n */\n private createMockFFmpeg(): any {\n logger.info('🧪 [AudioProcessor] 创建模拟FFmpeg处理器');\n\n const mockFFmpeg = (input: string) => {\n logger.info('🧪 [MockFFmpeg] 处理音频: ' + (input));\n\n return {\n audioBitrate: (bitrate: number) => {\n logger.info('🧪 [MockFFmpeg] 设置比特率: ' + (bitrate) + 'kbps');\n return mockFFmpeg(input);\n },\n\n audioFrequency: (sampleRate: number) => {\n logger.info('🧪 [MockFFmpeg] 设置采样率: ' + (sampleRate) + 'Hz');\n return mockFFmpeg(input);\n },\n\n audioChannels: (channels: number) => {\n logger.info('🧪 [MockFFmpeg] 设置声道数: ' + (channels));\n return mockFFmpeg(input);\n },\n\n audioCodec: (codec: string) => {\n logger.info('🧪 [MockFFmpeg] 设置编解码器: ' + (codec));\n return mockFFmpeg(input);\n },\n\n format: (format: string) => {\n logger.info('🧪 [MockFFmpeg] 设置输出格式: ' + (format));\n return mockFFmpeg(input);\n },\n\n on: (event: string, callback: Function) => {\n logger.info('🧪 [MockFFmpeg] 注册事件监听: ' + (event));\n\n if (event === 'progress') {\n // 模拟进度更新\n setTimeout(() => callback({ percent: 50 }), 100);\n setTimeout(() => callback({ percent: 100 }), 200);\n } else if (event === 'end') {\n // 模拟处理完成\n setTimeout(() => callback(), 300);\n }\n\n return mockFFmpeg(input);\n },\n\n save: async (outputPath: string) => {\n logger.info('🧪 [MockFFmpeg] 保存音频文件: ' + (outputPath));\n\n // 创建模拟输出文件\n const outputDir = path.dirname(outputPath);\n await fs.mkdir(outputDir, { recursive: true });\n await fs.writeFile(outputPath, 'Mock processed audio from ' + (input));\n },\n };\n };\n\n // 添加ffprobe方法\n mockFFmpeg.ffprobe = (filePath: string, callback: Function) => {\n logger.info('🧪 [MockFFmpeg] 获取音频元数据: ' + (filePath));\n\n setTimeout(() => {\n const mockMetadata = {\n streams: [\n {\n codec_type: 'audio',\n codec_name: 'mp3',\n bit_rate: '128000',\n sample_rate: '44100',\n channels: '2',\n },\n ],\n format: {\n format_name: 'mp3',\n duration: '180.5',\n size: '1024000',\n },\n };\n\n callback(null, mockMetadata);\n }, 100);\n };\n\n return mockFFmpeg;\n }\n\n /**\n * 批量音频处理\n */\n async batchProcess(\n inputPaths: string[],\n outputDir: string,\n options: AudioProcessingOptions,\n onProgress?: (completed: number, total: number) => void\n ): Promise<ProcessingResult[]> {\n this.ensureInitialized();\n\n logger.info('🎵 [AudioProcessor] 开始批量处理 ' + (inputPaths.length) + ' 个音频文件');\n\n const results: ProcessingResult[] = [];\n\n for (let i = 0; i < inputPaths.length; i++) {\n const inputPath = inputPaths[i]!;\n const fileName = path.basename(inputPath);\n const nameWithoutExt = path.parse(fileName).name;\n const outputFormat = options.format || 'mp3';\n const outputPath = path.join(outputDir, (nameWithoutExt) + '.' + (outputFormat));\n\n try {\n const result = await this.process(inputPath, outputPath, options);\n results.push(result);\n\n if (onProgress) {\n onProgress(i + 1, inputPaths.length);\n }\n } catch (error) {\n console.error('❌ [AudioProcessor] 批量处理失败: ' + (inputPath) + ':', error);\n results.push({\n success: false,\n error: '处理失败: ' + (error instanceof Error ? error.message : '未知错误'),\n });\n }\n }\n\n const successCount = results.filter((r) => r.success).length;\n logger.info('✅ [AudioProcessor] 批量处理完成,成功: ' + (successCount) + '/' + (inputPaths.length));\n\n return results;\n }\n\n /**\n * 提取音频封面\n */\n async extractCover(inputPath: string, outputPath: string): Promise<boolean> {\n this.ensureInitialized();\n\n return new Promise((resolve) => {\n try {\n this.ffmpeg(inputPath)\n .outputOptions(['-an', '-vcodec copy'])\n .on('error', (err: any) => {\n console.warn('⚠️ [AudioProcessor] 提取封面失败: ' + (err.message));\n resolve(false);\n })\n .on('end', () => {\n logger.info('🖼️ [AudioProcessor] 音频封面提取完成: ' + (outputPath));\n resolve(true);\n })\n .save(outputPath);\n } catch (error) {\n console.warn(`⚠️ [AudioProcessor] 提取封面异常:`, error);\n resolve(false);\n }\n });\n }\n\n /**\n * 音频降噪处理\n */\n async denoise(inputPath: string, outputPath: string): Promise<ProcessingResult> {\n this.ensureInitialized();\n\n const startTime = Date.now();\n logger.info('🔇 [AudioProcessor] 开始音频降噪: ' + (inputPath));\n\n return new Promise((resolve) => {\n try {\n this.ffmpeg(inputPath)\n .audioFilters('highpass=f=200,lowpass=f=3000')\n .on('error', (err: any) => {\n resolve({\n success: false,\n error: '降噪处理失败: ' + (err.message),\n processingTime: Date.now() - startTime,\n });\n })\n .on('end', async () => {\n const processedStats = await fs.stat(outputPath);\n\n resolve({\n success: true,\n processedPath: outputPath,\n processedSize: processedStats.size,\n processingTime: Date.now() - startTime,\n data: {\n operation: 'denoise',\n filters: 'highpass=f=200,lowpass=f=3000',\n },\n });\n })\n .save(outputPath);\n } catch (error) {\n resolve({\n success: false,\n error: '降噪处理异常: ' + (error instanceof Error ? error.message : '未知错误'),\n processingTime: Date.now() - startTime,\n });\n }\n });\n }\n}\n","/**\n * 视频处理器实现\n * 支持缩略图生成、格式转换、压缩等功能\n */\n\nimport * as path from 'path';\nimport { promises as fs } from 'fs';\nimport { existsSync } from 'fs';\nimport { createLogger } from '../../../logger';\n\nimport type {\n IFileProcessor,\n ProcessorType,\n ProcessingOptions,\n ProcessingResult,\n} from '../types';\n\nimport type { VideoProcessingOptions } from '../../types';\n\nconst logger = createLogger('VideoProcessor');\n\n// 视频处理相关类型定义\ninterface VideoMetadata {\n format: string;\n duration: number;\n bitrate: number;\n width: number;\n height: number;\n fps: number;\n codec: string;\n size: number;\n aspectRatio: number;\n}\n\n/**\n * 视频处理器\n * 使用FFmpeg进行视频处理\n */\nexport class VideoProcessor implements IFileProcessor {\n readonly type: ProcessorType = 'video';\n\n private ffmpeg: any = null;\n private isInitialized = false;\n\n /**\n * 初始化视频处理器\n */\n async initialize(): Promise<void> {\n logger.info('🎬 [VideoProcessor] 初始化视频处理器...');\n\n try {\n // 尝试加载FFmpeg库\n try {\n this.ffmpeg = require('fluent-ffmpeg');\n logger.info('✅ [VideoProcessor] FFmpeg库加载成功');\n } catch (error) {\n console.warn('⚠️ [VideoProcessor] FFmpeg库未安装,使用模拟模式');\n // 创建模拟FFmpeg对象\n this.ffmpeg = this.createMockFFmpeg();\n }\n\n this.isInitialized = true;\n logger.info('✅ [VideoProcessor] 视频处理器初始化完成');\n } catch (error) {\n console.error('❌ [VideoProcessor] 视频处理器初始化失败:', error);\n throw error;\n }\n }\n\n /**\n * 处理视频文件\n */\n async process(\n inputPath: string,\n outputPath: string,\n options: ProcessingOptions\n ): Promise<ProcessingResult> {\n this.ensureInitialized();\n\n if (options.type !== 'video') {\n throw new Error('处理选项类型不匹配:期望 video');\n }\n\n const videoOptions = options as VideoProcessingOptions;\n const startTime = Date.now();\n\n logger.info('🎬 [VideoProcessor] 开始处理视频: ' + (inputPath));\n\n try {\n // 检查输入文件是否存在\n if (!existsSync(inputPath)) {\n throw new Error('输入文件不存在: ' + (inputPath));\n }\n\n // 确保输出目录存在\n const outputDir = path.dirname(outputPath);\n await fs.mkdir(outputDir, { recursive: true });\n\n // 获取视频元数据\n const metadata = await this.getVideoMetadata(inputPath);\n logger.info(\n '📊 [VideoProcessor] 视频信息: ' + (metadata.width) + 'x' + (metadata.height) + ', ' + (this.formatDuration(metadata.duration)) + ', ' + (metadata.fps) + 'fps'\n );\n\n // 确定输出格式\n const outputFormat = this.determineOutputFormat(outputPath, videoOptions.format);\n\n // 执行视频处理\n await this.processVideo(inputPath, outputPath, videoOptions, outputFormat);\n\n // 生成缩略图(如果需要)\n let thumbnailPath: string | undefined;\n if (videoOptions.generateThumbnail !== false) {\n thumbnailPath = await this.generateThumbnail(\n inputPath,\n outputPath,\n videoOptions.thumbnailTime || 1\n );\n }\n\n // 获取处理后的文件信息\n const processedStats = await fs.stat(outputPath);\n const processingTime = Date.now() - startTime;\n\n logger.info('✅ [VideoProcessor] 视频处理完成: ' + (outputPath) + ', 耗时: ' + (processingTime) + 'ms');\n\n return {\n success: true,\n processedPath: outputPath,\n processedSize: processedStats.size,\n thumbnailPath,\n processingTime,\n data: {\n originalSize: metadata.size,\n processedSize: processedStats.size,\n compressionRatio: (metadata.size - processedStats.size) / metadata.size,\n duration: metadata.duration,\n originalFormat: metadata.format,\n processedFormat: outputFormat,\n dimensions: {\n original: { width: metadata.width, height: metadata.height },\n processed: { width: metadata.width, height: metadata.height }, // 处理后可能会变化\n },\n fps: metadata.fps,\n bitrate: metadata.bitrate,\n },\n };\n } catch (error) {\n console.error('❌ [VideoProcessor] 视频处理失败: ' + (inputPath) + ':', error);\n\n return {\n success: false,\n error: '视频处理失败: ' + (error instanceof Error ? error.message : '未知错误'),\n processingTime: Date.now() - startTime,\n };\n }\n }\n\n /**\n * 检查文件是否支持处理\n */\n supports(mimeType: string): boolean {\n const supportedTypes = [\n 'video/mp4',\n 'video/x-msvideo', // avi\n 'video/quicktime', // mov\n 'video/x-ms-wmv', // wmv\n 'video/webm',\n 'video/ogg',\n 'video/3gpp', // 3gp\n 'video/x-flv', // flv\n 'video/x-matroska', // mkv\n ];\n\n return supportedTypes.includes(mimeType.toLowerCase());\n }\n\n /**\n * 获取视频文件信息\n */\n async getFileInfo(filePath: string): Promise<Record<string, any>> {\n this.ensureInitialized();\n\n try {\n const metadata = await this.getVideoMetadata(filePath);\n\n return {\n duration: metadata.duration,\n durationFormatted: this.formatDuration(metadata.duration),\n dimensions: {\n width: metadata.width,\n height: metadata.height,\n },\n resolution: this.getResolutionDescription(metadata.width, metadata.height),\n aspectRatio: metadata.aspectRatio,\n fps: metadata.fps,\n bitrate: metadata.bitrate,\n format: metadata.format,\n codec: metadata.codec,\n fileSize: metadata.size,\n quality: this.getQualityDescription(metadata.width, metadata.height, metadata.bitrate),\n };\n } catch (error) {\n console.error('❌ [VideoProcessor] 获取视频信息失败: ' + (filePath) + ':', error);\n throw error;\n }\n }\n\n // ============= 私有方法 =============\n\n /**\n * 确保处理器已初始化\n */\n private ensureInitialized(): void {\n if (!this.isInitialized || !this.ffmpeg) {\n throw new Error('视频处理器未初始化');\n }\n }\n\n /**\n * 获取视频元数据\n */\n private async getVideoMetadata(filePath: string): Promise<VideoMetadata> {\n return new Promise((resolve, reject) => {\n try {\n this.ffmpeg.ffprobe(filePath, (err: any, metadata: any) => {\n if (err) {\n console.error('❌ [VideoProcessor] 获取视频元数据失败: ' + (filePath) + ':', err);\n reject(new Error('无法读取视频元数据: ' + (err.message)));\n return;\n }\n\n const videoStream = metadata.streams?.find(\n (stream: any) => stream.codec_type === 'video'\n );\n if (!videoStream) {\n reject(new Error('文件中未找到视频流'));\n return;\n }\n\n const width = parseInt(videoStream.width || '0');\n const height = parseInt(videoStream.height || '0');\n\n const result: VideoMetadata = {\n format: metadata.format?.format_name || 'unknown',\n duration: parseFloat(metadata.format?.duration || '0'),\n bitrate: parseInt(metadata.format?.bit_rate || '0') / 1000, // 转换为kbps\n width,\n height,\n fps: this.parseFPS(videoStream.r_frame_rate || '0/1'),\n codec: videoStream.codec_name || 'unknown',\n size: parseInt(metadata.format?.size || '0'),\n aspectRatio: width > 0 && height > 0 ? width / height : 16 / 9,\n };\n\n resolve(result);\n });\n } catch (error) {\n reject(error);\n }\n });\n }\n\n /**\n * 解析帧率\n */\n private parseFPS(frameRate: string): number {\n const parts = frameRate.split('/').map(Number);\n const numerator = parts[0] || 0;\n const denominator = parts[1] || 1;\n return denominator > 0 ? numerator / denominator : 0;\n }\n\n /**\n * 执行视频处理\n */\n private async processVideo(\n inputPath: string,\n outputPath: string,\n options: VideoProcessingOptions,\n outputFormat: string\n ): Promise<void> {\n return new Promise((resolve, reject) => {\n try {\n let command = this.ffmpeg(inputPath);\n\n // 设置视频编解码器\n command = this.setVideoCodec(command, outputFormat);\n\n // 设置质量\n if (options.quality) {\n command = this.setVideoQuality(command, options.quality);\n logger.info('🔧 [VideoProcessor] 设置视频质量: ' + (options.quality));\n }\n\n // 设置输出格式\n command = command.format(outputFormat);\n\n // 添加进度监听\n command.on('progress', (progress: any) => {\n if (progress.percent) {\n logger.info('🎬 [VideoProcessor] 处理进度: ' + (Math.round(progress.percent)) + '%');\n }\n });\n\n // 添加错误监听\n command.on('error', (err: any) => {\n console.error(`❌ [VideoProcessor] FFmpeg处理错误:`, err);\n reject(new Error('视频处理失败: ' + (err.message)));\n });\n\n // 添加完成监听\n command.on('end', () => {\n logger.info('✅ [VideoProcessor] FFmpeg处理完成: ' + (outputPath));\n resolve();\n });\n\n // 开始处理\n command.save(outputPath);\n } catch (error) {\n reject(error);\n }\n });\n }\n\n /**\n * 设置视频编解码器\n */\n private setVideoCodec(command: any, format: string): any {\n switch (format) {\n case 'mp4':\n return command.videoCodec('libx264').audioCodec('aac');\n case 'webm':\n return command.videoCodec('libvpx-vp9').audioCodec('libvorbis');\n case 'avi':\n return command.videoCodec('libx264').audioCodec('mp3');\n case 'mov':\n return command.videoCodec('libx264').audioCodec('aac');\n default:\n return command.videoCodec('libx264').audioCodec('aac');\n }\n }\n\n /**\n * 设置视频质量\n */\n private setVideoQuality(command: any, quality: number): any {\n // 质量范围:1-100,值越高质量越好\n const crf = Math.max(18, Math.min(51, 51 - Math.floor(quality * 0.33))); // 将1-100映射到51-18\n return command.outputOptions(['-crf ' + (crf)]);\n }\n\n /**\n * 确定输出格式\n */\n private determineOutputFormat(\n outputPath: string,\n requestedFormat?: VideoProcessingOptions['format']\n ): string {\n if (requestedFormat) {\n return requestedFormat;\n }\n\n const ext = path.extname(outputPath).toLowerCase();\n const formatMap: Record<string, string> = {\n '.mp4': 'mp4',\n '.avi': 'avi',\n '.mov': 'mov',\n '.webm': 'webm',\n };\n\n return formatMap[ext] || 'mp4';\n }\n\n /**\n * 生成缩略图\n */\n private async generateThumbnail(\n inputPath: string,\n outputPath: string,\n timeOffset: number\n ): Promise<string> {\n return new Promise((resolve, reject) => {\n try {\n const thumbnailPath = this.getThumbnailPath(outputPath);\n\n this.ffmpeg(inputPath)\n .seekInput(timeOffset)\n .frames(1)\n .size('320x240')\n .on('error', (err: any) => {\n console.warn('⚠️ [VideoProcessor] 缩略图生成失败: ' + (err.message));\n reject(err);\n })\n .on('end', () => {\n logger.info('🖼️ [VideoProcessor] 视频缩略图生成完成: ' + (thumbnailPath));\n resolve(thumbnailPath);\n })\n .save(thumbnailPath);\n } catch (error) {\n console.warn(`⚠️ [VideoProcessor] 缩略图生成异常:`, error);\n reject(error);\n }\n });\n }\n\n /**\n * 获取缩略图路径\n */\n private getThumbnailPath(originalPath: string): string {\n const ext = path.extname(originalPath);\n const basePath = originalPath.replace(ext, '');\n return (basePath) + '_thumb.jpg';\n }\n\n /**\n * 格式化时长显示\n */\n private formatDuration(seconds: number): string {\n const hours = Math.floor(seconds / 3600);\n const minutes = Math.floor((seconds % 3600) / 60);\n const remainingSeconds = Math.floor(seconds % 60);\n\n if (hours > 0) {\n return (hours) + ':' + (minutes.toString().padStart(2, '0')) + ':' + (remainingSeconds.toString().padStart(2, '0'));\n } else {\n return (minutes) + ':' + (remainingSeconds.toString().padStart(2, '0'));\n }\n }\n\n /**\n * 获取分辨率描述\n */\n private getResolutionDescription(width: number, height: number): string {\n if (width >= 3840 && height >= 2160) {\n return '4K UHD';\n } else if (width >= 1920 && height >= 1080) {\n return '1080p Full HD';\n } else if (width >= 1280 && height >= 720) {\n return '720p HD';\n } else if (width >= 640 && height >= 480) {\n return '480p SD';\n } else {\n return (width) + 'x' + (height);\n }\n }\n\n /**\n * 获取视频质量描述\n */\n private getQualityDescription(width: number, height: number, bitrate: number): string {\n const pixels = width * height;\n const bitratePerPixel = (bitrate / pixels) * 1000; // 每像素比特率\n\n if (pixels >= 1920 * 1080 && bitratePerPixel >= 0.1) {\n return '高清';\n } else if (pixels >= 1280 * 720 && bitratePerPixel >= 0.05) {\n return '标清';\n } else if (bitratePerPixel >= 0.02) {\n return '一般';\n } else {\n return '低质量';\n }\n }\n\n /**\n * 创建模拟FFmpeg对象(开发测试用)\n */\n private createMockFFmpeg(): any {\n logger.info('🧪 [VideoProcessor] 创建模拟FFmpeg处理器');\n\n const mockFFmpeg = (input: string) => {\n logger.info('🧪 [MockFFmpeg] 处理视频: ' + (input));\n\n return {\n videoCodec: (codec: string) => {\n logger.info('🧪 [MockFFmpeg] 设置视频编解码器: ' + (codec));\n return mockFFmpeg(input);\n },\n\n audioCodec: (codec: string) => {\n logger.info('🧪 [MockFFmpeg] 设置音频编解码器: ' + (codec));\n return mockFFmpeg(input);\n },\n\n format: (format: string) => {\n logger.info('🧪 [MockFFmpeg] 设置输出格式: ' + (format));\n return mockFFmpeg(input);\n },\n\n outputOptions: (options: string[]) => {\n logger.info(`🧪 [MockFFmpeg] 设置输出选项:`, options);\n return mockFFmpeg(input);\n },\n\n seekInput: (time: number) => {\n logger.info('🧪 [MockFFmpeg] 跳转到时间: ' + (time) + 's');\n return mockFFmpeg(input);\n },\n\n frames: (count: number) => {\n logger.info('🧪 [MockFFmpeg] 提取帧数: ' + (count));\n return mockFFmpeg(input);\n },\n\n size: (size: string) => {\n logger.info('🧪 [MockFFmpeg] 设置尺寸: ' + (size));\n return mockFFmpeg(input);\n },\n\n on: (event: string, callback: Function) => {\n logger.info('🧪 [MockFFmpeg] 注册事件监听: ' + (event));\n\n if (event === 'progress') {\n // 模拟进度更新\n setTimeout(() => callback({ percent: 25 }), 100);\n setTimeout(() => callback({ percent: 50 }), 200);\n setTimeout(() => callback({ percent: 75 }), 300);\n setTimeout(() => callback({ percent: 100 }), 400);\n } else if (event === 'end') {\n // 模拟处理完成\n setTimeout(() => callback(), 500);\n }\n\n return mockFFmpeg(input);\n },\n\n save: async (outputPath: string) => {\n logger.info('🧪 [MockFFmpeg] 保存视频文件: ' + (outputPath));\n\n // 创建模拟输出文件\n const outputDir = path.dirname(outputPath);\n await fs.mkdir(outputDir, { recursive: true });\n await fs.writeFile(outputPath, 'Mock processed video from ' + (input));\n },\n };\n };\n\n // 添加ffprobe方法\n mockFFmpeg.ffprobe = (filePath: string, callback: Function) => {\n logger.info('🧪 [MockFFmpeg] 获取视频元数据: ' + (filePath));\n\n setTimeout(() => {\n const mockMetadata = {\n streams: [\n {\n codec_type: 'video',\n codec_name: 'h264',\n width: '1920',\n height: '1080',\n r_frame_rate: '30/1',\n },\n ],\n format: {\n format_name: 'mp4',\n duration: '300.0',\n size: '50000000',\n bit_rate: '1000000',\n },\n };\n\n callback(null, mockMetadata);\n }, 100);\n };\n\n return mockFFmpeg;\n }\n\n /**\n * 批量视频处理\n */\n async batchProcess(\n inputPaths: string[],\n outputDir: string,\n options: VideoProcessingOptions,\n onProgress?: (completed: number, total: number) => void\n ): Promise<ProcessingResult[]> {\n this.ensureInitialized();\n\n logger.info('🎬 [VideoProcessor] 开始批量处理 ' + (inputPaths.length) + ' 个视频文件');\n\n const results: ProcessingResult[] = [];\n\n for (let i = 0; i < inputPaths.length; i++) {\n const inputPath = inputPaths[i]!;\n const fileName = path.basename(inputPath);\n const nameWithoutExt = path.parse(fileName).name;\n const outputFormat = options.format || 'mp4';\n const outputPath = path.join(outputDir, (nameWithoutExt) + '.' + (outputFormat));\n\n try {\n const result = await this.process(inputPath, outputPath, options);\n results.push(result);\n\n if (onProgress) {\n onProgress(i + 1, inputPaths.length);\n }\n } catch (error) {\n console.error('❌ [VideoProcessor] 批量处理失败: ' + (inputPath) + ':', error);\n results.push({\n success: false,\n error: '处理失败: ' + (error instanceof Error ? error.message : '未知错误'),\n });\n }\n }\n\n const successCount = results.filter((r) => r.success).length;\n logger.info('✅ [VideoProcessor] 批量处理完成,成功: ' + (successCount) + '/' + (inputPaths.length));\n\n return results;\n }\n\n /**\n * 提取视频帧\n */\n async extractFrames(\n inputPath: string,\n outputDir: string,\n options: {\n count?: number;\n interval?: number;\n format?: 'jpg' | 'png';\n } = {}\n ): Promise<string[]> {\n this.ensureInitialized();\n\n const { count = 10, interval, format = 'jpg' } = options;\n\n logger.info('🖼️ [VideoProcessor] 提取视频帧: ' + (inputPath) + ', 数量: ' + (count));\n\n return new Promise((resolve, reject) => {\n try {\n let command = this.ffmpeg(inputPath);\n\n if (interval) {\n // 按间隔提取\n command = command.outputOptions(['-vf fps=1/' + (interval)]);\n } else {\n // 按数量提取\n command = command.frames(count);\n }\n\n const outputPattern = path.join(outputDir, 'frame_%03d.' + (format));\n\n command\n .on('error', (err: any) => {\n console.error(`❌ [VideoProcessor] 提取帧失败:`, err);\n reject(new Error('提取帧失败: ' + (err.message)));\n })\n .on('end', async () => {\n // 查找生成的帧文件\n try {\n const files = await fs.readdir(outputDir);\n const frameFiles = files\n .filter((file) => file.startsWith('frame_') && file.endsWith('.' + (format)))\n .sort()\n .map((file) => path.join(outputDir, file));\n\n logger.info('✅ [VideoProcessor] 帧提取完成,共 ' + (frameFiles.length) + ' 帧');\n resolve(frameFiles);\n } catch (error) {\n reject(error);\n }\n })\n .save(outputPattern);\n } catch (error) {\n reject(error);\n }\n });\n }\n\n /**\n * 视频压缩\n */\n async compress(\n inputPath: string,\n outputPath: string,\n compressionLevel: 'low' | 'medium' | 'high' = 'medium'\n ): Promise<ProcessingResult> {\n this.ensureInitialized();\n\n logger.info('🗜️ [VideoProcessor] 开始视频压缩: ' + (inputPath) + ', 级别: ' + (compressionLevel));\n\n const options: VideoProcessingOptions = {\n type: 'video',\n quality: this.getCompressionQuality(compressionLevel),\n format: 'mp4',\n };\n\n return this.process(inputPath, outputPath, options);\n }\n\n /**\n * 获取压缩质量\n */\n private getCompressionQuality(level: 'low' | 'medium' | 'high'): number {\n switch (level) {\n case 'low':\n return 30;\n case 'medium':\n return 60;\n case 'high':\n return 85;\n default:\n return 60;\n }\n }\n}\n","/**\n * 文件处理队列管理系统\n * 支持异步任务调度、优先级排序、并发控制等功能\n */\n\nimport { EventEmitter } from 'events';\nimport { createLogger } from '../../../logger';\nimport type { IFileProcessor, ProcessingOptions, ProcessingResult, ProcessorType } from '../types';\n\nconst logger = createLogger('ProcessingQueue');\n\n// 队列任务相关类型定义\nexport interface QueueTask {\n id: string;\n inputPath: string;\n outputPath: string;\n options: ProcessingOptions;\n priority: TaskPriority;\n status: TaskStatus;\n processor?: IFileProcessor;\n startTime?: number;\n endTime?: number;\n result?: ProcessingResult;\n error?: string;\n retries: number;\n maxRetries: number;\n onProgress?: (task: QueueTask, progress: number) => void;\n onComplete?: (task: QueueTask, result: ProcessingResult) => void;\n onError?: (task: QueueTask, error: string) => void;\n}\n\nexport type TaskPriority = 'low' | 'normal' | 'high' | 'urgent';\nexport type TaskStatus = 'pending' | 'running' | 'completed' | 'failed' | 'cancelled';\n\nexport interface QueueOptions {\n maxConcurrentTasks?: number;\n maxRetries?: number;\n retryDelay?: number;\n taskTimeout?: number;\n autoStart?: boolean;\n}\n\nexport interface QueueStats {\n totalTasks: number;\n pendingTasks: number;\n runningTasks: number;\n completedTasks: number;\n failedTasks: number;\n cancelledTasks: number;\n averageProcessingTime: number;\n successRate: number;\n}\n\n/**\n * 文件处理队列管理器\n */\nexport class ProcessingQueue extends EventEmitter {\n private tasks: Map<string, QueueTask> = new Map();\n private runningTasks: Set<string> = new Set();\n private processors: Map<ProcessorType, IFileProcessor> = new Map();\n\n private options: Required<QueueOptions>;\n private isStarted = false;\n private processInterval: NodeJS.Timeout | null = null;\n\n constructor(options: QueueOptions = {}) {\n super();\n\n this.options = {\n maxConcurrentTasks: options.maxConcurrentTasks || 3,\n maxRetries: options.maxRetries || 2,\n retryDelay: options.retryDelay || 5000,\n taskTimeout: options.taskTimeout || 300000, // 5分钟\n autoStart: options.autoStart !== false,\n };\n\n logger.info('📋 [ProcessingQueue] 队列管理器已创建');\n\n if (this.options.autoStart) {\n this.start();\n }\n }\n\n /**\n * 注册文件处理器\n */\n registerProcessor(processor: IFileProcessor): void {\n this.processors.set(processor.type, processor);\n logger.info('🔧 [ProcessingQueue] 注册处理器: ' + (processor.type));\n }\n\n /**\n * 添加任务到队列\n */\n addTask(\n inputPath: string,\n outputPath: string,\n options: ProcessingOptions,\n taskOptions: Partial<\n Pick<QueueTask, 'priority' | 'maxRetries' | 'onProgress' | 'onComplete' | 'onError'>\n > = {}\n ): string {\n const taskId = this.generateTaskId();\n\n const task: QueueTask = {\n id: taskId,\n inputPath,\n outputPath,\n options,\n priority: taskOptions.priority || 'normal',\n status: 'pending',\n retries: 0,\n maxRetries: taskOptions.maxRetries || this.options.maxRetries,\n onProgress: taskOptions.onProgress,\n onComplete: taskOptions.onComplete,\n onError: taskOptions.onError,\n };\n\n // 获取对应的处理器\n const processor = this.processors.get(options.type);\n if (!processor) {\n throw new Error('未找到类型为 ' + (options.type) + ' 的文件处理器');\n }\n task.processor = processor;\n\n this.tasks.set(taskId, task);\n\n logger.info('📝 [ProcessingQueue] 添加任务: ' + (taskId) + ' (' + (inputPath) + ')');\n\n this.emit('taskAdded', task);\n\n // 如果队列已启动,尝试立即处理\n if (this.isStarted) {\n this.processNext();\n }\n\n return taskId;\n }\n\n /**\n * 启动队列处理\n */\n start(): void {\n if (this.isStarted) {\n console.warn('⚠️ [ProcessingQueue] 队列已经启动');\n return;\n }\n\n this.isStarted = true;\n logger.info('▶️ [ProcessingQueue] 启动队列处理');\n\n // 定期检查并处理任务\n this.processInterval = setInterval(() => {\n this.processNext();\n }, 1000);\n\n this.emit('started');\n\n // 立即尝试处理任务\n this.processNext();\n }\n\n /**\n * 停止队列处理\n */\n stop(): void {\n if (!this.isStarted) {\n console.warn('⚠️ [ProcessingQueue] 队列未启动');\n return;\n }\n\n this.isStarted = false;\n\n if (this.processInterval) {\n clearInterval(this.processInterval);\n this.processInterval = null;\n }\n\n logger.info('⏹️ [ProcessingQueue] 停止队列处理');\n this.emit('stopped');\n }\n\n /**\n * 暂停任务\n */\n pauseTask(taskId: string): boolean {\n const task = this.tasks.get(taskId);\n if (!task) {\n console.warn('⚠️ [ProcessingQueue] 任务不存在: ' + (taskId));\n return false;\n }\n\n if (task.status === 'running') {\n console.warn('⚠️ [ProcessingQueue] 无法暂停正在运行的任务: ' + (taskId));\n return false;\n }\n\n task.status = 'cancelled';\n logger.info('⏸️ [ProcessingQueue] 暂停任务: ' + (taskId));\n\n this.emit('taskCancelled', task);\n return true;\n }\n\n /**\n * 取消任务\n */\n cancelTask(taskId: string): boolean {\n const task = this.tasks.get(taskId);\n if (!task) {\n console.warn('⚠️ [ProcessingQueue] 任务不存在: ' + (taskId));\n return false;\n }\n\n if (task.status === 'running') {\n console.warn('⚠️ [ProcessingQueue] 无法取消正在运行的任务: ' + (taskId));\n return false;\n }\n\n task.status = 'cancelled';\n logger.info('❌ [ProcessingQueue] 取消任务: ' + (taskId));\n\n this.emit('taskCancelled', task);\n return true;\n }\n\n /**\n * 获取任务状态\n */\n getTask(taskId: string): QueueTask | undefined {\n return this.tasks.get(taskId);\n }\n\n /**\n * 获取所有任务\n */\n getAllTasks(): QueueTask[] {\n return Array.from(this.tasks.values());\n }\n\n /**\n * 获取待处理任务\n */\n getPendingTasks(): QueueTask[] {\n return Array.from(this.tasks.values()).filter((task) => task.status === 'pending');\n }\n\n /**\n * 获取正在运行的任务\n */\n getRunningTasks(): QueueTask[] {\n return Array.from(this.tasks.values()).filter((task) => task.status === 'running');\n }\n\n /**\n * 获取队列统计信息\n */\n getStats(): QueueStats {\n const allTasks = Array.from(this.tasks.values());\n const completedTasks = allTasks.filter((task) => task.status === 'completed');\n\n const totalProcessingTime = completedTasks.reduce((sum, task) => {\n if (task.startTime && task.endTime) {\n return sum + (task.endTime - task.startTime);\n }\n return sum;\n }, 0);\n\n return {\n totalTasks: allTasks.length,\n pendingTasks: allTasks.filter((task) => task.status === 'pending').length,\n runningTasks: allTasks.filter((task) => task.status === 'running').length,\n completedTasks: allTasks.filter((task) => task.status === 'completed').length,\n failedTasks: allTasks.filter((task) => task.status === 'failed').length,\n cancelledTasks: allTasks.filter((task) => task.status === 'cancelled').length,\n averageProcessingTime:\n completedTasks.length > 0 ? totalProcessingTime / completedTasks.length : 0,\n successRate: allTasks.length > 0 ? completedTasks.length / allTasks.length : 0,\n };\n }\n\n /**\n * 清理已完成的任务\n */\n cleanup(): void {\n const beforeCount = this.tasks.size;\n\n for (const [taskId, task] of Array.from(this.tasks.entries())) {\n if (task.status === 'completed' || task.status === 'failed' || task.status === 'cancelled') {\n this.tasks.delete(taskId);\n }\n }\n\n const afterCount = this.tasks.size;\n const cleanedCount = beforeCount - afterCount;\n\n logger.info('🧹 [ProcessingQueue] 清理完成,移除 ' + (cleanedCount) + ' 个任务');\n this.emit('cleanup', { cleaned: cleanedCount, remaining: afterCount });\n }\n\n // ============= 私有方法 =============\n\n /**\n * 处理下一个任务\n */\n private async processNext(): Promise<void> {\n if (!this.isStarted) {\n return;\n }\n\n // 检查并发限制\n if (this.runningTasks.size >= this.options.maxConcurrentTasks) {\n return;\n }\n\n // 获取下一个待处理任务\n const nextTask = this.getNextTask();\n if (!nextTask) {\n return;\n }\n\n // 开始处理任务\n await this.processTask(nextTask);\n }\n\n /**\n * 获取下一个待处理任务(按优先级排序)\n */\n private getNextTask(): QueueTask | null {\n const pendingTasks = this.getPendingTasks();\n if (pendingTasks.length === 0) {\n return null;\n }\n\n // 按优先级排序\n const priorityOrder: Record<TaskPriority, number> = {\n urgent: 4,\n high: 3,\n normal: 2,\n low: 1,\n };\n\n pendingTasks.sort((a, b) => {\n const priorityDiff = priorityOrder[b.priority] - priorityOrder[a.priority];\n if (priorityDiff !== 0) {\n return priorityDiff;\n }\n // 相同优先级按添加时间排序(FIFO)\n return 0;\n });\n\n return pendingTasks[0] || null;\n }\n\n /**\n * 处理单个任务\n */\n private async processTask(task: QueueTask): Promise<void> {\n if (!task.processor) {\n this.failTask(task, '未找到对应的文件处理器');\n return;\n }\n\n logger.info('🚀 [ProcessingQueue] 开始处理任务: ' + (task.id));\n\n // 更新任务状态\n task.status = 'running';\n task.startTime = Date.now();\n this.runningTasks.add(task.id);\n\n this.emit('taskStarted', task);\n\n // 设置超时\n const timeoutId = setTimeout(() => {\n if (task.status === 'running') {\n this.failTask(task, '任务处理超时');\n }\n }, this.options.taskTimeout);\n\n try {\n // 执行处理\n const result = await task.processor.process(task.inputPath, task.outputPath, task.options);\n\n clearTimeout(timeoutId);\n\n if (result.success) {\n this.completeTask(task, result);\n } else {\n this.retryOrFailTask(task, result.error || '处理失败');\n }\n } catch (error) {\n clearTimeout(timeoutId);\n const errorMessage = error instanceof Error ? error.message : '未知错误';\n this.retryOrFailTask(task, errorMessage);\n }\n }\n\n /**\n * 完成任务\n */\n private completeTask(task: QueueTask, result: ProcessingResult): void {\n task.status = 'completed';\n task.endTime = Date.now();\n task.result = result;\n\n this.runningTasks.delete(task.id);\n\n logger.info('✅ [ProcessingQueue] 任务完成: ' + (task.id));\n\n if (task.onComplete) {\n try {\n task.onComplete(task, result);\n } catch (error) {\n console.error('❌ [ProcessingQueue] 任务完成回调错误:', error);\n }\n }\n\n this.emit('taskCompleted', task, result);\n\n // 尝试处理下一个任务\n setTimeout(() => this.processNext(), 0);\n }\n\n /**\n * 重试或失败任务\n */\n private retryOrFailTask(task: QueueTask, error: string): void {\n this.runningTasks.delete(task.id);\n\n if (task.retries < task.maxRetries) {\n // 重试任务\n task.retries++;\n task.status = 'pending';\n task.error = undefined;\n\n logger.info('🔄 [ProcessingQueue] 重试任务: ' + (task.id) + ' (' + (task.retries) + '/' + (task.maxRetries) + ')');\n\n this.emit('taskRetried', task);\n\n // 延迟重试\n setTimeout(() => {\n if (this.isStarted) {\n this.processNext();\n }\n }, this.options.retryDelay);\n } else {\n // 任务失败\n this.failTask(task, error);\n }\n }\n\n /**\n * 失败任务\n */\n private failTask(task: QueueTask, error: string): void {\n task.status = 'failed';\n task.endTime = Date.now();\n task.error = error;\n\n this.runningTasks.delete(task.id);\n\n console.error('❌ [ProcessingQueue] 任务失败: ' + (task.id) + ' - ' + (error));\n\n if (task.onError) {\n try {\n task.onError(task, error);\n } catch (callbackError) {\n console.error('❌ [ProcessingQueue] 任务失败回调错误:', callbackError);\n }\n }\n\n this.emit('taskFailed', task, error);\n\n // 尝试处理下一个任务\n setTimeout(() => this.processNext(), 0);\n }\n\n /**\n * 生成唯一任务ID\n */\n private generateTaskId(): string {\n return 'task_' + (Date.now()) + '_' + (Math.random().toString(36).substr(2, 9));\n }\n\n /**\n * 批量添加任务\n */\n addBatchTasks(\n tasks: Array<{\n inputPath: string;\n outputPath: string;\n options: ProcessingOptions;\n priority?: TaskPriority;\n }>,\n onBatchProgress?: (completed: number, total: number) => void,\n onBatchComplete?: (results: Map<string, ProcessingResult>) => void\n ): string[] {\n const taskIds: string[] = [];\n const results = new Map<string, ProcessingResult>();\n let completedCount = 0;\n\n logger.info('📦 [ProcessingQueue] 批量添加 ' + (tasks.length) + ' 个任务');\n\n for (const taskSpec of tasks) {\n const taskId = this.addTask(taskSpec.inputPath, taskSpec.outputPath, taskSpec.options, {\n priority: taskSpec.priority,\n onComplete: (task, result) => {\n results.set(task.id, result);\n completedCount++;\n\n if (onBatchProgress) {\n onBatchProgress(completedCount, tasks.length);\n }\n\n if (completedCount === tasks.length && onBatchComplete) {\n onBatchComplete(results);\n }\n },\n onError: (task, error) => {\n results.set(task.id, { success: false, error });\n completedCount++;\n\n if (onBatchProgress) {\n onBatchProgress(completedCount, tasks.length);\n }\n\n if (completedCount === tasks.length && onBatchComplete) {\n onBatchComplete(results);\n }\n },\n });\n\n taskIds.push(taskId);\n }\n\n return taskIds;\n }\n\n /**\n * 获取队列健康状态\n */\n getHealthStatus(): {\n isHealthy: boolean;\n issues: string[];\n recommendations: string[];\n } {\n const stats = this.getStats();\n const issues: string[] = [];\n const recommendations: string[] = [];\n\n // 检查成功率\n if (stats.successRate < 0.8 && stats.totalTasks > 10) {\n issues.push('成功率过低: ' + ((stats.successRate * 100).toFixed(1)) + '%');\n recommendations.push('检查文件处理器配置和输入文件质量');\n }\n\n // 检查待处理任务积压\n if (stats.pendingTasks > 50) {\n issues.push('待处理任务积压: ' + (stats.pendingTasks) + ' 个');\n recommendations.push('考虑增加并发处理数或优化处理性能');\n }\n\n // 检查平均处理时间\n if (stats.averageProcessingTime > 60000) {\n // 超过1分钟\n issues.push('平均处理时间过长: ' + ((stats.averageProcessingTime / 1000).toFixed(1)) + '秒');\n recommendations.push('优化文件处理逻辑或减少处理复杂度');\n }\n\n return {\n isHealthy: issues.length === 0,\n issues,\n recommendations,\n };\n }\n}\n","/**\n * UniversalFile Server 模块入口\n */\n\n// 导出所有服务端类型\nexport type * from './types';\nexport type {\n IFileMetadataRepository,\n FileServicePersistenceConfig,\n} from './types';\n\n// 导出接口\nexport type {\n IStorageProvider,\n ICDNProvider,\n IFileProcessor,\n UniversalFileServiceConfig,\n StorageConfig,\n CDNConfig,\n CacheConfig,\n LocalStorageConfig,\n AliyunOSSConfig,\n AliyunCDNConfig,\n StorageResult,\n StorageMetadata,\n CDNResult,\n CDNStats,\n ProcessingResult,\n ProcessorInfo,\n FileRecord,\n FileQueryOptions,\n PaginatedResult,\n FileEvent,\n FileEventListener,\n FileEventType,\n // ProcessingOptions 从 ../types 重新导出\n UploadFileInfo,\n ProcessingOptions,\n} from './types';\n\n// 服务类(将在后续 Phase 中迁移)\n// export { UniversalFileService } from './UniversalFileService';\n\n// 初始化辅助函数\nexport {\n createUniversalFileService,\n createFileServiceConfig,\n createFileServiceFromEnv,\n} from './factory';\n\n// 预设配置\nexport {\n createLocalDevPreset,\n createAliyunOSSPreset,\n createSmartPreset,\n createImageServicePreset,\n createVideoServicePreset,\n createDocumentServicePreset,\n} from './presets';\n\n// 配置验证\nexport {\n validateStorageConfig,\n validateServiceConfig,\n validateEnvironment,\n getRequiredEnvVars,\n ConfigValidationError,\n} from './validation';\n\n// Providers\nexport * from './providers';\n\n// Processors\nexport * from './processors';\n\n// 工具函数\nexport { getMimeType } from './utils/mime';\n\n// 核心服务类\nexport { UniversalFileService } from './UniversalFileService';\n\n// 缓存和监控\nexport { CacheManager, cacheManager } from './cache/CacheManager';\nexport { PerformanceMonitor, performanceMonitor } from './monitoring/PerformanceMonitor';\nexport { CdnCacheStrategy } from './cdn/CdnCacheStrategy';\n\n// API 错误处理\nexport { ApiError, ApiErrorFactory, ApiResponseHelper, ValidationHelper } from './errors/ApiError';\nexport * from './types/api';\n\n// ============= Persistence =============\nexport {\n createDrizzleRepository,\n type DrizzleRepositoryConfig,\n type DrizzleTable,\n type DrizzleDb,\n type FieldMapping,\n} from './persistence/drizzle-repository';\n\nexport { createDrizzleFileRepository } from './adapters/drizzleAdapter';\n\nexport { FileDbService } from './db/services/fileDbService';\nexport { QueryOptimizer, queryOptimizer } from './db/middleware/queryOptimizer';\n\nexport { FileServiceConfigManager, createFileServiceConfigWithConfigManager } from './config-manager';\nexport { createUniversalFileServiceWithConfigManager } from './service-helpers';\n\n// ============= Configuration Helpers =============\nexport {\n // 配置加载\n loadConfigFromEnv,\n loadOSSConfigFromEnv,\n loadCDNConfigFromEnv,\n getDefaultLocalStorage,\n loadOSSConfigFromService,\n loadConfigWithFallback,\n // 默认配置常量\n DEFAULT_MAX_FILE_SIZE,\n DEFAULT_ALLOWED_MIME_TYPES,\n DEFAULT_CACHE_CONFIG,\n DEFAULT_FILE_SERVICE_CONFIG,\n DEFAULT_OSS_CONFIG_KEYS,\n // 服务工厂\n createFileServiceWithFactory,\n type FileServiceFactoryOptions,\n // 接口\n type IConfigService,\n type OSSConfigKeyMapping,\n // 单例辅助\n createSingleton,\n type SingletonFactory,\n} from './config-helpers';\n\n// ============= Drizzle Schemas =============\nexport * from './drizzle-schemas';\n","/**\n * 通用文件服务缓存管理器\n * 支持多层缓存策略:内存缓存 + Redis缓存\n */\n\nimport { LRUCache } from 'lru-cache';\nimport { createLogger } from '../../../logger';\n\nconst logger = createLogger('CacheManager');\n\n/**\n * 缓存项接口\n */\ninterface CacheItem<T = any> {\n /** 缓存数据 */\n data: T;\n /** 创建时间 */\n createdAt: number;\n /** 过期时间 */\n expiresAt: number;\n /** 访问次数 */\n accessCount: number;\n /** 最后访问时间 */\n lastAccessAt: number;\n}\n\n/**\n * 缓存统计信息\n */\ninterface CacheStats {\n /** 总请求次数 */\n totalRequests: number;\n /** 命中次数 */\n hits: number;\n /** 未命中次数 */\n misses: number;\n /** 命中率 */\n hitRate: number;\n /** 内存缓存大小 */\n memorySize: number;\n /** Redis缓存状态 */\n redisConnected: boolean;\n}\n\n/**\n * 缓存配置选项\n */\ninterface CacheOptions {\n /** 默认过期时间(秒) */\n defaultTTL?: number;\n /** 内存缓存最大条目数 */\n maxMemoryItems?: number;\n /** 是否启用Redis缓存 */\n enableRedis?: boolean;\n /** Redis连接配置 */\n redisConfig?: {\n host: string;\n port: number;\n password?: string;\n db?: number;\n };\n /** 缓存键前缀 */\n keyPrefix?: string;\n}\n\n/**\n * 缓存管理器\n */\nexport class CacheManager {\n private memoryCache: LRUCache<string, CacheItem>;\n private redisClient: any = null;\n private stats: CacheStats;\n private options: Required<CacheOptions>;\n\n constructor(options: CacheOptions = {}) {\n this.options = {\n defaultTTL: options.defaultTTL || 300, // 5分钟\n maxMemoryItems: options.maxMemoryItems || 1000,\n enableRedis: options.enableRedis || false,\n redisConfig: options.redisConfig || {\n host: 'localhost',\n port: 6379,\n db: 0,\n },\n keyPrefix: options.keyPrefix || 'universal-file:',\n };\n\n // 初始化内存缓存\n this.memoryCache = new LRUCache({\n max: this.options.maxMemoryItems,\n ttl: this.options.defaultTTL * 1000, // LRU缓存使用毫秒\n updateAgeOnGet: true,\n allowStale: false,\n });\n\n // 初始化统计信息\n this.stats = {\n totalRequests: 0,\n hits: 0,\n misses: 0,\n hitRate: 0,\n memorySize: 0,\n redisConnected: false,\n };\n\n // 初始化Redis连接(如果启用)\n if (this.options.enableRedis) {\n this.initRedis();\n }\n }\n\n /**\n * 初始化Redis连接\n */\n private async initRedis() {\n try {\n // 这里可以集成实际的Redis客户端,如ioredis\n // const Redis = require('ioredis');\n // this.redisClient = new Redis(this.options.redisConfig);\n\n logger.info('Redis缓存已禁用 - 请安装并配置Redis客户端');\n this.stats.redisConnected = false;\n } catch (error) {\n console.error('Redis连接失败:', error);\n this.stats.redisConnected = false;\n }\n }\n\n /**\n * 生成缓存键\n */\n private generateKey(key: string): string {\n return (this.options.keyPrefix) + (key);\n }\n\n /**\n * 获取缓存数据\n */\n async get<T = any>(key: string): Promise<T | null> {\n const cacheKey = this.generateKey(key);\n this.stats.totalRequests++;\n\n try {\n // 首先尝试从内存缓存获取\n const memoryItem = this.memoryCache.get(cacheKey);\n if (memoryItem && memoryItem.expiresAt > Date.now()) {\n memoryItem.accessCount++;\n memoryItem.lastAccessAt = Date.now();\n this.stats.hits++;\n this.updateHitRate();\n return memoryItem.data as T;\n }\n\n // 如果内存缓存未命中,尝试从Redis获取\n if (this.redisClient && this.stats.redisConnected) {\n const redisData = await this.redisClient.get(cacheKey);\n if (redisData) {\n const parsedData = JSON.parse(redisData);\n\n // 将数据放回内存缓存\n const cacheItem: CacheItem<T> = {\n data: parsedData.data,\n createdAt: parsedData.createdAt,\n expiresAt: parsedData.expiresAt,\n accessCount: parsedData.accessCount + 1,\n lastAccessAt: Date.now(),\n };\n\n this.memoryCache.set(cacheKey, cacheItem);\n this.stats.hits++;\n this.updateHitRate();\n return parsedData.data as T;\n }\n }\n\n // 缓存未命中\n this.stats.misses++;\n this.updateHitRate();\n return null;\n } catch (error) {\n console.error('缓存获取失败:', error);\n this.stats.misses++;\n this.updateHitRate();\n return null;\n }\n }\n\n /**\n * 设置缓存数据\n */\n async set<T = any>(key: string, data: T, ttl?: number): Promise<void> {\n const cacheKey = this.generateKey(key);\n const expireTime = ttl || this.options.defaultTTL;\n const now = Date.now();\n\n const cacheItem: CacheItem<T> = {\n data,\n createdAt: now,\n expiresAt: now + expireTime * 1000,\n accessCount: 0,\n lastAccessAt: now,\n };\n\n try {\n // 设置到内存缓存\n this.memoryCache.set(cacheKey, cacheItem);\n\n // 如果启用Redis,也设置到Redis\n if (this.redisClient && this.stats.redisConnected) {\n await this.redisClient.setex(cacheKey, expireTime, JSON.stringify(cacheItem));\n }\n\n this.updateMemorySize();\n } catch (error) {\n console.error('缓存设置失败:', error);\n }\n }\n\n /**\n * 删除缓存数据\n */\n async delete(key: string): Promise<void> {\n const cacheKey = this.generateKey(key);\n\n try {\n // 从内存缓存删除\n this.memoryCache.delete(cacheKey);\n\n // 从Redis删除\n if (this.redisClient && this.stats.redisConnected) {\n await this.redisClient.del(cacheKey);\n }\n\n this.updateMemorySize();\n } catch (error) {\n console.error('缓存删除失败:', error);\n }\n }\n\n /**\n * 批量删除缓存(支持模式匹配)\n */\n async deletePattern(pattern: string): Promise<void> {\n const cachePattern = this.generateKey(pattern);\n\n try {\n // 清理内存缓存中匹配的项\n const keys = Array.from(this.memoryCache.keys());\n for (const key of keys) {\n if (this.matchPattern(key, cachePattern)) {\n this.memoryCache.delete(key);\n }\n }\n\n // 清理Redis中匹配的项\n if (this.redisClient && this.stats.redisConnected) {\n const redisKeys = await this.redisClient.keys(cachePattern);\n if (redisKeys.length > 0) {\n await this.redisClient.del(...redisKeys);\n }\n }\n\n this.updateMemorySize();\n } catch (error) {\n console.error('批量缓存删除失败:', error);\n }\n }\n\n /**\n * 清空所有缓存\n */\n async clear(): Promise<void> {\n try {\n // 清空内存缓存\n this.memoryCache.clear();\n\n // 清空Redis缓存(仅删除带前缀的键)\n if (this.redisClient && this.stats.redisConnected) {\n const keys = await this.redisClient.keys((this.options.keyPrefix) + '*');\n if (keys.length > 0) {\n await this.redisClient.del(...keys);\n }\n }\n\n // 重置统计信息\n this.stats.hits = 0;\n this.stats.misses = 0;\n this.stats.totalRequests = 0;\n this.stats.hitRate = 0;\n this.updateMemorySize();\n } catch (error) {\n console.error('清空缓存失败:', error);\n }\n }\n\n /**\n * 获取缓存统计信息\n */\n getStats(): CacheStats {\n this.updateMemorySize();\n return { ...this.stats };\n }\n\n /**\n * 获取缓存项详情(用于调试)\n */\n getCacheItem(key: string): CacheItem | null {\n const cacheKey = this.generateKey(key);\n return this.memoryCache.get(cacheKey) || null;\n }\n\n /**\n * 预热缓存\n */\n async warmup<T>(items: Array<{ key: string; data: T; ttl?: number }>): Promise<void> {\n logger.info('开始预热缓存,共 ' + (items.length) + ' 项...');\n\n const promises = items.map((item) => this.set(item.key, item.data, item.ttl));\n\n try {\n await Promise.all(promises);\n logger.info('缓存预热完成');\n } catch (error) {\n console.error('缓存预热失败:', error);\n }\n }\n\n /**\n * 更新命中率\n */\n private updateHitRate(): void {\n this.stats.hitRate =\n this.stats.totalRequests > 0 ? (this.stats.hits / this.stats.totalRequests) * 100 : 0;\n }\n\n /**\n * 更新内存使用量\n */\n private updateMemorySize(): void {\n this.stats.memorySize = this.memoryCache.size;\n }\n\n /**\n * 模式匹配函数\n */\n private matchPattern(key: string, pattern: string): boolean {\n // 简单的通配符匹配,* 匹配任意字符\n const regexPattern = pattern.replace(/\\*/g, '.*').replace(/\\?/g, '.');\n\n const regex = new RegExp('^' + (regexPattern) + '$');\n return regex.test(key);\n }\n\n /**\n * 获取或设置缓存(如果不存在则调用生成函数)\n */\n async getOrSet<T>(key: string, generator: () => Promise<T>, ttl?: number): Promise<T> {\n // 尝试获取缓存\n const cachedData = await this.get<T>(key);\n if (cachedData !== null) {\n return cachedData;\n }\n\n // 缓存不存在,调用生成函数\n try {\n const data = await generator();\n await this.set(key, data, ttl);\n return data;\n } catch (error) {\n console.error('缓存生成失败:', error);\n throw error;\n }\n }\n\n /**\n * 关闭缓存管理器\n */\n async close(): Promise<void> {\n try {\n // 清理内存缓存\n this.memoryCache.clear();\n\n // 关闭Redis连接\n if (this.redisClient) {\n await this.redisClient.quit();\n }\n } catch (error) {\n console.error('关闭缓存管理器失败:', error);\n }\n }\n}\n\n/**\n * 单例缓存管理器实例\n */\nexport const cacheManager = new CacheManager({\n defaultTTL: 300, // 5分钟\n maxMemoryItems: 2000,\n enableRedis: false, // 开发环境暂时禁用Redis\n keyPrefix: 'universal-file:',\n});\n","/**\n * 通用文件服务性能监控器\n * 监控API响应时间、数据库查询性能、缓存命中率等指标\n */\n\n/**\n * 性能指标类型\n */\ninterface PerformanceMetric {\n /** 指标名称 */\n name: string;\n /** 指标值 */\n value: number;\n /** 单位 */\n unit: string;\n /** 时间戳 */\n timestamp: number;\n /** 标签 */\n labels?: Record<string, string>;\n}\n\n/**\n * 性能统计信息\n */\ninterface PerformanceStats {\n /** API响应时间统计 */\n apiResponseTimes: {\n /** 平均响应时间(毫秒) */\n average: number;\n /** 最小响应时间 */\n min: number;\n /** 最大响应时间 */\n max: number;\n /** P95响应时间 */\n p95: number;\n /** P99响应时间 */\n p99: number;\n /** 总请求数 */\n totalRequests: number;\n };\n\n /** 数据库查询性能 */\n databasePerformance: {\n /** 平均查询时间(毫秒) */\n averageQueryTime: number;\n /** 慢查询数量 */\n slowQueries: number;\n /** 总查询数 */\n totalQueries: number;\n /** 查询错误数 */\n queryErrors: number;\n };\n\n /** 文件操作性能 */\n fileOperations: {\n /** 文件上传统计 */\n uploads: {\n /** 总上传数 */\n total: number;\n /** 成功上传数 */\n successful: number;\n /** 失败上传数 */\n failed: number;\n /** 平均上传时间 */\n averageTime: number;\n /** 平均文件大小 */\n averageSize: number;\n };\n\n /** 文件下载统计 */\n downloads: {\n /** 总下载数 */\n total: number;\n /** 成功下载数 */\n successful: number;\n /** 失败下载数 */\n failed: number;\n /** 平均下载时间 */\n averageTime: number;\n };\n };\n\n /** 系统资源使用 */\n systemResources: {\n /** 内存使用量(MB) */\n memoryUsage: number;\n /** CPU使用率(%) */\n cpuUsage: number;\n /** 磁盘使用量(MB) */\n diskUsage: number;\n };\n}\n\n/**\n * 请求跟踪信息\n */\ninterface RequestTrace {\n /** 请求ID */\n requestId: string;\n /** 请求路径 */\n path: string;\n /** HTTP方法 */\n method: string;\n /** 开始时间 */\n startTime: number;\n /** 结束时间 */\n endTime?: number;\n /** 响应时间(毫秒) */\n duration?: number;\n /** 状态码 */\n statusCode?: number;\n /** 错误信息 */\n error?: string;\n /** 用户ID */\n userId?: string;\n /** 文件大小(字节) */\n fileSize?: number;\n}\n\n/**\n * 性能监控器\n */\nexport class PerformanceMonitor {\n private metrics: PerformanceMetric[] = [];\n private requestTraces: Map<string, RequestTrace> = new Map();\n private stats: PerformanceStats;\n private readonly maxMetrics = 10000; // 最大保存指标数量\n private readonly maxTraces = 1000; // 最大保存跟踪数量\n\n constructor() {\n this.stats = this.initializeStats();\n\n // 定期清理过期数据\n setInterval(() => {\n this.cleanupOldData();\n }, 60000); // 每分钟清理一次\n }\n\n /**\n * 初始化统计信息\n */\n private initializeStats(): PerformanceStats {\n return {\n apiResponseTimes: {\n average: 0,\n min: 0,\n max: 0,\n p95: 0,\n p99: 0,\n totalRequests: 0,\n },\n databasePerformance: {\n averageQueryTime: 0,\n slowQueries: 0,\n totalQueries: 0,\n queryErrors: 0,\n },\n fileOperations: {\n uploads: {\n total: 0,\n successful: 0,\n failed: 0,\n averageTime: 0,\n averageSize: 0,\n },\n downloads: {\n total: 0,\n successful: 0,\n failed: 0,\n averageTime: 0,\n },\n },\n systemResources: {\n memoryUsage: 0,\n cpuUsage: 0,\n diskUsage: 0,\n },\n };\n }\n\n /**\n * 开始请求跟踪\n */\n startRequest(requestId: string, path: string, method: string, userId?: string): void {\n const trace: RequestTrace = {\n requestId,\n path,\n method,\n startTime: Date.now(),\n userId,\n };\n\n this.requestTraces.set(requestId, trace);\n }\n\n /**\n * 结束请求跟踪\n */\n endRequest(requestId: string, statusCode: number, error?: string, fileSize?: number): void {\n const trace = this.requestTraces.get(requestId);\n if (!trace) return;\n\n const endTime = Date.now();\n const duration = endTime - trace.startTime;\n\n trace.endTime = endTime;\n trace.duration = duration;\n trace.statusCode = statusCode;\n trace.error = error;\n trace.fileSize = fileSize;\n\n // 记录API响应时间指标\n this.recordMetric('api_response_time', duration, 'ms', {\n path: trace.path,\n method: trace.method,\n status: statusCode.toString(),\n });\n\n // 更新统计信息\n this.updateApiStats(duration);\n\n // 如果是文件操作,更新文件操作统计\n if (trace.path.includes('upload')) {\n this.updateUploadStats(statusCode < 400, duration, fileSize);\n } else if (trace.path.includes('download')) {\n this.updateDownloadStats(statusCode < 400, duration);\n }\n\n // 如果跟踪数量过多,删除最旧的\n if (this.requestTraces.size > this.maxTraces) {\n const oldestKey = this.requestTraces.keys().next().value;\n if (oldestKey) {\n this.requestTraces.delete(oldestKey);\n }\n }\n }\n\n /**\n * 记录数据库查询性能\n */\n recordDatabaseQuery(queryTime: number, isError: boolean = false): void {\n this.recordMetric('db_query_time', queryTime, 'ms');\n\n this.stats.databasePerformance.totalQueries++;\n\n if (isError) {\n this.stats.databasePerformance.queryErrors++;\n }\n\n // 更新平均查询时间\n const total = this.stats.databasePerformance.totalQueries;\n const currentAvg = this.stats.databasePerformance.averageQueryTime;\n this.stats.databasePerformance.averageQueryTime =\n (currentAvg * (total - 1) + queryTime) / total;\n\n // 记录慢查询(超过1秒)\n if (queryTime > 1000) {\n this.stats.databasePerformance.slowQueries++;\n this.recordMetric('slow_query', 1, 'count');\n }\n }\n\n /**\n * 记录系统资源使用情况\n */\n recordSystemResources(): void {\n try {\n // 获取内存使用情况\n const memoryUsage = process.memoryUsage();\n const memoryUsedMB = memoryUsage.heapUsed / 1024 / 1024;\n\n this.stats.systemResources.memoryUsage = memoryUsedMB;\n this.recordMetric('memory_usage', memoryUsedMB, 'MB');\n\n // 记录其他系统指标(简化版本)\n this.recordMetric('heap_total', memoryUsage.heapTotal / 1024 / 1024, 'MB');\n this.recordMetric('heap_used', memoryUsage.heapUsed / 1024 / 1024, 'MB');\n this.recordMetric('external', memoryUsage.external / 1024 / 1024, 'MB');\n } catch (error) {\n console.error('记录系统资源失败:', error);\n }\n }\n\n /**\n * 记录自定义指标\n */\n recordMetric(name: string, value: number, unit: string, labels?: Record<string, string>): void {\n const metric: PerformanceMetric = {\n name,\n value,\n unit,\n timestamp: Date.now(),\n labels,\n };\n\n this.metrics.push(metric);\n\n // 如果指标数量过多,删除最旧的\n if (this.metrics.length > this.maxMetrics) {\n this.metrics.shift();\n }\n }\n\n /**\n * 获取性能统计信息\n */\n getStats(): PerformanceStats {\n // 更新系统资源信息\n this.recordSystemResources();\n\n return { ...this.stats };\n }\n\n /**\n * 获取指定时间范围内的指标\n */\n getMetrics(name?: string, startTime?: number, endTime?: number): PerformanceMetric[] {\n let filteredMetrics = this.metrics;\n\n if (name) {\n filteredMetrics = filteredMetrics.filter((m) => m.name === name);\n }\n\n if (startTime) {\n filteredMetrics = filteredMetrics.filter((m) => m.timestamp >= startTime);\n }\n\n if (endTime) {\n filteredMetrics = filteredMetrics.filter((m) => m.timestamp <= endTime);\n }\n\n return filteredMetrics;\n }\n\n /**\n * 获取请求跟踪信息\n */\n getRequestTraces(limit: number = 100): RequestTrace[] {\n const traces = Array.from(this.requestTraces.values());\n return traces.sort((a, b) => b.startTime - a.startTime).slice(0, limit);\n }\n\n /**\n * 获取慢请求列表\n */\n getSlowRequests(threshold: number = 1000): RequestTrace[] {\n return this.getRequestTraces()\n .filter((trace) => trace.duration && trace.duration > threshold)\n .sort((a, b) => (b.duration || 0) - (a.duration || 0));\n }\n\n /**\n * 获取错误请求列表\n */\n getErrorRequests(): RequestTrace[] {\n return this.getRequestTraces().filter((trace) => trace.statusCode && trace.statusCode >= 400);\n }\n\n /**\n * 生成性能报告\n */\n generateReport(): {\n summary: any;\n topSlowRequests: RequestTrace[];\n recentErrors: RequestTrace[];\n systemHealth: any;\n } {\n const stats = this.getStats();\n const slowRequests = this.getSlowRequests(500); // 500ms以上的请求\n const errorRequests = this.getErrorRequests();\n\n return {\n summary: {\n totalRequests: stats.apiResponseTimes.totalRequests,\n averageResponseTime: stats.apiResponseTimes.average,\n errorRate: (errorRequests.length / Math.max(stats.apiResponseTimes.totalRequests, 1)) * 100,\n cacheHitRate: 0, // 需要从缓存管理器获取\n slowQueryCount: stats.databasePerformance.slowQueries,\n },\n topSlowRequests: slowRequests.slice(0, 10),\n recentErrors: errorRequests.slice(0, 10),\n systemHealth: {\n memoryUsage: stats.systemResources.memoryUsage,\n queryPerformance: stats.databasePerformance.averageQueryTime,\n uptime: process.uptime(),\n },\n };\n }\n\n /**\n * 更新API统计信息\n */\n private updateApiStats(duration: number): void {\n const stats = this.stats.apiResponseTimes;\n stats.totalRequests++;\n\n // 更新平均响应时间\n stats.average = (stats.average * (stats.totalRequests - 1) + duration) / stats.totalRequests;\n\n // 更新最小/最大值\n if (stats.totalRequests === 1 || duration < stats.min) {\n stats.min = duration;\n }\n if (stats.totalRequests === 1 || duration > stats.max) {\n stats.max = duration;\n }\n\n // 计算百分位数(简化版本)\n const recentDurations = this.getMetrics('api_response_time', Date.now() - 300000) // 最近5分钟\n .map((m) => m.value)\n .sort((a, b) => a - b);\n\n if (recentDurations.length > 0) {\n stats.p95 = recentDurations[Math.floor(recentDurations.length * 0.95)] || 0;\n stats.p99 = recentDurations[Math.floor(recentDurations.length * 0.99)] || 0;\n }\n }\n\n /**\n * 更新上传统计信息\n */\n private updateUploadStats(success: boolean, duration: number, fileSize?: number): void {\n const uploads = this.stats.fileOperations.uploads;\n uploads.total++;\n\n if (success) {\n uploads.successful++;\n } else {\n uploads.failed++;\n }\n\n // 更新平均上传时间\n uploads.averageTime = (uploads.averageTime * (uploads.total - 1) + duration) / uploads.total;\n\n // 更新平均文件大小\n if (fileSize) {\n uploads.averageSize = (uploads.averageSize * (uploads.total - 1) + fileSize) / uploads.total;\n }\n }\n\n /**\n * 更新下载统计信息\n */\n private updateDownloadStats(success: boolean, duration: number): void {\n const downloads = this.stats.fileOperations.downloads;\n downloads.total++;\n\n if (success) {\n downloads.successful++;\n } else {\n downloads.failed++;\n }\n\n // 更新平均下载时间\n downloads.averageTime =\n (downloads.averageTime * (downloads.total - 1) + duration) / downloads.total;\n }\n\n /**\n * 清理过期数据\n */\n private cleanupOldData(): void {\n const oneHourAgo = Date.now() - 3600000; // 1小时前\n\n // 清理过期指标\n this.metrics = this.metrics.filter((m) => m.timestamp > oneHourAgo);\n\n // 清理过期跟踪\n for (const [requestId, trace] of this.requestTraces.entries()) {\n if (trace.startTime < oneHourAgo) {\n this.requestTraces.delete(requestId);\n }\n }\n }\n\n /**\n * 重置统计信息\n */\n reset(): void {\n this.metrics = [];\n this.requestTraces.clear();\n this.stats = this.initializeStats();\n }\n}\n\n/**\n * 单例性能监控器实例\n */\nexport const performanceMonitor = new PerformanceMonitor();\n\n/**\n * 性能监控装饰器\n */\nexport function measurePerformance(operation: string) {\n return function (_target: any, _propertyName: string, descriptor: PropertyDescriptor) {\n const method = descriptor.value;\n\n descriptor.value = async function (...args: any[]) {\n const requestId = (operation) + '_' + (Date.now()) + '_' + (Math.random().toString(36).substr(2, 9));\n\n try {\n performanceMonitor.startRequest(requestId, operation, 'INTERNAL');\n const result = await method.apply(this, args);\n performanceMonitor.endRequest(requestId, 200);\n return result;\n } catch (error) {\n performanceMonitor.endRequest(\n requestId,\n 500,\n error instanceof Error ? error.message : String(error)\n );\n throw error;\n }\n };\n\n return descriptor;\n };\n}\n","/**\n * CDN缓存策略管理\n * 优化静态资源缓存策略和预热机制\n */\n\n/**\n * 缓存策略类型\n */\nexport enum CacheStrategyType {\n /** 图片资源 */\n IMAGE = 'image',\n /** 视频资源 */\n VIDEO = 'video',\n /** 音频资源 */\n AUDIO = 'audio',\n /** 文档资源 */\n DOCUMENT = 'document',\n /** 压缩包 */\n ARCHIVE = 'archive',\n /** 静态资源 */\n STATIC = 'static',\n /** 其他 */\n OTHER = 'other',\n}\n\n/**\n * 缓存策略配置\n */\ninterface CacheStrategyConfig {\n /** 缓存策略类型 */\n type: CacheStrategyType;\n /** 缓存时间(秒) */\n ttl: number;\n /** 是否启用浏览器缓存 */\n browserCache: boolean;\n /** 浏览器缓存时间(秒) */\n browserCacheTtl: number;\n /** 是否启用CDN缓存 */\n cdnCache: boolean;\n /** CDN缓存时间(秒) */\n cdnCacheTtl: number;\n /** 是否启用预热 */\n enableWarmup: boolean;\n /** 缓存控制头 */\n cacheControl: string;\n /** 允许的文件类型 */\n allowedMimeTypes: string[];\n /** 文件大小限制(字节) */\n maxFileSize?: number;\n}\n\n/**\n * 缓存统计信息\n */\ninterface CacheStats {\n /** 命中次数 */\n hits: number;\n /** 未命中次数 */\n misses: number;\n /** 命中率 */\n hitRate: number;\n /** 总请求数 */\n totalRequests: number;\n /** 缓存大小估算 */\n estimatedSize: number;\n /** 节省的带宽(字节) */\n bandwidthSaved: number;\n}\n\n/**\n * CDN缓存策略管理器\n */\nexport class CdnCacheStrategy {\n private strategies: Map<CacheStrategyType, CacheStrategyConfig> = new Map();\n private stats: Map<CacheStrategyType, CacheStats> = new Map();\n\n constructor() {\n this.initializeDefaultStrategies();\n }\n\n /**\n * 初始化默认缓存策略\n */\n private initializeDefaultStrategies(): void {\n // 图片缓存策略\n this.strategies.set(CacheStrategyType.IMAGE, {\n type: CacheStrategyType.IMAGE,\n ttl: 30 * 24 * 3600, // 30天\n browserCache: true,\n browserCacheTtl: 7 * 24 * 3600, // 7天\n cdnCache: true,\n cdnCacheTtl: 30 * 24 * 3600, // 30天\n enableWarmup: true,\n cacheControl: 'public, max-age=604800, s-maxage=2592000',\n allowedMimeTypes: ['image/jpeg', 'image/png', 'image/gif', 'image/webp', 'image/svg+xml'],\n maxFileSize: 50 * 1024 * 1024, // 50MB\n });\n\n // 视频缓存策略\n this.strategies.set(CacheStrategyType.VIDEO, {\n type: CacheStrategyType.VIDEO,\n ttl: 7 * 24 * 3600, // 7天\n browserCache: true,\n browserCacheTtl: 24 * 3600, // 1天\n cdnCache: true,\n cdnCacheTtl: 7 * 24 * 3600, // 7天\n enableWarmup: false, // 视频文件通常较大,不预热\n cacheControl: 'public, max-age=86400, s-maxage=604800',\n allowedMimeTypes: ['video/mp4', 'video/avi', 'video/mov', 'video/wmv', 'video/webm'],\n maxFileSize: 500 * 1024 * 1024, // 500MB\n });\n\n // 音频缓存策略\n this.strategies.set(CacheStrategyType.AUDIO, {\n type: CacheStrategyType.AUDIO,\n ttl: 14 * 24 * 3600, // 14天\n browserCache: true,\n browserCacheTtl: 3 * 24 * 3600, // 3天\n cdnCache: true,\n cdnCacheTtl: 14 * 24 * 3600, // 14天\n enableWarmup: true,\n cacheControl: 'public, max-age=259200, s-maxage=1209600',\n allowedMimeTypes: ['audio/mpeg', 'audio/wav', 'audio/ogg', 'audio/m4a', 'audio/flac'],\n maxFileSize: 100 * 1024 * 1024, // 100MB\n });\n\n // 文档缓存策略\n this.strategies.set(CacheStrategyType.DOCUMENT, {\n type: CacheStrategyType.DOCUMENT,\n ttl: 24 * 3600, // 1天\n browserCache: true,\n browserCacheTtl: 3600, // 1小时\n cdnCache: true,\n cdnCacheTtl: 24 * 3600, // 1天\n enableWarmup: false,\n cacheControl: 'public, max-age=3600, s-maxage=86400',\n allowedMimeTypes: [\n 'application/pdf',\n 'application/msword',\n 'application/vnd.openxmlformats-officedocument.wordprocessingml.document',\n 'application/vnd.ms-excel',\n 'application/vnd.openxmlformats-officedocument.spreadsheetml.sheet',\n 'text/plain',\n 'text/csv',\n ],\n maxFileSize: 50 * 1024 * 1024, // 50MB\n });\n\n // 压缩包缓存策略\n this.strategies.set(CacheStrategyType.ARCHIVE, {\n type: CacheStrategyType.ARCHIVE,\n ttl: 24 * 3600, // 1天\n browserCache: true,\n browserCacheTtl: 1800, // 30分钟\n cdnCache: true,\n cdnCacheTtl: 24 * 3600, // 1天\n enableWarmup: false,\n cacheControl: 'public, max-age=1800, s-maxage=86400',\n allowedMimeTypes: [\n 'application/zip',\n 'application/x-rar-compressed',\n 'application/x-7z-compressed',\n 'application/gzip',\n 'application/x-tar',\n ],\n maxFileSize: 100 * 1024 * 1024, // 100MB\n });\n\n // 静态资源缓存策略\n this.strategies.set(CacheStrategyType.STATIC, {\n type: CacheStrategyType.STATIC,\n ttl: 365 * 24 * 3600, // 1年\n browserCache: true,\n browserCacheTtl: 30 * 24 * 3600, // 30天\n cdnCache: true,\n cdnCacheTtl: 365 * 24 * 3600, // 1年\n enableWarmup: true,\n cacheControl: 'public, max-age=2592000, s-maxage=31536000, immutable',\n allowedMimeTypes: [\n 'text/css',\n 'application/javascript',\n 'application/json',\n 'font/woff',\n 'font/woff2',\n 'font/ttf',\n ],\n maxFileSize: 10 * 1024 * 1024, // 10MB\n });\n\n // 其他文件缓存策略\n this.strategies.set(CacheStrategyType.OTHER, {\n type: CacheStrategyType.OTHER,\n ttl: 3600, // 1小时\n browserCache: true,\n browserCacheTtl: 300, // 5分钟\n cdnCache: false,\n cdnCacheTtl: 0,\n enableWarmup: false,\n cacheControl: 'public, max-age=300',\n allowedMimeTypes: [],\n maxFileSize: 10 * 1024 * 1024, // 10MB\n });\n\n // 初始化统计信息\n for (const type of Object.values(CacheStrategyType)) {\n this.stats.set(type, {\n hits: 0,\n misses: 0,\n hitRate: 0,\n totalRequests: 0,\n estimatedSize: 0,\n bandwidthSaved: 0,\n });\n }\n }\n\n /**\n * 根据MIME类型获取缓存策略\n */\n getStrategyByMimeType(mimeType: string): CacheStrategyConfig {\n for (const [type, strategy] of this.strategies.entries()) {\n if (strategy.allowedMimeTypes.includes(mimeType)) {\n return strategy;\n }\n }\n\n // 根据MIME类型推断策略\n if (mimeType.startsWith('image/')) {\n return this.strategies.get(CacheStrategyType.IMAGE)!;\n } else if (mimeType.startsWith('video/')) {\n return this.strategies.get(CacheStrategyType.VIDEO)!;\n } else if (mimeType.startsWith('audio/')) {\n return this.strategies.get(CacheStrategyType.AUDIO)!;\n } else if (\n mimeType.includes('pdf') ||\n mimeType.includes('document') ||\n mimeType.includes('word') ||\n mimeType.includes('excel')\n ) {\n return this.strategies.get(CacheStrategyType.DOCUMENT)!;\n } else if (\n mimeType.includes('zip') ||\n mimeType.includes('compressed') ||\n mimeType.includes('archive')\n ) {\n return this.strategies.get(CacheStrategyType.ARCHIVE)!;\n }\n\n return this.strategies.get(CacheStrategyType.OTHER)!;\n }\n\n /**\n * 生成缓存控制头\n */\n generateCacheHeaders(mimeType: string, fileSize?: number): Record<string, string> {\n const strategy = this.getStrategyByMimeType(mimeType);\n\n // 检查文件大小限制\n if (fileSize && strategy.maxFileSize && fileSize > strategy.maxFileSize) {\n // 大文件使用更短的缓存时间\n return {\n 'Cache-Control': 'public, max-age=300', // 5分钟\n Expires: new Date(Date.now() + 300 * 1000).toUTCString(),\n };\n }\n\n const headers: Record<string, string> = {\n 'Cache-Control': strategy.cacheControl,\n Expires: new Date(Date.now() + strategy.browserCacheTtl * 1000).toUTCString(),\n };\n\n // 添加ETag用于缓存验证\n if (strategy.browserCache) {\n headers['ETag'] = '\"' + (Date.now()) + '\"';\n }\n\n // 添加Last-Modified头\n headers['Last-Modified'] = new Date().toUTCString();\n\n // 为静态资源添加不可变标记\n if (strategy.type === CacheStrategyType.STATIC) {\n headers['Cache-Control'] += ', immutable';\n }\n\n return headers;\n }\n\n /**\n * 检查是否需要缓存预热\n */\n shouldWarmupCache(mimeType: string): boolean {\n const strategy = this.getStrategyByMimeType(mimeType);\n return strategy.enableWarmup;\n }\n\n /**\n * 记录缓存命中\n */\n recordCacheHit(mimeType: string, fileSize: number = 0): void {\n const strategy = this.getStrategyByMimeType(mimeType);\n const stats = this.stats.get(strategy.type);\n\n if (stats) {\n stats.hits++;\n stats.totalRequests++;\n stats.bandwidthSaved += fileSize;\n stats.hitRate = (stats.hits / stats.totalRequests) * 100;\n }\n }\n\n /**\n * 记录缓存未命中\n */\n recordCacheMiss(mimeType: string, fileSize: number = 0): void {\n const strategy = this.getStrategyByMimeType(mimeType);\n const stats = this.stats.get(strategy.type);\n\n if (stats) {\n stats.misses++;\n stats.totalRequests++;\n stats.estimatedSize += fileSize;\n stats.hitRate = (stats.hits / stats.totalRequests) * 100;\n }\n }\n\n /**\n * 获取缓存统计信息\n */\n getCacheStats(): Map<CacheStrategyType, CacheStats> {\n return new Map(this.stats);\n }\n\n /**\n * 获取总体缓存统计\n */\n getOverallStats(): CacheStats {\n const overall: CacheStats = {\n hits: 0,\n misses: 0,\n hitRate: 0,\n totalRequests: 0,\n estimatedSize: 0,\n bandwidthSaved: 0,\n };\n\n for (const stats of this.stats.values()) {\n overall.hits += stats.hits;\n overall.misses += stats.misses;\n overall.totalRequests += stats.totalRequests;\n overall.estimatedSize += stats.estimatedSize;\n overall.bandwidthSaved += stats.bandwidthSaved;\n }\n\n overall.hitRate = overall.totalRequests > 0 ? (overall.hits / overall.totalRequests) * 100 : 0;\n\n return overall;\n }\n\n /**\n * 生成缓存优化建议\n */\n generateOptimizationSuggestions(): Array<{\n type: CacheStrategyType;\n issue: string;\n suggestion: string;\n severity: 'low' | 'medium' | 'high';\n }> {\n const suggestions: Array<{\n type: CacheStrategyType;\n issue: string;\n suggestion: string;\n severity: 'low' | 'medium' | 'high';\n }> = [];\n\n for (const [type, stats] of this.stats.entries()) {\n if (stats.totalRequests > 100) {\n // 只对有足够请求量的资源类型分析\n // 命中率过低\n if (stats.hitRate < 60) {\n suggestions.push({\n type,\n issue: (type) + '类型文件缓存命中率过低 (' + (stats.hitRate.toFixed(1)) + '%)',\n suggestion: '考虑增加缓存时间或启用预热机制',\n severity: stats.hitRate < 30 ? 'high' : 'medium',\n });\n }\n\n // 缓存大小过大\n if (stats.estimatedSize > 1024 * 1024 * 1024) {\n // 1GB\n suggestions.push({\n type,\n issue: (type) + '类型文件缓存占用空间过大 (' + ((stats.estimatedSize / 1024 / 1024 / 1024).toFixed(2)) + 'GB)',\n suggestion: '考虑减少缓存时间或优化文件压缩',\n severity: 'medium',\n });\n }\n }\n }\n\n return suggestions;\n }\n\n /**\n * 更新缓存策略\n */\n updateStrategy(type: CacheStrategyType, config: Partial<CacheStrategyConfig>): void {\n const currentStrategy = this.strategies.get(type);\n if (currentStrategy) {\n this.strategies.set(type, { ...currentStrategy, ...config });\n }\n }\n\n /**\n * 重置统计信息\n */\n resetStats(): void {\n for (const type of Object.values(CacheStrategyType)) {\n this.stats.set(type, {\n hits: 0,\n misses: 0,\n hitRate: 0,\n totalRequests: 0,\n estimatedSize: 0,\n bandwidthSaved: 0,\n });\n }\n }\n}\n\n/**\n * 单例CDN缓存策略管理器\n */\nexport const cdnCacheStrategy = new CdnCacheStrategy();\n","/**\n * 通用文件服务 API 类型定义\n * 定义所有API接口的请求和响应格式\n */\n\n// ========== 基础响应格式 ==========\n\n/**\n * API响应的基础接口\n */\nexport interface ApiResponse<T = any> {\n /** 是否成功 */\n success: boolean;\n /** 响应数据 */\n data?: T;\n /** 错误信息 */\n error?: {\n /** 错误代码 */\n code: string;\n /** 错误消息 */\n message: string;\n /** 详细错误信息 */\n details?: any;\n };\n /** 元数据 */\n meta?: {\n /** 总记录数 */\n total?: number;\n /** 当前页码 */\n page?: number;\n /** 每页大小 */\n pageSize?: number;\n /** 总页数 */\n totalPages?: number;\n /** 请求ID */\n requestId?: string;\n /** 时间戳 */\n timestamp?: string;\n };\n}\n\n/**\n * 分页查询参数\n */\nexport interface PaginationParams {\n /** 页码,从1开始 */\n page?: number;\n /** 每页大小 */\n pageSize?: number;\n /** 排序字段 */\n orderBy?: string;\n /** 排序方向 */\n orderDirection?: 'asc' | 'desc';\n}\n\n/**\n * 文件上传响应\n */\nexport interface UploadResponse {\n /** 文件ID */\n fileId: string;\n /** 原始文件名 */\n originalName: string;\n /** 文件大小 */\n size: number;\n /** MIME类型 */\n mimeType: string;\n /** 访问URL */\n url: string;\n /** CDN URL */\n cdnUrl?: string;\n /** MD5哈希 */\n md5Hash: string;\n /** 上传时间 */\n uploadTime: string;\n}\n\n// ========== 文件管理API ==========\n\n/**\n * 文件上传请求参数\n */\nexport interface FileUploadParams {\n /** 目标文件夹ID */\n folderId?: string;\n /** 模块ID */\n moduleId?: string;\n /** 业务ID */\n businessId?: string;\n /** 文件标签 */\n tags?: string[];\n /** 是否为临时文件 */\n isTemporary?: boolean;\n /** 过期时间 */\n expiresAt?: string;\n /** 自定义元数据 */\n metadata?: Record<string, any>;\n}\n\n/**\n * 文件查询参数\n */\nexport interface FileQueryParams extends PaginationParams {\n /** 模块ID */\n moduleId?: string;\n /** 业务ID */\n businessId?: string;\n /** 文件夹ID */\n folderId?: string;\n /** MIME类型过滤 */\n mimeType?: string;\n /** 文件名搜索 */\n search?: string;\n /** 标签过滤 */\n tags?: string[];\n /** 文件大小范围 */\n sizeMin?: number;\n sizeMax?: number;\n /** 上传时间范围 */\n uploadTimeStart?: string;\n uploadTimeEnd?: string;\n /** 是否已删除 */\n isDeleted?: boolean;\n /** 是否临时文件 */\n isTemporary?: boolean;\n /** 上传者ID */\n uploaderId?: string;\n}\n\n/**\n * 文件信息响应\n */\nexport interface FileInfo {\n /** 文件ID */\n id: string;\n /** 原始文件名 */\n originalName: string;\n /** 存储文件名 */\n storedName: string;\n /** 文件扩展名 */\n extension?: string;\n /** MIME类型 */\n mimeType: string;\n /** 文件大小 */\n size: number;\n /** MD5哈希 */\n md5Hash: string;\n /** SHA256哈希 */\n sha256Hash?: string;\n /** 存储路径 */\n storagePath: string;\n /** CDN访问URL */\n cdnUrl?: string;\n /** 所属文件夹ID */\n folderId?: string;\n /** 模块ID */\n moduleId?: string;\n /** 业务ID */\n businessId?: string;\n /** 文件标签 */\n tags?: string[];\n /** 文件元信息 */\n metadata?: Record<string, any>;\n /** 是否为临时文件 */\n isTemporary: boolean;\n /** 是否已删除 */\n isDeleted: boolean;\n /** 访问次数 */\n accessCount: number;\n /** 下载次数 */\n downloadCount: number;\n /** 上传者ID */\n uploaderId: string;\n /** 上传时间 */\n uploadTime: string;\n /** 最后访问时间 */\n lastAccessTime?: string;\n /** 过期时间 */\n expiresAt?: string;\n /** 创建时间 */\n createdAt: string;\n /** 更新时间 */\n updatedAt: string;\n}\n\n/**\n * 文件列表响应\n */\nexport interface FileListResponse {\n /** 文件列表 */\n files: FileInfo[];\n /** 分页信息 */\n pagination: {\n /** 总记录数 */\n total: number;\n /** 当前页码 */\n page: number;\n /** 每页大小 */\n pageSize: number;\n /** 总页数 */\n totalPages: number;\n };\n}\n\n/**\n * 文件更新参数\n */\nexport interface FileUpdateParams {\n /** 新的文件名 */\n originalName?: string;\n /** 文件夹ID */\n folderId?: string;\n /** 文件标签 */\n tags?: string[];\n /** 自定义元数据 */\n metadata?: Record<string, any>;\n /** 过期时间 */\n expiresAt?: string;\n}\n\n// ========== 文件夹管理API ==========\n\n/**\n * 文件夹创建参数\n */\nexport interface FolderCreateParams {\n /** 文件夹名称 */\n name: string;\n /** 父文件夹ID */\n parentId?: string;\n /** 模块ID */\n moduleId?: string;\n /** 业务ID */\n businessId?: string;\n /** 文件夹描述 */\n description?: string;\n /** 显示顺序 */\n sortOrder?: number;\n}\n\n/**\n * 文件夹信息响应\n */\nexport interface FolderInfo {\n /** 文件夹ID */\n id: string;\n /** 文件夹名称 */\n name: string;\n /** 父文件夹ID */\n parentId?: string;\n /** 模块ID */\n moduleId?: string;\n /** 业务ID */\n businessId?: string;\n /** 文件夹路径 */\n path: string;\n /** 层级深度 */\n depth: number;\n /** 显示顺序 */\n sortOrder: number;\n /** 文件夹描述 */\n description?: string;\n /** 是否为系统文件夹 */\n isSystem: boolean;\n /** 创建者ID */\n createdBy: string;\n /** 创建时间 */\n createdAt: string;\n /** 更新时间 */\n updatedAt: string;\n /** 子文件夹列表 */\n children?: FolderInfo[];\n /** 文件数量 */\n fileCount?: number;\n}\n\n/**\n * 文件夹更新参数\n */\nexport interface FolderUpdateParams {\n /** 文件夹名称 */\n name?: string;\n /** 父文件夹ID */\n parentId?: string;\n /** 文件夹描述 */\n description?: string;\n /** 显示顺序 */\n sortOrder?: number;\n}\n\n// ========== 文件处理API ==========\n\n/**\n * 文件处理请求参数\n */\nexport interface FileProcessParams {\n /** 处理类型 */\n type: 'compress' | 'resize' | 'convert' | 'thumbnail' | 'watermark';\n /** 处理参数 */\n parameters: Record<string, any>;\n /** 优先级 */\n priority?: number;\n}\n\n/**\n * 文件处理状态响应\n */\nexport interface ProcessingStatus {\n /** 处理记录ID */\n id: string;\n /** 文件ID */\n fileId: string;\n /** 处理类型 */\n type: string;\n /** 处理状态 */\n status: 'pending' | 'processing' | 'completed' | 'failed';\n /** 处理进度 */\n progress?: number;\n /** 处理参数 */\n parameters?: Record<string, any>;\n /** 处理结果 */\n result?: Record<string, any>;\n /** 输出文件路径 */\n outputPath?: string;\n /** 错误信息 */\n errorMessage?: string;\n /** 开始时间 */\n startedAt?: string;\n /** 完成时间 */\n completedAt?: string;\n /** 创建时间 */\n createdAt: string;\n}\n\n// ========== 文件分享API ==========\n\n/**\n * 文件分享创建参数\n */\nexport interface ShareCreateParams {\n /** 分享的文件ID列表 */\n fileIds: string[];\n /** 分享标题 */\n title?: string;\n /** 分享描述 */\n description?: string;\n /** 访问密码 */\n password?: string;\n /** 访问权限 */\n permission?: 'view' | 'download';\n /** 最大下载次数 */\n maxDownloads?: number;\n /** 最大访问次数 */\n maxAccess?: number;\n /** 过期时间 */\n expiresAt?: string;\n}\n\n/**\n * 文件分享信息响应\n */\nexport interface ShareInfo {\n /** 分享ID */\n id: string;\n /** 分享代码 */\n shareCode: string;\n /** 分享的文件ID列表 */\n fileIds: string[];\n /** 分享标题 */\n title?: string;\n /** 分享描述 */\n description?: string;\n /** 是否有密码保护 */\n hasPassword: boolean;\n /** 访问权限 */\n permission: 'view' | 'download';\n /** 最大下载次数 */\n maxDownloads?: number;\n /** 当前下载次数 */\n downloadCount: number;\n /** 最大访问次数 */\n maxAccess?: number;\n /** 当前访问次数 */\n accessCount: number;\n /** 是否启用 */\n isActive: boolean;\n /** 过期时间 */\n expiresAt?: string;\n /** 创建者ID */\n createdBy: string;\n /** 创建时间 */\n createdAt: string;\n /** 分享链接 */\n shareUrl: string;\n}\n\n/**\n * 分享访问验证参数\n */\nexport interface ShareAccessParams {\n /** 分享代码 */\n shareCode: string;\n /** 访问密码 */\n password?: string;\n}\n\n// ========== 统计API ==========\n\n/**\n * 文件统计信息响应\n */\nexport interface FileStats {\n /** 总文件数 */\n totalFiles: number;\n /** 总文件大小 */\n totalSize: number;\n /** 按类型统计 */\n byType: Array<{\n /** MIME类型 */\n mimeType: string;\n /** 文件数量 */\n count: number;\n /** 总大小 */\n totalSize: number;\n }>;\n /** 按日期统计(最近30天) */\n byDate: Array<{\n /** 日期 */\n date: string;\n /** 上传数量 */\n count: number;\n /** 总大小 */\n totalSize: number;\n }>;\n /** 按模块统计 */\n byModule: Array<{\n /** 模块ID */\n moduleId: string;\n /** 文件数量 */\n count: number;\n /** 总大小 */\n totalSize: number;\n }>;\n}\n\n// ========== 错误代码定义 ==========\n\n/**\n * API错误代码枚举\n */\nexport enum ApiErrorCode {\n // 通用错误\n UNKNOWN_ERROR = 'UNKNOWN_ERROR',\n VALIDATION_ERROR = 'VALIDATION_ERROR',\n AUTHENTICATION_ERROR = 'AUTHENTICATION_ERROR',\n AUTHORIZATION_ERROR = 'AUTHORIZATION_ERROR',\n NOT_FOUND = 'NOT_FOUND',\n CONFLICT = 'CONFLICT',\n RATE_LIMIT_EXCEEDED = 'RATE_LIMIT_EXCEEDED',\n\n // 文件相关错误\n FILE_NOT_FOUND = 'FILE_NOT_FOUND',\n FILE_TOO_LARGE = 'FILE_TOO_LARGE',\n FILE_TYPE_NOT_SUPPORTED = 'FILE_TYPE_NOT_SUPPORTED',\n FILE_UPLOAD_FAILED = 'FILE_UPLOAD_FAILED',\n FILE_PROCESSING_FAILED = 'FILE_PROCESSING_FAILED',\n FILE_ALREADY_EXISTS = 'FILE_ALREADY_EXISTS',\n FILE_CORRUPTED = 'FILE_CORRUPTED',\n\n // 文件夹相关错误\n FOLDER_NOT_FOUND = 'FOLDER_NOT_FOUND',\n FOLDER_NOT_EMPTY = 'FOLDER_NOT_EMPTY',\n FOLDER_NAME_CONFLICT = 'FOLDER_NAME_CONFLICT',\n FOLDER_DEPTH_EXCEEDED = 'FOLDER_DEPTH_EXCEEDED',\n\n // 存储相关错误\n STORAGE_PROVIDER_ERROR = 'STORAGE_PROVIDER_ERROR',\n STORAGE_QUOTA_EXCEEDED = 'STORAGE_QUOTA_EXCEEDED',\n STORAGE_UNAVAILABLE = 'STORAGE_UNAVAILABLE',\n\n // 分享相关错误\n SHARE_NOT_FOUND = 'SHARE_NOT_FOUND',\n SHARE_EXPIRED = 'SHARE_EXPIRED',\n SHARE_PASSWORD_INCORRECT = 'SHARE_PASSWORD_INCORRECT',\n SHARE_ACCESS_DENIED = 'SHARE_ACCESS_DENIED',\n SHARE_DOWNLOAD_LIMIT_EXCEEDED = 'SHARE_DOWNLOAD_LIMIT_EXCEEDED',\n}\n\n/**\n * 错误消息映射\n */\nexport const ErrorMessages: Record<ApiErrorCode, string> = {\n [ApiErrorCode.UNKNOWN_ERROR]: '未知错误',\n [ApiErrorCode.VALIDATION_ERROR]: '参数验证失败',\n [ApiErrorCode.AUTHENTICATION_ERROR]: '身份验证失败',\n [ApiErrorCode.AUTHORIZATION_ERROR]: '权限不足',\n [ApiErrorCode.NOT_FOUND]: '资源不存在',\n [ApiErrorCode.CONFLICT]: '资源冲突',\n [ApiErrorCode.RATE_LIMIT_EXCEEDED]: '请求频率超限',\n\n [ApiErrorCode.FILE_NOT_FOUND]: '文件不存在',\n [ApiErrorCode.FILE_TOO_LARGE]: '文件过大',\n [ApiErrorCode.FILE_TYPE_NOT_SUPPORTED]: '不支持的文件类型',\n [ApiErrorCode.FILE_UPLOAD_FAILED]: '文件上传失败',\n [ApiErrorCode.FILE_PROCESSING_FAILED]: '文件处理失败',\n [ApiErrorCode.FILE_ALREADY_EXISTS]: '文件已存在',\n [ApiErrorCode.FILE_CORRUPTED]: '文件已损坏',\n\n [ApiErrorCode.FOLDER_NOT_FOUND]: '文件夹不存在',\n [ApiErrorCode.FOLDER_NOT_EMPTY]: '文件夹不为空',\n [ApiErrorCode.FOLDER_NAME_CONFLICT]: '文件夹名称冲突',\n [ApiErrorCode.FOLDER_DEPTH_EXCEEDED]: '文件夹层级过深',\n\n [ApiErrorCode.STORAGE_PROVIDER_ERROR]: '存储服务错误',\n [ApiErrorCode.STORAGE_QUOTA_EXCEEDED]: '存储配额已满',\n [ApiErrorCode.STORAGE_UNAVAILABLE]: '存储服务不可用',\n\n [ApiErrorCode.SHARE_NOT_FOUND]: '分享不存在',\n [ApiErrorCode.SHARE_EXPIRED]: '分享已过期',\n [ApiErrorCode.SHARE_PASSWORD_INCORRECT]: '分享密码错误',\n [ApiErrorCode.SHARE_ACCESS_DENIED]: '分享访问被拒绝',\n [ApiErrorCode.SHARE_DOWNLOAD_LIMIT_EXCEEDED]: '分享下载次数已达上限',\n};\n\n// ========== HTTP状态码映射 ==========\n\n/**\n * 错误代码到HTTP状态码的映射\n */\nexport const ErrorHttpStatusMap: Record<ApiErrorCode, number> = {\n [ApiErrorCode.UNKNOWN_ERROR]: 500,\n [ApiErrorCode.VALIDATION_ERROR]: 400,\n [ApiErrorCode.AUTHENTICATION_ERROR]: 401,\n [ApiErrorCode.AUTHORIZATION_ERROR]: 403,\n [ApiErrorCode.NOT_FOUND]: 404,\n [ApiErrorCode.CONFLICT]: 409,\n [ApiErrorCode.RATE_LIMIT_EXCEEDED]: 429,\n\n [ApiErrorCode.FILE_NOT_FOUND]: 404,\n [ApiErrorCode.FILE_TOO_LARGE]: 413,\n [ApiErrorCode.FILE_TYPE_NOT_SUPPORTED]: 415,\n [ApiErrorCode.FILE_UPLOAD_FAILED]: 500,\n [ApiErrorCode.FILE_PROCESSING_FAILED]: 500,\n [ApiErrorCode.FILE_ALREADY_EXISTS]: 409,\n [ApiErrorCode.FILE_CORRUPTED]: 422,\n\n [ApiErrorCode.FOLDER_NOT_FOUND]: 404,\n [ApiErrorCode.FOLDER_NOT_EMPTY]: 409,\n [ApiErrorCode.FOLDER_NAME_CONFLICT]: 409,\n [ApiErrorCode.FOLDER_DEPTH_EXCEEDED]: 400,\n\n [ApiErrorCode.STORAGE_PROVIDER_ERROR]: 502,\n [ApiErrorCode.STORAGE_QUOTA_EXCEEDED]: 507,\n [ApiErrorCode.STORAGE_UNAVAILABLE]: 503,\n\n [ApiErrorCode.SHARE_NOT_FOUND]: 404,\n [ApiErrorCode.SHARE_EXPIRED]: 410,\n [ApiErrorCode.SHARE_PASSWORD_INCORRECT]: 401,\n [ApiErrorCode.SHARE_ACCESS_DENIED]: 403,\n [ApiErrorCode.SHARE_DOWNLOAD_LIMIT_EXCEEDED]: 429,\n};\n","// @ts-nocheck\n/**\n * API错误处理工具类\n * 提供标准化的错误处理和响应格式\n */\n\nimport { NextResponse } from 'next/server';\nimport { ApiResponse, ApiErrorCode, ErrorMessages, ErrorHttpStatusMap } from '../types/api';\n\n/**\n * API错误类\n * 继承自Error,添加错误代码和详细信息\n */\nexport class ApiError extends Error {\n public readonly code: ApiErrorCode;\n public readonly statusCode: number;\n public readonly details?: any;\n\n constructor(code: ApiErrorCode, message?: string, details?: any, statusCode?: number) {\n super(message || ErrorMessages[code]);\n this.name = 'ApiError';\n this.code = code;\n this.statusCode = statusCode || ErrorHttpStatusMap[code] || 500;\n this.details = details;\n\n // 确保错误堆栈正确显示\n if (Error.captureStackTrace) {\n Error.captureStackTrace(this, ApiError);\n }\n }\n\n /**\n * 转换为API响应格式\n */\n toApiResponse(): ApiResponse {\n return {\n success: false,\n error: {\n code: this.code,\n message: this.message,\n details: this.details,\n },\n meta: {\n timestamp: new Date().toISOString(),\n },\n };\n }\n\n /**\n * 转换为NextResponse\n */\n toNextResponse(): NextResponse {\n return NextResponse.json(this.toApiResponse(), {\n status: this.statusCode,\n });\n }\n}\n\n/**\n * API错误工厂类\n * 提供便捷的错误创建方法\n */\nexport class ApiErrorFactory {\n /**\n * 创建文件不存在错误\n */\n static fileNotFound(fileId?: string): ApiError {\n return new ApiError(ApiErrorCode.FILE_NOT_FOUND, undefined, { fileId });\n }\n\n /**\n * 创建文件过大错误\n */\n static fileTooLarge(maxSize: number, actualSize: number): ApiError {\n return new ApiError(\n ApiErrorCode.FILE_TOO_LARGE,\n '文件大小 ' + (actualSize) + ' 字节超过限制 ' + (maxSize) + ' 字节',\n { maxSize, actualSize }\n );\n }\n\n /**\n * 创建不支持的文件类型错误\n */\n static fileTypeNotSupported(mimeType: string, supportedTypes?: string[]): ApiError {\n return new ApiError(ApiErrorCode.FILE_TYPE_NOT_SUPPORTED, '不支持的文件类型: ' + (mimeType), {\n mimeType,\n supportedTypes,\n });\n }\n\n /**\n * 创建文件上传失败错误\n */\n static fileUploadFailed(reason?: string): ApiError {\n return new ApiError(\n ApiErrorCode.FILE_UPLOAD_FAILED,\n reason ? '文件上传失败: ' + (reason) : undefined,\n { reason }\n );\n }\n\n /**\n * 创建文件夹不存在错误\n */\n static folderNotFound(folderId?: string): ApiError {\n return new ApiError(ApiErrorCode.FOLDER_NOT_FOUND, undefined, { folderId });\n }\n\n /**\n * 创建文件夹不为空错误\n */\n static folderNotEmpty(folderId: string, fileCount: number, subfolderCount: number): ApiError {\n return new ApiError(\n ApiErrorCode.FOLDER_NOT_EMPTY,\n '文件夹包含 ' + (fileCount) + ' 个文件和 ' + (subfolderCount) + ' 个子文件夹',\n { folderId, fileCount, subfolderCount }\n );\n }\n\n /**\n * 创建参数验证错误\n */\n static validationError(field: string, value: any, rule: string): ApiError {\n return new ApiError(ApiErrorCode.VALIDATION_ERROR, '字段 ' + (field) + ' 验证失败: ' + (rule), {\n field,\n value,\n rule,\n });\n }\n\n /**\n * 创建身份验证错误\n */\n static authenticationError(reason?: string): ApiError {\n return new ApiError(\n ApiErrorCode.AUTHENTICATION_ERROR,\n reason ? '身份验证失败: ' + (reason) : undefined,\n { reason }\n );\n }\n\n /**\n * 创建权限不足错误\n */\n static authorizationError(resource?: string, action?: string): ApiError {\n return new ApiError(\n ApiErrorCode.AUTHORIZATION_ERROR,\n resource && action ? '无权限对 ' + (resource) + ' 执行 ' + (action) + ' 操作' : undefined,\n { resource, action }\n );\n }\n\n /**\n * 创建资源冲突错误\n */\n static conflict(resource: string, reason?: string): ApiError {\n return new ApiError(\n ApiErrorCode.CONFLICT,\n reason ? (resource) + ' 冲突: ' + (reason) : (resource) + ' 已存在',\n { resource, reason }\n );\n }\n\n /**\n * 创建请求频率超限错误\n */\n static rateLimitExceeded(limit: number, windowMs: number): ApiError {\n return new ApiError(\n ApiErrorCode.RATE_LIMIT_EXCEEDED,\n '请求频率超限,' + (windowMs) + 'ms 内最多允许 ' + (limit) + ' 次请求',\n { limit, windowMs }\n );\n }\n\n /**\n * 创建存储服务错误\n */\n static storageProviderError(provider: string, reason?: string): ApiError {\n return new ApiError(\n ApiErrorCode.STORAGE_PROVIDER_ERROR,\n reason ? '存储服务 ' + (provider) + ' 错误: ' + (reason) : '存储服务 ' + (provider) + ' 不可用',\n { provider, reason }\n );\n }\n\n /**\n * 创建存储配额已满错误\n */\n static storageQuotaExceeded(used: number, limit: number): ApiError {\n return new ApiError(\n ApiErrorCode.STORAGE_QUOTA_EXCEEDED,\n '存储空间已满,已使用 ' + (used) + ' 字节,限制 ' + (limit) + ' 字节',\n { used, limit, remaining: Math.max(0, limit - used) }\n );\n }\n\n /**\n * 创建分享不存在错误\n */\n static shareNotFound(shareCode?: string): ApiError {\n return new ApiError(ApiErrorCode.SHARE_NOT_FOUND, undefined, { shareCode });\n }\n\n /**\n * 创建分享已过期错误\n */\n static shareExpired(shareCode: string, expiredAt: string): ApiError {\n return new ApiError(ApiErrorCode.SHARE_EXPIRED, '分享已于 ' + (expiredAt) + ' 过期', {\n shareCode,\n expiredAt,\n });\n }\n\n /**\n * 创建分享密码错误\n */\n static sharePasswordIncorrect(shareCode: string): ApiError {\n return new ApiError(ApiErrorCode.SHARE_PASSWORD_INCORRECT, undefined, { shareCode });\n }\n\n /**\n * 创建分享下载次数超限错误\n */\n static shareDownloadLimitExceeded(shareCode: string, maxDownloads: number): ApiError {\n return new ApiError(\n ApiErrorCode.SHARE_DOWNLOAD_LIMIT_EXCEEDED,\n '分享下载次数已达上限 ' + (maxDownloads) + ' 次',\n { shareCode, maxDownloads }\n );\n }\n}\n\n/**\n * API响应工具类\n * 提供标准化的成功响应格式\n */\nexport class ApiResponseHelper {\n /**\n * 创建成功响应\n */\n static success<T>(\n data?: T,\n meta?: {\n total?: number;\n page?: number;\n pageSize?: number;\n totalPages?: number;\n requestId?: string;\n }\n ): ApiResponse<T> {\n return {\n success: true,\n data,\n meta: {\n ...meta,\n timestamp: new Date().toISOString(),\n },\n };\n }\n\n /**\n * 创建分页响应\n */\n static paginated<T>(\n data: T[],\n total: number,\n page: number,\n pageSize: number,\n requestId?: string\n ): ApiResponse<{ items: T[]; pagination: any }> {\n const totalPages = Math.ceil(total / pageSize);\n\n return {\n success: true,\n data: {\n items: data,\n pagination: {\n total,\n page,\n pageSize,\n totalPages,\n hasNext: page < totalPages,\n hasPrev: page > 1,\n },\n },\n meta: {\n total,\n page,\n pageSize,\n totalPages,\n requestId,\n timestamp: new Date().toISOString(),\n },\n };\n }\n\n /**\n * 创建空响应\n */\n static empty(requestId?: string): ApiResponse<null> {\n return {\n success: true,\n data: null,\n meta: {\n requestId,\n timestamp: new Date().toISOString(),\n },\n };\n }\n\n /**\n * 转换为NextResponse\n */\n static toNextResponse<T>(response: ApiResponse<T>, status: number = 200): NextResponse {\n return NextResponse.json(response, { status });\n }\n}\n\n/**\n * 错误处理中间件装饰器\n */\nexport function withErrorHandler<T extends any[], R>(\n fn: (...args: T) => Promise<R>\n): (...args: T) => Promise<R> {\n return async (...args: T): Promise<R> => {\n try {\n return await fn(...args);\n } catch (error) {\n // 如果已经是ApiError,直接抛出\n if (error instanceof ApiError) {\n throw error;\n }\n\n // 处理常见的系统错误\n if (error instanceof Error) {\n // 数据库连接错误\n if (error.message.includes('connect') || error.message.includes('connection')) {\n throw new ApiError(ApiErrorCode.STORAGE_UNAVAILABLE, '数据库连接失败', {\n originalError: error.message,\n });\n }\n\n // 文件系统错误\n if (error.message.includes('ENOENT')) {\n throw new ApiError(ApiErrorCode.FILE_NOT_FOUND, '文件不存在', {\n originalError: error.message,\n });\n }\n\n if (error.message.includes('EACCES') || error.message.includes('permission')) {\n throw new ApiError(ApiErrorCode.AUTHORIZATION_ERROR, '文件权限不足', {\n originalError: error.message,\n });\n }\n\n if (error.message.includes('ENOSPC')) {\n throw new ApiError(ApiErrorCode.STORAGE_QUOTA_EXCEEDED, '磁盘空间不足', {\n originalError: error.message,\n });\n }\n }\n\n // 其他未知错误\n throw new ApiError(ApiErrorCode.UNKNOWN_ERROR, '服务器内部错误', {\n originalError: error instanceof Error ? error.message : String(error),\n });\n }\n };\n}\n\n/**\n * 异步错误处理包装器\n */\nexport function handleAsyncError(\n handler: (req: Request, ...args: any[]) => Promise<NextResponse>\n): (req: Request, ...args: any[]) => Promise<NextResponse> {\n return async (req: Request, ...args: any[]): Promise<NextResponse> => {\n try {\n return await handler(req, ...args);\n } catch (error) {\n console.error('API Error:', error);\n\n if (error instanceof ApiError) {\n return error.toNextResponse();\n }\n\n // 未知错误\n const apiError = new ApiError(ApiErrorCode.UNKNOWN_ERROR, '服务器内部错误', {\n originalError: error instanceof Error ? error.message : String(error),\n });\n\n return apiError.toNextResponse();\n }\n };\n}\n\n/**\n * 参数验证工具\n */\nexport class ValidationHelper {\n /**\n * 验证必填参数\n */\n static required(value: any, fieldName: string): void {\n if (value === undefined || value === null || value === '') {\n throw ApiErrorFactory.validationError(fieldName, value, '不能为空');\n }\n }\n\n /**\n * 验证字符串长度\n */\n static stringLength(value: string, fieldName: string, min?: number, max?: number): void {\n if (min !== undefined && value.length < min) {\n throw ApiErrorFactory.validationError(fieldName, value, '长度不能少于' + (min) + '个字符');\n }\n if (max !== undefined && value.length > max) {\n throw ApiErrorFactory.validationError(fieldName, value, '长度不能超过' + (max) + '个字符');\n }\n }\n\n /**\n * 验证数字范围\n */\n static numberRange(value: number, fieldName: string, min?: number, max?: number): void {\n if (min !== undefined && value < min) {\n throw ApiErrorFactory.validationError(fieldName, value, '不能小于' + (min));\n }\n if (max !== undefined && value > max) {\n throw ApiErrorFactory.validationError(fieldName, value, '不能大于' + (max));\n }\n }\n\n /**\n * 验证数组长度\n */\n static arrayLength(value: any[], fieldName: string, min?: number, max?: number): void {\n if (min !== undefined && value.length < min) {\n throw ApiErrorFactory.validationError(fieldName, value, '数组长度不能少于' + (min));\n }\n if (max !== undefined && value.length > max) {\n throw ApiErrorFactory.validationError(fieldName, value, '数组长度不能超过' + (max));\n }\n }\n\n /**\n * 验证文件类型\n */\n static fileType(mimeType: string, allowedTypes: string[]): void {\n if (!allowedTypes.includes(mimeType)) {\n throw ApiErrorFactory.fileTypeNotSupported(mimeType, allowedTypes);\n }\n }\n\n /**\n * 验证文件大小\n */\n static fileSize(size: number, maxSize: number): void {\n if (size > maxSize) {\n throw ApiErrorFactory.fileTooLarge(maxSize, size);\n }\n }\n\n /**\n * 验证UUID格式\n */\n static uuid(value: string, fieldName: string): void {\n const uuidRegex = /^[0-9a-f]{8}-[0-9a-f]{4}-[1-5][0-9a-f]{3}-[89ab][0-9a-f]{3}-[0-9a-f]{12}$/i;\n if (!uuidRegex.test(value)) {\n throw ApiErrorFactory.validationError(fieldName, value, '必须是有效的UUID格式');\n }\n }\n\n /**\n * 验证邮箱格式\n */\n static email(value: string, fieldName: string): void {\n const emailRegex = /^[^\\s@]+@[^\\s@]+\\.[^\\s@]+$/;\n if (!emailRegex.test(value)) {\n throw ApiErrorFactory.validationError(fieldName, value, '必须是有效的邮箱格式');\n }\n }\n\n /**\n * 验证URL格式\n */\n static url(value: string, fieldName: string): void {\n try {\n new URL(value);\n } catch {\n throw ApiErrorFactory.validationError(fieldName, value, '必须是有效的URL格式');\n }\n }\n}\n","// @ts-nocheck\n/**\n * Drizzle ORM 文件元数据持久化适配器\n *\n * 提供基于 Drizzle ORM 的数据库持久化实现\n */\n\nimport { eq, and, desc, sql, SQL } from 'drizzle-orm';\nimport type { FileMetadata, FileQueryOptions, PaginatedResult } from '../../types';\nimport type { IFileMetadataRepository } from '../types';\nimport { createLogger } from '../../../logger';\n\nconst logger = createLogger('DrizzleFileRepository');\n\n/**\n * Drizzle 表定义类型(兼容多种 Drizzle 表结构)\n */\nexport type DrizzleTable = any;\n\n/**\n * Drizzle 数据库连接类型\n */\nexport type DrizzleDb = any;\n\n/**\n * 字段映射配置\n *\n * 将 FileMetadata 的字段映射到数据库表的列名\n */\nexport interface FieldMapping {\n id?: string;\n filename?: string;\n originalName?: string;\n mimeType?: string;\n size?: string;\n hash?: string;\n storageType?: string;\n storagePath?: string;\n url?: string;\n cdnUrl?: string;\n moduleId?: string;\n businessId?: string;\n userId?: string;\n uploadedAt?: string;\n expiresAt?: string;\n metadata?: string;\n status?: string;\n processingStatus?: string;\n versions?: string;\n tags?: string;\n}\n\n/**\n * Drizzle 仓储配置\n */\nexport interface DrizzleRepositoryConfig {\n /** Drizzle 数据库实例 */\n db: DrizzleDb;\n /** 文件元数据表 */\n table: DrizzleTable;\n /** 字段映射(如果数据库列名与 FileMetadata 字段不同) */\n fieldMapping?: FieldMapping;\n}\n\n/**\n * 创建 Drizzle ORM 文件仓储\n *\n * @example\n * ```typescript\n * import { createDrizzleRepository } from '@qhr123/sa2kit/universalFile/server';\n * import { db } from './db';\n * import { fileMetadata } from './schema';\n *\n * const repository = createDrizzleRepository({\n * db,\n * table: fileMetadata,\n * fieldMapping: {\n * // 如果列名与 FileMetadata 字段不同,可以在这里映射\n * originalName: 'original_filename',\n * }\n * });\n * ```\n */\nexport function createDrizzleRepository(config: DrizzleRepositoryConfig): IFileMetadataRepository {\n const { db, table, fieldMapping = {} } = config;\n\n /**\n * 获取字段名(考虑映射)\n */\n const getField = (field: keyof FieldMapping): string => {\n return (fieldMapping[field] || field) as string;\n };\n\n /**\n * 将 FileMetadata 转换为数据库记录\n */\n const toDbRecord = (metadata: FileMetadata): any => {\n const record: any = {\n [getField('id')]: metadata.id,\n [getField('filename')]: metadata.filename,\n [getField('originalName')]: metadata.originalName,\n [getField('mimeType')]: metadata.mimeType,\n [getField('size')]: metadata.size,\n [getField('storageType')]: metadata.storageType,\n [getField('storagePath')]: metadata.storagePath,\n [getField('url')]: metadata.url,\n [getField('moduleId')]: metadata.moduleId,\n [getField('businessId')]: metadata.businessId,\n [getField('uploadedAt')]: metadata.uploadedAt,\n };\n\n // 可选字段\n if (metadata.hash !== undefined) record[getField('hash')] = metadata.hash;\n if (metadata.cdnUrl !== undefined) record[getField('cdnUrl')] = metadata.cdnUrl;\n if (metadata.userId !== undefined) record[getField('userId')] = metadata.userId;\n if (metadata.expiresAt !== undefined) record[getField('expiresAt')] = metadata.expiresAt;\n if (metadata.metadata !== undefined) record[getField('metadata')] = metadata.metadata;\n if (metadata.status !== undefined) record[getField('status')] = metadata.status;\n if (metadata.processingStatus !== undefined) record[getField('processingStatus')] = metadata.processingStatus;\n if (metadata.versions !== undefined) record[getField('versions')] = metadata.versions;\n if (metadata.tags !== undefined) record[getField('tags')] = metadata.tags;\n\n return record;\n };\n\n /**\n * 将数据库记录转换为 FileMetadata\n */\n const toFileMetadata = (record: any): FileMetadata => {\n const metadata: FileMetadata = {\n id: record[getField('id')],\n filename: record[getField('filename')],\n originalName: record[getField('originalName')],\n mimeType: record[getField('mimeType')],\n size: record[getField('size')],\n storageType: record[getField('storageType')],\n storagePath: record[getField('storagePath')],\n url: record[getField('url')],\n moduleId: record[getField('moduleId')],\n businessId: record[getField('businessId')],\n uploadedAt: record[getField('uploadedAt')],\n };\n\n // 可选字段\n if (record[getField('hash')]) metadata.hash = record[getField('hash')];\n if (record[getField('cdnUrl')]) metadata.cdnUrl = record[getField('cdnUrl')];\n if (record[getField('userId')]) metadata.userId = record[getField('userId')];\n if (record[getField('expiresAt')]) metadata.expiresAt = record[getField('expiresAt')];\n if (record[getField('metadata')]) metadata.metadata = record[getField('metadata')];\n if (record[getField('status')]) metadata.status = record[getField('status')];\n if (record[getField('processingStatus')]) metadata.processingStatus = record[getField('processingStatus')];\n if (record[getField('versions')]) metadata.versions = record[getField('versions')];\n if (record[getField('tags')]) metadata.tags = record[getField('tags')];\n\n return metadata;\n };\n\n return {\n async save(metadata: FileMetadata): Promise<void> {\n try {\n const record = toDbRecord(metadata);\n\n // 检查是否存在\n const existing = await db\n .select()\n .from(table)\n .where(eq(table[getField('id')], metadata.id))\n .limit(1);\n\n if (existing && existing.length > 0) {\n // 更新\n await db\n .update(table)\n .set(record)\n .where(eq(table[getField('id')], metadata.id));\n\n logger.info('✅ [DrizzleRepository] 文件元数据已更新: ' + (metadata.id));\n } else {\n // 插入\n await db.insert(table).values(record);\n logger.info('✅ [DrizzleRepository] 文件元数据已插入: ' + (metadata.id));\n }\n } catch (error) {\n logger.error('❌ [DrizzleRepository] 保存失败: ' + (metadata.id), error);\n throw error;\n }\n },\n\n async get(fileId: string): Promise<FileMetadata | null> {\n try {\n const result = await db\n .select()\n .from(table)\n .where(eq(table[getField('id')], fileId))\n .limit(1);\n\n if (!result || result.length === 0) {\n return null;\n }\n\n return toFileMetadata(result[0]);\n } catch (error) {\n logger.error('❌ [DrizzleRepository] 查询失败: ' + (fileId), error);\n throw error;\n }\n },\n\n async query(options: FileQueryOptions): Promise<PaginatedResult<FileMetadata>> {\n try {\n const {\n page = 1,\n pageSize = 20,\n moduleId,\n businessId,\n userId,\n mimeType,\n status,\n startDate,\n endDate,\n tags,\n } = options;\n\n // 构建查询条件\n const conditions: SQL[] = [];\n\n if (moduleId) {\n conditions.push(eq(table[getField('moduleId')], moduleId));\n }\n if (businessId) {\n conditions.push(eq(table[getField('businessId')], businessId));\n }\n if (userId) {\n conditions.push(eq(table[getField('userId')], userId));\n }\n if (mimeType) {\n conditions.push(eq(table[getField('mimeType')], mimeType));\n }\n if (status) {\n conditions.push(eq(table[getField('status')], status));\n }\n if (startDate) {\n conditions.push(sql(table[getField('uploadedAt')]) + ' >= ' + (startDate));\n }\n if (endDate) {\n conditions.push(sql(table[getField('uploadedAt')]) + ' <= ' + (endDate));\n }\n if (tags && tags.length > 0) {\n // 假设 tags 是 JSON 数组字段\n for (const tag of tags) {\n conditions.push(sql(table[getField('tags')]) + ' @> ' + (JSON.stringify([tag])));\n }\n }\n\n // 查询总数\n const countResult = await db\n .select({ count: sql<number>`count(*)` })\n .from(table)\n .where(conditions.length > 0 ? and(...conditions) : undefined);\n\n const total = Number(countResult[0]?.count || 0);\n\n // 查询数据\n const offset = (page - 1) * pageSize;\n const result = await db\n .select()\n .from(table)\n .where(conditions.length > 0 ? and(...conditions) : undefined)\n .orderBy(desc(table[getField('uploadedAt')]))\n .limit(pageSize)\n .offset(offset);\n\n const items = result.map(toFileMetadata);\n\n return {\n items,\n total,\n page,\n pageSize,\n totalPages: Math.ceil(total / pageSize),\n };\n } catch (error) {\n logger.error(`❌ [DrizzleRepository] 查询列表失败`, error);\n throw error;\n }\n },\n\n async delete(fileId: string): Promise<void> {\n try {\n await db\n .delete(table)\n .where(eq(table[getField('id')], fileId));\n\n logger.info('🗑️ [DrizzleRepository] 文件元数据已删除: ' + (fileId));\n } catch (error) {\n logger.error('❌ [DrizzleRepository] 删除失败: ' + (fileId), error);\n throw error;\n }\n },\n\n async batchDelete(fileIds: string[]): Promise<void> {\n try {\n if (fileIds.length === 0) return;\n\n // 批量删除\n await db\n .delete(table)\n .where(sql(table[getField('id')]) + ' = ANY(' + (fileIds) + ')');\n\n logger.info('🗑️ [DrizzleRepository] 批量删除成功: ' + (fileIds.length) + ' 个文件');\n } catch (error) {\n logger.error(`❌ [DrizzleRepository] 批量删除失败`, error);\n throw error;\n }\n },\n };\n}\n\n","/**\n * Drizzle ORM 适配器\n *\n * 实现 IFileMetadataRepository 接口\n */\n\nimport type { IFileMetadataRepository, FileQueryOptions, PaginatedResult, StorageType } from '../types';\nimport { eq, and, like, desc, asc } from 'drizzle-orm';\n\ntype FileMetadataInput = {\n id: string;\n originalName: string;\n storageName: string;\n size: number;\n mimeType: string;\n extension: string;\n hash?: string;\n uploadTime: Date;\n permission: 'public' | 'private' | 'authenticated' | 'owner-only';\n uploaderId: string;\n moduleId: string;\n businessId?: string;\n storageProvider: StorageType;\n storagePath: string;\n cdnUrl?: string;\n accessCount: number;\n lastAccessTime?: Date;\n expiresAt?: Date;\n metadata?: Record<string, any>;\n};\n\ninterface DrizzleAdapterOptions {\n db: any;\n fileMetadata: any;\n fileStorageProviders: any;\n}\n\nexport function createDrizzleFileRepository(options: DrizzleAdapterOptions): IFileMetadataRepository {\n const { db, fileMetadata: fileMetadataTable, fileStorageProviders } = options;\n\n return {\n async save(meta: any): Promise<void> {\n const [storageProvider] = await db\n .select()\n .from(fileStorageProviders)\n .where(eq(fileStorageProviders.type, meta.storageProvider as string))\n .limit(1);\n\n let providerId: number;\n\n if (!storageProvider) {\n const [defaultProvider] = await db\n .select()\n .from(fileStorageProviders)\n .where(eq(fileStorageProviders.isDefault, true))\n .limit(1);\n\n if (!defaultProvider) {\n throw new Error('未找到可用的存储提供者');\n }\n\n providerId = defaultProvider.id;\n } else {\n providerId = storageProvider.id;\n }\n\n await db.insert(fileMetadataTable).values({\n id: meta.id,\n originalName: meta.originalName,\n storedName: meta.storageName,\n extension: meta.extension,\n mimeType: meta.mimeType,\n size: meta.size,\n md5Hash: meta.hash?.substring(0, 32) || '',\n sha256Hash: meta.hash || '',\n storageProviderId: providerId,\n storagePath: meta.storagePath,\n cdnUrl: meta.cdnUrl,\n moduleId: meta.moduleId,\n businessId: meta.businessId,\n tags: [],\n metadata: meta.metadata,\n isTemporary: false,\n isDeleted: false,\n accessCount: meta.accessCount || 0,\n downloadCount: 0,\n uploaderId: meta.uploaderId || 'system',\n uploadTime: meta.uploadTime,\n lastAccessTime: meta.lastAccessTime,\n expiresAt: meta.expiresAt,\n });\n },\n\n async get(fileId: string): Promise<any | null> {\n const [record] = await db\n .select()\n .from(fileMetadataTable)\n .where(eq(fileMetadataTable.id, fileId))\n .limit(1);\n\n if (!record) {\n return null;\n }\n\n const [provider] = await db\n .select()\n .from(fileStorageProviders)\n .where(eq(fileStorageProviders.id, record.storageProviderId))\n .limit(1);\n\n if (!provider) {\n return null;\n }\n\n const result: FileMetadataInput = {\n id: record.id,\n originalName: record.originalName,\n storageName: record.storedName,\n size: record.size,\n mimeType: record.mimeType,\n extension: record.extension || '',\n hash: record.md5Hash,\n uploadTime: record.uploadTime,\n permission: 'public' as const,\n uploaderId: record.uploaderId,\n moduleId: record.moduleId || '',\n businessId: record.businessId || undefined,\n storageProvider: provider.type as StorageType,\n storagePath: record.storagePath,\n cdnUrl: record.cdnUrl || undefined,\n accessCount: record.accessCount,\n lastAccessTime: record.lastAccessTime || undefined,\n expiresAt: record.expiresAt || undefined,\n metadata: (record.metadata as Record<string, any>) || {},\n };\n\n return result;\n },\n\n async query(options: FileQueryOptions): Promise<PaginatedResult<any>> {\n const page = options.page || 1;\n const pageSize = options.pageSize || 20;\n const offset = (page - 1) * pageSize;\n\n const conditions: any[] = [];\n\n if (options.moduleId) {\n conditions.push(eq(fileMetadataTable.moduleId, options.moduleId));\n }\n\n if (options.businessId) {\n conditions.push(eq(fileMetadataTable.businessId, options.businessId));\n }\n\n if (options.uploaderId) {\n conditions.push(eq(fileMetadataTable.uploaderId, options.uploaderId));\n }\n\n if (options.mimeType) {\n conditions.push(like(fileMetadataTable.mimeType, `%${options.mimeType}%`));\n }\n\n const query = db.select().from(fileMetadataTable);\n\n if (conditions.length > 0) {\n query.where(and(...conditions));\n }\n\n const sortBy = options.orderBy || 'uploadTime';\n const sortOrder = options.orderDirection || 'desc';\n const orderFn = sortOrder === 'asc' ? asc : desc;\n query.orderBy(orderFn(fileMetadataTable[sortBy as keyof typeof fileMetadataTable] as any));\n\n query.limit(pageSize).offset(offset);\n\n const records = await query;\n\n const [countResult] = await db\n .select({ count: fileMetadataTable.id })\n .from(fileMetadataTable)\n .where(conditions.length > 0 ? and(...conditions) : undefined);\n\n const total = typeof countResult?.count === 'number' ? countResult.count : 0;\n const totalPages = Math.ceil(total / pageSize);\n\n const items: FileMetadataInput[] = [];\n for (const record of records) {\n const [provider] = await db\n .select()\n .from(fileStorageProviders)\n .where(eq(fileStorageProviders.id, record.storageProviderId))\n .limit(1);\n\n if (provider) {\n items.push({\n id: record.id,\n originalName: record.originalName,\n storageName: record.storedName,\n size: record.size,\n mimeType: record.mimeType,\n extension: record.extension || '',\n hash: record.md5Hash,\n uploadTime: record.uploadTime,\n permission: 'public' as const,\n uploaderId: record.uploaderId,\n moduleId: record.moduleId || '',\n businessId: record.businessId || undefined,\n storageProvider: provider.type as StorageType,\n storagePath: record.storagePath,\n cdnUrl: record.cdnUrl || undefined,\n accessCount: record.accessCount,\n lastAccessTime: record.lastAccessTime || undefined,\n expiresAt: record.expiresAt || undefined,\n metadata: (record.metadata as Record<string, any>) || {},\n });\n }\n }\n\n return {\n items,\n total,\n page,\n pageSize,\n totalPages,\n };\n },\n\n async delete(fileId: string): Promise<void> {\n await db\n .update(fileMetadataTable)\n .set({\n isDeleted: true,\n deletedAt: new Date(),\n updatedAt: new Date(),\n })\n .where(eq(fileMetadataTable.id, fileId));\n },\n\n async batchDelete(fileIds: string[]): Promise<void> {\n for (const fileId of fileIds) {\n await this.delete(fileId);\n }\n },\n };\n}\n","/**\n * 数据库查询优化中间件\n */\n\nimport { performanceMonitor } from '../../monitoring/PerformanceMonitor';\n\ninterface QueryPerformance {\n sql: string;\n duration: number;\n params?: any[];\n timestamp: number;\n type: 'SELECT' | 'INSERT' | 'UPDATE' | 'DELETE' | 'UNKNOWN';\n isSlow: boolean;\n}\n\nexport class QueryOptimizer {\n private queryHistory: QueryPerformance[] = [];\n private readonly maxHistorySize = 1000;\n private readonly slowQueryThreshold = 1000;\n\n async monitorQuery<T>(queryFn: () => Promise<T>, sql: string, params?: any[]): Promise<T> {\n const startTime = Date.now();\n let result: T;\n let error: Error | null = null;\n\n try {\n result = await queryFn();\n } catch (err) {\n error = err instanceof Error ? err : new Error(String(err));\n throw err;\n } finally {\n const duration = Date.now() - startTime;\n const queryType = this.getQueryType(sql);\n const isSlow = duration > this.slowQueryThreshold;\n\n this.addQueryToHistory({\n sql,\n duration,\n params,\n timestamp: Date.now(),\n type: queryType,\n isSlow,\n });\n\n performanceMonitor.recordDatabaseQuery(duration, error !== null);\n\n if (isSlow) {\n console.warn(`慢查询检测 (${duration}ms):`, {\n sql: sql.substring(0, 100) + (sql.length > 100 ? '...' : ''),\n duration,\n params: params?.slice(0, 3),\n });\n }\n }\n\n return result!;\n }\n\n private getQueryType(sql: string): QueryPerformance['type'] {\n const upperSql = sql.trim().toUpperCase();\n\n if (upperSql.startsWith('SELECT')) return 'SELECT';\n if (upperSql.startsWith('INSERT')) return 'INSERT';\n if (upperSql.startsWith('UPDATE')) return 'UPDATE';\n if (upperSql.startsWith('DELETE')) return 'DELETE';\n\n return 'UNKNOWN';\n }\n\n private addQueryToHistory(queryPerf: QueryPerformance): void {\n this.queryHistory.push(queryPerf);\n\n if (this.queryHistory.length > this.maxHistorySize) {\n this.queryHistory.shift();\n }\n }\n\n getQueryStats() {\n const now = Date.now();\n const oneHourAgo = now - 3600000;\n const recentQueries = this.queryHistory.filter((q) => q.timestamp > oneHourAgo);\n\n const stats = {\n total: recentQueries.length,\n byType: {} as Record<string, number>,\n slowQueries: recentQueries.filter((q) => q.isSlow).length,\n averageDuration: 0,\n maxDuration: 0,\n minDuration: Infinity,\n };\n\n if (recentQueries.length > 0) {\n recentQueries.forEach((q) => {\n stats.byType[q.type] = (stats.byType[q.type] || 0) + 1;\n });\n\n const durations = recentQueries.map((q) => q.duration);\n stats.averageDuration = durations.reduce((a, b) => a + b, 0) / durations.length;\n stats.maxDuration = Math.max(...durations);\n stats.minDuration = Math.min(...durations);\n }\n\n return stats;\n }\n}\n\nexport const queryOptimizer = new QueryOptimizer();\n","/**\n * 通用文件服务 - PostgreSQL 数据库表结构定义\n *\n * 这个文件定义了通用文件服务的完整数据库表结构,使用Drizzle ORM框架。\n * 支持多模块文件管理、版本控制、分享功能、处理记录等。\n *\n * 表结构概览:\n * - file_storage_providers: 存储提供者配置表\n * - file_folders: 文件夹表(支持层级结构)\n * - file_metadata: 文件元数据主表\n * - file_versions: 文件版本表\n * - file_processing_records: 文件处理记录表\n * - file_shares: 文件分享表\n * - file_access_logs: 文件访问日志表\n * - file_thumbnails: 文件缩略图表\n *\n * 设计特点:\n * - 支持多存储提供者(本地、OSS、CDN等)\n * - 完整的文件版本管理\n * - 灵活的文件夹层级结构\n * - 详细的访问日志和统计\n * - 文件处理流水线记录\n * - 安全的分享机制\n *\n * @fileoverview 数据库表结构 - 通用文件服务 (PostgreSQL)\n * @package sa2kit/universalFile/server\n */\n\nimport { relations } from 'drizzle-orm';\nimport {\n serial,\n text,\n timestamp,\n pgTable,\n json,\n integer,\n boolean,\n varchar,\n index,\n bigint,\n uuid,\n} from 'drizzle-orm/pg-core';\n\n/**\n * 存储提供者配置表 (file_storage_providers)\n *\n * 管理不同的文件存储提供者配置,支持本地存储、云存储等多种方式。\n * 每个提供者有独立的配置和优先级设置。\n */\nexport const fileStorageProviders = pgTable(\n 'file_storage_providers',\n {\n /** 主键ID */\n id: serial('id').primaryKey(),\n\n /** 提供者名称 */\n name: varchar('name', { length: 100 }).notNull().unique(),\n\n /** 提供者类型:local, aliyun_oss, aws_s3, qiniu, etc. */\n type: varchar('type', { length: 50 }).notNull(),\n\n /** 提供者配置(JSON格式存储具体配置信息) */\n config: json('config').notNull(),\n\n /** 是否启用 */\n isActive: boolean('is_active').notNull().default(true),\n\n /** 是否为默认提供者 */\n isDefault: boolean('is_default').notNull().default(false),\n\n /** 优先级(数字越小优先级越高) */\n priority: integer('priority').notNull().default(100),\n\n /** 最大文件大小限制(字节) */\n maxFileSize: bigint('max_file_size', { mode: 'number' }),\n\n /** 支持的文件类型(MIME类型列表) */\n supportedMimeTypes: json('supported_mime_types'),\n\n /** 创建时间 */\n createdAt: timestamp('created_at').defaultNow().notNull(),\n\n /** 更新时间 */\n updatedAt: timestamp('updated_at').defaultNow().notNull(),\n },\n (table) => ({\n /** 按类型查询的索引 */\n typeIndex: index('storage_providers_type_idx').on(table.type),\n\n /** 按活跃状态查询的索引 */\n isActiveIndex: index('storage_providers_is_active_idx').on(table.isActive),\n\n /** 按优先级排序的索引 */\n priorityIndex: index('storage_providers_priority_idx').on(table.priority),\n })\n);\n\n/**\n * 文件夹表 (file_folders)\n *\n * 支持层级结构的文件夹管理,每个模块可以有独立的文件夹结构。\n */\nexport const fileFolders = pgTable(\n 'file_folders',\n {\n /** 主键ID */\n id: uuid('id').primaryKey().defaultRandom(),\n\n /** 文件夹名称 */\n name: varchar('name', { length: 255 }).notNull(),\n\n /** 父文件夹ID(为null表示根文件夹) */\n parentId: uuid('parent_id'),\n\n /** 模块ID(标识属于哪个模块) */\n moduleId: varchar('module_id', { length: 100 }),\n\n /** 业务ID(具体业务实体的ID) */\n businessId: varchar('business_id', { length: 255 }),\n\n /** 文件夹路径(从根到当前文件夹的完整路径) */\n path: text('path').notNull(),\n\n /** 层级深度 */\n depth: integer('depth').notNull().default(0),\n\n /** 显示顺序 */\n sortOrder: integer('sort_order').notNull().default(0),\n\n /** 文件夹描述 */\n description: text('description'),\n\n /** 是否为系统文件夹 */\n isSystem: boolean('is_system').notNull().default(false),\n\n /** 创建者ID */\n createdBy: varchar('created_by', { length: 255 }).notNull(),\n\n /** 创建时间 */\n createdAt: timestamp('created_at').defaultNow().notNull(),\n\n /** 更新时间 */\n updatedAt: timestamp('updated_at').defaultNow().notNull(),\n },\n (table) => ({\n /** 按模块查询的索引 */\n moduleIndex: index('folders_module_idx').on(table.moduleId),\n\n /** 按业务ID查询的索引 */\n businessIndex: index('folders_business_idx').on(table.businessId),\n\n /** 按父文件夹查询的索引 */\n parentIndex: index('folders_parent_idx').on(table.parentId),\n\n /** 按路径查询的索引 */\n pathIndex: index('folders_path_idx').on(table.path),\n\n /** 组合索引:模块+业务+父文件夹 */\n moduleBusinessParentIndex: index('folders_module_business_parent_idx').on(\n table.moduleId,\n table.businessId,\n table.parentId\n ),\n })\n);\n\n/**\n * 文件元数据主表 (file_metadata)\n *\n * 存储文件的完整元数据信息,是文件服务的核心表。\n */\nexport const fileMetadata = pgTable(\n 'file_metadata',\n {\n /** 主键ID */\n id: uuid('id').primaryKey().defaultRandom(),\n\n /** 原始文件名 */\n originalName: varchar('original_name', { length: 500 }).notNull(),\n\n /** 存储文件名(系统生成的唯一文件名) */\n storedName: varchar('stored_name', { length: 500 }).notNull(),\n\n /** 文件扩展名 */\n extension: varchar('extension', { length: 20 }),\n\n /** MIME类型 */\n mimeType: varchar('mime_type', { length: 100 }).notNull(),\n\n /** 文件大小(字节) */\n size: bigint('size', { mode: 'number' }).notNull(),\n\n /** 文件MD5哈希值(用于去重和完整性校验) */\n md5Hash: varchar('md5_hash', { length: 32 }).notNull(),\n\n /** 文件SHA256哈希值 */\n sha256Hash: varchar('sha256_hash', { length: 64 }),\n\n /** 存储提供者ID */\n storageProviderId: integer('storage_provider_id')\n .references(() => fileStorageProviders.id)\n .notNull(),\n\n /** 存储路径 */\n storagePath: text('storage_path').notNull(),\n\n /** CDN访问URL */\n cdnUrl: text('cdn_url'),\n\n /** 所属文件夹ID */\n folderId: uuid('folder_id').references(() => fileFolders.id, { onDelete: 'set null' }),\n\n /** 模块ID */\n moduleId: varchar('module_id', { length: 100 }),\n\n /** 业务ID */\n businessId: varchar('business_id', { length: 255 }),\n\n /** 文件标签(JSON数组) */\n tags: json('tags'),\n\n /** 文件元信息(如图片尺寸、视频时长等) */\n metadata: json('metadata'),\n\n /** 是否为临时文件 */\n isTemporary: boolean('is_temporary').notNull().default(false),\n\n /** 是否已删除(软删除) */\n isDeleted: boolean('is_deleted').notNull().default(false),\n\n /** 访问次数 */\n accessCount: integer('access_count').notNull().default(0),\n\n /** 下载次数 */\n downloadCount: integer('download_count').notNull().default(0),\n\n /** 上传者ID */\n uploaderId: varchar('uploader_id', { length: 255 }).notNull(),\n\n /** 上传时间 */\n uploadTime: timestamp('upload_time').defaultNow().notNull(),\n\n /** 最后访问时间 */\n lastAccessTime: timestamp('last_access_time'),\n\n /** 过期时间(为null表示永不过期) */\n expiresAt: timestamp('expires_at'),\n\n /** 创建时间 */\n createdAt: timestamp('created_at').defaultNow().notNull(),\n\n /** 更新时间 */\n updatedAt: timestamp('updated_at').defaultNow().notNull(),\n\n /** 删除时间 */\n deletedAt: timestamp('deleted_at'),\n },\n (table) => ({\n /** 按MD5哈希查询的索引(去重用) */\n md5Index: index('file_metadata_md5_idx').on(table.md5Hash),\n\n /** 按SHA256哈希查询的索引 */\n sha256Index: index('file_metadata_sha256_idx').on(table.sha256Hash),\n\n /** 按模块查询的索引 */\n moduleIndex: index('file_metadata_module_idx').on(table.moduleId),\n\n /** 按业务ID查询的索引 */\n businessIndex: index('file_metadata_business_idx').on(table.businessId),\n\n /** 按上传者查询的索引 */\n uploaderIndex: index('file_metadata_uploader_idx').on(table.uploaderId),\n\n /** 按MIME类型查询的索引 */\n mimeTypeIndex: index('file_metadata_mime_type_idx').on(table.mimeType),\n\n /** 按删除状态查询的索引 */\n isDeletedIndex: index('file_metadata_is_deleted_idx').on(table.isDeleted),\n\n /** 按临时状态查询的索引 */\n isTemporaryIndex: index('file_metadata_is_temporary_idx').on(table.isTemporary),\n\n /** 按文件夹查询的索引 */\n folderIndex: index('file_metadata_folder_idx').on(table.folderId),\n\n /** 按上传时间查询的索引 */\n uploadTimeIndex: index('file_metadata_upload_time_idx').on(table.uploadTime),\n\n /** 组合索引:模块+业务+删除状态 */\n moduleBusinessDeletedIndex: index('file_metadata_module_business_deleted_idx').on(\n table.moduleId,\n table.businessId,\n table.isDeleted\n ),\n\n /** 组合索引:文件夹+删除状态 */\n folderDeletedIndex: index('file_metadata_folder_deleted_idx').on(\n table.folderId,\n table.isDeleted\n ),\n })\n);\n\n/**\n * 文件版本表 (file_versions)\n *\n * 支持文件的版本管理,记录文件的历史版本信息。\n */\nexport const fileVersions = pgTable(\n 'file_versions',\n {\n /** 主键ID */\n id: uuid('id').primaryKey().defaultRandom(),\n\n /** 关联的文件ID */\n fileId: uuid('file_id')\n .references(() => fileMetadata.id, { onDelete: 'cascade' })\n .notNull(),\n\n /** 版本号 */\n version: integer('version').notNull(),\n\n /** 版本描述 */\n description: text('description'),\n\n /** 文件大小 */\n size: bigint('size', { mode: 'number' }).notNull(),\n\n /** MD5哈希值 */\n md5Hash: varchar('md5_hash', { length: 32 }).notNull(),\n\n /** 存储路径 */\n storagePath: text('storage_path').notNull(),\n\n /** CDN访问URL */\n cdnUrl: text('cdn_url'),\n\n /** 是否为当前版本 */\n isCurrent: boolean('is_current').notNull().default(false),\n\n /** 创建者ID */\n createdBy: varchar('created_by', { length: 255 }).notNull(),\n\n /** 创建时间 */\n createdAt: timestamp('created_at').defaultNow().notNull(),\n },\n (table) => ({\n /** 按文件ID查询的索引 */\n fileIndex: index('file_versions_file_idx').on(table.fileId),\n\n /** 按当前版本查询的索引 */\n isCurrentIndex: index('file_versions_is_current_idx').on(table.isCurrent),\n\n /** 组合索引:文件+版本 */\n fileVersionIndex: index('file_versions_file_version_idx').on(table.fileId, table.version),\n })\n);\n\n/**\n * 文件处理记录表 (file_processing_records)\n *\n * 记录文件的处理历史,包括压缩、格式转换、缩略图生成等操作。\n */\nexport const fileProcessingRecords = pgTable(\n 'file_processing_records',\n {\n /** 主键ID */\n id: uuid('id').primaryKey().defaultRandom(),\n\n /** 关联的文件ID */\n fileId: uuid('file_id')\n .references(() => fileMetadata.id, { onDelete: 'cascade' })\n .notNull(),\n\n /** 处理类型:compress, resize, convert, thumbnail, watermark, etc. */\n processingType: varchar('processing_type', { length: 50 }).notNull(),\n\n /** 处理器名称 */\n processorName: varchar('processor_name', { length: 100 }).notNull(),\n\n /** 处理状态:pending, processing, completed, failed */\n status: varchar('status', { length: 20 }).notNull().default('pending'),\n\n /** 处理参数(JSON格式) */\n parameters: json('parameters'),\n\n /** 处理结果(JSON格式) */\n result: json('result'),\n\n /** 输出文件路径 */\n outputPath: text('output_path'),\n\n /** 输出文件大小 */\n outputSize: bigint('output_size', { mode: 'number' }),\n\n /** 处理耗时(毫秒) */\n processingTimeMs: integer('processing_time_ms'),\n\n /** 错误信息 */\n errorMessage: text('error_message'),\n\n /** 重试次数 */\n retryCount: integer('retry_count').notNull().default(0),\n\n /** 优先级 */\n priority: integer('priority').notNull().default(5),\n\n /** 开始时间 */\n startedAt: timestamp('started_at'),\n\n /** 完成时间 */\n completedAt: timestamp('completed_at'),\n\n /** 创建时间 */\n createdAt: timestamp('created_at').defaultNow().notNull(),\n\n /** 更新时间 */\n updatedAt: timestamp('updated_at').defaultNow().notNull(),\n },\n (table) => ({\n /** 按文件ID查询的索引 */\n fileIndex: index('file_processing_records_file_idx').on(table.fileId),\n\n /** 按处理状态查询的索引 */\n statusIndex: index('file_processing_records_status_idx').on(table.status),\n\n /** 按处理类型查询的索引 */\n processingTypeIndex: index('file_processing_records_processing_type_idx').on(\n table.processingType\n ),\n\n /** 按优先级查询的索引 */\n priorityIndex: index('file_processing_records_priority_idx').on(table.priority),\n\n /** 组合索引:文件+处理类型 */\n fileProcessingTypeIndex: index('file_processing_records_file_processing_type_idx').on(\n table.fileId,\n table.processingType\n ),\n })\n);\n\n/**\n * 文件分享表 (file_shares)\n *\n * 管理文件的分享功能,支持密码保护、过期时间、访问限制等。\n */\nexport const fileShares = pgTable(\n 'file_shares',\n {\n /** 主键ID */\n id: uuid('id').primaryKey().defaultRandom(),\n\n /** 分享代码(短链接标识) */\n shareCode: varchar('share_code', { length: 20 }).notNull().unique(),\n\n /** 分享的文件ID列表(JSON数组) */\n fileIds: json('file_ids').notNull(),\n\n /** 分享标题 */\n title: varchar('title', { length: 255 }),\n\n /** 分享描述 */\n description: text('description'),\n\n /** 访问密码 */\n password: varchar('password', { length: 100 }),\n\n /** 访问权限:view, download */\n permission: varchar('permission', { length: 20 }).notNull().default('view'),\n\n /** 最大下载次数(为null表示无限制) */\n maxDownloads: integer('max_downloads'),\n\n /** 当前下载次数 */\n downloadCount: integer('download_count').notNull().default(0),\n\n /** 最大访问次数(为null表示无限制) */\n maxAccess: integer('max_access'),\n\n /** 当前访问次数 */\n accessCount: integer('access_count').notNull().default(0),\n\n /** 是否启用 */\n isActive: boolean('is_active').notNull().default(true),\n\n /** 过期时间 */\n expiresAt: timestamp('expires_at'),\n\n /** 创建者ID */\n createdBy: varchar('created_by', { length: 255 }).notNull(),\n\n /** 创建时间 */\n createdAt: timestamp('created_at').defaultNow().notNull(),\n\n /** 更新时间 */\n updatedAt: timestamp('updated_at').defaultNow().notNull(),\n },\n (table) => ({\n /** 按分享代码查询的索引 */\n shareCodeIndex: index('file_shares_share_code_idx').on(table.shareCode),\n\n /** 按创建者查询的索引 */\n createdByIndex: index('file_shares_created_by_idx').on(table.createdBy),\n\n /** 按活跃状态查询的索引 */\n isActiveIndex: index('file_shares_is_active_idx').on(table.isActive),\n\n /** 按过期时间查询的索引 */\n expiresAtIndex: index('file_shares_expires_at_idx').on(table.expiresAt),\n })\n);\n\n/**\n * 文件访问日志表 (file_access_logs)\n *\n * 记录文件的访问历史,用于统计分析和安全审计。\n */\nexport const fileAccessLogs = pgTable(\n 'file_access_logs',\n {\n /** 主键ID */\n id: uuid('id').primaryKey().defaultRandom(),\n\n /** 关联的文件ID */\n fileId: uuid('file_id').references(() => fileMetadata.id, { onDelete: 'cascade' }),\n\n /** 分享ID(如果通过分享访问) */\n shareId: uuid('share_id').references(() => fileShares.id, { onDelete: 'set null' }),\n\n /** 访问类型:view, download, preview, thumbnail */\n accessType: varchar('access_type', { length: 20 }).notNull(),\n\n /** 用户ID */\n userId: varchar('user_id', { length: 255 }),\n\n /** 客户端IP地址 */\n ipAddress: varchar('ip_address', { length: 45 }),\n\n /** 用户代理字符串 */\n userAgent: text('user_agent'),\n\n /** 访问来源 */\n referer: text('referer'),\n\n /** 响应状态码 */\n statusCode: integer('status_code'),\n\n /** 传输字节数 */\n bytesTransferred: bigint('bytes_transferred', { mode: 'number' }),\n\n /** 响应时间(毫秒) */\n responseTimeMs: integer('response_time_ms'),\n\n /** 访问时间 */\n accessedAt: timestamp('accessed_at').defaultNow().notNull(),\n },\n (table) => ({\n /** 按文件ID查询的索引 */\n fileIndex: index('file_access_logs_file_idx').on(table.fileId),\n\n /** 按用户ID查询的索引 */\n userIndex: index('file_access_logs_user_idx').on(table.userId),\n\n /** 按访问类型查询的索引 */\n accessTypeIndex: index('file_access_logs_access_type_idx').on(table.accessType),\n\n /** 按访问时间查询的索引 */\n accessedAtIndex: index('file_access_logs_accessed_at_idx').on(table.accessedAt),\n\n /** 按分享ID查询的索引 */\n shareIndex: index('file_access_logs_share_idx').on(table.shareId),\n })\n);\n\n/**\n * 文件缩略图表 (file_thumbnails)\n *\n * 存储文件的缩略图信息,支持多种尺寸和格式。\n */\nexport const fileThumbnails = pgTable(\n 'file_thumbnails',\n {\n /** 主键ID */\n id: uuid('id').primaryKey().defaultRandom(),\n\n /** 关联的文件ID */\n fileId: uuid('file_id')\n .references(() => fileMetadata.id, { onDelete: 'cascade' })\n .notNull(),\n\n /** 缩略图类型:thumbnail, preview, poster(视频封面), etc. */\n type: varchar('type', { length: 50 }).notNull(),\n\n /** 缩略图规格:small, medium, large, 或具体尺寸如 \"200x200\" */\n size: varchar('size', { length: 20 }).notNull(),\n\n /** 缩略图宽度 */\n width: integer('width'),\n\n /** 缩略图高度 */\n height: integer('height'),\n\n /** 缩略图格式:jpg, png, webp, etc. */\n format: varchar('format', { length: 10 }).notNull(),\n\n /** 缩略图文件大小 */\n fileSize: integer('file_size').notNull(),\n\n /** 存储路径 */\n storagePath: text('storage_path').notNull(),\n\n /** CDN访问URL */\n cdnUrl: text('cdn_url'),\n\n /** 生成质量(1-100) */\n quality: integer('quality').default(85),\n\n /** 是否生成成功 */\n isGenerated: boolean('is_generated').notNull().default(false),\n\n /** 生成时间 */\n generatedAt: timestamp('generated_at'),\n\n /** 创建时间 */\n createdAt: timestamp('created_at').defaultNow().notNull(),\n },\n (table) => ({\n /** 按文件ID查询的索引 */\n fileIndex: index('file_thumbnails_file_idx').on(table.fileId),\n\n /** 按类型查询的索引 */\n typeIndex: index('file_thumbnails_type_idx').on(table.type),\n\n /** 按生成状态查询的索引 */\n isGeneratedIndex: index('file_thumbnails_is_generated_idx').on(table.isGenerated),\n\n /** 组合索引:文件+类型+尺寸 */\n fileTypeSizeIndex: index('file_thumbnails_file_type_size_idx').on(\n table.fileId,\n table.type,\n table.size\n ),\n })\n);\n\n// ========== 关系定义 ==========\n\nexport const fileStorageProvidersRelations = relations(fileStorageProviders, ({ many }) => ({\n files: many(fileMetadata),\n}));\n\nexport const fileFoldersRelations = relations(fileFolders, ({ one, many }) => ({\n parent: one(fileFolders, {\n fields: [fileFolders.parentId],\n references: [fileFolders.id],\n }),\n children: many(fileFolders),\n files: many(fileMetadata),\n}));\n\nexport const fileMetadataRelations = relations(fileMetadata, ({ one, many }) => ({\n storageProvider: one(fileStorageProviders, {\n fields: [fileMetadata.storageProviderId],\n references: [fileStorageProviders.id],\n }),\n folder: one(fileFolders, {\n fields: [fileMetadata.folderId],\n references: [fileFolders.id],\n }),\n versions: many(fileVersions),\n processingRecords: many(fileProcessingRecords),\n accessLogs: many(fileAccessLogs),\n thumbnails: many(fileThumbnails),\n}));\n\nexport const fileVersionsRelations = relations(fileVersions, ({ one }) => ({\n file: one(fileMetadata, {\n fields: [fileVersions.fileId],\n references: [fileMetadata.id],\n }),\n}));\n\nexport const fileProcessingRecordsRelations = relations(fileProcessingRecords, ({ one }) => ({\n file: one(fileMetadata, {\n fields: [fileProcessingRecords.fileId],\n references: [fileMetadata.id],\n }),\n}));\n\nexport const fileSharesRelations = relations(fileShares, ({ many }) => ({\n accessLogs: many(fileAccessLogs),\n}));\n\nexport const fileAccessLogsRelations = relations(fileAccessLogs, ({ one }) => ({\n file: one(fileMetadata, {\n fields: [fileAccessLogs.fileId],\n references: [fileMetadata.id],\n }),\n share: one(fileShares, {\n fields: [fileAccessLogs.shareId],\n references: [fileShares.id],\n }),\n}));\n\nexport const fileThumbnailsRelations = relations(fileThumbnails, ({ one }) => ({\n file: one(fileMetadata, {\n fields: [fileThumbnails.fileId],\n references: [fileMetadata.id],\n }),\n}));\n\n// ========== 导出类型 ==========\n\nexport type FileStorageProvider = typeof fileStorageProviders.$inferSelect;\nexport type NewFileStorageProvider = typeof fileStorageProviders.$inferInsert;\n\nexport type FileFolder = typeof fileFolders.$inferSelect;\nexport type NewFileFolder = typeof fileFolders.$inferInsert;\n\nexport type FileMetadata = typeof fileMetadata.$inferSelect;\nexport type NewFileMetadata = typeof fileMetadata.$inferInsert;\n\nexport type FileVersion = typeof fileVersions.$inferSelect;\nexport type NewFileVersion = typeof fileVersions.$inferInsert;\n\nexport type FileProcessingRecord = typeof fileProcessingRecords.$inferSelect;\nexport type NewFileProcessingRecord = typeof fileProcessingRecords.$inferInsert;\n\nexport type FileShare = typeof fileShares.$inferSelect;\nexport type NewFileShare = typeof fileShares.$inferInsert;\n\nexport type FileAccessLog = typeof fileAccessLogs.$inferSelect;\nexport type NewFileAccessLog = typeof fileAccessLogs.$inferInsert;\n\nexport type FileThumbnail = typeof fileThumbnails.$inferSelect;\nexport type NewFileThumbnail = typeof fileThumbnails.$inferInsert;\n\n","/**\n * 通用文件服务数据库操作类\n * 提供基础的文件数据库CRUD操作\n */\n\nimport { drizzle } from 'drizzle-orm/postgres-js';\nimport { eq, and, desc, sql, isNull, asc } from 'drizzle-orm';\nimport { v4 as uuidv4 } from 'uuid';\nimport { cacheManager } from '../../cache/CacheManager';\nimport { queryOptimizer } from '../middleware/queryOptimizer';\nimport {\n fileStorageProviders,\n fileFolders,\n fileMetadata,\n fileVersions,\n fileProcessingRecords,\n fileShares,\n fileAccessLogs,\n fileThumbnails,\n type FileStorageProvider,\n type FileFolder,\n type FileMetadata,\n type NewFileStorageProvider,\n type NewFileFolder,\n type NewFileMetadata,\n type NewFileVersion,\n type NewFileProcessingRecord,\n type NewFileShare,\n type NewFileAccessLog,\n type NewFileThumbnail,\n} from '../../drizzle-schemas';\n\ninterface FileQueryOptions {\n moduleId?: string;\n businessId?: string;\n folderId?: string;\n offset?: number;\n limit?: number;\n isDeleted?: boolean;\n uploaderId?: string;\n}\n\nexport class FileDbService {\n constructor(private db: ReturnType<typeof drizzle>) {}\n\n async getDefaultStorageProvider(): Promise<FileStorageProvider | null> {\n const result = await this.db\n .select()\n .from(fileStorageProviders)\n .where(and(eq(fileStorageProviders.isDefault, true), eq(fileStorageProviders.isActive, true)))\n .limit(1);\n\n return result[0] || null;\n }\n\n async createStorageProvider(provider: NewFileStorageProvider): Promise<FileStorageProvider> {\n const result = await this.db.insert(fileStorageProviders).values(provider).returning();\n if (!result[0]) {\n throw new Error('创建存储提供者失败');\n }\n return result[0];\n }\n\n async getFolderByPath(path: string, moduleId?: string): Promise<FileFolder | null> {\n const conditions = [eq(fileFolders.path, path)];\n\n if (moduleId) {\n conditions.push(eq(fileFolders.moduleId, moduleId));\n }\n\n const result = await this.db.select().from(fileFolders).where(and(...conditions)).limit(1);\n return result[0] || null;\n }\n\n async createFolder(folder: NewFileFolder): Promise<FileFolder> {\n const id = folder.id || uuidv4();\n const result = await this.db.insert(fileFolders).values({ ...folder, id }).returning();\n if (!result[0]) {\n throw new Error('创建文件夹失败');\n }\n return result[0];\n }\n\n async getFiles(options: FileQueryOptions = {}): Promise<{ files: FileMetadata[]; total: number }> {\n const whereConditions: any[] = [];\n\n if (options.moduleId) {\n whereConditions.push(eq(fileMetadata.moduleId, options.moduleId));\n }\n\n if (options.businessId) {\n whereConditions.push(eq(fileMetadata.businessId, options.businessId));\n }\n\n if (options.folderId) {\n whereConditions.push(eq(fileMetadata.folderId, options.folderId));\n }\n\n if (options.isDeleted !== undefined) {\n whereConditions.push(eq(fileMetadata.isDeleted, options.isDeleted));\n } else {\n whereConditions.push(eq(fileMetadata.isDeleted, false));\n }\n\n if (options.uploaderId) {\n whereConditions.push(eq(fileMetadata.uploaderId, options.uploaderId));\n }\n\n const whereClause = whereConditions.length > 0 ? and(...whereConditions) : undefined;\n\n const countResult = await this.db\n .select({ count: sql<number>`count(*)` })\n .from(fileMetadata)\n .where(whereClause);\n\n const total = countResult[0]?.count ?? 0;\n\n let query = this.db\n .select()\n .from(fileMetadata)\n .where(whereClause)\n .orderBy(desc(fileMetadata.uploadTime));\n\n if (options.limit) {\n query = query.limit(options.limit) as any;\n }\n\n if (options.offset) {\n query = query.offset(options.offset) as any;\n }\n\n const files = await query;\n\n return { files, total };\n }\n\n async getFileById(id: string): Promise<FileMetadata | null> {\n const cacheKey = `file:${id}`;\n const cached = await cacheManager.get<FileMetadata>(cacheKey);\n if (cached) {\n return cached;\n }\n\n const result = await queryOptimizer.monitorQuery(\n async () => {\n return await this.db.select().from(fileMetadata).where(eq(fileMetadata.id, id)).limit(1);\n },\n `SELECT * FROM file_metadata WHERE id = $1 LIMIT 1`,\n [id],\n );\n\n const file = result[0] || null;\n\n if (file) {\n await cacheManager.set(cacheKey, file, 300);\n }\n\n return file;\n }\n\n async createFile(file: NewFileMetadata): Promise<FileMetadata> {\n const result = await this.db.insert(fileMetadata).values(file).returning();\n if (!result[0]) {\n throw new Error('创建文件失败');\n }\n await cacheManager.delete(`file:${result[0].id}`);\n return result[0];\n }\n\n async updateFile(id: string, updates: Partial<FileMetadata>): Promise<FileMetadata> {\n const result = await this.db.update(fileMetadata).set(updates).where(eq(fileMetadata.id, id)).returning();\n await cacheManager.delete(`file:${id}`);\n if (!result[0]) {\n throw new Error('更新文件失败');\n }\n return result[0];\n }\n\n async deleteFile(id: string): Promise<void> {\n await this.db.update(fileMetadata).set({ isDeleted: true }).where(eq(fileMetadata.id, id));\n await cacheManager.delete(`file:${id}`);\n }\n\n async getFolderById(folderId: string): Promise<FileFolder | null> {\n const result = await this.db.select().from(fileFolders).where(eq(fileFolders.id, folderId)).limit(1);\n return result[0] || null;\n }\n\n async getFolders(moduleId?: string, businessId?: string): Promise<FileFolder[]> {\n const conditions: any[] = [];\n if (moduleId) {\n conditions.push(eq(fileFolders.moduleId, moduleId));\n }\n if (businessId) {\n conditions.push(eq(fileFolders.businessId, businessId));\n }\n\n const whereClause = conditions.length > 0 ? and(...conditions) : undefined;\n return this.db.select().from(fileFolders).where(whereClause).orderBy(asc(fileFolders.sortOrder));\n }\n\n async updateFolder(folderId: string, updates: Partial<FileFolder>): Promise<FileFolder> {\n const result = await this.db.update(fileFolders).set(updates).where(eq(fileFolders.id, folderId)).returning();\n if (!result[0]) {\n throw new Error('更新文件夹失败');\n }\n return result[0];\n }\n\n async deleteFolder(folderId: string): Promise<void> {\n await this.db.delete(fileFolders).where(eq(fileFolders.id, folderId));\n }\n\n async countFolderContents(folderId: string): Promise<{ files: number; folders: number }> {\n const [filesCount] = await this.db\n .select({ count: sql<number>`count(*)` })\n .from(fileMetadata)\n .where(and(eq(fileMetadata.folderId, folderId), eq(fileMetadata.isDeleted, false)));\n\n const [foldersCount] = await this.db\n .select({ count: sql<number>`count(*)` })\n .from(fileFolders)\n .where(eq(fileFolders.parentId, folderId));\n\n return {\n files: filesCount?.count ?? 0,\n folders: foldersCount?.count ?? 0,\n };\n }\n\n async createFileVersion(version: NewFileVersion): Promise<void> {\n await this.db.insert(fileVersions).values(version);\n }\n\n async createProcessingRecord(record: NewFileProcessingRecord): Promise<void> {\n await this.db.insert(fileProcessingRecords).values(record);\n }\n\n async createShare(share: NewFileShare): Promise<void> {\n await this.db.insert(fileShares).values(share);\n }\n\n async createAccessLog(log: NewFileAccessLog): Promise<void> {\n await this.db.insert(fileAccessLogs).values(log);\n }\n\n async createThumbnail(thumbnail: NewFileThumbnail): Promise<void> {\n await this.db.insert(fileThumbnails).values(thumbnail);\n }\n\n async listDeletedFiles(): Promise<FileMetadata[]> {\n return this.db.select().from(fileMetadata).where(eq(fileMetadata.isDeleted, true));\n }\n\n async clearDeletedFiles(days: number = 30): Promise<number> {\n const cutoff = new Date();\n cutoff.setDate(cutoff.getDate() - days);\n\n const result = await this.db\n .delete(fileMetadata)\n .where(and(eq(fileMetadata.isDeleted, true), sql`${fileMetadata.updatedAt} < ${cutoff}`));\n\n return (result as any).rowCount || 0;\n }\n\n async getStorageStats() {\n const totalFiles = await this.db.select({ count: sql<number>`count(*)` }).from(fileMetadata);\n const totalSize = await this.db\n .select({ total: sql<number>`sum(${fileMetadata.size})` })\n .from(fileMetadata)\n .where(eq(fileMetadata.isDeleted, false));\n\n const byStorage = await this.db\n .select({\n storageProviderId: fileMetadata.storageProviderId,\n count: sql<number>`count(*)`,\n totalSize: sql<number>`sum(${fileMetadata.size})`,\n })\n .from(fileMetadata)\n .where(eq(fileMetadata.isDeleted, false))\n .groupBy(fileMetadata.storageProviderId);\n\n return {\n totalFiles: totalFiles[0]?.count || 0,\n totalSize: totalSize[0]?.total || 0,\n byStorage,\n };\n }\n}\n","/**\n * 通用文件服务配置管理\n */\n\nimport type {\n StorageType,\n CDNType,\n LocalStorageConfig,\n AliyunOSSConfig,\n AliyunCDNConfig,\n StorageConfig,\n CDNConfig,\n} from './types';\n\nexport interface FileServiceConfig {\n defaultStorage: StorageType;\n storageProviders: Record<string, StorageConfig>;\n defaultCDN: CDNType;\n cdnProviders: Record<string, CDNConfig>;\n maxFileSize: number;\n allowedMimeTypes: string[];\n enableProcessing: boolean;\n processingQueueSize: number;\n cache: {\n metadataTTL: number;\n urlTTL: number;\n };\n}\n\n/**\n * 默认配置\n */\nconst DEFAULT_CONFIG: FileServiceConfig = {\n defaultStorage: 'aliyun-oss',\n storageProviders: {\n local: {\n type: 'local',\n enabled: false,\n rootPath: process.env.FILE_STORAGE_PATH || 'uploads',\n baseUrl: process.env.FILE_BASE_URL || '/uploads',\n } as LocalStorageConfig,\n 'aliyun-oss': {\n type: 'aliyun-oss',\n enabled: true,\n region: '',\n bucket: '',\n accessKeyId: '',\n accessKeySecret: '',\n } as AliyunOSSConfig,\n 'aws-s3': {\n type: 'aws-s3',\n enabled: false,\n } as StorageConfig,\n 'qcloud-cos': {\n type: 'qcloud-cos',\n enabled: false,\n } as StorageConfig,\n },\n defaultCDN: 'none',\n cdnProviders: {\n none: {\n type: 'none',\n enabled: false,\n } as CDNConfig,\n 'aliyun-cdn': {\n type: 'aliyun-cdn',\n enabled: false,\n domain: '',\n accessKeyId: '',\n accessKeySecret: '',\n } as AliyunCDNConfig,\n 'aws-cloudfront': {\n type: 'aws-cloudfront',\n enabled: false,\n } as CDNConfig,\n 'qcloud-cdn': {\n type: 'qcloud-cdn',\n enabled: false,\n } as CDNConfig,\n },\n maxFileSize: parseInt(process.env.MAX_FILE_SIZE || '104857600', 10),\n allowedMimeTypes: [\n 'image/jpeg',\n 'image/png',\n 'image/gif',\n 'image/webp',\n 'image/svg+xml',\n 'audio/mpeg',\n 'audio/wav',\n 'audio/ogg',\n 'audio/mp4',\n 'audio/aac',\n 'video/mp4',\n 'video/avi',\n 'video/mov',\n 'video/webm',\n 'video/mkv',\n 'application/pdf',\n 'text/plain',\n 'application/json',\n 'application/javascript',\n 'text/css',\n 'text/html',\n 'text/markdown',\n 'application/zip',\n 'application/x-zip-compressed',\n 'application/x-rar-compressed',\n 'application/x-7z-compressed',\n 'application/octet-stream',\n 'model/gltf+json',\n 'model/gltf-binary',\n ],\n enableProcessing: process.env.ENABLE_FILE_PROCESSING === 'true',\n processingQueueSize: parseInt(process.env.PROCESSING_QUEUE_SIZE || '10', 10),\n cache: {\n metadataTTL: parseInt(process.env.METADATA_CACHE_TTL || '3600', 10),\n urlTTL: parseInt(process.env.URL_CACHE_TTL || '1800', 10),\n },\n};\n\n/**\n * 配置管理器\n */\nexport class FileServiceConfigManager {\n private config: FileServiceConfig;\n\n constructor(customConfig?: Partial<FileServiceConfig>) {\n this.config = this.mergeConfig(DEFAULT_CONFIG, customConfig);\n this.validateConfig();\n }\n\n /**\n * 获取完整配置\n */\n getConfig(): FileServiceConfig {\n return { ...this.config };\n }\n\n /**\n * 获取存储提供者配置\n */\n getStorageConfig(type: StorageType): StorageConfig | undefined {\n return this.config.storageProviders[type];\n }\n\n /**\n * 获取CDN提供者配置\n */\n getCDNConfig(type: CDNType): CDNConfig | undefined {\n return this.config.cdnProviders[type];\n }\n\n /**\n * 更新配置\n */\n updateConfig(updates: Partial<FileServiceConfig>): void {\n this.config = this.mergeConfig(this.config, updates);\n this.validateConfig();\n }\n\n /**\n * 启用存储提供者\n */\n enableStorageProvider(type: StorageType, config?: Partial<StorageConfig>): void {\n if (this.config.storageProviders[type]) {\n this.config.storageProviders[type] = {\n ...this.config.storageProviders[type],\n ...config,\n enabled: true,\n };\n }\n }\n\n /**\n * 禁用存储提供者\n */\n disableStorageProvider(type: StorageType): void {\n if (this.config.storageProviders[type]) {\n this.config.storageProviders[type].enabled = false;\n }\n }\n\n /**\n * 启用CDN提供者\n */\n enableCDNProvider(type: CDNType, config?: Partial<CDNConfig>): void {\n if (this.config.cdnProviders[type]) {\n this.config.cdnProviders[type] = {\n ...this.config.cdnProviders[type],\n ...config,\n enabled: true,\n };\n this.config.defaultCDN = type;\n }\n }\n\n /**\n * 禁用CDN提供者\n */\n disableCDNProvider(type: CDNType): void {\n if (this.config.cdnProviders[type]) {\n this.config.cdnProviders[type].enabled = false;\n if (this.config.defaultCDN === type) {\n this.config.defaultCDN = 'none';\n }\n }\n }\n\n /**\n * 从环境变量加载阿里云OSS配置\n */\n loadAliyunOSSFromEnv(): void {\n const config: Partial<AliyunOSSConfig> = {\n region: process.env.ALIYUN_OSS_REGION,\n bucket: process.env.ALIYUN_OSS_BUCKET,\n accessKeyId: process.env.ALIYUN_OSS_ACCESS_KEY_ID,\n accessKeySecret: process.env.ALIYUN_OSS_ACCESS_KEY_SECRET,\n customDomain: process.env.ALIYUN_OSS_CUSTOM_DOMAIN,\n secure: process.env.ALIYUN_OSS_SECURE === 'true',\n };\n\n if (\n config.region &&\n config.bucket &&\n config.accessKeyId &&\n config.accessKeySecret\n ) {\n this.enableStorageProvider('aliyun-oss', config as StorageConfig);\n this.config.defaultStorage = 'aliyun-oss';\n }\n }\n\n /**\n * 从环境变量加载阿里云CDN配置\n */\n loadAliyunCDNFromEnv(): void {\n const config: Partial<AliyunCDNConfig> = {\n domain: process.env.ALIYUN_CDN_DOMAIN,\n accessKeyId: process.env.ALIYUN_CDN_ACCESS_KEY_ID,\n accessKeySecret: process.env.ALIYUN_CDN_ACCESS_KEY_SECRET,\n };\n\n if (config.domain && config.accessKeyId && config.accessKeySecret) {\n this.enableCDNProvider('aliyun-cdn', config as CDNConfig);\n }\n }\n\n /**\n * 验证配置\n */\n private validateConfig(): void {\n if (!this.config.defaultStorage) {\n throw new Error('默认存储类型未配置');\n }\n if (!this.config.storageProviders[this.config.defaultStorage]) {\n throw new Error('默认存储提供者配置不存在');\n }\n }\n\n /**\n * 深度合并配置\n */\n private mergeConfig(\n base: FileServiceConfig,\n override?: Partial<FileServiceConfig>,\n ): FileServiceConfig {\n if (!override) {\n return { ...base };\n }\n\n return {\n ...base,\n ...override,\n storageProviders: {\n ...base.storageProviders,\n ...override.storageProviders,\n },\n cdnProviders: {\n ...base.cdnProviders,\n ...override.cdnProviders,\n },\n cache: {\n ...base.cache,\n ...override.cache,\n },\n allowedMimeTypes: override.allowedMimeTypes || base.allowedMimeTypes,\n };\n }\n}\n\n/**\n * 创建配置管理器\n */\nexport async function createFileServiceConfigWithConfigManager(\n customConfig?: Partial<FileServiceConfig>,\n): Promise<FileServiceConfigManager> {\n const configManager = new FileServiceConfigManager(customConfig);\n configManager.loadAliyunOSSFromEnv();\n configManager.loadAliyunCDNFromEnv();\n return configManager;\n}\n","import { UniversalFileService } from './UniversalFileService';\nimport { createFileServiceConfigWithConfigManager } from './config-manager';\n\n/**\n * 创建支持动态配置加载的通用文件服务\n */\nexport async function createUniversalFileServiceWithConfigManager(): Promise<UniversalFileService> {\n const configManager = await createFileServiceConfigWithConfigManager();\n const config = configManager.getConfig();\n\n const defaultStorageType = config.defaultStorage || 'local';\n const storageConfig = config.storageProviders[defaultStorageType];\n\n if (!storageConfig) {\n throw new Error(`未找到存储配置: ${defaultStorageType}`);\n }\n\n const serviceConfig = {\n storage: storageConfig,\n cdn: config.defaultCDN !== 'none' ? config.cdnProviders[config.defaultCDN] : undefined,\n maxFileSize: config.maxFileSize,\n allowedMimeTypes: config.allowedMimeTypes,\n cache: {\n enabled: true,\n metadataTTL: config.cache.metadataTTL,\n urlTTL: config.cache.urlTTL,\n },\n defaultStorage: defaultStorageType,\n defaultCDN: config.defaultCDN,\n storageProviders: config.storageProviders,\n };\n\n const fileService = new UniversalFileService(serviceConfig as any);\n await fileService.initialize();\n return fileService;\n}\n","/**\n * 文件服务配置加载辅助工具\n *\n * 提供从环境变量加载配置、默认配置常量等通用功能\n */\n\nimport type {\n UniversalFileServiceConfig,\n AliyunOSSConfig,\n AliyunCDNConfig,\n LocalStorageConfig,\n StorageConfig,\n CDNConfig,\n} from './types';\nimport { UniversalFileService } from './UniversalFileService';\nimport { createLogger } from '../../logger';\n\nconst logger = createLogger('FileConfigHelpers');\n\n// ==================== 默认配置常量 ====================\n\n/**\n * 默认文件大小限制(字节)\n */\nexport const DEFAULT_MAX_FILE_SIZE = 104857600; // 100MB\n\n/**\n * 默认允许的 MIME 类型\n */\nexport const DEFAULT_ALLOWED_MIME_TYPES = [\n // 图片类型\n 'image/jpeg',\n 'image/png',\n 'image/gif',\n 'image/webp',\n 'image/svg+xml',\n 'image/bmp',\n 'image/tiff',\n // 音频类型\n 'audio/mpeg',\n 'audio/wav',\n 'audio/ogg',\n 'audio/mp4',\n 'audio/aac',\n 'audio/webm',\n 'audio/flac',\n // 视频类型\n 'video/mp4',\n 'video/avi',\n 'video/mov',\n 'video/webm',\n 'video/mkv',\n 'video/mpeg',\n 'video/quicktime',\n // 文档类型\n 'application/pdf',\n 'text/plain',\n 'application/json',\n 'application/javascript',\n 'text/css',\n 'text/html',\n 'text/markdown',\n 'application/xml',\n 'text/xml',\n // Office 文档\n 'application/msword',\n 'application/vnd.openxmlformats-officedocument.wordprocessingml.document',\n 'application/vnd.ms-excel',\n 'application/vnd.openxmlformats-officedocument.spreadsheetml.sheet',\n 'application/vnd.ms-powerpoint',\n 'application/vnd.openxmlformats-officedocument.presentationml.presentation',\n // 压缩文件\n 'application/zip',\n 'application/x-zip-compressed',\n 'application/x-rar-compressed',\n 'application/x-7z-compressed',\n 'application/x-tar',\n 'application/gzip',\n // 3D模型文件\n 'application/octet-stream',\n 'model/gltf+json',\n 'model/gltf-binary',\n 'model/obj',\n 'model/fbx',\n];\n\n/**\n * 默认缓存配置\n */\nexport const DEFAULT_CACHE_CONFIG = {\n enabled: false,\n metadataTTL: 3600, // 1小时\n urlTTL: 1800, // 30分钟\n};\n\n/**\n * 默认文件服务配置\n */\nexport const DEFAULT_FILE_SERVICE_CONFIG = {\n maxFileSize: DEFAULT_MAX_FILE_SIZE,\n allowedMimeTypes: DEFAULT_ALLOWED_MIME_TYPES,\n cache: DEFAULT_CACHE_CONFIG,\n enableMonitoring: false,\n} as const;\n\n// ==================== 环境变量配置加载 ====================\n\n/**\n * 从环境变量加载阿里云 OSS 配置\n *\n * 支持的环境变量:\n * - ALIYUN_OSS_REGION\n * - ALIYUN_OSS_BUCKET\n * - ALIYUN_OSS_ACCESS_KEY_ID\n * - ALIYUN_OSS_ACCESS_KEY_SECRET\n * - ALIYUN_OSS_CUSTOM_DOMAIN (可选)\n * - ALIYUN_OSS_SECURE (可选,默认 false)\n * - ALIYUN_OSS_INTERNAL (可选,默认 false)\n */\nexport function loadOSSConfigFromEnv(): AliyunOSSConfig | null {\n const region = process.env.ALIYUN_OSS_REGION;\n const bucket = process.env.ALIYUN_OSS_BUCKET;\n const accessKeyId = process.env.ALIYUN_OSS_ACCESS_KEY_ID;\n const accessKeySecret = process.env.ALIYUN_OSS_ACCESS_KEY_SECRET;\n\n // 验证必需字段\n if (!region || !bucket || !accessKeyId || !accessKeySecret) {\n logger.debug('OSS 环境变量配置不完整', {\n hasRegion: !!region,\n hasBucket: !!bucket,\n hasAccessKeyId: !!accessKeyId,\n hasAccessKeySecret: !!accessKeySecret,\n });\n return null;\n }\n\n const config: AliyunOSSConfig = {\n type: 'aliyun-oss',\n enabled: true,\n region,\n bucket,\n accessKeyId,\n accessKeySecret,\n customDomain: process.env.ALIYUN_OSS_CUSTOM_DOMAIN,\n secure: process.env.ALIYUN_OSS_SECURE === 'true',\n internal: process.env.ALIYUN_OSS_INTERNAL === 'true',\n };\n\n logger.info('✅ 从环境变量加载 OSS 配置成功', {\n region: config.region,\n bucket: config.bucket,\n hasCustomDomain: !!config.customDomain,\n });\n\n return config;\n}\n\n/**\n * 从环境变量加载阿里云 CDN 配置\n *\n * 支持的环境变量:\n * - ALIYUN_CDN_DOMAIN\n * - ALIYUN_CDN_ACCESS_KEY_ID\n * - ALIYUN_CDN_ACCESS_KEY_SECRET\n * - ALIYUN_CDN_REGION (可选)\n */\nexport function loadCDNConfigFromEnv(): AliyunCDNConfig | null {\n const domain = process.env.ALIYUN_CDN_DOMAIN;\n const accessKeyId = process.env.ALIYUN_CDN_ACCESS_KEY_ID;\n const accessKeySecret = process.env.ALIYUN_CDN_ACCESS_KEY_SECRET;\n\n // CDN 配置是可选的\n if (!domain || !accessKeyId || !accessKeySecret) {\n logger.debug('CDN 环境变量未配置或不完整');\n return null;\n }\n\n const config: AliyunCDNConfig = {\n type: 'aliyun-cdn',\n enabled: true,\n domain,\n accessKeyId,\n accessKeySecret,\n region: process.env.ALIYUN_CDN_REGION,\n };\n\n logger.info('✅ 从环境变量加载 CDN 配置成功', {\n domain: config.domain,\n });\n\n return config;\n}\n\n/**\n * 获取默认本地存储配置\n *\n * 支持的环境变量:\n * - FILE_STORAGE_PATH (可选,默认 'uploads')\n * - FILE_BASE_URL (可选,默认 '/uploads')\n */\nexport function getDefaultLocalStorage(): LocalStorageConfig {\n return {\n type: 'local',\n enabled: true,\n rootPath: process.env.FILE_STORAGE_PATH || 'uploads',\n baseUrl: process.env.FILE_BASE_URL || '/uploads',\n };\n}\n\n/**\n * 从环境变量加载完整的文件服务配置\n *\n * 配置优先级:\n * 1. 阿里云 OSS(如果配置完整)\n * 2. 本地存储(备用方案)\n *\n * 支持的环境变量:\n * - MAX_FILE_SIZE (可选,默认 100MB)\n * - ENABLE_CACHE (可选,默认 false)\n * - METADATA_CACHE_TTL (可选,默认 3600秒)\n * - URL_CACHE_TTL (可选,默认 1800秒)\n * - ENABLE_FILE_MONITORING (可选,默认 false)\n */\nexport function loadConfigFromEnv(): Partial<UniversalFileServiceConfig> {\n logger.info('从环境变量加载文件服务配置...');\n\n // 1. 尝试加载 OSS 配置\n const ossConfig = loadOSSConfigFromEnv();\n\n // 2. 加载 CDN 配置(可选)\n const cdnConfig = loadCDNConfigFromEnv();\n\n // 3. 决定存储方式:优先 OSS,否则本地存储\n const storage: StorageConfig = ossConfig || getDefaultLocalStorage();\n const defaultStorage = ossConfig ? 'aliyun-oss' : 'local';\n\n logger.info('使用存储方式: ' + (defaultStorage));\n\n // 4. 构建完整配置\n const config: Partial<UniversalFileServiceConfig> = {\n storage,\n defaultStorage,\n cdn: cdnConfig || undefined,\n defaultCDN: cdnConfig ? 'aliyun-cdn' : 'none',\n maxFileSize: process.env.MAX_FILE_SIZE\n ? parseInt(process.env.MAX_FILE_SIZE)\n : DEFAULT_MAX_FILE_SIZE,\n allowedMimeTypes: DEFAULT_ALLOWED_MIME_TYPES,\n cache: {\n enabled: process.env.ENABLE_CACHE === 'true',\n metadataTTL: process.env.METADATA_CACHE_TTL\n ? parseInt(process.env.METADATA_CACHE_TTL)\n : DEFAULT_CACHE_CONFIG.metadataTTL,\n urlTTL: process.env.URL_CACHE_TTL\n ? parseInt(process.env.URL_CACHE_TTL)\n : DEFAULT_CACHE_CONFIG.urlTTL,\n },\n enableMonitoring: process.env.ENABLE_FILE_MONITORING === 'true',\n };\n\n logger.info('✅ 配置加载完成');\n\n return config;\n}\n\n// ==================== 配置加载器接口 ====================\n\n/**\n * 配置服务接口\n *\n * 用于从配置管理系统加载配置\n */\nexport interface IConfigService {\n /**\n * 获取配置值\n */\n getConfig(key: string, defaultValue?: any): Promise<any>;\n}\n\n/**\n * 配置键映射\n */\nexport interface OSSConfigKeyMapping {\n region: string;\n bucket: string;\n accessKeyId: string;\n accessKeySecret: string;\n customDomain?: string;\n secure?: string;\n internal?: string;\n}\n\n/**\n * 默认的 OSS 配置键映射(阿里云标准)\n */\nexport const DEFAULT_OSS_CONFIG_KEYS: OSSConfigKeyMapping = {\n region: 'aliyun_oss_region',\n bucket: 'aliyun_oss_bucket',\n accessKeyId: 'aliyun_oss_access_key_id',\n accessKeySecret: 'aliyun_oss_access_key_secret',\n customDomain: 'aliyun_oss_custom_domain',\n secure: 'aliyun_oss_secure',\n internal: 'aliyun_oss_internal',\n};\n\n/**\n * 从配置服务加载 OSS 配置\n *\n * 通用函数,可用于任何实现了 IConfigService 接口的配置系统\n *\n * @param configService - 配置服务实例\n * @param keyMapping - 配置键映射(可选,默认使用标准键名)\n *\n * @example\n * ```typescript\n * import { loadOSSConfigFromService } from 'sa2kit/universalFile/server';\n *\n * const config = await loadOSSConfigFromService(myConfigService, {\n * region: 'oss_region',\n * bucket: 'oss_bucket',\n * // ...\n * });\n * ```\n */\nexport async function loadOSSConfigFromService(\n configService: IConfigService,\n keyMapping: Partial<OSSConfigKeyMapping> = DEFAULT_OSS_CONFIG_KEYS\n): Promise<AliyunOSSConfig | null> {\n const logger = createLogger('loadOSSConfigFromService');\n\n try {\n const keys = { ...DEFAULT_OSS_CONFIG_KEYS, ...keyMapping };\n\n const [region, bucket, accessKeyId, accessKeySecret, customDomain, secure, internal] =\n await Promise.all([\n configService.getConfig(keys.region),\n configService.getConfig(keys.bucket),\n configService.getConfig(keys.accessKeyId),\n configService.getConfig(keys.accessKeySecret),\n configService.getConfig(keys.customDomain || ''),\n configService.getConfig(keys.secure || ''),\n configService.getConfig(keys.internal || ''),\n ]);\n\n if (!region || !bucket || !accessKeyId || !accessKeySecret) {\n logger.debug('配置服务中的 OSS 配置不完整');\n return null;\n }\n\n const config: AliyunOSSConfig = {\n type: 'aliyun-oss',\n enabled: true,\n region,\n bucket,\n accessKeyId,\n accessKeySecret,\n customDomain,\n secure: secure === 'true' || secure === true,\n internal: internal === 'true' || internal === true,\n };\n\n logger.info('✅ 从配置服务加载 OSS 配置成功');\n\n return config;\n } catch (error) {\n logger.warn('从配置服务加载 OSS 配置失败:', error);\n return null;\n }\n}\n\n/**\n * 组合多个配置源\n *\n * 按优先级顺序尝试加载配置,返回第一个成功的配置\n *\n * @param loaders - 配置加载器数组(按优先级排序)\n *\n * @example\n * ```typescript\n * const config = await loadConfigWithFallback([\n * async () => loadOSSConfigFromService(configService),\n * () => loadOSSConfigFromEnv(),\n * ]);\n * ```\n */\nexport async function loadConfigWithFallback<T>(\n loaders: Array<() => Promise<T | null>>\n): Promise<T | null> {\n for (const loader of loaders) {\n try {\n const config = await loader();\n if (config) {\n return config;\n }\n } catch (error) {\n // 继续尝试下一个加载器\n continue;\n }\n }\n return null;\n}\n\n// ==================== 服务工厂 ====================\n\n/**\n * 文件服务工厂选项\n */\nexport interface FileServiceFactoryOptions {\n /**\n * 配置加载器(按优先级排序)\n */\n configLoaders?: Array<() => Promise<Partial<UniversalFileServiceConfig> | null>>;\n\n /**\n * 持久化仓储(可选)\n */\n repository?: any;\n\n /**\n * 自定义配置(会覆盖加载的配置)\n */\n customConfig?: Partial<UniversalFileServiceConfig>;\n\n /**\n * 是否自动初始化服务\n */\n autoInitialize?: boolean;\n}\n\n/**\n * 创建文件服务(工厂函数)\n *\n * 通用的服务创建函数,支持多种配置源和可选的持久化\n *\n * @param options - 工厂选项\n *\n * @example\n * ```typescript\n * import {\n * createFileServiceWithFactory,\n * loadOSSConfigFromService,\n * loadConfigFromEnv\n * } from 'sa2kit/universalFile/server';\n *\n * const service = await createFileServiceWithFactory({\n * configLoaders: [\n * async () => {\n * const ossConfig = await loadOSSConfigFromService(configService);\n * return ossConfig ? { storage: ossConfig, defaultStorage: 'aliyun-oss' } : null;\n * },\n * () => Promise.resolve(loadConfigFromEnv()),\n * ],\n * repository: myRepository,\n * autoInitialize: true,\n * });\n * ```\n */\nexport async function createFileServiceWithFactory(\n options: FileServiceFactoryOptions = {}\n): Promise<UniversalFileService> {\n const {\n configLoaders = [() => Promise.resolve(loadConfigFromEnv())],\n repository,\n customConfig,\n autoInitialize = false,\n } = options;\n\n const logger = createLogger('FileServiceFactory');\n\n logger.info('创建文件服务...');\n\n // 1. 加载配置(尝试所有配置加载器)\n let config: Partial<UniversalFileServiceConfig> | null = null;\n\n for (const loader of configLoaders) {\n try {\n const loadedConfig = await loader();\n if (loadedConfig) {\n config = loadedConfig;\n break;\n }\n } catch (error) {\n logger.warn('配置加载器失败:', error);\n continue;\n }\n }\n\n if (!config) {\n throw new Error('无法加载文件服务配置:所有配置源都失败');\n }\n\n // 2. 合并配置\n const finalConfig: Partial<UniversalFileServiceConfig> = {\n ...config,\n ...customConfig,\n };\n\n // 3. 添加持久化配置(如果提供)\n if (repository) {\n finalConfig.persistence = {\n enabled: true,\n repository,\n autoPersist: true,\n };\n }\n\n // 4. 创建服务\n const service = new UniversalFileService(finalConfig as UniversalFileServiceConfig);\n\n // 5. 可选的自动初始化\n if (autoInitialize) {\n try {\n await service.initialize();\n logger.info('✅ 文件服务创建并初始化完成');\n } catch (initError) {\n logger.warn('⚠️ 文件服务初始化失败,将提供延迟初始化的支持:', initError);\n\n // 返回服务实例,但标记为未完全初始化\n // 调用者可以稍后调用 reinitializeStorageProviders 来完成初始化\n logger.info('💡 提示:可调用 service.reinitializeStorageProviders() 来重新初始化存储提供者');\n }\n } else {\n logger.info('✅ 文件服务创建完成');\n }\n\n return service;\n}\n\n// ==================== 单例辅助函数 ====================\n\n/**\n * 单例工厂返回值\n */\nexport interface SingletonFactory<T> {\n /**\n * 获取单例实例\n */\n get(): Promise<T>;\n\n /**\n * 重置单例(主要用于测试)\n */\n reset(): void;\n\n /**\n * 检查单例是否已创建\n */\n isCreated(): boolean;\n}\n\n/**\n * 创建单例工厂\n *\n * 提供单例模式的通用实现,适用于需要单例的服务\n *\n * @param factory - 创建实例的工厂函数\n * @param options - 单例选项\n *\n * @example\n * ```typescript\n * const fileServiceSingleton = createSingleton(\n * async () => {\n * const service = new UniversalFileService(config);\n * await service.initialize();\n * return service;\n * },\n * { autoInitialize: true }\n * );\n *\n * // 获取单例\n * const service = await fileServiceSingleton.get();\n *\n * // 重置(测试用)\n * fileServiceSingleton.reset();\n * ```\n */\nexport function createSingleton<T>(\n factory: () => Promise<T>,\n options: {\n /** 是否在第一次获取时自动初始化(默认 true) */\n autoInitialize?: boolean;\n /** 单例名称(用于日志) */\n name?: string;\n } = {}\n): SingletonFactory<T> {\n const { autoInitialize = true, name = 'Singleton' } = options;\n const singletonLogger = createLogger(name);\n\n let instance: T | null = null;\n let initPromise: Promise<T> | null = null;\n\n return {\n async get(): Promise<T> {\n // 如果已经有实例,直接返回\n if (instance) {\n return instance;\n }\n\n // 如果正在初始化,等待初始化完成\n if (initPromise) {\n singletonLogger.debug('等待实例初始化完成...');\n return initPromise;\n }\n\n // 开始初始化\n singletonLogger.info('创建单例实例...');\n initPromise = factory();\n\n try {\n instance = await initPromise;\n singletonLogger.info('✅ 单例实例创建完成');\n return instance;\n } catch (error) {\n singletonLogger.error('❌ 单例实例创建失败:', error);\n initPromise = null; // 重置,允许重试\n throw error;\n }\n },\n\n reset(): void {\n if (instance) {\n singletonLogger.info('重置单例实例');\n instance = null;\n initPromise = null;\n }\n },\n\n isCreated(): boolean {\n return instance !== null;\n },\n };\n}\n\n"]}
|