Use the gin framework

This commit is contained in:
2025-10-26 14:48:02 +08:00
parent 9e0eb1497b
commit d844403505
29 changed files with 1612 additions and 1858 deletions

View File

@@ -1,9 +1,10 @@
package server
import (
"net/http"
adminctl "networkDev/controllers/admin"
"networkDev/utils"
"github.com/gin-gonic/gin"
)
// RegisterAdminRoutes 注册管理员后台相关路由
@@ -12,91 +13,98 @@ import (
// - /admin/dashboard: 管理员仪表盘(示例)
// - /admin/fragment/*: 布局内动态片段加载
// - /admin/api/settings*: 设置接口(查询/更新)
func RegisterAdminRoutes(mux *http.ServeMux) {
func RegisterAdminRoutes(router *gin.Engine) {
// /admin 根与前缀统一入口:根据是否登录跳转
mux.HandleFunc("/admin", adminctl.AdminIndexHandler)
mux.HandleFunc("/admin/", adminctl.AdminIndexHandler)
router.GET("/admin", adminctl.AdminIndexHandler)
router.GET("/admin/", adminctl.AdminIndexHandler)
// Admin 认证相关路由
mux.HandleFunc("/admin/login", func(w http.ResponseWriter, r *http.Request) {
if r.Method == http.MethodGet {
adminctl.LoginPageHandler(w, r)
return
}
if r.Method == http.MethodPost {
// 应用CSRF保护
utils.RequireCSRFToken(adminctl.LoginHandler)(w, r)
return
}
w.WriteHeader(http.StatusMethodNotAllowed)
})
router.GET("/admin/login", adminctl.LoginPageHandler)
router.POST("/admin/login", adminctl.LoginHandler) // CSRF验证在控制器内部处理
// 退出登录(无需拦截,幂等清理)
mux.HandleFunc("/admin/logout", adminctl.LogoutHandler)
router.POST("/admin/logout", adminctl.LogoutHandler)
// 验证码生成路由(无需认证)
mux.HandleFunc("/admin/captcha", adminctl.CaptchaHandler)
router.GET("/admin/captcha", adminctl.CaptchaHandler)
// CSRF令牌获取API无需认证但需要在登录页面等地方获取
mux.HandleFunc("/admin/api/csrf-token", utils.CSRFTokenHandler)
router.GET("/admin/api/csrf-token", func(c *gin.Context) {
// 生成新的CSRF令牌
token, err := utils.GenerateCSRFToken()
if err != nil {
c.JSON(500, gin.H{"success": false, "message": "生成CSRF令牌失败"})
return
}
// 设置令牌到Cookie和响应头
utils.SetCSRFToken(c, token)
// 返回令牌给前端
c.JSON(200, gin.H{
"success": true,
"message": "CSRF令牌生成成功",
"csrf_token": token,
})
})
// 后台布局页(需要管理员认证)
mux.HandleFunc("/admin/layout", adminctl.AdminAuthRequired(adminctl.AdminLayoutHandler))
router.GET("/admin/layout", adminctl.AdminAuthRequired(), adminctl.AdminLayoutHandler)
// 片段路由(需要管理员认证)
mux.HandleFunc("/admin/dashboard", adminctl.AdminAuthRequired(adminctl.DashboardFragmentHandler))
mux.HandleFunc("/admin/user", adminctl.AdminAuthRequired(adminctl.UserFragmentHandler))
mux.HandleFunc("/admin/settings", adminctl.AdminAuthRequired(adminctl.SettingsFragmentHandler))
mux.HandleFunc("/admin/apps", adminctl.AdminAuthRequired(adminctl.AppsFragmentHandler))
mux.HandleFunc("/admin/apis", adminctl.AdminAuthRequired(adminctl.APIFragmentHandler))
mux.HandleFunc("/admin/variables", adminctl.AdminAuthRequired(adminctl.VariableFragmentHandler))
router.GET("/admin/dashboard", adminctl.AdminAuthRequired(), adminctl.DashboardFragmentHandler)
router.GET("/admin/user", adminctl.AdminAuthRequired(), adminctl.UserFragmentHandler)
router.GET("/admin/settings", adminctl.AdminAuthRequired(), adminctl.SettingsFragmentHandler)
router.GET("/admin/apps", adminctl.AdminAuthRequired(), adminctl.AppsFragmentHandler)
router.GET("/admin/apis", adminctl.AdminAuthRequired(), adminctl.APIFragmentHandler)
router.GET("/admin/variables", adminctl.AdminAuthRequired(), adminctl.VariableFragmentHandler)
// 系统信息API用于仪表盘定时刷新
mux.HandleFunc("/admin/api/system/info", adminctl.AdminAuthRequired(adminctl.SystemInfoHandler))
router.GET("/admin/api/system/info", adminctl.AdminAuthRequired(), adminctl.SystemInfoHandler)
// 仪表盘统计数据API
mux.HandleFunc("/admin/api/dashboard/stats", adminctl.AdminAuthRequired(adminctl.DashboardStatsHandler))
router.GET("/admin/api/dashboard/stats", adminctl.AdminAuthRequired(), adminctl.DashboardStatsHandler)
// 个人资料API
mux.HandleFunc("/admin/api/user/profile", adminctl.AdminAuthRequired(adminctl.UserProfileQueryHandler))
mux.HandleFunc("/admin/api/user/profile/update", adminctl.AdminAuthRequired(utils.RequireCSRFToken(adminctl.UserProfileUpdateHandler)))
mux.HandleFunc("/admin/api/user/password", adminctl.AdminAuthRequired(utils.RequireCSRFToken(adminctl.UserPasswordUpdateHandler)))
router.GET("/admin/api/user/profile", adminctl.AdminAuthRequired(), adminctl.UserProfileQueryHandler)
router.POST("/admin/api/user/profile/update", adminctl.AdminAuthRequired(), adminctl.UserProfileUpdateHandler)
router.POST("/admin/api/user/password", adminctl.AdminAuthRequired(), adminctl.UserPasswordUpdateHandler)
// 系统设置API
mux.HandleFunc("/admin/api/settings", adminctl.AdminAuthRequired(adminctl.SettingsQueryHandler))
mux.HandleFunc("/admin/api/settings/update", adminctl.AdminAuthRequired(utils.RequireCSRFToken(adminctl.SettingsUpdateHandler)))
router.GET("/admin/api/settings", adminctl.AdminAuthRequired(), adminctl.SettingsQueryHandler)
router.POST("/admin/api/settings/update", adminctl.AdminAuthRequired(), adminctl.SettingsUpdateHandler)
// 应用管理API
mux.HandleFunc("/admin/api/apps/list", adminctl.AdminAuthRequired(adminctl.AppsListHandler))
mux.HandleFunc("/admin/api/apps/create", adminctl.AdminAuthRequired(utils.RequireCSRFToken(adminctl.AppCreateHandler)))
mux.HandleFunc("/admin/api/apps/update", adminctl.AdminAuthRequired(utils.RequireCSRFToken(adminctl.AppUpdateHandler)))
mux.HandleFunc("/admin/api/apps/delete", adminctl.AdminAuthRequired(utils.RequireCSRFToken(adminctl.AppDeleteHandler)))
mux.HandleFunc("/admin/api/apps/batch_delete", adminctl.AdminAuthRequired(utils.RequireCSRFToken(adminctl.AppsBatchDeleteHandler)))
mux.HandleFunc("/admin/api/apps/batch_update_status", adminctl.AdminAuthRequired(utils.RequireCSRFToken(adminctl.AppsBatchUpdateStatusHandler)))
mux.HandleFunc("/admin/api/apps/reset_secret", adminctl.AdminAuthRequired(utils.RequireCSRFToken(adminctl.AppResetSecretHandler)))
mux.HandleFunc("/admin/api/apps/get_app_data", adminctl.AdminAuthRequired(adminctl.AppGetAppDataHandler))
mux.HandleFunc("/admin/api/apps/update_app_data", adminctl.AdminAuthRequired(utils.RequireCSRFToken(adminctl.AppUpdateAppDataHandler)))
mux.HandleFunc("/admin/api/apps/get_announcement", adminctl.AdminAuthRequired(adminctl.AppGetAnnouncementHandler))
mux.HandleFunc("/admin/api/apps/update_announcement", adminctl.AdminAuthRequired(utils.RequireCSRFToken(adminctl.AppUpdateAnnouncementHandler)))
mux.HandleFunc("/admin/api/apps/get_multi_config", adminctl.AdminAuthRequired(adminctl.AppGetMultiConfigHandler))
mux.HandleFunc("/admin/api/apps/update_multi_config", adminctl.AdminAuthRequired(utils.RequireCSRFToken(adminctl.AppUpdateMultiConfigHandler)))
mux.HandleFunc("/admin/api/apps/get_bind_config", adminctl.AdminAuthRequired(adminctl.AppGetBindConfigHandler))
mux.HandleFunc("/admin/api/apps/update_bind_config", adminctl.AdminAuthRequired(utils.RequireCSRFToken(adminctl.AppUpdateBindConfigHandler)))
mux.HandleFunc("/admin/api/apps/get_register_config", adminctl.AdminAuthRequired(adminctl.AppGetRegisterConfigHandler))
mux.HandleFunc("/admin/api/apps/update_register_config", adminctl.AdminAuthRequired(utils.RequireCSRFToken(adminctl.AppUpdateRegisterConfigHandler)))
router.GET("/admin/api/apps/list", adminctl.AdminAuthRequired(), adminctl.AppsListHandler)
router.POST("/admin/api/apps/create", adminctl.AdminAuthRequired(), adminctl.AppCreateHandler)
router.POST("/admin/api/apps/update", adminctl.AdminAuthRequired(), adminctl.AppUpdateHandler)
router.POST("/admin/api/apps/delete", adminctl.AdminAuthRequired(), adminctl.AppDeleteHandler)
router.POST("/admin/api/apps/batch_delete", adminctl.AdminAuthRequired(), adminctl.AppsBatchDeleteHandler)
router.POST("/admin/api/apps/batch_update_status", adminctl.AdminAuthRequired(), adminctl.AppsBatchUpdateStatusHandler)
router.POST("/admin/api/apps/reset_secret", adminctl.AdminAuthRequired(), adminctl.AppResetSecretHandler)
router.GET("/admin/api/apps/get_app_data", adminctl.AdminAuthRequired(), adminctl.AppGetAppDataHandler)
router.POST("/admin/api/apps/update_app_data", adminctl.AdminAuthRequired(), adminctl.AppUpdateAppDataHandler)
router.GET("/admin/api/apps/get_announcement", adminctl.AdminAuthRequired(), adminctl.AppGetAnnouncementHandler)
router.POST("/admin/api/apps/update_announcement", adminctl.AdminAuthRequired(), adminctl.AppUpdateAnnouncementHandler)
router.GET("/admin/api/apps/get_multi_config", adminctl.AdminAuthRequired(), adminctl.AppGetMultiConfigHandler)
router.POST("/admin/api/apps/update_multi_config", adminctl.AdminAuthRequired(), adminctl.AppUpdateMultiConfigHandler)
router.GET("/admin/api/apps/get_bind_config", adminctl.AdminAuthRequired(), adminctl.AppGetBindConfigHandler)
router.POST("/admin/api/apps/update_bind_config", adminctl.AdminAuthRequired(), adminctl.AppUpdateBindConfigHandler)
router.GET("/admin/api/apps/get_register_config", adminctl.AdminAuthRequired(), adminctl.AppGetRegisterConfigHandler)
router.POST("/admin/api/apps/update_register_config", adminctl.AdminAuthRequired(), adminctl.AppUpdateRegisterConfigHandler)
// API接口管理API
mux.HandleFunc("/admin/api/apis/list", adminctl.AdminAuthRequired(adminctl.APIListHandler))
mux.HandleFunc("/admin/api/apis/update", adminctl.AdminAuthRequired(utils.RequireCSRFToken(adminctl.APIUpdateHandler)))
mux.HandleFunc("/admin/api/apis/apps", adminctl.AdminAuthRequired(adminctl.APIGetAppsHandler))
mux.HandleFunc("/admin/api/apis/types", adminctl.AdminAuthRequired(adminctl.APIGetTypesHandler))
mux.HandleFunc("/admin/api/apis/generate_keys", adminctl.AdminAuthRequired(utils.RequireCSRFToken(adminctl.APIGenerateKeysHandler)))
router.GET("/admin/api/apis/list", adminctl.AdminAuthRequired(), adminctl.APIListHandler)
router.POST("/admin/api/apis/update", adminctl.AdminAuthRequired(), adminctl.APIUpdateHandler)
router.GET("/admin/api/apis/apps", adminctl.AdminAuthRequired(), adminctl.APIGetAppsHandler)
router.GET("/admin/api/apis/types", adminctl.AdminAuthRequired(), adminctl.APIGetTypesHandler)
router.POST("/admin/api/apis/generate_keys", adminctl.AdminAuthRequired(), adminctl.APIGenerateKeysHandler)
// 变量管理API
mux.HandleFunc("/admin/variable/list", adminctl.AdminAuthRequired(adminctl.VariableListHandler))
mux.HandleFunc("/admin/variable/apps", adminctl.AdminAuthRequired(adminctl.VariableGetAppsHandler))
mux.HandleFunc("/admin/variable/create", adminctl.AdminAuthRequired(utils.RequireCSRFToken(adminctl.VariableCreateHandler)))
mux.HandleFunc("/admin/variable/update", adminctl.AdminAuthRequired(utils.RequireCSRFToken(adminctl.VariableUpdateHandler)))
mux.HandleFunc("/admin/variable/delete", adminctl.AdminAuthRequired(utils.RequireCSRFToken(adminctl.VariableDeleteHandler)))
mux.HandleFunc("/admin/variable/batch_delete", adminctl.AdminAuthRequired(utils.RequireCSRFToken(adminctl.VariablesBatchDeleteHandler)))
router.GET("/admin/variable/list", adminctl.AdminAuthRequired(), adminctl.VariableListHandler)
router.GET("/admin/variable/apps", adminctl.AdminAuthRequired(), adminctl.VariableGetAppsHandler)
router.POST("/admin/variable/create", adminctl.AdminAuthRequired(), adminctl.VariableCreateHandler)
router.POST("/admin/variable/update", adminctl.AdminAuthRequired(), adminctl.VariableUpdateHandler)
router.POST("/admin/variable/delete", adminctl.AdminAuthRequired(), adminctl.VariableDeleteHandler)
router.POST("/admin/variable/batch_delete", adminctl.AdminAuthRequired(), adminctl.VariablesBatchDeleteHandler)
}

View File

@@ -1,13 +1,14 @@
package server
import (
"net/http"
"networkDev/controllers/home"
"github.com/gin-gonic/gin"
)
// RegisterHomeRoutes 注册主页路由
// 只包含根路径,用于主页功能
func RegisterHomeRoutes(mux *http.ServeMux) {
func RegisterHomeRoutes(router *gin.Engine) {
// 根路径 - 主页
mux.HandleFunc("/", home.RootHandler)
router.GET("/", home.RootHandler)
}

View File

@@ -5,30 +5,32 @@ import (
"log"
"net/http"
"networkDev/web"
"github.com/gin-gonic/gin"
)
// RegisterRoutes 聚合注册所有路由
func RegisterRoutes(mux *http.ServeMux) {
registerStaticRoutes(mux)
registerFaviconRoute(mux)
RegisterHomeRoutes(mux)
RegisterAdminRoutes(mux)
func RegisterRoutes(router *gin.Engine) {
registerStaticRoutes(router)
registerFaviconRoute(router)
RegisterHomeRoutes(router)
RegisterAdminRoutes(router)
}
// registerStaticRoutes 注册静态资源路由
// 静态资源服务,将 /static/ 和 /assets/ 映射到嵌入的文件系统
func registerStaticRoutes(mux *http.ServeMux) {
func registerStaticRoutes(router *gin.Engine) {
if fsys, err := web.GetStaticFS(); err == nil {
// 为 /static/ 路径创建子文件系统
if staticSubFS, staticErr := fs.Sub(fsys, "static"); staticErr == nil {
mux.Handle("/static/", http.StripPrefix("/static/", http.FileServer(http.FS(staticSubFS))))
router.StaticFS("/static", http.FS(staticSubFS))
} else {
log.Printf("创建静态资源子文件系统失败: %v", staticErr)
}
// 为 /assets/ 路径创建子文件系统
if assetsSubFS, assetsErr := fs.Sub(fsys, "assets"); assetsErr == nil {
mux.Handle("/assets/", http.StripPrefix("/assets/", http.FileServer(http.FS(assetsSubFS))))
router.StaticFS("/assets", http.FS(assetsSubFS))
} else {
log.Printf("创建资产资源子文件系统失败: %v", assetsErr)
}
@@ -38,9 +40,9 @@ func registerStaticRoutes(mux *http.ServeMux) {
}
// registerFaviconRoute 注册favicon路由
func registerFaviconRoute(mux *http.ServeMux) {
func registerFaviconRoute(router *gin.Engine) {
// 将 /favicon.ico 重定向到 /assets/favicon.svg
mux.HandleFunc("/favicon.ico", func(w http.ResponseWriter, r *http.Request) {
http.Redirect(w, r, "/assets/favicon.svg", http.StatusMovedPermanently)
router.GET("/favicon.ico", func(c *gin.Context) {
c.Redirect(http.StatusMovedPermanently, "/assets/favicon.svg")
})
}