add gin utils
This commit is contained in:
26
pkg/gin/frame/cors.go
Normal file
26
pkg/gin/frame/cors.go
Normal 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()
|
||||
}
|
||||
}
|
||||
150
pkg/gin/frame/request_log.go
Normal file
150
pkg/gin/frame/request_log.go
Normal 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
67
pkg/gin/frame/response.go
Normal 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)
|
||||
}
|
||||
Reference in New Issue
Block a user