feat(Footer): 添加多服务器节点检测功能

在页脚添加多服务器节点检测功能,支持显示多个服务的节点状态和图标。修改了配置类型和组件逻辑,现在可以显示多个服务的节点信息,包括博客本体、Umami和随机图服务的节点状态。
This commit is contained in:
二叉树树
2026-01-11 03:06:37 +08:00
parent 4b53d01ab0
commit 292f3b07b8
3 changed files with 113 additions and 58 deletions

View File

@@ -1,7 +1,7 @@
---
import { execSync } from "node:child_process";
import { profileConfig } from "../config";
import { profileConfig, siteConfig } from "../config";
import { url } from "../utils/url-utils";
const currentYear = new Date().getFullYear();
@@ -47,73 +47,119 @@ try {
<a class="transition link text-[var(--primary)] font-medium inline-flex items-center" href="https://beian.miit.gov.cn/#/Integrated/index" target="_blank"><img alt="" src="/favicon/foot-icp.png" class="h-4 mr-1">皖ICP备2025099787号-2</a>
<br>
<div class="server-info-wrapper flex items-center justify-center">
<span class="server-info text-black/30 dark:text-white/30 text-xs"></span>
<img class="server-icon h-5 ml-1 hidden bg-white rounded p-0.5" alt="Server Icon">
<div class="server-info-container flex flex-col items-center justify-center gap-1 mt-1">
<!-- Server info will be injected here -->
</div>
<!-- <a class="transition link text-[var(--primary)] font-medium inline-flex items-center" href="https://beian.mps.gov.cn/#/query/webSearch?code=34010302002608" target="_blank"><img alt="" src="/favicon/foot-ga.png" class="h-4 mr-1">皖公网安备34010302002608号</a>
<br> -->
</div>
</div>
<script>
function updateServerInfo(server) {
const wrappers = document.querySelectorAll('.server-info-wrapper');
wrappers.forEach(wrapper => {
const serverInfo = wrapper.querySelector('.server-info');
const serverIcon = wrapper.querySelector('.server-icon');
if (serverInfo) {
if (server) {
serverInfo.innerText = `访问节点:${server}`;
if (serverIcon) {
const serverLower = server.toLowerCase();
if (serverLower === 'edgeone-pages') {
serverIcon.src = '/cdn/eo.png';
serverIcon.classList.remove('hidden');
serverInfo.classList.add('hidden');
} else if (serverLower === 'cloudflare') {
serverIcon.src = '/cdn/cf.svg';
serverIcon.classList.remove('hidden');
serverInfo.classList.add('hidden');
} else if (serverLower === 'esa') {
serverIcon.src = '/cdn/esa.svg';
serverIcon.classList.remove('hidden');
serverInfo.classList.add('hidden');
} else {
serverIcon.classList.add('hidden');
serverInfo.classList.remove('hidden');
}
}
} else {
serverInfo.innerText = "访问节点:未知";
serverInfo.classList.remove('hidden');
if (serverIcon) serverIcon.classList.add('hidden');
}
<script is:inline define:vars={{ serverConfig: siteConfig.server || [] }}>
function createServerEntry(config, index) {
const div = document.createElement('div');
div.className = 'flex items-center justify-center';
div.id = `server-entry-${index}`;
const label = document.createElement('span');
label.className = 'text-black/30 dark:text-white/30 text-xs mr-1';
label.innerText = `${config.text}`;
div.appendChild(label);
const valueSpan = document.createElement('span');
valueSpan.className = 'server-value text-black/30 dark:text-white/30 text-xs';
valueSpan.innerText = '检测中...';
div.appendChild(valueSpan);
const iconImg = document.createElement('img');
iconImg.className = 'server-icon h-5 ml-1 hidden bg-white rounded p-0.5';
iconImg.alt = 'Server Icon';
div.appendChild(iconImg);
return { div, valueSpan, iconImg };
}
function updateEntryDisplay(elements, server) {
const { valueSpan, iconImg } = elements;
if (server) {
valueSpan.innerText = server;
const serverLower = server.toLowerCase();
if (serverLower === 'edgeone-pages' || serverLower.includes('edgeone')) {
iconImg.src = '/cdn/eo.png';
iconImg.classList.remove('hidden');
valueSpan.classList.add('hidden');
} else if (serverLower === 'cloudflare') {
iconImg.src = '/cdn/cf.svg';
iconImg.classList.remove('hidden');
valueSpan.classList.add('hidden');
} else if (serverLower === 'esa') {
iconImg.src = '/cdn/esa.svg';
iconImg.classList.remove('hidden');
valueSpan.classList.add('hidden');
} else {
iconImg.classList.add('hidden');
valueSpan.classList.remove('hidden');
}
} else {
valueSpan.innerText = "未知";
valueSpan.classList.remove('hidden');
iconImg.classList.add('hidden');
}
}
async function checkServer(url) {
try {
const targetUrl = url || window.location.href;
const response = await fetch(targetUrl, { method: "HEAD" });
return response.headers.get('server');
} catch (error) {
console.warn(`Failed to fetch server info for ${url}:`, error);
return null;
}
}
async function initServerInfo() {
const containers = document.querySelectorAll('.server-info-container');
if (containers.length === 0) return;
// Cache fetched results to avoid duplicate requests
const results = {};
// Helper to get or fetch server info
const getServerInfo = async (url) => {
if (results[url] !== undefined) return results[url];
const server = await checkServer(url);
results[url] = server;
return server;
};
containers.forEach(container => {
// Clear existing content
container.innerHTML = '';
if (!serverConfig || serverConfig.length === 0) {
// Default fallback
const { div, valueSpan, iconImg } = createServerEntry({ text: '访问节点' }, 0);
container.appendChild(div);
getServerInfo('').then(server => {
updateEntryDisplay({ valueSpan, iconImg }, server);
});
} else {
serverConfig.forEach((config, index) => {
const elements = createServerEntry(config, index);
container.appendChild(elements.div);
getServerInfo(config.url).then(server => {
updateEntryDisplay(elements, server);
});
});
}
});
}
function initServerInfo() {
const isDevMode = localStorage.getItem("dev-mode") === "true";
if (isDevMode) {
const devServer = localStorage.getItem("dev-server");
updateServerInfo(devServer);
} else {
const url = window.location.href;
fetch(url, { method: "HEAD" })
.then(response => {
const server = response.headers.get('server');
updateServerInfo(server);
})
.catch(error => {
console.error("Failed to fetch server info:", error);
updateServerInfo(null);
});
}
}
initServerInfo();
document.addEventListener('astro:after-swap', initServerInfo); // Support View Transitions if enabled
// Support Swup if enabled (listen to content replacement)
document.addEventListener('astro:after-swap', initServerInfo);
document.addEventListener('content:replace', initServerInfo);
</script>

View File

@@ -60,6 +60,11 @@ export const siteConfig: SiteConfig = {
{ url: "https://acofork.com", alias: "EdgeOne CN" },
{ url: "https://2x.nz", alias: "Global" },
],
server: [
{ url: "", text: "博客本体节点" },
{ url: "https://umami.acofork.com", text: "Umami节点" },
{ url: "https://pic.acofork.com", text: "随机图节点" },
],
};
export const navBarConfig: NavBarConfig = {

View File

@@ -39,6 +39,10 @@ export type SiteConfig = {
favicon: Favicon[];
officialSites?: (string | { url: string; alias: string })[];
server?: {
url: string;
text: string;
}[];
};
export type Favicon = {