<script>
function setTRTH(container) {
// 处理单个 container 的逻辑
var downtimeCells = container.querySelectorAll('th.node-cell.os.center');
downtimeCells.forEach(function(cell) {
// 创建一个新的 <th> 元素
var newTh = document.createElement('th');
// 添加 class 属性
newTh.className = 'node-cell downtime center';
// 设置新元素的文本内容
newTh.textContent = '🕖备注';
// 将新元素插入到当前单元格的后面
cell.parentNode.insertBefore(newTh, cell.nextSibling);
});
const affLinks = {
1: {
// expiration: new Date('2024-12-31'),
content: {
type: 'link',
value: '<https://baidu.com>',
label: '购买同款',
icon: '<https://host.auto.cloudns.ch/https://img.icons8.com/?size=24&id=13012&format=png&color=000000>',
iconAlt: 'Icon'
}
},
2: {
// expiration: new Date('2024-12-31'),
content: {
type: 'icon',
value: '<https://host.auto.cloudns.ch/https://img.icons8.com/color/24/thumb-up--v1.png>',
// label: 'Icon',
// text: '赞'
}
},
3: {
expiration: new Date('2024-12-31'),
content: {
type: 'text',
// value: '<https://cdn3.iconfinder.com/data/icons/font-awesome-regular-1/640/handshake-64.png>',
// label: 'Icon',
value: ''
}
},
4: {
//expiration: new Date('2024-12-31'),
content: {
type: 'text',
// value: '<https://cdn3.iconfinder.com/data/icons/font-awesome-regular-1/640/handshake-64.png>',
// label: 'Icon',
value: '一切从白嫖开始'
}
},
5: {
expiration: new Date('3014-12-31'),
content: {
type: 'text',
value: ''
}
}
};
const createLink = (linkConfig) => {
const $link = document.createElement('a');
$link.href = linkConfig.value;
$link.textContent = linkConfig.label || linkConfig.value;
$link.target = '_blank';
if (linkConfig.icon) {
const $icon = document.createElement('img');
$icon.src = linkConfig.icon;
$icon.alt = linkConfig.iconAlt || '';
$link.appendChild($icon);
}
if (linkConfig.text) {
const $text = document.createElement('span');
$text.textContent = linkConfig.text;
$link.appendChild(document.createTextNode(' '));
$link.appendChild($text);
}
return $link;
};
const createIcon = (iconConfig) => {
const $icon = document.createElement('img');
$icon.src = iconConfig.value;
$icon.alt = iconConfig.label || 'Icon';
if (iconConfig.text) {
const $text = document.createElement('span');
$text.textContent = iconConfig.text;
$icon.appendChild(document.createTextNode(' '));
$icon.appendChild($text);
}
return $icon;
};
const createCountdown = (expirationDate) => {
const $countdown = document.createElement('div');
$countdown.textContent = ' ';
const $countdownTime = document.createElement('span');
const updateCountdown = () => {
const now = new Date();
const diff = expirationDate.getTime() - now.getTime();
if (diff <= 0) {
clearInterval(countdownInterval);
$countdownTime.textContent = '已过期';
return;
}
const days = Math.floor(diff / (1000 * 60 * 60 * 24));
const hours = Math.floor((diff % (1000 * 60 * 60 * 24)) / (1000 * 60 * 60));
const minutes = Math.floor((diff % (1000 * 60 * 60)) / (1000 * 60));
const seconds = Math.floor((diff % (1000 * 60)) / 1000);
$countdownTime.textContent = `${days}天 ${hours}小时 ${minutes}分钟 ${seconds}秒`;
};
const countdownInterval = setInterval(updateCountdown, 1000);
updateCountdown();
$countdown.appendChild($countdownTime);
return $countdown;
};
const rows = container.querySelectorAll('tr');
rows.forEach((row, index) => {
let osCell = row.querySelector('td.node-cell.os.center');
let downtimeCell = document.createElement('td');
downtimeCell.classList.add('node-cell', 'downtime', 'center');
let nodeId = row.id.substring(1);
let affLink = affLinks[nodeId];
if (!affLink) {
affLink = {
content: {
type: 'text',
value: '未定义'
}
};
}
if (osCell && affLink && affLink.content) {
switch (affLink.content.type) {
case 'link':
let link = createLink(affLink.content);
downtimeCell.appendChild(link);
break;
case 'icon':
let icon = createIcon(affLink.content);
downtimeCell.appendChild(icon);
break;
default:
let text = document.createTextNode(affLink.content.value);
downtimeCell.appendChild(text);
break;
}
if (affLink.expiration) {
let countdown = createCountdown(affLink.expiration);
downtimeCell.appendChild(countdown);
}
osCell.parentNode.insertBefore(downtimeCell, osCell.nextSibling);
}
});
// 获取所有的th元素
const headers = container.querySelectorAll('th');
// 定义一个图标映射对象
const iconMap = {
'状态': '🍀',
'名称': '🚀',
'系统': '🗂',
'地区': '🌎',
'在线': '⏱️',
'负载': '📋',
'网络↓|↑': '🚦',
'流量↓|↑': '📊',
'核心': '🎯',
'内存': '⚡',
'硬盘': '💾',
};
// 遍历每个th元素
headers.forEach((header) => {
let textContent = header.textContent.trim(); // 获取当前th的文本内容
if (textContent === '位置') {
textContent = '地区';
}
if (iconMap[textContent]) {
header.textContent = `${iconMap[textContent]} ${textContent}`;
}
});
}
function isDataLoaded(container) {
// 检查是否有表格
const table = container.querySelector('table');
if (!table) return false;
// 检查是否有表头
const thead = table.querySelector('thead');
if (!thead || !thead.querySelector('tr')) return false;
// 检查是否有数据行
const tbody = table.querySelector('tbody');
if (!tbody || !tbody.querySelector('tr')) return false;
// 检查是否有特定的单元格内容(例如,检查状态列是否存在)
const statusCell = tbody.querySelector('td.node-cell.status');
if (!statusCell) return false;
return true;
}
function waitForDataAndExecute(container, maxAttempts = 10, interval = 300) {
let attempts = 0;
function tryExecute() {
if (isDataLoaded(container)) {
if (!container.getAttribute('data-processed')) {
setTRTH(container);
container.setAttribute('data-processed', 'true');
}
} else if (attempts < maxAttempts) {
attempts++;
setTimeout(tryExecute, interval);
}
}
tryExecute();
}
function addArrow(thElement) {
const container = thElement.closest('.container-fluid.table-responsive.content');
// 创建一个 span 元素作为三角形
const triangle = document.createElement('span');
triangle.classList.add('triangle');
// 将三角形插入到 th 元素的开头
thElement.insertBefore(triangle, thElement.firstChild);
// 添加一些空白,使三角形和文本之间有一些间距
thElement.insertBefore(document.createTextNode(' '), triangle.nextSibling);
// 设置初始状态为显示(向下)
triangle.classList.add('down');
// 添加点击事件
thElement.addEventListener('click', function() {
// 找到所有的 node-group-cell 元素
const nodeGroupCells = thElement.closest('thead').querySelectorAll('.node-group-cell');
nodeGroupCells.forEach(cell => {
cell.classList.toggle('hidden');
});
// 同时隐藏/显示 tbody 中的所有行
const tbody = thElement.closest('table').querySelector('tbody');
if (tbody) {
tbody.classList.toggle('hidden');
}
// 切换三角形方向
triangle.classList.toggle('right');
triangle.classList.toggle('down');
// 切换 thElement 的文字颜色
thElement.classList.toggle('text-gray');
thElement.classList.toggle('font-normal');
thElement.classList.toggle('font-size');
if (container.style.padding === '10px 10px 5px 10px') {
container.style.padding = '20px'; // 展开显示时的 padding
} else {
container.style.padding = '10px 10px 5px 10px'; // 隐藏时的 padding
}
});
// 添加 CSS 样式
const style = document.createElement('style');
style.textContent = `
.triangle {
display: inline-block;
width: 0;
height: 0;
border-left: 5px solid transparent;
border-right: 5px solid transparent;
border-top: 8px solid #000;
transition: transform 0.3s;
}
.triangle.right {
transform: rotate(-90deg);
}
.triangle.down {
transform: rotate(0deg);
}
.hidden {
display: none !important;
}
.text-gray {
color: gray !important;
}
.font-normal {
font-weight: normal !important;
}
.font-size {
font-size: 14px !important;
}
`;
document.head.appendChild(style);
}
document.addEventListener('DOMContentLoaded', function() {
const nezhaSection = document.querySelector('.nezha');
if (nezhaSection) {
const observer = new MutationObserver(function(mutations) {
mutations.forEach(function(mutation) {
if (mutation.type === 'childList') {
const addedNodes = mutation.addedNodes;
for (let i = 0; i < addedNodes.length; i++) {
if (addedNodes[i].nodeType === Node.ELEMENT_NODE) {
const container = addedNodes[i];
if (container.classList.contains('container-fluid') &&
container.classList.contains('table-responsive') &&
container.classList.contains('content')) {
waitForDataAndExecute(container);
// 检测 node-group-tag 并添加箭头
const nodeGroupTags = container.querySelectorAll('.node-group-tag');
nodeGroupTags.forEach(tag => {
addArrow(tag.querySelector('th'));
});
}
}
}
}
});
});
observer.observe(nezhaSection, {
childList: true,
subtree: true
});
// 初始处理所有现有的容器
const containers = document.querySelectorAll('.container-fluid.table-responsive.content');
containers.forEach(container => {
waitForDataAndExecute(container);
// 检测 node-group-tag 并添加箭头
const nodeGroupTags = container.querySelectorAll('.node-group-tag');
nodeGroupTags.forEach(tag => {
addArrow(tag.querySelector('th'));
});
});
}
// 创建一个 <style> 元素
const styleElement = document.createElement('style');
// 定义 CSS 规则
styleElement.textContent = `
.container-fluid {
max-width: 70%;
}
body[theme="dark"]::before {
background-image: none !important;
}
body[theme="dark"] .content{
box-shadow: 0 10px 15px rgba(0, 0, 0, 0.1), 0 1px 3px rgba(0, 0, 0, 0.1) !important;
transition: transform 0.3s ease, fill 0.3s ease, box-shadow 0.3s ease !important;
}
body[theme="dark"] .content:hover {
transform: scale(1.05) !important;
}
body[theme="dark"] .navbar-brand img {
filter: invert(1);
}
body[theme="dark"] .triangle {
border-top: 8px solid #fff;
}
body[theme="light"]::before {
background-image: none !important;
background-color: #f3f4f6 !important;
}
body[theme="light"] .content{
background-color: #fff !important;
box-shadow: 0 10px 15px rgba(0, 0, 0, 0.1), 0 1px 3px rgba(0, 0, 0, 0.1) !important;
transition: transform 0.3s ease, fill 0.3s ease, box-shadow 0.3s ease !important;
}
body[theme="light"] .content:hover {
transform: scale(1.05) !important;
}
body[theme="light"] .navbar-brand img {
filter: invert(0);
}
body[theme="light"] .triangle {
border-top: 8px solid #000;
}
`;
// 将 <style> 元素添加到 <head> 中
document.head.appendChild(styleElement);
const logoImg = document.querySelector('.navbar-brand img');
if (logoImg) {
logoImg.src = '<http://host.auto.cloudns.ch/https://raw.githubusercontent.com/yushion/Webssh/refs/heads/master/webssh/static/img/favicon.png>';
}
const currentHour = new Date().getHours();
const bodyElement = document.querySelector('body');
if (bodyElement) {
if (currentHour < 6 || currentHour >= 18) {
bodyElement.setAttribute('theme', 'dark');
localStorage.setItem("theme", "dark");
}
}
// 修改 apple-touch-startup-image 的 href
const appleTouchLink = document.querySelector('link[rel="apple-touch-startup-image"]');
if (appleTouchLink) {
appleTouchLink.setAttribute('href', '<http://host.auto.cloudns.ch/https://raw.githubusercontent.com/yushion/Webssh/refs/heads/master/webssh/static/img/favicon.png>');
}
// 修改 shortcut icon 的 href
const shortcutIconLink = document.querySelector('link[rel="shortcut icon"]');
if (shortcutIconLink) {
shortcutIconLink.setAttribute('href', '<https://host.auto.cloudns.ch/https://raw.githubusercontent.com/yushion/Webssh/refs/heads/master/webssh/static/img/favicon.png>');
}
localStorage.setItem("semiTransparent", "true");
localStorage.setItem("showGroup", "true");
});
</script>