- main.go: 添加 Swagger 文档、初始化默认管理员 - 认证模块: 完善用户角色管理 - 新增工具模块: tool_handler, tool_repo, tool_service, tool model - 更新 go.mod 依赖 Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
242 lines
5.9 KiB
Go
242 lines
5.9 KiB
Go
package handler
|
||
|
||
import (
|
||
"net/http"
|
||
"strings"
|
||
|
||
"x-agents/server/internal/service"
|
||
|
||
"github.com/gin-gonic/gin"
|
||
)
|
||
|
||
// maskEmail 邮箱脱敏,只显示前后各1个字符
|
||
func maskEmail(email string) string {
|
||
if email == "" {
|
||
return ""
|
||
}
|
||
parts := strings.Split(email, "@")
|
||
if len(parts) != 2 {
|
||
return "***"
|
||
}
|
||
local := parts[0]
|
||
domain := parts[1]
|
||
if len(local) <= 2 {
|
||
local = "**"
|
||
} else {
|
||
local = string(local[0]) + "***" + string(local[len(local)-1])
|
||
}
|
||
if len(domain) <= 2 {
|
||
domain = "***"
|
||
} else {
|
||
domain = string(domain[0]) + "***" + string(domain[len(domain)-1])
|
||
}
|
||
return local + "@" + domain
|
||
}
|
||
|
||
// @title X-Agents API
|
||
// @version 1.0
|
||
// @description X-Agents 后端 API 文档
|
||
// @termsOfService http://swagger.io/terms/
|
||
|
||
// @contact.name API Support
|
||
// @contact.url http://www.example.com/support
|
||
// @contact.email support@example.com
|
||
|
||
// @license.name Apache 2.0
|
||
// @license.url http://www.apache.org/licenses/LICENSE-2.0.html
|
||
|
||
// @host localhost:8080
|
||
// @BasePath /
|
||
|
||
// @securityDefinitions.apikey BearerAuth
|
||
// @in header
|
||
// @name Authorization
|
||
// @description Type "Bearer" followed by a space and JWT token.
|
||
|
||
type AuthHandler struct {
|
||
authService *service.AuthService
|
||
}
|
||
|
||
func NewAuthHandler(authService *service.AuthService) *AuthHandler {
|
||
return &AuthHandler{authService: authService}
|
||
}
|
||
|
||
type LoginRequest struct {
|
||
Username string `json:"username" binding:"required"`
|
||
Password string `json:"password" binding:"required"`
|
||
}
|
||
|
||
type LoginResponse struct {
|
||
Token string `json:"token"`
|
||
User interface{} `json:"user"`
|
||
}
|
||
|
||
// RegisterRequest 注册请求
|
||
type RegisterRequest struct {
|
||
Username string `json:"username" binding:"required"`
|
||
Password string `json:"password" binding:"required"`
|
||
Email string `json:"email"`
|
||
}
|
||
|
||
// @Summary 用户登录
|
||
// @Description 用户登录并获取 JWT Token
|
||
// @Tags 认证
|
||
// @Accept json
|
||
// @Produce json
|
||
// @Param request body LoginRequest true "登录请求"
|
||
// @Success 200 {object} LoginResponse
|
||
// @Failure 400 {object} map[string]string
|
||
// @Failure 401 {object} map[string]string
|
||
// @Router /auth/login [post]
|
||
func (h *AuthHandler) Login(c *gin.Context) {
|
||
var req LoginRequest
|
||
if err := c.ShouldBindJSON(&req); err != nil {
|
||
c.JSON(http.StatusBadRequest, gin.H{"error": err.Error()})
|
||
return
|
||
}
|
||
|
||
resp, err := h.authService.Login(service.LoginRequest{
|
||
Username: req.Username,
|
||
Password: req.Password,
|
||
})
|
||
if err != nil {
|
||
c.JSON(http.StatusUnauthorized, gin.H{"error": err.Error()})
|
||
return
|
||
}
|
||
|
||
c.JSON(http.StatusOK, LoginResponse{
|
||
Token: resp.Token,
|
||
User: gin.H{
|
||
"id": resp.User.ID,
|
||
"username": resp.User.Username,
|
||
"email": resp.User.Email,
|
||
"role": resp.User.RoleID,
|
||
},
|
||
})
|
||
}
|
||
|
||
// @Summary 用户注册
|
||
// @Description 新用户注册账号
|
||
// @Tags 认证
|
||
// @Accept json
|
||
// @Produce json
|
||
// @Param RegisterRequest body handler.RegisterRequest true "注册请求"
|
||
// @Success 201 {object} map[string]interface{}
|
||
// @Failure 400 {object} map[string]string
|
||
// @Router /auth/register [post]
|
||
func (h *AuthHandler) Register(c *gin.Context) {
|
||
var req RegisterRequest
|
||
if err := c.ShouldBindJSON(&req); err != nil {
|
||
c.JSON(http.StatusBadRequest, gin.H{"error": err.Error()})
|
||
return
|
||
}
|
||
|
||
user, err := h.authService.Register(req.Username, req.Password, req.Email)
|
||
if err != nil {
|
||
c.JSON(http.StatusBadRequest, gin.H{"error": err.Error()})
|
||
return
|
||
}
|
||
|
||
c.JSON(http.StatusCreated, gin.H{
|
||
"id": user.ID,
|
||
"username": user.Username,
|
||
"email": maskEmail(user.Email),
|
||
})
|
||
}
|
||
|
||
// @Summary 获取当前用户信息
|
||
// @Description 获取已登录用户的详细信息
|
||
// @Tags 认证
|
||
// @Accept json
|
||
// @Produce json
|
||
// @Security BearerAuth
|
||
// @Success 200 {object} map[string]interface{}
|
||
// @Failure 401 {object} map[string]string
|
||
// @Router /auth/me [get]
|
||
func (h *AuthHandler) GetCurrentUser(c *gin.Context) {
|
||
userID, exists := c.Get("user_id")
|
||
if !exists {
|
||
c.JSON(http.StatusUnauthorized, gin.H{"error": "user not found in context"})
|
||
return
|
||
}
|
||
|
||
user, err := h.authService.GetUserByID(userID.(string))
|
||
if err != nil {
|
||
c.JSON(http.StatusNotFound, gin.H{"error": "user not found"})
|
||
return
|
||
}
|
||
|
||
c.JSON(http.StatusOK, gin.H{
|
||
"id": user.ID,
|
||
"username": user.Username,
|
||
"email": maskEmail(user.Email),
|
||
"role_id": user.RoleID,
|
||
"is_active": user.IsActive,
|
||
"created_at": user.CreatedAt,
|
||
})
|
||
}
|
||
|
||
// @Summary 获取所有用户
|
||
// @Description 获取所有用户列表(需要管理员权限)
|
||
// @Tags 用户管理
|
||
// @Accept json
|
||
// @Produce json
|
||
// @Security BearerAuth
|
||
// @Success 200 {object} map[string]interface{}
|
||
// @Failure 401 {object} map[string]string
|
||
// @Router /user/list [get]
|
||
func (h *AuthHandler) ListUsers(c *gin.Context) {
|
||
users, err := h.authService.GetAllUsers()
|
||
if err != nil {
|
||
c.JSON(http.StatusInternalServerError, gin.H{"error": err.Error()})
|
||
return
|
||
}
|
||
|
||
var userList []gin.H
|
||
for _, user := range users {
|
||
userList = append(userList, gin.H{
|
||
"id": user.ID,
|
||
"username": user.Username,
|
||
"email": maskEmail(user.Email),
|
||
"role_id": user.RoleID,
|
||
"is_active": user.IsActive,
|
||
"created_at": user.CreatedAt,
|
||
})
|
||
}
|
||
|
||
c.JSON(http.StatusOK, gin.H{"list": userList})
|
||
}
|
||
|
||
// @Summary 获取用户详情
|
||
// @Description 根据ID获取用户详情
|
||
// @Tags 用户管理
|
||
// @Accept json
|
||
// @Produce json
|
||
// @Security BearerAuth
|
||
// @Param id path string true "用户ID"
|
||
// @Success 200 {object} map[string]interface{}
|
||
// @Failure 404 {object} map[string]string
|
||
// @Router /user/{id} [get]
|
||
func (h *AuthHandler) GetUserByID(c *gin.Context) {
|
||
id := c.Param("id")
|
||
if id == "" {
|
||
c.JSON(http.StatusBadRequest, gin.H{"error": "user id is required"})
|
||
return
|
||
}
|
||
|
||
user, err := h.authService.GetUserByID(id)
|
||
if err != nil {
|
||
c.JSON(http.StatusNotFound, gin.H{"error": "user not found"})
|
||
return
|
||
}
|
||
|
||
c.JSON(http.StatusOK, gin.H{
|
||
"id": user.ID,
|
||
"username": user.Username,
|
||
"email": maskEmail(user.Email),
|
||
"role_id": user.RoleID,
|
||
"is_active": user.IsActive,
|
||
"created_at": user.CreatedAt,
|
||
})
|
||
}
|