Skip to content

Commit

Permalink
Version1.1.11
Browse files Browse the repository at this point in the history
 NewFeature
  1. 添加了国际化支持;修改api组件,适配国际化消息传参;添加了国际化引入的例子;
  • Loading branch information
KrisYu committed Jul 26, 2024
1 parent dc78b31 commit 142eff1
Show file tree
Hide file tree
Showing 16 changed files with 381 additions and 44 deletions.
1 change: 1 addition & 0 deletions go.mod
Original file line number Diff line number Diff line change
Expand Up @@ -63,6 +63,7 @@ require (
github.com/mitchellh/reflectwalk v1.0.2 // indirect
github.com/modern-go/concurrent v0.0.0-20180306012644-bacd9c7ef1dd // indirect
github.com/modern-go/reflect2 v1.0.2 // indirect
github.com/nicksnyder/go-i18n/v2 v2.4.0 // indirect
github.com/pelletier/go-toml/v2 v2.0.8 // indirect
github.com/pkg/errors v0.9.1 // indirect
github.com/russross/blackfriday/v2 v2.1.0 // indirect
Expand Down
2 changes: 2 additions & 0 deletions go.sum
Original file line number Diff line number Diff line change
Expand Up @@ -177,6 +177,8 @@ github.com/modern-go/concurrent v0.0.0-20180306012644-bacd9c7ef1dd h1:TRLaZ9cD/w
github.com/modern-go/concurrent v0.0.0-20180306012644-bacd9c7ef1dd/go.mod h1:6dJC0mAP4ikYIbvyc7fijjWJddQyLn8Ig3JB5CqoB9Q=
github.com/modern-go/reflect2 v1.0.2 h1:xBagoLtFs94CBntxluKeaWgTMpvLxC4ur3nMaC9Gz0M=
github.com/modern-go/reflect2 v1.0.2/go.mod h1:yWuevngMOJpCy52FWWMvUC8ws7m/LJsjYzDa0/r8luk=
github.com/nicksnyder/go-i18n/v2 v2.4.0 h1:3IcvPOAvnCKwNm0TB0dLDTuawWEj+ax/RERNC+diLMM=
github.com/nicksnyder/go-i18n/v2 v2.4.0/go.mod h1:nxYSZE9M0bf3Y70gPQjN9ha7XNHX7gMc814+6wVyEI4=
github.com/nsqio/go-nsq v1.1.0 h1:PQg+xxiUjA7V+TLdXw7nVrJ5Jbl3sN86EhGCQj4+FYE=
github.com/nsqio/go-nsq v1.1.0/go.mod h1:vKq36oyeVXgsS5Q8YEO7WghqidAVXQlcFxzQbQTuDEY=
github.com/nxadm/tail v1.4.4/go.mod h1:kenIhsEOeOJmVchQTgglprH7qJGnHDVpk1VPCcaMI8A=
Expand Down
69 changes: 36 additions & 33 deletions sdk/api/api.go
Original file line number Diff line number Diff line change
Expand Up @@ -4,10 +4,14 @@ import (
"errors"
"fmt"
"github.com/MrKrisYu/koi-go-common/logger"
"github.com/MrKrisYu/koi-go-common/sdk"
"github.com/MrKrisYu/koi-go-common/sdk/api/header"
"github.com/MrKrisYu/koi-go-common/sdk/api/response"
"github.com/MrKrisYu/koi-go-common/sdk/i18n"
"github.com/MrKrisYu/koi-go-common/sdk/service"
"github.com/gin-gonic/gin"
"github.com/gin-gonic/gin/binding"
"golang.org/x/text/language"
"io"
"net/http"
"reflect"
Expand All @@ -19,23 +23,11 @@ var (
)

type Api struct {
//Context *gin.Context
Logger *logger.Helper
//Errors error
}

//func (e *Api) AddError(err error) {
// if e.Errors == nil {
// e.Errors = err
// } else if err != nil {
// e.Logger.Error(err)
// e.Errors = fmt.Errorf("%v; %w", e.Errors, err)
// }
//}

// MakeContext 设置http上下文
func (e *Api) MakeContext(c *gin.Context) *Api {
//e.Context = c
e.Logger = GetRequestLogger(c)
return e
}
Expand All @@ -45,11 +37,6 @@ func (e *Api) MakeService(s *service.Service) *Api {
return e
}

// GetLogger 获取上下文提供的日志
//func (e *Api) GetLogger() *logger.Helper {
// return GetRequestLogger(e.Context)
//}

// Bind 参数校验
func (e *Api) Bind(ctx *gin.Context, d any, bindings ...binding.Binding) error {
var mergedErr error
Expand Down Expand Up @@ -78,11 +65,32 @@ func (e *Api) Bind(ctx *gin.Context, d any, bindings ...binding.Binding) error {
return mergedErr
}

func translate(ctx *gin.Context, message i18n.Message) string {
tag, exist := ctx.Get(header.AcceptLanguageFlag)
if !exist {
return message.DefaultMessage
}
lang := tag.(language.Tag)
translator := sdk.RuntimeContext.GetTranslator()
if translator == nil {
return message.DefaultMessage
}
if len(message.ID) == 0 {
return message.DefaultMessage
}
if message.Args == nil {
return translator.Tr(lang, message)
} else {
return translator.TrWithData(lang, message)
}
}

func (e *Api) OK(ctx *gin.Context, data any) {
message := translate(ctx, response.OK.Message)
if data == nil {
ctx.JSON(http.StatusOK, response.Response[any]{
Code: response.OK.Code,
Message: response.OK.Message,
Message: message,
Data: EmptyData,
})
return
Expand All @@ -99,47 +107,42 @@ func (e *Api) OK(ctx *gin.Context, data any) {
// 切片,使用ListDataWrapper封装
ret = response.Response[ListDataWrapper[any]]{
Code: response.OK.Code,
Message: response.OK.Message,
Message: message,
Data: ListDataWrapper[any]{Items: data},
}
break
case reflect.Struct:
// 结构体,直接返回
ret = response.Response[any]{
Code: response.OK.Code,
Message: response.OK.Message,
Message: message,
Data: data,
}
break
default:
// 非切片且非结构体,使用ValueWrapper封装
ret = response.Response[ValueWrapper[any]]{
Code: response.OK.Code,
Message: response.OK.Message,
Message: message,
Data: ValueWrapper[any]{Value: data},
}
}
ctx.JSON(http.StatusOK, ret)
// 一个请求事务完结后,把错误清空,避免错误过度传递,影响下个请求事务
//e.Errors = nil

}

func (e *Api) Error(ctx *gin.Context, businessStatus response.Status, errMsg ...string) {
errMessage := businessStatus.Message
func (e *Api) Error(ctx *gin.Context, businessStatus response.Status, errMsg ...i18n.MyError) {
statusMsg := translate(ctx, businessStatus.Message)
var msg string
if len(errMsg) > 0 {
errMessage = strings.Join([]string{errMessage, errMsg[0]}, ": ")
errorMsg := translate(ctx, errMsg[0].Message)
msg = strings.Join([]string{statusMsg, errorMsg}, ": ")
}
ctx.JSON(http.StatusOK, response.Response[struct{}]{
Code: businessStatus.Code,
Message: errMessage,
Message: msg,
Data: EmptyData,
})
// 一个请求事务完结后,把错误清空,避免错误过度传递,影响下个请求事务
//e.Errors = nil
}

func (e *Api) Translate(from, to any) {
CopyProperties(from, to)
}

// ListDataWrapper 用于包装切片
Expand Down
5 changes: 5 additions & 0 deletions sdk/api/header/common_header.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
package header

const (
AcceptLanguageFlag = "Accept-Language"
)
17 changes: 9 additions & 8 deletions sdk/api/response/code.go
Original file line number Diff line number Diff line change
@@ -1,15 +1,16 @@
package response

import "github.com/MrKrisYu/koi-go-common/sdk/i18n"

type Status struct {
Code int `json:"code"`
Message string `json:"message"`
Code int `json:"code"`
Message i18n.Message `json:"message"`
}

var (
OK = Status{Code: 2000, Message: "OK"}
RequestParamsError = Status{Code: 4000, Message: "Request Parameters Error"}
Unauthorized = Status{Code: 4001, Message: "Unauthorized Request"}
NotLoginUserOperation = Status{Code: 4002, Message: "Error for overstepping your authority"}
InternalServerError = Status{Code: 5000, Message: "Internal Server Error"}
ServiceError = Status{Code: 5001, Message: "Service Error"}
OK = Status{Code: 2000, Message: i18n.Message{ID: "response.ok", DefaultMessage: "OK"}}
RequestParamsError = Status{Code: 4000, Message: i18n.Message{ID: "response.badRequest", DefaultMessage: "Request Parameters Error"}}
Unauthorized = Status{Code: 4001, Message: i18n.Message{ID: "response.unauthorized", DefaultMessage: "Unauthorized Request"}}
InternalServerError = Status{Code: 5000, Message: i18n.Message{ID: "response.internalServerError", DefaultMessage: "Internal Server Error"}}
ServiceError = Status{Code: 5001, Message: i18n.Message{ID: "response.serviceError", DefaultMessage: "Service Error"}}
)
17 changes: 17 additions & 0 deletions sdk/i18n/error.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
package i18n

type MyError struct {
Err error
Message Message `json:"message"`
}

func (e MyError) Error() string {
return e.Err.Error()
}

func NewMyError(err error) MyError {
return MyError{
Err: err,
Message: Message{DefaultMessage: err.Error()},
}
}
39 changes: 39 additions & 0 deletions sdk/i18n/example/accept_language.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,39 @@
package example

import (
"fmt"
"github.com/MrKrisYu/koi-go-common/sdk/api/header"
"github.com/gin-gonic/gin"
"golang.org/x/text/language"
)

const (
LanguageReqQueryKey = "lang"
)

func GetLang(ctx *gin.Context) language.Tag {
matchedTag := DefaultLanguage
acceptLanguage := ctx.GetHeader(header.AcceptLanguageFlag)
if len(acceptLanguage) == 0 {
acceptLanguage, _ = ctx.GetQuery(LanguageReqQueryKey)
}
if len(acceptLanguage) == 0 {
fmt.Printf("[Middleware-AcceptLanguage] got lang=%s, match=%s \n\n", acceptLanguage, matchedTag.String())
return matchedTag
}
matcher := language.NewMatcher(AllowedLanguage)
_, index, confidence := matcher.Match(language.Make(acceptLanguage))
if confidence != language.No {
matchedTag = AllowedLanguage[index]
}
fmt.Printf("[Middleware-AcceptLanguage] got lang=%s, match=%s \n\n", acceptLanguage, matchedTag.String())
return matchedTag
}

func AcceptLanguage() gin.HandlerFunc {
return func(ctx *gin.Context) {
lang := GetLang(ctx)
ctx.Set(header.AcceptLanguageFlag, lang)
ctx.Next()
}
}
Loading

0 comments on commit 142eff1

Please sign in to comment.