c26b06f1cc
Go 控制面(SQLite + REST API)嵌入 Mihomo 数据面,Vue 3 多语言 Web 管理台。 含订阅/节点/规则/出站/监控/日志、OpenAPI、API Key、Gitea Actions CI 与开源文档; CI 使用 ubuntu-latest runner,Go/Docker 步骤走国内镜像与 shell,避免 GitHub 下载超时。 Co-authored-by: Cursor <cursoragent@cursor.com>
48 lines
1.0 KiB
Go
48 lines
1.0 KiB
Go
package api
|
|
|
|
import (
|
|
"embed"
|
|
"io/fs"
|
|
"net/http"
|
|
"strings"
|
|
|
|
"github.com/gin-gonic/gin"
|
|
)
|
|
|
|
//go:embed static/*
|
|
var staticFS embed.FS
|
|
|
|
func (s *Server) serveSPA(c *gin.Context) {
|
|
if strings.HasPrefix(c.Request.URL.Path, "/api/") {
|
|
c.JSON(http.StatusNotFound, gin.H{"error": "not found"})
|
|
return
|
|
}
|
|
sub, err := fs.Sub(staticFS, "static")
|
|
if err != nil {
|
|
c.String(http.StatusInternalServerError, "static fs error")
|
|
return
|
|
}
|
|
path := strings.TrimPrefix(c.Request.URL.Path, "/")
|
|
if path == "" {
|
|
path = "index.html"
|
|
}
|
|
data, err := fs.ReadFile(sub, path)
|
|
if err != nil {
|
|
data, err = fs.ReadFile(sub, "index.html")
|
|
if err != nil {
|
|
c.String(http.StatusNotFound, "not found")
|
|
return
|
|
}
|
|
}
|
|
contentType := "text/html; charset=utf-8"
|
|
switch {
|
|
case strings.HasSuffix(path, ".js"):
|
|
contentType = "application/javascript"
|
|
case strings.HasSuffix(path, ".css"):
|
|
contentType = "text/css"
|
|
case strings.HasSuffix(path, ".svg"):
|
|
contentType = "image/svg+xml"
|
|
}
|
|
c.Data(http.StatusOK, contentType, data)
|
|
}
|