package initialize import ( "net/http" "os" "strings" "git.echol.cn/loser/ai_proxy/server/docs" "git.echol.cn/loser/ai_proxy/server/global" "git.echol.cn/loser/ai_proxy/server/middleware" "git.echol.cn/loser/ai_proxy/server/router" "github.com/gin-gonic/gin" swaggerFiles "github.com/swaggo/files" ginSwagger "github.com/swaggo/gin-swagger" ) type justFilesFilesystem struct { fs http.FileSystem } func (fs justFilesFilesystem) Open(name string) (http.File, error) { f, err := fs.fs.Open(name) if err != nil { return nil, err } stat, err := f.Stat() if stat.IsDir() { return nil, os.ErrPermission } return f, nil } // 初始化总路由 func Routers() *gin.Engine { Router := gin.New() // 使用自定义的 Recovery 中间件,记录 panic 并入库 Router.Use(middleware.GinRecovery(true)) if gin.Mode() == gin.DebugMode { Router.Use(gin.Logger()) } if !global.GVA_CONFIG.MCP.Separate { sseServer := McpRun() // 注册mcp服务 Router.GET(global.GVA_CONFIG.MCP.SSEPath, func(c *gin.Context) { sseServer.SSEHandler().ServeHTTP(c.Writer, c.Request) }) Router.POST(global.GVA_CONFIG.MCP.MessagePath, func(c *gin.Context) { sseServer.MessageHandler().ServeHTTP(c.Writer, c.Request) }) } systemRouter := router.RouterGroupApp.System exampleRouter := router.RouterGroupApp.Example // 静态文件服务 Router.StaticFS(global.GVA_CONFIG.Local.StorePath, justFilesFilesystem{http.Dir(global.GVA_CONFIG.Local.StorePath)}) // 跨域,如需跨域可以打开下面的注释 // Router.Use(middleware.Cors()) // 直接放行全部跨域请求 // Router.Use(middleware.CorsByRules()) // 按照配置的规则放行跨域请求 // global.GVA_LOG.Info("use middleware cors") docs.SwaggerInfo.BasePath = global.GVA_CONFIG.System.RouterPrefix Router.GET(global.GVA_CONFIG.System.RouterPrefix+"/swagger/*any", ginSwagger.WrapHandler(swaggerFiles.Handler)) global.GVA_LOG.Info("register swagger handler") // 方便统一添加路由组前缀 多服务器上线使用 PublicGroup := Router.Group(global.GVA_CONFIG.System.RouterPrefix) PrivateGroup := Router.Group(global.GVA_CONFIG.System.RouterPrefix) PrivateGroup.Use(middleware.JWTAuth()).Use(middleware.CasbinHandler()) { // 健康监测 PublicGroup.GET("/health", func(c *gin.Context) { c.JSON(http.StatusOK, "ok") }) } { systemRouter.InitBaseRouter(PublicGroup) // 注册基础功能路由 不做鉴权 systemRouter.InitInitRouter(PublicGroup) // 自动初始化相关 } { systemRouter.InitApiRouter(PrivateGroup, PublicGroup) // 注册功能api路由 systemRouter.InitJwtRouter(PrivateGroup) // jwt相关路由 systemRouter.InitUserRouter(PrivateGroup) // 注册用户路由 systemRouter.InitMenuRouter(PrivateGroup) // 注册menu路由 systemRouter.InitSystemRouter(PrivateGroup) // system相关路由 systemRouter.InitSysVersionRouter(PrivateGroup) // 发版相关路由 systemRouter.InitCasbinRouter(PrivateGroup) // 权限相关路由 systemRouter.InitAutoCodeRouter(PrivateGroup, PublicGroup) // 创建自动化代码 systemRouter.InitAuthorityRouter(PrivateGroup) // 注册角色路由 systemRouter.InitSysDictionaryRouter(PrivateGroup) // 字典管理 systemRouter.InitAutoCodeHistoryRouter(PrivateGroup) // 自动化代码历史 systemRouter.InitSysOperationRecordRouter(PrivateGroup) // 操作记录 systemRouter.InitSysDictionaryDetailRouter(PrivateGroup) // 字典详情管理 systemRouter.InitAuthorityBtnRouterRouter(PrivateGroup) // 按钮权限管理 systemRouter.InitSysExportTemplateRouter(PrivateGroup, PublicGroup) // 导出模板 systemRouter.InitSysParamsRouter(PrivateGroup, PublicGroup) // 参数管理 systemRouter.InitSysErrorRouter(PrivateGroup, PublicGroup) // 错误日志 systemRouter.InitLoginLogRouter(PrivateGroup) // 登录日志 systemRouter.InitApiTokenRouter(PrivateGroup) // apiToken签发 systemRouter.InitSkillsRouter(PrivateGroup) // Skills 定义器 exampleRouter.InitCustomerRouter(PrivateGroup) // 客户路由 exampleRouter.InitFileUploadAndDownloadRouter(PrivateGroup) // 文件上传下载功能路由 exampleRouter.InitAttachmentCategoryRouterRouter(PrivateGroup) // 文件上传下载分类 } //插件路由安装 InstallPlugin(PrivateGroup, PublicGroup, Router) // 注册业务路由 initBizRouter(PrivateGroup, PublicGroup) // 在根路径下注册 AI 通用接口路由(不带 /api 前缀,走 /v1/**) router.RouterGroupApp.App.InitAiProxyRootRouter(Router) // 前端静态文件服务(放在最后,作为兜底路由) setupFrontendRoutes(Router) global.GVA_ROUTERS = Router.Routes() global.GVA_LOG.Info("router register success") return Router } // setupFrontendRoutes 配置前端静态文件路由 func setupFrontendRoutes(router *gin.Engine) { // 检查 dist 目录是否存在 if _, err := os.Stat("./dist"); os.IsNotExist(err) { global.GVA_LOG.Warn("前端 dist 目录不存在,跳过前端路由配置") return } // 静态资源目录 router.Static("/assets", "./dist/assets") router.StaticFile("/favicon.ico", "./dist/favicon.ico") // SPA 路由处理:所有非 API 请求都返回 index.html router.NoRoute(func(c *gin.Context) { path := c.Request.URL.Path // 如果是 API 请求(/api/* 或 /v1/*),返回 404 routerPrefix := global.GVA_CONFIG.System.RouterPrefix if routerPrefix == "" { routerPrefix = "/api" } if strings.HasPrefix(path, routerPrefix) || strings.HasPrefix(path, "/v1") { c.JSON(http.StatusNotFound, gin.H{ "code": 404, "msg": "接口不存在", }) return } // 其他请求返回前端页面 c.File("./dist/index.html") }) global.GVA_LOG.Info("前端静态文件路由配置成功") }