Files
dns-server/api/index.html
2025-11-29 19:32:55 +08:00

1767 lines
80 KiB
HTML
Raw 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">
<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>