74 lines
1.8 KiB
Go
74 lines
1.8 KiB
Go
package embed_static
|
||
|
||
import (
|
||
"embed"
|
||
"html/template"
|
||
"io/fs"
|
||
"net/http"
|
||
"strings"
|
||
|
||
"github.com/gin-gonic/gin"
|
||
)
|
||
|
||
//go:embed static/*
|
||
var staticFS embed.FS
|
||
|
||
//go:embed templates/*
|
||
var templatesFS embed.FS
|
||
|
||
// SetupEmbed 配置内嵌资源:SPA 前端 + 后台 HTML 模板
|
||
func SetupEmbed(r *gin.Engine) error {
|
||
tmpl, err := LoadTemplates()
|
||
if err != nil {
|
||
return err
|
||
}
|
||
r.SetHTMLTemplate(tmpl)
|
||
|
||
// React SPA 构建产物(Vite)
|
||
if sub, err := fs.Sub(staticFS, "static/spa/assets"); err == nil {
|
||
r.GET("/assets/*filepath", gin.WrapH(http.StripPrefix("/assets", http.FileServer(http.FS(sub)))))
|
||
}
|
||
|
||
// 后台管理遗留静态资源
|
||
if sub, err := fs.Sub(staticFS, "static/legacy"); err == nil {
|
||
r.GET("/legacy/*filepath", gin.WrapH(http.StripPrefix("/legacy", http.FileServer(http.FS(sub)))))
|
||
}
|
||
|
||
return nil
|
||
}
|
||
|
||
// ServeSPA 返回 React SPA 入口
|
||
func ServeSPA(c *gin.Context) {
|
||
data, err := staticFS.ReadFile("static/spa/index.html")
|
||
if err != nil {
|
||
c.String(http.StatusNotFound, "前端未构建,请运行: cd frontend && npm run build")
|
||
return
|
||
}
|
||
c.Data(http.StatusOK, "text/html; charset=utf-8", data)
|
||
}
|
||
|
||
// IsSPARoute 判断是否应由 SPA 处理
|
||
func IsSPARoute(path string) bool {
|
||
if strings.HasPrefix(path, "/api") ||
|
||
strings.HasPrefix(path, "/admin") ||
|
||
strings.HasPrefix(path, "/uploads") ||
|
||
strings.HasPrefix(path, "/legacy") ||
|
||
strings.HasPrefix(path, "/assets") {
|
||
return false
|
||
}
|
||
return true
|
||
}
|
||
|
||
func LoadTemplates() (*template.Template, error) {
|
||
sub, err := fs.Sub(templatesFS, "templates")
|
||
if err != nil {
|
||
return nil, err
|
||
}
|
||
tmpl := template.New("").Funcs(template.FuncMap{
|
||
"safeHTML": func(s string) template.HTML { return template.HTML(s) },
|
||
"add": func(a, b int) int { return a + b },
|
||
"sub": func(a, b int) int { return a - b },
|
||
})
|
||
return tmpl.ParseFS(sub, "*.html", "admin/*.html")
|
||
}
|