diff --git a/manage/user.go b/manage/user.go index bce2e03..ae273ab 100644 --- a/manage/user.go +++ b/manage/user.go @@ -1677,3 +1677,59 @@ func (m *Manager) PublicUserInfoByUserId(userId string) (*modelexts.User, *perro return userExt, nil } + +func (m *Manager) PublicUserInfoByUserIdOrName(userIdOrName string) (*modelexts.User, *perror.PlutoError) { + users, err := models.Users(qm.Where("user_id = ? OR name = ?", userIdOrName, userIdOrName)).All(m.db) + if err != nil { + return nil, perror.ServerError.Wrapper(err) + } + + // 优先精确匹配 user_id + var user *models.User + for _, u := range users { + if u.UserID == userIdOrName { + user = u + break + } + } + if user == nil { + // name 不保证唯一,仅当昵称唯一匹配时才按昵称查找,避免定位到错误用户 + for _, u := range users { + if u.Name != userIdOrName { + continue + } + if user != nil { + return nil, perror.UserNotExist + } + user = u + } + } + if user == nil { + return nil, perror.UserNotExist + } + + bindings, err := models.Bindings(qm.Where("user_id = ?", user.ID)).All(m.db) + + if err != nil { + return nil, perror.ServerError.Wrapper(err) + } + + userExt := &modelexts.User{ + User: user, + Bindings: bindings, + } + + return userExt, nil +} + +func (m *Manager) SearchUsersByName(name string) ([]*models.User, *perror.PlutoError) { + users, err := models.Users( + qm.Where("name LIKE ?", "%"+name+"%"), + qm.Limit(20), + ).All(m.db) + if err != nil { + return nil, perror.ServerError.Wrapper(err) + } + + return users, nil +} diff --git a/modelexts/exts.go b/modelexts/exts.go index cce6f75..b06d2d2 100644 --- a/modelexts/exts.go +++ b/modelexts/exts.go @@ -46,6 +46,12 @@ func (u User) PublicInfo() map[string]interface{} { return res } +func (u User) SearchInfo() map[string]interface{} { + res := u.PublicInfo() + res["user_id"] = u.User.UserID + return res +} + type Scopes struct { Application *models.Application `json:"application"` Scopes []*models.RbacScope `json:"scopes"` diff --git a/route/v1.go b/route/v1.go index f63cdae..388c2d7 100644 --- a/route/v1.go +++ b/route/v1.go @@ -120,6 +120,20 @@ func (r *Router) registerUserV1Routes(prefix string) { middle: middleware.NoAuthMiddleware, handler: r.v1.PublicUserInfoByUserId, }, + { + path: "/info/identity/{userIdOrName}/public", + description: "Get user public info like avatar, name by userId or unique name", + method: "GET", + middle: middleware.NoAuthMiddleware, + handler: r.v1.PublicUserInfoByUserIdOrName, + }, + { + path: "/search", + description: "Search users by name", + method: "GET", + middle: middleware.AccessTokenAuthMiddleware, + handler: r.v1.SearchUsers, + }, { path: "/delete", description: "Delete user", diff --git a/route/v1/user.go b/route/v1/user.go index 8f21504..46ee459 100644 --- a/route/v1/user.go +++ b/route/v1/user.go @@ -12,6 +12,7 @@ import ( perror "github.com/MuShare/pluto/datatype/pluto_error" "github.com/MuShare/pluto/datatype/request" "github.com/MuShare/pluto/manage" + "github.com/MuShare/pluto/modelexts" "github.com/MuShare/pluto/utils/general" "github.com/MuShare/pluto/utils/mail" routeUtils "github.com/MuShare/pluto/utils/route" @@ -405,6 +406,42 @@ func (router *Router) PublicUserInfoByUserId(w http.ResponseWriter, r *http.Requ return nil } +func (router *Router) PublicUserInfoByUserIdOrName(w http.ResponseWriter, r *http.Request) *perror.PlutoError { + vars := mux.Vars(r) + userIdOrName := vars["userIdOrName"] + res, perr := router.manager.PublicUserInfoByUserIdOrName(userIdOrName) + + if perr != nil { + return perr + } + + routeUtils.ResponseOK(res.PublicInfo(), w) + + return nil +} + +func (router *Router) SearchUsers(w http.ResponseWriter, r *http.Request) *perror.PlutoError { + name := r.URL.Query().Get("name") + if name == "" { + return perror.BadRequest + } + + users, perr := router.manager.SearchUsersByName(name) + + if perr != nil { + return perr + } + + res := make([]map[string]interface{}, 0) + for _, u := range users { + res = append(res, (&modelexts.User{User: u}).SearchInfo()) + } + + routeUtils.ResponseOK(res, w) + + return nil +} + func (router *Router) DeleteUser(w http.ResponseWriter, r *http.Request) *perror.PlutoError { payload, perr := routeUtils.GetAccessPayload(r) if perr != nil {