Merge remote-tracking branch 'origin/dev' into dev

# Conflicts:
#	server/api/admin/imgroup/im_group.go
#	server/api/admin/imuser/im_user.go
#	server/internal/controller/admin/sys/im_group.go
#	server/internal/controller/admin/sys/im_user.go
#	server/internal/library/imtenant/db.go
#	server/internal/logic/admin/member.go
#	server/internal/logic/sys/im_admin_scope.go
#	server/internal/logic/sys/im_group.go
#	server/internal/logic/sys/im_invite.go
#	server/internal/logic/sys/im_registration.go
#	server/internal/logic/sys/im_tenant.go
#	server/internal/logic/sys/im_user.go
#	server/internal/model/input/sysin/im_group.go
#	server/internal/model/input/sysin/im_invite.go
#	server/internal/model/input/sysin/im_user.go
#	server/internal/router/genrouter/im_invite.go
#	server/internal/router/genrouter/im_registration.go
#	server/internal/service/sys.go
#	server/manifest/config/config.example.yaml
#	server/storage/data/generate/im_audit_log_menu.sql
#	server/storage/data/generate/im_group_menu.sql
#	server/storage/data/generate/im_realname_menu.sql
#	server/storage/data/generate/im_tenant_menu.sql
#	server/storage/data/generate/im_user_menu.sql
#	server/storage/data/generate/im_work_order_menu.sql
#	server/storage/data/im_registration_invite_hotgo.sql
#	web/src/api/imGroup/index.ts
#	web/src/api/imUser/index.ts
#	web/src/views/im/registrationInvite/BatchViewModal.vue
#	web/src/views/im/registrationInvite/CreateModal.vue
#	web/src/views/im/registrationInvite/index.vue
#	web/src/views/im/registrationInvite/model.ts
#	web/src/views/imGroup/governance.vue
#	web/src/views/imGroup/members.vue
#	web/src/views/imUser/index.vue
#	web/src/views/imUser/model.ts
#	web/src/views/imUser/view.vue
#	web/src/views/system/config/ImRegistrationSetting.vue
This commit is contained in:
richjohnrambo
2026-09-04 12:01:22 +08:00
7 changed files with 1116 additions and 2 deletions
@@ -0,0 +1,50 @@
package imtenant
import (
"context"
"fmt"
"os"
"strconv"
"sync"
"github.com/gogf/gf/v2/frame/g"
sf "github.com/tinode/snowflake"
)
const defaultSnowflakeWorkerID = 1023
var (
snowflakeOnce sync.Once
snowflakeGen *sf.SnowFlake
snowflakeErr error
)
// NextSnowflakeID returns an unencrypted Snowflake ID suitable for IM BIGINT keys.
func NextSnowflakeID(ctx context.Context) (int64, error) {
snowflakeOnce.Do(func() {
workerID := g.Cfg().MustGet(ctx, "imDirectDb.snowflakeWorkerId", defaultSnowflakeWorkerID).Int()
if value := os.Getenv("IM_DIRECT_DB_SNOWFLAKE_WORKER_ID"); value != "" {
workerID, snowflakeErr = strconv.Atoi(value)
if snowflakeErr != nil {
snowflakeErr = fmt.Errorf("invalid IM_DIRECT_DB_SNOWFLAKE_WORKER_ID: %w", snowflakeErr)
return
}
}
if workerID < 0 || workerID > 1023 {
snowflakeErr = fmt.Errorf("IM Snowflake worker ID must be between 0 and 1023")
return
}
snowflakeGen, snowflakeErr = sf.NewSnowFlake(uint32(workerID))
})
if snowflakeErr != nil {
return 0, snowflakeErr
}
id, err := snowflakeGen.Next()
if err != nil {
return 0, err
}
if id == 0 || id > uint64(^uint64(0)>>1) {
return 0, fmt.Errorf("generated invalid IM Snowflake ID")
}
return int64(id), nil
}