parent
fb65771248
commit
cc1877fd39
@ -0,0 +1,186 @@
|
||||
package cc.yunxi.common.config;
|
||||
|
||||
import cc.yunxi.common.enums.SwaggerDisplayEnum;
|
||||
import com.baomidou.mybatisplus.core.toolkit.StringUtils;
|
||||
import com.fasterxml.classmate.ResolvedType;
|
||||
import com.fasterxml.jackson.databind.introspect.BeanPropertyDefinition;
|
||||
import lombok.extern.slf4j.Slf4j;
|
||||
import org.springframework.context.annotation.Configuration;
|
||||
import org.springframework.core.annotation.AnnotationUtils;
|
||||
import org.springframework.util.ReflectionUtils;
|
||||
import springfox.documentation.builders.ModelPropertyBuilder;
|
||||
import springfox.documentation.builders.OperationBuilder;
|
||||
import springfox.documentation.builders.ParameterBuilder;
|
||||
import springfox.documentation.service.AllowableListValues;
|
||||
import springfox.documentation.service.ResolvedMethodParameter;
|
||||
import springfox.documentation.spi.DocumentationType;
|
||||
import springfox.documentation.spi.schema.ModelPropertyBuilderPlugin;
|
||||
import springfox.documentation.spi.schema.contexts.ModelPropertyContext;
|
||||
import springfox.documentation.spi.service.ExpandedParameterBuilderPlugin;
|
||||
import springfox.documentation.spi.service.OperationBuilderPlugin;
|
||||
import springfox.documentation.spi.service.ParameterBuilderPlugin;
|
||||
import springfox.documentation.spi.service.contexts.OperationContext;
|
||||
import springfox.documentation.spi.service.contexts.ParameterContext;
|
||||
import springfox.documentation.spi.service.contexts.ParameterExpansionContext;
|
||||
|
||||
import java.lang.reflect.Field;
|
||||
import java.lang.reflect.Parameter;
|
||||
import java.util.*;
|
||||
import java.util.stream.Collectors;
|
||||
|
||||
/**
|
||||
* Swagger枚举转换扩展配置类
|
||||
*/
|
||||
@Configuration
|
||||
@Slf4j
|
||||
public class SwaggerEnumPlugin implements ModelPropertyBuilderPlugin, ParameterBuilderPlugin, OperationBuilderPlugin, ExpandedParameterBuilderPlugin {
|
||||
|
||||
private static final String DELIMITER = ",";
|
||||
|
||||
@Override
|
||||
public void apply(ModelPropertyContext context) {
|
||||
Optional<BeanPropertyDefinition> optional = context.getBeanPropertyDefinition();
|
||||
if (!optional.isPresent()) {
|
||||
return;
|
||||
}
|
||||
|
||||
Class<?> fieldType = optional.get().getField().getRawType();
|
||||
addDescForEnum(context, fieldType);
|
||||
}
|
||||
|
||||
private void addDescForEnum(ModelPropertyContext context, Class<?> fieldType) {
|
||||
if (Enum.class.isAssignableFrom(fieldType)) {
|
||||
SwaggerDisplayEnum anno = AnnotationUtils.findAnnotation(fieldType, SwaggerDisplayEnum.class);
|
||||
if (anno != null) {
|
||||
Object[] enumConstants = fieldType.getEnumConstants();
|
||||
List<String> displayValues = getDisplayValues(anno, enumConstants);
|
||||
|
||||
ModelPropertyBuilder builder = context.getBuilder();
|
||||
Field descField = ReflectionUtils.findField(builder.getClass(), "description");
|
||||
ReflectionUtils.makeAccessible(descField);
|
||||
String joinText = (ReflectionUtils.getField(descField, builder) == null ? "" : (ReflectionUtils.getField(descField, builder) + ":"))
|
||||
+ String.join(DELIMITER, displayValues);
|
||||
|
||||
// builder.description(joinText).type(context.getResolver().resolve(Integer.class));
|
||||
builder.description(joinText).type(context.getResolver().resolve(String.class));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void apply(OperationContext context) {
|
||||
Map<String, List<String>> map = new HashMap<>();
|
||||
List<ResolvedMethodParameter> parameters = context.getParameters();
|
||||
parameters.forEach(parameter -> {
|
||||
ResolvedType parameterType = parameter.getParameterType();
|
||||
Class<?> clazz = parameterType.getErasedType();
|
||||
if (Enum.class.isAssignableFrom(clazz)) {
|
||||
SwaggerDisplayEnum annotation = AnnotationUtils.findAnnotation(clazz, SwaggerDisplayEnum.class);
|
||||
if (annotation != null) {
|
||||
Object[] enumConstants = clazz.getEnumConstants();
|
||||
List<String> displayValues = getDisplayValues(annotation, enumConstants);
|
||||
map.put(parameter.defaultName().orElse(""), displayValues);
|
||||
|
||||
OperationBuilder operationBuilder = context.operationBuilder();
|
||||
Field parametersField = ReflectionUtils.findField(operationBuilder.getClass(), "parameters");
|
||||
ReflectionUtils.makeAccessible(parametersField);
|
||||
List<Parameter> list = (List<Parameter>) ReflectionUtils.getField(parametersField, operationBuilder);
|
||||
|
||||
map.forEach((k, v) -> {
|
||||
for (Parameter currentParameter : list) {
|
||||
if (StringUtils.equals(currentParameter.getName(), k)) {
|
||||
Field description = ReflectionUtils.findField(currentParameter.getClass(), "description");
|
||||
ReflectionUtils.makeAccessible(description);
|
||||
Object field = ReflectionUtils.getField(description, currentParameter);
|
||||
ReflectionUtils.setField(description, currentParameter, field + ":" + String.join(DELIMITER, v));
|
||||
break;
|
||||
}
|
||||
}
|
||||
});
|
||||
}
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
@Override
|
||||
public void apply(ParameterContext context) {
|
||||
Class<?> type = context.resolvedMethodParameter().getParameterType().getErasedType();
|
||||
ParameterBuilder parameterBuilder = context.parameterBuilder();
|
||||
setAvailableValue(parameterBuilder, type);
|
||||
}
|
||||
|
||||
private void setAvailableValue(ParameterBuilder parameterBuilder, Class<?> type) {
|
||||
if (Enum.class.isAssignableFrom(type)) {
|
||||
SwaggerDisplayEnum annotation = AnnotationUtils.findAnnotation(type, SwaggerDisplayEnum.class);
|
||||
if (annotation != null) {
|
||||
String code = annotation.code();
|
||||
Object[] enumConstants = type.getEnumConstants();
|
||||
List<String> displayValues = Arrays.stream(enumConstants).filter(Objects::nonNull).map(item -> {
|
||||
Class<?> currentClass = item.getClass();
|
||||
|
||||
Field codeField = ReflectionUtils.findField(currentClass, code);
|
||||
assert codeField != null;
|
||||
ReflectionUtils.makeAccessible(codeField);
|
||||
Object codeStr = ReflectionUtils.getField(codeField, item);
|
||||
assert codeStr != null;
|
||||
return codeStr.toString();
|
||||
|
||||
}).collect(Collectors.toList());
|
||||
|
||||
// 设置可用值
|
||||
AllowableListValues values = new AllowableListValues(displayValues, "LIST");
|
||||
parameterBuilder.allowableValues(values);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void apply(ParameterExpansionContext context) {
|
||||
Class<?> type = context.getFieldType().getErasedType();
|
||||
ParameterBuilder parameterBuilder = context.getParameterBuilder();
|
||||
if (Enum.class.isAssignableFrom(type)) {
|
||||
setAvailableValue(parameterBuilder, type);
|
||||
SwaggerDisplayEnum annotation = AnnotationUtils.findAnnotation(type, SwaggerDisplayEnum.class);
|
||||
if (annotation != null) {
|
||||
Object[] enumConstants = type.getEnumConstants();
|
||||
List<String> displayValues = getDisplayValues(annotation, enumConstants);
|
||||
|
||||
Field descField = ReflectionUtils.findField(parameterBuilder.getClass(), "description");
|
||||
ReflectionUtils.makeAccessible(descField);
|
||||
String joinText = (ReflectionUtils.getField(descField, parameterBuilder) == null ? "" : (ReflectionUtils.getField(descField, parameterBuilder) + ":"))
|
||||
+ String.join(DELIMITER, displayValues);
|
||||
|
||||
parameterBuilder.description(joinText);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private List<String> getDisplayValues(SwaggerDisplayEnum annotation, Object[] enumConstants) {
|
||||
if (annotation == null) {
|
||||
return new ArrayList<>();
|
||||
}
|
||||
String code = annotation.code();
|
||||
String desc = annotation.desc();
|
||||
return Arrays.stream(enumConstants).filter(Objects::nonNull).map(
|
||||
item -> {
|
||||
Class<?> currentClass = item.getClass();
|
||||
Field codeField = ReflectionUtils.findField(currentClass, code);
|
||||
assert codeField != null;
|
||||
ReflectionUtils.makeAccessible(codeField);
|
||||
Object codeStr = ReflectionUtils.getField(codeField, item);
|
||||
|
||||
Field descField = ReflectionUtils.findField(currentClass, desc);
|
||||
assert descField != null;
|
||||
ReflectionUtils.makeAccessible(descField);
|
||||
Object descStr = ReflectionUtils.getField(descField, item);
|
||||
|
||||
return codeStr + "、" + descStr;
|
||||
}
|
||||
).collect(Collectors.toList());
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean supports(DocumentationType documentationType) {
|
||||
return true;
|
||||
}
|
||||
}
|
@ -0,0 +1,65 @@
|
||||
package cc.yunxi.common.domain.convert;
|
||||
|
||||
import cc.yunxi.common.enums.BaseEnum;
|
||||
import cc.yunxi.common.factory.StringCodeToEnumConverterFactory;
|
||||
import com.baomidou.mybatisplus.annotation.IEnum;
|
||||
import com.fasterxml.jackson.core.JsonParser;
|
||||
import com.fasterxml.jackson.databind.BeanProperty;
|
||||
import com.fasterxml.jackson.databind.DeserializationContext;
|
||||
import com.fasterxml.jackson.databind.JsonDeserializer;
|
||||
import com.fasterxml.jackson.databind.JsonMappingException;
|
||||
import com.fasterxml.jackson.databind.deser.ContextualDeserializer;
|
||||
import lombok.Data;
|
||||
import lombok.EqualsAndHashCode;
|
||||
import lombok.NoArgsConstructor;
|
||||
import org.springframework.util.StringUtils;
|
||||
|
||||
import java.io.IOException;
|
||||
|
||||
@Data
|
||||
@NoArgsConstructor
|
||||
@EqualsAndHashCode(callSuper = true)
|
||||
public class EnumDeserializer extends JsonDeserializer<BaseEnum> implements ContextualDeserializer {
|
||||
|
||||
private Class<?> target;
|
||||
|
||||
public static final EnumDeserializer INSTANCE = new EnumDeserializer();
|
||||
|
||||
@SuppressWarnings("all")
|
||||
@Override
|
||||
public BaseEnum deserialize(JsonParser jsonParser, DeserializationContext ctx) throws IOException {
|
||||
if (!StringUtils.hasText(jsonParser.getText())) {
|
||||
return null;
|
||||
}
|
||||
// BaseEnum类 = target类相同 | tartget类的父类或接口
|
||||
if (BaseEnum.class.isAssignableFrom(target)) {
|
||||
return StringCodeToEnumConverterFactory.getEnum((Class) target, jsonParser.getText());
|
||||
}
|
||||
return defaultEnumTransform(target,jsonParser.getText());
|
||||
}
|
||||
|
||||
/**
|
||||
* @param ctx ctx
|
||||
* @param property property
|
||||
* @return 1
|
||||
* @throws JsonMappingException
|
||||
*/
|
||||
@Override
|
||||
public JsonDeserializer<?> createContextual(DeserializationContext ctx, BeanProperty property) throws JsonMappingException {
|
||||
Class<?> rawCls = ctx.getContextualType().getRawClass();
|
||||
EnumDeserializer enumDeserializer = new EnumDeserializer();
|
||||
enumDeserializer.setTarget(rawCls);
|
||||
return enumDeserializer;
|
||||
}
|
||||
|
||||
|
||||
public static BaseEnum defaultEnumTransform(Class<?> type, String indexString) {
|
||||
BaseEnum[] enumConstants = (BaseEnum[]) type.getEnumConstants();
|
||||
try {
|
||||
int index = Integer.parseInt(indexString);
|
||||
return enumConstants[index];
|
||||
} catch (NumberFormatException e) {
|
||||
return null;
|
||||
}
|
||||
}
|
||||
}
|
@ -0,0 +1,39 @@
|
||||
package cc.yunxi.common.domain.convert;
|
||||
|
||||
import cc.yunxi.common.enums.BaseEnum;
|
||||
import cc.yunxi.common.factory.StringCodeToEnumConverterFactory;
|
||||
import com.fasterxml.jackson.core.JsonGenerator;
|
||||
import com.fasterxml.jackson.core.JsonParser;
|
||||
import com.fasterxml.jackson.databind.*;
|
||||
import com.fasterxml.jackson.databind.deser.ContextualDeserializer;
|
||||
import lombok.Data;
|
||||
import lombok.EqualsAndHashCode;
|
||||
import lombok.NoArgsConstructor;
|
||||
import org.springframework.util.StringUtils;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.lang.reflect.Field;
|
||||
|
||||
@Data
|
||||
@NoArgsConstructor
|
||||
@EqualsAndHashCode(callSuper = true)
|
||||
public class EnumSerializer extends JsonSerializer<BaseEnum> {
|
||||
|
||||
public static final EnumSerializer INSTANCE = new EnumSerializer();
|
||||
|
||||
|
||||
@Override
|
||||
public void serialize(BaseEnum baseEnum, JsonGenerator jsonGenerator, SerializerProvider serializerProvider) throws IOException {
|
||||
// java 如何获取枚举类的成员属性? 此处有问题, todo
|
||||
jsonGenerator.writeStartObject();
|
||||
Field[] fields = baseEnum.getClass().getFields();
|
||||
for (Field field : fields) {
|
||||
try {
|
||||
jsonGenerator.writeStringField(field.getName(), String.valueOf(field.get(baseEnum)));
|
||||
} catch (IllegalAccessException e) {
|
||||
throw new RuntimeException(e);
|
||||
}
|
||||
}
|
||||
jsonGenerator.writeEndObject();
|
||||
}
|
||||
}
|
@ -1,10 +1,8 @@
|
||||
package cc.yunxi.common.domain;
|
||||
package cc.yunxi.common.domain.convert;
|
||||
|
||||
import com.fasterxml.jackson.core.JsonParser;
|
||||
import com.fasterxml.jackson.core.JsonProcessingException;
|
||||
import com.fasterxml.jackson.databind.DeserializationContext;
|
||||
import com.fasterxml.jackson.databind.JsonDeserializer;
|
||||
import org.springframework.format.annotation.DateTimeFormat;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.time.Instant;
|
@ -1,4 +1,4 @@
|
||||
package cc.yunxi.common.domain;
|
||||
package cc.yunxi.common.domain.convert;
|
||||
|
||||
import com.fasterxml.jackson.core.JsonGenerator;
|
||||
import com.fasterxml.jackson.databind.JsonSerializer;
|
@ -1,4 +1,4 @@
|
||||
package cc.yunxi.common.domain;
|
||||
package cc.yunxi.common.domain.function;
|
||||
|
||||
import java.io.Serializable;
|
||||
|
@ -0,0 +1,11 @@
|
||||
package cc.yunxi.common.enums;
|
||||
|
||||
/**
|
||||
* 枚举接口
|
||||
*/
|
||||
public interface BaseEnum {
|
||||
/**
|
||||
* 获取枚举编码
|
||||
*/
|
||||
String getCode();
|
||||
}
|
@ -0,0 +1,16 @@
|
||||
package cc.yunxi.common.enums;
|
||||
|
||||
import java.lang.annotation.ElementType;
|
||||
import java.lang.annotation.Retention;
|
||||
import java.lang.annotation.RetentionPolicy;
|
||||
import java.lang.annotation.Target;
|
||||
|
||||
/**
|
||||
* Swagger枚举转换注解
|
||||
*/
|
||||
@Target({ElementType.TYPE})
|
||||
@Retention(RetentionPolicy.RUNTIME)
|
||||
public @interface SwaggerDisplayEnum {
|
||||
String code() default "code";
|
||||
String desc() default "desc";
|
||||
}
|
@ -0,0 +1,17 @@
|
||||
package cc.yunxi.config;
|
||||
|
||||
|
||||
import lombok.Data;
|
||||
import org.springframework.boot.context.properties.ConfigurationProperties;
|
||||
import org.springframework.stereotype.Component;
|
||||
|
||||
/**
|
||||
* 回收员微信配置
|
||||
*/
|
||||
@Data
|
||||
@Component
|
||||
@ConfigurationProperties(prefix = "nxhs.wx.client")
|
||||
public class WxShProperties {
|
||||
private String appId;
|
||||
private String appSecret;
|
||||
}
|
@ -0,0 +1,14 @@
|
||||
package cc.yunxi.domain.query;
|
||||
|
||||
import cc.yunxi.enums.UserTypeEnum;
|
||||
import io.swagger.annotations.ApiModel;
|
||||
import io.swagger.annotations.ApiModelProperty;
|
||||
import lombok.Data;
|
||||
|
||||
@Data
|
||||
@ApiModel(value = "TestQuery", description = "测试查询条件")
|
||||
public class TestQuery {
|
||||
|
||||
@ApiModelProperty("UserTypeEnum枚举类")
|
||||
private UserTypeEnum userType;
|
||||
}
|
@ -0,0 +1,21 @@
|
||||
package cc.yunxi.domain.vo.recycleorder;
|
||||
|
||||
import io.swagger.annotations.ApiModel;
|
||||
import io.swagger.annotations.ApiModelProperty;
|
||||
import lombok.Data;
|
||||
|
||||
import javax.validation.constraints.NotBlank;
|
||||
|
||||
|
||||
@ApiModel(description = "回收订单- 接单 Request VO")
|
||||
@Data
|
||||
public class RecycleOrderTakingVO {
|
||||
|
||||
@ApiModelProperty(value = "回收订单id", required = true, example = "1763736089053364225")
|
||||
@NotBlank(message = "回收订单id不能为空")
|
||||
private String id;
|
||||
|
||||
// @ApiModelProperty(value = "回收员id", required = true, example = "533242995646951684")
|
||||
// @NotBlank(message = "回收员id不能为空")
|
||||
// private String staffsId;
|
||||
}
|
@ -0,0 +1,37 @@
|
||||
package cc.yunxi.domain.vo.recycleorder;
|
||||
|
||||
import io.swagger.annotations.ApiModel;
|
||||
import io.swagger.annotations.ApiModelProperty;
|
||||
import lombok.Data;
|
||||
|
||||
import javax.validation.constraints.Future;
|
||||
import javax.validation.constraints.NotBlank;
|
||||
import javax.validation.constraints.NotNull;
|
||||
import java.time.LocalDateTime;
|
||||
|
||||
@ApiModel(description = "回收订单- 编辑订单 Request VO")
|
||||
@Data
|
||||
public class RecycleOrderUpdateVO {
|
||||
|
||||
@ApiModelProperty(value = "回收订单id", required = true, example = "1763736089053364225")
|
||||
@NotBlank(message = "回收订单id不能为空")
|
||||
private String id;
|
||||
|
||||
@ApiModelProperty(value = "回收站id", required = true, example = "521632060801030597")
|
||||
private String recycleStationId;
|
||||
|
||||
@ApiModelProperty(value = "散户地址", required = true, example = "xxx市yyy区")
|
||||
private String recycleAddress;
|
||||
|
||||
@ApiModelProperty(value = "预约上门时间起", required = true, example = "2024-03-01 15:58:49")
|
||||
@Future(message = "预约上门时间起不正确")
|
||||
private LocalDateTime appointmentTimeStart;
|
||||
|
||||
@ApiModelProperty(value = "预约上门时间止",required = true, example = "2024-03-01 15:58:49")
|
||||
@Future(message = "预约上门时间止不正确")
|
||||
private LocalDateTime appointmentTimeEnd;
|
||||
|
||||
@ApiModelProperty(value = "备注", required = false, example = "请尽快上门")
|
||||
private String remark;
|
||||
|
||||
}
|
After Width: | Height: | Size: 352 KiB |
Loading…
Reference in new issue