feat: 文档整合scalar 主题, 优化 redoc-free主题, 优化页面渲染

This commit is contained in:
2026-01-08 12:52:45 +08:00
parent c18887d5a7
commit 90a2d139eb
10 changed files with 2291 additions and 86 deletions

View File

@@ -13,9 +13,7 @@ import (
"path/filepath"
"strings"
"git.zhangdeman.cn/zhangdeman/api-doc/enums"
"git.zhangdeman.cn/zhangdeman/consts"
"git.zhangdeman.cn/zhangdeman/gin/router/theme"
"github.com/gin-gonic/gin"
knife4goFiles "github.com/go-webtools/knife4go"
knife4goGin "github.com/go-webtools/knife4go/gin"
@@ -23,6 +21,9 @@ import (
ginSwagger "github.com/swaggo/gin-swagger"
)
//go:embed theme/*
var ThemeFiles embed.FS
// NewSwaggerUI ...
func NewSwaggerUI(docTitle string, docBaseUri string, uiTheme consts.SwaggerUITheme) *SwaggerUI {
return &SwaggerUI{
@@ -43,27 +44,20 @@ func (su *SwaggerUI) Handler() func(ctx *gin.Context) {
switch su.uiTheme {
case consts.SwaggerUIThemeKnife4go:
return su.HandleKnife4goUI()
case consts.SwaggerUIThemeYDocLucky:
// YDoc-Lucky-UI 主题处理
return su.HandleLuckyUI()
case consts.SwaggerUIThemeDefault:
return su.HandleSwaggerDefaultUI()
case consts.SwaggerUIThemeRedocFree:
// redoc免费版
return su.HandleRedocFreeUI()
case consts.SwaggerUIThemeElements:
return su.renderWebPage(theme.ElementsFiles, su.uiTheme)
case consts.SwaggerUIThemeSwaggerUI:
return su.renderWebPage(theme.SwaggerUIFiles, su.uiTheme)
case consts.SwaggerUIThemeYDocLucky, consts.SwaggerUIThemeElements, consts.SwaggerUIThemeSwaggerUI, consts.SwaggerUIThemeScalar, consts.SwaggerUIThemeRedocFree:
// YDoc-Lucky-UI 主题处理
return su.renderWebPage(su.uiTheme)
default:
return su.HandleSwaggerDefaultUI()
}
}
func (su *SwaggerUI) renderWebPage(themeFiles embed.FS, themeUI consts.SwaggerUITheme) func(ctx *gin.Context) {
func (su *SwaggerUI) renderWebPage(themeUI consts.SwaggerUITheme) func(ctx *gin.Context) {
return func(ctx *gin.Context) {
fileRealPath := strings.TrimPrefix(ctx.Request.RequestURI, su.baseUri)
byteData, _ := themeFiles.ReadFile(filepath.Join(themeUI.String(), fileRealPath))
byteData, _ := ThemeFiles.ReadFile(filepath.Join("theme", themeUI.String(), fileRealPath))
if strings.Contains(ctx.Request.RequestURI, ".html") {
byteData = []byte(strings.ReplaceAll(string(byteData), "{{BASE_URI}}", su.baseUri))
byteData = []byte(strings.ReplaceAll(string(byteData), "{{DOC_TITLE}}", su.docTitle))
@@ -86,28 +80,6 @@ func (su *SwaggerUI) renderWebPage(themeFiles embed.FS, themeUI consts.SwaggerUI
}
}
// HandleLuckyUI ...
func (su *SwaggerUI) HandleLuckyUI() func(ctx *gin.Context) {
// su.router.StaticFS(su.baseUri+"/assets", http.FS(ydocUIFiles))
return func(ctx *gin.Context) {
fileRealPath := strings.TrimPrefix(ctx.Request.RequestURI, su.baseUri)
byteData, _ := theme.YdocUIFiles.ReadFile(filepath.Join(enums.SwaggerUIThemeYDocLucky.String(), fileRealPath))
if strings.HasSuffix(ctx.Request.RequestURI, "html") {
byteData = []byte(strings.ReplaceAll(string(byteData), "{{BASE_URI}}", su.baseUri))
}
uriArr := strings.Split(ctx.Request.RequestURI, ".")
contentType := "text/" + uriArr[len(uriArr)-1]
if strings.HasSuffix(ctx.Request.RequestURI, "png") {
contentType = "image/png"
} else if strings.HasSuffix(ctx.Request.RequestURI, "js") {
contentType = "application/javascript"
}
ctx.Header(consts.HeaderKeyContentType.String(), contentType)
ctx.String(http.StatusOK, string(byteData))
ctx.Abort()
}
}
// HandleKnife4goUI ...
func (su *SwaggerUI) HandleKnife4goUI() func(ctx *gin.Context) {
resetOption := func(cfg *knife4goGin.Config) {
@@ -123,22 +95,3 @@ func (su *SwaggerUI) HandleKnife4goUI() func(ctx *gin.Context) {
func (su *SwaggerUI) HandleSwaggerDefaultUI() func(ctx *gin.Context) {
return ginSwagger.WrapHandler(swaggerFiles.Handler)
}
// HandleRedocFreeUI 处理redoc_free主题
func (su *SwaggerUI) HandleRedocFreeUI() func(ctx *gin.Context) {
return func(ctx *gin.Context) {
// TODO : 这部分数据支持外部传参替换
replaceTable := map[string]string{
"{{DOC_TITLE}}": su.docTitle,
"{{CSS_FAMILY}}": "https://fonts.googleapis.com/css?family=Montserrat:300,400,700|Roboto:300,400,700",
"{{DOC_PATH}}": "doc.json",
"{{REDOC_STANDALONE_JS}}": "https://cdn.redoc.ly/redoc/latest/bundles/redoc.standalone.js",
}
for k, v := range replaceTable {
theme.RedocFreeIndexContent = strings.ReplaceAll(theme.RedocFreeIndexContent, k, v)
}
ctx.Header(consts.HeaderKeyContentType.String(), "text/html; charset=utf-8")
ctx.String(http.StatusOK, theme.RedocFreeIndexContent)
ctx.Abort()
}
}