feat(settings): add home content customization and config injection

- Add home_content setting for custom homepage (HTML or iframe URL)
- Inject public settings into index.html to eliminate page flash
- Support ETag caching with automatic invalidation on settings update
- Add Vite plugin for dev mode settings injection
- Refactor HomeView to use appStore instead of local API calls
This commit is contained in:
Edric Li
2026-01-10 18:37:44 +08:00
parent e83f644c3f
commit 5265b12cc7
24 changed files with 533 additions and 40 deletions

View File

@@ -30,6 +30,7 @@ func ProvideRouter(
apiKeyAuth middleware2.APIKeyAuthMiddleware,
apiKeyService *service.APIKeyService,
subscriptionService *service.SubscriptionService,
settingService *service.SettingService,
) *gin.Engine {
if cfg.Server.Mode == "release" {
gin.SetMode(gin.ReleaseMode)
@@ -47,7 +48,7 @@ func ProvideRouter(
}
}
return SetupRouter(r, handlers, jwtAuth, adminAuth, apiKeyAuth, apiKeyService, subscriptionService, cfg)
return SetupRouter(r, handlers, jwtAuth, adminAuth, apiKeyAuth, apiKeyService, subscriptionService, settingService, cfg)
}
// ProvideHTTPServer 提供 HTTP 服务器

View File

@@ -1,6 +1,8 @@
package server
import (
"log"
"github.com/Wei-Shaw/sub2api/internal/config"
"github.com/Wei-Shaw/sub2api/internal/handler"
middleware2 "github.com/Wei-Shaw/sub2api/internal/server/middleware"
@@ -20,6 +22,7 @@ func SetupRouter(
apiKeyAuth middleware2.APIKeyAuthMiddleware,
apiKeyService *service.APIKeyService,
subscriptionService *service.SubscriptionService,
settingService *service.SettingService,
cfg *config.Config,
) *gin.Engine {
// 应用中间件
@@ -27,9 +30,17 @@ func SetupRouter(
r.Use(middleware2.CORS(cfg.CORS))
r.Use(middleware2.SecurityHeaders(cfg.Security.CSP))
// Serve embedded frontend if available
// Serve embedded frontend with settings injection if available
if web.HasEmbeddedFrontend() {
r.Use(web.ServeEmbeddedFrontend())
frontendServer, err := web.NewFrontendServer(settingService)
if err != nil {
log.Printf("Warning: Failed to create frontend server with settings injection: %v, using legacy mode", err)
r.Use(web.ServeEmbeddedFrontend())
} else {
// Register cache invalidation callback
settingService.SetOnUpdateCallback(frontendServer.InvalidateCache)
r.Use(frontendServer.Middleware())
}
}
// 注册路由