feat: Add public user information retrieval endpoint

- Introduced a new endpoint to fetch public user information without authentication.
- Implemented UserToPublicUserInfo function to format user data for the response.
- Updated UserService interface and user service implementation to support fetching users by username.
- Enhanced user handler to validate input parameters and check user status before responding.
This commit is contained in:
lafay
2026-01-10 03:52:35 +08:00
parent 22142db782
commit 06539dc086
7 changed files with 93 additions and 0 deletions

View File

@@ -62,6 +62,19 @@ func UserToUserInfo(user *model.User) *types.UserInfo {
}
}
// UserToPublicUserInfo 将 User 模型转换为 PublicUserInfo 响应
func UserToPublicUserInfo(user *model.User) *types.PublicUserInfo {
return &types.PublicUserInfo{
ID: user.ID,
Username: user.Username,
Avatar: user.Avatar,
Points: user.Points,
Role: user.Role,
Status: user.Status,
CreatedAt: user.CreatedAt,
}
}
// ProfileToProfileInfo 将 Profile 模型转换为 ProfileInfo 响应
func ProfileToProfileInfo(profile *model.Profile) *types.ProfileInfo {
return &types.ProfileInfo{

View File

@@ -93,6 +93,10 @@ func registerAuthRoutes(v1 *gin.RouterGroup, h *AuthHandler) {
// registerUserRoutes 注册用户路由
func registerUserRoutes(v1 *gin.RouterGroup, h *UserHandler, jwtService *auth.JWTService) {
// 公开用户信息路由(无需认证)
v1.GET("/users/public", h.GetPublicInfo)
// 需要认证的用户路由
userGroup := v1.Group("/user")
userGroup.Use(middleware.AuthMiddleware(jwtService))
{

View File

@@ -2,6 +2,7 @@ package handler
import (
"carrotskin/internal/container"
"carrotskin/internal/model"
"carrotskin/internal/service"
"carrotskin/internal/types"
@@ -315,3 +316,55 @@ func (h *UserHandler) ResetYggdrasilPassword(c *gin.Context) {
h.logger.Info("Yggdrasil密码重置成功", zap.Int64("userId", userID))
RespondSuccess(c, gin.H{"password": newPassword})
}
// GetPublicInfo 获取用户公开信息
// @Summary 获取用户公开信息
// @Description 根据用户名或用户ID获取用户的公开信息不包含敏感信息如邮箱
// @Tags user
// @Accept json
// @Produce json
// @Param username query string false "用户名"
// @Param id query int false "用户ID"
// @Success 200 {object} model.Response{data=types.PublicUserInfo} "获取成功"
// @Failure 400 {object} model.ErrorResponse "参数错误"
// @Failure 404 {object} model.ErrorResponse "用户不存在"
// @Router /api/v1/users/public [get]
func (h *UserHandler) GetPublicInfo(c *gin.Context) {
username := c.Query("username")
idStr := c.Query("id")
// 至少需要提供一个参数
if username == "" && idStr == "" {
RespondBadRequest(c, "必须提供用户名或用户ID", nil)
return
}
var user *model.User
var err error
// 优先使用用户名查询
if username != "" {
user, err = h.container.UserService.GetByUsername(c.Request.Context(), username)
} else {
// 使用用户ID查询
id := parseIntWithDefault(idStr, 0)
if id == 0 {
RespondBadRequest(c, "无效的用户ID", nil)
return
}
user, err = h.container.UserService.GetByID(c.Request.Context(), int64(id))
}
if err != nil || user == nil {
RespondNotFound(c, "用户不存在")
return
}
// 检查用户状态
if user.Status != 1 {
RespondNotFound(c, "用户不可用")
return
}
RespondSuccess(c, UserToPublicUserInfo(user))
}