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" ) func SetupRouter() *gin.Engine { if conf.Mode != gin.ReleaseMode { gin.SetMode(gin.DebugMode) } else { gin.SetMode(gin.ReleaseMode) } r := gin.Default() r.Use(cors.New(cors.Config{ AllowOrigins: []string{"*.kmux.cn*"}, AllowMethods: []string{"GET", "POST", "PUT", "DELETE", "PATCH"}, AllowHeaders: []string{"*", "X-Session-Id"}, ExposeHeaders: []string{"Content-Length"}, AllowCredentials: true, MaxAge: 12 * time.Hour, })) 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) v1 := api.Group("/v1") { v1.GET("/host", wkHandler.Host) } v2 := api.Group("/v2", sessionMiddleware) { v2.POST("/logout", wkHandler.Logout) 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 }