207 lines
7.6 KiB
JavaScript
207 lines
7.6 KiB
JavaScript
const dropArea = document.getElementById("drop-area");
|
||
const fileElem = document.getElementById("fileElem");
|
||
const uploadList = document.getElementById("uploadList");
|
||
const folderNameInput = document.getElementById("folderName");
|
||
const folderSelect = document.getElementById("folderSelect");
|
||
const searchableSelect = document.getElementById("searchableSelect");
|
||
const bucketNameInput = document.getElementById("bucketName");
|
||
const jsonResult = document.getElementById("jsonResult");
|
||
|
||
const API_UPLOAD = "http://app.wisdompulse.cn/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() {
|
||
const selected = folderSelect?.value || "";
|
||
if (selected === "custom") {
|
||
return (folderNameInput.value || "default").trim().replace(/^\/+|\/+$/g, "");
|
||
} else {
|
||
return selected || "default";
|
||
}
|
||
}
|
||
|
||
function getSearchable() {
|
||
return searchableSelect?.value === "true";
|
||
}
|
||
|
||
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;
|
||
}
|
||
|
||
function showMsg(msg, ok) {
|
||
const div = document.createElement("div");
|
||
div.className = ok ? "success" : "error";
|
||
div.innerHTML = msg;
|
||
uploadList.appendChild(div);
|
||
}
|
||
|
||
// 批量上传(单次FormData),统一进度条管理,JSON右侧展示
|
||
function handleFiles(fileList) {
|
||
uploadList.innerHTML = "";
|
||
jsonResult.textContent = "{}";
|
||
const bucket = getBucketName();
|
||
if (!bucket) {
|
||
showMsg("请输入 Bucket 名称", false);
|
||
return;
|
||
}
|
||
if (!fileList || !fileList.length) return;
|
||
const folder = getTargetFolder();
|
||
const searchable = getSearchable();
|
||
|
||
const fileArr = Array.from(fileList);
|
||
const progressItems = {};
|
||
fileArr.forEach(f => {
|
||
progressItems[f.name] = createProgressItem(f.name);
|
||
});
|
||
|
||
const form = new FormData();
|
||
form.append("bucket", bucket);
|
||
form.append("targetFolder", folder);
|
||
form.append("searchable", searchable);
|
||
fileArr.forEach(f => form.append("files", f, f.name));
|
||
|
||
const xhr = new XMLHttpRequest();
|
||
xhr.open("POST", API_UPLOAD);
|
||
|
||
xhr.upload.onprogress = function (e) {
|
||
if (e.lengthComputable) {
|
||
let percent = Math.round((e.loaded / e.total) * 98);
|
||
percent = Math.min(percent, 98);
|
||
fileArr.forEach(f => {
|
||
const pi = progressItems[f.name];
|
||
pi.querySelector("progress").value = percent;
|
||
pi.querySelector(".percent-label").textContent = percent + "%";
|
||
});
|
||
}
|
||
};
|
||
|
||
xhr.upload.onload = function () {
|
||
fileArr.forEach(f => {
|
||
const pi = progressItems[f.name];
|
||
pi.querySelector("progress").value = 99;
|
||
pi.querySelector(".percent-label").textContent = "99%";
|
||
const msgSpan = pi.querySelector(".upload-msg");
|
||
msgSpan.innerHTML = "<span style='color:#888;'>服务器处理中...</span>";
|
||
});
|
||
};
|
||
|
||
xhr.onload = function () {
|
||
fileArr.forEach(f => {
|
||
const pi = progressItems[f.name];
|
||
pi.querySelector("progress").value = 100;
|
||
pi.querySelector(".percent-label").textContent = "100%";
|
||
});
|
||
|
||
if (xhr.status === 200) {
|
||
try {
|
||
const res = JSON.parse(xhr.responseText);
|
||
jsonResult.textContent = JSON.stringify(res.files, null, 2);
|
||
fileArr.forEach(f => {
|
||
const pi = progressItems[f.name];
|
||
const msgSpan = pi.querySelector(".upload-msg");
|
||
if (res.files && res.files[f.name]) {
|
||
msgSpan.innerHTML = `<a href="${res.files[f.name]}" target="_blank">${f.name}</a> 上传成功`;
|
||
msgSpan.className = "success upload-msg";
|
||
} else {
|
||
msgSpan.innerHTML = "上传成功";
|
||
msgSpan.className = "success upload-msg";
|
||
}
|
||
});
|
||
} catch (e) {
|
||
jsonResult.textContent = "{}";
|
||
fileArr.forEach(f => {
|
||
const pi = progressItems[f.name];
|
||
pi.querySelector(".upload-msg").innerHTML = "上传成功";
|
||
pi.querySelector(".upload-msg").className = "success upload-msg";
|
||
});
|
||
}
|
||
} else if (xhr.status === 504 || xhr.status === 502) {
|
||
jsonResult.textContent = "{}";
|
||
fileArr.forEach(f => {
|
||
const pi = progressItems[f.name];
|
||
const msgSpan = pi.querySelector(".upload-msg");
|
||
msgSpan.innerHTML = "服务器处理中,请稍后在目标目录查看上传结果";
|
||
msgSpan.className = "success upload-msg";
|
||
});
|
||
} else {
|
||
jsonResult.textContent = "{}";
|
||
fileArr.forEach(f => {
|
||
const pi = progressItems[f.name];
|
||
const msgSpan = pi.querySelector(".upload-msg");
|
||
msgSpan.innerHTML = "上传失败 " + xhr.status;
|
||
msgSpan.className = "error upload-msg";
|
||
});
|
||
}
|
||
};
|
||
|
||
xhr.onerror = function () {
|
||
fileArr.forEach(f => {
|
||
const pi = progressItems[f.name];
|
||
pi.querySelector(".upload-msg").innerHTML = "上传异常";
|
||
pi.querySelector(".upload-msg").className = "error upload-msg";
|
||
});
|
||
jsonResult.textContent = "{}";
|
||
};
|
||
|
||
xhr.send(form);
|
||
}
|
||
|
||
// === 放在文件结尾,而不是 handleFiles 内部 ===
|
||
const bucketTip = document.getElementById("bucketTip");
|
||
bucketNameInput.addEventListener("change", function () {
|
||
if (bucketNameInput.value === "kbase-priv") {
|
||
bucketTip.innerHTML = "私有 bucket 中,文件的可访问链接有效期为 <b>7天</b>";
|
||
bucketTip.style.color = "#ec0924";
|
||
} else {
|
||
bucketTip.innerHTML = "";
|
||
bucketTip.style.color = "";
|
||
}
|
||
});
|
||
bucketNameInput.dispatchEvent(new Event("change"));
|
||
|
||
document.addEventListener("DOMContentLoaded", function () {
|
||
const defaultFolderPath = new Date().toISOString().slice(0, 10).replace(/-/g, "");
|
||
const folderSelect = document.getElementById("folderSelect");
|
||
const folderNameInput = document.getElementById("folderName");
|
||
const customFolderRow = document.getElementById("customFolderRow");
|
||
|
||
const defaultOption = document.getElementById("defaultFolderOption");
|
||
defaultOption.value = defaultFolderPath;
|
||
defaultOption.textContent = defaultFolderPath;
|
||
folderSelect.value = defaultFolderPath;
|
||
|
||
folderSelect.addEventListener("change", function () {
|
||
if (this.value === "custom") {
|
||
customFolderRow.style.display = "block";
|
||
} else {
|
||
customFolderRow.style.display = "none";
|
||
}
|
||
});
|
||
});
|