feat: 整合swagger-ui文档主题, 并优化文档页面渲染
This commit is contained in:
2
go.mod
2
go.mod
@@ -6,7 +6,7 @@ toolchain go1.24.2
|
||||
|
||||
require (
|
||||
git.zhangdeman.cn/zhangdeman/api-doc v1.0.3-0.20260107152122-a877079712ee
|
||||
git.zhangdeman.cn/zhangdeman/consts v0.0.0-20260108031051-bf46e2083c84
|
||||
git.zhangdeman.cn/zhangdeman/consts v0.0.0-20260108040723-8d5895324da5
|
||||
git.zhangdeman.cn/zhangdeman/dynamic-struct v0.0.0-20251207071238-9aa24be3d708
|
||||
git.zhangdeman.cn/zhangdeman/exception v0.0.0-20250510123912-a0d52fc093ab
|
||||
git.zhangdeman.cn/zhangdeman/graceful v0.0.0-20250529070945-92833db6f3a4
|
||||
|
||||
2
go.sum
2
go.sum
@@ -2,6 +2,8 @@ git.zhangdeman.cn/zhangdeman/api-doc v1.0.3-0.20260107152122-a877079712ee h1:cUr
|
||||
git.zhangdeman.cn/zhangdeman/api-doc v1.0.3-0.20260107152122-a877079712ee/go.mod h1:EO06OJ2rIS+s3CaXoGiX6yTuyhKFeSrgHukOY7FofHw=
|
||||
git.zhangdeman.cn/zhangdeman/consts v0.0.0-20260108031051-bf46e2083c84 h1:1+erCrsFvz5QuHKdraVuH7KmokUoqJULaKpWXMT6m3Y=
|
||||
git.zhangdeman.cn/zhangdeman/consts v0.0.0-20260108031051-bf46e2083c84/go.mod h1:5p8CEKGBxi7qPtTXDI3HDmqKAfIm5i/aBWdrbkbdNjc=
|
||||
git.zhangdeman.cn/zhangdeman/consts v0.0.0-20260108040723-8d5895324da5 h1:v02Z5/rLXxRUGMZLBPgOnL0hHN36bbH1tGTC+40pF1E=
|
||||
git.zhangdeman.cn/zhangdeman/consts v0.0.0-20260108040723-8d5895324da5/go.mod h1:5p8CEKGBxi7qPtTXDI3HDmqKAfIm5i/aBWdrbkbdNjc=
|
||||
git.zhangdeman.cn/zhangdeman/dynamic-struct v0.0.0-20251207071238-9aa24be3d708 h1:yVr38JAgPwS/6JeYdHLDa8PXU3fTa2dnENL1JGdu3ns=
|
||||
git.zhangdeman.cn/zhangdeman/dynamic-struct v0.0.0-20251207071238-9aa24be3d708/go.mod h1:iwegDT/6mX2INyxMAYxsL9pZdpEixiu1GdpHIG2It1k=
|
||||
git.zhangdeman.cn/zhangdeman/easylock v0.0.0-20230731062340-983985c12eda h1:bMD6r9gjRy7cO+T4zRQVYAesgIblBdTnhzT1vN5wjvI=
|
||||
|
||||
@@ -11,6 +11,7 @@ import (
|
||||
"testing"
|
||||
"time"
|
||||
|
||||
"git.zhangdeman.cn/zhangdeman/consts"
|
||||
"git.zhangdeman.cn/zhangdeman/rate_limit"
|
||||
"github.com/gin-gonic/gin"
|
||||
)
|
||||
@@ -19,7 +20,7 @@ func TestNewServer(t *testing.T) {
|
||||
|
||||
s := NewServer(9087, WithRateLimitInstance(rate_limit.MemoryClient), WithDocConfig(&DocConfig{
|
||||
Enable: true,
|
||||
UiTheme: "elements",
|
||||
UiTheme: consts.SwaggerUIThemeSwaggerUI.String(),
|
||||
BaseUri: "",
|
||||
Flag: "test-server",
|
||||
ServerList: nil,
|
||||
|
||||
@@ -8,6 +8,7 @@
|
||||
package router
|
||||
|
||||
import (
|
||||
"embed"
|
||||
"net/http"
|
||||
"path/filepath"
|
||||
"strings"
|
||||
@@ -46,21 +47,23 @@ func (su *SwaggerUI) Handler() func(ctx *gin.Context) {
|
||||
// YDoc-Lucky-UI 主题处理
|
||||
return su.HandleLuckyUI()
|
||||
case consts.SwaggerUIThemeDefault:
|
||||
return su.HandleSwaggerUI()
|
||||
return su.HandleSwaggerDefaultUI()
|
||||
case consts.SwaggerUIThemeRedocFree:
|
||||
// redoc免费版
|
||||
return su.HandleRedocFreeUI()
|
||||
case consts.SwaggerUIThemeElements:
|
||||
return su.HandleElements()
|
||||
return su.renderWebPage(theme.ElementsFiles, su.uiTheme)
|
||||
case consts.SwaggerUIThemeSwaggerUI:
|
||||
return su.renderWebPage(theme.SwaggerUIFiles, su.uiTheme)
|
||||
default:
|
||||
return su.HandleSwaggerUI()
|
||||
return su.HandleSwaggerDefaultUI()
|
||||
}
|
||||
}
|
||||
|
||||
func (su *SwaggerUI) HandleElements() gin.HandlerFunc {
|
||||
func (su *SwaggerUI) renderWebPage(themeFiles embed.FS, themeUI consts.SwaggerUITheme) func(ctx *gin.Context) {
|
||||
return func(ctx *gin.Context) {
|
||||
fileRealPath := strings.TrimPrefix(ctx.Request.RequestURI, su.baseUri)
|
||||
byteData, _ := theme.ElementsFiles.ReadFile(filepath.Join("elements", fileRealPath))
|
||||
byteData, _ := themeFiles.ReadFile(filepath.Join(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))
|
||||
@@ -73,7 +76,7 @@ func (su *SwaggerUI) HandleElements() gin.HandlerFunc {
|
||||
uriArr := strings.Split(ctx.Request.RequestURI, ".")
|
||||
contentType := "text/" + uriArr[len(uriArr)-1]
|
||||
if strings.HasSuffix(ctx.Request.RequestURI, "png") {
|
||||
contentType = "image/png"
|
||||
contentType = consts.MimeTypeImagePng
|
||||
} else if strings.HasSuffix(ctx.Request.RequestURI, "js") {
|
||||
contentType = "application/javascript"
|
||||
}
|
||||
@@ -116,8 +119,8 @@ func (su *SwaggerUI) HandleKnife4goUI() func(ctx *gin.Context) {
|
||||
return knife4goGin.WrapHandler(knife4goFiles.Handler, resetOption)
|
||||
}
|
||||
|
||||
// HandleSwaggerUI ...
|
||||
func (su *SwaggerUI) HandleSwaggerUI() func(ctx *gin.Context) {
|
||||
// HandleSwaggerDefaultUI ...
|
||||
func (su *SwaggerUI) HandleSwaggerDefaultUI() func(ctx *gin.Context) {
|
||||
return ginSwagger.WrapHandler(swaggerFiles.Handler)
|
||||
}
|
||||
|
||||
|
||||
@@ -17,3 +17,6 @@ var RedocFreeIndexContent string
|
||||
|
||||
//go:embed elements/*
|
||||
var ElementsFiles embed.FS
|
||||
|
||||
//go:embed swagger-ui/*
|
||||
var SwaggerUIFiles embed.FS
|
||||
|
||||
1726
router/theme/swagger-ui/2.x/theme-feeling-blue.css
Normal file
1726
router/theme/swagger-ui/2.x/theme-feeling-blue.css
Normal file
File diff suppressed because it is too large
Load Diff
1664
router/theme/swagger-ui/2.x/theme-flattop.css
Normal file
1664
router/theme/swagger-ui/2.x/theme-flattop.css
Normal file
File diff suppressed because it is too large
Load Diff
1741
router/theme/swagger-ui/2.x/theme-material.css
Normal file
1741
router/theme/swagger-ui/2.x/theme-material.css
Normal file
File diff suppressed because it is too large
Load Diff
1729
router/theme/swagger-ui/2.x/theme-monokai.css
Normal file
1729
router/theme/swagger-ui/2.x/theme-monokai.css
Normal file
File diff suppressed because it is too large
Load Diff
1660
router/theme/swagger-ui/2.x/theme-muted.css
Normal file
1660
router/theme/swagger-ui/2.x/theme-muted.css
Normal file
File diff suppressed because it is too large
Load Diff
1726
router/theme/swagger-ui/2.x/theme-newspaper.css
Normal file
1726
router/theme/swagger-ui/2.x/theme-newspaper.css
Normal file
File diff suppressed because it is too large
Load Diff
1673
router/theme/swagger-ui/2.x/theme-outline.css
Normal file
1673
router/theme/swagger-ui/2.x/theme-outline.css
Normal file
File diff suppressed because it is too large
Load Diff
1672
router/theme/swagger-ui/3.x/theme-feeling-blue.css
Normal file
1672
router/theme/swagger-ui/3.x/theme-feeling-blue.css
Normal file
File diff suppressed because it is too large
Load Diff
1672
router/theme/swagger-ui/3.x/theme-flattop.css
Normal file
1672
router/theme/swagger-ui/3.x/theme-flattop.css
Normal file
File diff suppressed because it is too large
Load Diff
1719
router/theme/swagger-ui/3.x/theme-material.css
Normal file
1719
router/theme/swagger-ui/3.x/theme-material.css
Normal file
File diff suppressed because it is too large
Load Diff
1792
router/theme/swagger-ui/3.x/theme-monokai.css
Normal file
1792
router/theme/swagger-ui/3.x/theme-monokai.css
Normal file
File diff suppressed because it is too large
Load Diff
1671
router/theme/swagger-ui/3.x/theme-newspaper.css
Normal file
1671
router/theme/swagger-ui/3.x/theme-newspaper.css
Normal file
File diff suppressed because it is too large
Load Diff
1652
router/theme/swagger-ui/3.x/theme-outline.css
Normal file
1652
router/theme/swagger-ui/3.x/theme-outline.css
Normal file
File diff suppressed because it is too large
Load Diff
116
router/theme/swagger-ui/index.html
Normal file
116
router/theme/swagger-ui/index.html
Normal file
@@ -0,0 +1,116 @@
|
||||
<!DOCTYPE html>
|
||||
<html lang="zh-CN">
|
||||
<head>
|
||||
<meta charset="UTF-8">
|
||||
<title>{{DOC_TITLE}}</title>
|
||||
<!-- 默认主题 -->
|
||||
<link href="3.x/theme-material.css" id="swagger-theme" rel="stylesheet" type="text/css">
|
||||
<link href="swagger-ui.css" rel="stylesheet" type="text/css">
|
||||
<style>
|
||||
.theme-selector {
|
||||
position: fixed;
|
||||
top: 20px;
|
||||
right: 20px;
|
||||
z-index: 100;
|
||||
background: white;
|
||||
padding: 10px;
|
||||
border-radius: 5px;
|
||||
box-shadow: 0 2px 10px rgba(0,0,0,0.1);
|
||||
}
|
||||
select {
|
||||
padding: 5px;
|
||||
border-radius: 3px;
|
||||
border: 1px solid #ccc;
|
||||
}
|
||||
</style>
|
||||
</head>
|
||||
<body>
|
||||
<div class="theme-selector">
|
||||
<label for="theme-select">选择主题: </label>
|
||||
<select id="theme-select" onchange="changeTheme(this.value)">
|
||||
<option value="theme-default">默认</option>
|
||||
<option value="3.x-theme-material">3.x-Material</option>
|
||||
<option value="3.x-theme-monokai">3.x-Monokai</option>
|
||||
<option value="3.x-theme-feeling-blue">3.x-Feeling Blue</option>
|
||||
<option value="3.x-theme-flattop">3.x-Flattop</option>
|
||||
<option value="3.x-theme-newspaper">3.x-Newspaper</option>
|
||||
<option value="3.x-theme-outline">3.x-Outline</option>
|
||||
<option value="2.x-theme-felling-blue.css">2.x-theme-felling-blue.css</option>
|
||||
<option value="2.x-theme-flattop.css">2.x-theme-flattop.css</option>
|
||||
<option value="2.x-theme-material.css">2.x-theme-material.css</option>
|
||||
<option value="2.x-theme-monokai.css">2.x-theme-monokai.css</option>
|
||||
<option value="2.x-theme-muted.css">2.x-theme-muted.css</option>
|
||||
<option value="2.x-theme-newspaper.css">2.x-theme-newspaper.css</option>
|
||||
<option value="2.x-theme-outline.css">2.x-theme-outline.css</option>
|
||||
</select>
|
||||
</div>
|
||||
|
||||
<div id="swagger-ui"></div>
|
||||
|
||||
<script src="swagger-ui-bundle.js"></script>
|
||||
<script src="swagger-ui-standalone-preset.js"></script>
|
||||
|
||||
<script>
|
||||
// 主题映射表
|
||||
const themes = {
|
||||
'theme-default': '',
|
||||
'3.x-theme-material': '3.x/theme-material.css',
|
||||
'3.x-theme-monokai': '3.x/theme-monokai.css',
|
||||
'3.x-theme-feeling-blue': '3.x/theme-feeling-blue.css',
|
||||
'3.x-theme-flattop': '3.x/theme-flattop.css',
|
||||
'3.x-theme-newspaper': '3.x/theme-newspaper.css',
|
||||
'3.x-theme-outline': '3.x/theme-outline.css',
|
||||
'2.x-theme-felling-blue.css': '2.x/theme-felling-blue.css',
|
||||
'2.x-theme-flattop.css': '2.x/theme-felling-flattop.css',
|
||||
'2.x-theme-material.css': '2.x/theme-material.css',
|
||||
'2.x-theme-monokai.css': '2.x/theme-monokai.css',
|
||||
'2.x-theme-muted.css': '2.x/theme-muted.css',
|
||||
'2.x-theme-newspaper.css': '2.x/theme-newspaper.css',
|
||||
'2.x-theme-outline.css': '2.x/theme-outline.css',
|
||||
};
|
||||
|
||||
// 切换主题函数
|
||||
function changeTheme(themeName) {
|
||||
const themeLink = document.getElementById('swagger-theme');
|
||||
|
||||
if (themeName === 'theme-default') {
|
||||
themeLink.href = themes['3.x-theme-material']; // 使用默认主题
|
||||
} else {
|
||||
themeLink.href = themes[themeName];
|
||||
}
|
||||
|
||||
// 保存到本地存储
|
||||
localStorage.setItem('swagger-theme', themeName);
|
||||
}
|
||||
|
||||
// 页面加载时恢复主题
|
||||
window.onload = function() {
|
||||
// 从本地存储恢复主题
|
||||
const savedTheme = localStorage.getItem('swagger-theme') || 'theme-material';
|
||||
document.getElementById('theme-select').value = savedTheme;
|
||||
|
||||
if (savedTheme !== 'theme-default') {
|
||||
document.getElementById('swagger-theme').href = themes[savedTheme];
|
||||
}
|
||||
|
||||
// 初始化 Swagger UI
|
||||
window.ui = SwaggerUIBundle({
|
||||
url: "{{DOC_PATH}}", // 你的 API 文档地址
|
||||
dom_id: '#swagger-ui',
|
||||
deepLinking: true,
|
||||
presets: [
|
||||
SwaggerUIBundle.presets.apis,
|
||||
SwaggerUIStandalonePreset
|
||||
],
|
||||
plugins: [
|
||||
SwaggerUIBundle.plugins.DownloadUrl
|
||||
],
|
||||
layout: "StandaloneLayout",
|
||||
filter: true,
|
||||
defaultModelsExpandDepth: 1,
|
||||
defaultModelExpandDepth: 1
|
||||
});
|
||||
}
|
||||
</script>
|
||||
</body>
|
||||
</html>
|
||||
2
router/theme/swagger-ui/swagger-ui-bundle.js
Normal file
2
router/theme/swagger-ui/swagger-ui-bundle.js
Normal file
File diff suppressed because one or more lines are too long
2
router/theme/swagger-ui/swagger-ui-standalone-preset.js
Normal file
2
router/theme/swagger-ui/swagger-ui-standalone-preset.js
Normal file
File diff suppressed because one or more lines are too long
3
router/theme/swagger-ui/swagger-ui.css
Normal file
3
router/theme/swagger-ui/swagger-ui.css
Normal file
File diff suppressed because one or more lines are too long
Reference in New Issue
Block a user