diff --git a/api/server/router/router.go b/api/server/router/router.go
index 20a5c20d..c7540bc4 100644
--- a/api/server/router/router.go
+++ b/api/server/router/router.go
@@ -17,6 +17,7 @@ limitations under the License.
package router
import (
+ "embed"
"net/http"
"github.com/gin-gonic/gin"
@@ -36,10 +37,14 @@ import (
"github.com/caoyingjunz/pixiu/api/server/router/tenant"
"github.com/caoyingjunz/pixiu/api/server/router/user"
"github.com/caoyingjunz/pixiu/cmd/app/options"
+ "github.com/caoyingjunz/pixiu/pkg/static"
)
type RegisterFunc func(o *options.Options)
+//go:embed static
+var EmbedFS embed.FS
+
func InstallRouters(o *options.Options) {
fs := []RegisterFunc{
middleware.InstallMiddlewares,
@@ -54,6 +59,7 @@ func InstallRouters(o *options.Options) {
install(o, fs...)
+ o.HttpEngine.GET("/", static.ServeEmbed("static", EmbedFS))
// 启动健康检查
o.HttpEngine.GET("/healthz", func(c *gin.Context) { c.String(http.StatusOK, "ok") })
// 启动 APIs 服务
diff --git a/api/server/router/static/index.html b/api/server/router/static/index.html
new file mode 100644
index 00000000..d03ebc12
--- /dev/null
+++ b/api/server/router/static/index.html
@@ -0,0 +1,43 @@
+
+
+
+
+
+ 欢迎使用 Pixiu
+
+
+
+
+
欢迎使用 Pixiu
+
+
+
\ No newline at end of file
diff --git a/pkg/static/embedfile.go b/pkg/static/embedfile.go
new file mode 100644
index 00000000..85928ded
--- /dev/null
+++ b/pkg/static/embedfile.go
@@ -0,0 +1,67 @@
+/*
+* Copyright 2024 Pixiu. All rights reserved.
+*
+* Licensed under the Apache License, Version 2.0 (the "License");
+* you may not use this file except in compliance with the License.
+* You may obtain a copy of the License at
+*
+* http:*www.apache.org/licenses/LICENSE-2.0
+*
+* Unless required by applicable law or agreed to in writing, software
+* distributed under the License is distributed on an "AS IS" BASIS,
+* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+* See the License for the specific language governing permissions and
+* limitations under the License.
+ */
+
+package static
+
+import (
+ "embed"
+ "io/fs"
+ "net/http"
+ "strings"
+
+ "github.com/gin-gonic/gin"
+)
+
+type embedFileSystem struct {
+ http.FileSystem
+}
+
+func (e embedFileSystem) Exists(prefix string, path string) bool {
+ _, err := e.Open(path)
+ return err == nil
+}
+
+func EmbedFolder(fsEmbed embed.FS, reqPath string) (ServeFileSystem, error) {
+ targetPath := strings.TrimSpace(reqPath)
+ if targetPath == "" {
+ return embedFileSystem{
+ FileSystem: http.FS(fsEmbed),
+ }, nil
+ }
+
+ fsys, _ := fs.Sub(fsEmbed, targetPath)
+ _, err := fsEmbed.Open(targetPath)
+ if err != nil {
+ return nil, err
+ }
+
+ return embedFileSystem{
+ FileSystem: http.FS(fsys),
+ }, nil
+}
+
+func ServeEmbed(reqPath string, fsEmbed embed.FS) gin.HandlerFunc {
+ embedFS, err := EmbedFolder(fsEmbed, reqPath)
+ if err != nil {
+ return func(c *gin.Context) {
+ c.JSON(http.StatusInternalServerError, gin.H{
+ "message": "initialization of embed folder failed",
+ "error": err.Error(),
+ })
+ }
+ }
+ return gin.WrapH(http.FileServer(embedFS))
+}
diff --git a/pkg/static/servefilesystem.go b/pkg/static/servefilesystem.go
new file mode 100644
index 00000000..8f041e3b
--- /dev/null
+++ b/pkg/static/servefilesystem.go
@@ -0,0 +1,52 @@
+/*
+Copyright 2024 The Pixiu Authors.
+
+Licensed under the Apache License, Version 2.0 (the "License");
+you may not use this file except in compliance with the License.
+You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+Unless required by applicable law or agreed to in writing, software
+distributed under the License is distributed on an "AS IS" BASIS,
+WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+See the License for the specific language governing permissions and
+limitations under the License.
+*/
+
+package static
+
+import (
+ "fmt"
+ "net/http"
+
+ "github.com/gin-gonic/gin"
+)
+
+type ServeFileSystem interface {
+ http.FileSystem
+ Exists(prefix string, path string) bool
+}
+
+// Serve returns a middleware handler that serves static files in the given directory.
+func Serve(urlPrefix string, fs ServeFileSystem) gin.HandlerFunc {
+ return ServeCached(urlPrefix, fs, 0)
+}
+
+// ServeCached returns a middleware handler that similar as Serve
+// but with the Cache-Control Header set as passed in the cacheAge parameter
+func ServeCached(urlPrefix string, fs ServeFileSystem, cacheAge uint) gin.HandlerFunc {
+ fileserver := http.FileServer(fs)
+ if urlPrefix != "" {
+ fileserver = http.StripPrefix(urlPrefix, fileserver)
+ }
+ return func(c *gin.Context) {
+ if fs.Exists(urlPrefix, c.Request.URL.Path) {
+ if cacheAge != 0 {
+ c.Writer.Header().Add("Cache-Control", fmt.Sprintf("max-age=%d", cacheAge))
+ }
+ fileserver.ServeHTTP(c.Writer, c.Request)
+ c.Abort()
+ }
+ }
+}