feat(settings): 支持系统设置按模块独立保存负载

This commit is contained in:
xuans 2026-10-16 18:50:07 +08:00
parent 681ecfc735
commit bfc36d3ad3
2 changed files with 15 additions and 12 deletions

View File

@ -820,20 +820,21 @@ export function useDashboard() {
} }
} }
async function saveSettings() { async function saveSettings(section) {
settingsError.value = ""; settingsError.value = "";
if (!canManageSystemSettings.value) { if (!canManageSystemSettings.value) {
settingsError.value = "只有超级管理员可以保存系统设置"; settingsError.value = "只有超级管理员可以保存系统设置";
return; return;
} }
verificationClock.value = Date.now(); verificationClock.value = Date.now();
if (!dnsReadyToSave.value) { // 只有在保存全部或保存 DNS 配置时才强依赖 DNS API 测试
if ((!section || section === "dns") && !dnsReadyToSave.value) {
settingsError.value = "DNS 服务商配置尚未通过在线测试,请先完成测试"; settingsError.value = "DNS 服务商配置尚未通过在线测试,请先完成测试";
return; return;
} }
settingsSaving.value = true; settingsSaving.value = true;
try { try {
const payload = settingsPayload(settingsForm.value); const payload = settingsPayload(settingsForm.value, section);
const response = await fetchAdmin("/api/v1/settings", { const response = await fetchAdmin("/api/v1/settings", {
method: "PUT", method: "PUT",
headers: { "Content-Type": "application/json" }, headers: { "Content-Type": "application/json" },
@ -842,8 +843,7 @@ export function useDashboard() {
const result = await response.json().catch(() => ({})); const result = await response.json().catch(() => ({}));
if (!response.ok) throw new Error(result.error || "保存系统设置失败"); if (!response.ok) throw new Error(result.error || "保存系统设置失败");
settings.value = result.settings; settings.value = result.settings;
showSettings.value = false; notice.value = result.message || "设置已保存";
notice.value = result.message || "系统设置已保存";
await loadData(); await loadData();
} catch (err) { } catch (err) {
settingsError.value = err.message || "保存系统设置失败"; settingsError.value = err.message || "保存系统设置失败";

View File

@ -19,21 +19,24 @@ const requestFields = {
], ],
}; };
export function settingsPayload(current) { export function settingsPayload(current, targetSection) {
const payload = {}; const payload = {};
for (const [section, fields] of Object.entries(requestFields)) { for (const [section, fields] of Object.entries(requestFields)) {
if (targetSection && targetSection !== section) continue;
const source = current[section] || {}; const source = current[section] || {};
payload[section] = Object.fromEntries( payload[section] = Object.fromEntries(
fields.filter((field) => source[field] !== undefined) fields.filter((field) => source[field] !== undefined)
.map((field) => [field, source[field]]), .map((field) => [field, source[field]]),
); );
} }
const dns = current.dns || {}; if (!targetSection || targetSection === "dns") {
payload.dns = { provider: dns.provider }; const dns = current.dns || {};
if (dns.credential_ref && dns.verification_token) { payload.dns = { provider: dns.provider };
payload.dns.credential_ref = dns.credential_ref; if (dns.credential_ref && dns.verification_token) {
payload.dns.verification_token = dns.verification_token; payload.dns.credential_ref = dns.credential_ref;
payload.dns.test_domain = dns.test_domain; payload.dns.verification_token = dns.verification_token;
payload.dns.test_domain = dns.test_domain;
}
} }
return payload; return payload;
} }