2
0
mirror of https://github.com/acepanel/panel.git synced 2026-02-04 17:17:13 +08:00

feat: 首页优化

This commit is contained in:
耗子
2023-10-25 20:40:37 +08:00
parent abf5962821
commit a4f1c8c6fa
3 changed files with 155 additions and 24 deletions

View File

@@ -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

View File

@@ -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)

View File

@@ -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>
`)
})
}