mirror of
https://github.com/openimsdk/open-im-server.git
synced 2026-06-26 04:08:11 +08:00
search nickname
This commit is contained in:
parent
d787d49d48
commit
48e023882a
@ -165,6 +165,8 @@ func newGinRouter(ctx context.Context, client discovery.SvcDiscoveryRegistry, co
|
||||
userRouterGroup.POST("/set_msg_receive_setting", u.SetMsgReceiveSetting)
|
||||
// 根据手机号精确查找用户(phoneSearchVisibility=true 时遵守 phone_visibility 设置)
|
||||
userRouterGroup.POST("/get_user_by_phone", u.GetUserByPhone)
|
||||
// 根据昵称精确查询用户(可多结果,与 getPaginationUsers 模糊搜索不同)
|
||||
userRouterGroup.POST("/get_users_by_nickname", u.GetUsersByNickname)
|
||||
|
||||
// 全局黑名单管理(仅管理员)
|
||||
userRouterGroup.POST("/add_global_blacklist", bl.AddGlobalBlacklist)
|
||||
|
||||
@ -321,3 +321,7 @@ func (u *UserApi) SetMsgReceiveSetting(c *gin.Context) {
|
||||
func (u *UserApi) GetUserByPhone(c *gin.Context) {
|
||||
a2r.Call(c, user.UserClient.GetUserByPhone, u.Client)
|
||||
}
|
||||
|
||||
func (u *UserApi) GetUsersByNickname(c *gin.Context) {
|
||||
a2r.Call(c, user.UserClient.GetUsersByNickname, u.Client)
|
||||
}
|
||||
|
||||
@ -22,6 +22,7 @@ import (
|
||||
"strings"
|
||||
"sync"
|
||||
"time"
|
||||
"unicode/utf8"
|
||||
|
||||
"github.com/openimsdk/open-im-server/v3/internal/rpc/relation"
|
||||
"github.com/openimsdk/open-im-server/v3/pkg/common/config"
|
||||
@ -451,6 +452,61 @@ func (s *userServer) GetUserByPhone(ctx context.Context, req *pbuser.GetUserByPh
|
||||
return &pbuser.GetUserByPhoneResp{UserInfo: pbUser}, nil
|
||||
}
|
||||
|
||||
// GetUsersByNickname 按昵称精确匹配查询普通用户(app_manger_level 与分页拉取用户一致)。
|
||||
// 全局黑名单用户会被过滤;手机号字段按 phone_visibility 与 getDesignateUsers 相同规则处理。
|
||||
func (s *userServer) GetUsersByNickname(ctx context.Context, req *pbuser.GetUsersByNicknameReq) (*pbuser.GetUsersByNicknameResp, error) {
|
||||
nickname := strings.TrimSpace(req.Nickname)
|
||||
if nickname == "" {
|
||||
return nil, errs.ErrArgs.WrapMsg("nickname is required")
|
||||
}
|
||||
if n := utf8.RuneCountInString(nickname); n < 1 || n > 64 {
|
||||
return nil, errs.ErrArgs.WrapMsg("nickname length must be 1-64 characters")
|
||||
}
|
||||
|
||||
users, err := s.db.FindOrdinaryUsersByNickname(ctx, constant.IMOrdinaryUser, constant.AppOrdinaryUsers, nickname)
|
||||
if err != nil {
|
||||
log.ZError(ctx, "GetUsersByNickname: FindOrdinaryUsersByNickname failed", err,
|
||||
"opUserID", mcontext.GetOpUserID(ctx), "nickname", nickname)
|
||||
return nil, err
|
||||
}
|
||||
if len(users) == 0 {
|
||||
return &pbuser.GetUsersByNicknameResp{}, nil
|
||||
}
|
||||
|
||||
userIDs := datautil.Slice(users, func(u *tablerelation.User) string { return u.UserID })
|
||||
blocked, err := s.globalBlackDB.FindBlocked(ctx, userIDs)
|
||||
if err != nil {
|
||||
log.ZError(ctx, "GetUsersByNickname: FindBlocked failed", err,
|
||||
"opUserID", mcontext.GetOpUserID(ctx), "count", len(userIDs))
|
||||
return nil, err
|
||||
}
|
||||
if len(blocked) > 0 {
|
||||
banned := make(map[string]struct{}, len(blocked))
|
||||
for _, b := range blocked {
|
||||
banned[b.UserID] = struct{}{}
|
||||
}
|
||||
filtered := make([]*tablerelation.User, 0, len(users))
|
||||
for _, u := range users {
|
||||
if _, ok := banned[u.UserID]; !ok {
|
||||
filtered = append(filtered, u)
|
||||
}
|
||||
}
|
||||
users = filtered
|
||||
}
|
||||
if len(users) == 0 {
|
||||
return &pbuser.GetUsersByNicknameResp{}, nil
|
||||
}
|
||||
|
||||
pbUsers := convert.UsersDB2Pb(users)
|
||||
viewerID := mcontext.GetOpUserID(ctx)
|
||||
if err := s.applyPhoneVisibility(ctx, viewerID, pbUsers, users); err != nil {
|
||||
log.ZError(ctx, "GetUsersByNickname: applyPhoneVisibility failed", err,
|
||||
"opUserID", viewerID, "count", len(users))
|
||||
return nil, err
|
||||
}
|
||||
return &pbuser.GetUsersByNicknameResp{UsersInfo: pbUsers}, nil
|
||||
}
|
||||
|
||||
func (s *userServer) AccountCheck(ctx context.Context, req *pbuser.AccountCheckReq) (resp *pbuser.AccountCheckResp, err error) {
|
||||
resp = &pbuser.AccountCheckResp{}
|
||||
if datautil.Duplicate(req.CheckUserIDs) {
|
||||
|
||||
@ -37,6 +37,8 @@ type UserDatabase interface {
|
||||
Find(ctx context.Context, userIDs []string) (users []*model.User, err error)
|
||||
// Find userInfo By Nickname
|
||||
FindByNickname(ctx context.Context, nickname string) (users []*model.User, err error)
|
||||
// FindOrdinaryUsersByNickname 昵称精确匹配,仅普通用户(与分页拉取用户 level 一致)
|
||||
FindOrdinaryUsersByNickname(ctx context.Context, level1 int64, level2 int64, nickname string) (users []*model.User, err error)
|
||||
// FindByPhone looks up a single user by exact phone number.
|
||||
// Returns errs.ErrRecordNotFound if no user has the given phone.
|
||||
FindByPhone(ctx context.Context, phone string) (user *model.User, err error)
|
||||
@ -138,6 +140,10 @@ func (u *userDatabase) FindByNickname(ctx context.Context, nickname string) (use
|
||||
return u.userDB.TakeByNickname(ctx, nickname)
|
||||
}
|
||||
|
||||
func (u *userDatabase) FindOrdinaryUsersByNickname(ctx context.Context, level1, level2 int64, nickname string) ([]*model.User, error) {
|
||||
return u.userDB.FindOrdinaryUsersByNickname(ctx, level1, level2, nickname)
|
||||
}
|
||||
|
||||
func (u *userDatabase) FindByPhone(ctx context.Context, phone string) (*model.User, error) {
|
||||
return u.userDB.FindByPhone(ctx, phone)
|
||||
}
|
||||
|
||||
@ -38,10 +38,12 @@ func NewUserMongo(db *mongo.Database) (database.User, error) {
|
||||
Options: options.Index().SetUnique(true),
|
||||
},
|
||||
{
|
||||
// 支持按手机号快速查找,phone 为空串的文档不参与索引
|
||||
Keys: bson.D{{Key: "phone", Value: 1}},
|
||||
Options: options.Index().SetSparse(true),
|
||||
},
|
||||
{
|
||||
Keys: bson.D{{Key: "nickname", Value: 1}},
|
||||
},
|
||||
}
|
||||
if _, err := coll.Indexes().CreateMany(context.Background(), indexes); err != nil {
|
||||
return nil, errs.Wrap(err)
|
||||
@ -80,6 +82,14 @@ func (u *UserMgo) TakeByNickname(ctx context.Context, nickname string) (user []*
|
||||
return mongoutil.Find[*model.User](ctx, u.coll, bson.M{"nickname": nickname})
|
||||
}
|
||||
|
||||
func (u *UserMgo) FindOrdinaryUsersByNickname(ctx context.Context, level1, level2 int64, nickname string) ([]*model.User, error) {
|
||||
query := bson.M{
|
||||
"nickname": nickname,
|
||||
"app_manger_level": bson.M{"$in": []int64{level1, level2}},
|
||||
}
|
||||
return mongoutil.Find[*model.User](ctx, u.coll, query, options.Find().SetLimit(100))
|
||||
}
|
||||
|
||||
func (u *UserMgo) FindByPhone(ctx context.Context, phone string) (*model.User, error) {
|
||||
return mongoutil.FindOne[*model.User](ctx, u.coll, bson.M{"phone": phone})
|
||||
}
|
||||
|
||||
@ -29,6 +29,8 @@ type User interface {
|
||||
Take(ctx context.Context, userID string) (user *model.User, err error)
|
||||
TakeNotification(ctx context.Context, level int64) (user []*model.User, err error)
|
||||
TakeByNickname(ctx context.Context, nickname string) (user []*model.User, err error)
|
||||
// FindOrdinaryUsersByNickname 按昵称精确匹配,且 app_manger_level 为普通用户范围(与分页拉取用户一致)
|
||||
FindOrdinaryUsersByNickname(ctx context.Context, level1 int64, level2 int64, nickname string) (users []*model.User, err error)
|
||||
FindByPhone(ctx context.Context, phone string) (user *model.User, err error)
|
||||
Page(ctx context.Context, pagination pagination.Pagination) (count int64, users []*model.User, err error)
|
||||
PageFindUser(ctx context.Context, level1 int64, level2 int64, pagination pagination.Pagination) (count int64, users []*model.User, err error)
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user