链接: EasyYapi官方文档.
第一步:安装插件
直接搜索 EasyYapi 作者:tangcent
第二步:配置数据
A 配置Postman
-
Postman.build example 的选中效果去除
-
Postman.export model 设置为UPDATE
B 配置Yapi
-
Yapi.server 填入域名信息
-
Yapi.tokens 可不用填,导出的时候会有弹框
C 其他配置
- http.timeOuts(s) 值设置大一些
第三步:导出接口
- 可在控制层类里面右键,选择 EasyApi 选择导出的渠道
- 选择导出单个接口时,可以选择 EasyApi.Export Api 可以选择当前页面要导出的接口
- 也可以在包名上右键选择导出,可以将包下所属接口都导出
遇到的问题:
以上就是基本操作了但是导出到渠道里面会有以下问题:
一、POSTMAN
- 接口里面没有服务名称做前缀
- 数组参数的值默认为[""] 空数组里面有个空串
- 一些常量字段每次导出时都要重新赋值,
- 接口的认证信息每次都要填写
二、YAPI
- 接口里面没有服务名称做前缀
- 。。
解决办法
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
实用技巧:
- post接口会将参数类里面的所有成员都当成业务参数进行输出
- 可以使用@keep queryDate,carModelList 进行字段限定
- 某个字段不为空时,可以在文档注释里面使用 @notNull进行标注即可
- 接口经常变动或是需要经常统计接口信息时,可以将相关信息维护在接口里面
- 接口导入到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);
});
}
```
错误问题整理:
- 枚举不能在yapi mock数据时,可以在recommond 勾选enum_use_ordinal,另外两个enum不要勾,大概率可以解决