// Package routers 路由配置 // 定义所有HTTP路由和路由组 package routers import ( "log" "github.com/LoveLosita/smartflow/backend/api" "github.com/LoveLosita/smartflow/backend/dao" "github.com/LoveLosita/smartflow/backend/middleware" "github.com/LoveLosita/smartflow/backend/pkg" "github.com/gin-gonic/gin" "github.com/spf13/viper" ) // StartEngine 注册路由 func StartEngine(r *gin.Engine) { // 从配置中获取端口 port := viper.GetString("server.port") if port == "" { port = "8080" // 默认端口 } // 启动服务器 log.Printf("Server starting on port %s...", port) if err := r.Run(":" + port); err != nil { log.Fatalf("Failed to start server: %v", err) } } func RegisterRouters(handlers *api.ApiHandlers, cache *dao.CacheDAO, userRepo *dao.UserDAO, limiter *pkg.RateLimiter) *gin.Engine { // 初始化Gin引擎 r := gin.Default() // 在这里注册所有的路由和路由组 apiGroup := r.Group("/api/v1") { // 健康检查路由 apiGroup.GET("/health", func(c *gin.Context) { c.JSON(200, gin.H{ "status": "ok", "version": "0.4.0.dev", }) }) userGroup := apiGroup.Group("/user") { userGroup.POST("/register", handlers.UserHandler.UserRegister) userGroup.POST("/login", handlers.UserHandler.UserLogin) userGroup.POST("/refresh-token", handlers.UserHandler.RefreshTokenHandler) userGroup.POST("/logout", middleware.JWTTokenAuth(cache), middleware.RateLimitMiddleware(limiter, 20, 1), handlers.UserHandler.UserLogout) } taskGroup := apiGroup.Group("/task") { taskGroup.Use(middleware.JWTTokenAuth(cache), middleware.RateLimitMiddleware(limiter, 20, 1)) taskGroup.POST("/create", middleware.IdempotencyMiddleware(cache), handlers.TaskHandler.AddTask) taskGroup.PUT("/complete", middleware.IdempotencyMiddleware(cache), handlers.TaskHandler.CompleteTask) taskGroup.PUT("/undo-complete", middleware.IdempotencyMiddleware(cache), handlers.TaskHandler.UndoCompleteTask) taskGroup.PUT("/update", middleware.IdempotencyMiddleware(cache), handlers.TaskHandler.UpdateTask) taskGroup.DELETE("/delete", middleware.IdempotencyMiddleware(cache), handlers.TaskHandler.DeleteTask) taskGroup.GET("/get", handlers.TaskHandler.GetUserTasks) taskGroup.POST("/batch-status", handlers.TaskHandler.BatchTaskStatus) } courseGroup := apiGroup.Group("/course") { courseGroup.Use(middleware.JWTTokenAuth(cache), middleware.RateLimitMiddleware(limiter, 20, 1)) courseGroup.POST("/validate", handlers.CourseHandler.CheckUserCourse) courseGroup.POST("/parse-image", handlers.CourseHandler.ParseCourseTableImage) courseGroup.POST("/import", middleware.IdempotencyMiddleware(cache), handlers.CourseHandler.AddUserCourses) } taskClassGroup := apiGroup.Group("/task-class") { taskClassGroup.Use(middleware.JWTTokenAuth(cache), middleware.RateLimitMiddleware(limiter, 20, 1)) taskClassGroup.POST("/add", middleware.IdempotencyMiddleware(cache), handlers.TaskClassHandler.UserAddTaskClass) taskClassGroup.GET("/list", handlers.TaskClassHandler.UserGetTaskClassInfos) taskClassGroup.GET("/get", handlers.TaskClassHandler.UserGetCompleteTaskClass) taskClassGroup.PUT("/update", middleware.IdempotencyMiddleware(cache), handlers.TaskClassHandler.UserUpdateTaskClass) taskClassGroup.POST("/insert-into-schedule", middleware.IdempotencyMiddleware(cache), handlers.TaskClassHandler.UserAddTaskClassItemIntoSchedule) taskClassGroup.DELETE("/delete-item", middleware.IdempotencyMiddleware(cache), handlers.TaskClassHandler.DeleteTaskClassItem) taskClassGroup.DELETE("/delete-class", middleware.IdempotencyMiddleware(cache), handlers.TaskClassHandler.DeleteTaskClass) taskClassGroup.PUT("/apply-batch-into-schedule", middleware.IdempotencyMiddleware(cache), handlers.TaskClassHandler.UserInsertBatchTaskClassItemsIntoSchedule) } scheduleGroup := apiGroup.Group("/schedule") { scheduleGroup.Use(middleware.JWTTokenAuth(cache), middleware.RateLimitMiddleware(limiter, 20, 1)) scheduleGroup.GET("/today", handlers.ScheduleHandler.GetUserTodaySchedule) scheduleGroup.GET("/week", handlers.ScheduleHandler.GetUserWeeklySchedule) scheduleGroup.DELETE("/delete", middleware.IdempotencyMiddleware(cache), handlers.ScheduleHandler.DeleteScheduleEvent) scheduleGroup.GET("/recent-completed", handlers.ScheduleHandler.GetUserRecentCompletedSchedules) scheduleGroup.GET("/current", handlers.ScheduleHandler.GetUserOngoingSchedule) scheduleGroup.DELETE("/undo-task-item", middleware.IdempotencyMiddleware(cache), handlers.ScheduleHandler.UserRevocateTaskItemFromSchedule) scheduleGroup.GET("/smart-planning", handlers.ScheduleHandler.SmartPlanning) scheduleGroup.POST("/smart-planning-multi", handlers.ScheduleHandler.SmartPlanningMulti) } agentGroup := apiGroup.Group("/agent") { agentGroup.Use(middleware.JWTTokenAuth(cache), middleware.RateLimitMiddleware(limiter, 20, 1)) agentGroup.POST("/chat", middleware.TokenQuotaGuard(cache, userRepo), handlers.AgentHandler.ChatAgent) agentGroup.GET("/conversation-meta", handlers.AgentHandler.GetConversationMeta) agentGroup.GET("/conversation-list", handlers.AgentHandler.GetConversationList) agentGroup.GET("/conversation-timeline", handlers.AgentHandler.GetConversationTimeline) agentGroup.GET("/schedule-preview", handlers.AgentHandler.GetSchedulePlanPreview) agentGroup.GET("/context-stats", handlers.AgentHandler.GetContextStats) agentGroup.POST("/schedule-state", handlers.AgentHandler.SaveScheduleState) } memoryGroup := apiGroup.Group("/memory") { memoryGroup.Use(middleware.JWTTokenAuth(cache), middleware.RateLimitMiddleware(limiter, 20, 1)) memoryGroup.GET("/items", handlers.MemoryHandler.ListItems) memoryGroup.GET("/items/:id", handlers.MemoryHandler.GetItem) memoryGroup.POST("/items", middleware.IdempotencyMiddleware(cache), handlers.MemoryHandler.CreateItem) memoryGroup.PATCH("/items/:id", middleware.IdempotencyMiddleware(cache), handlers.MemoryHandler.UpdateItem) memoryGroup.DELETE("/items/:id", middleware.IdempotencyMiddleware(cache), handlers.MemoryHandler.DeleteItem) memoryGroup.POST("/items/:id/restore", middleware.IdempotencyMiddleware(cache), handlers.MemoryHandler.RestoreItem) } activeScheduleGroup := apiGroup.Group("/active-schedule") { activeScheduleGroup.Use(middleware.JWTTokenAuth(cache), middleware.RateLimitMiddleware(limiter, 20, 1)) activeScheduleGroup.POST("/dry-run", handlers.ActiveSchedule.DryRun) activeScheduleGroup.POST("/trigger", handlers.ActiveSchedule.Trigger) activeScheduleGroup.POST("/preview", handlers.ActiveSchedule.CreatePreview) activeScheduleGroup.GET("/preview/:preview_id", handlers.ActiveSchedule.GetPreview) activeScheduleGroup.POST("/preview/:preview_id/confirm", handlers.ActiveSchedule.ConfirmPreview) } notificationGroup := apiGroup.Group("/notification") { notificationGroup.Use(middleware.JWTTokenAuth(cache), middleware.RateLimitMiddleware(limiter, 20, 1)) notificationGroup.GET("/channels/feishu", handlers.Notification.GetFeishuWebhook) notificationGroup.PUT("/channels/feishu", handlers.Notification.SaveFeishuWebhook) notificationGroup.DELETE("/channels/feishu", handlers.Notification.DeleteFeishuWebhook) notificationGroup.POST("/channels/feishu/test", handlers.Notification.TestFeishuWebhook) } } // 初始化Gin引擎 log.Println("Routes setup completed") return r }