From a4f1c8c6fa850d0e23fd7b8f336c01a6b260f93a Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E8=80=97=E5=AD=90?= Date: Wed, 25 Oct 2023 20:40:37 +0800 Subject: [PATCH] =?UTF-8?q?feat:=20=E9=A6=96=E9=A1=B5=E4=BC=98=E5=8C=96?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- app/http/controllers/info_controller.go | 116 ++++++++++++++++++++---- app/services/website.go | 51 ++++++++++- routes/api.go | 12 ++- 3 files changed, 155 insertions(+), 24 deletions(-) diff --git a/app/http/controllers/info_controller.go b/app/http/controllers/info_controller.go index b4839d20..41289c11 100644 --- a/app/http/controllers/info_controller.go +++ b/app/http/controllers/info_controller.go @@ -1,6 +1,7 @@ package controllers import ( + "database/sql" "fmt" "regexp" "strings" @@ -21,12 +22,14 @@ type MenuItem struct { } type InfoController struct { - plugin services.Plugin + plugin services.Plugin + setting services.Setting } func NewInfoController() *InfoController { return &InfoController{ - plugin: services.NewPluginImpl(), + plugin: services.NewPluginImpl(), + setting: services.NewSettingImpl(), } } @@ -44,21 +47,6 @@ func (c *InfoController) Name(ctx http.Context) http.Response { }) } -// Menu 获取面板菜单 -func (c *InfoController) Menu(ctx http.Context) http.Response { - return 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: "ssh", Title: "SSH", Icon: "layui-icon-layer", Jump: "ssh"}, - {Name: "plugin", Title: "插件中心", Icon: "layui-icon-app", Jump: "plugin"}, - {Name: "setting", Title: "面板设置", Icon: "layui-icon-set", Jump: "setting"}, - }) -} - // HomePlugins 获取首页插件 func (c *InfoController) HomePlugins(ctx http.Context) http.Response { var plugins []models.Plugin @@ -100,6 +88,100 @@ func (c *InfoController) SystemInfo(ctx http.Context) http.Response { }) } +// CountInfo 获取面板统计信息 +func (c *InfoController) CountInfo(ctx http.Context) http.Response { + var websiteCount int64 + err := facades.Orm().Query().Model(models.Website{}).Count(&websiteCount) + if err != nil { + websiteCount = -1 + } + + var mysql models.Plugin + mysqlInstalled := true + err = facades.Orm().Query().Where("slug like ?", "mysql%").FirstOrFail(&mysql) + if err != nil { + mysqlInstalled = false + } + var postgresql models.Plugin + postgresqlInstalled := true + err = facades.Orm().Query().Where("slug like ?", "postgresql%").FirstOrFail(&postgresql) + if err != nil { + postgresqlInstalled = false + } + var databaseCount int64 + if mysqlInstalled { + status := tools.Exec("systemctl status mysqld | grep Active | grep -v grep | awk '{print $2}'") + if status == "active" { + rootPassword := c.setting.Get(models.SettingKeyMysqlRootPassword) + type database struct { + Name string `json:"name"` + } + + db, err := sql.Open("mysql", "root:"+rootPassword+"@unix(/tmp/mysql.sock)/") + if err != nil { + facades.Log().With(map[string]any{ + "error": err.Error(), + }).Error("[面板][InfoController] 获取数据库列表失败") + databaseCount = -1 + } else { + defer db.Close() + rows, err := db.Query("SHOW DATABASES") + if err != nil { + facades.Log().With(map[string]any{ + "error": err.Error(), + }).Error("[面板][InfoController] 获取数据库列表失败") + databaseCount = -1 + } + defer rows.Close() + + var databases []database + for rows.Next() { + var d database + err := rows.Scan(&d.Name) + if err != nil { + continue + } + + databases = append(databases, d) + } + databaseCount = int64(len(databases)) + } + } + } + if postgresqlInstalled { + status := tools.Exec("systemctl status postgresql | grep Active | grep -v grep | awk '{print $2}'") + if status == "active" { + raw := tools.Exec(`echo "\l" | su - postgres -c "psql"`) + databases := strings.Split(raw, "\n") + databases = databases[3 : len(databases)-1] + databaseCount = int64(len(databases)) + } + } + + var ftpCount int64 + var ftpPlugin = c.plugin.GetInstalledBySlug("pureftpd") + if ftpPlugin.ID != 0 { + listRaw := tools.Exec("pure-pw list") + if len(listRaw) != 0 { + listArr := strings.Split(listRaw, "\n") + ftpCount = int64(len(listArr)) + } + } + + var cronCount int64 + err = facades.Orm().Query().Model(models.Cron{}).Count(&cronCount) + if err != nil { + cronCount = -1 + } + + return Success(ctx, http.Json{ + "website": websiteCount, + "database": databaseCount, + "ftp": ftpCount, + "cron": cronCount, + }) +} + // InstalledDbAndPhp 获取已安装的数据库和 PHP 版本 func (c *InfoController) InstalledDbAndPhp(ctx http.Context) http.Response { var php []models.Plugin diff --git a/app/services/website.go b/app/services/website.go index 09f29790..df87eb65 100644 --- a/app/services/website.go +++ b/app/services/website.go @@ -128,15 +128,56 @@ func (r *WebsiteImpl) Add(website PanelWebsite) (models.Website, error) { index := ` - -耗子Linux面板 + + + 耗子Linux面板 + -

耗子Linux面板

-

这是耗子Linux面板的网站默认页面!

-

当您看到此页面,说明您的网站已创建成功。

+
+

耗子Linux面板

+

这是耗子Linux面板的网站默认页面!

+

当您看到此页面,说明您的网站已创建成功。

+
+ ` tools.Write(website.Path+"/index.html", index, 0644) diff --git a/routes/api.go b/routes/api.go index 0b4ab9c1..be02a547 100644 --- a/routes/api.go +++ b/routes/api.go @@ -15,10 +15,10 @@ func Api() { r.Prefix("info").Group(func(r route.Router) { 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.Middleware(middleware.Jwt()).Get("countInfo", infoController.CountInfo) r.Middleware(middleware.Jwt()).Get("installedDbAndPhp", infoController.InstalledDbAndPhp) r.Middleware(middleware.Jwt()).Get("checkUpdate", infoController.CheckUpdate) r.Middleware(middleware.Jwt()).Post("update", infoController.Update) @@ -109,6 +109,14 @@ func Api() { }) facades.Route().Fallback(func(ctx http.Context) http.Response { - return ctx.Response().String(404, "not found") + return ctx.Response().String(404, ` +404 Not Found + +

404 Not Found

+
openresty
+ + + +`) }) }