Files
dns-server/api/index.html
T
2025-11-29 19:30:47 +08:00

1767 lines
80 KiB
HTML

<!DOCTYPE html>
<html lang="zh-CN">
<head>
<meta charset="UTF-8">
<title>DNS Server API 文档</title>
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<link rel="stylesheet" type="text/css" href="https://cdnjs.cloudflare.com/ajax/libs/swagger-ui/4.18.3/swagger-ui.css">
<style>
/* 基础样式 */
body {
margin: 0;
padding: 0;
font-family: -apple-system, BlinkMacSystemFont, "Segoe UI", Roboto, "Helvetica Neue", Arial, sans-serif;
background-color: #ffffff;
color: #333333;
transition: background-color 0.3s ease, color 0.3s ease;
}
/* 顶部导航控制容器 */
.topbar-controls {
display: flex;
align-items: center;
gap: 15px;
margin-left: auto;
}
/* 主题切换按钮 */
.theme-toggle-btn {
padding: 8px 12px;
background-color: transparent;
border: 1px solid transparent;
border-radius: 4px;
cursor: pointer;
font-size: 13px;
display: flex;
align-items: center;
gap: 6px;
transition: all 0.3s ease;
color: inherit;
}
.theme-toggle-btn:hover {
background-color: rgba(255, 255, 255, 0.1);
border-color: rgba(255, 255, 255, 0.2);
}
/* 浅色主题下的样式 */
.swagger-ui .topbar .topbar-wrapper .theme-toggle-btn {
color: #ecf0f1;
}
.swagger-ui .topbar .topbar-wrapper .theme-toggle-btn:hover {
background-color: rgba(255, 255, 255, 0.1);
}
/* 深色主题下的样式 */
body.dark-mode .swagger-ui .topbar .topbar-wrapper .theme-toggle-btn {
color: #e2e8f0;
}
body.dark-mode .swagger-ui .topbar .topbar-wrapper .theme-toggle-btn:hover {
background-color: rgba(255, 255, 255, 0.08);
border-color: rgba(255, 255, 255, 0.15);
}
/* 默认浅色主题样式 */
.swagger-ui .topbar {
background-color: #2c3e50;
padding: 15px 0;
}
.swagger-ui .topbar .topbar-wrapper .link {
color: #ecf0f1;
font-size: 1.2rem;
}
.swagger-ui .info {
margin: 20px 0;
}
.swagger-ui .info .title {
font-size: 2rem;
margin-bottom: 10px;
color: #333;
}
.swagger-ui .info .description {
font-size: 1rem;
color: #555;
margin-bottom: 15px;
}
/* 深色主题样式 - 增强版,提高所有文字对比度和可读性 */
body.dark-mode {
background-color: #1a1a1a;
color: #ffffff; /* 提高默认文字颜色亮度 */
}
body.dark-mode #theme-toggle {
background-color: #2d3748;
color: #ffffff; /* 提高主题切换按钮文字亮度 */
border-color: #4a5568;
}
body.dark-mode #theme-toggle:hover {
background-color: #4a5568;
}
body.dark-mode .swagger-ui {
background-color: #1a1a1a;
color: #ffffff; /* 提高整体文字颜色亮度 */
}
body.dark-mode .swagger-ui .topbar {
background-color: #1a202c;
}
body.dark-mode .swagger-ui .topbar .topbar-wrapper .link {
color: #ffffff; /* 提高顶部导航文字亮度 */
}
body.dark-mode .swagger-ui .info .title {
color: #ffffff;
}
body.dark-mode .swagger-ui .info .description {
color: #f8f9fa; /* 提高描述文字亮度 */
}
/* Swagger UI 深色模式组件样式 */
body.dark-mode .swagger-ui .opblock {
background-color: #2d3748;
border-color: #4a5568;
}
/* 增加深色模式下的标题和标签颜色 */
body.dark-mode .swagger-ui .opblock-tag {
color: #ffffff;
font-weight: 600;
}
body.dark-mode .swagger-ui .opblock-section-header h4 {
color: #ffffff;
font-weight: 600;
}
/* 增加深色模式下的按钮文字颜色 */
body.dark-mode .swagger-ui .btn {
color: #ffffff;
font-weight: 500;
}
/* 增加深色模式下的列表项颜色 */
body.dark-mode .swagger-ui .servers-title {
color: #ffffff;
font-weight: 600;
}
body.dark-mode .swagger-ui .servers li.server {
color: #ffffff; /* 提高服务器列表文字亮度 */
}
/* 增加深色模式下的过滤器文字颜色 */
body.dark-mode .swagger-ui .filter {
color: #ffffff; /* 提高过滤器文字亮度 */
}
/* 增加深色模式下的Tab文字颜色 */
body.dark-mode .swagger-ui .tab {
color: #ffffff; /* 提高标签页文字亮度 */
}
body.dark-mode .swagger-ui .tab.active {
color: #ffffff;
}
body.dark-mode .swagger-ui .opblock .opblock-summary {
background-color: #374151;
}
body.dark-mode .swagger-ui .opblock.opblock-get {
border-color: #3182ce;
}
body.dark-mode .swagger-ui .opblock.opblock-post {
border-color: #38a169;
}
body.dark-mode .swagger-ui .opblock.opblock-put {
border-color: #d69e2e;
}
body.dark-mode .swagger-ui .opblock.opblock-delete {
border-color: #e53e3e;
}
body.dark-mode .swagger-ui .opblock.opblock-patch {
border-color: #805ad5;
}
body.dark-mode .swagger-ui .opblock .opblock-summary-method {
background-color: #1a202c;
color: #ffffff; /* 提高方法标签文字亮度 */
}
body.dark-mode .swagger-ui .opblock-description-wrapper,
body.dark-mode .swagger-ui .opblock-external-docs-wrapper,
body.dark-mode .swagger-ui .opblock-title_normal {
color: #ffffff; /* 提高操作块描述文字亮度 */
}
body.dark-mode .swagger-ui .tab {
background-color: #374151;
color: #ffffff; /* 提高标签文字亮度 */
}
body.dark-mode .swagger-ui .tab.active {
background-color: #1a202c;
color: #ffffff;
}
body.dark-mode .swagger-ui .parameter__name,
body.dark-mode .swagger-ui .parameter__type {
color: #ffffff; /* 提高参数文字亮度 */
}
body.dark-mode .swagger-ui table thead tr {
background-color: #374151;
}
body.dark-mode .swagger-ui table tbody tr td {
border-color: #4a5568;
color: #ffffff; /* 提高表格单元格文字亮度 */
}
body.dark-mode .swagger-ui table tbody tr:nth-child(even) {
background-color: #2d3748;
}
/* 提高模型和类型文字亮度 */
body.dark-mode .swagger-ui .model-title {
color: #ffffff;
font-weight: 600;
}
body.dark-mode .swagger-ui .model-box {
background-color: #2d3748;
border-color: #4a5568;
}
body.dark-mode .swagger-ui .model-box .model-jump-to {
color: #63b3ed;
}
body.dark-mode .swagger-ui .model-title {
color: #ffffff;
}
/* 提高Markdown内容文字亮度 */
body.dark-mode .swagger-ui .markdown,
body.dark-mode .swagger-ui .markdown p {
color: #ffffff;
}
body.dark-mode .swagger-ui .markdown a {
color: #63b3ed;
}
/* 提高响应列文字亮度 */
body.dark-mode .swagger-ui .response-col_status {
color: #ffffff;
}
body.dark-mode .swagger-ui .response-col_links {
color: #63b3ed;
}
body.dark-mode .swagger-ui .execute-wrapper .btn.execute {
background-color: #3182ce;
border-color: #3182ce;
color: #ffffff;
}
body.dark-mode .swagger-ui .execute-wrapper .btn.execute:hover {
background-color: #2c5aa0;
border-color: #2c5aa0;
}
body.dark-mode .swagger-ui .auth-wrapper {
background-color: #2d3748;
}
body.dark-mode .swagger-ui .auth-wrapper .auth-btn {
background-color: #3182ce;
color: #ffffff;
}
/* 提高输入框文字亮度 */
body.dark-mode .swagger-ui textarea,
body.dark-mode .swagger-ui input[type="text"],
body.dark-mode .swagger-ui input[type="email"],
body.dark-mode .swagger-ui input[type="password"] {
background-color: #1a202c;
color: #ffffff; /* 提高输入框文字亮度 */
border-color: #4a5568;
}
/* 提高过滤器相关文字亮度 */
body.dark-mode .swagger-ui .filter {
background-color: #2d3748;
border-color: #4a5568;
color: #ffffff;
}
body.dark-mode .swagger-ui .filter .options {
background-color: #2d3748;
border-color: #4a5568;
}
body.dark-mode .swagger-ui .filter .options li:hover {
background-color: #4a5568;
}
body.dark-mode .swagger-ui .btn {
color: #ffffff;
}
body.dark-mode .swagger-ui .btn.cancel {
background-color: #4a5568;
border-color: #4a5568;
color: #ffffff;
}
body.dark-mode .swagger-ui .btn.cancel:hover {
background-color: #718096;
border-color: #718096;
}
/* 新增:提高路径文字亮度 */
body.dark-mode .swagger-ui .opblock-summary-path {
color: #ffffff;
font-weight: 500;
}
/* 新增:提高描述和文本内容亮度 */
body.dark-mode .swagger-ui .description,
body.dark-mode .swagger-ui .info_description,
body.dark-mode .swagger-ui .info .title small {
color: #ffffff;
}
/* 新增:提高响应示例文字亮度 */
body.dark-mode .swagger-ui .response-example {
color: #ffffff;
}
/* 新增:提高代码块文字亮度 */
body.dark-mode .swagger-ui .microlight {
color: #ffffff;
}
/* 新增:提高展开/折叠指示器文字亮度 */
body.dark-mode .swagger-ui .expand-operation,
body.dark-mode .swagger-ui .expand {
color: #ffffff;
}
/* 新增:提高错误和成功消息文字亮度 */
body.dark-mode .swagger-ui .response-error {
color: #ffffff;
}
body.dark-mode .swagger-ui .response-success {
color: #ffffff;
}
/* 新增:提高参数描述文字亮度 */
body.dark-mode .swagger-ui .parameter__description {
color: #ffffff;
}
/* 新增:提高枚举值文字亮度 */
body.dark-mode .swagger-ui .enum {
color: #ffffff;
}
/* 新增:适配API文档展开界面的所有文字元素 */
body.dark-mode .swagger-ui .opblock-body {
color: #ffffff;
}
body.dark-mode .swagger-ui .opblock-body .parameter__name {
color: #ffffff;
}
body.dark-mode .swagger-ui .opblock-body .parameter__type {
color: #ffffff;
}
body.dark-mode .swagger-ui .opblock-body .parameter__description {
color: #ffffff;
}
body.dark-mode .swagger-ui .opblock-body .body-param-options {
color: #ffffff;
}
body.dark-mode .swagger-ui .opblock-body .body-param-options .body-param-type {
color: #ffffff;
}
body.dark-mode .swagger-ui .responses-inner {
color: #ffffff;
}
body.dark-mode .swagger-ui .responses-inner h4 {
color: #ffffff;
}
body.dark-mode .swagger-ui .response-container {
color: #ffffff;
}
body.dark-mode .swagger-ui .response-container .response-wrapper {
color: #ffffff;
}
body.dark-mode .swagger-ui .response-container .response-code {
color: #ffffff;
}
body.dark-mode .swagger-ui .response-container .response-description {
color: #ffffff;
}
body.dark-mode .swagger-ui .model {
color: #ffffff;
}
body.dark-mode .swagger-ui .model .property {
color: #ffffff;
}
body.dark-mode .swagger-ui .model .property .property-name {
color: #ffffff;
}
body.dark-mode .swagger-ui .model .property .property-description {
color: #ffffff;
}
body.dark-mode .swagger-ui .model .property .property-type {
color: #ffffff;
}
body.dark-mode .swagger-ui .model .property .required {
color: #ffffff;
}
body.dark-mode .swagger-ui .scroll-to-top {
color: #ffffff;
}
body.dark-mode .swagger-ui .opblock-tag-section {
color: #ffffff;
}
body.dark-mode .swagger-ui .servers-title {
color: #ffffff;
}
body.dark-mode .swagger-ui .servers {
color: #ffffff;
}
body.dark-mode .swagger-ui .servers li {
color: #ffffff;
}
body.dark-mode .swagger-ui .servers li label {
color: #ffffff;
}
body.dark-mode .swagger-ui .servers li select {
color: #ffffff;
background-color: #1a202c;
border-color: #4a5568;
}
body.dark-mode .swagger-ui .auth-wrapper {
color: #ffffff;
}
body.dark-mode .swagger-ui .auth-wrapper .auth-title {
color: #ffffff;
}
body.dark-mode .swagger-ui .auth-wrapper .auth-list {
color: #ffffff;
}
body.dark-mode .swagger-ui .auth-wrapper .auth-item {
color: #ffffff;
}
body.dark-mode .swagger-ui .auth-wrapper .auth-item label {
color: #ffffff;
}
/* 确保代码块内的文字也清晰可见 */
body.dark-mode .swagger-ui pre {
color: #ffffff;
}
body.dark-mode .swagger-ui code {
color: #ffffff;
}
/* 确保所有表单元素的文字颜色正确 */
body.dark-mode .swagger-ui form {
color: #ffffff;
}
body.dark-mode .swagger-ui form label {
color: #ffffff;
}
body.dark-mode .swagger-ui select {
color: #ffffff;
background-color: #1a202c;
border-color: #4a5568;
}
/* 适配可能的嵌套内容 */
body.dark-mode .swagger-ui .opblock-body .schema {
color: #ffffff;
}
body.dark-mode .swagger-ui .opblock-body .schema .title {
color: #ffffff;
}
body.dark-mode .swagger-ui .opblock-body .schema .required {
color: #ffffff;
}
/* 适配可能的按钮组 */
body.dark-mode .swagger-ui .btn-group {
color: #ffffff;
}
/* 适配可能的标签 */
body.dark-mode .swagger-ui .tag {
color: #ffffff;
}
/* 适配可能的警告和提示信息 */
body.dark-mode .swagger-ui .warning {
color: #ffffff;
}
body.dark-mode .swagger-ui .hint {
color: #ffffff;
}
/* 适配可能的表格内容 */
body.dark-mode .swagger-ui table {
color: #ffffff;
}
body.dark-mode .swagger-ui table th {
color: #ffffff;
}
body.dark-mode .swagger-ui table td {
color: #ffffff;
}
/* 响应式设计 */
@media (max-width: 768px) {
.topbar-controls {
flex-direction: column;
align-items: flex-end;
gap: 10px;
}
.theme-toggle-btn {
padding: 6px 10px;
font-size: 12px;
}
.theme-toggle-btn span {
display: none;
}
}
</style>
</head>
<body>
<div id="swagger-ui"></div>
<script src="https://cdnjs.cloudflare.com/ajax/libs/swagger-ui/4.18.3/swagger-ui-bundle.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/swagger-ui/4.18.3/swagger-ui-standalone-preset.js"></script>
<script>
// 定义API文档的JSON
const swaggerDocument = {
"openapi": "3.0.3",
"info": {
"title": "DNS Server API",
"description": "DNS服务器完整API文档,包括统计信息、Shield管理、主机管理等功能。",
"version": "1.1.0",
"contact": {
"name": "DNS Server 支持",
"email": "support@dnsserver.com"
},
"license": {
"name": "Apache 2.0",
"url": "http://www.apache.org/licenses/LICENSE-2.0.html"
}
},
"servers": [
{
"url": "http://localhost:8080/api",
"description": "本地开发服务器"
},
{
"url": "http://{host}:{port}/api",
"description": "自定义服务器",
"variables": {
"host": {
"default": "localhost"
},
"port": {
"default": "8080"
}
}
}
],
"paths": {
"/stats": {
"get": {
"summary": "获取系统统计信息",
"description": "获取DNS服务器和Shield的详细统计信息,包括查询量、CPU使用率等。",
"tags": ["stats"],
"responses": {
"200": {
"description": "成功获取统计信息",
"content": {
"application/json": {
"schema": {
"type": "object",
"properties": {
"dns": {
"type": "object",
"properties": {
"Queries": {"type": "integer", "description": "总查询次数"},
"Blocked": {"type": "integer", "description": "被阻止的查询次数"},
"Allowed": {"type": "integer", "description": "允许的查询次数"},
"Errors": {"type": "integer", "description": "错误查询次数"},
"LastQuery": {"type": "string", "description": "最近一次查询时间"},
"AvgResponseTime": {"type": "number", "description": "平均响应时间(毫秒)"},
"TotalResponseTime": {"type": "number", "description": "总响应时间(毫秒)"},
"QueryTypes": {"type": "object", "description": "查询类型统计"},
"SourceIPs": {"type": "object", "description": "来源IP统计"},
"CpuUsage": {"type": "number", "description": "CPU使用率(百分比)"}
}
},
"shield": {"type": "object", "description": "Shield统计信息"},
"topQueryType": {"type": "string", "description": "最常见的查询类型"},
"activeIPs": {"type": "integer", "description": "活跃IP数量"},
"avgResponseTime": {"type": "number", "description": "平均响应时间(毫秒)"},
"cpuUsage": {"type": "number", "description": "CPU使用率(百分比)"},
"time": {"type": "string", "description": "统计时间"}
}
},
"examples": {
"default": {
"value": {
"dns": {
"Queries": 1250,
"Blocked": 230,
"Allowed": 1020,
"Errors": 0,
"LastQuery": "2023-07-15T14:30:45Z",
"AvgResponseTime": 12.5,
"TotalResponseTime": 15625,
"QueryTypes": {"A": 850, "AAAA": 250, "CNAME": 150},
"SourceIPs": {"192.168.1.100": 500, "192.168.1.101": 750},
"CpuUsage": 0.15
},
"shield": {},
"topQueryType": "A",
"activeIPs": 2,
"avgResponseTime": 12.5,
"cpuUsage": 0.15,
"time": "2023-07-15T14:30:45Z"
}
}
}
}
}
},
"500": {
"description": "服务器内部错误",
"content": {
"application/json": {
"schema": {
"type": "object",
"properties": {
"error": {"type": "string", "description": "错误信息"}
}
},
"example": {"error": "无法获取统计信息"}
}
}
}
}
}
},
"/stats/query-types": {
"get": {
"summary": "获取查询类型统计",
"description": "获取DNS查询类型的详细统计信息。",
"tags": ["stats"],
"responses": {
"200": {
"description": "成功获取查询类型统计",
"content": {
"application/json": {
"schema": {
"type": "array",
"items": {
"type": "object",
"properties": {
"type": {"type": "string", "description": "查询类型"},
"count": {"type": "integer", "description": "查询次数"}
}
}
},
"example": [
{"type": "A", "count": 850},
{"type": "AAAA", "count": 250},
{"type": "CNAME", "count": 150}
]
}
}
}
}
}
},
"/stats/top-clients": {
"get": {
"summary": "获取TOP客户端",
"description": "获取查询量最多的客户端IP列表。",
"tags": ["stats"],
"responses": {
"200": {
"description": "成功获取TOP客户端",
"content": {
"application/json": {
"schema": {
"type": "array",
"items": {
"type": "object",
"properties": {
"ip": {"type": "string", "description": "客户端IP地址"},
"count": {"type": "integer", "description": "查询次数"}
}
}
},
"example": [
{"ip": "192.168.1.100", "count": 500},
{"ip": "192.168.1.101", "count": 750}
]
}
}
}
}
}
},
"/stats/top-domains": {
"get": {
"summary": "获取TOP域名",
"description": "获取查询量最多的域名列表。",
"tags": ["stats"],
"responses": {
"200": {
"description": "成功获取TOP域名",
"content": {
"application/json": {
"schema": {
"type": "array",
"items": {
"type": "object",
"properties": {
"domain": {"type": "string", "description": "域名"},
"count": {"type": "integer", "description": "查询次数"}
}
}
},
"example": [
{"domain": "example.com", "count": 150},
{"domain": "google.com", "count": 120}
]
}
}
}
}
}
},
"/shield": {
"get": {
"summary": "获取Shield配置",
"description": "获取Shield的完整配置信息,包括启用状态、规则等。",
"tags": ["shield"],
"responses": {
"200": {
"description": "成功获取配置信息",
"content": {
"application/json": {
"schema": {
"type": "object",
"properties": {
"enabled": {"type": "boolean", "description": "是否启用Shield"},
"rulesCount": {"type": "integer", "description": "规则数量"},
"lastUpdate": {"type": "string", "description": "最后更新时间"},
"blacklists": {"type": "array", "description": "黑名单列表", "items": {"type": "object"}}
}
},
"example": {
"enabled": true,
"rulesCount": 5000,
"lastUpdate": "2023-07-15T10:00:00Z",
"blacklists": []
}
}
}
},
"500": {
"description": "服务器内部错误",
"content": {
"application/json": {
"schema": {
"type": "object",
"properties": {
"error": {"type": "string", "description": "错误信息"}
}
},
"example": {"error": "无法获取Shield配置"}
}
}
}
}
},
"post": {
"summary": "更新Shield配置",
"description": "更新Shield的全局配置信息。",
"tags": ["shield"],
"requestBody": {
"required": true,
"content": {
"application/json": {
"schema": {
"type": "object",
"properties": {
"enabled": {"type": "boolean", "description": "是否启用Shield"},
"updateInterval": {"type": "integer", "description": "更新间隔(秒)"}
}
},
"example": {
"enabled": true,
"updateInterval": 3600
}
}
}
},
"responses": {
"200": {
"description": "成功更新配置",
"content": {
"application/json": {
"schema": {
"type": "object",
"properties": {
"status": {"type": "string", "description": "操作状态"}
}
},
"example": {"status": "success"}
}
}
},
"400": {
"description": "请求参数错误",
"content": {
"application/json": {
"schema": {
"type": "object",
"properties": {
"error": {"type": "string", "description": "错误信息"}
}
},
"example": {"error": "参数格式错误"}
}
}
},
"500": {
"description": "服务器内部错误",
"content": {
"application/json": {
"schema": {
"type": "object",
"properties": {
"error": {"type": "string", "description": "错误信息"}
}
},
"example": {"error": "更新配置失败"}
}
}
}
}
},
"put": {
"summary": "重启Shield",
"description": "重新加载和应用Shield规则。",
"tags": ["shield"],
"responses": {
"200": {
"description": "成功重启Shield",
"content": {
"application/json": {
"schema": {
"type": "object",
"properties": {
"status": {"type": "string", "description": "操作状态"}
}
},
"example": {"status": "success"}
}
}
},
"500": {
"description": "服务器内部错误",
"content": {
"application/json": {
"schema": {
"type": "object",
"properties": {
"error": {"type": "string", "description": "错误信息"}
}
},
"example": {"error": "重启失败"}
}
}
}
}
}
},
"/shield/stats": {
"get": {
"summary": "获取Shield统计信息",
"description": "获取Shield的详细统计信息,包括拦截数量等。",
"tags": ["shield"],
"responses": {
"200": {
"description": "成功获取统计信息",
"content": {
"application/json": {
"schema": {
"type": "object",
"properties": {
"blockedCount": {"type": "integer", "description": "已拦截数量"},
"rulesCount": {"type": "integer", "description": "规则数量"},
"lastBlocked": {"type": "string", "description": "最近拦截时间"}
}
},
"example": {
"blockedCount": 1500,
"rulesCount": 5000,
"lastBlocked": "2023-07-15T14:25:30Z"
}
}
}
}
}
}
},
"/shield/top-blocked-domains": {
"get": {
"summary": "获取TOP被拦截域名",
"description": "获取被Shield拦截最多的域名列表。",
"tags": ["shield"],
"responses": {
"200": {
"description": "成功获取TOP被拦截域名",
"content": {
"application/json": {
"schema": {
"type": "array",
"items": {
"type": "object",
"properties": {
"domain": {"type": "string", "description": "被拦截的域名"},
"count": {"type": "integer", "description": "拦截次数"},
"lastSeen": {"type": "string", "description": "最近一次拦截时间"}
}
}
},
"example": [
{"domain": "ads.example.com", "count": 150, "lastSeen": "2023-07-15T14:25:30Z"},
{"domain": "tracking.example.org", "count": 120, "lastSeen": "2023-07-15T14:20:15Z"}
]
}
}
}
}
}
},
"/shield/recent-blocked-domains": {
"get": {
"summary": "获取最近被拦截域名",
"description": "获取最近被Shield拦截的域名列表。",
"tags": ["shield"],
"responses": {
"200": {
"description": "成功获取最近被拦截域名",
"content": {
"application/json": {
"schema": {
"type": "array",
"items": {
"type": "object",
"properties": {
"domain": {"type": "string", "description": "被拦截的域名"},
"ip": {"type": "string", "description": "请求来源IP"},
"timestamp": {"type": "string", "description": "拦截时间"}
}
}
},
"example": [
{"domain": "ads.example.com", "ip": "192.168.1.100", "timestamp": "2023-07-15T14:25:30Z"},
{"domain": "tracking.example.org", "ip": "192.168.1.101", "timestamp": "2023-07-15T14:20:15Z"}
]
}
}
}
}
}
},
"/shield/blacklists": {
"get": {
"summary": "获取黑名单列表",
"description": "获取所有远程黑名单的列表及详细信息。",
"tags": ["shield"],
"responses": {
"200": {
"description": "成功获取黑名单列表",
"content": {
"application/json": {
"schema": {
"type": "array",
"items": {
"type": "object",
"properties": {
"name": {"type": "string", "description": "黑名单名称"},
"url": {"type": "string", "description": "黑名单URL"},
"enabled": {"type": "boolean", "description": "是否启用"},
"lastUpdate": {"type": "string", "description": "最后更新时间"},
"status": {"type": "string", "description": "状态"},
"rulesCount": {"type": "integer", "description": "规则数量"}
}
}
},
"example": [
{
"name": "AdBlock List",
"url": "https://example.com/ads.txt",
"enabled": true,
"lastUpdate": "2023-07-15T10:00:00Z",
"status": "active",
"rulesCount": 1500
}
]
}
}
},
"500": {
"description": "服务器内部错误",
"content": {
"application/json": {
"schema": {
"type": "object",
"properties": {
"error": {"type": "string", "description": "错误信息"}
}
},
"example": {"error": "获取黑名单列表失败"}
}
}
}
}
},
"post": {
"summary": "添加黑名单",
"description": "添加新的远程黑名单URL。",
"tags": ["shield"],
"requestBody": {
"required": true,
"content": {
"application/json": {
"schema": {
"type": "object",
"required": ["name", "url"],
"properties": {
"name": {"type": "string", "description": "黑名单名称"},
"url": {"type": "string", "description": "黑名单URL"},
"enabled": {"type": "boolean", "description": "是否启用", "default": true}
}
},
"example": {
"name": "AdBlock List",
"url": "https://example.com/ads.txt",
"enabled": true
}
}
}
},
"responses": {
"200": {
"description": "成功添加黑名单",
"content": {
"application/json": {
"schema": {
"type": "object",
"properties": {
"status": {"type": "string", "description": "操作状态"}
}
},
"example": {"status": "success"}
}
}
},
"400": {
"description": "请求参数错误",
"content": {
"application/json": {
"schema": {
"type": "object",
"properties": {
"error": {"type": "string", "description": "错误信息"}
}
},
"example": {"error": "名称和URL为必填项"}
}
}
},
"500": {
"description": "服务器内部错误",
"content": {
"application/json": {
"schema": {
"type": "object",
"properties": {
"error": {"type": "string", "description": "错误信息"}
}
},
"example": {"error": "添加黑名单失败"}
}
}
}
}
},
"put": {
"summary": "更新黑名单",
"description": "更新黑名单的配置信息。",
"tags": ["shield"],
"requestBody": {
"required": true,
"content": {
"application/json": {
"schema": {
"type": "object",
"required": ["name"],
"properties": {
"name": {"type": "string", "description": "黑名单名称"},
"url": {"type": "string", "description": "黑名单URL"},
"enabled": {"type": "boolean", "description": "是否启用"}
}
},
"example": {
"name": "AdBlock List",
"url": "https://example.com/ads_new.txt",
"enabled": false
}
}
}
},
"responses": {
"200": {
"description": "成功更新黑名单",
"content": {
"application/json": {
"schema": {
"type": "object",
"properties": {
"status": {"type": "string", "description": "操作状态"}
}
},
"example": {"status": "success"}
}
}
},
"400": {
"description": "请求参数错误",
"content": {
"application/json": {
"schema": {
"type": "object",
"properties": {
"error": {"type": "string", "description": "错误信息"}
}
},
"example": {"error": "参数格式错误"}
}
}
},
"404": {
"description": "黑名单不存在",
"content": {
"application/json": {
"schema": {
"type": "object",
"properties": {
"error": {"type": "string", "description": "错误信息"}
}
},
"example": {"error": "黑名单不存在"}
}
}
},
"500": {
"description": "服务器内部错误",
"content": {
"application/json": {
"schema": {
"type": "object",
"properties": {
"error": {"type": "string", "description": "错误信息"}
}
},
"example": {"error": "更新黑名单失败"}
}
}
}
}
},
"patch": {
"summary": "批量更新黑名单状态",
"description": "批量更新多个黑名单的启用状态。",
"tags": ["shield"],
"requestBody": {
"required": true,
"content": {
"application/json": {
"schema": {
"type": "object",
"properties": {
"names": {"type": "array", "description": "黑名单名称列表", "items": {"type": "string"}},
"enabled": {"type": "boolean", "description": "是否启用"}
}
},
"example": {
"names": ["AdBlock List", "Tracking List"],
"enabled": true
}
}
}
},
"responses": {
"200": {
"description": "成功批量更新",
"content": {
"application/json": {
"schema": {
"type": "object",
"properties": {
"status": {"type": "string", "description": "操作状态"}
}
},
"example": {"status": "success"}
}
}
}
}
}
},
"/shield/blacklists/{name}": {
"delete": {
"summary": "删除黑名单",
"description": "根据名称删除指定的远程黑名单。",
"tags": ["shield"],
"parameters": [
{
"name": "name",
"in": "path",
"required": true,
"schema": {
"type": "string"
},
"description": "黑名单名称"
}
],
"responses": {
"200": {
"description": "成功删除黑名单",
"content": {
"application/json": {
"schema": {
"type": "object",
"properties": {
"status": {"type": "string", "description": "操作状态"}
}
},
"example": {"status": "success"}
}
}
},
"404": {
"description": "黑名单不存在",
"content": {
"application/json": {
"schema": {
"type": "object",
"properties": {
"error": {"type": "string", "description": "错误信息"}
}
},
"example": {"error": "黑名单不存在"}
}
}
},
"500": {
"description": "服务器内部错误",
"content": {
"application/json": {
"schema": {
"type": "object",
"properties": {
"error": {"type": "string", "description": "错误信息"}
}
},
"example": {"error": "删除黑名单失败"}
}
}
}
}
}
},
"/shield/blacklists/{name}/update": {
"post": {
"summary": "手动更新黑名单",
"description": "手动触发指定黑名单的更新操作。",
"tags": ["shield"],
"parameters": [
{
"name": "name",
"in": "path",
"required": true,
"schema": {
"type": "string"
},
"description": "黑名单名称"
}
],
"responses": {
"200": {
"description": "成功开始更新",
"content": {
"application/json": {
"schema": {
"type": "object",
"properties": {
"status": {"type": "string", "description": "操作状态"}
}
},
"example": {"status": "updating"}
}
}
},
"404": {
"description": "黑名单不存在",
"content": {
"application/json": {
"schema": {
"type": "object",
"properties": {
"error": {"type": "string", "description": "错误信息"}
}
},
"example": {"error": "黑名单不存在"}
}
}
}
}
}
},
"/hosts": {
"get": {
"summary": "获取主机配置",
"description": "获取当前的hosts配置信息。",
"tags": ["hosts"],
"responses": {
"200": {
"description": "成功获取hosts配置",
"content": {
"application/json": {
"schema": {
"type": "object",
"properties": {
"entries": {"type": "array", "description": "hosts条目列表", "items": {"type": "object"}},
"count": {"type": "integer", "description": "条目数量"}
}
},
"example": {
"entries": [],
"count": 0
}
}
}
}
}
},
"post": {
"summary": "更新hosts配置",
"description": "更新hosts配置内容。",
"tags": ["hosts"],
"requestBody": {
"required": true,
"content": {
"application/json": {
"schema": {
"type": "object",
"properties": {
"content": {"type": "string", "description": "hosts文件内容"}
}
},
"example": {
"content": "127.0.0.1 localhost\n192.168.1.1 example.com"
}
}
}
},
"responses": {
"200": {
"description": "成功更新hosts",
"content": {
"application/json": {
"schema": {
"type": "object",
"properties": {
"status": {"type": "string", "description": "操作状态"}
}
},
"example": {"status": "success"}
}
}
},
"400": {
"description": "请求参数错误",
"content": {
"application/json": {
"schema": {
"type": "object",
"properties": {
"error": {"type": "string", "description": "错误信息"}
}
},
"example": {"error": "参数格式错误"}
}
}
}
}
}
},
"/server/status": {
"get": {
"summary": "获取服务器状态",
"description": "获取DNS服务器的运行状态信息。",
"tags": ["server"],
"responses": {
"200": {
"description": "成功获取服务器状态",
"content": {
"application/json": {
"schema": {
"type": "object",
"properties": {
"status": {"type": "string", "description": "服务器状态"},
"uptime": {"type": "integer", "description": "运行时间(秒)"},
"version": {"type": "string", "description": "服务器版本"}
}
},
"example": {
"status": "running",
"uptime": 3600,
"version": "1.0.0"
}
}
}
}
}
}
},
"/server/config": {
"get": {
"summary": "获取服务器配置",
"description": "获取DNS服务器的配置信息。",
"tags": ["server"],
"responses": {
"200": {
"description": "成功获取服务器配置",
"content": {
"application/json": {
"schema": {
"type": "object",
"properties": {
"port": {"type": "integer", "description": "DNS服务端口"},
"httpPort": {"type": "integer", "description": "HTTP服务端口"},
"upstreamServers": {"type": "array", "description": "上游DNS服务器", "items": {"type": "string"}}
}
},
"example": {
"port": 53,
"httpPort": 8080,
"upstreamServers": ["8.8.8.8", "1.1.1.1"]
}
}
}
}
}
}
}
},
"tags": [
{
"name": "stats",
"description": "统计信息相关API - 获取系统运行统计、查询类型、客户端和域名统计等"
},
{
"name": "shield",
"description": "Shield功能相关API - 管理拦截规则、黑名单配置和拦截统计"
},
{
"name": "hosts",
"description": "主机配置API - 管理hosts文件配置"
},
{
"name": "server",
"description": "服务器管理API - 获取服务器状态和配置信息"
}
],
"components": {
"schemas": {
"ErrorResponse": {
"type": "object",
"properties": {
"error": {"type": "string", "description": "错误信息"}
}
},
"SuccessResponse": {
"type": "object",
"properties": {
"status": {"type": "string", "description": "操作状态", "enum": ["success", "error", "updating"]}
}
}
}
}
};
// 主题切换功能实现
function setupThemeToggle() {
// 检查本地存储的主题偏好
const savedTheme = localStorage.getItem('swagger-theme');
const prefersDark = window.matchMedia('(prefers-color-scheme: dark)').matches;
// 初始化主题
if (savedTheme === 'dark' || (!savedTheme && prefersDark)) {
enableDarkMode();
} else {
disableDarkMode();
}
// 切换主题函数
function enableDarkMode() {
document.body.classList.add('dark-mode');
localStorage.setItem('swagger-theme', 'dark');
}
function disableDarkMode() {
document.body.classList.remove('dark-mode');
localStorage.setItem('swagger-theme', 'light');
}
// 主题切换处理函数
function handleThemeToggle(themeToggle, themeText, themeIcon) {
if (document.body.classList.contains('dark-mode')) {
disableDarkMode();
themeText.textContent = '切换深色模式';
themeIcon.innerHTML = `
<circle cx="12" cy="12" r="5"></circle>
<line x1="12" y1="1" x2="12" y2="3"></line>
<line x1="12" y1="21" x2="12" y2="23"></line>
<line x1="4.22" y1="4.22" x2="5.64" y2="5.64"></line>
<line x1="18.36" y1="18.36" x2="19.78" y2="19.78"></line>
<line x1="1" y1="12" x2="3" y2="12"></line>
<line x1="21" y1="12" x2="23" y2="12"></line>
<line x1="4.22" y1="19.78" x2="5.64" y2="18.36"></line>
<line x1="18.36" y1="5.64" x2="19.78" y2="4.22"></line>
`;
} else {
enableDarkMode();
themeText.textContent = '切换浅色模式';
themeIcon.innerHTML = `
<path d="M21 12.79A9 9 0 1 1 11.21 3 7 7 0 0 0 21 12.79z"></path>
`;
}
}
// 监听系统主题变化
window.matchMedia('(prefers-color-scheme: dark)').addEventListener('change', (e) => {
// 只有当用户没有手动设置主题时,才跟随系统变化
if (!localStorage.getItem('swagger-theme')) {
if (e.matches) {
enableDarkMode();
} else {
disableDarkMode();
}
}
});
return { handleThemeToggle };
}
// 初始化Swagger UI和主题功能
window.onload = function() {
// 先设置主题切换的基础功能
const { handleThemeToggle } = setupThemeToggle();
// 然后初始化Swagger UI
const ui = SwaggerUIBundle({
spec: swaggerDocument,
dom_id: '#swagger-ui',
deepLinking: true,
presets: [
SwaggerUIBundle.presets.apis,
SwaggerUIStandalonePreset
],
plugins: [
SwaggerUIBundle.plugins.DownloadUrl,
// 自定义插件:将主题切换按钮添加到顶部导航区域
function() {
return {
wrapComponents: {
Topbar: function(Original) {
return class extends Original {
render() {
// 渲染原始顶部导航
const result = super.render();
// 创建主题切换按钮
const themeToggle = document.createElement('button');
themeToggle.id = 'theme-toggle';
themeToggle.setAttribute('aria-label', '切换主题');
themeToggle.className = 'theme-toggle-btn';
// 添加图标
const themeIcon = document.createElementNS('http://www.w3.org/2000/svg', 'svg');
themeIcon.id = 'theme-icon';
themeIcon.setAttribute('width', '16');
themeIcon.setAttribute('height', '16');
themeIcon.setAttribute('viewBox', '0 0 24 24');
themeIcon.setAttribute('fill', 'none');
themeIcon.setAttribute('stroke', 'currentColor');
themeIcon.setAttribute('stroke-width', '2');
themeIcon.setAttribute('stroke-linecap', 'round');
themeIcon.setAttribute('stroke-linejoin', 'round');
// 添加文本
const themeText = document.createElement('span');
themeText.id = 'theme-text';
// 根据当前主题设置图标和文本
if (document.body.classList.contains('dark-mode')) {
themeText.textContent = '切换浅色模式';
themeIcon.innerHTML = `<path d="M21 12.79A9 9 0 1 1 11.21 3 7 7 0 0 0 21 12.79z"></path>`;
} else {
themeText.textContent = '切换深色模式';
themeIcon.innerHTML = `
<circle cx="12" cy="12" r="5"></circle>
<line x1="12" y1="1" x2="12" y2="3"></line>
<line x1="12" y1="21" x2="12" y2="23"></line>
<line x1="4.22" y1="4.22" x2="5.64" y2="5.64"></line>
<line x1="18.36" y1="18.36" x2="19.78" y2="19.78"></line>
<line x1="1" y1="12" x2="3" y2="12"></line>
<line x1="21" y1="12" x2="23" y2="12"></line>
<line x1="4.22" y1="19.78" x2="5.64" y2="18.36"></line>
<line x1="18.36" y1="5.64" x2="19.78" y2="4.22"></line>
`;
}
// 组装按钮
themeToggle.appendChild(themeIcon);
themeToggle.appendChild(themeText);
// 添加点击事件
themeToggle.addEventListener('click', () => {
handleThemeToggle(themeToggle, themeText, themeIcon);
});
// 找到搜索框容器并添加主题切换按钮
setTimeout(() => {
const searchContainer = document.querySelector('.swagger-ui .topbar .topbar-wrapper');
if (searchContainer) {
// 创建一个容器来放置搜索框和主题按钮
const controlsContainer = document.createElement('div');
controlsContainer.className = 'topbar-controls';
// 找到现有的搜索框
const searchBox = searchContainer.querySelector('.download-url-wrapper');
if (searchBox) {
// 移除搜索框
searchContainer.removeChild(searchBox);
// 将搜索框和主题按钮添加到新容器
controlsContainer.appendChild(searchBox);
controlsContainer.appendChild(themeToggle);
// 将新容器添加到顶部导航
searchContainer.appendChild(controlsContainer);
} else {
// 如果找不到搜索框,直接添加主题按钮
searchContainer.appendChild(themeToggle);
}
}
}, 100);
return result;
}
};
}
}
};
}
],
layout: "StandaloneLayout",
// 添加自定义UI配置
tryItOutEnabled: true,
showRequestHeaders: true,
filter: true,
docExpansion: "list",
defaultModelsExpandDepth: 2,
defaultModelExpandDepth: 2,
persistAuthorization: true
});
window.ui = ui;
};
</script>
</body>
</html>