mirror of
https://github.com/acepanel/panel.git
synced 2026-02-04 17:17:13 +08:00
feat: home page
This commit is contained in:
@@ -44,14 +44,9 @@ func (receiver *Monitoring) Handle(ctx console.Context) error {
|
||||
return nil
|
||||
}
|
||||
|
||||
info, err := helpers.GetMonitoringInfo()
|
||||
if err != nil {
|
||||
facades.Log().Errorf("[面板] 系统监控失败: %s", err.Error())
|
||||
color.Redf("[面板] 系统监控失败: %s", err.Error())
|
||||
return nil
|
||||
}
|
||||
info := helpers.GetMonitoringInfo()
|
||||
|
||||
err = facades.Orm().Query().Create(&models.Monitor{
|
||||
err := facades.Orm().Query().Create(&models.Monitor{
|
||||
Info: info,
|
||||
})
|
||||
if err != nil {
|
||||
|
||||
@@ -97,12 +97,14 @@ func (receiver *Panel) Handle(ctx console.Context) error {
|
||||
return nil
|
||||
}
|
||||
|
||||
color.Greenln("用户名: " + user.Username)
|
||||
color.Greenln("密码: " + password)
|
||||
|
||||
nginxConf, err := os.ReadFile("/www/server/nginx/conf/nginx.conf")
|
||||
if err != nil {
|
||||
color.Redln("获取面板端口失败,请检查Nginx主配置文件")
|
||||
return nil
|
||||
}
|
||||
|
||||
match := regexp.MustCompile(`listen\s+(\d+)`).FindStringSubmatch(string(nginxConf))
|
||||
if len(match) < 2 {
|
||||
color.Redln("获取面板端口失败,请检查Nginx主配置文件")
|
||||
@@ -110,8 +112,6 @@ func (receiver *Panel) Handle(ctx console.Context) error {
|
||||
}
|
||||
|
||||
port := match[1]
|
||||
color.Greenln("用户名: " + user.Username)
|
||||
color.Greenln("密码: " + password)
|
||||
color.Greenln("面板端口: " + port)
|
||||
|
||||
case "getPort":
|
||||
|
||||
@@ -2,7 +2,7 @@ package controllers
|
||||
|
||||
import "github.com/goravel/framework/contracts/http"
|
||||
|
||||
func Success(ctx http.Context, data http.Json) {
|
||||
func Success(ctx http.Context, data any) {
|
||||
ctx.Response().Success().Json(http.Json{
|
||||
"code": 0,
|
||||
"message": "success",
|
||||
|
||||
@@ -1,12 +1,22 @@
|
||||
package controllers
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
|
||||
"github.com/goravel/framework/contracts/http"
|
||||
"github.com/goravel/framework/facades"
|
||||
|
||||
"panel/app/models"
|
||||
"panel/packages/helpers"
|
||||
)
|
||||
|
||||
type MenuItem struct {
|
||||
Name string `json:"name"`
|
||||
Title string `json:"title"`
|
||||
Icon string `json:"icon"`
|
||||
Jump string `json:"jump"`
|
||||
}
|
||||
|
||||
type InfoController struct {
|
||||
//Dependent services
|
||||
}
|
||||
@@ -30,3 +40,42 @@ func (r *InfoController) Name(ctx http.Context) {
|
||||
"name": setting.Value,
|
||||
})
|
||||
}
|
||||
|
||||
func (r *InfoController) Menu(ctx http.Context) {
|
||||
Success(ctx, []MenuItem{
|
||||
{Name: "home", Title: "主页", Icon: "layui-icon-home", Jump: "/"},
|
||||
{Name: "website", Title: "网站管理", Icon: "layui-icon-website", Jump: "website/list"},
|
||||
{Name: "monitor", Title: "资源监控", Icon: "layui-icon-chart-screen", Jump: "monitor"},
|
||||
{Name: "safe", Title: "系统安全", Icon: "layui-icon-auz", Jump: "safe"},
|
||||
{Name: "file", Title: "文件管理", Icon: "layui-icon-file", Jump: "file"},
|
||||
{Name: "cron", Title: "计划任务", Icon: "layui-icon-date", Jump: "cron"},
|
||||
{Name: "plugin", Title: "插件中心", Icon: "layui-icon-app", Jump: "plugin"},
|
||||
{Name: "setting", Title: "面板设置", Icon: "layui-icon-set", Jump: "setting"},
|
||||
})
|
||||
}
|
||||
|
||||
func (r *InfoController) HomePlugins(ctx http.Context) {
|
||||
var plugins []models.Plugin
|
||||
err := facades.Orm().Query().Where("show", 1).Find(&plugins)
|
||||
if err != nil {
|
||||
facades.Log().Error("[面板][InfoController] 查询首页插件失败 ", err)
|
||||
Error(ctx, http.StatusInternalServerError, "系统内部错误")
|
||||
return
|
||||
}
|
||||
|
||||
Success(ctx, plugins)
|
||||
}
|
||||
|
||||
func (r *InfoController) NowMonitor(ctx http.Context) {
|
||||
Success(ctx, helpers.GetMonitoringInfo())
|
||||
}
|
||||
|
||||
func (r *InfoController) SystemInfo(ctx http.Context) {
|
||||
monitorInfo := helpers.GetMonitoringInfo()
|
||||
|
||||
Success(ctx, http.Json{
|
||||
"os_name": monitorInfo.Host.Platform + " " + monitorInfo.Host.PlatformVersion,
|
||||
"uptime": fmt.Sprintf("%.2f", float64(monitorInfo.Host.Uptime)/86400),
|
||||
"panel_version": facades.Config().GetString("panel.version"),
|
||||
})
|
||||
}
|
||||
|
||||
32
app/http/controllers/task_controller.go
Normal file
32
app/http/controllers/task_controller.go
Normal file
@@ -0,0 +1,32 @@
|
||||
package controllers
|
||||
|
||||
import (
|
||||
"github.com/goravel/framework/contracts/http"
|
||||
"github.com/goravel/framework/facades"
|
||||
"panel/app/models"
|
||||
)
|
||||
|
||||
type TaskController struct {
|
||||
//Dependent services
|
||||
}
|
||||
|
||||
func NewTaskController() *TaskController {
|
||||
return &TaskController{
|
||||
//Inject services
|
||||
}
|
||||
}
|
||||
|
||||
func (r *TaskController) Status(ctx http.Context) {
|
||||
var task models.Task
|
||||
err := facades.Orm().Query().Where("status", models.TaskStatusWaiting).OrWhere("status", models.TaskStatusRunning).FirstOrFail(&task)
|
||||
if err == nil {
|
||||
Success(ctx, http.Json{
|
||||
"task": true,
|
||||
})
|
||||
return
|
||||
}
|
||||
|
||||
Success(ctx, http.Json{
|
||||
"task": false,
|
||||
})
|
||||
}
|
||||
@@ -13,7 +13,7 @@ import (
|
||||
// Jwt 确保通过 JWT 鉴权
|
||||
func Jwt() http.Middleware {
|
||||
return func(ctx http.Context) {
|
||||
token := ctx.Request().Header("Authorization", "")
|
||||
token := ctx.Request().Input("access_token", "")
|
||||
if len(token) == 0 {
|
||||
ctx.Request().AbortWithStatusJson(http.StatusUnauthorized, http.Json{
|
||||
"code": 401,
|
||||
|
||||
13
config/panel.go
Normal file
13
config/panel.go
Normal file
@@ -0,0 +1,13 @@
|
||||
package config
|
||||
|
||||
import (
|
||||
"github.com/goravel/framework/facades"
|
||||
)
|
||||
|
||||
func init() {
|
||||
config := facades.Config()
|
||||
config.Add("panel", map[string]any{
|
||||
"name": "耗子Linux面板",
|
||||
"version": "2.0.0",
|
||||
})
|
||||
}
|
||||
25
go.mod
25
go.mod
@@ -3,8 +3,14 @@ module panel
|
||||
go 1.18
|
||||
|
||||
require (
|
||||
github.com/goravel/framework v1.12.3-0.20230622070736-f7260a71f319
|
||||
google.golang.org/grpc v1.56.0
|
||||
github.com/gertd/go-pluralize v0.2.1
|
||||
github.com/gin-contrib/static v0.0.1
|
||||
github.com/gookit/color v1.5.3
|
||||
github.com/goravel/framework v1.12.3
|
||||
github.com/iancoleman/strcase v0.2.0
|
||||
github.com/mojocn/base64Captcha v1.3.5
|
||||
github.com/spf13/cast v1.5.1
|
||||
github.com/stretchr/testify v1.8.4
|
||||
)
|
||||
|
||||
require (
|
||||
@@ -39,12 +45,11 @@ require (
|
||||
github.com/dustin/go-humanize v1.0.1 // indirect
|
||||
github.com/fsnotify/fsnotify v1.6.0 // indirect
|
||||
github.com/gabriel-vasile/mimetype v1.4.2 // indirect
|
||||
github.com/gertd/go-pluralize v0.2.1 // indirect
|
||||
github.com/gin-contrib/sse v0.1.0 // indirect
|
||||
github.com/gin-contrib/static v0.0.1 // indirect
|
||||
github.com/gin-gonic/gin v1.9.1 // indirect
|
||||
github.com/glebarez/go-sqlite v1.21.1 // indirect
|
||||
github.com/glebarez/sqlite v1.8.0 // indirect
|
||||
github.com/go-ole/go-ole v1.2.6 // indirect
|
||||
github.com/go-playground/locales v0.14.1 // indirect
|
||||
github.com/go-playground/universal-translator v0.18.1 // indirect
|
||||
github.com/go-playground/validator/v10 v10.14.1 // indirect
|
||||
@@ -71,7 +76,6 @@ require (
|
||||
github.com/google/wire v0.5.0 // indirect
|
||||
github.com/googleapis/enterprise-certificate-proxy v0.2.3 // indirect
|
||||
github.com/googleapis/gax-go/v2 v2.8.0 // indirect
|
||||
github.com/gookit/color v1.5.3 // indirect
|
||||
github.com/gookit/filter v1.1.4 // indirect
|
||||
github.com/gookit/goutil v0.5.15 // indirect
|
||||
github.com/gookit/validate v1.4.6 // indirect
|
||||
@@ -81,7 +85,6 @@ require (
|
||||
github.com/hashicorp/errwrap v1.1.0 // indirect
|
||||
github.com/hashicorp/go-multierror v1.1.1 // indirect
|
||||
github.com/hashicorp/hcl v1.0.0 // indirect
|
||||
github.com/iancoleman/strcase v0.2.0 // indirect
|
||||
github.com/imdario/mergo v0.3.13 // indirect
|
||||
github.com/jackc/pgpassfile v1.0.0 // indirect
|
||||
github.com/jackc/pgservicefile v0.0.0-20221227161230-091c0ba34f0a // indirect
|
||||
@@ -104,7 +107,6 @@ require (
|
||||
github.com/moby/term v0.5.0 // indirect
|
||||
github.com/modern-go/concurrent v0.0.0-20180306012644-bacd9c7ef1dd // indirect
|
||||
github.com/modern-go/reflect2 v1.0.2 // indirect
|
||||
github.com/mojocn/base64Captcha v1.3.5 // indirect
|
||||
github.com/opencontainers/go-digest v1.0.0 // indirect
|
||||
github.com/opencontainers/image-spec v1.0.2 // indirect
|
||||
github.com/opencontainers/runc v1.1.5 // indirect
|
||||
@@ -117,21 +119,20 @@ require (
|
||||
github.com/remyoudompheng/bigfft v0.0.0-20230129092748-24d4a6f8daec // indirect
|
||||
github.com/rifflock/lfshook v0.0.0-20180920164130-b9218ef580f5 // indirect
|
||||
github.com/robfig/cron/v3 v3.0.1 // indirect
|
||||
github.com/rs/cors v1.9.0 // indirect
|
||||
github.com/russross/blackfriday/v2 v2.1.0 // indirect
|
||||
github.com/shirou/gopsutil v3.21.11+incompatible // indirect
|
||||
github.com/sirupsen/logrus v1.9.3 // indirect
|
||||
github.com/spf13/afero v1.9.5 // indirect
|
||||
github.com/spf13/cast v1.5.1 // indirect
|
||||
github.com/spf13/jwalterweatherman v1.1.0 // indirect
|
||||
github.com/spf13/pflag v1.0.5 // indirect
|
||||
github.com/spf13/viper v1.16.0 // indirect
|
||||
github.com/streadway/amqp v1.0.0 // indirect
|
||||
github.com/stretchr/objx v0.5.0 // indirect
|
||||
github.com/stretchr/testify v1.8.4 // indirect
|
||||
github.com/subosito/gotenv v1.4.2 // indirect
|
||||
github.com/tklauser/go-sysconf v0.3.11 // indirect
|
||||
github.com/tklauser/numcpus v0.6.0 // indirect
|
||||
github.com/twitchyliquid64/golang-asm v0.15.1 // indirect
|
||||
github.com/ugorji/go/codec v1.2.11 // indirect
|
||||
github.com/unrolled/secure v1.13.0 // indirect
|
||||
github.com/urfave/cli/v2 v2.25.6 // indirect
|
||||
github.com/xdg-go/pbkdf2 v1.0.0 // indirect
|
||||
github.com/xdg-go/scram v1.1.1 // indirect
|
||||
@@ -142,6 +143,7 @@ require (
|
||||
github.com/xo/terminfo v0.0.0-20220910002029-abceb7e1c41e // indirect
|
||||
github.com/xrash/smetrics v0.0.0-20201216005158-039620a65673 // indirect
|
||||
github.com/youmark/pkcs8 v0.0.0-20181117223130-1be2e3e5546d // indirect
|
||||
github.com/yusufpapurcu/wmi v1.2.3 // indirect
|
||||
go.mongodb.org/mongo-driver v1.7.5 // indirect
|
||||
go.opencensus.io v0.24.0 // indirect
|
||||
go.uber.org/atomic v1.11.0 // indirect
|
||||
@@ -160,6 +162,7 @@ require (
|
||||
google.golang.org/genproto v0.0.0-20230525234025-438c736192d0 // indirect
|
||||
google.golang.org/genproto/googleapis/api v0.0.0-20230525234020-1aefcd67740a // indirect
|
||||
google.golang.org/genproto/googleapis/rpc v0.0.0-20230530153820-e85fd2cbaebc // indirect
|
||||
google.golang.org/grpc v1.56.0 // indirect
|
||||
google.golang.org/protobuf v1.30.0 // indirect
|
||||
gopkg.in/ini.v1 v1.67.0 // indirect
|
||||
gopkg.in/yaml.v2 v2.4.0 // indirect
|
||||
|
||||
22
go.sum
22
go.sum
@@ -172,6 +172,8 @@ github.com/go-gl/glfw/v3.3/glfw v0.0.0-20191125211704-12ad95a8df72/go.mod h1:tQ2
|
||||
github.com/go-gl/glfw/v3.3/glfw v0.0.0-20200222043503-6f7a984d4dc4/go.mod h1:tQ2UAYgL5IevRw8kRxooKSPJfGvJ9fJQFa0TUsXzTg8=
|
||||
github.com/go-kit/log v0.1.0/go.mod h1:zbhenjAZHb184qTLMA9ZjW7ThYL0H2mk7Q6pNt4vbaY=
|
||||
github.com/go-logfmt/logfmt v0.5.0/go.mod h1:wCYkCAKZfumFQihp8CzCvQ3paCTfi41vtzG1KdI/P7A=
|
||||
github.com/go-ole/go-ole v1.2.6 h1:/Fpf6oFPoeFik9ty7siob0G6Ke8QvQEuVcuChpwXzpY=
|
||||
github.com/go-ole/go-ole v1.2.6/go.mod h1:pprOEPIfldk/42T2oK7lQ4v4JSDwmV0As9GaiUsvbm0=
|
||||
github.com/go-playground/assert/v2 v2.0.1/go.mod h1:VDjEfimB/XKnb+ZQfWdccd7VUvScMdVu0Titje2rxJ4=
|
||||
github.com/go-playground/assert/v2 v2.2.0 h1:JvknZsQTYeFEAhQwI4qEt9cyV5ONwRHC+lYKSsYSR8s=
|
||||
github.com/go-playground/locales v0.13.0/go.mod h1:taPMhCMXrRLJO55olJkUXHZBHCxTMfnGwq/HNwmWNS8=
|
||||
@@ -181,8 +183,6 @@ github.com/go-playground/universal-translator v0.17.0/go.mod h1:UkSxE5sNxxRwHyU+
|
||||
github.com/go-playground/universal-translator v0.18.1 h1:Bcnm0ZwsGyWbCzImXv+pAJnYK9S473LQFuzCbDbfSFY=
|
||||
github.com/go-playground/universal-translator v0.18.1/go.mod h1:xekY+UJKNuX9WP91TpwSH2VMlDf28Uj24BCp08ZFTUY=
|
||||
github.com/go-playground/validator/v10 v10.2.0/go.mod h1:uOYAAleCW8F/7oMFd6aG0GOhaH6EGOAJShg8Id5JGkI=
|
||||
github.com/go-playground/validator/v10 v10.14.0 h1:vgvQWe3XCz3gIeFDm/HnTIbj6UGmg/+t63MyGU2n5js=
|
||||
github.com/go-playground/validator/v10 v10.14.0/go.mod h1:9iXMNT7sEkjXb0I+enO7QXmzG6QCsPWY4zveKFVRSyU=
|
||||
github.com/go-playground/validator/v10 v10.14.1 h1:9c50NUPC30zyuKprjL3vNZ0m5oG+jU0zvx4AqHGnv4k=
|
||||
github.com/go-playground/validator/v10 v10.14.1/go.mod h1:9iXMNT7sEkjXb0I+enO7QXmzG6QCsPWY4zveKFVRSyU=
|
||||
github.com/go-redis/redis v6.15.9+incompatible h1:K0pv1D7EQUjfyoMql+r/jZqCLizCGKFlFgcHWWmHQjg=
|
||||
@@ -346,10 +346,8 @@ github.com/goravel/file-rotatelogs v0.0.0-20211215053220-2ab31dd9575c h1:obhFK91
|
||||
github.com/goravel/file-rotatelogs v0.0.0-20211215053220-2ab31dd9575c/go.mod h1:YSWsLXlG16u5CWFaXNZHhEQD10+NwF3xfgDV816OwLE=
|
||||
github.com/goravel/file-rotatelogs/v2 v2.4.1 h1:ogkeIFcTHSBRUBpZYiyJbpul8hkVXxHPuDbOaP78O1M=
|
||||
github.com/goravel/file-rotatelogs/v2 v2.4.1/go.mod h1:euk9qr52WrzM8ICs1hecFcR4CZ/ZZOPdacHfvHgbOf0=
|
||||
github.com/goravel/framework v1.12.2 h1:2d+RQEVzcky6ff6LxlcPvnAj0tZPc0Y4yQAXQk88+nA=
|
||||
github.com/goravel/framework v1.12.2/go.mod h1:96GRS8270PKLfJU9zrrLE7XKlp20S2TJ9RB337jBMy4=
|
||||
github.com/goravel/framework v1.12.3-0.20230622070736-f7260a71f319 h1:xs7YlSAXdSJs0olT59PBwwj+3Rn5nTKASgNc+GUqsV8=
|
||||
github.com/goravel/framework v1.12.3-0.20230622070736-f7260a71f319/go.mod h1:96GRS8270PKLfJU9zrrLE7XKlp20S2TJ9RB337jBMy4=
|
||||
github.com/goravel/framework v1.12.3 h1:gGP+7fV7qAoBVh6zz8C4caQX9Vs8XTmqSJdMa/S9BsI=
|
||||
github.com/goravel/framework v1.12.3/go.mod h1:96GRS8270PKLfJU9zrrLE7XKlp20S2TJ9RB337jBMy4=
|
||||
github.com/gorilla/securecookie v1.1.1/go.mod h1:ra0sb63/xPlUeL+yeDciTfxMRAA+MP+HVt/4epWDjd4=
|
||||
github.com/gorilla/sessions v1.2.1/go.mod h1:dk2InVEVJ0sfLlnXv9EAgkf6ecYs/i80K/zI+bUmuGM=
|
||||
github.com/grpc-ecosystem/go-grpc-middleware v1.4.0 h1:UH//fgunKIs4JdUbpDl1VZCDaL56wXCB/5+wF6uHfaI=
|
||||
@@ -522,11 +520,12 @@ github.com/rogpeppe/go-internal v1.2.2/go.mod h1:M8bDsm7K2OlrFYOpmOWEs/qY81heoFR
|
||||
github.com/rogpeppe/go-internal v1.3.0/go.mod h1:M8bDsm7K2OlrFYOpmOWEs/qY81heoFRclV5y23lUDJ4=
|
||||
github.com/rogpeppe/go-internal v1.9.0 h1:73kH8U+JUqXU8lRuOHeVHaa/SZPifC7BkcraZVejAe8=
|
||||
github.com/rs/cors v1.9.0 h1:l9HGsTsHJcvW14Nk7J9KFz8bzeAWXn3CG6bgt7LsrAE=
|
||||
github.com/rs/cors v1.9.0/go.mod h1:XyqrcTp5zjWr1wsJ8PIRZssZ8b/WMcMf71DJnit4EMU=
|
||||
github.com/russross/blackfriday/v2 v2.0.1/go.mod h1:+Rmxgy9KzJVeS9/2gXHxylqXiyQDYRxCVz55jmeOWTM=
|
||||
github.com/russross/blackfriday/v2 v2.1.0 h1:JIOH55/0cWyOuilr9/qlrm0BSXldqnqwMsf35Ld67mk=
|
||||
github.com/russross/blackfriday/v2 v2.1.0/go.mod h1:+Rmxgy9KzJVeS9/2gXHxylqXiyQDYRxCVz55jmeOWTM=
|
||||
github.com/seccomp/libseccomp-golang v0.9.2-0.20220502022130-f33da4d89646/go.mod h1:JA8cRccbGaA1s33RQf7Y1+q9gHmZX1yB/z9WDN1C6fg=
|
||||
github.com/shirou/gopsutil v3.21.11+incompatible h1:+1+c1VGhc88SSonWP6foOcLhvnKlUeu/erjjvaPEYiI=
|
||||
github.com/shirou/gopsutil v3.21.11+incompatible/go.mod h1:5b4v6he4MtMOwMlS0TUMTu2PcXUg8+E1lC7eC3UO/RA=
|
||||
github.com/shurcooL/sanitized_anchor_name v1.0.0/go.mod h1:1NzhyTcUVG4SuEtjjoZeVRXNmyL/1OwPU0+IJeTBvfc=
|
||||
github.com/sirupsen/logrus v1.4.0/go.mod h1:LxeOpSwHxABJmUn/MG1IvRgCAasNZTLOkJPxbbu5VWo=
|
||||
github.com/sirupsen/logrus v1.4.1/go.mod h1:ni0Sbl8bgC9z8RoU9G6nDWqqs/fq4eDPysMBDgk/93Q=
|
||||
@@ -574,6 +573,10 @@ github.com/syndtr/gocapability v0.0.0-20200815063812-42c35b437635/go.mod h1:hkRG
|
||||
github.com/tebeka/strftime v0.1.3/go.mod h1:7wJm3dZlpr4l/oVK0t1HYIc4rMzQ2XJlOMIUJUJH6XQ=
|
||||
github.com/tidwall/pretty v1.0.0 h1:HsD+QiTn7sK6flMKIvNmpqz1qrpP3Ps6jOKIKMooyg4=
|
||||
github.com/tidwall/pretty v1.0.0/go.mod h1:XNkn88O1ChpSDQmQeStsy+sBenx6DDtFZJxhVysOjyk=
|
||||
github.com/tklauser/go-sysconf v0.3.11 h1:89WgdJhk5SNwJfu+GKyYveZ4IaJ7xAkecBo+KdJV0CM=
|
||||
github.com/tklauser/go-sysconf v0.3.11/go.mod h1:GqXfhXY3kiPa0nAXPDIQIWzJbMCB7AmcWpGR8lSZfqI=
|
||||
github.com/tklauser/numcpus v0.6.0 h1:kebhY2Qt+3U6RNK7UqpYNA+tJ23IBEGKkB7JQBfDYms=
|
||||
github.com/tklauser/numcpus v0.6.0/go.mod h1:FEZLMke0lhOUG6w2JadTzp0a+Nl8PF/GFkQ5UVIcaL4=
|
||||
github.com/twitchyliquid64/golang-asm v0.15.1 h1:SU5vSMR7hnwNxj24w34ZyCi/FmDZTkS4MhqMhdFk5YI=
|
||||
github.com/twitchyliquid64/golang-asm v0.15.1/go.mod h1:a1lVb/DtPvCB8fslRZhAngC2+aY1QWCk3Cedj/Gdt08=
|
||||
github.com/ugorji/go v1.1.7/go.mod h1:kZn38zHttfInRq0xu/PH0az30d+z6vm202qpg1oXVMw=
|
||||
@@ -581,7 +584,6 @@ github.com/ugorji/go/codec v1.1.7/go.mod h1:Ax+UKWsSmolVDwsd+7N3ZtXu+yMGCf907BLY
|
||||
github.com/ugorji/go/codec v1.2.11 h1:BMaWp1Bb6fHwEtbplGBGJ498wD+LKlNSl25MjdZY4dU=
|
||||
github.com/ugorji/go/codec v1.2.11/go.mod h1:UNopzCgEMSXjBc6AOMqYvWC1ktqTAfzJZUZgYf6w6lg=
|
||||
github.com/unrolled/secure v1.13.0 h1:sdr3Phw2+f8Px8HE5sd1EHdj1aV3yUwed/uZXChLFsk=
|
||||
github.com/unrolled/secure v1.13.0/go.mod h1:BmF5hyM6tXczk3MpQkFf1hpKSRqCyhqcbiQtiAF7+40=
|
||||
github.com/urfave/cli v1.22.1/go.mod h1:Gos4lmkARVdJ6EkW0WaNv/tZAAMe9V7XWyB60NtXRu0=
|
||||
github.com/urfave/cli v1.22.5/go.mod h1:Gos4lmkARVdJ6EkW0WaNv/tZAAMe9V7XWyB60NtXRu0=
|
||||
github.com/urfave/cli/v2 v2.25.6 h1:yuSkgDSZfH3L1CjF2/5fNNg2KbM47pY2EvjBq4ESQnU=
|
||||
@@ -617,6 +619,8 @@ github.com/yuin/goldmark v1.1.27/go.mod h1:3hX8gzYuyVAZsxl0MRgGTJEmQBFcNTphYh9de
|
||||
github.com/yuin/goldmark v1.1.32/go.mod h1:3hX8gzYuyVAZsxl0MRgGTJEmQBFcNTphYh9decYSb74=
|
||||
github.com/yuin/goldmark v1.2.1/go.mod h1:3hX8gzYuyVAZsxl0MRgGTJEmQBFcNTphYh9decYSb74=
|
||||
github.com/yuin/goldmark v1.4.13/go.mod h1:6yULJ656Px+3vBD8DxQVa3kxgyrAnzto9xy5taEt/CY=
|
||||
github.com/yusufpapurcu/wmi v1.2.3 h1:E1ctvB7uKFMOJw3fdOW32DwGE9I7t++CRUEMKvFoFiw=
|
||||
github.com/yusufpapurcu/wmi v1.2.3/go.mod h1:SBZ9tNy3G9/m5Oi98Zks0QjeHVDvuK0qfxQmPyzfmi0=
|
||||
go.mongodb.org/mongo-driver v1.4.6/go.mod h1:WcMNYLx/IlOxLe6JRJiv2uXuCz6zBLndR4SoGjYphSc=
|
||||
go.mongodb.org/mongo-driver v1.7.5 h1:ny3p0reEpgsR2cfA5cjgwFZg3Cv/ofFh/8jbhGtz9VI=
|
||||
go.mongodb.org/mongo-driver v1.7.5/go.mod h1:VXEWRZ6URJIkUq2SCAyapmhH0ZLRBP+FT4xhp5Zvxng=
|
||||
@@ -791,6 +795,7 @@ golang.org/x/sys v0.0.0-20190606203320-7fc4e5ec1444/go.mod h1:h1NjWce9XRLGQEsW7w
|
||||
golang.org/x/sys v0.0.0-20190624142023-c5567b49c5d0/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||
golang.org/x/sys v0.0.0-20190726091711-fc99dfbffb4e/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||
golang.org/x/sys v0.0.0-20190904154756-749cb33beabd/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||
golang.org/x/sys v0.0.0-20190916202348-b4ddaad3f8a3/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||
golang.org/x/sys v0.0.0-20191001151750-bb3f8db39f24/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||
golang.org/x/sys v0.0.0-20191005200804-aed5e4c7ecf9/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||
golang.org/x/sys v0.0.0-20191010194322-b09406accb47/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||
@@ -839,6 +844,7 @@ golang.org/x/sys v0.0.0-20220722155257-8c9f86f7a55f/go.mod h1:oPkhp1MJrh7nUepCBc
|
||||
golang.org/x/sys v0.0.0-20220811171246-fbc7d0a398ab/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
|
||||
golang.org/x/sys v0.0.0-20220829200755-d48e67d00261/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
|
||||
golang.org/x/sys v0.0.0-20220908164124-27713097b956/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
|
||||
golang.org/x/sys v0.2.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
|
||||
golang.org/x/sys v0.5.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
|
||||
golang.org/x/sys v0.6.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
|
||||
golang.org/x/sys v0.8.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
|
||||
|
||||
@@ -2,21 +2,23 @@
|
||||
package helpers
|
||||
|
||||
import (
|
||||
"bufio"
|
||||
"bytes"
|
||||
"crypto/md5"
|
||||
"crypto/rand"
|
||||
"fmt"
|
||||
"io"
|
||||
"os"
|
||||
"os/exec"
|
||||
"reflect"
|
||||
"regexp"
|
||||
"sort"
|
||||
"strconv"
|
||||
"strings"
|
||||
"time"
|
||||
"unicode/utf8"
|
||||
|
||||
"github.com/shirou/gopsutil/cpu"
|
||||
"github.com/shirou/gopsutil/disk"
|
||||
"github.com/shirou/gopsutil/host"
|
||||
"github.com/shirou/gopsutil/load"
|
||||
"github.com/shirou/gopsutil/mem"
|
||||
"github.com/shirou/gopsutil/net"
|
||||
"github.com/shirou/gopsutil/process"
|
||||
)
|
||||
|
||||
// Empty 类似于 PHP 的 empty() 函数
|
||||
@@ -104,182 +106,43 @@ func Cut(begin, end, str string) string {
|
||||
return string([]rune(str)[b : b+e])
|
||||
}
|
||||
|
||||
// GetNetInfo 获取网络统计信息
|
||||
func GetNetInfo() (uint64, uint64) {
|
||||
file, err := os.Open("/proc/net/dev")
|
||||
if err != nil {
|
||||
panic(err)
|
||||
}
|
||||
defer file.Close()
|
||||
|
||||
scanner := bufio.NewScanner(file)
|
||||
allRs := make(map[string][]string)
|
||||
lineNumber := 0
|
||||
|
||||
for scanner.Scan() {
|
||||
lineNumber++
|
||||
if lineNumber < 3 {
|
||||
continue
|
||||
}
|
||||
|
||||
line := strings.TrimSpace(scanner.Text())
|
||||
line = strings.Replace(line, ":", " ", -1)
|
||||
re := regexp.MustCompile("[ ]+")
|
||||
line = re.ReplaceAllString(line, " ")
|
||||
arr := strings.Split(line, " ")
|
||||
|
||||
if len(arr) > 0 && arr[0] != "" {
|
||||
allRs[arr[0]+strconv.Itoa(lineNumber)] = []string{arr[0], arr[1], arr[9]}
|
||||
}
|
||||
}
|
||||
|
||||
var keys []string
|
||||
for key := range allRs {
|
||||
keys = append(keys, key)
|
||||
}
|
||||
sort.Strings(keys)
|
||||
|
||||
tx := uint64(0)
|
||||
rx := uint64(0)
|
||||
|
||||
for _, key := range keys {
|
||||
if strings.Contains(key, "lo") {
|
||||
continue
|
||||
}
|
||||
val := allRs[key]
|
||||
txValue, err := strconv.ParseUint(val[2], 10, 64)
|
||||
if err == nil {
|
||||
tx += txValue
|
||||
}
|
||||
rxValue, err := strconv.ParseUint(val[1], 10, 64)
|
||||
if err == nil {
|
||||
rx += rxValue
|
||||
}
|
||||
}
|
||||
|
||||
return tx, rx
|
||||
}
|
||||
|
||||
// MonitoringInfo 监控信息
|
||||
type MonitoringInfo struct {
|
||||
CpuUse float64 `json:"cpu_use"`
|
||||
Uptime float64 `json:"uptime"`
|
||||
UptimePercent float64 `json:"uptime_percent"`
|
||||
MemTotal float64 `json:"mem_total"`
|
||||
MemUse float64 `json:"mem_use"`
|
||||
MemUsePercent float64 `json:"mem_use_percent"`
|
||||
SwapTotal float64 `json:"swap_total"`
|
||||
SwapUse float64 `json:"swap_use"`
|
||||
SwapUsePercent float64 `json:"swap_use_percent"`
|
||||
NetTx uint64 `json:"net_tx"`
|
||||
NetRx uint64 `json:"net_rx"`
|
||||
Cpus []cpu.InfoStat `json:"cpus"`
|
||||
Percent []float64 `json:"percent"`
|
||||
Load *load.AvgStat `json:"load"`
|
||||
Host *host.InfoStat `json:"host"`
|
||||
Mem *mem.VirtualMemoryStat `json:"mem"`
|
||||
Swap *mem.SwapMemoryStat `json:"swap"`
|
||||
Net []net.IOCountersStat `json:"net"`
|
||||
Disk map[string]disk.IOCountersStat `json:"disk"`
|
||||
Process []*process.Process `json:"process"`
|
||||
}
|
||||
|
||||
// GetMonitoringInfo 获取监控数据
|
||||
func GetMonitoringInfo() (MonitoringInfo, error) {
|
||||
func GetMonitoringInfo() MonitoringInfo {
|
||||
var res MonitoringInfo
|
||||
res.Cpus, _ = cpu.Info()
|
||||
res.Percent, _ = cpu.Percent(time.Second, false)
|
||||
res.Load, _ = load.Avg()
|
||||
res.Host, _ = host.Info()
|
||||
res.Mem, _ = mem.VirtualMemory()
|
||||
res.Swap, _ = mem.SwapMemory()
|
||||
res.Net, _ = net.IOCounters(true)
|
||||
res.Disk, _ = disk.IOCounters()
|
||||
res.Process, _ = process.Processes()
|
||||
|
||||
// 网络流量
|
||||
netTx1, netRx1 := GetNetInfo()
|
||||
time.Sleep(time.Second)
|
||||
netTx2, netRx2 := GetNetInfo()
|
||||
res.NetTx = netTx2 - netTx1
|
||||
res.NetRx = netRx2 - netRx1
|
||||
|
||||
// CPU 信息
|
||||
cpuInfoRaw, err := os.ReadFile("/proc/cpuinfo")
|
||||
if err != nil {
|
||||
return MonitoringInfo{}, err
|
||||
}
|
||||
physicalArr := make(map[string]struct{})
|
||||
var siblingsSum float64
|
||||
var re = regexp.MustCompile(`\d+\.\d+`)
|
||||
uptimeOutput, err := exec.Command("uptime").Output()
|
||||
if err != nil {
|
||||
return MonitoringInfo{}, err
|
||||
}
|
||||
uptimeValues := re.FindAllString(string(uptimeOutput), -1)
|
||||
uptime1, _ := strconv.ParseFloat(uptimeValues[0], 64)
|
||||
res.Uptime = uptime1
|
||||
processors := bytes.Split(cpuInfoRaw, []byte("\nprocessor"))
|
||||
rePhysical := regexp.MustCompile(`physical id\s*:\s(.*)`)
|
||||
reSiblings := regexp.MustCompile(`siblings\s*:\s(.*)`)
|
||||
for _, v := range processors {
|
||||
physical := rePhysical.FindSubmatch(v)
|
||||
siblings := reSiblings.FindSubmatch(v)
|
||||
if len(physical) > 1 {
|
||||
pid := string(physical[1])
|
||||
if _, found := physicalArr[pid]; !found {
|
||||
if len(siblings) > 1 {
|
||||
siblingsValue, _ := strconv.ParseFloat(string(siblings[1]), 64)
|
||||
siblingsSum += siblingsValue
|
||||
}
|
||||
physicalArr[pid] = struct{}{}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// CPU 使用率
|
||||
cpuUse := 0.1
|
||||
psOutput, err := exec.Command("ps", "aux").Output()
|
||||
if err != nil {
|
||||
return MonitoringInfo{}, err
|
||||
}
|
||||
cpuRaw := strings.Split(string(psOutput), "\n")
|
||||
pid := os.Getpid()
|
||||
for _, v := range cpuRaw {
|
||||
v = strings.TrimSpace(v)
|
||||
v = regexp.MustCompile(`\s+`).ReplaceAllString(v, " ")
|
||||
values := strings.Split(v, " ")
|
||||
if len(values) > 2 {
|
||||
p, _ := strconv.Atoi(values[1])
|
||||
if p == pid {
|
||||
continue
|
||||
}
|
||||
cpu, _ := strconv.ParseFloat(values[2], 64)
|
||||
cpuUse += cpu
|
||||
}
|
||||
}
|
||||
cpuUse = cpuUse / siblingsSum
|
||||
if cpuUse > 100 {
|
||||
cpuUse = 100
|
||||
}
|
||||
res.CpuUse = cpuUse
|
||||
|
||||
// 内存使用率
|
||||
freeOutput, err := exec.Command("free", "-m").Output()
|
||||
if err != nil {
|
||||
return MonitoringInfo{}, err
|
||||
}
|
||||
memRaw := strings.Split(string(freeOutput), "\n")
|
||||
var memList, swapList string
|
||||
for _, v := range memRaw {
|
||||
if strings.Contains(v, "Mem") {
|
||||
memList = regexp.MustCompile(`\s+`).ReplaceAllString(v, " ")
|
||||
} else if strings.Contains(v, "Swap") {
|
||||
swapList = regexp.MustCompile(`\s+`).ReplaceAllString(v, " ")
|
||||
}
|
||||
}
|
||||
memArr := strings.Split(memList, " ")
|
||||
swapArr := strings.Split(swapList, " ")
|
||||
memTotal, _ := strconv.ParseFloat(memArr[1], 64)
|
||||
swapTotal, _ := strconv.ParseFloat(swapArr[1], 64)
|
||||
memUse, _ := strconv.ParseFloat(memArr[2], 64)
|
||||
swapUse, _ := strconv.ParseFloat(swapArr[2], 64)
|
||||
memUseP := (memUse / memTotal) * 100
|
||||
swapUseP := (swapUse / swapTotal) * 100
|
||||
uptime1P := uptime1 * 10
|
||||
if uptime1P > 100 {
|
||||
uptime1P = 100
|
||||
}
|
||||
|
||||
res.MemTotal = memTotal
|
||||
res.MemUse = memUse
|
||||
res.MemUsePercent = memUseP
|
||||
res.SwapTotal = swapTotal
|
||||
res.SwapUse = swapUse
|
||||
res.SwapUsePercent = swapUseP
|
||||
res.UptimePercent = uptime1P
|
||||
|
||||
return res, nil
|
||||
return res
|
||||
}
|
||||
|
||||
// IsDebian 判断是否是 Debian 系统
|
||||
func IsDebian() bool {
|
||||
_, err := os.Stat("/etc/debian_version")
|
||||
return err == nil
|
||||
}
|
||||
|
||||
// IsRHEL 判断是否是 RHEL 系统
|
||||
func IsRHEL() bool {
|
||||
_, err := os.Stat("/etc/redhat-release")
|
||||
return err == nil
|
||||
}
|
||||
|
||||
@@ -30,3 +30,12 @@ func Camel(s string) string {
|
||||
func LowerCamel(s string) string {
|
||||
return strcase.ToLowerCamel(s)
|
||||
}
|
||||
|
||||
func ContainsString(arr []string, str string) bool {
|
||||
for _, s := range arr {
|
||||
if s == str {
|
||||
return true
|
||||
}
|
||||
}
|
||||
return false
|
||||
}
|
||||
|
||||
@@ -40,19 +40,19 @@
|
||||
<script src="https://cdnjs.cdn.haozi.net/ace/1.6.1/ace.js"></script>
|
||||
<script src="https://cdnjs.cdn.haozi.net/echarts/5.4.2/echarts.min.js"></script>
|
||||
<script>
|
||||
var panel_name = '耗子Linux面板'
|
||||
layui.config({
|
||||
base: 'res/', // 静态资源所在路径
|
||||
version: new Date().getTime()
|
||||
}).use('index', function () {
|
||||
}).use(['index', 'setter'], function () {
|
||||
var admin = layui.admin
|
||||
var setter = layui.setter
|
||||
admin.req({
|
||||
url: '/api/panel/info/name',
|
||||
type: 'get',
|
||||
success: function (res) {
|
||||
if (res.code === 0) {
|
||||
panel_name = res.data.name
|
||||
document.title = panel_name
|
||||
setter.name = res.data.name
|
||||
document.title = setter.name
|
||||
}
|
||||
}
|
||||
})
|
||||
|
||||
@@ -5,30 +5,25 @@ Date: 2022-11-30
|
||||
-->
|
||||
<div class="layui-fluid">
|
||||
<div class="layui-row layui-col-space15">
|
||||
<div id="address1" class="layui-col-md12">
|
||||
<div class="layui-collapse">
|
||||
<div style="background: #fff;" class="layui-colla-content layui-show">
|
||||
<div class="text" style="overflow: hidden;height: 22px;">
|
||||
<div class="layui-carousel" id="home_ad" lay-filter="home_ad">
|
||||
<div carousel-item="">
|
||||
<a style="background: #fff;" href="https://hzbk.net"
|
||||
title="耗子博客" target="_blank"><i class="layui-icon layui-icon-release"></i> 耗子博客</a>
|
||||
<a style="background: #fff;" href="https://weavatar.com"
|
||||
title="WeAvatar" target="_blank"><i class="layui-icon layui-icon-release"></i>
|
||||
WeAvatar - 互联网公共头像服务</a>
|
||||
<a style="background: #fff;" href="https://wepublish.cn"
|
||||
title="WePublish" target="_blank"><i class="layui-icon layui-icon-release"></i>
|
||||
WePublish - WordPress的本土化版本</a>
|
||||
</div>
|
||||
</div>
|
||||
<div id="ad1" class="layui-col-md12">
|
||||
<div style="background: #fff;" class="layui-colla-content layui-show">
|
||||
<div id="ad1-carousel" class="layui-carousel"
|
||||
style="overflow: hidden;background: #fff;">
|
||||
<div carousel-item>
|
||||
<a style="background: #fff;" href="https://hzbk.net"
|
||||
title="耗子博客" target="_blank"><i class="layui-icon layui-icon-release"></i> 耗子博客</a>
|
||||
<a style="background: #fff;" href="https://weavatar.com"
|
||||
title="WeAvatar" target="_blank"><i class="layui-icon layui-icon-release"></i>
|
||||
WeAvatar - 互联网公共头像服务</a>
|
||||
<a style="background: #fff;" href="https://wepublish.cn"
|
||||
title="WePublish" target="_blank"><i class="layui-icon layui-icon-release"></i>
|
||||
WePublish - WordPress的本土化版本</a>
|
||||
</div>
|
||||
|
||||
</div>
|
||||
</div>
|
||||
|
||||
</div>
|
||||
</div>
|
||||
<div id="monitor1" class="layui-col-md6">
|
||||
|
||||
<div class="layui-card">
|
||||
<div class="layui-card-header">资源使用</div>
|
||||
<div class="layui-card-body layadmin-takerates">
|
||||
@@ -44,7 +39,6 @@ Date: 2022-11-30
|
||||
</div>
|
||||
</div>
|
||||
<div id="monitor2" class="layui-col-md3">
|
||||
|
||||
<div class="layui-card">
|
||||
<div class="layui-card-header">系统负载</div>
|
||||
<div class="layui-card-body layadmin-takerates">
|
||||
@@ -84,18 +78,18 @@ Date: 2022-11-30
|
||||
<div class="layui-carousel layadmin-carousel layadmin-shortcut" lay-anim="">
|
||||
<div carousel-item="">
|
||||
<ul class="layui-row layui-col-space10 layui-this">
|
||||
<script type="text/html" template lay-url="/api/panel/info/getHomePlugins">
|
||||
@{{# layui.each(d.data, function(index, item){ }}
|
||||
<script type="text/html" template lay-url="/api/panel/info/homePlugins">
|
||||
{{# layui.each(d.data, function(index, item){ }}
|
||||
<li class="layui-col-xs4 layui-col-md2 layui-col-sm4">
|
||||
<a lay-href="/plugin/@{{ item.slug }}">
|
||||
<a lay-href="/plugin/{{ item.slug }}">
|
||||
<i class="layui-icon layui-icon-engine"></i>
|
||||
<cite>@{{ item.name }}</cite>
|
||||
<cite>{{ item.name }}</cite>
|
||||
</a>
|
||||
</li>
|
||||
@{{# }); }}
|
||||
@{{# if(d.data.length === 0){ }}
|
||||
{{# }); }}
|
||||
{{# if(d.data.length === 0){ }}
|
||||
这里好像啥也没有...
|
||||
@{{# } }}
|
||||
{{# } }}
|
||||
</script>
|
||||
|
||||
</ul>
|
||||
@@ -162,119 +156,134 @@ Date: 2022-11-30
|
||||
</div>
|
||||
|
||||
<script>
|
||||
var home_timer;
|
||||
var uptime_1 = '获取中', uptime_5 = '获取中', uptime_15 = '获取中';
|
||||
var home_timer
|
||||
var uptime_1 = '获取中', uptime_5 = '获取中', uptime_15 = '获取中'
|
||||
|
||||
function refresh_home_info() {
|
||||
function formatBytes (size) {
|
||||
size = Number(size)
|
||||
var units = ['B', 'KB', 'MB', 'GB', 'TB', 'PB', 'EB', 'ZB', 'YB']
|
||||
var i = 0
|
||||
|
||||
while (size >= 1024 && i < units.length) {
|
||||
size /= 1024
|
||||
i++
|
||||
}
|
||||
|
||||
return size.toFixed(2) + ' ' + units[i]
|
||||
}
|
||||
|
||||
function formatPercentage (num) {
|
||||
num = Number(num)
|
||||
return num.toFixed(2) + '%'
|
||||
}
|
||||
|
||||
function refresh_home_info () {
|
||||
layui.use(['index', 'jquery', 'admin'], function () {
|
||||
let $ = layui.jquery
|
||||
, admin = layui.admin
|
||||
, element = layui.element;
|
||||
, element = layui.element
|
||||
|
||||
let device = layui.device();
|
||||
let cpu_info;
|
||||
let device = layui.device()
|
||||
let cpu_info
|
||||
admin.req({
|
||||
url: "/api/panel/info/getNowMonitor"
|
||||
url: '/api/panel/info/nowMonitor'
|
||||
, method: 'get'
|
||||
, success: function (result) {
|
||||
if (result.code !== 0) {
|
||||
console.log('耗子Linux面板:系统资源信息获取失败,接口返回' + result);
|
||||
layer.msg('系统资源获取失败,请刷新重试!')
|
||||
return false;
|
||||
return false
|
||||
}
|
||||
element.progress('home_cpu', result.data.cpu_use);
|
||||
element.progress('home_mem', result.data.mem_use_p);
|
||||
element.progress('uptime_1', result.data.uptime_1_p);
|
||||
element.progress('uptime_5', result.data.uptime_5_p);
|
||||
uptime_1 = result.data.uptime_1;
|
||||
uptime_5 = result.data.uptime_5;
|
||||
uptime_15 = result.data.uptime_15;
|
||||
// 判断一下移动设备不显示CPU型号,放不下。。。
|
||||
if (device.mobile) {
|
||||
cpu_info = result.data.cpu_info.physical + 'CPU ' + result.data.cpu_info.cores + '核心 ' + result.data.cpu_info.siblings + '线程';
|
||||
} else {
|
||||
cpu_info = result.data.cpu_info.name + ' ' + result.data.cpu_info.physical + 'CPU ' + result.data.cpu_info.cores + '核心 ' + result.data.cpu_info.siblings + '线程';
|
||||
element.progress('home_cpu', formatPercentage(result.data.percent[0]))
|
||||
element.progress('home_mem', formatPercentage(result.data.mem.usedPercent))
|
||||
|
||||
// 计算核心数
|
||||
let cores = 0
|
||||
for (let i = 0; i < result.data.cpus.length; i++) {
|
||||
cores += result.data.cpus[i].cores
|
||||
}
|
||||
$('#home_net_total').html(result.data.tx_total + ' / ' + result.data.rx_total);
|
||||
$('#home_net_now').html(result.data.tx_now + '/s / ' + result.data.rx_now + '/s');
|
||||
$('#home_cpu').text(cpu_info);
|
||||
$('#home_mem').text('使用' + result.data.mem_use + 'MB / ' + '总计' + result.data.mem_total + 'MB');
|
||||
element.render('progress');
|
||||
|
||||
// 计算负载百分比
|
||||
uptime_1 = formatPercentage(result.data.load.load1 / cores * 100)
|
||||
uptime_5 = formatPercentage(result.data.load.load5 / cores * 100)
|
||||
uptime_15 = formatPercentage(result.data.load.load15 / cores * 100)
|
||||
element.progress('uptime_1', uptime_1)
|
||||
element.progress('uptime_5', uptime_5)
|
||||
|
||||
cpu_info = result.data.cpus[0].modelName + ' ' + cores + '线程'
|
||||
//$('#home_net_total').html(result.data.tx_total + ' / ' + result.data.rx_total)
|
||||
//$('#home_net_now').html(result.data.tx_now + '/s / ' + result.data.rx_now + '/s')
|
||||
$('#home_cpu').text(cpu_info)
|
||||
$('#home_mem').text('使用 ' + formatBytes(result.data.mem.used) + ' / ' + '总计 ' + formatBytes(result.data.mem.total))
|
||||
element.render('progress')
|
||||
}
|
||||
, error: function (xhr, status, error) {
|
||||
console.log('耗子Linux面板:ajax请求出错,错误' + error);
|
||||
}
|
||||
});
|
||||
});
|
||||
})
|
||||
})
|
||||
}
|
||||
|
||||
// 先执行一次
|
||||
refresh_home_info();
|
||||
refresh_home_info()
|
||||
// 然后设置个定时器3s一次刷新
|
||||
clearInterval(home_timer);
|
||||
home_timer = setInterval(refresh_home_info, 3000);
|
||||
clearInterval(home_timer)
|
||||
home_timer = setInterval(refresh_home_info, 3000)
|
||||
// 获取系统信息,这部分信息无需更新。
|
||||
layui.use(['index', 'jquery', 'admin', 'carousel'], function () {
|
||||
let $ = layui.jquery
|
||||
, admin = layui.admin
|
||||
, element = layui.element
|
||||
, carousel = layui.carousel;
|
||||
, carousel = layui.carousel
|
||||
carousel.render({
|
||||
elem: '#home_ad'
|
||||
elem: '#ad1-carousel'
|
||||
, width: '100%'
|
||||
, height: '200px'
|
||||
, height: '22px'
|
||||
, anim: 'fade'
|
||||
, arrow: 'none'
|
||||
, indicator: 'none'
|
||||
});
|
||||
})
|
||||
admin.req({
|
||||
url: "/api/panel/info/getSystemInfo"
|
||||
url: '/api/panel/info/systemInfo'
|
||||
, method: 'get'
|
||||
, success: function (result) {
|
||||
if (result.code !== 0) {
|
||||
console.log('耗子Linux面板:系统信息获取失败,接口返回' + result);
|
||||
console.log('耗子Linux面板:系统信息获取失败,接口返回' + result)
|
||||
layer.msg('系统信息获取失败,请刷新重试!')
|
||||
return false;
|
||||
return false
|
||||
}
|
||||
$('#home_os_name').text(result.data.os_name);
|
||||
$('#home_panel_version').text(result.data.panel_version);
|
||||
$('#home_uptime').text('已不间断运行 ' + result.data.uptime + ' 天');
|
||||
$('#home_os_name').text(result.data.os_name)
|
||||
$('#home_panel_version').text(result.data.panel_version)
|
||||
$('#home_uptime').text('已不间断运行 ' + result.data.uptime + ' 天')
|
||||
}
|
||||
, error: function (xhr, status, error) {
|
||||
console.log('耗子Linux面板:ajax请求出错,错误' + error);
|
||||
}
|
||||
});
|
||||
});
|
||||
})
|
||||
})
|
||||
|
||||
// 监听鼠标悬停到uptime上的事件
|
||||
// 用于显示1分钟、5分钟、15分钟的负载
|
||||
layui.use(['jquery', 'layer'], function () {
|
||||
let $ = layui.jquery
|
||||
, layer = layui.layer
|
||||
, admin = layui.admin;
|
||||
, admin = layui.admin
|
||||
// 监听鼠标悬停到uptime上的事件
|
||||
// 用于显示1分钟、5分钟、15分钟的负载
|
||||
$('#monitor2').hover(function () {
|
||||
layer.tips('1分钟负载:' + uptime_1 + '<br>5分钟负载:' + uptime_5 + '<br>15分钟负载:' + uptime_15, '#monitor2', {
|
||||
tips: 1,
|
||||
time: 0
|
||||
});
|
||||
})
|
||||
}, function () {
|
||||
layer.closeAll('tips');
|
||||
});
|
||||
layer.closeAll('tips')
|
||||
})
|
||||
// 监听更新按钮点击事件
|
||||
$('#update_panel').click(function () {
|
||||
index = layer.msg('正在获取版本信息...', {
|
||||
icon: 16
|
||||
, time: 0
|
||||
});
|
||||
})
|
||||
admin.req(
|
||||
{
|
||||
url: '/api/panel/info/checkUpdate'
|
||||
, method: 'get'
|
||||
, success: function (result) {
|
||||
layer.close(index);
|
||||
layer.close(index)
|
||||
if (result.code !== 0) {
|
||||
layer.msg('获取版本信息失败,请刷新重试!')
|
||||
return false;
|
||||
return false
|
||||
}
|
||||
if (result.data.version) {
|
||||
admin.popup({
|
||||
@@ -291,17 +300,13 @@ Date: 2022-11-30
|
||||
skin: 'layui-anim layui-anim-upbit'
|
||||
,
|
||||
content: '最新版本:' + result.data.version + '<br><br>更新日志:' + result.data.describe + '<br><br>请在SSH执行<span class="layui-badge-rim">panel update</span>以更新面板!'
|
||||
});
|
||||
})
|
||||
} else {
|
||||
layer.msg('当前已是最新版本!')
|
||||
}
|
||||
}
|
||||
, error: function (xhr, status, error) {
|
||||
layer.close(index);
|
||||
layer.msg('获取版本信息失败,请刷新重试!')
|
||||
}
|
||||
}
|
||||
);
|
||||
});
|
||||
});
|
||||
)
|
||||
})
|
||||
})
|
||||
</script>
|
||||
|
||||
@@ -4,7 +4,7 @@
|
||||
<ul class="layui-nav layui-layout-left">
|
||||
<li class="layui-nav-item layadmin-flexible" lay-unselect>
|
||||
<a href="javascript:;" layadmin-event="flexible" title="侧边伸缩">
|
||||
<i class="layui-icon layui-icon-shrink-right" id="LAY_app_flexible"></i>
|
||||
<i class="layui-icon layui-icon-shrink-right" id="Panel_app_flexible"></i>
|
||||
</a>
|
||||
</li>
|
||||
<li class="layui-nav-item" lay-unselect>
|
||||
@@ -17,8 +17,8 @@
|
||||
|
||||
<li class="layui-nav-item" lay-unselect>
|
||||
<a lay-href="task" layadmin-event="message">
|
||||
<script type="text/html" template lay-url="/api/panel/task/getStatus">
|
||||
{{# if(d.data){ }}
|
||||
<script type="text/html" template lay-url="/api/panel/task/status">
|
||||
{{# if(d.data.task){ }}
|
||||
<i class="layui-icon layui-icon-loading-1 layui-anim layui-anim-rotate layui-anim-loop"></i>
|
||||
{{# } else { }}
|
||||
<i class="layui-icon layui-icon-component"></i>
|
||||
@@ -43,7 +43,7 @@
|
||||
</a>
|
||||
</li>
|
||||
<li style="margin-right: 15px;" class="layui-nav-item" lay-unselect>
|
||||
<script type="text/html" template lay-url="/api/panel/user/getInfo"
|
||||
<script type="text/html" template lay-url="/api/panel/user/info"
|
||||
lay-done="layui.element.render('nav', 'layadmin-layout-right');">
|
||||
<a href="javascript:;">
|
||||
<cite>{{= d.data.username }}</cite>
|
||||
@@ -61,11 +61,11 @@
|
||||
<!-- 侧边菜单 -->
|
||||
<div class="layui-side layui-side-menu">
|
||||
<div class="layui-side-scroll">
|
||||
<script type="text/html" template lay-url="/api/panel/info/getMenu?v={{ layui.cache.version }}"
|
||||
<script type="text/html" template lay-url="/api/panel/info/menu?v={{ layui.cache.version }}"
|
||||
lay-done="layui.element.render('nav', 'layadmin-system-side-menu');" id="TPL_layout">
|
||||
|
||||
<div class="layui-logo" lay-href="">
|
||||
{{ config('panel.name') }}
|
||||
<span>{{ layui.setter.name }}</span>
|
||||
</div>
|
||||
|
||||
<ul class="layui-nav layui-nav-tree" lay-shrink="all" id="LAY-system-side-menu" lay-filter="layadmin-system-side-menu">
|
||||
@@ -141,7 +141,7 @@
|
||||
<!-- 页面标签 -->
|
||||
<script type="text/html" template lay-done="layui.element.render('nav', 'layadmin-pagetabs-nav')">
|
||||
{{# if(layui.setter.pageTabs){ }}
|
||||
<div class="layadmin-pagetabs" id="LAY_app_tabs">
|
||||
<div class="layadmin-pagetabs" id="Panel_app_tabs">
|
||||
<div class="layui-icon layadmin-tabs-control layui-icon-prev" layadmin-event="leftPage"></div>
|
||||
<div class="layui-icon layadmin-tabs-control layui-icon-next" layadmin-event="rightPage"></div>
|
||||
<div class="layui-icon layadmin-tabs-control layui-icon-down">
|
||||
@@ -157,7 +157,7 @@
|
||||
</ul>
|
||||
</div>
|
||||
<div class="layui-tab" lay-unauto lay-allowClose="true" lay-filter="layadmin-layout-tabs">
|
||||
<ul class="layui-tab-title" id="LAY_app_tabsheader">
|
||||
<ul class="layui-tab-title" id="Panel_app_tabsheader">
|
||||
<li lay-id="/"><i class="layui-icon layui-icon-home"></i></li>
|
||||
</ul>
|
||||
</div>
|
||||
@@ -167,7 +167,7 @@
|
||||
|
||||
|
||||
<!-- 主体内容 -->
|
||||
<div class="layui-body" id="LAY_app_body">
|
||||
<div class="layui-body" id="Panel_app_body">
|
||||
<div class="layadmin-tabsbody-item layui-show"></div>
|
||||
</div>
|
||||
|
||||
|
||||
@@ -50,7 +50,7 @@
|
||||
, search = router.search;
|
||||
|
||||
// 设置面板名称
|
||||
$('#panel-login-name').text(panel_name);
|
||||
$('#panel-login-name').text(setter.name);
|
||||
|
||||
// 判断并清除定时器
|
||||
if (typeof home_timer !== 'undefined') {
|
||||
|
||||
@@ -14,12 +14,20 @@ func Web() {
|
||||
r.Prefix("info").Group(func(r route.Route) {
|
||||
infoController := controllers.NewInfoController()
|
||||
r.Get("name", infoController.Name)
|
||||
r.Middleware(middleware.Jwt()).Get("menu", infoController.Menu)
|
||||
r.Middleware(middleware.Jwt()).Get("homePlugins", infoController.HomePlugins)
|
||||
r.Middleware(middleware.Jwt()).Get("nowMonitor", infoController.NowMonitor)
|
||||
r.Middleware(middleware.Jwt()).Get("systemInfo", infoController.SystemInfo)
|
||||
})
|
||||
r.Prefix("user").Group(func(r route.Route) {
|
||||
userController := controllers.NewUserController()
|
||||
r.Post("login", userController.Login)
|
||||
r.Middleware(middleware.Jwt()).Get("info", userController.Info)
|
||||
})
|
||||
r.Prefix("task").Middleware(middleware.Jwt()).Group(func(r route.Route) {
|
||||
taskController := controllers.NewTaskController()
|
||||
r.Get("status", taskController.Status)
|
||||
})
|
||||
})
|
||||
|
||||
facades.Route().Fallback(func(ctx http.Context) {
|
||||
|
||||
Reference in New Issue
Block a user