package handler import ( "net/http" "strconv" "github.com/gin-gonic/gin" "github.com/user-management-system/internal/auth" "github.com/user-management-system/internal/domain" "github.com/user-management-system/internal/service" ) // UserHandler handles user management requests type UserHandler struct { userService *service.UserService } // NewUserHandler creates a new UserHandler func NewUserHandler(userService *service.UserService) *UserHandler { return &UserHandler{userService: userService} } func (h *UserHandler) CreateUser(c *gin.Context) { var req struct { Username string `json:"username" binding:"required"` Email string `json:"email"` Password string `json:"password"` Nickname string `json:"nickname"` } if err := c.ShouldBindJSON(&req); err != nil { c.JSON(http.StatusBadRequest, gin.H{"error": err.Error()}) return } user := &domain.User{ Username: req.Username, Email: domain.StrPtr(req.Email), Nickname: req.Nickname, Status: domain.UserStatusActive, } if req.Password != "" { hashed, err := auth.HashPassword(req.Password) if err != nil { c.JSON(http.StatusInternalServerError, gin.H{"error": "failed to hash password"}) return } user.Password = hashed } if err := h.userService.Create(c.Request.Context(), user); err != nil { handleError(c, err) return } c.JSON(http.StatusCreated, toUserResponse(user)) } func (h *UserHandler) ListUsers(c *gin.Context) { offset, _ := strconv.ParseInt(c.DefaultQuery("offset", "0"), 10, 64) limit, _ := strconv.ParseInt(c.DefaultQuery("limit", "20"), 10, 64) users, total, err := h.userService.List(c.Request.Context(), int(offset), int(limit)) if err != nil { handleError(c, err) return } userResponses := make([]*UserResponse, len(users)) for i, u := range users { userResponses[i] = toUserResponse(u) } c.JSON(http.StatusOK, gin.H{ "users": userResponses, "total": total, "offset": offset, "limit": limit, }) } func (h *UserHandler) GetUser(c *gin.Context) { id, err := strconv.ParseInt(c.Param("id"), 10, 64) if err != nil { c.JSON(http.StatusBadRequest, gin.H{"error": "invalid user id"}) return } user, err := h.userService.GetByID(c.Request.Context(), id) if err != nil { handleError(c, err) return } c.JSON(http.StatusOK, toUserResponse(user)) } func (h *UserHandler) UpdateUser(c *gin.Context) { id, err := strconv.ParseInt(c.Param("id"), 10, 64) if err != nil { c.JSON(http.StatusBadRequest, gin.H{"error": "invalid user id"}) return } var req struct { Email *string `json:"email"` Nickname *string `json:"nickname"` } if err := c.ShouldBindJSON(&req); err != nil { c.JSON(http.StatusBadRequest, gin.H{"error": err.Error()}) return } user, err := h.userService.GetByID(c.Request.Context(), id) if err != nil { handleError(c, err) return } if req.Email != nil { user.Email = req.Email } if req.Nickname != nil { user.Nickname = *req.Nickname } if err := h.userService.Update(c.Request.Context(), user); err != nil { handleError(c, err) return } c.JSON(http.StatusOK, toUserResponse(user)) } func (h *UserHandler) DeleteUser(c *gin.Context) { id, err := strconv.ParseInt(c.Param("id"), 10, 64) if err != nil { c.JSON(http.StatusBadRequest, gin.H{"error": "invalid user id"}) return } if err := h.userService.Delete(c.Request.Context(), id); err != nil { handleError(c, err) return } c.JSON(http.StatusOK, gin.H{"message": "user deleted"}) } func (h *UserHandler) UpdatePassword(c *gin.Context) { id, err := strconv.ParseInt(c.Param("id"), 10, 64) if err != nil { c.JSON(http.StatusBadRequest, gin.H{"error": "invalid user id"}) return } var req struct { OldPassword string `json:"old_password" binding:"required"` NewPassword string `json:"new_password" binding:"required"` } if err := c.ShouldBindJSON(&req); err != nil { c.JSON(http.StatusBadRequest, gin.H{"error": err.Error()}) return } if err := h.userService.ChangePassword(c.Request.Context(), id, req.OldPassword, req.NewPassword); err != nil { handleError(c, err) return } c.JSON(http.StatusOK, gin.H{"message": "密码修改成功"}) } func (h *UserHandler) UpdateUserStatus(c *gin.Context) { id, err := strconv.ParseInt(c.Param("id"), 10, 64) if err != nil { c.JSON(http.StatusBadRequest, gin.H{"error": "invalid user id"}) return } var req struct { Status string `json:"status" binding:"required"` } if err := c.ShouldBindJSON(&req); err != nil { c.JSON(http.StatusBadRequest, gin.H{"error": err.Error()}) return } var status domain.UserStatus switch req.Status { case "active", "1": status = domain.UserStatusActive case "inactive", "0": status = domain.UserStatusInactive case "locked", "2": status = domain.UserStatusLocked case "disabled", "3": status = domain.UserStatusDisabled default: c.JSON(http.StatusBadRequest, gin.H{"error": "invalid status"}) return } if err := h.userService.UpdateStatus(c.Request.Context(), id, status); err != nil { handleError(c, err) return } c.JSON(http.StatusOK, gin.H{"message": "status updated"}) } func (h *UserHandler) GetUserRoles(c *gin.Context) { c.JSON(http.StatusOK, gin.H{"roles": []interface{}{}}) } func (h *UserHandler) AssignRoles(c *gin.Context) { c.JSON(http.StatusOK, gin.H{"message": "role assignment not implemented"}) } func (h *UserHandler) UploadAvatar(c *gin.Context) { c.JSON(http.StatusOK, gin.H{"message": "avatar upload not implemented"}) } func (h *UserHandler) ListAdmins(c *gin.Context) { c.JSON(http.StatusOK, gin.H{"admins": []interface{}{}}) } func (h *UserHandler) CreateAdmin(c *gin.Context) { c.JSON(http.StatusOK, gin.H{"message": "admin creation not implemented"}) } func (h *UserHandler) DeleteAdmin(c *gin.Context) { c.JSON(http.StatusOK, gin.H{"message": "admin deletion not implemented"}) } type UserResponse struct { ID int64 `json:"id"` Username string `json:"username"` Email string `json:"email,omitempty"` Nickname string `json:"nickname,omitempty"` Status string `json:"status"` } func toUserResponse(u *domain.User) *UserResponse { email := "" if u.Email != nil { email = *u.Email } return &UserResponse{ ID: u.ID, Username: u.Username, Email: email, Nickname: u.Nickname, Status: strconv.FormatInt(int64(u.Status), 10), } }