123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182 |
- package resources
- import (
- "embed"
- "errors"
- "fmt"
- "github.com/gin-gonic/gin"
- "io/fs"
- "net/http"
- "os"
- "path"
- "path/filepath"
- "strings"
- )
- //go:embed assets/index.html
- var index []byte
- //go:embed assets/assets
- var Static embed.FS
- //go:embed images
- var Images embed.FS
- //go:embed assets/favicon.ico
- var ICO embed.FS
- //go:embed template/defaultAvatar.jpg
- var DefaultAvatar embed.FS
- //go:embed app/index.html
- var app []byte
- //go:embed app
- var APP embed.FS
- const (
- apiBase = "/api/v1"
- adminApi = "/admin-api/"
- assetsProxy = "assets"
- )
- func HtmlRouteHandler() gin.HandlerFunc {
- return func(context *gin.Context) {
- var uri = context.Request.URL.Path
- var ext = path.Ext(uri)
- if find := strings.Contains(uri, apiBase); find {
- return
- } else if find = ext == ".txt"; find {
- //打开文件
- file, err := os.Open("." + uri)
- defer file.Close()
- if err != nil {
- fmt.Println("打开文件错误", err)
- }
- context.File("." + uri)
- context.Abort()
- return
- }
- accept := context.Request.Header.Get("Accept")
- if strings.Contains(accept, "text/html") {
- writeIndex(context)
- }
- }
- }
- func writeIndex(context *gin.Context) {
- agent := context.Request.Header.Get("User-Agent")
- if strings.Contains(strings.ToLower(agent), "mobile") {
- context.Redirect(http.StatusFound, "/app")
- return
- }
- context.Writer.WriteHeader(200)
- context.Writer.Header().Add("Accept", "text/html")
- _, _ = context.Writer.Write(index)
- context.Writer.Flush()
- context.Abort()
- }
- type Resource struct {
- fs embed.FS
- path string
- }
- func NewResource() *Resource {
- return &Resource{
- fs: Static,
- path: "assets",
- }
- }
- func NewAppResource() *Resource {
- return &Resource{
- fs: APP,
- path: "app/",
- }
- }
- func NewImagesResource() *Resource {
- return &Resource{
- fs: Images,
- path: "images/",
- }
- }
- func (r *Resource) Open(name string) (fs.File, error) {
- if filepath.Separator != '/' && strings.ContainsRune(name, filepath.Separator) {
- return nil, errors.New("http: invalid character in file path")
- }
- fullName := r.getFullName(name)
- file, err := r.fs.Open(fullName)
- return file, err
- }
- func (r *Resource) getFullName(name string) string {
- if r.path == "assets" {
- return r.path + "/assets/" + name
- }
- return r.path + name
- }
- func InitResource(engine *gin.Engine) {
- resourceRouter(engine)
- engine.StaticFS("/assets", http.FS(NewResource()))
- engine.StaticFS("/app", http.FS(NewAppResource()))
- engine.StaticFS("/images", http.FS(NewImagesResource()))
- }
- type HtmlHandler struct{}
- func NewHtmlHandler() *HtmlHandler {
- return &HtmlHandler{}
- }
- // RedirectIndex 404 重定向
- func (h *HtmlHandler) RedirectIndex(context *gin.Context) {
- var uri = context.Request.URL.Path
- if strings.Contains(uri, adminApi) {
- context.Abort()
- return
- }
- accept := context.Request.Header.Get("Accept")
- if strings.Contains(accept, "text/html") {
- writeIndex(context)
- }
- }
- func (h *HtmlHandler) Index(context *gin.Context) {
- writeIndex(context)
- }
- func (h *HtmlHandler) App(context *gin.Context) {
- context.Writer.WriteHeader(200)
- context.Writer.Header().Add("Accept", "text/html")
- _, _ = context.Writer.Write(app)
- context.Writer.Flush()
- context.Abort()
- }
- // resourceRouter 静态资源配置
- func resourceRouter(engine *gin.Engine) {
- html := NewHtmlHandler()
- group := engine.Group("/")
- {
- group.GET("", html.Index)
- group.GET("/app", html.App)
- group.GET("/defaultAvatar", func(context *gin.Context) {
- context.Request.URL.Path = "template/defaultAvatar.jpg"
- staticServer := http.FileServer(http.FS(DefaultAvatar))
- staticServer.ServeHTTP(context.Writer, context.Request)
- context.Abort()
- })
- group.GET("favicon.ico", func(context *gin.Context) {
- context.Request.URL.Path = assetsProxy + context.Request.URL.Path
- staticServer := http.FileServer(http.FS(ICO))
- staticServer.ServeHTTP(context.Writer, context.Request)
- context.Abort()
- })
- }
- // 解决刷新 404 问题
- engine.NoRoute(html.RedirectIndex)
- }
|