支持公开用户主页、帖子图缩略图与编辑器图组排版。

新增用户签名与活动统计、图片灯箱;正文按需生成缩略图;TipTap 支持多图分组与环绕排版,并注入站点标题避免刷新闪烁。

Co-authored-by: Cursor <cursoragent@cursor.com>
This commit is contained in:
2026-08-01 12:29:50 +08:00
parent 822eef96be
commit 060b7707cb
51 changed files with 3563 additions and 397 deletions

View File

@@ -2,9 +2,11 @@ package embed_static
import (
"embed"
"html"
"html/template"
"io/fs"
"net/http"
"regexp"
"strings"
"github.com/gin-gonic/gin"
@@ -16,6 +18,16 @@ var staticFS embed.FS
//go:embed templates/*
var templatesFS embed.FS
var (
spaTitleRe = regexp.MustCompile(`(?s)<title>.*?</title>`)
spaBrandTitleFn func() string
)
// SetSPADocumentTitle 注册站点标题提供者ServeSPA 会注入到入口 HTML避免刷新闪烁
func SetSPADocumentTitle(fn func() string) {
spaBrandTitleFn = fn
}
// SetupEmbed 配置内嵌资源SPA 前端 + 后台 HTML 模板
func SetupEmbed(r *gin.Engine) error {
tmpl, err := LoadTemplates()
@@ -44,6 +56,12 @@ func ServeSPA(c *gin.Context) {
c.String(http.StatusNotFound, "前端未构建,请运行: cd frontend && npm run build")
return
}
if spaBrandTitleFn != nil {
if title := strings.TrimSpace(spaBrandTitleFn()); title != "" {
escaped := html.EscapeString(title)
data = spaTitleRe.ReplaceAll(data, []byte("<title>"+escaped+"</title>"))
}
}
c.Data(http.StatusOK, "text/html; charset=utf-8", data)
}
@@ -52,6 +70,7 @@ func IsSPARoute(path string) bool {
if strings.HasPrefix(path, "/api") ||
strings.HasPrefix(path, "/admin") ||
strings.HasPrefix(path, "/uploads") ||
strings.HasPrefix(path, "/media") ||
strings.HasPrefix(path, "/legacy") ||
strings.HasPrefix(path, "/assets") ||
strings.HasPrefix(path, "/oauth") ||