easy-yapi
easy-yapi copied to clipboard
[Bug] 枚举无法转换了
Describe the bug IntelliJ IDEA 2022.2 (Ultimate Edition) easyyapi: 2.4.3.191.0 最新版 提示枚举无法转换了。 [WARN] can not resolve com.alibaba.study.api.enums.OauthSourceEnum for com.alibaba.study.controller.oauth.request.OauthRequest#oauthSource 以前版本的枚举都是可以的。
在vo层的代码: /** * 授权来源 * * @see OauthSourceEnum */ @NotNull(message = "授权来源不能为空") @IsEnum(enumType = OauthSourceEnum.class, message = "授权来源错误") private String oauthSource;
我们的枚举: @Getter public enum OauthSourceEnum implements BaseEnum<String> { /** * 支付宝 */ ALIPAY("支付宝"),
;
final String description;
OauthSourceEnum(String description) {
this.description = description;
}
@Override
public String getCode() {
return this.name();
}
}
public interface BaseEnum<T> {
/**
* 返回枚举的code。一般建议直接返回枚举的name
*
* @return code
*/
T getCode();
/**
* 返回枚举的描述。返回枚举的中文 方便前端下拉
*
* @return description
*/
String getDescription();
}
期望能显示: 枚举: SHOW,HIDE
枚举备注: SHOW :显示 HIDE :隐藏
mock: @pick(["SHOW","HIDE"])
这个是以前的
现在空白了。
To Reproduce
Detailed Steps to reproduce the behavior:
- Open '...'
- Click on '....'
- See error
Expected behavior
A clear and concise description of what you expected to happen.
Screenshots
If applicable, add screenshots to help explain your problem.
Logs
- Add config: #Get the module from the comment,group the apis module=#module #-------------------- #Ignore class/api ignore=#ignore #-------------------- #deprecated info(java) method.doc[#deprecated]=groovy:"\n「已废弃」" + it.doc("deprecated") method.doc[@java.lang.Deprecated]=「已废弃」 method.doc[groovy:it.containingClass().hasDoc("deprecated")]=groovy:"\n「已废弃」" + it.containingClass().doc("deprecated") method.doc[groovy:it.containingClass().hasAnn("java.lang.Deprecated")]=「已废弃」 field.doc[#deprecated]=groovy:"\n「已废弃」" + it.doc("deprecated") field.doc[@java.lang.Deprecated]=「已废弃」 #-------------------- #deprecated info(kotlin) method.doc[@kotlin.Deprecated]=groovy:"\n「已废弃」" + it.ann("kotlin.Deprecated","message") method.doc[groovy:it.containingClass().hasAnn("kotlin.Deprecated")]=groovy:"\n「已废弃」 " + it.containingClass().ann("kotlin.Deprecated","message") field.doc[@kotlin.Deprecated]=groovy:"\n「已废弃」" + it.ann("kotlin.Deprecated","message") #-------------------- #Support for Jackson annotations [email protected]#value [email protected]#value field.mock[@com.fasterxml.jackson.annotation.JsonFormat]=groovy:``` return "@datetime("" + it.ann("com.fasterxml.jackson.annotation.JsonFormat","pattern") + "")"
#--------------------
#Support for Gson annotations
[email protected]#value
[email protected]#serialize
#--------------------
#ignore transient field
field.ignore=groovy:it.hasModifier("transient")
#--------------------
#The ObjectId and Date will be parsed as strings
json.rule.convert[org.bson.types.ObjectId]=java.lang.String
json.rule.convert[java.util.Date]=java.lang.String
json.rule.convert[java.sql.Date]=java.lang.String
json.rule.convert[java.sql.Time]=java.lang.String
json.rule.convert[java.sql.Timestamp]=java.lang.String
json.rule.convert[java.time.LocalDateTime]=java.lang.String
json.rule.convert[java.time.LocalDate]=java.lang.String
#--------------------
#resolve HttpEntity/RequestEntity/ResponseEntity/DeferredResult
###set resolveProperty = false
json.rule.convert[#regex:org.springframework.http.HttpEntity<(.*?)>]=${1}
json.rule.convert[org.springframework.http.HttpEntity]=java.lang.Object
json.rule.convert[#regex:org.springframework.http.RequestEntity<(.*?)>]=${1}
json.rule.convert[org.springframework.http.RequestEntity]=java.lang.Object
json.rule.convert[#regex:org.springframework.http.ResponseEntity<(.*?)>]=${1}
json.rule.convert[org.springframework.http.ResponseEntity]=java.lang.Object
json.rule.convert[#regex:org.springframework.web.context.request.async.DeferredResult<(.*?)>]=${1}
json.rule.convert[org.springframework.web.context.request.async.DeferredResult]=java.lang.Object
json.rule.convert[#regex:org.reactivestreams.Publisher<(.*?)>]=${1}
json.rule.convert[org.reactivestreams.Publisher]=java.lang.Object
###set resolveProperty = true
#--------------------
#Support spring.validations
[email protected]
param.ignore=groovy:it.type().isExtend("org.springframework.validation.BindingResult")
field.mock[@org.springframework.format.annotation.DateTimeFormat]=groovy:```
return "@datetime(\"" + it.ann("org.springframework.format.annotation.DateTimeFormat","pattern") + "\")"
#-------------------- #Support spring.ui param.ignore=groovy:it.type().name()=="org.springframework.ui.Model" param.ignore=groovy:it.type().name()=="org.springframework.ui.ModelMap" param.ignore=groovy:it.type().name()=="org.springframework.web.servlet.ModelAndView" #-------------------- #Support for javax.validation annotations [email protected] [email protected] [email protected] [email protected] [email protected] [email protected] #-------------------- #Support spring file type.is_file=groovy:it.isExtend("org.springframework.web.multipart.MultipartFile") #-------------------- #yapi tag api.tag[@java.lang.Deprecated]=deprecated api.tag[#deprecated]=deprecated api.tag[groovy:it.containingClass().hasAnn("java.lang.Deprecated")]=deprecated api.tag[groovy:it.containingClass().hasDoc("deprecated")]=deprecated #-------------------- #yapi tag for kotlin api.tag[@kotlin.Deprecated]=deprecated api.tag[groovy:it.containingClass().hasAnn("kotlin.Deprecated")]=deprecated #-------------------- #yapi status api.status[#undone]=undone api.status[#todo]=undone #-------------------- #yapi mock field.mock=#mock #-------------------- api.tag=#tag api.tag.delimiter=,&\n #-------------------- #ignore serialVersionUID constant.field.ignore=groovy:it.name()=="serialVersionUID" #-------------------- #mock for date ###set resolveMulti = first java_date_types=["java.util.Date","java.sql.Timestamp","java.time.LocalDate","java.time.LocalDateTime"] field.mock[groovy:${java_date_types}.contains(it.type().name())&&it.jsonType().name()=="java.lang.String"] = groovy:"@datetime" field.mock[groovy:${java_date_types}.contains(it.type().name())&&it.jsonType().name()=="java.lang.Long"] = groovy:"@timestamp@string("number", 3)" ###set resolveMulti = error #--------------------
mock for javax.validation
###set resolveMulti = first
define var
number_min=-9999 number_max=9999 float_dmin=2 java_integer_types=["java.lang.Integer","int","java.lang.Long","long","java.lang.Short","short","java.math.BigInteger"] java_float_types=["java.lang.Float","float","java.lang.Double","double","java.math.BigDecimal"]
mock_integer_or_float=${java_integer_types}.contains(it.type().name())?"@integer":"@float"
AssertTrue|AssertFalse|Email
field.mock[@javax.validation.constraints.AssertTrue]=true field.mock[@javax.validation.constraints.AssertFalse]=false field.mock[@javax.validation.constraints.Email]=groovy:"@email"
Positive&PositiveOrZero
field.mock[groovy:it.hasAnn("javax.validation.constraints.Positive")&&${java_integer_types}.contains(it.jsonType().name())]=groovy:"@integer(1,${number_max})" field.mock[groovy:it.hasAnn("javax.validation.constraints.PositiveOrZero")&&${java_integer_types}.contains(it.jsonType().name())]=groovy:"@integer(0,${number_max})" field.mock[groovy:it.hasAnn("javax.validation.constraints.Positive")&&${java_float_types}.contains(it.jsonType().name())]=groovy:"@float(0.01,${number_max},${float_dmin})" field.mock[groovy:it.hasAnn("javax.validation.constraints.PositiveOrZero")&&${java_float_types}.contains(it.jsonType().name())]=groovy:"@float(0,${number_max},${float_dmin})"
Negative&NegativeOrZero
field.mock[groovy:it.hasAnn("javax.validation.constraints.Negative")&&${java_integer_types}.contains(it.jsonType().name())]=groovy:"@integer(${number_min},-1)" field.mock[groovy:it.hasAnn("javax.validation.constraints.NegativeOrZero")&&${java_integer_types}.contains(it.jsonType().name())]=groovy:"@integer(${number_min},0)" field.mock[groovy:it.hasAnn("javax.validation.constraints.Negative")&&${java_float_types}.contains(it.jsonType().name())]=groovy:"@float(${number_min},0.01,${float_dmin})" field.mock[groovy:it.hasAnn("javax.validation.constraints.NegativeOrZero")&&${java_float_types}.contains(it.jsonType().name())]=groovy:"@float(${number_min},0,${float_dmin})"
Max+Min
field.mock[groovy:it.hasAnn("javax.validation.constraints.Max")&&it.hasAnn("javax.validation.constraints.Min")&&${java_integer_types}.contains(it.jsonType().name())]=groovy:"@integer("+it.ann("javax.validation.constraints.Min")+","+it.ann("javax.validation.constraints.Max")+")" field.mock[groovy:it.hasAnn("javax.validation.constraints.Max")&&it.hasAnn("javax.validation.constraints.Min")&&${java_float_types}.contains(it.jsonType().name())]=groovy:"@float("+it.ann("javax.validation.constraints.Min")+","+it.ann("javax.validation.constraints.Max")+",${float_dmin})"
Max|Min
field.mock[groovy:it.hasAnn("javax.validation.constraints.Max")&&${java_integer_types}.contains(it.jsonType().name())]=groovy:"@integer(0,"+it.ann("javax.validation.constraints.Max")+")" field.mock[groovy:it.hasAnn("javax.validation.constraints.Min")&&${java_integer_types}.contains(it.jsonType().name())]=groovy:"@integer("+it.ann("javax.validation.constraints.Min")+")" field.mock[groovy:it.hasAnn("javax.validation.constraints.Max")&&${java_float_types}.contains(it.jsonType().name())]=groovy:"@float(0,"+it.ann("javax.validation.constraints.Max")+")" field.mock[groovy:it.hasAnn("javax.validation.constraints.Min")&&${java_float_types}.contains(it.jsonType().name())]=groovy:"@float("+it.ann("javax.validation.constraints.Min")+")"
DecimalMax+DecimalMin
field.mock[groovy:it.hasAnn("javax.validation.constraints.DecimalMax")&&it.hasAnn("javax.validation.constraints.DecimalMin")&&${java_integer_types}.contains(it.jsonType().name())]=groovy:"@integer("+it.ann("javax.validation.constraints.DecimalMin")+","+it.ann("javax.validation.constraints.DecimalMax")+")" field.mock[groovy:it.hasAnn("javax.validation.constraints.DecimalMax")&&it.hasAnn("javax.validation.constraints.DecimalMin")&&${java_float_types}.contains(it.jsonType().name())]=groovy:"@float("+it.ann("javax.validation.constraints.DecimalMin")+","+it.ann("javax.validation.constraints.DecimalMax")+",${float_dmin})"
DecimalMax|DecimalMin
field.mock[groovy:it.hasAnn("javax.validation.constraints.DecimalMax")&&${java_integer_types}.contains(it.jsonType().name())]=groovy:"@integer(0,"+it.ann("javax.validation.constraints.DecimalMax")+")" field.mock[groovy:it.hasAnn("javax.validation.constraints.DecimalMin")&&${java_integer_types}.contains(it.jsonType().name())]=groovy:"@integer("+it.ann("javax.validation.constraints.DecimalMin")+")" field.mock[groovy:it.hasAnn("javax.validation.constraints.DecimalMax")&&${java_float_types}.contains(it.jsonType().name())]=groovy:"@float(0,"+it.ann("javax.validation.constraints.DecimalMax")+",${float_dmin})" field.mock[groovy:it.hasAnn("javax.validation.constraints.DecimalMin")&&${java_float_types}.contains(it.jsonType().name())]=groovy:"@float("+it.ann("javax.validation.constraints.DecimalMin")+",${float_dmin})" ###set resolveMulti = error #--------------------
@ConfigurationProperties
properties.prefix=@org.springframework.boot.context.properties.ConfigurationProperties#prefix #-------------------- #Support for Fastjson annotations [email protected]#value #-------------------- #enum auto select field by type enum.use.by.type=true
-
Console output
easy_api
- Please set Preferences(Settings) > Other Settings > EasyApi > Common > log to `LOW```
-
Logs of IDEA:
[TRACE] find config file:/Users/zhuangjiaju/IdeaProjects/ali-study/.easy.api.config [DEBUG] use recommend config [INFO] Start find apis... [TRACE] find config file:/Users/zhuangjiaju/IdeaProjects/ali-study/.easy.api.config [DEBUG] use recommend config [INFO] search api from: com.alibaba.study.controller.oauth.OauthController [INFO] Export to https://yapi.alibaba.com/project/217/interface/api/cat_1000558 success [WARN] can not resolve com.alibaba.study.api.enums.OauthSourceEnum for com.alibaba.study.controller.oauth.request.UnboundRequest#oauthSource [WARN] can not resolve com.alibaba.study.api.enums.RenderTypeEnum for com.alibaba.study.controller.oauth.request.OauthRequest#renderType [WARN] can not resolve com.alibaba.study.api.enums.OauthSourceEnum for com.alibaba.study.controller.oauth.request.OauthRequest#oauthSource [INFO] Apis exported completed
Add any other context about the problem here.
你可能需要关闭: https://github.com/tangcent/easy-yapi/blob/ecebe4d9de62dfabcc8227e75abf8bfc825eb2db/idea-plugin/src/main/resources/.recommend.easy.api.config#L532
如果没有解决你的问题,可能需要提供一下你这个字段
OauthRequest#oauthSource
上的注释
这次加的特性是出于这种情况的考虑:
http://easyyapi.com/setting/yapi-mock.html
我不确定使用枚举名称
的开发者多一些还是使用枚举中的一个字段
的开发者多一些
Anyway, 我都会优化一下这里的提示。
关闭 enum.use.by.type=true 就可以了。 但是还有一个疑问: /** * 授权来源 * * @see OauthSourceEnum#getCode() */ @NotNull(message = "授权来源不能为空") @IsEnum(enumType = OauthSourceEnum.class, message = "授权来源错误") private String oauthSource;
我的see 都是 后面跟方法的 是不是跟方法比较靠谱?
跟成员变量 显示红色的 比较丑陋。
跟方法就很好看
我的see 都是 后面跟方法的 是不是跟方法比较靠谱?
是的,跟方法好看一点,我应该是做过兼容了,field/method都可以处理。如果跟方法无法解析的话,可以提一个BUG。
哈哈 应该是不可以 我测试了下。 但是我关闭 enum.use.by.type=true 就符合我的预期了。
应该是不可以
我试了一下,这里确实有个BUG。
这个BUG在命中单一方法时不会触发, 只存在于命中多个method
时, 你这里正好由于继承的原因: getDescription命中了实现类和基类的两个方法。
你这里直接@see OauthSourceEnum#getDescription
不加()
, 能绕过这段错误的逻辑。
我一般是这样定义:
public class UserInfo {
/**
* @default 2
* @see com.itangcent.common.constant.UserType
*/
private int type;//用户类型
/**
* @default 2
* @see UserType#getType()
*/
private int userType;//用户类型
/**
* @default 2
* @see UserType#getDesc
*/
private String xxxx;//用户类型
}
然后导出结果是这样的:

enum.use.by.type=true
我加没加此配置都不行
版本
备注
结果
控制台打印
@liguanqiao 在Preferences(Settings) > Other Settings > EasyApi >Recommend最下面那行,取消选中。
@tangcent 好的,取消选中后可行