From 2d46729c279a4393a372041267443b2975660b66 Mon Sep 17 00:00:00 2001 From: CN-JS-HuiBai Date: Sat, 4 Apr 2026 19:25:39 +0800 Subject: [PATCH] =?UTF-8?q?=E4=BC=98=E5=8C=96=E7=99=BD=E8=89=B2=E4=B8=BB?= =?UTF-8?q?=E9=A2=98=E6=B8=B2=E6=9F=93=E9=80=BB=E8=BE=91?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- public/index.html | 11 ++++++++++- public/js/app.js | 22 +++++++++++++++++---- server/index.js | 49 ++++++++++++++++++++++++++++++++++++++++++++--- 3 files changed, 74 insertions(+), 8 deletions(-) diff --git a/public/index.html b/public/index.html index 2710de2..267c7e7 100644 --- a/public/index.html +++ b/public/index.html @@ -13,9 +13,18 @@ // Prevent theme flicker (function() { const savedTheme = localStorage.getItem('theme'); - if (savedTheme === 'light') { + const settings = window.SITE_SETTINGS || {}; + const defaultTheme = settings.default_theme || 'dark'; + const theme = savedTheme || defaultTheme; + + if (theme === 'light') { document.documentElement.classList.add('light-theme'); } + + // Also apply title if available to prevent flicker + if (settings.page_name) { + document.title = settings.page_name; + } })(); diff --git a/public/js/app.js b/public/js/app.js index 3da1588..b583a56 100644 --- a/public/js/app.js +++ b/public/js/app.js @@ -128,12 +128,24 @@ // Start data fetching fetchMetrics(); fetchNetworkHistory(); + + // Site settings + if (window.SITE_SETTINGS) { + applySiteSettings(window.SITE_SETTINGS); + // Actual theme class already applied in head, just update icons and inputs + const savedTheme = localStorage.getItem('theme'); + const currentTheme = savedTheme || window.SITE_SETTINGS.default_theme || 'dark'; + updateThemeIcons(currentTheme); + + // Still populate inputs + dom.pageNameInput.value = window.SITE_SETTINGS.page_name || ''; + dom.siteTitleInput.value = window.SITE_SETTINGS.title || ''; + dom.logoUrlInput.value = window.SITE_SETTINGS.logo_url || ''; + dom.defaultThemeInput.value = window.SITE_SETTINGS.default_theme || 'dark'; + } + loadSiteSettings(); - // Initial icon check based on early head script - const currentTheme = document.documentElement.classList.contains('light-theme') ? 'light' : 'dark'; - updateThemeIcons(currentTheme); - setInterval(fetchMetrics, REFRESH_INTERVAL); setInterval(fetchNetworkHistory, NETWORK_HISTORY_INTERVAL); } @@ -444,6 +456,8 @@ const response = await fetch('/api/settings'); const settings = await response.json(); + window.SITE_SETTINGS = settings; // Cache it globally + // Update inputs dom.pageNameInput.value = settings.page_name || ''; dom.siteTitleInput.value = settings.title || ''; diff --git a/server/index.js b/server/index.js index 7793642..eca9a37 100644 --- a/server/index.js +++ b/server/index.js @@ -276,7 +276,49 @@ app.use(async (req, res, next) => { next(); }); -app.use(express.static(path.join(__dirname, '..', 'public'))); +// Helper to serve index.html with injected settings +const serveIndex = async (req, res) => { + try { + const indexPath = path.join(__dirname, '..', 'public', 'index.html'); + if (!fs.existsSync(indexPath)) return res.status(404).send('Not found'); + + let html = fs.readFileSync(indexPath, 'utf8'); + + // Fetch settings + let settings = { + page_name: '数据可视化展示大屏', + title: '数据可视化展示大屏', + logo_url: null, + default_theme: 'dark' + }; + + if (isDbInitialized) { + try { + const [rows] = await db.query('SELECT * FROM site_settings WHERE id = 1'); + if (rows.length > 0) settings = rows[0]; + } catch (e) { + // DB not ready or table missing + } + } + + // Inject settings + const settingsJson = JSON.stringify(settings); + const injection = ``; + + // Replace with + injection + html = html.replace('', '' + injection); + + res.send(html); + } catch (err) { + console.error('Error serving index:', err); + res.status(500).send('Internal Server Error'); + } +}; + +app.get('/', serveIndex); +app.get('/index.html', serveIndex); + +app.use(express.static(path.join(__dirname, '..', 'public'), { index: false })); // ==================== Prometheus Source CRUD ==================== @@ -553,8 +595,9 @@ app.get('/api/metrics/cpu-history', async (req, res) => { }); // SPA fallback -app.get('*', (req, res) => { - res.sendFile(path.join(__dirname, '..', 'public', 'index.html')); +app.get('*', (req, res, next) => { + if (req.path.startsWith('/api/') || req.path.includes('.')) return next(); + serveIndex(req, res); });