feat: 文档生成支持配置基础信息

This commit is contained in:
2025-08-23 10:51:34 +08:00
parent a3b0c5f701
commit 03d10208ec
6 changed files with 245 additions and 38 deletions

View File

@ -7,6 +7,8 @@
// Date : 2024-04-23 22:16
package define
import "git.zhangdeman.cn/gateway/api-doc/enums"
// OpenapiDoc openapi文档结构, 文档规范参见 : https://openapi.apifox.cn/
type OpenapiDoc struct {
Openapi string `json:"openapi" required:"true"` // 必选. 这个字符串必须是开放 API 规范版本号提到的符合语义化版本号规范的版本号。openapi字段应该被工具或者客户端用来解释 OpenAPI 文档.
@ -231,8 +233,8 @@ type Contact struct {
// License 开源协议
type License struct {
Name string `json:"name,omitempty"` // 开源协议名
Url string `json:"url,omitempty"` // 开源协议地址
Name enums.License `json:"name,omitempty"` // 开源协议名
Url string `json:"url,omitempty"` // 开源协议地址
}
// ServerItem server 对象结构

116
enums/license.go Normal file
View File

@ -0,0 +1,116 @@
// Package enums ...
//
// Description : enums ...
//
// Author : go_developer@163.com<白茶清欢>
//
// Date : 2025-08-23 09:40
package enums
import (
"strings"
)
type License string
func (l License) String() string {
return string(l)
}
// MarshalJSON 支持序列化
func (l License) MarshalJSON() ([]byte, error) {
return []byte(`"` + l.String() + `"`), nil
}
// UnmarshalJSON 支持反序列化
func (l *License) UnmarshalJSON(d []byte) error {
*l = License(strings.Trim(string(d), `"`))
return nil
}
const (
LicenseAfl30 License = "AFL-3.0"
LicenseAgpl30 License = "AGPL-3.0"
LicenseApache10 License = "Apache-1.0"
LicenseApache11 License = "Apache-1.1"
LicenseApache20 License = "Apache-2.0"
LicenseArtistic20 License = "Artistic-2.0"
LicenseBsd2Clause License = "BSD-2-Clause"
LicenseBsd3Clause License = "BSD-3-Clause"
LicenseBsd4Clause License = "BSD-4-Clause"
LicenseBsl10 License = "BSL-1.0"
LicenseCcBy40 License = "CC-BY-4.0"
LicenseCcBySa40 License = "CC-BY-SA-4.0"
LicenseCc010 License = "CC0-1.0"
LicenseEcl20 License = "ECL-2.0"
LicenseEpl10 License = "EPL-1.0"
LicenseEpl20 License = "EPL-2.0"
LicenseEupl11 License = "EUPL-1.1"
LicenseEupl12 License = "EUPL-1.2"
LicenseGpl20 License = "GPL-2.0"
LicenseGpl30 License = "GPL-3.0"
LicenseIsc License = "ISC"
LicenseLgpl21 License = "LGPL-2.1"
LicenseLgpl30 License = "LGPL-3.0"
LicenseLppl13c License = "LPPL-1.3c"
LicenseMit License = "MIT"
LicenseMpl20 License = "MPL-2.0"
LicenseMsPl License = "MS-PL"
LicenseMsRl License = "MS-RL"
LicenseMulanpsl10 License = "MulanPSL-1.0"
LicenseMulanpubl10 License = "MulanPubL-1.0"
LicenseMulanpubl20 License = "MulanPubL-2.0"
LicenseNcsa License = "NCSA"
LicenseOfl11 License = "OFL-1.1"
LicenseOsl30 License = "OSL-3.0"
LicensePostgresql License = "PostgreSQL"
LicenseUpl10 License = "UPL-1.0"
LicenseUnlicense License = "Unlicense"
LicenseWtfpl License = "WTFPL"
LicenseZlib License = "Zlib"
)
var (
// LicenseUrlTable 洗衣链接表
LicenseUrlTable = map[License]string{
LicenseAfl30: "https://spdx.org/licenses/AFL-3.0",
LicenseAgpl30: "https://www.gnu.org/licenses/agpl-3.0.txt",
LicenseApache10: "https://www.apache.org/licenses/LICENSE-1.0",
LicenseApache11: "https://www.apache.org/licenses/LICENSE-1.1",
LicenseApache20: "https://www.apache.org/licenses/LICENSE-2.0.txt",
LicenseArtistic20: "https://spdx.org/licenses/Artistic-2.0",
LicenseBsd2Clause: "https://opensource.org/license/BSD-2-Clause",
LicenseBsd3Clause: "https://opensource.org/license/BSD-3-Clause",
LicenseBsd4Clause: "https://directory.fsf.org/wiki/License:BSD-4-Clause",
LicenseBsl10: "https://www.boost.org/LICENSE_1_0.txt",
LicenseCcBy40: "https://creativecommons.org/licenses/by/4.0/legalcode.txt",
LicenseCcBySa40: "https://creativecommons.org/licenses/by-sa/4.0/legalcode.txt",
LicenseCc010: "https://creativecommons.org/publicdomain/zero/1.0/legalcode.txt",
LicenseEcl20: "https://opensource.org/license/ecl-2-0",
LicenseEpl10: "https://www.eclipse.org/org/documents/epl-1.0/EPL-1.0.txt",
LicenseEpl20: "https://www.eclipse.org/org/documents/epl-2.0/EPL-2.0.txt",
LicenseEupl11: "https://joinup.ec.europa.eu/sites/default/files/custom-page/attachment/eupl1.1.-licence-en_0.pdf",
LicenseEupl12: "https://joinup.ec.europa.eu/sites/default/files/custom-page/attachment/eupl_v1.2_en.pdf",
LicenseGpl20: "https://www.gnu.org/licenses/old-licenses/gpl-2.0.html#SEC1",
LicenseGpl30: "https://www.gnu.org/licenses/gpl-3.0.html#license-text",
LicenseIsc: "https://spdx.org/licenses/ISC",
LicenseLgpl21: "https://www.gnu.org/licenses/old-licenses/lgpl-2.1-standalone.html",
LicenseLgpl30: "https://www.gnu.org/licenses/lgpl-3.0-standalone.html",
LicenseLppl13c: "https://www.latex-project.org/lppl/lppl-1-3c.txt",
LicenseMit: "https://spdx.org/licenses/MIT",
LicenseMpl20: "https://www.mozilla.org/en-US/MPL/2.0/",
LicenseMsPl: "https://opensource.org/license/ms-pl-html",
LicenseMsRl: "https://opensource.org/license/ms-rl-html",
LicenseMulanpsl10: "http://license.coscl.org.cn/MulanPSL",
LicenseMulanpubl10: "http://license.coscl.org.cn/MulanPubL-1.0",
LicenseMulanpubl20: "http://license.coscl.org.cn/MulanPubL-2.0",
LicenseNcsa: "https://spdx.org/licenses/NCSA",
LicenseOfl11: "https://openfontlicense.org/documents/OFL.txt",
LicenseOsl30: "https://opensource.org/license/osl-3-0-php",
LicensePostgresql: "https://www.postgresql.org/about/licence/",
LicenseUpl10: "https://spdx.org/licenses/UPL-1.0",
LicenseUnlicense: "https://unlicense.org/",
LicenseWtfpl: "https://spdx.org/licenses/WTFPL",
LicenseZlib: "https://www.zlib.net/zlib_license.html",
}
)

95
geerate_option.go Normal file
View File

@ -0,0 +1,95 @@
// Package api_doc ...
//
// Description : api_doc ...
//
// Author : go_developer@163.com<白茶清欢>
//
// Date : 2025-08-23 09:30
package api_doc
import (
"git.zhangdeman.cn/gateway/api-doc/define"
"git.zhangdeman.cn/gateway/api-doc/enums"
)
// SetGenerateOption 设置文档生成选项
type SetGenerateOption func(opt *define.OpenapiDoc)
// generateOption 生成文档的一些配置选项
type generateOption struct {
license enums.License // 文档的license
description string // 文档的描述
title string // 文档的标题
}
// WithDocLicense 设置文档协议名称 + 协议链接
func WithDocLicense(l enums.License) SetGenerateOption {
return func(opt *define.OpenapiDoc) {
if l == "" {
return
}
opt.Info.License.Name = l
opt.Info.License.Url = enums.LicenseUrlTable[l]
}
}
// WithDocDescription 设置文档描述
func WithDocDescription(desc string) SetGenerateOption {
return func(opt *define.OpenapiDoc) {
if desc == "" {
return
}
opt.Info.Description = desc
}
}
// WithDocTitle 设置文档标题
func WithDocTitle(title string) SetGenerateOption {
return func(opt *define.OpenapiDoc) {
if len(title) == 0 {
return
}
opt.Info.Title = title
}
}
// WithDocVersion 设置文档版本
func WithDocVersion(version string) SetGenerateOption {
return func(opt *define.OpenapiDoc) {
opt.Info.Version = version
}
}
// WithDocContactName 设置文档联系人名称
func WithDocContactName(name string) SetGenerateOption {
return func(opt *define.OpenapiDoc) {
if name == "" {
return
}
opt.Info.Contact.Name = name
}
}
// WithDocContactEmail 设置文档联系人邮箱
func WithDocContactEmail(email string) SetGenerateOption {
return func(opt *define.OpenapiDoc) {
opt.Info.Contact.Email = email
}
}
// WithDocContactHomePage 设置文档联系人主页
func WithDocContactHomePage(url string) SetGenerateOption {
return func(opt *define.OpenapiDoc) {
opt.Info.Contact.Url = url
}
}
// WithDocServers 设置文档服务器列表
func WithDocServers(serverList []*define.ServerItem) SetGenerateOption {
return func(opt *define.OpenapiDoc) {
if len(serverList) == 0 {
return
}
opt.Servers = serverList
}
}

View File

@ -25,48 +25,39 @@ import (
// Author : go_developer@163.com<白茶清欢>
//
// Date : 15:56 2024/7/22
func NewOpenapiDoc(info *define.Info, servers []*define.ServerItem) *Generate {
if nil == info {
info = &define.Info{
func NewOpenapiDoc(ofs ...SetGenerateOption) *Generate {
// 初始默认值
docCfg := &define.OpenapiDoc{
Openapi: consts.SwaggerDocVersion3,
Info: &define.Info{
Description: "openapi接口文档",
Title: "openapi接口文档",
TermsOfService: "",
Contact: nil,
License: nil,
Version: "0.0.1",
}
Contact: &define.Contact{
Name: "研发人员(developer)",
Url: "",
Email: "",
},
License: &define.License{
Name: enums.LicenseApache20,
Url: enums.LicenseUrlTable[consts.LicenseApache20],
},
Version: "0.0.1",
},
Servers: []*define.ServerItem{},
Components: &define.Components{Schemas: map[string]*define.Schema{}},
Tags: make([]*define.TagItem, 0),
Paths: make(map[string]*define.PathConfig),
}
if len(info.Version) == 0 {
info.Version = "0.0.1"
}
if nil == info.License {
info.License = &define.License{
Name: consts.LicenseApache20,
Url: consts.LicenseUrlTable[consts.LicenseApache20],
}
}
if nil == info.Contact {
info.Contact = &define.Contact{
Name: "研发人员(developer)",
Url: "",
Email: "",
}
}
if nil == servers {
servers = []*define.ServerItem{}
for _, option := range ofs {
option(docCfg)
}
return &Generate{
readMethodList: []string{
http.MethodGet, http.MethodHead, http.MethodConnect, http.MethodOptions, http.MethodTrace,
},
docData: &define.OpenapiDoc{
Openapi: consts.SwaggerDocVersion3,
Info: info,
Servers: servers,
Components: &define.Components{Schemas: map[string]*define.Schema{}},
Tags: make([]*define.TagItem, 0),
Paths: make(map[string]*define.PathConfig),
},
docData: docCfg,
}
}

View File

@ -15,6 +15,7 @@ import (
"strings"
apiDocDefine "git.zhangdeman.cn/gateway/api-doc/define"
"git.zhangdeman.cn/zhangdeman/consts"
"git.zhangdeman.cn/zhangdeman/wrapper"
)

View File

@ -12,7 +12,9 @@ import (
"strings"
"git.zhangdeman.cn/gateway/api-doc/define"
"git.zhangdeman.cn/gateway/api-doc/enums"
"git.zhangdeman.cn/gateway/api-doc/util"
"git.zhangdeman.cn/zhangdeman/consts"
"git.zhangdeman.cn/zhangdeman/wrapper"
)
@ -25,7 +27,7 @@ func Generate(docConfig *define.SwaggerInput) (*define.Swagger, error) {
formatDocConfig(docConfig)
swaggerInfo := &define.Swagger{
Schemes: docConfig.Schemes,
Swagger: consts.SwaggerDocVersion2,
Swagger: enums.SwaggerDocVersion2.String(),
Host: docConfig.Host,
BasePath: docConfig.BasePath,
Info: docConfig.Info,
@ -228,7 +230,7 @@ func generateParameterDefinitions(swaggerInfo *define.Swagger, uri string, paren
if subPathArr[1] == "[]" {
swaggerInfo.Definitions[parentPath].Properties[subPathArr[0]] = &define.SwaggerDefinitionProperty{
Description: paramConfig.Description,
Type: consts.SwaggerDataTypeArray,
Type: enums.SwaggerDataTypeArray.String(),
Items: &define.SwaggerDefinitionPropertyItem{
Type: util.GetSwaggerType(paramConfig.Type),
Ref: "",
@ -242,7 +244,7 @@ func generateParameterDefinitions(swaggerInfo *define.Swagger, uri string, paren
} else {
swaggerInfo.Definitions[parentPath].Properties[subPathArr[0]] = &define.SwaggerDefinitionProperty{
Description: "参数描述",
Type: consts.SwaggerDataTypeObject,
Type: enums.SwaggerDataTypeObject.String(),
AllOf: []map[string]string{
{
consts.SwaggerRefKey: getRefValue(parentPath + "." + subPathArr[0]),