diff --git a/README.md b/README.md
index 175a68a..de90afd 100644
--- a/README.md
+++ b/README.md
@@ -4,7 +4,7 @@
LOGO designed by 熊大 .
-
+
:trollface: Nezha Monitoring One-stop light monitoring and light operation and maintenance system. Supports system status, HTTP (SSL certificate change, upcoming expiration, expiration), TCP, Ping monitoring and alarm, scheduled tasks and web terminal.
@@ -14,7 +14,7 @@ \>> QQ 交流群:872069346 **加群要求:已搭建好哪吒监控 & 有 2+ 服务器, 机器人自动审核** -\>> [Use Cases | 我们的用户](https://www.google.com/search?q="powered+by+哪吒监控"&filter=0) (Google) +\>> [Use Cases | 我们的用户](https://www.google.com/search?q=%22powered+by+%E5%93%AA%E5%90%92%E7%9B%91%E6%8E%A7%22+OR+%22powered+by+Nezha+Monitoring%22&filter=0) (Google) | Default Theme | DayNight [@JackieSung](https://github.com/JackieSung4ev) | hotaru | | ---------------------------------------------------------------------------------------- | ------------------------------------------------------------------------------------------------------ | -------------------------------------------------------------------------- | @@ -25,7 +25,7 @@ ## User Guide - [中文文档](docs/UserGuide_zh.md) -- [English](docs/UserGuide_en.md) +- [English](docs/UserGuide_en.md) WIP ## Special Thanks @@ -33,6 +33,6 @@ - [@Erope](https://github.com/JackieSung4ev) for contributed a lot to our installation scripts and community building. - [@MikoyChinese](https://github.com/MikoyChinese) for our second community-contributed front-end theme. - [@AkkiaS7](https://github.com/Akkia) and [hhhkkk520](https://github.com/hhhkkk520) for the excellent contribution in the early days of globalization. -- [@dysf888](https://gitub.com/dysf888) for the installation script in windows. +- [@dysf888](https://gitub.com/dysf888) for the installation script in Windows. - [@MartijnLindeman](https://github.com/MartijnLindeman) for his perseverance has taken us to the international market. - and other [contributors](https://github.com/naiba/nezha/graphs/contributors). diff --git a/cmd/dashboard/controller/common_page.go b/cmd/dashboard/controller/common_page.go index 9ee6119..14d1b2f 100644 --- a/cmd/dashboard/controller/common_page.go +++ b/cmd/dashboard/controller/common_page.go @@ -2,7 +2,6 @@ package controller import ( "errors" - "fmt" "log" "net/http" "regexp" @@ -14,6 +13,7 @@ import ( "github.com/gorilla/websocket" "github.com/hashicorp/go-uuid" "github.com/jinzhu/copier" + "github.com/nicksnyder/go-i18n/v2/i18n" "golang.org/x/crypto/bcrypt" "golang.org/x/sync/singleflight" @@ -60,16 +60,18 @@ func (p *commonPage) issueViewPassword(c *gin.Context) { err := c.ShouldBind(&vpf) var hash []byte if err == nil && vpf.Password != singleton.Conf.Site.ViewPassword { - err = errors.New("查看密码错误") + err = errors.New(singleton.Localizer.MustLocalize(&i18n.LocalizeConfig{MessageID: "WrongAccessPassword"})) } if err == nil { hash, err = bcrypt.GenerateFromPassword([]byte(vpf.Password), bcrypt.DefaultCost) } if err != nil { mygin.ShowErrorPage(c, mygin.ErrInfo{ - Code: http.StatusOK, - Title: "出现错误", - Msg: fmt.Sprintf("请求错误:%s", err), + Code: http.StatusOK, + Title: singleton.Localizer.MustLocalize(&i18n.LocalizeConfig{ + MessageID: "AnErrorEccurred", + }), + Msg: err.Error(), }, true) c.Abort() return @@ -92,7 +94,7 @@ func (p *commonPage) checkViewPassword(c *gin.Context) { viewPassword, _ := c.Cookie(singleton.Conf.Site.CookieName + "-vp") if err := bcrypt.CompareHashAndPassword([]byte(viewPassword), []byte(singleton.Conf.Site.ViewPassword)); err != nil { c.HTML(http.StatusOK, "theme-"+singleton.Conf.Site.Theme+"/viewpassword", mygin.CommonEnvironment(c, gin.H{ - "Title": "验证查看密码", + "Title": singleton.Localizer.MustLocalize(&i18n.LocalizeConfig{MessageID: "VerifyPassword"}), "CustomCode": singleton.Conf.Site.CustomCode, })) c.Abort() @@ -116,7 +118,7 @@ func (p *commonPage) service(c *gin.Context) { }, nil }) c.HTML(http.StatusOK, "theme-"+singleton.Conf.Site.Theme+"/service", mygin.CommonEnvironment(c, gin.H{ - "Title": "服务状态", + "Title": singleton.Localizer.MustLocalize(&i18n.LocalizeConfig{MessageID: "ServicesStatus"}), "Services": res.([]interface{})[0], "CycleTransferStats": res.([]interface{})[1], "CustomCode": singleton.Conf.Site.CustomCode, @@ -139,11 +141,13 @@ func (cp *commonPage) home(c *gin.Context) { stat, err := cp.getServerStat() if err != nil { mygin.ShowErrorPage(c, mygin.ErrInfo{ - Code: http.StatusInternalServerError, - Title: "系统错误", - Msg: "服务器状态获取失败", - Link: "/", - Btn: "返回首页", + Code: http.StatusInternalServerError, + Title: singleton.Localizer.MustLocalize(&i18n.LocalizeConfig{ + MessageID: "SystemError", + }), + Msg: "服务器状态获取失败", + Link: "/", + Btn: "返回首页", }, true) return } @@ -167,11 +171,13 @@ func (cp *commonPage) ws(c *gin.Context) { conn, err := upgrader.Upgrade(c.Writer, c.Request, nil) if err != nil { mygin.ShowErrorPage(c, mygin.ErrInfo{ - Code: http.StatusInternalServerError, - Title: "网络错误", - Msg: "Websocket协议切换失败", - Link: "/", - Btn: "返回首页", + Code: http.StatusInternalServerError, + Title: singleton.Localizer.MustLocalize(&i18n.LocalizeConfig{ + MessageID: "NetowrkError", + }), + Msg: "Websocket协议切换失败", + Link: "/", + Btn: "返回首页", }, true) return } @@ -312,11 +318,13 @@ func (cp *commonPage) terminal(c *gin.Context) { conn, err := upgrader.Upgrade(c.Writer, c.Request, nil) if err != nil { mygin.ShowErrorPage(c, mygin.ErrInfo{ - Code: http.StatusInternalServerError, - Title: "网络错误", - Msg: "Websocket协议切换失败", - Link: "/", - Btn: "返回首页", + Code: http.StatusInternalServerError, + Title: singleton.Localizer.MustLocalize(&i18n.LocalizeConfig{ + MessageID: "NetowrkError", + }), + Msg: "Websocket协议切换失败", + Link: "/", + Btn: "返回首页", }, true) return } @@ -447,11 +455,13 @@ func (cp *commonPage) createTerminal(c *gin.Context) { id, err := uuid.GenerateUUID() if err != nil { mygin.ShowErrorPage(c, mygin.ErrInfo{ - Code: http.StatusInternalServerError, - Title: "系统错误", - Msg: "生成会话ID失败", - Link: "/server", - Btn: "返回重试", + Code: http.StatusInternalServerError, + Title: singleton.Localizer.MustLocalize(&i18n.LocalizeConfig{ + MessageID: "SystemError", + }), + Msg: "生成会话ID失败", + Link: "/server", + Btn: "返回重试", }, true) return } diff --git a/cmd/dashboard/controller/controller.go b/cmd/dashboard/controller/controller.go index 1fe5278..bd1997a 100644 --- a/cmd/dashboard/controller/controller.go +++ b/cmd/dashboard/controller/controller.go @@ -26,116 +26,7 @@ func ServeWeb(port uint) *http.Server { pprof.Register(r) } r.Use(mygin.RecordPath) - r.SetFuncMap(template.FuncMap{ - "tr": func(id string, dataAndCount ...interface{}) string { - conf := i18n.LocalizeConfig{ - MessageID: id, - } - if len(dataAndCount) > 0 { - conf.TemplateData = dataAndCount[0] - } - if len(dataAndCount) > 1 { - conf.PluralCount = dataAndCount[1] - } - return singleton.Localizer.MustLocalize(&conf) - }, - "toValMap": func(val interface{}) map[string]interface{} { - return map[string]interface{}{ - "Value": val, - } - }, - "tf": func(t time.Time) string { - return t.In(singleton.Loc).Format("2006年1月2号 15:04:05") - }, - "len": func(slice []interface{}) string { - return strconv.Itoa(len(slice)) - }, - "safe": func(s string) template.HTML { - return template.HTML(s) // #nosec - }, - "tag": func(s string) template.HTML { - return template.HTML(`<` + s + `>`) // #nosec - }, - "stf": func(s uint64) string { - return time.Unix(int64(s), 0).In(singleton.Loc).Format("2006年1月2号 15:04") - }, - "sf": func(duration uint64) string { - return time.Duration(time.Duration(duration) * time.Second).String() - }, - "sft": func(future time.Time) string { - return time.Until(future).Round(time.Second).String() - }, - "bf": func(b uint64) string { - return bytefmt.ByteSize(b) - }, - "ts": func(s string) string { - return strings.TrimSpace(s) - }, - "float32f": func(f float32) string { - return fmt.Sprintf("%.2f", f) - }, - "divU64": func(a, b uint64) float32 { - if b == 0 { - if a > 0 { - return 100 - } - return 0 - } - if a == 0 { - // 这是从未在线的情况 - return 0.00001 / float32(b) * 100 - } - return float32(a) / float32(b) * 100 - }, - "div": func(a, b int) float32 { - if b == 0 { - if a > 0 { - return 100 - } - return 0 - } - if a == 0 { - // 这是从未在线的情况 - return 0.00001 / float32(b) * 100 - } - return float32(a) / float32(b) * 100 - }, - "addU64": func(a, b uint64) uint64 { - return a + b - }, - "add": func(a, b int) int { - return a + b - }, - "dayBefore": func(i int) string { - year, month, day := time.Now().Date() - today := time.Date(year, month, day, 0, 0, 0, 0, time.Local) - return today.AddDate(0, 0, i-29).Format("1月2号") - }, - "className": func(percent float32) string { - if percent == 0 { - return "" - } - if percent > 95 { - return "good" - } - if percent > 80 { - return "warning" - } - return "danger" - }, - "statusName": func(percent float32) string { - if percent == 0 { - return "无数据" - } - if percent > 95 { - return "良好" - } - if percent > 80 { - return "低可用" - } - return "故障" - }, - }) + r.SetFuncMap(funcMap) r.Static("/static", "resource/static") r.LoadHTMLGlob("resource/template/**/*.html") routers(r) @@ -176,3 +67,114 @@ func routers(r *gin.Engine) { ma.serve() } } + +var funcMap = template.FuncMap{ + "tr": func(id string, dataAndCount ...interface{}) string { + conf := i18n.LocalizeConfig{ + MessageID: id, + } + if len(dataAndCount) > 0 { + conf.TemplateData = dataAndCount[0] + } + if len(dataAndCount) > 1 { + conf.PluralCount = dataAndCount[1] + } + return singleton.Localizer.MustLocalize(&conf) + }, + "toValMap": func(val interface{}) map[string]interface{} { + return map[string]interface{}{ + "Value": val, + } + }, + "tf": func(t time.Time) string { + return t.In(singleton.Loc).Format("2006年1月2号 15:04:05") + }, + "len": func(slice []interface{}) string { + return strconv.Itoa(len(slice)) + }, + "safe": func(s string) template.HTML { + return template.HTML(s) // #nosec + }, + "tag": func(s string) template.HTML { + return template.HTML(`<` + s + `>`) // #nosec + }, + "stf": func(s uint64) string { + return time.Unix(int64(s), 0).In(singleton.Loc).Format("2006年1月2号 15:04") + }, + "sf": func(duration uint64) string { + return time.Duration(time.Duration(duration) * time.Second).String() + }, + "sft": func(future time.Time) string { + return time.Until(future).Round(time.Second).String() + }, + "bf": func(b uint64) string { + return bytefmt.ByteSize(b) + }, + "ts": func(s string) string { + return strings.TrimSpace(s) + }, + "float32f": func(f float32) string { + return fmt.Sprintf("%.2f", f) + }, + "divU64": func(a, b uint64) float32 { + if b == 0 { + if a > 0 { + return 100 + } + return 0 + } + if a == 0 { + // 这是从未在线的情况 + return 0.00001 / float32(b) * 100 + } + return float32(a) / float32(b) * 100 + }, + "div": func(a, b int) float32 { + if b == 0 { + if a > 0 { + return 100 + } + return 0 + } + if a == 0 { + // 这是从未在线的情况 + return 0.00001 / float32(b) * 100 + } + return float32(a) / float32(b) * 100 + }, + "addU64": func(a, b uint64) uint64 { + return a + b + }, + "add": func(a, b int) int { + return a + b + }, + "dayBefore": func(i int) string { + year, month, day := time.Now().Date() + today := time.Date(year, month, day, 0, 0, 0, 0, time.Local) + return today.AddDate(0, 0, i-29).Format("1月2号") + }, + "className": func(percent float32) string { + if percent == 0 { + return "" + } + if percent > 95 { + return "good" + } + if percent > 80 { + return "warning" + } + return "danger" + }, + "statusName": func(percent float32) string { + if percent == 0 { + return "无数据" + } + if percent > 95 { + return "良好" + } + if percent > 80 { + return "低可用" + } + return "故障" + }, +} diff --git a/cmd/dashboard/controller/guest_page.go b/cmd/dashboard/controller/guest_page.go index 8512d15..a7c08ad 100644 --- a/cmd/dashboard/controller/guest_page.go +++ b/cmd/dashboard/controller/guest_page.go @@ -4,6 +4,7 @@ import ( "net/http" "github.com/gin-gonic/gin" + "github.com/nicksnyder/go-i18n/v2/i18n" "github.com/naiba/nezha/model" "github.com/naiba/nezha/pkg/mygin" @@ -40,7 +41,7 @@ func (gp *guestPage) login(c *gin.Context) { RegistrationLink = "https://gitee.com/signup" } c.HTML(http.StatusOK, "dashboard/login", mygin.CommonEnvironment(c, gin.H{ - "Title": "登录", + "Title": singleton.Localizer.MustLocalize(&i18n.LocalizeConfig{MessageID: "Login"}), "LoginType": LoginType, "RegistrationLink": RegistrationLink, })) diff --git a/cmd/dashboard/controller/member_api.go b/cmd/dashboard/controller/member_api.go index 93865e1..1b4f2c8 100644 --- a/cmd/dashboard/controller/member_api.go +++ b/cmd/dashboard/controller/member_api.go @@ -551,6 +551,7 @@ func (ma *memberAPI) logout(c *gin.Context) { type settingForm struct { Title string Admin string + Language string Theme string CustomCode string ViewPassword string @@ -572,6 +573,7 @@ func (ma *memberAPI) updateSetting(c *gin.Context) { }) return } + singleton.Conf.Language = sf.Language singleton.Conf.EnableIPChangeNotification = sf.EnableIPChangeNotification == "on" singleton.Conf.EnablePlainIPInNotification = sf.EnablePlainIPInNotification == "on" singleton.Conf.Cover = sf.Cover @@ -594,6 +596,8 @@ func (ma *memberAPI) updateSetting(c *gin.Context) { }) return } + // 更新系统语言 + singleton.InitLocalizer() c.JSON(http.StatusOK, model.Response{ Code: http.StatusOK, }) diff --git a/cmd/dashboard/controller/member_page.go b/cmd/dashboard/controller/member_page.go index ff84ce5..e658369 100644 --- a/cmd/dashboard/controller/member_page.go +++ b/cmd/dashboard/controller/member_page.go @@ -7,6 +7,7 @@ import ( "github.com/naiba/nezha/model" "github.com/naiba/nezha/pkg/mygin" "github.com/naiba/nezha/service/singleton" + "github.com/nicksnyder/go-i18n/v2/i18n" ) type memberPage struct { @@ -18,8 +19,8 @@ func (mp *memberPage) serve() { mr.Use(mygin.Authorize(mygin.AuthorizeOption{ Member: true, IsPage: true, - Msg: "此页面需要登录", - Btn: "点此登录", + Msg: singleton.Localizer.MustLocalize(&i18n.LocalizeConfig{MessageID: "YouAreNotAuthorized"}), + Btn: singleton.Localizer.MustLocalize(&i18n.LocalizeConfig{MessageID: "Login"}), Redirect: "/login", })) mr.GET("/server", mp.server) @@ -33,14 +34,14 @@ func (mp *memberPage) server(c *gin.Context) { singleton.SortedServerLock.RLock() defer singleton.SortedServerLock.RUnlock() c.HTML(http.StatusOK, "dashboard/server", mygin.CommonEnvironment(c, gin.H{ - "Title": "服务器管理", + "Title": singleton.Localizer.MustLocalize(&i18n.LocalizeConfig{MessageID: "ServersManagement"}), "Servers": singleton.SortedServerList, })) } func (mp *memberPage) monitor(c *gin.Context) { c.HTML(http.StatusOK, "dashboard/monitor", mygin.CommonEnvironment(c, gin.H{ - "Title": "服务监控", + "Title": singleton.Localizer.MustLocalize(&i18n.LocalizeConfig{MessageID: "ServicesManagement"}), "Monitors": singleton.ServiceSentinelShared.Monitors(), })) } @@ -49,7 +50,7 @@ func (mp *memberPage) cron(c *gin.Context) { var crons []model.Cron singleton.DB.Find(&crons) c.HTML(http.StatusOK, "dashboard/cron", mygin.CommonEnvironment(c, gin.H{ - "Title": "计划任务", + "Title": singleton.Localizer.MustLocalize(&i18n.LocalizeConfig{MessageID: "ScheduledTasks"}), "Crons": crons, })) } @@ -60,7 +61,7 @@ func (mp *memberPage) notification(c *gin.Context) { var ar []model.AlertRule singleton.DB.Find(&ar) c.HTML(http.StatusOK, "dashboard/notification", mygin.CommonEnvironment(c, gin.H{ - "Title": "报警通知", + "Title": singleton.Localizer.MustLocalize(&i18n.LocalizeConfig{MessageID: "Notification"}), "Notifications": nf, "AlertRules": ar, })) @@ -68,6 +69,6 @@ func (mp *memberPage) notification(c *gin.Context) { func (mp *memberPage) setting(c *gin.Context) { c.HTML(http.StatusOK, "dashboard/setting", mygin.CommonEnvironment(c, gin.H{ - "Title": "系统设置", + "Title": singleton.Localizer.MustLocalize(&i18n.LocalizeConfig{MessageID: "Settings"}), })) } diff --git a/cmd/dashboard/controller/oauth2.go b/cmd/dashboard/controller/oauth2.go index 200809b..38010b5 100644 --- a/cmd/dashboard/controller/oauth2.go +++ b/cmd/dashboard/controller/oauth2.go @@ -108,7 +108,7 @@ func (oa *oauth2controller) callback(c *gin.Context) { } var isAdmin bool for _, admin := range strings.Split(singleton.Conf.Oauth2.Admin, ",") { - if admin != "" && gu.GetLogin() == admin { + if admin != "" && strings.ToLower(gu.GetLogin()) == strings.ToLower(admin) { isAdmin = true break } diff --git a/cmd/playground/main.go b/cmd/playground/main.go index 246a667..7905807 100644 --- a/cmd/playground/main.go +++ b/cmd/playground/main.go @@ -1,51 +1,5 @@ package main -import ( - "fmt" - - "github.com/naiba/nezha/service/singleton" - "github.com/nicksnyder/go-i18n/v2/i18n" - "golang.org/x/text/language" -) - -func htmlTemplateTranslateFn(id string, data interface{}, count interface{}) string { - return singleton.Localizer.MustLocalize(&i18n.LocalizeConfig{ - MessageID: id, - TemplateData: data, - PluralCount: count, - }) -} - func main() { - singleton.InitConfigFromPath("data/config.yaml") - singleton.InitLocalizer() - fmt.Println(singleton.Localizer.MustLocalize(&i18n.LocalizeConfig{ - MessageID: "nezhaMonitor", - })) - fmt.Println(singleton.Localizer.MustLocalize(&i18n.LocalizeConfig{ - MessageID: "nezhaMonitor", - })) - - fmt.Println("tr nezhaMonitor", htmlTemplateTranslateFn("nezhaMonitor", nil, nil)) - fmt.Println("tr nezhaMonitor", htmlTemplateTranslateFn("nezhaMonitor", nil, 2)) - fmt.Println("tr nezhaMonitor", htmlTemplateTranslateFn("nezhaMonitor", map[string]string{ - "Ext": "Plus", - }, 2)) - - bundle := i18n.NewBundle(language.English) - localizer := i18n.NewLocalizer(bundle, "en") - catsMessage := &i18n.Message{ - ID: "Cats", - One: "I have {{.PluralCount}} cat.", - Other: "I have {{.PluralCount}} cats.", - } - fmt.Println(localizer.MustLocalize(&i18n.LocalizeConfig{ - DefaultMessage: catsMessage, - PluralCount: 1, - })) - fmt.Println(localizer.MustLocalize(&i18n.LocalizeConfig{ - DefaultMessage: catsMessage, - PluralCount: 2, - })) } diff --git a/pkg/mygin/mygin.go b/pkg/mygin/mygin.go index 80c53a5..d2afde0 100644 --- a/pkg/mygin/mygin.go +++ b/pkg/mygin/mygin.go @@ -5,6 +5,7 @@ import ( "strings" "github.com/gin-gonic/gin" + "github.com/nicksnyder/go-i18n/v2/i18n" "github.com/naiba/nezha/model" "github.com/naiba/nezha/service/singleton" @@ -34,6 +35,15 @@ func CommonEnvironment(c *gin.Context, data map[string]interface{}) gin.H { if ok { data["Admin"] = u } + data["LANG"] = map[string]string{ + "Add": singleton.Localizer.MustLocalize(&i18n.LocalizeConfig{MessageID: "Add"}), + "Edit": singleton.Localizer.MustLocalize(&i18n.LocalizeConfig{MessageID: "Edit"}), + "AlarmRule": singleton.Localizer.MustLocalize(&i18n.LocalizeConfig{MessageID: "AlarmRule"}), + "Notification": singleton.Localizer.MustLocalize(&i18n.LocalizeConfig{MessageID: "NotificationMethod"}), + "Server": singleton.Localizer.MustLocalize(&i18n.LocalizeConfig{MessageID: "Server"}), + "Monitor": singleton.Localizer.MustLocalize(&i18n.LocalizeConfig{MessageID: "ServicesManagement"}), + "Cron": singleton.Localizer.MustLocalize(&i18n.LocalizeConfig{MessageID: "ScheduledTasks"}), + } return data } diff --git a/pkg/utils/utils.go b/pkg/utils/utils.go index 5989423..5f8cacd 100644 --- a/pkg/utils/utils.go +++ b/pkg/utils/utils.go @@ -68,3 +68,14 @@ func IPDesensitize(ipAddr string) string { ipAddr = ipv6Desensitize(ipAddr) return ipAddr } + +func PathExists(path string) (bool, error) { + _, err := os.Stat(path) + if err == nil { + return true, nil + } + if os.IsNotExist(err) { + return false, nil + } + return false, err +} diff --git a/resource/static/main.js b/resource/static/main.js index 5f19527..6b15125 100644 --- a/resource/static/main.js +++ b/resource/static/main.js @@ -1,3 +1,19 @@ +let LANG = { + Add: "添加", + Edit: "修改", + AlarmRule: "报警规则", + Notification: "通知方式", + Server: "服务器", + Monitor: "监控", + Cron: "计划任务", +} + +function updateLang(newLang) { + if (newLang) { + LANG = newLang; + } +} + function readableBytes(bytes) { if (!bytes) { return '0B' @@ -105,11 +121,11 @@ function showFormModal(modelSelector, formID, URL, getData) { function addOrEditAlertRule(rule) { const modal = $(".rule.modal"); - modal.children(".header").text((rule ? "修改" : "添加") + "报警规则"); + modal.children(".header").text((rule ? LANG.Edit : LANG.Add) + ' ' + LANG.AlarmRule); modal .find(".nezha-primary-btn.button") .html( - rule ? '修改' : '添加' + rule ? LANG.Edit + '' : LANG.Add + '' ); modal.find("input[name=ID]").val(rule ? rule.ID : null); modal.find("input[name=Name]").val(rule ? rule.Name : null); @@ -125,13 +141,13 @@ function addOrEditAlertRule(rule) { function addOrEditNotification(notification) { const modal = $(".notification.modal"); - modal.children(".header").text((notification ? "修改" : "添加") + "通知方式"); + modal.children(".header").text((notification ? LANG.Edit : LANG.Add) + ' ' + LANG.Notification); modal .find(".nezha-primary-btn.button") .html( notification - ? '修改' - : '添加' + ? LANG.Edit + '' + : LANG.Add + '' ); modal.find("input[name=ID]").val(notification ? notification.ID : null); modal.find("input[name=Name]").val(notification ? notification.Name : null); @@ -188,11 +204,11 @@ function post(path, params, method = 'post') { function addOrEditServer(server, conf) { const modal = $(".server.modal"); - modal.children(".header").text((server ? "修改" : "添加") + "服务器"); + modal.children(".header").text((server ? LANG.Edit : LANG.Add) + ' ' + LANG.Server); modal .find(".nezha-primary-btn.button") .html( - server ? '修改' : '添加' + server ? LANG.Edit + '' : LANG.Add + '' ); modal.find("input[name=id]").val(server ? server.ID : null); modal.find("input[name=name]").val(server ? server.Name : null); @@ -216,11 +232,11 @@ function addOrEditServer(server, conf) { function addOrEditMonitor(monitor) { const modal = $(".monitor.modal"); - modal.children(".header").text((monitor ? "修改" : "添加") + "监控"); + modal.children(".header").text((monitor ? LANG.Edit : LANG.Add) + ' ' + LANG.Monitor); modal .find(".nezha-primary-btn.button") .html( - monitor ? '修改' : '添加' + monitor ? LANG.Edit + '' : LANG.Add + '' ); modal.find("input[name=ID]").val(monitor ? monitor.ID : null); modal.find("input[name=Name]").val(monitor ? monitor.Name : null); @@ -257,11 +273,11 @@ function addOrEditMonitor(monitor) { function addOrEditCron(cron) { const modal = $(".cron.modal"); - modal.children(".header").text((cron ? "修改" : "添加") + "计划任务"); + modal.children(".header").text((cron ? LANG.Edit : LANG.Add) + ' ' + LANG.Cron); modal .find(".nezha-primary-btn.button") .html( - cron ? '修改' : '添加' + cron ? LANG.Edit + '' : LANG.Add + '' ); modal.find("input[name=ID]").val(cron ? cron.ID : null); modal.find("input[name=Name]").val(cron ? cron.Name : null); diff --git a/resource/template/common/footer.html b/resource/template/common/footer.html index b52fd65..b4bc34a 100644 --- a/resource/template/common/footer.html +++ b/resource/template/common/footer.html @@ -1,16 +1,22 @@ {{define "common/footer"}} - + +