This commit is contained in:
Alex Yang
2026-03-30 01:04:46 +08:00
parent 050aa421b1
commit f627244b8f
5978 changed files with 1502187 additions and 2947 deletions
+38 -173
View File
@@ -121,10 +121,9 @@ if (typeof trackersDatabase === 'undefined') {
var trackersLoading = false;
}
// 域名信息数据库缓存
let domainInfoDatabase = null;
let domainInfoLoaded = false;
let domainInfoLoading = false;
// 域名信息缓存(用于 API 调用)
let domainInfoCache = {};
let domainInfoCacheLoading = {};
// WebSocket连接和重连计时器
let logsWsConnection = null;
@@ -163,43 +162,51 @@ async function loadTrackersDatabase() {
}
}
// 加载域名信息数据库
async function loadDomainInfoDatabase() {
if (domainInfoLoaded) {
return domainInfoDatabase;
// 从 API 获取域名信息
async function getDomainInfoFromAPI(domain) {
// 检查缓存
if (domainInfoCache[domain]) {
return domainInfoCache[domain];
}
if (domainInfoLoading) {
// 等待正在进行的加载完成
while (domainInfoLoading) {
// 检查是否正在加载中
if (domainInfoCacheLoading[domain]) {
while (domainInfoCacheLoading[domain]) {
await new Promise(resolve => setTimeout(resolve, 100));
}
return domainInfoDatabase;
return domainInfoCache[domain] || null;
}
domainInfoLoading = true;
domainInfoCacheLoading[domain] = true;
try {
const response = await fetch('domain-info/domains/domain-info.json');
const response = await fetch(`/api/domain-info?domains=${encodeURIComponent(domain)}`);
if (!response.ok) {
console.error('加载域名信息数据库失败,HTTP状态:', response.status, response.statusText);
console.error('请求URL:', response.url);
domainInfoDatabase = { domains: {}, categories: {} };
return domainInfoDatabase;
console.error('获取域名信息失败:', response.statusText);
return null;
}
domainInfoDatabase = await response.json();
domainInfoLoaded = true;
return domainInfoDatabase;
const data = await response.json();
// API 返回的是数组,取第一个匹配的结果
if (Array.isArray(data) && data.length > 0) {
const info = data[0];
// 缓存结果
domainInfoCache[domain] = {
name: info.name || '未知',
icon: info.icon || null,
category: info.category || '未知',
company: info.company || '未知'
};
return domainInfoCache[domain];
}
return null;
} catch (error) {
console.error('加载域名信息数据库失败,错误信息:', error.message);
console.error('错误堆栈:', error.stack);
domainInfoDatabase = { domains: {}, categories: {} };
return domainInfoDatabase;
console.error('获取域名信息失败:', error);
return null;
} finally {
domainInfoLoading = false;
domainInfoCacheLoading[domain] = false;
}
}
@@ -238,152 +245,10 @@ async function isDomainInTrackerDatabase(domain) {
return null;
}
// 根据域名查找对应的网站信息
// 根据域名查找对应的网站信息(使用 API
async function getDomainInfo(domain) {
if (!domainInfoDatabase || !domainInfoLoaded) {
await loadDomainInfoDatabase();
}
if (!domainInfoDatabase || !domainInfoDatabase.domains) {
console.error('域名信息数据库无效或为空');
return null;
}
// 规范化域名,移除可能的端口号
const normalizedDomain = domain.replace(/:\d+$/, '').toLowerCase();
// 遍历所有公司
for (const companyKey in domainInfoDatabase.domains) {
if (domainInfoDatabase.domains.hasOwnProperty(companyKey)) {
const companyData = domainInfoDatabase.domains[companyKey];
const companyName = companyData.company || companyKey;
// 遍历公司下的所有网站和类别
for (const websiteKey in companyData) {
if (companyData.hasOwnProperty(websiteKey) && websiteKey !== 'company') {
const website = companyData[websiteKey];
// 如果有URL属性,直接检查域名
if (website.url) {
// 处理字符串类型的URL
if (typeof website.url === 'string') {
if (isDomainMatch(website.url, normalizedDomain, website.categoryId)) {
return {
name: website.name,
icon: website.icon,
categoryId: website.categoryId,
categoryName: domainInfoDatabase.categories[website.categoryId] || '未知',
company: website.company || companyName
};
}
}
// 处理对象类型的URL
else if (typeof website.url === 'object') {
for (const urlKey in website.url) {
if (website.url.hasOwnProperty(urlKey)) {
const urlValue = website.url[urlKey];
if (isDomainMatch(urlValue, normalizedDomain, website.categoryId)) {
return {
name: website.name,
icon: website.icon,
categoryId: website.categoryId,
categoryName: domainInfoDatabase.categories[website.categoryId] || '未知',
company: website.company || companyName
};
}
}
}
}
} else if (typeof website === 'object' && website !== null) {
// 没有URL属性,可能是嵌套的类别
for (const nestedWebsiteKey in website) {
if (website.hasOwnProperty(nestedWebsiteKey) && nestedWebsiteKey !== 'company') {
const nestedWebsite = website[nestedWebsiteKey];
if (nestedWebsite.url) {
// 处理字符串类型的URL
if (typeof nestedWebsite.url === 'string') {
if (isDomainMatch(nestedWebsite.url, normalizedDomain, nestedWebsite.categoryId)) {
return {
name: nestedWebsite.name,
icon: nestedWebsite.icon,
categoryId: nestedWebsite.categoryId,
categoryName: domainInfoDatabase.categories[nestedWebsite.categoryId] || '未知',
company: nestedWebsite.company || companyName
};
}
}
// 处理对象类型的URL
else if (typeof nestedWebsite.url === 'object') {
for (const urlKey in nestedWebsite.url) {
if (nestedWebsite.url.hasOwnProperty(urlKey)) {
const urlValue = nestedWebsite.url[urlKey];
if (isDomainMatch(urlValue, normalizedDomain, nestedWebsite.categoryId)) {
return {
name: nestedWebsite.name,
icon: nestedWebsite.icon,
categoryId: nestedWebsite.categoryId,
categoryName: domainInfoDatabase.categories[nestedWebsite.categoryId] || '未知',
company: nestedWebsite.company || companyName
};
}
}
}
}
} else if (typeof nestedWebsite === 'object' && nestedWebsite !== null) {
// 嵌套类别中的嵌套类别,递归检查
for (const secondNestedWebsiteKey in nestedWebsite) {
if (nestedWebsite.hasOwnProperty(secondNestedWebsiteKey) && secondNestedWebsiteKey !== 'company') {
const secondNestedWebsite = nestedWebsite[secondNestedWebsiteKey];
if (secondNestedWebsite.url) {
// 处理字符串类型的URL
if (typeof secondNestedWebsite.url === 'string') {
if (isDomainMatch(secondNestedWebsite.url, normalizedDomain, secondNestedWebsite.categoryId)) {
return {
name: secondNestedWebsite.name,
icon: secondNestedWebsite.icon,
categoryId: secondNestedWebsite.categoryId,
categoryName: domainInfoDatabase.categories[secondNestedWebsite.categoryId] || '未知',
company: secondNestedWebsite.company || companyName
};
}
}
// 处理对象类型的URL
else if (typeof secondNestedWebsite.url === 'object') {
for (const urlKey in secondNestedWebsite.url) {
if (secondNestedWebsite.url.hasOwnProperty(urlKey)) {
const urlValue = secondNestedWebsite.url[urlKey];
if (isDomainMatch(urlValue, normalizedDomain, secondNestedWebsite.categoryId)) {
return {
name: secondNestedWebsite.name,
icon: secondNestedWebsite.icon,
categoryId: secondNestedWebsite.categoryId,
categoryName: domainInfoDatabase.categories[secondNestedWebsite.categoryId] || '未知',
company: secondNestedWebsite.company || companyName
};
}
}
}
}
}
}
}
} else {
}
}
}
} else {
}
}
}
}
}
return null;
return await getDomainInfoFromAPI(domain);
}
// 检查域名是否匹配
function isDomainMatch(urlValue, targetDomain, categoryId) {
@@ -1931,7 +1796,7 @@ async function showLogDetailModal(log) {
<div class="mt-1">
<div class="flex items-center mb-1 flex-wrap">
<span class="text-gray-500 dark:text-gray-400 mr-2">类别:</span>
<span class="flex-grow">${domainInfo.categoryName || '未知'}</span>
<span class="flex-grow">${domainInfo.category || '未知'}</span>
</div>
<div class="flex items-center flex-wrap">
<span class="text-gray-500 dark:text-gray-400 mr-2">所属单位/公司:</span>