chore: udpate pwa site
This commit is contained in:
@@ -44,10 +44,14 @@ func initStaticRoutes(root *gin.RouterGroup) {
|
|||||||
contentType := mime.TypeByExtension(ext)
|
contentType := mime.TypeByExtension(ext)
|
||||||
if contentType == "" {
|
if contentType == "" {
|
||||||
switch ext {
|
switch ext {
|
||||||
case ".js": contentType = "application/javascript"
|
case ".js":
|
||||||
case ".css": contentType = "text/css"
|
contentType = "application/javascript"
|
||||||
case ".svg": contentType = "image/svg+xml"
|
case ".css":
|
||||||
default: contentType = "application/octet-stream"
|
contentType = "text/css"
|
||||||
|
case ".svg":
|
||||||
|
contentType = "image/svg+xml"
|
||||||
|
default:
|
||||||
|
contentType = "application/octet-stream"
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -55,7 +59,7 @@ func initStaticRoutes(root *gin.RouterGroup) {
|
|||||||
if gzFile, err := staticFS.Open(gzPath); err == nil {
|
if gzFile, err := staticFS.Open(gzPath); err == nil {
|
||||||
defer gzFile.Close()
|
defer gzFile.Close()
|
||||||
ctx.Header("Content-Type", contentType)
|
ctx.Header("Content-Type", contentType)
|
||||||
|
|
||||||
if isGzipSupported {
|
if isGzipSupported {
|
||||||
// 极致性能:流式透传压缩包 (RSS 占用极低)
|
// 极致性能:流式透传压缩包 (RSS 占用极低)
|
||||||
ctx.Header("Content-Encoding", "gzip")
|
ctx.Header("Content-Encoding", "gzip")
|
||||||
@@ -85,6 +89,13 @@ func initStaticRoutes(root *gin.RouterGroup) {
|
|||||||
|
|
||||||
// logo.svg 等单文件处理
|
// logo.svg 等单文件处理
|
||||||
root.GET("/logo.svg", func(ctx *gin.Context) {
|
root.GET("/logo.svg", func(ctx *gin.Context) {
|
||||||
|
settings := services.NewSettingsService()
|
||||||
|
icon := settings.Get(constant.SectionSite, constant.KeyIcon)
|
||||||
|
if icon != "" {
|
||||||
|
ctx.Header("Cache-Control", "public, max-age=86400")
|
||||||
|
ctx.Data(http.StatusOK, "image/svg+xml", []byte(icon))
|
||||||
|
return
|
||||||
|
}
|
||||||
serveSingleFile(ctx, "logo.svg", "image/svg+xml", "public, max-age=86400")
|
serveSingleFile(ctx, "logo.svg", "image/svg+xml", "public, max-age=86400")
|
||||||
})
|
})
|
||||||
|
|
||||||
@@ -111,7 +122,7 @@ func initPWARoutes(root *gin.RouterGroup) {
|
|||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
// 动态 manifest 处理 (支持由 Go 后端控制标题)
|
// 动态 manifest 处理 (支持由 Go 后端控制标题和图标)
|
||||||
root.GET("/manifest.webmanifest", handleManifest)
|
root.GET("/manifest.webmanifest", handleManifest)
|
||||||
|
|
||||||
// 动态匹配 workbox-*.js (Vite PWA 生成的库文件)
|
// 动态匹配 workbox-*.js (Vite PWA 生成的库文件)
|
||||||
@@ -121,6 +132,7 @@ func initPWARoutes(root *gin.RouterGroup) {
|
|||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
func handleManifest(ctx *gin.Context) {
|
func handleManifest(ctx *gin.Context) {
|
||||||
staticFS := static.GetFS()
|
staticFS := static.GetFS()
|
||||||
if staticFS == nil {
|
if staticFS == nil {
|
||||||
@@ -150,6 +162,16 @@ func handleManifest(ctx *gin.Context) {
|
|||||||
manifest["short_name"] = title
|
manifest["short_name"] = title
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// 注入后端配置的图标 (首选 logo.svg)
|
||||||
|
manifest["icons"] = []map[string]interface{}{
|
||||||
|
{
|
||||||
|
"src": "/logo.svg",
|
||||||
|
"sizes": "any",
|
||||||
|
"type": "image/svg+xml",
|
||||||
|
"purpose": "any maskable",
|
||||||
|
},
|
||||||
|
}
|
||||||
|
|
||||||
res, _ := json.Marshal(manifest)
|
res, _ := json.Marshal(manifest)
|
||||||
ctx.Header("Cache-Control", "public, no-cache")
|
ctx.Header("Cache-Control", "public, no-cache")
|
||||||
ctx.Data(200, "application/manifest+json", res)
|
ctx.Data(200, "application/manifest+json", res)
|
||||||
@@ -162,7 +184,9 @@ func serveSingleFile(ctx *gin.Context, filename string, contentType string, cach
|
|||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
if cache != "" { ctx.Header("Cache-Control", cache) }
|
if cache != "" {
|
||||||
|
ctx.Header("Cache-Control", cache)
|
||||||
|
}
|
||||||
ctx.Header("Content-Type", contentType)
|
ctx.Header("Content-Type", contentType)
|
||||||
|
|
||||||
isGzipSupported := strings.Contains(ctx.GetHeader("Accept-Encoding"), "gzip")
|
isGzipSupported := strings.Contains(ctx.GetHeader("Accept-Encoding"), "gzip")
|
||||||
@@ -221,7 +245,9 @@ func serveSPA(ctx *gin.Context, urlPrefix string, status int) {
|
|||||||
|
|
||||||
html := string(data)
|
html := string(data)
|
||||||
baseHref := urlPrefix + "/"
|
baseHref := urlPrefix + "/"
|
||||||
if urlPrefix == "" { baseHref = "/" }
|
if urlPrefix == "" {
|
||||||
|
baseHref = "/"
|
||||||
|
}
|
||||||
html = strings.Replace(html, "<head>", "<head>\n <base href=\""+baseHref+"\">", 1)
|
html = strings.Replace(html, "<head>", "<head>\n <base href=\""+baseHref+"\">", 1)
|
||||||
configScript := `<script>window.__BASE_URL__ = "` + urlPrefix + `"; window.__API_VERSION__ = "/api/v1";</script>`
|
configScript := `<script>window.__BASE_URL__ = "` + urlPrefix + `"; window.__API_VERSION__ = "/api/v1";</script>`
|
||||||
html = strings.Replace(html, "</head>", configScript+"</head>", 1)
|
html = strings.Replace(html, "</head>", configScript+"</head>", 1)
|
||||||
|
|||||||
Binary file not shown.
|
Before Width: | Height: | Size: 546 KiB |
Binary file not shown.
|
Before Width: | Height: | Size: 546 KiB |
+4
-14
@@ -70,21 +70,11 @@ export default defineConfig({
|
|||||||
display: 'standalone',
|
display: 'standalone',
|
||||||
icons: [
|
icons: [
|
||||||
{
|
{
|
||||||
src: 'pwa-icon-192.png',
|
src: 'logo.svg',
|
||||||
sizes: '192x192',
|
sizes: 'any',
|
||||||
type: 'image/png'
|
type: 'image/svg+xml',
|
||||||
},
|
|
||||||
{
|
|
||||||
src: 'pwa-icon-512.png',
|
|
||||||
sizes: '512x512',
|
|
||||||
type: 'image/png'
|
|
||||||
},
|
|
||||||
{
|
|
||||||
src: 'pwa-icon-512.png',
|
|
||||||
sizes: '512x512',
|
|
||||||
type: 'image/png',
|
|
||||||
purpose: 'any maskable'
|
purpose: 'any maskable'
|
||||||
}
|
},
|
||||||
]
|
]
|
||||||
},
|
},
|
||||||
workbox: {
|
workbox: {
|
||||||
|
|||||||
Reference in New Issue
Block a user