上传模型时显示全屏进度

This commit is contained in:
zhangshun
2026-07-08 18:27:51 +08:00
parent 025835c5b3
commit 0665d7a008
2 changed files with 140 additions and 3 deletions

View File

@@ -95,6 +95,74 @@
opacity: 0.72; opacity: 0.72;
} }
.upload-progress-overlay {
position: fixed;
inset: 0;
z-index: 100000;
display: grid;
place-items: center;
padding: 24px;
background: rgba(15, 23, 42, 0.58);
}
.upload-progress-overlay[hidden] {
display: none;
}
.upload-progress-panel {
width: min(460px, 100%);
display: grid;
gap: 12px;
padding: 22px 24px;
border: 1px solid #dbe5ec;
border-radius: 8px;
background: #ffffff;
box-shadow: 0 18px 48px rgba(15, 23, 42, 0.24);
}
.upload-progress-title {
color: #1c2733;
font-size: 18px;
font-weight: 700;
}
.upload-progress-message {
color: #405469;
font-size: 14px;
line-height: 1.5;
word-break: break-all;
}
.upload-progress-track {
height: 10px;
overflow: hidden;
border-radius: 999px;
background: #e8eef3;
}
.upload-progress-bar {
width: 0;
height: 100%;
border-radius: inherit;
background: #1f6f8b;
transition: width 180ms ease;
}
.upload-progress-meta {
color: #27613a;
font-size: 13px;
font-weight: 700;
}
.upload-progress-file {
max-height: 48px;
overflow: auto;
color: #647586;
font-size: 12px;
line-height: 1.4;
word-break: break-all;
}
.upload-target-path { .upload-target-path {
display: grid; display: grid;
grid-template-columns: 64px minmax(0, 1fr); grid-template-columns: 64px minmax(0, 1fr);

View File

@@ -529,10 +529,19 @@ async function openUploadModelDialog() {
model: String(form.get("model") ?? "") model: String(form.get("model") ?? "")
}; };
let completedCount = 0; let completedCount = 0;
const totalCount = state.files.length;
setUploadDialogBusy(state, true); setUploadDialogBusy(state, true);
showUploadProgressOverlay(totalCount);
try { try {
for (const [index, file] of state.files.entries()) { for (const [index, file] of state.files.entries()) {
updateUploadStatus(`正在上传 ${index + 1}/${state.files.length}${file.name}`); const uploadingMessage = `正在上传 ${index + 1}/${totalCount}${file.name}`;
updateUploadStatus(uploadingMessage);
updateUploadProgressOverlay({
total: totalCount,
completed: completedCount,
message: uploadingMessage,
fileName: file.name
});
await waitForUploadStatusPaint(); await waitForUploadStatusPaint();
await uploadModelToBackend({ await uploadModelToBackend({
file, file,
@@ -544,12 +553,20 @@ async function openUploadModelDialog() {
properties properties
}); });
completedCount += 1; completedCount += 1;
updateUploadStatus(`已完成 ${completedCount}/${state.files.length}`); const completedMessage = `已完成 ${completedCount}/${totalCount}`;
updateUploadStatus(completedMessage);
updateUploadProgressOverlay({
total: totalCount,
completed: completedCount,
message: completedMessage,
fileName: file.name
});
} }
} catch (error) { } catch (error) {
updateUploadStatus(`上传失败,已完成 ${completedCount}/${state.files.length},请处理后重试。`); updateUploadStatus(`上传失败,已完成 ${completedCount}/${totalCount},请处理后重试。`);
throw error; throw error;
} finally { } finally {
hideUploadProgressOverlay();
if (completedCount < state.files.length) { if (completedCount < state.files.length) {
setUploadDialogBusy(state, false); setUploadDialogBusy(state, false);
} }
@@ -704,6 +721,58 @@ function waitForUploadStatusPaint() {
}); });
} }
function showUploadProgressOverlay(total: number) {
let overlay = document.querySelector<HTMLElement>("#modelUploadProgressOverlay");
if (!overlay) {
overlay = document.createElement("div");
overlay.id = "modelUploadProgressOverlay";
overlay.className = "upload-progress-overlay";
overlay.setAttribute("role", "status");
overlay.setAttribute("aria-live", "polite");
overlay.innerHTML = `
<div class="upload-progress-panel">
<div class="upload-progress-title">模型上传中</div>
<div id="modelUploadProgressMessage" class="upload-progress-message">正在准备上传...</div>
<div class="upload-progress-track">
<div id="modelUploadProgressBar" class="upload-progress-bar"></div>
</div>
<div id="modelUploadProgressMeta" class="upload-progress-meta">0/${total}</div>
<div id="modelUploadProgressFile" class="upload-progress-file"></div>
</div>
`;
document.body.appendChild(overlay);
}
overlay.hidden = false;
updateUploadProgressOverlay({
total,
completed: 0,
message: "正在准备上传...",
fileName: ""
});
}
function updateUploadProgressOverlay(options: {
total: number;
completed: number;
message: string;
fileName: string;
}) {
const message = document.querySelector<HTMLElement>("#modelUploadProgressMessage");
const meta = document.querySelector<HTMLElement>("#modelUploadProgressMeta");
const file = document.querySelector<HTMLElement>("#modelUploadProgressFile");
const bar = document.querySelector<HTMLElement>("#modelUploadProgressBar");
const percent = options.total > 0 ? Math.round((options.completed / options.total) * 100) : 0;
if (message) message.textContent = options.message;
if (meta) meta.textContent = `${options.completed}/${options.total}`;
if (file) file.textContent = options.fileName;
if (bar) bar.style.width = `${percent}%`;
}
function hideUploadProgressOverlay() {
const overlay = document.querySelector<HTMLElement>("#modelUploadProgressOverlay");
if (overlay) overlay.hidden = true;
}
function setUploadDialogBusy(state: UploadFormState, busy: boolean) { function setUploadDialogBusy(state: UploadFormState, busy: boolean) {
const form = document.querySelector<HTMLFormElement>("#modelUploadPopupForm"); const form = document.querySelector<HTMLFormElement>("#modelUploadPopupForm");
if (!form) return; if (!form) return;