From 5698169f20f310d274a43723bc01dda55a16d4ea Mon Sep 17 00:00:00 2001 From: ryan Date: Sat, 13 Jun 2026 16:27:08 +0800 Subject: [PATCH] refactor(router): extract route registration into helper methods --- docs/docs.go | 64 +++---- docs/swagger.json | 64 +++---- docs/swagger.yaml | 36 ++-- internal/apps/health/routers.go | 2 +- internal/router/middlewares.go | 2 +- internal/router/router.go | 313 +++++++++++++++++--------------- 6 files changed, 253 insertions(+), 228 deletions(-) diff --git a/docs/docs.go b/docs/docs.go index bbcdeca1..d70cdd28 100644 --- a/docs/docs.go +++ b/docs/docs.go @@ -107,6 +107,38 @@ const docTemplate = `{ } } }, + "/api/health": { + "get": { + "description": "检查服务是否正常运行,可用于负载均衡存活探测", + "produces": [ + "application/json" + ], + "tags": [ + "health" + ], + "summary": "健康检查", + "responses": { + "200": { + "description": "服务正常", + "schema": { + "allOf": [ + { + "$ref": "#/definitions/util.ResponseAny" + }, + { + "type": "object", + "properties": { + "data": { + "type": "string" + } + } + } + ] + } + } + } + } + }, "/api/v1/admin/auth-sources": { "get": { "security": [ @@ -3426,38 +3458,6 @@ const docTemplate = `{ } } }, - "/api/v1/health": { - "get": { - "description": "检查服务是否正常运行,可用于负载均衡存活探测", - "produces": [ - "application/json" - ], - "tags": [ - "health" - ], - "summary": "健康检查", - "responses": { - "200": { - "description": "服务正常", - "schema": { - "allOf": [ - { - "$ref": "#/definitions/util.ResponseAny" - }, - { - "type": "object", - "properties": { - "data": { - "type": "string" - } - } - } - ] - } - } - } - } - }, "/api/v1/oauth/callback": { "post": { "description": "接收前端传回的 state 和 code,完成 OAuth/OIDC 认证并建立会话。支持登录(login)和账号绑定(bind)两种场景。", diff --git a/docs/swagger.json b/docs/swagger.json index bfaffed1..cddb8371 100644 --- a/docs/swagger.json +++ b/docs/swagger.json @@ -100,6 +100,38 @@ } } }, + "/api/health": { + "get": { + "description": "检查服务是否正常运行,可用于负载均衡存活探测", + "produces": [ + "application/json" + ], + "tags": [ + "health" + ], + "summary": "健康检查", + "responses": { + "200": { + "description": "服务正常", + "schema": { + "allOf": [ + { + "$ref": "#/definitions/util.ResponseAny" + }, + { + "type": "object", + "properties": { + "data": { + "type": "string" + } + } + } + ] + } + } + } + } + }, "/api/v1/admin/auth-sources": { "get": { "security": [ @@ -3419,38 +3451,6 @@ } } }, - "/api/v1/health": { - "get": { - "description": "检查服务是否正常运行,可用于负载均衡存活探测", - "produces": [ - "application/json" - ], - "tags": [ - "health" - ], - "summary": "健康检查", - "responses": { - "200": { - "description": "服务正常", - "schema": { - "allOf": [ - { - "$ref": "#/definitions/util.ResponseAny" - }, - { - "type": "object", - "properties": { - "data": { - "type": "string" - } - } - } - ] - } - } - } - } - }, "/api/v1/oauth/callback": { "post": { "description": "接收前端传回的 state 和 code,完成 OAuth/OIDC 认证并建立会话。支持登录(login)和账号绑定(bind)两种场景。", diff --git a/docs/swagger.yaml b/docs/swagger.yaml index 57454a17..08492a0b 100644 --- a/docs/swagger.yaml +++ b/docs/swagger.yaml @@ -1190,6 +1190,24 @@ paths: summary: 校验人机验证解答 tags: - cap + /api/health: + get: + description: 检查服务是否正常运行,可用于负载均衡存活探测 + produces: + - application/json + responses: + "200": + description: 服务正常 + schema: + allOf: + - $ref: '#/definitions/util.ResponseAny' + - properties: + data: + type: string + type: object + summary: 健康检查 + tags: + - health /api/v1/admin/auth-sources: get: description: 返回所有已配置的 OAuth/OIDC 认证源列表,包括已启用和未启用的,需要管理员权限 @@ -3193,24 +3211,6 @@ paths: summary: Sample Hello API tags: - custom - /api/v1/health: - get: - description: 检查服务是否正常运行,可用于负载均衡存活探测 - produces: - - application/json - responses: - "200": - description: 服务正常 - schema: - allOf: - - $ref: '#/definitions/util.ResponseAny' - - properties: - data: - type: string - type: object - summary: 健康检查 - tags: - - health /api/v1/oauth/{source}/authorize: get: description: 根据指定认证源名称发起 OAuth 授权,支持 purpose 参数用于区分登录和账号绑定场景。认证源必须已启用。 diff --git a/internal/apps/health/routers.go b/internal/apps/health/routers.go index a6ede446..e78cbc3f 100644 --- a/internal/apps/health/routers.go +++ b/internal/apps/health/routers.go @@ -18,7 +18,7 @@ import ( // @Tags health // @Produce json // @Success 200 {object} util.ResponseAny{data=string} "服务正常" -// @Router /api/v1/health [get] +// @Router /api/health [get] func Health(c *gin.Context) { c.JSON(http.StatusOK, util.OKNil()) } diff --git a/internal/router/middlewares.go b/internal/router/middlewares.go index 65db3974..cb2122d4 100644 --- a/internal/router/middlewares.go +++ b/internal/router/middlewares.go @@ -45,7 +45,7 @@ func loggerMiddleware() gin.HandlerFunc { // 打印日志 // 排除健康检查接口 - healthPath := config.Config.App.APIPrefix + "/v1/health" + healthPath := config.Config.App.APIPrefix + "/health" if c.Request.URL.Path != healthPath { logger.InfoF( ctx, diff --git a/internal/router/router.go b/internal/router/router.go index 7d8eb8af..6c694e7f 100644 --- a/internal/router/router.go +++ b/internal/router/router.go @@ -146,164 +146,28 @@ func registerRoutes(r *gin.Engine) { } // CAPTCHA - capGroup := apiGroup.Group("/cap") - { - capGroup.POST("/challenge", capApp.Challenge) - capGroup.POST("/redeem", capApp.Redeem) - } + registerCaptchaRoutes(apiGroup) + + // Health + apiGroup.GET("/health", health.Health) // API V1 apiV1Router := apiGroup.Group("/v1") { - // Health - apiV1Router.GET("/health", health.Health) - // OAuth - apiV1Router.GET("/oauth/sources", oauth.GetLoginSources) - apiV1Router.GET("/oauth/login", oauth.GetLoginURL) - apiV1Router.GET("/oauth/:source/authorize", oauth.Authorize) - apiV1Router.GET("/oauth/logout", oauth.Logout) - apiV1Router.POST("/oauth/callback", oauth.Callback) - apiV1Router.GET("/oauth/user-info", oauth.LoginRequired(), oauth.UserInfo) - apiV1Router.GET("/user-info", oauth.LoginRequired(), oauth.UserInfo) - apiV1Router.GET("/oauth/external-accounts", oauth.LoginRequired(), oauth.ListExternalAccounts) - apiV1Router.POST("/oauth/external-accounts/:id/delete", oauth.LoginRequired(), oauth.DeleteExternalAccount) + registerOAuthRoutes(apiV1Router) // User - userRouter := apiV1Router.Group("/user") - { - userRouter.POST("/login", capApp.VerifyMiddleware(capUtil.GetDefaultManager(), "login", func() bool { - enabled, err := model.GetBoolByKey(context.Background(), model.ConfigKeyCapLoginEnabled) - if err != nil { - return false - } - return enabled - }), user.Login) - userRouter.POST("/register", capApp.VerifyMiddleware(capUtil.GetDefaultManager(), "register", func() bool { - enabled, err := model.GetBoolByKey(context.Background(), model.ConfigKeyCapLoginEnabled) - if err != nil { - return false - } - return enabled - }), user.Register) - userRouter.POST("/send-email-code", capApp.VerifyMiddleware(capUtil.GetDefaultManager(), "send_email_code", func() bool { - enabled, err := model.GetBoolByKey(context.Background(), model.ConfigKeyCapLoginEnabled) - if err != nil { - return false - } - return enabled - }), user.SendEmailCode) - userRouter.GET("/logout", user.Logout) - userRouter.GET("/self", oauth.LoginRequired(), oauth.UserInfo) - userRouter.POST("/change-password", oauth.LoginRequired(), user.ChangePassword) - userRouter.PUT("/profile", oauth.LoginRequired(), user.UpdateProfile) - - // Access Token - tokenRouter := userRouter.Group("/access-tokens") - tokenRouter.Use(oauth.LoginRequired(), oauth.DisallowTokenAuth()) - { - tokenRouter.GET("", user.ListAccessTokens) - tokenRouter.POST("", user.CreateAccessToken) - tokenRouter.DELETE("/:id", user.DeleteAccessToken) - tokenRouter.POST("/:id/rotate", user.RotateAccessToken) - } - } + registerUserRoutes(apiV1Router) // Upload registerUploadRoutes(apiV1Router) // Config (public) - configRouter := apiV1Router.Group("/config") - { - configRouter.GET("/public", publicconfig.GetPublicConfig) - } + registerConfigRoutes(apiV1Router) // Admin - adminRouter := apiV1Router.Group("/admin") - adminRouter.Use(oauth.LoginRequired(), admin.LoginAdminRequired()) - { - // System status - adminRouter.GET("/status", admin_status.GetSystemStatus) - - // Database info & export - adminRouter.GET("/db-info", admin_status.GetDatabaseInfo) - adminRouter.GET("/db-export", admin_status.ExportDatabase) - - // Database management - adminRouter.GET("/db-manage/overview", admin_db_manage.GetDBOverview) - adminRouter.GET("/db-manage/tables", admin_db_manage.ListDBTables) - adminRouter.GET("/db-manage/table-data", admin_db_manage.GetDBTableData) - adminRouter.POST("/db-manage/query", admin_db_manage.ExecuteSQL) - - // Cache management - adminRouter.GET("/cache/status", admin_cache.GetCacheStatus) - adminRouter.POST("/cache/config", admin_cache.UpdateCacheConfig) - adminRouter.POST("/cache/clear", admin_cache.ClearCache) - - // Application update - adminRouter.GET("/update", admin_updater.GetUpdateStatus) - adminRouter.POST("/update/apply", admin_updater.ApplyUpdate) - - // System logs - adminRouter.GET("/logs", admin_logs.GetLogs) - adminRouter.GET("/logs/access", admin_logs.GetAccessLogs) - adminRouter.GET("/logs/analytics", admin_logs.GetLogsAnalytics) - adminRouter.GET("/logs/ws", admin_logs.HandleLogWebSocket) - - // Task dispatch - adminRouter.GET("/tasks/types", admin_task.ListTaskTypes) - adminRouter.POST("/tasks/dispatch", admin_task.DispatchTask) - - // Task executions - adminRouter.GET("/tasks/executions", admin_task.ListTaskExecutions) - adminRouter.GET("/tasks/executions/:id", admin_task.GetTaskExecution) - adminRouter.POST("/tasks/executions/:id/retry", admin_task.RetryTask) - - // Task schedules - adminRouter.GET("/tasks/schedules", admin_task.ListSchedules) - adminRouter.POST("/tasks/schedules", admin_task.CreateSchedule) - adminRouter.PUT("/tasks/schedules/:id", admin_task.UpdateSchedule) - adminRouter.DELETE("/tasks/schedules/:id", admin_task.DeleteSchedule) - - // Users - adminRouter.GET("/users", admin_user.ListUsers) - adminRouter.POST("/users", admin_user.CreateUser) - adminRouter.GET("/users/:id", admin_user.GetUser) - adminRouter.PUT("/users/:id/status", admin_user.UpdateUserStatus) - adminRouter.DELETE("/users/:id", admin_user.DeleteUser) - - // Uploads - registerAdminUploadRoutes(adminRouter) - - // System Config - adminRouter.POST("/system-configs", system_config.CreateSystemConfig) - adminRouter.GET("/system-configs", system_config.ListSystemConfigs) - adminRouter.POST("/system-configs/smtp/test", system_config.TestSMTP) - - systemConfigRouter := adminRouter.Group("/system-configs/:key") - { - systemConfigRouter.GET("", system_config.GetSystemConfig) - systemConfigRouter.PUT("", system_config.UpdateSystemConfig) - } - - // Templates - adminRouter.GET("/templates", admin_template.ListTemplates) - adminRouter.POST("/templates", admin_template.CreateTemplate) - - templateRouter := adminRouter.Group("/templates/:key") - { - templateRouter.GET("", admin_template.GetTemplate) - templateRouter.PUT("", admin_template.UpdateTemplate) - templateRouter.DELETE("", admin_template.DeleteTemplate) - } - - // Auth Sources - adminRouter.GET("/auth-sources", admin_auth_source.ListAuthSources) - adminRouter.POST("/auth-sources", admin_auth_source.CreateAuthSource) - adminRouter.PUT("/auth-sources/:id", admin_auth_source.UpdateAuthSource) - adminRouter.PUT("/auth-sources/:id/toggle", admin_auth_source.ToggleAuthSource) - adminRouter.DELETE("/auth-sources/:id", admin_auth_source.DeleteAuthSource) - } + registerAdminRoutes(apiV1Router) // Register custom business routes registerCustomRoutes(apiV1Router) @@ -314,6 +178,67 @@ func registerRoutes(r *gin.Engine) { registerFrontend(r) } +func registerCaptchaRoutes(apiGroup *gin.RouterGroup) { + capGroup := apiGroup.Group("/cap") + { + capGroup.POST("/challenge", capApp.Challenge) + capGroup.POST("/redeem", capApp.Redeem) + } +} + +func registerOAuthRoutes(apiV1Router *gin.RouterGroup) { + apiV1Router.GET("/oauth/sources", oauth.GetLoginSources) + apiV1Router.GET("/oauth/login", oauth.GetLoginURL) + apiV1Router.GET("/oauth/:source/authorize", oauth.Authorize) + apiV1Router.GET("/oauth/logout", oauth.Logout) + apiV1Router.POST("/oauth/callback", oauth.Callback) + apiV1Router.GET("/oauth/user-info", oauth.LoginRequired(), oauth.UserInfo) + apiV1Router.GET("/user-info", oauth.LoginRequired(), oauth.UserInfo) + apiV1Router.GET("/oauth/external-accounts", oauth.LoginRequired(), oauth.ListExternalAccounts) + apiV1Router.POST("/oauth/external-accounts/:id/delete", oauth.LoginRequired(), oauth.DeleteExternalAccount) +} + +func registerUserRoutes(apiV1Router *gin.RouterGroup) { + userRouter := apiV1Router.Group("/user") + { + userRouter.POST("/login", capApp.VerifyMiddleware(capUtil.GetDefaultManager(), "login", func() bool { + enabled, err := model.GetBoolByKey(context.Background(), model.ConfigKeyCapLoginEnabled) + if err != nil { + return false + } + return enabled + }), user.Login) + userRouter.POST("/register", capApp.VerifyMiddleware(capUtil.GetDefaultManager(), "register", func() bool { + enabled, err := model.GetBoolByKey(context.Background(), model.ConfigKeyCapLoginEnabled) + if err != nil { + return false + } + return enabled + }), user.Register) + userRouter.POST("/send-email-code", capApp.VerifyMiddleware(capUtil.GetDefaultManager(), "send_email_code", func() bool { + enabled, err := model.GetBoolByKey(context.Background(), model.ConfigKeyCapLoginEnabled) + if err != nil { + return false + } + return enabled + }), user.SendEmailCode) + userRouter.GET("/logout", user.Logout) + userRouter.GET("/self", oauth.LoginRequired(), oauth.UserInfo) + userRouter.POST("/change-password", oauth.LoginRequired(), user.ChangePassword) + userRouter.PUT("/profile", oauth.LoginRequired(), user.UpdateProfile) + + // Access Token + tokenRouter := userRouter.Group("/access-tokens") + tokenRouter.Use(oauth.LoginRequired(), oauth.DisallowTokenAuth()) + { + tokenRouter.GET("", user.ListAccessTokens) + tokenRouter.POST("", user.CreateAccessToken) + tokenRouter.DELETE("/:id", user.DeleteAccessToken) + tokenRouter.POST("/:id/rotate", user.RotateAccessToken) + } + } +} + func registerUploadRoutes(apiV1Router *gin.RouterGroup) { uploadRouter := apiV1Router.Group("/upload") uploadRouter.Use(oauth.LoginRequired()) @@ -327,6 +252,106 @@ func registerUploadRoutes(apiV1Router *gin.RouterGroup) { } } +func registerConfigRoutes(apiV1Router *gin.RouterGroup) { + configRouter := apiV1Router.Group("/config") + { + configRouter.GET("/public", publicconfig.GetPublicConfig) + } +} + +func registerAdminRoutes(apiV1Router *gin.RouterGroup) { + adminRouter := apiV1Router.Group("/admin") + adminRouter.Use(oauth.LoginRequired(), admin.LoginAdminRequired()) + { + // System status + adminRouter.GET("/status", admin_status.GetSystemStatus) + + // Database info & export + adminRouter.GET("/db-info", admin_status.GetDatabaseInfo) + adminRouter.GET("/db-export", admin_status.ExportDatabase) + + // Database management + adminRouter.GET("/db-manage/overview", admin_db_manage.GetDBOverview) + adminRouter.GET("/db-manage/tables", admin_db_manage.ListDBTables) + adminRouter.GET("/db-manage/table-data", admin_db_manage.GetDBTableData) + adminRouter.POST("/db-manage/query", admin_db_manage.ExecuteSQL) + + // Cache management + adminRouter.GET("/cache/status", admin_cache.GetCacheStatus) + adminRouter.POST("/cache/config", admin_cache.UpdateCacheConfig) + adminRouter.POST("/cache/clear", admin_cache.ClearCache) + + // Application update + adminRouter.GET("/update", admin_updater.GetUpdateStatus) + adminRouter.POST("/update/apply", admin_updater.ApplyUpdate) + + // System logs + adminRouter.GET("/logs", admin_logs.GetLogs) + adminRouter.GET("/logs/access", admin_logs.GetAccessLogs) + adminRouter.GET("/logs/analytics", admin_logs.GetLogsAnalytics) + adminRouter.GET("/logs/ws", admin_logs.HandleLogWebSocket) + + // Task dispatch + registerAdminTaskRoutes(adminRouter) + + // Users + adminRouter.GET("/users", admin_user.ListUsers) + adminRouter.POST("/users", admin_user.CreateUser) + adminRouter.GET("/users/:id", admin_user.GetUser) + adminRouter.PUT("/users/:id/status", admin_user.UpdateUserStatus) + adminRouter.DELETE("/users/:id", admin_user.DeleteUser) + + // Uploads + registerAdminUploadRoutes(adminRouter) + + // System Config + adminRouter.POST("/system-configs", system_config.CreateSystemConfig) + adminRouter.GET("/system-configs", system_config.ListSystemConfigs) + adminRouter.POST("/system-configs/smtp/test", system_config.TestSMTP) + + systemConfigRouter := adminRouter.Group("/system-configs/:key") + { + systemConfigRouter.GET("", system_config.GetSystemConfig) + systemConfigRouter.PUT("", system_config.UpdateSystemConfig) + } + + // Templates + adminRouter.GET("/templates", admin_template.ListTemplates) + adminRouter.POST("/templates", admin_template.CreateTemplate) + + templateRouter := adminRouter.Group("/templates/:key") + { + templateRouter.GET("", admin_template.GetTemplate) + templateRouter.PUT("", admin_template.UpdateTemplate) + templateRouter.DELETE("", admin_template.DeleteTemplate) + } + + // Auth Sources + adminRouter.GET("/auth-sources", admin_auth_source.ListAuthSources) + adminRouter.POST("/auth-sources", admin_auth_source.CreateAuthSource) + adminRouter.PUT("/auth-sources/:id", admin_auth_source.UpdateAuthSource) + adminRouter.PUT("/auth-sources/:id/toggle", admin_auth_source.ToggleAuthSource) + adminRouter.DELETE("/auth-sources/:id", admin_auth_source.DeleteAuthSource) + } +} + +func registerAdminTaskRoutes(adminRouter *gin.RouterGroup) { + // Task dispatch + adminRouter.GET("/tasks/types", admin_task.ListTaskTypes) + adminRouter.POST("/tasks/dispatch", admin_task.DispatchTask) + + // Task executions + adminRouter.GET("/tasks/executions", admin_task.ListTaskExecutions) + adminRouter.GET("/tasks/executions/:id", admin_task.GetTaskExecution) + adminRouter.POST("/tasks/executions/:id/retry", admin_task.RetryTask) + + // Task schedules + adminRouter.GET("/tasks/schedules", admin_task.ListSchedules) + adminRouter.POST("/tasks/schedules", admin_task.CreateSchedule) + adminRouter.PUT("/tasks/schedules/:id", admin_task.UpdateSchedule) + adminRouter.DELETE("/tasks/schedules/:id", admin_task.DeleteSchedule) +} + func registerAdminUploadRoutes(adminRouter *gin.RouterGroup) { adminUploadsRouter := adminRouter.Group("/uploads") {