2025-03-27 16:27:41 +08:00

132 lines
3.2 KiB
Go

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(),
})
}