Files
fuyouawa-comfyui-easytoolkit/web/base64_loader.js
T

139 lines
5.7 KiB
JavaScript

import { app } from "../../../scripts/app.js";
app.registerExtension({
name: "EasyToolkit.Misc.Base64Uploader",
async beforeRegisterNodeDef(nodeType, nodeData, app) {
if (nodeData.name !== "Base64Uploader") return;
const onNodeCreated = nodeType.prototype.onNodeCreated;
nodeType.prototype.onNodeCreated = function () {
if (onNodeCreated) onNodeCreated.apply(this, arguments);
let uuid_widget = this.widgets?.find(w => w.name === "uuid");
if (uuid_widget && (!uuid_widget.value || uuid_widget.value === "")) {
uuid_widget.value = crypto.randomUUID();
}
uuid_widget.disabled = true;
let progressWidget = this.addWidget("text", "upload_progress", "正在准备上传...", () => {});
progressWidget.disabled = true;
progressWidget.value = "待命中...";
this.addWidget("button", "选择文件上传", null, async () => {
const input = document.createElement("input");
input.type = "file";
input.accept = "*/*";
input.style.display = "none";
input.onchange = async (event) => {
const file = event.target.files[0];
if (!file) return;
uuid_widget = this.widgets?.find(w => w.name === "uuid");
let filename_widget = this.widgets?.find(w => w.name === "filename");
progressWidget = this.widgets?.find(w => w.name === "upload_progress");
if (!uuid_widget || !filename_widget || !progressWidget) {
alert("Cannot find uuid or filename or progress widget.");
return;
}
filename_widget.value = file.name;
// 查找或创建进度显示
progressWidget.value = "正在准备上传...";
try {
// 使用分块上传避免大文件卡死
await this.uploadFileInChunks(file, uuid_widget.value, file.name, progressWidget);
progressWidget.value = "上传完成!";
} catch (error) {
console.error("Upload failed:", error);
progressWidget.value = `上传失败: ${error.message}`;
alert(`Update failed: ${error.message}`);
}
};
input.click(); // 打开文件选择对话框
});
this.addWidget("button", "重新生成UUID", null, async () => {
uuid_widget = this.widgets?.find(w => w.name === "uuid");
uuid_widget.value = crypto.randomUUID();
});
};
},
});
// 添加分块上传方法到节点原型
app.registerExtension({
name: "EasyToolkit.Misc.Base64Uploader.Upload",
async beforeRegisterNodeDef(nodeType, nodeData, app) {
if (nodeData.name !== "Base64Uploader") return;
nodeType.prototype.uploadFileInChunks = async function(file, uuid, filename, progressWidget) {
const CHUNK_SIZE = 1024 * 1024; // 1MB chunks
const totalChunks = Math.ceil(file.size / CHUNK_SIZE);
// 先初始化上传
progressWidget.value = "正在初始化上传...";
const initResponse = await fetch("/base64_cache_loader/init_upload", {
method: "POST",
headers: { "Content-Type": "application/json" },
body: JSON.stringify({
"uuid": uuid,
"filename": filename,
"total_chunks": totalChunks,
"file_size": file.size
}),
});
const initResult = await initResponse.json();
if (!initResult.success) {
throw new Error(initResult.error || "Initialization failed");
}
// 分块上传文件
for (let chunkIndex = 0; chunkIndex < totalChunks; chunkIndex++) {
const start = chunkIndex * CHUNK_SIZE;
const end = Math.min(start + CHUNK_SIZE, file.size);
const chunk = file.slice(start, end);
progressWidget.value = `上传中... ${Math.round(((chunkIndex + 1) / totalChunks) * 100)}% (${chunkIndex + 1}/${totalChunks})`;
// 给UI一个更新的机会
await new Promise(resolve => setTimeout(resolve, 0));
const formData = new FormData();
formData.append("uuid", uuid);
formData.append("chunk_index", chunkIndex.toString());
formData.append("chunk_data", chunk);
const response = await fetch("/base64_cache_loader/upload_chunk", {
method: "POST",
body: formData,
});
const result = await response.json();
if (!result.success) {
throw new Error(result.error || `Update chunk ${chunkIndex + 1} failed`);
}
}
// 完成上传
progressWidget.value = "正在完成上传...";
const finalizeResponse = await fetch("/base64_cache_loader/finalize_upload", {
method: "POST",
headers: { "Content-Type": "application/json" },
body: JSON.stringify({
"uuid": uuid
}),
});
const finalizeResult = await finalizeResponse.json();
if (!finalizeResult.success) {
throw new Error(finalizeResult.error || "Finalization failed");
}
};
},
});