2024-04-19 18:20:17 +08:00
|
|
|
|
// Package swagger ...
|
|
|
|
|
//
|
|
|
|
|
// Description : swagger ...
|
|
|
|
|
//
|
|
|
|
|
// Author : go_developer@163.com<白茶清欢>
|
|
|
|
|
//
|
|
|
|
|
// Date : 2024-04-19 18:16
|
|
|
|
|
package swagger
|
|
|
|
|
|
|
|
|
|
import (
|
|
|
|
|
"git.zhangdeman.cn/gateway/api-doc/define"
|
2024-04-22 11:54:03 +08:00
|
|
|
|
"git.zhangdeman.cn/gateway/api-doc/util"
|
|
|
|
|
"git.zhangdeman.cn/zhangdeman/consts"
|
|
|
|
|
"git.zhangdeman.cn/zhangdeman/wrapper"
|
|
|
|
|
"net/http"
|
|
|
|
|
"strings"
|
2024-04-19 18:20:17 +08:00
|
|
|
|
)
|
|
|
|
|
|
|
|
|
|
// Generate 生成文档
|
|
|
|
|
//
|
|
|
|
|
// Author : zhangdeman001@ke.com<张德满>
|
|
|
|
|
//
|
|
|
|
|
// Date : 18:17 2024/4/19
|
2024-04-22 11:54:03 +08:00
|
|
|
|
func Generate(docConfig *define.SwaggerInput) (*define.Swagger, error) {
|
|
|
|
|
formatDocConfig(docConfig)
|
|
|
|
|
swaggerInfo := &define.Swagger{
|
|
|
|
|
Schemes: docConfig.Schemes,
|
2024-04-25 16:34:22 +08:00
|
|
|
|
Swagger: consts.SwaggerDocVersion2,
|
2024-04-22 11:54:03 +08:00
|
|
|
|
Host: docConfig.Host,
|
|
|
|
|
BasePath: docConfig.BasePath,
|
|
|
|
|
Info: docConfig.Info,
|
2024-04-22 18:21:46 +08:00
|
|
|
|
Paths: map[string]map[string]*define.SwaggerPathConfig{},
|
|
|
|
|
Definitions: map[string]*define.SwaggerDefinition{},
|
2024-04-22 11:54:03 +08:00
|
|
|
|
}
|
2024-04-22 18:21:46 +08:00
|
|
|
|
generatePathConfig(swaggerInfo, docConfig)
|
2024-04-22 11:54:03 +08:00
|
|
|
|
return swaggerInfo, nil
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// formatDocConfig 格式化填充dock配置
|
|
|
|
|
//
|
|
|
|
|
// Author : go_developer@163.com<白茶清欢>
|
|
|
|
|
//
|
|
|
|
|
// Date : 10:54 2024/4/22
|
|
|
|
|
func formatDocConfig(docConfig *define.SwaggerInput) {
|
2024-04-22 18:21:46 +08:00
|
|
|
|
if len(docConfig.Schemes) == 0 {
|
2024-12-23 17:56:01 +08:00
|
|
|
|
docConfig.Schemes = []string{
|
|
|
|
|
consts.SchemeHTTP.String(),
|
|
|
|
|
}
|
2024-04-22 11:54:03 +08:00
|
|
|
|
}
|
2024-04-22 18:21:46 +08:00
|
|
|
|
docConfig.Host = wrapper.String(docConfig.Host).ReplaceChar(map[string]string{
|
2024-12-23 17:56:01 +08:00
|
|
|
|
consts.SchemeHTTP.String() + "://": "",
|
|
|
|
|
consts.SchemeHTTPS.String() + "://": "",
|
2024-04-22 18:21:46 +08:00
|
|
|
|
}).Value()
|
2024-04-22 11:54:03 +08:00
|
|
|
|
for _, itemPath := range docConfig.PathConfigList {
|
|
|
|
|
// 默认请求类型 application/json
|
|
|
|
|
itemPath.ContentType = strings.TrimSpace(itemPath.ContentType)
|
|
|
|
|
itemPath.ContentType = wrapper.TernaryOperator.String(len(itemPath.ContentType) == 0, consts.MimeTypeJson, wrapper.String(itemPath.ContentType)).Value()
|
|
|
|
|
// 默认post请求
|
|
|
|
|
itemPath.Method = strings.TrimSpace(itemPath.Method)
|
2024-04-22 18:55:03 +08:00
|
|
|
|
itemPath.Method = wrapper.TernaryOperator.String(len(itemPath.ContentType) == 0, wrapper.String(strings.ToLower(http.MethodPost)), wrapper.String(strings.ToLower(itemPath.Method))).Value()
|
2024-04-22 11:54:03 +08:00
|
|
|
|
// 默认summary
|
|
|
|
|
itemPath.Summary = strings.TrimSpace(itemPath.Summary)
|
|
|
|
|
itemPath.Summary = wrapper.TernaryOperator.String(len(itemPath.Summary) == 0, wrapper.String("接口 : "+itemPath.Uri), wrapper.String(itemPath.Summary)).Value()
|
|
|
|
|
// 默认标签
|
2025-02-07 21:27:33 +08:00
|
|
|
|
if len(itemPath.TagList) == 0 {
|
|
|
|
|
itemPath.TagList = []string{"未分组"}
|
|
|
|
|
}
|
2024-04-22 11:54:03 +08:00
|
|
|
|
for _, itemParam := range itemPath.ParameterList {
|
|
|
|
|
// 填充默认参数位置
|
|
|
|
|
itemParam.In = strings.TrimSpace(itemParam.In)
|
2024-04-22 18:21:46 +08:00
|
|
|
|
itemParam.In = wrapper.TernaryOperator.String(len(itemParam.In) == 0, wrapper.String(util.GetParameterDefaultLocation(itemPath.Method)), wrapper.String(itemParam.In)).Value()
|
2024-04-22 11:54:03 +08:00
|
|
|
|
|
|
|
|
|
// 参数类型没填, 按照字符串处理
|
|
|
|
|
itemParam.Type = strings.TrimSpace(itemParam.Type)
|
|
|
|
|
itemParam.Type = wrapper.TernaryOperator.String(len(itemParam.Type) == 0, wrapper.String(itemParam.Type), wrapper.String(itemParam.Type)).Value()
|
|
|
|
|
|
|
|
|
|
// 参数描述
|
|
|
|
|
itemParam.Description = strings.TrimSpace(itemParam.Description)
|
|
|
|
|
itemParam.Description = wrapper.TernaryOperator.String(len(itemParam.Description) == 0, wrapper.String(itemParam.Type+" : "+itemParam.Name), wrapper.String(itemParam.Description)).Value()
|
|
|
|
|
}
|
|
|
|
|
|
2024-04-22 18:55:03 +08:00
|
|
|
|
for _, itemResponseConfig := range itemPath.ResponseList {
|
|
|
|
|
for _, itemResponse := range itemResponseConfig.List {
|
|
|
|
|
// 默认返回数据类型
|
|
|
|
|
itemResponse.Type = strings.TrimSpace(itemResponse.Type)
|
2024-12-23 17:56:01 +08:00
|
|
|
|
itemResponse.Type = wrapper.TernaryOperator.String(len(itemResponse.Type) == 0, wrapper.String(consts.DataTypeString), wrapper.String(itemResponse.Type)).Value()
|
2024-04-22 18:55:03 +08:00
|
|
|
|
// 填充默认描述
|
|
|
|
|
itemResponse.Description = strings.TrimSpace(itemResponse.Description)
|
|
|
|
|
itemResponse.Description = wrapper.TernaryOperator.String(len(itemResponse.Description) == 0, wrapper.String(itemResponse.Type+" : "+itemResponse.Field), wrapper.String(itemResponse.Description)).Value()
|
|
|
|
|
}
|
2024-04-22 11:54:03 +08:00
|
|
|
|
}
|
|
|
|
|
}
|
2024-04-19 18:20:17 +08:00
|
|
|
|
}
|
2024-04-22 18:21:46 +08:00
|
|
|
|
|
|
|
|
|
// generatePathConfig 生成接口配置
|
|
|
|
|
//
|
|
|
|
|
// Author : go_developer@163.com<白茶清欢>
|
|
|
|
|
//
|
|
|
|
|
// Date : 12:00 2024/4/22
|
|
|
|
|
func generatePathConfig(swaggerInfo *define.Swagger, docConfig *define.SwaggerInput) {
|
|
|
|
|
for _, itemPath := range docConfig.PathConfigList {
|
|
|
|
|
itemPath.Uri = getUri(itemPath.Uri)
|
|
|
|
|
if _, exist := swaggerInfo.Paths[itemPath.Uri]; !exist {
|
|
|
|
|
swaggerInfo.Paths[itemPath.Uri] = map[string]*define.SwaggerPathConfig{}
|
|
|
|
|
}
|
|
|
|
|
// 处理请求类型的配置
|
|
|
|
|
swaggerInfo.Paths[itemPath.Uri][itemPath.Method] = &define.SwaggerPathConfig{
|
|
|
|
|
Description: itemPath.Description,
|
|
|
|
|
Consumes: []string{itemPath.ContentType},
|
|
|
|
|
Tags: itemPath.TagList,
|
|
|
|
|
Summary: itemPath.Summary,
|
|
|
|
|
Parameters: make([]*define.SwaggerPathConfigParameter, 0),
|
2024-04-22 18:55:03 +08:00
|
|
|
|
Responses: make(map[string]*define.SwaggerPathConfigResponse),
|
2024-04-22 18:21:46 +08:00
|
|
|
|
}
|
|
|
|
|
// 生成参数配置
|
|
|
|
|
generatePathParameterConfig(swaggerInfo, itemPath)
|
2024-04-25 16:45:32 +08:00
|
|
|
|
// 生成相应配置
|
|
|
|
|
generatePathResponseConfig(swaggerInfo, itemPath)
|
2024-04-22 18:21:46 +08:00
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// generatePathParameterConfig 生成接口的参数配置
|
|
|
|
|
//
|
|
|
|
|
// Author : go_developer@163.com<白茶清欢>
|
|
|
|
|
//
|
|
|
|
|
// Date : 12:09 2024/4/22
|
|
|
|
|
func generatePathParameterConfig(swaggerInfo *define.Swagger, pathConfig *define.SwaggerPathInput) {
|
|
|
|
|
swaggerInfo.Paths[pathConfig.Uri][pathConfig.Method].Parameters = make([]*define.SwaggerPathConfigParameter, 0)
|
|
|
|
|
hasDealTable := map[string]bool{}
|
|
|
|
|
|
|
|
|
|
for _, itemParamInput := range pathConfig.ParameterList {
|
|
|
|
|
if len(itemParamInput.Name) == 0 {
|
|
|
|
|
// 未指定参数名, 忽略
|
|
|
|
|
continue
|
|
|
|
|
}
|
|
|
|
|
// name 可能是 x.x.x 递归数组, 或者 x.x.[].x
|
|
|
|
|
namePath := strings.Split(itemParamInput.Name, ".")
|
2024-04-23 11:24:17 +08:00
|
|
|
|
realParamName := namePath[0]
|
|
|
|
|
parentPath := ""
|
2024-12-23 17:56:01 +08:00
|
|
|
|
if strings.ToUpper(itemParamInput.In) == consts.RequestDataLocationBody.String() && !strings.Contains(realParamName, ".") {
|
2024-04-23 11:24:17 +08:00
|
|
|
|
realParamName = "jsonBody"
|
2024-04-26 21:27:57 +08:00
|
|
|
|
parentPath = strings.ReplaceAll(pathConfig.Uri, ".", "-") + ".jsonBody"
|
2024-04-23 11:24:17 +08:00
|
|
|
|
}
|
|
|
|
|
generateParameterDefinitions(swaggerInfo, pathConfig.Uri, parentPath, itemParamInput.Name, itemParamInput)
|
2024-04-23 13:49:12 +08:00
|
|
|
|
if _, exist := hasDealTable[realParamName]; !exist {
|
|
|
|
|
hasDealTable[realParamName] = true
|
2024-04-23 11:24:17 +08:00
|
|
|
|
generateParam := &define.SwaggerPathConfigParameter{
|
2024-04-23 12:17:46 +08:00
|
|
|
|
Type: wrapper.TernaryOperator.String(realParamName == "jsonBody", "", wrapper.String(itemParamInput.Type)).Value(),
|
|
|
|
|
Description: wrapper.TernaryOperator.String(realParamName == "jsonBody", "参数结构", wrapper.String(itemParamInput.Description)).Value(),
|
2024-04-23 11:24:17 +08:00
|
|
|
|
Name: realParamName,
|
2024-04-22 18:21:46 +08:00
|
|
|
|
In: itemParamInput.In,
|
|
|
|
|
Required: itemParamInput.Required,
|
2025-02-07 21:27:33 +08:00
|
|
|
|
Schema: &define.SwaggerPathConfigParameterSchema{
|
|
|
|
|
Ref: "",
|
|
|
|
|
},
|
2024-04-23 11:24:17 +08:00
|
|
|
|
}
|
|
|
|
|
if len(parentPath) > 0 {
|
2025-02-07 21:27:33 +08:00
|
|
|
|
generateParam.Schema.Ref = getRefValue(pathConfig.Uri + ".jsonBody")
|
2024-04-23 12:19:02 +08:00
|
|
|
|
generateParam.Type = ""
|
2024-04-23 11:24:17 +08:00
|
|
|
|
}
|
|
|
|
|
swaggerInfo.Paths[pathConfig.Uri][pathConfig.Method].Parameters = append(swaggerInfo.Paths[pathConfig.Uri][pathConfig.Method].Parameters, generateParam)
|
2024-04-22 18:21:46 +08:00
|
|
|
|
}
|
|
|
|
|
}
|
2024-04-22 18:55:03 +08:00
|
|
|
|
|
2024-04-25 16:45:32 +08:00
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// generatePathResponseConfig 生成响应配置
|
|
|
|
|
//
|
|
|
|
|
// Author : go_developer@163.com<白茶清欢>
|
|
|
|
|
//
|
|
|
|
|
// Date : 16:43 2024/4/25
|
|
|
|
|
func generatePathResponseConfig(swaggerInfo *define.Swagger, pathConfig *define.SwaggerPathInput) {
|
|
|
|
|
hasDealResponseTable := map[string]bool{}
|
2024-04-23 12:17:46 +08:00
|
|
|
|
for _, itemResponseConfig := range pathConfig.ResponseList {
|
2024-04-22 18:55:03 +08:00
|
|
|
|
for _, itemResponseInput := range itemResponseConfig.List {
|
|
|
|
|
if len(itemResponseInput.Field) == 0 {
|
|
|
|
|
// 未指定参数名, 忽略
|
|
|
|
|
continue
|
|
|
|
|
}
|
|
|
|
|
// name 可能是 x.x.x 递归数组, 或者 x.x.[].x
|
2024-04-26 21:27:57 +08:00
|
|
|
|
outputDefine := strings.TrimLeft(strings.ReplaceAll(pathConfig.Uri, ".", "-"), "/") + "." + itemResponseConfig.Code + ".output"
|
2024-04-25 15:55:58 +08:00
|
|
|
|
generateParameterDefinitions(swaggerInfo, pathConfig.Uri, outputDefine, itemResponseInput.Field, &define.SwaggerParameterInput{
|
|
|
|
|
Type: itemResponseInput.Type,
|
|
|
|
|
Description: itemResponseInput.Description,
|
|
|
|
|
Name: itemResponseInput.Field,
|
2024-12-23 17:56:01 +08:00
|
|
|
|
In: consts.RequestDataLocationBody.String(),
|
2024-04-25 15:55:58 +08:00
|
|
|
|
Required: false,
|
|
|
|
|
EnumList: nil,
|
|
|
|
|
})
|
2024-04-22 18:55:03 +08:00
|
|
|
|
namePath := strings.Split(itemResponseInput.Field, ".")
|
|
|
|
|
if _, exist := hasDealResponseTable[namePath[0]]; !exist {
|
|
|
|
|
hasDealResponseTable[namePath[0]] = true
|
|
|
|
|
swaggerInfo.Paths[pathConfig.Uri][pathConfig.Method].Responses[itemResponseConfig.Code] = &define.SwaggerPathConfigResponse{
|
2024-04-23 12:17:46 +08:00
|
|
|
|
Description: "返回数据",
|
2024-12-23 17:56:01 +08:00
|
|
|
|
Schema: &define.SwaggerPathConfigResponseSchema{
|
|
|
|
|
Ref: getRefValue(outputDefine),
|
2024-04-22 18:55:03 +08:00
|
|
|
|
},
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
2024-04-23 12:17:46 +08:00
|
|
|
|
}
|
2024-04-22 18:21:46 +08:00
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// generateParameterDefinitions 生成请求参数的描述
|
|
|
|
|
//
|
|
|
|
|
// Author : go_developer@163.com<白茶清欢>
|
|
|
|
|
//
|
|
|
|
|
// Date : 14:06 2024/4/22
|
|
|
|
|
func generateParameterDefinitions(swaggerInfo *define.Swagger, uri string, parentPath string, subPath string, paramConfig *define.SwaggerParameterInput) {
|
2024-04-25 17:06:33 +08:00
|
|
|
|
setGlobalMapDefinition(swaggerInfo, paramConfig.Type)
|
2024-04-26 21:27:57 +08:00
|
|
|
|
uri = strings.ReplaceAll(strings.TrimLeft(uri, "/"), ".", "-")
|
2024-04-23 11:54:53 +08:00
|
|
|
|
parentPath = strings.TrimLeft(parentPath, "/")
|
2024-04-25 17:06:33 +08:00
|
|
|
|
checkPath := getCheckPath(parentPath)
|
2024-04-22 18:21:46 +08:00
|
|
|
|
subPathArr := strings.Split(subPath, ".")
|
2024-04-25 17:06:33 +08:00
|
|
|
|
initAnyDefinition(swaggerInfo, checkPath)
|
2024-04-23 11:24:17 +08:00
|
|
|
|
|
2024-04-22 18:21:46 +08:00
|
|
|
|
if len(subPathArr) == 1 {
|
2024-04-25 17:06:33 +08:00
|
|
|
|
handleOneLevelSubPath(swaggerInfo, uri, parentPath, subPath, paramConfig)
|
2024-04-22 18:21:46 +08:00
|
|
|
|
return
|
|
|
|
|
}
|
|
|
|
|
if len(parentPath) == 0 {
|
|
|
|
|
parentPath = uri + ".input"
|
|
|
|
|
}
|
|
|
|
|
if len(subPathArr) == 2 {
|
2024-04-25 17:58:28 +08:00
|
|
|
|
if subPathArr[0] != "[]" {
|
2024-04-25 16:34:22 +08:00
|
|
|
|
initAnyDefinition(swaggerInfo, parentPath)
|
2024-04-23 15:54:06 +08:00
|
|
|
|
}
|
2024-04-22 18:21:46 +08:00
|
|
|
|
if subPathArr[1] == "[]" {
|
|
|
|
|
swaggerInfo.Definitions[parentPath].Properties[subPathArr[0]] = &define.SwaggerDefinitionProperty{
|
|
|
|
|
Description: paramConfig.Description,
|
2024-04-25 17:06:33 +08:00
|
|
|
|
Type: consts.SwaggerDataTypeArray,
|
2025-02-07 21:27:33 +08:00
|
|
|
|
Items: &define.SwaggerDefinitionPropertyItem{
|
|
|
|
|
Type: util.GetSwaggerType(paramConfig.Type),
|
|
|
|
|
Ref: "",
|
|
|
|
|
Enum: nil,
|
2024-04-23 15:54:06 +08:00
|
|
|
|
},
|
2024-04-22 18:21:46 +08:00
|
|
|
|
}
|
|
|
|
|
} else {
|
2024-04-23 16:53:40 +08:00
|
|
|
|
if subPathArr[0] == "[]" {
|
2024-04-23 22:15:23 +08:00
|
|
|
|
generateParameterDefinitions(swaggerInfo, uri, parentPath+".item", subPathArr[1], paramConfig)
|
2024-04-23 16:53:40 +08:00
|
|
|
|
return
|
|
|
|
|
} else {
|
|
|
|
|
swaggerInfo.Definitions[parentPath].Properties[subPathArr[0]] = &define.SwaggerDefinitionProperty{
|
|
|
|
|
Description: "参数描述",
|
2024-04-25 16:34:22 +08:00
|
|
|
|
Type: consts.SwaggerDataTypeObject,
|
2024-04-25 17:06:33 +08:00
|
|
|
|
AllOf: []map[string]string{
|
|
|
|
|
{
|
|
|
|
|
consts.SwaggerRefKey: getRefValue(parentPath + "." + subPathArr[0]),
|
|
|
|
|
},
|
|
|
|
|
},
|
2024-04-23 16:53:40 +08:00
|
|
|
|
}
|
2024-04-23 14:43:23 +08:00
|
|
|
|
}
|
|
|
|
|
storageSubPath := parentPath + "." + subPathArr[0]
|
2024-04-23 16:53:40 +08:00
|
|
|
|
if subPathArr[1] == "[]" {
|
2024-04-23 20:47:10 +08:00
|
|
|
|
storageSubPath += ".item"
|
2024-04-23 16:53:40 +08:00
|
|
|
|
}
|
2024-04-25 16:34:22 +08:00
|
|
|
|
initAnyDefinition(swaggerInfo, storageSubPath)
|
|
|
|
|
swaggerInfo.Definitions[storageSubPath].Type = wrapper.TernaryOperator.String(strings.HasSuffix(parentPath, "[]"), "array", consts.SwaggerDataTypeObject).Value()
|
2024-04-25 17:06:33 +08:00
|
|
|
|
// 设置字段必传
|
|
|
|
|
addRequiredField(swaggerInfo, storageSubPath, subPathArr[1], paramConfig.Required)
|
2024-04-23 14:43:23 +08:00
|
|
|
|
swaggerInfo.Definitions[storageSubPath].Properties[subPathArr[1]] = &define.SwaggerDefinitionProperty{
|
|
|
|
|
Description: paramConfig.Description,
|
2024-04-23 15:54:06 +08:00
|
|
|
|
Type: util.GetSwaggerType(paramConfig.Type),
|
2024-04-23 14:43:23 +08:00
|
|
|
|
}
|
2024-04-22 18:21:46 +08:00
|
|
|
|
}
|
|
|
|
|
return
|
|
|
|
|
}
|
2024-04-23 15:54:06 +08:00
|
|
|
|
|
|
|
|
|
if _, exist := swaggerInfo.Definitions[parentPath].Properties[subPathArr[0]]; !exist {
|
2024-04-23 20:47:10 +08:00
|
|
|
|
if subPathArr[1] == "[]" {
|
|
|
|
|
nextParentPath := parentPath + "." + subPathArr[0] + ".item"
|
|
|
|
|
swaggerInfo.Definitions[parentPath].Properties[subPathArr[0]] = &define.SwaggerDefinitionProperty{
|
|
|
|
|
Description: "参数描述",
|
2024-04-25 17:06:33 +08:00
|
|
|
|
Type: consts.SwaggerDataTypeArray,
|
2025-02-07 21:27:33 +08:00
|
|
|
|
Items: &define.SwaggerDefinitionPropertyItem{
|
|
|
|
|
Type: "",
|
|
|
|
|
Ref: getRefValue(nextParentPath),
|
|
|
|
|
Enum: nil,
|
2024-04-23 20:47:10 +08:00
|
|
|
|
},
|
|
|
|
|
}
|
|
|
|
|
generateParameterDefinitions(swaggerInfo, uri, nextParentPath, strings.Join(subPathArr[2:], "."), paramConfig)
|
|
|
|
|
return
|
|
|
|
|
}
|
2024-04-23 16:53:40 +08:00
|
|
|
|
itemSwaggerDefinition := &define.SwaggerDefinitionProperty{
|
2024-04-23 15:54:06 +08:00
|
|
|
|
Description: "对象描述",
|
2024-04-25 16:34:22 +08:00
|
|
|
|
Type: wrapper.TernaryOperator.String(subPathArr[1] == "[]", "array", consts.SwaggerDataTypeObject).Value(),
|
2024-04-23 15:54:06 +08:00
|
|
|
|
Items: nil,
|
2024-04-23 16:53:40 +08:00
|
|
|
|
AllOf: nil,
|
|
|
|
|
}
|
2024-04-25 16:34:22 +08:00
|
|
|
|
if itemSwaggerDefinition.Type == consts.SwaggerDataTypeObject {
|
2024-04-23 16:53:40 +08:00
|
|
|
|
itemSwaggerDefinition.AllOf = []map[string]string{map[string]string{
|
2024-04-25 17:06:33 +08:00
|
|
|
|
consts.SwaggerRefKey: getRefValue(parentPath + "." + subPathArr[0]),
|
2024-04-23 16:53:40 +08:00
|
|
|
|
}}
|
2024-04-25 17:06:33 +08:00
|
|
|
|
} else if itemSwaggerDefinition.Type == consts.SwaggerDataTypeArray {
|
2024-04-23 16:53:40 +08:00
|
|
|
|
itemSwaggerDefinition.Description = "数组描述"
|
2025-02-07 21:27:33 +08:00
|
|
|
|
itemSwaggerDefinition.Items = &define.SwaggerDefinitionPropertyItem{
|
|
|
|
|
Type: "",
|
|
|
|
|
Ref: getRefValue(parentPath + "." + subPathArr[0] + ".item"),
|
|
|
|
|
Enum: nil,
|
2024-04-23 16:53:40 +08:00
|
|
|
|
}
|
2024-04-23 15:54:06 +08:00
|
|
|
|
}
|
2024-04-23 16:53:40 +08:00
|
|
|
|
swaggerInfo.Definitions[parentPath].Properties[subPathArr[0]] = itemSwaggerDefinition
|
2024-04-23 15:54:06 +08:00
|
|
|
|
}
|
2024-04-22 18:21:46 +08:00
|
|
|
|
generateParameterDefinitions(swaggerInfo, uri, parentPath+"."+subPathArr[0], strings.Join(subPathArr[1:], "."), paramConfig)
|
|
|
|
|
}
|
|
|
|
|
|
2024-04-25 17:06:33 +08:00
|
|
|
|
// handleOneLevelSubPath 处理subPath一层的情况
|
|
|
|
|
//
|
|
|
|
|
// Author : go_developer@163.com<白茶清欢>
|
|
|
|
|
//
|
|
|
|
|
// Date : 16:50 2024/4/25
|
|
|
|
|
func handleOneLevelSubPath(swaggerInfo *define.Swagger, uri string, parentPath string, subPath string, paramConfig *define.SwaggerParameterInput) {
|
2024-12-23 17:56:01 +08:00
|
|
|
|
if paramConfig.In != strings.ToLower(consts.RequestDataLocationBody.String()) && !isGenerateOutput(parentPath) {
|
2024-04-25 17:06:33 +08:00
|
|
|
|
// 长度为1, 还不在 body, 无需生成结构体
|
|
|
|
|
return
|
|
|
|
|
}
|
2024-04-26 21:27:57 +08:00
|
|
|
|
if strings.HasSuffix(paramConfig.Type, "[]") {
|
|
|
|
|
swaggerInfo.Definitions[parentPath].Properties[subPath] = &define.SwaggerDefinitionProperty{
|
|
|
|
|
Description: paramConfig.Description,
|
|
|
|
|
Type: consts.SwaggerDataTypeArray,
|
2025-02-07 21:27:33 +08:00
|
|
|
|
Items: &define.SwaggerDefinitionPropertyItem{
|
|
|
|
|
Type: util.GetSwaggerType(strings.TrimSuffix(paramConfig.Type, "[]")),
|
|
|
|
|
Ref: "",
|
|
|
|
|
Enum: nil,
|
2024-04-26 21:27:57 +08:00
|
|
|
|
},
|
|
|
|
|
}
|
|
|
|
|
return
|
|
|
|
|
}
|
2024-04-25 17:21:42 +08:00
|
|
|
|
if isGlobalMapType(paramConfig.Type) {
|
|
|
|
|
swaggerInfo.Definitions[parentPath].Properties[subPath] = &define.SwaggerDefinitionProperty{
|
|
|
|
|
Description: paramConfig.Description,
|
|
|
|
|
Type: consts.SwaggerDataTypeObject,
|
|
|
|
|
AllOf: []map[string]string{
|
|
|
|
|
{
|
|
|
|
|
consts.SwaggerRefKey: getRefValue(consts.SwaggerBaseObjectDefinitionName),
|
|
|
|
|
},
|
|
|
|
|
},
|
|
|
|
|
}
|
|
|
|
|
return
|
|
|
|
|
}
|
2024-04-25 17:06:33 +08:00
|
|
|
|
initAnyDefinition(swaggerInfo, parentPath)
|
|
|
|
|
if paramConfig.Required {
|
|
|
|
|
swaggerInfo.Definitions[parentPath].Required = append(swaggerInfo.Definitions[parentPath].Required, subPath)
|
|
|
|
|
}
|
|
|
|
|
swaggerInfo.Definitions[parentPath].Properties[subPath] = &define.SwaggerDefinitionProperty{
|
|
|
|
|
Description: paramConfig.Description,
|
|
|
|
|
Type: util.GetSwaggerType(paramConfig.Type),
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
2024-04-25 15:55:58 +08:00
|
|
|
|
func getUri(uri string) string {
|
|
|
|
|
return "/" + strings.TrimLeft(uri, "/")
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// setGlobalMapDefinition ...
|
2024-04-22 18:55:03 +08:00
|
|
|
|
//
|
|
|
|
|
// Author : go_developer@163.com<白茶清欢>
|
|
|
|
|
//
|
2024-04-25 15:55:58 +08:00
|
|
|
|
// Date : 15:38 2024/4/25
|
2024-04-25 17:06:33 +08:00
|
|
|
|
func setGlobalMapDefinition(swaggerInfo *define.Swagger, dataType string) {
|
|
|
|
|
if !isGlobalMapType(dataType) {
|
|
|
|
|
return
|
|
|
|
|
}
|
2024-04-25 17:21:42 +08:00
|
|
|
|
// 只要最终类型存在mao, 就一定会用到 consts.SwaggerBaseObjectDefinitionName
|
2024-04-22 18:55:03 +08:00
|
|
|
|
if nil == swaggerInfo.Definitions {
|
|
|
|
|
swaggerInfo.Definitions = map[string]*define.SwaggerDefinition{}
|
|
|
|
|
}
|
2024-04-25 17:21:42 +08:00
|
|
|
|
if _, exist := swaggerInfo.Definitions[consts.SwaggerBaseObjectDefinitionName]; exist {
|
2024-04-22 18:55:03 +08:00
|
|
|
|
return
|
|
|
|
|
}
|
2024-04-25 17:21:42 +08:00
|
|
|
|
swaggerInfo.Definitions[consts.SwaggerBaseObjectDefinitionName] = &define.SwaggerDefinition{
|
2024-04-25 16:34:22 +08:00
|
|
|
|
Type: consts.SwaggerDataTypeObject,
|
2024-04-25 17:06:33 +08:00
|
|
|
|
Required: make([]string, 0),
|
2024-04-25 15:55:58 +08:00
|
|
|
|
Properties: make(map[string]*define.SwaggerDefinitionProperty),
|
2024-04-23 20:47:10 +08:00
|
|
|
|
}
|
2024-04-22 18:55:03 +08:00
|
|
|
|
}
|
|
|
|
|
|
2024-04-25 15:55:58 +08:00
|
|
|
|
// isGlobalMapType ...
|
|
|
|
|
//
|
|
|
|
|
// Author : go_developer@163.com<白茶清欢>
|
|
|
|
|
//
|
|
|
|
|
// Date : 15:46 2024/4/25
|
2024-04-25 16:34:22 +08:00
|
|
|
|
func isGlobalMapType(dataType string) bool {
|
2024-04-25 15:55:58 +08:00
|
|
|
|
return wrapper.ArrayType([]string{
|
2024-12-23 17:56:01 +08:00
|
|
|
|
consts.DataTypeMapAnyAny.String(),
|
|
|
|
|
consts.DataTypeMapStrUint.String(),
|
|
|
|
|
consts.DataTypeMapStrInt.String(),
|
|
|
|
|
consts.DataTypeMapStrSlice.String(),
|
|
|
|
|
consts.DataTypeMapStrFloat.String(),
|
|
|
|
|
consts.DataTypeMapStrBool.String(),
|
|
|
|
|
consts.DataTypeMapStrAny.String(),
|
2024-04-25 15:55:58 +08:00
|
|
|
|
}).Has(dataType) >= 0
|
2024-04-22 18:21:46 +08:00
|
|
|
|
}
|
2024-04-25 16:34:22 +08:00
|
|
|
|
|
|
|
|
|
// initAnyDefinition 初始化一个definition
|
|
|
|
|
//
|
|
|
|
|
// Author : go_developer@163.com<白茶清欢>
|
|
|
|
|
//
|
|
|
|
|
// Date : 16:21 2024/4/25
|
|
|
|
|
func initAnyDefinition(swaggerInfo *define.Swagger, definitionName string) {
|
2024-04-25 17:06:33 +08:00
|
|
|
|
if len(definitionName) == 0 {
|
|
|
|
|
return
|
|
|
|
|
}
|
2024-04-25 16:34:22 +08:00
|
|
|
|
if nil == swaggerInfo.Definitions {
|
|
|
|
|
swaggerInfo.Definitions = map[string]*define.SwaggerDefinition{}
|
|
|
|
|
}
|
|
|
|
|
if _, exist := swaggerInfo.Definitions[definitionName]; exist {
|
|
|
|
|
return
|
|
|
|
|
}
|
|
|
|
|
swaggerInfo.Definitions[definitionName] = &define.SwaggerDefinition{
|
|
|
|
|
Type: consts.SwaggerDataTypeObject,
|
2024-12-23 17:56:01 +08:00
|
|
|
|
Format: consts.DataTypeMapStrAny.String(),
|
2024-04-25 16:34:22 +08:00
|
|
|
|
Required: make([]string, 0),
|
|
|
|
|
Properties: make(map[string]*define.SwaggerDefinitionProperty),
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// getRefValue 获取refValue
|
|
|
|
|
//
|
|
|
|
|
// Author : go_developer@163.com<白茶清欢>
|
|
|
|
|
//
|
|
|
|
|
// Date : 16:31 2024/4/25
|
|
|
|
|
func getRefValue(path string) string {
|
2024-04-25 16:45:32 +08:00
|
|
|
|
return consts.SwaggerRefValPrefix + strings.TrimLeft(path, "/")
|
2024-04-25 16:34:22 +08:00
|
|
|
|
}
|
2024-04-25 17:06:33 +08:00
|
|
|
|
|
|
|
|
|
// addRequiredField 添加必传字段
|
|
|
|
|
//
|
|
|
|
|
// Author : go_developer@163.com<白茶清欢>
|
|
|
|
|
//
|
|
|
|
|
// Date : 16:57 2024/4/25
|
|
|
|
|
func addRequiredField(swaggerInfo *define.Swagger, definitionName string, field string, isRequired bool) {
|
|
|
|
|
if !isRequired {
|
|
|
|
|
return
|
|
|
|
|
}
|
|
|
|
|
swaggerInfo.Definitions[definitionName].Required = append(swaggerInfo.Definitions[definitionName].Required, definitionName)
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// getCheckPath 获取检查的Definition
|
|
|
|
|
//
|
|
|
|
|
// Author : go_developer@163.com<白茶清欢>
|
|
|
|
|
//
|
|
|
|
|
// Date : 17:01 2024/4/25
|
|
|
|
|
func getCheckPath(parentPath string) string {
|
|
|
|
|
parentPathArr := strings.Split(parentPath, ".")
|
2024-04-25 17:54:15 +08:00
|
|
|
|
if isGenerateOutput(parentPath) {
|
|
|
|
|
return strings.Join([]string{parentPathArr[0], parentPathArr[1], parentPathArr[2]}, ".")
|
|
|
|
|
} else {
|
|
|
|
|
if len(parentPathArr) >= 2 {
|
|
|
|
|
return strings.Join([]string{parentPathArr[0], parentPathArr[1]}, ".")
|
|
|
|
|
}
|
2024-04-25 17:06:33 +08:00
|
|
|
|
}
|
|
|
|
|
return parentPath
|
|
|
|
|
}
|
2024-04-25 17:54:15 +08:00
|
|
|
|
|
|
|
|
|
// isGenerateOutput ...
|
|
|
|
|
//
|
|
|
|
|
// Author : go_developer@163.com<白茶清欢>
|
|
|
|
|
//
|
|
|
|
|
// Date : 17:52 2024/4/25
|
|
|
|
|
func isGenerateOutput(parentPath string) bool {
|
|
|
|
|
parentPathArr := strings.Split(parentPath, ".")
|
|
|
|
|
if len(parentPathArr) >= 3 && parentPathArr[2] == "output" {
|
|
|
|
|
return true
|
|
|
|
|
}
|
|
|
|
|
return false
|
|
|
|
|
}
|