package middleware import ( "bytes" "github.com/flipped-aurora/gin-vue-admin/server/utils" "io/ioutil" "net/http" "strconv" "time" "github.com/flipped-aurora/gin-vue-admin/server/global" "github.com/flipped-aurora/gin-vue-admin/server/model/system" "github.com/flipped-aurora/gin-vue-admin/server/service" "github.com/gin-gonic/gin" "go.uber.org/zap" ) var operationRecordService = service.ServiceGroupApp.SystemServiceGroup.OperationRecordService func OperationRecord() gin.HandlerFunc { return func(c *gin.Context) { var body []byte var userId int if c.Request.Method != http.MethodGet { var err error body, err = ioutil.ReadAll(c.Request.Body) if err != nil { global.GVA_LOG.Error("read body from request error:", zap.Any("err", err)) } else { c.Request.Body = ioutil.NopCloser(bytes.NewBuffer(body)) } } claims := utils.GetClaims(c) if claims.ID != 0 { userId = int(claims.ID) } else { id, err := strconv.Atoi(c.Request.Header.Get("x-user-id")) if err != nil { userId = 0 } userId = id } record := system.SysOperationRecord{ Ip: c.ClientIP(), Method: c.Request.Method, Path: c.Request.URL.Path, Agent: c.Request.UserAgent(), Body: string(body), UserID: userId, } // 存在某些未知错误 TODO //values := c.Request.Header.Values("content-type") //if len(values) >0 && strings.Contains(values[0], "boundary") { // record.Body = "file" //} writer := responseBodyWriter{ ResponseWriter: c.Writer, body: &bytes.Buffer{}, } c.Writer = writer now := time.Now() c.Next() latency := time.Since(now) record.ErrorMessage = c.Errors.ByType(gin.ErrorTypePrivate).String() record.Status = c.Writer.Status() record.Latency = latency record.Resp = writer.body.String() if err := operationRecordService.CreateSysOperationRecord(record); err != nil { global.GVA_LOG.Error("create operation record error:", zap.Any("err", err)) } } } 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) }