243 lines
6.5 KiB
Go
243 lines
6.5 KiB
Go
package handler
|
||
|
||
import (
|
||
"net/http"
|
||
"strconv"
|
||
|
||
"github.com/gin-gonic/gin"
|
||
"github.com/rs/zerolog/log"
|
||
"tss-rocks-be/internal/types"
|
||
"fmt"
|
||
)
|
||
|
||
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) {
|
||
userID, exists := c.Get("user_id")
|
||
if !exists {
|
||
c.JSON(http.StatusUnauthorized, gin.H{"error": "Unauthorized"})
|
||
return
|
||
}
|
||
|
||
// 将用户ID转换为int64
|
||
var id int64
|
||
switch v := userID.(type) {
|
||
case int64:
|
||
id = v
|
||
case int:
|
||
id = int64(v)
|
||
case float64:
|
||
id = int64(v)
|
||
default:
|
||
log.Error().
|
||
Str("type", fmt.Sprintf("%T", userID)).
|
||
Interface("value", userID).
|
||
Msg("Invalid user_id type")
|
||
c.JSON(http.StatusInternalServerError, gin.H{"error": "Invalid user_id type"})
|
||
return
|
||
}
|
||
|
||
// 获取用户信息
|
||
user, err := h.service.GetUser(c.Request.Context(), int(id))
|
||
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, 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,
|
||
})
|
||
}
|