Files
api-doc/util/struct_field.go

204 lines
5.2 KiB
Go

// Package util ...
//
// Description : api_doc ...
//
// Author : go_developer@163.com<白茶清欢>
//
// Date : 2025-02-12 22:15
package util
import (
"reflect"
"strconv"
"strings"
"git.zhangdeman.cn/zhangdeman/api-doc/define"
utilPkg "git.zhangdeman.cn/zhangdeman/util"
)
var (
ParseStructFieldTag = parseStructFieldTag{}
)
type parseStructFieldTag struct {
}
// GetParamName 获取参数名称
func (psf parseStructFieldTag) GetParamName(structField reflect.StructField) (string, bool) {
paramNameTagList := []string{
define.TagJson, define.TagForm,
define.TagXml, define.TagYaml,
define.TagYml,
}
for _, tag := range paramNameTagList {
tagVal := structField.Tag.Get(tag)
if tagVal == "" {
continue
}
parts := strings.Split(tagVal, ",")
jsonName := ""
omit := false
if len(parts) > 0 {
if parts[0] == "-" {
return "", false // 跳过该字段
}
if parts[0] != "" {
jsonName = parts[0]
}
}
for _, part := range parts[1:] {
switch part {
case define.TagNameOmitempty:
omit = true
}
}
return jsonName, omit
}
// 未设置相关字段, 则字段名即为参数名
return structField.Name, false
}
// GetParamDesc ...
func (psf parseStructFieldTag) GetParamDesc(structField reflect.StructField) string {
descTagList := []string{define.TagDc, define.TagDesc, define.TagDescription}
for _, tag := range descTagList {
tagVal := structField.Tag.Get(tag)
if tagVal != "" {
return strings.ReplaceAll(tagVal, "###", "`")
}
}
// 没有显示的设置参数描述, 则使用参数名作为参数描述
paramName, _ := psf.GetParamName(structField)
return paramName
}
// GetDefaultValue 获取默认值
func (psf parseStructFieldTag) GetDefaultValue(structField reflect.StructField) any {
defaultTagList := []string{define.TagD, define.TagDefault}
fieldType := structField.Type.Kind().String()
for _, tag := range defaultTagList {
val, exist := structField.Tag.Lookup(tag)
val = strings.TrimSpace(val)
if !exist || len(val) == 0 {
continue
}
if strings.HasPrefix(fieldType, "int") {
i, _ := strconv.Atoi(val)
return i
}
if strings.HasPrefix(fieldType, "uint") {
uintVal, _ := strconv.ParseUint(val, 10, 64)
return uintVal
}
if strings.HasPrefix(fieldType, "float") {
floatVal, _ := strconv.ParseFloat(val, 64)
return floatVal
}
if strings.HasPrefix(fieldType, "string") {
return val
}
if strings.HasPrefix(fieldType, "bool") {
if val == "true" {
return true
} else {
return false
}
}
return val
}
return nil
}
// GetValidateRule 获取验证规则
func (psf parseStructFieldTag) GetValidateRule(structField reflect.StructField) string {
defaultTagList := []string{define.TagValidate, define.TagBinding}
for _, tag := range defaultTagList {
if tagVal, exist := structField.Tag.Lookup(tag); exist && len(tagVal) > 0 {
return tagVal
}
}
return ""
}
// Deprecated 是否弃用
func (psf parseStructFieldTag) Deprecated(structField reflect.StructField) bool {
defaultTagList := []string{define.TagDeprecated}
for _, tag := range defaultTagList {
if tagVal, exist := structField.Tag.Lookup(tag); exist && (tagVal == "1" || strings.ToLower(tagVal) == "true") {
return true
}
}
return false
}
// Summary 摘要信息
func (psf parseStructFieldTag) Summary(structField reflect.StructField) string {
defaultTagList := []string{define.TagSummary}
for _, tag := range defaultTagList {
if tagVal, exist := structField.Tag.Lookup(tag); exist && len(tagVal) > 0 {
return tagVal
}
}
paramName, _ := psf.GetParamName(structField)
return paramName
}
// EnumDescription .枚举值详细描述
func (psf parseStructFieldTag) EnumDescription(structField reflect.StructField) map[string]string {
defaultTagList := []string{define.TagNameEnumDescription}
res := make(map[string]string)
for _, tag := range defaultTagList {
if tagVal, exist := structField.Tag.Lookup(tag); exist && len(tagVal) > 0 {
tagVal = strings.ReplaceAll(tagVal, "###", "`")
enumList := strings.Split(tagVal, "||")
for _, enum := range enumList {
enumArr := strings.Split(enum, ":")
if len(enumArr) < 2 {
continue
}
res[enumArr[0]] = strings.Join(enumArr[1:], ":")
}
return res
}
}
return res
}
// GetExampleValue 示例值
func (psf parseStructFieldTag) GetExampleValue(structField reflect.StructField) any {
exampleTagList := []string{define.TagEg, define.TagExample}
structFieldType := structField.Type
if structFieldType.Kind() == reflect.Ptr {
structFieldType = structFieldType.Elem()
}
fieldTypeKind := structFieldType.Kind()
for _, tag := range exampleTagList {
example := strings.TrimSpace(structField.Tag.Get(tag))
if example == "" {
continue
}
switch fieldTypeKind {
case reflect.String:
return example
case reflect.Int, reflect.Int8, reflect.Int16, reflect.Int32, reflect.Int64:
var res int64
if err := utilPkg.ConvertAssign(&res, example); err == nil {
return res
}
case reflect.Float32, reflect.Float64:
var res float64
if err := utilPkg.ConvertAssign(&res, example); err == nil {
return res
}
case reflect.Bool:
var res bool
if err := utilPkg.ConvertAssign(&res, example); err == nil {
return res
}
default:
return example
}
}
return nil
}