diff --git a/public/index.html b/public/index.html index f7f5b7d..8636350 100644 --- a/public/index.html +++ b/public/index.html @@ -479,8 +479,9 @@ -
+
+
diff --git a/public/js/app.js b/public/js/app.js index 7ed7549..e32dac6 100644 --- a/public/js/app.js +++ b/public/js/app.js @@ -75,6 +75,7 @@ routeTargetInput: document.getElementById('routeTargetInput'), btnAddRoute: document.getElementById('btnAddRoute'), latencyRoutesList: document.getElementById('latencyRoutesList'), + btnCancelEditRoute: document.getElementById('btnCancelEditRoute'), detailDiskTotal: document.getElementById('detailDiskTotal'), // Server Details Modal serverDetailModal: document.getElementById('serverDetailModal'), @@ -131,6 +132,7 @@ } let myMap2D = null; + let editingRouteId = null; // ---- Initialize ---- function init() { @@ -163,6 +165,10 @@ }); } + if (dom.btnCancelEditRoute) { + dom.btnCancelEditRoute.onclick = cancelEditRoute; + } + dom.settingsModal.addEventListener('click', (e) => { if (e.target === dom.settingsModal) closeSettings(); }); @@ -1541,11 +1547,40 @@ 目标: ${escapeHtml(route.latency_target)} - +
+ + +
`).join(''); } + window.editRoute = function(id, source_id, source, dest, target) { + editingRouteId = id; + dom.routeSourceSelect.value = source_id; + dom.routeSourceInput.value = source; + dom.routeDestInput.value = dest; + dom.routeTargetInput.value = target; + + dom.btnAddRoute.textContent = '保存修改'; + dom.btnCancelEditRoute.style.display = 'block'; + + // Select the tab just in case (though it's already there) + const tab = Array.from(dom.modalTabs).find(t => t.dataset.tab === 'routes'); + if (tab) tab.click(); + }; + + function cancelEditRoute() { + editingRouteId = null; + dom.routeSourceSelect.value = ""; + dom.routeSourceInput.value = ""; + dom.routeDestInput.value = ""; + dom.routeTargetInput.value = ""; + + dom.btnAddRoute.textContent = '添加线路'; + dom.btnCancelEditRoute.style.display = 'none'; + } + async function addLatencyRoute() { if (!user) { showSiteMessage('请先登录及进行身份验证', 'error'); @@ -1563,21 +1598,24 @@ return; } + const url = editingRouteId ? `/api/latency-routes/${editingRouteId}` : '/api/latency-routes'; + const method = editingRouteId ? 'PUT' : 'POST'; + try { - const response = await fetch('/api/latency-routes', { - method: 'POST', + const response = await fetch(url, { + method, headers: { 'Content-Type': 'application/json' }, body: JSON.stringify({ source_id: parseInt(source_id), latency_source, latency_dest, latency_target }) }); if (response.ok) { - showSiteMessage('线路添加成功', 'success'); - dom.routeSourceInput.value = ''; - dom.routeDestInput.value = ''; - dom.routeTargetInput.value = ''; + showSiteMessage(editingRouteId ? '线路更新成功' : '线路添加成功', 'success'); + cancelEditRoute(); loadLatencyRoutes(); fetchLatency(); } else { + const err = await response.json(); + showSiteMessage(`操作失败: ${err.error}`, 'error'); if (response.status === 401) openLoginModal(); } } catch (err) { diff --git a/server/index.js b/server/index.js index c1db118..29ba3bd 100644 --- a/server/index.js +++ b/server/index.js @@ -892,6 +892,19 @@ app.delete('/api/latency-routes/:id', requireAuth, async (req, res) => { } }); +app.put('/api/latency-routes/:id', requireAuth, async (req, res) => { + const { source_id, latency_source, latency_dest, latency_target } = req.body; + try { + await db.query( + 'UPDATE latency_routes SET source_id = ?, latency_source = ?, latency_dest = ?, latency_target = ? WHERE id = ?', + [source_id, latency_source, latency_dest, latency_target, req.params.id] + ); + res.json({ success: true }); + } catch (err) { + res.status(500).json({ error: 'Failed to update latency route' }); + } +}); + // ==================== Metrics Latency ==================== app.get('/api/metrics/latency', async (req, res) => {