From 0915d85dd9e090c1b03739751a962833e1f890c5 Mon Sep 17 00:00:00 2001 From: suwenxiong Date: Wed, 30 Jan 2019 11:17:31 +0800 Subject: [PATCH] opti: docs --- CHANGELOG.md | 6 + .../Setting/ProjectToken/ProjectToken.js | 7 +- docs/NAV.md | 3 +- docs/openapi-doc.html | 1403 +++++++++++++++++ package.json | 3 +- static/doc/devops/index.html | 20 +- static/doc/documents/2019-01-15-14-05-46.png | Bin 0 -> 69521 bytes static/doc/documents/CHANGELOG.html | 41 +- static/doc/documents/adv_mock.html | 4 +- static/doc/documents/api.html | 4 +- static/doc/documents/case.html | 10 +- static/doc/documents/data.html | 4 +- static/doc/documents/export-data.html | 4 +- static/doc/documents/index.html | 4 +- static/doc/documents/manage.html | 4 +- static/doc/documents/mock.html | 6 +- static/doc/documents/plugin-dev.html | 4 +- static/doc/documents/plugin-hooks.html | 4 +- static/doc/documents/plugin-index.html | 4 +- static/doc/documents/plugin-list.html | 8 +- static/doc/documents/project.html | 4 +- static/doc/documents/qa.html | 4 +- static/doc/documents/quickstart.html | 6 +- static/doc/documents/redev.html | 4 +- static/doc/index.html | 4 +- static/doc/openapi-doc.html | 1403 +++++++++++++++++ static/doc/openapi.html | 1403 +++++++++++++++++ static/doc/search_json.js | 78 +- static/doc/ydoc/scripts/app.js | 2 +- static/doc/ydoc/styles/style.css | 106 +- static/doc/ydoc/ydoc-plugin-search/search.js | 18 +- 31 files changed, 4497 insertions(+), 78 deletions(-) create mode 100644 docs/openapi-doc.html create mode 100644 static/doc/documents/2019-01-15-14-05-46.png create mode 100644 static/doc/openapi-doc.html create mode 100644 static/doc/openapi.html diff --git a/CHANGELOG.md b/CHANGELOG.md index c2b42ec2..ba6af558 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,3 +1,9 @@ +### v1.5.0 + +* 优化开放 api功能,现在 token 带有用户信息了 +* 修复无法获取请求302 跳转前的 headers + + ### v1.4.4 * 优化了 json-schema 编辑器交互,修复了参数名写到一半提示重复的问题 * 优化了首页体验,提升页面打开速度 diff --git a/client/containers/Project/Setting/ProjectToken/ProjectToken.js b/client/containers/Project/Setting/ProjectToken/ProjectToken.js index d9da2866..a8c48ee1 100644 --- a/client/containers/Project/Setting/ProjectToken/ProjectToken.js +++ b/client/containers/Project/Setting/ProjectToken/ProjectToken.js @@ -75,8 +75,9 @@ class ProjectToken extends Component { 为确保项目内数据的安全性和私密性,请勿轻易将该token暴露给项目组外用户。
- {/*

open接口:

*/} - {/*
+

open接口:

+

详细接口文档

+
  • /api/open/run_auto_test [运行自动化测试]
  • /api/open/import_data [导入数据]
  • @@ -89,7 +90,7 @@ class ProjectToken extends Component {
  • /api/interface/add_cat [新增接口分类]
  • /api/interface/getCatMenu [获取所有分类]
-
*/} +
); } diff --git a/docs/NAV.md b/docs/NAV.md index 459efbd9..bb192111 100644 --- a/docs/NAV.md +++ b/docs/NAV.md @@ -3,4 +3,5 @@ * [教程](documents/index.md) -* [内网部署](devops/index.md) \ No newline at end of file +* [内网部署](devops/index.md) +* [开放Api](openapi.html) \ No newline at end of file diff --git a/docs/openapi-doc.html b/docs/openapi-doc.html new file mode 100644 index 00000000..177c2888 --- /dev/null +++ b/docs/openapi-doc.html @@ -0,0 +1,1403 @@ + + + + yapi开放 api + + + + + +
+ + +
+ + + \ No newline at end of file diff --git a/package.json b/package.json index c4cd4abe..d22bb7b5 100755 --- a/package.json +++ b/package.json @@ -12,7 +12,8 @@ "start": " node server/app.js", "test": "ava", "build-client": "NODE_ENV=production ykit pack -m", - "npm-publish": "node ./npm-publish.js" + "npm-publish": "node ./npm-publish.js", + "docs": "ydoc build && cp docs/openapi-doc.html static/doc/openapi.html" }, "scripts-info": { "start": "运行生产环境服务器", diff --git a/static/doc/devops/index.html b/static/doc/devops/index.html index 5c8333c5..3cf07778 100644 --- a/static/doc/devops/index.html +++ b/static/doc/devops/index.html @@ -1,4 +1,4 @@ -内网部署

内网部署

使用我们提供的 yapi-cli 工具,部署 YApi 平台是非常容易的。建议部署成 http 站点,因 chrome 浏览器安全限制,部署成 https 会导致测试功能在请求 http 站点时文件上传功能异常。

如果您是将服务器代理到 nginx 服务器,请配置 nginx 支持 websocket。

在location /添加
@@ -103,7 +103,7 @@ yapi update -v v1.1.0 //升级到指定版本
   "mail": {...},
   "ldapLogin": {
       "enable": true,
-      "server": "ldap://l-ldapt1.ops.dev.cn0.qunar.com",
+      "server": "ldap://l-ldapt1.com",
       "baseDn": "CN=Admin,CN=Users,DC=test,DC=com",
       "bindPassword": "password123",
       "searchDn": "OU=UserContainer,DC=test,DC=com",
@@ -146,6 +146,20 @@ yapi update -v v1.1.0 //升级到指定版本
 }
 
 
+

如何配置mongodb集群

+

请升级到 yapi >= 1.4.0以上版本,然后在 config.json db项,配置 connectString:

+

+{
+  "port": "***",
+  "db": {
+    "connectString": "mongodb://127.0.0.100:8418,127.0.0.101:8418,127.0.0.102:8418/yapidb?slaveOk=true",
+    "user": "******",
+    "pass": "******"
+  },
+}
+
+
+

详细配置参考: wiki

diff --git a/static/doc/documents/2019-01-15-14-05-46.png b/static/doc/documents/2019-01-15-14-05-46.png new file mode 100644 index 0000000000000000000000000000000000000000..0e77bdbc842eec0474fe9b8a11e5519f229dd07c GIT binary patch literal 69521 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 literal 0 HcmV?d00001 diff --git a/static/doc/documents/CHANGELOG.html b/static/doc/documents/CHANGELOG.html index 4182fecb..8b955f5a 100644 --- a/static/doc/documents/CHANGELOG.html +++ b/static/doc/documents/CHANGELOG.html @@ -1,4 +1,4 @@ -教程

v1.5.0

+
    +
  • 优化开放 api功能,现在 token 带有用户信息了
  • +
  • 修复无法获取请求302 跳转前的 headers
  • +
+

v1.4.4

+
    +
  • 优化了 json-schema 编辑器交互,修复了参数名写到一半提示重复的问题
  • +
  • 优化了首页体验,提升页面打开速度
  • +
  • 新增自动化测试通用规则配置功能
  • +
+

v1.4.3

+
    +
  • 修复了可视化安装,mongodb 报错的问题
  • +
  • 支持了 swagger 导出功能
  • +
  • 支持了克隆测试用例
  • +
+

v1.4.2

+
    +
  • 优化数据导入对 headers 处理,如果 requestType 是 json,自动增加header "content-type/json"
  • +
  • fix: 修改了测试集合有多个项目接口时,切换执行环境相互覆盖不生效的问题 #692
  • +
  • fix: mongoose warning 'Error: (node:3819) DeprecationWarning: collection.ensureIndex is deprecated. Use createIndexes instead'
  • +
  • opti: 去掉没必要的redux-thunk
  • +
  • 接口更新没有变化时,不记录日志,避免cron多次导入swagger的接口时,导致动态里展示一大堆的无意义日志
  • +
+

v1.4.1

+
    +
  • 支持任何人都可以添加分组,只有管理员才能修改项目是否公开
  • +
  • 支持 mongodb 集群
  • +
+

Bug Fixed

+
    +
  • 修改 mock严格模式,GET带有 JSON BODY 导致的验证问题
  • +
  • 对 queryPath 改动导致的bug,支持通过 xxx?controller=name 等 query 参数区分路径
  • +
  • 因 tui-editor 需要安装github 依赖,导致部分机器无法部署成功的问题
  • +
+

v1.3.23

  • 接口tag功能
  • 数据导入增加 merge 功能
  • 增加参数的批量导入功能
  • +
  • json schema 可视化编辑器增加 mock 功能

Bug Fixed

    diff --git a/static/doc/documents/adv_mock.html b/static/doc/documents/adv_mock.html index 50ba8d03..1e12422a 100644 --- a/static/doc/documents/adv_mock.html +++ b/static/doc/documents/adv_mock.html @@ -1,4 +1,4 @@ -高级Mock-教程

    高级Mock

    高级 Mock 分为Mock 期望自定义 Mock 脚本两种方式。

    Mock 期望

    在测试时,很多时候需要根据不同的请求参数、IP 返回不同的 HTTP Code、HTTP 头和 JSON 数据。

    diff --git a/static/doc/documents/api.html b/static/doc/documents/api.html index 50af61c0..1ce1a78c 100644 --- a/static/doc/documents/api.html +++ b/static/doc/documents/api.html @@ -1,4 +1,4 @@ -接口设置-教程

    接口设置

    进入项目页,可以看到项目下的所有接口,需要注意的是,YApi有 接口集合测试集合 两个概念。

    diff --git a/static/doc/documents/data.html b/static/doc/documents/data.html index f21193fa..fed8fd81 100644 --- a/static/doc/documents/data.html +++ b/static/doc/documents/data.html @@ -1,4 +1,4 @@ -数据导入-教程

    数据导入

    在数据管理可快速导入其他格式的接口数据,方便快速添加接口。YApi 目前支持 postman, swagger, har 数据导入。

    v1.3.23+ 增加数据导入的3种同步方式 normal, good, mergin

      diff --git a/static/doc/documents/export-data.html b/static/doc/documents/export-data.html index 9721e1f8..9f1b6835 100644 --- a/static/doc/documents/export-data.html +++ b/static/doc/documents/export-data.html @@ -1,4 +1,4 @@ -数据导出-教程

      数据导出

      为了方便开发者将接口数据分析给第三方或其他使用者,YApi 内置了方便易用的接口数据导出功能。

      使用教程

      在 项目 -> 数据管理,选择需要导出的数据方式,一共有三种导出方式,html,markdown,json。然后点击导出按钮,将会下载数据文件。

      diff --git a/static/doc/documents/index.html b/static/doc/documents/index.html index 33ab3f36..26c27dcc 100644 --- a/static/doc/documents/index.html +++ b/static/doc/documents/index.html @@ -1,4 +1,4 @@ -YApi-教程

      YApi

      在开始使用 YApi 之前,我们先来熟悉一下 YApi 的网站结构,这将让你快速了解YApi。

      登录与注册

      想要使用 YApi ,首先要注册账号。

      diff --git a/static/doc/documents/manage.html b/static/doc/documents/manage.html index eee7f5ab..11ba7e95 100644 --- a/static/doc/documents/manage.html +++ b/static/doc/documents/manage.html @@ -1,4 +1,4 @@ -权限权利-教程

      权限权利

      接口管理的逻辑较为复杂,操作频率高,层层审批将严重拖慢生产效率,因此传统的金字塔管理模式并不适用。

      YApi 将扁平化管理模式的思想引入到产品的权限管理中,超级管理员 拥有最高的权限,并将权限分配给若干 组长超级管理员 只需管理组长 即可,实际上管理YAPI各大分组与项目的是“组长”。组长对分组或项目负责,一般由BU负责人/项目负责人担任。

      认识组长

      diff --git a/static/doc/documents/mock.html b/static/doc/documents/mock.html index b0625c68..3272d5d1 100644 --- a/static/doc/documents/mock.html +++ b/static/doc/documents/mock.html @@ -1,4 +1,4 @@ -Mock介绍-教程

      Mock介绍

      YApi的 Mock 功能可以根据用户的输入接口信息如协议、URL、接口名、请求头、请求参数、返回数据([返回数据](#mock))生成 Mock 接口,这些接口会自动生成模拟数据,创建者可以自由构造需要的数据。

      mock地址解析YApi平台网址 + mock + 您的项目id + 接口实际请求path

      假设你 YApi 的部署地址为:http://yapi.xxx.com 然后用这个地址作为示例

      @@ -22,7 +22,7 @@

      方式1. mockjs

      原理

      -

      基于 mockjs,跟 Mockjs 区别是 yapi 基于 json + 注释 定义 mock 数据,无法使用 mockjs 原有的函数功能。

      +

      基于 mockjs,跟 Mockjs 区别是 yapi 基于 json + 注释 定义 mock 数据,无法使用 mockjs 原有的函数功能。

      1. 正则表达式需要基于 rule 书写,示例如下:
      diff --git a/static/doc/documents/plugin-dev.html b/static/doc/documents/plugin-dev.html index 3e7f606e..bf152bd5 100644 --- a/static/doc/documents/plugin-dev.html +++ b/static/doc/documents/plugin-dev.html @@ -1,4 +1,4 @@ -教程

      运行开发服务器

      npm install
       npm install -g ykit #依赖 ykit 
       npm run dev #启动开发服务器
      diff --git a/static/doc/documents/plugin-hooks.html b/static/doc/documents/plugin-hooks.html
      index aafb7a52..5e3027eb 100644
      --- a/static/doc/documents/plugin-hooks.html
      +++ b/static/doc/documents/plugin-hooks.html
      @@ -1,4 +1,4 @@
      -教程

      后端 hookList

      目前 hooksList 只有下面列出的部分,如果您有其他的需求,可提建议到 github 或者 qq 群

      /**
        * 钩子配置
      diff --git a/static/doc/documents/plugin-index.html b/static/doc/documents/plugin-index.html
      index 0bdfef9a..b8e7a430 100644
      --- a/static/doc/documents/plugin-index.html
      +++ b/static/doc/documents/plugin-index.html
      @@ -1,4 +1,4 @@
      -教程

      安装

      假设插件名为:yapi-plugin-demo,安装方法如下:

      cd {项目目录}
       yapi plugin yapi-plugin-demo
      diff --git a/static/doc/documents/plugin-list.html b/static/doc/documents/plugin-list.html
      index 54b2dcc9..f065b4fa 100644
      --- a/static/doc/documents/plugin-list.html
      +++ b/static/doc/documents/plugin-list.html
      @@ -1,4 +1,4 @@
      -教程
      diff --git a/static/doc/documents/project.html b/static/doc/documents/project.html index 7fc770e8..b43bb58a 100644 --- a/static/doc/documents/project.html +++ b/static/doc/documents/project.html @@ -1,4 +1,4 @@ -项目操作-教程

      项目操作

      基本设置

      • tag 信息:可自定义tag名称和tag描述,tag信息可用在接口tag标识中;
      • diff --git a/static/doc/documents/qa.html b/static/doc/documents/qa.html index 50225a80..d2042e6e 100644 --- a/static/doc/documents/qa.html +++ b/static/doc/documents/qa.html @@ -1,4 +1,4 @@ -常见问题解答-教程

        常见问题解答

        本页面罗列了大家使用 YApi 时遇到的常见问题.

        如果没有找到您要的答案,请联系管理员.

        Q1 怎样联系组长?

        diff --git a/static/doc/documents/quickstart.html b/static/doc/documents/quickstart.html index 659c5ea2..d11db89b 100644 --- a/static/doc/documents/quickstart.html +++ b/static/doc/documents/quickstart.html @@ -1,4 +1,4 @@ -如何创建接口?-教程

        如何创建接口?

        把大象装进冰箱分几步?三步:把冰箱门打开,把大象装进去,关门,搞定~

        新建接口分几步?也是三步:

        -

        想了解更多权限信息,请查看权限列表

        +

        想了解更多权限信息,请查看权限列表

        选择项目

          diff --git a/static/doc/documents/redev.html b/static/doc/documents/redev.html index 1e1173e0..f559e672 100644 --- a/static/doc/documents/redev.html +++ b/static/doc/documents/redev.html @@ -1,4 +1,4 @@ -教程

          安装YApi

          1.创建工程目录

          mkdir yapi && cd yapi
           git clone https://github.com/YMFE/yapi.git vendors --depth=1 # 或者下载 zip 包解压到 vendors 目录
          diff --git a/static/doc/index.html b/static/doc/index.html
          index f9ea32ad..ab76da4e 100644
          --- a/static/doc/index.html
          +++ b/static/doc/index.html
          @@ -1,4 +1,4 @@
          -YApi 接口管理平台

          YApi

          旨在为开发、产品、测试人员提供更优雅的接口管理服务。可以帮助开发者轻松创建、发布、维护 API

          当前版本: v1.5.0

          bg
          权限管理

          YApi 成熟的团队管理扁平化项目权限配置满足各类企业的需求

          可视化接口管理

          基于 websocket 的多人协作接口编辑功能和类 postman 测试工具,让多人协作成倍提升开发效率

          Mock Server

          易用的 Mock Server,再也不用担心 mock 数据的生成了

          自动化测试

          完善的接口自动化测试,保证数据的正确性

          数据导入

          支持导入 swagger, postman, har 数据格式,方便迁移旧项目

          插件机制

          强大的插件机制,满足各类业务需求

          diff --git a/static/doc/openapi-doc.html b/static/doc/openapi-doc.html new file mode 100644 index 00000000..177c2888 --- /dev/null +++ b/static/doc/openapi-doc.html @@ -0,0 +1,1403 @@ + + + + yapi开放 api + + + + + +
          + + +
          + + + \ No newline at end of file diff --git a/static/doc/openapi.html b/static/doc/openapi.html new file mode 100644 index 00000000..177c2888 --- /dev/null +++ b/static/doc/openapi.html @@ -0,0 +1,1403 @@ + + + + yapi开放 api + + + + + +
          + + +
          + + + \ No newline at end of file diff --git a/static/doc/search_json.js b/static/doc/search_json.js index 93a9955f..4c646e42 100644 --- a/static/doc/search_json.js +++ b/static/doc/search_json.js @@ -702,6 +702,11 @@ window.ydoc_plugin_search_json = { "title": "详细使用方法", "url": "/documents/case.html#服务端自动化测试-详细使用方法", "content": "详细使用方法点击服务端测试,出现如下弹窗,用户访问该 url 就可以获取当前测试用例的所有测试结果。" + }, + { + "title": "配置通用规则", + "url": "/documents/case.html#配置通用规则", + "content": "配置通用规则配置通用规则能够使自动化测试,可以基于通用的规则去控制,无需手动一个一个维护case." } ] }, @@ -759,6 +764,11 @@ window.ydoc_plugin_search_json = { "title": "详细使用方法", "url": "/documents/case.html#服务端自动化测试-详细使用方法", "content": "详细使用方法点击服务端测试,出现如下弹窗,用户访问该 url 就可以获取当前测试用例的所有测试结果。" + }, + { + "title": "配置通用规则", + "url": "/documents/case.html#配置通用规则", + "content": "配置通用规则配置通用规则能够使自动化测试,可以基于通用的规则去控制,无需手动一个一个维护case." } ] }, @@ -1209,10 +1219,35 @@ window.ydoc_plugin_search_json = { "content": "", "url": "/documents/CHANGELOG.html", "children": [ + { + "title": "v1.5.0", + "url": "/documents/CHANGELOG.html#v1.5.0", + "content": "v1.5.0优化开放 api功能,现在 token 带有用户信息了\n修复无法获取请求302 跳转前的 headers\n" + }, + { + "title": "v1.4.4", + "url": "/documents/CHANGELOG.html#v1.4.4", + "content": "v1.4.4优化了 json-schema 编辑器交互,修复了参数名写到一半提示重复的问题\n优化了首页体验,提升页面打开速度\n新增自动化测试通用规则配置功能\n" + }, + { + "title": "v1.4.3", + "url": "/documents/CHANGELOG.html#v1.4.3", + "content": "v1.4.3修复了可视化安装,mongodb 报错的问题\n支持了 swagger 导出功能\n支持了克隆测试用例\n" + }, + { + "title": "v1.4.2", + "url": "/documents/CHANGELOG.html#v1.4.2", + "content": "v1.4.2优化数据导入对 headers 处理,如果 requestType 是 json,自动增加header \"content-type/json\"\nfix: 修改了测试集合有多个项目接口时,切换执行环境相互覆盖不生效的问题 #692\nfix: mongoose warning 'Error: (node:3819) DeprecationWarning: collection.ensureIndex is deprecated. Use createIndexes instead'\nopti: 去掉没必要的redux-thunk\n接口更新没有变化时,不记录日志,避免cron多次导入swagger的接口时,导致动态里展示一大堆的无意义日志\n" + }, + { + "title": "v1.4.1", + "url": "/documents/CHANGELOG.html#v1.4.1", + "content": "v1.4.1支持任何人都可以添加分组,只有管理员才能修改项目是否公开\n支持 mongodb 集群\nBug Fixed修改 mock严格模式,GET带有 JSON BODY 导致的验证问题\n对 queryPath 改动导致的bug,支持通过 xxx?controller=name 等 query 参数区分路径\n因 tui-editor 需要安装github 依赖,导致部分机器无法部署成功的问题\n" + }, { "title": "v1.3.23", "url": "/documents/CHANGELOG.html#v1.3.23", - "content": "v1.3.23接口tag功能\n数据导入增加 merge 功能\n增加参数的批量导入功能\nBug Fixed接口path中写入 ?name=xxx bug\n高级mock 匹配 data: [{item: XXX}] 时匹配不成功\n接口运行 query params 自动勾选\nmock get 带 cookie 时跨域\njson schema 嵌套多层 array 预览不展示 bug\nswagger URL 导入 跨域问题\n" + "content": "v1.3.23接口tag功能\n数据导入增加 merge 功能\n增加参数的批量导入功能\njson schema 可视化编辑器增加 mock 功能\nBug Fixed接口path中写入 ?name=xxx bug\n高级mock 匹配 data: [{item: XXX}] 时匹配不成功\n接口运行 query params 自动勾选\nmock get 带 cookie 时跨域\njson schema 嵌套多层 array 预览不展示 bug\nswagger URL 导入 跨域问题\n" }, { "title": "v1.3.22", @@ -1391,10 +1426,35 @@ window.ydoc_plugin_search_json = { "content": "", "url": "/documents/CHANGELOG.html", "children": [ + { + "title": "v1.5.0", + "url": "/documents/CHANGELOG.html#v1.5.0", + "content": "v1.5.0优化开放 api功能,现在 token 带有用户信息了\n修复无法获取请求302 跳转前的 headers\n" + }, + { + "title": "v1.4.4", + "url": "/documents/CHANGELOG.html#v1.4.4", + "content": "v1.4.4优化了 json-schema 编辑器交互,修复了参数名写到一半提示重复的问题\n优化了首页体验,提升页面打开速度\n新增自动化测试通用规则配置功能\n" + }, + { + "title": "v1.4.3", + "url": "/documents/CHANGELOG.html#v1.4.3", + "content": "v1.4.3修复了可视化安装,mongodb 报错的问题\n支持了 swagger 导出功能\n支持了克隆测试用例\n" + }, + { + "title": "v1.4.2", + "url": "/documents/CHANGELOG.html#v1.4.2", + "content": "v1.4.2优化数据导入对 headers 处理,如果 requestType 是 json,自动增加header \"content-type/json\"\nfix: 修改了测试集合有多个项目接口时,切换执行环境相互覆盖不生效的问题 #692\nfix: mongoose warning 'Error: (node:3819) DeprecationWarning: collection.ensureIndex is deprecated. Use createIndexes instead'\nopti: 去掉没必要的redux-thunk\n接口更新没有变化时,不记录日志,避免cron多次导入swagger的接口时,导致动态里展示一大堆的无意义日志\n" + }, + { + "title": "v1.4.1", + "url": "/documents/CHANGELOG.html#v1.4.1", + "content": "v1.4.1支持任何人都可以添加分组,只有管理员才能修改项目是否公开\n支持 mongodb 集群\nBug Fixed修改 mock严格模式,GET带有 JSON BODY 导致的验证问题\n对 queryPath 改动导致的bug,支持通过 xxx?controller=name 等 query 参数区分路径\n因 tui-editor 需要安装github 依赖,导致部分机器无法部署成功的问题\n" + }, { "title": "v1.3.23", "url": "/documents/CHANGELOG.html#v1.3.23", - "content": "v1.3.23接口tag功能\n数据导入增加 merge 功能\n增加参数的批量导入功能\nBug Fixed接口path中写入 ?name=xxx bug\n高级mock 匹配 data: [{item: XXX}] 时匹配不成功\n接口运行 query params 自动勾选\nmock get 带 cookie 时跨域\njson schema 嵌套多层 array 预览不展示 bug\nswagger URL 导入 跨域问题\n" + "content": "v1.3.23接口tag功能\n数据导入增加 merge 功能\n增加参数的批量导入功能\njson schema 可视化编辑器增加 mock 功能\nBug Fixed接口path中写入 ?name=xxx bug\n高级mock 匹配 data: [{item: XXX}] 时匹配不成功\n接口运行 query params 自动勾选\nmock get 带 cookie 时跨域\njson schema 嵌套多层 array 预览不展示 bug\nswagger URL 导入 跨域问题\n" }, { "title": "v1.3.22", @@ -1613,7 +1673,7 @@ window.ydoc_plugin_search_json = { { "title": "配置LDAP登录", "url": "/devops/index.html#配置ldap登录", - "content": "配置LDAP登录打开项目目录 config.json 文件,添加如下字段:{ \"port\": \"*****\",\n \"adminAccount\": \"********\",\n \"db\": {...},\n \"mail\": {...},\n \"ldapLogin\": {\n \"enable\": true,\n \"server\": \"ldap://l-ldapt1.ops.dev.cn0.qunar.com\",\n \"baseDn\": \"CN=Admin,CN=Users,DC=test,DC=com\",\n \"bindPassword\": \"password123\",\n \"searchDn\": \"OU=UserContainer,DC=test,DC=com\",\n \"searchStandard\": \"mail\", // 自定义格式: \"searchStandard\": \"&(objectClass=user)(cn=%s)\"\n \"emailPostfix\": \"@163.com\",\n \"emailKey\": \"mail\",\n \"usernameKey\": \"name\"\n }\n}\n\n这里面的配置项含义如下:enable 表示是否配置 LDAP 登录,true(支持 LDAP登录 )/false(不支持LDAP登录);\nserver LDAP 服务器地址,前面需要加上 ldap:// 前缀,也可以是 ldaps:// 表示是通过 SSL 连接;\nbaseDn LDAP 服务器的登录用户名,必须是从根结点到用户节点的全路径(非必须);\nbindPassword 登录该 LDAP 服务器的密码(非必须);\nsearchDn 查询用户数据的路径,类似数据库中的一张表的地址,注意这里也必须是全路径;\nsearchStandard 查询条件,这里是 mail 表示查询用户信息是通过邮箱信息来查询的。注意,该字段信息与LDAP数据库存储数据的字段相对应,如果如果存储用户邮箱信息的字段是 email, 这里就需要修改成 email.(1.3.18+支持)自定义filter表达式,基本形式为:&(objectClass=user)(cn=%s), 其中%s会被username替换\nemailPostfix 登陆邮箱后缀(非必须)\nemailKey: ldap数据库存放邮箱信息的字段(v1.3.21 新增 非必须)\nusernameKey: ldap数据库存放用户名信息的字段(v1.3.21 新增 非必须)\n重启服务器后,可以在登录页看到如下画面,说明 ladp 配置成功" + "content": "配置LDAP登录打开项目目录 config.json 文件,添加如下字段:{ \"port\": \"*****\",\n \"adminAccount\": \"********\",\n \"db\": {...},\n \"mail\": {...},\n \"ldapLogin\": {\n \"enable\": true,\n \"server\": \"ldap://l-ldapt1.com\",\n \"baseDn\": \"CN=Admin,CN=Users,DC=test,DC=com\",\n \"bindPassword\": \"password123\",\n \"searchDn\": \"OU=UserContainer,DC=test,DC=com\",\n \"searchStandard\": \"mail\", // 自定义格式: \"searchStandard\": \"&(objectClass=user)(cn=%s)\"\n \"emailPostfix\": \"@163.com\",\n \"emailKey\": \"mail\",\n \"usernameKey\": \"name\"\n }\n}\n\n这里面的配置项含义如下:enable 表示是否配置 LDAP 登录,true(支持 LDAP登录 )/false(不支持LDAP登录);\nserver LDAP 服务器地址,前面需要加上 ldap:// 前缀,也可以是 ldaps:// 表示是通过 SSL 连接;\nbaseDn LDAP 服务器的登录用户名,必须是从根结点到用户节点的全路径(非必须);\nbindPassword 登录该 LDAP 服务器的密码(非必须);\nsearchDn 查询用户数据的路径,类似数据库中的一张表的地址,注意这里也必须是全路径;\nsearchStandard 查询条件,这里是 mail 表示查询用户信息是通过邮箱信息来查询的。注意,该字段信息与LDAP数据库存储数据的字段相对应,如果如果存储用户邮箱信息的字段是 email, 这里就需要修改成 email.(1.3.18+支持)自定义filter表达式,基本形式为:&(objectClass=user)(cn=%s), 其中%s会被username替换\nemailPostfix 登陆邮箱后缀(非必须)\nemailKey: ldap数据库存放邮箱信息的字段(v1.3.21 新增 非必须)\nusernameKey: ldap数据库存放用户名信息的字段(v1.3.21 新增 非必须)\n重启服务器后,可以在登录页看到如下画面,说明 ladp 配置成功" }, { "title": "禁止注册", @@ -1624,6 +1684,11 @@ window.ydoc_plugin_search_json = { "title": "版本通知", "url": "/devops/index.html#版本通知", "content": "版本通知(v1.3.19+ 增加)在 config.json 添加 \"versionNotify\": true 配置项,就可以开启版本通知功能,默认为 false,修改完成后,请重启 yapi 服务器。{ \"port\": \"******\",\n \"adminAccount\": \"*****\",\n \"versionNotify\": true\n}\n\n" + }, + { + "title": "如何配置mongodb集群", + "url": "/devops/index.html#版本通知-如何配置mongodb集群", + "content": "如何配置mongodb集群请升级到 yapi >= 1.4.0以上版本,然后在 config.json db项,配置 connectString:{\n \"port\": \"***\",\n \"db\": {\n \"connectString\": \"mongodb://127.0.0.100:8418,127.0.0.101:8418,127.0.0.102:8418/yapidb?slaveOk=true\",\n \"user\": \"******\",\n \"pass\": \"******\"\n },\n}\n\n详细配置参考: wiki" } ] }, @@ -1670,7 +1735,7 @@ window.ydoc_plugin_search_json = { { "title": "配置LDAP登录", "url": "/devops/index.html#配置ldap登录", - "content": "配置LDAP登录打开项目目录 config.json 文件,添加如下字段:{ \"port\": \"*****\",\n \"adminAccount\": \"********\",\n \"db\": {...},\n \"mail\": {...},\n \"ldapLogin\": {\n \"enable\": true,\n \"server\": \"ldap://l-ldapt1.ops.dev.cn0.qunar.com\",\n \"baseDn\": \"CN=Admin,CN=Users,DC=test,DC=com\",\n \"bindPassword\": \"password123\",\n \"searchDn\": \"OU=UserContainer,DC=test,DC=com\",\n \"searchStandard\": \"mail\", // 自定义格式: \"searchStandard\": \"&(objectClass=user)(cn=%s)\"\n \"emailPostfix\": \"@163.com\",\n \"emailKey\": \"mail\",\n \"usernameKey\": \"name\"\n }\n}\n\n这里面的配置项含义如下:enable 表示是否配置 LDAP 登录,true(支持 LDAP登录 )/false(不支持LDAP登录);\nserver LDAP 服务器地址,前面需要加上 ldap:// 前缀,也可以是 ldaps:// 表示是通过 SSL 连接;\nbaseDn LDAP 服务器的登录用户名,必须是从根结点到用户节点的全路径(非必须);\nbindPassword 登录该 LDAP 服务器的密码(非必须);\nsearchDn 查询用户数据的路径,类似数据库中的一张表的地址,注意这里也必须是全路径;\nsearchStandard 查询条件,这里是 mail 表示查询用户信息是通过邮箱信息来查询的。注意,该字段信息与LDAP数据库存储数据的字段相对应,如果如果存储用户邮箱信息的字段是 email, 这里就需要修改成 email.(1.3.18+支持)自定义filter表达式,基本形式为:&(objectClass=user)(cn=%s), 其中%s会被username替换\nemailPostfix 登陆邮箱后缀(非必须)\nemailKey: ldap数据库存放邮箱信息的字段(v1.3.21 新增 非必须)\nusernameKey: ldap数据库存放用户名信息的字段(v1.3.21 新增 非必须)\n重启服务器后,可以在登录页看到如下画面,说明 ladp 配置成功" + "content": "配置LDAP登录打开项目目录 config.json 文件,添加如下字段:{ \"port\": \"*****\",\n \"adminAccount\": \"********\",\n \"db\": {...},\n \"mail\": {...},\n \"ldapLogin\": {\n \"enable\": true,\n \"server\": \"ldap://l-ldapt1.com\",\n \"baseDn\": \"CN=Admin,CN=Users,DC=test,DC=com\",\n \"bindPassword\": \"password123\",\n \"searchDn\": \"OU=UserContainer,DC=test,DC=com\",\n \"searchStandard\": \"mail\", // 自定义格式: \"searchStandard\": \"&(objectClass=user)(cn=%s)\"\n \"emailPostfix\": \"@163.com\",\n \"emailKey\": \"mail\",\n \"usernameKey\": \"name\"\n }\n}\n\n这里面的配置项含义如下:enable 表示是否配置 LDAP 登录,true(支持 LDAP登录 )/false(不支持LDAP登录);\nserver LDAP 服务器地址,前面需要加上 ldap:// 前缀,也可以是 ldaps:// 表示是通过 SSL 连接;\nbaseDn LDAP 服务器的登录用户名,必须是从根结点到用户节点的全路径(非必须);\nbindPassword 登录该 LDAP 服务器的密码(非必须);\nsearchDn 查询用户数据的路径,类似数据库中的一张表的地址,注意这里也必须是全路径;\nsearchStandard 查询条件,这里是 mail 表示查询用户信息是通过邮箱信息来查询的。注意,该字段信息与LDAP数据库存储数据的字段相对应,如果如果存储用户邮箱信息的字段是 email, 这里就需要修改成 email.(1.3.18+支持)自定义filter表达式,基本形式为:&(objectClass=user)(cn=%s), 其中%s会被username替换\nemailPostfix 登陆邮箱后缀(非必须)\nemailKey: ldap数据库存放邮箱信息的字段(v1.3.21 新增 非必须)\nusernameKey: ldap数据库存放用户名信息的字段(v1.3.21 新增 非必须)\n重启服务器后,可以在登录页看到如下画面,说明 ladp 配置成功" }, { "title": "禁止注册", @@ -1681,6 +1746,11 @@ window.ydoc_plugin_search_json = { "title": "版本通知", "url": "/devops/index.html#版本通知", "content": "版本通知(v1.3.19+ 增加)在 config.json 添加 \"versionNotify\": true 配置项,就可以开启版本通知功能,默认为 false,修改完成后,请重启 yapi 服务器。{ \"port\": \"******\",\n \"adminAccount\": \"*****\",\n \"versionNotify\": true\n}\n\n" + }, + { + "title": "如何配置mongodb集群", + "url": "/devops/index.html#版本通知-如何配置mongodb集群", + "content": "如何配置mongodb集群请升级到 yapi >= 1.4.0以上版本,然后在 config.json db项,配置 connectString:{\n \"port\": \"***\",\n \"db\": {\n \"connectString\": \"mongodb://127.0.0.100:8418,127.0.0.101:8418,127.0.0.102:8418/yapidb?slaveOk=true\",\n \"user\": \"******\",\n \"pass\": \"******\"\n },\n}\n\n详细配置参考: wiki" } ] } diff --git a/static/doc/ydoc/scripts/app.js b/static/doc/ydoc/scripts/app.js index 9f3c9f95..e1e4fa14 100644 --- a/static/doc/ydoc/scripts/app.js +++ b/static/doc/ydoc/scripts/app.js @@ -74,7 +74,7 @@ function initComponents() { navigation = responsiveNav('.js-nav', { customToggle: '#js-nav-btn', open: function() { - $menu.classList.remove('active'); + if ($menu) $menu.classList.remove('active'); setTimeout(itemAddActive, 0); } }); diff --git a/static/doc/ydoc/styles/style.css b/static/doc/ydoc/styles/style.css index 0e0174a9..0379895e 100644 --- a/static/doc/ydoc/styles/style.css +++ b/static/doc/ydoc/styles/style.css @@ -26,6 +26,7 @@ body { ::-webkit-scrollbar { width: 6px; + height: 4px; } ::-webkit-scrollbar-track { @@ -90,7 +91,7 @@ h6, .h6 { ::before, ::after { box-sizing: border-box; - -webkit-tap-highlight-color: transparent; + -webkit-tap-highlight-color: rgba(0, 0, 0, 0); } html { @@ -216,7 +217,7 @@ input::-moz-focus-inner { } mark { - background-color: transparent; + background-color: rgba(0, 0, 0, 0); } a, @@ -582,7 +583,7 @@ a:link, a:visited { } .nav-toggle { - -webkit-tap-highlight-color: transparent; + -webkit-tap-highlight-color: rgba(0, 0, 0, 0); -webkit-touch-callout: none; -webkit-user-select: none; -moz-user-select: none; @@ -606,6 +607,10 @@ a:link, a:visited { } } +html { + height: 100%; +} + body { width: 100%; height: 100%; @@ -1371,6 +1376,14 @@ body { font-weight: 500; } +.markdown-body h2 { + margin: .54rem 0 .24rem; +} + +.markdown-body h3 { + margin: .32rem 0 .16rem; +} + .markdown-body a { text-decoration: none; background-color: rgba(187, 239, 253, 0.3); @@ -1385,6 +1398,25 @@ body { border-bottom-color: rgba(3, 17, 31, 0.87); } +.markdown-body .type { + color: #1890ff; + font-size: 16px; +} + +.markdown-body .versionTag { + background: #1890ff; + color: white; + border-radius: 4px; + padding: 2px 4px; + font-size: 14px; +} + +.markdown-body .desc { + font-size: 16px; + font-weight: normal; + color: rgba(0, 0, 0, 0.65); +} + /* PrismJS 1.14.0 http://prismjs.com/download.html#themes=prism&languages=markup+css+clike+javascript */ /** @@ -1608,15 +1640,25 @@ pre[class*="language-"] { .m-header-nav .m-header-subtitle .link { display: inline-block; + padding-left: .5em; + padding-right: .5em; width: 100%; + background-color: transparent; + border-radius: 4px; + line-height: .32rem; + transition: all 0.2s; +} + +.m-header-nav .m-header-subtitle .link:hover { + color: #1890ff; + background-color: #d9edff; } .m-header-nav .item { - margin-bottom: 0.08rem; width: 100%; display: inline-block; line-height: 1.8; - margin: 0 0.08rem; + padding: 0 0.08rem; position: relative; cursor: pointer; transition: all 0.2s; @@ -1629,15 +1671,24 @@ pre[class*="language-"] { .m-header-nav .item.active { font-weight: bold; - color: rgba(3, 17, 31, 0.87); -} - -.m-header-nav .item.active .href { - border-bottom: 2px solid #1890ff; + color: #1890ff; } .m-header-nav .href { - padding: .5em; + display: inline-block; + padding-left: .5em; + padding-right: .5em; + height: .32rem; + line-height: .32rem; + width: 100%; + background-color: transparent; + border-radius: 4px; + transition: all 0.2s; +} + +.m-header-nav .href:active { + color: #1890ff; + background-color: #d9edff; } .m-header-btn { @@ -1651,7 +1702,7 @@ pre[class*="language-"] { padding: .12rem; cursor: pointer; transition: color 0.2s; - -webkit-tap-highlight-color: transparent; + -webkit-tap-highlight-color: rgba(0, 0, 0, 0); -webkit-touch-callout: none; -webkit-user-select: none; -moz-user-select: none; @@ -1676,7 +1727,8 @@ pre[class*="language-"] { padding: 0; } .m-header-nav .m-header-items > .item:hover .m-header-subtitle { - display: block; + display: flex; + flex-wrap: wrap; } .m-header-nav .m-header-subtitle { display: none; @@ -1710,16 +1762,37 @@ pre[class*="language-"] { top: -.16rem; transform: translateX(-50%); } + .m-header-nav .m-header-subtitle .link { + display: inline-block; + padding: 0; + width: auto; + } + .m-header-nav .m-header-subtitle .link:hover { + font-weight: bold; + color: rgba(3, 17, 31, 0.87); + background-color: transparent; + } + .m-header-nav .href { + border-radius: 0; + } + .m-header-nav .href:hover { + font-weight: bold; + color: rgba(3, 17, 31, 0.87); + background-color: transparent; + } .m-header-nav .item { margin: 0 0.16rem; line-height: .64rem; width: auto; transition: color 0.2s; } - .m-header-nav .item:hover { + .m-header-nav .item.active { font-weight: bold; color: rgba(3, 17, 31, 0.87); } + .m-header-nav .item.active .href { + border-bottom: 2px solid #1890ff; + } .m-header .m-header-nav { overflow: inherit; } @@ -1779,8 +1852,9 @@ pre[class*="language-"] { margin-bottom: .16rem; } -.m-summary-block .m-summary-block { - margin-bottom: 0; +.m-summary-block.active > .href { + font-weight: bold; + color: #1890ff; } .m-summary-title { diff --git a/static/doc/ydoc/ydoc-plugin-search/search.js b/static/doc/ydoc/ydoc-plugin-search/search.js index 6697dbd4..582b00cf 100644 --- a/static/doc/ydoc/ydoc-plugin-search/search.js +++ b/static/doc/ydoc/ydoc-plugin-search/search.js @@ -10,10 +10,10 @@ $(function(){ // 判断是否为空对象 function realObj(obj) { - for (var i in obj) { - return true; + if (JSON.stringify(obj) === '{}') { + return false; // 如果为空,返回false } - return false; + return true; } // 防抖函数 @@ -35,15 +35,16 @@ $(function(){ var index = str.indexOf(val); var startIndex = index > highlightTextPrevNum ? index - highlightTextPrevNum : 0; var sliceStr = str.slice(startIndex, index + val.length + highlightTextNextNum); - var addHighlightStr = sliceStr.replace(val, '' + val + ''); + var reg = new RegExp('(' + val + ')', 'gi'); // 搜索的值进行高亮替换时, 忽略大小写 + var addHighlightStr = sliceStr.replace(reg, '' + '$1' + ''); var ellipsis = (sliceStr.lastIndexOf(val) != -1) || (sliceStr.lastIndexOf(val) > highlightTextNextNum) ? '...' : ''; return addHighlightStr + ellipsis; } // 隐藏搜索结果框 - function hideSearchResult() { - $searchResult.hide(); - } + // function hideSearchResult() { + // $searchResult.hide(); + // } // 监听输入的内容 $searchInput.on('input', debounce(function(e) { @@ -97,6 +98,7 @@ $(function(){ activeIndex = (activeIndex + 1) % length; $captions[activeIndex].classList.add('active'); } else if (e.keyCode == 13) { + $searchResult.hide(); window.open($captions[activeIndex].href, '_self'); } }); @@ -113,7 +115,7 @@ $(function(){ } }, 300)); - $searchResult.on('click', function(e){ + $searchResult.on('click', function (e) { return false; })