i18n.go 2.7 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139
  1. package middleware
  2. import (
  3. "app/commons/constant"
  4. "app/commons/services"
  5. "bufio"
  6. "bytes"
  7. "fmt"
  8. "github.com/gin-gonic/gin"
  9. "github.com/tidwall/gjson"
  10. "github.com/tidwall/sjson"
  11. "net"
  12. "net/http"
  13. )
  14. func I18n() gin.HandlerFunc {
  15. return func(ctx *gin.Context) {
  16. lang := constant.LangeEn // 默认英文
  17. // postman会覆盖掉language
  18. if val := ctx.GetHeader(constant.HeaderKeyLang); len(val) > 0 {
  19. lang = val
  20. }
  21. if val := ctx.GetHeader(constant.HeaderKeyLanguage); len(val) > 0 {
  22. lang = val
  23. }
  24. ctx.Set(constant.HeaderKeyLang, lang)
  25. // 开始处理返回结果
  26. w := NewResWriter(ctx.Writer)
  27. ctx.Writer = w
  28. // 调用下一个中间件
  29. ctx.Next()
  30. // 最终输出内容
  31. defer func() {
  32. w.Flush()
  33. }()
  34. var err error
  35. // 获取返回结果
  36. if bodyString := w.Body.String(); len(bodyString) > 0 {
  37. msg := gjson.Get(bodyString, "msg").String()
  38. if len(msg) == 0 {
  39. return
  40. }
  41. // 翻译返回码
  42. key := fmt.Sprintf("%s", msg)
  43. i18nText := services.GetI18nService().Translate(lang, key)
  44. bodyString, err = sjson.Set(bodyString, "msg", i18nText)
  45. if err != nil {
  46. return
  47. }
  48. // 重新写入响应
  49. w.Body.Reset()
  50. w.Body.Write([]byte(bodyString))
  51. }
  52. }
  53. }
  54. type ResWriter struct {
  55. Writer gin.ResponseWriter // the actual ResponseWriter to flush to
  56. status int // the HTTP response code from WriteHeader
  57. Body *bytes.Buffer // the response content body
  58. Flushed bool
  59. }
  60. func NewResWriter(w gin.ResponseWriter) *ResWriter {
  61. return &ResWriter{
  62. Writer: w,
  63. status: w.Status(),
  64. Body: &bytes.Buffer{},
  65. }
  66. }
  67. func (w *ResWriter) Header() http.Header {
  68. return w.Writer.Header() // use the actual response header
  69. }
  70. func (w *ResWriter) Write(buf []byte) (int, error) {
  71. w.Body.Write(buf)
  72. return len(buf), nil
  73. }
  74. func (w *ResWriter) WriteString(s string) (n int, err error) {
  75. n, err = w.Write([]byte(s))
  76. return
  77. }
  78. const (
  79. noWritten = -1
  80. )
  81. func (w *ResWriter) Written() bool {
  82. return w.Body.Len() != noWritten
  83. }
  84. func (w *ResWriter) WriteHeader(status int) {
  85. w.status = status
  86. }
  87. func (w *ResWriter) WriteHeaderNow() {
  88. }
  89. func (w *ResWriter) Status() int {
  90. return w.status
  91. }
  92. func (w *ResWriter) Size() int {
  93. return w.Body.Len()
  94. }
  95. func (w *ResWriter) Hijack() (net.Conn, *bufio.ReadWriter, error) {
  96. return w.Writer.(http.Hijacker).Hijack()
  97. }
  98. func (w *ResWriter) CloseNotify() <-chan bool {
  99. return w.Writer.(http.CloseNotifier).CloseNotify()
  100. }
  101. func (w *ResWriter) Pusher() http.Pusher {
  102. return w.Pusher()
  103. }
  104. func (w *ResWriter) Flush() {
  105. w.realFlush()
  106. }
  107. func (w *ResWriter) realFlush() {
  108. if w.Flushed {
  109. return
  110. }
  111. w.Writer.WriteHeader(w.status)
  112. if w.Body.Len() > 0 {
  113. _, err := w.Writer.Write(w.Body.Bytes())
  114. if err != nil {
  115. panic(err)
  116. }
  117. w.Body.Reset()
  118. }
  119. w.Flushed = true
  120. }