fix(i18n): If the translation content is not found, use the default language for translation

This commit is contained in:
LinkinStar 2023-01-06 18:00:51 +08:00
parent f504ba5a61
commit 5c2723e617
12 changed files with 47 additions and 45 deletions

View File

@ -21,7 +21,7 @@ type RespBody struct {
// TrMsg translate the reason cause as a message // TrMsg translate the reason cause as a message
func (r *RespBody) TrMsg(lang i18n.Language) *RespBody { func (r *RespBody) TrMsg(lang i18n.Language) *RespBody {
if len(r.Message) == 0 { if len(r.Message) == 0 {
r.Message = translator.GlobalTrans.Tr(lang, r.Reason) r.Message = translator.Tr(lang, r.Reason)
} }
return r return r
} }

View File

@ -106,3 +106,12 @@ func CheckLanguageIsValid(lang string) bool {
} }
return false return false
} }
// Tr use language to translate data. If this language translation is not available, return default english translation.
func Tr(lang i18n.Language, data string) string {
translation := GlobalTrans.Tr(lang, data)
if translation == data {
return GlobalTrans.Tr(i18n.DefaultLanguage, data)
}
return translation
}

View File

@ -102,7 +102,7 @@ func createDefaultValidator(la i18n.Language) *validator.Validate {
validate.RegisterTagNameFunc(func(fld reflect.StructField) (res string) { validate.RegisterTagNameFunc(func(fld reflect.StructField) (res string) {
defer func() { defer func() {
if len(res) > 0 { if len(res) > 0 {
res = translator.GlobalTrans.Tr(la, res) res = translator.Tr(la, res)
} }
}() }()
if jsonTag := fld.Tag.Get("json"); len(jsonTag) > 0 { if jsonTag := fld.Tag.Get("json"); len(jsonTag) > 0 {
@ -168,7 +168,7 @@ func (m *MyValidator) Check(value interface{}) (errFields []*FormErrorField, err
return nil, nil return nil, nil
} }
for _, errField := range errFields { for _, errField := range errFields {
errField.ErrorMsg = translator.GlobalTrans.Tr(m.Lang, errField.ErrorMsg) errField.ErrorMsg = translator.Tr(m.Lang, errField.ErrorMsg)
} }
return errFields, err return errFields, err
} }

View File

@ -113,7 +113,7 @@ func (uc *UserController) UserEmailLogin(ctx *gin.Context) {
if !captchaPass { if !captchaPass {
errFields := append([]*validator.FormErrorField{}, &validator.FormErrorField{ errFields := append([]*validator.FormErrorField{}, &validator.FormErrorField{
ErrorField: "captcha_code", ErrorField: "captcha_code",
ErrorMsg: translator.GlobalTrans.Tr(handler.GetLang(ctx), reason.CaptchaVerificationFailed), ErrorMsg: translator.Tr(handler.GetLang(ctx), reason.CaptchaVerificationFailed),
}) })
handler.HandleResponse(ctx, errors.BadRequest(reason.CaptchaVerificationFailed), errFields) handler.HandleResponse(ctx, errors.BadRequest(reason.CaptchaVerificationFailed), errFields)
return return
@ -124,7 +124,7 @@ func (uc *UserController) UserEmailLogin(ctx *gin.Context) {
_, _ = uc.actionService.ActionRecordAdd(ctx, schema.ActionRecordTypeLogin, ctx.ClientIP()) _, _ = uc.actionService.ActionRecordAdd(ctx, schema.ActionRecordTypeLogin, ctx.ClientIP())
errFields := append([]*validator.FormErrorField{}, &validator.FormErrorField{ errFields := append([]*validator.FormErrorField{}, &validator.FormErrorField{
ErrorField: "e_mail", ErrorField: "e_mail",
ErrorMsg: translator.GlobalTrans.Tr(handler.GetLang(ctx), reason.EmailOrPasswordWrong), ErrorMsg: translator.Tr(handler.GetLang(ctx), reason.EmailOrPasswordWrong),
}) })
handler.HandleResponse(ctx, errors.BadRequest(reason.EmailOrPasswordWrong), errFields) handler.HandleResponse(ctx, errors.BadRequest(reason.EmailOrPasswordWrong), errFields)
return return
@ -151,7 +151,7 @@ func (uc *UserController) RetrievePassWord(ctx *gin.Context) {
if !captchaPass { if !captchaPass {
errFields := append([]*validator.FormErrorField{}, &validator.FormErrorField{ errFields := append([]*validator.FormErrorField{}, &validator.FormErrorField{
ErrorField: "captcha_code", ErrorField: "captcha_code",
ErrorMsg: translator.GlobalTrans.Tr(handler.GetLang(ctx), reason.CaptchaVerificationFailed), ErrorMsg: translator.Tr(handler.GetLang(ctx), reason.CaptchaVerificationFailed),
}) })
handler.HandleResponse(ctx, errors.BadRequest(reason.CaptchaVerificationFailed), errFields) handler.HandleResponse(ctx, errors.BadRequest(reason.CaptchaVerificationFailed), errFields)
return return
@ -236,7 +236,7 @@ func (uc *UserController) UserRegisterByEmail(ctx *gin.Context) {
if !captchaPass { if !captchaPass {
errFields := append([]*validator.FormErrorField{}, &validator.FormErrorField{ errFields := append([]*validator.FormErrorField{}, &validator.FormErrorField{
ErrorField: "captcha_code", ErrorField: "captcha_code",
ErrorMsg: translator.GlobalTrans.Tr(handler.GetLang(ctx), reason.CaptchaVerificationFailed), ErrorMsg: translator.Tr(handler.GetLang(ctx), reason.CaptchaVerificationFailed),
}) })
handler.HandleResponse(ctx, errors.BadRequest(reason.CaptchaVerificationFailed), errFields) handler.HandleResponse(ctx, errors.BadRequest(reason.CaptchaVerificationFailed), errFields)
return return
@ -245,7 +245,8 @@ func (uc *UserController) UserRegisterByEmail(ctx *gin.Context) {
resp, errFields, err := uc.userService.UserRegisterByEmail(ctx, req) resp, errFields, err := uc.userService.UserRegisterByEmail(ctx, req)
if len(errFields) > 0 { if len(errFields) > 0 {
for _, field := range errFields { for _, field := range errFields {
field.ErrorMsg = translator.GlobalTrans.Tr(handler.GetLang(ctx), field.ErrorMsg) field.ErrorMsg = translator.
Tr(handler.GetLang(ctx), field.ErrorMsg)
} }
handler.HandleResponse(ctx, err, errFields) handler.HandleResponse(ctx, err, errFields)
} else { } else {
@ -312,7 +313,7 @@ func (uc *UserController) UserVerifyEmailSend(ctx *gin.Context) {
if !captchaPass { if !captchaPass {
errFields := append([]*validator.FormErrorField{}, &validator.FormErrorField{ errFields := append([]*validator.FormErrorField{}, &validator.FormErrorField{
ErrorField: "captcha_code", ErrorField: "captcha_code",
ErrorMsg: translator.GlobalTrans.Tr(handler.GetLang(ctx), reason.CaptchaVerificationFailed), ErrorMsg: translator.Tr(handler.GetLang(ctx), reason.CaptchaVerificationFailed),
}) })
handler.HandleResponse(ctx, errors.BadRequest(reason.CaptchaVerificationFailed), errFields) handler.HandleResponse(ctx, errors.BadRequest(reason.CaptchaVerificationFailed), errFields)
return return
@ -350,7 +351,7 @@ func (uc *UserController) UserModifyPassWord(ctx *gin.Context) {
if !oldPassVerification { if !oldPassVerification {
errFields := append([]*validator.FormErrorField{}, &validator.FormErrorField{ errFields := append([]*validator.FormErrorField{}, &validator.FormErrorField{
ErrorField: "old_pass", ErrorField: "old_pass",
ErrorMsg: translator.GlobalTrans.Tr(handler.GetLang(ctx), reason.OldPasswordVerificationFailed), ErrorMsg: translator.Tr(handler.GetLang(ctx), reason.OldPasswordVerificationFailed),
}) })
handler.HandleResponse(ctx, errors.BadRequest(reason.OldPasswordVerificationFailed), errFields) handler.HandleResponse(ctx, errors.BadRequest(reason.OldPasswordVerificationFailed), errFields)
return return
@ -358,7 +359,7 @@ func (uc *UserController) UserModifyPassWord(ctx *gin.Context) {
if req.OldPass == req.Pass { if req.OldPass == req.Pass {
errFields := append([]*validator.FormErrorField{}, &validator.FormErrorField{ errFields := append([]*validator.FormErrorField{}, &validator.FormErrorField{
ErrorField: "pass", ErrorField: "pass",
ErrorMsg: translator.GlobalTrans.Tr(handler.GetLang(ctx), reason.NewPasswordSameAsPreviousSetting), ErrorMsg: translator.Tr(handler.GetLang(ctx), reason.NewPasswordSameAsPreviousSetting),
}) })
handler.HandleResponse(ctx, errors.BadRequest(reason.NewPasswordSameAsPreviousSetting), errFields) handler.HandleResponse(ctx, errors.BadRequest(reason.NewPasswordSameAsPreviousSetting), errFields)
return return
@ -386,7 +387,7 @@ func (uc *UserController) UserUpdateInfo(ctx *gin.Context) {
req.UserID = middleware.GetLoginUserIDFromContext(ctx) req.UserID = middleware.GetLoginUserIDFromContext(ctx)
errFields, err := uc.userService.UpdateInfo(ctx, req) errFields, err := uc.userService.UpdateInfo(ctx, req)
for _, field := range errFields { for _, field := range errFields {
field.ErrorMsg = translator.GlobalTrans.Tr(handler.GetLang(ctx), field.ErrorMsg) field.ErrorMsg = translator.Tr(handler.GetLang(ctx), field.ErrorMsg)
} }
handler.HandleResponse(ctx, err, errFields) handler.HandleResponse(ctx, err, errFields)
} }
@ -491,7 +492,7 @@ func (uc *UserController) UserChangeEmailSendCode(ctx *gin.Context) {
if !captchaPass { if !captchaPass {
errFields := append([]*validator.FormErrorField{}, &validator.FormErrorField{ errFields := append([]*validator.FormErrorField{}, &validator.FormErrorField{
ErrorField: "captcha_code", ErrorField: "captcha_code",
ErrorMsg: translator.GlobalTrans.Tr(handler.GetLang(ctx), reason.CaptchaVerificationFailed), ErrorMsg: translator.Tr(handler.GetLang(ctx), reason.CaptchaVerificationFailed),
}) })
handler.HandleResponse(ctx, errors.BadRequest(reason.CaptchaVerificationFailed), errFields) handler.HandleResponse(ctx, errors.BadRequest(reason.CaptchaVerificationFailed), errFields)
return return

View File

@ -246,9 +246,9 @@ type QuestionPageReq struct {
} }
const ( const (
QuestionPageRespOperationTypeAsked = "question.operation_type.asked" QuestionPageRespOperationTypeAsked = "asked"
QuestionPageRespOperationTypeAnswered = "question.operation_type.answered" QuestionPageRespOperationTypeAnswered = "answered"
QuestionPageRespOperationTypeModified = "question.operation_type.modified" QuestionPageRespOperationTypeModified = "modified"
) )
type QuestionPageResp struct { type QuestionPageResp struct {

View File

@ -134,7 +134,7 @@ type SiteThemeResp struct {
func (s *SiteThemeResp) TrTheme(ctx context.Context) { func (s *SiteThemeResp) TrTheme(ctx context.Context) {
la := handler.GetLangByCtx(ctx) la := handler.GetLangByCtx(ctx)
for _, option := range s.ThemeOptions { for _, option := range s.ThemeOptions {
tr := translator.GlobalTrans.Tr(la, option.Value) tr := translator.Tr(la, option.Value)
// if tr is equal the option value means not found translation, so use the original label // if tr is equal the option value means not found translation, so use the original label
if tr != option.Value { if tr != option.Value {
option.Label = tr option.Label = tr

View File

@ -134,7 +134,7 @@ func (ns *NotificationService) GetNotificationPage(ctx context.Context, searchCo
continue continue
} }
lang, _ := ctx.Value(constant.AcceptLanguageFlag).(i18n.Language) lang, _ := ctx.Value(constant.AcceptLanguageFlag).(i18n.Language)
item.NotificationAction = translator.GlobalTrans.Tr(lang, item.NotificationAction) item.NotificationAction = translator.Tr(lang, item.NotificationAction)
item.ID = notificationInfo.ID item.ID = notificationInfo.ID
item.UpdateTime = notificationInfo.UpdatedAt.Unix() item.UpdateTime = notificationInfo.UpdatedAt.Unix()
if notificationInfo.IsRead == schema.NotificationRead { if notificationInfo.IsRead == schema.NotificationRead {

View File

@ -6,9 +6,7 @@ import (
"time" "time"
"github.com/answerdev/answer/internal/base/constant" "github.com/answerdev/answer/internal/base/constant"
"github.com/answerdev/answer/internal/base/handler"
"github.com/answerdev/answer/internal/base/reason" "github.com/answerdev/answer/internal/base/reason"
"github.com/answerdev/answer/internal/base/translator"
"github.com/answerdev/answer/internal/service/activity_common" "github.com/answerdev/answer/internal/service/activity_common"
"github.com/answerdev/answer/internal/service/activity_queue" "github.com/answerdev/answer/internal/service/activity_queue"
"github.com/answerdev/answer/internal/service/config" "github.com/answerdev/answer/internal/service/config"
@ -250,13 +248,7 @@ func (qs *QuestionCommon) Info(ctx context.Context, questionID string, loginUser
func (qs *QuestionCommon) FormatQuestionsPage( func (qs *QuestionCommon) FormatQuestionsPage(
ctx context.Context, questionList []*entity.Question, loginUserID string, orderCond string) ( ctx context.Context, questionList []*entity.Question, loginUserID string, orderCond string) (
formattedQuestions []*schema.QuestionPageResp, err error) { formattedQuestions []*schema.QuestionPageResp, err error) {
language := handler.GetLangByCtx(ctx)
askedOp := translator.GlobalTrans.Tr(language, schema.QuestionPageRespOperationTypeAsked)
answeredOp := translator.GlobalTrans.Tr(language, schema.QuestionPageRespOperationTypeAnswered)
modifiedOp := translator.GlobalTrans.Tr(language, schema.QuestionPageRespOperationTypeModified)
formattedQuestions = make([]*schema.QuestionPageResp, 0) formattedQuestions = make([]*schema.QuestionPageResp, 0)
questionIDs := make([]string, 0) questionIDs := make([]string, 0)
userIDs := make([]string, 0) userIDs := make([]string, 0)
for _, questionInfo := range questionList { for _, questionInfo := range questionList {
@ -300,20 +292,20 @@ func (qs *QuestionCommon) FormatQuestionsPage(
// if order condition is newest or nobody edited or nobody answered, only show question author // if order condition is newest or nobody edited or nobody answered, only show question author
if orderCond == schema.QuestionOrderCondNewest || (!haveEdited && !haveAnswered) { if orderCond == schema.QuestionOrderCondNewest || (!haveEdited && !haveAnswered) {
t.OperationType = askedOp t.OperationType = schema.QuestionPageRespOperationTypeAsked
t.OperatedAt = questionInfo.CreatedAt.Unix() t.OperatedAt = questionInfo.CreatedAt.Unix()
t.Operator = &schema.QuestionPageRespOperator{ID: questionInfo.UserID} t.Operator = &schema.QuestionPageRespOperator{ID: questionInfo.UserID}
} else { } else {
// if no one // if no one
if haveEdited { if haveEdited {
t.OperationType = modifiedOp t.OperationType = schema.QuestionPageRespOperationTypeModified
t.OperatedAt = questionInfo.UpdatedAt.Unix() t.OperatedAt = questionInfo.UpdatedAt.Unix()
t.Operator = &schema.QuestionPageRespOperator{ID: questionInfo.LastEditUserID} t.Operator = &schema.QuestionPageRespOperator{ID: questionInfo.LastEditUserID}
} }
if haveAnswered { if haveAnswered {
if t.LastAnsweredAt.Unix() > t.OperatedAt { if t.LastAnsweredAt.Unix() > t.OperatedAt {
t.OperationType = answeredOp t.OperationType = schema.QuestionPageRespOperationTypeAnswered
t.OperatedAt = t.LastAnsweredAt.Unix() t.OperatedAt = t.LastAnsweredAt.Unix()
t.Operator = &schema.QuestionPageRespOperator{ID: t.LastAnsweredUserID} t.Operator = &schema.QuestionPageRespOperator{ID: t.LastAnsweredUserID}
} }

View File

@ -140,8 +140,8 @@ func (qs *QuestionService) CloseMsgList(ctx context.Context, lang i18n.Language)
return nil, errors.InternalServer(reason.UnknownError).WithError(err).WithStack() return nil, errors.InternalServer(reason.UnknownError).WithError(err).WithStack()
} }
for _, t := range resp { for _, t := range resp {
t.Name = translator.GlobalTrans.Tr(lang, t.Name) t.Name = translator.Tr(lang, t.Name)
t.Description = translator.GlobalTrans.Tr(lang, t.Description) t.Description = translator.Tr(lang, t.Description)
} }
return resp, err return resp, err
} }
@ -163,7 +163,7 @@ func (qs *QuestionService) CheckAddQuestion(ctx context.Context, req *schema.Que
errorlist := make([]*validator.FormErrorField, 0) errorlist := make([]*validator.FormErrorField, 0)
errorlist = append(errorlist, &validator.FormErrorField{ errorlist = append(errorlist, &validator.FormErrorField{
ErrorField: "tags", ErrorField: "tags",
ErrorMsg: translator.GlobalTrans.Tr(handler.GetLangByCtx(ctx), reason.TagNotFound), ErrorMsg: translator.Tr(handler.GetLangByCtx(ctx), reason.TagNotFound),
}) })
err = errors.BadRequest(reason.RecommendTagEnter) err = errors.BadRequest(reason.RecommendTagEnter)
return errorlist, err return errorlist, err
@ -176,7 +176,7 @@ func (qs *QuestionService) CheckAddQuestion(ctx context.Context, req *schema.Que
errorlist := make([]*validator.FormErrorField, 0) errorlist := make([]*validator.FormErrorField, 0)
errorlist = append(errorlist, &validator.FormErrorField{ errorlist = append(errorlist, &validator.FormErrorField{
ErrorField: "tags", ErrorField: "tags",
ErrorMsg: translator.GlobalTrans.Tr(handler.GetLangByCtx(ctx), reason.RecommendTagEnter), ErrorMsg: translator.Tr(handler.GetLangByCtx(ctx), reason.RecommendTagEnter),
}) })
err = errors.BadRequest(reason.RecommendTagEnter) err = errors.BadRequest(reason.RecommendTagEnter)
return errorlist, err return errorlist, err
@ -213,7 +213,7 @@ func (qs *QuestionService) AddQuestion(ctx context.Context, req *schema.Question
errorlist := make([]*validator.FormErrorField, 0) errorlist := make([]*validator.FormErrorField, 0)
errorlist = append(errorlist, &validator.FormErrorField{ errorlist = append(errorlist, &validator.FormErrorField{
ErrorField: "tags", ErrorField: "tags",
ErrorMsg: translator.GlobalTrans.Tr(handler.GetLangByCtx(ctx), reason.TagNotFound), ErrorMsg: translator.Tr(handler.GetLangByCtx(ctx), reason.TagNotFound),
}) })
err = errors.BadRequest(reason.RecommendTagEnter) err = errors.BadRequest(reason.RecommendTagEnter)
return errorlist, err return errorlist, err
@ -226,7 +226,7 @@ func (qs *QuestionService) AddQuestion(ctx context.Context, req *schema.Question
errorlist := make([]*validator.FormErrorField, 0) errorlist := make([]*validator.FormErrorField, 0)
errorlist = append(errorlist, &validator.FormErrorField{ errorlist = append(errorlist, &validator.FormErrorField{
ErrorField: "tags", ErrorField: "tags",
ErrorMsg: translator.GlobalTrans.Tr(handler.GetLangByCtx(ctx), reason.RecommendTagEnter), ErrorMsg: translator.Tr(handler.GetLangByCtx(ctx), reason.RecommendTagEnter),
}) })
err = errors.BadRequest(reason.RecommendTagEnter) err = errors.BadRequest(reason.RecommendTagEnter)
return errorlist, err return errorlist, err
@ -539,7 +539,7 @@ func (qs *QuestionService) UpdateQuestion(ctx context.Context, req *schema.Quest
errorlist := make([]*validator.FormErrorField, 0) errorlist := make([]*validator.FormErrorField, 0)
errorlist = append(errorlist, &validator.FormErrorField{ errorlist = append(errorlist, &validator.FormErrorField{
ErrorField: "tags", ErrorField: "tags",
ErrorMsg: translator.GlobalTrans.Tr(handler.GetLangByCtx(ctx), reason.RecommendTagEnter), ErrorMsg: translator.Tr(handler.GetLangByCtx(ctx), reason.RecommendTagEnter),
}) })
err = errors.BadRequest(reason.RecommendTagEnter) err = errors.BadRequest(reason.RecommendTagEnter)
return errorlist, err return errorlist, err

View File

@ -74,8 +74,8 @@ func (rs *ReportService) GetReportTypeList(ctx context.Context, lang i18n.Langua
err = errors.BadRequest(reason.UnknownError) err = errors.BadRequest(reason.UnknownError)
} }
for _, t := range resp { for _, t := range resp {
t.Name = translator.GlobalTrans.Tr(lang, t.Name) t.Name = translator.Tr(lang, t.Name)
t.Description = translator.GlobalTrans.Tr(lang, t.Description) t.Description = translator.Tr(lang, t.Description)
} }
return resp, err return resp, err
} }

View File

@ -72,13 +72,13 @@ func (rs *RoleService) GetRoleMapping(ctx context.Context) (roleMapping map[int]
func (rs *RoleService) translateRole(ctx context.Context, role *entity.Role) { func (rs *RoleService) translateRole(ctx context.Context, role *entity.Role) {
switch role.Name { switch role.Name {
case roleUserName: case roleUserName:
role.Name = translator.GlobalTrans.Tr(handler.GetLangByCtx(ctx), trRoleNameUser) role.Name = translator.Tr(handler.GetLangByCtx(ctx), trRoleNameUser)
role.Description = translator.GlobalTrans.Tr(handler.GetLangByCtx(ctx), trRoleDescriptionUser) role.Description = translator.Tr(handler.GetLangByCtx(ctx), trRoleDescriptionUser)
case roleAdminName: case roleAdminName:
role.Name = translator.GlobalTrans.Tr(handler.GetLangByCtx(ctx), trRoleNameAdmin) role.Name = translator.Tr(handler.GetLangByCtx(ctx), trRoleNameAdmin)
role.Description = translator.GlobalTrans.Tr(handler.GetLangByCtx(ctx), trRoleDescriptionAdmin) role.Description = translator.Tr(handler.GetLangByCtx(ctx), trRoleDescriptionAdmin)
case roleModeratorName: case roleModeratorName:
role.Name = translator.GlobalTrans.Tr(handler.GetLangByCtx(ctx), trRoleNameModerator) role.Name = translator.Tr(handler.GetLangByCtx(ctx), trRoleNameModerator)
role.Description = translator.GlobalTrans.Tr(handler.GetLangByCtx(ctx), trRoleDescriptionModerator) role.Description = translator.Tr(handler.GetLangByCtx(ctx), trRoleDescriptionModerator)
} }
} }

View File

@ -510,7 +510,7 @@ func (us *UserService) UserChangeEmailSendCode(ctx context.Context, req *schema.
if exist { if exist {
resp = append([]*validator.FormErrorField{}, &validator.FormErrorField{ resp = append([]*validator.FormErrorField{}, &validator.FormErrorField{
ErrorField: "e_mail", ErrorField: "e_mail",
ErrorMsg: translator.GlobalTrans.Tr(handler.GetLangByCtx(ctx), reason.EmailDuplicate), ErrorMsg: translator.Tr(handler.GetLangByCtx(ctx), reason.EmailDuplicate),
}) })
return resp, errors.BadRequest(reason.EmailDuplicate) return resp, errors.BadRequest(reason.EmailDuplicate)
} }