Compare commits
1 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
| e7b5a1ce09 |
143
app.py
143
app.py
@@ -244,7 +244,7 @@ HTML_TEMPLATE = '''<!DOCTYPE html>
|
||||
</div>
|
||||
|
||||
<!-- 统计卡片 -->
|
||||
<div class="grid grid-cols-2 md:grid-cols-5 gap-4 mb-8">
|
||||
<div class="grid grid-cols-2 md:grid-cols-4 gap-4 mb-8">
|
||||
<div class="card rounded-xl p-4">
|
||||
<div class="flex items-center justify-between">
|
||||
<div>
|
||||
@@ -281,34 +281,6 @@ HTML_TEMPLATE = '''<!DOCTYPE html>
|
||||
<i class="ri-terminal-box-line text-3xl text-purple-400 opacity-50"></i>
|
||||
</div>
|
||||
</div>
|
||||
<div class="card rounded-xl p-4">
|
||||
<div class="flex items-center justify-between">
|
||||
<div>
|
||||
<p class="text-gray-400 text-sm">系统Cron</p>
|
||||
<p id="systemCronCount" class="text-2xl font-bold text-orange-400">-</p>
|
||||
</div>
|
||||
<i class="ri-timer-line text-3xl text-orange-400 opacity-50"></i>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<!-- 系统 Cron 列表 -->
|
||||
<div class="card rounded-xl p-6 mb-8">
|
||||
<div class="flex items-center justify-between mb-4">
|
||||
<h2 class="text-xl font-bold flex items-center gap-2">
|
||||
<i class="ri-timer-line text-orange-400"></i>
|
||||
主机 Cron 列表
|
||||
</h2>
|
||||
<button onclick="loadCrons()" class="btn bg-orange-600 hover:bg-orange-700 px-3 py-1 rounded text-sm flex items-center gap-1">
|
||||
<i class="ri-refresh-line"></i> 刷新
|
||||
</button>
|
||||
</div>
|
||||
<div id="cronsList" class="space-y-3">
|
||||
<div class="text-center py-8 text-gray-400">
|
||||
<i class="ri-loader-4-line text-2xl animate-spin"></i>
|
||||
<p class="mt-2 text-sm">加载中...</p>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<!-- 筛选器 -->
|
||||
@@ -337,6 +309,33 @@ HTML_TEMPLATE = '''<!DOCTYPE html>
|
||||
<p class="mt-2">加载中...</p>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<!-- 系统 Cron 列表 -->
|
||||
<div class="card rounded-xl p-6 mt-8">
|
||||
<div class="flex items-center justify-between mb-4">
|
||||
<h2 class="text-xl font-bold flex items-center gap-2">
|
||||
<i class="ri-timer-line text-orange-400"></i>
|
||||
主机 Cron 列表
|
||||
<span id="systemCronCount" class="text-sm text-gray-400 ml-2">-</span>
|
||||
</h2>
|
||||
<button onclick="loadCrons()" class="btn bg-orange-600 hover:bg-orange-700 px-3 py-1 rounded text-sm flex items-center gap-1">
|
||||
<i class="ri-refresh-line"></i> 刷新
|
||||
</button>
|
||||
</div>
|
||||
|
||||
<!-- Cron 概述 -->
|
||||
<div id="cronSummary" class="mb-4 p-4 bg-gray-800/50 rounded-lg border border-gray-700">
|
||||
<div class="text-center py-4 text-gray-400 text-sm">加载中...</div>
|
||||
</div>
|
||||
|
||||
<!-- Cron 详细列表 -->
|
||||
<div id="cronsList" class="space-y-3">
|
||||
<div class="text-center py-8 text-gray-400">
|
||||
<i class="ri-loader-4-line text-2xl animate-spin"></i>
|
||||
<p class="mt-2 text-sm">加载中...</p>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<!-- 日志模态框 -->
|
||||
@@ -686,6 +685,7 @@ HTML_TEMPLATE = '''<!DOCTYPE html>
|
||||
|
||||
function renderCrons(crons) {
|
||||
const list = document.getElementById('cronsList');
|
||||
document.getElementById('systemCronCount').textContent = `${crons.length} 个`;
|
||||
|
||||
if (crons.length === 0) {
|
||||
list.innerHTML = `
|
||||
@@ -697,6 +697,54 @@ HTML_TEMPLATE = '''<!DOCTYPE html>
|
||||
return;
|
||||
}
|
||||
|
||||
// 分类统计并生成概述
|
||||
const userCrons = crons.filter(c => c.source === 'user');
|
||||
const systemCrons = crons.filter(c => c.source === 'system');
|
||||
const cronDCrons = crons.filter(c => c.source === 'cron.d');
|
||||
|
||||
// 分析用户任务用途
|
||||
const userTaskTypes = analyzeUserCrons(userCrons);
|
||||
|
||||
// 生成概述
|
||||
let summaryHtml = `
|
||||
<div class="grid grid-cols-1 md:grid-cols-3 gap-4">
|
||||
<div class="bg-blue-500/10 rounded-lg p-3 border border-blue-500/30">
|
||||
<div class="flex items-center gap-2 mb-2">
|
||||
<i class="ri-user-line text-blue-400"></i>
|
||||
<span class="text-blue-400 font-medium">用户任务</span>
|
||||
<span class="text-blue-300 text-sm">${userCrons.length} 个</span>
|
||||
</div>
|
||||
<div class="text-gray-300 text-sm space-y-1">
|
||||
${userTaskTypes.map(t => `<div><span class="text-gray-400">${t.count}个</span> ${t.name}</div>`).join('')}
|
||||
</div>
|
||||
</div>
|
||||
<div class="bg-red-500/10 rounded-lg p-3 border border-red-500/30">
|
||||
<div class="flex items-center gap-2 mb-2">
|
||||
<i class="ri-settings-line text-red-400"></i>
|
||||
<span class="text-red-400 font-medium">系统任务</span>
|
||||
<span class="text-red-300 text-sm">${systemCrons.length} 个</span>
|
||||
</div>
|
||||
<div class="text-gray-300 text-sm space-y-1">
|
||||
<div><span class="text-gray-400">每小时</span> 执行 cron.hourly</div>
|
||||
<div><span class="text-gray-400">每天</span> 执行 cron.daily</div>
|
||||
<div><span class="text-gray-400">每周</span> 执行 cron.weekly</div>
|
||||
<div><span class="text-gray-400">每月</span> 执行 cron.monthly</div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="bg-green-500/10 rounded-lg p-3 border border-green-500/30">
|
||||
<div class="flex items-center gap-2 mb-2">
|
||||
<i class="ri-file-list-line text-green-400"></i>
|
||||
<span class="text-green-400 font-medium">cron.d</span>
|
||||
<span class="text-green-300 text-sm">${cronDCrons.length} 个</span>
|
||||
</div>
|
||||
<div class="text-gray-300 text-sm space-y-1">
|
||||
${cronDCrons.map(c => `<div><span class="text-gray-400">${c.file}</span> ${c.description || ''}</div>`).join('')}
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
`;
|
||||
document.getElementById('cronSummary').innerHTML = summaryHtml;
|
||||
|
||||
const sourceColors = {
|
||||
'user': { bg: 'bg-blue-500/20', text: 'text-blue-400', label: '用户' },
|
||||
'system': { bg: 'bg-red-500/20', text: 'text-red-400', label: '系统' },
|
||||
@@ -735,6 +783,43 @@ HTML_TEMPLATE = '''<!DOCTYPE html>
|
||||
list.innerHTML = html;
|
||||
}
|
||||
|
||||
function analyzeUserCrons(crons) {
|
||||
const types = [];
|
||||
|
||||
// 服务监控
|
||||
const monitors = crons.filter(c => c.command.includes('service-monitor') || c.command.includes('monitor.py') || c.command.includes('cpu-monitor') || c.command.includes('disk-monitor'));
|
||||
if (monitors.length > 0) types.push({ name: '系统监控', count: monitors.length });
|
||||
|
||||
// 股票/板块相关
|
||||
const stocks = crons.filter(c => c.command.includes('stock') || c.command.includes('board_monitor'));
|
||||
if (stocks.length > 0) types.push({ name: 'A股数据/板块监控', count: stocks.length });
|
||||
|
||||
// 每日总结
|
||||
const summaries = crons.filter(c => c.command.includes('daily-summary') || c.command.includes('summary'));
|
||||
if (summaries.length > 0) types.push({ name: '每日总结', count: summaries.length });
|
||||
|
||||
// 清理脚本
|
||||
const cleanups = crons.filter(c => c.command.includes('cleanup') || c.command.includes('clean'));
|
||||
if (cleanups.length > 0) types.push({ name: '清理脚本', count: cleanups.length });
|
||||
|
||||
// 其他
|
||||
const others = crons.filter(c =>
|
||||
!c.command.includes('service-monitor') &&
|
||||
!c.command.includes('monitor.py') &&
|
||||
!c.command.includes('cpu-monitor') &&
|
||||
!c.command.includes('disk-monitor') &&
|
||||
!c.command.includes('stock') &&
|
||||
!c.command.includes('board_monitor') &&
|
||||
!c.command.includes('daily-summary') &&
|
||||
!c.command.includes('summary') &&
|
||||
!c.command.includes('cleanup') &&
|
||||
!c.command.includes('clean')
|
||||
);
|
||||
if (others.length > 0) types.push({ name: '其他任务', count: others.length });
|
||||
|
||||
return types;
|
||||
}
|
||||
|
||||
function escapeHtml(text) {
|
||||
const div = document.createElement('div');
|
||||
div.textContent = text;
|
||||
|
||||
Reference in New Issue
Block a user