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

Merge pull request #91 from TheTNB/kkumar-gcc/#45

feat: support localization
This commit is contained in:
krishan kumar
2024-04-28 18:45:37 +05:30
committed by GitHub
12 changed files with 609 additions and 163 deletions

View File

@@ -1,6 +1,7 @@
package commands
import (
"context"
"crypto/x509"
"encoding/pem"
@@ -25,7 +26,8 @@ func (receiver *CertRenew) Signature() string {
// Description The console command description.
func (receiver *CertRenew) Description() string {
return "[面板] 证书续签"
ctx := context.Background()
return facades.Lang(ctx).Get("commands.panel:cert-renew.description")
}
// Extend The console command extend.
@@ -36,7 +38,7 @@ func (receiver *CertRenew) Extend() command.Extend {
}
// Handle Execute the console command.
func (receiver *CertRenew) Handle(ctx console.Context) error {
func (receiver *CertRenew) Handle(console.Context) error {
if internal.Status != internal.StatusNormal {
return nil
}

View File

@@ -1,6 +1,7 @@
package commands
import (
"context"
"strconv"
"github.com/gookit/color"
@@ -27,7 +28,8 @@ func (receiver *Monitoring) Signature() string {
// Description The console command description.
func (receiver *Monitoring) Description() string {
return "[面板] 系统监控"
ctx := context.Background()
return facades.Lang(ctx).Get("commands.panel:monitoring.description")
}
// Extend The console command extend.
@@ -38,7 +40,7 @@ func (receiver *Monitoring) Extend() command.Extend {
}
// Handle Execute the console command.
func (receiver *Monitoring) Handle(ctx console.Context) error {
func (receiver *Monitoring) Handle(console.Context) error {
if internal.Status != internal.StatusNormal {
return nil
}
@@ -51,6 +53,8 @@ func (receiver *Monitoring) Handle(ctx console.Context) error {
info := tools.GetMonitoringInfo()
translate := facades.Lang(context.Background())
// 去除部分数据以减少数据库存储
info.Disk = nil
for _, cpu := range info.Cpus {
@@ -70,7 +74,7 @@ func (receiver *Monitoring) Handle(ctx console.Context) error {
})
if err != nil {
facades.Log().Infof("[面板] 系统监控保存失败: %s", err.Error())
color.Redf("[面板] 系统监控保存失败: %s", err.Error())
color.Redf(translate.Get("commands.panel:monitoring.fail")+": %s", err.Error())
return nil
}

View File

@@ -1,6 +1,7 @@
package commands
import (
"context"
"fmt"
"os"
"path/filepath"
@@ -31,7 +32,8 @@ func (receiver *Panel) Signature() string {
// Description The console command description.
func (receiver *Panel) Description() string {
return "[面板] 命令行"
ctx := context.Background()
return facades.Lang(ctx).Get("commands.panel.description")
}
// Extend The console command extend.
@@ -50,74 +52,76 @@ func (receiver *Panel) Handle(ctx console.Context) error {
arg4 := ctx.Argument(4)
arg5 := ctx.Argument(5)
translate := facades.Lang(context.Background())
switch action {
case "init":
var check models.User
err := facades.Orm().Query().FirstOrFail(&check)
if err == nil {
color.Redln("面板已初始化")
color.Redln(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("初始化失败")
color.Redln(translate.Get("commands.panel.init.fail"))
return nil
}
hash, err := facades.Hash().Make(tools.RandomString(32))
if err != nil {
color.Redln("初始化失败")
color.Redln(translate.Get("commands.panel.init.fail"))
return nil
}
user := services.NewUserImpl()
_, err = user.Create("admin", hash)
if err != nil {
color.Redln("创建管理员失败")
color.Redln(translate.Get("commands.panel.init.adminFail"))
return nil
}
color.Greenln("初始化成功")
color.Greenln(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("当前有任务正在执行,禁止更新")
color.Redln(translate.Get("commands.panel.update.taskCheck"))
return nil
}
panel, err := tools.GetLatestPanelVersion()
if err != nil {
color.Redln("获取最新版本失败")
color.Redln(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("更新失败: " + err.Error())
color.Redln(translate.Get("commands.panel.update.fail") + ": " + err.Error())
return nil
}
internal.Status = internal.StatusNormal
color.Greenln("更新成功")
color.Greenln(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("获取管理员信息失败")
color.Redln(translate.Get("commands.panel.getInfo.adminGetFail"))
return nil
}
password := tools.RandomString(16)
hash, err := facades.Hash().Make(password)
if err != nil {
color.Redln("生成密码失败")
color.Redln(translate.Get("commands.panel.getInfo.passwordGenerationFail"))
return nil
}
user.Username = tools.RandomString(8)
@@ -128,13 +132,13 @@ func (receiver *Panel) Handle(ctx console.Context) error {
err = facades.Orm().Query().Save(&user)
if err != nil {
color.Redln("保存管理员信息失败")
color.Redln(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("获取面板端口失败")
color.Redln(translate.Get("commands.panel.portFail"))
return nil
}
ip, err := tools.GetPublicIP()
@@ -146,42 +150,42 @@ func (receiver *Panel) Handle(ctx console.Context) error {
protocol = "https"
}
color.Greenln("用户名: " + user.Username)
color.Greenln("密码: " + password)
color.Greenln("面板端口: " + port)
color.Greenln("面板入口: " + facades.Config().GetString("http.entrance"))
color.Greenln("面板地址: " + protocol + "://" + ip + ":" + port + facades.Config().GetString("http.entrance"))
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"))
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("获取面板端口失败")
color.Redln(translate.Get("commands.panel.portFail"))
return nil
}
color.Greenln("面板端口: " + port)
color.Greenln(translate.Get("commands.panel.port") + ": " + port)
case "getEntrance":
color.Greenln("面板入口: " + facades.Config().GetString("http.entrance"))
color.Greenln(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("获取面板入口失败")
color.Redln(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("删除面板入口失败")
color.Redln(translate.Get("commands.panel.deleteEntrance.fail"))
return nil
}
color.Greenln("删除面板入口成功")
color.Greenln(translate.Get("commands.panel.deleteEntrance.success"))
case "writePlugin":
slug := arg1
version := arg2
if len(slug) == 0 || len(version) == 0 {
color.Redln("参数错误")
color.Redln(translate.Get("commands.panel.writePlugin.paramFail"))
return nil
}
@@ -193,31 +197,31 @@ func (receiver *Panel) Handle(ctx console.Context) error {
})
if err != nil {
color.Redln("写入插件安装状态失败")
color.Redln(translate.Get("commands.panel.writePlugin.fail"))
return nil
}
color.Greenln("写入插件安装状态成功")
color.Greenln(translate.Get("commands.panel.writePlugin.success"))
case "deletePlugin":
slug := arg1
if len(slug) == 0 {
color.Redln("参数错误")
color.Redln(translate.Get("commands.panel.deletePlugin.paramFail"))
return nil
}
_, err := facades.Orm().Query().Where("slug", slug).Delete(&models.Plugin{})
if err != nil {
color.Redln("移除插件安装状态失败")
color.Redln(translate.Get("commands.panel.deletePlugin.fail"))
return nil
}
color.Greenln("移除插件安装状态成功")
color.Greenln(translate.Get("commands.panel.deletePlugin.success"))
case "writeMysqlPassword":
password := arg1
if len(password) == 0 {
color.Redln("参数错误")
color.Redln(translate.Get("commands.panel.writeMysqlPassword.paramFail"))
return nil
}
@@ -229,20 +233,20 @@ func (receiver *Panel) Handle(ctx console.Context) error {
})
if err != nil {
color.Redln("写入MySQL root密码失败")
color.Redln(translate.Get("commands.panel.writeMysqlPassword.fail"))
return nil
}
color.Greenln("写入MySQL root密码成功")
color.Greenln(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("清理任务失败")
color.Redln(translate.Get("commands.panel.cleanTask.fail"))
return nil
}
color.Greenln("清理任务成功")
color.Greenln(translate.Get("commands.panel.cleanTask.success"))
case "backup":
backupType := arg1
@@ -251,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("参数错误")
color.Redln(translate.Get("commands.panel.backup.paramFail"))
return nil
}
color.Greenln(hr)
color.Greenln("★ 开始备份 [" + carbon.Now().ToDateTimeString() + "]")
color.Greenln("★ " + translate.Get("commands.panel.backup.start") + " [" + carbon.Now().ToDateTimeString() + "]")
color.Greenln(hr)
if !tools.Exists(path) {
if err := tools.Mkdir(path, 0644); err != nil {
color.Redln("|-创建备份目录失败: " + err.Error())
color.Redln("|-" + translate.Get("commands.panel.backup.backupDirFail") + ": " + err.Error())
return nil
}
}
switch backupType {
case "website":
color.Yellowln("|-目标网站: " + name)
color.Yellowln("|-" + 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("|-网站不存在")
color.Redln("|-" + translate.Get("commands.panel.backup.siteNotExist"))
color.Greenln(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("|-备份失败: " + err.Error())
color.Redln("|-" + translate.Get("commands.panel.backup.backupFail") + ": " + err.Error())
return nil
}
color.Greenln("|-备份成功")
color.Greenln("|-" + translate.Get("commands.panel.backup.backupSuccess"))
case "mysql":
rootPassword := services.NewSettingImpl().Get(models.SettingKeyMysqlRootPassword)
@@ -289,81 +293,81 @@ func (receiver *Panel) Handle(ctx console.Context) error {
err := os.Setenv("MYSQL_PWD", rootPassword)
if err != nil {
color.Redln("|-备份MySQL数据库失败: " + err.Error())
color.Redln("|-" + translate.Get("commands.panel.backup.mysqlBackupFail") + ": " + err.Error())
color.Greenln(hr)
return nil
}
color.Greenln("|-目标MySQL数据库: " + name)
color.Greenln("|-开始导出")
color.Greenln("|-" + translate.Get("commands.panel.backup.targetMysql") + ": " + name)
color.Greenln("|-" + translate.Get("commands.panel.backup.startExport"))
if _, err = tools.Exec(`mysqldump -uroot ` + name + ` > /tmp/` + backupFile + ` 2>&1`); err != nil {
color.Redln("|-导出失败: " + err.Error())
color.Redln("|-" + translate.Get("commands.panel.backup.exportFail") + ": " + err.Error())
return nil
}
color.Greenln("|-导出成功")
color.Greenln("|-开始压缩")
color.Greenln("|-" + translate.Get("commands.panel.backup.exportSuccess"))
color.Greenln("|-" + translate.Get("commands.panel.backup.startCompress"))
if _, err = tools.Exec("cd /tmp && zip -r " + backupFile + ".zip " + backupFile); err != nil {
color.Redln("|-压缩失败: " + err.Error())
color.Redln("|-" + translate.Get("commands.panel.backup.compressFail") + ": " + err.Error())
return nil
}
if err := tools.Remove("/tmp/" + backupFile); err != nil {
color.Redln("|-删除失败: " + err.Error())
color.Redln("|-" + translate.Get("commands.panel.backup.deleteFail") + ": " + err.Error())
return nil
}
color.Greenln("|-压缩成功")
color.Greenln("|-开始移动")
color.Greenln("|-" + translate.Get("commands.panel.backup.compressSuccess"))
color.Greenln("|-" + translate.Get("commands.panel.backup.startMove"))
if err := tools.Mv("/tmp/"+backupFile+".zip", path+"/"+backupFile+".zip"); err != nil {
color.Redln("|-移动失败: " + err.Error())
color.Redln("|-" + translate.Get("commands.panel.backup.moveFail") + ": " + err.Error())
return nil
}
color.Greenln("|-移动成功")
color.Greenln("|-" + translate.Get("commands.panel.backup.moveSuccess"))
_ = os.Unsetenv("MYSQL_PWD")
color.Greenln("|-备份成功")
color.Greenln("|-" + 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("|-获取数据库失败: " + err.Error())
color.Redln("|-" + translate.Get("commands.panel.backup.databaseGetFail") + ": " + err.Error())
color.Greenln(hr)
return nil
}
if !strings.Contains(check, name) {
color.Redln("|-数据库不存在")
color.Redln("|-" + translate.Get("commands.panel.backup.databaseNotExist"))
color.Greenln(hr)
return nil
}
color.Greenln("|-目标PostgreSQL数据库: " + name)
color.Greenln("|-开始导出")
color.Greenln("|-" + translate.Get("commands.panel.backup.targetPostgres") + ": " + name)
color.Greenln("|-" + translate.Get("commands.panel.backup.startExport"))
if _, err = tools.Exec(`su - postgres -c "pg_dump '` + name + `'" > /tmp/` + backupFile + ` 2>&1`); err != nil {
color.Redln("|-导出失败: " + err.Error())
color.Redln("|-" + translate.Get("commands.panel.backup.exportFail") + ": " + err.Error())
return nil
}
color.Greenln("|-导出成功")
color.Greenln("|-开始压缩")
color.Greenln("|-" + translate.Get("commands.panel.backup.exportSuccess"))
color.Greenln("|-" + translate.Get("commands.panel.backup.startCompress"))
if _, err = tools.Exec("cd /tmp && zip -r " + backupFile + ".zip " + backupFile); err != nil {
color.Redln("|-压缩失败: " + err.Error())
color.Redln("|-" + translate.Get("commands.panel.backup.compressFail") + ": " + err.Error())
return nil
}
if err := tools.Remove("/tmp/" + backupFile); err != nil {
color.Redln("|-删除失败: " + err.Error())
color.Redln("|-" + translate.Get("commands.panel.backup.deleteFail") + ": " + err.Error())
return nil
}
color.Greenln("|-压缩成功")
color.Greenln("|-开始移动")
color.Greenln("|-" + translate.Get("commands.panel.backup.compressSuccess"))
color.Greenln("|-" + translate.Get("commands.panel.backup.startMove"))
if err := tools.Mv("/tmp/"+backupFile+".zip", path+"/"+backupFile+".zip"); err != nil {
color.Redln("|-移动失败: " + err.Error())
color.Redln("|-" + translate.Get("commands.panel.backup.moveFail") + ": " + err.Error())
return nil
}
color.Greenln("|-移动成功")
color.Greenln("|-备份成功")
color.Greenln("|-" + translate.Get("commands.panel.backup.moveSuccess"))
color.Greenln("|-" + translate.Get("commands.panel.backup.success"))
}
color.Greenln(hr)
files, err := os.ReadDir(path)
if err != nil {
color.Redln("|-清理失败: " + err.Error())
color.Redln("|-" + translate.Get("commands.panel.backup.cleanupFail") + ": " + err.Error())
return nil
}
var filteredFiles []os.FileInfo
@@ -381,15 +385,15 @@ 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("|-清理备份: " + fileToDelete)
color.Yellowln("|-" + translate.Get("commands.panel.backup.cleanBackup") + ": " + fileToDelete)
if err := tools.Remove(fileToDelete); err != nil {
color.Redln("|-清理失败: " + err.Error())
color.Redln("|-" + translate.Get("commands.panel.backup.cleanupFail") + ": " + err.Error())
return nil
}
}
color.Greenln("|-清理完成")
color.Greenln("|-" + translate.Get("commands.panel.backup.cleanupSuccess"))
color.Greenln(hr)
color.Greenln("☆ 备份完成 [" + carbon.Now().ToDateTimeString() + "]")
color.Greenln("☆ " + translate.Get("commands.panel.backup.success") + " [" + carbon.Now().ToDateTimeString() + "]")
color.Greenln(hr)
case "cutoff":
@@ -397,44 +401,44 @@ func (receiver *Panel) Handle(ctx console.Context) error {
save := arg2
hr := `+----------------------------------------------------`
if len(name) == 0 || len(save) == 0 {
color.Redln("参数错误")
color.Redln(translate.Get("commands.panel.cutoff.paramFail"))
return nil
}
color.Greenln(hr)
color.Greenln("★ 开始切割 [" + carbon.Now().ToDateTimeString() + "]")
color.Greenln("★ " + translate.Get("commands.panel.cutoff.start") + " [" + carbon.Now().ToDateTimeString() + "]")
color.Greenln(hr)
color.Yellowln("|-目标网站: " + name)
color.Yellowln("|-" + 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("|-网站不存在")
color.Redln("|-" + translate.Get("commands.panel.cutoff.siteNotExist"))
color.Greenln(hr)
return nil
}
logPath := "/www/wwwlogs/" + website.Name + ".log"
if !tools.Exists(logPath) {
color.Redln("|-日志文件不存在")
color.Redln("|-" + translate.Get("commands.panel.cutoff.logNotExist"))
color.Greenln(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("|-备份失败: " + err.Error())
color.Redln("|-" + translate.Get("commands.panel.cutoff.backupFail") + ": " + err.Error())
return nil
}
if _, err := tools.Exec(`echo "" > ` + logPath); err != nil {
color.Redln("|-清空失败: " + err.Error())
color.Redln("|-" + translate.Get("commands.panel.cutoff.clearFail") + ": " + err.Error())
return nil
}
color.Greenln("|-切割成功")
color.Greenln("|-" + translate.Get("commands.panel.cutoff.cutSuccess"))
color.Greenln(hr)
files, err := os.ReadDir("/www/wwwlogs")
if err != nil {
color.Redln("|-清理失败: " + err.Error())
color.Redln("|-" + translate.Get("commands.panel.cutoff.cleanupFail") + ": " + err.Error())
return nil
}
var filteredFiles []os.FileInfo
@@ -452,15 +456,15 @@ 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("|-清理日志: " + fileToDelete)
color.Yellowln("|-" + translate.Get("commands.panel.cutoff.clearLog") + ": " + fileToDelete)
if err := tools.Remove(fileToDelete); err != nil {
color.Redln("|-清理失败: " + err.Error())
color.Redln("|-" + translate.Get("commands.panel.cutoff.cleanupFail") + ": " + err.Error())
return nil
}
}
color.Greenln("|-清理完成")
color.Greenln("|-" + translate.Get("commands.panel.cutoff.cleanupSuccess"))
color.Greenln(hr)
color.Greenln("☆ 切割完成 [" + carbon.Now().ToDateTimeString() + "]")
color.Greenln("☆ " + translate.Get("commands.panel.cutoff.end") + " [" + carbon.Now().ToDateTimeString() + "]")
color.Greenln(hr)
case "writeSite":
@@ -470,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("参数错误")
color.Redln(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("网站已存在")
color.Redln(translate.Get("commands.panel.writeSite.siteExist"))
return nil
}
_, err := os.Stat(path)
if os.IsNotExist(err) {
color.Redln("网站目录不存在")
color.Redln(translate.Get("commands.panel.writeSite.pathNotExist"))
return nil
}
@@ -494,32 +498,32 @@ func (receiver *Panel) Handle(ctx console.Context) error {
Ssl: ssl,
})
if err != nil {
color.Redln("写入网站失败")
color.Redln(translate.Get("commands.panel.writeSite.fail"))
return nil
}
color.Greenln("写入网站成功")
color.Greenln(translate.Get("commands.panel.writeSite.success"))
case "deleteSite":
name := arg1
if len(name) == 0 {
color.Redln("参数错误")
color.Redln(translate.Get("commands.panel.deleteSite.paramFail"))
return nil
}
_, err := facades.Orm().Query().Where("name", name).Delete(&models.Website{})
if err != nil {
color.Redln("删除网站失败")
color.Redln(translate.Get("commands.panel.deleteSite.fail"))
return nil
}
color.Greenln("删除网站成功")
color.Greenln(translate.Get("commands.panel.deleteSite.success"))
case "writeSetting":
key := arg1
value := arg2
if len(key) == 0 || len(value) == 0 {
color.Redln("参数错误")
color.Redln(translate.Get("commands.panel.writeSetting.paramFail"))
return nil
}
@@ -530,16 +534,16 @@ func (receiver *Panel) Handle(ctx console.Context) error {
Value: value,
})
if err != nil {
color.Redln("写入设置失败")
color.Redln(translate.Get("commands.panel.writeSetting.fail"))
return nil
}
color.Greenln("写入设置成功")
color.Greenln(translate.Get("commands.panel.writeSetting.success"))
case "getSetting":
key := arg1
if len(key) == 0 {
color.Redln("参数错误")
color.Redln(translate.Get("commands.panel.getSetting.paramFail"))
return nil
}
@@ -553,17 +557,17 @@ func (receiver *Panel) Handle(ctx console.Context) error {
case "deleteSetting":
key := arg1
if len(key) == 0 {
color.Redln("参数错误")
color.Redln(translate.Get("commands.panel.deleteSetting.paramFail"))
return nil
}
_, err := facades.Orm().Query().Where("key", key).Delete(&models.Setting{})
if err != nil {
color.Redln("删除设置失败")
color.Redln(translate.Get("commands.panel.deleteSetting.fail"))
return nil
}
color.Greenln("删除设置成功")
color.Greenln(translate.Get("commands.panel.deleteSetting.success"))
case "addSite":
name := arg1
@@ -572,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("参数错误")
color.Redln(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("参数错误")
color.Redln(translate.Get("commands.panel.addSite.paramFail"))
return nil
}
@@ -595,7 +599,7 @@ func (receiver *Panel) Handle(ctx console.Context) error {
return nil
}
if id != 0 {
color.Redln("网站名已存在")
color.Redln(translate.Get("commands.panel.addSite.siteExist"))
return nil
}
@@ -614,12 +618,12 @@ func (receiver *Panel) Handle(ctx console.Context) error {
return nil
}
color.Greenln("网站添加成功")
color.Greenln(translate.Get("commands.panel.addSite.success"))
case "removeSite":
name := arg1
if len(name) == 0 {
color.Redln("参数错误")
color.Redln(translate.Get("commands.panel.removeSite.paramFail"))
return nil
}
@@ -630,7 +634,7 @@ func (receiver *Panel) Handle(ctx console.Context) error {
return nil
}
if id == 0 {
color.Redln("网站名不存在")
color.Redln(translate.Get("commands.panel.removeSite.siteNotExist"))
return nil
}
@@ -639,12 +643,12 @@ func (receiver *Panel) Handle(ctx console.Context) error {
return nil
}
color.Greenln("网站删除成功")
color.Greenln(translate.Get("commands.panel.removeSite.success"))
case "installPlugin":
slug := arg1
if len(slug) == 0 {
color.Redln("参数错误")
color.Redln(translate.Get("commands.panel.installPlugin.paramFail"))
return nil
}
@@ -654,12 +658,12 @@ func (receiver *Panel) Handle(ctx console.Context) error {
return nil
}
color.Greenln("任务已提交")
color.Greenln(translate.Get("commands.panel.installPlugin.success"))
case "uninstallPlugin":
slug := arg1
if len(slug) == 0 {
color.Redln("参数错误")
color.Redln(translate.Get("commands.panel.uninstallPlugin.paramFail"))
return nil
}
@@ -669,12 +673,12 @@ func (receiver *Panel) Handle(ctx console.Context) error {
return nil
}
color.Greenln("任务已提交")
color.Greenln(translate.Get("commands.panel.uninstallPlugin.success"))
case "updatePlugin":
slug := arg1
if len(slug) == 0 {
color.Redln("参数错误")
color.Redln(translate.Get("commands.panel.updatePlugin.paramFail"))
return nil
}
@@ -684,34 +688,34 @@ func (receiver *Panel) Handle(ctx console.Context) error {
return nil
}
color.Greenln("任务已提交")
color.Greenln(translate.Get("commands.panel.updatePlugin.success"))
default:
color.Yellowln(facades.Config().GetString("panel.name") + "命令行工具 - " + facades.Config().GetString("panel.version"))
color.Greenln("请使用以下命令")
color.Greenln("panel update 更新 / 修复面板到最新版本")
color.Greenln("panel getInfo 重新初始化面板账号信息")
color.Greenln("panel getPort 获取面板访问端口")
color.Greenln("panel getEntrance 获取面板访问入口")
color.Greenln("panel deleteEntrance 删除面板访问入口")
color.Greenln("panel cleanTask 清理面板运行中和等待中的任务[任务卡住时使用]")
color.Greenln("panel backup {website/mysql/postgresql} {name} {path} {save_copies} 备份网站 / MySQL数据库 / PostgreSQL数据库到指定目录并保留指定数量")
color.Greenln("panel cutoff {website_name} {save_copies} 切割网站日志并保留指定数量")
color.Greenln("panel installPlugin {slug} 安装插件")
color.Greenln("panel uninstallPlugin {slug} 卸载插件")
color.Greenln("panel updatePlugin {slug} 更新插件")
color.Greenln("panel addSite {name} {domain} {port} {path} {php} 添加网站[域名和端口用英文逗号分隔]")
color.Greenln("panel removeSite {name} 删除网站")
color.Redln("以下命令请在开发者指导下使用:")
color.Yellowln("panel init 初始化面板")
color.Yellowln("panel writePlugin {slug} {version} 写入插件安装状态")
color.Yellowln("panel deletePlugin {slug} 移除插件安装状态")
color.Yellowln("panel writeMysqlPassword {password} 写入MySQL root密码")
color.Yellowln("panel writeSite {name} {status} {path} {php} {ssl} 写入网站数据到面板")
color.Yellowln("panel deleteSite {name} 删除面板网站数据")
color.Yellowln("panel getSetting {name} 获取面板设置数据")
color.Yellowln("panel writeSetting {name} {value} 写入 / 更新面板设置数据")
color.Yellowln("panel deleteSetting {name} 删除面板设置数据")
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"))
}
return nil

View File

@@ -1,6 +1,8 @@
package commands
import (
"context"
"github.com/goravel/framework/contracts/console"
"github.com/goravel/framework/contracts/console/command"
"github.com/goravel/framework/facades"
@@ -21,7 +23,7 @@ func (receiver *PanelTask) Signature() string {
// Description The console command description.
func (receiver *PanelTask) Description() string {
return "[面板] 每日任务"
return facades.Lang(context.Background()).Get("commands.panel:task.description")
}
// Extend The console command extend.
@@ -32,7 +34,7 @@ func (receiver *PanelTask) Extend() command.Extend {
}
// Handle Execute the console command.
func (receiver *PanelTask) Handle(ctx console.Context) error {
func (receiver *PanelTask) Handle(console.Context) error {
internal.Status = internal.StatusMaintain
// 优化数据库

View File

@@ -2,6 +2,7 @@ package controllers
import (
"github.com/goravel/framework/contracts/http"
"github.com/goravel/framework/facades"
)
// SuccessResponse 通用成功响应
@@ -26,14 +27,14 @@ func Success(ctx http.Context, data any) http.Response {
// Error 响应错误
func Error(ctx http.Context, code int, message string) http.Response {
return ctx.Response().Json(code, &ErrorResponse{
Message: "错误: " + message,
Message: facades.Lang(ctx).Get("messages.mistake") + ": " + message,
})
}
// ErrorSystem 响应系统错误
func ErrorSystem(ctx http.Context) http.Response {
return ctx.Response().Json(http.StatusInternalServerError, &ErrorResponse{
Message: "系统内部错误",
Message: facades.Lang(ctx).Get("errors.internal"),
})
}

View File

@@ -11,10 +11,11 @@ import (
// Jwt 确保通过 JWT 鉴权
func Jwt() http.Middleware {
return func(ctx http.Context) {
translate := facades.Lang(ctx)
token := ctx.Request().Header("Authorization", ctx.Request().Header("Sec-WebSocket-Protocol"))
if len(token) == 0 {
ctx.Request().AbortWithStatusJson(http.StatusUnauthorized, http.Json{
"message": "未登录",
"message": translate.Get("auth.token.missing"),
})
return
}
@@ -26,7 +27,7 @@ func Jwt() http.Middleware {
if err != nil {
// 到达刷新时间上限
ctx.Request().AbortWithStatusJson(http.StatusUnauthorized, http.Json{
"message": "登录已过期",
"message": translate.Get("auth.token.expired"),
})
return
}
@@ -34,7 +35,7 @@ func Jwt() http.Middleware {
token = "Bearer " + token
} else {
ctx.Request().AbortWithStatusJson(http.StatusUnauthorized, http.Json{
"message": "登录已过期",
"message": translate.Get("auth.token.expired"),
})
return
}

View File

@@ -4,6 +4,8 @@ import (
"strings"
"github.com/goravel/framework/contracts/http"
"github.com/goravel/framework/contracts/translation"
"github.com/goravel/framework/facades"
"panel/internal/services"
)
@@ -12,6 +14,7 @@ import (
func MustInstall() http.Middleware {
return func(ctx http.Context) {
path := ctx.Request().Path()
translate := facades.Lang(ctx)
var slug string
if strings.HasPrefix(path, "/api/panel/website") {
slug = "openresty"
@@ -19,7 +22,7 @@ func MustInstall() http.Middleware {
pathArr := strings.Split(path, "/")
if len(pathArr) < 4 {
ctx.Request().AbortWithStatusJson(http.StatusForbidden, http.Json{
"message": "插件不存在",
"message": translate.Get("errors.plugin.notExist"),
})
return
}
@@ -31,14 +34,18 @@ func MustInstall() http.Middleware {
installedPlugins, err := services.NewPluginImpl().AllInstalled()
if err != nil {
ctx.Request().AbortWithStatusJson(http.StatusInternalServerError, http.Json{
"message": "系统内部错误",
"message": translate.Get("errors.internal"),
})
return
}
if installedPlugin.Slug != plugin.Slug {
ctx.Request().AbortWithStatusJson(http.StatusForbidden, http.Json{
"message": "插件 " + slug + " 未安装",
"message": translate.Get("errors.plugin.notInstalled", translation.Option{
Replace: map[string]string{
"slug": slug,
},
}),
})
return
}
@@ -53,7 +60,12 @@ func MustInstall() http.Middleware {
_, requireFound := pluginsMap[require]
if !requireFound {
ctx.Request().AbortWithStatusJson(http.StatusForbidden, http.Json{
"message": "插件 " + slug + " 需要依赖 " + require + " 插件",
"message": translate.Get("errors.plugin.dependent", translation.Option{
Replace: map[string]string{
"slug": slug,
"dependency": require,
},
}),
})
return
}
@@ -63,7 +75,12 @@ func MustInstall() http.Middleware {
_, excludeFound := pluginsMap[exclude]
if excludeFound {
ctx.Request().AbortWithStatusJson(http.StatusForbidden, http.Json{
"message": "插件 " + slug + " 不兼容 " + exclude + " 插件",
"message": translate.Get("errors.plugin.incompatible", translation.Option{
Replace: map[string]string{
"slug": slug,
"exclude": exclude,
},
}),
})
return
}

View File

@@ -2,6 +2,7 @@ package middleware
import (
"github.com/goravel/framework/contracts/http"
"github.com/goravel/framework/facades"
"panel/internal"
)
@@ -9,25 +10,26 @@ import (
// Status 检查程序状态
func Status() http.Middleware {
return func(ctx http.Context) {
translate := facades.Lang(ctx)
switch internal.Status {
case internal.StatusUpgrade:
ctx.Request().AbortWithStatusJson(http.StatusServiceUnavailable, http.Json{
"message": "面板升级中,请稍后",
"message": translate.Get("status.upgrade"),
})
return
case internal.StatusMaintain:
ctx.Request().AbortWithStatusJson(http.StatusServiceUnavailable, http.Json{
"message": "面板正在运行维护,请稍后",
"message": translate.Get("status.maintain"),
})
return
case internal.StatusClosed:
ctx.Request().AbortWithStatusJson(http.StatusForbidden, http.Json{
"message": "面板已关闭",
"message": translate.Get("status.closed"),
})
return
case internal.StatusFailed:
ctx.Request().AbortWithStatusJson(http.StatusInternalServerError, http.Json{
"message": "面板运行出错,请检查排除或联系支持",
"message": translate.Get("status.failed"),
})
return
default:

View File

@@ -19,6 +19,7 @@ import (
"github.com/goravel/framework/schedule"
"github.com/goravel/framework/support/carbon"
"github.com/goravel/framework/testing"
"github.com/goravel/framework/translation"
"github.com/goravel/framework/validation"
"github.com/goravel/gin"
@@ -60,7 +61,7 @@ func init() {
// The application locale determines the default locale that will be used
// by the translation service provider.You are free to set this value
// to any of the locales which will be supported by the application.
"locale": "zh_CN",
"locale": config.Env("APP_LOCALE", "zh_CN"),
// Application Fallback Locale
//
@@ -96,6 +97,7 @@ func init() {
&crypt.ServiceProvider{},
&filesystem.ServiceProvider{},
&validation.ServiceProvider{},
&translation.ServiceProvider{},
&testing.ServiceProvider{},
&providers.AppServiceProvider{},
&providers.AuthServiceProvider{},

205
lang/en.json Normal file
View File

@@ -0,0 +1,205 @@
{
"auth": {
"token": {
"expired": "login has expired",
"missing": "not logged in"
}
},
"commands": {
"panel:cert-renew": {
"description": "[Panel] Certificate renewal"
},
"panel:monitoring": {
"description": "[Panel] System Monitoring",
"fail": "[Panel] System monitoring failed to save"
},
"panel": {
"description": "[Panel] Command line",
"forDeveloper": "Please use the following commands under the guidance of the developer",
"use": "Please use the following commands",
"tool": "command line tool",
"portFail": "failed to get panel port",
"port": "Panel port",
"entrance": "Panel entrance",
"update": {
"description": "update/fix panel to latest version",
"taskCheck": "There is currently a task being executed and updates are prohibited.",
"versionFail": "failed to get latest version",
"fail": "update failed",
"success": "update completed"
},
"getInfo": {
"description": "reinitialize panel account information",
"adminGetFail": "failed to get administrator information",
"adminSaveFail": "failed to save administrator information",
"passwordGenerationFail": "failed to generate password",
"username": "Username",
"password": "Password",
"address": "Panel address"
},
"getPort": {
"description": "get the panel access port"
},
"getEntrance": {
"description": "get panel access"
},
"deleteEntrance": {
"description": "delete panel access",
"fail": "failed to delete panel entrance",
"success": "panel entrance deleted successfully"
},
"cleanTask": {
"description": "clean up running and waiting tasks in the panel [used when tasks are stuck]",
"fail": "failed to clean up tasks",
"success": "tasks cleaned up successfully"
},
"backup": {
"description": "back up website/MySQL database/PostgreSQL database to the specified directory and retain the specified amount",
"paramFail": "backup type, path, name and keep amount are required",
"start": "start backup",
"backupDirFail": "failed to create backup directory",
"targetSite": "target website",
"siteNotExist": "website does not exist",
"backupFail": "backup failed",
"backupSuccess": "backup successful",
"mysqlBackupFail": "MySQL database backup failed",
"targetMysql": "target MySQL database",
"startExport": "start exporting",
"exportFail": "export failed",
"exportSuccess": "export successful",
"startCompress": "start compressing",
"compressFail": "compression failed",
"compressSuccess": "compression successful",
"startMove": "start moving",
"moveFail": "move failed",
"moveSuccess": "move successful",
"databaseGetFail": "failed to get database",
"databaseNotExist": "database does not exist",
"targetPostgres": "target PostgreSQL database",
"cleanBackup" : "clean backup",
"cleanupFail": "cleanup failed",
"cleanupSuccess": "cleanup successful",
"deleteFail": "failed to delete",
"success": "backup completed"
},
"cutoff": {
"description": "cut website logs and keep specified amount",
"paramFail": "website domain name and keep amount are required",
"start": "start cutting",
"targetSite": "target website",
"siteNotExist": "website does not exist",
"logNotExist": "log file does not exist",
"backupFail": "backup failed",
"clearFail": "clearing failed",
"cleanupFail": "cleanup failed",
"clearLog": "clear log",
"cutSuccess": "cutting successful",
"cleanupSuccess": "cleanup successful",
"end": "cutting completed"
},
"installPlugin": {
"description": "install plugin",
"paramFail": "plugin slug is required",
"success": "task has been submitted"
},
"uninstallPlugin": {
"description": "uninstall plugin",
"paramFail": "plugin slug is required",
"success": "task has been submitted"
},
"updatePlugin": {
"description": "update plugin",
"paramFail": "plugin slug is required",
"success": "task has been submitted"
},
"addSite": {
"description": "add website [domain name and port separated by commas]",
"paramFail": "name, domain, port and path are required",
"siteExist": "website already exists",
"success": "website added successfully"
},
"removeSite": {
"description": "remove website",
"paramFail": "name is required",
"siteNotExist": "website does not exist",
"success": "website deleted successfully"
},
"init": {
"description": "initialize the panel",
"exist": "panel has been initialized",
"success": "initialization successful",
"adminFound": "failed to create administrator",
"fail": "initialization failed"
},
"writePlugin": {
"description": "write plugin installation status",
"paramFail": "plugin slug and version are required",
"fail": "failed to write plugin installation status",
"success": "plugin installation status written successfully"
},
"deletePlugin": {
"description": "delete plugin installation status",
"paramFail": "plugin slug is required",
"fail": "failed to remove plugin installation status",
"success": "plugin installation status removed successfully"
},
"writeMysqlPassword": {
"description": "write MySQL root password",
"paramFail": "MySQL root password is required",
"fail": "failed to write MySQL root password",
"success": "MySQL root password written successfully"
},
"writeSite": {
"description": "write website data to the panel",
"paramFail": "name and path are required",
"siteExist": "website already exists",
"pathNotExist": "website directory does not exist",
"fail": "failed to write to website",
"success": "writing to website successfully"
},
"deleteSite": {
"description": "delete panel website data",
"paramFail": "website name is required",
"fail": "failed to delete website",
"success": "website deleted successfully"
},
"getSetting": {
"description": "get panel setting data",
"paramFail": "key is required"
},
"writeSetting": {
"description": "write/update panel setting data",
"paramFail": "key and value are required",
"fail": "Writing settings failed",
"success": "settings written successfully"
},
"deleteSetting": {
"description": "delete panel setting data",
"paramFail": "key is required",
"fail": "failed to delete settings",
"success": "settings deleted successfully"
}
},
"panel:task": {
"description": "[Panel] Daily tasks"
}
},
"errors": {
"internal": "internal system error",
"plugin": {
"notExist": "plugin does not exist",
"notInstalled": "plugin :slug is not installed",
"dependent": "plugin :slug requires dependency :dependency",
"incompatible": "plugin :slug is incompatible with :exclude plugin"
}
},
"messages": {
"mistake": "mistake"
},
"status": {
"upgrade": "Panel is currently undergoing an upgrade. Please try again later.",
"maintain": "Panel is currently undergoing maintenance. Please try again later.",
"closed": "Panel is closed.",
"failed": "Panel encountered an error during operation. Please check the troubleshooting or contact support."
}
}

205
lang/zh_CN.json Normal file
View File

@@ -0,0 +1,205 @@
{
"auth": {
"token": {
"expired": "登录已过期",
"missing": "未登录"
}
},
"commands": {
"panel:cert-renew": {
"description": "[面板] 证书续签"
},
"panel:monitoring": {
"description": "[面板] 系统监控",
"fail": "[面板] 系统监控保存失败"
},
"panel": {
"description": "[面板] 命令行",
"forDeveloper": "以下命令请在开发者指导下使用",
"use": "请使用以下命令",
"tool": "命令行工具",
"port": "面板端口",
"portFail": "获取面板端口失败",
"entrance": "面板入口",
"update": {
"description": "更新 / 修复面板到最新版本",
"taskCheck": "当前有任务正在执行,禁止更新",
"versionFail": "获取最新版本失败",
"fail": "更新失败",
"success": "更新成功"
},
"getInfo": {
"description": "重新初始化面板账号信息",
"adminGetFail": "获取管理员信息失败",
"adminSaveFail": "保存管理员信息失败",
"passwordGenerationFail": "生成密码失败",
"username": "用户名",
"password": "密码",
"address": "面板地址"
},
"getPort": {
"description": "获取面板访问端口"
},
"getEntrance": {
"description": "获取面板访问入口"
},
"deleteEntrance": {
"description": "删除面板访问入口",
"fail": "删除面板入口失败",
"success": "删除面板入口成功"
},
"cleanTask": {
"description": "清理面板运行中和等待中的任务[任务卡住时使用]",
"fail": "清理任务失败",
"success": "清理任务成功"
},
"backup": {
"description": "备份网站 / MySQL数据库 / PostgreSQL数据库到指定目录并保留指定数量",
"paramFail": "参数错误",
"start": "开始备份",
"backupDirFail": "创建备份目录失败",
"targetSite": "目标网站",
"siteNotExist": "网站不存在",
"backupFail": "备份失败",
"backupSuccess": "备份成功",
"mysqlBackupFail": "备份MySQL数据库失败",
"targetMysql": "目标MySQL数据库",
"startExport": "开始导出",
"exportFail": "导出失败",
"exportSuccess": "导出成功",
"startCompress": "开始压缩",
"compressFail": "压缩失败",
"compressSuccess": "压缩成功",
"startMove": "开始移动",
"moveFail": "移动失败",
"moveSuccess": "移动成功",
"databaseGetFail": "获取数据库失败",
"databaseNotExist": "数据库不存在",
"targetPostgres": "目标PostgreSQL数据库",
"cleanBackup": "清理备份",
"cleanupFail": "清理失败",
"cleanupSuccess": "清理完成",
"deleteFail": "删除失败",
"success": "备份完成"
},
"cutoff": {
"description": "切割网站日志并保留指定数量",
"paramFail": "参数错误",
"start": "开始切割",
"targetSite": "目标网站",
"siteNotExist": "网站不存在",
"logNotExist": "日志文件不存在",
"backupFail": "备份失败",
"clearFail": "清空失败",
"cleanupFail": "清理失败",
"clearLog": "清理日志",
"cutSuccess": "切割成功",
"cleanupSuccess": "清理完成",
"end": "切割完成"
},
"installPlugin": {
"description": "安装插件",
"paramFail": "参数错误",
"success": "任务已提交"
},
"uninstallPlugin": {
"description": "卸载插件",
"paramFail": "参数错误",
"success": "任务已提交"
},
"updatePlugin": {
"description": "更新插件",
"paramFail": "参数错误",
"success": "任务已提交"
},
"addSite": {
"description": "添加网站[域名和端口用英文逗号分隔]",
"paramFail": "参数错误",
"siteExist": "网站名已存在",
"success": "网站添加成功"
},
"removeSite": {
"description": "删除网站",
"paramFail": "参数错误",
"siteNotExist": "网站名不存在",
"success": "网站删除成功"
},
"init": {
"description": "初始化面板",
"exist": "面板已初始化",
"success": "初始化成功",
"adminFail": "创建管理员失败",
"fail": "初始化失败"
},
"writePlugin": {
"description": "写入插件安装状态",
"paramFail": "参数错误",
"fail": "写入插件安装状态失败",
"success": "写入插件安装状态成功"
},
"deletePlugin": {
"description": "移除插件安装状态",
"paramFail": "参数错误",
"fail": "移除插件安装状态失败",
"success": "移除插件安装状态成功"
},
"writeMysqlPassword": {
"description": "写入MySQL root密码",
"paramFail": "参数错误",
"fail": "写入MySQL root密码失败",
"success": "写入MySQL root密码成功"
},
"writeSite": {
"description": "写入网站数据到面板",
"paramFail": "参数错误",
"siteExist": "网站已存在",
"pathNotExist": "网站目录不存在",
"fail": "写入网站失败",
"success": "写入网站成功"
},
"deleteSite": {
"description": "删除面板网站数据",
"paramFail": "参数错误",
"fail": "删除网站失败",
"success": "删除网站成功"
},
"getSetting": {
"description": "获取面板设置数据",
"paramFail": "参数错误"
},
"writeSetting": {
"description": "写入 / 更新面板设置数据",
"paramFail": "参数错误",
"fail": "写入设置失败",
"success": "写入设置成功"
},
"deleteSetting": {
"description": "删除面板设置数据",
"paramFail": "参数错误",
"fail": "删除设置失败",
"success": "删除设置成功"
}
},
"panel:task": {
"description": "[面板] 每日任务"
}
},
"errors": {
"internal": "系统内部错误",
"plugin": {
"notExist": "插件不存在",
"notInstalled": "插件 :slug 未安装",
"dependent": "插件 :slug 需要依赖 :dependency 插件",
"incompatible": "插件 :slug 不兼容 :exclude 插件"
}
},
"messages": {
"mistake": "错误"
},
"status": {
"upgrade": "面板升级中,请稍后",
"maintain": "面板正在运行维护,请稍后",
"closed": "面板已关闭",
"failed": "面板运行出错,请检查排除或联系支持"
}
}

View File

@@ -4,5 +4,6 @@ APP_DEBUG=false
APP_PORT=8888
APP_ENTRANCE=/
APP_SSL=false
APP_LOCALE=
JWT_SECRET=