package auth import ( "net/http" "github.com/gin-gonic/gin" "gorm.io/gorm" "rill/internal/httpx" "rill/internal/user" ) // UpdateProfileRequest 更新个人资料请求,仅更新请求中提供的字段;gender 空串表示清空。 type UpdateProfileRequest struct { Nickname *string `json:"nickname" binding:"omitempty,max=50" example:"Alice"` Gender *string `json:"gender" binding:"omitempty,len=0|oneof=male female other" example:"male"` Birthday *string `json:"birthday" binding:"omitempty" example:"1995-06-15"` } // @Summary Get current user profile // @Description Return the authenticated user's profile, including groups. // @Tags user // @Produce json // @Success 200 {object} model.User // @Security BearerAuth // @Failure 401 {object} httpx.ErrorResponse "unauthorized or session expired" // @Failure 403 {object} httpx.ErrorResponse "account disabled" // @Router /me [get] func Me() gin.HandlerFunc { return func(c *gin.Context) { current, ok := CurrentUser(c) if !ok { httpx.RespondUnauthorized(c) return } c.JSON(http.StatusOK, current) } } // @Summary Update current user profile // @Description Update the authenticated user's nickname, gender, and birthday. birthday accepts YYYY-MM-DD, an empty string clears it, and omitting it keeps the current value. // @Tags user // @Accept json // @Produce json // @Param profile body auth.UpdateProfileRequest true "Fields to update" // @Success 200 {object} model.User // @Failure 400 {object} httpx.ErrorResponse "invalid request" // @Security BearerAuth // @Failure 401 {object} httpx.ErrorResponse "unauthorized or session expired" // @Failure 403 {object} httpx.ErrorResponse "account disabled" // @Failure 500 {object} httpx.ErrorResponse // @Router /me [put] func UpdateMe(db *gorm.DB) gin.HandlerFunc { return func(c *gin.Context) { var req UpdateProfileRequest if err := c.ShouldBindJSON(&req); err != nil { c.JSON(http.StatusBadRequest, httpx.ErrorResponse{Error: "invalid request: " + err.Error()}) return } current, ok := CurrentUser(c) if !ok { httpx.RespondUnauthorized(c) return } updates := make(map[string]any, 3) if req.Nickname != nil { updates["nickname"] = *req.Nickname current.Nickname = *req.Nickname } if req.Gender != nil { updates["gender"] = *req.Gender current.Gender = *req.Gender } if req.Birthday != nil { birthday, err := user.NormalizeBirthday(req.Birthday) if err != nil { c.JSON(http.StatusBadRequest, httpx.ErrorResponse{Error: err.Error()}) return } if birthday.IsZero() { updates["birthday"] = nil } else { updates["birthday"] = birthday } current.Birthday = birthday } if len(updates) == 0 { c.JSON(http.StatusOK, current) return } ctx := c.Request.Context() if err := db.WithContext(ctx).Model(¤t).Updates(updates).Error; err != nil { httpx.RespondDBError(c, err) return } c.JSON(http.StatusOK, current) } }