Files
dns-server/js/query.js
2025-11-29 19:32:55 +08:00

301 lines
9.5 KiB
JavaScript
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.
// DNS查询页面功能实现
// 初始化查询页面
function initQueryPage() {
console.log('初始化DNS查询页面...');
setupQueryEventListeners();
loadQueryHistory();
}
// 执行DNS查询
async function handleDNSQuery() {
const domainInput = document.getElementById('dns-query-domain');
const resultDiv = document.getElementById('query-result');
if (!domainInput || !resultDiv) {
console.error('找不到必要的DOM元素');
return;
}
const domain = domainInput.value.trim();
if (!domain) {
showErrorMessage('请输入域名');
return;
}
try {
const response = await fetch(`/api/query?domain=${encodeURIComponent(domain)}`);
if (!response.ok) {
throw new Error('查询失败');
}
const result = await response.json();
displayQueryResult(result, domain);
saveQueryHistory(domain, result);
loadQueryHistory();
} catch (error) {
console.error('DNS查询出错:', error);
showErrorMessage('查询失败,请稍后重试');
}
}
// 显示查询结果
function displayQueryResult(result, domain) {
const resultDiv = document.getElementById('query-result');
if (!resultDiv) return;
// 显示结果容器
resultDiv.classList.remove('hidden');
// 解析结果
const status = result.blocked ? '被屏蔽' : '正常';
const statusClass = result.blocked ? 'text-danger' : 'text-success';
const blockType = result.blocked ? result.blockRuleType || '未知' : '正常';
const blockRule = result.blocked ? result.blockRule || '未知' : '无';
const blockSource = result.blocked ? result.blocksource || '未知' : '无';
const timestamp = new Date(result.timestamp).toLocaleString();
// 更新结果显示
document.getElementById('result-domain').textContent = domain;
document.getElementById('result-status').innerHTML = `<span class="${statusClass}">${status}</span>`;
document.getElementById('result-type').textContent = blockType;
// 检查是否存在屏蔽规则显示元素,如果不存在则创建
let blockRuleElement = document.getElementById('result-block-rule');
if (!blockRuleElement) {
// 创建屏蔽规则显示区域
const grid = resultDiv.querySelector('.grid');
if (grid) {
const newGridItem = document.createElement('div');
newGridItem.className = 'bg-gray-50 p-4 rounded-lg';
newGridItem.innerHTML = `
<h4 class="text-sm font-medium text-gray-500 mb-2">屏蔽规则</h4>
<p class="text-lg font-semibold" id="result-block-rule">-</p>
`;
grid.appendChild(newGridItem);
blockRuleElement = document.getElementById('result-block-rule');
}
}
// 更新屏蔽规则显示
if (blockRuleElement) {
blockRuleElement.textContent = blockRule;
}
// 检查是否存在屏蔽来源显示元素,如果不存在则创建
let blockSourceElement = document.getElementById('result-block-source');
if (!blockSourceElement) {
// 创建屏蔽来源显示区域
const grid = resultDiv.querySelector('.grid');
if (grid) {
const newGridItem = document.createElement('div');
newGridItem.className = 'bg-gray-50 p-4 rounded-lg';
newGridItem.innerHTML = `
<h4 class="text-sm font-medium text-gray-500 mb-2">屏蔽来源</h4>
<p class="text-lg font-semibold" id="result-block-source">-</p>
`;
grid.appendChild(newGridItem);
blockSourceElement = document.getElementById('result-block-source');
}
}
// 更新屏蔽来源显示
if (blockSourceElement) {
blockSourceElement.textContent = blockSource;
}
document.getElementById('result-time').textContent = timestamp;
document.getElementById('result-details').textContent = JSON.stringify(result, null, 2);
}
// 保存查询历史
function saveQueryHistory(domain, result) {
// 获取现有历史记录
let history = JSON.parse(localStorage.getItem('dnsQueryHistory') || '[]');
// 创建历史记录项
const historyItem = {
domain: domain,
timestamp: new Date().toISOString(),
result: {
blocked: result.blocked,
blockRuleType: result.blockRuleType,
blockRule: result.blockRule,
blocksource: result.blocksource
}
};
// 添加到历史记录开头
history.unshift(historyItem);
// 限制历史记录数量
if (history.length > 20) {
history = history.slice(0, 20);
}
// 保存到本地存储
localStorage.setItem('dnsQueryHistory', JSON.stringify(history));
}
// 加载查询历史
function loadQueryHistory() {
const historyDiv = document.getElementById('query-history');
if (!historyDiv) return;
// 获取历史记录
const history = JSON.parse(localStorage.getItem('dnsQueryHistory') || '[]');
if (history.length === 0) {
historyDiv.innerHTML = '<div class="text-center text-gray-500 py-4">暂无查询历史</div>';
return;
}
// 生成历史记录HTML
const historyHTML = history.map(item => {
const statusClass = item.result.blocked ? 'text-danger' : 'text-success';
const statusText = item.result.blocked ? '被屏蔽' : '正常';
const blockType = item.result.blocked ? item.result.blockRuleType : '正常';
const blockRule = item.result.blocked ? item.result.blockRule : '无';
const blockSource = item.result.blocked ? item.result.blocksource : '无';
const formattedTime = new Date(item.timestamp).toLocaleString();
return `
<div class="flex flex-col md:flex-row justify-between items-start md:items-center p-3 bg-gray-50 rounded-lg hover:bg-gray-100 transition-colors">
<div class="flex-1">
<div class="flex items-center space-x-2">
<span class="font-medium">${item.domain}</span>
<span class="${statusClass} text-sm">${statusText}</span>
<span class="text-xs text-gray-500">${blockType}</span>
</div>
<div class="text-xs text-gray-500 mt-1">规则: ${blockRule}</div>
<div class="text-xs text-gray-500 mt-1">来源: ${blockSource}</div>
<div class="text-xs text-gray-500 mt-1">${formattedTime}</div>
</div>
<button class="mt-2 md:mt-0 px-3 py-1 bg-primary text-white text-sm rounded-md hover:bg-primary/90 transition-colors" onclick="requeryFromHistory('${item.domain}')">
<i class="fa fa-refresh mr-1"></i>重新查询
</button>
</div>
`;
}).join('');
historyDiv.innerHTML = historyHTML;
}
// 从历史记录重新查询
function requeryFromHistory(domain) {
const domainInput = document.getElementById('dns-query-domain');
if (domainInput) {
domainInput.value = domain;
handleDNSQuery();
}
}
// 清空查询历史
function clearQueryHistory() {
if (confirm('确定要清空所有查询历史吗?')) {
localStorage.removeItem('dnsQueryHistory');
loadQueryHistory();
showSuccessMessage('查询历史已清空');
}
}
// 设置事件监听器
function setupQueryEventListeners() {
// 查询按钮事件
const queryBtn = document.getElementById('dns-query-btn');
if (queryBtn) {
queryBtn.addEventListener('click', handleDNSQuery);
}
// 输入框回车键事件
const domainInput = document.getElementById('dns-query-domain');
if (domainInput) {
domainInput.addEventListener('keypress', (e) => {
if (e.key === 'Enter') {
e.preventDefault();
handleDNSQuery();
}
});
}
// 清空历史按钮事件
const clearHistoryBtn = document.getElementById('clear-history-btn');
if (clearHistoryBtn) {
clearHistoryBtn.addEventListener('click', clearQueryHistory);
}
}
// 显示成功消息
function showSuccessMessage(message) {
showNotification(message, 'success');
}
// 显示错误消息
function showErrorMessage(message) {
showNotification(message, 'error');
}
// 显示通知
function showNotification(message, type = 'info') {
// 移除现有通知
const existingNotification = document.querySelector('.notification');
if (existingNotification) {
existingNotification.remove();
}
// 创建新通知
const notification = document.createElement('div');
notification.className = `notification fixed bottom-4 right-4 px-6 py-3 rounded-lg shadow-lg z-50 transform transition-all duration-300 ease-in-out translate-y-0 opacity-0`;
// 设置通知样式
if (type === 'success') {
notification.classList.add('bg-green-500', 'text-white');
} else if (type === 'error') {
notification.classList.add('bg-red-500', 'text-white');
} else {
notification.classList.add('bg-blue-500', 'text-white');
}
notification.innerHTML = `
<div class="flex items-center space-x-2">
<i class="fa ${type === 'success' ? 'fa-check-circle' : type === 'error' ? 'fa-exclamation-circle' : 'fa-info-circle'}"></i>
<span>${message}</span>
</div>
`;
document.body.appendChild(notification);
// 显示通知
setTimeout(() => {
notification.classList.remove('opacity-0');
notification.classList.add('opacity-100');
}, 10);
// 3秒后隐藏通知
setTimeout(() => {
notification.classList.remove('opacity-100');
notification.classList.add('opacity-0');
setTimeout(() => {
notification.remove();
}, 300);
}, 3000);
}
// 页面加载完成后初始化
if (document.readyState === 'loading') {
document.addEventListener('DOMContentLoaded', initQueryPage);
} else {
initQueryPage();
}
// 当切换到DNS查询页面时重新加载数据
document.addEventListener('DOMContentLoaded', () => {
// 监听hash变化当切换到DNS查询页面时重新加载数据
window.addEventListener('hashchange', () => {
if (window.location.hash === '#query') {
initQueryPage();
}
});
});