improve & fix : 主题优化及bug修复 (#409)

* 主题优化及bug修复

default主题
1.修复主box过宽导致的系列问题(pc和移动端)
2.network页面适配深色模式和浅色模式

status-server主题
1. network页面折线图取数逻辑优化,丢包率一直是100%时,不显示丢包markline线
2. 隐藏所有table横向滚动条
3. 关闭折线图hover效果,大幅提升echarts图表渲染速度
4. 移动端页底显示位置优化

* 刷新cdn缓存

* 修复default深色模式在ios设备不生效bug

* 1. 恢复主baox 1680px宽度,用其他方式修复上一版存在bug(移动端左右留空不一致等)
2. 首页echarts自动适配深色浅色模式

* fix
This commit is contained in:
nap0o 2024-08-16 23:14:28 -04:00 committed by GitHub
parent daab64d232
commit e9428d5757
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
12 changed files with 208 additions and 223 deletions

View File

@ -1,148 +1,141 @@
.ui.container {
width: 95vw !important;
max-width: 1680px !important;
html[nz-theme='dark'] body {
background-color: #121212 !important;
color: #fff !important;
}
html[nz-theme='dark'] {
body {
background-color: #121212 !important;
color: #fff !important;
}
html[nz-theme='dark'] .ui.menu {
background-color: #282828 !important;
}
.ui.menu {
background-color: #282828 !important;
}
html[nz-theme='dark'] .ui.menu * {
color: #fff !important;
}
.ui.menu * {
color: #fff !important;
}
html[nz-theme='dark'] .accordion {
background-color: #282828 !important;
}
.accordion {
background-color: #282828 !important;
}
html[nz-theme='dark'] .accordion .title {
color: #fff !important;
}
.accordion .title {
color: #fff !important;
}
html[nz-theme='dark'] .ui.card {
background-color: #3f3f3f !important;
border: none !important;
box-shadow: none !important;
}
.ui.card {
background-color: #3f3f3f !important;
border: none !important;
box-shadow: none !important;
}
html[nz-theme='dark'] .header {
color: #fff !important;
}
.header {
color: #fff !important;
}
html[nz-theme='dark'] .description {
color: #fff !important;
}
.description {
color: #fff !important;
}
html[nz-theme='dark'] .icon {
color: #fff !important;
}
.icon {
color: #fff !important;
}
html[nz-theme='dark'] .ui.popup {
background-color: #575757 !important;
color: #fff !important;
}
.ui.popup {
background-color: #575757 !important;
color: #fff !important;
}
html[nz-theme='dark'] .ui.table {
background-color: #282828 !important;
color: #fff !important;
}
.ui.table {
background-color: #282828 !important;
color: #fff !important;
}
html[nz-theme='dark'] .ui thead th {
background-color: #3f3f3f !important;
color: #fff !important;
}
.ui thead th {
background-color: #3f3f3f !important;
color: #fff !important;
}
html[nz-theme='dark'] .ui.buttons .button {
background-color: #3f3f3f !important;
color: #fff !important;
}
.ui.buttons .button {
background-color: #3f3f3f !important;
color: #fff !important;
}
html[nz-theme='dark'] .ui.modal {
background-color: #282828 !important;
}
.ui.modal {
background-color: #282828 !important;
}
html[nz-theme='dark'] .ui.modal * {
color: #fff !important;
}
.ui.modal * {
color: #fff !important;
}
html[nz-theme='dark'] textarea,
html[nz-theme='dark'] input,
html[nz-theme='dark'] select,
html[nz-theme='dark'] .dropdown {
background-color: #3f3f3f !important;
color: #fff !important;
}
textarea,
input,
select,
.dropdown {
background-color: #3f3f3f !important;
color: #fff !important;
}
html[nz-theme='dark'] .ui.message {
background-color: unset !important;
}
.ui.message {
background-color: unset !important;
}
html[nz-theme='dark'] .ui.dropdown .menu {
background-color: #575757 !important;
color: #fff !important;
}
.ui.dropdown .menu {
background-color: #575757 !important;
color: #fff !important;
}
html[nz-theme='dark'] .ui.modal>.header {
background-color: #3f3f3f !important;
}
.ui.modal>.header {
background-color: #3f3f3f !important;
}
html[nz-theme='dark'] .ui.modal>.content {
background-color: #282828 !important;
}
.ui.modal>.content {
background-color: #282828 !important;
}
html[nz-theme='dark'] .ui.modal>.actions {
background-color: #3f3f3f !important;
}
.ui.modal>.actions {
background-color: #3f3f3f !important;
}
html[nz-theme='dark'] #alert {
background-color: #3f3f3f !important;
color: #fff !important;
}
#alert {
background-color: #3f3f3f !important;
color: #fff !important;
}
html[nz-theme='dark'] .ui.form .field>label {
color: unset !important;
}
.ui.form .field>label {
color: unset !important;
}
html[nz-theme='dark'] .ui.segment {
background-color: #3f3f3f !important;
}
.ui.segment {
background-color: #3f3f3f !important;
}
html[nz-theme='dark'] .ui.segment textarea,
html[nz-theme='dark'] input,
html[nz-theme='dark'] select,
html[nz-theme='dark'] .dropdown {
background-color: #575757 !important;
color: #fff !important;
}
.ui.segment textarea,
input,
select,
.dropdown {
background-color: #575757 !important;
color: #fff !important;
}
html[nz-theme='dark'] form label {
color: #fff !important;
}
form label {
color: #fff !important;
}
html[nz-theme='dark'] .ui.inverted.segment {
background-color: #121212 !important;
}
.ui.inverted.segment {
background-color: #121212 !important;
}
html[nz-theme='dark'] .ui.inverted.segment * {
color: #8b8b8b !important;
}
.ui.inverted.segment * {
color: #8b8b8b !important;
}
html[nz-theme='dark'] .menu .dropdown {
background-color: #282828 !important;
color: #fff !important;
}
.menu .dropdown {
background-color: #282828 !important;
color: #fff !important;
}
html[nz-theme='dark'] .ui.menu .ui.dropdown .menu>.item {
color: #fff !important;
}
.ui.menu .ui.dropdown .menu>.item {
color: #fff !important;
}
.login .ui.message{
color: #8b8b8b !important;
}
}
html[nz-theme='dark'] .login .ui.message{
color: #8b8b8b !important;
}

View File

@ -9,6 +9,11 @@ td {
word-break: break-all;
}
.ui.container{
width: 95vw !important;
max-width: 1680px !important;
}
.nb-container {
padding-top: 75px;
min-height: 100vh;

View File

@ -1,14 +1,5 @@
/* 屏幕适配 */
@media only screen and (min-width:1200px) {
.ui.container {
width: 95% !important;
font-size: 90% !important;
max-width: 1300px !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;
@ -41,16 +32,6 @@ i.fi {
margin: 0px 6px 0px 2px;
}
body {
content: " " !important;
background: fixed !important;
z-index: -1 !important;
top: 0 !important;
right: 0 !important;
bottom: 0 !important;
left: 0 !important;
}
td {
word-wrap: break-word;
word-break: break-all;
@ -63,6 +44,11 @@ td {
margin-bottom: -47px;
}
.ui.container {
width: 95%;
max-width: 1680px !important;
}
#app .ui.fluid.accordion {
margin-bottom: 1rem;
}

View File

@ -9,6 +9,10 @@ body {
margin: 0 auto;
}
.container-fluid::-webkit-scrollbar {
display: none;
}
.nezha {
min-height: calc(100vh - 100px);
}
@ -470,14 +474,13 @@ footer p{
background-image: url(/static/theme-server-status/img/rb.png);
}
@media only screen and (max-width: 767px) {
body {
font-size: 10px !important;
padding-top:60px !important;
}
.nezha {
min-height: calc(100vh - 80px);
min-height: calc(74.5vh);
}
.content {
padding: 0;

View File

@ -16,8 +16,6 @@
showSwitchTemplate({{ .Themes }}, {{ .Conf.Site.Theme }})
</script>
{{ end }}
<script>
</script>
</body>
</html>
{{end}}

View File

@ -14,8 +14,8 @@
<link rel="stylesheet" href="https://unpkg.com/bootstrap-icons@1.11.3/font/bootstrap-icons.min.css">
<link rel="stylesheet" href="https://unpkg.com/flag-icons@7.2.3/css/flag-icons.min.css">
<link rel="stylesheet" type="text/css" href="/static/semantic-ui-alerts.min.css">
<link rel="stylesheet" type="text/css" href="/static/theme-default/css/main.css?v20240616">
<link rel="stylesheet" type="text/css" href="/static/darkmode.css?v20240813">
<link rel="stylesheet" type="text/css" href="/static/theme-default/css/main.css?v20240816">
<link rel="stylesheet" type="text/css" href="/static/darkmode.css?v20240816">
<script src="https://unpkg.com/jquery@3.7.1/dist/jquery.min.js"></script>
<script src="https://unpkg.com/semantic-ui@2.4.0/dist/semantic.min.js"></script>
<script src="https://unpkg.com/vue@2.6.14/dist/vue.min.js"></script>
@ -23,7 +23,7 @@
<script src="/static/semantic-ui-alerts.min.js"></script>
<script src="/static/theme-default/js/mixin.js?v20240302"></script>
<script>
document.documentElement.setAttribute('nz-theme', window.matchMedia('(prefers-color-scheme: dark)').matches ? 'dark' : 'light')
document.documentElement.setAttribute('nz-theme', window.matchMedia('(prefers-color-scheme: dark)').matches ? 'dark' : 'light');
</script>
</head>

View File

@ -240,12 +240,12 @@
const itemHeight = isMobile ? 10 : 10;
const gridLeft = 25;
const gridRight = 12;
const fontColor = "rgba(0, 0, 0, 0.68)";
const backgroundColor = '';
const borderColor = "#ffffff";
const chartData = this.chartDataList[id - 1];
const chartContainer = this.$refs[`chart${id}`][0];
const chart = echarts.init(chartContainer, null, {
const chartTheme = $('html').attr('nz-theme') == "dark" ? "dark" : "";
const chart = echarts.init(chartContainer, chartTheme, {
renderer: 'canvas',
useDirtyRect: false,
width: 'auto',
@ -283,7 +283,6 @@
trigger: 'axis',
textStyle: {
fontSize: fontSize,
color: fontColor
}
},
legend: {
@ -292,7 +291,6 @@
show: true,
textStyle: {
fontSize: fontSize,
color: fontColor
},
lineStyle: {
cap: 'butt'
@ -332,7 +330,6 @@
series: seriesData,
textStyle: {
fontSize: fontSize,
color: fontColor
},
grid: {
top: '30',

View File

@ -18,7 +18,7 @@
</div>
</div>
<div class="ui container">
<div ref="chartDom" style="border-radius: 28px; margin-top: 15px;height: 520px;overflow: hidden"></div>
<div ref="chartDom" style="margin-top: 15px;height: 520px;overflow: hidden"></div>
</div>
</div>
@ -65,10 +65,10 @@
}
},
grid: {
left: '8%',
right: '8%',
left: this.isMobile ? '8%' : '3.8%',
right: this.isMobile ? '8%' : '3.8%',
},
backgroundColor: 'rgba(255, 255, 255, 0.8)',
backgroundColor: '',
toolbox: {
feature: {
dataZoom: {
@ -243,7 +243,8 @@
return str.includes('Windows')
},
renderChart() {
this.myChart = echarts.init(this.$refs.chartDom);
const chartTheme = $('html').attr('nz-theme') == "dark" ? "dark" : "";
this.myChart = echarts.init(this.$refs.chartDom,chartTheme);
this.myChart.setOption(this.option);
},
resizeHandle () {

View File

@ -1,36 +1,36 @@
{{define "theme-server-status/footer"}}
</div>
<footer class="container-fluid">
<p>{{ .Conf.Site.Brand }} | Theme ServerStatus | Powered by <a target="_blank" href="https://github.com/naiba/nezha">{{tr "NezhaMonitoring"}}</a> {{.Version}}</p>
</footer>
<aside class="toolbox">
<template v-if="showTools">
<span v-if="page=='index' && countryMapChartData.length!=0" class="showMapChart">
<i @click="showMapChart" data-toggle="modal" data-target="#mapChartBox" class="bi bi-geo-alt"></i>
</span>
<span class="toggleView">
<i v-if="showGroup" @click="toggleShowGroup" class="show-nogroup bi bi-justify"></i>
<i v-else @click="toggleShowGroup" class="show-group bi bi-view-stacked"></i>
</span>
<span class="toggleSemiTransparent" @click="toggleSemiTransparent">
<i class="bi" :class="semiTransparent ? 'bi-droplet' : 'bi-droplet-half'"></i>
</span>
</template>
<span v-if="!showTools">
<i @click="toggleShowTools" class="bi bi-three-dots"></i>
</span>
<span class="setTheme">
<i v-if="theme === 'light'" @click="setTheme('dark')" class="setTheme-dark bi bi-moon-fill"></i>
<i v-else @click="setTheme('light')" class="setTheme-light bi bi-brightness-high-fill"></i>
</span>
<span v-if="showGoTop" class="showGoTop">
<i @click="goTop" class="goTop bi bi-arrow-up"></i>
</span>
</aside>
<template v-if="semiTransparent">
<link rel="stylesheet" href="/static/theme-server-status/css/light.plus.css?v20240807">
<link rel="stylesheet" href="/static/theme-server-status/css/dark.plus.css?v20240807">
</template>
</div>
<footer class="container-fluid">
<p>{{ .Conf.Site.Brand }} | Theme ServerStatus | Powered by <a target="_blank" href="https://github.com/naiba/nezha">{{tr "NezhaMonitoring"}}</a> {{.Version}}</p>
</footer>
<aside class="toolbox">
<template v-if="showTools">
<span v-if="page=='index' && countryMapChartData.length!=0" class="showMapChart">
<i @click="showMapChart" data-toggle="modal" data-target="#mapChartBox" class="bi bi-geo-alt"></i>
</span>
<span class="toggleView">
<i v-if="showGroup" @click="toggleShowGroup" class="show-nogroup bi bi-justify"></i>
<i v-else @click="toggleShowGroup" class="show-group bi bi-view-stacked"></i>
</span>
<span class="toggleSemiTransparent" @click="toggleSemiTransparent">
<i class="bi" :class="semiTransparent ? 'bi-droplet' : 'bi-droplet-half'"></i>
</span>
</template>
<span v-if="!showTools">
<i @click="toggleShowTools" class="bi bi-three-dots"></i>
</span>
<span class="setTheme">
<i v-if="theme === 'light'" @click="setTheme('dark')" class="setTheme-dark bi bi-moon-fill"></i>
<i v-else @click="setTheme('light')" class="setTheme-light bi bi-brightness-high-fill"></i>
</span>
<span v-if="showGoTop" class="showGoTop">
<i @click="goTop" class="goTop bi bi-arrow-up"></i>
</span>
</aside>
<template v-if="semiTransparent">
<link rel="stylesheet" href="/static/theme-server-status/css/light.plus.css?v20240807">
<link rel="stylesheet" href="/static/theme-server-status/css/dark.plus.css?v20240807">
</template>
</div>
{{if ts .CustomCode}}{{.CustomCode|safe}}{{end}}
</body>

View File

@ -16,7 +16,7 @@
<script src="https://unpkg.com/bootstrap@3.4.1/dist/js/bootstrap.min.js"></script>
<script src="https://unpkg.com/vue@2.6.14/dist/vue.min.js"></script>
<script src="https://unpkg.com/echarts@5.5.0/dist/echarts.min.js"></script>
<link rel="stylesheet" href="/static/theme-server-status/css/main.css?v202408011">
<link rel="stylesheet" href="/static/theme-server-status/css/main.css?v202408016">
<link rel="stylesheet" href="/static/theme-server-status/css/dark.css?v202408011">
<link rel="stylesheet" href="/static/theme-server-status/css/light.css?v20240811">
<script src="/static/theme-server-status/js/mixin.js?v20240811"></script>

View File

@ -551,6 +551,10 @@
symbol: 'none',
data: data,
connectNulls: true,
legendHoverLink: false,
emphasis: {
disabled: true
},
lineStyle: {
width: lineStyleWidth
}
@ -560,7 +564,7 @@
const legendData = chartData.map(item => item.monitor_name);
const maxLegendsPerRowMobile = localStorage.getItem("maxLegendsPerRowMobile") ? localStorage.getItem("maxLegendsPerRowMobile") : 3;
const maxLegendsPerRowPc = localStorage.getItem("maxLegendsPerRowPc") ? localStorage.getItem("maxLegendsPerRowPc") : 6;
const autoIncrement = Math.floor((legendData.length - 1) / (this.isMobile ? maxLegendsPerRowMobile : maxLegendsPerRowPc)) * (this.isMobile ? 20 : 28)
const autoIncrement = Math.floor((legendData.length - 1) / (this.isMobile ? maxLegendsPerRowMobile : maxLegendsPerRowPc)) * (this.isMobile ? 20 : 28);
const height = 300 + autoIncrement;
const gridTop = 40 + autoIncrement;
const legendIcon = this.isMobile ? 'rect' : "";

View File

@ -12,7 +12,7 @@
</li>
<li class="dropdown-item" v-for="server in servers" @click="showCharts(server.ID)">
<a><i :class="'fi fi-' + (server.Host.CountryCode || 'rb')"></i> @#server.Name#@ <i v-if="server.ID == currentServerId" class="check icon"></i></a>
</li>
</li>
</ul>
</div>
<div class="chartTitle"><i class="chartCountryCode" :class="'fi fi-' + chartCountryCode"></i> @#chartTitle#@</div>
@ -44,7 +44,6 @@
},
methods: {
showCharts(id) {
const chartContainer = document.getElementById('chartbox');
// 发起数据请求
const url = `/api/v1/monitor/${id}`;
fetch(url)
@ -64,17 +63,13 @@
});
},
renderCharts(id, reload = false) {
if (!this.chartDataList[id]) return;
this.disposeCharts();
if(!this.chartDataList[id]) return;
if(this.chart) this.disposeCharts(this.chart);
this.currentServerId = id;
this.chartCountryCode = this.getServerCountryCode(id);
this.chartTitle = this.chartDataList[id][0].server_name;
const chartData = this.chartDataList[id];
const chartContainer = document.getElementById('chartbox');
this.chartTitle = chartData[0].server_name;
if (reload) {
const existingChart = echarts.getInstanceByDom(chartContainer);
if (existingChart) existingChart.dispose();
}
// 定义图表参数值
const MaxTCPPingValue = {{.Conf.MaxTCPPingValue}} ? {{.Conf.MaxTCPPingValue}} : 300;
const autoheight = this.isMobile ? (window.innerHeight - 200) : (window.innerHeight - 250);
@ -111,34 +106,35 @@
let data = { main: [], markLine: []};
item.avg_delay.forEach((avgDelay, index) => {
const threshold = 0.9 * MaxTCPPingValue; // 定义阀值,用于判断是否丢包
const filterAvgDelay = item.avg_delay.filter(value => value !== 0 && value !== MaxTCPPingValue);
const max = Math.max(...filterAvgDelay).toFixed(1);
const autoAvgDelay = 1.05 * max > 0.91 * MaxTCPPingValue ? 1.05 * max : 0.91 * MaxTCPPingValue;
// 定义丢包 1. avgDelay==0 2. avgDelay>=MaxTCPPingValue 3. avgDelay>=threshold
if(avgDelay == 0 || avgDelay >= MaxTCPPingValue){ //绝对丢包
loss += 1;
const lossrate = 100 * loss / (index + 1);
data['main'].push(
[item.created_at[index], autoAvgDelay, lossrate]
);
data['markLine'].push({
xAxis: item.created_at[index],
label: { show: false },
emphasis: { disabled: true },
lineStyle: { type: "solid" }
});
if(lossrate != 100) {
data['main'].push(
[item.created_at[index], MaxTCPPingValue, lossrate]
);
data['markLine'].push({
xAxis: item.created_at[index],
label: { show: false },
emphasis: { disabled: true },
lineStyle: { type: "solid" }
});
}
} else if (avgDelay >= threshold && avgDelay < MaxTCPPingValue){ // 相对丢包
loss += 1;
const lossrate = 100 * loss / (index + 1);
data['main'].push(
[item.created_at[index], avgDelay, lossrate]
);
data['markLine'].push({
xAxis: item.created_at[index],
label: { show: false },
emphasis: { disabled: true },
lineStyle: { type: "solid" }
});
if(lossrate != 100) {
data['main'].push(
[item.created_at[index], avgDelay, lossrate]
);
data['markLine'].push({
xAxis: item.created_at[index],
label: { show: false },
emphasis: { disabled: true },
lineStyle: { type: "solid" }
});
}
} else { // 未丢包
const lossrate = 100 * loss / (index + 1);
data['main'].push(
@ -158,6 +154,10 @@
smooth: true,
symbol: 'none',
connectNulls: true,
legendHoverLink: false,
emphasis: {
disabled: true
},
lineStyle: {
width: lineStyleWidth
},
@ -216,7 +216,7 @@
});
const maxLegendsPerRowMobile = localStorage.getItem("maxLegendsPerRowMobile") ? localStorage.getItem("maxLegendsPerRowMobile") : 3;
const maxLegendsPerRowPc = localStorage.getItem("maxLegendsPerRowPc") ? localStorage.getItem("maxLegendsPerRowPc") : 6;
const autoIncrement = Math.floor((legendData.length - 1) / (this.isMobile ? maxLegendsPerRowMobile : maxLegendsPerRowPc)) * (this.isMobile ? 20 : 28)
const autoIncrement = Math.floor((legendData.length - 1) / (this.isMobile ? maxLegendsPerRowMobile : maxLegendsPerRowPc)) * (this.isMobile ? 20 : 28);
const height = autoheight + autoIncrement;
const gridTop = 40 + autoIncrement;
const legendIcon = this.isMobile ? 'rect' : "";
@ -333,11 +333,9 @@
}
});
},
disposeCharts(){
if(this.chart) {
this.chart.dispose();
this.chart = null;
}
disposeCharts(chart){
chart.dispose();
chart = null;
},
getServerCountryCode(id){
const result = this.servers.find(item => item.ID == id);