修复无法保存配置的问题
This commit is contained in:
@@ -1813,22 +1813,17 @@
|
|||||||
|
|
||||||
const settings = {
|
const settings = {
|
||||||
page_name: dom.pageNameInput.value.trim(),
|
page_name: dom.pageNameInput.value.trim(),
|
||||||
title: dom.siteTitleInput.value.trim(),
|
title: dom.siteTitleInput ? dom.siteTitleInput.value.trim() : dom.pageNameInput.value.trim(),
|
||||||
logo_url: dom.logoUrlInput.value.trim(),
|
logo_url: dom.logoUrlInput ? dom.logoUrlInput.value.trim() : '',
|
||||||
default_theme: dom.defaultThemeInput.value,
|
|
||||||
show_95_bandwidth: dom.show95BandwidthInput.value === "1" ? 1 : 0,
|
|
||||||
p95_type: dom.p95TypeSelect.value,
|
|
||||||
ps_filing: dom.psFilingInput ? dom.psFilingInput.value : '',
|
|
||||||
icp_filing: dom.icpFilingInput ? dom.icpFilingInput.value : '',
|
|
||||||
logo_url_dark: dom.logoUrlDarkInput ? dom.logoUrlDarkInput.value.trim() : '',
|
logo_url_dark: dom.logoUrlDarkInput ? dom.logoUrlDarkInput.value.trim() : '',
|
||||||
favicon_url: dom.faviconUrlInput ? dom.faviconUrlInput.value.trim() : ''
|
favicon_url: dom.faviconUrlInput ? dom.faviconUrlInput.value.trim() : '',
|
||||||
|
default_theme: dom.defaultThemeInput ? dom.defaultThemeInput.value : 'dark',
|
||||||
|
show_95_bandwidth: dom.show95BandwidthInput ? (dom.show95BandwidthInput.value === "1") : false,
|
||||||
|
p95_type: dom.p95TypeSelect ? dom.p95TypeSelect.value : 'tx',
|
||||||
|
ps_filing: dom.psFilingInput ? dom.psFilingInput.value.trim() : '',
|
||||||
|
icp_filing: dom.icpFilingInput ? dom.icpFilingInput.value.trim() : ''
|
||||||
};
|
};
|
||||||
|
|
||||||
// If user sets default to auto, we should clear their manual override or set it to auto
|
|
||||||
if (settings.default_theme === 'auto') {
|
|
||||||
localStorage.setItem('theme', 'auto');
|
|
||||||
}
|
|
||||||
|
|
||||||
dom.btnSaveSiteSettings.disabled = true;
|
dom.btnSaveSiteSettings.disabled = true;
|
||||||
dom.btnSaveSiteSettings.textContent = '保存中...';
|
dom.btnSaveSiteSettings.textContent = '保存中...';
|
||||||
|
|
||||||
@@ -1841,17 +1836,20 @@
|
|||||||
|
|
||||||
if (response.ok) {
|
if (response.ok) {
|
||||||
showSiteMessage('设置保存成功', 'success');
|
showSiteMessage('设置保存成功', 'success');
|
||||||
applySiteSettings(settings);
|
// Update global object and UI immediately
|
||||||
|
window.SITE_SETTINGS = { ...window.SITE_SETTINGS, ...settings };
|
||||||
|
applySiteSettings(window.SITE_SETTINGS);
|
||||||
} else {
|
} else {
|
||||||
const err = await response.json();
|
const err = await response.json();
|
||||||
showSiteMessage(`保存失败: ${err.error}`, 'error');
|
showSiteMessage(`保存失败: ${err.error || '未知错误'}`, 'error');
|
||||||
if (response.status === 401) openLoginModal();
|
if (response.status === 401) openLoginModal();
|
||||||
}
|
}
|
||||||
} catch (err) {
|
} catch (err) {
|
||||||
showSiteMessage(`保存失败: ${err.message}`, 'error');
|
showSiteMessage(`保存失败: ${err.message}`, 'error');
|
||||||
|
console.error('Save settings error:', err);
|
||||||
} finally {
|
} finally {
|
||||||
dom.btnSaveSiteSettings.disabled = false;
|
dom.btnSaveSiteSettings.disabled = false;
|
||||||
dom.btnSaveSiteSettings.textContent = '保存基础设置';
|
dom.btnSaveSiteSettings.textContent = '保存设置';
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -57,58 +57,41 @@ async function checkAndFixDatabase() {
|
|||||||
// Check for new columns in site_settings
|
// Check for new columns in site_settings
|
||||||
const [columns] = await db.query("SHOW COLUMNS FROM site_settings");
|
const [columns] = await db.query("SHOW COLUMNS FROM site_settings");
|
||||||
const columnNames = columns.map(c => c.Field);
|
const columnNames = columns.map(c => c.Field);
|
||||||
if (!columnNames.includes('show_95_bandwidth')) {
|
const addColumn = async (columnName, sql) => {
|
||||||
console.log(`[Database Integrity] ⚠️ Missing column 'show_95_bandwidth' in 'site_settings'. Adding it...`);
|
if (!columnNames.includes(columnName)) {
|
||||||
await db.query("ALTER TABLE site_settings ADD COLUMN show_95_bandwidth TINYINT(1) DEFAULT 0 AFTER default_theme");
|
try {
|
||||||
console.log(`[Database Integrity] ✅ Column 'show_95_bandwidth' added.`);
|
console.log(`[Database Integrity] ⚠️ Missing column '${columnName}' in 'site_settings'. Adding it...`);
|
||||||
}
|
await db.query(sql);
|
||||||
if (!columnNames.includes('p95_type')) {
|
console.log(`[Database Integrity] ✅ Column '${columnName}' added.`);
|
||||||
console.log(`[Database Integrity] ⚠️ Missing column 'p95_type' in 'site_settings'. Adding it...`);
|
} catch (err) {
|
||||||
await db.query("ALTER TABLE site_settings ADD COLUMN p95_type VARCHAR(20) DEFAULT 'tx' AFTER show_95_bandwidth");
|
console.error(`[Database Integrity] ❌ Failed to add column '${columnName}':`, err.message);
|
||||||
console.log(`[Database Integrity] ✅ Column 'p95_type' added.`);
|
// Try without AFTER if it exists
|
||||||
}
|
if (sql.includes('AFTER')) {
|
||||||
if (!columnNames.includes('blackbox_source_id')) {
|
try {
|
||||||
console.log(`[Database Integrity] ⚠️ Missing column 'blackbox_source_id' in 'site_settings'. Adding it...`);
|
const fallback = sql.split(' AFTER')[0];
|
||||||
await db.query("ALTER TABLE site_settings ADD COLUMN blackbox_source_id INT AFTER p95_type");
|
console.log(`[Database Integrity] 🔄 Retrying column '${columnName}' WITHOUT 'AFTER'...`);
|
||||||
console.log(`[Database Integrity] ✅ Column 'blackbox_source_id' added.`);
|
await db.query(fallback);
|
||||||
}
|
console.log(`[Database Integrity] ✅ Column '${columnName}' added via fallback.`);
|
||||||
if (!columnNames.includes('latency_source')) {
|
} catch (err2) {
|
||||||
console.log(`[Database Integrity] ⚠️ Missing column 'latency_source' in 'site_settings'. Adding it...`);
|
console.error(`[Database Integrity] ❌ Fallback also failed:`, err2.message);
|
||||||
await db.query("ALTER TABLE site_settings ADD COLUMN latency_source VARCHAR(100) AFTER blackbox_source_id");
|
}
|
||||||
console.log(`[Database Integrity] ✅ Column 'latency_source' added.`);
|
}
|
||||||
}
|
}
|
||||||
if (!columnNames.includes('latency_dest')) {
|
}
|
||||||
console.log(`[Database Integrity] ⚠️ Missing column 'latency_dest' in 'site_settings'. Adding it...`);
|
};
|
||||||
await db.query("ALTER TABLE site_settings ADD COLUMN latency_dest VARCHAR(100) AFTER latency_source");
|
|
||||||
console.log(`[Database Integrity] ✅ Column 'latency_dest' added.`);
|
await addColumn('show_95_bandwidth', "ALTER TABLE site_settings ADD COLUMN show_95_bandwidth TINYINT(1) DEFAULT 0 AFTER default_theme");
|
||||||
}
|
await addColumn('p95_type', "ALTER TABLE site_settings ADD COLUMN p95_type VARCHAR(20) DEFAULT 'tx' AFTER show_95_bandwidth");
|
||||||
if (!columnNames.includes('latency_target')) {
|
await addColumn('blackbox_source_id', "ALTER TABLE site_settings ADD COLUMN blackbox_source_id INT AFTER p95_type");
|
||||||
console.log(`[Database Integrity] ⚠️ Missing column 'latency_target' in 'site_settings'. Adding it...`);
|
await addColumn('latency_source', "ALTER TABLE site_settings ADD COLUMN latency_source VARCHAR(100) AFTER blackbox_source_id");
|
||||||
await db.query("ALTER TABLE site_settings ADD COLUMN latency_target VARCHAR(255) AFTER latency_dest");
|
await addColumn('latency_dest', "ALTER TABLE site_settings ADD COLUMN latency_dest VARCHAR(100) AFTER latency_source");
|
||||||
console.log(`[Database Integrity] ✅ Column 'latency_target' added.`);
|
await addColumn('latency_target', "ALTER TABLE site_settings ADD COLUMN latency_target VARCHAR(255) AFTER latency_dest");
|
||||||
}
|
await addColumn('icp_filing', "ALTER TABLE site_settings ADD COLUMN icp_filing VARCHAR(255) AFTER latency_target");
|
||||||
if (!columnNames.includes('icp_filing')) {
|
await addColumn('ps_filing', "ALTER TABLE site_settings ADD COLUMN ps_filing VARCHAR(255) AFTER icp_filing");
|
||||||
console.log(`[Database Integrity] ⚠️ Missing column 'icp_filing' in 'site_settings'. Adding it...`);
|
await addColumn('logo_url_dark', "ALTER TABLE site_settings ADD COLUMN logo_url_dark TEXT AFTER logo_url");
|
||||||
await db.query("ALTER TABLE site_settings ADD COLUMN icp_filing VARCHAR(255) AFTER latency_target");
|
await addColumn('favicon_url', "ALTER TABLE site_settings ADD COLUMN favicon_url TEXT AFTER logo_url_dark");
|
||||||
console.log(`[Database Integrity] ✅ Column 'icp_filing' added.`);
|
|
||||||
}
|
|
||||||
if (!columnNames.includes('ps_filing')) {
|
|
||||||
console.log(`[Database Integrity] ⚠️ Missing column 'ps_filing' in 'site_settings'. Adding it...`);
|
|
||||||
await db.query("ALTER TABLE site_settings ADD COLUMN ps_filing VARCHAR(255) AFTER icp_filing");
|
|
||||||
console.log(`[Database Integrity] ✅ Column 'ps_filing' added.`);
|
|
||||||
}
|
|
||||||
if (!columnNames.includes('logo_url_dark')) {
|
|
||||||
console.log(`[Database Integrity] ⚠️ Missing column 'logo_url_dark' in 'site_settings'. Adding it...`);
|
|
||||||
await db.query("ALTER TABLE site_settings ADD COLUMN logo_url_dark TEXT AFTER logo_url");
|
|
||||||
console.log(`[Database Integrity] ✅ Column 'logo_url_dark' added.`);
|
|
||||||
}
|
|
||||||
if (!columnNames.includes('favicon_url')) {
|
|
||||||
console.log(`[Database Integrity] ⚠️ Missing column 'favicon_url' in 'site_settings'. Adding it...`);
|
|
||||||
await db.query("ALTER TABLE site_settings ADD COLUMN favicon_url TEXT AFTER logo_url_dark");
|
|
||||||
console.log(`[Database Integrity] ✅ Column 'favicon_url' added.`);
|
|
||||||
}
|
|
||||||
} catch (err) {
|
} catch (err) {
|
||||||
console.error('[Database Integrity] ❌ Error checking integrity:', err.message);
|
console.error('[Database Integrity] ❌ Overall site_settings check error:', err.message);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -588,34 +588,67 @@ app.get('/api/settings', async (req, res) => {
|
|||||||
|
|
||||||
// Update site settings
|
// Update site settings
|
||||||
app.post('/api/settings', requireAuth, async (req, res) => {
|
app.post('/api/settings', requireAuth, async (req, res) => {
|
||||||
const { page_name, title, logo_url, logo_url_dark, favicon_url, default_theme, show_95_bandwidth, p95_type, blackbox_source_id, latency_source, latency_dest, latency_target, icp_filing, ps_filing } = req.body;
|
try {
|
||||||
try {
|
// 1. Fetch current settings first to preserve fields not sent by the UI
|
||||||
await db.query(
|
const [rows] = await db.query('SELECT * FROM site_settings WHERE id = 1');
|
||||||
`INSERT INTO site_settings (id, page_name, title, logo_url, logo_url_dark, favicon_url, default_theme, show_95_bandwidth, p95_type, blackbox_source_id, latency_source, latency_dest, latency_target, icp_filing, ps_filing)
|
let current = rows.length > 0 ? rows[0] : {};
|
||||||
VALUES (1, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?)
|
|
||||||
ON DUPLICATE KEY UPDATE
|
// 2. Destructure fields from body
|
||||||
page_name = VALUES(page_name),
|
const {
|
||||||
title = VALUES(title),
|
page_name, title, logo_url, logo_url_dark, favicon_url,
|
||||||
logo_url = VALUES(logo_url),
|
default_theme, show_95_bandwidth, p95_type,
|
||||||
logo_url_dark = VALUES(logo_url_dark),
|
icp_filing, ps_filing
|
||||||
favicon_url = VALUES(favicon_url),
|
} = req.body;
|
||||||
default_theme = VALUES(default_theme),
|
|
||||||
show_95_bandwidth = VALUES(show_95_bandwidth),
|
// 3. Prepare parameters, prioritizing body but falling back to current
|
||||||
p95_type = VALUES(p95_type),
|
const settings = {
|
||||||
blackbox_source_id = VALUES(blackbox_source_id),
|
page_name: page_name !== undefined ? page_name : (current.page_name || '数据可视化展示大屏'),
|
||||||
latency_source = VALUES(latency_source),
|
title: title !== undefined ? title : (current.title || '数据可视化展示大屏'),
|
||||||
latency_dest = VALUES(latency_dest),
|
logo_url: logo_url !== undefined ? logo_url : (current.logo_url || null),
|
||||||
latency_target = VALUES(latency_target),
|
logo_url_dark: logo_url_dark !== undefined ? logo_url_dark : (current.logo_url_dark || null),
|
||||||
icp_filing = VALUES(icp_filing),
|
favicon_url: favicon_url !== undefined ? favicon_url : (current.favicon_url || null),
|
||||||
ps_filing = VALUES(ps_filing)`,
|
default_theme: default_theme !== undefined ? default_theme : (current.default_theme || 'dark'),
|
||||||
[
|
show_95_bandwidth: show_95_bandwidth !== undefined ? (show_95_bandwidth ? 1 : 0) : (current.show_95_bandwidth || 0),
|
||||||
page_name, title, logo_url, logo_url_dark, favicon_url, default_theme,
|
p95_type: p95_type !== undefined ? p95_type : (current.p95_type || 'tx'),
|
||||||
show_95_bandwidth ? 1 : 0, p95_type || 'tx',
|
blackbox_source_id: current.blackbox_source_id || null, // UI doesn't send this
|
||||||
blackbox_source_id || null, latency_source || null,
|
latency_source: current.latency_source || null, // UI doesn't send this
|
||||||
latency_dest || null, latency_target || null,
|
latency_dest: current.latency_dest || null, // UI doesn't send this
|
||||||
icp_filing || null, ps_filing || null
|
latency_target: current.latency_target || null, // UI doesn't send this
|
||||||
]
|
icp_filing: icp_filing !== undefined ? icp_filing : (current.icp_filing || null),
|
||||||
);
|
ps_filing: ps_filing !== undefined ? ps_filing : (current.ps_filing || null)
|
||||||
|
};
|
||||||
|
|
||||||
|
// 4. Update database
|
||||||
|
await db.query(
|
||||||
|
`INSERT INTO site_settings (
|
||||||
|
id, page_name, title, logo_url, logo_url_dark, favicon_url,
|
||||||
|
default_theme, show_95_bandwidth, p95_type,
|
||||||
|
blackbox_source_id, latency_source, latency_dest, latency_target,
|
||||||
|
icp_filing, ps_filing
|
||||||
|
) VALUES (1, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?)
|
||||||
|
ON DUPLICATE KEY UPDATE
|
||||||
|
page_name = VALUES(page_name),
|
||||||
|
title = VALUES(title),
|
||||||
|
logo_url = VALUES(logo_url),
|
||||||
|
logo_url_dark = VALUES(logo_url_dark),
|
||||||
|
favicon_url = VALUES(favicon_url),
|
||||||
|
default_theme = VALUES(default_theme),
|
||||||
|
show_95_bandwidth = VALUES(show_95_bandwidth),
|
||||||
|
p95_type = VALUES(p95_type),
|
||||||
|
blackbox_source_id = VALUES(blackbox_source_id),
|
||||||
|
latency_source = VALUES(latency_source),
|
||||||
|
latency_dest = VALUES(latency_dest),
|
||||||
|
latency_target = VALUES(latency_target),
|
||||||
|
icp_filing = VALUES(icp_filing),
|
||||||
|
ps_filing = VALUES(ps_filing)`,
|
||||||
|
[
|
||||||
|
settings.page_name, settings.title, settings.logo_url, settings.logo_url_dark, settings.favicon_url,
|
||||||
|
settings.default_theme, settings.show_95_bandwidth, settings.p95_type,
|
||||||
|
settings.blackbox_source_id, settings.latency_source, settings.latency_dest, settings.latency_target,
|
||||||
|
settings.icp_filing, settings.ps_filing
|
||||||
|
]
|
||||||
|
);
|
||||||
|
|
||||||
res.json({ success: true });
|
res.json({ success: true });
|
||||||
} catch (err) {
|
} catch (err) {
|
||||||
console.error('Error updating settings:', err);
|
console.error('Error updating settings:', err);
|
||||||
|
|||||||
Reference in New Issue
Block a user