fix version 1

This commit is contained in:
2026-09-22 21:15:34 +08:00
parent 9f86366638
commit d63d7e8b3a
277 changed files with 9959 additions and 1514 deletions

View File

@@ -20,6 +20,7 @@ require (
github.com/coreos/go-semver v0.3.1 // indirect
github.com/coreos/go-systemd/v22 v22.7.0 // indirect
github.com/gabriel-vasile/mimetype v1.4.15 // indirect
github.com/gin-contrib/cors v1.7.9 // indirect
github.com/gin-contrib/sse v1.1.2 // indirect
github.com/go-playground/locales v0.14.1 // indirect
github.com/go-playground/universal-translator v0.18.2 // indirect
@@ -27,6 +28,7 @@ require (
github.com/go-sql-driver/mysql v1.10.1 // indirect
github.com/goccy/go-json v0.10.6 // indirect
github.com/goccy/go-yaml v1.19.2 // indirect
github.com/golang-jwt/jwt/v5 v5.3.1 // indirect
github.com/golang/protobuf v1.5.4 // indirect
github.com/google/uuid v1.6.0 // indirect
github.com/grpc-ecosystem/grpc-gateway/v2 v2.30.0 // indirect

View File

@@ -24,6 +24,8 @@ github.com/davecgh/go-spew v1.1.2-0.20180830191138-d8f796af33cc h1:U9qPSI2PIWSS1
github.com/davecgh/go-spew v1.1.2-0.20180830191138-d8f796af33cc/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=
github.com/gabriel-vasile/mimetype v1.4.15 h1:05iP/CYtZ/w455R/KZM6rZ5ieAdh99UPtd+d3YzLmaI=
github.com/gabriel-vasile/mimetype v1.4.15/go.mod h1:azpTcoLcDZRNgFou5j+APrqQx9HqVPWa6ijYQIIVswQ=
github.com/gin-contrib/cors v1.7.9 h1:69rz5YU6PW7XlQ4VPXacl77ldFiUvR0E0bmEqmbq86w=
github.com/gin-contrib/cors v1.7.9/go.mod h1:KTqiTA5HzlWPgVz7p4tolzAuptzGO7DEJn/CbklG0nU=
github.com/gin-contrib/sse v1.1.2 h1:MU2fgl1RrdYTMcgJLtz2kJF+vPg3xrqaaKfUUU18tCo=
github.com/gin-contrib/sse v1.1.2/go.mod h1:QXzuVkA0YO7o/gun03UI1Q+FTI8ZV/n5t03kIQAI89s=
github.com/gin-gonic/gin v1.12.0 h1:b3YAbrZtnf8N//yjKeU2+MQsh2mY5htkZidOM7O0wG8=
@@ -42,6 +44,8 @@ github.com/goccy/go-json v0.10.6 h1:p8HrPJzOakx/mn/bQtjgNjdTcN+/S6FcG2CTtQOrHVU=
github.com/goccy/go-json v0.10.6/go.mod h1:oq7eo15ShAhp70Anwd5lgX2pLfOS3QCiwU/PULtXL6M=
github.com/goccy/go-yaml v1.19.2 h1:PmFC1S6h8ljIz6gMRBopkjP1TVT7xuwrButHID66PoM=
github.com/goccy/go-yaml v1.19.2/go.mod h1:XBurs7gK8ATbW4ZPGKgcbrY1Br56PdM69F7LkFRi1kA=
github.com/golang-jwt/jwt/v5 v5.3.1 h1:kYf81DTWFe7t+1VvL7eS+jKFVWaUnK9cB1qbwn63YCY=
github.com/golang-jwt/jwt/v5 v5.3.1/go.mod h1:fxCRLWMO43lRc8nhHWY6LGqRcf+1gQWArsqaEUEa5bE=
github.com/golang/protobuf v1.5.4 h1:i7eJL8qZTpSEXOPTxNKhASYpMn+8e5Q6AdndVa1dWek=
github.com/golang/protobuf v1.5.4/go.mod h1:lnTiLA8Wa4RWRcIUkrtSVa5nRhsEGBg48fD6rSs7xps=
github.com/google/go-cmp v0.7.0 h1:wk8382ETsv4JYUZwIsn6YpYiWiBsYLSJiTsyBybVuN8=

View File

@@ -3,7 +3,7 @@ package log
import (
"errors"
"log"
"strings"
"net"
"bsm/full/module/base/logs/internal/impl"
"bsm/full/module/base/logs/internal/models"
@@ -16,9 +16,8 @@ func Create(c *gin.Context) {
request = make([]*models.LogData, 0)
)
// 验证请求IP禁止公网网段提交
ip := c.ClientIP()
if ip == "127.0.0.1" || ip == "localhost" || strings.HasPrefix(ip, "10.") || strings.HasPrefix(ip, "172.") || strings.HasPrefix(ip, "192.") {
// 验证请求IP:仅允许内网/本机地址提交,禁止公网网段提交
if !isPrivateIP(c.ClientIP()) {
log.Printf("request ip is not allowed")
err := errors.New("request ip is not allowed")
infra.Response.Error(c, err)
@@ -45,3 +44,15 @@ func Create(c *gin.Context) {
infra.Response.Success(c, "")
}
// isPrivateIP 判断是否为内网或本机地址
func isPrivateIP(ip string) bool {
if ip == "localhost" {
return true
}
parsed := net.ParseIP(ip)
if parsed == nil {
return false
}
return parsed.IsLoopback() || parsed.IsPrivate()
}

View File

@@ -13,6 +13,7 @@ import (
var (
DefaultPage = 1
DefaultSize = 50
MaxSize = 200
)
func LogFetch(c *gin.Context) {
@@ -30,26 +31,27 @@ func LogFetch(c *gin.Context) {
tx = impl.DBService.Model(&models.LogData{})
)
var size int
var page int
if request["op_name"] != "" {
tx.Where("op_name like ?", "%"+request["op_name"].(string)+"%")
}
if request["service"] != "" {
tx.Where("service like ?", "%"+request["service"].(string)+"%")
}
if request["op_ip"] != "" {
tx.Where("op_ip = ?", "%"+request["ip"].(string)+"%")
}
if request["level"] != "" {
tx.Where("level = ?", request["level"].(int))
// 分页参数归一化page 至少为 1size 默认 50 且不超过上限
page := normalizePage(getInt(request, "page"))
sizeInput := getInt(request, "size")
if sizeInput <= 0 {
// 兼容 page_size 写法
sizeInput = getInt(request, "page_size")
}
size := normalizeSize(sizeInput)
if page <= 0 {
page = DefaultPage
// 过滤条件统一用安全类型断言取值,键名与查询列保持一致
if opName := getString(request, "op_name"); opName != "" {
tx = tx.Where("op_name like ?", "%"+opName+"%")
}
if size <= 0 {
size = DefaultSize
if service := getString(request, "service"); service != "" {
tx = tx.Where("service like ?", "%"+service+"%")
}
if opIP := getString(request, "op_ip"); opIP != "" {
tx = tx.Where("op_ip = ?", opIP)
}
if level := getInt(request, "level"); level > 0 {
tx = tx.Where("level = ?", level)
}
if err := tx.Count(&count).Limit(size).Offset((page - 1) * size).Find(&data).Error; err != nil {
@@ -63,3 +65,43 @@ func LogFetch(c *gin.Context) {
"total": count,
})
}
// getString 安全读取字符串参数,缺失或类型不符时返回空串
func getString(m map[string]any, key string) string {
if v, ok := m[key].(string); ok {
return v
}
return ""
}
// getInt 安全读取整型参数,兼容 JSON 反序列化产生的 float64
func getInt(m map[string]any, key string) int {
switch v := m[key].(type) {
case int:
return v
case int64:
return int(v)
case float64:
return int(v)
}
return 0
}
// normalizePage 归一化页码,最小为 DefaultPage
func normalizePage(page int) int {
if page < DefaultPage {
return DefaultPage
}
return page
}
// normalizeSize 归一化每页条数:默认 DefaultSize并限制不超过 MaxSize
func normalizeSize(size int) int {
if size <= 0 {
return DefaultSize
}
if size > MaxSize {
return MaxSize
}
return size
}

View File

@@ -6,25 +6,33 @@ import (
"bsm/full/module/base/logs/internal/logic/hello"
"bsm/full/module/base/logs/internal/logic/log"
"git.apinb.com/bsm-sdk/core/middleware"
"github.com/gin-gonic/gin"
)
func Register(srvKey string, engine *gin.Engine) {
v1_key := fmt.Sprintf("/rest/%s", srvKey)
registerAnonymous(v1_key, engine)
registerAuth(v1_key, engine)
}
// registerAnonymous 不需要auth的接口
func registerAnonymous(v1_key string, engine *gin.Engine) {
// Anonymous router.
fmt.Println(v1_key)
anonymous := engine.Group(v1_key)
{
// anonymous.Use(middleware.JwtAuth(impl.RedisCache))
anonymous.GET("/ping", hello.Ping)
anonymous.POST("/create", log.Create)
anonymous.POST("/fetch", log.LogFetch)
anonymous.POST("/total", log.Total)
}
}
// registerAuth 需要JWT鉴权的业务接口
func registerAuth(v1_key string, engine *gin.Engine) {
// Authorized router.
auth := engine.Group(v1_key)
auth.Use(middleware.JwtAuth(true))
{
auth.POST("/create", log.Create)
auth.POST("/fetch", log.LogFetch)
auth.POST("/total", log.Total)
}
}