mirror of
				https://github.com/continew-org/continew-starter.git
				synced 2025-10-30 23:00:11 +08:00 
			
		
		
		
	feat(api-doc): 增加对 BaseEnum 枚举接口的详细展示
This commit is contained in:
		| @@ -17,17 +17,28 @@ | ||||
| package top.continew.starter.apidoc.autoconfigure; | ||||
|  | ||||
| import cn.hutool.core.map.MapUtil; | ||||
| import cn.hutool.core.util.ClassUtil; | ||||
| import cn.hutool.core.util.StrUtil; | ||||
| import com.fasterxml.jackson.databind.type.CollectionType; | ||||
| import com.fasterxml.jackson.databind.type.SimpleType; | ||||
| import io.swagger.v3.oas.models.Components; | ||||
| import io.swagger.v3.oas.models.OpenAPI; | ||||
| import io.swagger.v3.oas.models.info.Contact; | ||||
| import io.swagger.v3.oas.models.info.Info; | ||||
| import io.swagger.v3.oas.models.info.License; | ||||
| import io.swagger.v3.oas.models.media.Schema; | ||||
| import io.swagger.v3.oas.models.security.SecurityRequirement; | ||||
| import io.swagger.v3.oas.models.security.SecurityScheme; | ||||
| import jakarta.annotation.PostConstruct; | ||||
| import org.slf4j.Logger; | ||||
| import org.slf4j.LoggerFactory; | ||||
| import org.springdoc.core.customizers.GlobalOpenApiCustomizer; | ||||
| import org.springdoc.core.configuration.SpringDocConfiguration; | ||||
| import org.springdoc.core.customizers.*; | ||||
| import org.springdoc.core.properties.SpringDocConfigProperties; | ||||
| import org.springdoc.core.providers.JavadocProvider; | ||||
| import org.springdoc.core.service.OpenAPIService; | ||||
| import org.springdoc.core.service.SecurityService; | ||||
| import org.springdoc.core.utils.PropertyResolverUtils; | ||||
| import org.springframework.boot.autoconfigure.AutoConfiguration; | ||||
| import org.springframework.boot.autoconfigure.condition.ConditionalOnMissingBean; | ||||
| import org.springframework.boot.context.properties.EnableConfigurationProperties; | ||||
| @@ -37,11 +48,13 @@ import org.springframework.http.CacheControl; | ||||
| import org.springframework.web.servlet.config.annotation.EnableWebMvc; | ||||
| import org.springframework.web.servlet.config.annotation.ResourceHandlerRegistry; | ||||
| import org.springframework.web.servlet.config.annotation.WebMvcConfigurer; | ||||
| import top.continew.starter.apidoc.handler.OpenApiHandler; | ||||
| import top.continew.starter.apidoc.util.EnumTypeUtils; | ||||
| import top.continew.starter.core.autoconfigure.project.ProjectProperties; | ||||
| import top.continew.starter.core.enums.BaseEnum; | ||||
| import top.continew.starter.core.util.GeneralPropertySourceFactory; | ||||
|  | ||||
| import java.util.List; | ||||
| import java.util.Map; | ||||
| import java.util.*; | ||||
| import java.util.concurrent.TimeUnit; | ||||
|  | ||||
| /** | ||||
| @@ -51,7 +64,7 @@ import java.util.concurrent.TimeUnit; | ||||
|  * @since 1.0.0 | ||||
|  */ | ||||
| @EnableWebMvc | ||||
| @AutoConfiguration | ||||
| @AutoConfiguration(before = SpringDocConfiguration.class) | ||||
| @EnableConfigurationProperties(SpringDocExtensionProperties.class) | ||||
| @PropertySource(value = "classpath:default-api-doc.yml", factory = GeneralPropertySourceFactory.class) | ||||
| public class SpringDocAutoConfiguration implements WebMvcConfigurer { | ||||
| @@ -127,6 +140,112 @@ public class SpringDocAutoConfiguration implements WebMvcConfigurer { | ||||
|         }; | ||||
|     } | ||||
|  | ||||
|     /** | ||||
|      * 自定义 openapi 处理器 | ||||
|      */ | ||||
|     @Bean | ||||
|     public OpenAPIService openApiBuilder(Optional<OpenAPI> openAPI, | ||||
|                                          SecurityService securityParser, | ||||
|                                          SpringDocConfigProperties springDocConfigProperties, | ||||
|                                          PropertyResolverUtils propertyResolverUtils, | ||||
|                                          Optional<List<OpenApiBuilderCustomizer>> openApiBuilderCustomisers, | ||||
|                                          Optional<List<ServerBaseUrlCustomizer>> serverBaseUrlCustomisers, | ||||
|                                          Optional<JavadocProvider> javadocProvider) { | ||||
|         return new OpenApiHandler(openAPI, securityParser, springDocConfigProperties, propertyResolverUtils, openApiBuilderCustomisers, serverBaseUrlCustomisers, javadocProvider); | ||||
|     } | ||||
|  | ||||
|     /** | ||||
|      * 展示 枚举类型和值 | ||||
|      * | ||||
|      * @return | ||||
|      */ | ||||
|     @Bean | ||||
|     public ParameterCustomizer customParameterCustomizer() { | ||||
|         return (parameterModel, methodParameter) -> { | ||||
|             // 判断方法参数类型是否为 IBaseEnum 的子类型 | ||||
|             if (ClassUtil.isAssignable(BaseEnum.class, methodParameter.getParameterType())) { | ||||
|                 String description = parameterModel.getDescription(); | ||||
|                 // TODO 会重复调用,有什么优雅的判读方式吗? | ||||
|                 if (StrUtil.contains(description, "color:red")) { | ||||
|                     return parameterModel; | ||||
|                 } | ||||
|                 Schema schema = parameterModel.getSchema(); | ||||
|  | ||||
|                 // 获取方法参数类型的所有枚举常量 | ||||
|                 BaseEnum[] enumConstants = (BaseEnum[])methodParameter.getParameterType().getEnumConstants(); | ||||
|                 List<String> list = new ArrayList<>(); | ||||
|                 Map<Object, String> descMap = new HashMap<>(); | ||||
|  | ||||
|                 // 遍历枚举常量,获取其值和描述 | ||||
|                 for (BaseEnum constant : enumConstants) { | ||||
|                     list.add(constant.getValue().toString()); | ||||
|                     descMap.put(constant.getValue(), constant.getDescription()); | ||||
|                 } | ||||
|  | ||||
|                 // 枚举值类型 | ||||
|                 String enumValueType = EnumTypeUtils.getEnumValueTypeAsString(methodParameter.getParameterType()); | ||||
|                 schema.setType(enumValueType); | ||||
|                 switch (enumValueType) { | ||||
|                     case "integer" -> schema.setFormat("int32"); | ||||
|                     case "long" -> schema.setFormat("int64"); | ||||
|                     case "number" -> schema.setFormat("double"); | ||||
|                 } | ||||
|  | ||||
|                 // 设置枚举值列表和描述 | ||||
|                 schema.setEnum(list); | ||||
|                 parameterModel.setDescription(description + "<span style='color:red'>" + descMap + "</span>"); | ||||
|             } | ||||
|             return parameterModel; | ||||
|         }; | ||||
|     } | ||||
|  | ||||
|     /** | ||||
|      * 展示 枚举类型和值 | ||||
|      * | ||||
|      * @return | ||||
|      */ | ||||
|     @Bean | ||||
|     public PropertyCustomizer customPropertyCustomizer() { | ||||
|         return (schema, type) -> { | ||||
|             Class<?> rawClass; | ||||
|             // 获取原始类的类型 | ||||
|             if (type.getType() instanceof SimpleType) { | ||||
|                 rawClass = ((SimpleType)type.getType()).getRawClass(); | ||||
|             } else if (type.getType() instanceof CollectionType) { | ||||
|                 rawClass = ((CollectionType)type.getType()).getContentType().getRawClass(); | ||||
|             } else { | ||||
|                 rawClass = Object.class; | ||||
|             } | ||||
|  | ||||
|             // 检查原始类是否实现了 IBaseEnum 接口 | ||||
|             if (ClassUtil.isAssignable(BaseEnum.class, rawClass)) { | ||||
|                 BaseEnum[] enumConstants = (BaseEnum[])rawClass.getEnumConstants(); | ||||
|                 List<String> list = new ArrayList<>(); | ||||
|                 Map<Object, String> descMap = new HashMap<>(); | ||||
|                 // 遍历枚举常量,获取其值和描述 | ||||
|                 for (BaseEnum constant : enumConstants) { | ||||
|                     list.add(constant.getValue().toString()); | ||||
|                     descMap.put(constant.getValue(), constant.getDescription()); | ||||
|                 } | ||||
|                 // 获取泛型类型 | ||||
|                 String enumValueType = EnumTypeUtils.getEnumValueTypeAsString(rawClass); | ||||
|                 schema.setType(enumValueType); | ||||
|                 // 根据枚举值类型设置 schema 的格式 | ||||
|                 switch (enumValueType) { | ||||
|                     case "integer" -> schema.setFormat("int32"); | ||||
|                     case "long" -> schema.setFormat("int64"); | ||||
|                     case "number" -> schema.setFormat("double"); | ||||
|                 } | ||||
|  | ||||
|                 // 设置枚举值列表和描述 | ||||
|                 schema.setEnum(list); | ||||
|                 schema.setDescription(schema.getDescription() + "<span style='color:red'>" + descMap + "</span>"); | ||||
|                 return schema; | ||||
|             } | ||||
|             return schema; | ||||
|         }; | ||||
|     } | ||||
|  | ||||
|     @PostConstruct | ||||
|     public void postConstruct() { | ||||
|         log.debug("[ContiNew Starter] - Auto Configuration 'ApiDoc' completed initialization."); | ||||
|   | ||||
| @@ -0,0 +1,286 @@ | ||||
| /* | ||||
|  * Copyright (c) 2022-present Charles7c Authors. All Rights Reserved. | ||||
|  * <p> | ||||
|  * Licensed under the GNU LESSER GENERAL PUBLIC LICENSE 3.0; | ||||
|  * you may not use this file except in compliance with the License. | ||||
|  * You may obtain a copy of the License at | ||||
|  * <p> | ||||
|  * http://www.gnu.org/licenses/lgpl.html | ||||
|  * <p> | ||||
|  * Unless required by applicable law or agreed to in writing, software | ||||
|  * distributed under the License is distributed on an "AS IS" BASIS, | ||||
|  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. | ||||
|  * See the License for the specific language governing permissions and | ||||
|  * limitations under the License. | ||||
|  */ | ||||
|  | ||||
| package top.continew.starter.apidoc.handler; | ||||
|  | ||||
| import cn.hutool.core.collection.CollUtil; | ||||
| import cn.hutool.core.io.IoUtil; | ||||
| import io.swagger.v3.core.jackson.TypeNameResolver; | ||||
| import io.swagger.v3.core.util.AnnotationsUtils; | ||||
| import io.swagger.v3.oas.annotations.tags.Tags; | ||||
| import io.swagger.v3.oas.models.Components; | ||||
| import io.swagger.v3.oas.models.OpenAPI; | ||||
| import io.swagger.v3.oas.models.Operation; | ||||
| import io.swagger.v3.oas.models.Paths; | ||||
| import io.swagger.v3.oas.models.tags.Tag; | ||||
| import org.apache.commons.lang3.StringUtils; | ||||
| import org.springdoc.core.customizers.OpenApiBuilderCustomizer; | ||||
| import org.springdoc.core.customizers.ServerBaseUrlCustomizer; | ||||
| import org.springdoc.core.properties.SpringDocConfigProperties; | ||||
| import org.springdoc.core.providers.JavadocProvider; | ||||
| import org.springdoc.core.service.OpenAPIService; | ||||
| import org.springdoc.core.service.SecurityService; | ||||
| import org.springdoc.core.utils.PropertyResolverUtils; | ||||
| import org.springframework.context.ApplicationContext; | ||||
| import org.springframework.core.annotation.AnnotatedElementUtils; | ||||
| import org.springframework.util.CollectionUtils; | ||||
| import org.springframework.web.method.HandlerMethod; | ||||
|  | ||||
| import java.io.StringReader; | ||||
| import java.lang.reflect.Method; | ||||
| import java.util.*; | ||||
| import java.util.function.Function; | ||||
| import java.util.stream.Collectors; | ||||
| import java.util.stream.Stream; | ||||
|  | ||||
| /** | ||||
|  * 自定义 openapi 处理器 对源码功能进行修改 增强使用 | ||||
|  */ | ||||
| @SuppressWarnings("all") | ||||
| public class OpenApiHandler extends OpenAPIService { | ||||
|  | ||||
|     /** | ||||
|      * The Basic error controller. | ||||
|      */ | ||||
|     private static Class<?> basicErrorController; | ||||
|  | ||||
|     /** | ||||
|      * The Security parser. | ||||
|      */ | ||||
|     private final SecurityService securityParser; | ||||
|  | ||||
|     /** | ||||
|      * The Mappings map. | ||||
|      */ | ||||
|     private final Map<String, Object> mappingsMap = new HashMap<>(); | ||||
|  | ||||
|     /** | ||||
|      * The Springdoc tags. | ||||
|      */ | ||||
|     private final Map<HandlerMethod, Tag> springdocTags = new HashMap<>(); | ||||
|  | ||||
|     /** | ||||
|      * The Open api builder customisers. | ||||
|      */ | ||||
|     private final Optional<List<OpenApiBuilderCustomizer>> openApiBuilderCustomisers; | ||||
|  | ||||
|     /** | ||||
|      * The server base URL customisers. | ||||
|      */ | ||||
|     private final Optional<List<ServerBaseUrlCustomizer>> serverBaseUrlCustomizers; | ||||
|  | ||||
|     /** | ||||
|      * The Spring doc config properties. | ||||
|      */ | ||||
|     private final SpringDocConfigProperties springDocConfigProperties; | ||||
|  | ||||
|     /** | ||||
|      * The Cached open api map. | ||||
|      */ | ||||
|     private final Map<String, OpenAPI> cachedOpenAPI = new HashMap<>(); | ||||
|  | ||||
|     /** | ||||
|      * The Property resolver utils. | ||||
|      */ | ||||
|     private final PropertyResolverUtils propertyResolverUtils; | ||||
|  | ||||
|     /** | ||||
|      * The javadoc provider. | ||||
|      */ | ||||
|     private final Optional<JavadocProvider> javadocProvider; | ||||
|  | ||||
|     /** | ||||
|      * The Context. | ||||
|      */ | ||||
|     private ApplicationContext context; | ||||
|  | ||||
|     /** | ||||
|      * The Open api. | ||||
|      */ | ||||
|     private OpenAPI openAPI; | ||||
|  | ||||
|     /** | ||||
|      * The Is servers present. | ||||
|      */ | ||||
|     private boolean isServersPresent; | ||||
|  | ||||
|     /** | ||||
|      * The Server base url. | ||||
|      */ | ||||
|     private String serverBaseUrl; | ||||
|  | ||||
|     /** | ||||
|      * Instantiates a new Open api builder. | ||||
|      * | ||||
|      * @param openAPI                   the open api | ||||
|      * @param securityParser            the security parser | ||||
|      * @param springDocConfigProperties the spring doc config properties | ||||
|      * @param propertyResolverUtils     the property resolver utils | ||||
|      * @param openApiBuilderCustomizers the open api builder customisers | ||||
|      * @param serverBaseUrlCustomizers  the server base url customizers | ||||
|      * @param javadocProvider           the javadoc provider | ||||
|      */ | ||||
|     public OpenApiHandler(Optional<OpenAPI> openAPI, | ||||
|                           SecurityService securityParser, | ||||
|                           SpringDocConfigProperties springDocConfigProperties, | ||||
|                           PropertyResolverUtils propertyResolverUtils, | ||||
|                           Optional<List<OpenApiBuilderCustomizer>> openApiBuilderCustomizers, | ||||
|                           Optional<List<ServerBaseUrlCustomizer>> serverBaseUrlCustomizers, | ||||
|                           Optional<JavadocProvider> javadocProvider) { | ||||
|         super(openAPI, securityParser, springDocConfigProperties, propertyResolverUtils, openApiBuilderCustomizers, serverBaseUrlCustomizers, javadocProvider); | ||||
|         if (openAPI.isPresent()) { | ||||
|             this.openAPI = openAPI.get(); | ||||
|             if (this.openAPI.getComponents() == null) | ||||
|                 this.openAPI.setComponents(new Components()); | ||||
|             if (this.openAPI.getPaths() == null) | ||||
|                 this.openAPI.setPaths(new Paths()); | ||||
|             if (!CollectionUtils.isEmpty(this.openAPI.getServers())) | ||||
|                 this.isServersPresent = true; | ||||
|         } | ||||
|         this.propertyResolverUtils = propertyResolverUtils; | ||||
|         this.securityParser = securityParser; | ||||
|         this.springDocConfigProperties = springDocConfigProperties; | ||||
|         this.openApiBuilderCustomisers = openApiBuilderCustomizers; | ||||
|         this.serverBaseUrlCustomizers = serverBaseUrlCustomizers; | ||||
|         this.javadocProvider = javadocProvider; | ||||
|         if (springDocConfigProperties.isUseFqn()) | ||||
|             TypeNameResolver.std.setUseFqn(true); | ||||
|     } | ||||
|  | ||||
|     @Override | ||||
|     public Operation buildTags(HandlerMethod handlerMethod, Operation operation, OpenAPI openAPI, Locale locale) { | ||||
|  | ||||
|         Set<Tag> tags = new HashSet<>(); | ||||
|         Set<String> tagsStr = new HashSet<>(); | ||||
|  | ||||
|         buildTagsFromMethod(handlerMethod.getMethod(), tags, tagsStr, locale); | ||||
|         buildTagsFromClass(handlerMethod.getBeanType(), tags, tagsStr, locale); | ||||
|  | ||||
|         if (!CollectionUtils.isEmpty(tagsStr)) | ||||
|             tagsStr = tagsStr.stream() | ||||
|                 .map(str -> propertyResolverUtils.resolve(str, locale)) | ||||
|                 .collect(Collectors.toSet()); | ||||
|  | ||||
|         if (springdocTags.containsKey(handlerMethod)) { | ||||
|             Tag tag = springdocTags.get(handlerMethod); | ||||
|             tagsStr.add(tag.getName()); | ||||
|             if (openAPI.getTags() == null || !openAPI.getTags().contains(tag)) { | ||||
|                 openAPI.addTagsItem(tag); | ||||
|             } | ||||
|         } | ||||
|  | ||||
|         if (!CollectionUtils.isEmpty(tagsStr)) { | ||||
|             if (CollectionUtils.isEmpty(operation.getTags())) | ||||
|                 operation.setTags(new ArrayList<>(tagsStr)); | ||||
|             else { | ||||
|                 Set<String> operationTagsSet = new HashSet<>(operation.getTags()); | ||||
|                 operationTagsSet.addAll(tagsStr); | ||||
|                 operation.getTags().clear(); | ||||
|                 operation.getTags().addAll(operationTagsSet); | ||||
|             } | ||||
|         } | ||||
|  | ||||
|         if (isAutoTagClasses(operation)) { | ||||
|  | ||||
|             if (javadocProvider.isPresent()) { | ||||
|                 String description = javadocProvider.get().getClassJavadoc(handlerMethod.getBeanType()); | ||||
|                 if (StringUtils.isNotBlank(description)) { | ||||
|                     Tag tag = new Tag(); | ||||
|  | ||||
|                     // 自定义部分 修改使用java注释当tag名 | ||||
|                     List<String> list = IoUtil.readLines(new StringReader(description), new ArrayList<>()); | ||||
|                     // tag.setName(tagAutoName); | ||||
|                     tag.setName(list.get(0)); | ||||
|                     operation.addTagsItem(list.get(0)); | ||||
|  | ||||
|                     tag.setDescription(description); | ||||
|                     if (openAPI.getTags() == null || !openAPI.getTags().contains(tag)) { | ||||
|                         openAPI.addTagsItem(tag); | ||||
|                     } | ||||
|                 } | ||||
|             } else { | ||||
|                 String tagAutoName = splitCamelCase(handlerMethod.getBeanType().getSimpleName()); | ||||
|                 operation.addTagsItem(tagAutoName); | ||||
|             } | ||||
|         } | ||||
|  | ||||
|         if (!CollectionUtils.isEmpty(tags)) { | ||||
|             // Existing tags | ||||
|             List<Tag> openApiTags = openAPI.getTags(); | ||||
|             if (!CollectionUtils.isEmpty(openApiTags)) | ||||
|                 tags.addAll(openApiTags); | ||||
|             openAPI.setTags(new ArrayList<>(tags)); | ||||
|         } | ||||
|  | ||||
|         // Handle SecurityRequirement at operation level | ||||
|         io.swagger.v3.oas.annotations.security.SecurityRequirement[] securityRequirements = securityParser | ||||
|             .getSecurityRequirements(handlerMethod); | ||||
|         if (securityRequirements != null) { | ||||
|             if (securityRequirements.length == 0) | ||||
|                 operation.setSecurity(Collections.emptyList()); | ||||
|             else | ||||
|                 securityParser.buildSecurityRequirement(securityRequirements, operation); | ||||
|         } | ||||
|  | ||||
|         return operation; | ||||
|     } | ||||
|  | ||||
|     private void buildTagsFromMethod(Method method, Set<Tag> tags, Set<String> tagsStr, Locale locale) { | ||||
|         // method tags | ||||
|         Set<Tags> tagsSet = AnnotatedElementUtils.findAllMergedAnnotations(method, Tags.class); | ||||
|         Set<io.swagger.v3.oas.annotations.tags.Tag> methodTags = tagsSet.stream() | ||||
|             .flatMap(x -> Stream.of(x.value())) | ||||
|             .collect(Collectors.toSet()); | ||||
|         methodTags.addAll(AnnotatedElementUtils | ||||
|             .findAllMergedAnnotations(method, io.swagger.v3.oas.annotations.tags.Tag.class)); | ||||
|         if (!CollectionUtils.isEmpty(methodTags)) { | ||||
|             tagsStr.addAll(toSet(methodTags, tag -> propertyResolverUtils.resolve(tag.name(), locale))); | ||||
|             List<io.swagger.v3.oas.annotations.tags.Tag> allTags = new ArrayList<>(methodTags); | ||||
|             addTags(allTags, tags, locale); | ||||
|         } | ||||
|     } | ||||
|  | ||||
|     private void addTags(List<io.swagger.v3.oas.annotations.tags.Tag> sourceTags, Set<Tag> tags, Locale locale) { | ||||
|         Optional<Set<Tag>> optionalTagSet = AnnotationsUtils.getTags(sourceTags | ||||
|             .toArray(new io.swagger.v3.oas.annotations.tags.Tag[0]), true); | ||||
|         optionalTagSet.ifPresent(tagsSet -> { | ||||
|             tagsSet.forEach(tag -> { | ||||
|                 tag.name(propertyResolverUtils.resolve(tag.getName(), locale)); | ||||
|                 tag.description(propertyResolverUtils.resolve(tag.getDescription(), locale)); | ||||
|                 if (tags.stream().noneMatch(t -> t.getName().equals(tag.getName()))) | ||||
|                     tags.add(tag); | ||||
|             }); | ||||
|         }); | ||||
|     } | ||||
|  | ||||
|     /** | ||||
|      * 将collection转化为Set集合,但是两者的泛型不同<br> | ||||
|      * <B>{@code Collection<E>  ------>  Set<T> } </B> | ||||
|      * | ||||
|      * @param collection 需要转化的集合 | ||||
|      * @param function   collection中的泛型转化为set泛型的lambda表达式 | ||||
|      * @param <E>        collection中的泛型 | ||||
|      * @param <T>        Set中的泛型 | ||||
|      * @return 转化后的Set | ||||
|      */ | ||||
|     public static <E, T> Set<T> toSet(Collection<E> collection, Function<E, T> function) { | ||||
|         if (CollUtil.isEmpty(collection) || function == null) { | ||||
|             return CollUtil.newHashSet(); | ||||
|         } | ||||
|         return collection.stream().map(function).filter(Objects::nonNull).collect(Collectors.toSet()); | ||||
|     } | ||||
|  | ||||
| } | ||||
| @@ -0,0 +1,69 @@ | ||||
| /* | ||||
|  * Copyright (c) 2022-present Charles7c Authors. All Rights Reserved. | ||||
|  * <p> | ||||
|  * Licensed under the GNU LESSER GENERAL PUBLIC LICENSE 3.0; | ||||
|  * you may not use this file except in compliance with the License. | ||||
|  * You may obtain a copy of the License at | ||||
|  * <p> | ||||
|  * http://www.gnu.org/licenses/lgpl.html | ||||
|  * <p> | ||||
|  * Unless required by applicable law or agreed to in writing, software | ||||
|  * distributed under the License is distributed on an "AS IS" BASIS, | ||||
|  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. | ||||
|  * See the License for the specific language governing permissions and | ||||
|  * limitations under the License. | ||||
|  */ | ||||
|  | ||||
| package top.continew.starter.apidoc.util; | ||||
|  | ||||
| import top.continew.starter.core.enums.BaseEnum; | ||||
|  | ||||
| import java.lang.reflect.ParameterizedType; | ||||
| import java.lang.reflect.Type; | ||||
|  | ||||
| /** | ||||
|  * 枚举类型工具 | ||||
|  * | ||||
|  * @Author echo | ||||
|  * @date 2024/07/31 | ||||
|  */ | ||||
| public class EnumTypeUtils { | ||||
|  | ||||
|     /** | ||||
|      * 获取enum值类型 | ||||
|      * | ||||
|      * @param enumClass enum class | ||||
|      * @return {@link String } | ||||
|      */ | ||||
|     public static String getEnumValueTypeAsString(Class<?> enumClass) { | ||||
|         try { | ||||
|             // 获取枚举类实现的所有接口 | ||||
|             Type[] interfaces = enumClass.getGenericInterfaces(); | ||||
|             // 遍历所有接口 | ||||
|             for (Type type : interfaces) { | ||||
|                 // 检查接口是否为参数化类型 | ||||
|                 if (type instanceof ParameterizedType parameterizedType) { | ||||
|                     // 检查接口的原始类型是否为 BaseEnum | ||||
|                     if (parameterizedType.getRawType() == BaseEnum.class) { | ||||
|                         Type actualType = parameterizedType.getActualTypeArguments()[0]; | ||||
|                         // 检查实际类型参数是否为类类型 | ||||
|                         if (actualType instanceof Class<?> actualClass) { | ||||
|                             if (actualClass == Integer.class) { | ||||
|                                 return "integer"; | ||||
|                             } else if (actualClass == Long.class) { | ||||
|                                 return "long"; | ||||
|                             } else if (actualClass == Double.class) { | ||||
|                                 return "number"; | ||||
|                             } else if (actualClass == String.class) { | ||||
|                                 return "string"; | ||||
|                             } | ||||
|                         } | ||||
|                     } | ||||
|                 } | ||||
|             } | ||||
|         } catch (Exception e) { | ||||
|             e.printStackTrace(); | ||||
|         } | ||||
|         return "string"; | ||||
|     } | ||||
| } | ||||
		Reference in New Issue
	
	Block a user
	 吴泽威
					吴泽威