answer/internal/router/ui.go

96 lines
2.3 KiB
Go
Raw Normal View History

2022-09-29 12:37:02 +08:00
package router
import (
"embed"
"fmt"
"io/fs"
"net/http"
"os"
2022-09-30 16:14:00 +08:00
"github.com/answerdev/answer/ui"
2022-09-30 16:14:00 +08:00
"github.com/gin-gonic/gin"
"github.com/segmentfault/pacman/log"
2022-09-29 12:37:02 +08:00
)
const UIIndexFilePath = "build/index.html"
2022-09-30 16:14:00 +08:00
const UIRootFilePath = "build"
2022-09-29 12:37:02 +08:00
const UIStaticPath = "build/static"
// UIRouter is an interface that provides ui static file routers
type UIRouter struct {
}
// NewUIRouter creates a new UIRouter instance with the embed resources
func NewUIRouter() *UIRouter {
return &UIRouter{}
}
// _resource is an interface that provides static file, it's a private interface
type _resource struct {
fs embed.FS
}
// Open to implement the interface by http.FS required
func (r *_resource) Open(name string) (fs.File, error) {
name = fmt.Sprintf(UIStaticPath+"/%s", name)
log.Debugf("open static path %s", name)
return r.fs.Open(name)
}
// Register a new static resource which generated by ui directory
func (a *UIRouter) Register(r *gin.Engine) {
staticPath := os.Getenv("ANSWER_STATIC_PATH")
// if ANSWER_STATIC_PATH is set and not empty, ignore embed resource
if staticPath != "" {
2022-09-29 14:21:49 +08:00
info, err := os.Stat(staticPath)
2022-09-29 12:37:02 +08:00
if err != nil || !info.IsDir() {
log.Error(err)
} else {
log.Debugf("registering static path %s", staticPath)
r.LoadHTMLGlob(staticPath + "/*.html")
r.Static("/static", staticPath+"/static")
r.NoRoute(func(c *gin.Context) {
c.HTML(http.StatusOK, "index.html", gin.H{})
})
// return immediately if the static path is set
return
}
}
// handle the static file by default ui static files
r.StaticFS("/static", http.FS(&_resource{
fs: ui.Build,
}))
// specify the not router for default routes and redirect
r.NoRoute(func(c *gin.Context) {
2022-11-14 11:50:00 +08:00
urlPath := c.Request.URL.Path
2022-09-30 16:14:00 +08:00
filePath := ""
2022-11-14 11:50:00 +08:00
switch urlPath {
2022-09-30 16:14:00 +08:00
case "/favicon.ico":
c.Header("content-type", "image/vnd.microsoft.icon")
2022-11-14 11:50:00 +08:00
filePath = UIRootFilePath + urlPath
2022-10-19 14:35:21 +08:00
case "/manifest.json":
2022-11-14 11:50:00 +08:00
filePath = UIRootFilePath + urlPath
case "/install":
2022-11-14 11:50:00 +08:00
// if answer is running by run command user can not access install page.
c.Redirect(http.StatusFound, "/")
return
2022-09-30 16:14:00 +08:00
default:
filePath = UIIndexFilePath
c.Header("content-type", "text/html;charset=utf-8")
}
2022-11-14 11:50:00 +08:00
file, err := ui.Build.ReadFile(filePath)
2022-09-29 12:37:02 +08:00
if err != nil {
log.Error(err)
c.Status(http.StatusNotFound)
return
}
2022-09-30 16:14:00 +08:00
c.String(http.StatusOK, string(file))
2022-09-29 12:37:02 +08:00
})
}