diff --git a/build.gradle b/build.gradle index eb99970..26fe9af 100644 --- a/build.gradle +++ b/build.gradle @@ -4,7 +4,7 @@ plugins { } group 'com.github.jetplugins' -version '0.8.1' +version '0.9' sourceCompatibility = 1.8 targetCompatibility = 1.8 compileJava.options.encoding = "UTF-8" diff --git a/docs/GUIDE.md b/docs/GUIDE.md index 6e5672a..b6cd777 100644 --- a/docs/GUIDE.md +++ b/docs/GUIDE.md @@ -3,11 +3,10 @@ ## 快速开始 1. 安装插件: [Yapi X](https://plugins.jetbrains.com/plugin/17425-yapi-x) -2. 添加配置文件: .yapix, 内容: `yapiProjectId=你的项目id` -3. 选中上传的方法: 执行"Upload To YApi" +2. 选中上传的方法: 执行"Upload To YApi" - 支持整个类、多个类、当个方法API文档上传 -- 插件配置路径: File -> Settings -> Tools -> Yapi X +- 插件配置路径: File -> Settings -> Other Settings -> Yapi X 提示: 默认情况下右键菜单是"Upload To YApi", 可通过插件菜单配置为Rap2, Eolinker等 @@ -16,7 +15,12 @@ 1. 文档注释: 类、方法、字段文档注释应完善 2. 使用实体类: 接收参数、响应参数,避免使用map等类型 -TODO +| 目标 | 描述 | +| :--- | :--- | +| 接口分类 | 文档标记@menu > 类文档注释第一行(推荐)| +| 接口名称 | 文档标记@description > 方法文档注释第一行(推荐) | +| 字段名称 | 字段描述 (也兼容swagger) | +| 文档标记 @ignore | 标记的类、方法、字段会被忽略(有浸入性) | ## 平台 目前支持多个平台YApi, Rap2, Eolinker,包括公有部署和私有部署,支持账户密码登录。 @@ -48,9 +52,12 @@ TODO | rap2ProjectId | integer | Rap2项目id | | eolinkerProjectId | string | Eolinker项目id | | showdocProjectId | string | ShowDoc项目id | +| | | | | yapiUrl | string | YApi服务地址 | 场景:插件无法支持YApi统一登录方式,此时可使用项目token方式 | | yapiProjectToken | string | YApi项目访问token | | | | | +| strict | boolean | 是否开启严格模式, true(默认), false | 严格模式下不会解析无分类、无接口名的 | +| | | | | returnWrapType | string | 方法返回值,统一包装类限定名 | 场景: spring统一配置了返回包装类 | | returnUnwrapTypes | string | 方法返回值,指定不需要包装的类 | 场景: 某些类不需要spring统一包装, 多个用英文逗号分割 | | parameterIgnoreTypes | list<string> | 方法参数忽略的类全称 | 场景: 某些方法参数不是由浏览器客户端上传到 | diff --git a/src/main/java/io/yapix/action/AbstractAction.java b/src/main/java/io/yapix/action/AbstractAction.java index 48b0a40..12b58c8 100644 --- a/src/main/java/io/yapix/action/AbstractAction.java +++ b/src/main/java/io/yapix/action/AbstractAction.java @@ -36,9 +36,7 @@ import io.yapix.parse.ApiParser; import io.yapix.parse.model.ClassParseData; import io.yapix.parse.model.MethodParseData; -import java.util.ArrayList; import java.util.List; -import java.util.Map; import java.util.Objects; import java.util.concurrent.ExecutorService; import java.util.concurrent.Executors; @@ -222,7 +220,7 @@ public void run(@NotNull ProgressIndicator indicator) { AtomicInteger count = new AtomicInteger(); AtomicDouble fraction = new AtomicDouble(); - List urls = new ArrayList<>(); + List urls = null; try { List> futures = Lists.newArrayListWithExpectedSize(apis.size()); for (int i = 0; i < apis.size() && !indicator.isCanceled(); i++) { @@ -252,16 +250,10 @@ public void run(@NotNull ProgressIndicator indicator) { } catch (InterruptedException e) { // ignore } finally { - if (urls.size() == 1) { - String url = urls.get(0).getApiUrl(); + if (urls != null && !urls.isEmpty()) { + ApiUploadResult uploadResult = urls.get(0); + String url = urls.size() == 1 ? uploadResult.getApiUrl() : uploadResult.getCategoryUrl(); notifyInfo("Upload successful", format("%s", url, url)); - } else { - Map> categories = urls.stream() - .collect(Collectors.groupingBy(ApiUploadResult::getCategoryUrl)); - notifyInfo(format("Upload result: categories=%d - apis=%d/%d", categories.size(), urls.size(), - apis.size())); - categories.keySet().forEach( - url -> notifyInfo("Upload successful", format("%s", url, url))); } threadPool.shutdown(); afterAction.get(); diff --git a/src/main/java/io/yapix/base/util/PasswordSafeUtils.java b/src/main/java/io/yapix/base/util/PasswordSafeUtils.java index de16c7c..91f81d0 100644 --- a/src/main/java/io/yapix/base/util/PasswordSafeUtils.java +++ b/src/main/java/io/yapix/base/util/PasswordSafeUtils.java @@ -15,19 +15,19 @@ private PasswordSafeUtils() { * 获取密码 */ public static String getPassword(String key, String username) { - return PasswordSafe.getInstance().getPassword(createCredentialAttributes(key, username)); + CredentialAttributes attributes = new CredentialAttributes( + CredentialAttributesKt.generateServiceName(DefaultConstants.ID, key), username); + return PasswordSafe.getInstance().getPassword(attributes); } /** * 存储密码 */ public static void storePassword(String key, String username, String password) { - Credentials credentials = new Credentials("", password); - PasswordSafe.getInstance().set(createCredentialAttributes(key, username), credentials); - } - - private static CredentialAttributes createCredentialAttributes(String key, String username) { - return new CredentialAttributes(CredentialAttributesKt.generateServiceName(DefaultConstants.ID, key), username); + Credentials credentials = new Credentials(username, password); + CredentialAttributes attributes = new CredentialAttributes( + CredentialAttributesKt.generateServiceName(DefaultConstants.ID, key)); + PasswordSafe.getInstance().set(attributes, credentials); } } diff --git a/src/main/java/io/yapix/process/eolinker/config/EolinkerSettings.java b/src/main/java/io/yapix/process/eolinker/config/EolinkerSettings.java index 512b23c..fb040ea 100644 --- a/src/main/java/io/yapix/process/eolinker/config/EolinkerSettings.java +++ b/src/main/java/io/yapix/process/eolinker/config/EolinkerSettings.java @@ -42,7 +42,9 @@ public class EolinkerSettings implements PersistentStateComponent { */ private long cookiesTtl; - /** 授权用户id */ + /** + * 授权用户id + */ private Long cookiesUserId; public static Rap2Settings getInstance() { @@ -63,6 +65,11 @@ public static Rap2Settings getInstance() { return settings; } + public static void storeInstance(@NotNull Rap2Settings state) { + getInstance().loadState(state); + PasswordSafeUtils.storePassword(PASSWORD_KEY, state.account, state.password); + } + @Nullable @Override public Rap2Settings getState() { diff --git a/src/main/java/io/yapix/process/rap2/config/Rap2SettingsConfiguration.java b/src/main/java/io/yapix/process/rap2/config/Rap2SettingsConfiguration.java index 2a8cb88..b0579f2 100644 --- a/src/main/java/io/yapix/process/rap2/config/Rap2SettingsConfiguration.java +++ b/src/main/java/io/yapix/process/rap2/config/Rap2SettingsConfiguration.java @@ -38,7 +38,7 @@ public boolean isModified() { @Override public void apply() { Rap2Settings data = form.get(); - Rap2Settings.getInstance().loadState(data); + Rap2Settings.storeInstance(data); } @Override diff --git a/src/main/java/io/yapix/process/rap2/config/Rap2SettingsDialog.java b/src/main/java/io/yapix/process/rap2/config/Rap2SettingsDialog.java index 62b1595..1e66882 100644 --- a/src/main/java/io/yapix/process/rap2/config/Rap2SettingsDialog.java +++ b/src/main/java/io/yapix/process/rap2/config/Rap2SettingsDialog.java @@ -66,7 +66,7 @@ protected void doOKAction() { settings.setCookiesTtl(testResult.getAuthCookies().getTtl()); settings.setCookiesUserId(testResult.getAuthUser().getId()); // 存储配置 - Rap2Settings.getInstance().loadState(settings); + Rap2Settings.storeInstance(settings); super.doOKAction(); } if (code == Code.NETWORK_ERROR) { diff --git a/src/main/java/io/yapix/process/showdoc/config/ShowdocSettings.java b/src/main/java/io/yapix/process/showdoc/config/ShowdocSettings.java index be33bac..ecea872 100644 --- a/src/main/java/io/yapix/process/showdoc/config/ShowdocSettings.java +++ b/src/main/java/io/yapix/process/showdoc/config/ShowdocSettings.java @@ -55,6 +55,11 @@ public static ShowdocSettings getInstance() { return settings; } + public static void storeInstance(@NotNull ShowdocSettings state) { + getInstance().loadState(state); + PasswordSafeUtils.storePassword(PASSWORD_KEY, state.account, state.password); + } + @Nullable @Override public ShowdocSettings getState() { diff --git a/src/main/java/io/yapix/process/showdoc/config/ShowdocSettingsConfiguration.java b/src/main/java/io/yapix/process/showdoc/config/ShowdocSettingsConfiguration.java index b69dd3b..8548ce9 100644 --- a/src/main/java/io/yapix/process/showdoc/config/ShowdocSettingsConfiguration.java +++ b/src/main/java/io/yapix/process/showdoc/config/ShowdocSettingsConfiguration.java @@ -38,7 +38,7 @@ public boolean isModified() { @Override public void apply() { ShowdocSettings data = form.get(); - ShowdocSettings.getInstance().loadState(data); + ShowdocSettings.storeInstance(data); } @Override diff --git a/src/main/java/io/yapix/process/showdoc/config/ShowdocSettingsDialog.java b/src/main/java/io/yapix/process/showdoc/config/ShowdocSettingsDialog.java index c925024..9bdc25f 100644 --- a/src/main/java/io/yapix/process/showdoc/config/ShowdocSettingsDialog.java +++ b/src/main/java/io/yapix/process/showdoc/config/ShowdocSettingsDialog.java @@ -65,7 +65,7 @@ protected void doOKAction() { settings.setCookies(testResult.getAuthCookies().getCookies()); settings.setCookiesTtl(testResult.getAuthCookies().getTtl()); // 存储配置 - ShowdocSettings.getInstance().loadState(settings); + ShowdocSettings.storeInstance(settings); super.doOKAction(); } if (code == Code.NETWORK_ERROR) { diff --git a/src/main/java/io/yapix/process/yapi/config/YapiSettings.java b/src/main/java/io/yapix/process/yapi/config/YapiSettings.java index 9d21aa2..fadde16 100644 --- a/src/main/java/io/yapix/process/yapi/config/YapiSettings.java +++ b/src/main/java/io/yapix/process/yapi/config/YapiSettings.java @@ -60,6 +60,11 @@ public static YapiSettings getInstance() { return settings; } + public static void storeInstance(@NotNull YapiSettings state) { + getInstance().loadState(state); + PasswordSafeUtils.storePassword(PASSWORD_KEY, state.account, state.password); + } + @Nullable @Override public YapiSettings getState() { @@ -68,7 +73,6 @@ public YapiSettings getState() { @Override public void loadState(@NotNull YapiSettings state) { - PasswordSafeUtils.storePassword(PASSWORD_KEY, state.account, state.password); XmlSerializerUtil.copyBean(state, this); } diff --git a/src/main/java/io/yapix/process/yapi/config/YapiSettingsConfiguration.java b/src/main/java/io/yapix/process/yapi/config/YapiSettingsConfiguration.java index 8806ccc..02f5f4a 100644 --- a/src/main/java/io/yapix/process/yapi/config/YapiSettingsConfiguration.java +++ b/src/main/java/io/yapix/process/yapi/config/YapiSettingsConfiguration.java @@ -38,7 +38,7 @@ public boolean isModified() { @Override public void apply() { YapiSettings data = form.get(); - YapiSettings.getInstance().loadState(data); + YapiSettings.storeInstance(data); } @Override diff --git a/src/main/java/io/yapix/process/yapi/config/YapiSettingsDialog.java b/src/main/java/io/yapix/process/yapi/config/YapiSettingsDialog.java index 7afeadf..29a01cb 100644 --- a/src/main/java/io/yapix/process/yapi/config/YapiSettingsDialog.java +++ b/src/main/java/io/yapix/process/yapi/config/YapiSettingsDialog.java @@ -62,7 +62,7 @@ protected void doOKAction() { settings.setCookies(testResult.getAuthCookies().getCookies()); settings.setCookiesTtl(testResult.getAuthCookies().getTtl()); // 存储配置 - YapiSettings.getInstance().loadState(settings); + YapiSettings.storeInstance(settings); super.doOKAction(); } if (code == Code.NETWORK_ERROR) { diff --git a/src/main/resources/META-INF/plugin.xml b/src/main/resources/META-INF/plugin.xml index 9340363..0046826 100644 --- a/src/main/resources/META-INF/plugin.xml +++ b/src/main/resources/META-INF/plugin.xml @@ -76,6 +76,15 @@ 0.9

+
    +
  • feat: 默认严格不上传未指定分类和名称接口
  • +
  • feat: 支持类和方法级别忽略ignore标记
  • +
  • feat: 支持解析抽象类型see标记指定多个实现
  • +
  • fix: 安全存储密码敏感信息
  • +
  • fix: 支持控制层继承接口方法
  • +
  • optimize: 细节优化体验交互
  • +

0.8

  • Feat: Update only when API changes for yapi/rap2.