operation.go 1.9 KB
Newer Older
G
Granty1 已提交
1 2 3 4 5
package middleware

import (
	"bytes"
	"gin-vue-admin/global"
G
granty1 已提交
6
	"gin-vue-admin/model"
7
	"gin-vue-admin/model/request"
G
granty1 已提交
8
	"gin-vue-admin/service"
G
Granty1 已提交
9
	"github.com/gin-gonic/gin"
10
	"go.uber.org/zap"
G
Granty1 已提交
11 12
	"io/ioutil"
	"net/http"
13
	"strconv"
G
Granty1 已提交
14
	"time"
G
Granty1 已提交
15 16
)

G
Granty1 已提交
17
func OperationRecord() gin.HandlerFunc {
G
Granty1 已提交
18
	return func(c *gin.Context) {
G
Granty1 已提交
19
		var body []byte
20
		var userId int
G
Granty1 已提交
21 22 23 24
		if c.Request.Method != http.MethodGet {
			var err error
			body, err = ioutil.ReadAll(c.Request.Body)
			if err != nil {
25
				global.GVA_LOG.Error("read body from request error:", zap.Any("err", err))
G
Granty1 已提交
26 27
			} else {
				c.Request.Body = ioutil.NopCloser(bytes.NewBuffer(body))
G
Granty1 已提交
28
			}
G
Granty1 已提交
29
		}
30 31 32
		if claims, ok := c.Get("claims"); ok {
			waitUse := claims.(*request.CustomClaims)
			userId = int(waitUse.ID)
33
		} else {
34 35 36 37 38
			id, err := strconv.Atoi(c.Request.Header.Get("x-user-id"))
			if err != nil {
				userId = 0
			}
			userId = id
G
Granty1 已提交
39 40 41 42 43 44 45
		}
		record := model.SysOperationRecord{
			Ip:     c.ClientIP(),
			Method: c.Request.Method,
			Path:   c.Request.URL.Path,
			Agent:  c.Request.UserAgent(),
			Body:   string(body),
Mr.奇淼('s avatar
Mr.奇淼( 已提交
46
			UserID: userId,
G
Granty1 已提交
47
		}
48 49 50 51 52
		// 存在某些未知错误 TODO
		//values := c.Request.Header.Values("content-type")
		//if len(values) >0 && strings.Contains(values[0], "boundary") {
		//	record.Body = "file"
		//}
G
Granty1 已提交
53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68
		writer := responseBodyWriter{
			ResponseWriter: c.Writer,
			body:           &bytes.Buffer{},
		}
		c.Writer = writer
		now := time.Now()

		c.Next()

		latency := time.Now().Sub(now)
		record.ErrorMessage = c.Errors.ByType(gin.ErrorTypePrivate).String()
		record.Status = c.Writer.Status()
		record.Latency = latency
		record.Resp = writer.body.String()

		if err := service.CreateSysOperationRecord(record); err != nil {
69
			global.GVA_LOG.Error("create operation record error:", zap.Any("err", err))
G
Granty1 已提交
70 71 72 73
		}
	}
}

G
Granty1 已提交
74 75 76 77 78 79 80 81
type responseBodyWriter struct {
	gin.ResponseWriter
	body *bytes.Buffer
}

func (r responseBodyWriter) Write(b []byte) (int, error) {
	r.body.Write(b)
	return r.ResponseWriter.Write(b)
G
Granty1 已提交
82
}