Merge branch 'feature/rest_enum' into 'master'

封装枚举类接口及调整mybatisplus

See merge request infra/axzo-framework-commons!35
This commit is contained in:
田立勇 2023-03-27 11:10:30 +00:00
commit af30be5fcb
6 changed files with 249 additions and 6 deletions

View File

@ -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<Map<String, Object>> 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<EnumMeta, String> keyMapper = enumMeta -> StringUtil.uncapitalize(enumMeta.getSimpleName());
Function<EnumMeta, List<EnumItemVO>> 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<String, Object> map = Seq.seq(enumMetas).toMap(keyMapper, valueMapper);
return ApiResult.ok(map);
}
@ApiOperation("获取枚举文档")
@GetMapping("/enums/doc")
@Timed
public ApiListResult<EnumMetaVO> getEnumDocs() {
val enumMetas = Seq.of(properties.getEnumResource().getScanPackages())
.flatMap(pkg -> findClassPathEnums(pkg, classLoader).stream())
.filter(EnumMeta::isNotDeprecated)
.map(enumMeta -> {
List<EnumItemVO> 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<EnumMeta> findClassPathEnums(String packageName, ClassLoader classLoader) {
return _findEnumMetas(Resources.findEnumClasses(packageName, classLoader));
}
private static List<EnumMeta> _findEnumMetas(Class<? extends Enum<?>>[] classes) {
List<EnumMeta> 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;
}
}

View File

@ -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 = {};
}
}

View File

@ -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;
}

View File

@ -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<Object, String> items;
}

View File

@ -11,6 +11,8 @@ cn.axzo.framework.autoconfigure.data.IdAutoConfiguration,\
cn.axzo.framework.autoconfigure.web.cors.CorsAutoConfiguration,\ cn.axzo.framework.autoconfigure.web.cors.CorsAutoConfiguration,\
cn.axzo.framework.autoconfigure.web.PageWebAutoConfiguration,\ cn.axzo.framework.autoconfigure.web.PageWebAutoConfiguration,\
cn.axzo.framework.autoconfigure.web.exception.ExceptionHandlerAutoConfiguration,\ 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.validation.SpringValidatorAutoConfiguration,\
cn.axzo.framework.autoconfigure.web.advice.BodyAdviceAutoConfiguration,\ cn.axzo.framework.autoconfigure.web.advice.BodyAdviceAutoConfiguration,\
cn.axzo.framework.autoconfigure.web.FilterAutoConfiguration,\ cn.axzo.framework.autoconfigure.web.FilterAutoConfiguration,\

View File

@ -1,9 +1,6 @@
package cn.axzo.framework.data.mybatisplus.model; package cn.axzo.framework.data.mybatisplus.model;
import com.baomidou.mybatisplus.annotation.FieldFill; import com.baomidou.mybatisplus.annotation.*;
import com.baomidou.mybatisplus.annotation.IdType;
import com.baomidou.mybatisplus.annotation.TableField;
import com.baomidou.mybatisplus.annotation.TableId;
import com.baomidou.mybatisplus.extension.activerecord.Model; import com.baomidou.mybatisplus.extension.activerecord.Model;
import lombok.Data; import lombok.Data;
@ -21,10 +18,11 @@ public abstract class BaseEntity<T extends Model<?>> extends Model<T> {
private Long id; private Long id;
/** /**
* 是否删除0否 1是 * 是否删除0否,删除id
*/ */
@TableLogic(value = "0", delval = "id")
@TableField(value = "is_delete", fill = FieldFill.INSERT) @TableField(value = "is_delete", fill = FieldFill.INSERT)
private Integer isDelete = 0; private Long isDelete;
/** /**
* 创建时间 * 创建时间