diff --git a/axzo-common-autoconfigure/src/main/java/cn/axzo/framework/autoconfigure/web/rest/EnumResource.java b/axzo-common-autoconfigure/src/main/java/cn/axzo/framework/autoconfigure/web/rest/EnumResource.java new file mode 100644 index 0000000..c38141e --- /dev/null +++ b/axzo-common-autoconfigure/src/main/java/cn/axzo/framework/autoconfigure/web/rest/EnumResource.java @@ -0,0 +1,164 @@ +package cn.axzo.framework.autoconfigure.web.rest; + +import cn.axzo.framework.autoconfigure.web.rest.vo.EnumItemVO; +import cn.axzo.framework.autoconfigure.web.rest.vo.EnumMetaVO; +import cn.axzo.framework.core.InternalException; +import cn.axzo.framework.core.enums.ICode; +import cn.axzo.framework.core.enums.IStringCode; +import cn.axzo.framework.core.enums.meta.EnumMeta; +import cn.axzo.framework.core.enums.meta.IntCode; +import cn.axzo.framework.core.io.Resources; +import cn.axzo.framework.core.util.ClassUtil; +import cn.axzo.framework.core.util.StringUtil; +import cn.axzo.framework.domain.web.code.IRespCode; +import cn.axzo.framework.domain.web.result.ApiListResult; +import cn.axzo.framework.domain.web.result.ApiResult; +import io.micrometer.core.annotation.Timed; +import io.swagger.annotations.Api; +import io.swagger.annotations.ApiOperation; +import lombok.RequiredArgsConstructor; +import lombok.extern.slf4j.Slf4j; +import lombok.val; +import org.jooq.lambda.Seq; +import org.springframework.beans.factory.BeanClassLoaderAware; +import org.springframework.boot.autoconfigure.condition.ConditionalOnProperty; +import org.springframework.boot.autoconfigure.condition.ConditionalOnWebApplication; +import org.springframework.web.bind.annotation.GetMapping; +import org.springframework.web.bind.annotation.RequestMapping; +import org.springframework.web.bind.annotation.RestController; + +import java.util.ArrayList; +import java.util.Arrays; +import java.util.List; +import java.util.Map; +import java.util.function.Function; + +import static cn.axzo.framework.core.enums.meta.EnumType.INT_ENUM; +import static cn.axzo.framework.core.enums.meta.EnumType.STRING_ENUM; +import static java.util.stream.Collectors.toList; + +/** + * @Author: liyong.tian + * @Date: 2023/3/21 15:26 + * @Description: + */ +@Slf4j +@Api(tags = "Enum API") +@RequestMapping("/webApi/v1") +@ConditionalOnProperty(value = "spring.rest.enum-resource.enabled", havingValue = "true") +@ConditionalOnWebApplication +@RestController +@RequiredArgsConstructor +public class EnumResource implements BeanClassLoaderAware { + + private ClassLoader classLoader = ClassUtil.getDefaultClassLoader(); + + private final RestResourceProperties properties; + + @ApiOperation("获取枚举列表") + @GetMapping("/enums") + public ApiResult> getEnums() { + log.info("REST request to get a list of Enums"); + val enumMetas = Seq.of(properties.getEnumResource().getScanPackages()) + .flatMap(pkg -> findClassPathEnums(pkg, classLoader).stream()) + .filter(EnumMeta::isNotDeprecated) + .toList(); + Function keyMapper = enumMeta -> StringUtil.uncapitalize(enumMeta.getSimpleName()); + Function> valueMapper = enumMeta -> { + switch (enumMeta.getEnumType()) { + case INT_ENUM: + return enumMeta.getIntCodes() + .stream() + .map(iCode -> new EnumItemVO(iCode.getCode(), iCode.getName())) + .collect(toList()); + case STRING_ENUM: + return enumMeta.getStringCodes() + .stream() + .map(iCode -> new EnumItemVO(iCode.getCode(), iCode.getName())) + .collect(toList()); + default: + throw new InternalException("will not happen!"); + } + }; + Map map = Seq.seq(enumMetas).toMap(keyMapper, valueMapper); + return ApiResult.ok(map); + } + + @ApiOperation("获取枚举文档") + @GetMapping("/enums/doc") + @Timed + public ApiListResult getEnumDocs() { + val enumMetas = Seq.of(properties.getEnumResource().getScanPackages()) + .flatMap(pkg -> findClassPathEnums(pkg, classLoader).stream()) + .filter(EnumMeta::isNotDeprecated) + .map(enumMeta -> { + List items; + switch (enumMeta.getEnumType()) { + case INT_ENUM: + items = enumMeta.getIntCodes() + .stream() + .map(iCode -> new EnumItemVO(iCode.getCode(), iCode.getName())) + .collect(toList()); + break; + case STRING_ENUM: + items = enumMeta.getStringCodes() + .stream() + .map(iCode -> new EnumItemVO(iCode.getCode(), iCode.getName())) + .collect(toList()); + break; + default: + throw new InternalException("will not happen!"); + } + return new EnumMetaVO() + .setClassName(enumMeta.getClassName()) + .setDescription(enumMeta.getDescription()) + .setEnumType(enumMeta.getEnumType().getName()) + .setSimpleName(enumMeta.getSimpleName()) + .setItems(Seq.seq(items).distinct(EnumItemVO::getCode).toMap(EnumItemVO::getCode, EnumItemVO::getName)); + }) + .toList(); + return ApiListResult.ok(enumMetas); + } + + public static List findClassPathEnums(String packageName, ClassLoader classLoader) { + return _findEnumMetas(Resources.findEnumClasses(packageName, classLoader)); + } + + private static List _findEnumMetas(Class>[] classes) { + List enumMetas = new ArrayList<>(); + Arrays.stream(classes).forEach(clazz -> { + // int code + if (ICode.class.isAssignableFrom(clazz)) { + EnumMeta enumMeta = new EnumMeta(clazz, INT_ENUM); + Arrays.stream(clazz.getEnumConstants()).forEach(aEnum -> enumMeta.addIntCode((ICode) aEnum)); + enumMetas.add(enumMeta); + return; + } + + // string code + if (IStringCode.class.isAssignableFrom(clazz)) { + EnumMeta enumMeta; + if (IRespCode.class.isAssignableFrom(clazz)) { + // int code + enumMeta = new EnumMeta(clazz, INT_ENUM); + Arrays.stream(clazz.getEnumConstants()).forEach(aEnum -> { + IRespCode respCode = (IRespCode) aEnum; + IntCode code = new IntCode(StringUtil.parseInt(respCode.getRespCode()), respCode.getMessage()); + enumMeta.addIntCode(code); + }); + } else { + // string code + enumMeta = new EnumMeta(clazz, STRING_ENUM); + Arrays.stream(clazz.getEnumConstants()).forEach(aEnum -> enumMeta.addStringCode((IStringCode) aEnum)); + } + enumMetas.add(enumMeta); + } + }); + return enumMetas; + } + + @Override + public void setBeanClassLoader(ClassLoader classLoader) { + this.classLoader = classLoader; + } +} diff --git a/axzo-common-autoconfigure/src/main/java/cn/axzo/framework/autoconfigure/web/rest/RestResourceProperties.java b/axzo-common-autoconfigure/src/main/java/cn/axzo/framework/autoconfigure/web/rest/RestResourceProperties.java new file mode 100644 index 0000000..8010fd7 --- /dev/null +++ b/axzo-common-autoconfigure/src/main/java/cn/axzo/framework/autoconfigure/web/rest/RestResourceProperties.java @@ -0,0 +1,32 @@ +package cn.axzo.framework.autoconfigure.web.rest; + +import lombok.Data; +import lombok.Getter; +import org.springframework.boot.context.properties.ConfigurationProperties; +import org.springframework.validation.annotation.Validated; + +import javax.validation.Valid; +import javax.validation.constraints.NotNull; + +/** + * @Author: liyong.tian + * @Date: 2023/3/21 15:44 + * @Description: + */ +@Validated +@Getter +@ConfigurationProperties("spring.rest") +public class RestResourceProperties { + + @Valid + private final EnumResource enumResource = new EnumResource(); + + @Data + public class EnumResource { + + private boolean enabled; + + @NotNull + private String[] scanPackages = {}; + } +} diff --git a/axzo-common-autoconfigure/src/main/java/cn/axzo/framework/autoconfigure/web/rest/vo/EnumItemVO.java b/axzo-common-autoconfigure/src/main/java/cn/axzo/framework/autoconfigure/web/rest/vo/EnumItemVO.java new file mode 100644 index 0000000..cf7773c --- /dev/null +++ b/axzo-common-autoconfigure/src/main/java/cn/axzo/framework/autoconfigure/web/rest/vo/EnumItemVO.java @@ -0,0 +1,18 @@ +package cn.axzo.framework.autoconfigure.web.rest.vo; + +import lombok.AllArgsConstructor; +import lombok.Data; + +/** + * @Author: liyong.tian + * @Date: 2023/3/21 15:53 + * @Description: + */ +@Data +@AllArgsConstructor +public class EnumItemVO { + + private Object code; + + private String name; +} diff --git a/axzo-common-autoconfigure/src/main/java/cn/axzo/framework/autoconfigure/web/rest/vo/EnumMetaVO.java b/axzo-common-autoconfigure/src/main/java/cn/axzo/framework/autoconfigure/web/rest/vo/EnumMetaVO.java new file mode 100644 index 0000000..578c64c --- /dev/null +++ b/axzo-common-autoconfigure/src/main/java/cn/axzo/framework/autoconfigure/web/rest/vo/EnumMetaVO.java @@ -0,0 +1,29 @@ +package cn.axzo.framework.autoconfigure.web.rest.vo; + +import lombok.Data; +import lombok.experimental.Accessors; + +import java.util.Map; + +/** + * @Author: liyong.tian + * @Date: 2023/3/21 15:54 + * @Description: + */ +@Data +@Accessors(chain = true) +public class EnumMetaVO { + + private String group; + + private String simpleName; + + private String description; + + private String enumType; + + private String className; + + // code <=> name + private Map items; +} diff --git a/axzo-common-autoconfigure/src/main/resources/META-INF/spring.factories b/axzo-common-autoconfigure/src/main/resources/META-INF/spring.factories index 8f9a464..267add4 100644 --- a/axzo-common-autoconfigure/src/main/resources/META-INF/spring.factories +++ b/axzo-common-autoconfigure/src/main/resources/META-INF/spring.factories @@ -11,6 +11,8 @@ cn.axzo.framework.autoconfigure.data.IdAutoConfiguration,\ cn.axzo.framework.autoconfigure.web.cors.CorsAutoConfiguration,\ cn.axzo.framework.autoconfigure.web.PageWebAutoConfiguration,\ cn.axzo.framework.autoconfigure.web.exception.ExceptionHandlerAutoConfiguration,\ +cn.axzo.framework.autoconfigure.web.rest.RestResourceProperties,\ +cn.axzo.framework.autoconfigure.web.rest.EnumResource,\ cn.axzo.framework.autoconfigure.validation.SpringValidatorAutoConfiguration,\ cn.axzo.framework.autoconfigure.web.advice.BodyAdviceAutoConfiguration,\ cn.axzo.framework.autoconfigure.web.FilterAutoConfiguration,\ diff --git a/axzo-common-datas/axzo-data-mybatis-plus/src/main/java/cn/axzo/framework/data/mybatisplus/model/BaseEntity.java b/axzo-common-datas/axzo-data-mybatis-plus/src/main/java/cn/axzo/framework/data/mybatisplus/model/BaseEntity.java index 61e6653..189be2e 100644 --- a/axzo-common-datas/axzo-data-mybatis-plus/src/main/java/cn/axzo/framework/data/mybatisplus/model/BaseEntity.java +++ b/axzo-common-datas/axzo-data-mybatis-plus/src/main/java/cn/axzo/framework/data/mybatisplus/model/BaseEntity.java @@ -1,9 +1,6 @@ package cn.axzo.framework.data.mybatisplus.model; -import com.baomidou.mybatisplus.annotation.FieldFill; -import com.baomidou.mybatisplus.annotation.IdType; -import com.baomidou.mybatisplus.annotation.TableField; -import com.baomidou.mybatisplus.annotation.TableId; +import com.baomidou.mybatisplus.annotation.*; import com.baomidou.mybatisplus.extension.activerecord.Model; import lombok.Data; @@ -21,10 +18,11 @@ public abstract class BaseEntity> extends Model { private Long id; /** - * 是否删除:0否 1是 + * 是否删除:0否,删除id */ + @TableLogic(value = "0", delval = "id") @TableField(value = "is_delete", fill = FieldFill.INSERT) - private Integer isDelete = 0; + private Long isDelete; /** * 创建时间