feat: 整合elements主题
This commit is contained in:
8
go.mod
8
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-20260106015608-42e268aea545
|
||||
git.zhangdeman.cn/zhangdeman/consts v0.0.0-20260108031051-bf46e2083c84
|
||||
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
|
||||
@@ -22,8 +22,11 @@ require (
|
||||
github.com/gin-contrib/timeout v1.1.0
|
||||
github.com/gin-gonic/gin v1.11.0
|
||||
github.com/go-playground/validator/v10 v10.30.1
|
||||
github.com/go-webtools/knife4go v1.0.4
|
||||
github.com/jedib0t/go-pretty/v6 v6.7.8
|
||||
github.com/mcuadros/go-defaults v1.2.0
|
||||
github.com/swaggo/files v1.0.1
|
||||
github.com/swaggo/gin-swagger v1.6.1
|
||||
go.uber.org/zap v1.27.1
|
||||
)
|
||||
|
||||
@@ -57,7 +60,6 @@ require (
|
||||
github.com/go-playground/locales v0.14.1 // indirect
|
||||
github.com/go-playground/universal-translator v0.18.1 // indirect
|
||||
github.com/go-redis/redis_rate/v10 v10.0.1 // indirect
|
||||
github.com/go-webtools/knife4go v1.0.4 // indirect
|
||||
github.com/goccy/go-json v0.10.5 // indirect
|
||||
github.com/goccy/go-yaml v1.19.1 // indirect
|
||||
github.com/gorilla/websocket v1.5.3 // indirect
|
||||
@@ -87,8 +89,6 @@ require (
|
||||
github.com/rivo/uniseg v0.4.7 // indirect
|
||||
github.com/sbabiv/xml2map v1.2.1 // indirect
|
||||
github.com/spaolacci/murmur3 v1.1.0 // indirect
|
||||
github.com/swaggo/files v1.0.1 // indirect
|
||||
github.com/swaggo/gin-swagger v1.6.1 // indirect
|
||||
github.com/swaggo/swag v1.16.6 // indirect
|
||||
github.com/tidwall/gjson v1.18.0 // indirect
|
||||
github.com/tidwall/match v1.2.0 // indirect
|
||||
|
||||
4
go.sum
4
go.sum
@@ -1,7 +1,7 @@
|
||||
git.zhangdeman.cn/zhangdeman/api-doc v1.0.3-0.20260107152122-a877079712ee h1:cUrlM+87fQW8StLbGBA8EB+Ke3ZR1QslWyZqbXyD5C0=
|
||||
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-20260106015608-42e268aea545 h1:A6UeeMcSqAlHUmA2coWIuiCS/W9ySylhZMa/0HbFDcQ=
|
||||
git.zhangdeman.cn/zhangdeman/consts v0.0.0-20260106015608-42e268aea545/go.mod h1:5p8CEKGBxi7qPtTXDI3HDmqKAfIm5i/aBWdrbkbdNjc=
|
||||
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/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=
|
||||
|
||||
@@ -19,6 +19,7 @@ import (
|
||||
apiDocDefine "git.zhangdeman.cn/zhangdeman/api-doc/define"
|
||||
"git.zhangdeman.cn/zhangdeman/api-doc/enums"
|
||||
"git.zhangdeman.cn/zhangdeman/api-doc/openapi"
|
||||
"git.zhangdeman.cn/zhangdeman/consts"
|
||||
"git.zhangdeman.cn/zhangdeman/gin/define"
|
||||
"git.zhangdeman.cn/zhangdeman/graceful"
|
||||
"github.com/jedib0t/go-pretty/v6/table"
|
||||
@@ -172,7 +173,7 @@ func (s *server) RegisterDocHandler() {
|
||||
})
|
||||
ctx.Abort()
|
||||
}
|
||||
}, NewSwaggerUI(fmt.Sprintf("[%v]接口文档", s.option.docConfig.Flag), s.option.docConfig.BaseUri, enums.SwaggerUITheme(s.option.docConfig.UiTheme)).Handler())
|
||||
}, NewSwaggerUI(fmt.Sprintf("[%v]接口文档", s.option.docConfig.Flag), s.option.docConfig.BaseUri, consts.SwaggerUITheme(s.option.docConfig.UiTheme)).Handler())
|
||||
s.router.GET("/swagger-resources", func(ctx *gin.Context) { // lucky UI获取分组信息
|
||||
ctx.Writer.Header().Set("Access-Control-Allow-Origin", "*") // 允许访问所有域
|
||||
ctx.JSON(http.StatusOK, []map[string]any{
|
||||
|
||||
@@ -9,25 +9,17 @@ package router
|
||||
|
||||
import (
|
||||
"testing"
|
||||
"time"
|
||||
|
||||
"git.zhangdeman.cn/zhangdeman/rate_limit"
|
||||
"github.com/gin-gonic/gin"
|
||||
)
|
||||
|
||||
type testCommon struct {
|
||||
UserID uint `json:"user_id"`
|
||||
}
|
||||
|
||||
type testForm struct {
|
||||
Meta `json:"-" method:"get" path:"test" rate-limit:"1/5/60" tag:"测试,验证" summary:"本地调试"`
|
||||
testCommon
|
||||
Name string `json:"name"`
|
||||
}
|
||||
|
||||
func TestNewServer(t *testing.T) {
|
||||
|
||||
s := NewServer(9087, WithRateLimitInstance(rate_limit.MemoryClient), WithDocConfig(&DocConfig{
|
||||
Enable: true,
|
||||
UiTheme: "ydoc-lucky-ui",
|
||||
UiTheme: "elements",
|
||||
BaseUri: "",
|
||||
Flag: "test-server",
|
||||
ServerList: nil,
|
||||
@@ -42,9 +34,27 @@ func TestNewServer(t *testing.T) {
|
||||
s.Start()
|
||||
}
|
||||
|
||||
type testCategory struct {
|
||||
Meta `json:"-" method:"get" path:"test" rate-limit:"1/5/60" tag:"测试,验证" summary:"本地调试"`
|
||||
ID int64 `json:"id" description:"分类ID" eg:"123" binding:"required,min=10,max=100"`
|
||||
Sex string `json:"sex" dc:"性别" binding:"required,oneof=man woman" enum-desc:"man:男||woman:女"`
|
||||
Name string `json:"name" description:"分类名称" eg:"baichaqinghuan" binding:"required,min=8"`
|
||||
}
|
||||
type testProduct struct {
|
||||
ID int64 `json:"id,omitempty" description:"产品ID" example:"1001" required:"true" binding:"required"`
|
||||
Name string `json:"name" description:"产品名称" example:"iPhone 13" minLength:"2" maxLength:"100" required:"true"`
|
||||
Price float64 `json:"price" description:"价格" example:"6999.99" min:"0"`
|
||||
Stock int `json:"stock" description:"库存" example:"100" min:"0"`
|
||||
Tags []string `json:"tags" description:"标签"`
|
||||
Attributes map[string]string `json:"attributes" description:"属性"`
|
||||
CreatedAt time.Time `json:"created_at" description:"创建时间"`
|
||||
UpdatedAt *time.Time `json:"updated_at,omitempty" description:"更新时间"`
|
||||
Category *testCategory `json:"category,omitempty" description:"分类"`
|
||||
}
|
||||
|
||||
type testController struct {
|
||||
}
|
||||
|
||||
func (tc testController) Test(ctx *gin.Context, requestData *testForm) (*testCommon, error) {
|
||||
return &testCommon{UserID: requestData.UserID}, nil
|
||||
func (tc testController) Test(ctx *gin.Context, requestData *testCategory) (*testProduct, error) {
|
||||
return &testProduct{}, nil
|
||||
}
|
||||
|
||||
@@ -13,8 +13,8 @@ import (
|
||||
"strings"
|
||||
|
||||
"git.zhangdeman.cn/zhangdeman/api-doc/enums"
|
||||
"git.zhangdeman.cn/zhangdeman/api-doc/theme"
|
||||
"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,7 +23,7 @@ import (
|
||||
)
|
||||
|
||||
// NewSwaggerUI ...
|
||||
func NewSwaggerUI(docTitle string, docBaseUri string, uiTheme enums.SwaggerUITheme) *SwaggerUI {
|
||||
func NewSwaggerUI(docTitle string, docBaseUri string, uiTheme consts.SwaggerUITheme) *SwaggerUI {
|
||||
return &SwaggerUI{
|
||||
baseUri: docBaseUri,
|
||||
docTitle: docTitle,
|
||||
@@ -34,27 +34,55 @@ func NewSwaggerUI(docTitle string, docBaseUri string, uiTheme enums.SwaggerUIThe
|
||||
type SwaggerUI struct {
|
||||
baseUri string
|
||||
docTitle string
|
||||
uiTheme enums.SwaggerUITheme // 文档主题, swaggerUI / knife4go, 默认 knife4go
|
||||
uiTheme consts.SwaggerUITheme // 文档主题, swaggerUI / knife4go, 默认 knife4go
|
||||
}
|
||||
|
||||
// Handler 访问文档的接口处理
|
||||
func (su *SwaggerUI) Handler() func(ctx *gin.Context) {
|
||||
switch su.uiTheme {
|
||||
case enums.SwaggerUIThemeKnife4go:
|
||||
case consts.SwaggerUIThemeKnife4go:
|
||||
return su.HandleKnife4goUI()
|
||||
case enums.SwaggerUIThemeYDocLucky:
|
||||
case consts.SwaggerUIThemeYDocLucky:
|
||||
// YDoc-Lucky-UI 主题处理
|
||||
return su.HandleLuckyUI()
|
||||
case enums.SwaggerUIThemeDefault:
|
||||
case consts.SwaggerUIThemeDefault:
|
||||
return su.HandleSwaggerUI()
|
||||
case enums.SwaggerUIThemeRedocFree:
|
||||
case consts.SwaggerUIThemeRedocFree:
|
||||
// redoc免费版
|
||||
return su.HandleRedocFreeUI()
|
||||
case consts.SwaggerUIThemeElements:
|
||||
return su.HandleElements()
|
||||
default:
|
||||
return su.HandleSwaggerUI()
|
||||
}
|
||||
}
|
||||
|
||||
func (su *SwaggerUI) HandleElements() gin.HandlerFunc {
|
||||
return func(ctx *gin.Context) {
|
||||
fileRealPath := strings.TrimPrefix(ctx.Request.RequestURI, su.baseUri)
|
||||
byteData, _ := theme.ElementsFiles.ReadFile(filepath.Join("elements", 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))
|
||||
byteData = []byte(strings.ReplaceAll(string(byteData), "{{DOC_PATH}}", "doc.json"))
|
||||
ctx.Header(consts.HeaderKeyContentType.String(), "text/html; charset=utf-8")
|
||||
ctx.String(http.StatusOK, string(byteData))
|
||||
ctx.Abort()
|
||||
return
|
||||
}
|
||||
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()
|
||||
}
|
||||
}
|
||||
|
||||
// HandleLuckyUI ...
|
||||
func (su *SwaggerUI) HandleLuckyUI() func(ctx *gin.Context) {
|
||||
// su.router.StaticFS(su.baseUri+"/assets", http.FS(ydocUIFiles))
|
||||
|
||||
16
router/theme/elements/index.html
Normal file
16
router/theme/elements/index.html
Normal file
@@ -0,0 +1,16 @@
|
||||
<!doctype html>
|
||||
<html lang="en">
|
||||
<head>
|
||||
<meta charset="utf-8">
|
||||
<meta content="width=device-width, initial-scale=1, shrink-to-fit=no" name="viewport">
|
||||
<title>{{DOC_TITLE}}</title>
|
||||
<!-- Embed elements Elements via Web Component -->
|
||||
<script src="web-components.min.js"></script>
|
||||
<link href="styles.min.css" rel="stylesheet">
|
||||
</head>
|
||||
<body>
|
||||
<!--github 地址: https://github.com/stoplightio/elements-->
|
||||
<elements-api apiDescriptionUrl="{{DOC_PATH}}" layout="sidebar" router="hash"/>
|
||||
|
||||
</body>
|
||||
</html>
|
||||
1
router/theme/elements/styles.min.css
vendored
Normal file
1
router/theme/elements/styles.min.css
vendored
Normal file
File diff suppressed because one or more lines are too long
2
router/theme/elements/web-components.min.js
vendored
Normal file
2
router/theme/elements/web-components.min.js
vendored
Normal file
File diff suppressed because one or more lines are too long
@@ -1,16 +1,19 @@
|
||||
// Package router ...
|
||||
// Package theme ...
|
||||
//
|
||||
// Description : theme ...
|
||||
//
|
||||
// Author : go_developer@163.com<白茶清欢>
|
||||
//
|
||||
// Date : 2025-08-23 09:23
|
||||
package router
|
||||
package theme
|
||||
|
||||
import "embed"
|
||||
|
||||
//go:embed theme/ydoc-lucky-ui/*
|
||||
//go:embed ydoc-lucky-ui/*
|
||||
var YdocUIFiles embed.FS
|
||||
|
||||
//go:embed theme/redoc-free/index.html
|
||||
//go:embed redoc-free/index.html
|
||||
var RedocFreeIndexContent string
|
||||
|
||||
//go:embed elements/*
|
||||
var ElementsFiles embed.FS
|
||||
Reference in New Issue
Block a user