From 7ed9fb4a488630035b0e39c94ccd195ed293cb02 Mon Sep 17 00:00:00 2001 From: wangzhengkun Date: Fri, 5 Aug 2022 15:31:10 +0800 Subject: [PATCH] =?UTF-8?q?feat:=20i18n=E8=B7=AF=E5=BE=84=E4=BF=AE?= =?UTF-8?q?=E6=94=B9?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- backend/app/api/v1/user.go | 23 +++++--- backend/app/dto/common_res.go | 50 +++++++++------- backend/constant/errres/errs.go | 2 +- backend/global/global.go | 1 - backend/i18n/i18n.go | 57 ++++++++++++++++--- backend/i18n/lang/en.toml | 3 + backend/i18n/lang/zh.toml | 3 + backend/init/router/router.go | 17 ++++++ backend/lang/en.toml | 2 - backend/lang/zh.toml | 2 - backend/middlerware/i18n.go | 27 --------- backend/{middlerware => middleware}/cors.go | 2 +- backend/{middlerware => middleware}/jwt.go | 2 +- backend/{middlerware => middleware}/logger.go | 2 +- backend/router/router.go | 24 -------- 15 files changed, 121 insertions(+), 96 deletions(-) create mode 100644 backend/i18n/lang/en.toml create mode 100644 backend/i18n/lang/zh.toml delete mode 100644 backend/lang/en.toml delete mode 100644 backend/lang/zh.toml delete mode 100644 backend/middlerware/i18n.go rename backend/{middlerware => middleware}/cors.go (98%) rename backend/{middlerware => middleware}/jwt.go (97%) rename backend/{middlerware => middleware}/logger.go (95%) delete mode 100644 backend/router/router.go diff --git a/backend/app/api/v1/user.go b/backend/app/api/v1/user.go index b7c24555b..5f169faeb 100644 --- a/backend/app/api/v1/user.go +++ b/backend/app/api/v1/user.go @@ -1,6 +1,7 @@ package v1 import ( + "github.com/1Panel-dev/1Panel/constant/errres" "strconv" "github.com/1Panel-dev/1Panel/app/dto" @@ -18,25 +19,27 @@ func (b *BaseApi) Login(c *gin.Context) { func (b *BaseApi) Register(c *gin.Context) { var req dto.UserCreate _ = c.ShouldBindJSON(&req) + res := dto.NewResult(c) if err := global.Validator.Struct(req); err != nil { - dto.NewResult(c).ErrorCode(500, err.Error()) + res.ErrorWithDetail(errres.InvalidParam, err.Error()) return } if err := userService.Register(req); err != nil { - global.Logger.Error("注册失败!", err) dto.NewResult(c).ErrorCode(500, err.Error()) return } - dto.NewResult(c).Success() + res.Success() } func (b *BaseApi) GetUserList(c *gin.Context) { // 这里到时候一起拦截一下 p, ok1 := c.GetQuery("page") ps, ok2 := c.GetQuery("pageSize") + res := dto.NewResult(c) + if !(ok1 && ok2) { - dto.NewResult(c).ErrorCode(500, "参数错误") + res.Error(errres.InvalidParam) return } page, err := strconv.Atoi(p) @@ -58,7 +61,7 @@ func (b *BaseApi) GetUserList(c *gin.Context) { dto.NewResult(c).ErrorCode(500, err.Error()) return } - dto.NewResult(c).SuccessWithData(dto.PageResult{ + res.SuccessWithData(dto.PageResult{ Items: list, Total: total, }) @@ -67,9 +70,10 @@ func (b *BaseApi) GetUserList(c *gin.Context) { func (b *BaseApi) DeleteUser(c *gin.Context) { var req dto.OperationWithName _ = c.ShouldBindJSON(&req) + res := dto.NewResult(c) if err := global.Validator.Struct(req); err != nil { - dto.NewResult(c).ErrorCode(500, err.Error()) + res.Error(errres.InvalidParam) return } if err := userService.Delete(req.Name); err != nil { @@ -83,9 +87,10 @@ func (b *BaseApi) DeleteUser(c *gin.Context) { func (b *BaseApi) UpdateUser(c *gin.Context) { var req dto.UserUpdate _ = c.ShouldBindJSON(&req) + res := dto.NewResult(c) if err := global.Validator.Struct(req); err != nil { - dto.NewResult(c).ErrorCode(500, err.Error()) + res.Error(errres.InvalidParam) return } upMap := make(map[string]interface{}) @@ -100,8 +105,10 @@ func (b *BaseApi) UpdateUser(c *gin.Context) { func (b *BaseApi) GetUserInfo(c *gin.Context) { name, ok := c.Params.Get("name") + res := dto.NewResult(c) + if !ok { - dto.NewResult(c).ErrorCode(500, "参数错误") + res.Error(errres.InvalidParam) return } diff --git a/backend/app/dto/common_res.go b/backend/app/dto/common_res.go index d131e8e9b..af3fbc6c9 100644 --- a/backend/app/dto/common_res.go +++ b/backend/app/dto/common_res.go @@ -1,9 +1,8 @@ package dto import ( - "net/http" - "github.com/1Panel-dev/1Panel/i18n" + "net/http" "github.com/gin-gonic/gin" ) @@ -13,6 +12,11 @@ type PageResult struct { Items interface{} `json:"items"` } +type ResDef struct { + Code int + MsgID string +} + type Response struct { Code int `json:"code"` //提示代码 Msg string `json:"msg"` //提示信息 @@ -27,19 +31,10 @@ func NewResult(ctx *gin.Context) *Result { return &Result{Ctx: ctx} } -func NewError(code int, msg string) Response { - return Response{ - Code: code, - Msg: i18n.GetMsg(msg), - Data: gin.H{}, - } -} - -func NewSuccess(code int, msg string) Response { - return Response{ - Code: code, - Msg: i18n.GetMsg(msg), - Data: gin.H{}, +func NewError(code int, msg string) ResDef { + return ResDef{ + Code: code, + MsgID: msg, } } @@ -48,16 +43,20 @@ func (r *Result) Success() { r.Ctx.Abort() } -func (r *Result) ErrorCode(code int, msg string) { - res := Response{} - res.Code = code - res.Msg = i18n.GetMsg(msg) - res.Data = gin.H{} +func (r *Result) Error(re ResDef) { + res := Response{ + Code: re.Code, + Msg: i18n.GetMsg(re.MsgID), + } r.Ctx.JSON(http.StatusOK, res) r.Ctx.Abort() } -func (r *Result) Error(res Response) { +func (r *Result) ErrorWithDetail(re ResDef, err string) { + res := Response{ + Code: re.Code, + Msg: i18n.GetMsgWithMap(re.MsgID, map[string]interface{}{"detail": err}), + } r.Ctx.JSON(http.StatusOK, res) r.Ctx.Abort() } @@ -72,3 +71,12 @@ func (r *Result) SuccessWithData(data interface{}) { res.Data = data r.Ctx.JSON(http.StatusOK, res) } + +func (r *Result) ErrorCode(code int, msg string) { + res := Response{} + res.Code = code + res.Msg = msg + res.Data = gin.H{} + r.Ctx.JSON(http.StatusOK, res) + r.Ctx.Abort() +} diff --git a/backend/constant/errres/errs.go b/backend/constant/errres/errs.go index 075e2c0bb..178b9f959 100644 --- a/backend/constant/errres/errs.go +++ b/backend/constant/errres/errs.go @@ -16,7 +16,7 @@ const ( ) var ( - OK = dto.NewSuccess(Success, "Ok") + OK = dto.NewError(Success, "Ok") InvalidParam = dto.NewError(InvalidParams, "InvalidParams") JwtExpired = dto.NewError(InvalidJwtExpired, "JwtExpired") JwtNotFound = dto.NewError(InvalidJwtNotFound, "JwtNotFound") diff --git a/backend/global/global.go b/backend/global/global.go index 5f65a4bf3..01a8ef19c 100644 --- a/backend/global/global.go +++ b/backend/global/global.go @@ -2,7 +2,6 @@ package global import ( "github.com/1Panel-dev/1Panel/configs" - "github.com/go-playground/validator/v10" "github.com/sirupsen/logrus" "gorm.io/gorm" diff --git a/backend/i18n/i18n.go b/backend/i18n/i18n.go index 78b0183d1..e437ec927 100644 --- a/backend/i18n/i18n.go +++ b/backend/i18n/i18n.go @@ -1,11 +1,54 @@ package i18n +import ( + "embed" + ginI18n "github.com/gin-contrib/i18n" + "github.com/gin-gonic/gin" + "github.com/nicksnyder/go-i18n/v2/i18n" + "github.com/pelletier/go-toml/v2" + "golang.org/x/text/language" +) + func GetMsg(msg string) string { - // content := ginI18n.MustGetMessage(msg) - // if content == "" { - // return msg - // } else { - // return content - // } - return "" + content := ginI18n.MustGetMessage(msg) + if content == "" { + return msg + } else { + return content + } +} + +func GetMsgWithMap(msg string, maps map[string]interface{}) string { + content := ginI18n.MustGetMessage(&i18n.LocalizeConfig{ + MessageID: msg, + TemplateData: maps, + }) + if content == "" { + return msg + } else { + return content + } +} + +//go:embed lang/* +var fs embed.FS + +func GinI18nLocalize() gin.HandlerFunc { + return ginI18n.Localize(ginI18n.WithBundle(&ginI18n.BundleCfg{ + RootPath: "./lang", + AcceptLanguage: []language.Tag{language.Chinese, language.English}, + DefaultLanguage: language.Chinese, + FormatBundleFile: "toml", + UnmarshalFunc: toml.Unmarshal, + Loader: &ginI18n.EmbedLoader{FS: fs}, + }), + ginI18n.WithGetLngHandle( + func(context *gin.Context, defaultLng string) string { + lng := context.GetHeader("Accept-Language") + if lng == "" { + return defaultLng + } + return lng + }, + )) } diff --git a/backend/i18n/lang/en.toml b/backend/i18n/lang/en.toml new file mode 100644 index 000000000..325674de2 --- /dev/null +++ b/backend/i18n/lang/en.toml @@ -0,0 +1,3 @@ +#common +InvalidParams = "parameter validation error {.detail}" +JwtNotFound = "" \ No newline at end of file diff --git a/backend/i18n/lang/zh.toml b/backend/i18n/lang/zh.toml new file mode 100644 index 000000000..ada7403b7 --- /dev/null +++ b/backend/i18n/lang/zh.toml @@ -0,0 +1,3 @@ +#common +InvalidParams = "参数错误: {.detail}" +JwtNotFound = "需要jwt校验" \ No newline at end of file diff --git a/backend/init/router/router.go b/backend/init/router/router.go index 3a119c9fc..f6b4b224b 100644 --- a/backend/init/router/router.go +++ b/backend/init/router/router.go @@ -1,12 +1,29 @@ package router import ( + "github.com/1Panel-dev/1Panel/docs" + "github.com/1Panel-dev/1Panel/i18n" + "github.com/1Panel-dev/1Panel/middleware" rou "github.com/1Panel-dev/1Panel/router" + ginI18n "github.com/gin-contrib/i18n" "github.com/gin-gonic/gin" + swaggerfiles "github.com/swaggo/files" + ginSwagger "github.com/swaggo/gin-swagger" + "html/template" ) func Routers() *gin.Engine { Router := gin.Default() + + docs.SwaggerInfo.BasePath = "/api/v1" + Router.GET("/swagger/*any", ginSwagger.WrapHandler(swaggerfiles.Handler)) + Router.Use(i18n.GinI18nLocalize()) + + Router.SetFuncMap(template.FuncMap{ + "Localize": ginI18n.GetMessage, + }) + Router.Use(middleware.JwtAuth()) + systemRouter := rou.RouterGroupApp PublicGroup := Router.Group("") diff --git a/backend/lang/en.toml b/backend/lang/en.toml deleted file mode 100644 index 7986ccb85..000000000 --- a/backend/lang/en.toml +++ /dev/null @@ -1,2 +0,0 @@ -#common -InvalidParams = "Parameter error" \ No newline at end of file diff --git a/backend/lang/zh.toml b/backend/lang/zh.toml deleted file mode 100644 index a2360ddde..000000000 --- a/backend/lang/zh.toml +++ /dev/null @@ -1,2 +0,0 @@ -#common -InvalidParams = "参数错误" \ No newline at end of file diff --git a/backend/middlerware/i18n.go b/backend/middlerware/i18n.go deleted file mode 100644 index b6ca72ca4..000000000 --- a/backend/middlerware/i18n.go +++ /dev/null @@ -1,27 +0,0 @@ -package middlerware - -import ( - ginI18n "github.com/gin-contrib/i18n" - "github.com/gin-gonic/gin" - "github.com/pelletier/go-toml/v2" - "golang.org/x/text/language" -) - -func GinI18nLocalize() gin.HandlerFunc { - return ginI18n.Localize(ginI18n.WithBundle(&ginI18n.BundleCfg{ - RootPath: "./backend/lang", - AcceptLanguage: []language.Tag{language.Chinese, language.English}, - DefaultLanguage: language.Chinese, - FormatBundleFile: "toml", - UnmarshalFunc: toml.Unmarshal, - }), - ginI18n.WithGetLngHandle( - func(context *gin.Context, defaultLng string) string { - lng := context.GetHeader("Accept-Language") - if lng == "" { - return defaultLng - } - return lng - }, - )) -} diff --git a/backend/middlerware/cors.go b/backend/middleware/cors.go similarity index 98% rename from backend/middlerware/cors.go rename to backend/middleware/cors.go index 0d2a9ee09..98c6e50dc 100644 --- a/backend/middlerware/cors.go +++ b/backend/middleware/cors.go @@ -1,4 +1,4 @@ -package middlerware +package middleware import ( "net/http" diff --git a/backend/middlerware/jwt.go b/backend/middleware/jwt.go similarity index 97% rename from backend/middlerware/jwt.go rename to backend/middleware/jwt.go index 9971ee9c8..9af734ee2 100644 --- a/backend/middlerware/jwt.go +++ b/backend/middleware/jwt.go @@ -1,4 +1,4 @@ -package middlerware +package middleware import ( "errors" diff --git a/backend/middlerware/logger.go b/backend/middleware/logger.go similarity index 95% rename from backend/middlerware/logger.go rename to backend/middleware/logger.go index d57382118..d79f8f2bc 100644 --- a/backend/middlerware/logger.go +++ b/backend/middleware/logger.go @@ -1,4 +1,4 @@ -package middlerware +package middleware import ( "github.com/1Panel-dev/1Panel/app/model" diff --git a/backend/router/router.go b/backend/router/router.go deleted file mode 100644 index be505b1c5..000000000 --- a/backend/router/router.go +++ /dev/null @@ -1,24 +0,0 @@ -package router - -import ( - "html/template" - - "github.com/1Panel-dev/1Panel/docs" - "github.com/1Panel-dev/1Panel/middlerware" - ginI18n "github.com/gin-contrib/i18n" - "github.com/gin-gonic/gin" - swaggerfiles "github.com/swaggo/files" - ginSwagger "github.com/swaggo/gin-swagger" -) - -func Routers() *gin.Engine { - r := gin.Default() - docs.SwaggerInfo.BasePath = "/api/v1" - r.GET("/swagger/*any", ginSwagger.WrapHandler(swaggerfiles.Handler)) - r.Use(middlerware.GinI18nLocalize()) - r.SetFuncMap(template.FuncMap{ - "Localize": ginI18n.GetMessage, - }) - r.Use(middlerware.JwtAuth()) - return r -}