diff --git a/docker-compose.yml b/docker-compose.yml index e4449b5ad..24735abe9 100644 --- a/docker-compose.yml +++ b/docker-compose.yml @@ -114,6 +114,7 @@ services: openim-web: image: ${IMAGE_REGISTRY:-ghcr.io/openimsdk}/openim-web:${OPENIM_WEB_IMAGE_VERSION:-v3.5.0-docker} container_name: openim-web + platform: linux/amd64 restart: always ports: - "${OPENIM_WEB_PORT:-11001}:80" @@ -211,6 +212,7 @@ services: # # https://github.com/openimsdk/open-im-server/issues/1662 # image: ${IMAGE_REGISTRY:-ghcr.io/openimsdk}/openim-admin:${ADMIN_FRONT_VERSION:-toc-base-open-docker.35} # container_name: openim-admin + # platform: linux/amd64 # restart: always # ports: # - "${OPENIM_ADMIN_FRONT_PORT:-11002}:80" diff --git a/go.mod b/go.mod index 5e8e7275b..b0eda8970 100644 --- a/go.mod +++ b/go.mod @@ -156,3 +156,6 @@ require ( golang.org/x/crypto v0.14.0 // indirect gopkg.in/ini.v1 v1.67.0 // indirect ) +replace ( + github.com/OpenIMSDK/protocol v0.0.47 => github.com/AndrewZuo01/protocol v0.0.0-20240112093520-fd9c53e27b94 +) \ No newline at end of file diff --git a/internal/rpc/user/user.go b/internal/rpc/user/user.go index 158e37d70..f647d6686 100644 --- a/internal/rpc/user/user.go +++ b/internal/rpc/user/user.go @@ -229,11 +229,20 @@ 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) { - total, users, err := s.PageFindUser(ctx, constant.IMOrdinaryUser, req.Pagination) - if err != nil { - return nil, err + if req.UserID == "" && req.UserName == "" { + total, users, err := s.PageFindUser(ctx, constant.IMOrdinaryUser, constant.AppOrdinaryUsers, req.Pagination) + if err != nil { + return nil, err + } + return &pbuser.GetPaginationUsersResp{Total: int32(total), Users: convert.UsersDB2Pb(users)}, err + } else { + total, users, err := s.PageFindUserWithKeyword(ctx, constant.IMOrdinaryUser, constant.AppOrdinaryUsers, req.UserID, req.UserName, req.Pagination) + if err != nil { + return nil, err + } + return &pbuser.GetPaginationUsersResp{Total: int32(total), Users: convert.UsersDB2Pb(users)}, err } - return &pbuser.GetPaginationUsersResp{Total: int32(total), Users: convert.UsersDB2Pb(users)}, err + } func (s *userServer) UserRegister(ctx context.Context, req *pbuser.UserRegisterReq) (resp *pbuser.UserRegisterResp, err error) { @@ -591,31 +600,38 @@ func (s *userServer) UpdateNotificationAccountInfo(ctx context.Context, req *pbu } func (s *userServer) SearchNotificationAccount(ctx context.Context, req *pbuser.SearchNotificationAccountReq) (*pbuser.SearchNotificationAccountResp, error) { + // Check if user is an admin if err := authverify.CheckIMAdmin(ctx); err != nil { return nil, err } var users []*relation.UserModel var err error + + // If a keyword is provided in the request if req.Keyword != "" { + // Find users by keyword users, err = s.UserDatabase.Find(ctx, []string{req.Keyword}) if err != nil { return nil, err } + + // Convert users to response format resp := s.userModelToResp(users, req.Pagination) if resp.Total != 0 { return resp, nil } + + // Find users by nickname if no users found by keyword users, err = s.UserDatabase.FindByNickname(ctx, req.Keyword) if err != nil { return nil, err } resp = s.userModelToResp(users, req.Pagination) return resp, nil - - return resp, nil } + // If no keyword, find users with notification settings users, err = s.UserDatabase.FindNotification(ctx, constant.AppNotificationAdmin) if err != nil { return nil, err diff --git a/pkg/common/db/controller/user.go b/pkg/common/db/controller/user.go index cedae5c97..b1cace955 100644 --- a/pkg/common/db/controller/user.go +++ b/pkg/common/db/controller/user.go @@ -48,10 +48,12 @@ type UserDatabase interface { //Update(ctx context.Context, user *relation.UserModel) (err error) // UpdateByMap update (zero value) external guarantee userID exists UpdateByMap(ctx context.Context, userID string, args map[string]any) (err error) + // FindUser + PageFindUser(ctx context.Context, level1 int64, level2 int64, pagination pagination.Pagination) (count int64, users []*relation.UserModel, err error) + //FindUser with keyword + PageFindUserWithKeyword(ctx context.Context, level1 int64, level2 int64, userID string, userName string, pagination pagination.Pagination) (count int64, users []*relation.UserModel, err error) // Page If not found, no error is returned Page(ctx context.Context, pagination pagination.Pagination) (count int64, users []*relation.UserModel, err error) - // FindUser - PageFindUser(ctx context.Context, level int64, pagination pagination.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 @@ -185,8 +187,11 @@ func (u *userDatabase) Page(ctx context.Context, pagination pagination.Paginatio return u.userDB.Page(ctx, pagination) } -func (u *userDatabase) PageFindUser(ctx context.Context, level int64, pagination pagination.Pagination) (count int64, users []*relation.UserModel, err error) { - return u.userDB.PageFindUser(ctx, level, pagination) +func (u *userDatabase) PageFindUser(ctx context.Context, level1 int64, level2 int64, pagination pagination.Pagination) (count int64, users []*relation.UserModel, err error) { + return u.userDB.PageFindUser(ctx, level1, level2, pagination) +} +func (u *userDatabase) PageFindUserWithKeyword(ctx context.Context, level1 int64, level2 int64, userID, userName string, pagination pagination.Pagination) (count int64, users []*relation.UserModel, err error) { + return u.userDB.PageFindUserWithKeyword(ctx, level1, level2, userID, userName, pagination) } // IsExist Does userIDs exist? As long as there is one, it will be true. diff --git a/pkg/common/db/mgo/user.go b/pkg/common/db/mgo/user.go index b07f82928..3ab71b209 100644 --- a/pkg/common/db/mgo/user.go +++ b/pkg/common/db/mgo/user.go @@ -18,6 +18,7 @@ import ( "context" "github.com/OpenIMSDK/protocol/user" "github.com/OpenIMSDK/tools/errs" + "go.mongodb.org/mongo-driver/bson/primitive" "time" "github.com/OpenIMSDK/tools/mgoutil" @@ -78,8 +79,42 @@ func (u *UserMgo) Page(ctx context.Context, pagination pagination.Pagination) (c return mgoutil.FindPage[*relation.UserModel](ctx, u.coll, bson.M{}, pagination) } -func (u *UserMgo) PageFindUser(ctx context.Context, level int64, pagination pagination.Pagination) (count int64, users []*relation.UserModel, err error) { - return mgoutil.FindPage[*relation.UserModel](ctx, u.coll, bson.M{"app_manger_level": level}, pagination) +func (u *UserMgo) PageFindUser(ctx context.Context, level1 int64, level2 int64, pagination pagination.Pagination) (count int64, users []*relation.UserModel, err error) { + query := bson.M{ + "$or": []bson.M{ + {"app_manger_level": level1}, + {"app_manger_level": level2}, + }, + } + + return mgoutil.FindPage[*relation.UserModel](ctx, u.coll, query, pagination) +} +func (u *UserMgo) PageFindUserWithKeyword(ctx context.Context, level1 int64, level2 int64, userID string, userName string, pagination pagination.Pagination) (count int64, users []*relation.UserModel, err error) { + // Initialize the base query with level conditions + query := bson.M{ + "$and": []bson.M{ + {"app_manger_level": bson.M{"$in": []int64{level1, level2}}}, + }, + } + + // Add userID and userName conditions to the query if they are provided + if userID != "" || userName != "" { + userConditions := []bson.M{} + if userID != "" { + // Use regex for userID + regexPattern := primitive.Regex{Pattern: userID, Options: "i"} // 'i' for case-insensitive matching + userConditions = append(userConditions, bson.M{"user_id": regexPattern}) + } + if userName != "" { + // Use regex for userName + regexPattern := primitive.Regex{Pattern: userName, Options: "i"} // 'i' for case-insensitive matching + userConditions = append(userConditions, bson.M{"nickname": regexPattern}) + } + query["$and"] = append(query["$and"].([]bson.M), bson.M{"$or": userConditions}) + } + + // Perform the paginated search + return mgoutil.FindPage[*relation.UserModel](ctx, u.coll, query, pagination) } func (u *UserMgo) GetAllUserID(ctx context.Context, pagination pagination.Pagination) (int64, []string, error) { diff --git a/pkg/common/db/table/relation/user.go b/pkg/common/db/table/relation/user.go index a1b4269d1..8d40a8f67 100644 --- a/pkg/common/db/table/relation/user.go +++ b/pkg/common/db/table/relation/user.go @@ -56,7 +56,8 @@ type UserModelInterface interface { TakeNotification(ctx context.Context, level int64) (user []*UserModel, err error) TakeByNickname(ctx context.Context, nickname string) (user []*UserModel, err error) Page(ctx context.Context, pagination pagination.Pagination) (count int64, users []*UserModel, err error) - PageFindUser(ctx context.Context, level int64, pagination pagination.Pagination) (count int64, users []*UserModel, err error) + PageFindUser(ctx context.Context, level1 int64, level2 int64, pagination pagination.Pagination) (count int64, users []*UserModel, err error) + PageFindUserWithKeyword(ctx context.Context, level1 int64, level2 int64, userID, userName string, pagination pagination.Pagination) (count int64, users []*UserModel, err error) Exist(ctx context.Context, userID string) (exist bool, err error) GetAllUserID(ctx context.Context, pagination pagination.Pagination) (count int64, userIDs []string, err error) GetUserGlobalRecvMsgOpt(ctx context.Context, userID string) (opt int, err error)