mirror of
https://github.com/acepanel/panel.git
synced 2026-02-04 17:17:13 +08:00
feat: 首页优化
This commit is contained in:
@@ -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
|
||||
|
||||
@@ -128,15 +128,56 @@ func (r *WebsiteImpl) Add(website PanelWebsite) (models.Website, error) {
|
||||
index := `<!DOCTYPE html>
|
||||
<html lang="zh-CN">
|
||||
<head>
|
||||
<meta charset="utf-8">
|
||||
<title>耗子Linux面板</title>
|
||||
<meta charset="UTF-8">
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1.0">
|
||||
<title>耗子Linux面板</title>
|
||||
<style>
|
||||
body {
|
||||
background-color: #f9f9f9;
|
||||
margin: 0;
|
||||
padding: 0;
|
||||
}
|
||||
.container {
|
||||
max-width: 800px;
|
||||
margin: 2em auto;
|
||||
background-color: #ffffff;
|
||||
padding: 20px;
|
||||
border-radius: 12px;
|
||||
box-shadow: 0 4px 8px rgba(0, 0, 0, 0.1);
|
||||
}
|
||||
h1 {
|
||||
font-size: 2.5em;
|
||||
margin-top: 0;
|
||||
margin-bottom: 20px;
|
||||
text-align: center;
|
||||
color: #333;
|
||||
border-bottom: 2px solid #ddd;
|
||||
padding-bottom: 0.5em;
|
||||
}
|
||||
p {
|
||||
color: #555;
|
||||
line-height: 1.8;
|
||||
}
|
||||
@media screen and (max-width: 768px) {
|
||||
.container {
|
||||
padding: 15px;
|
||||
margin: 2em 15px;
|
||||
}
|
||||
h1 {
|
||||
font-size: 1.8em;
|
||||
}
|
||||
}
|
||||
</style>
|
||||
</head>
|
||||
<body>
|
||||
<h1>耗子Linux面板</h1>
|
||||
<p>这是耗子Linux面板的网站默认页面!</p>
|
||||
<p>当您看到此页面,说明您的网站已创建成功。</p>
|
||||
<div class="container">
|
||||
<h1>耗子Linux面板</h1>
|
||||
<p>这是耗子Linux面板的网站默认页面!</p>
|
||||
<p>当您看到此页面,说明您的网站已创建成功。</p>
|
||||
</div>
|
||||
</body>
|
||||
</html>
|
||||
|
||||
`
|
||||
tools.Write(website.Path+"/index.html", index, 0644)
|
||||
|
||||
|
||||
@@ -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, `<html>
|
||||
<head><title>404 Not Found</title></head>
|
||||
<body>
|
||||
<center><h1>404 Not Found</h1></center>
|
||||
<hr><center>openresty</center>
|
||||
</body>
|
||||
</html>
|
||||
|
||||
`)
|
||||
})
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user