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

refactor: 重命名软件包名

This commit is contained in:
耗子
2024-05-29 21:31:01 +08:00
parent ca504e1acc
commit 1fbea148e3
82 changed files with 395 additions and 395 deletions

View File

@@ -10,9 +10,9 @@ import (
"github.com/goravel/framework/facades"
"github.com/goravel/framework/support/carbon"
"panel/app/models"
"panel/internal"
"panel/internal/services"
"github.com/TheTNB/panel/app/models"
"github.com/TheTNB/panel/internal"
"github.com/TheTNB/panel/internal/services"
)
// CertRenew 证书续签

View File

@@ -4,17 +4,17 @@ import (
"context"
"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"
"github.com/goravel/framework/support/color"
"github.com/spf13/cast"
"panel/app/models"
"panel/internal"
"panel/internal/services"
"panel/pkg/tools"
"github.com/TheTNB/panel/app/models"
"github.com/TheTNB/panel/internal"
"github.com/TheTNB/panel/internal/services"
"github.com/TheTNB/panel/pkg/tools"
)
// Monitoring 系统监控
@@ -77,7 +77,7 @@ func (receiver *Monitoring) Handle(console.Context) error {
})
if err != nil {
facades.Log().Infof("[面板] 系统监控保存失败: %s", err.Error())
color.Redf(translate.Get("commands.panel:monitoring.fail")+": %s", err.Error())
color.Red().Printfln(translate.Get("commands.panel:monitoring.fail")+": %s", err.Error())
return nil
}

View File

@@ -8,17 +8,17 @@ import (
"sort"
"strings"
"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"
"github.com/goravel/framework/support/color"
"github.com/spf13/cast"
"panel/app/models"
"panel/internal"
"panel/internal/services"
"panel/pkg/tools"
"github.com/TheTNB/panel/app/models"
"github.com/TheTNB/panel/internal"
"github.com/TheTNB/panel/internal/services"
"github.com/TheTNB/panel/pkg/tools"
)
// Panel 面板命令行
@@ -59,69 +59,69 @@ func (receiver *Panel) Handle(ctx console.Context) error {
var check models.User
err := facades.Orm().Query().FirstOrFail(&check)
if err == nil {
color.Redln(translate.Get("commands.panel.init.exist"))
color.Red().Printfln(translate.Get("commands.panel.init.exist"))
return nil
}
settings := []models.Setting{{Key: models.SettingKeyName, Value: "耗子 Linux 面板"}, {Key: models.SettingKeyMonitor, Value: "1"}, {Key: models.SettingKeyMonitorDays, Value: "30"}, {Key: models.SettingKeyBackupPath, Value: "/www/backup"}, {Key: models.SettingKeyWebsitePath, Value: "/www/wwwroot"}, {Key: models.SettingKeyVersion, Value: facades.Config().GetString("panel.version")}}
err = facades.Orm().Query().Create(&settings)
if err != nil {
color.Redln(translate.Get("commands.panel.init.fail"))
color.Red().Printfln(translate.Get("commands.panel.init.fail"))
return nil
}
hash, err := facades.Hash().Make(tools.RandomString(32))
if err != nil {
color.Redln(translate.Get("commands.panel.init.fail"))
color.Red().Printfln(translate.Get("commands.panel.init.fail"))
return nil
}
user := services.NewUserImpl()
_, err = user.Create("admin", hash)
if err != nil {
color.Redln(translate.Get("commands.panel.init.adminFail"))
color.Red().Printfln(translate.Get("commands.panel.init.adminFail"))
return nil
}
color.Greenln(translate.Get("commands.panel.init.success"))
color.Green().Printfln(translate.Get("commands.panel.init.success"))
case "update":
var task models.Task
err := facades.Orm().Query().Where("status", models.TaskStatusRunning).OrWhere("status", models.TaskStatusWaiting).FirstOrFail(&task)
if err == nil {
color.Redln(translate.Get("commands.panel.update.taskCheck"))
color.Red().Printfln(translate.Get("commands.panel.update.taskCheck"))
return nil
}
panel, err := tools.GetLatestPanelVersion()
if err != nil {
color.Redln(translate.Get("commands.panel.update.versionFail"))
color.Red().Printfln(translate.Get("commands.panel.update.versionFail"))
return err
}
internal.Status = internal.StatusUpgrade
if err = tools.UpdatePanel(panel); err != nil {
internal.Status = internal.StatusFailed
color.Redln(translate.Get("commands.panel.update.fail") + ": " + err.Error())
color.Red().Printfln(translate.Get("commands.panel.update.fail") + ": " + err.Error())
return nil
}
internal.Status = internal.StatusNormal
color.Greenln(translate.Get("commands.panel.update.success"))
color.Green().Printfln(translate.Get("commands.panel.update.success"))
tools.RestartPanel()
case "getInfo":
var user models.User
err := facades.Orm().Query().Where("id", 1).FirstOrFail(&user)
if err != nil {
color.Redln(translate.Get("commands.panel.getInfo.adminGetFail"))
color.Red().Printfln(translate.Get("commands.panel.getInfo.adminGetFail"))
return nil
}
password := tools.RandomString(16)
hash, err := facades.Hash().Make(password)
if err != nil {
color.Redln(translate.Get("commands.panel.getInfo.passwordGenerationFail"))
color.Red().Printfln(translate.Get("commands.panel.getInfo.passwordGenerationFail"))
return nil
}
user.Username = tools.RandomString(8)
@@ -132,13 +132,13 @@ func (receiver *Panel) Handle(ctx console.Context) error {
err = facades.Orm().Query().Save(&user)
if err != nil {
color.Redln(translate.Get("commands.panel.getInfo.adminSaveFail"))
color.Red().Printfln(translate.Get("commands.panel.getInfo.adminSaveFail"))
return nil
}
port, err := tools.Exec(`cat /www/panel/panel.conf | grep APP_PORT | awk -F '=' '{print $2}' | tr -d '\n'`)
if err != nil {
color.Redln(translate.Get("commands.panel.portFail"))
color.Red().Printfln(translate.Get("commands.panel.portFail"))
return nil
}
ip, err := tools.GetPublicIP()
@@ -150,42 +150,42 @@ func (receiver *Panel) Handle(ctx console.Context) error {
protocol = "https"
}
color.Greenln(translate.Get("commands.panel.getInfo.username") + ": " + user.Username)
color.Greenln(translate.Get("commands.panel.getInfo.password") + ": " + password)
color.Greenln(translate.Get("commands.panel.port") + ": " + port)
color.Greenln(translate.Get("commands.panel.entrance") + ": " + facades.Config().GetString("http.entrance"))
color.Greenln(translate.Get("commands.panel.getInfo.address") + ": " + protocol + "://" + ip + ":" + port + facades.Config().GetString("http.entrance"))
color.Green().Printfln(translate.Get("commands.panel.getInfo.username") + ": " + user.Username)
color.Green().Printfln(translate.Get("commands.panel.getInfo.password") + ": " + password)
color.Green().Printfln(translate.Get("commands.panel.port") + ": " + port)
color.Green().Printfln(translate.Get("commands.panel.entrance") + ": " + facades.Config().GetString("http.entrance"))
color.Green().Printfln(translate.Get("commands.panel.getInfo.address") + ": " + protocol + "://" + ip + ":" + port + facades.Config().GetString("http.entrance"))
case "getPort":
port, err := tools.Exec(`cat /www/panel/panel.conf | grep APP_PORT | awk -F '=' '{print $2}' | tr -d '\n'`)
if err != nil {
color.Redln(translate.Get("commands.panel.portFail"))
color.Red().Printfln(translate.Get("commands.panel.portFail"))
return nil
}
color.Greenln(translate.Get("commands.panel.port") + ": " + port)
color.Green().Printfln(translate.Get("commands.panel.port") + ": " + port)
case "getEntrance":
color.Greenln(translate.Get("commands.panel.entrance") + ": " + facades.Config().GetString("http.entrance"))
color.Green().Printfln(translate.Get("commands.panel.entrance") + ": " + facades.Config().GetString("http.entrance"))
case "deleteEntrance":
oldEntrance, err := tools.Exec(`cat /www/panel/panel.conf | grep APP_ENTRANCE | awk -F '=' '{print $2}' | tr -d '\n'`)
if err != nil {
color.Redln(translate.Get("commands.panel.deleteEntrance.fail"))
color.Red().Printfln(translate.Get("commands.panel.deleteEntrance.fail"))
return nil
}
if _, err = tools.Exec("sed -i 's!APP_ENTRANCE=" + oldEntrance + "!APP_ENTRANCE=/!g' /www/panel/panel.conf"); err != nil {
color.Redln(translate.Get("commands.panel.deleteEntrance.fail"))
color.Red().Printfln(translate.Get("commands.panel.deleteEntrance.fail"))
return nil
}
color.Greenln(translate.Get("commands.panel.deleteEntrance.success"))
color.Green().Printfln(translate.Get("commands.panel.deleteEntrance.success"))
case "writePlugin":
slug := arg1
version := arg2
if len(slug) == 0 || len(version) == 0 {
color.Redln(translate.Get("commands.panel.writePlugin.paramFail"))
color.Red().Printfln(translate.Get("commands.panel.writePlugin.paramFail"))
return nil
}
@@ -197,31 +197,31 @@ func (receiver *Panel) Handle(ctx console.Context) error {
})
if err != nil {
color.Redln(translate.Get("commands.panel.writePlugin.fail"))
color.Red().Printfln(translate.Get("commands.panel.writePlugin.fail"))
return nil
}
color.Greenln(translate.Get("commands.panel.writePlugin.success"))
color.Green().Printfln(translate.Get("commands.panel.writePlugin.success"))
case "deletePlugin":
slug := arg1
if len(slug) == 0 {
color.Redln(translate.Get("commands.panel.deletePlugin.paramFail"))
color.Red().Printfln(translate.Get("commands.panel.deletePlugin.paramFail"))
return nil
}
_, err := facades.Orm().Query().Where("slug", slug).Delete(&models.Plugin{})
if err != nil {
color.Redln(translate.Get("commands.panel.deletePlugin.fail"))
color.Red().Printfln(translate.Get("commands.panel.deletePlugin.fail"))
return nil
}
color.Greenln(translate.Get("commands.panel.deletePlugin.success"))
color.Green().Printfln(translate.Get("commands.panel.deletePlugin.success"))
case "writeMysqlPassword":
password := arg1
if len(password) == 0 {
color.Redln(translate.Get("commands.panel.writeMysqlPassword.paramFail"))
color.Red().Printfln(translate.Get("commands.panel.writeMysqlPassword.paramFail"))
return nil
}
@@ -233,20 +233,20 @@ func (receiver *Panel) Handle(ctx console.Context) error {
})
if err != nil {
color.Redln(translate.Get("commands.panel.writeMysqlPassword.fail"))
color.Red().Printfln(translate.Get("commands.panel.writeMysqlPassword.fail"))
return nil
}
color.Greenln(translate.Get("commands.panel.writeMysqlPassword.success"))
color.Green().Printfln(translate.Get("commands.panel.writeMysqlPassword.success"))
case "cleanTask":
_, err := facades.Orm().Query().Model(&models.Task{}).Where("status", models.TaskStatusRunning).OrWhere("status", models.TaskStatusWaiting).Update("status", models.TaskStatusFailed)
if err != nil {
color.Redln(translate.Get("commands.panel.cleanTask.fail"))
color.Red().Printfln(translate.Get("commands.panel.cleanTask.fail"))
return nil
}
color.Greenln(translate.Get("commands.panel.cleanTask.success"))
color.Green().Printfln(translate.Get("commands.panel.cleanTask.success"))
case "backup":
backupType := arg1
@@ -255,37 +255,37 @@ func (receiver *Panel) Handle(ctx console.Context) error {
save := arg4
hr := `+----------------------------------------------------`
if len(backupType) == 0 || len(name) == 0 || len(path) == 0 || len(save) == 0 {
color.Redln(translate.Get("commands.panel.backup.paramFail"))
color.Red().Printfln(translate.Get("commands.panel.backup.paramFail"))
return nil
}
color.Greenln(hr)
color.Greenln("★ " + translate.Get("commands.panel.backup.start") + " [" + carbon.Now().ToDateTimeString() + "]")
color.Greenln(hr)
color.Green().Printfln(hr)
color.Green().Printfln("★ " + translate.Get("commands.panel.backup.start") + " [" + carbon.Now().ToDateTimeString() + "]")
color.Green().Printfln(hr)
if !tools.Exists(path) {
if err := tools.Mkdir(path, 0644); err != nil {
color.Redln("|-" + translate.Get("commands.panel.backup.backupDirFail") + ": " + err.Error())
color.Red().Printfln("|-" + translate.Get("commands.panel.backup.backupDirFail") + ": " + err.Error())
return nil
}
}
switch backupType {
case "website":
color.Yellowln("|-" + translate.Get("commands.panel.backup.targetSite") + ": " + name)
color.Yellow().Printfln("|-" + translate.Get("commands.panel.backup.targetSite") + ": " + name)
var website models.Website
if err := facades.Orm().Query().Where("name", name).FirstOrFail(&website); err != nil {
color.Redln("|-" + translate.Get("commands.panel.backup.siteNotExist"))
color.Greenln(hr)
color.Red().Printfln("|-" + translate.Get("commands.panel.backup.siteNotExist"))
color.Green().Printfln(hr)
return nil
}
backupFile := path + "/" + website.Name + "_" + carbon.Now().ToShortDateTimeString() + ".zip"
if _, err := tools.Exec(`cd '` + website.Path + `' && zip -r '` + backupFile + `' .`); err != nil {
color.Redln("|-" + translate.Get("commands.panel.backup.backupFail") + ": " + err.Error())
color.Red().Printfln("|-" + translate.Get("commands.panel.backup.backupFail") + ": " + err.Error())
return nil
}
color.Greenln("|-" + translate.Get("commands.panel.backup.backupSuccess"))
color.Green().Printfln("|-" + translate.Get("commands.panel.backup.backupSuccess"))
case "mysql":
rootPassword := services.NewSettingImpl().Get(models.SettingKeyMysqlRootPassword)
@@ -293,81 +293,81 @@ func (receiver *Panel) Handle(ctx console.Context) error {
err := os.Setenv("MYSQL_PWD", rootPassword)
if err != nil {
color.Redln("|-" + translate.Get("commands.panel.backup.mysqlBackupFail") + ": " + err.Error())
color.Greenln(hr)
color.Red().Printfln("|-" + translate.Get("commands.panel.backup.mysqlBackupFail") + ": " + err.Error())
color.Green().Printfln(hr)
return nil
}
color.Greenln("|-" + translate.Get("commands.panel.backup.targetMysql") + ": " + name)
color.Greenln("|-" + translate.Get("commands.panel.backup.startExport"))
color.Green().Printfln("|-" + translate.Get("commands.panel.backup.targetMysql") + ": " + name)
color.Green().Printfln("|-" + translate.Get("commands.panel.backup.startExport"))
if _, err = tools.Exec(`mysqldump -uroot ` + name + ` > /tmp/` + backupFile + ` 2>&1`); err != nil {
color.Redln("|-" + translate.Get("commands.panel.backup.exportFail") + ": " + err.Error())
color.Red().Printfln("|-" + translate.Get("commands.panel.backup.exportFail") + ": " + err.Error())
return nil
}
color.Greenln("|-" + translate.Get("commands.panel.backup.exportSuccess"))
color.Greenln("|-" + translate.Get("commands.panel.backup.startCompress"))
color.Green().Printfln("|-" + translate.Get("commands.panel.backup.exportSuccess"))
color.Green().Printfln("|-" + translate.Get("commands.panel.backup.startCompress"))
if _, err = tools.Exec("cd /tmp && zip -r " + backupFile + ".zip " + backupFile); err != nil {
color.Redln("|-" + translate.Get("commands.panel.backup.compressFail") + ": " + err.Error())
color.Red().Printfln("|-" + translate.Get("commands.panel.backup.compressFail") + ": " + err.Error())
return nil
}
if err := tools.Remove("/tmp/" + backupFile); err != nil {
color.Redln("|-" + translate.Get("commands.panel.backup.deleteFail") + ": " + err.Error())
color.Red().Printfln("|-" + translate.Get("commands.panel.backup.deleteFail") + ": " + err.Error())
return nil
}
color.Greenln("|-" + translate.Get("commands.panel.backup.compressSuccess"))
color.Greenln("|-" + translate.Get("commands.panel.backup.startMove"))
color.Green().Printfln("|-" + translate.Get("commands.panel.backup.compressSuccess"))
color.Green().Printfln("|-" + translate.Get("commands.panel.backup.startMove"))
if err := tools.Mv("/tmp/"+backupFile+".zip", path+"/"+backupFile+".zip"); err != nil {
color.Redln("|-" + translate.Get("commands.panel.backup.moveFail") + ": " + err.Error())
color.Red().Printfln("|-" + translate.Get("commands.panel.backup.moveFail") + ": " + err.Error())
return nil
}
color.Greenln("|-" + translate.Get("commands.panel.backup.moveSuccess"))
color.Green().Printfln("|-" + translate.Get("commands.panel.backup.moveSuccess"))
_ = os.Unsetenv("MYSQL_PWD")
color.Greenln("|-" + translate.Get("commands.panel.backup.success"))
color.Green().Printfln("|-" + translate.Get("commands.panel.backup.success"))
case "postgresql":
backupFile := name + "_" + carbon.Now().ToShortDateTimeString() + ".sql"
check, err := tools.Exec(`su - postgres -c "psql -l" 2>&1`)
if err != nil {
color.Redln("|-" + translate.Get("commands.panel.backup.databaseGetFail") + ": " + err.Error())
color.Greenln(hr)
color.Red().Printfln("|-" + translate.Get("commands.panel.backup.databaseGetFail") + ": " + err.Error())
color.Green().Printfln(hr)
return nil
}
if !strings.Contains(check, name) {
color.Redln("|-" + translate.Get("commands.panel.backup.databaseNotExist"))
color.Greenln(hr)
color.Red().Printfln("|-" + translate.Get("commands.panel.backup.databaseNotExist"))
color.Green().Printfln(hr)
return nil
}
color.Greenln("|-" + translate.Get("commands.panel.backup.targetPostgres") + ": " + name)
color.Greenln("|-" + translate.Get("commands.panel.backup.startExport"))
color.Green().Printfln("|-" + translate.Get("commands.panel.backup.targetPostgres") + ": " + name)
color.Green().Printfln("|-" + translate.Get("commands.panel.backup.startExport"))
if _, err = tools.Exec(`su - postgres -c "pg_dump '` + name + `'" > /tmp/` + backupFile + ` 2>&1`); err != nil {
color.Redln("|-" + translate.Get("commands.panel.backup.exportFail") + ": " + err.Error())
color.Red().Printfln("|-" + translate.Get("commands.panel.backup.exportFail") + ": " + err.Error())
return nil
}
color.Greenln("|-" + translate.Get("commands.panel.backup.exportSuccess"))
color.Greenln("|-" + translate.Get("commands.panel.backup.startCompress"))
color.Green().Printfln("|-" + translate.Get("commands.panel.backup.exportSuccess"))
color.Green().Printfln("|-" + translate.Get("commands.panel.backup.startCompress"))
if _, err = tools.Exec("cd /tmp && zip -r " + backupFile + ".zip " + backupFile); err != nil {
color.Redln("|-" + translate.Get("commands.panel.backup.compressFail") + ": " + err.Error())
color.Red().Printfln("|-" + translate.Get("commands.panel.backup.compressFail") + ": " + err.Error())
return nil
}
if err := tools.Remove("/tmp/" + backupFile); err != nil {
color.Redln("|-" + translate.Get("commands.panel.backup.deleteFail") + ": " + err.Error())
color.Red().Printfln("|-" + translate.Get("commands.panel.backup.deleteFail") + ": " + err.Error())
return nil
}
color.Greenln("|-" + translate.Get("commands.panel.backup.compressSuccess"))
color.Greenln("|-" + translate.Get("commands.panel.backup.startMove"))
color.Green().Printfln("|-" + translate.Get("commands.panel.backup.compressSuccess"))
color.Green().Printfln("|-" + translate.Get("commands.panel.backup.startMove"))
if err := tools.Mv("/tmp/"+backupFile+".zip", path+"/"+backupFile+".zip"); err != nil {
color.Redln("|-" + translate.Get("commands.panel.backup.moveFail") + ": " + err.Error())
color.Red().Printfln("|-" + translate.Get("commands.panel.backup.moveFail") + ": " + err.Error())
return nil
}
color.Greenln("|-" + translate.Get("commands.panel.backup.moveSuccess"))
color.Greenln("|-" + translate.Get("commands.panel.backup.success"))
color.Green().Printfln("|-" + translate.Get("commands.panel.backup.moveSuccess"))
color.Green().Printfln("|-" + translate.Get("commands.panel.backup.success"))
}
color.Greenln(hr)
color.Green().Printfln(hr)
files, err := os.ReadDir(path)
if err != nil {
color.Redln("|-" + translate.Get("commands.panel.backup.cleanupFail") + ": " + err.Error())
color.Red().Printfln("|-" + translate.Get("commands.panel.backup.cleanupFail") + ": " + err.Error())
return nil
}
var filteredFiles []os.FileInfo
@@ -385,60 +385,60 @@ func (receiver *Panel) Handle(ctx console.Context) error {
})
for i := cast.ToInt(save); i < len(filteredFiles); i++ {
fileToDelete := filepath.Join(path, filteredFiles[i].Name())
color.Yellowln("|-" + translate.Get("commands.panel.backup.cleanBackup") + ": " + fileToDelete)
color.Yellow().Printfln("|-" + translate.Get("commands.panel.backup.cleanBackup") + ": " + fileToDelete)
if err := tools.Remove(fileToDelete); err != nil {
color.Redln("|-" + translate.Get("commands.panel.backup.cleanupFail") + ": " + err.Error())
color.Red().Printfln("|-" + translate.Get("commands.panel.backup.cleanupFail") + ": " + err.Error())
return nil
}
}
color.Greenln("|-" + translate.Get("commands.panel.backup.cleanupSuccess"))
color.Greenln(hr)
color.Greenln("☆ " + translate.Get("commands.panel.backup.success") + " [" + carbon.Now().ToDateTimeString() + "]")
color.Greenln(hr)
color.Green().Printfln("|-" + translate.Get("commands.panel.backup.cleanupSuccess"))
color.Green().Printfln(hr)
color.Green().Printfln("☆ " + translate.Get("commands.panel.backup.success") + " [" + carbon.Now().ToDateTimeString() + "]")
color.Green().Printfln(hr)
case "cutoff":
name := arg1
save := arg2
hr := `+----------------------------------------------------`
if len(name) == 0 || len(save) == 0 {
color.Redln(translate.Get("commands.panel.cutoff.paramFail"))
color.Red().Printfln(translate.Get("commands.panel.cutoff.paramFail"))
return nil
}
color.Greenln(hr)
color.Greenln("★ " + translate.Get("commands.panel.cutoff.start") + " [" + carbon.Now().ToDateTimeString() + "]")
color.Greenln(hr)
color.Green().Printfln(hr)
color.Green().Printfln("★ " + translate.Get("commands.panel.cutoff.start") + " [" + carbon.Now().ToDateTimeString() + "]")
color.Green().Printfln(hr)
color.Yellowln("|-" + translate.Get("commands.panel.cutoff.targetSite") + ": " + name)
color.Yellow().Printfln("|-" + translate.Get("commands.panel.cutoff.targetSite") + ": " + name)
var website models.Website
if err := facades.Orm().Query().Where("name", name).FirstOrFail(&website); err != nil {
color.Redln("|-" + translate.Get("commands.panel.cutoff.siteNotExist"))
color.Greenln(hr)
color.Red().Printfln("|-" + translate.Get("commands.panel.cutoff.siteNotExist"))
color.Green().Printfln(hr)
return nil
}
logPath := "/www/wwwlogs/" + website.Name + ".log"
if !tools.Exists(logPath) {
color.Redln("|-" + translate.Get("commands.panel.cutoff.logNotExist"))
color.Greenln(hr)
color.Red().Printfln("|-" + translate.Get("commands.panel.cutoff.logNotExist"))
color.Green().Printfln(hr)
return nil
}
backupPath := "/www/wwwlogs/" + website.Name + "_" + carbon.Now().ToShortDateTimeString() + ".log.zip"
if _, err := tools.Exec(`cd /www/wwwlogs && zip -r ` + backupPath + ` ` + website.Name + ".log"); err != nil {
color.Redln("|-" + translate.Get("commands.panel.cutoff.backupFail") + ": " + err.Error())
color.Red().Printfln("|-" + translate.Get("commands.panel.cutoff.backupFail") + ": " + err.Error())
return nil
}
if _, err := tools.Exec(`echo "" > ` + logPath); err != nil {
color.Redln("|-" + translate.Get("commands.panel.cutoff.clearFail") + ": " + err.Error())
color.Red().Printfln("|-" + translate.Get("commands.panel.cutoff.clearFail") + ": " + err.Error())
return nil
}
color.Greenln("|-" + translate.Get("commands.panel.cutoff.cutSuccess"))
color.Green().Printfln("|-" + translate.Get("commands.panel.cutoff.cutSuccess"))
color.Greenln(hr)
color.Green().Printfln(hr)
files, err := os.ReadDir("/www/wwwlogs")
if err != nil {
color.Redln("|-" + translate.Get("commands.panel.cutoff.cleanupFail") + ": " + err.Error())
color.Red().Printfln("|-" + translate.Get("commands.panel.cutoff.cleanupFail") + ": " + err.Error())
return nil
}
var filteredFiles []os.FileInfo
@@ -456,16 +456,16 @@ func (receiver *Panel) Handle(ctx console.Context) error {
})
for i := cast.ToInt(save); i < len(filteredFiles); i++ {
fileToDelete := filepath.Join("/www/wwwlogs", filteredFiles[i].Name())
color.Yellowln("|-" + translate.Get("commands.panel.cutoff.clearLog") + ": " + fileToDelete)
color.Yellow().Printfln("|-" + translate.Get("commands.panel.cutoff.clearLog") + ": " + fileToDelete)
if err := tools.Remove(fileToDelete); err != nil {
color.Redln("|-" + translate.Get("commands.panel.cutoff.cleanupFail") + ": " + err.Error())
color.Red().Printfln("|-" + translate.Get("commands.panel.cutoff.cleanupFail") + ": " + err.Error())
return nil
}
}
color.Greenln("|-" + translate.Get("commands.panel.cutoff.cleanupSuccess"))
color.Greenln(hr)
color.Greenln("☆ " + translate.Get("commands.panel.cutoff.end") + " [" + carbon.Now().ToDateTimeString() + "]")
color.Greenln(hr)
color.Green().Printfln("|-" + translate.Get("commands.panel.cutoff.cleanupSuccess"))
color.Green().Printfln(hr)
color.Green().Printfln("☆ " + translate.Get("commands.panel.cutoff.end") + " [" + carbon.Now().ToDateTimeString() + "]")
color.Green().Printfln(hr)
case "writeSite":
name := arg1
@@ -474,19 +474,19 @@ func (receiver *Panel) Handle(ctx console.Context) error {
php := cast.ToInt(arg4)
ssl := cast.ToBool(ctx.Argument(5))
if len(name) == 0 || len(path) == 0 {
color.Redln(translate.Get("commands.panel.writeSite.paramFail"))
color.Red().Printfln(translate.Get("commands.panel.writeSite.paramFail"))
return nil
}
var website models.Website
if err := facades.Orm().Query().Where("name", name).FirstOrFail(&website); err == nil {
color.Redln(translate.Get("commands.panel.writeSite.siteExist"))
color.Red().Printfln(translate.Get("commands.panel.writeSite.siteExist"))
return nil
}
_, err := os.Stat(path)
if os.IsNotExist(err) {
color.Redln(translate.Get("commands.panel.writeSite.pathNotExist"))
color.Red().Printfln(translate.Get("commands.panel.writeSite.pathNotExist"))
return nil
}
@@ -498,32 +498,32 @@ func (receiver *Panel) Handle(ctx console.Context) error {
Ssl: ssl,
})
if err != nil {
color.Redln(translate.Get("commands.panel.writeSite.fail"))
color.Red().Printfln(translate.Get("commands.panel.writeSite.fail"))
return nil
}
color.Greenln(translate.Get("commands.panel.writeSite.success"))
color.Green().Printfln(translate.Get("commands.panel.writeSite.success"))
case "deleteSite":
name := arg1
if len(name) == 0 {
color.Redln(translate.Get("commands.panel.deleteSite.paramFail"))
color.Red().Printfln(translate.Get("commands.panel.deleteSite.paramFail"))
return nil
}
_, err := facades.Orm().Query().Where("name", name).Delete(&models.Website{})
if err != nil {
color.Redln(translate.Get("commands.panel.deleteSite.fail"))
color.Red().Printfln(translate.Get("commands.panel.deleteSite.fail"))
return nil
}
color.Greenln(translate.Get("commands.panel.deleteSite.success"))
color.Green().Printfln(translate.Get("commands.panel.deleteSite.success"))
case "writeSetting":
key := arg1
value := arg2
if len(key) == 0 || len(value) == 0 {
color.Redln(translate.Get("commands.panel.writeSetting.paramFail"))
color.Red().Printfln(translate.Get("commands.panel.writeSetting.paramFail"))
return nil
}
@@ -534,16 +534,16 @@ func (receiver *Panel) Handle(ctx console.Context) error {
Value: value,
})
if err != nil {
color.Redln(translate.Get("commands.panel.writeSetting.fail"))
color.Red().Printfln(translate.Get("commands.panel.writeSetting.fail"))
return nil
}
color.Greenln(translate.Get("commands.panel.writeSetting.success"))
color.Green().Printfln(translate.Get("commands.panel.writeSetting.success"))
case "getSetting":
key := arg1
if len(key) == 0 {
color.Redln(translate.Get("commands.panel.getSetting.paramFail"))
color.Red().Printfln(translate.Get("commands.panel.getSetting.paramFail"))
return nil
}
@@ -557,17 +557,17 @@ func (receiver *Panel) Handle(ctx console.Context) error {
case "deleteSetting":
key := arg1
if len(key) == 0 {
color.Redln(translate.Get("commands.panel.deleteSetting.paramFail"))
color.Red().Printfln(translate.Get("commands.panel.deleteSetting.paramFail"))
return nil
}
_, err := facades.Orm().Query().Where("key", key).Delete(&models.Setting{})
if err != nil {
color.Redln(translate.Get("commands.panel.deleteSetting.fail"))
color.Red().Printfln(translate.Get("commands.panel.deleteSetting.fail"))
return nil
}
color.Greenln(translate.Get("commands.panel.deleteSetting.success"))
color.Green().Printfln(translate.Get("commands.panel.deleteSetting.success"))
case "addSite":
name := arg1
@@ -576,14 +576,14 @@ func (receiver *Panel) Handle(ctx console.Context) error {
path := arg4
php := arg5
if len(name) == 0 || len(domain) == 0 || len(port) == 0 || len(path) == 0 {
color.Redln(translate.Get("commands.panel.addSite.paramFail"))
color.Red().Printfln(translate.Get("commands.panel.addSite.paramFail"))
return nil
}
domains := strings.Split(domain, ",")
ports := strings.Split(port, ",")
if len(domains) == 0 || len(ports) == 0 {
color.Redln(translate.Get("commands.panel.addSite.paramFail"))
color.Red().Printfln(translate.Get("commands.panel.addSite.paramFail"))
return nil
}
@@ -595,11 +595,11 @@ func (receiver *Panel) Handle(ctx console.Context) error {
website := services.NewWebsiteImpl()
id, err := website.GetIDByName(name)
if err != nil {
color.Redln(err.Error())
color.Red().Printfln(err.Error())
return nil
}
if id != 0 {
color.Redln(translate.Get("commands.panel.addSite.siteExist"))
color.Red().Printfln(translate.Get("commands.panel.addSite.siteExist"))
return nil
}
@@ -614,108 +614,108 @@ func (receiver *Panel) Handle(ctx console.Context) error {
Db: false,
})
if err != nil {
color.Redln(err.Error())
color.Red().Printfln(err.Error())
return nil
}
color.Greenln(translate.Get("commands.panel.addSite.success"))
color.Green().Printfln(translate.Get("commands.panel.addSite.success"))
case "removeSite":
name := arg1
if len(name) == 0 {
color.Redln(translate.Get("commands.panel.removeSite.paramFail"))
color.Red().Printfln(translate.Get("commands.panel.removeSite.paramFail"))
return nil
}
website := services.NewWebsiteImpl()
id, err := website.GetIDByName(name)
if err != nil {
color.Redln(err.Error())
color.Red().Printfln(err.Error())
return nil
}
if id == 0 {
color.Redln(translate.Get("commands.panel.removeSite.siteNotExist"))
color.Red().Printfln(translate.Get("commands.panel.removeSite.siteNotExist"))
return nil
}
if err = website.Delete(id); err != nil {
color.Redln(err.Error())
color.Red().Printfln(err.Error())
return nil
}
color.Greenln(translate.Get("commands.panel.removeSite.success"))
color.Green().Printfln(translate.Get("commands.panel.removeSite.success"))
case "installPlugin":
slug := arg1
if len(slug) == 0 {
color.Redln(translate.Get("commands.panel.installPlugin.paramFail"))
color.Red().Printfln(translate.Get("commands.panel.installPlugin.paramFail"))
return nil
}
plugin := services.NewPluginImpl()
if err := plugin.Install(slug); err != nil {
color.Redln(err.Error())
color.Red().Printfln(err.Error())
return nil
}
color.Greenln(translate.Get("commands.panel.installPlugin.success"))
color.Green().Printfln(translate.Get("commands.panel.installPlugin.success"))
case "uninstallPlugin":
slug := arg1
if len(slug) == 0 {
color.Redln(translate.Get("commands.panel.uninstallPlugin.paramFail"))
color.Red().Printfln(translate.Get("commands.panel.uninstallPlugin.paramFail"))
return nil
}
plugin := services.NewPluginImpl()
if err := plugin.Uninstall(slug); err != nil {
color.Redln(err.Error())
color.Red().Printfln(err.Error())
return nil
}
color.Greenln(translate.Get("commands.panel.uninstallPlugin.success"))
color.Green().Printfln(translate.Get("commands.panel.uninstallPlugin.success"))
case "updatePlugin":
slug := arg1
if len(slug) == 0 {
color.Redln(translate.Get("commands.panel.updatePlugin.paramFail"))
color.Red().Printfln(translate.Get("commands.panel.updatePlugin.paramFail"))
return nil
}
plugin := services.NewPluginImpl()
if err := plugin.Update(slug); err != nil {
color.Redln(err.Error())
color.Red().Printfln(err.Error())
return nil
}
color.Greenln(translate.Get("commands.panel.updatePlugin.success"))
color.Green().Printfln(translate.Get("commands.panel.updatePlugin.success"))
default:
color.Yellowln(facades.Config().GetString("panel.name") + " - " + translate.Get("commands.panel.tool") + " - " + facades.Config().GetString("panel.version"))
color.Greenln(translate.Get("commands.panel.use") + "")
color.Greenln("panel update " + translate.Get("commands.panel.update.description"))
color.Greenln("panel getInfo " + translate.Get("commands.panel.getInfo.description"))
color.Greenln("panel getPort " + translate.Get("commands.panel.getPort.description"))
color.Greenln("panel getEntrance " + translate.Get("commands.panel.getEntrance.description"))
color.Greenln("panel deleteEntrance " + translate.Get("commands.panel.deleteEntrance.description"))
color.Greenln("panel cleanTask " + translate.Get("commands.panel.cleanTask.description"))
color.Greenln("panel backup {website/mysql/postgresql} {name} {path} {save_copies} " + translate.Get("commands.panel.backup.description"))
color.Greenln("panel cutoff {website_name} {save_copies} " + translate.Get("commands.panel.cutoff.description"))
color.Greenln("panel installPlugin {slug} " + translate.Get("commands.panel.installPlugin.description"))
color.Greenln("panel uninstallPlugin {slug} " + translate.Get("commands.panel.uninstallPlugin.description"))
color.Greenln("panel updatePlugin {slug} " + translate.Get("commands.panel.updatePlugin.description"))
color.Greenln("panel addSite {name} {domain} {port} {path} {php} " + translate.Get("commands.panel.addSite.description"))
color.Greenln("panel removeSite {name} " + translate.Get("commands.panel.removeSite.description"))
color.Redln(translate.Get("commands.panel.forDeveloper") + ":")
color.Yellowln("panel init " + translate.Get("commands.panel.init.description"))
color.Yellowln("panel writePlugin {slug} {version} " + translate.Get("commands.panel.writePlugin.description"))
color.Yellowln("panel deletePlugin {slug} " + translate.Get("commands.panel.deletePlugin.description"))
color.Yellowln("panel writeMysqlPassword {password} " + translate.Get("commands.panel.writeMysqlPassword.description"))
color.Yellowln("panel writeSite {name} {status} {path} {php} {ssl} " + translate.Get("commands.panel.writeSite.description"))
color.Yellowln("panel deleteSite {name} " + translate.Get("commands.panel.deleteSite.description"))
color.Yellowln("panel getSetting {name} " + translate.Get("commands.panel.getSetting.description"))
color.Yellowln("panel writeSetting {name} {value} " + translate.Get("commands.panel.writeSetting.description"))
color.Yellowln("panel deleteSetting {name} " + translate.Get("commands.panel.deleteSetting.description"))
color.Yellow().Printfln(facades.Config().GetString("panel.name") + " - " + translate.Get("commands.panel.tool") + " - " + facades.Config().GetString("panel.version"))
color.Green().Printfln(translate.Get("commands.panel.use") + "")
color.Green().Printfln("panel update " + translate.Get("commands.panel.update.description"))
color.Green().Printfln("panel getInfo " + translate.Get("commands.panel.getInfo.description"))
color.Green().Printfln("panel getPort " + translate.Get("commands.panel.getPort.description"))
color.Green().Printfln("panel getEntrance " + translate.Get("commands.panel.getEntrance.description"))
color.Green().Printfln("panel deleteEntrance " + translate.Get("commands.panel.deleteEntrance.description"))
color.Green().Printfln("panel cleanTask " + translate.Get("commands.panel.cleanTask.description"))
color.Green().Printfln("panel backup {website/mysql/postgresql} {name} {path} {save_copies} " + translate.Get("commands.panel.backup.description"))
color.Green().Printfln("panel cutoff {website_name} {save_copies} " + translate.Get("commands.panel.cutoff.description"))
color.Green().Printfln("panel installPlugin {slug} " + translate.Get("commands.panel.installPlugin.description"))
color.Green().Printfln("panel uninstallPlugin {slug} " + translate.Get("commands.panel.uninstallPlugin.description"))
color.Green().Printfln("panel updatePlugin {slug} " + translate.Get("commands.panel.updatePlugin.description"))
color.Green().Printfln("panel addSite {name} {domain} {port} {path} {php} " + translate.Get("commands.panel.addSite.description"))
color.Green().Printfln("panel removeSite {name} " + translate.Get("commands.panel.removeSite.description"))
color.Red().Printfln(translate.Get("commands.panel.forDeveloper") + ":")
color.Yellow().Printfln("panel init " + translate.Get("commands.panel.init.description"))
color.Yellow().Printfln("panel writePlugin {slug} {version} " + translate.Get("commands.panel.writePlugin.description"))
color.Yellow().Printfln("panel deletePlugin {slug} " + translate.Get("commands.panel.deletePlugin.description"))
color.Yellow().Printfln("panel writeMysqlPassword {password} " + translate.Get("commands.panel.writeMysqlPassword.description"))
color.Yellow().Printfln("panel writeSite {name} {status} {path} {php} {ssl} " + translate.Get("commands.panel.writeSite.description"))
color.Yellow().Printfln("panel deleteSite {name} " + translate.Get("commands.panel.deleteSite.description"))
color.Yellow().Printfln("panel getSetting {name} " + translate.Get("commands.panel.getSetting.description"))
color.Yellow().Printfln("panel writeSetting {name} {value} " + translate.Get("commands.panel.writeSetting.description"))
color.Yellow().Printfln("panel deleteSetting {name} " + translate.Get("commands.panel.deleteSetting.description"))
}
return nil

View File

@@ -8,8 +8,8 @@ import (
"github.com/goravel/framework/facades"
"github.com/goravel/framework/support/carbon"
"panel/internal"
"panel/pkg/tools"
"github.com/TheTNB/panel/internal"
"github.com/TheTNB/panel/pkg/tools"
)
// PanelTask 面板每日任务

View File

@@ -5,7 +5,7 @@ import (
"github.com/goravel/framework/contracts/schedule"
"github.com/goravel/framework/facades"
"panel/app/console/commands"
"github.com/TheTNB/panel/app/console/commands"
)
type Kernel struct {

View File

@@ -7,9 +7,9 @@ import (
"github.com/goravel/framework/contracts/http"
"github.com/goravel/framework/facades"
"panel/internal"
"panel/internal/services"
"panel/pkg/tools"
"github.com/TheTNB/panel/internal"
"github.com/TheTNB/panel/internal/services"
"github.com/TheTNB/panel/pkg/tools"
)
type AssetController struct {

View File

@@ -4,12 +4,12 @@ import (
"github.com/goravel/framework/contracts/http"
"github.com/goravel/framework/facades"
requests "panel/app/http/requests/cert"
commonrequests "panel/app/http/requests/common"
"panel/app/models"
"panel/internal"
"panel/internal/services"
"panel/pkg/acme"
requests "github.com/TheTNB/panel/app/http/requests/cert"
commonrequests "github.com/TheTNB/panel/app/http/requests/common"
"github.com/TheTNB/panel/app/models"
"github.com/TheTNB/panel/internal"
"github.com/TheTNB/panel/internal/services"
"github.com/TheTNB/panel/pkg/acme"
)
type CertController struct {

View File

@@ -5,6 +5,7 @@ import (
"strconv"
"strings"
"github.com/TheTNB/panel/pkg/tools"
"github.com/docker/docker/api/types"
"github.com/docker/docker/api/types/container"
"github.com/docker/docker/api/types/image"
@@ -13,11 +14,10 @@ import (
"github.com/docker/go-connections/nat"
"github.com/goravel/framework/contracts/http"
"github.com/goravel/framework/support/carbon"
"panel/pkg/tools"
commonrequests "panel/app/http/requests/common"
requests "panel/app/http/requests/container"
"panel/internal/services"
commonrequests "github.com/TheTNB/panel/app/http/requests/common"
requests "github.com/TheTNB/panel/app/http/requests/container"
"github.com/TheTNB/panel/internal/services"
)
type ContainerController struct {

View File

@@ -9,10 +9,10 @@ import (
"github.com/goravel/framework/support/carbon"
"github.com/spf13/cast"
"panel/app/models"
"panel/internal"
"panel/internal/services"
"panel/pkg/tools"
"github.com/TheTNB/panel/app/models"
"github.com/TheTNB/panel/internal"
"github.com/TheTNB/panel/internal/services"
"github.com/TheTNB/panel/pkg/tools"
)
type CronController struct {

View File

@@ -8,12 +8,12 @@ import (
"strings"
"syscall"
commonrequests "github.com/TheTNB/panel/app/http/requests/common"
"github.com/goravel/framework/contracts/http"
"github.com/goravel/framework/support/carbon"
commonrequests "panel/app/http/requests/common"
requests "panel/app/http/requests/file"
"panel/pkg/tools"
requests "github.com/TheTNB/panel/app/http/requests/file"
"github.com/TheTNB/panel/pkg/tools"
)
type FileController struct {

View File

@@ -9,10 +9,10 @@ import (
"github.com/goravel/framework/contracts/http"
"github.com/goravel/framework/facades"
"panel/app/models"
"panel/internal"
"panel/internal/services"
"panel/pkg/tools"
"github.com/TheTNB/panel/app/models"
"github.com/TheTNB/panel/internal"
"github.com/TheTNB/panel/internal/services"
"github.com/TheTNB/panel/pkg/tools"
)
type MenuItem struct {

View File

@@ -8,9 +8,9 @@ import (
"github.com/goravel/framework/support/carbon"
"github.com/spf13/cast"
"panel/app/models"
"panel/internal"
"panel/internal/services"
"github.com/TheTNB/panel/app/models"
"github.com/TheTNB/panel/internal"
"github.com/TheTNB/panel/internal/services"
)
type MonitorController struct {

View File

@@ -4,9 +4,9 @@ import (
"github.com/goravel/framework/contracts/http"
"github.com/goravel/framework/facades"
"panel/app/models"
"panel/internal"
"panel/internal/services"
"github.com/TheTNB/panel/app/models"
"github.com/TheTNB/panel/internal"
"github.com/TheTNB/panel/internal/services"
)
type PluginController struct {

View File

@@ -8,12 +8,12 @@ import (
"github.com/goravel/framework/facades"
"github.com/spf13/cast"
"panel/app/http/controllers"
"panel/app/models"
"panel/internal"
"panel/internal/services"
"panel/pkg/tools"
"panel/types"
"github.com/TheTNB/panel/app/http/controllers"
"github.com/TheTNB/panel/app/models"
"github.com/TheTNB/panel/internal"
"github.com/TheTNB/panel/internal/services"
"github.com/TheTNB/panel/pkg/tools"
"github.com/TheTNB/panel/types"
)
type Fail2banController struct {

View File

@@ -8,11 +8,11 @@ import (
"github.com/goravel/framework/contracts/http"
"github.com/spf13/cast"
"panel/app/http/controllers"
"panel/app/models"
"panel/internal"
"panel/internal/services"
"panel/pkg/tools"
"github.com/TheTNB/panel/app/http/controllers"
"github.com/TheTNB/panel/app/models"
"github.com/TheTNB/panel/internal"
"github.com/TheTNB/panel/internal/services"
"github.com/TheTNB/panel/pkg/tools"
)
type MySQLController struct {

View File

@@ -8,8 +8,8 @@ import (
"github.com/goravel/framework/contracts/http"
"github.com/spf13/cast"
"panel/app/http/controllers"
"panel/pkg/tools"
"github.com/TheTNB/panel/app/http/controllers"
"github.com/TheTNB/panel/pkg/tools"
)
type OpenRestyController struct {

View File

@@ -1,10 +1,10 @@
package plugins
import (
"github.com/TheTNB/panel/app/http/controllers"
"github.com/TheTNB/panel/internal"
"github.com/TheTNB/panel/internal/services"
"github.com/goravel/framework/contracts/http"
"panel/app/http/controllers"
"panel/internal"
"panel/internal/services"
)
type PHPController struct {

View File

@@ -9,8 +9,8 @@ import (
"github.com/goravel/framework/facades"
"github.com/spf13/cast"
"panel/app/http/controllers"
"panel/pkg/tools"
"github.com/TheTNB/panel/app/http/controllers"
"github.com/TheTNB/panel/pkg/tools"
)
type PhpMyAdminController struct {

View File

@@ -6,12 +6,12 @@ import (
"github.com/goravel/framework/contracts/http"
"github.com/goravel/framework/support/carbon"
"panel/app/http/controllers"
"panel/app/models"
"panel/internal"
"panel/internal/services"
"panel/pkg/tools"
"panel/types"
"github.com/TheTNB/panel/app/http/controllers"
"github.com/TheTNB/panel/app/models"
"github.com/TheTNB/panel/internal"
"github.com/TheTNB/panel/internal/services"
"github.com/TheTNB/panel/pkg/tools"
"github.com/TheTNB/panel/types"
)
type Postgresql15Controller struct {

View File

@@ -6,12 +6,12 @@ import (
"github.com/goravel/framework/contracts/http"
"github.com/goravel/framework/support/carbon"
"panel/app/http/controllers"
"panel/app/models"
"panel/internal"
"panel/internal/services"
"panel/pkg/tools"
"panel/types"
"github.com/TheTNB/panel/app/http/controllers"
"github.com/TheTNB/panel/app/models"
"github.com/TheTNB/panel/internal"
"github.com/TheTNB/panel/internal/services"
"github.com/TheTNB/panel/pkg/tools"
"github.com/TheTNB/panel/types"
)
type Postgresql16Controller struct {

View File

@@ -7,8 +7,8 @@ import (
"github.com/goravel/framework/contracts/http"
"github.com/spf13/cast"
"panel/app/http/controllers"
"panel/pkg/tools"
"github.com/TheTNB/panel/app/http/controllers"
"github.com/TheTNB/panel/pkg/tools"
)
type PureFtpdController struct {

View File

@@ -5,9 +5,9 @@ import (
"github.com/goravel/framework/contracts/http"
"panel/app/http/controllers"
"panel/pkg/tools"
"panel/types"
"github.com/TheTNB/panel/app/http/controllers"
"github.com/TheTNB/panel/pkg/tools"
"github.com/TheTNB/panel/types"
)
type RedisController struct {

View File

@@ -6,13 +6,13 @@ import (
"github.com/goravel/framework/contracts/http"
"panel/app/http/controllers"
commonrequests "panel/app/http/requests/common"
requests "panel/app/http/requests/plugins/rsync"
"panel/internal"
"panel/internal/services"
"panel/pkg/tools"
"panel/types"
"github.com/TheTNB/panel/app/http/controllers"
commonrequests "github.com/TheTNB/panel/app/http/requests/common"
requests "github.com/TheTNB/panel/app/http/requests/plugins/rsync"
"github.com/TheTNB/panel/internal"
"github.com/TheTNB/panel/internal/services"
"github.com/TheTNB/panel/pkg/tools"
"github.com/TheTNB/panel/types"
)
type RsyncController struct {

View File

@@ -8,11 +8,11 @@ import (
"github.com/goravel/framework/support/json"
"github.com/spf13/cast"
"panel/app/http/controllers"
"panel/internal"
"panel/internal/services"
"panel/pkg/tools"
"panel/types"
"github.com/TheTNB/panel/app/http/controllers"
"github.com/TheTNB/panel/internal"
"github.com/TheTNB/panel/internal/services"
"github.com/TheTNB/panel/pkg/tools"
"github.com/TheTNB/panel/types"
)
type S3fsController struct {

View File

@@ -4,10 +4,10 @@ import (
"strconv"
"strings"
"github.com/TheTNB/panel/pkg/tools"
"github.com/goravel/framework/contracts/http"
"panel/pkg/tools"
"panel/app/http/controllers"
"github.com/TheTNB/panel/app/http/controllers"
)
type SupervisorController struct {

View File

@@ -7,8 +7,8 @@ import (
"github.com/goravel/framework/contracts/http"
"github.com/spf13/cast"
"panel/app/http/controllers"
"panel/pkg/tools"
"github.com/TheTNB/panel/app/http/controllers"
"github.com/TheTNB/panel/pkg/tools"
)
type ToolBoxController struct {

View File

@@ -4,11 +4,11 @@ import (
"regexp"
"strings"
commonrequests "github.com/TheTNB/panel/app/http/requests/common"
"github.com/goravel/framework/contracts/http"
"github.com/spf13/cast"
commonrequests "panel/app/http/requests/common"
"panel/pkg/tools"
"github.com/TheTNB/panel/pkg/tools"
)
type SafeController struct {

View File

@@ -5,11 +5,11 @@ import (
"github.com/goravel/framework/facades"
"github.com/spf13/cast"
requests "panel/app/http/requests/setting"
"panel/app/models"
"panel/internal"
"panel/internal/services"
"panel/pkg/tools"
requests "github.com/TheTNB/panel/app/http/requests/setting"
"github.com/TheTNB/panel/app/models"
"github.com/TheTNB/panel/internal"
"github.com/TheTNB/panel/internal/services"
"github.com/TheTNB/panel/pkg/tools"
)
type SettingController struct {

View File

@@ -12,10 +12,10 @@ import (
"github.com/gorilla/websocket"
"github.com/spf13/cast"
"panel/app/models"
"panel/internal"
"panel/internal/services"
"panel/pkg/ssh"
"github.com/TheTNB/panel/app/models"
"github.com/TheTNB/panel/internal"
"github.com/TheTNB/panel/internal/services"
"github.com/TheTNB/panel/pkg/ssh"
)
type SshController struct {

View File

@@ -5,7 +5,7 @@ import (
"github.com/goravel/framework/facades"
"github.com/swaggo/http-swagger/v2"
_ "panel/docs"
_ "github.com/TheTNB/panel/docs"
)
type SwaggerController struct {

View File

@@ -4,8 +4,8 @@ import (
"github.com/goravel/framework/contracts/http"
"github.com/goravel/framework/facades"
"panel/app/models"
"panel/pkg/tools"
"github.com/TheTNB/panel/app/models"
"github.com/TheTNB/panel/pkg/tools"
)
type TaskController struct {

View File

@@ -4,8 +4,8 @@ import (
"github.com/goravel/framework/contracts/http"
"github.com/goravel/framework/facades"
"panel/app/http/requests/user"
"panel/app/models"
"github.com/TheTNB/panel/app/http/requests/user"
"github.com/TheTNB/panel/app/models"
)
type UserController struct {

View File

@@ -8,12 +8,12 @@ import (
"github.com/goravel/framework/contracts/http"
"github.com/goravel/framework/facades"
commonrequests "panel/app/http/requests/common"
requests "panel/app/http/requests/website"
"panel/app/models"
"panel/internal"
"panel/internal/services"
"panel/pkg/tools"
commonrequests "github.com/TheTNB/panel/app/http/requests/common"
requests "github.com/TheTNB/panel/app/http/requests/website"
"github.com/TheTNB/panel/app/models"
"github.com/TheTNB/panel/internal"
"github.com/TheTNB/panel/internal/services"
"github.com/TheTNB/panel/pkg/tools"
)
type WebsiteController struct {

View File

@@ -3,7 +3,7 @@ package http
import (
"github.com/goravel/framework/contracts/http"
"panel/app/http/middleware"
"github.com/TheTNB/panel/app/http/middleware"
)
type Kernel struct {

View File

@@ -7,7 +7,7 @@ import (
"github.com/goravel/framework/contracts/translation"
"github.com/goravel/framework/facades"
"panel/internal/services"
"github.com/TheTNB/panel/internal/services"
)
// MustInstall 确保已安装插件

View File

@@ -4,7 +4,7 @@ import (
"github.com/goravel/framework/contracts/http"
"github.com/goravel/framework/facades"
"panel/internal"
"github.com/TheTNB/panel/internal"
)
// Status 检查程序状态

View File

@@ -4,7 +4,7 @@ import (
"github.com/goravel/framework/contracts/http"
"github.com/goravel/framework/contracts/validation"
"panel/pkg/acme"
"github.com/TheTNB/panel/pkg/acme"
)
type DNSStore struct {

View File

@@ -4,7 +4,7 @@ import (
"github.com/goravel/framework/contracts/http"
"github.com/goravel/framework/contracts/validation"
"panel/pkg/acme"
"github.com/TheTNB/panel/pkg/acme"
)
type DNSUpdate struct {

View File

@@ -4,7 +4,7 @@ import (
"github.com/goravel/framework/contracts/http"
"github.com/goravel/framework/contracts/validation"
"panel/types"
"github.com/TheTNB/panel/types"
)
type ContainerCreate struct {

View File

@@ -4,7 +4,7 @@ import (
"github.com/goravel/framework/contracts/http"
"github.com/goravel/framework/contracts/validation"
"panel/types"
"github.com/TheTNB/panel/types"
)
type ContainerUpdate struct {

View File

@@ -4,7 +4,7 @@ import (
"github.com/goravel/framework/contracts/http"
"github.com/goravel/framework/contracts/validation"
"panel/types"
"github.com/TheTNB/panel/types"
)
type NetworkCreate struct {

View File

@@ -4,7 +4,7 @@ import (
"github.com/goravel/framework/contracts/http"
"github.com/goravel/framework/contracts/validation"
"panel/types"
"github.com/TheTNB/panel/types"
)
type VolumeCreate struct {

View File

@@ -5,7 +5,7 @@ import (
"github.com/goravel/framework/facades"
"panel/app/models"
"github.com/TheTNB/panel/app/models"
)
// ProcessTask 处理面板任务

View File

@@ -3,7 +3,7 @@ package models
import (
"github.com/goravel/framework/support/carbon"
"panel/pkg/acme"
"github.com/TheTNB/panel/pkg/acme"
)
type CertDNS struct {

View File

@@ -3,7 +3,7 @@ package models
import (
"github.com/goravel/framework/support/carbon"
"panel/pkg/tools"
"github.com/TheTNB/panel/pkg/tools"
)
type Monitor struct {

View File

@@ -4,7 +4,7 @@ import (
"github.com/goravel/framework/contracts/foundation"
"github.com/goravel/framework/facades"
"panel/app/console"
"github.com/TheTNB/panel/app/console"
)
type ConsoleServiceProvider struct {

View File

@@ -5,7 +5,7 @@ import (
"github.com/goravel/framework/contracts/foundation"
"github.com/goravel/framework/facades"
"panel/database/seeders"
"github.com/TheTNB/panel/database/seeders"
)
type DatabaseServiceProvider struct {

View File

@@ -5,7 +5,7 @@ import (
"github.com/goravel/framework/contracts/queue"
"github.com/goravel/framework/facades"
"panel/app/jobs"
"github.com/TheTNB/panel/app/jobs"
)
type QueueServiceProvider struct {

View File

@@ -4,8 +4,8 @@ import (
"github.com/goravel/framework/contracts/foundation"
"github.com/goravel/framework/facades"
"panel/app/http"
"panel/routes"
"github.com/TheTNB/panel/app/http"
"github.com/TheTNB/panel/routes"
)
type RouteServiceProvider struct {

View File

@@ -5,7 +5,7 @@ import (
"github.com/goravel/framework/contracts/validation"
"github.com/goravel/framework/facades"
"panel/app/rules"
"github.com/TheTNB/panel/app/rules"
)
type ValidationServiceProvider struct {

View File

@@ -5,7 +5,7 @@ import (
"github.com/goravel/framework/contracts/validation"
"panel/pkg/captcha"
"github.com/TheTNB/panel/pkg/captcha"
)
type Captcha struct {

View File

@@ -1,9 +1,9 @@
package rules
import (
"github.com/TheTNB/panel/pkg/tools"
"github.com/goravel/framework/contracts/validation"
"github.com/spf13/cast"
"panel/pkg/tools"
)
type PathExists struct {

View File

@@ -1,9 +1,9 @@
package rules
import (
"github.com/TheTNB/panel/pkg/tools"
"github.com/goravel/framework/contracts/validation"
"github.com/spf13/cast"
"panel/pkg/tools"
)
type PathNotExists struct {

View File

@@ -4,7 +4,7 @@ import (
"github.com/gookit/validate/locales/zhcn"
"github.com/goravel/framework/foundation"
"panel/config"
"github.com/TheTNB/panel/config"
)
func Boot() {

View File

@@ -23,7 +23,7 @@ import (
"github.com/goravel/framework/validation"
"github.com/goravel/gin"
"panel/app/providers"
"github.com/TheTNB/panel/app/providers"
)
// Boot Start all init methods of the current folder to bootstrap all config.

4
go.mod
View File

@@ -1,4 +1,4 @@
module panel
module github.com/TheTNB/panel
go 1.22
@@ -6,7 +6,6 @@ require (
github.com/docker/docker v26.1.3+incompatible
github.com/docker/go-connections v0.5.0
github.com/go-resty/resty/v2 v2.13.1
github.com/gookit/color v1.5.4
github.com/gookit/validate v1.5.2
github.com/goravel/framework v1.13.1-0.20240529102137-443e5efce883
github.com/goravel/gin v1.1.6-0.20240426085159-718e4d6d5f4f
@@ -102,6 +101,7 @@ require (
github.com/google/pprof v0.0.0-20240227163752-401108e1b7e7 // indirect
github.com/google/uuid v1.6.0 // indirect
github.com/google/wire v0.6.0 // indirect
github.com/gookit/color v1.5.4 // indirect
github.com/gookit/filter v1.2.1 // indirect
github.com/gookit/goutil v0.6.15 // indirect
github.com/goravel/file-rotatelogs/v2 v2.4.2 // indirect

View File

@@ -1,6 +1,6 @@
package internal
import "panel/app/models"
import "github.com/TheTNB/panel/app/models"
type Backup interface {
WebsiteList() ([]BackupFile, error)

View File

@@ -1,9 +1,9 @@
package internal
import (
requests "panel/app/http/requests/cert"
"panel/app/models"
"panel/pkg/acme"
requests "github.com/TheTNB/panel/app/http/requests/cert"
"github.com/TheTNB/panel/app/models"
"github.com/TheTNB/panel/pkg/acme"
)
type Cert interface {

View File

@@ -7,8 +7,8 @@ import (
"github.com/docker/docker/api/types/network"
"github.com/docker/docker/api/types/volume"
requests "panel/app/http/requests/container"
paneltypes "panel/types"
requests "github.com/TheTNB/panel/app/http/requests/container"
paneltypes "github.com/TheTNB/panel/types"
)
type Container interface {

View File

@@ -1,6 +1,6 @@
package internal
import "panel/app/models"
import "github.com/TheTNB/panel/app/models"
type Cron interface {
AddToSystem(cron models.Cron) error

View File

@@ -1,6 +1,6 @@
package internal
import "panel/types"
import "github.com/TheTNB/panel/types"
type PHPExtension struct {
Name string `json:"name"`

View File

@@ -1,6 +1,6 @@
package internal
import "panel/app/models"
import "github.com/TheTNB/panel/app/models"
// PanelPlugin 插件元数据结构
type PanelPlugin struct {

View File

@@ -9,9 +9,9 @@ import (
"github.com/goravel/framework/support/carbon"
"panel/app/models"
"panel/internal"
"panel/pkg/tools"
"github.com/TheTNB/panel/app/models"
"github.com/TheTNB/panel/internal"
"github.com/TheTNB/panel/pkg/tools"
)
type BackupImpl struct {

View File

@@ -9,10 +9,10 @@ import (
"github.com/goravel/framework/facades"
requests "panel/app/http/requests/cert"
"panel/app/models"
"panel/pkg/acme"
"panel/pkg/tools"
requests "github.com/TheTNB/panel/app/http/requests/cert"
"github.com/TheTNB/panel/app/models"
"github.com/TheTNB/panel/pkg/acme"
"github.com/TheTNB/panel/pkg/tools"
)
type CertImpl struct {

View File

@@ -15,8 +15,8 @@ import (
"github.com/docker/docker/client"
"github.com/goravel/framework/support/json"
requests "panel/app/http/requests/container"
paneltypes "panel/types"
requests "github.com/TheTNB/panel/app/http/requests/container"
paneltypes "github.com/TheTNB/panel/types"
)
type Container struct {

View File

@@ -3,8 +3,8 @@ package services
import (
"strings"
"panel/app/models"
"panel/pkg/tools"
"github.com/TheTNB/panel/app/models"
"github.com/TheTNB/panel/pkg/tools"
)
type CronImpl struct {

View File

@@ -12,10 +12,10 @@ import (
"github.com/goravel/framework/facades"
"github.com/spf13/cast"
"panel/app/models"
"panel/internal"
"panel/pkg/tools"
"panel/types"
"github.com/TheTNB/panel/app/models"
"github.com/TheTNB/panel/internal"
"github.com/TheTNB/panel/pkg/tools"
"github.com/TheTNB/panel/types"
)
type PHPImpl struct {

View File

@@ -6,8 +6,8 @@ import (
"github.com/goravel/framework/facades"
"panel/app/models"
"panel/internal"
"github.com/TheTNB/panel/app/models"
"github.com/TheTNB/panel/internal"
)
type PluginImpl struct {

View File

@@ -2,8 +2,8 @@
package services
import (
"github.com/TheTNB/panel/app/models"
"github.com/goravel/framework/facades"
"panel/app/models"
)
type SettingImpl struct {

View File

@@ -3,8 +3,8 @@ package services
import (
"github.com/goravel/framework/facades"
"panel/app/jobs"
"panel/app/models"
"github.com/TheTNB/panel/app/jobs"
"github.com/TheTNB/panel/app/models"
)
type TaskImpl struct {

View File

@@ -4,7 +4,7 @@ package services
import (
"github.com/goravel/framework/facades"
"panel/app/models"
"github.com/TheTNB/panel/app/models"
)
type UserImpl struct {

View File

@@ -10,13 +10,13 @@ import (
"strconv"
"strings"
requests "github.com/TheTNB/panel/app/http/requests/website"
"github.com/goravel/framework/facades"
"github.com/spf13/cast"
requests "panel/app/http/requests/website"
"panel/app/models"
"panel/internal"
"panel/pkg/tools"
"github.com/TheTNB/panel/app/models"
"github.com/TheTNB/panel/internal"
"github.com/TheTNB/panel/pkg/tools"
)
type WebsiteImpl struct {

View File

@@ -1,6 +1,6 @@
package internal
import "panel/app/models"
import "github.com/TheTNB/panel/app/models"
type User interface {
Create(name, password string) (models.User, error)

View File

@@ -1,8 +1,8 @@
package internal
import (
requests "panel/app/http/requests/website"
"panel/app/models"
requests "github.com/TheTNB/panel/app/http/requests/website"
"github.com/TheTNB/panel/app/models"
)
type Website interface {

View File

@@ -19,7 +19,7 @@ package main
import (
"github.com/goravel/framework/facades"
"panel/bootstrap"
"github.com/TheTNB/panel/bootstrap"
)
// @title 耗子 Linux 面板 API
@@ -27,7 +27,7 @@ import (
// @description 耗子 Linux 面板的 API 信息
// @contact.name 耗子科技
// @contact.email i@haozi.net
// @contact.email admin@haozi.net
// @license.name GNU Affero General Public License v3
// @license url https://www.gnu.org/licenses/agpl-3.0.html

View File

@@ -5,7 +5,7 @@ import (
"golang.org/x/crypto/ssh"
"panel/pkg/tools"
"github.com/TheTNB/panel/pkg/tools"
)
type AuthMethod int8

View File

@@ -10,8 +10,8 @@ import (
"time"
"github.com/go-resty/resty/v2"
"github.com/gookit/color"
"github.com/goravel/framework/support/carbon"
"github.com/goravel/framework/support/color"
"github.com/goravel/framework/support/env"
"github.com/shirou/gopsutil/cpu"
"github.com/shirou/gopsutil/disk"
@@ -402,108 +402,108 @@ func GetPanelVersion(version string) (PanelInfo, error) {
// UpdatePanel 更新面板
func UpdatePanel(panelInfo PanelInfo) error {
color.Greenln("目标版本: " + panelInfo.Version)
color.Greenln("下载链接: " + panelInfo.DownloadUrl)
color.Green().Printfln("目标版本: " + panelInfo.Version)
color.Green().Printfln("下载链接: " + panelInfo.DownloadUrl)
color.Greenln("前置检查...")
color.Green().Printfln("前置检查...")
if Exists("/tmp/panel-storage.zip") || Exists("/tmp/panel.conf.bak") {
return errors.New("检测到 /tmp 存在临时文件,可能是上次更新失败导致的,请谨慎排除后重试")
}
color.Greenln("备份面板数据...")
color.Green().Printfln("备份面板数据...")
// 备份面板
if err := Archive([]string{"/www/panel"}, "/www/backup/panel/panel-"+carbon.Now().ToShortDateTimeString()+".zip"); err != nil {
color.Redln("备份面板失败")
color.Red().Printfln("备份面板失败")
return err
}
if _, err := Exec("cd /www/panel/storage && zip -r /tmp/panel-storage.zip *"); err != nil {
color.Redln("备份面板数据失败")
color.Red().Printfln("备份面板数据失败")
return err
}
if _, err := Exec("cp -f /www/panel/panel.conf /tmp/panel.conf.bak"); err != nil {
color.Redln("备份面板配置失败")
color.Red().Printfln("备份面板配置失败")
return err
}
if !Exists("/tmp/panel-storage.zip") || !Exists("/tmp/panel.conf.bak") {
return errors.New("备份面板数据失败")
}
color.Greenln("备份完成")
color.Green().Printfln("备份完成")
color.Greenln("清理旧版本...")
color.Green().Printfln("清理旧版本...")
if _, err := Exec("rm -rf /www/panel/*"); err != nil {
color.Redln("清理旧版本失败")
color.Red().Printfln("清理旧版本失败")
return err
}
color.Greenln("清理完成")
color.Green().Printfln("清理完成")
color.Greenln("正在下载...")
color.Green().Printfln("正在下载...")
if _, err := Exec("wget -T 120 -t 3 -O /www/panel/" + panelInfo.DownloadName + " " + panelInfo.DownloadUrl); err != nil {
color.Redln("下载失败")
color.Red().Printfln("下载失败")
return err
}
if _, err := Exec("wget -T 20 -t 3 -O /www/panel/" + panelInfo.Checksums + " " + panelInfo.ChecksumsUrl); err != nil {
color.Redln("下载失败")
color.Red().Printfln("下载失败")
return err
}
if !Exists("/www/panel/"+panelInfo.DownloadName) || !Exists("/www/panel/"+panelInfo.Checksums) {
return errors.New("下载失败")
}
color.Greenln("下载完成")
color.Green().Printfln("下载完成")
color.Greenln("校验下载文件...")
color.Green().Printfln("校验下载文件...")
check, err := Exec("cd /www/panel && sha256sum -c " + panelInfo.Checksums + " --ignore-missing")
if check != panelInfo.DownloadName+": OK" || err != nil {
return errors.New("下载文件校验失败")
}
if err = Remove("/www/panel/" + panelInfo.Checksums); err != nil {
color.Redln("清理临时文件失败")
color.Red().Printfln("清理临时文件失败")
return err
}
color.Greenln("文件校验完成")
color.Green().Printfln("文件校验完成")
color.Greenln("更新新版本...")
color.Green().Printfln("更新新版本...")
if _, err = Exec("cd /www/panel && unzip -o " + panelInfo.DownloadName + " && rm -rf " + panelInfo.DownloadName); err != nil {
color.Redln("更新失败")
color.Red().Printfln("更新失败")
return err
}
if !Exists("/www/panel/panel") {
return errors.New("更新失败,可能是下载过程中出现了问题")
}
color.Greenln("更新完成")
color.Green().Printfln("更新完成")
color.Greenln("恢复面板数据...")
color.Green().Printfln("恢复面板数据...")
if _, err = Exec("cp -f /tmp/panel-storage.zip /www/panel/storage/panel-storage.zip && cd /www/panel/storage && unzip -o panel-storage.zip && rm -rf panel-storage.zip"); err != nil {
color.Redln("恢复面板数据失败")
color.Red().Printfln("恢复面板数据失败")
return err
}
if _, err = Exec("cp -f /tmp/panel.conf.bak /www/panel/panel.conf"); err != nil {
color.Redln("恢复面板配置失败")
color.Red().Printfln("恢复面板配置失败")
return err
}
if _, err = Exec("cp -f /www/panel/scripts/panel.sh /usr/bin/panel"); err != nil {
color.Redln("恢复面板脚本失败")
color.Red().Printfln("恢复面板脚本失败")
return err
}
if !Exists("/www/panel/storage/panel.db") || !Exists("/www/panel/panel.conf") {
return errors.New("恢复面板数据失败")
}
color.Greenln("恢复完成")
color.Green().Printfln("恢复完成")
color.Greenln("设置面板文件权限...")
color.Green().Printfln("设置面板文件权限...")
_, _ = Exec("chmod -R 700 /www/panel")
_, _ = Exec("chmod -R 700 /usr/bin/panel")
color.Greenln("设置完成")
color.Green().Printfln("设置完成")
if _, err = Exec("/www/panel/panel --env=panel.conf artisan migrate"); err != nil {
color.Redln("运行面板数据库迁移失败")
color.Red().Printfln("运行面板数据库迁移失败")
return err
}
if _, err = Exec("bash /www/panel/scripts/update_panel.sh"); err != nil {
color.Redln("执行面板升级后脚本失败")
color.Red().Printfln("执行面板升级后脚本失败")
return err
}
if _, err = Exec("panel writeSetting version " + panelInfo.Version); err != nil {
color.Redln("写入面板版本号失败")
color.Red().Printfln("写入面板版本号失败")
return err
}
@@ -514,14 +514,14 @@ func UpdatePanel(panelInfo PanelInfo) error {
}
func RestartPanel() {
color.Greenln("重启面板...")
color.Green().Printfln("重启面板...")
err := ExecAsync("sleep 2 && systemctl restart panel")
if err != nil {
color.Redln("重启失败")
color.Red().Printfln("重启失败")
return
}
color.Greenln("重启完成")
color.Green().Printfln("重启完成")
}
// IsChina 是否中国大陆

View File

@@ -4,8 +4,8 @@ import (
"github.com/goravel/framework/contracts/route"
"github.com/goravel/framework/facades"
"panel/app/http/controllers"
"panel/app/http/middleware"
"github.com/TheTNB/panel/app/http/controllers"
"github.com/TheTNB/panel/app/http/middleware"
)
func Api() {

View File

@@ -4,8 +4,8 @@ import (
"github.com/goravel/framework/contracts/route"
"github.com/goravel/framework/facades"
"panel/app/http/controllers/plugins"
"panel/app/http/middleware"
"github.com/TheTNB/panel/app/http/controllers/plugins"
"github.com/TheTNB/panel/app/http/middleware"
)
// Plugin 加载插件路由

View File

@@ -5,9 +5,9 @@ import (
"github.com/stretchr/testify/suite"
"panel/internal"
"panel/internal/services"
"panel/tests"
"github.com/TheTNB/panel/internal"
"github.com/TheTNB/panel/internal/services"
"github.com/TheTNB/panel/tests"
)
type SettingTestSuite struct {

View File

@@ -3,7 +3,7 @@ package tests
import (
"github.com/goravel/framework/testing"
"panel/bootstrap"
"github.com/TheTNB/panel/bootstrap"
)
func init() {

View File

@@ -6,10 +6,10 @@ import (
"github.com/goravel/framework/facades"
"github.com/stretchr/testify/suite"
"panel/app/models"
"panel/internal"
"panel/internal/services"
"panel/tests"
"github.com/TheTNB/panel/app/models"
"github.com/TheTNB/panel/internal"
"github.com/TheTNB/panel/internal/services"
"github.com/TheTNB/panel/tests"
)
type UserTestSuite struct {