This commit is contained in:
sjk
2026-01-16 22:06:46 +08:00
parent 816bf29a2a
commit 3d402639da
114 changed files with 10763 additions and 419 deletions

View File

@@ -414,6 +414,10 @@
<span class="menu-icon">🔗</span>
<span>链接管理</span>
</div>
<div class="menu-item" onclick="switchPage('database')">
<span class="menu-icon">💾</span>
<span>数据库管理</span>
</div>
<div class="menu-item" onclick="switchPage('browser')">
<span class="menu-icon">🌐</span>
<span>浏览器测试</span>
@@ -543,6 +547,111 @@
</div>
</div>
</div>
<!-- 数据库管理页面 -->
<div id="database" class="page-content">
<!-- 统计卡片 -->
<div class="stats-grid" style="margin-bottom: 24px;">
<div class="stat-card">
<div class="stat-label">总站点数</div>
<div class="stat-value" id="dbTotalSites">-</div>
</div>
<div class="stat-card">
<div class="stat-label">总点击数</div>
<div class="stat-value" id="dbTotalClicks">-</div>
</div>
<div class="stat-card">
<div class="stat-label">总回复数</div>
<div class="stat-value" id="dbTotalReplies">-</div>
</div>
<div class="stat-card">
<div class="stat-label">成功互动</div>
<div class="stat-value" id="dbSuccessful">-</div>
</div>
</div>
<!-- 数据表切换 -->
<div class="card">
<div class="card-header">
<div style="display: flex; gap: 12px;">
<button class="btn btn-primary" id="btnShowSites" onclick="showDatabaseView('sites')">站点列表</button>
<button class="btn" id="btnShowClicks" onclick="showDatabaseView('clicks')">点击记录</button>
<button class="btn" id="btnShowInteractions" onclick="showDatabaseView('interactions')">互动记录</button>
<button class="btn btn-success" onclick="refreshDatabaseData()" style="margin-left: auto;">🔄 刷新</button>
</div>
</div>
<div class="card-body">
<!-- 站点列表 -->
<div id="dbSitesView" class="db-view">
<div class="table-container">
<table class="table">
<thead>
<tr>
<th>ID</th>
<th>站点名称</th>
<th>URL</th>
<th>状态</th>
<th>点击数</th>
<th>回复数</th>
<th>创建时间</th>
</tr>
</thead>
<tbody id="dbSitesTableBody">
<tr>
<td colspan="7" class="empty-state">加载中...</td>
</tr>
</tbody>
</table>
</div>
</div>
<!-- 点击记录 -->
<div id="dbClicksView" class="db-view" style="display: none;">
<div class="table-container">
<table class="table">
<thead>
<tr>
<th>ID</th>
<th>站点ID</th>
<th>URL</th>
<th>点击时间</th>
<th>设备类型</th>
</tr>
</thead>
<tbody id="dbClicksTableBody">
<tr>
<td colspan="5" class="empty-state">加载中...</td>
</tr>
</tbody>
</table>
</div>
</div>
<!-- 互动记录 -->
<div id="dbInteractionsView" class="db-view" style="display: none;">
<div class="table-container">
<table class="table">
<thead>
<tr>
<th>ID</th>
<th>站点ID</th>
<th>互动时间</th>
<th>发送内容</th>
<th>收到回复</th>
<th>状态</th>
</tr>
</thead>
<tbody id="dbInteractionsTableBody">
<tr>
<td colspan="6" class="empty-state">加载中...</td>
</tr>
</tbody>
</table>
</div>
</div>
</div>
</div>
</div>
</div>
</div>
</div>
@@ -565,9 +674,15 @@
'dashboard': '数据概览',
'scheduler': '调度器管理',
'urls': '链接管理',
'database': '数据库管理',
'browser': '浏览器测试'
};
document.getElementById('breadcrumb').textContent = breadcrumbMap[page];
// 如果切换到数据库页面,加载数据
if (page === 'database') {
loadDatabaseData();
}
}
// 显示Toast提示
@@ -822,6 +937,130 @@
}, 1000);
}
// ==================== 数据库管理相关函数 ====================
// 切换数据库视图
function showDatabaseView(view) {
// 隐藏所有视图
document.querySelectorAll('.db-view').forEach(v => v.style.display = 'none');
// 显示目标视图
document.getElementById(`db${view.charAt(0).toUpperCase() + view.slice(1)}View`).style.display = 'block';
// 更新按钮状态
document.getElementById('btnShowSites').className = view === 'sites' ? 'btn btn-primary' : 'btn';
document.getElementById('btnShowClicks').className = view === 'clicks' ? 'btn btn-primary' : 'btn';
document.getElementById('btnShowInteractions').className = view === 'interactions' ? 'btn btn-primary' : 'btn';
}
// 加载数据库数据
async function loadDatabaseData() {
try {
// 加载统计数据
const statsRes = await fetch(`${API_BASE}/api/statistics`);
const statsData = await statsRes.json();
if (statsData.success) {
const stats = statsData.data;
document.getElementById('dbTotalSites').textContent = stats.total_sites || 0;
document.getElementById('dbTotalClicks').textContent = stats.total_clicks || 0;
document.getElementById('dbTotalReplies').textContent = stats.total_replies || 0;
document.getElementById('dbSuccessful').textContent = stats.successful_interactions || 0;
}
// 加载站点数据
await loadDatabaseSites();
await loadDatabaseClicks();
await loadDatabaseInteractions();
} catch (error) {
showToast('加载数据库数据失败: ' + error.message, 'error');
}
}
// 加载站点列表
async function loadDatabaseSites() {
try {
const res = await fetch(`${API_BASE}/api/urls`);
const data = await res.json();
const tbody = document.getElementById('dbSitesTableBody');
if (data.success && data.data && data.data.length > 0) {
tbody.innerHTML = data.data.map(site => `
<tr>
<td>${site.id}</td>
<td>${site.site_name || '-'}</td>
<td><a href="${site.site_url}" target="_blank" class="table-url" title="${site.site_url}">${site.site_url}</a></td>
<td><span class="tag ${site.status === 'active' ? 'tag-success' : 'tag-error'}">${site.status === 'active' ? '活跃' : '未激活'}</span></td>
<td>${site.click_count || 0}</td>
<td>${site.reply_count || 0}</td>
<td>${site.created_at || '-'}</td>
</tr>
`).join('');
} else {
tbody.innerHTML = '<tr><td colspan="7" class="empty-state">暂无站点数据</td></tr>';
}
} catch (error) {
console.error('加载站点数据失败:', error);
}
}
// 加载点击记录
async function loadDatabaseClicks() {
try {
const res = await fetch(`${API_BASE}/api/clicks?limit=100`);
const data = await res.json();
const tbody = document.getElementById('dbClicksTableBody');
if (data.success && data.data && data.data.length > 0) {
tbody.innerHTML = data.data.map(click => `
<tr>
<td>${click.id}</td>
<td>${click.site_id || '-'}</td>
<td><span class="table-url" title="${click.site_url || ''}">${(click.site_url || '-').substring(0, 50)}...</span></td>
<td>${click.click_time || '-'}</td>
<td>${click.device_type || '-'}</td>
</tr>
`).join('');
} else {
tbody.innerHTML = '<tr><td colspan="5" class="empty-state">暂无点击记录</td></tr>';
}
} catch (error) {
console.error('加载点击记录失败:', error);
}
}
// 加载互动记录
async function loadDatabaseInteractions() {
try {
const res = await fetch(`${API_BASE}/api/interactions?limit=100`);
const data = await res.json();
const tbody = document.getElementById('dbInteractionsTableBody');
if (data.success && data.data && data.data.length > 0) {
tbody.innerHTML = data.data.map(interaction => `
<tr>
<td>${interaction.id}</td>
<td>${interaction.site_id || '-'}</td>
<td>${interaction.interaction_time || '-'}</td>
<td><span class="table-url" title="${interaction.reply_content || ''}">${(interaction.reply_content || '-').substring(0, 30)}...</span></td>
<td><span class="tag ${interaction.response_received ? 'tag-success' : 'tag-error'}">${interaction.response_received ? '是' : '否'}</span></td>
<td><span class="tag ${interaction.interaction_status === 'success' ? 'tag-success' : 'tag-error'}">${interaction.interaction_status || '-'}</span></td>
</tr>
`).join('');
} else {
tbody.innerHTML = '<tr><td colspan="6" class="empty-state">暂无互动记录</td></tr>';
}
} catch (error) {
console.error('加载互动记录失败:', error);
}
}
// 刷新数据库数据
function refreshDatabaseData() {
showToast('正在刷新数据...', 'info');
loadDatabaseData();
}
// 初始化
function init() {
getSchedulerStatus();