docs(website): 添加简记memo产品原型和UI设计规范文档

- 新增「简记memo」一体化小程序产品原型设计文档
- 新增简记memo完整版UI视觉设计规范和界面细节
- 添加IDEA项目配置文件.gitignore
- 创建404页面HTML文件,包含响应式布局和错误提示
- 添加关于页面HTML文件,展示品牌介绍和团队信息
- 实现AES加解密工具函数,支持请求体加密
- 添加用户协议页面基础框架
This commit is contained in:
sunct
2026-07-31 14:12:32 +08:00
commit 3c3bf53ae4
115 changed files with 21304 additions and 0 deletions
+88
View File
@@ -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 生成请求IDbase36 紧凑字符串)
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),
)
}
}