Compare commits

...
7 Commits
Author SHA1 Message Date
nap0o 7f7763606d 修复echarts不显示bug (#330)
* angel-kanade模版增加主题切换功能

* Add files via upload

* 调整legend图例间距

* 渲染方式调整会canvas

* Update home.html
2024-03-02 15:20:32 +08:00
naiba 77de1b44bc kkgithub 已失效 2024-02-28 23:30:59 +08:00
naiba da6a3463ed 后台关闭切换主题功能 2024-02-27 21:05:39 +08:00
github-actions[bot] 6fa149519d update contributors[no ci] 2024-02-27 12:43:12 +00:00
nap0o 8e67d3487e angel-kanade模版增加主题切换功能 (#329) 2024-02-27 20:42:56 +08:00
github-actions[bot] 8033c6a0b7 update contributors[no ci] 2024-02-26 12:59:18 +00:00
naiba abb108a83e 💄 限制最大宽度 2024-02-26 20:58:50 +08:00
20 changed files with 239 additions and 164 deletions
+20 -20
View File
@@ -4,7 +4,7 @@
<br> <br>
<small><i>LOGO designed by <a href="https://xio.ng" target="_blank">熊大</a> .</i></small> <small><i>LOGO designed by <a href="https://xio.ng" target="_blank">熊大</a> .</i></small>
<br><br> <br><br>
<img alt="GitHub release (with filter)" src="https://img.shields.io/github/v/release/naiba/nezha?color=brightgreen&style=for-the-badge&logo=github&label=Dashboard">&nbsp;<img src="https://img.shields.io/github/v/release/nezhahq/agent?color=brightgreen&label=Agent&style=for-the-badge&logo=github">&nbsp;<img src="https://img.shields.io/github/actions/workflow/status/nezhahq/agent/agent.yml?label=Agent%20CI&logo=github&style=for-the-badge">&nbsp;<img src="https://img.shields.io/badge/Installer-v0.15.8-brightgreen?style=for-the-badge&logo=linux"> <img alt="GitHub release (with filter)" src="https://img.shields.io/github/v/release/naiba/nezha?color=brightgreen&style=for-the-badge&logo=github&label=Dashboard">&nbsp;<img src="https://img.shields.io/github/v/release/nezhahq/agent?color=brightgreen&label=Agent&style=for-the-badge&logo=github">&nbsp;<img src="https://img.shields.io/github/actions/workflow/status/nezhahq/agent/agent.yml?label=Agent%20CI&logo=github&style=for-the-badge">&nbsp;<img src="https://img.shields.io/badge/Installer-v0.15.9-brightgreen?style=for-the-badge&logo=linux">
<br> <br>
<br> <br>
<p>:trollface: <b>Nezha Monitoring: Self-hostable, lightweight, servers and websites monitoring and O&M tool.</b></p> <p>:trollface: <b>Nezha Monitoring: Self-hostable, lightweight, servers and websites monitoring and O&M tool.</b></p>
@@ -65,33 +65,33 @@ You can change the dashboard language in the settings page (`/setting`) after th
<a href="https://github.com/cantoblanco" title="Kris"> <a href="https://github.com/cantoblanco" title="Kris">
<img src="https://avatars.githubusercontent.com/u/116849421?v=4" width="50;" alt="Kris"/> <img src="https://avatars.githubusercontent.com/u/116849421?v=4" width="50;" alt="Kris"/>
</a> </a>
<a href="https://github.com/spiritLHLS" title="spiritlhl"> <a href="https://github.com/CosmosZ-code" title="CosmosZ-code">
<img src="https://avatars.githubusercontent.com/u/103393591?v=4" width="50;" alt="spiritlhl"/> <img src="https://avatars.githubusercontent.com/u/81398224?v=4" width="50;" alt="CosmosZ-code"/>
</a> </a>
<a href="https://github.com/liuyanxi975" title="刘颜溪"> <a href="https://github.com/liuyanxi975" title="刘颜溪">
<img src="https://avatars.githubusercontent.com/u/24417037?v=4" width="50;" alt="刘颜溪"/> <img src="https://avatars.githubusercontent.com/u/24417037?v=4" width="50;" alt="刘颜溪"/>
</a> </a>
<a href="https://github.com/CosmosZ-code" title="CosmosZ-code"> <a href="https://github.com/spiritLHLS" title="spiritlhl">
<img src="https://avatars.githubusercontent.com/u/81398224?v=4" width="50;" alt="CosmosZ-code"/> <img src="https://avatars.githubusercontent.com/u/103393591?v=4" width="50;" alt="spiritlhl"/>
</a>
<a href="https://github.com/uubulb" title="UUBulb">
<img src="https://avatars.githubusercontent.com/u/35923940?v=4" width="50;" alt="UUBulb"/>
</a>
<a href="https://github.com/lvgj-stack" title="Ko no dio">
<img src="https://avatars.githubusercontent.com/u/38449861?v=4" width="50;" alt="Ko no dio"/>
</a>
<a href="https://github.com/hhhkkk520" title="Kris">
<img src="https://avatars.githubusercontent.com/u/52115472?v=4" width="50;" alt="Kris"/>
</a> </a>
<a href="https://github.com/1ridic" title="1ridic"> <a href="https://github.com/1ridic" title="1ridic">
<img src="https://avatars.githubusercontent.com/u/88495501?v=4" width="50;" alt="1ridic"/> <img src="https://avatars.githubusercontent.com/u/88495501?v=4" width="50;" alt="1ridic"/>
</a> </a>
<a href="https://github.com/Mmx233" title="Mmx">
<img src="https://avatars.githubusercontent.com/u/36563672?v=4" width="50;" alt="Mmx"/>
</a>
<a href="https://github.com/nap0o" title="nap0o"> <a href="https://github.com/nap0o" title="nap0o">
<img src="https://avatars.githubusercontent.com/u/144927971?v=4" width="50;" alt="nap0o"/> <img src="https://avatars.githubusercontent.com/u/144927971?v=4" width="50;" alt="nap0o"/>
</a> </a>
<a href="https://github.com/hhhkkk520" title="Kris">
<img src="https://avatars.githubusercontent.com/u/52115472?v=4" width="50;" alt="Kris"/>
</a>
<a href="https://github.com/lvgj-stack" title="Ko no dio">
<img src="https://avatars.githubusercontent.com/u/38449861?v=4" width="50;" alt="Ko no dio"/>
</a>
<a href="https://github.com/uubulb" title="UUBulb">
<img src="https://avatars.githubusercontent.com/u/35923940?v=4" width="50;" alt="UUBulb"/>
</a>
<a href="https://github.com/Mmx233" title="Mmx">
<img src="https://avatars.githubusercontent.com/u/36563672?v=4" width="50;" alt="Mmx"/>
</a>
<a href="https://github.com/rootmelo92118" title="rootmelo92118"> <a href="https://github.com/rootmelo92118" title="rootmelo92118">
<img src="https://avatars.githubusercontent.com/u/32770959?v=4" width="50;" alt="rootmelo92118"/> <img src="https://avatars.githubusercontent.com/u/32770959?v=4" width="50;" alt="rootmelo92118"/>
</a> </a>
@@ -104,6 +104,9 @@ You can change the dashboard language in the settings page (`/setting`) after th
<a href="https://github.com/ch8o" title="no-name-now"> <a href="https://github.com/ch8o" title="no-name-now">
<img src="https://avatars.githubusercontent.com/u/9103372?v=4" width="50;" alt="no-name-now"/> <img src="https://avatars.githubusercontent.com/u/9103372?v=4" width="50;" alt="no-name-now"/>
</a> </a>
<a href="https://github.com/DarcJC" title="Darc Z.">
<img src="https://avatars.githubusercontent.com/u/53445798?v=4" width="50;" alt="Darc Z."/>
</a>
<a href="https://github.com/Creling" title="Creling"> <a href="https://github.com/Creling" title="Creling">
<img src="https://avatars.githubusercontent.com/u/43109504?v=4" width="50;" alt="Creling"/> <img src="https://avatars.githubusercontent.com/u/43109504?v=4" width="50;" alt="Creling"/>
</a> </a>
@@ -161,9 +164,6 @@ You can change the dashboard language in the settings page (`/setting`) after th
<a href="https://github.com/Es-dese" title="Esdese"> <a href="https://github.com/Es-dese" title="Esdese">
<img src="https://avatars.githubusercontent.com/u/71542548?v=4" width="50;" alt="Esdese"/> <img src="https://avatars.githubusercontent.com/u/71542548?v=4" width="50;" alt="Esdese"/>
</a> </a>
<a href="https://github.com/DarcJC" title="Darc Z.">
<img src="https://avatars.githubusercontent.com/u/53445798?v=4" width="50;" alt="Darc Z."/>
</a>
<a href="https://github.com/wwng2333" title="Crazy"> <a href="https://github.com/wwng2333" title="Crazy">
<img src="https://avatars.githubusercontent.com/u/17147265?v=4" width="50;" alt="Crazy"/> <img src="https://avatars.githubusercontent.com/u/17147265?v=4" width="50;" alt="Crazy"/>
</a><!--GAMFC_DELIMITER_END--> </a><!--GAMFC_DELIMITER_END-->
+4 -2
View File
@@ -858,8 +858,9 @@ type settingForm struct {
GRPCHost string GRPCHost string
Cover uint8 Cover uint8
EnableIPChangeNotification string EnableIPChangeNotification string
EnablePlainIPInNotification string EnablePlainIPInNotification string
DisableSwitchTemplateInFrontend string
} }
func (ma *memberAPI) updateSetting(c *gin.Context) { func (ma *memberAPI) updateSetting(c *gin.Context) {
@@ -907,6 +908,7 @@ func (ma *memberAPI) updateSetting(c *gin.Context) {
singleton.Conf.Language = sf.Language singleton.Conf.Language = sf.Language
singleton.Conf.EnableIPChangeNotification = sf.EnableIPChangeNotification == "on" singleton.Conf.EnableIPChangeNotification = sf.EnableIPChangeNotification == "on"
singleton.Conf.EnablePlainIPInNotification = sf.EnablePlainIPInNotification == "on" singleton.Conf.EnablePlainIPInNotification = sf.EnablePlainIPInNotification == "on"
singleton.Conf.DisableSwitchTemplateInFrontend = sf.DisableSwitchTemplateInFrontend == "on"
singleton.Conf.Cover = sf.Cover singleton.Conf.Cover = sf.Cover
singleton.Conf.GRPCHost = sf.GRPCHost singleton.Conf.GRPCHost = sf.GRPCHost
singleton.Conf.IgnoredIPNotification = sf.IgnoredIPNotification singleton.Conf.IgnoredIPNotification = sf.IgnoredIPNotification
+2 -1
View File
@@ -98,7 +98,8 @@ type Config struct {
ProxyGRPCPort uint ProxyGRPCPort uint
TLS bool TLS bool
EnablePlainIPInNotification bool // 通知信息IP不打码 EnablePlainIPInNotification bool // 通知信息IP不打码
DisableSwitchTemplateInFrontend bool // 前台禁用切换模板功能
// IP变更提醒 // IP变更提醒
EnableIPChangeNotification bool EnableIPChangeNotification bool
+3
View File
@@ -630,3 +630,6 @@ other = "Template"
[Stat] [Stat]
other = "Stat" other = "Stat"
[DisableSwitchTemplateInFrontend]
other = "Disable Switch Template in Frontend"
+4 -1
View File
@@ -203,7 +203,7 @@ other = "Agregar Servidor"
other = "Editar Grupo de Servidores en Lote" other = "Editar Grupo de Servidores en Lote"
[BatchDeleteServer] [BatchDeleteServer]
other = "Eliminar Servidores en Lote"" other = "Eliminar Servidores en Lote"
[InputServerGroupName] [InputServerGroupName]
other = "Ingrese Nombre del Grupo de Servidores" other = "Ingrese Nombre del Grupo de Servidores"
@@ -630,3 +630,6 @@ other = "Plantilla"
[Stat] [Stat]
other = "Stat" other = "Stat"
[DisableSwitchTemplateInFrontend]
other = "Deshabilitar Cambio de Plantilla en Frontend"
+3
View File
@@ -630,3 +630,6 @@ other = "主题"
[Stat] [Stat]
other = "信息" other = "信息"
[DisableSwitchTemplateInFrontend]
other = "禁止前台切换模板"
+3
View File
@@ -630,3 +630,6 @@ other = "主題"
[Stat] [Stat]
other = "信息" other = "信息"
[DisableSwitchTemplateInFrontend]
other = "禁止前台切換主題"
+1
View File
@@ -3,6 +3,7 @@
.ui.container { .ui.container {
width:95% !important; width:95% !important;
font-size: 90% !important; font-size: 90% !important;
max-width: 1300px !important;
} }
} }
@media only screen and (max-width:767px) { @media only screen and (max-width:767px) {
+11 -2
View File
@@ -70,18 +70,24 @@
<input type="text" name="IPChangeNotificationTag" placeholder="" value="{{.Conf.IPChangeNotificationTag}}"> <input type="text" name="IPChangeNotificationTag" placeholder="" value="{{.Conf.IPChangeNotificationTag}}">
</div> </div>
<div class="field"> <div class="field">
<div class="ui nf-ssl checkbox ip-change"> <div class="ui checkbox ip-change">
<input name="EnableIPChangeNotification" type="checkbox" tabindex="0" class="hidden"> <input name="EnableIPChangeNotification" type="checkbox" tabindex="0" class="hidden">
<label>{{tr "Enable"}}</label> <label>{{tr "Enable"}}</label>
</div> </div>
</div> </div>
</div> </div>
<div class="field"> <div class="field">
<div class="ui nf-ssl checkbox plain-ip"> <div class="ui checkbox plain-ip">
<input name="EnablePlainIPInNotification" type="checkbox" tabindex="0" class="hidden"> <input name="EnablePlainIPInNotification" type="checkbox" tabindex="0" class="hidden">
<label>{{tr "NotificationMessagesDoNotHideIP"}}</label> <label>{{tr "NotificationMessagesDoNotHideIP"}}</label>
</div> </div>
</div> </div>
<div class="field">
<div class="ui checkbox disable-switch-template">
<input name="DisableSwitchTemplateInFrontend" type="checkbox" tabindex="0" class="hidden">
<label>{{tr "DisableSwitchTemplateInFrontend"}}</label>
</div>
</div>
<button class="ui button" type="submit">{{tr "Save"}}</button> <button class="ui button" type="submit">{{tr "Save"}}</button>
</form> </form>
</div> </div>
@@ -128,5 +134,8 @@
{{if .Conf.EnablePlainIPInNotification}} {{if .Conf.EnablePlainIPInNotification}}
$('.checkbox.plain-ip').checkbox('set checked') $('.checkbox.plain-ip').checkbox('set checked')
{{ end }} {{ end }}
{{if .Conf.DisableSwitchTemplateInFrontend }}
$('.checkbox.disable-switch-template').checkbox('set checked')
{{ end }}
</script> </script>
{{end}} {{end}}
+2 -1
View File
@@ -1,4 +1,5 @@
{{define "theme-angel-kanade/footer"}} {{define "theme-angel-kanade/footer"}}
</div>
<div class="ui inverted vertical footer segment"> <div class="ui inverted vertical footer segment">
<div class="ui center aligned is-size-7 container"> <div class="ui center aligned is-size-7 container">
<b>&copy; <a style="color: white;" href="/">{{.Conf.Site.Brand}}</a></b> | <b>&copy; <a style="color: white;" href="/">{{.Conf.Site.Brand}}</a></b> |
@@ -13,12 +14,12 @@
<script src="/static/semantic-ui-alerts.min.js"></script> <script src="/static/semantic-ui-alerts.min.js"></script>
<script src="https://lf6-cdn-tos.bytecdntp.com/cdn/expire-1-y/vue/2.6.14/vue.min.js"></script> <script src="https://lf6-cdn-tos.bytecdntp.com/cdn/expire-1-y/vue/2.6.14/vue.min.js"></script>
<script src="/static/main.js?v20240224"></script> <script src="/static/main.js?v20240224"></script>
<script src="/static/theme-default/js/mixin.js?v20240226"></script>
<script> <script>
(function () { (function () {
updateLang({{.LANG }}); updateLang({{.LANG }});
})(); })();
</script> </script>
</body> </body>
</html> </html>
{{end}} {{end}}
+101 -100
View File
@@ -3,118 +3,116 @@
{{if ts .CustomCode}} {{.CustomCode|safe}} {{end}} {{if ts .CustomCode}} {{.CustomCode|safe}} {{end}}
{{template "theme-angel-kanade/menu" .}} {{template "theme-angel-kanade/menu" .}}
<div class="nb-container"> <div class="nb-container">
<div class="ui container"> <div class="ui container">
<div id="app"> <div class="ui styled fluid accordion" v-for="group in groups">
<div class="ui styled fluid accordion" v-for="group in groups"> <div class="active title">
<div class="active title"> <i class="dropdown icon"></i>
<i class="dropdown icon"></i> @#(group.Tag!==''?group.Tag:'{{tr "Default"}}')#@
@#(group.Tag!==''?group.Tag:'{{tr "Default"}}')#@ </div>
</div> <div class="active content">
<div class="active content"> <div class="ui four stackable status cards">
<div class="ui four stackable status cards"> <div v-for="server in group.data" :id="server.ID" class="ui card">
<div v-for="server in group.data" :id="server.ID" class="ui card"> <div class="content" v-if="server.Host" style="margin-top: 10px; padding-bottom: 5px">
<div class="content" v-if="server.Host" style="margin-top: 10px; padding-bottom: 5px"> <div class="header">
<div class="header"> <img v-if="server.Host.CountryCode" style="border-radius: 50%;box-shadow:-1px -1px 2px #eee, 1px 1px 2px #000;width:19px;" :src="'https://lf6-cdn-tos.bytecdntp.com/cdn/expire-1-y/flag-icon-css/4.1.5/flags/1x1/'+server.Host.CountryCode + '.svg'" alt="国家"/>&nbsp;<i v-if='server.Host.Platform == "darwin"'
<img v-if="server.Host.CountryCode" style="border-radius: 50%;box-shadow:-1px -1px 2px #eee, 1px 1px 2px #000;width:19px;" :src="'https://lf6-cdn-tos.bytecdntp.com/cdn/expire-1-y/flag-icon-css/4.1.5/flags/1x1/'+server.Host.CountryCode + '.svg'" alt="国家"/>&nbsp;<i v-if='server.Host.Platform == "darwin"' class="apple icon"></i><i v-else-if='isWindowsPlatform(server.Host.Platform)'
class="apple icon"></i><i v-else-if='isWindowsPlatform(server.Host.Platform)' class="windows icon"></i><i v-else :class="'fl-' + getFontLogoClass(server.Host.Platform)"></i>
class="windows icon"></i><i v-else :class="'fl-' + getFontLogoClass(server.Host.Platform)"></i> @#server.Name + (server.live?'':'[{{tr "Offline"}}]')#@
@#server.Name + (server.live?'':'[{{tr "Offline"}}]')#@ <i class="nezha-secondary-font info circle icon" style="height: 28px"></i>
<i class="nezha-secondary-font info circle icon" style="height: 28px"></i> <div class="ui content popup" style="margin-bottom: 0">
<div class="ui content popup" style="margin-bottom: 0"> {{tr "Platform"}}: @#server.Host.Platform#@-@#server.Host.PlatformVersion#@
{{tr "Platform"}}: @#server.Host.Platform#@-@#server.Host.PlatformVersion#@ [<span
[<span v-if="server.Host.Virtualization">@#server.Host.Virtualization#@:</span>@#server.Host.Arch#@]<br />
v-if="server.Host.Virtualization">@#server.Host.Virtualization#@:</span>@#server.Host.Arch#@]<br /> CPU: @#server.Host.CPU#@<br />
CPU: @#server.Host.CPU#@<br /> {{tr "DiskUsed"}}:
{{tr "DiskUsed"}}: @#formatByteSize(server.State.DiskUsed)#@/@#formatByteSize(server.Host.DiskTotal)#@<br />
@#formatByteSize(server.State.DiskUsed)#@/@#formatByteSize(server.Host.DiskTotal)#@<br /> {{tr "MemUsed"}}:
{{tr "MemUsed"}}: @#formatByteSize(server.State.MemUsed)#@/@#formatByteSize(server.Host.MemTotal)#@<br />
@#formatByteSize(server.State.MemUsed)#@/@#formatByteSize(server.Host.MemTotal)#@<br /> {{tr "SwapUsed"}}:
{{tr "SwapUsed"}}: @#formatByteSize(server.State.SwapUsed)#@/@#formatByteSize(server.Host.SwapTotal)#@<br />
@#formatByteSize(server.State.SwapUsed)#@/@#formatByteSize(server.Host.SwapTotal)#@<br /> {{tr "NetTransfer"}}: <i
{{tr "NetTransfer"}}: <i class="arrow alternate circle down outline icon"></i>@#formatByteSize(server.State.NetInTransfer)#@<i
class="arrow alternate circle down outline icon"></i>@#formatByteSize(server.State.NetInTransfer)#@<i class="arrow alternate circle up outline icon"></i>@#formatByteSize(server.State.NetOutTransfer)#@<br />
class="arrow alternate circle up outline icon"></i>@#formatByteSize(server.State.NetOutTransfer)#@<br /> {{tr "Load"}}: @# toFixed2(server.State.Load1) #@/@# toFixed2(server.State.Load5) #@/@#
{{tr "Load"}}: @# toFixed2(server.State.Load1) #@/@# toFixed2(server.State.Load5) #@/@# toFixed2(server.State.Load15) #@<br />
toFixed2(server.State.Load15) #@<br /> {{tr "ProcessCount"}}: @# server.State.ProcessCount #@<br />
{{tr "ProcessCount"}}: @# server.State.ProcessCount #@<br /> {{tr "ConnCount"}}: TCP @# server.State.TcpConnCount #@ / UDP @# server.State.UdpConnCount #@<br />
{{tr "ConnCount"}}: TCP @# server.State.TcpConnCount #@ / UDP @# server.State.UdpConnCount #@<br /> {{tr "BootTime"}}: @# formatTimestamp(server.Host.BootTime) #@<br />
{{tr "BootTime"}}: @# formatTimestamp(server.Host.BootTime) #@<br /> {{tr "LastActive"}}: @# new Date(server.LastActive).toLocaleString() #@<br />
{{tr "LastActive"}}: @# new Date(server.LastActive).toLocaleString() #@<br /> {{tr "Version"}}: @#server.Host.Version#@<br />
{{tr "Version"}}: @#server.Host.Version#@<br />
</div>
<div class="ui divider" style="margin-bottom: 5px"></div>
</div> </div>
<div class="description"> <div class="ui divider" style="margin-bottom: 5px"></div>
<div class="ui grid"> </div>
<div class="three wide column">CPU</div> <div class="description">
<div class="thirteen wide column"> <div class="ui grid">
<div :class="formatPercent(server.live,server.State.CPU, 100).class"> <div class="three wide column">CPU</div>
<div class="bar" :style="formatPercent(server.live,server.State.CPU, 100).style"> <div class="thirteen wide column">
<small>@#formatPercent(server.live,server.State.CPU,100).percent#@%</small> <div :class="formatPercent(server.live,server.State.CPU, 100).class">
</div> <div class="bar" :style="formatPercent(server.live,server.State.CPU, 100).style">
<small>@#formatPercent(server.live,server.State.CPU,100).percent#@%</small>
</div> </div>
</div> </div>
<div class="three wide column">{{tr "MemUsed"}}</div> </div>
<div class="thirteen wide column"> <div class="three wide column">{{tr "MemUsed"}}</div>
<div :class="formatPercent(server.live,server.State.MemUsed, server.Host.MemTotal).class"> <div class="thirteen wide column">
<div class="bar" <div :class="formatPercent(server.live,server.State.MemUsed, server.Host.MemTotal).class">
:style="formatPercent(server.live,server.State.MemUsed, server.Host.MemTotal).style"> <div class="bar"
<small>@#parseInt(server.State?server.State.MemUsed/server.Host.MemTotal*100:0)#@%</small> :style="formatPercent(server.live,server.State.MemUsed, server.Host.MemTotal).style">
</div> <small>@#parseInt(server.State?server.State.MemUsed/server.Host.MemTotal*100:0)#@%</small>
</div> </div>
</div> </div>
<div class="three wide column">{{tr "SwapUsed"}}</div> </div>
<div class="thirteen wide column"> <div class="three wide column">{{tr "SwapUsed"}}</div>
<div :class="formatPercent(server.live,server.State.SwapUsed, server.Host.SwapTotal).class"> <div class="thirteen wide column">
<div class="bar" <div :class="formatPercent(server.live,server.State.SwapUsed, server.Host.SwapTotal).class">
:style="formatPercent(server.live,server.State.SwapUsed, server.Host.SwapTotal).style"> <div class="bar"
<small>@#parseInt(server.State?server.State.SwapUsed/server.Host.SwapTotal*100:0)#@%</small> :style="formatPercent(server.live,server.State.SwapUsed, server.Host.SwapTotal).style">
</div> <small>@#parseInt(server.State?server.State.SwapUsed/server.Host.SwapTotal*100:0)#@%</small>
</div> </div>
</div> </div>
<div class="three wide column">{{tr "NetSpeed"}}</div> </div>
<div class="thirteen wide column"> <div class="three wide column">{{tr "NetSpeed"}}</div>
<i class="arrow alternate circle down outline icon"></i> <div class="thirteen wide column">
@#formatByteSize(server.State.NetInSpeed)#@/s <i class="arrow alternate circle down outline icon"></i>
<i class="arrow alternate circle up outline icon"></i> @#formatByteSize(server.State.NetInSpeed)#@/s
@#formatByteSize(server.State.NetOutSpeed)#@/s <i class="arrow alternate circle up outline icon"></i>
</div> @#formatByteSize(server.State.NetOutSpeed)#@/s
<div class="three wide column">{{tr "NetTransfer"}}</div> </div>
<div class="thirteen wide column"> <div class="three wide column">{{tr "NetTransfer"}}</div>
<i class="arrow circle down icon"></i> <div class="thirteen wide column">
@#formatByteSize(server.State.NetInTransfer)#@ <i class="arrow circle down icon"></i>
&nbsp; @#formatByteSize(server.State.NetInTransfer)#@
<i class="arrow circle up icon"></i> &nbsp;
@#formatByteSize(server.State.NetOutTransfer)#@ <i class="arrow circle up icon"></i>
</div> @#formatByteSize(server.State.NetOutTransfer)#@
<div class="three wide column">{{tr "DiskUsed"}}</div> </div>
<div class="thirteen wide column"> <div class="three wide column">{{tr "DiskUsed"}}</div>
<div :class="formatPercent(server.live,server.State.DiskUsed, server.Host.DiskTotal).class"> <div class="thirteen wide column">
<div class="bar" <div :class="formatPercent(server.live,server.State.DiskUsed, server.Host.DiskTotal).class">
:style="formatPercent(server.live,server.State.DiskUsed, server.Host.DiskTotal).style"> <div class="bar"
<small>@#parseInt(server.State?server.State.DiskUsed/server.Host.DiskTotal*100:0)#@%</small> :style="formatPercent(server.live,server.State.DiskUsed, server.Host.DiskTotal).style">
</div> <small>@#parseInt(server.State?server.State.DiskUsed/server.Host.DiskTotal*100:0)#@%</small>
</div> </div>
</div> </div>
<div class="three wide column">{{tr "Info"}}</div> </div>
<div class="thirteen wide column"> <div class="three wide column">{{tr "Info"}}</div>
<i class="bi bi-cpu-fill" style="font-size: 1.1rem; color: #4a86e8;"></i> @#getCoreAndGHz(server.Host.CPU)#@ <div class="thirteen wide column">
&nbsp; <i class="bi bi-cpu-fill" style="font-size: 1.1rem; color: #4a86e8;"></i> @#getCoreAndGHz(server.Host.CPU)#@
<i class="bi bi-memory" style="font-size: 1.1rem; color: #00ac0d;"></i> @#getByteToGB(server.Host.MemTotal)#@ &nbsp;
&nbsp; <i class="bi bi-memory" style="font-size: 1.1rem; color: #00ac0d;"></i> @#getByteToGB(server.Host.MemTotal)#@
<i class="bi bi-hdd-rack-fill" style="font-size: 1.1rem; color: #980000"></i> @#getByteToGB(server.Host.DiskTotal)#@ &nbsp;
</div> <i class="bi bi-hdd-rack-fill" style="font-size: 1.1rem; color: #980000"></i> @#getByteToGB(server.Host.DiskTotal)#@
<div class="three wide column">{{tr "Uptime"}}</div> </div>
<div class="thirteen wide column"> <div class="three wide column">{{tr "Uptime"}}</div>
<i class="clock icon"></i>@#secondToDate(server.State.Uptime)#@ <div class="thirteen wide column">
</div> <i class="clock icon"></i>@#secondToDate(server.State.Uptime)#@
</div> </div>
</div> </div>
</div> </div>
<div class="content" v-else> </div>
<p>@#server.Name#@</p> <div class="content" v-else>
<p>{{tr "ServerIsOffline"}}</p> <p>@#server.Name#@</p>
</div> <p>{{tr "ServerIsOffline"}}</p>
</div> </div>
</div> </div>
</div> </div>
@@ -129,10 +127,13 @@
el: '#app', el: '#app',
delimiters: ['@#', '#@'], delimiters: ['@#', '#@'],
data: { data: {
defaultTemplate: {{.Conf.Site.Theme}},
templates: {{.Themes}},
data: initData, data: initData,
groups: [], groups: [],
cache: [], cache: [],
}, },
mixins: [mixinsVue],
created() { created() {
this.group() this.group()
}, },
+9
View File
@@ -1,4 +1,5 @@
{{define "theme-angel-kanade/menu"}} {{define "theme-angel-kanade/menu"}}
<div id="app">
<div class="ui large top fixed menu nb-menu"> <div class="ui large top fixed menu nb-menu">
<div class="ui container"> <div class="ui container">
<a class="item" href="/"> <a class="item" href="/">
@@ -15,6 +16,14 @@
{{else}} {{else}}
<a class='item{{if eq .MatchedPath "/"}} active{{end}}' href="/"><i class="home icon"></i>{{tr "Home"}}</a> <a class='item{{if eq .MatchedPath "/"}} active{{end}}' href="/"><i class="home icon"></i>{{tr "Home"}}</a>
<a class='item{{if eq .MatchedPath "/service"}} active{{end}}' href="/service"><i class="rss icon"></i>{{tr "Services"}}</a> <a class='item{{if eq .MatchedPath "/service"}} active{{end}}' href="/service"><i class="rss icon"></i>{{tr "Services"}}</a>
<div class="item ui simple dropdown">
<div class="text"><i class="bi bi-incognito icon" style="margin-right:3px;"></i>{{tr "Template" }}<i class="dropdown icon" style="margin-right:0px;"></i></div>
<div class="menu">
<a v-for="(value, key) in templates" :key="key" @click="toggleTemplate(key)" class="item"><i class="th large icon"></i>@#value#@
<i class="check icon" v-if="preferredTemplate === key"></i>
</a>
</div>
</div>
{{end}} {{end}}
<div class="right menu"> <div class="right menu">
<div class="item"> <div class="item">
+11 -1
View File
@@ -76,10 +76,20 @@
{{end}} {{end}}
</tbody> </tbody>
</table> </table>
{{end}} {{end}}
</div> </div>
</div> </div>
</div> </div>
{{template "theme-angel-kanade/footer" .}} {{template "theme-angel-kanade/footer" .}}
<script>
new Vue({
el: '#app',
delimiters: ['@#', '#@'],
data: {
defaultTemplate: {{.Conf.Site.Theme}},
templates: {{.Themes}}
},
mixins: [mixinsVue]
})
</script>
{{end}} {{end}}
+10
View File
@@ -7,6 +7,16 @@
{{.Version}}</small> {{.Version}}</small>
</div> </div>
</div> </div>
{{ if not .Conf.DisableSwitchTemplateInFrontend }}
<script>
function showSwitchTemplate(list, currentBackendTheme) {
console.log(list, currentBackendTheme);
}
showSwitchTemplate({{ .Themes }}, {{ .Conf.Site.Theme }})
</script>
{{ end }}
<script>
</script>
</body> </body>
</html> </html>
{{end}} {{end}}
+11 -9
View File
@@ -140,16 +140,15 @@
page: 'index', page: 'index',
defaultTemplate: {{.Conf.Site.Theme}}, defaultTemplate: {{.Conf.Site.Theme}},
templates: {{.Themes}}, templates: {{.Themes}},
data: [], servers: [],
groups: [], groups: [],
cache: [], cache: [],
chartDataList: [], chartDataList: [],
activePopup: null, activePopup: null,
}, },
mixins: [mixinsVue], mixins: [mixinsVue],
created() { created() {
this.data = JSON.parse('{{.Servers}}').servers; this.servers = JSON.parse('{{.Servers}}').servers;
this.group() this.group()
}, },
methods: { methods: {
@@ -189,8 +188,9 @@
const MaxTCPPingValue = {{.MaxTCPPingValue}} ? {{.MaxTCPPingValue}} : 300; const MaxTCPPingValue = {{.MaxTCPPingValue}} ? {{.MaxTCPPingValue}} : 300;
const isMobile = this.checkIsMobile(); const isMobile = this.checkIsMobile();
const fontSize = isMobile ? 10 : 9; const fontSize = isMobile ? 10 : 9;
const itemGap = isMobile ? 5 : 2; const itemGap = isMobile ? 6 : 6;
const itemWidth = isMobile ? 20 : 15; const itemWidth = isMobile ? 10 : 10;
const itemHeight = isMobile ? 10 : 10;
const gridLeft = 25; const gridLeft = 25;
const gridRight = 12; const gridRight = 12;
const fontColor = "rgba(0, 0, 0, 0.68)"; const fontColor = "rgba(0, 0, 0, 0.68)";
@@ -211,10 +211,10 @@
if (avgDelay > 0.9 * MaxTCPPingValue) { if (avgDelay > 0.9 * MaxTCPPingValue) {
loss += 1; loss += 1;
} }
return [new Date(item.created_at[index]).toLocaleString(), avgDelay]; return [item.created_at[index], avgDelay];
}); });
const lossRate = ((loss / item.created_at.length) * 100).toFixed(1); const lossRate = ((loss / item.created_at.length) * 100).toFixed(1);
item.monitor_name = item.monitor_name + " " + lossRate + "%"; item.monitor_name = item.monitor_name.includes("%") ? item.monitor_name : `${item.monitor_name} ${lossRate}%`;
return { return {
name: item.monitor_name, name: item.monitor_name,
type: 'line', type: 'line',
@@ -237,6 +237,7 @@
} }
}, },
legend: { legend: {
icon: 'rect',
data: chartData.map(item => item.monitor_name), data: chartData.map(item => item.monitor_name),
show: true, show: true,
textStyle: { textStyle: {
@@ -250,6 +251,7 @@
bottom: 0, bottom: 0,
itemGap: itemGap, itemGap: itemGap,
itemWidth: itemWidth, itemWidth: itemWidth,
itemHeight: itemHeight,
padding: [5,0,5,0] padding: [5,0,5,0]
}, },
xAxis: { xAxis: {
@@ -283,7 +285,7 @@
color: fontColor color: fontColor
}, },
grid: { grid: {
top: '40', top: '30',
bottom: '20', bottom: '20',
left: gridLeft, left: gridLeft,
right: gridRight right: gridRight
@@ -358,7 +360,7 @@
return ''; return '';
}, },
group() { group() {
this.groups = groupingData(this.data, "Tag") this.groups = groupingData(this.servers, "Tag")
}, },
formatPercent(live, used, total) { formatPercent(live, used, total) {
const percent = live ? (parseInt(used / total * 100) || 0) : -1 const percent = live ? (parseInt(used / total * 100) || 0) : -1
+1 -1
View File
@@ -21,7 +21,7 @@
<a data-toggle="dropdown"><i class="bi bi-gear-wide-connected" style="position:relative;top:1px;margin-right:3px;font-size:1.1rem;"></i>{{tr "Feature" }}<b class="caret"></b></a> <a data-toggle="dropdown"><i class="bi bi-gear-wide-connected" style="position:relative;top:1px;margin-right:3px;font-size:1.1rem;"></i>{{tr "Feature" }}<b class="caret"></b></a>
<ul class="dropdown-menu" style="min-width:100px;"> <ul class="dropdown-menu" style="min-width:100px;">
<li><a href="/service"><i class="rss icon"></i>{{tr "Services" }}</a></li> <li><a href="/service"><i class="rss icon"></i>{{tr "Services" }}</a></li>
<li><a href="/network"><i class="bi bi-hdd-network icon"></i>{{tr "NetworkSpiter"}}</a></li> <li><a href="/network"><i class="bi bi-hdd-network icon"></i>{{tr "NetworkSpiter"}}</a></li>
</ul> </ul>
</li> </li>
</template> </template>
+37 -20
View File
@@ -24,21 +24,35 @@
page: 'index', page: 'index',
defaultTemplate: {{.Conf.Site.Theme}}, defaultTemplate: {{.Conf.Site.Theme}},
templates: {{.Themes}}, templates: {{.Themes}},
cache: [],
servers: [],
nodesTag: [], nodesTag: [],
nodesNoTag: [], nodesNoTag: [],
chartDataList: [] chartDataList: [],
ws: null
}, },
mixins: [mixinsVue], mixins: [mixinsVue],
created() { created() {
initData = JSON.parse('{{.Servers}}').servers; this.servers = JSON.parse('{{.Servers}}').servers;
if(this.showGroup) { if(this.showGroup) {
this.nodesTag = this.groupingData(this.handleNodes(initData),"Tag"); this.nodesTag = this.groupingData(this.handleNodes(this.servers),"Tag");
} else { } else {
this.nodesNoTag = this.handleNodes(initData); this.nodesNoTag = this.handleNodes(this.servers);
} }
}, },
mounted() { mounted() {
// 初始化时建立WebSocket连接
this.connect(); this.connect();
// 监听页面可见性变化
document.addEventListener("visibilitychange", () => {
if (document.visibilityState === "visible") {
setTimeout(() => {
if (document.hasFocus()) {
this.connect();
}
}, 200);
}
});
}, },
methods: { methods: {
isWindowsPlatform(str) { isWindowsPlatform(str) {
@@ -156,12 +170,18 @@
return parseFloat((bytes / Math.pow(1024, i)).toFixed(2)) + sizes[i]; return parseFloat((bytes / Math.pow(1024, i)).toFixed(2)) + sizes[i];
}, },
connect() { connect() {
const wsProtocol = window.location.protocol === "https:" ? "wss" : "ws" // 如果已经存在 WebSocket 连接并且处于开启状态,则不重复建立连接
const ws = new WebSocket(wsProtocol + '://' + window.location.host + '/ws'); if (this.ws && this.ws.readyState === WebSocket.OPEN) {
ws.onopen = function () { console.log('Closing old WebSocket connection...');
this.ws.close();
}
const wsProtocol = window.location.protocol === "https:" ? "wss" : "ws";
this.ws = new WebSocket(wsProtocol + '://' + window.location.host + '/ws');
this.ws.onopen = function () {
console.log("Connection open ...") console.log("Connection open ...")
} }
ws.onmessage = (evt) => { this.ws.onmessage = (evt) => {
let jsonData = evt.data let jsonData = evt.data
const data = JSON.parse(jsonData) const data = JSON.parse(jsonData)
for (let i = 0; i < data.servers?.length; i++) { for (let i = 0; i < data.servers?.length; i++) {
@@ -179,13 +199,13 @@
this.nodesNoTag = this.handleNodes(data.servers); this.nodesNoTag = this.handleNodes(data.servers);
} }
} }
ws.onclose = () => { this.ws.onclose = () => {
setTimeout(function () { setTimeout(() => {
this.connect() this.connect();
}, 5000); }, 5000);
} };
ws.onerror = function () { this.ws.onerror = () => {
ws.close() this.ws.close()
} }
}, },
handleNodes(servers) { handleNodes(servers) {
@@ -289,12 +309,10 @@
if (avgDelay > 0.9 * MaxTCPPingValue) { if (avgDelay > 0.9 * MaxTCPPingValue) {
loss += 1; loss += 1;
} }
return [new Date(item.created_at[index]).toLocaleString(), avgDelay]; return [item.created_at[index], avgDelay];
}); });
const lossRate = ((loss / item.created_at.length) * 100).toFixed(1); const lossRate = ((loss / item.created_at.length) * 100).toFixed(1);
if (!item.monitor_name.includes("%")) { item.monitor_name = item.monitor_name.includes("%") ? item.monitor_name : `${item.monitor_name} ${lossRate}%`;
item.monitor_name = item.monitor_name + " " + lossRate + "%";
}
return { return {
name: item.monitor_name, name: item.monitor_name,
type: 'line', type: 'line',
@@ -367,8 +385,7 @@
chart.setOption(option); chart.setOption(option);
}, },
reloadCharts() { // 重新加载所有图表 reloadCharts() { // 重新加载所有图表
const data = JSON.parse('{{.Servers}}').servers; this.servers.forEach(node => {
data.forEach(node => {
const id = node.ID; const id = node.ID;
const chartData = this.chartDataList[id - 1]; const chartData = this.chartDataList[id - 1];
if (chartData) { if (chartData) {
+2 -2
View File
@@ -38,8 +38,8 @@ $download = "https://github.com/$agentrepo/releases/download/$agenttag/$file"
$nssmdownload="https://github.com/$nssmrepo/releases/download/$nssmtag/nssm.zip" $nssmdownload="https://github.com/$nssmrepo/releases/download/$nssmtag/nssm.zip"
Write-Host "Location:$region,connect directly!" -BackgroundColor DarkRed -ForegroundColor Green Write-Host "Location:$region,connect directly!" -BackgroundColor DarkRed -ForegroundColor Green
}else{ }else{
$download = "https://kkgithub.com/$agentrepo/releases/download/$agenttag/$file" $download = "https://dn-dao-github-mirror.daocloud.io/$agentrepo/releases/download/$agenttag/$file"
$nssmdownload="https://kkgithub.com/$nssmrepo/releases/download/$nssmtag/nssm.zip" $nssmdownload="https://dn-dao-github-mirror.daocloud.io/$nssmrepo/releases/download/$nssmtag/nssm.zip"
Write-Host "Location:CN,use mirror address" -BackgroundColor DarkRed -ForegroundColor Green Write-Host "Location:CN,use mirror address" -BackgroundColor DarkRed -ForegroundColor Green
} }
echo $download echo $download
+2 -2
View File
@@ -14,7 +14,7 @@ NZ_AGENT_SERVICE="/etc/systemd/system/nezha-agent.service"
NZ_AGENT_SERVICERC="/etc/init.d/nezha-agent" NZ_AGENT_SERVICERC="/etc/init.d/nezha-agent"
NZ_DASHBOARD_SERVICE="/etc/systemd/system/nezha-dashboard.service" NZ_DASHBOARD_SERVICE="/etc/systemd/system/nezha-dashboard.service"
NZ_DASHBOARD_SERVICERC="/etc/init.d/nezha-dashboard" NZ_DASHBOARD_SERVICERC="/etc/init.d/nezha-dashboard"
NZ_VERSION="v0.15.8" NZ_VERSION="v0.15.9"
red='\033[0;31m' red='\033[0;31m'
green='\033[0;32m' green='\033[0;32m'
@@ -94,7 +94,7 @@ pre_check() {
Docker_IMG="ghcr.io\/naiba\/nezha-dashboard" Docker_IMG="ghcr.io\/naiba\/nezha-dashboard"
else else
GITHUB_RAW_URL="gitee.com/naibahq/nezha/raw/master" GITHUB_RAW_URL="gitee.com/naibahq/nezha/raw/master"
GITHUB_URL="kkgithub.com" GITHUB_URL="dn-dao-github-mirror.daocloud.io"
Get_Docker_URL="get.docker.com" Get_Docker_URL="get.docker.com"
Get_Docker_Argu=" -s docker --mirror Aliyun" Get_Docker_Argu=" -s docker --mirror Aliyun"
Docker_IMG="registry.cn-shanghai.aliyuncs.com\/naibahq\/nezha-dashboard" Docker_IMG="registry.cn-shanghai.aliyuncs.com\/naibahq\/nezha-dashboard"
+2 -2
View File
@@ -14,7 +14,7 @@ NZ_AGENT_SERVICE="/etc/systemd/system/nezha-agent.service"
NZ_AGENT_SERVICERC="/etc/init.d/nezha-agent" NZ_AGENT_SERVICERC="/etc/init.d/nezha-agent"
NZ_DASHBOARD_SERVICE="/etc/systemd/system/nezha-dashboard.service" NZ_DASHBOARD_SERVICE="/etc/systemd/system/nezha-dashboard.service"
NZ_DASHBOARD_SERVICERC="/etc/init.d/nezha-dashboard" NZ_DASHBOARD_SERVICERC="/etc/init.d/nezha-dashboard"
NZ_VERSION="v0.15.8" NZ_VERSION="v0.15.9"
red='\033[0;31m' red='\033[0;31m'
green='\033[0;32m' green='\033[0;32m'
@@ -93,7 +93,7 @@ pre_check() {
Docker_IMG="ghcr.io\/naiba\/nezha-dashboard" Docker_IMG="ghcr.io\/naiba\/nezha-dashboard"
else else
GITHUB_RAW_URL="gitee.com/naibahq/nezha/raw/master" GITHUB_RAW_URL="gitee.com/naibahq/nezha/raw/master"
GITHUB_URL="kkgithub.com" GITHUB_URL="dn-dao-github-mirror.daocloud.io"
Get_Docker_URL="get.docker.com" Get_Docker_URL="get.docker.com"
Get_Docker_Argu=" -s docker --mirror Aliyun" Get_Docker_Argu=" -s docker --mirror Aliyun"
Docker_IMG="registry.cn-shanghai.aliyuncs.com\/naibahq\/nezha-dashboard" Docker_IMG="registry.cn-shanghai.aliyuncs.com\/naibahq\/nezha-dashboard"