From 7c1abb77bd0e14bacfc8a8264a40637b4afed20b Mon Sep 17 00:00:00 2001 From: Youzini-afk <13153778771cx@gmail.com> Date: Fri, 27 Mar 2026 15:54:21 +0800 Subject: [PATCH] =?UTF-8?q?feat:=20=E4=B8=80=E9=94=AE=E5=AF=BC=E5=87=BA/?= =?UTF-8?q?=E5=AF=BC=E5=85=A5=E5=85=A8=E9=83=A86=E4=B8=AA=E4=BB=BB?= =?UTF-8?q?=E5=8A=A1=E9=A2=84=E8=AE=BE?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- panel.html | 6 ++++ panel.js | 96 ++++++++++++++++++++++++++++++++++++++++++++++++++++++ style.css | 13 ++++++++ 3 files changed, 115 insertions(+) diff --git a/panel.html b/panel.html index f2b481b..f6420b6 100644 --- a/panel.html +++ b/panel.html @@ -1433,6 +1433,12 @@ accept=".json,application/json" hidden /> +
{ + const file = importAllInput.files?.[0]; + if (!file) return; + try { + const text = await file.text(); + const parsed = JSON.parse(text); + if (parsed?.format !== "st-bme-all-task-profiles" || !parsed?.profiles) { + throw new Error("文件格式不正确,请选择「导出全部」生成的文件"); + } + const settings = _getSettings?.() || {}; + let mergedProfiles = settings.taskProfiles || {}; + let importedCount = 0; + for (const [taskType, entry] of Object.entries(parsed.profiles)) { + try { + const imported = parseImportedTaskProfile( + mergedProfiles, + entry, + taskType, + ); + mergedProfiles = imported.taskProfiles; + importedCount++; + } catch (innerError) { + console.warn(`[ST-BME] 跳过导入任务 ${taskType}:`, innerError); + } + } + if (importedCount === 0) { + toastr.warning("没有成功导入任何预设", "ST-BME"); + return; + } + _patchTaskProfiles(mergedProfiles); + toastr.success(`已导入 ${importedCount} 个任务预设`, "ST-BME"); + } catch (error) { + console.error("[ST-BME] 导入全部预设失败:", error); + toastr.error(`导入全部预设失败: ${error?.message || error}`, "ST-BME"); + } finally { + importAllInput.value = ""; + } + }); + importAllInput.dataset.bmeBound = "true"; + } } function _handleTaskProfileWorkspaceInput(event) { @@ -2025,6 +2068,12 @@ async function _handleTaskProfileWorkspaceClick(event) { case "import-profile": document.getElementById("bme-task-profile-import")?.click(); return; + case "export-all-profiles": + _downloadAllTaskProfiles(state.taskProfiles); + return; + case "import-all-profiles": + document.getElementById("bme-task-profile-import-all")?.click(); + return; case "restore-default-profile": { const confirmed = window.confirm( "这会重建当前任务的默认预设,并切换到默认预设。是否继续?", @@ -2100,6 +2149,13 @@ function _renderTaskProfileWorkspace(state) { `, ) .join("")} + + +
@@ -3555,6 +3611,46 @@ function _sanitizeFileName(fileName = "profile.json") { return String(fileName || "profile.json").replace(/[<>:"/\\|?*\x00-\x1f]/g, "-"); } +function _downloadAllTaskProfiles(taskProfiles) { + try { + const taskTypes = getTaskTypeOptions().map((t) => t.id); + const profiles = {}; + for (const taskType of taskTypes) { + try { + const exported = serializeTaskProfile(taskProfiles, taskType); + profiles[taskType] = exported; + } catch { + // skip missing + } + } + if (Object.keys(profiles).length === 0) { + toastr.warning("没有可导出的预设", "ST-BME"); + return; + } + const payload = { + format: "st-bme-all-task-profiles", + version: 1, + exportedAt: new Date().toISOString(), + profiles, + }; + const blob = new Blob([JSON.stringify(payload, null, 2)], { + type: "application/json", + }); + const url = URL.createObjectURL(blob); + const anchor = document.createElement("a"); + anchor.href = url; + anchor.download = _sanitizeFileName("st-bme-all-profiles.json"); + document.body.appendChild(anchor); + anchor.click(); + anchor.remove(); + URL.revokeObjectURL(url); + toastr.success(`已导出 ${Object.keys(profiles).length} 个任务预设`, "ST-BME"); + } catch (error) { + console.error("[ST-BME] 导出全部预设失败:", error); + toastr.error(`导出全部预设失败: ${error?.message || error}`, "ST-BME"); + } +} + function _cloneJson(value) { return JSON.parse(JSON.stringify(value ?? null)); } diff --git a/style.css b/style.css index eee36df..784db0f 100644 --- a/style.css +++ b/style.css @@ -1377,6 +1377,19 @@ display: flex; gap: 8px; flex-wrap: wrap; + align-items: center; +} + +.bme-bulk-profile-btn { + font-size: 12px; + padding: 0 10px; + min-height: 28px; + opacity: 0.72; + transition: opacity 0.15s; +} + +.bme-bulk-profile-btn:hover { + opacity: 1; } .bme-task-type-btn,