添加MongoDB认证支持并优化序列号生成工具
This commit is contained in:
@@ -8,6 +8,7 @@ package mongo
|
|||||||
import (
|
import (
|
||||||
"context"
|
"context"
|
||||||
"fmt"
|
"fmt"
|
||||||
|
"net/url"
|
||||||
"os"
|
"os"
|
||||||
"os/signal"
|
"os/signal"
|
||||||
"strings"
|
"strings"
|
||||||
@@ -34,6 +35,8 @@ type DataSourceConfig struct {
|
|||||||
Name string `json:"name"`
|
Name string `json:"name"`
|
||||||
Address string `json:"address"`
|
Address string `json:"address"`
|
||||||
Database string `json:"database"`
|
Database string `json:"database"`
|
||||||
|
Username string `json:"username"`
|
||||||
|
Password string `json:"password"`
|
||||||
MaxPoolSize int32 `json:"maxPoolSize"`
|
MaxPoolSize int32 `json:"maxPoolSize"`
|
||||||
MinPoolSize int32 `json:"minPoolSize"`
|
MinPoolSize int32 `json:"minPoolSize"`
|
||||||
ConnectTimeout time.Duration `json:"connectTimeout"`
|
ConnectTimeout time.Duration `json:"connectTimeout"`
|
||||||
@@ -110,9 +113,25 @@ func (d *BaseDataSource) Connect(ctx context.Context) error {
|
|||||||
dbName = gstr.SubStr(dbName, 0, strings.Index(dbName, "?"))
|
dbName = gstr.SubStr(dbName, 0, strings.Index(dbName, "?"))
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// 构建连接URI
|
||||||
|
connectionURI := fmt.Sprintf("mongodb://%s", d.config.Address)
|
||||||
|
|
||||||
|
// 如果配置了用户名和密码,添加到URI中
|
||||||
|
if d.config.Username != "" {
|
||||||
|
// URL编码用户名和密码,正确处理特殊字符
|
||||||
|
encodedUsername := url.QueryEscape(d.config.Username)
|
||||||
|
encodedPassword := url.QueryEscape(d.config.Password)
|
||||||
|
|
||||||
|
// 构建认证信息
|
||||||
|
authInfo := fmt.Sprintf("%s:%s@", encodedUsername, encodedPassword)
|
||||||
|
|
||||||
|
// 将认证信息插入到URI中
|
||||||
|
connectionURI = fmt.Sprintf("mongodb://%s%s", authInfo, d.config.Address)
|
||||||
|
}
|
||||||
|
|
||||||
// 构建连接选项
|
// 构建连接选项
|
||||||
opt := options.Client().
|
opt := options.Client().
|
||||||
ApplyURI(d.config.Address).
|
ApplyURI(connectionURI).
|
||||||
SetMaxPoolSize(uint64(d.config.MaxPoolSize)).
|
SetMaxPoolSize(uint64(d.config.MaxPoolSize)).
|
||||||
SetMinPoolSize(uint64(d.config.MinPoolSize)).
|
SetMinPoolSize(uint64(d.config.MinPoolSize)).
|
||||||
SetConnectTimeout(d.config.ConnectTimeout).
|
SetConnectTimeout(d.config.ConnectTimeout).
|
||||||
@@ -302,6 +321,8 @@ func (m *DataSourceManager) InitializeFromConfig(ctx context.Context) error {
|
|||||||
Name: name,
|
Name: name,
|
||||||
Address: gconv.String(address),
|
Address: gconv.String(address),
|
||||||
Database: gconv.String(subMap["database"]),
|
Database: gconv.String(subMap["database"]),
|
||||||
|
Username: gconv.String(subMap["username"]),
|
||||||
|
Password: gconv.String(subMap["password"]),
|
||||||
MaxPoolSize: int32(gconv.Int(subMap["maxPoolSize"])),
|
MaxPoolSize: int32(gconv.Int(subMap["maxPoolSize"])),
|
||||||
MinPoolSize: int32(gconv.Int(subMap["minPoolSize"])),
|
MinPoolSize: int32(gconv.Int(subMap["minPoolSize"])),
|
||||||
ConnectTimeout: gconv.Duration(subMap["connectTimeout"]),
|
ConnectTimeout: gconv.Duration(subMap["connectTimeout"]),
|
||||||
|
|||||||
@@ -57,7 +57,7 @@ func commandMonitor() *event.CommandMonitor {
|
|||||||
fmt.Printf("[%s] 开始执行命令 | 数据库: %s | 集合: %s | 命令: %+v\n",
|
fmt.Printf("[%s] 开始执行命令 | 数据库: %s | 集合: %s | 命令: %+v\n",
|
||||||
time.Now().Format("2006-01-02 15:04:05"),
|
time.Now().Format("2006-01-02 15:04:05"),
|
||||||
evt.DatabaseName,
|
evt.DatabaseName,
|
||||||
evt.Command.Lookup("collection").StringValue(), // 获取集合名
|
//evt.Command.Lookup("collection").StringValue(), // 获取集合名
|
||||||
evt.Command,
|
evt.Command,
|
||||||
)
|
)
|
||||||
|
|
||||||
|
|||||||
@@ -4,6 +4,7 @@ import (
|
|||||||
"context"
|
"context"
|
||||||
"encoding/json"
|
"encoding/json"
|
||||||
"fmt"
|
"fmt"
|
||||||
|
"github.com/gogf/gf/v2/os/gtime"
|
||||||
"net"
|
"net"
|
||||||
"reflect"
|
"reflect"
|
||||||
"sort"
|
"sort"
|
||||||
@@ -339,3 +340,44 @@ func Struct(params any, pointer any) error {
|
|||||||
}
|
}
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// IncrSequence 自增序列号 - 通用序列号工具
|
||||||
|
func IncrSequence(ctx context.Context, prefix string, incrLen int, seqSep string) (string, error) {
|
||||||
|
// 1. 校验incrLen合法性(至少1位,最多10位,避免位数过大)
|
||||||
|
if incrLen < 1 || incrLen > 8 {
|
||||||
|
g.Log().Warningf(ctx, "自增数位数[%d]不合法,默认使用8位", incrLen)
|
||||||
|
incrLen = 8 // 兜底默认8位
|
||||||
|
}
|
||||||
|
// 2. 获取当前时间,格式化为"年月日"(如20260226)
|
||||||
|
timeStr := gtime.Now().Format("Ymd")
|
||||||
|
// 3. 拼接Redis的key(seq:前缀:时间字符串),确保每天一个独立的自增序列
|
||||||
|
redisKey := fmt.Sprintf("%s:%s:%s", "SEQ", prefix, timeStr)
|
||||||
|
// 4. 调用Redis的Incr做自增,失败则生成兜底序列号
|
||||||
|
seqNum, err := g.Redis().Incr(ctx, redisKey)
|
||||||
|
if err != nil {
|
||||||
|
return "", fmt.Errorf("redis自增失败: %w", err)
|
||||||
|
}
|
||||||
|
// 5. 自动清理过期key,定时任务
|
||||||
|
|
||||||
|
// 6. 校验自增数是否超过incrLen位上限,超过则取模(避免格式混乱)
|
||||||
|
maxSeq := intPow10(incrLen) - 1
|
||||||
|
if seqNum > int64(maxSeq) {
|
||||||
|
return "", fmt.Errorf("自增数[%d]超过%d位上限[%d]", seqNum, incrLen, maxSeq)
|
||||||
|
}
|
||||||
|
// 7. 格式化自增数为指定位数,不足补零
|
||||||
|
seqFormat := fmt.Sprintf("%%0%dd", incrLen) // 动态生成格式化字符串
|
||||||
|
seqStr := fmt.Sprintf(seqFormat, seqNum)
|
||||||
|
// 8. 拼接最终序列号
|
||||||
|
finalSeq := fmt.Sprintf("%s%s%s%s%s", prefix, seqSep, timeStr, seqSep, seqStr)
|
||||||
|
|
||||||
|
return finalSeq, nil
|
||||||
|
}
|
||||||
|
|
||||||
|
// intPow10 计算10的n次方(辅助函数,如intPow10(6)=1000000)
|
||||||
|
func intPow10(n int) int {
|
||||||
|
result := 1
|
||||||
|
for i := 0; i < n; i++ {
|
||||||
|
result *= 10
|
||||||
|
}
|
||||||
|
return result
|
||||||
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user