mirror of
https://github.com/Buriburizaem0n/nezha_domains.git
synced 2026-02-04 12:40:07 +00:00
feat: add i18n support
This commit is contained in:
@@ -1,8 +1,6 @@
|
||||
package controller
|
||||
|
||||
import (
|
||||
"errors"
|
||||
"fmt"
|
||||
"strconv"
|
||||
"time"
|
||||
|
||||
@@ -99,7 +97,7 @@ func updateAlertRule(c *gin.Context) (any, error) {
|
||||
|
||||
var r model.AlertRule
|
||||
if err := singleton.DB.First(&r, id).Error; err != nil {
|
||||
return nil, fmt.Errorf("alert id %d does not exist", id)
|
||||
return nil, singleton.Localizer.ErrorT("alert id %d does not exist", id)
|
||||
}
|
||||
|
||||
if err := validateRule(&r); err != nil {
|
||||
@@ -154,22 +152,22 @@ func validateRule(r *model.AlertRule) error {
|
||||
for _, rule := range r.Rules {
|
||||
if !rule.IsTransferDurationRule() {
|
||||
if rule.Duration < 3 {
|
||||
return errors.New("错误: Duration 至少为 3")
|
||||
return singleton.Localizer.ErrorT("duration need to be at least 3")
|
||||
}
|
||||
} else {
|
||||
if rule.CycleInterval < 1 {
|
||||
return errors.New("错误: cycle_interval 至少为 1")
|
||||
return singleton.Localizer.ErrorT("cycle_interval need to be at least 1")
|
||||
}
|
||||
if rule.CycleStart == nil {
|
||||
return errors.New("错误: cycle_start 未设置")
|
||||
return singleton.Localizer.ErrorT("cycle_start is not set")
|
||||
}
|
||||
if rule.CycleStart.After(time.Now()) {
|
||||
return errors.New("错误: cycle_start 是个未来值")
|
||||
return singleton.Localizer.ErrorT("cycle_start is a future value")
|
||||
}
|
||||
}
|
||||
}
|
||||
} else {
|
||||
return errors.New("至少定义一条规则")
|
||||
return singleton.Localizer.ErrorT("need to configure at least a single rule")
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
@@ -185,7 +185,7 @@ func commonHandler[T any](handler handlerFunc[T]) func(*gin.Context) {
|
||||
switch err.(type) {
|
||||
case *gormError:
|
||||
log.Printf("NEZHA>> gorm error: %v", err)
|
||||
c.JSON(http.StatusOK, newErrorResponse(errors.New("database error")))
|
||||
c.JSON(http.StatusOK, newErrorResponse(singleton.Localizer.ErrorT("database error")))
|
||||
return
|
||||
case *wsError:
|
||||
// Connection is upgraded to WebSocket, so c.Writer is no longer usable
|
||||
|
||||
@@ -1,7 +1,6 @@
|
||||
package controller
|
||||
|
||||
import (
|
||||
"errors"
|
||||
"fmt"
|
||||
"strconv"
|
||||
|
||||
@@ -61,7 +60,7 @@ func createCron(c *gin.Context) (uint64, error) {
|
||||
cr.Cover = cf.Cover
|
||||
|
||||
if cr.TaskType == model.CronTypeCronTask && cr.Cover == model.CronCoverAlertTrigger {
|
||||
return 0, errors.New("计划任务类型不得使用触发服务器执行方式")
|
||||
return 0, singleton.Localizer.ErrorT("scheduled tasks cannot be triggered by alarms")
|
||||
}
|
||||
|
||||
// 对于计划任务类型,需要更新CronJob
|
||||
@@ -120,7 +119,7 @@ func updateCron(c *gin.Context) (any, error) {
|
||||
cr.Cover = cf.Cover
|
||||
|
||||
if cr.TaskType == model.CronTypeCronTask && cr.Cover == model.CronCoverAlertTrigger {
|
||||
return nil, errors.New("计划任务类型不得使用触发服务器执行方式")
|
||||
return nil, singleton.Localizer.ErrorT("scheduled tasks cannot be triggered by alarms")
|
||||
}
|
||||
|
||||
// 对于计划任务类型,需要更新CronJob
|
||||
@@ -159,7 +158,7 @@ func manualTriggerCron(c *gin.Context) (any, error) {
|
||||
|
||||
var cr model.Cron
|
||||
if err := singleton.DB.First(&cr, id).Error; err != nil {
|
||||
return nil, fmt.Errorf("task id %d does not exist", id)
|
||||
return nil, singleton.Localizer.ErrorT("task id %d does not exist", id)
|
||||
}
|
||||
|
||||
singleton.ManualTrigger(&cr)
|
||||
|
||||
@@ -1,8 +1,6 @@
|
||||
package controller
|
||||
|
||||
import (
|
||||
"errors"
|
||||
"fmt"
|
||||
"strconv"
|
||||
|
||||
"github.com/gin-gonic/gin"
|
||||
@@ -55,7 +53,7 @@ func createDDNS(c *gin.Context) (uint64, error) {
|
||||
}
|
||||
|
||||
if df.MaxRetries < 1 || df.MaxRetries > 10 {
|
||||
return 0, errors.New("重试次数必须为大于 1 且不超过 10 的整数")
|
||||
return 0, singleton.Localizer.ErrorT("the retry count must be an integer between 1 and 10")
|
||||
}
|
||||
|
||||
p.Name = df.Name
|
||||
@@ -78,7 +76,7 @@ func createDDNS(c *gin.Context) (uint64, error) {
|
||||
// IDN to ASCII
|
||||
domainValid, domainErr := idna.Lookup.ToASCII(domain)
|
||||
if domainErr != nil {
|
||||
return 0, fmt.Errorf("域名 %s 解析错误: %v", domain, domainErr)
|
||||
return 0, singleton.Localizer.ErrorT("error parsing %s: %v", domain, domainErr)
|
||||
}
|
||||
p.Domains[n] = domainValid
|
||||
}
|
||||
@@ -119,12 +117,12 @@ func updateDDNS(c *gin.Context) (any, error) {
|
||||
}
|
||||
|
||||
if df.MaxRetries < 1 || df.MaxRetries > 10 {
|
||||
return nil, errors.New("重试次数必须为大于 1 且不超过 10 的整数")
|
||||
return nil, singleton.Localizer.ErrorT("the retry count must be an integer between 1 and 10")
|
||||
}
|
||||
|
||||
var p model.DDNSProfile
|
||||
if err = singleton.DB.First(&p, id).Error; err != nil {
|
||||
return nil, fmt.Errorf("profile id %d does not exist", id)
|
||||
return nil, singleton.Localizer.ErrorT("profile id %d does not exist", id)
|
||||
}
|
||||
|
||||
p.Name = df.Name
|
||||
@@ -147,7 +145,7 @@ func updateDDNS(c *gin.Context) (any, error) {
|
||||
// IDN to ASCII
|
||||
domainValid, domainErr := idna.Lookup.ToASCII(domain)
|
||||
if domainErr != nil {
|
||||
return nil, fmt.Errorf("域名 %s 解析错误: %v", domain, domainErr)
|
||||
return nil, singleton.Localizer.ErrorT("error parsing %s: %v", domain, domainErr)
|
||||
}
|
||||
p.Domains[n] = domainValid
|
||||
}
|
||||
|
||||
@@ -1,7 +1,6 @@
|
||||
package controller
|
||||
|
||||
import (
|
||||
"errors"
|
||||
"strconv"
|
||||
"time"
|
||||
|
||||
@@ -26,7 +25,7 @@ import (
|
||||
// @Success 200 {object} model.CreateFMResponse
|
||||
// @Router /file [get]
|
||||
func createFM(c *gin.Context) (*model.CreateFMResponse, error) {
|
||||
idStr := c.Param("id")
|
||||
idStr := c.Query("id")
|
||||
id, err := strconv.ParseUint(idStr, 10, 64)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
@@ -43,7 +42,7 @@ func createFM(c *gin.Context) (*model.CreateFMResponse, error) {
|
||||
server := singleton.ServerList[id]
|
||||
singleton.ServerLock.RUnlock()
|
||||
if server == nil || server.TaskStream == nil {
|
||||
return nil, errors.New("server not found or not connected")
|
||||
return nil, singleton.Localizer.ErrorT("server not found or not connected")
|
||||
}
|
||||
|
||||
fmData, _ := utils.Json.Marshal(&model.TaskFM{
|
||||
|
||||
@@ -1,7 +1,6 @@
|
||||
package controller
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"strconv"
|
||||
|
||||
"github.com/gin-gonic/gin"
|
||||
@@ -93,7 +92,7 @@ func updateNAT(c *gin.Context) (any, error) {
|
||||
|
||||
var n model.NAT
|
||||
if err = singleton.DB.First(&n, id).Error; err != nil {
|
||||
return nil, fmt.Errorf("profile id %d does not exist", id)
|
||||
return nil, singleton.Localizer.ErrorT("profile id %d does not exist", id)
|
||||
}
|
||||
|
||||
n.Name = nf.Name
|
||||
|
||||
@@ -1,7 +1,6 @@
|
||||
package controller
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"strconv"
|
||||
|
||||
"github.com/gin-gonic/gin"
|
||||
@@ -65,7 +64,7 @@ func createNotification(c *gin.Context) (uint64, error) {
|
||||
}
|
||||
// 未勾选跳过检查
|
||||
if !nf.SkipCheck {
|
||||
if err := ns.Send("这是测试消息"); err != nil {
|
||||
if err := ns.Send(singleton.Localizer.T("a test message")); err != nil {
|
||||
return 0, err
|
||||
}
|
||||
}
|
||||
@@ -104,7 +103,7 @@ func updateNotification(c *gin.Context) (any, error) {
|
||||
|
||||
var n model.Notification
|
||||
if err := singleton.DB.First(&n, id).Error; err != nil {
|
||||
return nil, fmt.Errorf("notification id %d does not exist", id)
|
||||
return nil, singleton.Localizer.ErrorT("notification id %d does not exist", id)
|
||||
}
|
||||
|
||||
n.Name = nf.Name
|
||||
@@ -123,7 +122,7 @@ func updateNotification(c *gin.Context) (any, error) {
|
||||
}
|
||||
// 未勾选跳过检查
|
||||
if !nf.SkipCheck {
|
||||
if err := ns.Send("这是测试消息"); err != nil {
|
||||
if err := ns.Send(singleton.Localizer.T("a test message")); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,7 +1,6 @@
|
||||
package controller
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"slices"
|
||||
"strconv"
|
||||
|
||||
@@ -78,7 +77,7 @@ func createNotificationGroup(c *gin.Context) (uint64, error) {
|
||||
}
|
||||
|
||||
if count != int64(len(ngf.Notifications)) {
|
||||
return 0, fmt.Errorf("have invalid notification id")
|
||||
return 0, singleton.Localizer.ErrorT("have invalid notification id")
|
||||
}
|
||||
|
||||
err := singleton.DB.Transaction(func(tx *gorm.DB) error {
|
||||
@@ -129,7 +128,7 @@ func updateNotificationGroup(c *gin.Context) (any, error) {
|
||||
}
|
||||
var ngDB model.NotificationGroup
|
||||
if err := singleton.DB.First(&ngDB, id).Error; err != nil {
|
||||
return nil, fmt.Errorf("group id %d does not exist", id)
|
||||
return nil, singleton.Localizer.ErrorT("group id %d does not exist", id)
|
||||
}
|
||||
|
||||
ngDB.Name = ngf.Name
|
||||
@@ -140,7 +139,7 @@ func updateNotificationGroup(c *gin.Context) (any, error) {
|
||||
return nil, newGormError("%v", err)
|
||||
}
|
||||
if count != int64(len(ngf.Notifications)) {
|
||||
return nil, fmt.Errorf("have invalid notification id")
|
||||
return nil, singleton.Localizer.ErrorT("have invalid notification id")
|
||||
}
|
||||
|
||||
err = singleton.DB.Transaction(func(tx *gorm.DB) error {
|
||||
|
||||
@@ -1,7 +1,6 @@
|
||||
package controller
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"strconv"
|
||||
|
||||
"github.com/gin-gonic/gin"
|
||||
@@ -57,7 +56,7 @@ func updateServer(c *gin.Context) (any, error) {
|
||||
|
||||
var s model.Server
|
||||
if err := singleton.DB.First(&s, id).Error; err != nil {
|
||||
return nil, fmt.Errorf("server id %d does not exist", id)
|
||||
return nil, singleton.Localizer.ErrorT("server id %d does not exist", id)
|
||||
}
|
||||
|
||||
s.Name = sf.Name
|
||||
|
||||
@@ -1,7 +1,6 @@
|
||||
package controller
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"slices"
|
||||
"strconv"
|
||||
|
||||
@@ -76,7 +75,7 @@ func createServerGroup(c *gin.Context) (uint64, error) {
|
||||
return 0, newGormError("%v", err)
|
||||
}
|
||||
if count != int64(len(sgf.Servers)) {
|
||||
return 0, fmt.Errorf("have invalid server id")
|
||||
return 0, singleton.Localizer.ErrorT("have invalid server id")
|
||||
}
|
||||
|
||||
err := singleton.DB.Transaction(func(tx *gorm.DB) error {
|
||||
@@ -128,7 +127,7 @@ func updateServerGroup(c *gin.Context) (any, error) {
|
||||
|
||||
var sgDB model.ServerGroup
|
||||
if err := singleton.DB.First(&sgDB, id).Error; err != nil {
|
||||
return nil, fmt.Errorf("group id %d does not exist", id)
|
||||
return nil, singleton.Localizer.ErrorT("group id %d does not exist", id)
|
||||
}
|
||||
sgDB.Name = sg.Name
|
||||
|
||||
@@ -137,7 +136,7 @@ func updateServerGroup(c *gin.Context) (any, error) {
|
||||
return nil, err
|
||||
}
|
||||
if count != int64(len(sg.Servers)) {
|
||||
return nil, fmt.Errorf("have invalid server id")
|
||||
return nil, singleton.Localizer.ErrorT("have invalid server id")
|
||||
}
|
||||
|
||||
err = singleton.DB.Transaction(func(tx *gorm.DB) error {
|
||||
|
||||
@@ -1,8 +1,6 @@
|
||||
package controller
|
||||
|
||||
import (
|
||||
"errors"
|
||||
"fmt"
|
||||
"strconv"
|
||||
"strings"
|
||||
"time"
|
||||
@@ -78,14 +76,14 @@ func listServiceHistory(c *gin.Context) ([]*model.ServiceInfos, error) {
|
||||
singleton.ServerLock.RLock()
|
||||
server, ok := singleton.ServerList[id]
|
||||
if !ok {
|
||||
return nil, errors.New("server not found")
|
||||
return nil, singleton.Localizer.ErrorT("server not found")
|
||||
}
|
||||
|
||||
_, isMember := c.Get(model.CtxKeyAuthorizedUser)
|
||||
authorized := isMember // TODO || isViewPasswordVerfied
|
||||
|
||||
if server.HideForGuest && !authorized {
|
||||
return nil, errors.New("unauthorized")
|
||||
return nil, singleton.Localizer.ErrorT("unauthorized")
|
||||
}
|
||||
singleton.ServerLock.RUnlock()
|
||||
|
||||
@@ -154,7 +152,7 @@ func listServerWithServices(c *gin.Context) ([]uint64, error) {
|
||||
server, ok := singleton.ServerList[id]
|
||||
if !ok {
|
||||
singleton.ServerLock.RUnlock()
|
||||
return nil, errors.New("server not found")
|
||||
return nil, singleton.Localizer.ErrorT("server not found")
|
||||
}
|
||||
|
||||
if !server.HideForGuest || authorized {
|
||||
@@ -201,7 +199,7 @@ func createService(c *gin.Context) (uint64, error) {
|
||||
m.FailTriggerTasks = mf.FailTriggerTasks
|
||||
|
||||
if err := singleton.DB.Create(&m).Error; err != nil {
|
||||
return 0, err
|
||||
return 0, newGormError("%v", err)
|
||||
}
|
||||
|
||||
var skipServers []uint64
|
||||
@@ -246,7 +244,7 @@ func updateService(c *gin.Context) (any, error) {
|
||||
}
|
||||
var m model.Service
|
||||
if err := singleton.DB.First(&m, id).Error; err != nil {
|
||||
return nil, fmt.Errorf("service id %d does not exist", id)
|
||||
return nil, singleton.Localizer.ErrorT("service id %d does not exist", id)
|
||||
}
|
||||
m.Name = mf.Name
|
||||
m.Target = strings.TrimSpace(mf.Target)
|
||||
@@ -265,7 +263,7 @@ func updateService(c *gin.Context) (any, error) {
|
||||
m.FailTriggerTasks = mf.FailTriggerTasks
|
||||
|
||||
if err := singleton.DB.Save(&m).Error; err != nil {
|
||||
return nil, err
|
||||
return nil, newGormError("%v", err)
|
||||
}
|
||||
|
||||
var skipServers []uint64
|
||||
|
||||
@@ -63,9 +63,10 @@ func updateConfig(c *gin.Context) (any, error) {
|
||||
singleton.Conf.CustomCodeDashboard = sf.CustomCodeDashboard
|
||||
|
||||
if err := singleton.Conf.Save(); err != nil {
|
||||
return nil, err
|
||||
return nil, newGormError("%v", err)
|
||||
}
|
||||
|
||||
singleton.OnNameserverUpdate()
|
||||
singleton.OnUpdateLang(singleton.Conf.Language)
|
||||
return nil, nil
|
||||
}
|
||||
|
||||
@@ -1,7 +1,6 @@
|
||||
package controller
|
||||
|
||||
import (
|
||||
"errors"
|
||||
"time"
|
||||
|
||||
"github.com/gin-gonic/gin"
|
||||
@@ -41,7 +40,7 @@ func createTerminal(c *gin.Context) (*model.CreateTerminalResponse, error) {
|
||||
server := singleton.ServerList[createTerminalReq.ServerID]
|
||||
singleton.ServerLock.RUnlock()
|
||||
if server == nil || server.TaskStream == nil {
|
||||
return nil, errors.New("server not found or not connected")
|
||||
return nil, singleton.Localizer.ErrorT("server not found or not connected")
|
||||
}
|
||||
|
||||
terminalData, _ := utils.Json.Marshal(&model.TerminalTask{
|
||||
|
||||
@@ -1,8 +1,6 @@
|
||||
package controller
|
||||
|
||||
import (
|
||||
"errors"
|
||||
|
||||
"github.com/gin-gonic/gin"
|
||||
"github.com/naiba/nezha/model"
|
||||
"github.com/naiba/nezha/service/singleton"
|
||||
@@ -44,10 +42,10 @@ func createUser(c *gin.Context) (uint64, error) {
|
||||
}
|
||||
|
||||
if len(uf.Password) < 6 {
|
||||
return 0, errors.New("password length must be greater than 6")
|
||||
return 0, singleton.Localizer.ErrorT("password length must be greater than 6")
|
||||
}
|
||||
if uf.Username == "" {
|
||||
return 0, errors.New("username can't be empty")
|
||||
return 0, singleton.Localizer.ErrorT("username can't be empty")
|
||||
}
|
||||
|
||||
var u model.User
|
||||
|
||||
Reference in New Issue
Block a user