package server import ( "fmt" "strings" "github.com/gofiber/fiber/v2" "github.com/gofiber/fiber/v2/middleware/cors" "github.com/gofiber/fiber/v2/middleware/logger" "github.com/gofiber/fiber/v2/middleware/recover" "github.com/gofiber/template/html/v2" "gitee.ltd/lxh/wechat-robot/internal/config" "gitee.ltd/lxh/wechat-robot/internal/handler" "gitee.ltd/lxh/wechat-robot/internal/middleware" ) // Server 表示HTTP服务器 type Server struct { app *fiber.App config *config.Config } // New 创建新的服务器实例 func New(cfg *config.Config) *Server { // 初始化模板引擎 engine := html.New("./internal/view", ".html") engine.Reload(cfg.Server.Env == "development") // 开发环境下启用热重载 // 添加自定义模板函数 engine.AddFunc("sub", func(a, b int) int { return a - b }) // 创建Fiber应用 app := fiber.New(fiber.Config{ Views: engine, ViewsLayout: "layouts/main", ErrorHandler: customErrorHandler, EnablePrintRoutes: cfg.Server.Env == "development", }) // 注册中间件 app.Use(recover.New()) app.Use(logger.New(logger.Config{ Format: "[${time}] ${status} - ${latency} ${method} ${path}\n", })) app.Use(cors.New()) // 静态文件服务 app.Static("/public", "./public") return &Server{ app: app, config: cfg, } } // SetupRoutes 设置路由 func (s *Server) SetupRoutes() { // 公共路由 s.app.Get("/", handler.Home) s.app.Get("/login", handler.LoginPage) s.app.Post("/login", handler.LoginSubmit) s.app.Get("/logout", handler.Logout) // 受保护的路由 auth := s.app.Group("/admin", middleware.Authenticate()) // 机器人管理 auth.Get("/robots", handler.ListRobots) auth.Get("/robots/new", handler.NewRobotForm) auth.Post("/robots", handler.CreateRobot) auth.Get("/robots/:id", handler.ShowRobot) auth.Delete("/robots/:id", handler.DeleteRobot) auth.Get("/robots/:id/login", handler.RobotLogin) auth.Post("/robots/:id/logout", handler.RobotLogout) // 联系人管理 auth.Get("/robots/:id/contacts", handler.ListContacts) auth.Get("/robots/:id/contacts/:contactId", handler.ShowContact) auth.Get("/robots/:id/contacts/:contactId/members", handler.ListGroupMembers) // 消息管理 auth.Get("/robots/:id/contacts/:contactId/messages", handler.ListMessages) // API路由 api := s.app.Group("/api") api.Get("/robots", handler.APIListRobots) api.Get("/robots/:id/status", handler.APIGetRobotStatus) // 更多API路由... } // Start 启动HTTP服务器 func (s *Server) Start() error { addr := s.config.Server.Address() fmt.Printf("Server starting on %s\n", addr) return s.app.Listen(addr) } // Shutdown 优雅地关闭服务器 func (s *Server) Shutdown() error { if s.app != nil { return s.app.Shutdown() } return nil } // 自定义错误处理器 func customErrorHandler(c *fiber.Ctx, err error) error { code := fiber.StatusInternalServerError if e, ok := err.(*fiber.Error); ok { code = e.Code } // 检查是否请求API if strings.HasPrefix(c.Path(), "/api") { return c.Status(code).JSON(fiber.Map{ "error": true, "message": err.Error(), }) } // 网页错误 return c.Status(code).Render("error", fiber.Map{ "Title": fmt.Sprintf("Error %d", code), "StatusCode": code, "ErrorMessage": err.Error(), }) }