idea-easyYapi的使用

本文详细介绍了如何安装和配置EasyYapi,以及如何将接口导出到Postman和Yapi。在使用过程中,提到的常见问题包括接口前缀缺失、数组参数默认值和认证信息的处理。文章还提供了问题解决方案和实用技巧,如自定义配置、日志打印及Mock数据设置。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

链接: EasyYapi官方文档.

第一步:安装插件 

直接搜索 EasyYapi    作者:tangcent 

 第二步:配置数据

       A 配置Postman
       B 配置Yapi
  • Yapi.server   填入域名信息

  • Yapi.tokens  可不用填,导出的时候会有弹框

       C 其他配置

  • http.timeOuts(s)   值设置大一些        

 第三步:导出接口

  • 可在控制层类里面右键,选择 EasyApi   选择导出的渠道
  • 选择导出单个接口时,可以选择 EasyApi.Export Api   可以选择当前页面要导出的接口
  • 也可以在包名上右键选择导出,可以将包下所属接口都导出


遇到的问题:

        以上就是基本操作了但是导出到渠道里面会有以下问题:

        一、POSTMAN
  1. 接口里面没有服务名称做前缀
  2. 数组参数的值默认为[""]  空数组里面有个空串
  3. 一些常量字段每次导出时都要重新赋值,
  4. 接口的认证信息每次都要填写 
        二、YAPI
  1. 接口里面没有服务名称做前缀
  2. 。。

解决办法

idea设置里面找到   other settings.EasyApi.Remote填入以下链接

将链接里面的blob改为raw

https://gitee.com/soldier_jw/configuration-file/raw/master/easy-yapi/groovy.config

 以上远程链接里面的内容也可以 写到     other settings.EasyApi.BuilinConfig里面

以上配置是通用配置,但是有些项目就需要一些特定配置,例 :1、接口服务名的设置   2、特定字段的预期值

可以使用本地配置   在项目下面创建文件 .easy.api.config

实用技巧:

  1. post接口会将参数类里面的所有成员都当成业务参数进行输出
    1. 可以使用@keep queryDate,carModelList   进行字段限定
  2. 某个字段不为空时,可以在文档注释里面使用  @notNull进行标注即可
  3. 接口经常变动或是需要经常统计接口信息时,可以将相关信息维护在接口里面
  4. 接口导入到postman里面时,认证信息可以以变量的形式维护在postman里面,以环境区分

# 打印日志:
http.call.before=groovy:logger.info("call:"+request.url())
http.call.after=groovy:logger.info("response:"+response.string())
api.class.parse.before=groovy:logger.info("[api] before parse class:"+it)
api.class.parse.after=groovy:logger.info("[api] after parse class:"+it)
api.method.parse.before=groovy:logger.info("[api] before parse method:"+it)
api.method.parse.after=groovy:logger.info("[api] after parse method:"+it)
api.param.parse.before=groovy:logger.info("[api] before parse param:"+it)
api.param.parse.after=groovy:logger.info("[api] after parse param:"+it)
json.class.parse.before=groovy:logger.info("[json] before parse class:"+it)
json.class.parse.after=groovy:logger.info("[json] after parse class:"+it)
json.method.parse.before=groovy:logger.info("[json] before parse method:"+it)
json.method.parse.after=groovy:logger.info("[json] after parse method:"+it)
json.field.parse.before=groovy:logger.info("[json] before parse field:"+it)
json.field.parse.after=groovy:logger.info("[json] after parse field:"+it)

自用脚本

#properties.additional=https://raw.githubusercontent.com/tangcent/easy-yapi/master/third/javax.validation.mock.config
#properties.additional=https://raw.githubusercontent.com/tangcent/easy-yapi/master/third/swagger.config
#properties.additional=https://raw.githubusercontent.com/tangcent/easy-yapi/master/third/swagger.advanced.config
# 可以 直接 引用 本地文件 
#properties.additional=/usr/tangcent/easy-yapi/master/third/.yapi.config

# 打印日志
# 打印日志:
# http.call.before=groovy:logger.info("call:"+request.url())
# http.call.after=groovy:logger.info("response:"+response.string()) 



#dev=true


# 在输出的url中添加前缀标识
# class.prefix.path=/BIform

folder.name=#folder
# 忽略在字段上注释了ignore的字段
field.ignore[#ignore]=true
# 输出参数类中的默认值,也可在文档注释中写明 
field.default.value=#default


# tag只以逗号进行分隔
api.tag=#tag
api.tag.delimiter=,
#--------------------

# 添加备注
# 移出 header里面的token
# export.after=groovy:api.removeHeader("token")
# 添加 header属性
method.additional.header={name: "Authorization",value: "{{Authorization}}",desc: "认证Token",required:true, example:""}
# method.additional.header={name: "lan",value: "zh",desc: "语言:zh或en",required:true, example:"zh或en"}


# 将url里面的特定字符替换,postman 和yapi替换的东西不一样,所以要分两次替换
export.after=groovy:api.setPath(api.path().replace("\$","").replaceAll("\\{app.base-path:","").replaceAll("\\}",""))

 

# tool 工具方法查看:https://easyyapi.com/setting/tools/tool.html
 
# postman 请求参数mock数据 
# 查询日期和业务起始时间
field.demo[field:queryDate]=groovy:tool.today()
field.demo[field:dataBeginDate]=2022-12-07

# 这里把所有的车系和版型都设置进去,   后端代码会自动将逗号分隔,所以可以合到一起
 field.demo[field:carModelList]=['1','2','3','4']
# field.demo[field:carTypeList]=['1,2,3,7,9,8,30,31,11,12,13,17,29,28,330,331']


# 锁单
field.demo[field:bigOrderType|string]=002
field.demo[field:blindOrderType|string]=002
# 海外小定
# field.demo[field:orderType]=S001
field.demo[field:dateLevel|int]=1
# 1为大区,2为城市
field.demo[field:rankType|int]=1
# 1为占比值,2为比率值
field.demo[field:rankType|int]=1
# 1为大定,2为锁单
field.demo[field:optionOrderType|int]=1
# 交付还是开票
field.demo[field:dataType]=DELIVERY
# date    date,car_model
field.demo[field:returnFields]=date

# 车系code ============================================================
field.demo[field:BigOrderPieModel.carTypeList]=[1]



# 新增小定
field.demo[field:smallOrderFocus|string]=ORDER_NEW


# 向前翻页
field.demo[field:after|boolean]=false
# 14个时间节点数据
field.demo[field:pageSize|int]=14

# 
field.demo[field:focus|string]=1

# 字段注释上有 notNull时,yapi上显示为必须字段  2023-05-31
field.required[#notNull]=true
field.required[#NotNull]=true
field.required[#notnull]=true
field.required[#notBlank]=true
field.required[#NotBlank]=true
field.required[#notblank]=true

 
param.required=@com.sun.istack.internal.NotNull


# postman专用  导入到postman的时候,集合里面总会生成 一个空字串,每次都要删除,很费事
# 将map的value置为空时,导入到yapi的时候,会少很多数据,所以要跟yapi区分开
export.after=groovy:``` 
    // 为postman时走以下逻辑   获取当前导出的渠道: markdown/postman/yapi
    if(!"postman".equals(runtime.channel())){
        return
    }
    // 获取 请求参数数据
    def body = api.request.body 
	 


    if(body!=null && body instanceof Map){ 
        for(k in body.keySet().toList()){
            // 为集合时才置为空
            if(body[k] instanceof List){ 
		    body[k]=[]  
            }   
        } 
    }
    // 将处理好的请求参数设置回去
    api.setBody(body)
```


# yapi专用   对一些注解进行处理,对参数类的某些字段进行特殊注释
# 这里是获取参数类里面的
export.after=groovy:```
    // 为yapi时走以下逻辑   获取当前导出的渠道: markdown/postman/yapi
    if(!"yapi".equals(runtime.channel())){
        return
    }
   // 根据类名解析出全类名 ,可以避免暴露敏感数据,有些工程没有这个类会报错
   def privilege_class = helper.resolveLink("{@link RowPrivilegeProperty}") 
   // 有些工程没有这个类会报错
   if(null != privilege_class){  
       for(arg in it.args()){
           for (item in arg.type().fields()){

            	def privilege_class_value = item.annValue(privilege_class.name,"dataType")  

                if(null == privilege_class_value){ continue }
                if ("BI.Data.Car.Model".equals(privilege_class_value)){
                    groovy:api.appendDesc("<font color='red' size=3> <b>涉及到车系权限</font>")
                }
            }       
        }
    }


     // 将数据周期放到备注里面
     def dc = it.doc("dc")
     if(dc != null){
     	groovy:api.appendDesc("<br/><font size=3> <b>数据周期:"+dc+"</font>")
     }
     // 将数据接口表放到备注里面

     def table = it.doc("table") 
     if(table != null){ 
     	groovy:api.appendDesc("<br/><font size=1> <b>涉及表:"+table+"</font>")
     }
 

    // 调用此接口需要开通的权限
   def permission_check_class = helper.resolveLink("{@link PermissionCheck}")  
   if(null != permission_check_class){
	// 服务code
       	def privilege_class_appCode = it.annValue(permission_check_class.name,"appCode")  
	// 权限编码
	def privilege_class_permissionCode = it.annValue(permission_check_class.name,"permissionCode")  

	// 如果方法上没有 权限注解则从类上取
	if(null == privilege_class_appCode){
	    def clazz =it.containingClass()
	    privilege_class_appCode = clazz.annValue(permission_check_class.name,"appCode")  
	    privilege_class_permissionCode = clazz.annValue(permission_check_class.name,"permissionCode")  

	}

        groovy:api.appendDesc("</br><font size=3> <b>需要配置权限   appCode:"+privilege_class_appCode+",  编码:"+privilege_class_permissionCode+"</font>")        
	// logger.error(privilege_class_appCode+"------"+privilege_class_permissionCode)
   }

``` 

 

# 只在请求参数里面展示 在方法doc.keep里面注释的字段
#关掉缓存
json.cache.disable=true
json.group=groovy:session.get("keep")
param.before[groovy:it.method().hasDoc("keep")]=groovy:```
    session.set("keep", it.method().doc("keep").split(","))
```
param.after[groovy:it.method().hasDoc("keep")]=groovy:```
    session.remove("keep")
```
field.ignore[groovy:session.get("keep")!=null]=groovy:```
    !tool.equalOrIntersect(session.get("keep"),it.name())
```










# ↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓========更改字段的注释========↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓ 

field.doc=groovy:```
  	def split_class = helper.resolveLink("{@link SplitParam}")
	if(null == split_class){
		return
	}
	if(it.hasAnn(split_class.name)){
		return "(单个名称对应多个code)"
	}
```

# 获取参数注解里面的值,并将其输出到yapi备注里
field.hasAnn[helper.resolveLink("{@link SplitParam}")]=groovy:```
  def ann_class_name = helper.resolveLink("{@link SplitParam}").name
	logger.error("=-====="+ann_class_name)
       def data_type = it.annValue(ann_class_name,"dataType")
       if(null == data_type){ return }
       if ("BI.Data.Car.Model".equals(data_type)){
return ""
//           return "**涉及车系权限**"
       }
```
 


# ↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑========更改字段的注释========↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑


# 当请求参数为map时,可以 在方法上打上json体,然后设置到
# https://github.com/tangcent/easy-yapi/issues/854

#export.after[#body]=groovy:```
#    import groovy.json.JsonSlurper
#    api.setJsonBody(new JsonSlurper().parseText(it.doc("body")), null)
#```
#  要输出的字段       @required 参数是否必填         @comment  字符释义
#{"ssid":"","uid":"","room_type":"","@required":{"ssid":true,"uid":true,"room_type":true},"@comment":{"ssid":"ssid test","uid":"uid test","room_type":""}} 




# 对返回的类进行更改
# method.return[#return]=groovy: helper.resolveLink(it.doc("return"))
#method.return = com.zeekr.vo.v2.leads.NewLeadsCardVO

#method.return[#return]=groovy: "com.zeekr.utils.response.Result<" +  helper.resolveLink(it.doc("return")) +">"


#  yapi进行mock
mock.[*queryDate]=@now('yyyy-MM-dd')
mock.[dataBeginDate]=2022-01-01
 

mock.[country]=@pick(["荷兰","瑞典"]
mock.[orderSource]=@pick(["个人","企业"])
 

mock.[after|boolean]=false

mock.[*|string]=''
mock.[carModelList]=''
   



#  如果没有doc注释的话,使用这个参数去填
# field.doc[groovy:tool.isNullOrEmpty(it.doc())]=fffffffffsfdsfdsfds







# ========================生成统计信息=============================================================
control=```
	def control = ["order":"OrderController","delivery": "DeliveryController","car":"ProduceController"]
```
# ${control}
#  control["order"]
#

api.class.parse.before=groovy:``` 
    localStorage.set("class_name",it.name())
    // 只取第一行
    localStorage.set("folder_name",it.doc().split("\n")[0]) 
```


export.after=groovy:```
    // 生成 接口名称和url
    def 业务域名称 = localStorage.get("folder_name")

    // 将过期注解拿到 
    def 接口名称 = api.name()
    if(it.hasAnn("java.lang.Deprecated")){
	接口名称 = "已过期_"+接口名称 
    }
    api.setName(接口名称)

    def table_list = it.doc("table")
    def tag = it.doc("tag")

    def 业务周期 = it.doc("dc")
    def class_full_name = localStorage.get("class_name")
    def tab = "\t"
	// 统计业务周期
  //  logger.error(业务域名称+tab+api.name()+tab+api.path()+tab+业务周期+tab+table_list)  
//   logger.error(业务域名称+tab+api.name()+tab+api.path()+tab+class_full_name+tab+"姬园辉") 
   logger.error(业务域名称+tab+"姬园辉"+tab+接口名称+tab+tag+tab+api.path()+tab+table_list) 
  // api.setBody("bodyType33333333")
//    logger.error("-----"+httpClient.request().url())
// api.setBody(["x":"y"],"描述") 
// api.addParam("name","tang","user name")
// api.setResponseBody("json",["x":"y"])

// api.setResponseBody("json",["x":"y","aaa":["bbb":"333"]]) 
```

# ========================生成统计信息=============================================================
# export.after=groovy: logger.info("正在导出: "+api.name())
# -------

# 将token设置到变量里面
postman.prerequest=```
var auth = pm.environment.get("Authorization");
if(null == auth){
    pm.sendRequest("http://127.0.0.1:81/token.json", 
    function (err, response) {  
    	pm.environment.set("Authorization", response.json().biotd);
    });
}

```

错误问题整理:

  1. 枚举不能在yapi  mock数据时,可以在recommond 勾选enum_use_ordinal,另外两个enum不要勾,大概率可以解决
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值