tss-rocks/backend/internal/handler/user.go

227 lines
6.2 KiB
Go
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

package handler
import (
"net/http"
"strconv"
"github.com/gin-gonic/gin"
"github.com/rs/zerolog/log"
"tss-rocks-be/internal/types"
)
type UpdateCurrentUserRequest struct {
Email string `json:"email,omitempty" binding:"omitempty,email"`
CurrentPassword string `json:"current_password,omitempty"`
NewPassword string `json:"new_password,omitempty" binding:"omitempty,min=8"`
DisplayName string `json:"display_name,omitempty" binding:"omitempty,max=64"`
}
type CreateUserRequest struct {
Email string `json:"email" binding:"required,email"`
Password string `json:"password" binding:"required,min=8"`
Role string `json:"role" binding:"required,oneof=admin editor"`
DisplayName string `json:"display_name,omitempty" binding:"omitempty,max=64"`
}
type UpdateUserRequest struct {
Email string `json:"email,omitempty" binding:"omitempty,email"`
Password string `json:"password,omitempty" binding:"omitempty,min=8"`
Role string `json:"role,omitempty" binding:"omitempty,oneof=admin editor"`
Status string `json:"status,omitempty" binding:"omitempty,oneof=active inactive"`
DisplayName string `json:"display_name,omitempty" binding:"omitempty,max=64"`
}
// ListUsers returns a list of users
func (h *Handler) ListUsers(c *gin.Context) {
// Parse query parameters
params := &types.ListUsersParams{
Page: 1,
PerPage: 10,
}
if page := c.Query("page"); page != "" {
if p, err := strconv.Atoi(page); err == nil && p > 0 {
params.Page = p
}
}
if perPage := c.Query("per_page"); perPage != "" {
if pp, err := strconv.Atoi(perPage); err == nil && pp > 0 {
params.PerPage = pp
}
}
params.Sort = c.Query("sort")
params.Role = c.Query("role")
params.Status = c.Query("status")
params.Email = c.Query("email")
// Get users
users, err := h.service.ListUsers(c.Request.Context(), params)
if err != nil {
log.Error().Err(err).Msg("Failed to list users")
c.JSON(http.StatusInternalServerError, gin.H{"error": "Failed to list users"})
return
}
c.JSON(http.StatusOK, gin.H{
"data": users,
})
}
// CreateUser creates a new user
func (h *Handler) CreateUser(c *gin.Context) {
var req CreateUserRequest
if err := c.ShouldBindJSON(&req); err != nil {
c.JSON(http.StatusBadRequest, gin.H{"error": err.Error()})
return
}
user, err := h.service.CreateUser(c.Request.Context(), req.Email, req.Email, req.Password, req.Role)
if err != nil {
log.Error().Err(err).Msg("Failed to create user")
c.JSON(http.StatusInternalServerError, gin.H{"error": "Failed to create user"})
return
}
c.JSON(http.StatusCreated, gin.H{
"data": user,
})
}
// GetUser returns user details
func (h *Handler) GetUser(c *gin.Context) {
id, err := strconv.Atoi(c.Param("id"))
if err != nil {
c.JSON(http.StatusBadRequest, gin.H{"error": "Invalid user ID"})
return
}
user, err := h.service.GetUser(c.Request.Context(), id)
if err != nil {
log.Error().Err(err).Msg("Failed to get user")
c.JSON(http.StatusInternalServerError, gin.H{"error": "Failed to get user"})
return
}
c.JSON(http.StatusOK, gin.H{
"data": user,
})
}
// UpdateUser updates user information
func (h *Handler) UpdateUser(c *gin.Context) {
id, err := strconv.Atoi(c.Param("id"))
if err != nil {
c.JSON(http.StatusBadRequest, gin.H{"error": "Invalid user ID"})
return
}
var req UpdateUserRequest
if err := c.ShouldBindJSON(&req); err != nil {
c.JSON(http.StatusBadRequest, gin.H{"error": err.Error()})
return
}
user, err := h.service.UpdateUser(c.Request.Context(), id, &types.UpdateUserInput{
Email: req.Email,
Password: req.Password,
Role: req.Role,
Status: req.Status,
DisplayName: req.DisplayName,
})
if err != nil {
log.Error().Err(err).Msg("Failed to update user")
c.JSON(http.StatusInternalServerError, gin.H{"error": "Failed to update user"})
return
}
c.JSON(http.StatusOK, gin.H{
"data": user,
})
}
// DeleteUser deletes a user
func (h *Handler) DeleteUser(c *gin.Context) {
id, err := strconv.Atoi(c.Param("id"))
if err != nil {
c.JSON(http.StatusBadRequest, gin.H{"error": "Invalid user ID"})
return
}
if err := h.service.DeleteUser(c.Request.Context(), id); err != nil {
log.Error().Err(err).Msg("Failed to delete user")
c.JSON(http.StatusInternalServerError, gin.H{"error": "Failed to delete user"})
return
}
c.Status(http.StatusNoContent)
}
// GetCurrentUser returns the current user's information
func (h *Handler) GetCurrentUser(c *gin.Context) {
// 从上下文中获取用户ID由认证中间件设置
userID, exists := c.Get("user_id")
if !exists {
c.JSON(http.StatusUnauthorized, gin.H{"error": "Unauthorized"})
return
}
// 获取用户信息
user, err := h.service.GetUser(c.Request.Context(), userID.(int))
if err != nil {
log.Error().Err(err).Msg("Failed to get user")
c.JSON(http.StatusInternalServerError, gin.H{"error": "Failed to get user information"})
return
}
c.JSON(http.StatusOK, gin.H{
"data": user,
})
}
// UpdateCurrentUser updates the current user's information
func (h *Handler) UpdateCurrentUser(c *gin.Context) {
// 从上下文中获取用户ID由认证中间件设置
userID, exists := c.Get("user_id")
if !exists {
c.JSON(http.StatusUnauthorized, gin.H{"error": "Unauthorized"})
return
}
var req UpdateCurrentUserRequest
if err := c.ShouldBindJSON(&req); err != nil {
c.JSON(http.StatusBadRequest, gin.H{"error": err.Error()})
return
}
// 如果要更新密码,需要验证当前密码
if req.NewPassword != "" {
if req.CurrentPassword == "" {
c.JSON(http.StatusBadRequest, gin.H{"error": "Current password is required to update password"})
return
}
// 验证当前密码
if err := h.service.VerifyPassword(c.Request.Context(), userID.(int), req.CurrentPassword); err != nil {
c.JSON(http.StatusUnauthorized, gin.H{"error": "Invalid current password"})
return
}
}
// 更新用户信息
user, err := h.service.UpdateUser(c.Request.Context(), userID.(int), &types.UpdateUserInput{
Email: req.Email,
Password: req.NewPassword,
DisplayName: req.DisplayName,
})
if err != nil {
log.Error().Err(err).Msg("Failed to update user")
c.JSON(http.StatusInternalServerError, gin.H{"error": "Failed to update user information"})
return
}
c.JSON(http.StatusOK, gin.H{
"data": user,
})
}