| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855 |
- import type { InferResponseType } from 'hono/client';
- import { fileClient } from "../api";
- import { isWeapp, isH5 } from './platform';
- import Taro from '@tarojs/taro';
- // 平台检测 - 使用统一的 platform.ts
- const isMiniProgram = isWeapp();
- const isBrowser = isH5();
- if (isMiniProgram) {
- try {
- Taro = require('@tarojs/taro');
- } catch (e) {
- // 忽略错误,回退到原生小程序
- }
- }
- export interface MinioProgressEvent {
- stage: 'uploading' | 'complete' | 'error';
- message: string;
- progress: number;
- details?: {
- loaded: number;
- total: number;
- };
- timestamp: number;
- }
- export interface MinioProgressCallbacks {
- onProgress?: (event: MinioProgressEvent) => void;
- onComplete?: () => void;
- onError?: (error: Error) => void;
- signal?: AbortSignal | { aborted: boolean };
- }
- export interface UploadResult {
- fileUrl: string;
- fileKey: string;
- bucketName: string;
- fileId: number;
- }
- interface UploadPart {
- ETag: string;
- PartNumber: number;
- }
- interface UploadProgressDetails {
- partNumber: number;
- totalParts: number;
- partSize: number;
- totalSize: number;
- partProgress?: number;
- }
- type MinioMultipartUploadPolicy = InferResponseType<typeof fileClient["multipart-policy"]['$post'], 200>
- type MinioUploadPolicy = InferResponseType<typeof fileClient["upload-policy"]['$post'], 200>
- const PART_SIZE = 5 * 1024 * 1024; // 每部分5MB
- // ==================== H5 实现(保留原有代码) ====================
- export class MinIOXHRMultipartUploader {
- /**
- * 使用XHR分段上传文件到MinIO(H5环境)
- */
- static async upload(
- policy: MinioMultipartUploadPolicy,
- file: File | Blob,
- key: string,
- callbacks?: MinioProgressCallbacks
- ): Promise<UploadResult> {
- const partSize = PART_SIZE;
- const totalSize = file.size;
- const totalParts = Math.ceil(totalSize / partSize);
- const uploadedParts: UploadPart[] = [];
-
- callbacks?.onProgress?.({
- stage: 'uploading',
- message: '准备上传文件...',
- progress: 0,
- details: {
- loaded: 0,
- total: totalSize
- },
- timestamp: Date.now()
- });
-
- // 分段上传
- for (let i = 0; i < totalParts; i++) {
- const start = i * partSize;
- const end = Math.min(start + partSize, totalSize);
- const partBlob = file.slice(start, end);
- const partNumber = i + 1;
-
- try {
- const etag = await this.uploadPart(
- policy.partUrls[i],
- partBlob,
- callbacks,
- {
- partNumber,
- totalParts,
- partSize: partBlob.size,
- totalSize
- }
- );
-
- uploadedParts.push({
- ETag: etag,
- PartNumber: partNumber
- });
-
- // 更新进度
- const progress = Math.round((end / totalSize) * 100);
- callbacks?.onProgress?.({
- stage: 'uploading',
- message: `上传文件片段 ${partNumber}/${totalParts}`,
- progress,
- details: {
- loaded: end,
- total: totalSize,
- },
- timestamp: Date.now()
- });
- } catch (error) {
- callbacks?.onError?.(error instanceof Error ? error : new Error(String(error)));
- throw error;
- }
- }
-
- // 完成上传
- try {
- await this.completeMultipartUpload(policy, key, uploadedParts);
-
- callbacks?.onProgress?.({
- stage: 'complete',
- message: '文件上传完成',
- progress: 100,
- timestamp: Date.now()
- });
-
- callbacks?.onComplete?.();
- return {
- fileUrl: `${policy.host}/${key}`,
- fileKey: key,
- bucketName: policy.bucket,
- fileId: result.file.id
- };
- } catch (error) {
- callbacks?.onError?.(error instanceof Error ? error : new Error(String(error)));
- throw error;
- }
- }
-
- // 上传单个片段
- private static uploadPart(
- uploadUrl: string,
- partBlob: Blob,
- callbacks?: MinioProgressCallbacks,
- progressDetails?: UploadProgressDetails
- ): Promise<string> {
- return new Promise((resolve, reject) => {
- const xhr = new XMLHttpRequest();
-
- xhr.upload.onprogress = (event) => {
- if (event.lengthComputable && callbacks?.onProgress) {
- const partProgress = Math.round((event.loaded / event.total) * 100);
- callbacks.onProgress({
- stage: 'uploading',
- message: `上传文件片段 ${progressDetails?.partNumber}/${progressDetails?.totalParts} (${partProgress}%)`,
- progress: Math.round((
- (progressDetails?.partNumber ? (progressDetails.partNumber - 1) * (progressDetails.partSize || 0) : 0) + event.loaded
- ) / (progressDetails?.totalSize || 1) * 100),
- details: {
- ...progressDetails,
- loaded: event.loaded,
- total: event.total
- },
- timestamp: Date.now()
- });
- }
- };
-
- xhr.onload = () => {
- if (xhr.status >= 200 && xhr.status < 300) {
- const etag = xhr.getResponseHeader('ETag')?.replace(/"/g, '') || '';
- resolve(etag);
- } else {
- reject(new Error(`上传片段失败: ${xhr.status} ${xhr.statusText}`));
- }
- };
-
- xhr.onerror = () => reject(new Error('上传片段失败'));
-
- xhr.open('PUT', uploadUrl);
- xhr.send(partBlob);
-
- if (callbacks?.signal) {
- if ('addEventListener' in callbacks.signal) {
- callbacks.signal.addEventListener('abort', () => {
- xhr.abort();
- reject(new Error('上传已取消'));
- });
- }
- }
- });
- }
-
- // 完成分段上传
- private static async completeMultipartUpload(
- policy: MinioMultipartUploadPolicy,
- key: string,
- uploadedParts: UploadPart[]
- ): Promise<{ fileId: number }> {
- const response = await fileClient["multipart-complete"].$post({
- json: {
- bucket: policy.bucket,
- key,
- uploadId: policy.uploadId,
- parts: uploadedParts.map(part => ({ partNumber: part.PartNumber, etag: part.ETag }))
- }
- });
-
- if (!response.ok) {
- throw new Error(`完成分段上传失败: ${response.status} ${response.statusText}`);
- }
-
- return response.json();
- }
- }
- export class MinIOXHRUploader {
- /**
- * 使用XHR上传文件到MinIO(H5环境)
- */
- static upload(
- policy: MinioUploadPolicy,
- file: File | Blob,
- key: string,
- callbacks?: MinioProgressCallbacks
- ): Promise<UploadResult> {
- const formData = new FormData();
- // 添加 MinIO 需要的字段
- Object.entries(policy.uploadPolicy).forEach(([k, value]) => {
- if (k !== 'key' && k !== 'host' && k !== 'prefix' && k !== 'ossType' && typeof value === 'string') {
- formData.append(k, value);
- }
- });
- formData.append('key', key);
- formData.append('file', file);
- return new Promise((resolve, reject) => {
- const xhr = new XMLHttpRequest();
- // 上传进度处理
- if (callbacks?.onProgress) {
- xhr.upload.onprogress = (event) => {
- if (event.lengthComputable) {
- callbacks.onProgress?.({
- stage: 'uploading',
- message: '正在上传文件...',
- progress: Math.round((event.loaded * 100) / event.total),
- details: {
- loaded: event.loaded,
- total: event.total
- },
- timestamp: Date.now()
- });
- }
- };
- }
- // 完成处理
- xhr.onload = () => {
- if (xhr.status >= 200 && xhr.status < 300) {
- if (callbacks?.onProgress) {
- callbacks.onProgress({
- stage: 'complete',
- message: '文件上传完成',
- progress: 100,
- timestamp: Date.now()
- });
- }
- callbacks?.onComplete?.();
- resolve({
- fileUrl: `${policy.uploadPolicy.host}/${key}`,
- fileKey: key,
- bucketName: policy.uploadPolicy.bucket,
- fileId: result.file.id
- });
- } else {
- const error = new Error(`上传失败: ${xhr.status} ${xhr.statusText}`);
- callbacks?.onError?.(error);
- reject(error);
- }
- };
- // 错误处理
- xhr.onerror = () => {
- const error = new Error('上传失败');
- if (callbacks?.onProgress) {
- callbacks.onProgress({
- stage: 'error',
- message: '文件上传失败',
- progress: 0,
- timestamp: Date.now()
- });
- }
- callbacks?.onError?.(error);
- reject(error);
- };
- // 根据当前页面协议和 host 配置决定最终的上传地址
- const currentProtocol = typeof window !== 'undefined' ? window.location.protocol : 'https:';
- const host = policy.uploadPolicy.host?.startsWith('http')
- ? policy.uploadPolicy.host
- : `${currentProtocol}//${policy.uploadPolicy.host}`;
-
- xhr.open('POST', host);
- xhr.send(formData);
- // 处理取消
- if (callbacks?.signal) {
- if ('addEventListener' in callbacks.signal) {
- callbacks.signal.addEventListener('abort', () => {
- xhr.abort();
- reject(new Error('上传已取消'));
- });
- }
- }
- });
- }
- }
- // ==================== 小程序实现 ====================
- export class TaroMinIOMultipartUploader {
- /**
- * 使用 Taro 分段上传文件到 MinIO(小程序环境)
- */
- static async upload(
- policy: MinioMultipartUploadPolicy,
- filePath: string,
- key: string,
- callbacks?: MinioProgressCallbacks
- ): Promise<UploadResult> {
- const partSize = PART_SIZE;
-
- // 获取文件信息
- const fileInfo = await getFileInfoPromise(filePath);
- const totalSize = fileInfo.size;
- const totalParts = Math.ceil(totalSize / partSize);
- const uploadedParts: UploadPart[] = [];
-
- callbacks?.onProgress?.({
- stage: 'uploading',
- message: '准备上传文件...',
- progress: 0,
- details: {
- loaded: 0,
- total: totalSize
- },
- timestamp: Date.now()
- });
-
- // 分段上传
- for (let i = 0; i < totalParts; i++) {
- if (callbacks?.signal && 'aborted' in callbacks.signal && callbacks.signal.aborted) {
- throw new Error('上传已取消');
- }
-
- const start = i * partSize;
- const end = Math.min(start + partSize, totalSize);
- const partNumber = i + 1;
-
- try {
- // 读取文件片段
- const partData = await this.readFileSlice(filePath, start, end);
-
- const etag = await this.uploadPart(
- policy.partUrls[i],
- partData,
- callbacks,
- {
- partNumber,
- totalParts,
- partSize: end - start,
- totalSize
- }
- );
-
- uploadedParts.push({
- ETag: etag,
- PartNumber: partNumber
- });
-
- // 更新进度
- const progress = Math.round((end / totalSize) * 100);
- callbacks?.onProgress?.({
- stage: 'uploading',
- message: `上传文件片段 ${partNumber}/${totalParts}`,
- progress,
- details: {
- loaded: end,
- total: totalSize,
- },
- timestamp: Date.now()
- });
- } catch (error) {
- callbacks?.onError?.(error instanceof Error ? error : new Error(String(error)));
- throw error;
- }
- }
-
- // 完成上传
- try {
- const result = await this.completeMultipartUpload(policy, key, uploadedParts);
-
- callbacks?.onProgress?.({
- stage: 'complete',
- message: '文件上传完成',
- progress: 100,
- timestamp: Date.now()
- });
-
- callbacks?.onComplete?.();
- return {
- fileUrl: `${policy.host}/${key}`,
- fileKey: key,
- bucketName: policy.bucket,
- fileId: result.fileId
- };
- } catch (error) {
- callbacks?.onError?.(error instanceof Error ? error : new Error(String(error)));
- throw error;
- }
- }
-
- // 读取文件片段
- private static async readFileSlice(filePath: string, start: number, end: number): Promise<string | ArrayBuffer> {
- return new Promise((resolve, reject) => {
- try {
- const fs = Taro?.getFileSystemManager?.();
- if (!fs) {
- reject(new Error('小程序文件系统不可用'));
- return;
- }
-
- const fileData = fs.readFileSync(filePath, undefined, start, end - start );
- resolve(fileData);
- } catch (error) {
- reject(error);
- }
- });
- }
-
- // 上传单个片段
- private static async uploadPart(
- uploadUrl: string,
- partData: ArrayBuffer,
- callbacks?: MinioProgressCallbacks,
- progressDetails?: UploadProgressDetails
- ): Promise<string> {
- return new Promise((resolve, reject) => {
- Taro?.request?.({
- url: uploadUrl,
- method: 'PUT',
- data: partData,
- header: {
- 'Content-Type': 'application/octet-stream'
- },
- success: (res: any) => {
- if (res.statusCode >= 200 && res.statusCode < 300) {
- const etag = res.header?.['ETag']?.replace(/"/g, '') || '';
- resolve(etag);
- } else {
- reject(new Error(`上传片段失败: ${res.statusCode}`));
- }
- },
- fail: (error: any) => {
- reject(new Error(`上传片段失败: ${error.errMsg}`));
- }
- }) || reject(new Error('小程序环境不可用'));
- });
- }
-
- // 完成分段上传
- private static async completeMultipartUpload(
- policy: MinioMultipartUploadPolicy,
- key: string,
- uploadedParts: UploadPart[]
- ): Promise<{ fileId: number }> {
- const response = await fileClient["multipart-complete"].$post({
- json: {
- bucket: policy.bucket,
- key,
- uploadId: policy.uploadId,
- parts: uploadedParts.map(part => ({ partNumber: part.PartNumber, etag: part.ETag }))
- }
- });
-
- if (!response.ok) {
- throw new Error(`完成分段上传失败: ${response.status} ${response.statusText}`);
- }
-
- return await response.json();
- }
- }
- export class TaroMinIOUploader {
- /**
- * 使用 Taro 上传文件到 MinIO(小程序环境)
- */
- static async upload(
- policy: MinioUploadPolicy,
- filePath: string,
- key: string,
- callbacks?: MinioProgressCallbacks
- ): Promise<UploadResult> {
- // 获取文件信息
- const fileInfo = await getFileInfoPromise(filePath);
- const totalSize = fileInfo.size;
-
- callbacks?.onProgress?.({
- stage: 'uploading',
- message: '准备上传文件...',
- progress: 0,
- details: {
- loaded: 0,
- total: totalSize
- },
- timestamp: Date.now()
- });
-
- return new Promise((resolve, reject) => {
- // 准备表单数据
- const formData: Record<string, any> = {};
-
- // 添加 MinIO 需要的字段
- Object.entries(policy.uploadPolicy).forEach(([k, value]) => {
- if (k !== 'key' && k !== 'host' && k !== 'prefix' && k !== 'ossType' && typeof value === 'string') {
- formData[k] = value;
- }
- });
-
- formData['key'] = key;
-
- try {
- const fileSystemManager = Taro?.getFileSystemManager?.();
- if (!fileSystemManager) {
- throw new Error('小程序环境不可用');
- }
- const fileData = fileSystemManager.readFileSync(filePath, 'binary');
-
- const formDataObj = new FormData();
- Object.entries(formData).forEach(([k, value]) => {
- formDataObj.append(k, value);
- });
- formDataObj.append('file', new Blob([fileData]));
- Taro?.request?.({
- url: policy.uploadPolicy.host,
- method: 'POST',
- data: formDataObj,
- header: {
- 'Content-Type': 'multipart/form-data'
- },
- success: (res) => {
- if (res.statusCode >= 200 && res.statusCode < 300) {
- callbacks?.onProgress?.({
- stage: 'complete',
- message: '文件上传完成',
- progress: 100,
- timestamp: Date.now()
- });
- callbacks?.onComplete?.();
- resolve({
- fileUrl: `${policy.uploadPolicy.host}/${key}`,
- fileKey: key,
- bucketName: policy.uploadPolicy.bucket,
- fileId: policy.file.id
- });
- } else {
- reject(new Error(`上传失败: ${res.statusCode}`));
- }
- },
- fail: (error: any) => {
- reject(new Error(`上传失败: ${error.errMsg}`));
- }
- });
- } catch (error: any) {
- reject(new Error(`读取文件失败: ${error.message || error.errMsg}`));
- }
- });
- }
- }
- // ==================== 统一 API ====================
- /**
- * 根据运行环境自动选择合适的上传器
- */
- export class UniversalMinIOMultipartUploader {
- static async upload(
- policy: MinioMultipartUploadPolicy,
- file: File | Blob | string,
- key: string,
- callbacks?: MinioProgressCallbacks
- ): Promise<UploadResult> {
- if (isBrowser && (file instanceof File || file instanceof Blob)) {
- return MinIOXHRMultipartUploader.upload(policy, file, key, callbacks);
- } else if (isMiniProgram && typeof file === 'string') {
- return TaroMinIOMultipartUploader.upload(policy, file, key, callbacks);
- } else {
- throw new Error('不支持的运行环境或文件类型');
- }
- }
- }
- export class UniversalMinIOUploader {
- static async upload(
- policy: MinioUploadPolicy,
- file: File | Blob | string,
- key: string,
- callbacks?: MinioProgressCallbacks
- ): Promise<UploadResult> {
- if (isBrowser && (file instanceof File || file instanceof Blob)) {
- return MinIOXHRUploader.upload(policy, file, key, callbacks);
- } else if (isMiniProgram && typeof file === 'string') {
- return TaroMinIOUploader.upload(policy, file, key, callbacks);
- } else {
- throw new Error('不支持的运行环境或文件类型');
- }
- }
- }
- // ==================== 通用函数 ====================
- export async function getUploadPolicy(key: string, fileName: string, fileType?: string, fileSize?: number): Promise<MinioUploadPolicy> {
- const policyResponse = await fileClient["upload-policy"].$post({
- json: {
- path: key,
- name: fileName,
- type: fileType,
- size: fileSize
- }
- });
- if (!policyResponse.ok) {
- throw new Error('获取上传策略失败');
- }
- return policyResponse.json();
- }
- export async function getMultipartUploadPolicy(totalSize: number, fileKey: string, fileType?: string, fileName: string = 'unnamed-file') {
- const policyResponse = await fileClient["multipart-policy"].$post({
- json: {
- totalSize,
- partSize: PART_SIZE,
- fileKey,
- type: fileType,
- name: fileName
- }
- });
- if (!policyResponse.ok) {
- throw new Error('获取分段上传策略失败');
- }
- return await policyResponse.json();
- }
- /**
- * 统一的上传函数,自动适应运行环境
- */
- export async function uploadMinIOWithPolicy(
- uploadPath: string,
- file: File | Blob | string,
- fileKey: string,
- callbacks?: MinioProgressCallbacks
- ): Promise<UploadResult> {
- if(uploadPath === '/') uploadPath = '';
- else{
- if(!uploadPath.endsWith('/')) uploadPath = `${uploadPath}/`
- if(uploadPath.startsWith('/')) uploadPath = uploadPath.replace(/^\//, '');
- }
-
- let fileSize: number;
- let fileType: string | undefined;
- let fileName: string;
-
- if (isBrowser && (file instanceof File || file instanceof Blob)) {
- fileSize = file.size;
- fileType = (file as File).type || undefined;
- fileName = (file as File).name || fileKey;
- } else if (isMiniProgram && typeof file === 'string') {
- try {
- const fileInfo = await getFileInfoPromise(file);
- fileSize = fileInfo.size;
- fileType = undefined;
- fileName = fileKey;
- } catch {
- fileSize = 0;
- fileType = undefined;
- fileName = fileKey;
- }
- } else {
- throw new Error('不支持的文件类型');
- }
-
- if (fileSize > PART_SIZE) {
- if (isBrowser && !(file instanceof File)) {
- throw new Error('不支持的文件类型,无法获取文件名');
- }
-
- const policy = await getMultipartUploadPolicy(
- fileSize,
- `${uploadPath}${fileKey}`,
- fileType,
- fileName
- );
-
- if (isBrowser) {
- return MinIOXHRMultipartUploader.upload(policy, file as File | Blob, policy.key, callbacks);
- } else {
- return TaroMinIOMultipartUploader.upload(policy, file as string, policy.key, callbacks);
- }
- } else {
- if (isBrowser && !(file instanceof File)) {
- throw new Error('不支持的文件类型,无法获取文件名');
- }
-
- const policy = await getUploadPolicy(`${uploadPath}${fileKey}`, fileName, fileType, fileSize);
-
- if (isBrowser) {
- return MinIOXHRUploader.upload(policy, file as File | Blob, policy.uploadPolicy.key, callbacks);
- } else {
- return TaroMinIOUploader.upload(policy, file as string, policy.uploadPolicy.key, callbacks);
- }
- }
- }
- // ==================== 小程序工具函数 ====================
- /**
- * Promise封装的getFileInfo函数
- */
- async function getFileInfoPromise(filePath: string): Promise<{ size: number }> {
- return new Promise((resolve, reject) => {
- const fs = Taro?.getFileSystemManager?.();
- if (!fs) {
- reject(new Error('小程序文件系统不可用'));
- return;
- }
-
- fs.getFileInfo({
- filePath,
- success: (res) => {
- resolve({ size: res.size });
- },
- fail: (error) => {
- reject(new Error(`获取文件信息失败: ${error.errMsg}`));
- }
- });
- });
- }
- // 新增:自动适应运行环境的文件选择并上传函数
- /**
- * 自动适应运行环境:选择文件并上传到 MinIO
- * 小程序:使用 Taro.chooseImage
- * H5:使用 input[type="file"]
- */
- export async function uploadFromSelect(
- uploadPath: string = '',
- options: {
- sourceType?: ('album' | 'camera')[],
- count?: number,
- accept?: string,
- maxSize?: number,
- } = {},
- callbacks?: MinioProgressCallbacks
- ): Promise<UploadResult> {
- const { sourceType = ['album', 'camera'], count = 1, accept = '*', maxSize = 10 * 1024 * 1024 } = options;
- if (isMiniProgram) {
- return new Promise((resolve, reject) => {
- if (typeof Taro === 'undefined') {
- reject(new Error('Taro 环境未找到'));
- return;
- }
-
- Taro.chooseImage({
- count,
- sourceType: sourceType as any, // 确保类型兼容
- success: async (res) => {
- const tempFilePath = res.tempFilePaths[0];
- const fileName = res.tempFiles[0]?.name || tempFilePath.split('/').pop() || 'unnamed-file';
-
- try {
- const result = await uploadMinIOWithPolicy(uploadPath, tempFilePath, fileName, callbacks);
- resolve(result);
- } catch (error) {
- reject(error);
- }
- },
- fail: reject
- });
- });
- } else if (isBrowser) {
- return new Promise((resolve, reject) => {
- const input = document.createElement('input');
- input.type = 'file';
- input.accept = accept;
- input.multiple = count > 1;
-
- input.onchange = async (event) => {
- const files = (event.target as HTMLInputElement).files;
- if (!files || files.length === 0) {
- reject(new Error('未选择文件'));
- return;
- }
-
- const file = files[0];
- if (file.size > maxSize) {
- reject(new Error(`文件大小超过限制: ${maxSize / 1024 / 1024}MB`));
- return;
- }
-
- const fileName = file.name || 'unnamed-file';
-
- try {
- const result = await uploadMinIOWithPolicy(uploadPath, file, fileName, callbacks);
- resolve(result);
- } catch (error) {
- reject(error);
- }
- };
-
- input.click();
- });
- } else {
- throw new Error('不支持的运行环境');
- }
- }
- // 默认导出
- export default {
- MinIOXHRMultipartUploader,
- MinIOXHRUploader,
- TaroMinIOMultipartUploader,
- TaroMinIOUploader,
- UniversalMinIOMultipartUploader,
- UniversalMinIOUploader,
- getUploadPolicy,
- getMultipartUploadPolicy,
- uploadMinIOWithPolicy,
- uploadFromSelect
- };
|