feat: 添加用户认证模块

- main.go: 初始化 User/Role 模型、UserRepository、AuthService 和 AuthHandler
- 添加 /auth/register、/auth/login、/auth/me 路由
- auth_handler.go: 新增 GetCurrentUser 接口获取当前用户信息
- .gitignore: 添加 .bitfun/ 目录忽略

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
This commit is contained in:
2026-03-11 10:25:50 +08:00
parent cea49bb685
commit 51a1202168
3 changed files with 46 additions and 1 deletions

3
.gitignore vendored
View File

@@ -214,3 +214,6 @@ test/
hs_err_pid* hs_err_pid*
replay_pid* replay_pid*
# BitFun snapshot data - auto managed
.bitfun/

View File

@@ -9,6 +9,7 @@ import (
"time" "time"
"x-agents/server/internal/config" "x-agents/server/internal/config"
"x-agents/server/internal/handler" "x-agents/server/internal/handler"
"x-agents/server/internal/middleware"
"x-agents/server/internal/model" "x-agents/server/internal/model"
"x-agents/server/internal/repository" "x-agents/server/internal/repository"
"x-agents/server/internal/service" "x-agents/server/internal/service"
@@ -70,13 +71,14 @@ func main() {
} }
// 3. 自动迁移表 // 3. 自动迁移表
db.AutoMigrate(&model.DatabaseInfo{}, &model.SubTableInfo{}, &model.ModelInfo{}, &model.KnowledgeBase{}, &model.KnowledgeDocument{}) db.AutoMigrate(&model.DatabaseInfo{}, &model.SubTableInfo{}, &model.ModelInfo{}, &model.KnowledgeBase{}, &model.KnowledgeDocument{}, &model.User{}, &model.Role{})
// 4. 初始化 Repository // 4. 初始化 Repository
dbRepo := repository.NewDatabaseRepository(db) dbRepo := repository.NewDatabaseRepository(db)
subTableRepo := repository.NewSubTableRepository(db) subTableRepo := repository.NewSubTableRepository(db)
modelRepo := repository.NewModelRepository(db) modelRepo := repository.NewModelRepository(db)
knowledgeRepo := repository.NewKnowledgeRepository(db) knowledgeRepo := repository.NewKnowledgeRepository(db)
userRepo := repository.NewUserRepository(db)
// 5. 初始化 Service // 5. 初始化 Service
dbService := service.NewDatabaseService(dbRepo, subTableRepo) dbService := service.NewDatabaseService(dbRepo, subTableRepo)
@@ -88,6 +90,7 @@ func main() {
log.Printf("Warning: Failed to initialize upload service: %v (files will not be available)", err) log.Printf("Warning: Failed to initialize upload service: %v (files will not be available)", err)
} }
knowledgeService := service.NewKnowledgeService(knowledgeRepo, modelRepo, uploadService, cfg.PythonServiceURL, cfg.AICoreServiceAddr, cfg.MarkdownLocalPath) knowledgeService := service.NewKnowledgeService(knowledgeRepo, modelRepo, uploadService, cfg.PythonServiceURL, cfg.AICoreServiceAddr, cfg.MarkdownLocalPath)
authService := service.NewAuthService(cfg.JWTSecret, userRepo)
// 6. 初始化 Handler // 6. 初始化 Handler
dbHandler := handler.NewDatabaseHandler(dbService) dbHandler := handler.NewDatabaseHandler(dbService)
@@ -96,6 +99,7 @@ func main() {
modelHandler := handler.NewModelHandler(modelService) modelHandler := handler.NewModelHandler(modelService)
systemHandler := handler.NewSystemHandler() systemHandler := handler.NewSystemHandler()
knowledgeHandler := handler.NewKnowledgeHandler(knowledgeService) knowledgeHandler := handler.NewKnowledgeHandler(knowledgeService)
authHandler := handler.NewAuthHandler(authService)
var uploadHandler *handler.UploadHandler var uploadHandler *handler.UploadHandler
if uploadService != nil { if uploadService != nil {
uploadHandler = handler.NewUploadHandler(uploadService, knowledgeRepo) uploadHandler = handler.NewUploadHandler(uploadService, knowledgeRepo)
@@ -144,6 +148,20 @@ func main() {
c.Next() c.Next()
}) })
// 认证模块(无需登录)
authGroup := r.Group("/auth")
{
authGroup.POST("/register", authHandler.Register)
authGroup.POST("/login", authHandler.Login)
}
// 需要登录的认证模块
authProtectedGroup := r.Group("/auth")
authProtectedGroup.Use(middleware.Auth(cfg.JWTSecret))
{
authProtectedGroup.GET("/me", authHandler.GetCurrentUser)
}
// 数据库管理模块 // 数据库管理模块
databaseGroup := r.Group("/database") databaseGroup := r.Group("/database")
{ {

View File

@@ -78,3 +78,27 @@ func (h *AuthHandler) Register(c *gin.Context) {
"email": user.Email, "email": user.Email,
}) })
} }
// GetCurrentUser 获取当前登录用户信息
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": user.Email,
"role_id": user.RoleID,
"is_active": user.IsActive,
"created_at": user.CreatedAt,
})
}