前言
哪吒探针是一款广受欢迎的服务器监控工具,本篇博客将分享如何为其自定义主题样式,包括界面优化、动态进度条以及缓存数据的处理。
样式调整与背景图片
以下是 CSS 样式,用于适配不同屏幕设备和自定义页面的背景。
/* 屏幕适配 */
@media only screen and (min-width: 1200px) {
.ui.container {
width: 80% !important;
}
}
@media only screen and (max-width: 767px) {
.ui.card>.content>.header:not(.ui), .ui.cards>.card>.content>.header:not(.ui) {
margin-top: 0.4em !important;
}
}
/* 整体图标 */
i.icon {
color: #000;
width: 1.2em !important;
}
/* 背景图片 */
body {
content: " " !important;
background: fixed !important;
z-index: -1 !important;
top: 0 !important;
right: 0 !important;
bottom: 0 !important;
left: 0 !important;
background-position: top !important;
background-repeat: no-repeat !important;
background-size: cover !important;
background-image: url(https://gitee.com/wxte/img/raw/master/image.webp) !important;
font-family: Arial,Helvetica,sans-serif !important;
}
/* 导航栏 */
.ui.large.menu {
border: 0 !important;
border-radius: 0px !important;
background-color: rgba(255, 255, 255, 55%) !important;
}
/* 首页按钮 */
.ui.menu .active.item {
background-color: transparent !important;
}
/* 导航栏下拉框 */
.ui.dropdown .menu {
border: 0 !important;
border-radius: 0 !important;
background-color: rgba(255, 255, 255, 80%) !important;
}
/* 登陆按钮 */
.nezha-primary-btn {
background-color: transparent !important;
color: #000 !important;
}
/* 大卡片 */
#app .ui.fluid.accordion {
background-color: #fbfbfb26 !important;
border-radius: 0.4rem !important;
}
/* 小卡片 */
.ui.four.cards>.card {
border-radius: 0.6rem !important;
background-color: #fafafaa3 !important;
}
.status.cards .wide.column {
padding-top: 0 !important;
padding-bottom: 0 !important;
height: 3.3rem !important;
}
.status.cards .three.wide.column {
padding-right: 0rem !important;
}
.status.cards .wide.column:nth-child(1) {
margin-top: 2rem !important;
}
.status.cards .wide.column:nth-child(2) {
margin-top: 2rem !important;
}
.status.cards .description {
padding-bottom: 0 !important;
}
/* 小鸡名 */
.status.cards .flag {
margin-right: 0.5rem !important;
}
/* 弹出卡片图标 */
.status.cards .header > .info.icon {
margin-right: 0 !important;
}
.nezha-secondary-font {
color: #5E72E4 !important;
}
/* 进度条 */
.ui.progress {
border-radius: 50rem !important;
}
.ui.progress .bar {
min-width: 1.8em !important;
border-radius: 15px !important;
line-height: 1.65em !important;
}
.ui.fine.progress> .bar {
background-color: #21ba45 !important;
}
.ui.progress> .bar {
background-color: #000 !important;
}
.ui.progress.fine .bar {
background-color: #21ba45 !important;
}
.ui.progress.warning .bar {
background-color: #ff9800 !important;
}
.ui.progress.error .bar {
background-color: #e41e10 !important;
}
.ui.progress.offline .bar {
background-color: #000 !important;
}
/* 上传下载 */
.status.cards .outline.icon {
margin-right: 1px !important;
}
i.arrow.alternate.circle.down.outline.icon {
color: #21ba45 !important;
}
i.arrow.alternate.circle.up.outline.icon {
color: red !important;
}
/* 弹出卡片小箭头 */
.ui.right.center.popup {
margin: -3px 0 0 0.914286em !important;
-webkit-transform-origin: left 50% !important;
transform-origin: left 50% !important;
}
.ui.bottom.left.popup {
margin-left: 1px !important;
margin-top: 3px !important;
}
.ui.top.left.popup {
margin-left: 0 !important;
margin-bottom: 10px !important;
}
.ui.top.right.popup {
margin-right: 0 !important;
margin-bottom: 8px !important;
}
.ui.left.center.popup {
margin: -3px .91428571em 0 0 !important;
-webkit-transform-origin: right 50% !important;
transform-origin: right 50% !important;
}
.ui.right.center.popup:before,
.ui.left.center.popup:before {
border: 0px solid #fafafaeb !important;
background: #fafafaeb !important;
}
.ui.top.popup:before {
border-color: #fafafaeb transparent transparent !important;
}
.ui.popup:before {
border-color: #fafafaeb transparent transparent !important;
}
.ui.bottom.left.popup:before {
border-radius: 0 !important;
border: 1px solid transparent !important;
border-color: #fafafaeb transparent transparent !important;
background: #fafafaeb !important;
-webkit-box-shadow: 0px 0px 0 0 #fafafaeb !important;
box-shadow: 0px 0px 0 0 #fafafaeb !important;
-webkit-tap-highlight-color: rgba(0,0,0,0) !important;
}
.ui.bottom.right.popup:before {
border-radius: 0 !important;
border: 1px solid transparent !important;
border-color: #fafafaeb transparent transparent !important;
background: #fafafaeb !important
-webkit-box-shadow: 0px 0px 0 0 #fafafaeb !important;
box-shadow: 0px 0px 0 0 #fafafaeb !important;
-webkit-tap-highlight-color: rgba(0,0,0,0) !important;
}
.ui.top.left.popup:before {
border-radius: 0 !important;
border: 1px solid transparent !important;
border-color: #fafafaeb transparent transparent !important;
background: #fafafaeb !important;
-webkit-box-shadow: 0px 0px 0 0 #fafafaeb !important;
box-shadow: 0px 0px 0 0 #fafafaeb !important;
-webkit-tap-highlight-color: rgba(0,0,0,0) !important;
}
.ui.top.right.popup:before {
border-radius: 0 !important;
border: 1px solid transparent !important;
border-color: #fafafaeb transparent transparent !important;
background: #fafafaeb !important;
-webkit-box-shadow: 0px 0px 0 0 #fafafaeb !important;
box-shadow: 0px 0px 0 0 #fafafaeb !important;
-webkit-tap-highlight-color: rgba(0,0,0,0) !important;
}
.ui.left.center.popup:before {
border-radius: 0 !important;
border: 1px solid transparent !important;
border-color: #fafafaeb transparent transparent !important;
background: #fafafaeb !important;
-webkit-box-shadow: 0px 0px 0 0 #fafafaeb !important;
box-shadow: 0px 0px 0 0 #fafafaeb !important;
-webkit-tap-highlight-color: rgba(0,0,0,0) !important;
}
/* 弹出卡片 */
.status.cards .ui.content.popup {
min-width: 20rem !important;
line-height: 2rem !important;
border-radius: 5px !important;
border: 1px solid transparent !important;
background-color: #fafafaeb !important;
font-family: Arial,Helvetica,sans-serif !important;
}
.ui.content {
margin: 0 !important;
padding: 1em !important;
}
/* 服务页 */
.ui.table {
background: RGB(225,225,225,0.6) !important;
}
.ui.table thead th {
background: transparent !important;
}
/* 服务页进度条 */
.service-status .good {
background-color: #21ba45 !important;
}
.service-status .danger {
background-color: red !important;
}
.service-status .warning {
background-color: orange !important;
}
/* 版权 */
.ui.inverted.segment, .ui.primary.inverted.segment {
color: #000 !important;
font-weight: bold !important;
background-color: #fafafaa3 !important;
}
</style>
<!--Logo和版权-->
<script>
window.onload = function(){
var avatar=document.querySelector(".item img")
var footer=document.querySelector("div.is-size-7")
footer.innerHTML=""
footer.style.visibility="visible"
avatar.src="https://www.loliapi.com/acg/pp/"
avatar.style.visibility="visible"
}
</script>
<!-- 进度条颜色动态变化 -->
<script>
window.onload = function(){
var avatar=document.querySelector(".item img")
var footer=document.querySelector("div.is-size-7")
footer.innerHTML=""
footer.style.visibility="visible"
avatar.src="https://www.loliapi.com/acg/pp/"
avatar.style.visibility="visible"
// 默认分组模式
if(!localStorage.getItem("showGroup")){
localStorage.setItem("showGroup", true);
}
// 默认暗黑模式
if(!localStorage.getItem("theme")){
localStorage.setItem("theme", 'dark');
}
// 默认半透明效果
if(!localStorage.getItem("semiTransparent")){
localStorage.setItem("semiTransparent", 'true');
}
const extraData = {
1: {
pid: 0,
shop: 'crunchbits',
price: '$4',
cycle: 'month',
start: '2024-09-27',
expire: '2024-10-27',
autoPay: '否'
},
2: {
pid: 0,
shop: 'crunchbits',
price: '$4',
cycle: 'month',
start: '2024-09-28',
expire: '2024-10-28',
autoPay: '否'
},
3: {
pid: 0,
shop: 'crunchbits',
price: '¥99',
cycle: 'Year',
start: '2024-07-08',
expire: '2025-07-08',
autoPay: '否'
},
4: {
pid: 0,
shop: 'crunchbits',
price: '$99',
cycle: 'Year',
start: '2024-01-09',
expire: '2025-01-09',
autoPay: '否'
},
9: {
pid: 0,
shop: 'crunchbits',
price: '$22.69',
cycle: '季',
start: '2024-10-12',
expire: '2025-01-13',
autoPay: '否'
},
12: {
pid: 0,
shop: 'racknerd',
price: '$10.98',
cycle: 'Year',
start: '2024-09-29',
expire: '∞',
autoPay: '否'
},
13: {
pid: 0,
shop: 'rainyun',
price: '$14',
cycle: 'Year',
start: '2024-09-28',
expire: '2025-09-28',
autoPay: '否'
},
14: {
pid: 0,
shop: 'rainyun',
price: '$10.00',
cycle: 'Year',
start: '2024-10-10',
expire: '2026-10-10',
autoPay: '是'
},
15: {
pid: 0,
shop: 'colocrossing',
price: '$10.00',
cycle: 'Year',
start: '2024-10-11',
expire: '2026-10-11',
autoPay: '否'
},
}
const cycleNames = {
'年付': 'year',
'半年付': 'half',
'季付': 'quarterly',
'月付': 'month',
'年': 'year',
'半': 'half',
'季': 'quarterly',
'月': 'month',
'Year': 'year',
'Half': 'half',
'Quarterly': 'quarterly',
'Month': 'month',
'Y': 'year',
'H': 'half',
'Q': 'quarterly',
'M': 'month',
'year': 'year',
'half': 'half',
'quarterly': 'quarterly',
'month': 'month',
}
const cycleValues = {
year: 365,
half: 180,
quarterly: 90,
month: 30,
}
const cats = document.querySelectorAll('.ui.accordion');
cats.forEach((e, i)=>{
let $catsTitle = e.querySelector('.title');
let ct = $catsTitle.innerText;
ct = ct.trim();
let $itemCard = e.querySelectorAll('.ui.card');
let uiCardCount = $itemCard.length;
$catsTitle.innerHTML = $catsTitle.innerHTML.replace(ct, ct+ ' ('+ uiCardCount +')');
$itemCard.forEach((ee, ii)=>{
let $content = ee.querySelector('.content');
let $descriptionGrid = ee.querySelector('.description .ui.grid');
let $itemTitle = $content.querySelector('.header');
let id = ee.getAttribute('id');
if(extraData[id]){
let pid = extraData[id].pid;
pid = parseInt(pid);
let shop = extraData[id].shop;
let price = extraData[id].price;
let start = extraData[id].start;
let expire = extraData[id].expire;
let cycle = extraData[id].cycle;
let autoPay = extraData[id].autoPay;
let cycleName = cycleNames[cycle];
let cycleValue = cycleValues[cycleName];
let nowTime = parseInt(new Date().getTime() / 1000);
let beginTime = parseInt(new Date(start).getTime() / 1000);
if(autoPay && autoPay=='是'){
let beginDate = new Date(start);
let nowDate = new Date();
let mSteps = {
year: 12,
half: 6,
quarterly: 3,
month: 1,
}
expire = beginDate.setMonth(beginDate.getMonth() + mSteps[cycleName]);
expire = new Date(expire);
while(expire.getTime() < nowDate.getTime()){
expire= expire.setMonth(expire.getMonth() + mSteps[cycleName]);
expire= new Date(expire);
}
expire= expire.toLocaleDateString();
}
let endTime= parseInt(new Date(expire).getTime() / 1000);
if(expire){
// 到期日期行
let $expireL= document.createElement('div');
$expireL.setAttribute('class', 'three wide column');
$expireL.innerHTML= '到期';
$descriptionGrid.insertBefore($expireL, $descriptionGrid.childNodes[$descriptionGrid.childNodes.length-3])
// 到期日期行右侧进度条
let $expireR= document.createElement('div');
let aTime= (nowTime - beginTime);
let bTime= (endTime - beginTime);
let remainingTime= (endTime - nowTime); // 剩余时间
// 使用剩余时间的百分比来计算进度条长度
let cTime= parseInt((remainingTime / bTime) * 100); // 计算剩余时间的百分比
// 固定颜色为 rgb(99, 98, 103)
let progressColor= `rgb(99, 98, 103)`;
// 添加高亮效果
let textStyle= 'text-shadow: 0 0 10px #fff, 0 0 20px #fff, 0 0 30px #ffe6e6; left: .5em; text-align: right; color: #fff;';
// 如果到期是无限的,移除文本样式
if (expire= '∞') {
textStyle= '';
}
// 设置进度条的宽度和颜色,使用 !important 确保自定义样式生效
$expireR.setAttribute('class', 'expire-box thirteen wide column');
$expireR.innerHTML= `<div class="ui indicating progress active" style="margin-top: -0.2em;"> <!-- 向上移动进度条 -->
<div class="bar" style="line-height: 1em !important; transition-duration: 300ms; min-width: unset; width: ${cTime}% !important; padding-left: 0.4em; background-color: ${progressColor} !important; box-shadow: 0px 0px 15px rgba(255, 255, 255, 0.8) !important;">
<div class="progress" style="${textStyle}">${expire}</div>
</div>
</div>`;
$descriptionGrid.insertBefore($expireR, $descriptionGrid.childNodes[$descriptionGrid.childNodes.length - 3]);
}
}
});
});
}
</script>