add gin utils

This commit is contained in:
2022-04-08 14:41:53 +08:00
parent 01f5c3f43d
commit 91766b82ff
5 changed files with 296 additions and 0 deletions

26
pkg/gin/frame/cors.go Normal file
View File

@@ -0,0 +1,26 @@
package frame
import (
"net/http"
"github.com/gin-gonic/gin"
)
func Cors() gin.HandlerFunc {
return func(c *gin.Context) {
method := c.Request.Method
c.Header("Access-Control-Allow-Origin", "*")
c.Header("Access-Control-Allow-Headers", "Content-Type,AccessToken,X-CSRF-Token, Authorization, Token")
c.Header("Access-Control-Allow-Methods", "GET,POST,PUT,PATCH,DELETE,OPTIONS")
c.Header("Access-Control-Expose-Headers", "Content-Length, Access-Control-Allow-Origin, Access-Control-Allow-Headers, Content-Type")
c.Header("Access-Control-Allow-Credentials", "true")
//放行所有OPTIONS方法
if method == "OPTIONS" {
c.AbortWithStatus(http.StatusNoContent)
}
// 处理请求
c.Next()
}
}

View File

@@ -0,0 +1,150 @@
package frame
import (
"bytes"
"encoding/json"
"fmt"
"io"
"io/ioutil"
"net/http"
"strings"
"time"
"github.com/gin-gonic/gin"
"github.com/lyydhl-zhang/common-module/pkg/logger"
)
type requestLog struct {
RequestID string `json:"request_id"`
RequestTime string `json:"request_time"`
RequestMethod string `json:"request_method"`
RequestUri string `json:"request_uri"`
RequestProto string `json:"request_proto"`
RequestUa string `json:"request_ua"`
RequestReferer string `json:"request_referer"`
RequestPostData string `json:"request_post_data"`
RequestClientIp string `json:"request_client_ip"`
ResponseCode int `json:"response_code"`
ResponseMsg string `json:"response_msg"`
ResponseData interface{} `json:"response_data"`
TimeUsed string `json:"time_used"`
}
type bodyLogWriter struct {
gin.ResponseWriter
body *bytes.Buffer
}
func (w bodyLogWriter) Write(b []byte) (int, error) {
w.body.Write(b)
return w.ResponseWriter.Write(b)
}
func (w bodyLogWriter) WriteString(s string) (int, error) {
w.body.WriteString(s)
return w.ResponseWriter.WriteString(s)
}
func RequestLog() gin.HandlerFunc {
return func(c *gin.Context) {
// 开始时间
startTime := time.Now()
bodyLogWriter := &bodyLogWriter{body: bytes.NewBufferString(""), ResponseWriter: c.Writer}
c.Writer = bodyLogWriter
// 获取请求参数
requestBody := getRequestBody(c)
// 处理请求
c.Next()
var requestID string
var responseCode int
var responseMsg string
var responseData interface{}
responseBody := bodyLogWriter.body.String()
if len(responseBody) > 0 {
response := response{}
err := json.Unmarshal([]byte(responseBody), &response)
if err == nil {
requestID = response.RequestId
responseCode = response.Code
responseMsg = response.Message
responseData = response.Data
}
}
// 日志格式
accessLog := &requestLog{
RequestID: requestID,
RequestTime: startTime.Format("2006-01-02 15:04:05.999999999"),
RequestMethod: c.Request.Method,
RequestUri: c.Request.RequestURI,
RequestProto: c.Request.Proto,
RequestUa: c.Request.UserAgent(),
RequestReferer: c.Request.Referer(),
RequestPostData: requestBody,
RequestClientIp: c.ClientIP(),
ResponseCode: responseCode,
ResponseMsg: responseMsg,
ResponseData: responseData,
TimeUsed: fmt.Sprintf("%s", time.Since(startTime)), // 记录请求所用时间
}
l, err := json.Marshal(accessLog)
if err == nil {
logger.Logger.Infof("%s", l)
} else {
logger.Logger.Infof("%v", accessLog)
}
}
}
// getRequestBody 获取请求参数
func getRequestBody(c *gin.Context) string {
switch c.Request.Method {
case http.MethodPost:
fallthrough
case http.MethodPut:
fallthrough
case http.MethodPatch:
// ioutil
//var bodyBytes []byte
//bodyBytes, err := ioutil.ReadAll(c.Request.Body)
//if err != nil {
// return ""
//}
//
//c.Request.Body = ioutil.NopCloser(bytes.NewBuffer(bodyBytes))
//return string(bodyBytes)
// buffer
var buffer [512]byte
result := bytes.NewBuffer(nil)
for {
n, err := c.Request.Body.Read(buffer[0:])
result.Write(buffer[0:n])
if err != nil && err == io.EOF {
break
} else if err != nil {
return ""
}
}
c.Request.Body = ioutil.NopCloser(result)
return formatStr(result.String())
}
return ""
}
func formatStr(content string) string {
if len(content) == 0 {
return ""
}
content = strings.Replace(content, " ", "", -1)
content = strings.Replace(content, "\n", "", -1)
content = strings.Replace(content, "\r", "", -1)
return content
}

67
pkg/gin/frame/response.go Normal file
View File

@@ -0,0 +1,67 @@
package frame
import (
"github.com/gin-gonic/gin"
"github.com/google/uuid"
)
// Response 数据结构体
type response struct {
// Code 业务状态码
Code int `json:"code"`
// Message 提示信息
Message string `json:"message"`
// Data 数据用interface{}的目的是可以用任意数据
Data interface{} `json:"data"`
// RequestId 请求ID
RequestId string `json:"request_id"`
// Errors 错误提示,如 xx字段不能为空等
// Errors []ErrorItem `json:"errors"`
}
// ErrorItem 错误项
//type ErrorItem struct {
// Key string `json:"key"`
// Value string `json:"error"`
//}
// NewResponse return response instance
func NewResponse() *response {
return &response{
Code: 200,
Message: "",
Data: nil,
RequestId: uuid.NewString(),
}
}
// Wrapper include context
type wrapper struct {
ctx *gin.Context
}
// WrapContext wrap content
func WrapContext(ctx *gin.Context) *wrapper {
return &wrapper{ctx: ctx}
}
// Json 输出json,支持自定义response结构体
func (wrapper *wrapper) Json(response *response) {
wrapper.ctx.JSON(200, response)
}
// Success 成功的输出
func (wrapper *wrapper) Success(message string, data interface{}) {
response := NewResponse()
response.Message = message
response.Data = data
wrapper.Json(response)
}
// Error 错误输出
func (wrapper *wrapper) Error(code int, message string) {
response := NewResponse()
response.Code = code
response.Message = message
wrapper.Json(response)
}