From 8bc3fd3cb735122db9aebc2c5caf75f751701f56 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E6=98=94=E5=BF=B5?= <12574910+72wo@users.noreply.github.com> Date: Sat, 28 Feb 2026 00:21:33 +0800 Subject: [PATCH] =?UTF-8?q?```=20feat(dict):=20=E6=B7=BB=E5=8A=A0=E5=AD=97?= =?UTF-8?q?=E5=85=B8=E6=95=B0=E6=8D=AE=E5=8E=8B=E7=BC=A9=E5=8A=A0=E5=AF=86?= =?UTF-8?q?=E5=8A=9F=E8=83=BD?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit - 在字典数据接口中集成压缩和加密机制 - 实现Gzip压缩、XOR加密和Base64编码流程 - 新增CompressAndEncrypt和DecryptAndDecompress工具函数 - 在middleware中启用压缩中间件支持 ``` --- modules/base/middleware/gzib.go | 70 ++++++++++++++++++ modules/base/middleware/middleware.go | 2 +- modules/dict/controller/admin/dict_info.go | 85 +++++++++++++++++++++- 3 files changed, 154 insertions(+), 3 deletions(-) create mode 100644 modules/base/middleware/gzib.go diff --git a/modules/base/middleware/gzib.go b/modules/base/middleware/gzib.go new file mode 100644 index 000000000..7ba755359 --- /dev/null +++ b/modules/base/middleware/gzib.go @@ -0,0 +1,70 @@ +package middleware + +import ( + "compress/flate" + "compress/gzip" + "strings" + + "github.com/andybalholm/brotli" + "github.com/gogf/gf/v2/net/ghttp" +) + +func CompressMiddleware(r *ghttp.Request) { + ae := strings.ToLower(r.Header.Get("Accept-Encoding")) + + // 先执行后面的逻辑 + r.Middleware.Next() + + // 已经压缩过就跳过 + if r.Response.Header().Get("Content-Encoding") != "" { + return + } + + // 只压缩文本类型 + contentType := r.Response.Header().Get("Content-Type") + compressTypes := []string{ + "text/", + "application/json", + "application/javascript", + "application/xml", + } + need := false + for _, t := range compressTypes { + if strings.HasPrefix(contentType, t) { + need = true + break + } + } + if !need { + return + } + + buf := r.Response.Buffer() + if len(buf) == 0 { + return + } + + // 优先 Brotli + if strings.Contains(ae, "br") { + r.Response.Header().Set("Content-Encoding", "br") + r.Response.Header().Del("Content-Length") + r.Response.ClearBuffer() + + wr := brotli.NewWriterLevel(r.Response.Writer, brotli.BestCompression) + defer wr.Close() + wr.Write(buf) + return + } + + // 降级 Gzip + if strings.Contains(ae, "gzip") { + r.Response.Header().Set("Content-Encoding", "gzip") + r.Response.Header().Del("Content-Length") + r.Response.ClearBuffer() + + wr, _ := gzip.NewWriterLevel(r.Response.Writer, flate.BestCompression) + defer wr.Close() + wr.Write(buf) + return + } +} diff --git a/modules/base/middleware/middleware.go b/modules/base/middleware/middleware.go index f67f80c17..16be447da 100644 --- a/modules/base/middleware/middleware.go +++ b/modules/base/middleware/middleware.go @@ -156,7 +156,7 @@ func init() { tt.ServeHTTP(r.Response.Writer, r.Request) }) - + g.Server().Use(CompressMiddleware) g.Server().BindHandler("/server/*", func(r *ghttp.Request) { servert := new(ServerHandler) id := gconv.Uint16(r.URL.Query().Get("id")) diff --git a/modules/dict/controller/admin/dict_info.go b/modules/dict/controller/admin/dict_info.go index 355cb9f23..f3079aa96 100644 --- a/modules/dict/controller/admin/dict_info.go +++ b/modules/dict/controller/admin/dict_info.go @@ -1,12 +1,17 @@ package admin import ( + "bytes" + "compress/gzip" "context" + "encoding/base64" + "fmt" "blazing/cool" "blazing/modules/dict/service" + "github.com/gogf/gf/v2/encoding/gjson" "github.com/gogf/gf/v2/frame/g" ) @@ -35,7 +40,83 @@ type DictInfoDataReq struct { // Data 方法 获得字典数据 func (c *DictInfoController) Data(ctx context.Context, req *DictInfoDataReq) (res *cool.BaseRes, err error) { service := service.NewDictInfoService() - data, err := service.Data(ctx, req.Types) - res = cool.Ok(data) + data, _ := service.Data(ctx, req.Types) + r, _ := gjson.EncodeString(data) + encryptedStr, _ := CompressAndEncrypt(r) + res = cool.Ok(encryptedStr) return } + +// 异或密钥(两端必须一致) +const xorKey = "simple_key_123" + +// Xor 异或加解密(复用同一个函数) +func Xor(data []byte) []byte { + keyLen := len(xorKey) + result := make([]byte, len(data)) + for i := 0; i < len(data); i++ { + result[i] = data[i] ^ xorKey[i%keyLen] + } + return result +} + +// GzipCompress Gzip压缩 +func GzipCompress(data []byte) ([]byte, error) { + var buf bytes.Buffer + gz := gzip.NewWriter(&buf) + _, err := gz.Write(data) + if err != nil { + return nil, err + } + if err := gz.Close(); err != nil { + return nil, err + } + return buf.Bytes(), nil +} + +// GzipDecompress Gzip解压 +func GzipDecompress(data []byte) ([]byte, error) { + buf := bytes.NewBuffer(data) + gz, err := gzip.NewReader(buf) + if err != nil { + return nil, err + } + defer gz.Close() + + var res bytes.Buffer + _, err = res.ReadFrom(gz) + return res.Bytes(), err +} + +// CompressAndEncrypt 压缩+异或+Base64 +func CompressAndEncrypt(plainText string) (string, error) { + // 1. 字符串转字节数组 + rawData := []byte(plainText) + // 2. Gzip压缩 + compressed, err := GzipCompress(rawData) + if err != nil { + return "", fmt.Errorf("压缩失败:%v", err) + } + // 3. 异或加密 + encrypted := Xor(compressed) + // 4. Base64编码 + return base64.StdEncoding.EncodeToString(encrypted), nil +} + +// DecryptAndDecompress Base64+异或+解压 +func DecryptAndDecompress(encryptedStr string) (string, error) { + // 1. Base64解码 + encryptedData, err := base64.StdEncoding.DecodeString(encryptedStr) + if err != nil { + return "", fmt.Errorf("Base64解码失败:%v", err) + } + // 2. 异或解密 + decrypted := Xor(encryptedData) + // 3. Gzip解压 + decompressed, err := GzipDecompress(decrypted) + if err != nil { + return "", fmt.Errorf("解压失败:%v", err) + } + // 4. 字节数组转字符串 + return string(decompressed), nil +}