diff --git a/go.mod b/go.mod index e7d9097d2..ce8b6d4d7 100644 --- a/go.mod +++ b/go.mod @@ -133,7 +133,7 @@ require ( golang.org/x/arch v0.3.0 // indirect golang.org/x/net v0.17.0 // indirect golang.org/x/oauth2 v0.13.0 // indirect - golang.org/x/sys v0.13.0 // indirect + golang.org/x/sys v0.14.0 // indirect golang.org/x/text v0.13.0 // indirect golang.org/x/time v0.3.0 // indirect golang.org/x/xerrors v0.0.0-20220907171357-04be3eba64a2 // indirect diff --git a/go.sum b/go.sum index b1ee37912..bebd7dd92 100644 --- a/go.sum +++ b/go.sum @@ -438,8 +438,8 @@ golang.org/x/sys v0.0.0-20220715151400-c0bba94af5f8/go.mod h1:oPkhp1MJrh7nUepCBc golang.org/x/sys v0.0.0-20220722155257-8c9f86f7a55f/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.5.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.6.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= -golang.org/x/sys v0.13.0 h1:Af8nKPmuFypiUBjVoU9V20FiaFXOcuZI21p0ycVYYGE= -golang.org/x/sys v0.13.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= +golang.org/x/sys v0.14.0 h1:Vz7Qs629MkJkGyHxUlRHizWJRG2j8fbQKjELVSNhy7Q= +golang.org/x/sys v0.14.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA= golang.org/x/term v0.0.0-20201126162022-7de9c90e9dd1/go.mod h1:bj7SfCRtBDWHUb9snDiAeCFNEtKQo2Wmx5Cou7ajbmo= golang.org/x/term v0.0.0-20210927222741-03fcf44c2211/go.mod h1:jbD1KX2456YbFQfuXm/mYQcufACuNUgVhRMnK/tPxf8= golang.org/x/term v0.5.0/go.mod h1:jMB1sMXY+tzblOD4FWmEbocvup2/aLOaQEp7JmGp78k= diff --git a/internal/rpc/user/user.go b/internal/rpc/user/user.go index e0f29d27d..34ba29928 100644 --- a/internal/rpc/user/user.go +++ b/internal/rpc/user/user.go @@ -17,6 +17,7 @@ package user import ( "context" "errors" + "github.com/openimsdk/open-im-server/v3/pkg/common/db/newmgo" "strings" "time" @@ -77,10 +78,10 @@ func Start(client registry.SvcDiscoveryRegistry, server *grpc.Server) error { for k, v := range config.Config.Manager.UserID { users = append(users, &tablerelation.UserModel{UserID: v, Nickname: config.Config.Manager.Nickname[k], AppMangerLevel: constant.AppAdmin}) } - userDB := relation.NewUserGorm(db) + userDB := newmgo.NewUserMongo(mongo.GetDatabase()) cache := cache.NewUserCacheRedis(rdb, userDB, cache.GetDefaultOpt()) userMongoDB := unrelation.NewUserMongoDriver(mongo.GetDatabase()) - database := controller.NewUserDatabase(userDB, cache, tx.NewGorm(db), userMongoDB) + database := controller.NewUserDatabase(userDB, cache, tx.NewMongo(mongo.GetClient()), userMongoDB) friendRpcClient := rpcclient.NewFriendRpcClient(client) groupRpcClient := rpcclient.NewGroupRpcClient(client) msgRpcClient := rpcclient.NewMessageRpcClient(client) @@ -118,12 +119,11 @@ func (s *userServer) UpdateUserInfo(ctx context.Context, req *pbuser.UpdateUserI if err := CallbackBeforeUpdateUserInfo(ctx, req); err != nil { return nil, err } - user := convert.UserPb2DB(req.UserInfo) - if err != nil { - return nil, err + data := convert.UserPb2DBMap(req.UserInfo) + if len(data) == 0 { + return nil, errs.ErrArgs.Wrap("no data to update") } - err = s.Update(ctx, user) - if err != nil { + if err := s.UpdateByMap(ctx, req.UserInfo.UserID, data); err != nil { return nil, err } _ = s.friendNotificationSender.UserInfoUpdatedNotification(ctx, req.UserInfo.UserID) @@ -189,12 +189,7 @@ func (s *userServer) AccountCheck(ctx context.Context, req *pbuser.AccountCheckR } func (s *userServer) GetPaginationUsers(ctx context.Context, req *pbuser.GetPaginationUsersReq) (resp *pbuser.GetPaginationUsersResp, err error) { - var pageNumber, showNumber int32 - if req.Pagination != nil { - pageNumber = req.Pagination.PageNumber - showNumber = req.Pagination.ShowNumber - } - users, total, err := s.Page(ctx, pageNumber, showNumber) + total, users, err := s.Page(ctx, req.Pagination) if err != nil { return nil, err } @@ -259,11 +254,11 @@ func (s *userServer) GetGlobalRecvMessageOpt(ctx context.Context, req *pbuser.Ge // GetAllUserID Get user account by page. func (s *userServer) GetAllUserID(ctx context.Context, req *pbuser.GetAllUserIDReq) (resp *pbuser.GetAllUserIDResp, err error) { - userIDs, err := s.UserDatabase.GetAllUserID(ctx, req.Pagination.PageNumber, req.Pagination.ShowNumber) + total, userIDs, err := s.UserDatabase.GetAllUserID(ctx, req.Pagination) if err != nil { return nil, err } - return &pbuser.GetAllUserIDResp{UserIDs: userIDs}, nil + return &pbuser.GetAllUserIDResp{Total: int32(total), UserIDs: userIDs}, nil } // SubscribeOrCancelUsersStatus Subscribe online or cancel online users. diff --git a/internal/tools/msg.go b/internal/tools/msg.go index ad8f5c471..f09613069 100644 --- a/internal/tools/msg.go +++ b/internal/tools/msg.go @@ -91,7 +91,7 @@ func InitMsgTool() (*MsgTool, error) { userDatabase := controller.NewUserDatabase( userDB, cache.NewUserCacheRedis(rdb, relation.NewUserGorm(db), cache.GetDefaultOpt()), - tx.NewGorm(db), + tx.NewMongo(mongo.GetClient()), userMongoDB, ) groupDatabase := controller.InitGroupDatabase(db, rdb, mongo.GetDatabase(), nil) diff --git a/internal/tools/msg_doc_convert.go b/internal/tools/msg_doc_convert.go index 758625be1..b9150c362 100644 --- a/internal/tools/msg_doc_convert.go +++ b/internal/tools/msg_doc_convert.go @@ -32,7 +32,7 @@ func (c *MsgTool) convertTools() { for _, conversationID := range conversationIDs { conversationIDs = append(conversationIDs, msgprocessor.GetNotificationConversationIDByConversationID(conversationID)) } - userIDs, err := c.userDatabase.GetAllUserID(ctx, 0, 0) + _, userIDs, err := c.userDatabase.GetAllUserID(ctx, nil) if err != nil { log.ZError(ctx, "get all user ids failed", err) return diff --git a/pkg/common/convert/user.go b/pkg/common/convert/user.go index abb3a2144..782b9ab1c 100644 --- a/pkg/common/convert/user.go +++ b/pkg/common/convert/user.go @@ -48,3 +48,26 @@ func UserPb2DB(user *sdkws.UserInfo) *relationtb.UserModel { userDB.GlobalRecvMsgOpt = user.GlobalRecvMsgOpt return &userDB } + +func UserPb2DBMap(user *sdkws.UserInfo) map[string]any { + if user == nil { + return nil + } + val := make(map[string]any) + if user.Nickname != "" { + val["nickname"] = user.Nickname + } + if user.FaceURL != "" { + val["face_url"] = user.FaceURL + } + if user.Ex != "" { + val["ex"] = user.FaceURL + } + if user.AppMangerLevel != 0 { + val["app_manger_level"] = user.AppMangerLevel + } + if user.GlobalRecvMsgOpt != 0 { + val["global_recv_msg_opt"] = user.GlobalRecvMsgOpt + } + return val +} diff --git a/pkg/common/db/cache/user.go b/pkg/common/db/cache/user.go index d1164f2c0..e0f22b2f7 100644 --- a/pkg/common/db/cache/user.go +++ b/pkg/common/db/cache/user.go @@ -18,6 +18,7 @@ import ( "context" "encoding/json" "errors" + relationtb "github.com/openimsdk/open-im-server/v3/pkg/common/db/table/relation" "hash/crc32" "strconv" "time" @@ -31,8 +32,6 @@ import ( "github.com/dtm-labs/rockscache" "github.com/redis/go-redis/v9" - - relationtb "github.com/openimsdk/open-im-server/v3/pkg/common/db/table/relation" ) const ( @@ -59,7 +58,8 @@ type UserCache interface { type UserCacheRedis struct { metaCache - rdb redis.UniversalClient + rdb redis.UniversalClient + //userDB relationtb.UserModelInterface userDB relationtb.UserModelInterface expireTime time.Duration rcClient *rockscache.Client @@ -100,39 +100,13 @@ func (u *UserCacheRedis) getUserGlobalRecvMsgOptKey(userID string) string { } func (u *UserCacheRedis) GetUserInfo(ctx context.Context, userID string) (userInfo *relationtb.UserModel, err error) { - return getCache( - ctx, - u.rcClient, - u.getUserInfoKey(userID), - u.expireTime, - func(ctx context.Context) (*relationtb.UserModel, error) { - return u.userDB.Take(ctx, userID) - }, + return getCache(ctx, u.rcClient, u.getUserInfoKey(userID), u.expireTime, func(ctx context.Context) (*relationtb.UserModel, error) { + return u.userDB.Take(ctx, userID) + }, ) } func (u *UserCacheRedis) GetUsersInfo(ctx context.Context, userIDs []string) ([]*relationtb.UserModel, error) { - //var keys []string - //for _, userID := range userIDs { - // keys = append(keys, u.getUserInfoKey(userID)) - //} - //return batchGetCache( - // ctx, - // u.rcClient, - // keys, - // u.expireTime, - // func(user *relationtb.UserModel, keys []string) (int, error) { - // for i, key := range keys { - // if key == u.getUserInfoKey(user.UserID) { - // return i, nil - // } - // } - // return 0, errIndex - // }, - // func(ctx context.Context) ([]*relationtb.UserModel, error) { - // return u.userDB.Find(ctx, userIDs) - // }, - //) return batchGetCache2(ctx, u.rcClient, u.expireTime, userIDs, func(userID string) string { return u.getUserInfoKey(userID) }, func(ctx context.Context, userID string) (*relationtb.UserModel, error) { @@ -214,8 +188,7 @@ func (u *UserCacheRedis) SetUserStatus(ctx context.Context, userID string, statu UserIDNum := crc32.ChecksumIEEE([]byte(userID)) modKey := strconv.Itoa(int(UserIDNum % statusMod)) key := olineStatusKey + modKey - log.ZDebug(ctx, "SetUserStatus args", "userID", userID, "status", status, - "platformID", platformID, "modKey", modKey, "key", key) + log.ZDebug(ctx, "SetUserStatus args", "userID", userID, "status", status, "platformID", platformID, "modKey", modKey, "key", key) isNewKey, err := u.rdb.Exists(ctx, key).Result() if err != nil { return errs.Wrap(err) diff --git a/pkg/common/db/controller/user.go b/pkg/common/db/controller/user.go index eccb86bcb..3a70ff5b3 100644 --- a/pkg/common/db/controller/user.go +++ b/pkg/common/db/controller/user.go @@ -16,6 +16,9 @@ package controller import ( "context" + "github.com/OpenIMSDK/tools/tx" + "github.com/openimsdk/open-im-server/v3/pkg/common/db/newmgo/mgotool" + "github.com/openimsdk/open-im-server/v3/pkg/common/db/table/relation" "time" "github.com/OpenIMSDK/protocol/user" @@ -23,11 +26,9 @@ import ( unrelationtb "github.com/openimsdk/open-im-server/v3/pkg/common/db/table/unrelation" "github.com/OpenIMSDK/tools/errs" - "github.com/OpenIMSDK/tools/tx" "github.com/OpenIMSDK/tools/utils" "github.com/openimsdk/open-im-server/v3/pkg/common/db/cache" - "github.com/openimsdk/open-im-server/v3/pkg/common/db/table/relation" ) type UserDatabase interface { @@ -42,11 +43,11 @@ type UserDatabase interface { // UpdateByMap update (zero value) external guarantee userID exists UpdateByMap(ctx context.Context, userID string, args map[string]any) (err error) // Page If not found, no error is returned - Page(ctx context.Context, pageNumber, showNumber int32) (users []*relation.UserModel, count int64, err error) + Page(ctx context.Context, pagination mgotool.Pagination) (count int64, users []*relation.UserModel, err error) // IsExist true as long as one exists IsExist(ctx context.Context, userIDs []string) (exist bool, err error) // GetAllUserID Get all user IDs - GetAllUserID(ctx context.Context, pageNumber, showNumber int32) ([]string, error) + GetAllUserID(ctx context.Context, pagination mgotool.Pagination) (int64, []string, error) // InitOnce Inside the function, first query whether it exists in the db, if it exists, do nothing; if it does not exist, insert it InitOnce(ctx context.Context, users []*relation.UserModel) (err error) // CountTotal Get the total number of users @@ -68,13 +69,13 @@ type UserDatabase interface { } type userDatabase struct { + tx tx.CtxTx userDB relation.UserModelInterface cache cache.UserCache - tx tx.Tx mongoDB unrelationtb.UserModelInterface } -func NewUserDatabase(userDB relation.UserModelInterface, cache cache.UserCache, tx tx.Tx, mongoDB unrelationtb.UserModelInterface) UserDatabase { +func NewUserDatabase(userDB relation.UserModelInterface, cache cache.UserCache, tx tx.CtxTx, mongoDB unrelationtb.UserModelInterface) UserDatabase { return &userDatabase{userDB: userDB, cache: cache, tx: tx, mongoDB: mongoDB} } @@ -107,50 +108,42 @@ func (u *userDatabase) FindWithError(ctx context.Context, userIDs []string) (use // Find Get the information of the specified user. If the userID is not found, no error will be returned. func (u *userDatabase) Find(ctx context.Context, userIDs []string) (users []*relation.UserModel, err error) { - users, err = u.cache.GetUsersInfo(ctx, userIDs) - return + return u.cache.GetUsersInfo(ctx, userIDs) } // Create Insert multiple external guarantees that the userID is not repeated and does not exist in the db. func (u *userDatabase) Create(ctx context.Context, users []*relation.UserModel) (err error) { - if err := u.tx.Transaction(func(tx any) error { - err = u.userDB.Create(ctx, users) - if err != nil { + return u.tx.Transaction(ctx, func(ctx context.Context) error { + if err = u.userDB.Create(ctx, users); err != nil { return err } - return nil - }); err != nil { - return err - } - var userIDs []string - for _, user := range users { - userIDs = append(userIDs, user.UserID) - } - return u.cache.DelUsersInfo(userIDs...).ExecDel(ctx) + return u.cache.DelUsersInfo(utils.Slice(users, func(e *relation.UserModel) string { + return e.UserID + })...).ExecDel(ctx) + }) } -// Update (non-zero value) externally guarantees that userID exists. -func (u *userDatabase) Update(ctx context.Context, user *relation.UserModel) (err error) { - if err := u.userDB.Update(ctx, user); err != nil { - return err - } - return u.cache.DelUsersInfo(user.UserID).ExecDel(ctx) -} +//// Update (non-zero value) externally guarantees that userID exists. +//func (u *userDatabase) Update(ctx context.Context, user *relation.UserModel) (err error) { +// if err := u.userDB.Update(ctx, user); err != nil { +// return err +// } +// return u.cache.DelUsersInfo(user.UserID).ExecDel(ctx) +//} // UpdateByMap update (zero value) externally guarantees that userID exists. func (u *userDatabase) UpdateByMap(ctx context.Context, userID string, args map[string]any) (err error) { - if err := u.userDB.UpdateByMap(ctx, userID, args); err != nil { - return err - } - return u.cache.DelUsersInfo(userID).ExecDel(ctx) + return u.tx.Transaction(ctx, func(ctx context.Context) error { + if err := u.userDB.UpdateByMap(ctx, userID, args); err != nil { + return err + } + return u.cache.DelUsersInfo(userID).ExecDel(ctx) + }) } // Page Gets, returns no error if not found. -func (u *userDatabase) Page( - ctx context.Context, - pageNumber, showNumber int32, -) (users []*relation.UserModel, count int64, err error) { - return u.userDB.Page(ctx, pageNumber, showNumber) +func (u *userDatabase) Page(ctx context.Context, pagination mgotool.Pagination) (count int64, users []*relation.UserModel, err error) { + return u.userDB.Page(ctx, pagination) } // IsExist Does userIDs exist? As long as there is one, it will be true. @@ -166,8 +159,8 @@ func (u *userDatabase) IsExist(ctx context.Context, userIDs []string) (exist boo } // GetAllUserID Get all user IDs. -func (u *userDatabase) GetAllUserID(ctx context.Context, pageNumber, showNumber int32) (userIDs []string, err error) { - return u.userDB.GetAllUserID(ctx, pageNumber, showNumber) +func (u *userDatabase) GetAllUserID(ctx context.Context, pagination mgotool.Pagination) (total int64, userIDs []string, err error) { + return u.userDB.GetAllUserID(ctx, pagination) } // CountTotal Get the total number of users. diff --git a/pkg/common/db/newmgo/mgotool/tool.go b/pkg/common/db/newmgo/mgotool/tool.go index 25ee9851f..2cb655d3f 100644 --- a/pkg/common/db/newmgo/mgotool/tool.go +++ b/pkg/common/db/newmgo/mgotool/tool.go @@ -64,11 +64,27 @@ func FindOne[T any](ctx context.Context, coll *mongo.Collection, filter any, opt } func FindPage[T any](ctx context.Context, coll *mongo.Collection, filter any, pagination Pagination, opts ...*options.FindOptions) (int64, []T, error) { - count, err := Count[T](ctx, coll, filter) + countOpt := options.Count() + for _, opt := range opts { + if opt.Skip != nil { + countOpt.SetSkip(*opt.Skip) + } + if opt.Limit != nil { + countOpt.SetLimit(*opt.Limit) + } + } + count, err := Count(ctx, coll, filter, countOpt) if err != nil { return 0, nil, err } - opt := options.Find().SetSkip(int64(pagination.GetPageNumber() * pagination.GetShowNumber())).SetLimit(int64(pagination.GetShowNumber())) + if count == 0 || pagination == nil { + return count, nil, nil + } + skip := int64(pagination.GetPageNumber()-1) * int64(pagination.GetShowNumber()) + if skip < 0 || skip >= count || pagination.GetShowNumber() <= 0 { + return count, nil, nil + } + opt := options.Find().SetSkip(skip).SetLimit(int64(pagination.GetShowNumber())) res, err := Find[T](ctx, coll, filter, append(opts, opt)...) if err != nil { return 0, nil, err @@ -79,3 +95,12 @@ func FindPage[T any](ctx context.Context, coll *mongo.Collection, filter any, pa func Count(ctx context.Context, coll *mongo.Collection, filter any, opts ...*options.CountOptions) (int64, error) { return coll.CountDocuments(ctx, filter, opts...) } + +func Exist(ctx context.Context, coll *mongo.Collection, filter any, opts ...*options.CountOptions) (bool, error) { + opts = append(opts, options.Count().SetLimit(1)) + count, err := Count(ctx, coll, filter, opts...) + if err != nil { + return false, err + } + return count > 0, nil +} diff --git a/pkg/common/db/newmgo/user.go b/pkg/common/db/newmgo/user.go index 7b20811ec..97bc3565a 100644 --- a/pkg/common/db/newmgo/user.go +++ b/pkg/common/db/newmgo/user.go @@ -1,86 +1,32 @@ package newmgo -import ( - "context" - "github.com/openimsdk/open-im-server/v3/pkg/common/db/newmgo/mgotool" - "go.mongodb.org/mongo-driver/bson" - "go.mongodb.org/mongo-driver/mongo" - "go.mongodb.org/mongo-driver/mongo/options" - "time" -) - -type UserModel struct { - UserID string `bson:"user_id"` - Nickname string `bson:"nickname"` - FaceURL string `bson:"face_url"` - Ex string `bson:"ex"` - AppMangerLevel int32 `bson:"app_manger_level"` - GlobalRecvMsgOpt int32 `bson:"global_recv_msg_opt"` - CreateTime time.Time `bson:"create_time"` -} - -type UserModelInterface interface { - Create(ctx context.Context, users []*UserModel) (err error) - UpdateByMap(ctx context.Context, userID string, args map[string]any) (err error) - // 获取指定用户信息 不存在,也不返回错误 - Find(ctx context.Context, userIDs []string) (users []*UserModel, err error) - // 获取某个用户信息 不存在,则返回错误 - Take(ctx context.Context, userID string) (user *UserModel, err error) - // 获取用户信息 不存在,不返回错误 - Page(ctx context.Context, pageNumber, showNumber int32) (users []*UserModel, count int64, err error) - GetAllUserID(ctx context.Context, pageNumber, showNumber int32) (userIDs []string, err error) - GetUserGlobalRecvMsgOpt(ctx context.Context, userID string) (opt int, err error) - // 获取用户总数 - CountTotal(ctx context.Context, before *time.Time) (count int64, err error) - // 获取范围内用户增量 - CountRangeEverydayTotal(ctx context.Context, start time.Time, end time.Time) (map[string]int64, error) -} - -type UserMgo struct { - coll *mongo.Collection -} - -func (u *UserMgo) Create(ctx context.Context, users []*UserModel) error { - return mgotool.InsertMany(ctx, u.coll, users) -} - -func (u *UserMgo) UpdateOneByMap(ctx context.Context, userID string, args map[string]any) error { - if len(args) == 0 { - return nil - } - return mgotool.UpdateOne(ctx, u.coll, bson.M{"user_id": userID}, bson.M{"$set": args}, true) -} - -func (u *UserMgo) Find(ctx context.Context, userIDs []string) (users []*UserModel, err error) { - return mgotool.Find[*UserModel](ctx, u.coll, bson.M{"user_id": bson.M{"$in": userIDs}}) -} - -func (u *UserMgo) Take(ctx context.Context, userID string) (user *UserModel, err error) { - return mgotool.FindOne[*UserModel](ctx, u.coll, bson.M{"user_id": userID}) -} - -func (u *UserMgo) Page(ctx context.Context, pagination mgotool.Pagination) (count int64, users []*UserModel, err error) { - return mgotool.FindPage[*UserModel](ctx, u.coll, bson.M{}, pagination) -} - -func (u *UserMgo) GetAllUserID(ctx context.Context, pagination mgotool.Pagination) (int64, []string, error) { - return mgotool.FindPage[string](ctx, u.coll, bson.M{}, pagination, options.Find().SetProjection(bson.M{"user_id": 1})) -} - -func (u *UserMgo) GetUserGlobalRecvMsgOpt(ctx context.Context, userID string) (opt int, err error) { - return mgotool.FindOne[int](ctx, u.coll, bson.M{"user_id": userID}, options.FindOne().SetProjection(bson.M{"global_recv_msg_opt": 1})) -} - -func (u *UserMgo) CountTotal(ctx context.Context, before *time.Time) (count int64, err error) { - return mgotool.Count(ctx, u.coll, bson.M{"create_time": bson.M{"$lt": before}}) -} - -func (u *UserMgo) CountRangeEverydayTotal(ctx context.Context, start time.Time, end time.Time) (map[string]int64, error) { - //type Temp struct { - // CreateTime time.Time `bson:"create_time"` - // Number int64 `bson:"number"` - //} - //mgotool.Find(ctx, u.coll, bson.M{"create_time": bson.M{"$gte": start, "$lt": end}}, options.Find().SetProjection(bson.M{"create_time": 1})) - panic("implement me") - return nil, nil -} +//import ( +// "context" +// "github.com/openimsdk/open-im-server/v3/pkg/common/db/newmgo/mgotool" +// "time" +//) +// +//type UserModel struct { +// UserID string `bson:"user_id"` +// Nickname string `bson:"nickname"` +// FaceURL string `bson:"face_url"` +// Ex string `bson:"ex"` +// AppMangerLevel int32 `bson:"app_manger_level"` +// GlobalRecvMsgOpt int32 `bson:"global_recv_msg_opt"` +// CreateTime time.Time `bson:"create_time"` +//} +// +//type UserModelInterface interface { +// Create(ctx context.Context, users []*UserModel) (err error) +// UpdateByMap(ctx context.Context, userID string, args map[string]any) (err error) +// Find(ctx context.Context, userIDs []string) (users []*UserModel, err error) +// Take(ctx context.Context, userID string) (user *UserModel, err error) +// Page(ctx context.Context, pagination mgotool.Pagination) (count int64, users []*UserModel, err error) +// Exist(ctx context.Context, userID string) (exist bool, err error) +// GetAllUserID(ctx context.Context, pagination mgotool.Pagination) (count int64, userIDs []string, err error) +// GetUserGlobalRecvMsgOpt(ctx context.Context, userID string) (opt int, err error) +// // 获取用户总数 +// CountTotal(ctx context.Context, before *time.Time) (count int64, err error) +// // 获取范围内用户增量 +// CountRangeEverydayTotal(ctx context.Context, start time.Time, end time.Time) (map[string]int64, error) +//} diff --git a/pkg/common/db/newmgo/user_mgo.go b/pkg/common/db/newmgo/user_mgo.go index edbd61e3f..7e78abe82 100644 --- a/pkg/common/db/newmgo/user_mgo.go +++ b/pkg/common/db/newmgo/user_mgo.go @@ -1 +1,70 @@ package newmgo + +import ( + "context" + "github.com/openimsdk/open-im-server/v3/pkg/common/db/newmgo/mgotool" + "github.com/openimsdk/open-im-server/v3/pkg/common/db/table/relation" + "go.mongodb.org/mongo-driver/bson" + "go.mongodb.org/mongo-driver/mongo" + "go.mongodb.org/mongo-driver/mongo/options" + "time" +) + +func NewUserMongo(db *mongo.Database) relation.UserModelInterface { + return &UserMgo{ + coll: db.Collection("user"), + } +} + +type UserMgo struct { + coll *mongo.Collection +} + +func (u *UserMgo) Create(ctx context.Context, users []*relation.UserModel) error { + return mgotool.InsertMany(ctx, u.coll, users) +} + +func (u *UserMgo) UpdateByMap(ctx context.Context, userID string, args map[string]any) (err error) { + if len(args) == 0 { + return nil + } + return mgotool.UpdateOne(ctx, u.coll, bson.M{"user_id": userID}, bson.M{"$set": args}, true) +} + +func (u *UserMgo) Find(ctx context.Context, userIDs []string) (users []*relation.UserModel, err error) { + return mgotool.Find[*relation.UserModel](ctx, u.coll, bson.M{"user_id": bson.M{"$in": userIDs}}) +} + +func (u *UserMgo) Take(ctx context.Context, userID string) (user *relation.UserModel, err error) { + return mgotool.FindOne[*relation.UserModel](ctx, u.coll, bson.M{"user_id": userID}) +} + +func (u *UserMgo) Page(ctx context.Context, pagination mgotool.Pagination) (count int64, users []*relation.UserModel, err error) { + return mgotool.FindPage[*relation.UserModel](ctx, u.coll, bson.M{}, pagination) +} + +func (u *UserMgo) GetAllUserID(ctx context.Context, pagination mgotool.Pagination) (int64, []string, error) { + return mgotool.FindPage[string](ctx, u.coll, bson.M{}, pagination, options.Find().SetProjection(bson.M{"user_id": 1})) +} + +func (u *UserMgo) Exist(ctx context.Context, userID string) (exist bool, err error) { + return mgotool.Exist(ctx, u.coll, bson.M{"user_id": userID}) +} + +func (u *UserMgo) GetUserGlobalRecvMsgOpt(ctx context.Context, userID string) (opt int, err error) { + return mgotool.FindOne[int](ctx, u.coll, bson.M{"user_id": userID}, options.FindOne().SetProjection(bson.M{"global_recv_msg_opt": 1})) +} + +func (u *UserMgo) CountTotal(ctx context.Context, before *time.Time) (count int64, err error) { + return mgotool.Count(ctx, u.coll, bson.M{"create_time": bson.M{"$lt": before}}) +} + +func (u *UserMgo) CountRangeEverydayTotal(ctx context.Context, start time.Time, end time.Time) (map[string]int64, error) { + //type Temp struct { + // CreateTime time.Time `bson:"create_time"` + // Number int64 `bson:"number"` + //} + //mgotool.Find(ctx, u.coll, bson.M{"create_time": bson.M{"$gte": start, "$lt": end}}, options.Find().SetProjection(bson.M{"create_time": 1})) + panic("implement me") + return nil, nil +} diff --git a/pkg/common/db/relation/user_model.go b/pkg/common/db/relation/user_model.go index fd7ba3f84..8ae245c84 100644 --- a/pkg/common/db/relation/user_model.go +++ b/pkg/common/db/relation/user_model.go @@ -32,7 +32,8 @@ type UserGorm struct { } func NewUserGorm(db *gorm.DB) relation.UserModelInterface { - return &UserGorm{NewMetaDB(db, &relation.UserModel{})} + //return &UserGorm{NewMetaDB(db, &relation.UserModel{})} + return nil } // 插入多条. diff --git a/pkg/common/db/table/relation/user.go b/pkg/common/db/table/relation/user.go index 07da7adc7..62bd43343 100644 --- a/pkg/common/db/table/relation/user.go +++ b/pkg/common/db/table/relation/user.go @@ -16,21 +16,18 @@ package relation import ( "context" + "github.com/openimsdk/open-im-server/v3/pkg/common/db/newmgo/mgotool" "time" ) -const ( - UserModelTableName = "users" -) - type UserModel struct { - UserID string `gorm:"column:user_id;primary_key;size:64"` - Nickname string `gorm:"column:name;size:255"` - FaceURL string `gorm:"column:face_url;size:255"` - Ex string `gorm:"column:ex;size:1024"` - CreateTime time.Time `gorm:"column:create_time;index:create_time;autoCreateTime"` - AppMangerLevel int32 `gorm:"column:app_manger_level;default:1"` - GlobalRecvMsgOpt int32 `gorm:"column:global_recv_msg_opt"` + UserID string `bson:"user_id"` + Nickname string `bson:"nickname"` + FaceURL string `bson:"face_url"` + Ex string `bson:"ex"` + AppMangerLevel int32 `bson:"app_manger_level"` + GlobalRecvMsgOpt int32 `bson:"global_recv_msg_opt"` + CreateTime time.Time `bson:"create_time"` } func (u *UserModel) GetNickname() string { @@ -41,29 +38,22 @@ func (u *UserModel) GetFaceURL() string { return u.FaceURL } -func (u *UserModel) GetUserID() string { +func (u UserModel) GetUserID() string { return u.UserID } -func (u *UserModel) GetEx() string { +func (u UserModel) GetEx() string { return u.Ex } -func (UserModel) TableName() string { - return UserModelTableName -} - type UserModelInterface interface { Create(ctx context.Context, users []*UserModel) (err error) UpdateByMap(ctx context.Context, userID string, args map[string]any) (err error) - Update(ctx context.Context, user *UserModel) (err error) - // 获取指定用户信息 不存在,也不返回错误 Find(ctx context.Context, userIDs []string) (users []*UserModel, err error) - // 获取某个用户信息 不存在,则返回错误 Take(ctx context.Context, userID string) (user *UserModel, err error) - // 获取用户信息 不存在,不返回错误 - Page(ctx context.Context, pageNumber, showNumber int32) (users []*UserModel, count int64, err error) - GetAllUserID(ctx context.Context, pageNumber, showNumber int32) (userIDs []string, err error) + Page(ctx context.Context, pagination mgotool.Pagination) (count int64, users []*UserModel, err error) + Exist(ctx context.Context, userID string) (exist bool, err error) + GetAllUserID(ctx context.Context, pagination mgotool.Pagination) (count int64, userIDs []string, err error) GetUserGlobalRecvMsgOpt(ctx context.Context, userID string) (opt int, err error) // 获取用户总数 CountTotal(ctx context.Context, before *time.Time) (count int64, err error)