// 统一返回格式 + 自动加密 package utils import ( "encoding/json" "go.uber.org/zap" "net/http" "simple-memo/global" "github.com/gin-gonic/gin" ) // Response 统一返回结构体 type Response struct { Code int `json:"code"` // 200成功 Msg string `json:"msg"` // 提示信息 Data interface{} `json:"data,omitempty"` } // LogContextFields 从 context 中提取链路日志字段 func LogContextFields(c *gin.Context) []zap.Field { fields := []zap.Field{} if c == nil { return fields } ctx := c.Request.Context() // 优先从标准 context 读取 if v := ctx.Value(RequestIdKey); v != nil { fields = append(fields, zap.String("request_id", v.(string))) } else if v, ok := c.Get("request_id"); ok { fields = append(fields, zap.String("request_id", v.(string))) } if v := ctx.Value(RequestRouteKey); v != nil { fields = append(fields, zap.String("route", v.(string))) } else if v, ok := c.Get("route"); ok { fields = append(fields, zap.String("route", v.(string))) } if v := ctx.Value(ClientIPKey); v != nil { fields = append(fields, zap.String("client_ip", v.(string))) } else if v, ok := c.Get("client_ip"); ok { fields = append(fields, zap.String("client_ip", v.(string))) } if uid := c.GetUint("userID"); uid > 0 { fields = append(fields, zap.Uint("user_id", uid)) } return fields } // Result 统一返回(根据请求路径决定是否加密) func Result(c *gin.Context, code int, msg string, data interface{}) { // 添加缓存控制头,防止浏览器缓存 c.Header("Cache-Control", "no-cache, no-store, must-revalidate") c.Header("Pragma", "no-cache") c.Header("Expires", "0") resp := Response{Code: code, Msg: msg, Data: data} // 先序列化成JSON jsonStr, _ := json.Marshal(resp) // ====================== 日志:打印【要加密的明文】 ====================== baseFields := LogContextFields(c) global.Logger.Info("【返回原始明文】", append(baseFields, zap.String("path", c.Request.URL.Path), zap.String("raw_data", string(jsonStr)), )..., ) // 判断是否为网页端接口(/api/web 路径) isWebAPI := len(c.Request.URL.Path) >= 8 && c.Request.URL.Path[:8] == "/api/web" if isWebAPI { // 网页端:直接返回JSON,不加密 c.JSON(http.StatusOK, resp) } else { // 小程序端:加密返回 encrypted, err := AESEncrypt(jsonStr) if err != nil { global.Logger.Error("加密失败", append(baseFields, zap.Error(err))..., ) c.JSON(http.StatusOK, Response{Code: 500, Msg: "加密错误"}) return } // ====================== 日志:打印【加密后返回给前端的串】 ====================== global.Logger.Info("【返回加密数据】", append(baseFields, zap.String("encrypt_data", encrypted), )..., ) c.JSON(http.StatusOK, gin.H{"data": encrypted}) } } // Ok 成功 func Ok(c *gin.Context, data interface{}) { Result(c, 200, "success", data) } // Fail 失败 func Fail(c *gin.Context, msg string, code ...int) { needCode := 400 if len(code) > 0 { needCode = code[0] } Result(c, needCode, msg, nil) }