init
This commit is contained in:
232
templates/admin_health_checks.html
Normal file
232
templates/admin_health_checks.html
Normal file
@@ -0,0 +1,232 @@
|
||||
<!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/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>
|
||||
</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>
|
||||
Reference in New Issue
Block a user