Files
dns-server/static/index.html
Alex Yang 073f1961b1 更新web
2026-01-21 09:46:49 +08:00

1438 lines
100 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>DNS服务器控制台</title>
<!-- Tailwind CSS -->
<script src="css/vendor/tailwind.css"></script>
<!-- Font Awesome -->
<link href="css/font-awesome.min.css" rel="stylesheet">
<!-- 自定义样式 -->
<link href="css/style.css" rel="stylesheet">
<!-- Chart.js 本地备用 -->
<script src="js/vendor/chart.umd.min.js" onerror="this.onerror=null;this.src='js/chart.umd.min.js';"></script>
<!-- Tailwind 配置 -->
<script src="js/vendor/tailwind.js"></script>
<!-- 自定义工具类 -->
<style type="text/tailwindcss" src="css/index.css"></style>
</head>
<body class="bg-gray-50 text-dark font-sans">
<div class="flex h-screen overflow-hidden">
<!-- 侧边栏 -->
<aside id="sidebar" class="fixed inset-y-0 left-0 w-64 bg-white border-r border-gray-200 flex flex-col transition-transform duration-300 z-50 hidden md:flex">
<!-- Logo -->
<div class="flex items-center justify-center h-16 border-b border-gray-200">
<i class="fa fa-server text-3xl text-primary mr-3"></i>
<h1 class="text-xl font-bold text-primary">DNS 控制台</h1>
</div>
<!-- 菜单 -->
<nav class="flex-1 overflow-y-auto p-4">
<ul class="space-y-1">
<li>
<a href="#dashboard" class="flex items-center px-4 py-3 text-gray-700 hover:bg-gray-100 rounded-md transition-all sidebar-item-active">
<i class="fa fa-tachometer mr-3 text-lg"></i>
<span>仪表盘</span>
</a>
</li>
<li>
<a href="#shield" class="flex items-center px-4 py-3 text-gray-700 hover:bg-gray-100 rounded-md transition-all">
<i class="fa fa-shield mr-3 text-lg"></i>
<span>屏蔽管理</span>
</a>
</li>
<li>
<a href="#hosts" class="flex items-center px-4 py-3 text-gray-700 hover:bg-gray-100 rounded-md transition-all">
<i class="fa fa-file-text mr-3 text-lg"></i>
<span>Hosts管理</span>
</a>
</li>
<li>
<a href="#gfwlist" class="flex items-center px-4 py-3 text-gray-700 hover:bg-gray-100 rounded-md transition-all">
<i class="fa fa-globe mr-3 text-lg"></i>
<span>GFWList管理</span>
</a>
</li>
<li>
<a href="#query" class="flex items-center px-4 py-3 text-gray-700 hover:bg-gray-100 rounded-md transition-all">
<i class="fa fa-search mr-3 text-lg"></i>
<span>DNS屏蔽查询</span>
</a>
</li>
<li>
<a href="#logs" class="flex items-center px-4 py-3 text-gray-700 hover:bg-gray-100 rounded-md transition-all">
<i class="fa fa-file-text-o mr-3 text-lg"></i>
<span>查询日志</span>
</a>
</li>
<li>
<a href="#config" class="flex items-center px-4 py-3 text-gray-700 hover:bg-gray-100 rounded-md transition-all">
<i class="fa fa-cog mr-3 text-lg"></i>
<span>系统设置</span>
</a>
</li>
</ul>
</nav>
<!-- 底部信息 -->
<div class="p-4 border-t border-gray-200 text-center text-gray-500 text-sm">
<p>DNS服务器 v1.2.0</p>
<p class="mt-1" id="uptime">正常运行中</p>
</div>
</aside>
<!-- 移动端侧边栏 -->
<aside id="mobile-sidebar" class="fixed inset-y-0 left-0 w-64 bg-white border-r border-gray-200 flex flex-col transition-transform duration-300 z-50 -translate-x-full md:hidden">
<!-- 移动端关闭按钮 -->
<div class="absolute top-4 right-4">
<button id="close-sidebar" class="p-2 text-gray-500 hover:text-gray-700 focus:outline-none">
<i class="fa fa-times text-xl"></i>
</button>
</div>
<!-- Logo -->
<div class="flex items-center justify-center h-16 border-b border-gray-200">
<i class="fa fa-server text-3xl text-primary mr-3"></i>
<h1 class="text-xl font-bold text-primary">DNS 控制台</h1>
</div>
<!-- 菜单 -->
<nav class="flex-1 overflow-y-auto p-4">
<ul class="space-y-1">
<li>
<a href="#dashboard" class="flex items-center px-4 py-3 text-gray-700 hover:bg-gray-100 rounded-md transition-all sidebar-item-active">
<i class="fa fa-tachometer mr-3 text-lg"></i>
<span>仪表盘</span>
</a>
</li>
<li>
<a href="#shield" class="flex items-center px-4 py-3 text-gray-700 hover:bg-gray-100 rounded-md transition-all">
<i class="fa fa-shield mr-3 text-lg"></i>
<span>屏蔽管理</span>
</a>
</li>
<li>
<a href="#hosts" class="flex items-center px-4 py-3 text-gray-700 hover:bg-gray-100 rounded-md transition-all">
<i class="fa fa-file-text mr-3 text-lg"></i>
<span>Hosts管理</span>
</a>
</li>
<li>
<a href="#gfwlist" class="flex items-center px-4 py-3 text-gray-700 hover:bg-gray-100 rounded-md transition-all">
<i class="fa fa-globe mr-3 text-lg"></i>
<span>GFWList管理</span>
</a>
</li>
<li>
<a href="#query" class="flex items-center px-4 py-3 text-gray-700 hover:bg-gray-100 rounded-md transition-all">
<i class="fa fa-search mr-3 text-lg"></i>
<span>DNS屏蔽查询</span>
</a>
</li>
<li>
<a href="#logs" class="flex items-center px-4 py-3 text-gray-700 hover:bg-gray-100 rounded-md transition-all">
<i class="fa fa-file-text-o mr-3 text-lg"></i>
<span>查询日志</span>
</a>
</li>
<li>
<a href="#config" class="flex items-center px-4 py-3 text-gray-700 hover:bg-gray-100 rounded-md transition-all">
<i class="fa fa-cog mr-3 text-lg"></i>
<span>系统设置</span>
</a>
</li>
</ul>
</nav>
<!-- 底部信息 -->
<div class="p-4 border-t border-gray-200 text-center text-gray-500 text-sm">
<p>DNS服务器 v1.2.0</p>
<p class="mt-1" id="uptime">正常运行中</p>
</div>
</aside>
<!-- 侧边栏遮罩层 -->
<div id="sidebar-overlay" class="fixed inset-0 bg-black bg-opacity-50 z-40 hidden md:hidden"></div>
<!-- 主内容区 -->
<main class="flex-1 flex flex-col md:ml-64">
<!-- 顶部导航栏 -->
<header class="bg-white border-b border-gray-200 h-16 flex items-center justify-between px-4 sm:px-6 sticky top-0 z-30 shadow-sm">
<div class="flex items-center">
<button id="toggle-sidebar" class="block md:hidden text-gray-500 hover:text-gray-700 focus:outline-none p-1 sm:p-2 transition-all">
<i class="fa fa-bars text-lg sm:text-xl"></i>
</button>
<h2 class="ml-2 sm:ml-4 text-base sm:text-lg md:text-xl font-semibold" id="page-title">仪表盘</h2>
</div>
<div class="flex items-center space-x-2 sm:space-x-4">
<button class="p-1.5 sm:p-2 text-gray-500 hover:text-gray-700 rounded-full hover:bg-gray-100 transition-all">
<i class="fa fa-bell text-sm sm:text-lg"></i>
</button>
<!-- 账户下拉菜单 -->
<div class="relative group" id="account-dropdown">
<button class="flex items-center p-1.5 sm:p-2 rounded-full hover:bg-gray-100 transition-colors focus:outline-none">
<img src="images/user.jpg" alt="用户头像" class="w-7 h-7 sm:w-8 sm:h-8 rounded-full">
<span class="ml-1 sm:ml-2 hidden md:block text-sm">管理员</span>
<i class="fa fa-caret-down ml-1 text-xs hidden md:block"></i>
</button>
<!-- 下拉菜单 -->
<div class="absolute right-0 mt-2 w-48 bg-white rounded-lg shadow-lg py-2 z-50 hidden group-hover:block" id="account-menu">
<button id="change-password-btn" class="w-full text-left px-4 py-2 text-sm text-gray-700 hover:bg-gray-100 transition-colors">
<i class="fa fa-key mr-2"></i>修改密码
</button>
<button id="logout-btn" class="w-full text-left px-4 py-2 text-sm text-gray-700 hover:bg-gray-100 transition-colors">
<i class="fa fa-sign-out mr-2"></i>注销
</button>
</div>
</div>
</div>
</header>
<!-- 页面内容 -->
<div class="p-4 sm:p-6 overflow-y-auto flex-1">
<!-- 仪表盘部分 -->
<div id="dashboard-content" class="space-y-6">
<!-- 统计卡片 -->
<div class="grid grid-cols-1 sm:grid-cols-2 md:grid-cols-3 lg:grid-cols-4 gap-4 sm:gap-6">
<!-- 查询总量卡片 -->
<div class="bg-blue-50 rounded-lg p-3 sm:p-4 card-shadow relative overflow-hidden transition-all hover:shadow-md">
<!-- 颜色蒙版 -->
<div class="absolute -bottom-6 -right-6 w-20 h-20 sm:w-24 sm:h-24 rounded-full bg-primary opacity-10"></div>
<div class="relative z-10">
<div class="flex items-center justify-between mb-3 sm:mb-4">
<h3 class="text-xs sm:text-sm text-gray-500 font-medium">查询总量</h3>
<div class="p-1.5 sm:p-2 rounded-full bg-primary/10 text-primary">
<i class="fa fa-refresh text-xs sm:text-sm"></i>
</div>
</div>
<div class="mb-2">
<div class="flex items-end justify-between">
<p class="text-2xl sm:text-3xl font-bold" id="total-queries">0</p>
<span class="text-success text-xs sm:text-sm flex items-center">
<i class="fa fa-arrow-up mr-1 text-xs"></i>
<span id="queries-percent">0%</span>
</span>
</div>
</div>
</div>
</div>
<!-- 屏蔽数量卡片 -->
<div class="bg-red-50 rounded-lg p-3 sm:p-4 card-shadow relative overflow-hidden transition-all hover:shadow-md">
<!-- 颜色蒙版 -->
<div class="absolute -bottom-6 -right-6 w-20 h-20 sm:w-24 sm:h-24 rounded-full bg-danger opacity-10"></div>
<div class="relative z-10">
<div class="flex items-center justify-between mb-3 sm:mb-4">
<h3 class="text-xs sm:text-sm text-gray-500 font-medium">屏蔽数量</h3>
<div class="p-1.5 sm:p-2 rounded-full bg-danger/10 text-danger">
<i class="fa fa-ban text-xs sm:text-sm"></i>
</div>
</div>
<div class="mb-2">
<div class="flex items-end justify-between">
<p class="text-2xl sm:text-3xl font-bold" id="blocked-queries">0</p>
<span class="text-danger text-xs sm:text-sm flex items-center">
<i class="fa fa-arrow-up mr-1 text-xs"></i>
<span id="blocked-percent">0%</span>
</span>
</div>
</div>
</div>
</div>
<!-- 正常解析卡片 -->
<div class="bg-green-50 rounded-lg p-3 sm:p-4 card-shadow relative overflow-hidden transition-all hover:shadow-md">
<!-- 颜色蒙版 -->
<div class="absolute -bottom-6 -right-6 w-20 h-20 sm:w-24 sm:h-24 rounded-full bg-success opacity-10"></div>
<div class="relative z-10">
<div class="flex items-center justify-between mb-3 sm:mb-4">
<h3 class="text-xs sm:text-sm text-gray-500 font-medium">正常解析</h3>
<div class="p-1.5 sm:p-2 rounded-full bg-success/10 text-success">
<i class="fa fa-check text-xs sm:text-sm"></i>
</div>
</div>
<div class="mb-2">
<div class="flex items-end justify-between">
<p class="text-2xl sm:text-3xl font-bold" id="allowed-queries">0</p>
<span class="text-success text-xs sm:text-sm flex items-center">
<i class="fa fa-arrow-up mr-1 text-xs"></i>
<span id="allowed-percent">0%</span>
</span>
</div>
</div>
</div>
</div>
<!-- 错误数量卡片 -->
<div class="bg-yellow-50 rounded-lg p-3 sm:p-4 card-shadow relative overflow-hidden transition-all hover:shadow-md">
<!-- 颜色蒙版 -->
<div class="absolute -bottom-6 -right-6 w-20 h-20 sm:w-24 sm:h-24 rounded-full bg-warning opacity-10"></div>
<div class="relative z-10">
<div class="flex items-center justify-between mb-3 sm:mb-4">
<h3 class="text-xs sm:text-sm text-gray-500 font-medium">错误数量</h3>
<div class="p-1.5 sm:p-2 rounded-full bg-warning/10 text-warning">
<i class="fa fa-exclamation-triangle text-xs sm:text-sm"></i>
</div>
</div>
<div class="mb-2">
<div class="flex items-end justify-between">
<p class="text-2xl sm:text-3xl font-bold" id="error-queries">0</p>
<span class="text-warning text-xs sm:text-sm flex items-center">
<i class="fa fa-arrow-up mr-1 text-xs"></i>
<span id="error-percent">0%</span>
</span>
</div>
</div>
</div>
</div>
<!-- 平均响应时间卡片 -->
<div class="bg-white rounded-lg p-3 sm:p-4 card-shadow relative overflow-hidden transition-all hover:shadow-md">
<!-- 颜色蒙版 -->
<div class="absolute -bottom-6 -right-6 w-20 h-20 sm:w-24 sm:h-24 rounded-full bg-info opacity-10"></div>
<div class="relative z-10">
<div class="flex items-center justify-between mb-3 sm:mb-4">
<h3 class="text-xs sm:text-sm text-gray-500 font-medium">平均响应时间</h3>
<div class="p-1.5 sm:p-2 rounded-full bg-info/10 text-info">
<i class="fa fa-clock-o text-xs sm:text-sm"></i>
</div>
</div>
<div class="mb-2">
<div class="flex items-end justify-between">
<p class="text-2xl sm:text-3xl font-bold" id="avg-response-time">0ms</p>
<span class="text-success text-xs sm:text-sm flex items-center">
<i class="fa fa-arrow-down mr-1 text-xs"></i>
<span id="response-time-percent">0%</span>
</span>
</div>
</div>
</div>
</div>
<!-- 最常用查询类型卡片 -->
<div class="bg-white rounded-lg p-3 sm:p-4 card-shadow relative overflow-hidden transition-all hover:shadow-md">
<!-- 颜色蒙版 -->
<div class="absolute -bottom-6 -right-6 w-20 h-20 sm:w-24 sm:h-24 rounded-full bg-secondary opacity-10"></div>
<div class="relative z-10">
<div class="flex items-center justify-between mb-3 sm:mb-4">
<h3 class="text-xs sm:text-sm text-gray-500 font-medium">最常用查询类型</h3>
<div class="p-1.5 sm:p-2 rounded-full bg-secondary/10 text-secondary">
<i class="fa fa-database text-xs sm:text-sm"></i>
</div>
</div>
<div class="flex items-end justify-between">
<p class="text-2xl sm:text-3xl font-bold" id="top-query-type">A</p>
<span class="text-primary text-xs sm:text-sm flex items-center">
<i class="fa fa-circle text-xs mr-1"></i>
<span id="query-type-percentage">0%</span>
</span>
</div>
</div>
</div>
<!-- 活跃来源IP数卡片 -->
<div class="bg-white rounded-lg p-3 sm:p-4 card-shadow relative overflow-hidden transition-all hover:shadow-md">
<!-- 颜色蒙版 -->
<div class="absolute -bottom-6 -right-6 w-20 h-20 sm:w-24 sm:h-24 rounded-full bg-success opacity-10"></div>
<div class="relative z-10">
<div class="flex items-center justify-between mb-3 sm:mb-4">
<h3 class="text-xs sm:text-sm text-gray-500 font-medium">活跃来源IP</h3>
<div class="p-1.5 sm:p-2 rounded-full bg-success/10 text-success">
<i class="fa fa-globe text-xs sm:text-sm"></i>
</div>
</div>
<div class="mb-2">
<div class="flex items-end justify-between">
<p class="text-2xl sm:text-3xl font-bold" id="active-ips">0</p>
<span class="text-success text-xs sm:text-sm flex items-center">
<i class="fa fa-arrow-up mr-1 text-xs"></i>
<span id="active-ips-percent">0%</span>
</span>
</div>
</div>
</div>
</div>
<!-- DNSSEC使用率卡片 -->
<div class="bg-white rounded-lg p-3 sm:p-4 card-shadow relative overflow-hidden transition-all hover:shadow-md">
<!-- 颜色蒙版 -->
<div class="absolute -bottom-6 -right-6 w-20 h-20 sm:w-24 sm:h-24 rounded-full bg-primary opacity-10"></div>
<div class="relative z-10">
<div class="flex items-center justify-between mb-3 sm:mb-4">
<h3 class="text-xs sm:text-sm text-gray-500 font-medium">DNSSEC使用率</h3>
<div class="p-1.5 sm:p-2 rounded-full bg-primary/10 text-primary">
<i class="fa fa-lock text-xs sm:text-sm"></i>
</div>
</div>
<div class="mb-2">
<div class="flex items-end justify-between">
<p class="text-2xl sm:text-3xl font-bold" id="dnssec-usage">0%</p>
<span class="text-primary text-xs sm:text-sm flex items-center">
<i class="fa fa-check mr-1 text-xs"></i>
<span id="dnssec-status">已禁用</span>
</span>
</div>
</div>
<div class="flex items-center space-x-2 sm:space-x-4 text-xs sm:text-xs text-gray-500">
<div class="flex items-center">
<span class="w-2 h-2 bg-green-500 rounded-full mr-1"></span>
<span>成功: <span id="dnssec-success">0</span></span>
</div>
<div class="flex items-center">
<span class="w-2 h-2 bg-red-500 rounded-full mr-1"></span>
<span>失败: <span id="dnssec-failed">0</span></span>
</div>
<div class="flex items-center">
<span class="w-2 h-2 bg-blue-500 rounded-full mr-1"></span>
<span>总查询: <span id="dnssec-queries">0</span></span>
</div>
</div>
</div>
</div>
</div>
<!-- 图表和数据表格 -->
<div class="grid grid-cols-1 md:grid-cols-2 lg:grid-cols-3 gap-4 sm:gap-6">
<!-- 三个图表在同一行显示 -->
<div class="bg-white rounded-lg p-4 sm:p-6 card-shadow">
<h3 class="text-base sm:text-lg font-semibold mb-3 sm:mb-6">解析与屏蔽比例</h3>
<div class="h-48 sm:h-64 flex items-center justify-center">
<canvas id="ratio-chart"></canvas>
</div>
</div>
<div class="bg-white rounded-lg p-4 sm:p-6 card-shadow">
<h3 class="text-base sm:text-lg font-semibold mb-3 sm:mb-6">解析类型统计</h3>
<div class="h-48 sm:h-64 flex items-center justify-center">
<canvas id="query-type-chart"></canvas>
</div>
</div>
<div class="bg-white rounded-lg p-4 sm:p-6 card-shadow">
<div class="flex items-center justify-between mb-3 sm:mb-6">
<h3 class="text-base sm:text-lg font-semibold">DNS请求趋势</h3>
<!-- 展开按钮 -->
<button id="expand-chart-btn" class="p-1.5 sm:p-2 rounded-full bg-primary/10 text-primary hover:bg-primary/20 transition-colors" title="展开详细图表">
<i class="fa fa-expand text-xs sm:text-sm"></i>
</button>
</div>
<div class="h-48 sm:h-64">
<canvas id="dns-requests-chart"></canvas>
</div>
</div>
</div>
<!-- 详细图表浮窗 -->
<div id="chart-modal" class="fixed inset-0 bg-black/50 flex items-center justify-center z-50 hidden">
<div class="bg-white rounded-lg w-full max-w-5xl max-h-[90vh] overflow-hidden">
<div class="flex items-center justify-between p-6 border-b border-gray-200">
<h3 class="text-lg sm:text-xl font-semibold">DNS请求趋势详细图表</h3>
<div class="flex items-center space-x-4">
<!-- 时间范围切换按钮 -->
<div class="flex space-x-2">
<button class="time-range-btn px-4 py-2 rounded-md bg-primary text-white" data-range="24h">24小时</button>
<button class="time-range-btn px-4 py-2 rounded-md bg-gray-200 text-gray-700 hover:bg-gray-300 transition-colors" data-range="7d">7天</button>
<button class="time-range-btn px-4 py-2 rounded-md bg-gray-200 text-gray-700 hover:bg-gray-300 transition-colors" data-range="30d">30天</button>
</div>
<!-- 关闭按钮 -->
<button id="close-modal-btn" class="p-2 rounded-full bg-gray-200 text-gray-700 hover:bg-gray-300 transition-colors">
<i class="fa fa-times"></i>
</button>
</div>
</div>
<div class="p-6">
<div class="h-full max-h-[calc(90vh-120px)]">
<canvas id="detailed-dns-requests-chart"></canvas>
</div>
</div>
</div>
</div>
<!-- 最近活动表格 -->
<div class="grid grid-cols-1 lg:grid-cols-2 gap-6">
<!-- 被拦截域名排行 -->
<div class="bg-white rounded-lg p-6 card-shadow">
<h3 class="text-base sm:text-lg font-semibold mb-3 sm:mb-4">被拦截域名排行</h3>
<div class="h-64 overflow-y-auto pr-2 scrollbar-thin scrollbar-thumb-gray-300 scrollbar-track-transparent">
<div class="space-y-3" id="top-blocked-table">
<div class="flex items-center justify-between p-3 rounded-md hover:bg-gray-50 transition-colors border-l-4 border-danger">
<div class="flex-1 min-w-0">
<div class="flex items-center">
<span class="w-6 h-6 flex items-center justify-center rounded-full bg-danger/10 text-danger text-xs font-medium mr-3">1</span>
<span class="font-medium truncate">example1.com</span>
</div>
</div>
<span class="ml-4 flex-shrink-0 font-semibold text-danger">150</span>
</div>
<div class="flex items-center justify-between p-3 rounded-md hover:bg-gray-50 transition-colors border-l-4 border-danger">
<div class="flex-1 min-w-0">
<div class="flex items-center">
<span class="w-6 h-6 flex items-center justify-center rounded-full bg-danger/10 text-danger text-xs font-medium mr-3">2</span>
<span class="font-medium truncate">example2.com</span>
</div>
</div>
<span class="ml-4 flex-shrink-0 font-semibold text-danger">130</span>
</div>
<div class="flex items-center justify-between p-3 rounded-md hover:bg-gray-50 transition-colors border-l-4 border-danger">
<div class="flex-1 min-w-0">
<div class="flex items-center">
<span class="w-6 h-6 flex items-center justify-center rounded-full bg-danger/10 text-danger text-xs font-medium mr-3">3</span>
<span class="font-medium truncate">example3.com</span>
</div>
</div>
<span class="ml-4 flex-shrink-0 font-semibold text-danger">120</span>
</div>
<div class="flex items-center justify-between p-3 rounded-md hover:bg-gray-50 transition-colors border-l-4 border-danger">
<div class="flex-1 min-w-0">
<div class="flex items-center">
<span class="w-6 h-6 flex items-center justify-center rounded-full bg-danger/10 text-danger text-xs font-medium mr-3">4</span>
<span class="font-medium truncate">example4.com</span>
</div>
</div>
<span class="ml-4 flex-shrink-0 font-semibold text-danger">110</span>
</div>
<div class="flex items-center justify-between p-3 rounded-md hover:bg-gray-50 transition-colors border-l-4 border-danger">
<div class="flex-1 min-w-0">
<div class="flex items-center">
<span class="w-6 h-6 flex items-center justify-center rounded-full bg-danger/10 text-danger text-xs font-medium mr-3">5</span>
<span class="font-medium truncate">example5.com</span>
</div>
</div>
<span class="ml-4 flex-shrink-0 font-semibold text-danger">100</span>
</div>
</div>
</div>
</div>
<!-- 请求域名排行 -->
<div class="bg-white rounded-lg p-6 card-shadow">
<h3 class="text-base sm:text-lg font-semibold mb-3 sm:mb-4">请求域名排行</h3>
<div class="h-64 overflow-y-auto pr-2 scrollbar-thin scrollbar-thumb-gray-300 scrollbar-track-transparent">
<div class="space-y-3" id="top-domains-table">
<div class="flex items-center justify-between p-3 rounded-md hover:bg-gray-50 transition-colors border-l-4 border-success">
<div class="flex-1 min-w-0">
<div class="flex items-center">
<span class="w-6 h-6 flex items-center justify-center rounded-full bg-success/10 text-success text-xs font-medium mr-3">1</span>
<span class="font-medium truncate">example.com</span>
</div>
</div>
<span class="ml-4 flex-shrink-0 font-semibold text-success">50</span>
</div>
</div>
</div>
</div>
</div>
<!-- 排行表格 -->
<div class="grid grid-cols-1 lg:grid-cols-2 gap-6 mt-6">
<!-- 客户端排行 -->
<div class="bg-white rounded-lg p-6 card-shadow">
<div class="flex items-center justify-between mb-4">
<h3 class="text-base sm:text-lg font-semibold">客户端排行</h3>
<div id="top-clients-loading" class="flex items-center text-sm text-gray-500">
<i class="fa fa-spinner fa-spin mr-2"></i>
<span>加载中...</span>
</div>
<div id="top-clients-error" class="flex items-center text-sm text-danger hidden">
<i class="fa fa-exclamation-circle mr-2"></i>
<span>加载失败</span>
<button id="retry-top-clients" class="ml-2 text-primary hover:underline">重试</button>
</div>
</div>
<div class="h-64 overflow-y-auto pr-2 scrollbar-thin scrollbar-thumb-gray-300 scrollbar-track-transparent">
<div class="space-y-3" id="top-clients-table">
<div class="flex items-center justify-between p-3 rounded-md hover:bg-gray-50 transition-colors border-l-4 border-primary">
<div class="flex-1 min-w-0">
<div class="flex items-center">
<span class="w-6 h-6 flex items-center justify-center rounded-full bg-primary/10 text-primary text-xs font-medium mr-3">1</span>
<span class="font-medium truncate">192.168.1.1</span>
</div>
</div>
<span class="ml-4 flex-shrink-0 font-semibold text-primary">500</span>
</div>
<div class="flex items-center justify-between p-3 rounded-md hover:bg-gray-50 transition-colors border-l-4 border-primary">
<div class="flex-1 min-w-0">
<div class="flex items-center">
<span class="w-6 h-6 flex items-center justify-center rounded-full bg-primary/10 text-primary text-xs font-medium mr-3">2</span>
<span class="font-medium truncate">192.168.1.2</span>
</div>
</div>
<span class="ml-4 flex-shrink-0 font-semibold text-primary">450</span>
</div>
<div class="flex items-center justify-between p-3 rounded-md hover:bg-gray-50 transition-colors border-l-4 border-primary">
<div class="flex-1 min-w-0">
<div class="flex items-center">
<span class="w-6 h-6 flex items-center justify-center rounded-full bg-primary/10 text-primary text-xs font-medium mr-3">3</span>
<span class="font-medium truncate">192.168.1.3</span>
</div>
</div>
<span class="ml-4 flex-shrink-0 font-semibold text-primary">400</span>
</div>
<div class="flex items-center justify-between p-3 rounded-md hover:bg-gray-50 transition-colors border-l-4 border-primary">
<div class="flex-1 min-w-0">
<div class="flex items-center">
<span class="w-6 h-6 flex items-center justify-center rounded-full bg-primary/10 text-primary text-xs font-medium mr-3">4</span>
<span class="font-medium truncate">192.168.1.4</span>
</div>
</div>
<span class="ml-4 flex-shrink-0 font-semibold text-primary">350</span>
</div>
<div class="flex items-center justify-between p-3 rounded-md hover:bg-gray-50 transition-colors border-l-4 border-primary">
<div class="flex-1 min-w-0">
<div class="flex items-center">
<span class="w-6 h-6 flex items-center justify-center rounded-full bg-primary/10 text-primary text-xs font-medium mr-3">5</span>
<span class="font-medium truncate">192.168.1.5</span>
</div>
</div>
<span class="ml-4 flex-shrink-0 font-semibold text-primary">300</span>
</div>
</div>
</div>
</div>
</div>
</div>
<!-- 其他页面内容(初始隐藏) -->
<div id="shield-content" class="hidden space-y-6">
<!-- 屏蔽规则统计信息 -->
<div class="bg-white rounded-lg p-6 card-shadow">
<h3 class="text-base sm:text-lg font-semibold mb-4 sm:mb-6">屏蔽规则统计</h3>
<div class="grid grid-cols-1 sm:grid-cols-2 lg:grid-cols-4 gap-4">
<div class="bg-blue-50 p-4 rounded-lg">
<div class="flex items-center justify-between mb-2">
<h4 class="text-sm font-medium text-gray-500">域名规则</h4>
<i class="fa fa-list text-blue-500"></i>
</div>
<p class="text-2xl font-bold" id="domain-rules-count">0</p>
</div>
<div class="bg-green-50 p-4 rounded-lg">
<div class="flex items-center justify-between mb-2">
<h4 class="text-sm font-medium text-gray-500">域名例外</h4>
<i class="fa fa-check-circle text-green-500"></i>
</div>
<p class="text-2xl font-bold counter" id="domain-exceptions-count">0</p>
</div>
<div class="bg-purple-50 p-4 rounded-lg">
<div class="flex items-center justify-between mb-2">
<h4 class="text-sm font-medium text-gray-500">正则规则</h4>
<i class="fa fa-code text-purple-500"></i>
</div>
<p class="text-2xl font-bold counter" id="regex-rules-count">0</p>
</div>
<div class="bg-yellow-50 p-4 rounded-lg">
<div class="flex items-center justify-between mb-2">
<h4 class="text-sm font-medium text-gray-500">正则例外</h4>
<i class="fa fa-exclamation-circle text-yellow-500"></i>
</div>
<p class="text-2xl font-bold counter" id="regex-exceptions-count">0</p>
</div>
<div class="bg-red-50 p-4 rounded-lg">
<div class="flex items-center justify-between mb-2">
<h4 class="text-sm font-medium text-gray-500">Hosts规则</h4>
<i class="fa fa-file-text text-red-500"></i>
</div>
<p class="text-2xl font-bold counter" id="hosts-rules-count">0</p>
</div>
<div class="bg-indigo-50 p-4 rounded-lg">
<div class="flex items-center justify-between mb-2">
<h4 class="text-sm font-medium text-gray-500">黑名单数量</h4>
<i class="fa fa-ban text-indigo-500"></i>
</div>
<p class="text-2xl font-bold counter" id="blacklist-count">0</p>
<div class="flex items-center justify-between mt-2">
<h5 class="text-xs font-medium text-gray-500">禁用数量</h5>
<p class="text-sm font-bold text-red-600 counter" id="blacklist-disabled-count">0</p>
</div>
</div>
</div>
</div>
<!-- 自定义规则管理 -->
<div class="bg-white rounded-lg p-4 sm:p-6 card-shadow">
<h3 class="text-base sm:text-lg font-semibold mb-4 sm:mb-6">自定义规则管理</h3>
<!-- 添加规则表单 -->
<div id="add-rule-form" class="mb-6 bg-gray-50 p-3 sm:p-4 rounded-lg">
<div class="flex flex-col sm:flex-row items-stretch sm:items-center space-y-3 sm:space-y-0 sm:space-x-3">
<input type="text" id="new-rule" placeholder="输入规则例如example.com 或 regex:/example\.com/" class="flex-1 px-3 sm:px-4 py-2 border border-gray-300 rounded-md focus:outline-none focus:ring-2 focus:ring-primary focus:border-transparent text-sm">
<button id="save-rule-btn" class="px-3 sm:px-4 py-2 bg-success text-white rounded-md hover:bg-success/90 transition-colors text-sm">
保存
</button>
<div id="save-rule-status" class="flex items-center justify-center text-xs sm:text-sm mt-2 sm:mt-0"></div>
</div>
</div>
<!-- 规则列表 -->
<div class="overflow-x-auto">
<table class="min-w-full resizable-table">
<thead>
<tr class="border-b border-gray-200">
<th class="text-left py-2 sm:py-3 px-2 sm:px-4 text-xs sm:text-sm font-medium text-gray-500">规则</th>
<th class="text-center py-2 sm:py-3 px-2 sm:px-4 text-xs sm:text-sm font-medium text-gray-500">状态</th>
<th class="text-right py-2 sm:py-3 px-2 sm:px-4 text-xs sm:text-sm font-medium text-gray-500">操作</th>
</tr>
</thead>
<tbody id="rules-table-body">
<tr>
<td colspan="3" class="py-3 sm:py-4 text-center text-gray-500">暂无规则</td>
</tr>
</tbody>
</table>
</div>
</div>
<!-- 远程黑名单管理 -->
<div class="bg-white rounded-lg p-4 sm:p-6 card-shadow">
<h3 class="text-base sm:text-lg font-semibold mb-4 sm:mb-6">远程黑名单管理</h3>
<!-- 添加黑名单表单 -->
<div id="add-blacklist-form" class="mb-6 bg-gray-50 p-3 sm:p-4 rounded-lg">
<div class="grid grid-cols-1 sm:grid-cols-2 md:grid-cols-3 gap-3 sm:gap-4">
<div>
<label for="blacklist-name" class="block text-xs sm:text-sm font-medium text-gray-700 mb-1">名称</label>
<input type="text" id="blacklist-name" placeholder="输入黑名单名称" class="w-full px-3 sm:px-4 py-2 border border-gray-300 rounded-md focus:outline-none focus:ring-2 focus:ring-primary focus:border-transparent text-sm">
</div>
<div>
<label for="blacklist-url" class="block text-xs sm:text-sm font-medium text-gray-700 mb-1">URL</label>
<input type="text" id="blacklist-url" placeholder="输入黑名单URL" class="w-full px-3 sm:px-4 py-2 border border-gray-300 rounded-md focus:outline-none focus:ring-2 focus:ring-primary focus:border-transparent text-sm">
</div>
<div class="flex flex-col items-start justify-end space-y-2">
<div class="flex items-center space-x-2 w-full">
<button id="save-blacklist-btn" class="flex-1 sm:flex-none px-3 sm:px-4 py-2 bg-success text-white rounded-md hover:bg-success/90 transition-colors text-sm">
保存
</button>
</div>
<div id="save-blacklist-status" class="flex items-center justify-center text-xs sm:text-sm w-full mt-1"></div>
</div>
</div>
</div>
<!-- 黑名单列表 -->
<div class="overflow-x-auto">
<table class="min-w-full resizable-table">
<thead>
<tr class="border-b border-gray-200">
<th class="text-left py-2 sm:py-3 px-2 sm:px-4 text-xs sm:text-sm font-medium text-gray-500">名称</th>
<th class="text-left py-2 sm:py-3 px-2 sm:px-4 text-xs sm:text-sm font-medium text-gray-500">URL</th>
<th class="text-center py-2 sm:py-3 px-2 sm:px-4 text-xs sm:text-sm font-medium text-gray-500">状态</th>
<th class="text-center py-2 sm:py-3 px-2 sm:px-4 text-xs sm:text-sm font-medium text-gray-500"></th>
<th class="text-right py-2 sm:py-3 px-2 sm:px-4 text-xs sm:text-sm font-medium text-gray-500">操作</th>
</tr>
</thead>
<tbody id="blacklists-table-body">
<tr>
<td colspan="5" class="py-3 sm:py-4 text-center text-gray-500">暂无黑名单</td>
</tr>
</tbody>
</table>
</div>
</div>
</div>
<div id="hosts-content" class="hidden space-y-6">
<!-- Hosts管理页面内容 -->
<div class="bg-white rounded-lg p-4 sm:p-6 card-shadow">
<h3 class="text-base sm:text-lg font-semibold mb-4 sm:mb-6">Hosts条目管理</h3>
<!-- 添加hosts条目表单 -->
<div id="add-hosts-form" class="mb-6 bg-gray-50 p-3 sm:p-4 rounded-lg">
<div class="flex flex-col sm:flex-row items-stretch sm:items-center space-y-3 sm:space-y-0 sm:space-x-3">
<input type="text" id="hosts-ip" placeholder="IP地址" class="w-full sm:w-32 px-3 sm:px-4 py-2 border border-gray-300 rounded-md focus:outline-none focus:ring-2 focus:ring-primary focus:border-transparent text-sm">
<input type="text" id="hosts-domain" placeholder="域名" class="flex-1 px-3 sm:px-4 py-2 border border-gray-300 rounded-md focus:outline-none focus:ring-2 focus:ring-primary focus:border-transparent text-sm">
<button id="save-hosts-btn" class="px-3 sm:px-4 py-2 bg-success text-white rounded-md hover:bg-success/90 transition-colors text-sm">
保存
</button>
</div>
</div>
<!-- Hosts列表 -->
<div class="overflow-x-auto">
<table class="min-w-full resizable-table">
<thead>
<tr class="border-b border-gray-200">
<th class="text-left py-2 sm:py-3 px-2 sm:px-4 text-xs sm:text-sm font-medium text-gray-500">IP地址</th>
<th class="text-left py-2 sm:py-3 px-2 sm:px-4 text-xs sm:text-sm font-medium text-gray-500">域名</th>
<th class="text-right py-2 sm:py-3 px-2 sm:px-4 text-xs sm:text-sm font-medium text-gray-500">操作</th>
</tr>
</thead>
<tbody id="hosts-table-body">
<tr>
<td colspan="3" class="py-3 sm:py-4 text-center text-gray-500">暂无Hosts条目</td>
</tr>
</tbody>
</table>
</div>
</div>
</div>
<div id="query-content" class="hidden space-y-6">
<!-- DNS查询表单 -->
<div class="bg-white rounded-lg p-4 sm:p-6 card-shadow">
<h3 class="text-base sm:text-lg font-semibold mb-4 sm:mb-6">DNS查询</h3>
<!-- 查询表单 -->
<div class="flex flex-col sm:flex-row space-y-3 sm:space-y-0 sm:space-x-3">
<div class="flex-1">
<input type="text" id="dns-query-domain" placeholder="输入域名例如example.com" class="w-full px-3 sm:px-4 py-2 sm:py-3 border border-gray-300 rounded-md focus:outline-none focus:ring-2 focus:ring-primary focus:border-transparent text-sm">
</div>
<button id="dns-query-btn" class="px-4 sm:px-6 py-2 sm:py-3 bg-primary text-white rounded-md hover:bg-primary/90 transition-colors text-sm sm:text-base">
<i class="fa fa-search mr-1 sm:mr-2 text-xs sm:text-sm"></i>查询
</button>
</div>
</div>
<!-- 查询结果展示 -->
<div id="query-result" class="bg-white rounded-lg p-4 sm:p-6 card-shadow hidden">
<h3 class="text-base sm:text-lg font-semibold mb-3 sm:mb-4">查询结果</h3>
<div class="space-y-4">
<div class="grid grid-cols-1 md:grid-cols-2 gap-4">
<div class="bg-gray-50 p-4 rounded-lg">
<h4 class="text-sm font-medium text-gray-500 mb-2">域名</h4>
<p class="text-lg font-semibold" id="result-domain">-</p>
</div>
<div class="bg-gray-50 p-4 rounded-lg">
<h4 class="text-sm font-medium text-gray-500 mb-2">状态</h4>
<p class="text-lg font-semibold" id="result-status">-</p>
</div>
<div class="bg-gray-50 p-4 rounded-lg">
<h4 class="text-sm font-medium text-gray-500 mb-2">屏蔽类型</h4>
<p class="text-lg font-semibold" id="result-type">-</p>
</div>
<div class="bg-gray-50 p-4 rounded-lg">
<h4 class="text-sm font-medium text-gray-500 mb-2">查询时间</h4>
<p class="text-lg font-semibold" id="result-time">-</p>
</div>
</div>
<!-- 详细信息 -->
<div class="bg-gray-50 p-4 rounded-lg">
<h4 class="text-sm font-medium text-gray-500 mb-2">详细信息</h4>
<pre class="bg-white p-4 rounded-md border border-gray-200 overflow-x-auto" id="result-details">-</pre>
</div>
</div>
</div>
<!-- 查询历史记录 -->
<div class="bg-white rounded-lg p-6 card-shadow">
<div class="flex items-center justify-between mb-6">
<h3 class="text-lg font-semibold">查询历史</h3>
<button id="clear-history-btn" class="text-sm text-gray-500 hover:text-danger transition-colors">
<i class="fa fa-trash mr-1"></i>清空历史
</button>
</div>
<!-- 历史记录列表 -->
<div id="query-history" class="space-y-2 sm:space-y-3">
<div class="text-center text-gray-500 py-4">
暂无查询历史
</div>
</div>
</div>
</div>
<!-- 查询日志页面 -->
<div id="logs-content" class="hidden space-y-6">
<!-- 日志统计概览 -->
<div class="grid grid-cols-1 sm:grid-cols-2 md:grid-cols-3 lg:grid-cols-4 xl:grid-cols-4 gap-6">
<!-- 总查询数 -->
<div class="bg-blue-50 rounded-lg p-4 card-shadow relative overflow-hidden">
<div class="absolute -bottom-8 -right-8 w-24 h-24 rounded-full bg-primary opacity-10"></div>
<div class="relative z-10">
<div class="flex items-center justify-between mb-4">
<h3 class="text-gray-500 font-medium">总查询数</h3>
<div class="p-2 rounded-full bg-primary/10 text-primary">
<i class="fa fa-refresh"></i>
</div>
</div>
<div class="mb-2">
<div class="flex items-end justify-between">
<p class="text-3xl font-bold" id="logs-total-queries">0</p>
</div>
</div>
</div>
</div>
<!-- 平均响应时间 -->
<div class="bg-white rounded-lg p-4 card-shadow relative overflow-hidden">
<div class="absolute -bottom-8 -right-8 w-24 h-24 rounded-full bg-info opacity-10"></div>
<div class="relative z-10">
<div class="flex items-center justify-between mb-4">
<h3 class="text-gray-500 font-medium">平均响应时间</h3>
<div class="p-2 rounded-full bg-info/10 text-info">
<i class="fa fa-clock-o"></i>
</div>
</div>
<div class="mb-2">
<div class="flex items-end justify-between">
<p class="text-3xl font-bold" id="logs-avg-response-time">0ms</p>
</div>
</div>
</div>
</div>
<!-- 活跃来源IP -->
<div class="bg-white rounded-lg p-4 card-shadow relative overflow-hidden">
<div class="absolute -bottom-8 -right-8 w-24 h-24 rounded-full bg-success opacity-10"></div>
<div class="relative z-10">
<div class="flex items-center justify-between mb-4">
<h3 class="text-gray-500 font-medium">活跃来源IP</h3>
<div class="p-2 rounded-full bg-success/10 text-success">
<i class="fa fa-globe"></i>
</div>
</div>
<div class="mb-2">
<div class="flex items-end justify-between">
<p class="text-3xl font-bold" id="logs-active-ips">0</p>
</div>
</div>
</div>
</div>
<!-- 屏蔽率 -->
<div class="bg-red-50 rounded-lg p-4 card-shadow relative overflow-hidden">
<div class="absolute -bottom-8 -right-8 w-24 h-24 rounded-full bg-danger opacity-10"></div>
<div class="relative z-10">
<div class="flex items-center justify-between mb-4">
<h3 class="text-gray-500 font-medium">屏蔽率</h3>
<div class="p-2 rounded-full bg-danger/10 text-danger">
<i class="fa fa-ban"></i>
</div>
</div>
<div class="mb-2">
<div class="flex items-end justify-between">
<p class="text-3xl font-bold" id="logs-block-rate">0%</p>
</div>
</div>
</div>
</div>
</div>
<!-- 日志搜索和过滤 -->
<div class="bg-white rounded-lg p-4 sm:p-6 card-shadow">
<div class="grid grid-cols-1 sm:grid-cols-2 md:grid-cols-4 gap-3">
<div class="sm:col-span-2">
<input type="text" id="logs-search" placeholder="搜索域名或客户端IP" class="w-full px-3 sm:px-4 py-2 sm:py-3 border border-gray-300 rounded-md focus:outline-none focus:ring-2 focus:ring-primary focus:border-transparent text-sm">
</div>
<div class="w-full">
<select id="logs-result-filter" class="w-full px-3 sm:px-4 py-2 sm:py-3 border border-gray-300 rounded-md focus:outline-none focus:ring-2 focus:ring-primary focus:border-transparent text-sm">
<option value="">全部结果</option>
<option value="allowed">允许</option>
<option value="blocked">屏蔽</option>
<option value="error">错误</option>
</select>
</div>
<div class="w-full">
<select id="logs-per-page" class="w-full px-3 sm:px-4 py-2 sm:py-3 border border-gray-300 rounded-md focus:outline-none focus:ring-2 focus:ring-primary focus:border-transparent text-sm">
<option value="10">10条/页</option>
<option value="20">20条/页</option>
<option value="30" selected>30条/页</option>
<option value="50">50条/页</option>
<option value="100">100条/页</option>
</select>
</div>
<div class="sm:col-span-4 mt-3">
<button id="logs-search-btn" class="w-full sm:w-auto px-4 sm:px-6 py-2 sm:py-3 bg-primary text-white rounded-md hover:bg-primary/90 transition-colors text-sm sm:text-base">
<i class="fa fa-search mr-1 sm:mr-2 text-xs sm:text-sm"></i>搜索
</button>
</div>
</div>
</div>
<!-- 日志趋势图表 -->
<div class="bg-white rounded-lg p-4 sm:p-6 card-shadow">
<div class="flex items-center justify-between mb-4 sm:mb-6">
<h3 class="text-base sm:text-lg font-semibold">查询趋势</h3>
<div class="flex space-x-2">
<button class="time-range-btn px-4 py-2 rounded-md bg-primary text-white" data-range="24h">24小时</button>
<button class="time-range-btn px-4 py-2 rounded-md bg-gray-200 text-gray-700 hover:bg-gray-300 transition-colors" data-range="7d">7天</button>
<button class="time-range-btn px-4 py-2 rounded-md bg-gray-200 text-gray-700 hover:bg-gray-300 transition-colors" data-range="30d">30天</button>
</div>
</div>
<div class="h-64">
<canvas id="logs-trend-chart"></canvas>
</div>
</div>
<!-- 日志详情表格 -->
<div class="bg-white rounded-lg p-4 sm:p-6 card-shadow">
<div class="flex items-center justify-between mb-4 sm:mb-6">
<div class="flex items-center">
<h3 class="text-lg font-semibold">查询日志详情</h3>
<button id="logs-refresh-btn" class="ml-3 p-2 text-gray-500 hover:text-primary hover:bg-gray-100 rounded-full transition-colors" title="刷新日志">
<i class="fa fa-refresh"></i>
</button>
</div>
<div id="logs-loading" class="flex items-center text-sm text-gray-500 hidden">
<i class="fa fa-spinner fa-spin mr-2"></i>
<span>加载中...</span>
</div>
</div>
<div class="overflow-x-auto">
<table class="min-w-full resizable-table">
<thead>
<tr class="border-b border-gray-200">
<th class="text-left py-2 sm:py-3 px-2 sm:px-4 text-xs sm:text-sm font-medium text-gray-500 cursor-pointer hover:text-primary transition-colors" data-sort="time">
<div class="flex items-center">
时间
<i class="fa fa-sort ml-1 text-xs"></i>
</div>
</th>
<th class="text-left py-2 sm:py-3 px-2 sm:px-4 text-xs sm:text-sm font-medium text-gray-500 cursor-pointer hover:text-primary transition-colors" data-sort="clientIp">
<div class="flex items-center">
客户端IP
<i class="fa fa-sort ml-1 text-xs"></i>
</div>
</th>
<th class="text-left py-2 sm:py-3 px-2 sm:px-4 text-xs sm:text-sm font-medium text-gray-500 cursor-pointer hover:text-primary transition-colors" data-sort="domain">
<div class="flex items-center">
请求
<i class="fa fa-sort ml-1 text-xs"></i>
</div>
</th>
<th class="text-left py-2 sm:py-3 px-2 sm:px-4 text-xs sm:text-sm font-medium text-gray-500">响应时间</th>
<th class="text-center py-2 sm:py-3 px-2 sm:px-4 text-xs sm:text-sm font-medium text-gray-500">操作</th>
</tr>
</thead>
<tbody id="logs-table-body">
<tr>
<td colspan="5" class="py-6 sm:py-8 text-center text-gray-500 border-b border-gray-100">
<i class="fa fa-file-text-o text-3xl sm:text-4xl mb-2 text-gray-300"></i>
<div>暂无查询日志</div>
</td>
</tr>
</tbody>
</table>
</div>
<!-- 分页 -->
<div class="flex items-center justify-between mt-6">
<div class="text-sm text-gray-500">
显示 <span id="logs-current-page">1</span> / <span id="logs-total-pages">1</span>
</div>
<div class="flex items-center space-x-4">
<div class="flex items-center space-x-2">
<span class="text-sm text-gray-500">每页显示:</span>
<select id="logs-per-page" class="px-3 py-2 border border-gray-300 rounded-md focus:outline-none focus:ring-2 focus:ring-primary focus:border-transparent">
<option value="10">10条</option>
<option value="20">20条</option>
<option value="30" selected>30条</option>
<option value="50">50条</option>
<option value="100">100条</option>
</select>
</div>
<div class="flex items-center space-x-2">
<span class="text-sm text-gray-500">页码:</span>
<input type="number" id="logs-page-input" min="1" max="1" value="1" class="w-16 px-3 py-2 border border-gray-300 rounded-md focus:outline-none focus:ring-2 focus:ring-primary focus:border-transparent text-center">
<button id="logs-go-page" class="px-4 py-2 bg-primary text-white rounded-md hover:bg-primary/90 transition-colors">
前往
</button>
</div>
<div class="flex space-x-2">
<button id="logs-prev-page" class="px-4 py-2 border border-gray-300 rounded-md text-gray-700 hover:bg-gray-50 focus:outline-none focus:ring-2 focus:ring-gray-500 focus:border-transparent" disabled>
<i class="fa fa-chevron-left"></i>
</button>
<button id="logs-next-page" class="px-4 py-2 border border-gray-300 rounded-md text-gray-700 hover:bg-gray-50 focus:outline-none focus:ring-2 focus:ring-gray-500 focus:border-transparent" disabled>
<i class="fa fa-chevron-right"></i>
</button>
</div>
</div>
</div>
</div>
</div>
<div id="gfwlist-content" class="hidden">
<div class="bg-white rounded-lg p-6 card-shadow">
<h3 class="text-lg font-semibold mb-6">GFWList管理</h3>
<form id="gfwlist-form">
<div class="mb-8">
<h4 class="text-md font-medium mb-4">基本设置</h4>
<div class="grid grid-cols-1 gap-6">
<div>
<div class="flex items-center justify-between">
<div>
<label for="gfwlist-enabled" class="block text-sm font-medium text-gray-700">启用GFWList</label>
<p class="mt-1 text-xs text-gray-500">启用后GFWList中的域名将被解析到指定的目标IP</p>
</div>
<button id="gfwlist-enabled" type="button" class="toggle-btn bg-gray-300 hover:bg-gray-400 text-white font-medium py-1 px-3 rounded-md transition-colors duration-200">
<i class="fa fa-toggle-off"></i>
</button>
</div>
</div>
</div>
</div>
<div class="mb-8">
<h4 class="text-md font-medium mb-4">GFWList解析目标IP</h4>
<div class="grid grid-cols-1 md:grid-cols-2 gap-6">
<div>
<label for="gfwlist-target-ip" class="block text-sm font-medium text-gray-700 mb-1">目标IP地址</label>
<input type="text" id="gfwlist-target-ip" class="w-full px-4 py-2 border border-gray-300 rounded-md focus:outline-none focus:ring-2 focus:ring-primary focus:border-transparent" placeholder="127.0.0.1">
<p class="mt-1 text-xs text-gray-500">GFWList中的域名将被解析到这个IP</p>
</div>
</div>
</div>
<div class="mb-8" id="allowed-sites-section">
<h4 class="text-md font-medium mb-4">通行网站</h4>
<p class="text-sm text-gray-500 mb-4">开启以下开关后对应域名将使用GFWList目标IP进行解析</p>
<div class="grid grid-cols-1 sm:grid-cols-2 md:grid-cols-4 gap-4">
<div class="bg-gray-50 p-4 rounded-lg">
<div class="flex items-center justify-between">
<div class="flex items-center">
<img src="/images/gfwlist/google.png" alt="Google" class="w-5 h-5 mr-2">
<span class="text-sm font-medium text-gray-700">谷歌 (Google)</span>
</div>
<button id="gfwlist-google" type="button" class="toggle-btn bg-gray-300 hover:bg-gray-400 text-white font-medium py-1 px-3 rounded-md transition-colors duration-200">
<i class="fa fa-toggle-off"></i>
</button>
</div>
</div>
<div class="bg-gray-50 p-4 rounded-lg">
<div class="flex items-center justify-between">
<div class="flex items-center">
<img src="/images/gfwlist/youtube.png" alt="YouTube" class="w-5 h-5 mr-2">
<span class="text-sm font-medium text-gray-700">YouTube</span>
</div>
<button id="gfwlist-youtube" type="button" class="toggle-btn bg-gray-300 hover:bg-gray-400 text-white font-medium py-1 px-3 rounded-md transition-colors duration-200">
<i class="fa fa-toggle-off"></i>
</button>
</div>
</div>
<div class="bg-gray-50 p-4 rounded-lg">
<div class="flex items-center justify-between">
<div>
<span class="text-sm font-medium text-gray-700">Facebook</span>
</div>
<button id="gfwlist-facebook" type="button" class="toggle-btn bg-gray-300 hover:bg-gray-400 text-white font-medium py-1 px-3 rounded-md transition-colors duration-200">
<i class="fa fa-toggle-off"></i>
</button>
</div>
</div>
<div class="bg-gray-50 p-4 rounded-lg">
<div class="flex items-center justify-between">
<div>
<span class="text-sm font-medium text-gray-700">X (Twitter)</span>
</div>
<button id="gfwlist-twitter" type="button" class="toggle-btn bg-gray-300 hover:bg-gray-400 text-white font-medium py-1 px-3 rounded-md transition-colors duration-200">
<i class="fa fa-toggle-off"></i>
</button>
</div>
</div>
<div class="bg-gray-50 p-4 rounded-lg">
<div class="flex items-center justify-between">
<div class="flex items-center">
<img src="/images/gfwlist/amazon.png" alt="Amazon" class="w-5 h-5 mr-2">
<span class="text-sm font-medium text-gray-700">Amazon</span>
</div>
<button id="gfwlist-amazon" type="button" class="toggle-btn bg-gray-300 hover:bg-gray-400 text-white font-medium py-1 px-3 rounded-md transition-colors duration-200">
<i class="fa fa-toggle-off"></i>
</button>
</div>
</div>
<div class="bg-gray-50 p-4 rounded-lg">
<div class="flex items-center justify-between">
<div class="flex items-center">
<img src="/images/gfwlist/bbc.png" alt="BBC" class="w-5 h-5 mr-2">
<span class="text-sm font-medium text-gray-700">BBC</span>
</div>
<button id="gfwlist-bbc" type="button" class="toggle-btn bg-gray-300 hover:bg-gray-400 text-white font-medium py-1 px-3 rounded-md transition-colors duration-200">
<i class="fa fa-toggle-off"></i>
</button>
</div>
</div>
<div class="bg-gray-50 p-4 rounded-lg">
<div class="flex items-center justify-between">
<div class="flex items-center">
<img src="/images/gfwlist/discord.png" alt="Discord" class="w-5 h-5 mr-2">
<span class="text-sm font-medium text-gray-700">Discord</span>
</div>
<button id="gfwlist-discord" type="button" class="toggle-btn bg-gray-300 hover:bg-gray-400 text-white font-medium py-1 px-3 rounded-md transition-colors duration-200">
<i class="fa fa-toggle-off"></i>
</button>
</div>
</div>
<div class="bg-gray-50 p-4 rounded-lg">
<div class="flex items-center justify-between">
<div class="flex items-center">
<img src="/images/gfwlist/dropbox.png" alt="Dropbox" class="w-5 h-5 mr-2">
<span class="text-sm font-medium text-gray-700">Dropbox</span>
</div>
<button id="gfwlist-dropbox" type="button" class="toggle-btn bg-gray-300 hover:bg-gray-400 text-white font-medium py-1 px-3 rounded-md transition-colors duration-200">
<i class="fa fa-toggle-off"></i>
</button>
</div>
</div>
<div class="bg-gray-50 p-4 rounded-lg">
<div class="flex items-center justify-between">
<div class="flex items-center">
<img src="/images/gfwlist/microsoft.png" alt="Microsoft" class="w-5 h-5 mr-2">
<span class="text-sm font-medium text-gray-700">Microsoft</span>
</div>
<button id="gfwlist-microsoft" type="button" class="toggle-btn bg-gray-300 hover:bg-gray-400 text-white font-medium py-1 px-3 rounded-md transition-colors duration-200">
<i class="fa fa-toggle-off"></i>
</button>
</div>
</div>
<div class="bg-gray-50 p-4 rounded-lg">
<div class="flex items-center justify-between">
<div class="flex items-center">
<img src="/images/gfwlist/steam.png" alt="Steam" class="w-5 h-5 mr-2">
<span class="text-sm font-medium text-gray-700">Steam</span>
</div>
<button id="gfwlist-steam" type="button" class="toggle-btn bg-gray-300 hover:bg-gray-400 text-white font-medium py-1 px-3 rounded-md transition-colors duration-200">
<i class="fa fa-toggle-off"></i>
</button>
</div>
</div>
<div class="bg-gray-50 p-4 rounded-lg">
<div class="flex items-center justify-between">
<div class="flex items-center">
<img src="/images/gfwlist/telegram.png" alt="Telegram" class="w-5 h-5 mr-2">
<span class="text-sm font-medium text-gray-700">Telegram</span>
</div>
<button id="gfwlist-telegram" type="button" class="toggle-btn bg-gray-300 hover:bg-gray-400 text-white font-medium py-1 px-3 rounded-md transition-colors duration-200">
<i class="fa fa-toggle-off"></i>
</button>
</div>
</div>
<div class="bg-gray-50 p-4 rounded-lg">
<div class="flex items-center justify-between">
<div class="flex items-center">
<img src="/images/gfwlist/tiktok.png" alt="TikTok" class="w-5 h-5 mr-2">
<span class="text-sm font-medium text-gray-700">TikTok</span>
</div>
<button id="gfwlist-tiktok" type="button" class="toggle-btn bg-gray-300 hover:bg-gray-400 text-white font-medium py-1 px-3 rounded-md transition-colors duration-200">
<i class="fa fa-toggle-off"></i>
</button>
</div>
</div>
<div class="bg-gray-50 p-4 rounded-lg">
<div class="flex items-center justify-between">
<div class="flex items-center">
<img src="/images/gfwlist/v2ex.png" alt="V2EX" class="w-5 h-5 mr-2">
<span class="text-sm font-medium text-gray-700">V2EX</span>
</div>
<button id="gfwlist-v2ex" type="button" class="toggle-btn bg-gray-300 hover:bg-gray-400 text-white font-medium py-1 px-3 rounded-md transition-colors duration-200">
<i class="fa fa-toggle-off"></i>
</button>
</div>
</div>
<div class="bg-gray-50 p-4 rounded-lg">
<div class="flex items-center justify-between">
<div class="flex items-center">
<img src="/images/gfwlist/wikimedia.png" alt="Wikimedia" class="w-5 h-5 mr-2">
<span class="text-sm font-medium text-gray-700">Wikimedia</span>
</div>
<button id="gfwlist-wikimedia" type="button" class="toggle-btn bg-gray-300 hover:bg-gray-400 text-white font-medium py-1 px-3 rounded-md transition-colors duration-200">
<i class="fa fa-toggle-off"></i>
</button>
</div>
</div>
<div class="bg-gray-50 p-4 rounded-lg">
<div class="flex items-center justify-between">
<div class="flex items-center">
<img src="/images/gfwlist/yahoo.png" alt="Yahoo" class="w-5 h-5 mr-2">
<span class="text-sm font-medium text-gray-700">Yahoo</span>
</div>
<button id="gfwlist-yahoo" type="button" class="toggle-btn bg-gray-300 hover:bg-gray-400 text-white font-medium py-1 px-3 rounded-md transition-colors duration-200">
<i class="fa fa-toggle-off"></i>
</button>
</div>
</div>
</div>
</div>
<div class="flex justify-end">
<button type="button" id="gfwlist-save-btn" class="px-6 py-2 bg-primary text-white rounded-md hover:bg-primary/90 focus:outline-none focus:ring-2 focus:ring-primary focus:border-transparent">
保存配置
</button>
</div>
</form>
</div>
</div>
<div id="config-content" class="hidden">
<!-- 系统设置页面内容 -->
<div class="bg-white rounded-lg p-6 card-shadow max-w-3xl">
<h3 class="text-lg font-semibold mb-6">系统设置</h3>
<!-- 配置表单 -->
<form id="config-form">
<!-- DNS配置 -->
<div class="mb-8">
<h4 class="text-md font-medium mb-4">DNS服务器配置</h4>
<div class="grid grid-cols-1 sm:grid-cols-2 md:grid-cols-2 gap-6">
<div>
<label for="dns-port" class="block text-sm font-medium text-gray-700 mb-1">端口</label>
<input type="number" id="dns-port" class="w-full px-4 py-2 border border-gray-300 rounded-md focus:outline-none focus:ring-2 focus:ring-primary focus:border-transparent" placeholder="53">
</div>
<div>
<label for="dns-run-mode" class="block text-sm font-medium text-gray-700 mb-1">运行模式</label>
<select id="dns-run-mode" class="w-full px-4 py-2 border border-gray-300 rounded-md focus:outline-none focus:ring-2 focus:ring-primary focus:border-transparent">
<option value="parallel">并行模式</option>
<option value="fast-ip">最快的上游DNS服务器</option>
</select>
</div>
<div class="md:col-span-2">
<label for="dns-upstream-servers" class="block text-sm font-medium text-gray-700 mb-1">上游DNS服务器 (每行一个)</label>
<textarea id="dns-upstream-servers" rows="4" class="w-full px-4 py-2 border border-gray-300 rounded-md focus:outline-none focus:ring-2 focus:ring-primary focus:border-transparent" placeholder="8.8.8.8&#10;1.1.1.1"></textarea>
</div>
<div>
<label for="dns-dnssec-upstream-servers" class="block text-sm font-medium text-gray-700 mb-1">DNSSEC上游DNS服务器 (每行一个)</label>
<textarea id="dns-dnssec-upstream-servers" rows="4" class="w-full px-4 py-2 border border-gray-300 rounded-md focus:outline-none focus:ring-2 focus:ring-primary focus:border-transparent" placeholder="8.8.8.8&#10;1.1.1.1"></textarea>
</div>
<div>
<label for="dns-save-interval" class="block text-sm font-medium text-gray-700 mb-1">保存间隔 (秒)</label>
<input type="number" id="dns-save-interval" class="w-full px-4 py-2 border border-gray-300 rounded-md focus:outline-none focus:ring-2 focus:ring-primary focus:border-transparent" placeholder="300">
</div>
<div>
<label for="dns-cache-mode" class="block text-sm font-medium text-gray-700 mb-1">缓存模式</label>
<select id="dns-cache-mode" class="w-full px-4 py-2 border border-gray-300 rounded-md focus:outline-none focus:ring-2 focus:ring-primary focus:border-transparent">
<option value="memory">内存缓存</option>
<option value="file">文件缓存</option>
</select>
</div>
<div>
<label for="dns-cache-size" class="block text-sm font-medium text-gray-700 mb-1">缓存大小 (MB)</label>
<input type="number" id="dns-cache-size" class="w-full px-4 py-2 border border-gray-300 rounded-md focus:outline-none focus:ring-2 focus:ring-primary focus:border-transparent" placeholder="100">
</div>
<div>
<label for="dns-max-cache-ttl" class="block text-sm font-medium text-gray-700 mb-1">最大缓存TTL (分钟)</label>
<input type="number" id="dns-max-cache-ttl" class="w-full px-4 py-2 border border-gray-300 rounded-md focus:outline-none focus:ring-2 focus:ring-primary focus:border-transparent" placeholder="120">
</div>
<div>
<label for="dns-min-cache-ttl" class="block text-sm font-medium text-gray-700 mb-1">最小缓存TTL (分钟)</label>
<input type="number" id="dns-min-cache-ttl" class="w-full px-4 py-2 border border-gray-300 rounded-md focus:outline-none focus:ring-2 focus:ring-primary focus:border-transparent" placeholder="5">
</div>
<div class="md:col-span-2">
<label class="flex items-center space-x-2">
<input type="checkbox" id="dns-enable-ipv6" class="rounded text-primary focus:ring-primary">
<span class="text-sm font-medium text-gray-700">启用IPv6解析AAAA记录</span>
</label>
</div>
</div>
</div>
<!-- HTTP配置 -->
<div class="mb-8">
<h4 class="text-md font-medium mb-4">HTTP服务器配置</h4>
<div class="grid grid-cols-1 sm:grid-cols-2 md:grid-cols-2 gap-6">
<div>
<label for="http-port" class="block text-sm font-medium text-gray-700 mb-1">端口</label>
<input type="number" id="http-port" class="w-full px-4 py-2 border border-gray-300 rounded-md focus:outline-none focus:ring-2 focus:ring-primary focus:border-transparent" placeholder="8080">
</div>
</div>
</div>
<!-- 屏蔽配置 -->
<div class="mb-8">
<h4 class="text-md font-medium mb-4">屏蔽配置</h4>
<div>
<label for="shield-update-interval" class="block text-sm font-medium text-gray-700 mb-1">更新间隔 (秒)</label>
<input type="number" id="shield-update-interval" class="w-full px-4 py-2 border border-gray-300 rounded-md focus:outline-none focus:ring-2 focus:ring-primary focus:border-transparent" placeholder="3600">
</div>
<div class="mt-4">
<label for="shield-block-method" class="block text-sm font-medium text-gray-700 mb-1">屏蔽方法</label>
<select id="shield-block-method" class="w-full px-4 py-2 border border-gray-300 rounded-md focus:outline-none focus:ring-2 focus:ring-primary focus:border-transparent">
<option value="NXDOMAIN">返回NXDOMAIN</option>
<option value="refused">返回refused</option>
<option value="emptyIP">返回0.0.0.0</option>
<option value="customIP">返回自定义IP</option>
</select>
</div>
<div class="mt-4" id="custom-block-ip-container">
<label for="shield-custom-block-ip" class="block text-sm font-medium text-gray-700 mb-1">自定义屏蔽IP</label>
<input type="text" id="shield-custom-block-ip" class="w-full px-4 py-2 border border-gray-300 rounded-md focus:outline-none focus:ring-2 focus:ring-primary focus:border-transparent" placeholder="127.0.0.1">
</div>
</div>
</div>
<!-- 操作按钮 -->
<div class="flex justify-end space-x-4">
<button type="button" id="restart-service-btn" class="px-6 py-2 border border-gray-300 rounded-md text-gray-700 hover:bg-gray-50 focus:outline-none focus:ring-2 focus:ring-gray-500 focus:border-transparent">
重启服务
</button>
<button type="button" id="save-config-btn" class="px-6 py-2 bg-primary text-white rounded-md hover:bg-primary/90 focus:outline-none focus:ring-2 focus:ring-primary focus:border-transparent">
保存配置
</button>
</div>
</form>
</div>
</div>
</div>
</main>
</div>
<!-- 修改密码模态框 -->
<!-- 日志详情模态框 -->
<div id="log-detail-modal" class="fixed inset-0 bg-black bg-opacity-50 z-50 hidden flex items-center justify-center">
<div class="bg-white rounded-lg shadow-xl p-6 w-full max-w-md">
<div class="flex justify-between items-center mb-4">
<h3 class="text-xl font-semibold">日志详情</h3>
<button id="close-log-modal-btn" class="text-gray-500 hover:text-gray-700 focus:outline-none">
<i class="fa fa-times text-xl"></i>
</button>
</div>
<div id="log-detail-content">
<!-- 日志详情内容将通过JS动态填充 -->
</div>
</div>
</div>
<div id="change-password-modal" class="fixed inset-0 bg-black bg-opacity-50 z-50 hidden flex items-center justify-center">
<div class="bg-white rounded-lg shadow-xl p-6 w-full max-w-md">
<div class="flex justify-between items-center mb-4">
<h3 class="text-xl font-semibold">修改密码</h3>
<button id="close-modal-btn" class="text-gray-500 hover:text-gray-700 focus:outline-none">
<i class="fa fa-times text-xl"></i>
</button>
</div>
<form id="change-password-form">
<div class="mb-4">
<label for="current-password" class="block text-sm font-medium text-gray-700 mb-1">当前密码</label>
<input type="password" id="current-password" name="currentPassword" placeholder="请输入当前密码" class="w-full px-4 py-2 border border-gray-300 rounded-md focus:outline-none focus:ring-2 focus:ring-primary focus:border-transparent" required>
</div>
<div class="mb-4">
<label for="new-password" class="block text-sm font-medium text-gray-700 mb-1">新密码</label>
<input type="password" id="new-password" name="newPassword" placeholder="请输入新密码" class="w-full px-4 py-2 border border-gray-300 rounded-md focus:outline-none focus:ring-2 focus:ring-primary focus:border-transparent" required>
</div>
<div class="mb-6">
<label for="confirm-password" class="block text-sm font-medium text-gray-700 mb-1">确认密码</label>
<input type="password" id="confirm-password" name="confirmPassword" placeholder="请再次输入新密码" class="w-full px-4 py-2 border border-gray-300 rounded-md focus:outline-none focus:ring-2 focus:ring-primary focus:border-transparent" required>
<div id="password-mismatch" class="text-danger text-sm mt-1 hidden">新密码和确认密码不匹配</div>
</div>
<div class="flex items-center justify-end space-x-3">
<button type="button" id="cancel-change-password" class="px-4 py-2 bg-gray-200 text-gray-700 rounded-md hover:bg-gray-300 transition-colors">取消</button>
<button type="submit" id="save-password-btn" class="px-4 py-2 bg-primary text-white rounded-md hover:bg-primary/90 transition-colors">保存</button>
</div>
</form>
</div>
</div>
<!-- 脚本 -->
<script src="js/main.js"></script>
<script src="js/api.js"></script>
<script src="js/dashboard.js"></script>
<script src="js/shield.js"></script>
<script src="js/hosts.js"></script>
<script src="js/query.js"></script>
<script src="js/logs.js"></script>
<script src="js/config.js"></script>
<!-- 直接渲染滚动列表的静态HTML内容 -->
</body>
</html>