feat(marketing): user profile update, ad placement management, logo limits
- Add PUT /auth/profile endpoint for nickname and avatar updates - Add ad_placements table and CRUD admin API for managing ad units - Add GET /marketing/ad-config public API for mini-program to fetch ad config - Reduce logo limit from 10 to 3 per user, add 2MB file size validation Made-with: Cursor
This commit is contained in:
@@ -8,6 +8,7 @@ import (
|
||||
"github.com/gin-gonic/gin"
|
||||
|
||||
"wx_service/internal/common/auth/service"
|
||||
"wx_service/internal/middleware"
|
||||
"wx_service/internal/model"
|
||||
)
|
||||
|
||||
@@ -148,3 +149,35 @@ func (h *AuthHandler) DevLogin(c *gin.Context) {
|
||||
},
|
||||
}))
|
||||
}
|
||||
|
||||
type updateProfileRequest struct {
|
||||
Nickname string `json:"nickname"`
|
||||
AvatarURL string `json:"avatar_url"`
|
||||
}
|
||||
|
||||
func (h *AuthHandler) UpdateProfile(c *gin.Context) {
|
||||
user := middleware.MustCurrentUser(c)
|
||||
|
||||
var req updateProfileRequest
|
||||
if err := c.ShouldBindJSON(&req); err != nil {
|
||||
c.JSON(http.StatusBadRequest, model.Error(http.StatusBadRequest, "参数错误"))
|
||||
return
|
||||
}
|
||||
if req.Nickname == "" && req.AvatarURL == "" {
|
||||
c.JSON(http.StatusBadRequest, model.Error(http.StatusBadRequest, "请提供昵称或头像"))
|
||||
return
|
||||
}
|
||||
|
||||
updated, err := h.authService.UpdateProfile(c.Request.Context(), user.ID, req.Nickname, req.AvatarURL)
|
||||
if err != nil {
|
||||
log.Printf("[update_profile] error: %v", err)
|
||||
c.JSON(http.StatusInternalServerError, model.Error(http.StatusInternalServerError, "更新失败"))
|
||||
return
|
||||
}
|
||||
|
||||
c.JSON(http.StatusOK, model.Success(gin.H{
|
||||
"id": updated.ID,
|
||||
"nickname": updated.NickName,
|
||||
"avatar_url": updated.AvatarURL,
|
||||
}))
|
||||
}
|
||||
|
||||
@@ -192,6 +192,31 @@ func (s *AuthService) DevLogin(ctx context.Context, miniProgramID uint) (*LoginR
|
||||
}, nil
|
||||
}
|
||||
|
||||
// UpdateProfile 更新用户昵称和头像。
|
||||
func (s *AuthService) UpdateProfile(ctx context.Context, userID uint, nickname, avatarURL string) (*model.User, error) {
|
||||
tx := s.db.WithContext(ctx)
|
||||
var user model.User
|
||||
if err := tx.First(&user, userID).Error; err != nil {
|
||||
return nil, fmt.Errorf("find user: %w", err)
|
||||
}
|
||||
|
||||
updates := map[string]interface{}{}
|
||||
if nickname != "" {
|
||||
updates["nick_name"] = nickname
|
||||
user.NickName = nickname
|
||||
}
|
||||
if avatarURL != "" {
|
||||
updates["avatar_url"] = avatarURL
|
||||
user.AvatarURL = avatarURL
|
||||
}
|
||||
if len(updates) > 0 {
|
||||
if err := tx.Model(&user).Updates(updates).Error; err != nil {
|
||||
return nil, fmt.Errorf("update profile: %w", err)
|
||||
}
|
||||
}
|
||||
return &user, nil
|
||||
}
|
||||
|
||||
func (s *AuthService) getSmokeMode(ctx context.Context, uid int) (string, error) {
|
||||
var profile smokemodel.SmokeUserProfile
|
||||
err := s.db.WithContext(ctx).
|
||||
|
||||
Reference in New Issue
Block a user