Files
JieXi/templates/admin_health_checks.html
2025-11-30 19:49:25 +08:00

236 lines
11 KiB
HTML
Raw Permalink Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
<!DOCTYPE html>
<html lang="zh-CN">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>健康检查配置 - 管理后台</title>
<link rel="stylesheet" href="/static/css/ui-components.css?v=3">
<link rel="stylesheet" href="/static/css/admin.css">
</head>
<body class="admin-layout">
<header class="admin-header">
<div class="header-container">
<a href="/admin/dashboard" class="brand">
<span style="font-size: 1.5rem;"></span> JieXi Admin
</a>
<nav class="nav-links">
<a href="/admin/dashboard" class="nav-item">仪表板</a>
<a href="/admin/users" class="nav-item">用户管理</a>
<a href="/admin/apis" class="nav-item">接口管理</a>
<a href="/admin/redeem-codes" class="nav-item">兑换码</a>
<a href="/admin/config" class="nav-item active">系统配置</a>
<a href="/admin/logs" class="nav-item">日志审计</a>
</nav>
<div class="user-actions">
<a href="/admin/profile" class="ui-btn ui-btn-secondary ui-btn-sm">账号设置</a>
<button class="ui-btn ui-btn-secondary ui-btn-sm" onclick="logout()">退出登录</button>
</div>
</div>
</header>
<main class="main-container">
<div class="page-header">
<h1 class="page-title">健康检查配置</h1>
<div class="actions">
<a href="/admin/config" class="ui-btn ui-btn-secondary">返回配置</a>
<button class="ui-btn ui-btn-primary" onclick="showAddModal()">+ 添加配置</button>
</div>
</div>
<div class="ui-card">
<div class="table-container">
<table id="healthTable">
<thead>
<tr>
<th>ID</th>
<th>平台</th>
<th>测试链接</th>
<th>检查间隔</th>
<th>告警邮箱</th>
<th>状态</th>
<th>操作</th>
</tr>
</thead>
<tbody>
<tr>
<td colspan="7" style="text-align: center; color: var(--text-muted);">加载中...</td>
</tr>
</tbody>
</table>
</div>
</div>
</main>
<!-- Health Check Modal -->
<div id="healthModal" class="ui-modal">
<div class="ui-modal-overlay" onclick="closeModal()"></div>
<div class="ui-modal-content">
<h3 id="modalTitle">添加健康检查配置</h3>
<form id="healthForm">
<input type="hidden" id="configId">
<div class="form-group">
<label>平台类型 *</label>
<select id="platform" class="ui-input" required>
<option value="douyin">抖音 (douyin)</option>
<option value="tiktok">TikTok (tiktok)</option>
<option value="bilibili">哔哩哔哩 (bilibili)</option>
<option value="kuaishou">快手 (kuaishou)</option>
<option value="pipixia">皮皮虾 (pipixia)</option>
<option value="weibo">微博 (weibo)</option>
</select>
</div>
<div class="form-group">
<label>测试视频链接 *</label>
<input type="url" id="testUrl" class="ui-input" required placeholder="https://...">
<small class="text-muted text-sm">用于健康检查的测试视频链接</small>
</div>
<div class="form-group">
<label>检查间隔(秒)*</label>
<input type="number" id="checkInterval" class="ui-input" value="300" min="60" max="3600" required>
<small class="text-muted text-sm">建议300秒5分钟</small>
</div>
<div class="form-group">
<label>告警邮箱</label>
<input type="email" id="alertEmail" class="ui-input" placeholder="admin@example.com">
<small class="text-muted text-sm">接口异常时发送告警邮件</small>
</div>
<div class="form-group">
<label>是否启用</label>
<select id="isEnabled" class="ui-input">
<option value="true">启用</option>
<option value="false">禁用</option>
</select>
</div>
<div class="ui-modal-actions">
<button type="button" class="ui-btn ui-btn-secondary" onclick="closeModal()">取消</button>
<button type="submit" class="ui-btn ui-btn-primary">保存</button>
</div>
</form>
</div>
</div>
<script src="/static/js/ui-components.js"></script>
<script>
async function loadHealthChecks() {
try {
const response = await fetch('/admin/api/health-checks');
const result = await response.json();
if (result.success) {
const tbody = document.querySelector('#healthTable tbody');
if (result.data.length === 0) {
tbody.innerHTML = '<tr><td colspan="7" style="text-align: center; padding: 2rem; color: var(--text-muted);">暂无配置</td></tr>';
return;
}
tbody.innerHTML = result.data.map(c => `
<tr>
<td>${c.id}</td>
<td><span class="badge badge-neutral">${c.platform}</span></td>
<td style="max-width: 300px; overflow: hidden; text-overflow: ellipsis;" class="text-sm text-muted" title="${c.test_url}">${c.test_url}</td>
<td>${c.check_interval}秒</td>
<td class="text-sm">${c.alert_email || '-'}</td>
<td><span class="badge ${c.is_enabled ? 'badge-success' : 'badge-neutral'}">${c.is_enabled ? '启用' : '禁用'}</span></td>
<td>
<div class="flex gap-2">
<button class="ui-btn ui-btn-secondary ui-btn-sm" onclick='editConfig(${JSON.stringify(c)})'>编辑</button>
<button class="ui-btn ui-btn-danger ui-btn-sm" onclick="deleteConfig(${c.id})">删除</button>
</div>
</td>
</tr>
`).join('');
}
} catch (error) {
UI.notify('加载失败: ' + error.message, 'error');
}
}
function showAddModal() {
document.getElementById('modalTitle').textContent = '添加健康检查配置';
document.getElementById('healthForm').reset();
document.getElementById('configId').value = '';
document.getElementById('checkInterval').value = '300';
document.getElementById('healthModal').classList.add('show');
}
function editConfig(config) {
document.getElementById('modalTitle').textContent = '编辑健康检查配置';
document.getElementById('configId').value = config.id;
document.getElementById('platform').value = config.platform;
document.getElementById('testUrl').value = config.test_url;
document.getElementById('checkInterval').value = config.check_interval;
document.getElementById('alertEmail').value = config.alert_email || '';
document.getElementById('isEnabled').value = config.is_enabled;
document.getElementById('healthModal').classList.add('show');
}
function closeModal() {
document.getElementById('healthModal').classList.remove('show');
}
async function deleteConfig(id) {
UI.confirm('确认删除', '确定要删除此配置吗?', async () => {
try {
const response = await fetch(`/admin/api/health-checks/${id}`, { method: 'DELETE' });
const result = await response.json();
if (result.success) {
UI.notify('删除成功', 'success');
loadHealthChecks();
} else {
UI.notify('删除失败: ' + result.message, 'error');
}
} catch (error) {
UI.notify('删除失败: ' + error.message, 'error');
}
});
}
document.getElementById('healthForm').addEventListener('submit', async (e) => {
e.preventDefault();
const configId = document.getElementById('configId').value;
const data = {
platform: document.getElementById('platform').value,
test_url: document.getElementById('testUrl').value,
check_interval: parseInt(document.getElementById('checkInterval').value),
alert_email: document.getElementById('alertEmail').value || null,
is_enabled: document.getElementById('isEnabled').value === 'true'
};
try {
const url = configId ? `/admin/api/health-checks/${configId}` : '/admin/api/health-checks';
const method = configId ? 'PUT' : 'POST';
const response = await fetch(url, {
method: method,
headers: { 'Content-Type': 'application/json' },
body: JSON.stringify(data)
});
const result = await response.json();
if (result.success) {
UI.notify(configId ? '更新成功' : '创建成功', 'success');
closeModal();
loadHealthChecks();
} else {
UI.notify('操作失败: ' + result.message, 'error');
}
} catch (error) {
UI.notify('操作失败: ' + error.message, 'error');
}
});
async function logout() {
try {
await fetch('/admin/logout', { method: 'POST' });
window.location.href = '/admin/login';
} catch (error) {
UI.notify('退出失败', 'error');
}
}
loadHealthChecks();
</script>
</body>
</html>