From f530d7e045399e68d45dddfa00108c14bb23f24d Mon Sep 17 00:00:00 2001 From: HenryDu8133 <813367384@qq.com> Date: Fri, 31 Jul 2026 19:41:26 +0800 Subject: [PATCH] =?UTF-8?q?refactor:=20=E9=87=8D=E6=9E=84=E6=96=87?= =?UTF-8?q?=E4=BB=B6=E5=AD=98=E5=82=A8=E8=B7=AF=E5=BE=84=E5=B9=B6=E6=B8=85?= =?UTF-8?q?=E7=90=86=E5=86=97=E4=BD=99=E4=BB=A3=E7=A0=81?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit - 将项目文件存储从 public/uploads 迁移至项目根目录专用目录 - 更新所有前端页面的路径提示文本与API请求路径 - 移除冗余的列车详情展开收起功能及相关代码 - 重构服务器端文件路径处理逻辑,增强路径访问安全性 - 清理旧注释和未使用的变量与函数 --- CloudServer/public/generator.html | 4 +- CloudServer/public/index.html | 104 +-------------- CloudServer/public/infoboard.html | 50 +------- CloudServer/public/listmanager.html | 6 +- CloudServer/public/music.html | 5 +- CloudServer/public/tempbroadcast.html | 2 +- CloudServer/server.js | 177 ++++++++++---------------- 7 files changed, 79 insertions(+), 269 deletions(-) diff --git a/CloudServer/public/generator.html b/CloudServer/public/generator.html index fc17c79..4f84609 100644 --- a/CloudServer/public/generator.html +++ b/CloudServer/public/generator.html @@ -1251,7 +1251,7 @@ async function loadList() { try { - const res = await fetch('/api/files/content?path=uploads/list.txt'); + const res = await fetch('/api/files/content?path=list.txt'); const data = await res.json(); listData = []; if (data.success && data.content) { @@ -1418,7 +1418,7 @@ method: 'POST', headers: {'Content-Type': 'application/json'}, body: JSON.stringify({ - path: 'uploads/list.txt', + path: 'list.txt', content: content + '\n' }) }); diff --git a/CloudServer/public/index.html b/CloudServer/public/index.html index 13c4cc5..2302866 100644 --- a/CloudServer/public/index.html +++ b/CloudServer/public/index.html @@ -857,7 +857,6 @@ // --- State --- let allFiles = []; let currentPath = 'root'; - let expandedTrains = new Set(); let stationCodeMap = {}; let broadcastingStations = new Set(); @@ -951,101 +950,26 @@ if (!state.activeTrains || state.activeTrains.length === 0) list.innerHTML = '
No active trains
'; state.activeTrains.forEach(tr => { - const isExpanded = expandedTrains.has(tr.trainId); const div = document.createElement('div'); div.className = 'status-item'; - - let detailsHtml = ''; - if (tr.tripLogs && tr.tripLogs.length > 0) { - detailsHtml = tr.tripLogs.map(log => { - const time = new Date(log.time).toLocaleTimeString(); - const stCode = stationCodeMap[log.station] || log.station; - return ` -
- ${time} - ${stCode} - ${log.action} -
- `; - }).join(''); - } else { - detailsHtml = '
No trip history
'; - } - const currentStCode = stationCodeMap[tr.currentStation] || tr.currentStation || '-'; - div.innerHTML = ` -
+ div.innerHTML = ` +
${tr.trainId}
-
${currentStCode}
+
${currentStCode} ${tr.status || '-'}
-
${isExpanded ? ICONS.chevronUp : ICONS.chevronDown}
-
-
-
-
Trip Logs
- ${detailsHtml} -
- +
`; list.appendChild(div); }); - - // Network Statistics - const statsDiv = document.createElement('div'); - statsDiv.className = 'status-item'; - const isStatsExpanded = expandedTrains.has('__STATS__'); - - let statsHtml = '
No data
'; - if (state.travelTimes) { - const keys = Object.keys(state.travelTimes).sort(); - if (keys.length > 0) { - statsHtml = keys.map(key => { - const times = state.travelTimes[key]; - const [from, to] = key.split('|'); - const fromCode = stationCodeMap[from] || from; - const toCode = stationCodeMap[to] || to; - const avg = Math.ceil(times.reduce((a, b) => a + b, 0) / times.length); - return ` -
- ${fromCode} → ${toCode} - ${avg}s - (${times.length}) -
- `; - }).join(''); - } - } - - statsDiv.innerHTML = ` -
-
-
NETWORK STATISTICS
-
-
- -
${isStatsExpanded ? ICONS.chevronUp : ICONS.chevronDown}
-
-
-
-
- ROUTE - AVG - CNT -
- ${statsHtml} -
- `; - list.appendChild(statsDiv); } } - - /* Removed separate Travel Times renderer */ function showRadioStream() { document.getElementById('file-manager-view').style.display = 'none'; @@ -1120,18 +1044,6 @@ }); } - function toggleTrain(id) { - if (expandedTrains.has(id)) expandedTrains.delete(id); - else expandedTrains.add(id); - // We need to re-render to update icons/state, but since state updates often, - // just toggling the DOM element is smoother until next update - const details = document.getElementById(`details-${id}`); - if (details) { - details.classList.toggle('open'); - // Force re-render on next update will respect the Set - } - } - function addLog(logText) { const container = document.getElementById('console-logs'); const div = document.createElement('div'); @@ -1334,14 +1246,6 @@ await fetch(`/api/trains/${encodeURIComponent(id)}`, { method: 'DELETE' }); } - async function deleteStats() { - if (!confirm('Are you sure you want to clear all network travel time statistics?')) return; - const res = await fetch('/api/stats', { method: 'DELETE' }); - const data = await res.json(); - if (data.success) showToast('Success', 'Network statistics cleared'); - else showToast('Error', data.message); - } - function triggerUpload() { if (currentPath === 'config') document.getElementById('upload-config').click(); else if (currentPath === 'general') document.getElementById('upload-general').click(); diff --git a/CloudServer/public/infoboard.html b/CloudServer/public/infoboard.html index 03fb413..a093e8a 100644 --- a/CloudServer/public/infoboard.html +++ b/CloudServer/public/infoboard.html @@ -184,19 +184,6 @@ background: var(--bg-hover); } - .train-details { - display: none; - background: rgba(0, 0, 0, 0.2); - padding: 12px 20px; - font-size: 0.8rem; - color: var(--text-muted); - border-top: 1px solid var(--bg-border); - } - - .train-details.open { - display: block; - } - .trip-log { display: grid; grid-template-columns: 80px 1fr auto; @@ -380,7 +367,6 @@ }; // --- State --- - let expandedTrains = new Set(); let stationCodeMap = {}; let broadcastingStations = new Set(); let messageLog = []; @@ -526,27 +512,8 @@ list.innerHTML = '
暂无活跃列车
'; } else { state.activeTrains.forEach(tr => { - const isExpanded = expandedTrains.has(tr.trainId); const div = document.createElement('div'); div.className = 'status-item train-item'; - div.onclick = () => toggleTrain(tr.trainId); - - let detailsHtml = ''; - if (tr.tripLogs && tr.tripLogs.length > 0) { - detailsHtml = tr.tripLogs.slice().reverse().map(log => { - const time = new Date(log.time).toLocaleTimeString(); - const stCode = stationCodeMap[log.station] || log.station; - return ` -
- ${time} - ${stCode} - ${log.action === 'Arrival' ? '到达' : '出发'} -
- `; - }).join(''); - } else { - detailsHtml = '
暂无运行历史
'; - } const currentStCode = stationCodeMap[tr.currentStation] || tr.currentStation || '-'; const statusColor = tr.status === 'At Station' ? 'var(--success)' : 'var(--warning)'; @@ -556,13 +523,9 @@
${tr.trainId} ${tr.destination || '未知终点'}
-
${currentStCode} ${tr.status === 'At Station' ? '在站' : '运行中'}
+
${currentStCode} ${tr.status === 'At Station' ? '在站' : (tr.status === 'Departed' ? '已发车' : '运行中')}
-
${isExpanded ? ICONS.chevronUp : ICONS.chevronDown}
-
-
-
运行日志 (Trip Logs)
- ${detailsHtml} +
`; @@ -572,15 +535,6 @@ } } - function toggleTrain(id) { - if (expandedTrains.has(id)) expandedTrains.delete(id); - else expandedTrains.add(id); - const details = document.getElementById(`details-${id}`); - if (details) { - details.classList.toggle('open'); - } - } - function updateStationDots() { const dots = document.querySelectorAll('[id^="station-dot-"]'); dots.forEach(dot => { diff --git a/CloudServer/public/listmanager.html b/CloudServer/public/listmanager.html index b983f72..6e0f9ae 100644 --- a/CloudServer/public/listmanager.html +++ b/CloudServer/public/listmanager.html @@ -397,7 +397,7 @@
-
对 uploads/list.txt 进行增删改;每条记录格式:站号==音频文件1,音频文件2,... (支持多个站号用 / 分隔)
+
对 /opt/CC-StationBroadcast/list.txt 进行增删改;每条记录格式:站号==音频文件1,音频文件2,... (支持多个站号用 / 分隔)
@@ -545,7 +545,7 @@ } async function loadList() { - const res = await fetch('/api/files/content?path=uploads/list.txt'); + const res = await fetch('/api/files/content?path=list.txt'); const data = await res.json(); listData = []; if (data.success && data.content) { @@ -704,7 +704,7 @@ const res = await fetch('/api/files/content', { method: 'POST', headers: { 'Content-Type': 'application/json' }, - body: JSON.stringify({ path: 'uploads/list.txt', content: content + '\n' }) + body: JSON.stringify({ path: 'list.txt', content: content + '\n' }) }); const data = await res.json(); if (!data.success) throw new Error(data.message || 'Save failed'); diff --git a/CloudServer/public/music.html b/CloudServer/public/music.html index 560c072..11b1bbb 100644 --- a/CloudServer/public/music.html +++ b/CloudServer/public/music.html @@ -180,7 +180,7 @@ 未选择
- +
@@ -316,7 +316,7 @@ if (tracks.length === 0) { sel.innerHTML = ''; onTrackChange(); - setStatus("没有可用音频(请上传到 uploads/audio/general)"); + setStatus("没有可用音频(请上传到 /opt/CC-StationBroadcast/Audio/general)"); return; } sel.appendChild(new Option("请选择…", "")); @@ -433,4 +433,3 @@ - diff --git a/CloudServer/public/tempbroadcast.html b/CloudServer/public/tempbroadcast.html index c9d7155..976e079 100644 --- a/CloudServer/public/tempbroadcast.html +++ b/CloudServer/public/tempbroadcast.html @@ -206,7 +206,7 @@
- 需要服务端已存在 lsts.wav(建议放在 uploads/audio/general/lsts.wav)。点击“合成”会自动中文 TTS 并拼接生成临时广播,随后可发布到所选站台。 + 需要服务端已存在 lsts.wav(建议放在 /opt/CC-StationBroadcast/Audio/general/lsts.wav)。点击“合成”会自动中文 TTS 并拼接生成临时广播,随后可发布到所选站台。