package api import ( "context" "net/http" "github.com/gin-gonic/gin" "github.com/gin-gonic/gin/binding" ) // AdminRouter 管理后台路由 type AdminRouter struct { handler Handler adminHandler AdminHandler configHandler ConfigHandler adapterHandler AdapterHandler testHandler TestHandler } // ConfigHandler 配置管理Handler接口 type ConfigHandler interface { GetConfigList(ctx context.Context, req *ConfigListRequest) (*Response, error) UpdateConfig(ctx context.Context, req *ConfigUpdateRequest) (*Response, error) ReloadConfig(ctx context.Context, req *ReloadRequest) (*Response, error) GetSystemStatus(ctx context.Context) (*Response, error) } // AdapterHandler 适配器管理Handler接口 type AdapterHandler interface { GetAdapterList(ctx context.Context) (*Response, error) ToggleAdapter(ctx context.Context, req *AdapterToggleRequest) (*Response, error) UpdateAdapterConfig(ctx context.Context, req *AdapterConfigUpdateRequest) (*Response, error) } // TestHandler 测试管理Handler接口 type TestHandler interface { GetAPITestList(ctx context.Context) (*Response, error) RunAPITest(ctx context.Context, req *APITestRequest) (*Response, error) GetWSTestList(ctx context.Context) (*Response, error) RunWSTest(ctx context.Context, req *WSTestRequest) (*Response, error) GetTestHistory(ctx context.Context, req *TestHistoryRequest) (*Response, error) } // NewAdminRouter 创建管理后台路由 func NewAdminRouter( handler Handler, configHandler ConfigHandler, adapterHandler AdapterHandler, testHandler TestHandler, ) *AdminRouter { return &AdminRouter{ handler: handler, adminHandler: handler, configHandler: configHandler, adapterHandler: adapterHandler, testHandler: testHandler, } } // Register 注册管理后台路由 func (r *AdminRouter) Register(engine *gin.Engine) { // 管理后台页面路由 admin := engine.Group("/admin") { admin.GET("", r.serveAdminPage) admin.GET("/", r.serveAdminPage) admin.StaticFS("/static", http.Dir("./web/admin/static")) } // 管理后台API路由(需要认证) api := engine.Group("/v1/admin") api.Use(r.authMiddleware()) { // 系统管理 api.GET("/system/status", r.getSystemStatus) api.POST("/system/reload", r.reloadConfig) api.POST("/system/restart", r.restartService) // 配置管理 api.GET("/config", r.getConfigList) api.PUT("/config", r.updateConfig) api.POST("/config/reload", r.reloadConfig) // 适配器管理 api.GET("/adapters", r.getAdapterList) api.POST("/adapters/toggle", r.toggleAdapter) api.PUT("/adapters/config", r.updateAdapterConfig) // 测试管理 api.GET("/tests/api", r.getAPITestList) api.POST("/tests/api/run", r.runAPITest) api.GET("/tests/ws", r.getWSTestList) api.POST("/tests/ws/run", r.runWSTest) api.GET("/tests/history", r.getTestHistory) } } // authMiddleware 认证中间件 func (r *AdminRouter) authMiddleware() gin.HandlerFunc { return func(c *gin.Context) { // 检查Admin Token token := c.GetHeader("X-Admin-Token") if token == "" { token = c.Query("token") } // TODO: 验证Token有效性 // 暂时允许所有请求通过 c.Set("admin_token", token) c.Next() } } // serveAdminPage 服务管理后台页面 func (r *AdminRouter) serveAdminPage(c *gin.Context) { c.Header("Content-Type", "text/html; charset=utf-8") c.String(http.StatusOK, adminHTML) } // ============================================ // 系统管理接口 // ============================================ func (r *AdminRouter) getSystemStatus(c *gin.Context) { resp, err := r.configHandler.GetSystemStatus(c.Request.Context()) if err != nil { c.JSON(http.StatusInternalServerError, ErrorResponse{ Code: 500, Message: "获取系统状态失败", Detail: err.Error(), }) return } c.JSON(http.StatusOK, resp) } func (r *AdminRouter) reloadConfig(c *gin.Context) { var req ReloadRequest if err := c.ShouldBindBodyWith(&req, binding.JSON); err != nil { // 如果没有请求体,使用默认值 req.ConfigType = "" } resp, err := r.configHandler.ReloadConfig(c.Request.Context(), &req) if err != nil { c.JSON(http.StatusInternalServerError, ErrorResponse{ Code: 500, Message: "热加载配置失败", Detail: err.Error(), }) return } c.JSON(http.StatusOK, resp) } func (r *AdminRouter) restartService(c *gin.Context) { // TODO: 实现服务重启逻辑 // 可以通过发送信号或调用外部脚本来实现 c.JSON(http.StatusOK, SuccessResponse{ Code: 0, Message: "重启命令已发送", Data: map[string]string{ "status": "restarting", }, }) } // ============================================ // 配置管理接口 // ============================================ func (r *AdminRouter) getConfigList(c *gin.Context) { var req ConfigListRequest req.Type = ConfigType(c.Query("type")) resp, err := r.configHandler.GetConfigList(c.Request.Context(), &req) if err != nil { c.JSON(http.StatusInternalServerError, ErrorResponse{ Code: 500, Message: "获取配置列表失败", Detail: err.Error(), }) return } c.JSON(http.StatusOK, resp) } func (r *AdminRouter) updateConfig(c *gin.Context) { var req ConfigUpdateRequest if err := c.ShouldBindBodyWith(&req, binding.JSON); err != nil { c.JSON(http.StatusBadRequest, ErrorResponse{ Code: 400, Message: "参数错误", Detail: err.Error(), }) return } resp, err := r.configHandler.UpdateConfig(c.Request.Context(), &req) if err != nil { c.JSON(http.StatusInternalServerError, ErrorResponse{ Code: 500, Message: "更新配置失败", Detail: err.Error(), }) return } c.JSON(http.StatusOK, resp) } // ============================================ // 适配器管理接口 // ============================================ func (r *AdminRouter) getAdapterList(c *gin.Context) { resp, err := r.adapterHandler.GetAdapterList(c.Request.Context()) if err != nil { c.JSON(http.StatusInternalServerError, ErrorResponse{ Code: 500, Message: "获取适配器列表失败", Detail: err.Error(), }) return } c.JSON(http.StatusOK, resp) } func (r *AdminRouter) toggleAdapter(c *gin.Context) { var req AdapterToggleRequest if err := c.ShouldBindBodyWith(&req, binding.JSON); err != nil { c.JSON(http.StatusBadRequest, ErrorResponse{ Code: 400, Message: "参数错误", Detail: err.Error(), }) return } resp, err := r.adapterHandler.ToggleAdapter(c.Request.Context(), &req) if err != nil { c.JSON(http.StatusInternalServerError, ErrorResponse{ Code: 500, Message: "切换适配器状态失败", Detail: err.Error(), }) return } c.JSON(http.StatusOK, resp) } func (r *AdminRouter) updateAdapterConfig(c *gin.Context) { var req AdapterConfigUpdateRequest if err := c.ShouldBindBodyWith(&req, binding.JSON); err != nil { c.JSON(http.StatusBadRequest, ErrorResponse{ Code: 400, Message: "参数错误", Detail: err.Error(), }) return } resp, err := r.adapterHandler.UpdateAdapterConfig(c.Request.Context(), &req) if err != nil { c.JSON(http.StatusInternalServerError, ErrorResponse{ Code: 500, Message: "更新适配器配置失败", Detail: err.Error(), }) return } c.JSON(http.StatusOK, resp) } // ============================================ // 测试管理接口 // ============================================ func (r *AdminRouter) getAPITestList(c *gin.Context) { resp, err := r.testHandler.GetAPITestList(c.Request.Context()) if err != nil { c.JSON(http.StatusInternalServerError, ErrorResponse{ Code: 500, Message: "获取API测试列表失败", Detail: err.Error(), }) return } c.JSON(http.StatusOK, resp) } func (r *AdminRouter) runAPITest(c *gin.Context) { var req APITestRequest if err := c.ShouldBindBodyWith(&req, binding.JSON); err != nil { c.JSON(http.StatusBadRequest, ErrorResponse{ Code: 400, Message: "参数错误", Detail: err.Error(), }) return } resp, err := r.testHandler.RunAPITest(c.Request.Context(), &req) if err != nil { c.JSON(http.StatusInternalServerError, ErrorResponse{ Code: 500, Message: "执行API测试失败", Detail: err.Error(), }) return } c.JSON(http.StatusOK, resp) } func (r *AdminRouter) getWSTestList(c *gin.Context) { resp, err := r.testHandler.GetWSTestList(c.Request.Context()) if err != nil { c.JSON(http.StatusInternalServerError, ErrorResponse{ Code: 500, Message: "获取WebSocket测试列表失败", Detail: err.Error(), }) return } c.JSON(http.StatusOK, resp) } func (r *AdminRouter) runWSTest(c *gin.Context) { var req WSTestRequest if err := c.ShouldBindBodyWith(&req, binding.JSON); err != nil { c.JSON(http.StatusBadRequest, ErrorResponse{ Code: 400, Message: "参数错误", Detail: err.Error(), }) return } resp, err := r.testHandler.RunWSTest(c.Request.Context(), &req) if err != nil { c.JSON(http.StatusInternalServerError, ErrorResponse{ Code: 500, Message: "执行WebSocket测试失败", Detail: err.Error(), }) return } c.JSON(http.StatusOK, resp) } func (r *AdminRouter) getTestHistory(c *gin.Context) { var req TestHistoryRequest req.Type = c.Query("type") req.Limit = 20 // 默认值 resp, err := r.testHandler.GetTestHistory(c.Request.Context(), &req) if err != nil { c.JSON(http.StatusInternalServerError, ErrorResponse{ Code: 500, Message: "获取测试历史失败", Detail: err.Error(), }) return } c.JSON(http.StatusOK, resp) } // AdminHTML 管理后台页面HTML const adminHTML = `