u
This commit is contained in:
1 parent
c7240ea7c9
commit
189a085353
26 files changed
+2650
-201
No files matched your search
@@ -203,14 +203,113 @@ export function getFileExtension(fileName) {
|
||||
return fileExt;
|
||||
}
|
||||
|
||||
// 上传到阿里云
|
||||
// blob fileName fileSize xh moduleid father cateid
|
||||
export function downloadZip(files, fileName = "文件合集", callback) {
|
||||
const zip = new JSZip();
|
||||
const addedFiles = new Set();
|
||||
|
||||
const tasks = files.map((item) => {
|
||||
return getAliyunFileBlob(item.mx_mapfilename)
|
||||
.then((res) => {
|
||||
const uniqueFileName = getUniqueFileName(item.mx_filename, addedFiles);
|
||||
zip.file(uniqueFileName, res, { binary: true });
|
||||
addedFiles.add(uniqueFileName);
|
||||
})
|
||||
.catch((err) => {
|
||||
// 捕获单个文件下载失败的错误,不影响其他文件下载
|
||||
console.error(`Failed to download file: ${item.mx_filename}`, err);
|
||||
});
|
||||
});
|
||||
|
||||
// 关键:使用 Promise.all 确保所有任务完成
|
||||
return Promise.all(tasks)
|
||||
.then(() => zip.generateAsync({ type: "blob" }))
|
||||
.then((res) => {
|
||||
saveAs(res, `${fileName}.zip`);
|
||||
callback && callback();
|
||||
})
|
||||
.catch((err) => {
|
||||
callback && callback();
|
||||
throw err;
|
||||
});
|
||||
}
|
||||
|
||||
// 处理文件名重复的函数
|
||||
function getUniqueFileName(fileName, addedFiles) {
|
||||
let uniqueFileName = fileName;
|
||||
let counter = 1;
|
||||
|
||||
// 如果文件名已经存在,则在文件名后加上 (1), (2), ...
|
||||
while (addedFiles.has(uniqueFileName)) {
|
||||
const fileNameWithoutExtension = uniqueFileName.replace(/\.[^/.]+$/, "");
|
||||
const extension = uniqueFileName.slice(uniqueFileName.lastIndexOf("."));
|
||||
uniqueFileName = `${fileNameWithoutExtension} (${counter})${extension}`;
|
||||
counter++;
|
||||
}
|
||||
|
||||
return uniqueFileName;
|
||||
}
|
||||
|
||||
// ============================================ 阿里云上传和下载 ============================================
|
||||
|
||||
let cachedCredentials = null; // 用来缓存凭证
|
||||
let isFetchingCredentials = false; // 控制是否正在请求凭证
|
||||
|
||||
// 获取阿里云文件的上传凭证
|
||||
export function getAliyunUploadCredentials() {
|
||||
return new Promise((resolve, reject) => {
|
||||
// 如果缓存中有有效的凭证,则直接使用
|
||||
if (cachedCredentials && !isCredentialsExpired(cachedCredentials)) {
|
||||
resolve(cachedCredentials); // 凭证未过期,直接返回缓存的凭证
|
||||
} else {
|
||||
// 如果正在请求凭证,则等待
|
||||
if (isFetchingCredentials) {
|
||||
const interval = setInterval(() => {
|
||||
// 等待直到凭证被请求完毕
|
||||
if (!isFetchingCredentials) {
|
||||
clearInterval(interval); // 请求完成后停止轮询
|
||||
resolve(cachedCredentials); // 返回缓存的凭证
|
||||
}
|
||||
}, 100); // 每100ms检查一次
|
||||
} else {
|
||||
// 如果凭证过期,重新请求新的凭证
|
||||
isFetchingCredentials = true; // 设置为正在请求凭证状态
|
||||
getAliyunKeyApi()
|
||||
.then((res) => {
|
||||
if (res.success) {
|
||||
const { accessid, policy, signature, expire, dir, host } = res.data;
|
||||
|
||||
// 缓存凭证,并记录过期时间
|
||||
cachedCredentials = {
|
||||
accessid,
|
||||
policy,
|
||||
signature,
|
||||
expire: parseInt(expire, 10),
|
||||
dir,
|
||||
host,
|
||||
};
|
||||
|
||||
isFetchingCredentials = false; // 请求完成,解除锁定
|
||||
resolve(cachedCredentials); // 返回新凭证
|
||||
} else {
|
||||
isFetchingCredentials = false; // 请求失败,解除锁定
|
||||
reject(new Error("获取凭证失败"));
|
||||
}
|
||||
})
|
||||
.catch((err) => {
|
||||
isFetchingCredentials = false; // 请求失败,解除锁定
|
||||
reject(new Error("请求凭证失败:" + err.message));
|
||||
});
|
||||
}
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
// 上传文件到阿里云
|
||||
export function uploadFile(blob, fileName, fileExt, fileSize, xh, moduleid, father, cateid) {
|
||||
return new Promise((resolve, reject) => {
|
||||
getAliyunKeyApi()
|
||||
.then(async (res) => {
|
||||
getAliyunUploadCredentials()
|
||||
.then(async (aliyunKey) => {
|
||||
try {
|
||||
const aliyunKey = res.data;
|
||||
const formData = new FormData();
|
||||
|
||||
let uniqueName = `${Date.now()}_${Math.random().toString(36).slice(2)}`;
|
||||
@@ -219,12 +318,17 @@ export function uploadFile(blob, fileName, fileExt, fileSize, xh, moduleid, fath
|
||||
uniqueName += `.${fileExt}`;
|
||||
}
|
||||
|
||||
// 构造上传的文件路径
|
||||
formData.append("key", `${aliyunKey.dir}${uniqueName}`);
|
||||
formData.append("OSSAccessKeyId", aliyunKey.accessid);
|
||||
formData.append("policy", aliyunKey.policy);
|
||||
formData.append("Signature", aliyunKey.signature);
|
||||
formData.append("file", blob, uniqueName);
|
||||
|
||||
console.log(formData);
|
||||
console.log(aliyunKey.host);
|
||||
console.log(aliyunKey.dir);
|
||||
|
||||
const xhr = new XMLHttpRequest();
|
||||
xhr.open("POST", aliyunKey.host, true);
|
||||
|
||||
@@ -232,6 +336,7 @@ export function uploadFile(blob, fileName, fileExt, fileSize, xh, moduleid, fath
|
||||
if (xhr.status === 200 || xhr.status === 204) {
|
||||
const allFilePath = `${aliyunKey.host}/${aliyunKey.dir}${uniqueName}`;
|
||||
|
||||
// 上传后处理(插入文件记录等)
|
||||
const insertRes = await insertFileApi({
|
||||
father,
|
||||
mx_moduleid: moduleid,
|
||||
@@ -278,76 +383,35 @@ export function uploadFile(blob, fileName, fileExt, fileSize, xh, moduleid, fath
|
||||
});
|
||||
}
|
||||
|
||||
// 检查凭证是否过期
|
||||
function isCredentialsExpired(credentials) {
|
||||
const currentTime = Math.floor(Date.now() / 1000);
|
||||
return currentTime > credentials.expire;
|
||||
}
|
||||
|
||||
// 获取阿里云文件的 Blob 数据(用于下载)
|
||||
export function getAliyunFileBlob(url) {
|
||||
return new Promise((resolve, reject) => {
|
||||
// 创建一个独立的异步函数来处理 fetch 请求
|
||||
async function fetchFile() {
|
||||
try {
|
||||
const response = await fetch(url, { mode: "cors" });
|
||||
getAliyunUploadCredentials()
|
||||
.then((aliyunKey) => {
|
||||
const downloadUrl = `${url}?OSSAccessKeyId=${aliyunKey.accessid}&policy=${aliyunKey.policy}&Signature=${aliyunKey.signature}`;
|
||||
|
||||
// 检查响应状态
|
||||
if (!response.ok) {
|
||||
reject(new Error(`下载失败:${response.status}`));
|
||||
return;
|
||||
}
|
||||
|
||||
// 获取文件内容
|
||||
const blob = await response.blob();
|
||||
|
||||
// 返回blob
|
||||
resolve(blob);
|
||||
} catch (error) {
|
||||
reject(error);
|
||||
}
|
||||
}
|
||||
|
||||
// 调用异步函数
|
||||
fetchFile();
|
||||
});
|
||||
}
|
||||
|
||||
export function downloadZip(files, fileName = "文件合集", callback) {
|
||||
const zip = new JSZip();
|
||||
const addedFiles = new Set();
|
||||
|
||||
const tasks = files.map((item) => {
|
||||
return getAliyunFileBlob(item.mx_mapfilename)
|
||||
.then((res) => {
|
||||
const uniqueFileName = getUniqueFileName(item.mx_filename, addedFiles);
|
||||
zip.file(uniqueFileName, res, { binary: true });
|
||||
addedFiles.add(uniqueFileName);
|
||||
fetch(downloadUrl, { mode: "cors" })
|
||||
.then((response) => {
|
||||
if (!response.ok) {
|
||||
throw new Error(`下载失败,状态码:${response.status}`);
|
||||
}
|
||||
return response.blob();
|
||||
})
|
||||
.then((blob) => {
|
||||
resolve(blob);
|
||||
})
|
||||
.catch((error) => {
|
||||
reject(error);
|
||||
});
|
||||
})
|
||||
.catch((err) => {
|
||||
// 捕获单个文件下载失败的错误,不影响其他文件下载
|
||||
console.error(`Failed to download file: ${item.mx_filename}`, err);
|
||||
});
|
||||
.catch(reject);
|
||||
});
|
||||
|
||||
// 关键:使用 Promise.all 确保所有任务完成
|
||||
return Promise.all(tasks)
|
||||
.then(() => zip.generateAsync({ type: "blob" }))
|
||||
.then((res) => {
|
||||
saveAs(res, `${fileName}.zip`);
|
||||
callback && callback();
|
||||
})
|
||||
.catch((err) => {
|
||||
callback && callback();
|
||||
throw err;
|
||||
});
|
||||
}
|
||||
|
||||
// 处理文件名重复的函数
|
||||
function getUniqueFileName(fileName, addedFiles) {
|
||||
let uniqueFileName = fileName;
|
||||
let counter = 1;
|
||||
|
||||
// 如果文件名已经存在,则在文件名后加上 (1), (2), ...
|
||||
while (addedFiles.has(uniqueFileName)) {
|
||||
const fileNameWithoutExtension = uniqueFileName.replace(/\.[^/.]+$/, "");
|
||||
const extension = uniqueFileName.slice(uniqueFileName.lastIndexOf("."));
|
||||
uniqueFileName = `${fileNameWithoutExtension} (${counter})${extension}`;
|
||||
counter++;
|
||||
}
|
||||
|
||||
return uniqueFileName;
|
||||
}
|
||||
// ============================================ 阿里云上传和下载 ============================================
|
||||
Reference in new issue
Block a user