4a1d949e41
完整 Web 管理平台,涵盖: P0 生产加固: - 会话超时(空闲+绝对) + CSRF 防护 + 登录失败限流 - HTTPS/TLS 证书管理(自签生成/上传/删除/过期提醒) - SSL Bump (HTTPS 透明代理) 可视化配置 - 配置文件 diff 预览 + 二次确认才写入 - 服务控制二次确认 + 操作期间按钮锁定 P1 运维能力: - 日志轮转管理(logrotate) + 日志状态监控 - 告警规则(5xx/命中率/磁盘/客户端流量) - 多 Squid 实例管理 + 一键切换 - squidclient mgr 实时性能指标 - 流量异常检测(突增/大文件/高频小包/新客户端) P2 日志分析增强: - 日志持久化到 SQLite + 历史时间范围查询 - 导出 CSV/JSON(日志/KPI/异常/审计) - GeoIP 地图(Leaflet + ip-api.com 离线可选 GeoLite2) - 每客户端 24h 趋势图 - 自定义 Squid logformat 解析器 P3 体验锦上添花: - 暗/亮主题切换(cookie 持久化) - WebSSH 终端(xterm.js + paramiko) - 完整审计日志 + 用户管理 技术栈: Flask 3.0 + SQLAlchemy 2.0 + SQLite + Chart.js + Leaflet 总代码量: ~16500 行 (15 Python 模块 + 34 模板 + CSS) 路由数: 73
29 lines
1.4 KiB
HTML
29 lines
1.4 KiB
HTML
{% set _theme = theme|default('dark') %}
|
|
{% set _icon = '☀️' if _theme == 'light' else '🌙' %}
|
|
<button class="theme-toggle" type="button" onclick="toggleTheme()" title="切换主题 (暗/亮)" aria-label="切换主题">
|
|
<span id="theme-icon">{{ _icon }}</span>
|
|
</button>
|
|
<script>
|
|
function toggleTheme() {
|
|
const current = document.body.classList.contains('theme-light') ? 'light' : 'dark';
|
|
const next = current === 'light' ? 'dark' : 'light';
|
|
document.cookie = `theme=${next}; path=/; max-age=${365*24*3600}; samesite=Lax`;
|
|
document.body.classList.toggle('theme-light', next === 'light');
|
|
const icon = document.getElementById('theme-icon');
|
|
if (icon) icon.textContent = next === 'light' ? '☀️' : '🌙';
|
|
}
|
|
// initial state — keep icon in sync if cookie says light but the body class
|
|
// hasn't been set yet (e.g. partial rendered before server emitted the class)
|
|
(function() {
|
|
const match = document.cookie.match(/theme=(\w+)/);
|
|
if (match && match[1] === 'light') {
|
|
document.body.classList.add('theme-light');
|
|
const icon = document.getElementById('theme-icon');
|
|
if (icon) icon.textContent = '☀️';
|
|
} else if (match && match[1] === 'dark') {
|
|
document.body.classList.remove('theme-light');
|
|
const icon = document.getElementById('theme-icon');
|
|
if (icon) icon.textContent = '🌙';
|
|
}
|
|
})();
|
|
</script> |