From add07d47f190c2d1eff4d31859833d1000195e79 Mon Sep 17 00:00:00 2001 From: qhd <1766646056@qq.com> Date: Thu, 26 Feb 2026 17:47:19 +0800 Subject: [PATCH] =?UTF-8?q?=E6=B7=BB=E5=8A=A0MongoDB=E8=AE=A4=E8=AF=81?= =?UTF-8?q?=E6=94=AF=E6=8C=81=E5=B9=B6=E4=BC=98=E5=8C=96=E5=BA=8F=E5=88=97?= =?UTF-8?q?=E5=8F=B7=E7=94=9F=E6=88=90=E5=B7=A5=E5=85=B7?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- db/mongo/connection.go | 23 ++++++++++++++++++++++- db/mongo/mongo.go | 2 +- utils/utils.go | 42 ++++++++++++++++++++++++++++++++++++++++++ 3 files changed, 65 insertions(+), 2 deletions(-) diff --git a/db/mongo/connection.go b/db/mongo/connection.go index 10f3fc9..41cd249 100644 --- a/db/mongo/connection.go +++ b/db/mongo/connection.go @@ -8,6 +8,7 @@ package mongo import ( "context" "fmt" + "net/url" "os" "os/signal" "strings" @@ -34,6 +35,8 @@ type DataSourceConfig struct { Name string `json:"name"` Address string `json:"address"` Database string `json:"database"` + Username string `json:"username"` + Password string `json:"password"` MaxPoolSize int32 `json:"maxPoolSize"` MinPoolSize int32 `json:"minPoolSize"` 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, "?")) } + // 构建连接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(). - ApplyURI(d.config.Address). + ApplyURI(connectionURI). SetMaxPoolSize(uint64(d.config.MaxPoolSize)). SetMinPoolSize(uint64(d.config.MinPoolSize)). SetConnectTimeout(d.config.ConnectTimeout). @@ -302,6 +321,8 @@ func (m *DataSourceManager) InitializeFromConfig(ctx context.Context) error { Name: name, Address: gconv.String(address), Database: gconv.String(subMap["database"]), + Username: gconv.String(subMap["username"]), + Password: gconv.String(subMap["password"]), MaxPoolSize: int32(gconv.Int(subMap["maxPoolSize"])), MinPoolSize: int32(gconv.Int(subMap["minPoolSize"])), ConnectTimeout: gconv.Duration(subMap["connectTimeout"]), diff --git a/db/mongo/mongo.go b/db/mongo/mongo.go index 56f7694..0ffb978 100644 --- a/db/mongo/mongo.go +++ b/db/mongo/mongo.go @@ -57,7 +57,7 @@ func commandMonitor() *event.CommandMonitor { fmt.Printf("[%s] 开始执行命令 | 数据库: %s | 集合: %s | 命令: %+v\n", time.Now().Format("2006-01-02 15:04:05"), evt.DatabaseName, - evt.Command.Lookup("collection").StringValue(), // 获取集合名 + //evt.Command.Lookup("collection").StringValue(), // 获取集合名 evt.Command, ) diff --git a/utils/utils.go b/utils/utils.go index 2eed0ac..4f741c2 100644 --- a/utils/utils.go +++ b/utils/utils.go @@ -4,6 +4,7 @@ import ( "context" "encoding/json" "fmt" + "github.com/gogf/gf/v2/os/gtime" "net" "reflect" "sort" @@ -339,3 +340,44 @@ func Struct(params any, pointer any) error { } 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 +}