加载前端 SPA 资源

示例代码

package controller import ( "net/http" "strings" "github.com/sohaha/zlsgo/zarray" "github.com/sohaha/zlsgo/zfile" "github.com/sohaha/zlsgo/znet" "github.com/sohaha/zlsgo/zutil" "github.com/sohaha/zstatic" "github.com/sohaha/zstatic/build" "github.com/zlsgo/app_core/service" ) type Dashboard struct { service.App } // Dashboarder dashboard 文件服务器 type Dashboarder struct { cache *zarray.Maper[string, []byte] group *build.FileGroup } // dashboardFileserver 初始化 dashboard 文件服务器 var dashboardFileserver = zutil.Once(func() *Dashboarder { // 前端打包编译出来的文件夹 group, _ := zstatic.Group("../frontend/dist") return &Dashboarder{ cache: zarray.NewHashMap[string, []byte](), group: group, } }) // ReadDashboardFile 读取 dashboard 文件 // 另外还需要把 404 处理交给 dashboard 文件服务器 func ReadDashboardFile(c *znet.Context, prefix string) (err error) { name := c.GetParam("file") nameNil := name == "" if !nameNil { name = strings.TrimPrefix(name, "/") } else if nameNil { name = c.Request.URL.Path } name = zarray.Join([]string{prefix, name}, "/") b, _, _ := dashboardFileserver().cache.ProvideGet(name, func() (b []byte, ok bool) { possiblePaths := []string{ name, name + ".html", name + "/index.html", "404.html", } for _, path := range possiblePaths { if b, err = dashboardFileserver().group.MustBytes(path); err == nil { break } } return b, err == nil }) if err != nil { return err } c.SetContentType(zfile.GetMimeType(name, b)) c.SetHeader("Cache-Control", "max-age=14400") c.Byte(http.StatusOK, b) return nil } // Init 初始化 dashboard 路由 func (h *Dashboard) Init(r *znet.Engine) error { // 处理 dashboard 文件 r.Any("{file:.*}", func(c *znet.Context) error { return ReadDashboardFile(c, "/dashboard") }) return nil }