130 lines
4.4 KiB
JavaScript

// uploader.js
const dropArea = document.getElementById("drop-area");
const fileElem = document.getElementById("fileElem");
const uploadList = document.getElementById("uploadList");
const folderNameInput = document.getElementById("folderName");
const bucketNameInput = document.getElementById("bucketName");
const API_UPLOAD = "http://localhost:18081/api/v1/doc/upload-files";
dropArea.addEventListener("click", () => fileElem.click());
dropArea.addEventListener("dragover", e => {
e.preventDefault(); dropArea.classList.add("dragover");
});
dropArea.addEventListener("dragleave", e => {
e.preventDefault(); dropArea.classList.remove("dragover");
});
dropArea.addEventListener("drop", e => {
e.preventDefault(); dropArea.classList.remove("dragover");
handleFiles(e.dataTransfer.files);
});
fileElem.addEventListener("change", () => handleFiles(fileElem.files));
function getTargetFolder() {
let folder = (folderNameInput.value || "").trim();
if (!folder) folder = "default";
folder = folder.replace(/^\/+|\/+$/g, "");
return folder;
}
function getBucketName() {
let bucket = (bucketNameInput.value || "").trim();
return bucket.replace(/^\/+|\/+$/g, "");
}
// 工具:为单个文件显示进度
function createProgressItem(filename) {
const wrapper = document.createElement("div");
wrapper.className = "progress-item";
wrapper.innerHTML = `
<span class="file-label">${filename}</span>
<progress value="0" max="100" style="width:60%;margin:0 10px;"></progress>
<span class="percent-label">0%</span>
<span class="upload-msg"></span>
`;
uploadList.appendChild(wrapper);
return wrapper;
}
async function handleFiles(files) {
uploadList.innerHTML = "";
const bucket = getBucketName();
if (!bucket) {
showMsg("请输入 Bucket 名称", false);
return;
}
if (!files || !files.length) return;
const folder = getTargetFolder();
// 多文件逐个上传,每个单独显示进度
for (const file of files) {
await uploadSingleFile(file, bucket, folder);
}
}
function showMsg(msg, ok) {
const div = document.createElement("div");
div.className = ok ? "success" : "error";
div.innerHTML = msg;
uploadList.appendChild(div);
}
// 单文件上传,带进度条
function uploadSingleFile(file, bucket, folder) {
return new Promise((resolve) => {
const form = new FormData();
form.append("bucket", bucket);
form.append("files", file, file.name);
const progressItem = createProgressItem(file.name);
const progressBar = progressItem.querySelector("progress");
const percentLabel = progressItem.querySelector(".percent-label");
const msgSpan = progressItem.querySelector(".upload-msg");
const xhr = new XMLHttpRequest();
xhr.open("POST", API_UPLOAD);
xhr.upload.onprogress = function (e) {
if (e.lengthComputable) {
const percent = Math.round((e.loaded / e.total) * 100);
progressBar.value = percent;
percentLabel.textContent = percent + "%";
}
};
xhr.onload = function () {
progressBar.value = 100;
percentLabel.textContent = "100%";
if (xhr.status === 200) {
try {
const res = JSON.parse(xhr.responseText);
// 查找本文件上传结果
let link = "";
if (res.files && res.files[file.name]) {
link = `<a href="${res.files[file.name]}" target="_blank">${file.name}</a> 上传成功`;
msgSpan.innerHTML = link;
msgSpan.className = "success";
} else {
msgSpan.innerHTML = "上传成功";
msgSpan.className = "success";
}
} catch (e) {
msgSpan.innerHTML = "上传成功";
msgSpan.className = "success";
}
} else {
msgSpan.innerHTML = "上传失败 " + xhr.status;
msgSpan.className = "error";
}
resolve();
};
xhr.onerror = function () {
msgSpan.innerHTML = "上传异常";
msgSpan.className = "error";
resolve();
};
xhr.send(form);
});
}