76 lines
2.6 KiB
TypeScript
76 lines
2.6 KiB
TypeScript
import * as tus from 'tus-js-client';
|
|
import { promises as fs } from 'fs';
|
|
import * as mime from 'mime-types';
|
|
|
|
export const uploader = async (
|
|
endpoint: string = 'http://localhost:8080',
|
|
input: Buffer | string,
|
|
externalFileName: string = 'unknown', // 允许外部传入文件名
|
|
onProgress?: (percentage: number) => void,
|
|
onSuccess?: (url: string) => void,
|
|
onError?: (error: Error) => void
|
|
) => {
|
|
let fileBuffer: Buffer;
|
|
let fileName: string;
|
|
let fileType: string;
|
|
|
|
// 确定输入是Buffer还是文件路径
|
|
if (typeof input === 'string') {
|
|
try {
|
|
fileBuffer = await fs.readFile(input);
|
|
fileName = input.split('/').pop() || 'unknown';
|
|
fileType = mime.lookup(input) || 'application/octet-stream';
|
|
} catch (error: any) {
|
|
console.error("读取文件失败: " + error.message);
|
|
if (onError) onError(error);
|
|
return;
|
|
}
|
|
} else {
|
|
fileBuffer = input;
|
|
fileName = externalFileName; // 使用外部传入的文件名
|
|
// 尝试获取文件类型,这里简化处理,实际应用中可能需要更复杂的逻辑
|
|
fileType = mime.lookup(fileName) || 'application/octet-stream';
|
|
}
|
|
|
|
const upload = new tus.Upload(fileBuffer as any, {
|
|
endpoint: `${endpoint}/files/`,
|
|
retryDelays: [0, 3000, 5000, 10000, 20000],
|
|
metadata: { filename: fileName, filetype: fileType },
|
|
onError: (error) => {
|
|
console.error("上传失败: " + error.message);
|
|
if (onError) onError(error);
|
|
},
|
|
onProgress: (bytesUploaded, bytesTotal) => {
|
|
const percentage = (bytesUploaded / bytesTotal) * 100;
|
|
if (onProgress) onProgress(percentage);
|
|
},
|
|
onSuccess: () => {
|
|
console.log("上传完成");
|
|
if (onSuccess) onSuccess(upload.url!);
|
|
},
|
|
});
|
|
|
|
// 寻找并继续之前的上传
|
|
upload.findPreviousUploads().then((previousUploads) => {
|
|
if (previousUploads && previousUploads.length > 0) {
|
|
upload.resumeFromPreviousUpload(previousUploads[0]!);
|
|
}
|
|
});
|
|
|
|
return upload;
|
|
};
|
|
|
|
export const uploaderPromise = (
|
|
endpoint: string,
|
|
input: Buffer | string,
|
|
externalFileName: string = 'unknown', // 允许外部传入文件名
|
|
onProgress?: (percentage: number) => void
|
|
): Promise<string> => {
|
|
return new Promise((resolve, reject) => {
|
|
uploader(endpoint, input, externalFileName, onProgress, resolve, reject)
|
|
.then((upload) => {
|
|
upload!.start();
|
|
})
|
|
.catch(reject);
|
|
});
|
|
}; |