docs(website): 添加简记memo产品原型和UI设计规范文档
- 新增「简记memo」一体化小程序产品原型设计文档 - 新增简记memo完整版UI视觉设计规范和界面细节 - 添加IDEA项目配置文件.gitignore - 创建404页面HTML文件,包含响应式布局和错误提示 - 添加关于页面HTML文件,展示品牌介绍和团队信息 - 实现AES加解密工具函数,支持请求体加密 - 添加用户协议页面基础框架
This commit is contained in:
@@ -0,0 +1,88 @@
|
||||
// 请求日志中间件:记录请求ID、路由、客户端IP等关键信息
|
||||
package middleware
|
||||
|
||||
import (
|
||||
"context"
|
||||
"fmt"
|
||||
"simple-memo/global"
|
||||
"simple-memo/utils"
|
||||
"strconv"
|
||||
"time"
|
||||
|
||||
"github.com/gin-gonic/gin"
|
||||
"github.com/sony/sonyflake"
|
||||
"go.uber.org/zap"
|
||||
)
|
||||
|
||||
// requestIDSF 用于生成全局唯一的请求ID
|
||||
var requestIDSF *sonyflake.Sonyflake
|
||||
|
||||
func init() {
|
||||
requestIDSF = sonyflake.NewSonyflake(sonyflake.Settings{})
|
||||
}
|
||||
|
||||
// genRequestID 基于 sonyflake 生成请求ID(base36 紧凑字符串)
|
||||
func genRequestID() string {
|
||||
if requestIDSF == nil {
|
||||
return fmt.Sprintf("%x", time.Now().UnixNano())
|
||||
}
|
||||
id, err := requestIDSF.NextID()
|
||||
if err != nil {
|
||||
return fmt.Sprintf("%x", time.Now().UnixNano())
|
||||
}
|
||||
// base36 编码:紧凑且只含 [0-9a-z]
|
||||
return strconv.FormatUint(id, 36)
|
||||
}
|
||||
|
||||
// RequestLog 请求日志中间件
|
||||
func RequestLog() gin.HandlerFunc {
|
||||
return func(c *gin.Context) {
|
||||
start := time.Now()
|
||||
|
||||
// 优先从请求头获取 request-id,否则自动生成
|
||||
requestID := c.GetHeader("X-Request-ID")
|
||||
if requestID == "" {
|
||||
requestID = genRequestID()
|
||||
}
|
||||
|
||||
// 客户端IP
|
||||
clientIP := c.ClientIP()
|
||||
|
||||
// 路由路径
|
||||
route := c.Request.URL.Path
|
||||
|
||||
// 请求方法
|
||||
method := c.Request.Method
|
||||
|
||||
// 写入标准 context,供整条链路使用
|
||||
ctx := context.WithValue(c.Request.Context(), utils.RequestIdKey, requestID)
|
||||
ctx = context.WithValue(ctx, utils.RequestRouteKey, route)
|
||||
ctx = context.WithValue(ctx, utils.ClientIPKey, clientIP)
|
||||
c.Request = c.Request.WithContext(ctx)
|
||||
|
||||
// 同时记录到 gin context,兼容老代码
|
||||
c.Set("request_id", requestID)
|
||||
c.Set("client_ip", clientIP)
|
||||
c.Set("route", route)
|
||||
|
||||
// 打印请求进入日志
|
||||
global.Logger.Info("【请求进入】",
|
||||
zap.String("request_id", requestID),
|
||||
zap.String("route", route),
|
||||
zap.String("method", method),
|
||||
zap.String("client_ip", clientIP),
|
||||
zap.String("user_agent", c.Request.UserAgent()),
|
||||
)
|
||||
|
||||
c.Next()
|
||||
|
||||
// 请求结束后打印耗时日志
|
||||
duration := time.Since(start)
|
||||
global.Logger.Info("【请求结束】",
|
||||
zap.String("request_id", requestID),
|
||||
zap.String("route", route),
|
||||
zap.Int("status", c.Writer.Status()),
|
||||
zap.Duration("duration", duration),
|
||||
)
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user