feat(broadcast): 播报系统Tab+API+历史查询+消息分类
This commit is contained in:
@@ -0,0 +1,96 @@
|
||||
<!DOCTYPE html>
|
||||
<html lang="zh-CN">
|
||||
<head>
|
||||
<meta charset="UTF-8">
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1.0">
|
||||
<title>Broadcast History - MoFin</title>
|
||||
<style>
|
||||
*{margin:0;padding:0;box-sizing:border-box}
|
||||
body{font-family:-apple-system,BlinkMacSystemFont,'Segoe UI',sans-serif;background:#0a0a0f;color:#e0e0e0;padding:20px}
|
||||
h1{color:#fff;font-size:1.5em;margin-bottom:16px}
|
||||
.filters{display:flex;gap:8px;margin-bottom:16px;flex-wrap:wrap}
|
||||
.filters select,.filters input{background:#1a1a2e;color:#e0e0e0;border:1px solid #333;padding:6px 12px;border-radius:4px}
|
||||
.filters button{background:#3b82f6;color:#fff;padding:6px 16px;border-radius:4px;border:none;cursor:pointer}
|
||||
.filters button:hover{background:#2563eb}
|
||||
.table{width:100%;border-collapse:collapse;margin-top:12px}
|
||||
th,td{padding:8px 12px;text-align:left;border-bottom:1px solid #333}
|
||||
th{color:#888;font-size:0.85em}
|
||||
tr:hover{background:#1a1a2e}
|
||||
.tag{display:inline-block;padding:2px 8px;border-radius:4px;font-size:0.8em}
|
||||
a{color:#3b82f6;text-decoration:none}
|
||||
a:hover{text-decoration:underline}
|
||||
.back{display:inline-block;margin-bottom:16px;color:#3b82f6}
|
||||
</style>
|
||||
</head>
|
||||
<body>
|
||||
<a href="/" class="back">← Back to Dashboard</a>
|
||||
<h1>Broadcast History</h1>
|
||||
<div class="filters">
|
||||
<input type="date" id="startDate" placeholder="Start Date">
|
||||
<input type="date" id="endDate" placeholder="End Date">
|
||||
<input type="text" id="keyword" placeholder="Keyword..." style="min-width:200px">
|
||||
<select id="filterCat">
|
||||
<option value="">All Types</option>
|
||||
<option value="trading">Trading</option>
|
||||
<option value="system_error">Error</option>
|
||||
<option value="health">Health</option>
|
||||
<option value="market">Market</option>
|
||||
<option value="news">News</option>
|
||||
<option value="strategy">Strategy</option>
|
||||
<option value="general">System</option>
|
||||
</select>
|
||||
<button onclick="searchHistory()">Search</button>
|
||||
</div>
|
||||
<div id="results"></div>
|
||||
<div id="detail-modal" style="display:none" class="fixed inset-0 z-50 flex items-center justify-center bg-black/60" onclick="if(event.target===this)this.style.display='none'">
|
||||
<div style="background:#1a1a2e;border:1px solid #444;border-radius:12px;padding:24px;max-width:700px;max-height:80vh;overflow-y:auto;box-shadow:0 20px 60px rgba(0,0,0,0.5)">
|
||||
<div style="display:flex;justify-content:space-between;align-items:center;margin-bottom:16px">
|
||||
<h3 id="detail-title" style="color:#fff;font-size:1.1em"></h3>
|
||||
<button onclick="document.getElementById('detail-modal').style.display='none'" style="background:none;border:none;color:#888;font-size:20px;cursor:pointer">×</button>
|
||||
</div>
|
||||
<pre id="detail-content" style="color:#ccc;font-size:13px;white-space:pre-wrap;line-height:1.6"></pre>
|
||||
</div>
|
||||
</div>
|
||||
<script>
|
||||
function searchHistory() {
|
||||
var params = new URLSearchParams();
|
||||
var s = document.getElementById('startDate').value;
|
||||
var e = document.getElementById('endDate').value;
|
||||
var k = document.getElementById('keyword').value;
|
||||
var c = document.getElementById('filterCat').value;
|
||||
if (s) params.set('start', s);
|
||||
if (e) params.set('end', e);
|
||||
if (k) params.set('keyword', k);
|
||||
if (c) params.set('category', c);
|
||||
params.set('limit', '200');
|
||||
fetch('/api/broadcast/search?' + params).then(r => r.json()).then(data => {
|
||||
var el = document.getElementById('results');
|
||||
if (!data.length) { el.innerHTML = '<div style="color:#888;padding:20px">No results</div>'; return; }
|
||||
var cat_colors = {trading:'#22c55e',system_error:'#ef4444',health:'#3b82f6',market:'#f59e0b',news:'#8b5cf6',strategy:'#06b6d4',general:'#6b7280'};
|
||||
var cat_labels = {trading:'Trading',system_error:'Error',health:'Health',market:'Market',news:'News',strategy:'Strategy',general:'System'};
|
||||
var h = '<table class="table"><tr><th>Time</th><th>Type</th><th>Title</th><th>Content</th></tr>';
|
||||
data.forEach(m => {
|
||||
var color = cat_colors[m.category]||'#6b7280';
|
||||
var label = cat_labels[m.category]||m.category;
|
||||
var preview = m.content.length>80 ? m.content.slice(0,80)+'...' : m.content;
|
||||
var time = (m.ts||'').slice(0,16).replace('T',' ');
|
||||
h += '<tr onclick="showDetail(\'' + m.content.replace(/'/g,"\\'").replace(/\n/g,"\\n") + '\',\'' + (m.title||'').replace(/'/g,"\\'") + '\')" style="cursor:pointer">';
|
||||
h += '<td style="white-space:nowrap">'+time+'</td>';
|
||||
h += '<td><span class="tag" style="background:'+color+'22;color:'+color+'">'+label+'</span></td>';
|
||||
h += '<td style="font-weight:600;color:#e0e0e0">'+(m.title||'-')+'</td>';
|
||||
h += '<td style="color:#aaa">'+preview+'</td>';
|
||||
h += '</tr>';
|
||||
});
|
||||
h += '</table>';
|
||||
el.innerHTML = h;
|
||||
}).catch(e => { document.getElementById('results').innerHTML = '<div style="color:red">'+e.message+'</div>'; });
|
||||
}
|
||||
function showDetail(content, title) {
|
||||
document.getElementById('detail-title').textContent = title || 'Detail';
|
||||
document.getElementById('detail-content').textContent = content;
|
||||
document.getElementById('detail-modal').style.display = 'flex';
|
||||
}
|
||||
searchHistory();
|
||||
</script>
|
||||
</body>
|
||||
</html>
|
||||
Reference in New Issue
Block a user