package router import ( "ckwk/internal/conf" "ckwk/internal/handler" "ckwk/internal/middleware" "ckwk/pkg/log" "ckwk/web" "io/fs" "net/http" "strings" "time" "github.com/gin-contrib/cors" "github.com/gin-gonic/gin" "go.uber.org/zap" ) var ( AllowOrigins []string AllowMethods []string AllowHeaders []string ) func init() { if conf.IsBuildDebugMode() { AllowOrigins = []string{"*"} AllowMethods = []string{"*"} AllowHeaders = []string{"*"} gin.SetMode(gin.DebugMode) } else { AllowOrigins = []string{"*.kmux.cn"} AllowMethods = []string{"GET", "POST", "PUT", "DELETE", "PATCH"} AllowHeaders = []string{"X-Session-Id"} gin.SetMode(gin.ReleaseMode) } } func SetupRouter() *gin.Engine { r := gin.Default() r.Use(cors.New(cors.Config{ AllowOrigins: AllowOrigins, AllowMethods: AllowMethods, AllowHeaders: AllowHeaders, ExposeHeaders: []string{"Content-Length"}, AllowCredentials: true, MaxAge: 12 * time.Hour, })) r.Use(middleware.DebugHTTPLog()) wkHandler := handler.NewWKHandler() sessionMiddleware := middleware.SessionMiddleware(wkHandler.Session) // schedule.StartCron(wkHandler.Session) dist, err := fs.Sub(web.Public, web.DistDir) if err != nil { log.Fatal("failed to read dist dir", zap.Error(err)) } distHTTP := http.FS(dist) r.StaticFS("/js", http.FS(mustSub(dist, "js"))) r.StaticFS("/assets", http.FS(mustSub(dist, "assets"))) r.StaticFileFS("/favicon.png", "favicon.png", distHTTP) api := r.Group("/api") { api.POST("/login", wkHandler.Login) api.Any("/version", handler.Version) debug := api.Group("/debug") { debug.GET("/config", handler.DebugConfig) debug.POST("/config", handler.UpdateDebugConfig) debug.GET("/logs", handler.DebugLogs) debug.GET("/logs/download", handler.DebugLogsDownload) debug.GET("/logs/ws", handler.DebugLogWS) debug.GET("/ws/logs", handler.DebugLogWS) } v1 := api.Group("/v1") { v1.GET("/host", wkHandler.Host) } v2 := api.Group("/v2", sessionMiddleware) { v2.POST("/logout", wkHandler.Logout) v2.POST("/userinfo", wkHandler.UserInfo) v2.POST("/course", wkHandler.Course) v2.POST("/study", wkHandler.Study) v2.POST("/record", wkHandler.AllRecord) } } r.NoRoute(func(ctx *gin.Context) { if strings.HasPrefix(ctx.Request.URL.Path, "/api") { ctx.JSON(404, gin.H{"code": 404, "msg": "API not found"}) return } ctx.Header("Content-Type", "text/html; charset=utf-8") http.ServeFileFS(ctx.Writer, ctx.Request, dist, "index.html") }) return r } // 辅助函数:简化 fs.Sub 的错误处理 func mustSub(f fs.FS, dir string) fs.FS { sub, err := fs.Sub(f, dir) if err != nil { panic("failed to find static dir: " + dir) } return sub }