From ab599ef0f7584611dd38c25f687fe1365b244ac1 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E8=80=97=E5=AD=90?= Date: Sun, 16 Jul 2023 17:22:49 +0800 Subject: [PATCH] feat: php74 --- app/console/commands/monitoring.go | 5 +- app/console/commands/panel.go | 10 +- app/http/controllers/info_controller.go | 10 +- app/http/controllers/plugin_controller.go | 25 +- .../plugins/mysql80/mysql80_controller.go | 120 +++--- .../plugins/openresty/openresty_controller.go | 36 +- .../plugins/php74/php74_controller.go | 373 ++++++++++++++++++ app/models/monitor.go | 11 +- app/plugins/php74/php74.go | 11 + app/services/plugin.go | 10 + app/services/task.go | 31 ++ app/services/website.go | 28 +- packages/{helpers => helper}/helpers.go | 4 +- packages/{helpers => helper}/helpers_test.go | 2 +- packages/{helpers => helper}/os.go | 2 +- packages/{helpers => helper}/os_test.go | 2 +- packages/{helpers => helper}/string.go | 2 +- packages/{helpers => helper}/string_test.go | 2 +- packages/{helpers => helper}/system.go | 2 +- packages/{helpers => helper}/system_test.go | 2 +- public/panel/config.js | 4 +- public/panel/views/login.html | 3 +- routes/plugin.go | 19 + 23 files changed, 573 insertions(+), 141 deletions(-) create mode 100644 app/http/controllers/plugins/php74/php74_controller.go create mode 100644 app/plugins/php74/php74.go create mode 100644 app/services/task.go rename packages/{helpers => helper}/helpers.go (98%) rename packages/{helpers => helper}/helpers_test.go (94%) rename packages/{helpers => helper}/os.go (95%) rename packages/{helpers => helper}/os_test.go (96%) rename packages/{helpers => helper}/string.go (99%) rename packages/{helpers => helper}/string_test.go (99%) rename packages/{helpers => helper}/system.go (99%) rename packages/{helpers => helper}/system_test.go (99%) diff --git a/app/console/commands/monitoring.go b/app/console/commands/monitoring.go index adfb0334..50faa4e3 100644 --- a/app/console/commands/monitoring.go +++ b/app/console/commands/monitoring.go @@ -4,14 +4,13 @@ import ( "strconv" "github.com/gookit/color" - "github.com/goravel/framework/contracts/console" "github.com/goravel/framework/contracts/console/command" "github.com/goravel/framework/facades" "github.com/goravel/framework/support/carbon" "panel/app/models" - "panel/packages/helpers" + "panel/packages/helper" ) type Monitoring struct { @@ -44,7 +43,7 @@ func (receiver *Monitoring) Handle(ctx console.Context) error { return nil } - info := helpers.GetMonitoringInfo() + info := helper.GetMonitoringInfo() err := facades.Orm().Query().Create(&models.Monitor{ Info: info, diff --git a/app/console/commands/panel.go b/app/console/commands/panel.go index 7b59bded..1ec17b88 100644 --- a/app/console/commands/panel.go +++ b/app/console/commands/panel.go @@ -13,7 +13,7 @@ import ( "panel/app/models" "panel/app/services" - "panel/packages/helpers" + "panel/packages/helper" ) type Panel struct { @@ -58,7 +58,7 @@ func (receiver *Panel) Handle(ctx console.Context) error { return nil } - hash, err := facades.Hash().Make(helpers.RandomString(32)) + hash, err := facades.Hash().Make(helper.RandomString(32)) if err != nil { color.Redln("初始化失败") return nil @@ -74,7 +74,7 @@ func (receiver *Panel) Handle(ctx console.Context) error { color.Greenln("初始化成功") case "update": - err := helpers.UpdatePanel() + err := helper.UpdatePanel() if err != nil { color.Redln("更新失败: " + err.Error()) return nil @@ -90,14 +90,14 @@ func (receiver *Panel) Handle(ctx console.Context) error { return nil } - password := helpers.RandomString(16) + password := helper.RandomString(16) hash, err := facades.Hash().Make(password) if err != nil { color.Redln("生成密码失败") return nil } - user.Username = helpers.RandomString(8) + user.Username = helper.RandomString(8) user.Password = hash err = facades.Orm().Query().Save(&user) diff --git a/app/http/controllers/info_controller.go b/app/http/controllers/info_controller.go index 1b80a777..27fc0eae 100644 --- a/app/http/controllers/info_controller.go +++ b/app/http/controllers/info_controller.go @@ -8,7 +8,7 @@ import ( "panel/app/models" "panel/app/services" - "panel/packages/helpers" + "panel/packages/helper" ) type MenuItem struct { @@ -19,12 +19,12 @@ type MenuItem struct { } type InfoController struct { - //Dependent services + // Dependent services } func NewInfoController() *InfoController { return &InfoController{ - //Inject services + // Inject services } } @@ -81,11 +81,11 @@ func (r *InfoController) HomePlugins(ctx http.Context) { } func (r *InfoController) NowMonitor(ctx http.Context) { - Success(ctx, helpers.GetMonitoringInfo()) + Success(ctx, helper.GetMonitoringInfo()) } func (r *InfoController) SystemInfo(ctx http.Context) { - monitorInfo := helpers.GetMonitoringInfo() + monitorInfo := helper.GetMonitoringInfo() Success(ctx, http.Json{ "os_name": monitorInfo.Host.Platform + " " + monitorInfo.Host.PlatformVersion, diff --git a/app/http/controllers/plugin_controller.go b/app/http/controllers/plugin_controller.go index 83eceeec..e9bc5d94 100644 --- a/app/http/controllers/plugin_controller.go +++ b/app/http/controllers/plugin_controller.go @@ -1,12 +1,10 @@ package controllers import ( - "github.com/goravel/framework/contracts/queue" - "github.com/goravel/framework/facades" - "panel/app/jobs" "sync" "github.com/goravel/framework/contracts/http" + "github.com/goravel/framework/facades" "panel/app/models" "panel/app/services" @@ -14,11 +12,13 @@ import ( type PluginController struct { plugin services.Plugin + task services.Task } func NewPluginController() *PluginController { return &PluginController{ plugin: services.NewPluginImpl(), + task: services.NewTaskImpl(), } } @@ -116,7 +116,7 @@ func (r *PluginController) Install(ctx http.Context) { return } - processTask(task.ID) + r.task.Process(task.ID) Success(ctx, "任务已提交") } @@ -159,7 +159,7 @@ func (r *PluginController) Uninstall(ctx http.Context) { return } - processTask(task.ID) + r.task.Process(task.ID) Success(ctx, "任务已提交") } @@ -202,7 +202,7 @@ func (r *PluginController) Update(ctx http.Context) { return } - processTask(task.ID) + r.task.Process(task.ID) Success(ctx, "任务已提交") } @@ -231,16 +231,3 @@ func (r *PluginController) UpdateShow(ctx http.Context) { Success(ctx, "操作成功") } - -// processTask 处理任务 -func processTask(taskID uint) { - go func() { - err := facades.Queue().Job(&jobs.ProcessTask{}, []queue.Arg{ - {Type: "uint", Value: taskID}, - }).Dispatch() - if err != nil { - facades.Log().Error("[面板][PluginController] 运行任务失败: " + err.Error()) - return - } - }() -} diff --git a/app/http/controllers/plugins/mysql80/mysql80_controller.go b/app/http/controllers/plugins/mysql80/mysql80_controller.go index b5c198df..d4565ff1 100644 --- a/app/http/controllers/plugins/mysql80/mysql80_controller.go +++ b/app/http/controllers/plugins/mysql80/mysql80_controller.go @@ -16,7 +16,7 @@ import ( "panel/app/http/controllers" "panel/app/http/controllers/plugins" "panel/app/services" - "panel/packages/helpers" + "panel/packages/helper" ) type Mysql80Controller struct { @@ -35,7 +35,7 @@ func (r *Mysql80Controller) Status(ctx http.Context) { return } - out := helpers.ExecShell("systemctl status mysql | grep Active | grep -v grep | awk '{print $2}'") + out := helper.ExecShell("systemctl status mysql | grep Active | grep -v grep | awk '{print $2}'") status := strings.TrimSpace(out) if len(status) == 0 { controllers.Error(ctx, http.StatusInternalServerError, "获取MySQL状态失败") @@ -55,8 +55,8 @@ func (r *Mysql80Controller) Reload(ctx http.Context) { return } - _ = helpers.ExecShell("systemctl reload mysql") - out := helpers.ExecShell("systemctl status mysql | grep Active | grep -v grep | awk '{print $2}'") + helper.ExecShell("systemctl reload mysql") + out := helper.ExecShell("systemctl status mysql | grep Active | grep -v grep | awk '{print $2}'") status := strings.TrimSpace(out) if len(status) == 0 { controllers.Error(ctx, http.StatusInternalServerError, "获取MySQL状态失败") @@ -76,8 +76,8 @@ func (r *Mysql80Controller) Restart(ctx http.Context) { return } - _ = helpers.ExecShell("systemctl restart mysql") - out := helpers.ExecShell("systemctl status mysql | grep Active | grep -v grep | awk '{print $2}'") + helper.ExecShell("systemctl restart mysql") + out := helper.ExecShell("systemctl status mysql | grep Active | grep -v grep | awk '{print $2}'") status := strings.TrimSpace(out) if len(status) == 0 { controllers.Error(ctx, http.StatusInternalServerError, "获取MySQL状态失败") @@ -97,8 +97,8 @@ func (r *Mysql80Controller) Start(ctx http.Context) { return } - _ = helpers.ExecShell("systemctl start mysql") - out := helpers.ExecShell("systemctl status mysql | grep Active | grep -v grep | awk '{print $2}'") + helper.ExecShell("systemctl start mysql") + out := helper.ExecShell("systemctl status mysql | grep Active | grep -v grep | awk '{print $2}'") status := strings.TrimSpace(out) if len(status) == 0 { controllers.Error(ctx, http.StatusInternalServerError, "获取MySQL状态失败") @@ -118,15 +118,15 @@ func (r *Mysql80Controller) Stop(ctx http.Context) { return } - _ = helpers.ExecShell("systemctl stop mysql") - out := helpers.ExecShell("systemctl status mysql | grep Active | grep -v grep | awk '{print $2}'") + helper.ExecShell("systemctl stop mysql") + out := helper.ExecShell("systemctl status mysql | grep Active | grep -v grep | awk '{print $2}'") status := strings.TrimSpace(out) if len(status) == 0 { controllers.Error(ctx, http.StatusInternalServerError, "获取MySQL状态失败") return } - if status == "active" { + if status != "active" { controllers.Success(ctx, true) } else { controllers.Success(ctx, false) @@ -140,7 +140,7 @@ func (r *Mysql80Controller) GetConfig(ctx http.Context) { } // 获取配置 - config := helpers.ReadFile("mysql80") + config := helper.ReadFile("mysql80") if len(config) == 0 { controllers.Error(ctx, http.StatusInternalServerError, "获取MySQL配置失败") return @@ -161,7 +161,7 @@ func (r *Mysql80Controller) SaveConfig(ctx http.Context) { return } - if !helpers.WriteFile("mysql80", config, 0644) { + if !helper.WriteFile("mysql80", config, 0644) { controllers.Error(ctx, http.StatusInternalServerError, "写入MySQL配置失败") return } @@ -181,13 +181,13 @@ func (r *Mysql80Controller) Load(ctx http.Context) { return } - status := helpers.ExecShell("systemctl status mysqld | grep Active | grep -v grep | awk '{print $2}'") + status := helper.ExecShell("systemctl status mysqld | grep Active | grep -v grep | awk '{print $2}'") if strings.TrimSpace(status) != "active" { controllers.Error(ctx, http.StatusInternalServerError, "MySQL 已停止运行") return } - raw := helpers.ExecShell("mysqladmin -uroot -p" + rootPassword + " extended-status 2>&1") + raw := helper.ExecShell("mysqladmin -uroot -p" + rootPassword + " extended-status 2>&1") if strings.Contains(raw, "Access denied for user") { controllers.Error(ctx, http.StatusBadRequest, "MySQL root密码错误") return @@ -230,7 +230,7 @@ func (r *Mysql80Controller) Load(ctx http.Context) { data[i] = map[string]string{"name": expression.name, "value": matches[1]} if expression.name == "发送" || expression.name == "接收" { - data[i]["value"] = helpers.FormatBytes(cast.ToFloat64(matches[1])) + data[i]["value"] = helper.FormatBytes(cast.ToFloat64(matches[1])) } } } @@ -253,7 +253,7 @@ func (r *Mysql80Controller) ErrorLog(ctx http.Context) { return } - log := helpers.ExecShell("tail -n 100 /www/server/mysql/mysql-error.log") + log := helper.ExecShell("tail -n 100 /www/server/mysql/mysql-error.log") controllers.Success(ctx, log) } @@ -263,7 +263,7 @@ func (r *Mysql80Controller) ClearErrorLog(ctx http.Context) { return } - helpers.ExecShell("echo '' > /www/server/mysql/mysql-error.log") + helper.ExecShell("echo '' > /www/server/mysql/mysql-error.log") controllers.Success(ctx, "清空错误日志成功") } @@ -273,7 +273,7 @@ func (r *Mysql80Controller) SlowLog(ctx http.Context) { return } - log := helpers.ExecShell("tail -n 100 /www/server/mysql/mysql-slow.log") + log := helper.ExecShell("tail -n 100 /www/server/mysql/mysql-slow.log") controllers.Success(ctx, log) } @@ -283,7 +283,7 @@ func (r *Mysql80Controller) ClearSlowLog(ctx http.Context) { return } - helpers.ExecShell("echo '' > /www/server/mysql/mysql-slow.log") + helper.ExecShell("echo '' > /www/server/mysql/mysql-slow.log") controllers.Success(ctx, "清空慢查询日志成功") } @@ -308,7 +308,7 @@ func (r *Mysql80Controller) SetRootPassword(ctx http.Context) { return } - out := helpers.ExecShell("systemctl status mysql | grep Active | grep -v grep | awk '{print $2}'") + out := helper.ExecShell("systemctl status mysql | grep Active | grep -v grep | awk '{print $2}'") status := strings.TrimSpace(out) if len(status) == 0 { controllers.Error(ctx, http.StatusInternalServerError, "获取MySQL状态失败") @@ -327,12 +327,12 @@ func (r *Mysql80Controller) SetRootPassword(ctx http.Context) { oldRootPassword := r.setting.Get("mysql_root_password") if oldRootPassword != rootPassword { - helpers.ExecShell("mysql -uroot -p" + oldRootPassword + " -e \"ALTER USER 'root'@'localhost' IDENTIFIED BY '" + rootPassword + "';\"") - helpers.ExecShell("mysql -uroot -p" + oldRootPassword + " -e \"FLUSH PRIVILEGES;\"") + helper.ExecShell("mysql -uroot -p" + oldRootPassword + " -e \"ALTER USER 'root'@'localhost' IDENTIFIED BY '" + rootPassword + "';\"") + helper.ExecShell("mysql -uroot -p" + oldRootPassword + " -e \"FLUSH PRIVILEGES;\"") err := r.setting.Set("mysql_root_password", rootPassword) if err != nil { - helpers.ExecShell("mysql -uroot -p" + rootPassword + " -e \"ALTER USER 'root'@'localhost' IDENTIFIED BY '" + oldRootPassword + "';\"") - helpers.ExecShell("mysql -uroot -p" + rootPassword + " -e \"FLUSH PRIVILEGES;\"") + helper.ExecShell("mysql -uroot -p" + rootPassword + " -e \"ALTER USER 'root'@'localhost' IDENTIFIED BY '" + oldRootPassword + "';\"") + helper.ExecShell("mysql -uroot -p" + rootPassword + " -e \"FLUSH PRIVILEGES;\"") controllers.Error(ctx, http.StatusInternalServerError, "设置root密码失败") return } @@ -347,7 +347,7 @@ func (r *Mysql80Controller) DatabaseList(ctx http.Context) { return } - out := helpers.ExecShell("mysql -uroot -p" + r.setting.Get("mysql_root_password") + " -e \"show databases;\"") + out := helper.ExecShell("mysql -uroot -p" + r.setting.Get("mysql_root_password") + " -e \"show databases;\"") databases := strings.Split(out, "\n") databases = databases[1 : len(databases)-1] @@ -397,10 +397,10 @@ func (r *Mysql80Controller) AddDatabase(ctx http.Context) { user := ctx.Request().Input("user") password := ctx.Request().Input("password") - helpers.ExecShell("mysql -uroot -p" + rootPassword + " -e \"CREATE DATABASE IF NOT EXISTS " + database + " DEFAULT CHARSET utf8mb4 COLLATE utf8mb4_general_ci;\"") - helpers.ExecShell("mysql -uroot -p" + rootPassword + " -e \"CREATE USER '" + user + "'@'localhost' IDENTIFIED BY '" + password + "';\"") - helpers.ExecShell("mysql -uroot -p" + rootPassword + " -e \"GRANT ALL PRIVILEGES ON " + database + ".* TO '" + user + "'@'localhost';\"") - helpers.ExecShell("mysql -uroot -p" + rootPassword + " -e \"FLUSH PRIVILEGES;\"") + helper.ExecShell("mysql -uroot -p" + rootPassword + " -e \"CREATE DATABASE IF NOT EXISTS " + database + " DEFAULT CHARSET utf8mb4 COLLATE utf8mb4_general_ci;\"") + helper.ExecShell("mysql -uroot -p" + rootPassword + " -e \"CREATE USER '" + user + "'@'localhost' IDENTIFIED BY '" + password + "';\"") + helper.ExecShell("mysql -uroot -p" + rootPassword + " -e \"GRANT ALL PRIVILEGES ON " + database + ".* TO '" + user + "'@'localhost';\"") + helper.ExecShell("mysql -uroot -p" + rootPassword + " -e \"FLUSH PRIVILEGES;\"") controllers.Success(ctx, "添加数据库成功") } @@ -425,7 +425,7 @@ func (r *Mysql80Controller) DeleteDatabase(ctx http.Context) { rootPassword := r.setting.Get("mysql_root_password") database := ctx.Request().Input("database") - helpers.ExecShell("mysql -uroot -p" + rootPassword + " -e \"DROP DATABASE IF EXISTS " + database + ";\"") + helper.ExecShell("mysql -uroot -p" + rootPassword + " -e \"DROP DATABASE IF EXISTS " + database + ";\"") controllers.Success(ctx, "删除数据库成功") } @@ -434,8 +434,8 @@ func (r *Mysql80Controller) DeleteDatabase(ctx http.Context) { func (r *Mysql80Controller) BackupList(ctx http.Context) { backupPath := "/www/backup/mysql" - if !helpers.Exists(backupPath) { - helpers.Mkdir(backupPath, 0644) + if !helper.Exists(backupPath) { + helper.Mkdir(backupPath, 0644) } files, err := os.ReadDir(backupPath) @@ -457,7 +457,7 @@ func (r *Mysql80Controller) BackupList(ctx http.Context) { backupFiles = append(backupFiles, map[string]string{ "file": file.Name(), - "size": helpers.FormatBytes(float64(info.Size())), + "size": helper.FormatBytes(float64(info.Size())), }) } @@ -486,8 +486,8 @@ func (r *Mysql80Controller) CreateBackup(ctx http.Context) { rootPassword := r.setting.Get("mysql_root_password") database := ctx.Request().Input("database") backupFile := backupPath + "/" + database + "_" + carbon.Now().ToShortDateTimeString() + ".sql" - if !helpers.Exists(backupPath) { - helpers.Mkdir(backupPath, 0644) + if !helper.Exists(backupPath) { + helper.Mkdir(backupPath, 0644) } err = os.Setenv("MYSQL_PWD", rootPassword) if err != nil { @@ -496,9 +496,9 @@ func (r *Mysql80Controller) CreateBackup(ctx http.Context) { return } - helpers.ExecShell("mysqldump -uroot " + database + " > " + backupFile) - helpers.ExecShell("zip -r " + backupFile + ".zip " + backupFile) - helpers.RemoveFile(backupFile) + helper.ExecShell("mysqldump -uroot " + database + " > " + backupFile) + helper.ExecShell("zip -r " + backupFile + ".zip " + backupFile) + helper.RemoveFile(backupFile) _ = os.Unsetenv("MYSQL_PWD") controllers.Success(ctx, "备份成功") @@ -524,7 +524,7 @@ func (r *Mysql80Controller) DeleteBackup(ctx http.Context) { backupPath := "/www/backup/mysql" file := ctx.Request().Input("file") - helpers.RemoveFile(backupPath + "/" + file) + helper.RemoveFile(backupPath + "/" + file) controllers.Success(ctx, "删除备份成功") } @@ -552,7 +552,7 @@ func (r *Mysql80Controller) RestoreBackup(ctx http.Context) { rootPassword := r.setting.Get("mysql_root_password") file := ctx.Request().Input("file") backupFile := backupPath + "/" + file - if !helpers.Exists(backupFile) { + if !helper.Exists(backupFile) { controllers.Error(ctx, http.StatusBadRequest, "备份文件不存在") return } @@ -568,35 +568,35 @@ func (r *Mysql80Controller) RestoreBackup(ctx http.Context) { ext := filepath.Ext(file) switch ext { case ".zip": - helpers.ExecShell("unzip -o " + backupFile + " -d " + backupPath) + helper.ExecShell("unzip -o " + backupFile + " -d " + backupPath) backupFile = strings.TrimSuffix(backupFile, ext) case ".gz": if strings.HasSuffix(file, ".tar.gz") { // 解压.tar.gz文件 - helpers.ExecShell("tar -zxvf " + backupFile + " -C " + backupPath) + helper.ExecShell("tar -zxvf " + backupFile + " -C " + backupPath) backupFile = strings.TrimSuffix(backupFile, ".tar.gz") } else { // 解压.gz文件 - helpers.ExecShell("gzip -d " + backupFile) + helper.ExecShell("gzip -d " + backupFile) backupFile = strings.TrimSuffix(backupFile, ext) } case ".bz2": - helpers.ExecShell("bzip2 -d " + backupFile) + helper.ExecShell("bzip2 -d " + backupFile) backupFile = strings.TrimSuffix(backupFile, ext) case ".tar": - helpers.ExecShell("tar -xvf " + backupFile + " -C " + backupPath) + helper.ExecShell("tar -xvf " + backupFile + " -C " + backupPath) backupFile = strings.TrimSuffix(backupFile, ext) case ".rar": - helpers.ExecShell("unrar x " + backupFile + " " + backupPath) + helper.ExecShell("unrar x " + backupFile + " " + backupPath) backupFile = strings.TrimSuffix(backupFile, ext) } - if !helpers.Exists(backupFile) { + if !helper.Exists(backupFile) { controllers.Error(ctx, http.StatusBadRequest, "自动解压备份文件失败,请手动解压") return } - helpers.ExecShell("mysql -uroot " + ctx.Request().Input("database") + " < " + backupFile) + helper.ExecShell("mysql -uroot " + ctx.Request().Input("database") + " < " + backupFile) _ = os.Unsetenv("MYSQL_PWD") controllers.Success(ctx, "还原成功") @@ -615,7 +615,7 @@ func (r *Mysql80Controller) UserList(ctx http.Context) { } rootPassword := r.setting.Get("mysql_root_password") - out := helpers.ExecShell("mysql -uroot -p" + rootPassword + " -e 'select user,host from mysql.user'") + out := helper.ExecShell("mysql -uroot -p" + rootPassword + " -e 'select user,host from mysql.user'") rawUsers := strings.Split(out, "\n") users := make([]User, 0) for _, rawUser := range rawUsers { @@ -624,7 +624,7 @@ func (r *Mysql80Controller) UserList(ctx http.Context) { continue } - out := helpers.ExecShell("mysql -uroot -p" + rootPassword + " -e 'show grants for " + user[0] + "@" + user[1] + "'") + out := helper.ExecShell("mysql -uroot -p" + rootPassword + " -e 'show grants for " + user[0] + "@" + user[1] + "'") rawPrivileges := strings.Split(out, "\n") privileges := make([]string, 0) for _, rawPrivilege := range rawPrivileges { @@ -664,9 +664,9 @@ func (r *Mysql80Controller) AddUser(ctx http.Context) { user := ctx.Request().Input("user") password := ctx.Request().Input("password") database := ctx.Request().Input("database") - helpers.ExecShell("mysql -uroot -p" + rootPassword + " -e \"CREATE USER '" + user + "'@'localhost' IDENTIFIED BY '" + password + ";'\"") - helpers.ExecShell("mysql -uroot -p" + rootPassword + " -e \"GRANT ALL PRIVILEGES ON " + database + ".* TO '" + user + "'@'localhost';\"") - helpers.ExecShell("mysql -uroot -p" + rootPassword + " -e \"FLUSH PRIVILEGES;\"") + helper.ExecShell("mysql -uroot -p" + rootPassword + " -e \"CREATE USER '" + user + "'@'localhost' IDENTIFIED BY '" + password + ";'\"") + helper.ExecShell("mysql -uroot -p" + rootPassword + " -e \"GRANT ALL PRIVILEGES ON " + database + ".* TO '" + user + "'@'localhost';\"") + helper.ExecShell("mysql -uroot -p" + rootPassword + " -e \"FLUSH PRIVILEGES;\"") controllers.Success(ctx, "添加成功") } @@ -691,7 +691,7 @@ func (r *Mysql80Controller) DeleteUser(ctx http.Context) { rootPassword := r.setting.Get("mysql_root_password") user := ctx.Request().Input("user") - helpers.ExecShell("mysql -uroot -p" + rootPassword + " -e \"DROP USER '" + user + "'@'localhost';\"") + helper.ExecShell("mysql -uroot -p" + rootPassword + " -e \"DROP USER '" + user + "'@'localhost';\"") controllers.Success(ctx, "删除成功") } @@ -718,8 +718,8 @@ func (r *Mysql80Controller) SetUserPassword(ctx http.Context) { rootPassword := r.setting.Get("mysql_root_password") user := ctx.Request().Input("user") password := ctx.Request().Input("password") - helpers.ExecShell("mysql -uroot -p" + rootPassword + " -e \"ALTER USER '" + user + "'@'localhost' IDENTIFIED BY '" + password + "';\"") - helpers.ExecShell("mysql -uroot -p" + rootPassword + " -e \"FLUSH PRIVILEGES;\"") + helper.ExecShell("mysql -uroot -p" + rootPassword + " -e \"ALTER USER '" + user + "'@'localhost' IDENTIFIED BY '" + password + "';\"") + helper.ExecShell("mysql -uroot -p" + rootPassword + " -e \"FLUSH PRIVILEGES;\"") controllers.Success(ctx, "修改成功") } @@ -746,9 +746,9 @@ func (r *Mysql80Controller) SetUserPrivileges(ctx http.Context) { rootPassword := r.setting.Get("mysql_root_password") user := ctx.Request().Input("user") database := ctx.Request().Input("database") - helpers.ExecShell("mysql -uroot -p" + rootPassword + " -e \"REVOKE ALL PRIVILEGES ON *.* FROM '" + user + "'@'localhost';\"") - helpers.ExecShell("mysql -uroot -p" + rootPassword + " -e \"GRANT ALL PRIVILEGES ON " + database + ".* TO '" + user + "'@'localhost';\"") - helpers.ExecShell("mysql -uroot -p" + rootPassword + " -e \"FLUSH PRIVILEGES;\"") + helper.ExecShell("mysql -uroot -p" + rootPassword + " -e \"REVOKE ALL PRIVILEGES ON *.* FROM '" + user + "'@'localhost';\"") + helper.ExecShell("mysql -uroot -p" + rootPassword + " -e \"GRANT ALL PRIVILEGES ON " + database + ".* TO '" + user + "'@'localhost';\"") + helper.ExecShell("mysql -uroot -p" + rootPassword + " -e \"FLUSH PRIVILEGES;\"") controllers.Success(ctx, "修改成功") } diff --git a/app/http/controllers/plugins/openresty/openresty_controller.go b/app/http/controllers/plugins/openresty/openresty_controller.go index f27ac545..87455488 100644 --- a/app/http/controllers/plugins/openresty/openresty_controller.go +++ b/app/http/controllers/plugins/openresty/openresty_controller.go @@ -12,7 +12,7 @@ import ( "panel/app/http/controllers" "panel/app/http/controllers/plugins" - "panel/packages/helpers" + "panel/packages/helper" ) type OpenRestyController struct { @@ -31,7 +31,7 @@ func (r *OpenRestyController) Status(ctx http.Context) { return } - out := helpers.ExecShell("systemctl status openresty | grep Active | grep -v grep | awk '{print $2}'") + out := helper.ExecShell("systemctl status openresty | grep Active | grep -v grep | awk '{print $2}'") status := strings.TrimSpace(out) if len(status) == 0 { controllers.Error(ctx, http.StatusInternalServerError, "获取OpenResty状态失败") @@ -51,8 +51,8 @@ func (r *OpenRestyController) Reload(ctx http.Context) { return } - _ = helpers.ExecShell("systemctl reload openresty") - out := helpers.ExecShell("systemctl status openresty | grep Active | grep -v grep | awk '{print $2}'") + helper.ExecShell("systemctl reload openresty") + out := helper.ExecShell("systemctl status openresty | grep Active | grep -v grep | awk '{print $2}'") status := strings.TrimSpace(out) if len(status) == 0 { controllers.Error(ctx, http.StatusInternalServerError, "获取OpenResty状态失败") @@ -72,8 +72,8 @@ func (r *OpenRestyController) Start(ctx http.Context) { return } - _ = helpers.ExecShell("systemctl start openresty") - out := helpers.ExecShell("systemctl status openresty | grep Active | grep -v grep | awk '{print $2}'") + helper.ExecShell("systemctl start openresty") + out := helper.ExecShell("systemctl status openresty | grep Active | grep -v grep | awk '{print $2}'") status := strings.TrimSpace(out) if len(status) == 0 { controllers.Error(ctx, http.StatusInternalServerError, "获取OpenResty状态失败") @@ -93,15 +93,15 @@ func (r *OpenRestyController) Stop(ctx http.Context) { return } - _ = helpers.ExecShell("systemctl stop openresty") - out := helpers.ExecShell("systemctl status openresty | grep Active | grep -v grep | awk '{print $2}'") + helper.ExecShell("systemctl stop openresty") + out := helper.ExecShell("systemctl status openresty | grep Active | grep -v grep | awk '{print $2}'") status := strings.TrimSpace(out) if len(status) == 0 { controllers.Error(ctx, http.StatusInternalServerError, "获取OpenResty状态失败") return } - if status == "active" { + if status != "active" { controllers.Success(ctx, "停止OpenResty成功") } else { controllers.Error(ctx, 1, "停止OpenResty失败: "+string(out)) @@ -114,8 +114,8 @@ func (r *OpenRestyController) Restart(ctx http.Context) { return } - _ = helpers.ExecShell("systemctl restart openresty") - out := helpers.ExecShell("systemctl status openresty | grep Active | grep -v grep | awk '{print $2}'") + helper.ExecShell("systemctl restart openresty") + out := helper.ExecShell("systemctl status openresty | grep Active | grep -v grep | awk '{print $2}'") status := strings.TrimSpace(out) if len(status) == 0 { controllers.Error(ctx, http.StatusInternalServerError, "获取OpenResty状态失败") @@ -135,7 +135,7 @@ func (r *OpenRestyController) GetConfig(ctx http.Context) { return } - config := helpers.ReadFile("/www/server/openresty/conf/nginx.conf") + config := helper.ReadFile("/www/server/openresty/conf/nginx.conf") if len(config) == 0 { controllers.Error(ctx, http.StatusInternalServerError, "获取OpenResty配置失败") return @@ -156,7 +156,7 @@ func (r *OpenRestyController) SaveConfig(ctx http.Context) { return } - if !helpers.WriteFile("/www/server/openresty/conf/nginx.conf", config, 0644) { + if !helper.WriteFile("/www/server/openresty/conf/nginx.conf", config, 0644) { controllers.Error(ctx, http.StatusInternalServerError, "保存OpenResty配置失败") return } @@ -170,7 +170,7 @@ func (r *OpenRestyController) ErrorLog(ctx http.Context) { return } - out := helpers.ExecShell("tail -n 100 /www/wwwlogs/nginx_error.log") + out := helper.ExecShell("tail -n 100 /www/wwwlogs/nginx_error.log") controllers.Success(ctx, out) } @@ -180,7 +180,7 @@ func (r *OpenRestyController) ClearErrorLog(ctx http.Context) { return } - _ = helpers.ExecShell("echo '' > /www/wwwlogs/nginx_error.log") + _ = helper.ExecShell("echo '' > /www/wwwlogs/nginx_error.log") controllers.Success(ctx, "清空OpenResty错误日志成功") } @@ -201,13 +201,13 @@ func (r *OpenRestyController) Load(ctx http.Context) { raw := resp.String() var data map[int]map[string]any - out := helpers.ExecShell("ps aux | grep nginx | grep 'worker process' | wc -l") + out := helper.ExecShell("ps aux | grep nginx | grep 'worker process' | wc -l") workers := strings.TrimSpace(out) data[0]["name"] = "工作进程" data[0]["value"] = workers - out = helpers.ExecShell("ps aux | grep nginx | grep 'worker process' | awk '{memsum+=$6};END {print memsum}'") - mem := helpers.FormatBytes(cast.ToFloat64(strings.TrimSpace(out))) + out = helper.ExecShell("ps aux | grep nginx | grep 'worker process' | awk '{memsum+=$6};END {print memsum}'") + mem := helper.FormatBytes(cast.ToFloat64(strings.TrimSpace(out))) data[1]["name"] = "内存占用" data[1]["value"] = mem diff --git a/app/http/controllers/plugins/php74/php74_controller.go b/app/http/controllers/plugins/php74/php74_controller.go new file mode 100644 index 00000000..fd930333 --- /dev/null +++ b/app/http/controllers/plugins/php74/php74_controller.go @@ -0,0 +1,373 @@ +package php74 + +import ( + "fmt" + "regexp" + "strings" + "time" + + "github.com/goravel/framework/contracts/http" + "github.com/goravel/framework/facades" + "github.com/imroc/req/v3" + + "panel/app/http/controllers" + "panel/app/http/controllers/plugins" + "panel/app/models" + "panel/app/services" + "panel/packages/helper" +) + +type Php74Controller struct { + setting services.Setting + task services.Task + version string +} + +func NewPhp74Controller() *Php74Controller { + return &Php74Controller{ + setting: services.NewSettingImpl(), + task: services.NewTaskImpl(), + version: "74", + } +} + +func (c *Php74Controller) Status(ctx http.Context) { + if !plugins.Check(ctx, "php"+c.version) { + return + } + + out := helper.ExecShell("systemctl status php-fpm-" + c.version + " | grep Active | grep -v grep | awk '{print $2}'") + status := strings.TrimSpace(out) + if len(status) == 0 { + controllers.Error(ctx, http.StatusInternalServerError, "获取PHP-"+c.version+"运行状态失败") + return + } + + if status == "active" { + controllers.Success(ctx, true) + } else { + controllers.Success(ctx, false) + } +} + +func (c *Php74Controller) Reload(ctx http.Context) { + if !plugins.Check(ctx, "php"+c.version) { + return + } + + helper.ExecShell("systemctl reload php-fpm-" + c.version) + out := helper.ExecShell("systemctl status php-fpm-" + c.version + " | grep Active | grep -v grep | awk '{print $2}'") + status := strings.TrimSpace(out) + if len(status) == 0 { + controllers.Error(ctx, http.StatusInternalServerError, "获取PHP-"+c.version+"运行状态失败") + return + } + + if status == "active" { + controllers.Success(ctx, true) + } else { + controllers.Success(ctx, false) + } +} + +func (c *Php74Controller) Start(ctx http.Context) { + if !plugins.Check(ctx, "php"+c.version) { + return + } + + helper.ExecShell("systemctl start php-fpm-" + c.version) + out := helper.ExecShell("systemctl status php-fpm-" + c.version + " | grep Active | grep -v grep | awk '{print $2}'") + status := strings.TrimSpace(out) + if len(status) == 0 { + controllers.Error(ctx, http.StatusInternalServerError, "获取PHP-"+c.version+"运行状态失败") + return + } + + if status == "active" { + controllers.Success(ctx, true) + } else { + controllers.Success(ctx, false) + } +} + +func (c *Php74Controller) Stop(ctx http.Context) { + if !plugins.Check(ctx, "php"+c.version) { + return + } + + helper.ExecShell("systemctl stop php-fpm-" + c.version) + out := helper.ExecShell("systemctl status php-fpm-" + c.version + " | grep Active | grep -v grep | awk '{print $2}'") + status := strings.TrimSpace(out) + if len(status) == 0 { + controllers.Error(ctx, http.StatusInternalServerError, "获取PHP-"+c.version+"运行状态失败") + return + } + + if status != "active" { + controllers.Success(ctx, true) + } else { + controllers.Success(ctx, false) + } +} + +func (c *Php74Controller) Restart(ctx http.Context) { + if !plugins.Check(ctx, "php"+c.version) { + return + } + + helper.ExecShell("systemctl restart php-fpm-" + c.version) + out := helper.ExecShell("systemctl status php-fpm-" + c.version + " | grep Active | grep -v grep | awk '{print $2}'") + status := strings.TrimSpace(out) + if len(status) == 0 { + controllers.Error(ctx, http.StatusInternalServerError, "获取PHP-"+c.version+"运行状态失败") + return + } + + if status == "active" { + controllers.Success(ctx, true) + } else { + controllers.Success(ctx, false) + } +} + +func (c *Php74Controller) GetConfig(ctx http.Context) { + if !plugins.Check(ctx, "php"+c.version) { + return + } + + config := helper.ReadFile("/www/server/php/" + c.version + "/etc/php.ini") + controllers.Success(ctx, config) +} + +func (c *Php74Controller) SaveConfig(ctx http.Context) { + if !plugins.Check(ctx, "php"+c.version) { + return + } + + config := ctx.Request().Input("config") + helper.WriteFile("/www/server/php/"+c.version+"/etc/php.ini", config, 0644) + c.Reload(ctx) +} + +func (c *Php74Controller) Load(ctx http.Context) { + if !plugins.Check(ctx, "php"+c.version) { + return + } + + client := req.C().SetTimeout(10 * time.Second) + resp, err := client.R().Get("http://127.0.0.1/phpfpm_" + c.version + "_status") + if err != nil || !resp.IsSuccessState() { + facades.Log().Error("获取PHP-" + c.version + "运行状态失败") + controllers.Error(ctx, http.StatusInternalServerError, "[PHP-"+c.version+"] 获取运行状态失败") + return + } + + raw := resp.String() + dataKeys := []string{"应用池", "工作模式", "启动时间", "接受连接", "监听队列", "最大监听队列", "监听队列长度", "空闲进程数量", "活动进程数量", "总进程数量", "最大活跃进程数量", "达到进程上限次数", "慢请求"} + regexKeys := []string{"pool", "process manager", "start time", "accepted conn", "listen queue", "max listen queue", "listen queue len", "idle processes", "active processes", "total processes", "max active processes", "max children reached", "slow requests"} + + type Data struct { + Name string `json:"name"` + Value string `json:"value"` + } + data := make([]Data, len(dataKeys)) + for i := range dataKeys { + data[i].Name = dataKeys[i] + + r := regexp.MustCompile(fmt.Sprintf("%s:\\s+(.*)", regexKeys[i])) + match := r.FindStringSubmatch(raw) + + if len(match) > 1 { + data[i].Value = strings.TrimSpace(match[1]) + } + } + + controllers.Success(ctx, data) +} + +func (c *Php74Controller) ErrorLog(ctx http.Context) { + if !plugins.Check(ctx, "php"+c.version) { + return + } + + log := helper.ExecShell("tail -n 100 /www/server/php/" + c.version + "/var/log/php-fpm.log") + controllers.Success(ctx, log) +} + +func (c *Php74Controller) SlowLog(ctx http.Context) { + if !plugins.Check(ctx, "php"+c.version) { + return + } + + log := helper.ExecShell("tail -n 100 /www/server/php/" + c.version + "/var/log/slow.log") + controllers.Success(ctx, log) +} + +func (c *Php74Controller) ClearErrorLog(ctx http.Context) { + if !plugins.Check(ctx, "php"+c.version) { + return + } + + helper.ExecShell("echo '' > /www/server/php/" + c.version + "/var/log/php-fpm.log") + controllers.Success(ctx, true) +} + +func (c *Php74Controller) ClearSlowLog(ctx http.Context) { + if !plugins.Check(ctx, "php"+c.version) { + return + } + + helper.ExecShell("echo '' > /www/server/php/" + c.version + "/var/log/slow.log") + controllers.Success(ctx, true) +} + +type Extension struct { + Name string `json:"name"` + Slug string `json:"slug"` + Description string `json:"description"` + Installed bool `json:"installed"` +} + +func (c *Php74Controller) GetExtensionList(ctx http.Context) { + if !plugins.Check(ctx, "php"+c.version) { + return + } + + extensions := c.GetExtensions() + controllers.Success(ctx, extensions) +} + +func (c *Php74Controller) InstallExtension(ctx http.Context) { + if !plugins.Check(ctx, "php"+c.version) { + return + } + + slug := ctx.Request().Input("slug") + if len(slug) == 0 { + controllers.Error(ctx, http.StatusBadRequest, "参数错误") + return + } + + extensions := c.GetExtensions() + for _, item := range extensions { + if item.Slug == slug { + if item.Installed { + controllers.Error(ctx, http.StatusBadRequest, "扩展已安装") + return + } + + var task models.Task + task.Name = "安装PHP-" + c.version + "扩展-" + item.Name + task.Status = models.TaskStatusWaiting + task.Shell = "bash scripts/php_extensions/" + item.Slug + ".sh install " + c.version + ">> /tmp/" + item.Slug + ".log 2>&1" + task.Log = "/tmp/" + item.Slug + ".log" + if err := facades.Orm().Query().Create(&task); err != nil { + facades.Log().Error("[PHP-" + c.version + "] 创建安装拓展任务失败:" + err.Error()) + controllers.Error(ctx, http.StatusInternalServerError, "系统内部错误") + return + } + + c.task.Process(task.ID) + + controllers.Success(ctx, true) + return + } + } + + controllers.Error(ctx, http.StatusBadRequest, "扩展不存在") +} + +func (c *Php74Controller) UninstallExtension(ctx http.Context) { + if !plugins.Check(ctx, "php"+c.version) { + return + } + + slug := ctx.Request().Input("slug") + if len(slug) == 0 { + controllers.Error(ctx, http.StatusBadRequest, "参数错误") + return + } + + extensions := c.GetExtensions() + for _, item := range extensions { + if item.Slug == slug { + if !item.Installed { + controllers.Error(ctx, http.StatusBadRequest, "扩展未安装") + return + } + + var task models.Task + task.Name = "卸载PHP-" + c.version + "扩展-" + item.Name + task.Status = models.TaskStatusWaiting + task.Shell = "bash scripts/php_extensions/" + item.Slug + ".sh uninstall " + c.version + ">> /tmp/" + item.Slug + ".log 2>&1" + task.Log = "/tmp/" + item.Slug + ".log" + if err := facades.Orm().Query().Create(&task); err != nil { + facades.Log().Error("[PHP-" + c.version + "] 创建卸载拓展任务失败:" + err.Error()) + controllers.Error(ctx, http.StatusInternalServerError, "系统内部错误") + return + } + + c.task.Process(task.ID) + + controllers.Success(ctx, true) + return + } + } + + controllers.Error(ctx, http.StatusBadRequest, "扩展不存在") +} + +func (c *Php74Controller) GetExtensions() []Extension { + var extensions []Extension + extensions = append(extensions, Extension{ + Name: "OPcache", + Slug: "Zend OPcache", + Description: "OPcache 通过将 PHP 脚本预编译的字节码存储到共享内存中来提升 PHP 的性能,存储预编译字节码可以省去每次加载和解析 PHP 脚本的开销。", + Installed: false, + }) + extensions = append(extensions, Extension{ + Name: "PhpRedis", + Slug: "redis", + Description: "PhpRedis 是一个用C语言编写的PHP模块,用来连接并操作 Redis 数据库上的数据。", + Installed: false, + }) + extensions = append(extensions, Extension{ + Name: "ImageMagick", + Slug: "imagick", + Description: "ImageMagick 是一个免费的创建、编辑、合成图片的软件。", + Installed: false, + }) + extensions = append(extensions, Extension{ + Name: "Exif", + Slug: "exif", + Description: "通过 exif 扩展,你可以操作图像元数据。", + Installed: false, + }) + extensions = append(extensions, Extension{ + Name: "pdo_pgsql", + Slug: "pdo_pgsql", + Description: "(需先安装PostgreSQL)pdo_pgsql 是一个驱动程序,它实现了 PHP 数据对象(PDO)接口以启用从 PHP 到 PostgreSQL 数据库的访问。", + Installed: false, + }) + extensions = append(extensions, Extension{ + Name: "ionCube", + Slug: "ionCube Loader", + Description: "ionCube 是一个专业级的PHP加密解密工具。", + Installed: false, + }) + + raw := helper.ExecShell("/www/server/php/" + c.version + "/bin/php -m") + rawExtensionList := strings.Split(raw, "\n") + + for _, item := range rawExtensionList { + if !strings.Contains(item, "[") && item != "" { + for i := range extensions { + if extensions[i].Name == item { + extensions[i].Installed = true + } + } + } + } + + return extensions +} diff --git a/app/models/monitor.go b/app/models/monitor.go index bcc6da23..bad0b0a4 100644 --- a/app/models/monitor.go +++ b/app/models/monitor.go @@ -2,12 +2,13 @@ package models import ( "github.com/goravel/framework/support/carbon" - "panel/packages/helpers" + + "panel/packages/helper" ) type Monitor struct { - ID uint `gorm:"primaryKey" json:"id"` - Info helpers.MonitoringInfo `gorm:"type:json;serializer:json" json:"info"` - CreatedAt carbon.DateTime `gorm:"autoCreateTime;column:created_at" json:"created_at"` - UpdatedAt carbon.DateTime `gorm:"autoUpdateTime;column:updated_at" json:"updated_at"` + ID uint `gorm:"primaryKey" json:"id"` + Info helper.MonitoringInfo `gorm:"type:json;serializer:json" json:"info"` + CreatedAt carbon.DateTime `gorm:"autoCreateTime;column:created_at" json:"created_at"` + UpdatedAt carbon.DateTime `gorm:"autoUpdateTime;column:updated_at" json:"updated_at"` } diff --git a/app/plugins/php74/php74.go b/app/plugins/php74/php74.go new file mode 100644 index 00000000..7e0263ca --- /dev/null +++ b/app/plugins/php74/php74.go @@ -0,0 +1,11 @@ +package php74 + +var ( + Name = "PHP-7.4" + Author = "耗子" + Description = "PHP 是世界上最好的语言!" + Slug = "php74" + Version = "7.4.33" + Requires = []string{} + Excludes = []string{} +) diff --git a/app/services/plugin.go b/app/services/plugin.go index b86982cb..373bdd51 100644 --- a/app/services/plugin.go +++ b/app/services/plugin.go @@ -7,6 +7,7 @@ import ( "panel/app/models" "panel/app/plugins/mysql80" "panel/app/plugins/openresty" + "panel/app/plugins/php74" ) // PanelPlugin 插件元数据结构 @@ -64,6 +65,15 @@ func (r *PluginImpl) All() []PanelPlugin { Requires: mysql80.Requires, Excludes: mysql80.Excludes, }) + p = append(p, PanelPlugin{ + Name: php74.Name, + Author: php74.Author, + Description: php74.Description, + Slug: php74.Slug, + Version: php74.Version, + Requires: php74.Requires, + Excludes: php74.Excludes, + }) return p } diff --git a/app/services/task.go b/app/services/task.go new file mode 100644 index 00000000..bc64c878 --- /dev/null +++ b/app/services/task.go @@ -0,0 +1,31 @@ +package services + +import ( + "github.com/goravel/framework/contracts/queue" + "github.com/goravel/framework/facades" + + "panel/app/jobs" +) + +type Task interface { + Process(taskID uint) +} + +type TaskImpl struct { +} + +func NewTaskImpl() *TaskImpl { + return &TaskImpl{} +} + +func (r *TaskImpl) Process(taskID uint) { + go func() { + err := facades.Queue().Job(&jobs.ProcessTask{}, []queue.Arg{ + {Type: "uint", Value: taskID}, + }).Dispatch() + if err != nil { + facades.Log().Error("[面板][TaskService] 运行任务失败: " + err.Error()) + return + } + }() +} diff --git a/app/services/website.go b/app/services/website.go index 5eaa349d..32420950 100644 --- a/app/services/website.go +++ b/app/services/website.go @@ -10,7 +10,7 @@ import ( "golang.org/x/exp/slices" "panel/app/models" - "panel/packages/helpers" + "panel/packages/helper" ) type Website interface { @@ -106,7 +106,7 @@ func (r *WebsiteImpl) Add(website PanelWebsite) (models.Website, error) { return w, err } - helpers.Mkdir(website.Path, 0755) + helper.Mkdir(website.Path, 0755) index := ` @@ -123,7 +123,7 @@ func (r *WebsiteImpl) Add(website PanelWebsite) (models.Website, error) { ` - helpers.WriteFile(website.Path+"/index.html", index, 0644) + helper.WriteFile(website.Path+"/index.html", index, 0644) domainArr := strings.Split(website.Domain, "\n") portList := "" @@ -213,12 +213,12 @@ server `, portList, domainList, website.Path, website.Php, website.Name, website.Name, website.Name) - helpers.WriteFile("/www/server/panel/vhost/openresty/"+website.Name+".conf", nginxConf, 0644) - helpers.WriteFile("/www/server/panel/vhost/openresty/rewrite/"+website.Name+".conf", "", 0644) - helpers.WriteFile("/www/server/panel/vhost/openresty/ssl/"+website.Name+".pem", "", 0644) - helpers.WriteFile("/www/server/panel/vhost/openresty/ssl/"+website.Name+".key", "", 0644) + helper.WriteFile("/www/server/panel/vhost/openresty/"+website.Name+".conf", nginxConf, 0644) + helper.WriteFile("/www/server/panel/vhost/openresty/rewrite/"+website.Name+".conf", "", 0644) + helper.WriteFile("/www/server/panel/vhost/openresty/ssl/"+website.Name+".pem", "", 0644) + helper.WriteFile("/www/server/panel/vhost/openresty/ssl/"+website.Name+".key", "", 0644) - helpers.ExecShellAsync("systemctl reload openresty") + helper.ExecShellAsync("systemctl reload openresty") // TODO 创建数据库 @@ -236,13 +236,13 @@ func (r *WebsiteImpl) Delete(name string) error { return err } - helpers.RemoveFile("/www/server/panel/vhost/openresty/" + website.Name + ".conf") - helpers.RemoveFile("/www/server/panel/vhost/openresty/rewrite/" + website.Name + ".conf") - helpers.RemoveFile("/www/server/panel/vhost/openresty/ssl/" + website.Name + ".pem") - helpers.RemoveFile("/www/server/panel/vhost/openresty/ssl/" + website.Name + ".key") - helpers.RemoveFile(website.Path) + helper.RemoveFile("/www/server/panel/vhost/openresty/" + website.Name + ".conf") + helper.RemoveFile("/www/server/panel/vhost/openresty/rewrite/" + website.Name + ".conf") + helper.RemoveFile("/www/server/panel/vhost/openresty/ssl/" + website.Name + ".pem") + helper.RemoveFile("/www/server/panel/vhost/openresty/ssl/" + website.Name + ".key") + helper.RemoveFile(website.Path) - helpers.ExecShellAsync("systemctl reload openresty") + helper.ExecShellAsync("systemctl reload openresty") // TODO 删除数据库 diff --git a/packages/helpers/helpers.go b/packages/helper/helpers.go similarity index 98% rename from packages/helpers/helpers.go rename to packages/helper/helpers.go index 940e117b..12c4d62c 100644 --- a/packages/helpers/helpers.go +++ b/packages/helper/helpers.go @@ -1,5 +1,5 @@ -// Package helpers 存放辅助方法 -package helpers +// Package helper 存放辅助方法 +package helper import ( "errors" diff --git a/packages/helpers/helpers_test.go b/packages/helper/helpers_test.go similarity index 94% rename from packages/helpers/helpers_test.go rename to packages/helper/helpers_test.go index ba78a7fa..70248436 100644 --- a/packages/helpers/helpers_test.go +++ b/packages/helper/helpers_test.go @@ -1,4 +1,4 @@ -package helpers +package helper import ( "testing" diff --git a/packages/helpers/os.go b/packages/helper/os.go similarity index 95% rename from packages/helpers/os.go rename to packages/helper/os.go index 9f7c2610..6cea4fcb 100644 --- a/packages/helpers/os.go +++ b/packages/helper/os.go @@ -1,4 +1,4 @@ -package helpers +package helper import ( "os" diff --git a/packages/helpers/os_test.go b/packages/helper/os_test.go similarity index 96% rename from packages/helpers/os_test.go rename to packages/helper/os_test.go index 10e1fdf8..888597ee 100644 --- a/packages/helpers/os_test.go +++ b/packages/helper/os_test.go @@ -1,4 +1,4 @@ -package helpers +package helper import ( "testing" diff --git a/packages/helpers/string.go b/packages/helper/string.go similarity index 99% rename from packages/helpers/string.go rename to packages/helper/string.go index 0743d75b..fb0f6a32 100644 --- a/packages/helpers/string.go +++ b/packages/helper/string.go @@ -1,4 +1,4 @@ -package helpers +package helper import ( "crypto/md5" diff --git a/packages/helpers/string_test.go b/packages/helper/string_test.go similarity index 99% rename from packages/helpers/string_test.go rename to packages/helper/string_test.go index 40a61205..98144ea3 100644 --- a/packages/helpers/string_test.go +++ b/packages/helper/string_test.go @@ -1,4 +1,4 @@ -package helpers +package helper import ( "testing" diff --git a/packages/helpers/system.go b/packages/helper/system.go similarity index 99% rename from packages/helpers/system.go rename to packages/helper/system.go index 14078ebd..23ce067d 100644 --- a/packages/helpers/system.go +++ b/packages/helper/system.go @@ -1,4 +1,4 @@ -package helpers +package helper import ( "os" diff --git a/packages/helpers/system_test.go b/packages/helper/system_test.go similarity index 99% rename from packages/helpers/system_test.go rename to packages/helper/system_test.go index e6a1bea5..6698d797 100644 --- a/packages/helpers/system_test.go +++ b/packages/helper/system_test.go @@ -1,4 +1,4 @@ -package helpers +package helper import ( "os" diff --git a/public/panel/config.js b/public/panel/config.js index 89d6e0ca..58f8432d 100644 --- a/public/panel/config.js +++ b/public/panel/config.js @@ -40,7 +40,9 @@ layui.define(['all'], function (exports) { }, // 独立页面路由,可随意添加(无需写参数) - indPage: ['/login', // 登入页 + indPage: [ + '/login', + '/logout', ], // 配置业务模块目录中的特殊模块 diff --git a/public/panel/views/login.html b/public/panel/views/login.html index 23bc8cc1..f016d1cb 100644 --- a/public/panel/views/login.html +++ b/public/panel/views/login.html @@ -85,8 +85,7 @@ * 所以这里强制刷新到主页 * location.hash = search.redirect ? decodeURIComponent(search.redirect) : '/'; */ - //location.href = '/'; - location.hash = search.redirect ? decodeURIComponent(search.redirect) : '/'; + location.href = '/'; }); } }); diff --git a/routes/plugin.go b/routes/plugin.go index 58fdd176..70318f9c 100644 --- a/routes/plugin.go +++ b/routes/plugin.go @@ -6,6 +6,7 @@ import ( "panel/app/http/controllers/plugins/mysql80" "panel/app/http/controllers/plugins/openresty" + "panel/app/http/controllers/plugins/php74" "panel/app/http/middleware" ) @@ -53,4 +54,22 @@ func Plugin() { route.Post("setUserPassword", mysql80Controller.SetUserPassword) route.Post("setUserPrivileges", mysql80Controller.SetUserPrivileges) }) + facades.Route().Prefix("api/plugins/php74").Middleware(middleware.Jwt()).Group(func(route route.Route) { + php74Controller := php74.NewPhp74Controller() + route.Get("status", php74Controller.Status) + route.Post("reload", php74Controller.Reload) + route.Post("start", php74Controller.Start) + route.Post("stop", php74Controller.Stop) + route.Post("restart", php74Controller.Restart) + route.Get("load", php74Controller.Load) + route.Get("config", php74Controller.GetConfig) + route.Post("config", php74Controller.SaveConfig) + route.Get("errorLog", php74Controller.ErrorLog) + route.Get("slowLog", php74Controller.SlowLog) + route.Get("clearErrorLog", php74Controller.ClearErrorLog) + route.Get("clearSlowLog", php74Controller.ClearSlowLog) + route.Get("extensions", php74Controller.GetExtensionList) + route.Post("installExtension", php74Controller.InstallExtension) + route.Post("uninstallExtension", php74Controller.UninstallExtension) + }) }