更新
This commit is contained in:
+38
-173
@@ -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>
|
||||
|
||||
Reference in New Issue
Block a user