@ -7,6 +7,8 @@
package auth
package auth
import (
import (
"strings"
"github.com/veypi/vbase/cfg"
"github.com/veypi/vbase/cfg"
"github.com/veypi/vbase/models"
"github.com/veypi/vbase/models"
"github.com/veypi/vigo"
"github.com/veypi/vigo"
@ -15,25 +17,32 @@ import (
// PublicUserInfo 公开的用户信息(仅包含无关紧要的信息)
// PublicUserInfo 公开的用户信息(仅包含无关紧要的信息)
type PublicUserInfo struct {
type PublicUserInfo struct {
ID string ` json:"id" `
ID string ` json:"id" `
Name string ` json:"name" `
Username string ` json:"username" `
Username string ` json:"username" `
Nickname string ` json:"nickname" `
Nickname string ` json:"nickname" `
Icon string ` json:"icon" `
Avatar string ` json:"avatar" `
Avatar string ` json:"avatar" `
}
}
// SearchUsersRequest 搜索用户请求
// SearchUsersRequest 搜索用户请求
type SearchUsersRequest struct {
type SearchUsersRequest struct {
Keyword * string ` json:"keyword" src:"query" desc:"搜索关键词(用户名或昵称)" `
Keyword * string ` json:"keyword" src:"query" desc:"搜索关键词(用户名或昵称)" `
Limit int ` json:"limit" src:"query" default:"20" desc:"返回数量限制" `
Limit int ` json:"limit" src:"query" default:"20" desc:"返回数量限制" `
IDs [ ] string ` json:"ids" src:"json" desc:"用户ID列表" `
}
}
// SearchUsersResponse 搜索用户响应
// SearchUsersResponse 搜索用户响应
type SearchUsersResponse struct {
type SearchUsersResponse struct {
Items [ ] PublicUserInfo ` json:"items" `
Items [ ] PublicUserInfo ` json:"items" `
Total int64 ` json:"total" `
Total int64 ` json:"total" `
}
}
// searchUsers 搜索用户(公开接口,仅返回公开信息)
// searchUsers 搜索用户(公开接口,仅返回公开信息)
func searchUsers ( x * vigo . X , req * SearchUsersRequest ) ( * SearchUsersResponse , error ) {
func searchUsers ( x * vigo . X , req * SearchUsersRequest ) ( * SearchUsersResponse , error ) {
if len ( req . IDs ) > 0 {
return searchUsersByIDs ( req )
}
if req . Limit <= 0 || req . Limit > 50 {
if req . Limit <= 0 || req . Limit > 50 {
req . Limit = 20
req . Limit = 20
}
}
@ -59,12 +68,7 @@ func searchUsers(x *vigo.X, req *SearchUsersRequest) (*SearchUsersResponse, erro
// 转换为公开信息
// 转换为公开信息
items := make ( [ ] PublicUserInfo , len ( users ) )
items := make ( [ ] PublicUserInfo , len ( users ) )
for i , user := range users {
for i , user := range users {
items [ i ] = PublicUserInfo {
items [ i ] = buildPublicUserInfo ( & user )
ID : user . ID ,
Username : user . Username ,
Nickname : user . Nickname ,
Avatar : user . Avatar ,
}
}
}
return & SearchUsersResponse {
return & SearchUsersResponse {
@ -72,3 +76,69 @@ func searchUsers(x *vigo.X, req *SearchUsersRequest) (*SearchUsersResponse, erro
Total : total ,
Total : total ,
} , nil
} , nil
}
}
func searchUsersByIDs ( req * SearchUsersRequest ) ( * SearchUsersResponse , error ) {
ids := make ( [ ] string , 0 , len ( req . IDs ) )
seen := make ( map [ string ] struct { } , len ( req . IDs ) )
for _ , id := range req . IDs {
id = strings . TrimSpace ( id )
if id == "" {
continue
}
if _ , ok := seen [ id ] ; ok {
continue
}
seen [ id ] = struct { } { }
ids = append ( ids , id )
}
if len ( ids ) == 0 {
return & SearchUsersResponse {
Items : [ ] PublicUserInfo { } ,
Total : 0 ,
} , nil
}
var users [ ] models . User
if err := cfg . DB ( ) .
Model ( & models . User { } ) .
Where ( "status = ? AND id IN ?" , models . UserStatusActive , ids ) .
Find ( & users ) . Error ; err != nil {
return nil , vigo . ErrInternalServer . WithError ( err )
}
userMap := make ( map [ string ] models . User , len ( users ) )
for _ , user := range users {
userMap [ user . ID ] = user
}
items := make ( [ ] PublicUserInfo , 0 , len ( users ) )
for _ , id := range ids {
user , ok := userMap [ id ]
if ! ok {
continue
}
items = append ( items , buildPublicUserInfo ( & user ) )
}
return & SearchUsersResponse {
Items : items ,
Total : int64 ( len ( items ) ) ,
} , nil
}
func buildPublicUserInfo ( user * models . User ) PublicUserInfo {
name := user . Nickname
if name == "" {
name = user . Username
}
return PublicUserInfo {
ID : user . ID ,
Name : name ,
Username : user . Username ,
Nickname : user . Nickname ,
Icon : user . Avatar ,
Avatar : user . Avatar ,
}
}