@alibarbar/common 1.0.0 → 1.0.2

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.
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["../src/types/upload.ts","../src/browser/upload.ts"],"names":["UploadStatus","splitFileIntoChunks","calculateBlobMD5","result"],"mappings":"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","file":"chunk-TADFN7AL.js","sourcesContent":["/**\n * 文件上传相关类型定义\n */\n\n/**\n * 上传初始化请求参数\n */\nexport interface UploadInitRequest {\n fileName: string;\n fileSize: number;\n fileMd5: string;\n chunkSize?: number;\n}\n\n/**\n * 上传初始化响应\n */\nexport interface UploadInitResponse {\n taskId: string;\n totalChunks: number;\n existingChunks: number[];\n instantUpload: boolean;\n fileUrl?: string;\n chunkSize: number;\n}\n\n/**\n * 分片上传响应\n */\nexport interface ChunkUploadResponse {\n chunkIndex: number;\n success: boolean;\n message: string;\n chunkMd5: string;\n}\n\n/**\n * 完成上传响应\n */\nexport interface CompleteUploadResponse {\n taskId: string;\n fileUrl: string;\n fileName: string;\n fileSize: number;\n fileMd5: string;\n success: boolean;\n message: string;\n}\n\n/**\n * 上传进度信息\n */\nexport interface UploadProgress {\n taskId: string;\n fileName: string;\n fileSize: number;\n totalChunks: number;\n uploadedChunks: number;\n percentage: number;\n status: string;\n uploadedSize: number;\n}\n\n/**\n * API响应包装类型\n */\nexport interface ApiResponse<T> {\n code: number;\n message: string;\n data: T;\n timestamp: number;\n}\n\n/**\n * 上传配置选项\n */\nexport interface UploadOptions {\n /** 分片大小(字节),默认 2MB */\n chunkSize?: number;\n /** 并发上传数量,默认 3 */\n concurrency?: number;\n /** 重试次数,默认 3 */\n retryCount?: number;\n /** 重试延迟(毫秒),默认 1000 */\n retryDelay?: number;\n /** 基础API地址 */\n baseURL?: string;\n /** 请求头 */\n headers?: Record<string, string>;\n /** 上传进度回调 */\n onProgress?: (progress: UploadProgress) => void;\n /** 上传完成回调 */\n onComplete?: (result: CompleteUploadResponse) => void;\n /** 上传错误回调 */\n onError?: (error: Error) => void;\n}\n\n/**\n * 上传状态\n */\nexport enum UploadStatus {\n PENDING = 'pending',\n UPLOADING = 'uploading',\n PAUSED = 'paused',\n COMPLETED = 'completed',\n FAILED = 'failed',\n CANCELLED = 'cancelled',\n}\n\n/**\n * 文件分片信息\n */\nexport interface ChunkInfo {\n index: number;\n start: number;\n end: number;\n blob: Blob;\n md5?: string;\n}\n","/**\n * 文件分片上传工具类\n * 支持分片上传、断点续传、进度追踪\n */\n\nimport {\n UploadOptions,\n UploadInitRequest,\n UploadInitResponse,\n ChunkUploadResponse,\n CompleteUploadResponse,\n UploadProgress,\n UploadStatus,\n ChunkInfo,\n ApiResponse,\n} from '../types/upload';\nimport { calculateBlobMD5, splitFileIntoChunks } from './file';\n\n/**\n * 文件上传器类\n */\nexport class ChunkUploader {\n private file: File;\n private options: Required<UploadOptions>;\n private taskId: string | null = null;\n private chunks: ChunkInfo[] = [];\n private uploadedChunks: Set<number> = new Set();\n private status: UploadStatus = UploadStatus.PENDING;\n private abortController: AbortController | null = null;\n private initResponse: UploadInitResponse | null = null;\n\n constructor(file: File, options: UploadOptions = {}) {\n this.file = file;\n this.options = {\n chunkSize: options.chunkSize || 2 * 1024 * 1024, // 默认2MB\n concurrency: options.concurrency || 3,\n retryCount: options.retryCount || 3,\n retryDelay: options.retryDelay || 1000,\n baseURL: options.baseURL || '',\n headers: options.headers || {},\n onProgress: options.onProgress || (() => {}),\n onComplete: options.onComplete || (() => {}),\n onError: options.onError || (() => {}),\n };\n }\n\n /**\n * 初始化上传\n */\n private async initUpload(): Promise<UploadInitResponse> {\n const fileMd5 = await this.calculateFileMD5();\n const request: UploadInitRequest = {\n fileName: this.file.name,\n fileSize: this.file.size,\n fileMd5,\n chunkSize: this.options.chunkSize,\n };\n\n const response = await this.request<ApiResponse<UploadInitResponse>>('/api/files/common/init', {\n method: 'POST',\n headers: {\n 'Content-Type': 'application/json',\n ...this.options.headers,\n },\n body: JSON.stringify(request),\n });\n\n if (response.code !== 200) {\n throw new Error(response.message || '初始化上传失败');\n }\n\n return response.data;\n }\n\n /**\n * 计算文件MD5(简化版,实际应该使用spark-md5等库)\n */\n private async calculateFileMD5(): Promise<string> {\n // 这里使用简化的方法,实际项目中应该使用spark-md5库\n const chunks = splitFileIntoChunks(this.file, this.options.chunkSize);\n const md5Promises = chunks.map((chunk, index) =>\n calculateBlobMD5(chunk).then(md5 => ({ index, md5 }))\n );\n const md5Results = await Promise.all(md5Promises);\n // 简单拼接,实际应该使用正确的MD5算法\n return md5Results.map(r => r.md5).join('');\n }\n\n /**\n * 准备分片\n */\n private prepareChunks(): void {\n const blobChunks = splitFileIntoChunks(this.file, this.options.chunkSize);\n this.chunks = blobChunks.map((blob, index) => ({\n index,\n start: index * this.options.chunkSize,\n end: Math.min((index + 1) * this.options.chunkSize, this.file.size),\n blob,\n }));\n }\n\n /**\n * 获取已上传的分片列表\n */\n private async getUploadedChunks(): Promise<number[]> {\n if (!this.taskId) return [];\n\n try {\n const response = await this.request<ApiResponse<number[]>>(\n `/api/files/common/chunks/${this.taskId}`,\n {\n method: 'GET',\n headers: this.options.headers,\n }\n );\n\n if (response.code === 200) {\n return response.data || [];\n }\n } catch (error) {\n console.warn('获取已上传分片失败:', error);\n }\n\n return [];\n }\n\n /**\n * 上传单个分片\n */\n private async uploadChunk(chunkInfo: ChunkInfo, retryCount = 0): Promise<void> {\n if (!this.taskId) {\n throw new Error('任务ID不存在');\n }\n\n if (this.uploadedChunks.has(chunkInfo.index)) {\n return; // 已上传,跳过\n }\n\n try {\n // 计算分片MD5\n const chunkMd5 = await calculateBlobMD5(chunkInfo.blob);\n\n const formData = new FormData();\n formData.append('file', chunkInfo.blob, this.file.name);\n\n const url = `/api/files/common/chunk?taskId=${this.taskId}&chunkIndex=${chunkInfo.index}&chunkMd5=${chunkMd5}`;\n\n const response = await this.request<ApiResponse<ChunkUploadResponse>>(url, {\n method: 'POST',\n headers: this.options.headers,\n body: formData,\n });\n\n if (response.code === 200 && response.data.success) {\n this.uploadedChunks.add(chunkInfo.index);\n this.updateProgress();\n } else {\n throw new Error(response.message || '分片上传失败');\n }\n } catch (error) {\n if (retryCount < this.options.retryCount) {\n await this.delay(this.options.retryDelay);\n return this.uploadChunk(chunkInfo, retryCount + 1);\n }\n throw error;\n }\n }\n\n /**\n * 并发上传分片\n */\n private async uploadChunksConcurrently(): Promise<void> {\n const chunksToUpload = this.chunks.filter(chunk => !this.uploadedChunks.has(chunk.index));\n\n if (chunksToUpload.length === 0) {\n return; // 所有分片已上传\n }\n\n // 使用信号量控制并发数\n let currentIndex = 0;\n const semaphore = new Array(this.options.concurrency).fill(null);\n const allUploadPromises: Promise<void>[] = [];\n\n const uploadNext = async (): Promise<void> => {\n while (this.status === UploadStatus.UPLOADING) {\n // 原子性地获取下一个分片索引\n const chunkIndex = currentIndex++;\n if (chunkIndex >= chunksToUpload.length) {\n break; // 没有更多分片需要上传\n }\n\n const chunk = chunksToUpload[chunkIndex];\n // 创建上传 Promise 并添加到总数组中\n const uploadPromise = this.uploadChunk(chunk);\n allUploadPromises.push(uploadPromise);\n\n // 等待当前分片上传完成(这样可以控制并发数)\n await uploadPromise;\n }\n };\n\n // 启动并发上传任务(最多 concurrency 个并发)\n const concurrencyPromises = semaphore.map(() => uploadNext());\n\n // 等待所有并发任务完成\n await Promise.all(concurrencyPromises);\n\n // 确保所有上传 Promise 都已完成(双重保险)\n await Promise.all(allUploadPromises);\n\n // 最终验证所有分片都已上传\n const totalChunks = this.chunks.length;\n const uploadedCount = this.uploadedChunks.size;\n if (uploadedCount < totalChunks) {\n const missingChunks = this.chunks\n .map((chunk, index) => (!this.uploadedChunks.has(index) ? index : null))\n .filter(index => index !== null);\n throw new Error(\n `上传未完成:已上传 ${uploadedCount}/${totalChunks} 个分片,缺失分片索引: ${missingChunks.join(', ')}`\n );\n }\n }\n\n /**\n * 获取上传进度(用于验证上传是否完成)\n */\n private async getUploadProgress(): Promise<UploadProgress | null> {\n if (!this.taskId) {\n return null;\n }\n\n try {\n const response = await this.request<ApiResponse<UploadProgress>>(\n `/api/files/common/progress/${this.taskId}`,\n {\n method: 'GET',\n headers: this.options.headers,\n }\n );\n\n if (response.code === 200) {\n return response.data;\n }\n } catch (error) {\n console.warn('获取上传进度失败:', error);\n }\n\n return null;\n }\n\n /**\n * 完成上传(调用后端合并分片接口)\n *\n * 只有在进度为 100% 时才会被调用\n */\n private async completeUpload(): Promise<CompleteUploadResponse> {\n if (!this.taskId) {\n throw new Error('任务ID不存在');\n }\n\n const response = await this.request<ApiResponse<CompleteUploadResponse>>(\n `/api/files/common/complete/${this.taskId}`,\n {\n method: 'POST',\n headers: this.options.headers,\n }\n );\n\n if (response.code !== 200) {\n throw new Error(response.message || '完成上传失败');\n }\n\n return response.data;\n }\n\n /**\n * 更新上传进度(仅用于回调前端显示)\n */\n private async updateProgress(): Promise<void> {\n if (!this.taskId) return;\n\n try {\n const response = await this.request<ApiResponse<UploadProgress>>(\n `/api/files/common/progress/${this.taskId}`,\n {\n method: 'GET',\n headers: this.options.headers,\n }\n );\n\n if (response.code === 200 && this.options.onProgress) {\n this.options.onProgress(response.data);\n }\n } catch (error) {\n console.warn('获取上传进度失败:', error);\n }\n }\n\n /**\n * 开始上传\n */\n async upload(): Promise<CompleteUploadResponse> {\n try {\n this.status = UploadStatus.UPLOADING;\n this.abortController = new AbortController();\n\n // 1. 初始化上传\n const initResponse = await this.initUpload();\n this.taskId = initResponse.taskId;\n\n // 如果已经完成上传(秒传)\n if (initResponse.instantUpload && initResponse.fileUrl) {\n this.status = UploadStatus.COMPLETED;\n const result: CompleteUploadResponse = {\n taskId: this.taskId,\n fileUrl: initResponse.fileUrl,\n fileName: this.file.name,\n fileSize: this.file.size,\n fileMd5: '',\n success: true,\n message: '文件已存在,秒传成功',\n };\n this.options.onComplete(result);\n return result;\n }\n\n // 2. 准备分片\n this.prepareChunks();\n\n // 3. 获取已上传的分片(断点续传)\n const existingChunks = await this.getUploadedChunks();\n existingChunks.forEach(index => this.uploadedChunks.add(index));\n\n // 4. 上传分片\n await this.uploadChunksConcurrently();\n\n // 5. 再次验证所有分片都已上传(双重检查)\n const totalChunks = this.chunks.length;\n const uploadedCount = this.uploadedChunks.size;\n if (uploadedCount < totalChunks) {\n throw new Error(\n `上传验证失败:已上传 ${uploadedCount}/${totalChunks} 个分片,无法完成上传`\n );\n }\n\n // 6. 获取最终上传进度,确认100%完成\n const progress = await this.getUploadProgress();\n if (!progress || progress.percentage < 100) {\n const current = progress ? progress.percentage : 0;\n throw new Error(`上传未完成:当前进度 ${current}%`);\n }\n\n // 7. 进度为 100% 时,调用完成接口,通知后端合并分片\n const result = await this.completeUpload();\n\n this.status = UploadStatus.COMPLETED;\n this.options.onComplete(result);\n\n return result;\n } catch (error) {\n this.status = UploadStatus.FAILED;\n const err = error instanceof Error ? error : new Error(String(error));\n this.options.onError(err);\n throw err;\n }\n }\n\n /**\n * 暂停上传\n */\n pause(): void {\n if (this.status === UploadStatus.UPLOADING) {\n this.status = UploadStatus.PAUSED;\n if (this.abortController) {\n this.abortController.abort();\n }\n }\n }\n\n /**\n * 恢复上传\n */\n async resume(): Promise<CompleteUploadResponse> {\n if (this.status === UploadStatus.PAUSED) {\n return this.upload();\n }\n throw new Error('当前状态无法恢复上传');\n }\n\n /**\n * 取消上传\n */\n async cancel(): Promise<void> {\n if (this.taskId && this.status === UploadStatus.UPLOADING) {\n try {\n await this.request<ApiResponse<null>>(`/api/files/common/cancel/${this.taskId}`, {\n method: 'POST',\n headers: this.options.headers,\n });\n } catch (error) {\n console.warn('取消上传失败:', error);\n }\n }\n\n this.status = UploadStatus.CANCELLED;\n if (this.abortController) {\n this.abortController.abort();\n }\n }\n\n /**\n * 获取当前状态\n */\n getStatus(): UploadStatus {\n return this.status;\n }\n\n /**\n * 获取任务ID\n */\n getTaskId(): string | null {\n return this.taskId;\n }\n\n /**\n * HTTP请求封装\n */\n private async request<T>(url: string, options: RequestInit = {}): Promise<T> {\n const fullUrl = `${this.options.baseURL}${url}`;\n const signal = this.abortController?.signal;\n\n const response = await fetch(fullUrl, {\n ...options,\n signal,\n });\n\n if (!response.ok) {\n throw new Error(`HTTP错误: ${response.status} ${response.statusText}`);\n }\n\n return response.json();\n }\n\n /**\n * 延迟函数\n */\n private delay(ms: number): Promise<void> {\n return new Promise(resolve => setTimeout(resolve, ms));\n }\n}\n\n/**\n * 创建文件上传器实例\n * @param file - 文件对象\n * @param options - 上传配置选项\n * @returns 上传器实例\n */\nexport function createUploader(file: File, options?: UploadOptions): ChunkUploader {\n return new ChunkUploader(file, options);\n}\n"]}
package/dist/index.d.mts CHANGED
@@ -8,7 +8,7 @@ export { ParsedUrl, buildUrl, getQueryParams, isAbsoluteUrl, joinUrl, normalizeU
8
8
  export { HSL, RGB, contrast, darken, hexToRgb, hslToRgb, lighten, mix, rgbToHex, rgbToHsl } from './color.mjs';
9
9
  export { CurrencyCode, Locale, TranslationDictionary, createTranslator, formatCurrencyI18n, formatDateI18n, formatNumberI18n, formatRelativeTime, getLocale, pluralize, translate } from './i18n.mjs';
10
10
  export { calculateBlobMD5, calculateFileMD5, formatFileSize, getFileExtension, getFileNameWithoutExtension, splitFileIntoChunks } from './file.mjs';
11
- export { A as ApiResponse, h as ChunkInfo, b as ChunkUploadResponse, C as ChunkUploader, d as CompleteUploadResponse, U as UploadInitRequest, a as UploadInitResponse, f as UploadOptions, e as UploadProgress, g as UploadStatus, c as createUploader } from './upload-DzlQtUBc.mjs';
11
+ export { A as ApiResponse, h as ChunkInfo, b as ChunkUploadResponse, C as ChunkUploader, d as CompleteUploadResponse, U as UploadInitRequest, a as UploadInitResponse, f as UploadOptions, e as UploadProgress, g as UploadStatus, c as createUploader } from './upload-DlwmBwz0.mjs';
12
12
  export { StorageOptions, cookie, getStorageKeyPair, localStorage, sessionStorage, setStorageKeyPair, storage } from './storage.mjs';
13
13
  export { checkOnline, downloadFile, fetchWithRetry, fetchWithTimeout, request } from './network.mjs';
14
14
  export { $, $$, addClass, copyToClipboard, getElementOffset, getScrollPosition, getStyle, isInViewport, removeClass, scrollTo, setStyle, toggleClass } from './dom.mjs';
package/dist/index.d.ts CHANGED
@@ -8,7 +8,7 @@ export { ParsedUrl, buildUrl, getQueryParams, isAbsoluteUrl, joinUrl, normalizeU
8
8
  export { HSL, RGB, contrast, darken, hexToRgb, hslToRgb, lighten, mix, rgbToHex, rgbToHsl } from './color.js';
9
9
  export { CurrencyCode, Locale, TranslationDictionary, createTranslator, formatCurrencyI18n, formatDateI18n, formatNumberI18n, formatRelativeTime, getLocale, pluralize, translate } from './i18n.js';
10
10
  export { calculateBlobMD5, calculateFileMD5, formatFileSize, getFileExtension, getFileNameWithoutExtension, splitFileIntoChunks } from './file.js';
11
- export { A as ApiResponse, h as ChunkInfo, b as ChunkUploadResponse, C as ChunkUploader, d as CompleteUploadResponse, U as UploadInitRequest, a as UploadInitResponse, f as UploadOptions, e as UploadProgress, g as UploadStatus, c as createUploader } from './upload-DzlQtUBc.js';
11
+ export { A as ApiResponse, h as ChunkInfo, b as ChunkUploadResponse, C as ChunkUploader, d as CompleteUploadResponse, U as UploadInitRequest, a as UploadInitResponse, f as UploadOptions, e as UploadProgress, g as UploadStatus, c as createUploader } from './upload-DlwmBwz0.js';
12
12
  export { StorageOptions, cookie, getStorageKeyPair, localStorage, sessionStorage, setStorageKeyPair, storage } from './storage.js';
13
13
  export { checkOnline, downloadFile, fetchWithRetry, fetchWithTimeout, request } from './network.js';
14
14
  export { $, $$, addClass, copyToClipboard, getElementOffset, getScrollPosition, getStyle, isInViewport, removeClass, scrollTo, setStyle, toggleClass } from './dom.js';
package/dist/index.js CHANGED
@@ -6,7 +6,7 @@ var chunkJQZBPAPO_js = require('./chunk-JQZBPAPO.js');
6
6
  var chunk56W6YECK_js = require('./chunk-56W6YECK.js');
7
7
  var chunkY364QIQH_js = require('./chunk-Y364QIQH.js');
8
8
  var chunkOX5PLOWB_js = require('./chunk-OX5PLOWB.js');
9
- var chunkF3LAGHPG_js = require('./chunk-F3LAGHPG.js');
9
+ var chunkTADFN7AL_js = require('./chunk-TADFN7AL.js');
10
10
  var chunk7V5UQXIO_js = require('./chunk-7V5UQXIO.js');
11
11
  var chunkXVUE53T3_js = require('./chunk-XVUE53T3.js');
12
12
  var chunkDYBSRI7V_js = require('./chunk-DYBSRI7V.js');
@@ -14,11 +14,11 @@ var chunk4RGXV4SJ_js = require('./chunk-4RGXV4SJ.js');
14
14
  var chunkJK2SE3I2_js = require('./chunk-JK2SE3I2.js');
15
15
  var chunkZDMFMUDR_js = require('./chunk-ZDMFMUDR.js');
16
16
  var chunkD7CS5EKF_js = require('./chunk-D7CS5EKF.js');
17
- var chunkLCXGZISK_js = require('./chunk-LCXGZISK.js');
17
+ var chunkLOAZSPGQ_js = require('./chunk-LOAZSPGQ.js');
18
18
  var chunk27UDDVLZ_js = require('./chunk-27UDDVLZ.js');
19
19
  var chunkI3L42475_js = require('./chunk-I3L42475.js');
20
20
  var chunkTQN37HIN_js = require('./chunk-TQN37HIN.js');
21
- var chunkMMR6XQNX_js = require('./chunk-MMR6XQNX.js');
21
+ var chunk3FRYJPHG_js = require('./chunk-3FRYJPHG.js');
22
22
  var chunkKGFTD255_js = require('./chunk-KGFTD255.js');
23
23
 
24
24
 
@@ -225,15 +225,15 @@ Object.defineProperty(exports, "translate", {
225
225
  });
226
226
  Object.defineProperty(exports, "ChunkUploader", {
227
227
  enumerable: true,
228
- get: function () { return chunkF3LAGHPG_js.ChunkUploader; }
228
+ get: function () { return chunkTADFN7AL_js.ChunkUploader; }
229
229
  });
230
230
  Object.defineProperty(exports, "UploadStatus", {
231
231
  enumerable: true,
232
- get: function () { return chunkF3LAGHPG_js.UploadStatus; }
232
+ get: function () { return chunkTADFN7AL_js.UploadStatus; }
233
233
  });
234
234
  Object.defineProperty(exports, "createUploader", {
235
235
  enumerable: true,
236
- get: function () { return chunkF3LAGHPG_js.createUploader; }
236
+ get: function () { return chunkTADFN7AL_js.createUploader; }
237
237
  });
238
238
  Object.defineProperty(exports, "calculateBlobMD5", {
239
239
  enumerable: true,
@@ -489,79 +489,79 @@ Object.defineProperty(exports, "unescapeHtml", {
489
489
  });
490
490
  Object.defineProperty(exports, "chunk", {
491
491
  enumerable: true,
492
- get: function () { return chunkLCXGZISK_js.chunk; }
492
+ get: function () { return chunkLOAZSPGQ_js.chunk; }
493
493
  });
494
494
  Object.defineProperty(exports, "compact", {
495
495
  enumerable: true,
496
- get: function () { return chunkLCXGZISK_js.compact; }
496
+ get: function () { return chunkLOAZSPGQ_js.compact; }
497
497
  });
498
498
  Object.defineProperty(exports, "difference", {
499
499
  enumerable: true,
500
- get: function () { return chunkLCXGZISK_js.difference; }
500
+ get: function () { return chunkLOAZSPGQ_js.difference; }
501
501
  });
502
502
  Object.defineProperty(exports, "drop", {
503
503
  enumerable: true,
504
- get: function () { return chunkLCXGZISK_js.drop; }
504
+ get: function () { return chunkLOAZSPGQ_js.drop; }
505
505
  });
506
506
  Object.defineProperty(exports, "dropWhile", {
507
507
  enumerable: true,
508
- get: function () { return chunkLCXGZISK_js.dropWhile; }
508
+ get: function () { return chunkLOAZSPGQ_js.dropWhile; }
509
509
  });
510
510
  Object.defineProperty(exports, "findIndexBy", {
511
511
  enumerable: true,
512
- get: function () { return chunkLCXGZISK_js.findIndexBy; }
512
+ get: function () { return chunkLOAZSPGQ_js.findIndexBy; }
513
513
  });
514
514
  Object.defineProperty(exports, "flatten", {
515
515
  enumerable: true,
516
- get: function () { return chunkLCXGZISK_js.flatten; }
516
+ get: function () { return chunkLOAZSPGQ_js.flatten; }
517
517
  });
518
518
  Object.defineProperty(exports, "groupBy", {
519
519
  enumerable: true,
520
- get: function () { return chunkLCXGZISK_js.groupBy; }
520
+ get: function () { return chunkLOAZSPGQ_js.groupBy; }
521
521
  });
522
522
  Object.defineProperty(exports, "intersection", {
523
523
  enumerable: true,
524
- get: function () { return chunkLCXGZISK_js.intersection; }
524
+ get: function () { return chunkLOAZSPGQ_js.intersection; }
525
525
  });
526
526
  Object.defineProperty(exports, "partition", {
527
527
  enumerable: true,
528
- get: function () { return chunkLCXGZISK_js.partition; }
528
+ get: function () { return chunkLOAZSPGQ_js.partition; }
529
529
  });
530
530
  Object.defineProperty(exports, "sample", {
531
531
  enumerable: true,
532
- get: function () { return chunkLCXGZISK_js.sample; }
532
+ get: function () { return chunkLOAZSPGQ_js.sample; }
533
533
  });
534
534
  Object.defineProperty(exports, "shuffle", {
535
535
  enumerable: true,
536
- get: function () { return chunkLCXGZISK_js.shuffle; }
536
+ get: function () { return chunkLOAZSPGQ_js.shuffle; }
537
537
  });
538
538
  Object.defineProperty(exports, "sortBy", {
539
539
  enumerable: true,
540
- get: function () { return chunkLCXGZISK_js.sortBy; }
540
+ get: function () { return chunkLOAZSPGQ_js.sortBy; }
541
541
  });
542
542
  Object.defineProperty(exports, "take", {
543
543
  enumerable: true,
544
- get: function () { return chunkLCXGZISK_js.take; }
544
+ get: function () { return chunkLOAZSPGQ_js.take; }
545
545
  });
546
546
  Object.defineProperty(exports, "takeWhile", {
547
547
  enumerable: true,
548
- get: function () { return chunkLCXGZISK_js.takeWhile; }
548
+ get: function () { return chunkLOAZSPGQ_js.takeWhile; }
549
549
  });
550
550
  Object.defineProperty(exports, "union", {
551
551
  enumerable: true,
552
- get: function () { return chunkLCXGZISK_js.union; }
552
+ get: function () { return chunkLOAZSPGQ_js.union; }
553
553
  });
554
554
  Object.defineProperty(exports, "unique", {
555
555
  enumerable: true,
556
- get: function () { return chunkLCXGZISK_js.unique; }
556
+ get: function () { return chunkLOAZSPGQ_js.unique; }
557
557
  });
558
558
  Object.defineProperty(exports, "unzip", {
559
559
  enumerable: true,
560
- get: function () { return chunkLCXGZISK_js.unzip; }
560
+ get: function () { return chunkLOAZSPGQ_js.unzip; }
561
561
  });
562
562
  Object.defineProperty(exports, "zip", {
563
563
  enumerable: true,
564
- get: function () { return chunkLCXGZISK_js.zip; }
564
+ get: function () { return chunkLOAZSPGQ_js.zip; }
565
565
  });
566
566
  Object.defineProperty(exports, "deepClone", {
567
567
  enumerable: true,
@@ -753,51 +753,51 @@ Object.defineProperty(exports, "isValidUrl", {
753
753
  });
754
754
  Object.defineProperty(exports, "ceil", {
755
755
  enumerable: true,
756
- get: function () { return chunkMMR6XQNX_js.ceil; }
756
+ get: function () { return chunk3FRYJPHG_js.ceil; }
757
757
  });
758
758
  Object.defineProperty(exports, "clamp", {
759
759
  enumerable: true,
760
- get: function () { return chunkMMR6XQNX_js.clamp; }
760
+ get: function () { return chunk3FRYJPHG_js.clamp; }
761
761
  });
762
762
  Object.defineProperty(exports, "floor", {
763
763
  enumerable: true,
764
- get: function () { return chunkMMR6XQNX_js.floor; }
764
+ get: function () { return chunk3FRYJPHG_js.floor; }
765
765
  });
766
766
  Object.defineProperty(exports, "formatBytes", {
767
767
  enumerable: true,
768
- get: function () { return chunkMMR6XQNX_js.formatBytes; }
768
+ get: function () { return chunk3FRYJPHG_js.formatBytes; }
769
769
  });
770
770
  Object.defineProperty(exports, "formatCurrency", {
771
771
  enumerable: true,
772
- get: function () { return chunkMMR6XQNX_js.formatCurrency; }
772
+ get: function () { return chunk3FRYJPHG_js.formatCurrency; }
773
773
  });
774
774
  Object.defineProperty(exports, "formatNumber", {
775
775
  enumerable: true,
776
- get: function () { return chunkMMR6XQNX_js.formatNumber; }
776
+ get: function () { return chunk3FRYJPHG_js.formatNumber; }
777
777
  });
778
778
  Object.defineProperty(exports, "isBetween", {
779
779
  enumerable: true,
780
- get: function () { return chunkMMR6XQNX_js.isBetween; }
780
+ get: function () { return chunk3FRYJPHG_js.isBetween; }
781
781
  });
782
782
  Object.defineProperty(exports, "parseNumber", {
783
783
  enumerable: true,
784
- get: function () { return chunkMMR6XQNX_js.parseNumber; }
784
+ get: function () { return chunk3FRYJPHG_js.parseNumber; }
785
785
  });
786
786
  Object.defineProperty(exports, "percent", {
787
787
  enumerable: true,
788
- get: function () { return chunkMMR6XQNX_js.percent; }
788
+ get: function () { return chunk3FRYJPHG_js.percent; }
789
789
  });
790
790
  Object.defineProperty(exports, "random", {
791
791
  enumerable: true,
792
- get: function () { return chunkMMR6XQNX_js.random; }
792
+ get: function () { return chunk3FRYJPHG_js.random; }
793
793
  });
794
794
  Object.defineProperty(exports, "round", {
795
795
  enumerable: true,
796
- get: function () { return chunkMMR6XQNX_js.round; }
796
+ get: function () { return chunk3FRYJPHG_js.round; }
797
797
  });
798
798
  Object.defineProperty(exports, "toFixed", {
799
799
  enumerable: true,
800
- get: function () { return chunkMMR6XQNX_js.toFixed; }
800
+ get: function () { return chunk3FRYJPHG_js.toFixed; }
801
801
  });
802
802
  Object.defineProperty(exports, "buildUrl", {
803
803
  enumerable: true,
package/dist/index.mjs CHANGED
@@ -4,7 +4,7 @@ export { Queue, batch, debounce, memoize, once, retry, throttle, timeout } from
4
4
  export { Tracker, createTracker, flush, getTracker, initTracker, setCommonParams, setUserInfo, trackClick, trackEvent, trackExposure, trackPageView } from './chunk-PJ7UCTX4.mjs';
5
5
  export { contrast, darken, hexToRgb, hslToRgb, lighten, mix, rgbToHex, rgbToHsl } from './chunk-QIOC54LQ.mjs';
6
6
  export { createTranslator, formatCurrencyI18n, formatDateI18n, formatNumberI18n, formatRelativeTime, getLocale, pluralize, translate } from './chunk-QIBE7GVN.mjs';
7
- export { ChunkUploader, UploadStatus, createUploader } from './chunk-QV6MIQ7H.mjs';
7
+ export { ChunkUploader, UploadStatus, createUploader } from './chunk-RZAVU7BP.mjs';
8
8
  export { calculateBlobMD5, calculateFileMD5, formatFileSize, getFileExtension, getFileNameWithoutExtension, splitFileIntoChunks } from './chunk-ZVJ6NQUM.mjs';
9
9
  export { cookie, getStorageKeyPair, localStorage, sessionStorage, setStorageKeyPair, storage } from './chunk-HME2N3VY.mjs';
10
10
  export { base64Decode, base64Encode, exportPrivateKey, exportPublicKey, generateRSAKeyPair, generateRandomString, generateUUID, hash, importPrivateKey, importPublicKey, rsaDecrypt, rsaEncrypt, sha256 } from './chunk-HLDFI7R2.mjs';
@@ -12,11 +12,11 @@ export { checkOnline, downloadFile, fetchWithRetry, fetchWithTimeout, request }
12
12
  export { $, $$, addClass, copyToClipboard, getElementOffset, getScrollPosition, getStyle, isInViewport, removeClass, scrollTo, setStyle, toggleClass } from './chunk-LF4CILQS.mjs';
13
13
  export { csvToJson, jsonToCsv, jsonToXml, jsonToYaml, xmlToJson, yamlToJson } from './chunk-7E6GELHJ.mjs';
14
14
  export { camelCase, capitalize, escapeHtml, highlight, kebabCase, mask, maskEmail, maskPhone, pascalCase, removeAccents, slugify, snakeCase, template, truncate, unescapeHtml } from './chunk-XJTZDXSR.mjs';
15
- export { chunk, compact, difference, drop, dropWhile, findIndexBy, flatten, groupBy, intersection, partition, sample, shuffle, sortBy, take, takeWhile, union, unique, unzip, zip } from './chunk-2FFSQ573.mjs';
15
+ export { chunk, compact, difference, drop, dropWhile, findIndexBy, flatten, groupBy, intersection, partition, sample, shuffle, sortBy, take, takeWhile, union, unique, unzip, zip } from './chunk-2R2QWFJC.mjs';
16
16
  export { deepClone, deepMerge, defaults, get, invert, isEmptyObject, isEqual, keys, mapKeys, mapValues, merge, omit, omitBy, pick, pickBy, set, transform, values } from './chunk-JBLX27WD.mjs';
17
17
  export { addDays, addMonths, addYears, diffDays, endOfDay, formatDate, getDateFormatByGMT, getQuarter, getRelativeTime, getTimeFromGMT, getWeekNumber, isToday, isWeekday, isWeekend, isYesterday, startOfDay } from './chunk-5BGSUGTI.mjs';
18
18
  export { isEmpty, isFloat, isInteger, isNumeric, isValidDomain, isValidEmail, isValidHexColor, isValidIP, isValidIdCard, isValidJSON, isValidPhone, isValidUUID, isValidUrl } from './chunk-NSSDYX2U.mjs';
19
- export { ceil, clamp, floor, formatBytes, formatCurrency, formatNumber, isBetween, parseNumber, percent, random, round, toFixed } from './chunk-ALDC6LRJ.mjs';
19
+ export { ceil, clamp, floor, formatBytes, formatCurrency, formatNumber, isBetween, parseNumber, percent, random, round, toFixed } from './chunk-CDSGEAOK.mjs';
20
20
  export { buildUrl, getQueryParams, isAbsoluteUrl, joinUrl, normalizeUrl, parseUrl, removeQueryParams, setQueryParams, updateQueryParams } from './chunk-YXM6Q4JS.mjs';
21
21
  //# sourceMappingURL=index.mjs.map
22
22
  //# sourceMappingURL=index.mjs.map
package/dist/number.js CHANGED
@@ -1,56 +1,56 @@
1
1
  'use strict';
2
2
 
3
- var chunkMMR6XQNX_js = require('./chunk-MMR6XQNX.js');
3
+ var chunk3FRYJPHG_js = require('./chunk-3FRYJPHG.js');
4
4
 
5
5
 
6
6
 
7
7
  Object.defineProperty(exports, "ceil", {
8
8
  enumerable: true,
9
- get: function () { return chunkMMR6XQNX_js.ceil; }
9
+ get: function () { return chunk3FRYJPHG_js.ceil; }
10
10
  });
11
11
  Object.defineProperty(exports, "clamp", {
12
12
  enumerable: true,
13
- get: function () { return chunkMMR6XQNX_js.clamp; }
13
+ get: function () { return chunk3FRYJPHG_js.clamp; }
14
14
  });
15
15
  Object.defineProperty(exports, "floor", {
16
16
  enumerable: true,
17
- get: function () { return chunkMMR6XQNX_js.floor; }
17
+ get: function () { return chunk3FRYJPHG_js.floor; }
18
18
  });
19
19
  Object.defineProperty(exports, "formatBytes", {
20
20
  enumerable: true,
21
- get: function () { return chunkMMR6XQNX_js.formatBytes; }
21
+ get: function () { return chunk3FRYJPHG_js.formatBytes; }
22
22
  });
23
23
  Object.defineProperty(exports, "formatCurrency", {
24
24
  enumerable: true,
25
- get: function () { return chunkMMR6XQNX_js.formatCurrency; }
25
+ get: function () { return chunk3FRYJPHG_js.formatCurrency; }
26
26
  });
27
27
  Object.defineProperty(exports, "formatNumber", {
28
28
  enumerable: true,
29
- get: function () { return chunkMMR6XQNX_js.formatNumber; }
29
+ get: function () { return chunk3FRYJPHG_js.formatNumber; }
30
30
  });
31
31
  Object.defineProperty(exports, "isBetween", {
32
32
  enumerable: true,
33
- get: function () { return chunkMMR6XQNX_js.isBetween; }
33
+ get: function () { return chunk3FRYJPHG_js.isBetween; }
34
34
  });
35
35
  Object.defineProperty(exports, "parseNumber", {
36
36
  enumerable: true,
37
- get: function () { return chunkMMR6XQNX_js.parseNumber; }
37
+ get: function () { return chunk3FRYJPHG_js.parseNumber; }
38
38
  });
39
39
  Object.defineProperty(exports, "percent", {
40
40
  enumerable: true,
41
- get: function () { return chunkMMR6XQNX_js.percent; }
41
+ get: function () { return chunk3FRYJPHG_js.percent; }
42
42
  });
43
43
  Object.defineProperty(exports, "random", {
44
44
  enumerable: true,
45
- get: function () { return chunkMMR6XQNX_js.random; }
45
+ get: function () { return chunk3FRYJPHG_js.random; }
46
46
  });
47
47
  Object.defineProperty(exports, "round", {
48
48
  enumerable: true,
49
- get: function () { return chunkMMR6XQNX_js.round; }
49
+ get: function () { return chunk3FRYJPHG_js.round; }
50
50
  });
51
51
  Object.defineProperty(exports, "toFixed", {
52
52
  enumerable: true,
53
- get: function () { return chunkMMR6XQNX_js.toFixed; }
53
+ get: function () { return chunk3FRYJPHG_js.toFixed; }
54
54
  });
55
55
  //# sourceMappingURL=number.js.map
56
56
  //# sourceMappingURL=number.js.map
package/dist/number.mjs CHANGED
@@ -1,3 +1,3 @@
1
- export { ceil, clamp, floor, formatBytes, formatCurrency, formatNumber, isBetween, parseNumber, percent, random, round, toFixed } from './chunk-ALDC6LRJ.mjs';
1
+ export { ceil, clamp, floor, formatBytes, formatCurrency, formatNumber, isBetween, parseNumber, percent, random, round, toFixed } from './chunk-CDSGEAOK.mjs';
2
2
  //# sourceMappingURL=number.mjs.map
3
3
  //# sourceMappingURL=number.mjs.map
@@ -125,6 +125,7 @@ declare class ChunkUploader {
125
125
  private uploadedChunks;
126
126
  private status;
127
127
  private abortController;
128
+ private initResponse;
128
129
  constructor(file: File, options?: UploadOptions);
129
130
  /**
130
131
  * 初始化上传
@@ -151,11 +152,17 @@ declare class ChunkUploader {
151
152
  */
152
153
  private uploadChunksConcurrently;
153
154
  /**
154
- * 完成上传
155
+ * 获取上传进度(用于验证上传是否完成)
156
+ */
157
+ private getUploadProgress;
158
+ /**
159
+ * 完成上传(调用后端合并分片接口)
160
+ *
161
+ * 只有在进度为 100% 时才会被调用
155
162
  */
156
163
  private completeUpload;
157
164
  /**
158
- * 更新上传进度
165
+ * 更新上传进度(仅用于回调前端显示)
159
166
  */
160
167
  private updateProgress;
161
168
  /**
@@ -125,6 +125,7 @@ declare class ChunkUploader {
125
125
  private uploadedChunks;
126
126
  private status;
127
127
  private abortController;
128
+ private initResponse;
128
129
  constructor(file: File, options?: UploadOptions);
129
130
  /**
130
131
  * 初始化上传
@@ -151,11 +152,17 @@ declare class ChunkUploader {
151
152
  */
152
153
  private uploadChunksConcurrently;
153
154
  /**
154
- * 完成上传
155
+ * 获取上传进度(用于验证上传是否完成)
156
+ */
157
+ private getUploadProgress;
158
+ /**
159
+ * 完成上传(调用后端合并分片接口)
160
+ *
161
+ * 只有在进度为 100% 时才会被调用
155
162
  */
156
163
  private completeUpload;
157
164
  /**
158
- * 更新上传进度
165
+ * 更新上传进度(仅用于回调前端显示)
159
166
  */
160
167
  private updateProgress;
161
168
  /**
package/dist/upload.d.mts CHANGED
@@ -1 +1 @@
1
- export { C as ChunkUploader, c as createUploader } from './upload-DzlQtUBc.mjs';
1
+ export { C as ChunkUploader, c as createUploader } from './upload-DlwmBwz0.mjs';
package/dist/upload.d.ts CHANGED
@@ -1 +1 @@
1
- export { C as ChunkUploader, c as createUploader } from './upload-DzlQtUBc.js';
1
+ export { C as ChunkUploader, c as createUploader } from './upload-DlwmBwz0.js';
package/dist/upload.js CHANGED
@@ -1,17 +1,17 @@
1
1
  'use strict';
2
2
 
3
- var chunkF3LAGHPG_js = require('./chunk-F3LAGHPG.js');
3
+ var chunkTADFN7AL_js = require('./chunk-TADFN7AL.js');
4
4
  require('./chunk-7V5UQXIO.js');
5
5
 
6
6
 
7
7
 
8
8
  Object.defineProperty(exports, "ChunkUploader", {
9
9
  enumerable: true,
10
- get: function () { return chunkF3LAGHPG_js.ChunkUploader; }
10
+ get: function () { return chunkTADFN7AL_js.ChunkUploader; }
11
11
  });
12
12
  Object.defineProperty(exports, "createUploader", {
13
13
  enumerable: true,
14
- get: function () { return chunkF3LAGHPG_js.createUploader; }
14
+ get: function () { return chunkTADFN7AL_js.createUploader; }
15
15
  });
16
16
  //# sourceMappingURL=upload.js.map
17
17
  //# sourceMappingURL=upload.js.map
package/dist/upload.mjs CHANGED
@@ -1,4 +1,4 @@
1
- export { ChunkUploader, createUploader } from './chunk-QV6MIQ7H.mjs';
1
+ export { ChunkUploader, createUploader } from './chunk-RZAVU7BP.mjs';
2
2
  import './chunk-ZVJ6NQUM.mjs';
3
3
  //# sourceMappingURL=upload.mjs.map
4
4
  //# sourceMappingURL=upload.mjs.map
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@alibarbar/common",
3
- "version": "1.0.0",
3
+ "version": "1.0.2",
4
4
  "description": "Alibarbar 通用工具库",
5
5
  "main": "./dist/index.cjs",
6
6
  "module": "./dist/index.js",
@@ -1 +0,0 @@
1
- {"version":3,"sources":["../src/core/array.ts"],"names":["shuffled"],"mappings":";AASO,SAAS,OAAU,GAAA,EAAe;AACvC,EAAA,OAAO,KAAA,CAAM,IAAA,CAAK,IAAI,GAAA,CAAI,GAAG,CAAC,CAAA;AAChC;AAQO,SAAS,OAAA,CACd,KACA,KAAA,EACgB;AAChB,EAAA,MAAM,MAAA,GAAS,OAAO,KAAA,KAAU,QAAA,GAC5B,CAAC,IAAA,KAAa,IAAA,CAA2B,KAAK,CAAA,GAC9C,KAAA;AAEJ,EAAA,OAAO,GAAA,CAAI,MAAA;AAAA,IACT,CAAC,KAAK,IAAA,KAAS;AACb,MAAA,MAAM,GAAA,GAAM,OAAO,IAAI,CAAA;AACvB,MAAA,IAAI,CAAC,GAAA,CAAI,GAAG,CAAA,EAAG;AACb,QAAA,GAAA,CAAI,GAAG,IAAI,EAAC;AAAA,MACd;AACA,MAAA,GAAA,CAAI,GAAG,CAAA,CAAE,IAAA,CAAK,IAAI,CAAA;AAClB,MAAA,OAAO,GAAA;AAAA,IACT,CAAA;AAAA,IACA;AAAC,GACH;AACF;AAQO,SAAS,KAAA,CAAS,KAAU,IAAA,EAAqB;AACtD,EAAA,MAAM,SAAgB,EAAC;AACvB,EAAA,KAAA,IAAS,IAAI,CAAA,EAAG,CAAA,GAAI,GAAA,CAAI,MAAA,EAAQ,KAAK,IAAA,EAAM;AACzC,IAAA,MAAA,CAAO,KAAK,GAAA,CAAI,KAAA,CAAM,CAAA,EAAG,CAAA,GAAI,IAAI,CAAC,CAAA;AAAA,EACpC;AACA,EAAA,OAAO,MAAA;AACT;AAQO,SAAS,OAAA,CAAW,GAAA,EAAkB,KAAA,GAAQ,CAAA,EAAQ;AAC3D,EAAA,OAAO,KAAA,GAAQ,IACX,GAAA,CAAI,MAAA;AAAA,IACF,CAAC,GAAA,EAAK,GAAA,KAAQ,GAAA,CAAI,OAAO,KAAA,CAAM,OAAA,CAAQ,GAAG,CAAA,GAAI,OAAA,CAAQ,GAAA,EAAK,KAAA,GAAQ,CAAC,IAAI,GAAG,CAAA;AAAA,IAC3E;AAAC,GACH,GACC,GAAA;AACP;AAOO,SAAS,QAAW,GAAA,EAAe;AACxC,EAAA,MAAM,MAAA,GAAS,CAAC,GAAG,GAAG,CAAA;AACtB,EAAA,KAAA,IAAS,IAAI,MAAA,CAAO,MAAA,GAAS,CAAA,EAAG,CAAA,GAAI,GAAG,CAAA,EAAA,EAAK;AAC1C,IAAA,MAAM,IAAI,IAAA,CAAK,KAAA,CAAM,KAAK,MAAA,EAAO,IAAK,IAAI,CAAA,CAAE,CAAA;AAC5C,IAAA,CAAC,MAAA,CAAO,CAAC,CAAA,EAAG,MAAA,CAAO,CAAC,CAAC,CAAA,GAAI,CAAC,MAAA,CAAO,CAAC,CAAA,EAAG,MAAA,CAAO,CAAC,CAAC,CAAA;AAAA,EAChD;AACA,EAAA,OAAO,MAAA;AACT;AAUO,SAAS,MAAA,CAAU,GAAA,EAAU,KAAA,GAAQ,CAAA,EAAY;AACtD,EAAA,IAAI,GAAA,CAAI,WAAW,CAAA,EAAG;AACpB,IAAA,MAAM,IAAI,MAAM,gCAAgC,CAAA;AAAA,EAClD;AAEA,EAAA,IAAI,UAAU,CAAA,EAAG;AACf,IAAA,MAAMA,SAAAA,GAAW,QAAQ,GAAG,CAAA;AAC5B,IAAA,OAAOA,UAAS,CAAC,CAAA;AAAA,EACnB;AAEA,EAAA,IAAI,SAAS,GAAA,CAAI,MAAA,EAAQ,OAAO,CAAC,GAAG,GAAG,CAAA;AACvC,EAAA,MAAM,QAAA,GAAW,QAAQ,GAAG,CAAA;AAC5B,EAAA,OAAO,QAAA,CAAS,KAAA,CAAM,CAAA,EAAG,KAAK,CAAA;AAChC;AAQO,SAAS,UAAA,CAAc,MAAW,IAAA,EAAgB;AACvD,EAAA,MAAM,IAAA,GAAO,IAAI,GAAA,CAAI,IAAI,CAAA;AACzB,EAAA,OAAO,KAAK,MAAA,CAAO,CAAA,IAAA,KAAQ,CAAC,IAAA,CAAK,GAAA,CAAI,IAAI,CAAC,CAAA;AAC5C;AAQO,SAAS,YAAA,CAAgB,MAAW,IAAA,EAAgB;AACzD,EAAA,MAAM,IAAA,GAAO,IAAI,GAAA,CAAI,IAAI,CAAA;AACzB,EAAA,OAAO,KAAK,MAAA,CAAO,CAAA,IAAA,KAAQ,IAAA,CAAK,GAAA,CAAI,IAAI,CAAC,CAAA;AAC3C;AAQO,SAAS,KAAA,CAAS,MAAW,IAAA,EAAgB;AAClD,EAAA,OAAO,OAAO,CAAC,GAAG,IAAA,EAAM,GAAG,IAAI,CAAC,CAAA;AAClC;AASO,SAAS,MAAA,CACd,GAAA,EACA,KAAA,EACA,KAAA,GAAwB,KAAA,EACnB;AACL,EAAA,MAAM,MAAA,GAAS,OAAO,KAAA,KAAU,QAAA,GAC5B,CAAC,IAAA,KAAa,IAAA,CAA2B,KAAK,CAAA,GAC9C,KAAA;AAEJ,EAAA,MAAM,MAAA,GAAS,CAAC,GAAG,GAAG,CAAA;AACtB,EAAA,MAAA,CAAO,IAAA,CAAK,CAAC,CAAA,EAAG,CAAA,KAAM;AACpB,IAAA,MAAM,IAAA,GAAO,OAAO,CAAC,CAAA;AACrB,IAAA,MAAM,IAAA,GAAO,OAAO,CAAC,CAAA;AACrB,IAAA,IAAI,IAAA,GAAO,IAAA,EAAM,OAAO,KAAA,KAAU,QAAQ,EAAA,GAAK,CAAA;AAC/C,IAAA,IAAI,IAAA,GAAO,IAAA,EAAM,OAAO,KAAA,KAAU,QAAQ,CAAA,GAAI,EAAA;AAC9C,IAAA,OAAO,CAAA;AAAA,EACT,CAAC,CAAA;AACD,EAAA,OAAO,MAAA;AACT;AAQO,SAAS,WAAA,CAAe,KAAU,SAAA,EAAyC;AAChF,EAAA,OAAO,GAAA,CAAI,UAAU,SAAS,CAAA;AAChC;AAQO,SAAS,SAAA,CAAa,KAAU,SAAA,EAA6C;AAClF,EAAA,MAAM,SAAc,EAAC;AACrB,EAAA,MAAM,QAAa,EAAC;AACpB,EAAA,GAAA,CAAI,QAAQ,CAAA,IAAA,KAAQ;AAClB,IAAA,IAAI,SAAA,CAAU,IAAI,CAAA,EAAG;AACnB,MAAA,MAAA,CAAO,KAAK,IAAI,CAAA;AAAA,IAClB,CAAA,MAAO;AACL,MAAA,KAAA,CAAM,KAAK,IAAI,CAAA;AAAA,IACjB;AAAA,EACF,CAAC,CAAA;AACD,EAAA,OAAO,CAAC,QAAQ,KAAK,CAAA;AACvB;AAOO,SAAS,OACX,MAAA,EACuE;AAC1E,EAAA,MAAM,SAAA,GAAY,KAAK,GAAA,CAAI,GAAG,OAAO,GAAA,CAAI,CAAA,GAAA,KAAQ,GAAA,CAAkB,MAAM,CAAC,CAAA;AAC1E,EAAA,MAAM,SAAmF,EAAC;AAC1F,EAAA,KAAA,IAAS,CAAA,GAAI,CAAA,EAAG,CAAA,GAAI,SAAA,EAAW,CAAA,EAAA,EAAK;AAClC,IAAA,MAAA,CAAO,IAAA;AAAA,MACL,MAAA,CAAO,GAAA,CAAI,CAAA,GAAA,KAAQ,GAAA,CAAkB,CAAC,CAAC;AAAA,KAGzC;AAAA,EACF;AACA,EAAA,OAAO,MAAA;AACT;AAOO,SAAS,MACd,KAAA,EACG;AACH,EAAA,IAAI,KAAA,CAAM,MAAA,KAAW,CAAA,EAAG,OAAO,EAAC;AAChC,EAAA,MAAM,MAAA,GAAU,KAAA,CAAM,CAAC,CAAA,CAAgB,MAAA;AACvC,EAAA,MAAM,MAAA,GAAS,MAAM,IAAA,CAAK,EAAE,QAAO,EAAG,MAAM,EAAE,CAAA;AAC9C,EAAA,KAAA,CAAM,QAAQ,CAAA,IAAA,KAAQ;AACpB,IAAC,IAAA,CAAmB,OAAA,CAAQ,CAAC,GAAA,EAAK,KAAA,KAAU;AAC1C,MAAA,MAAA,CAAO,KAAK,CAAA,CAAE,IAAA,CAAK,GAAG,CAAA;AAAA,IACxB,CAAC,CAAA;AAAA,EACH,CAAC,CAAA;AACD,EAAA,OAAO,MAAA;AACT;AAOO,SAAS,QAAW,GAAA,EAAqD;AAC9E,EAAA,OAAO,IAAI,MAAA,CAAO,CAAC,IAAA,KAAoB,OAAA,CAAQ,IAAI,CAAC,CAAA;AACtD;AAQO,SAAS,IAAA,CAAQ,KAAU,CAAA,EAAgB;AAChD,EAAA,OAAO,GAAA,CAAI,KAAA,CAAM,CAAA,EAAG,CAAC,CAAA;AACvB;AAQO,SAAS,IAAA,CAAQ,KAAU,CAAA,EAAgB;AAChD,EAAA,OAAO,GAAA,CAAI,MAAM,CAAC,CAAA;AACpB;AAQO,SAAS,SAAA,CAAa,KAAU,SAAA,EAAsC;AAC3E,EAAA,MAAM,SAAc,EAAC;AACrB,EAAA,KAAA,MAAW,QAAQ,GAAA,EAAK;AACtB,IAAA,IAAI,CAAC,SAAA,CAAU,IAAI,CAAA,EAAG;AACtB,IAAA,MAAA,CAAO,KAAK,IAAI,CAAA;AAAA,EAClB;AACA,EAAA,OAAO,MAAA;AACT;AAQO,SAAS,SAAA,CAAa,KAAU,SAAA,EAAsC;AAC3E,EAAA,IAAI,KAAA,GAAQ,CAAA;AACZ,EAAA,OAAO,QAAQ,GAAA,CAAI,MAAA,IAAU,UAAU,GAAA,CAAI,KAAK,CAAC,CAAA,EAAG;AAClD,IAAA,KAAA,EAAA;AAAA,EACF;AACA,EAAA,OAAO,GAAA,CAAI,MAAM,KAAK,CAAA;AACxB","file":"chunk-2FFSQ573.mjs","sourcesContent":["/**\n * 数组工具函数\n */\n\n/**\n * 数组去重\n * @param arr - 输入数组\n * @returns 去重后的数组\n */\nexport function unique<T>(arr: T[]): T[] {\n return Array.from(new Set(arr));\n}\n\n/**\n * 数组分组\n * @param arr - 输入数组\n * @param keyFn - 分组键函数或属性名\n * @returns 分组后的对象\n */\nexport function groupBy<T, K extends string | number>(\n arr: T[],\n keyFn: ((item: T) => K) | string\n): Record<K, T[]> {\n const getKey = typeof keyFn === 'string' \n ? (item: T) => (item as Record<string, K>)[keyFn] as K\n : keyFn;\n \n return arr.reduce(\n (acc, item) => {\n const key = getKey(item);\n if (!acc[key]) {\n acc[key] = [];\n }\n acc[key].push(item);\n return acc;\n },\n {} as Record<K, T[]>\n );\n}\n\n/**\n * 数组分块\n * @param arr - 输入数组\n * @param size - 每块大小\n * @returns 分块后的二维数组\n */\nexport function chunk<T>(arr: T[], size: number): T[][] {\n const chunks: T[][] = [];\n for (let i = 0; i < arr.length; i += size) {\n chunks.push(arr.slice(i, i + size));\n }\n return chunks;\n}\n\n/**\n * 数组扁平化\n * @param arr - 输入数组\n * @param depth - 扁平化深度,默认为 1\n * @returns 扁平化后的数组\n */\nexport function flatten<T>(arr: (T | T[])[], depth = 1): T[] {\n return depth > 0\n ? arr.reduce<T[]>(\n (acc, val) => acc.concat(Array.isArray(val) ? flatten(val, depth - 1) : val),\n []\n )\n : (arr as T[]);\n}\n\n/**\n * 数组随机打乱(Fisher-Yates算法)\n * @param arr - 输入数组\n * @returns 打乱后的新数组\n */\nexport function shuffle<T>(arr: T[]): T[] {\n const result = [...arr];\n for (let i = result.length - 1; i > 0; i--) {\n const j = Math.floor(Math.random() * (i + 1));\n [result[i], result[j]] = [result[j], result[i]];\n }\n return result;\n}\n\n/**\n * 随机取样\n * @param arr - 输入数组\n * @param count - 取样数量,默认为 1。当 count=1 时返回单个元素,否则返回数组\n * @returns 随机取样的数组或单个元素\n */\nexport function sample<T>(arr: T[]): T;\nexport function sample<T>(arr: T[], count: number): T | T[];\nexport function sample<T>(arr: T[], count = 1): T | T[] {\n if (arr.length === 0) {\n throw new Error('Cannot sample from empty array');\n }\n \n if (count === 1) {\n const shuffled = shuffle(arr);\n return shuffled[0];\n }\n \n if (count >= arr.length) return [...arr];\n const shuffled = shuffle(arr);\n return shuffled.slice(0, count);\n}\n\n/**\n * 数组差集(在arr1中但不在arr2中的元素)\n * @param arr1 - 第一个数组\n * @param arr2 - 第二个数组\n * @returns 差集数组\n */\nexport function difference<T>(arr1: T[], arr2: T[]): T[] {\n const set2 = new Set(arr2);\n return arr1.filter(item => !set2.has(item));\n}\n\n/**\n * 数组交集\n * @param arr1 - 第一个数组\n * @param arr2 - 第二个数组\n * @returns 交集数组\n */\nexport function intersection<T>(arr1: T[], arr2: T[]): T[] {\n const set2 = new Set(arr2);\n return arr1.filter(item => set2.has(item));\n}\n\n/**\n * 数组并集\n * @param arr1 - 第一个数组\n * @param arr2 - 第二个数组\n * @returns 并集数组\n */\nexport function union<T>(arr1: T[], arr2: T[]): T[] {\n return unique([...arr1, ...arr2]);\n}\n\n/**\n * 按属性排序\n * @param arr - 输入数组\n * @param keyFn - 获取排序键的函数或属性名\n * @param order - 排序顺序,'asc' 或 'desc',默认为 'asc'\n * @returns 排序后的新数组\n */\nexport function sortBy<T, K extends string | number>(\n arr: T[],\n keyFn: ((item: T) => K) | string,\n order: 'asc' | 'desc' = 'asc'\n): T[] {\n const getKey = typeof keyFn === 'string'\n ? (item: T) => (item as Record<string, K>)[keyFn] as K\n : keyFn;\n \n const result = [...arr];\n result.sort((a, b) => {\n const keyA = getKey(a);\n const keyB = getKey(b);\n if (keyA < keyB) return order === 'asc' ? -1 : 1;\n if (keyA > keyB) return order === 'asc' ? 1 : -1;\n return 0;\n });\n return result;\n}\n\n/**\n * 按条件查找索引\n * @param arr - 输入数组\n * @param predicate - 条件函数\n * @returns 找到的索引,未找到返回 -1\n */\nexport function findIndexBy<T>(arr: T[], predicate: (item: T) => boolean): number {\n return arr.findIndex(predicate);\n}\n\n/**\n * 数组分割(满足条件/不满足条件)\n * @param arr - 输入数组\n * @param predicate - 条件函数\n * @returns 包含两个数组的元组:[满足条件的数组, 不满足条件的数组]\n */\nexport function partition<T>(arr: T[], predicate: (item: T) => boolean): [T[], T[]] {\n const truthy: T[] = [];\n const falsy: T[] = [];\n arr.forEach(item => {\n if (predicate(item)) {\n truthy.push(item);\n } else {\n falsy.push(item);\n }\n });\n return [truthy, falsy];\n}\n\n/**\n * 数组压缩(将多个数组合并成元组数组)\n * @param arrays - 要压缩的数组\n * @returns 压缩后的元组数组\n */\nexport function zip<T extends readonly unknown[]>(\n ...arrays: T\n): Array<{ [K in keyof T]: T[K] extends readonly (infer U)[] ? U : never }> {\n const maxLength = Math.max(...arrays.map(arr => (arr as unknown[]).length));\n const result: Array<{ [K in keyof T]: T[K] extends readonly (infer U)[] ? U : never }> = [];\n for (let i = 0; i < maxLength; i++) {\n result.push(\n arrays.map(arr => (arr as unknown[])[i]) as {\n [K in keyof T]: T[K] extends readonly (infer U)[] ? U : never;\n }\n );\n }\n return result;\n}\n\n/**\n * 数组解压(将元组数组拆分成多个数组)\n * @param array - 要解压的数组\n * @returns 解压后的数组元组\n */\nexport function unzip<T extends readonly unknown[]>(\n array: Array<{ [K in keyof T]: T[number] extends readonly (infer U)[] ? U : never }>\n): T {\n if (array.length === 0) return [] as unknown as T;\n const length = (array[0] as unknown[]).length;\n const result = Array.from({ length }, () => []) as unknown as unknown[][];\n array.forEach(item => {\n (item as unknown[]).forEach((val, index) => {\n result[index].push(val);\n });\n });\n return result as unknown as T;\n}\n\n/**\n * 移除假值(null, undefined, false, 0, '')\n * @param arr - 输入数组\n * @returns 移除假值后的数组\n */\nexport function compact<T>(arr: (T | null | undefined | false | 0 | '')[]): T[] {\n return arr.filter((item): item is T => Boolean(item));\n}\n\n/**\n * 取前N个元素\n * @param arr - 输入数组\n * @param n - 要取的元素数量\n * @returns 前N个元素的数组\n */\nexport function take<T>(arr: T[], n: number): T[] {\n return arr.slice(0, n);\n}\n\n/**\n * 跳过前N个元素\n * @param arr - 输入数组\n * @param n - 要跳过的元素数量\n * @returns 跳过后的数组\n */\nexport function drop<T>(arr: T[], n: number): T[] {\n return arr.slice(n);\n}\n\n/**\n * 条件取元素(直到条件不满足)\n * @param arr - 输入数组\n * @param predicate - 条件函数\n * @returns 满足条件的连续元素数组\n */\nexport function takeWhile<T>(arr: T[], predicate: (item: T) => boolean): T[] {\n const result: T[] = [];\n for (const item of arr) {\n if (!predicate(item)) break;\n result.push(item);\n }\n return result;\n}\n\n/**\n * 条件跳过元素(直到条件不满足)\n * @param arr - 输入数组\n * @param predicate - 条件函数\n * @returns 跳过后的数组\n */\nexport function dropWhile<T>(arr: T[], predicate: (item: T) => boolean): T[] {\n let index = 0;\n while (index < arr.length && predicate(arr[index])) {\n index++;\n }\n return arr.slice(index);\n}\n"]}
@@ -1 +0,0 @@
1
- {"version":3,"sources":["../src/format/number.ts"],"names":["dec"],"mappings":"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","file":"chunk-ALDC6LRJ.mjs","sourcesContent":["/**\n * 数字工具函数\n */\n\n/**\n * 数字格式化(千分位)\n * @param num - 数字\n * @param options - 格式化选项\n * @returns 格式化后的字符串\n */\nexport function formatNumber(\n num: number,\n options: {\n decimals?: number;\n separator?: string;\n decimalPoint?: string;\n minimumFractionDigits?: number;\n } = {}\n): string {\n const {\n decimals,\n separator = ',',\n decimalPoint = '.',\n minimumFractionDigits,\n } = options;\n \n // 如果没有指定 decimals,自动检测小数位\n let numStr: string;\n if (decimals !== undefined) {\n numStr = num.toFixed(decimals);\n } else if (minimumFractionDigits !== undefined) {\n numStr = num.toFixed(minimumFractionDigits);\n } else {\n // 自动检测小数位\n const str = num.toString();\n if (str.includes('.')) {\n numStr = str;\n } else {\n numStr = num.toFixed(0);\n }\n }\n \n const parts = numStr.split('.');\n parts[0] = parts[0].replace(/\\B(?=(\\d{3})+(?!\\d))/g, separator);\n return parts.join(decimalPoint);\n}\n\n/**\n * 生成随机数\n * @param min - 最小值\n * @param max - 最大值\n * @param integer - 是否为整数,默认为 false\n * @returns 随机数\n */\nexport function random(min: number, max: number, integer = false): number {\n const value = Math.random() * (max - min) + min;\n return integer ? Math.floor(value) : value;\n}\n\n/**\n * 限制数值范围\n * @param num - 数字\n * @param min - 最小值\n * @param max - 最大值\n * @returns 限制后的数字\n */\nexport function clamp(num: number, min: number, max: number): number {\n return Math.min(Math.max(num, min), max);\n}\n\n/**\n * 增强版四舍五入\n * @param num - 数字\n * @param decimals - 小数位数,默认为 0\n * @returns 四舍五入后的数字\n */\nexport function round(num: number, decimals = 0): number {\n const factor = Math.pow(10, decimals);\n return Math.round(num * factor) / factor;\n}\n\n/**\n * 增强版向下取整\n * @param num - 数字\n * @param decimals - 小数位数,默认为 0\n * @returns 向下取整后的数字\n */\nexport function floor(num: number, decimals = 0): number {\n const factor = Math.pow(10, decimals);\n return Math.floor(num * factor) / factor;\n}\n\n/**\n * 增强版向上取整\n * @param num - 数字\n * @param decimals - 小数位数,默认为 0\n * @returns 向上取整后的数字\n */\nexport function ceil(num: number, decimals = 0): number {\n const factor = Math.pow(10, decimals);\n return Math.ceil(num * factor) / factor;\n}\n\n/**\n * 保留小数位(增强版)\n * @param num - 数字\n * @param decimals - 小数位数\n * @returns 格式化后的字符串\n */\nexport function toFixed(num: number, decimals: number): string {\n return num.toFixed(decimals);\n}\n\n/**\n * 解析数字字符串\n * @param str - 数字字符串\n * @param defaultValue - 默认值,解析失败时返回\n * @returns 解析后的数字\n */\nexport function parseNumber(str: string, defaultValue = 0): number {\n const num = Number(str);\n return isNaN(num) ? defaultValue : num;\n}\n\n/**\n * 判断是否在范围内\n * @param num - 数字\n * @param min - 最小值\n * @param max - 最大值\n * @param inclusive - 是否包含边界,默认为 true\n * @returns 是否在范围内\n */\nexport function isBetween(num: number, min: number, max: number, inclusive = true): boolean {\n if (inclusive) {\n return num >= min && num <= max;\n }\n return num > min && num < max;\n}\n\n/**\n * 百分比计算\n * @param value - 当前值(0-1之间的小数)或当前值(当提供total时)\n * @param decimals - 小数位数,默认为 0(当value是0-1之间的小数时)或总值(当value是实际值时)\n * @returns 百分比数字(当value是0-1之间的小数时)或百分比字符串(当提供total时)\n */\nexport function percent(value: number, decimals?: number): number;\nexport function percent(value: number, total: number, decimals: number): string;\nexport function percent(\n value: number,\n decimalsOrTotal?: number,\n decimals?: number\n): number | string {\n // 如果 value 是 0-1 之间的小数,且只传了一个参数或第二个参数是小数位数\n if (value >= 0 && value <= 1 && (decimalsOrTotal === undefined || decimalsOrTotal < 10)) {\n const dec = decimalsOrTotal ?? 0;\n return Number((value * 100).toFixed(dec));\n }\n \n // 如果提供了 total(第二个参数大于等于10,认为是total)\n if (decimalsOrTotal !== undefined && decimalsOrTotal >= 10) {\n const total = decimalsOrTotal;\n const dec = decimals ?? 2;\n if (total === 0) return '0%';\n return `${((value / total) * 100).toFixed(dec)}%`;\n }\n \n // 默认情况:value 是 0-1 之间的小数\n const dec = decimalsOrTotal ?? 0;\n return Number((value * 100).toFixed(dec));\n}\n\n/**\n * 货币格式化\n * @param num - 数字\n * @param currency - 货币符号,默认为 '¥'\n * @param decimals - 小数位数,默认为 2\n * @returns 格式化后的货币字符串\n */\nexport function formatCurrency(num: number, currency = '¥', decimals = 2): string {\n return `${currency}${formatNumber(num, { decimals, separator: ',' })}`;\n}\n\n/**\n * 字节格式化\n * @param bytes - 字节数\n * @param decimals - 小数位数,默认为 2\n * @returns 格式化后的字节字符串\n */\nexport function formatBytes(bytes: number, decimals = 2): string {\n if (bytes === 0) return '0 Bytes';\n const k = 1024;\n const sizes = ['Bytes', 'KB', 'MB', 'GB', 'TB', 'PB'];\n const i = Math.floor(Math.log(bytes) / Math.log(k));\n return `${parseFloat((bytes / Math.pow(k, i)).toFixed(decimals))} ${sizes[i]}`;\n}\n"]}
@@ -1 +0,0 @@
1
- {"version":3,"sources":["../src/types/upload.ts","../src/browser/upload.ts"],"names":["UploadStatus","splitFileIntoChunks","calculateBlobMD5","result"],"mappings":"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","file":"chunk-F3LAGHPG.js","sourcesContent":["/**\n * 文件上传相关类型定义\n */\n\n/**\n * 上传初始化请求参数\n */\nexport interface UploadInitRequest {\n fileName: string;\n fileSize: number;\n fileMd5: string;\n chunkSize?: number;\n}\n\n/**\n * 上传初始化响应\n */\nexport interface UploadInitResponse {\n taskId: string;\n totalChunks: number;\n existingChunks: number[];\n instantUpload: boolean;\n fileUrl?: string;\n chunkSize: number;\n}\n\n/**\n * 分片上传响应\n */\nexport interface ChunkUploadResponse {\n chunkIndex: number;\n success: boolean;\n message: string;\n chunkMd5: string;\n}\n\n/**\n * 完成上传响应\n */\nexport interface CompleteUploadResponse {\n taskId: string;\n fileUrl: string;\n fileName: string;\n fileSize: number;\n fileMd5: string;\n success: boolean;\n message: string;\n}\n\n/**\n * 上传进度信息\n */\nexport interface UploadProgress {\n taskId: string;\n fileName: string;\n fileSize: number;\n totalChunks: number;\n uploadedChunks: number;\n percentage: number;\n status: string;\n uploadedSize: number;\n}\n\n/**\n * API响应包装类型\n */\nexport interface ApiResponse<T> {\n code: number;\n message: string;\n data: T;\n timestamp: number;\n}\n\n/**\n * 上传配置选项\n */\nexport interface UploadOptions {\n /** 分片大小(字节),默认 2MB */\n chunkSize?: number;\n /** 并发上传数量,默认 3 */\n concurrency?: number;\n /** 重试次数,默认 3 */\n retryCount?: number;\n /** 重试延迟(毫秒),默认 1000 */\n retryDelay?: number;\n /** 基础API地址 */\n baseURL?: string;\n /** 请求头 */\n headers?: Record<string, string>;\n /** 上传进度回调 */\n onProgress?: (progress: UploadProgress) => void;\n /** 上传完成回调 */\n onComplete?: (result: CompleteUploadResponse) => void;\n /** 上传错误回调 */\n onError?: (error: Error) => void;\n}\n\n/**\n * 上传状态\n */\nexport enum UploadStatus {\n PENDING = 'pending',\n UPLOADING = 'uploading',\n PAUSED = 'paused',\n COMPLETED = 'completed',\n FAILED = 'failed',\n CANCELLED = 'cancelled',\n}\n\n/**\n * 文件分片信息\n */\nexport interface ChunkInfo {\n index: number;\n start: number;\n end: number;\n blob: Blob;\n md5?: string;\n}\n","/**\n * 文件分片上传工具类\n * 支持分片上传、断点续传、进度追踪\n */\n\nimport {\n UploadOptions,\n UploadInitRequest,\n UploadInitResponse,\n ChunkUploadResponse,\n CompleteUploadResponse,\n UploadProgress,\n UploadStatus,\n ChunkInfo,\n ApiResponse,\n} from '../types/upload';\nimport { calculateBlobMD5, splitFileIntoChunks } from './file';\n\n/**\n * 文件上传器类\n */\nexport class ChunkUploader {\n private file: File;\n private options: Required<UploadOptions>;\n private taskId: string | null = null;\n private chunks: ChunkInfo[] = [];\n private uploadedChunks: Set<number> = new Set();\n private status: UploadStatus = UploadStatus.PENDING;\n private abortController: AbortController | null = null;\n\n constructor(file: File, options: UploadOptions = {}) {\n this.file = file;\n this.options = {\n chunkSize: options.chunkSize || 2 * 1024 * 1024, // 默认2MB\n concurrency: options.concurrency || 3,\n retryCount: options.retryCount || 3,\n retryDelay: options.retryDelay || 1000,\n baseURL: options.baseURL || '',\n headers: options.headers || {},\n onProgress: options.onProgress || (() => {}),\n onComplete: options.onComplete || (() => {}),\n onError: options.onError || (() => {}),\n };\n }\n\n /**\n * 初始化上传\n */\n private async initUpload(): Promise<UploadInitResponse> {\n const fileMd5 = await this.calculateFileMD5();\n const request: UploadInitRequest = {\n fileName: this.file.name,\n fileSize: this.file.size,\n fileMd5,\n chunkSize: this.options.chunkSize,\n };\n\n const response = await this.request<ApiResponse<UploadInitResponse>>('/api/files/common/init', {\n method: 'POST',\n headers: {\n 'Content-Type': 'application/json',\n ...this.options.headers,\n },\n body: JSON.stringify(request),\n });\n\n if (response.code !== 200) {\n throw new Error(response.message || '初始化上传失败');\n }\n\n return response.data;\n }\n\n /**\n * 计算文件MD5(简化版,实际应该使用spark-md5等库)\n */\n private async calculateFileMD5(): Promise<string> {\n // 这里使用简化的方法,实际项目中应该使用spark-md5库\n const chunks = splitFileIntoChunks(this.file, this.options.chunkSize);\n const md5Promises = chunks.map((chunk, index) =>\n calculateBlobMD5(chunk).then(md5 => ({ index, md5 }))\n );\n const md5Results = await Promise.all(md5Promises);\n // 简单拼接,实际应该使用正确的MD5算法\n return md5Results.map(r => r.md5).join('');\n }\n\n /**\n * 准备分片\n */\n private prepareChunks(): void {\n const blobChunks = splitFileIntoChunks(this.file, this.options.chunkSize);\n this.chunks = blobChunks.map((blob, index) => ({\n index,\n start: index * this.options.chunkSize,\n end: Math.min((index + 1) * this.options.chunkSize, this.file.size),\n blob,\n }));\n }\n\n /**\n * 获取已上传的分片列表\n */\n private async getUploadedChunks(): Promise<number[]> {\n if (!this.taskId) return [];\n\n try {\n const response = await this.request<ApiResponse<number[]>>(\n `/api/files/common/chunks/${this.taskId}`,\n {\n method: 'GET',\n headers: this.options.headers,\n }\n );\n\n if (response.code === 200) {\n return response.data || [];\n }\n } catch (error) {\n console.warn('获取已上传分片失败:', error);\n }\n\n return [];\n }\n\n /**\n * 上传单个分片\n */\n private async uploadChunk(chunkInfo: ChunkInfo, retryCount = 0): Promise<void> {\n if (!this.taskId) {\n throw new Error('任务ID不存在');\n }\n\n if (this.uploadedChunks.has(chunkInfo.index)) {\n return; // 已上传,跳过\n }\n\n try {\n // 计算分片MD5\n const chunkMd5 = await calculateBlobMD5(chunkInfo.blob);\n\n const formData = new FormData();\n formData.append('file', chunkInfo.blob, this.file.name);\n\n const url = `/api/files/common/chunk?taskId=${this.taskId}&chunkIndex=${chunkInfo.index}&chunkMd5=${chunkMd5}`;\n\n const response = await this.request<ApiResponse<ChunkUploadResponse>>(url, {\n method: 'POST',\n headers: this.options.headers,\n body: formData,\n });\n\n if (response.code === 200 && response.data.success) {\n this.uploadedChunks.add(chunkInfo.index);\n this.updateProgress();\n } else {\n throw new Error(response.message || '分片上传失败');\n }\n } catch (error) {\n if (retryCount < this.options.retryCount) {\n await this.delay(this.options.retryDelay);\n return this.uploadChunk(chunkInfo, retryCount + 1);\n }\n throw error;\n }\n }\n\n /**\n * 并发上传分片\n */\n private async uploadChunksConcurrently(): Promise<void> {\n const chunksToUpload = this.chunks.filter(chunk => !this.uploadedChunks.has(chunk.index));\n\n const uploadPromises: Promise<void>[] = [];\n let currentIndex = 0;\n\n const uploadNext = async (): Promise<void> => {\n while (currentIndex < chunksToUpload.length && this.status === UploadStatus.UPLOADING) {\n const chunk = chunksToUpload[currentIndex++];\n const promise = this.uploadChunk(chunk).then(() => {\n if (currentIndex < chunksToUpload.length) {\n return uploadNext();\n }\n });\n uploadPromises.push(promise);\n\n if (uploadPromises.length >= this.options.concurrency) {\n await Promise.race(uploadPromises);\n uploadPromises.splice(\n uploadPromises.findIndex(p => p === promise),\n 1\n );\n }\n }\n };\n\n // 启动并发上传\n const concurrencyPromises: Promise<void>[] = [];\n for (let i = 0; i < this.options.concurrency; i++) {\n concurrencyPromises.push(uploadNext());\n }\n\n await Promise.all(concurrencyPromises);\n }\n\n /**\n * 完成上传\n */\n private async completeUpload(): Promise<CompleteUploadResponse> {\n if (!this.taskId) {\n throw new Error('任务ID不存在');\n }\n\n const response = await this.request<ApiResponse<CompleteUploadResponse>>(\n `/api/files/common/complete/${this.taskId}`,\n {\n method: 'POST',\n headers: this.options.headers,\n }\n );\n\n if (response.code !== 200) {\n throw new Error(response.message || '完成上传失败');\n }\n\n return response.data;\n }\n\n /**\n * 更新上传进度\n */\n private async updateProgress(): Promise<void> {\n if (!this.taskId) return;\n\n try {\n const response = await this.request<ApiResponse<UploadProgress>>(\n `/api/files/common/progress/${this.taskId}`,\n {\n method: 'GET',\n headers: this.options.headers,\n }\n );\n\n if (response.code === 200 && this.options.onProgress) {\n this.options.onProgress(response.data);\n }\n } catch (error) {\n console.warn('获取上传进度失败:', error);\n }\n }\n\n /**\n * 开始上传\n */\n async upload(): Promise<CompleteUploadResponse> {\n try {\n this.status = UploadStatus.UPLOADING;\n this.abortController = new AbortController();\n\n // 1. 初始化上传\n const initResponse = await this.initUpload();\n this.taskId = initResponse.taskId;\n\n // 如果已经完成上传(秒传)\n if (initResponse.instantUpload && initResponse.fileUrl) {\n this.status = UploadStatus.COMPLETED;\n const result: CompleteUploadResponse = {\n taskId: this.taskId,\n fileUrl: initResponse.fileUrl,\n fileName: this.file.name,\n fileSize: this.file.size,\n fileMd5: '',\n success: true,\n message: '文件已存在,秒传成功',\n };\n this.options.onComplete(result);\n return result;\n }\n\n // 2. 准备分片\n this.prepareChunks();\n\n // 3. 获取已上传的分片(断点续传)\n const existingChunks = await this.getUploadedChunks();\n existingChunks.forEach(index => this.uploadedChunks.add(index));\n\n // 4. 上传分片\n await this.uploadChunksConcurrently();\n\n // 5. 完成上传\n const result = await this.completeUpload();\n this.status = UploadStatus.COMPLETED;\n this.options.onComplete(result);\n\n return result;\n } catch (error) {\n this.status = UploadStatus.FAILED;\n const err = error instanceof Error ? error : new Error(String(error));\n this.options.onError(err);\n throw err;\n }\n }\n\n /**\n * 暂停上传\n */\n pause(): void {\n if (this.status === UploadStatus.UPLOADING) {\n this.status = UploadStatus.PAUSED;\n if (this.abortController) {\n this.abortController.abort();\n }\n }\n }\n\n /**\n * 恢复上传\n */\n async resume(): Promise<CompleteUploadResponse> {\n if (this.status === UploadStatus.PAUSED) {\n return this.upload();\n }\n throw new Error('当前状态无法恢复上传');\n }\n\n /**\n * 取消上传\n */\n async cancel(): Promise<void> {\n if (this.taskId && this.status === UploadStatus.UPLOADING) {\n try {\n await this.request<ApiResponse<null>>(`/api/files/common/cancel/${this.taskId}`, {\n method: 'POST',\n headers: this.options.headers,\n });\n } catch (error) {\n console.warn('取消上传失败:', error);\n }\n }\n\n this.status = UploadStatus.CANCELLED;\n if (this.abortController) {\n this.abortController.abort();\n }\n }\n\n /**\n * 获取当前状态\n */\n getStatus(): UploadStatus {\n return this.status;\n }\n\n /**\n * 获取任务ID\n */\n getTaskId(): string | null {\n return this.taskId;\n }\n\n /**\n * HTTP请求封装\n */\n private async request<T>(url: string, options: RequestInit = {}): Promise<T> {\n const fullUrl = `${this.options.baseURL}${url}`;\n const signal = this.abortController?.signal;\n\n const response = await fetch(fullUrl, {\n ...options,\n signal,\n });\n\n if (!response.ok) {\n throw new Error(`HTTP错误: ${response.status} ${response.statusText}`);\n }\n\n return response.json();\n }\n\n /**\n * 延迟函数\n */\n private delay(ms: number): Promise<void> {\n return new Promise(resolve => setTimeout(resolve, ms));\n }\n}\n\n/**\n * 创建文件上传器实例\n * @param file - 文件对象\n * @param options - 上传配置选项\n * @returns 上传器实例\n */\nexport function createUploader(file: File, options?: UploadOptions): ChunkUploader {\n return new ChunkUploader(file, options);\n}\n"]}