├── .dockerignore ├── .eslintignore ├── .eslintrc.js ├── .github └── ISSUE_TEMPLATE.md ├── .gitignore ├── .npmignore ├── .npmrc ├── CHANGELOG.md ├── Dockerfile ├── LICENSE ├── README.md ├── client ├── Application.js ├── common.js ├── components │ ├── AceEditor │ │ ├── AceEditor.js │ │ ├── AceEditor.scss │ │ └── mockEditor.js │ ├── AuthenticatedComponent.js │ ├── Breadcrumb │ │ ├── Breadcrumb.js │ │ └── Breadcrumb.scss │ ├── CaseEnv │ │ ├── index.js │ │ └── index.scss │ ├── EasyDragSort │ │ └── EasyDragSort.js │ ├── ErrMsg │ │ ├── ErrMsg.js │ │ └── ErrMsg.scss │ ├── Footer │ │ ├── Footer.js │ │ └── Footer.scss │ ├── GuideBtns │ │ └── GuideBtns.js │ ├── Header │ │ ├── Header.js │ │ ├── Header.scss │ │ └── Search │ │ │ ├── Search.js │ │ │ └── Search.scss │ ├── Intro │ │ ├── Intro.js │ │ └── Intro.scss │ ├── Label │ │ ├── Label.js │ │ └── Label.scss │ ├── Loading │ │ ├── Loading.js │ │ └── Loading.scss │ ├── LogoSVG │ │ └── index.js │ ├── MockDoc │ │ ├── MockDoc.js │ │ └── MockDoc.scss │ ├── ModalPostman │ │ ├── MethodsList.js │ │ ├── MockList.js │ │ ├── VariablesSelect.js │ │ ├── index.js │ │ └── index.scss │ ├── MyPopConfirm │ │ └── MyPopConfirm.js │ ├── Notify │ │ └── Notify.js │ ├── Postman │ │ ├── CheckCrossInstall.js │ │ ├── Postman.js │ │ └── Postman.scss │ ├── ProjectCard │ │ ├── ProjectCard.js │ │ └── ProjectCard.scss │ ├── SchemaTable │ │ ├── SchemaTable.js │ │ └── index.scss │ ├── Subnav │ │ ├── Subnav.js │ │ └── Subnav.scss │ ├── TimeLine │ │ ├── TimeLine.js │ │ └── TimeLine.scss │ ├── UsernameAutoComplete │ │ └── UsernameAutoComplete.js │ └── index.js ├── constants │ └── variable.js ├── containers │ ├── AddProject │ │ ├── AddProject.js │ │ └── Addproject.scss │ ├── DevTools │ │ └── DevTools.js │ ├── Follows │ │ ├── Follows.js │ │ └── Follows.scss │ ├── Group │ │ ├── Group.js │ │ ├── Group.scss │ │ ├── GroupList │ │ │ ├── GroupList.js │ │ │ └── GroupList.scss │ │ ├── GroupLog │ │ │ └── GroupLog.js │ │ ├── GroupSetting │ │ │ ├── GroupSetting.js │ │ │ └── GroupSetting.scss │ │ ├── MemberList │ │ │ ├── MemberList.js │ │ │ └── MemberList.scss │ │ └── ProjectList │ │ │ ├── ProjectList.js │ │ │ ├── ProjectList.scss │ │ │ └── UpDateModal.js │ ├── Home │ │ ├── Home.js │ │ └── Home.scss │ ├── Login │ │ ├── Login.js │ │ ├── Login.scss │ │ ├── LoginContainer.js │ │ ├── LoginWrap.js │ │ └── Reg.js │ ├── News │ │ ├── News.js │ │ ├── News.scss │ │ ├── NewsList │ │ │ └── NewsList.js │ │ └── NewsTimeline │ │ │ └── NewsTimeline.js │ ├── Project │ │ ├── Activity │ │ │ ├── Activity.js │ │ │ └── Activity.scss │ │ ├── Interface │ │ │ ├── Interface.js │ │ │ ├── InterfaceCol │ │ │ │ ├── CaseReport.js │ │ │ │ ├── ImportInterface.js │ │ │ │ ├── InterfaceCaseContent.js │ │ │ │ ├── InterfaceCaseContent.scss │ │ │ │ ├── InterfaceColContent.js │ │ │ │ ├── InterfaceColMenu.js │ │ │ │ └── InterfaceColMenu.scss │ │ │ ├── InterfaceList │ │ │ │ ├── AddInterfaceCatForm.js │ │ │ │ ├── AddInterfaceForm.js │ │ │ │ ├── Edit.js │ │ │ │ ├── Edit.scss │ │ │ │ ├── InterfaceContent.js │ │ │ │ ├── InterfaceEditForm.js │ │ │ │ ├── InterfaceList.js │ │ │ │ ├── InterfaceMenu.js │ │ │ │ ├── Run │ │ │ │ │ ├── AddColModal.js │ │ │ │ │ ├── Run.js │ │ │ │ │ └── Run.scss │ │ │ │ ├── View.js │ │ │ │ ├── View.scss │ │ │ │ ├── editor.css │ │ │ │ └── interfaceMenu.scss │ │ │ └── interface.scss │ │ ├── Project.js │ │ └── Setting │ │ │ ├── ProjectData │ │ │ ├── ProjectData.js │ │ │ └── ProjectData.scss │ │ │ ├── ProjectEnv │ │ │ ├── ProjectEnvContent.js │ │ │ ├── index.js │ │ │ └── index.scss │ │ │ ├── ProjectMember │ │ │ └── ProjectMember.js │ │ │ ├── ProjectMessage │ │ │ ├── ProjectMessage.js │ │ │ ├── ProjectTag.js │ │ │ └── ProjectTag.scss │ │ │ ├── ProjectMock │ │ │ └── index.js │ │ │ ├── ProjectRequest │ │ │ ├── ProjectRequest.js │ │ │ └── project-request.scss │ │ │ ├── ProjectToken │ │ │ ├── ProjectToken.js │ │ │ └── ProjectToken.scss │ │ │ ├── Setting.js │ │ │ └── Setting.scss │ ├── User │ │ ├── List.js │ │ ├── Profile.js │ │ ├── User.js │ │ └── index.scss │ └── index.js ├── font │ ├── QIconLab.eot │ ├── QIconLab.svg │ ├── QIconLab.ttf │ └── QIconLab.woff ├── images │ └── loading.gif ├── index.js ├── plugin.js ├── reducer │ ├── create.js │ ├── middleware │ │ └── messageMiddleware.js │ └── modules │ │ ├── addInterface.js │ │ ├── follow.js │ │ ├── group.js │ │ ├── interface.js │ │ ├── interfaceCol.js │ │ ├── menu.js │ │ ├── mockCol.js │ │ ├── news.js │ │ ├── project.js │ │ ├── reducer.js │ │ └── user.js └── styles │ ├── common.scss │ ├── mixin.scss │ ├── public-sass.scss │ └── theme.less ├── common ├── HandleImportData.js ├── config.js ├── createContext.js ├── diff-view.js ├── formats.js ├── lib.js ├── markdown.js ├── mergeJsonSchema.js ├── mock-extra.js ├── plugin.js ├── postmanLib.js ├── power-string.js ├── schema-transformTo-table.js ├── tui-editor │ └── dist │ │ ├── tui-editor-2x.png │ │ ├── tui-editor-Editor-all.min.js │ │ ├── tui-editor-Editor.min.js │ │ ├── tui-editor-Viewer-all.min.js │ │ ├── tui-editor-Viewer.min.js │ │ ├── tui-editor-contents.min.css │ │ ├── tui-editor-extChart.min.js │ │ ├── tui-editor-extColorSyntax.min.js │ │ ├── tui-editor-extScrollSync.min.js │ │ ├── tui-editor-extTable.min.js │ │ ├── tui-editor-extUML.min.js │ │ ├── tui-editor.min.css │ │ └── tui-editor.png └── utils.js ├── config_example.json ├── docs ├── NAV.md ├── devops │ ├── SUMMARY.md │ ├── index.md │ └── ldap.png ├── documents │ ├── 2019-01-15-14-05-46.png │ ├── CHANGELOG.md │ ├── SUMMARY.md │ ├── adv_mock.md │ ├── api.md │ ├── case-col.png │ ├── case.md │ ├── clone-project.png │ ├── clone-project.png.png │ ├── data.md │ ├── export-data.md │ ├── export-data.png │ ├── images │ │ ├── autoTest.png │ │ ├── autoTestResult.png │ │ ├── baseSet.png │ │ ├── bianlif.jpeg │ │ ├── case_add.jpg │ │ ├── case_add_modal.jpg │ │ ├── case_col_add.jpg │ │ ├── case_col_add_modal.jpg │ │ ├── case_list.jpg │ │ ├── charles.png │ │ ├── dbbmklogo.jpg │ │ ├── elong.jpeg │ │ ├── favicon.ico │ │ ├── getQuery.png │ │ ├── interface_add.png │ │ ├── interface_add_cat.png │ │ ├── interface_run.png │ │ ├── interface_run_valid.png │ │ ├── intro_page_1.png │ │ ├── intro_page_2.png │ │ ├── intro_page_3.png │ │ ├── jd.jpeg │ │ ├── jsonSchema.png │ │ ├── kuaishou.jpeg │ │ ├── lianjia.jpeg │ │ ├── logo_header22@2x.png │ │ ├── logo_header@2x.png │ │ ├── mock-strice.png │ │ ├── mock-strice2.png │ │ ├── mock-strice3.png │ │ ├── mock.jpg │ │ ├── project-remove.png │ │ ├── project_add_view.png │ │ ├── project_group.png │ │ ├── project_list.png │ │ ├── requestSet.png │ │ ├── schema-mock-1.png │ │ ├── schema-mock-2.png │ │ ├── shouqian.png │ │ ├── show.jpeg │ │ ├── usage │ │ │ ├── add-group.png │ │ │ ├── adv-mock-case1.png │ │ │ ├── adv-mock-case3.png │ │ │ ├── adv-mock-case4-new.png │ │ │ ├── adv-mock-case4.png │ │ │ ├── adv-mock-case5-new.png │ │ │ ├── adv-mock-case5.png │ │ │ ├── adv-mock.jpg │ │ │ ├── api_add_btn.png │ │ │ ├── api_add_panel.png │ │ │ ├── api_res.png │ │ │ ├── case-edit.jpg │ │ │ ├── case-list.gif │ │ │ ├── case-list.jpg │ │ │ ├── case_key_body_json.png │ │ │ ├── case_key_list.png │ │ │ ├── case_key_query.png │ │ │ ├── case_key_res.png │ │ │ ├── case_key_res_query.png │ │ │ ├── chrome-1.jpg │ │ │ ├── chrome-2.jpg │ │ │ ├── chrome-3.jpg │ │ │ ├── chrome-4.jpg │ │ │ ├── chrome-5.jpg │ │ │ ├── chrome-6.jpg │ │ │ ├── hover.png │ │ │ ├── index.png │ │ │ ├── json-schema-demo.jpg │ │ │ ├── json-schema-mock.jpg │ │ │ ├── login.png │ │ │ ├── manage_ask.png │ │ │ ├── manage_ask_group.png │ │ │ ├── manage_find_manager.png │ │ │ ├── manage_find_project_owner.png │ │ │ ├── manage_intro_group.png │ │ │ ├── mock-demo.jpg │ │ │ ├── modal-postman-tips.png │ │ │ ├── modal-postman.gif │ │ │ ├── postman-1.jpg │ │ │ ├── postman-2.jpg │ │ │ ├── postman-3.jpg │ │ │ ├── project-message.png │ │ │ ├── project.png │ │ │ ├── projectCopy.png │ │ │ ├── project_add.png │ │ │ ├── project_add_panel.png │ │ │ ├── project_copy_ok.png │ │ │ ├── project_setting.png │ │ │ ├── project_setting_env.png │ │ │ ├── project_setting_global.png │ │ │ ├── project_setting_logo.png │ │ │ └── user.png │ │ ├── vip.jpeg │ │ ├── xuetangx.jpg │ │ ├── ykit.jpg │ │ └── yonyou.jpg │ ├── import-case.png │ ├── import-json-data.png │ ├── index.md │ ├── manage.md │ ├── mock.md │ ├── plugin-dev.md │ ├── plugin-hooks.md │ ├── plugin-index.md │ ├── plugin-list.md │ ├── project.md │ ├── qa.md │ ├── quickstart.md │ ├── redev.md │ └── test-case.png ├── index.jsx ├── openapi-doc.html ├── openapi.html └── web.css ├── exts ├── yapi-plugin-advanced-mock │ ├── AdvMock.js │ ├── MockCol │ │ ├── CaseDesModal.js │ │ ├── CaseDesModal.scss │ │ ├── MockCol.js │ │ └── mockColReducer.js │ ├── advMockModel.js │ ├── caseModel.js │ ├── client.js │ ├── controller.js │ ├── index.js │ └── server.js ├── yapi-plugin-export-data │ ├── .sass-cache │ │ ├── 3f3d6afdb6793d0137c849fff0c1eee600369f02 │ │ │ └── defaultTheme.scssc │ │ └── 8d7dcd37f61732054a9966925c8cce5b23a209ac │ │ │ └── defaultTheme.scssc │ ├── client.js │ ├── controller.js │ ├── defaultTheme.css │ ├── defaultTheme.css.map │ ├── defaultTheme.js │ ├── defaultTheme.scss │ ├── index.js │ └── server.js ├── yapi-plugin-export-swagger2-data │ ├── client.js │ ├── controller.js │ ├── index.js │ └── server.js ├── yapi-plugin-gen-services │ ├── .sass-cache │ │ ├── 3f3d6afdb6793d0137c849fff0c1eee600369f02 │ │ │ └── defaultTheme.scssc │ │ └── 8d7dcd37f61732054a9966925c8cce5b23a209ac │ │ │ └── defaultTheme.scssc │ ├── Services │ │ ├── Services.js │ │ └── Services.scss │ ├── client.js │ ├── controller.js │ ├── defaultTheme.css │ ├── defaultTheme.css.map │ ├── defaultTheme.js │ ├── defaultTheme.scss │ ├── index.js │ └── server.js ├── yapi-plugin-import-har │ ├── client.js │ └── index.js ├── yapi-plugin-import-postman │ ├── client.js │ └── index.js ├── yapi-plugin-import-swagger │ ├── client.js │ ├── index.js │ ├── run.js │ └── server.js ├── yapi-plugin-import-yapi-json │ ├── client.js │ └── index.js ├── yapi-plugin-statistics │ ├── client.js │ ├── controller.js │ ├── index.js │ ├── server.js │ ├── statisMockModel.js │ ├── statisticsClientPage │ │ ├── StatisChart.js │ │ ├── StatisTable.js │ │ ├── index.js │ │ └── index.scss │ ├── test.js │ └── util.js ├── yapi-plugin-swagger-auto-sync │ ├── client.js │ ├── controller │ │ └── syncController.js │ ├── index.js │ ├── interfaceSyncUtils.js │ ├── server.js │ ├── swaggerAutoSync │ │ └── swaggerAutoSync.js │ └── syncModel.js ├── yapi-plugin-test │ ├── client.js │ └── index.js └── yapi-plugin-wiki │ ├── client.js │ ├── controller.js │ ├── index.js │ ├── server.js │ ├── util.js │ ├── wikiModel.js │ └── wikiPage │ ├── Editor.js │ ├── View.js │ ├── index.js │ └── index.scss ├── nodemon.json ├── npm-publish.js ├── package-lock.json ├── package.json ├── plugin.json ├── server ├── app.js ├── controllers │ ├── base.js │ ├── follow.js │ ├── group.js │ ├── interface.js │ ├── interfaceCol.js │ ├── log.js │ ├── open.js │ ├── project.js │ ├── test.js │ └── user.js ├── install.js ├── middleware │ └── mockServer.js ├── models │ ├── avatar.js │ ├── base.js │ ├── follow.js │ ├── group.js │ ├── interface.js │ ├── interfaceCase.js │ ├── interfaceCat.js │ ├── interfaceCol.js │ ├── log.js │ ├── project.js │ ├── storage.js │ ├── token.js │ └── user.js ├── plugin.js ├── router.js ├── utils │ ├── commons.js │ ├── db.js │ ├── initConfig.js │ ├── ldap.js │ ├── mongoose-auto-increment.js │ ├── notice.js │ ├── reportHtml │ │ ├── defaultTheme.css │ │ ├── defaultTheme.js │ │ └── index.js │ ├── sandbox.js │ ├── storage.js │ └── token.js ├── websocket.js └── yapi.js ├── static ├── attachment │ └── cross-request.zip ├── dev.html ├── iconfont │ ├── iconfont.eot │ ├── iconfont.svg │ ├── iconfont.ttf │ └── iconfont.woff ├── image │ ├── avatar-1.png │ ├── avatar.png │ ├── demo-img@1x.jpg │ ├── demo-img@2x.jpg │ └── favicon.png ├── index.html └── prd │ ├── assets.js │ ├── index@4bf34ac5d0d400162c8b.css │ ├── index@4bf34ac5d0d400162c8b.css.gz │ ├── index@4bf34ac5d0d400162c8b.js │ ├── index@4bf34ac5d0d400162c8b.js.gz │ ├── lib2@b606a4c30ccd185aa92f.js │ ├── lib2@b606a4c30ccd185aa92f.js.gz │ ├── lib3@bae7dadd0771f0f60dd8.js │ ├── lib3@bae7dadd0771f0f60dd8.js.gz │ ├── lib@ff671d00820016606eda.js │ ├── lib@ff671d00820016606eda.js.gz │ └── manifest@f2f4bd774d6c221b3d5f.js ├── test ├── common │ ├── common.test.js │ └── mergeJsonSchema.test.js ├── lib.test.js ├── mock-extra.test.js └── server │ ├── commons.test.js │ └── mockServer.test.js ├── webpack.alias.js ├── yapi-base-flow.jpg ├── ydoc.js ├── ydocfile.js └── ykit.config.js /.dockerignore: -------------------------------------------------------------------------------- 1 | node_modules/ 2 | /logs 3 | .git/ -------------------------------------------------------------------------------- /.eslintignore: -------------------------------------------------------------------------------- 1 | node_modules/* 2 | common/json-schema-mockjs.js -------------------------------------------------------------------------------- /.eslintrc.js: -------------------------------------------------------------------------------- 1 | module.exports = { 2 | env: { 3 | "browser": true, 4 | "commonjs": true, 5 | "es6": true, 6 | "node": true 7 | }, 8 | extends: ["eslint:recommended", "plugin:react/recommended"], 9 | parser: "babel-eslint", 10 | parserOptions: { 11 | "ecmaFeatures": { 12 | "jsx": true 13 | }, 14 | "sourceType": "module" 15 | }, 16 | plugins: [ 17 | "react", 18 | "import" 19 | ], 20 | rules: { 21 | "indent": ["off", 2], 22 | "react/display-name": ["off"], 23 | "react/jsx-indent": ["error", 2], 24 | "comma-dangle": ["error", "never"], 25 | "no-console": ["off"], 26 | "import/no-unresolved": ["off"], 27 | "react/no-find-dom-node": ["off"], 28 | "no-empty": ["off"] 29 | // "react/no-unescaped-entities": 0 30 | }, 31 | settings:{ 32 | "react": { 33 | "version": "detect" 34 | } 35 | } 36 | }; 37 | 38 | -------------------------------------------------------------------------------- /.github/ISSUE_TEMPLATE.md: -------------------------------------------------------------------------------- 1 | ## 版本号 2 | ~ 3 | 4 | ## 什么问题 5 | ~ 6 | 7 | ## 如何复现此问题 8 | ~ 9 | 10 | ## 什么浏览器 11 | ~ 12 | 13 | ## 什么系统(Linux, Windows, macOS) 14 | -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | # kdiff3 ignore 2 | *.orig 3 | 4 | # maven ignore 5 | target/ 6 | 7 | # eclipse ignore 8 | .settings/ 9 | .project 10 | .classpath 11 | .history 12 | 13 | # idea ignore 14 | .idea/ 15 | *.ipr 16 | *.iml 17 | *.iws 18 | 19 | # temp ignore 20 | *.log 21 | *.cache 22 | *.diff 23 | *.patch 24 | *.tmp 25 | 26 | # system ignore 27 | .DS_Store 28 | Thumbs.db 29 | 30 | # package ignore (optional) 31 | # *.jar 32 | # *.war 33 | # *.zip 34 | # *.tar 35 | # *.tar.gz 36 | 37 | node_modules/ 38 | runtime/ 39 | /prd/ 40 | /dev/ 41 | .tags 42 | .tags1 43 | tsconfig.json 44 | client/plugin-module.js 45 | .vscode 46 | /iconfont 47 | -------------------------------------------------------------------------------- /.npmignore: -------------------------------------------------------------------------------- 1 | /docs 2 | /test 3 | /static/doc 4 | /iconfont 5 | /ydoc.js 6 | /ydocfile.js 7 | -------------------------------------------------------------------------------- /.npmrc: -------------------------------------------------------------------------------- 1 | sass_binary_site=https://npm.taobao.org/mirrors/node-sass/ 2 | -------------------------------------------------------------------------------- /Dockerfile: -------------------------------------------------------------------------------- 1 | FROM node:12-alpine 2 | ENV TZ="Asia/Shanghai" 3 | # 使用阿里云镜像 4 | RUN sed -i 's/dl-cdn.alpinelinux.org/mirrors.aliyun.com/g' /etc/apk/repositories 5 | WORKDIR /yapi/vendors 6 | COPY . /yapi/vendors/ 7 | 8 | RUN apk add --no-cache wget python make && cd /yapi/vendors && npm set strict-ssl false && npm install --production --registry https://registry.npm.taobao.org 9 | 10 | EXPOSE 3000 11 | ENTRYPOINT ["node"] 12 | -------------------------------------------------------------------------------- /client/components/AceEditor/AceEditor.js: -------------------------------------------------------------------------------- 1 | import React from 'react'; 2 | import mockEditor from './mockEditor'; 3 | import PropTypes from 'prop-types'; 4 | import './AceEditor.scss'; 5 | 6 | const ModeMap = { 7 | javascript: 'ace/mode/javascript', 8 | json: 'ace/mode/json', 9 | text: 'ace/mode/text', 10 | xml: 'ace/mode/xml', 11 | html: 'ace/mode/html' 12 | }; 13 | 14 | const defaultStyle = { width: '100%', height: '200px' }; 15 | 16 | function getMode(mode) { 17 | return ModeMap[mode] || ModeMap.text; 18 | } 19 | 20 | class AceEditor extends React.PureComponent { 21 | constructor(props) { 22 | super(props); 23 | } 24 | 25 | static propTypes = { 26 | data: PropTypes.any, 27 | onChange: PropTypes.func, 28 | className: PropTypes.string, 29 | mode: PropTypes.string, //enum[json, text, javascript], default is javascript 30 | readOnly: PropTypes.bool, 31 | callback: PropTypes.func, 32 | style: PropTypes.object, 33 | fullScreen: PropTypes.bool, 34 | insertCode: PropTypes.func 35 | }; 36 | 37 | componentDidMount() { 38 | this.editor = mockEditor({ 39 | container: this.editorElement, 40 | data: this.props.data, 41 | onChange: this.props.onChange, 42 | readOnly: this.props.readOnly, 43 | fullScreen: this.props.fullScreen 44 | }); 45 | let mode = this.props.mode || 'javascript'; 46 | this.editor.editor.getSession().setMode(getMode(mode)); 47 | if (typeof this.props.callback === 'function') { 48 | this.props.callback(this.editor.editor); 49 | } 50 | } 51 | 52 | UNSAFE_componentWillReceiveProps(nextProps) { 53 | if (!this.editor) { 54 | return; 55 | } 56 | if (nextProps.data !== this.props.data && this.editor.getValue() !== nextProps.data) { 57 | this.editor.setValue(nextProps.data); 58 | let mode = nextProps.mode || 'javascript'; 59 | this.editor.editor.getSession().setMode(getMode(mode)); 60 | this.editor.editor.clearSelection(); 61 | } 62 | } 63 | 64 | render() { 65 | return ( 66 |
{title}
86 |{desc}
87 |{opration}
88 |
40 | {this.props.desc}
41 |
{this.props.msg}
47 |{this.state.mockURL}
69 | 70 |高效、易用、可部署的API管理平台
34 |38 | {location.protocol + 39 | '//' + 40 | location.hostname + 41 | (location.port !== '' ? ':' + location.port : '') + 42 | `/mock/${currProject._id}${currProject.basepath}/yourPath`} 43 |
44 | 49 |{` 39 | npm i sm2tsservice -D 40 | `}41 |
{` 43 | touch json2service.json 44 | `}45 |
{` 46 | { 47 | "url": "yapi-swagger.json", 48 | "remoteUrl": "${location.protocol}//${location.hostname}${location.port ? `:${location.port}` : ''}/api/open/plugin/export-full?type=json&pid=${id}&status=all&token=${this.props.token}", 49 | "type": "yapi", 50 | "swaggerParser": {} 51 | } 52 | `} 53 |54 |
{` 56 | touch json2service.json 57 | `}58 |
{` 59 | { 60 | "url": "${location.protocol}//${location.hostname}${location.port ? `:${location.port}` : ''}/api/open/plugin/export-full?type=json&pid=${id}&status=all&token=${this.props.token}", 61 | "type": "yapi", 62 | "swaggerParser": {} 63 | } 64 | `} 65 |66 |
{` 68 | (./node_modules/.bin/)sm2tsservice --clear 69 | `}70 |
Swagger数据导入( 支持 v2.0+ )
21 |22 | 通过命令行导入接口数据 23 |
24 | ` 25 | }; 26 | }); 27 | }; 28 | -------------------------------------------------------------------------------- /exts/yapi-plugin-import-swagger/index.js: -------------------------------------------------------------------------------- 1 | module.exports = { 2 | server: true, 3 | client: true 4 | } -------------------------------------------------------------------------------- /exts/yapi-plugin-import-swagger/server.js: -------------------------------------------------------------------------------- 1 | module.exports = function(){ 2 | this.bindHook('import_data', function(importDataModule){ 3 | importDataModule.swagger = async (res)=>{ 4 | try{ 5 | return await require('./run.js')(res) 6 | }catch(err){ 7 | this.commons.log(err, 'error') 8 | return false; 9 | } 10 | } 11 | }) 12 | } -------------------------------------------------------------------------------- /exts/yapi-plugin-import-yapi-json/client.js: -------------------------------------------------------------------------------- 1 | import { message } from 'antd'; 2 | 3 | function importData(importDataModule) { 4 | async function run(res) { 5 | try { 6 | let interfaceData = { apis: [], cats: [] }; 7 | res = JSON.parse(res); 8 | res.forEach(item => { 9 | interfaceData.cats.push({ 10 | name: item.name, 11 | desc: item.desc 12 | }); 13 | item.list.forEach(api => { 14 | api.catname = item.name; 15 | }); 16 | interfaceData.apis = interfaceData.apis.concat(item.list); 17 | }); 18 | return interfaceData; 19 | } catch (e) { 20 | console.error(e); 21 | message.error('数据格式有误'); 22 | } 23 | } 24 | 25 | if (!importDataModule || typeof importDataModule !== 'object') { 26 | console.error('importDataModule 参数Must be Object Type'); 27 | return null; 28 | } 29 | 30 | importDataModule.json = { 31 | name: 'json', 32 | run: run, 33 | desc: 'YApi接口 json数据导入' 34 | }; 35 | } 36 | 37 | module.exports = function() { 38 | this.bindHook('import_data', importData); 39 | }; 40 | -------------------------------------------------------------------------------- /exts/yapi-plugin-import-yapi-json/index.js: -------------------------------------------------------------------------------- 1 | module.exports = { 2 | server: false, 3 | client: true 4 | } -------------------------------------------------------------------------------- /exts/yapi-plugin-statistics/client.js: -------------------------------------------------------------------------------- 1 | /** 2 | * Created by gxl.gao on 2017/10/24. 3 | */ 4 | import StatisticsPage from './statisticsClientPage/index' 5 | 6 | module.exports = function () { 7 | this.bindHook('header_menu', function (menu) { 8 | menu.statisticsPage = { 9 | path: '/statistic', 10 | name: '系统信息', 11 | icon: 'bar-chart', 12 | adminFlag: true 13 | } 14 | }) 15 | this.bindHook('app_route', function (app) { 16 | app.statisticsPage = { 17 | path: '/statistic', 18 | component: StatisticsPage 19 | } 20 | }) 21 | 22 | 23 | } -------------------------------------------------------------------------------- /exts/yapi-plugin-statistics/index.js: -------------------------------------------------------------------------------- 1 | /** 2 | * Created by gxl.gao on 2017/10/24. 3 | */ 4 | module.exports = { 5 | server: true, 6 | client: true, 7 | httpCodes: [ 8 | 100,101,102,200,201,202,203,204,205,206,207,208,226,300,301,302,303,304,305,307,308,400,401,402,403,404,405,406,407,408,409,410,411,412,413,414,415,416,417,418,422,423,424,426,428,429,431,500,501,502,503,504,505,506,507,508,510,511 9 | ] 10 | } -------------------------------------------------------------------------------- /exts/yapi-plugin-statistics/server.js: -------------------------------------------------------------------------------- 1 | /** 2 | * Created by gxl.gao on 2017/10/24. 3 | */ 4 | const yapi = require('yapi.js'); 5 | const mongoose = require('mongoose'); 6 | const controller = require('./controller'); 7 | const statisModel = require('./statisMockModel.js'); 8 | const commons = require('./util.js'); 9 | 10 | module.exports = function() { 11 | yapi.connect.then(function() { 12 | let Col = mongoose.connection.db.collection('statis_mock'); 13 | Col.createIndex({ 14 | interface_id: 1 15 | }); 16 | Col.createIndex({ 17 | project_id: 1 18 | }); 19 | Col.createIndex({ 20 | group_id: 1 21 | }); 22 | Col.createIndex({ 23 | time: 1 24 | }); 25 | Col.createIndex({ 26 | date: 1 27 | }); 28 | }); 29 | 30 | this.bindHook('add_router', function(addRouter) { 31 | addRouter({ 32 | controller: controller, 33 | method: 'get', 34 | path: 'statismock/count', 35 | action: 'getStatisCount' 36 | }); 37 | 38 | addRouter({ 39 | controller: controller, 40 | method: 'get', 41 | path: 'statismock/get', 42 | action: 'getMockDateList' 43 | }); 44 | addRouter({ 45 | controller: controller, 46 | method: 'get', 47 | path: 'statismock/get_system_status', 48 | action: 'getSystemStatus' 49 | }); 50 | addRouter({ 51 | controller: controller, 52 | method: 'get', 53 | path: 'statismock/group_data_statis', 54 | action: 'groupDataStatis' 55 | }); 56 | }); 57 | 58 | // MockServer生成mock数据后触发 59 | this.bindHook('mock_after', function(context) { 60 | let interfaceId = context.interfaceData._id; 61 | let projectId = context.projectData._id; 62 | let groupId = context.projectData.group_id; 63 | //let ip = context.ctx.originalUrl; 64 | let ip = yapi.commons.getIp(context.ctx); 65 | 66 | let data = { 67 | interface_id: interfaceId, 68 | project_id: projectId, 69 | group_id: groupId, 70 | time: yapi.commons.time(), 71 | ip: ip, 72 | date: commons.formatYMD(new Date()) 73 | }; 74 | let inst = yapi.getInst(statisModel); 75 | 76 | try { 77 | inst.save(data).then(); 78 | } catch (e) { 79 | yapi.commons.log('mockStatisError', e); 80 | } 81 | }); 82 | }; 83 | -------------------------------------------------------------------------------- /exts/yapi-plugin-statistics/statisMockModel.js: -------------------------------------------------------------------------------- 1 | /** 2 | * Created by gxl.gao on 2017/10/24. 3 | */ 4 | const yapi = require('yapi.js'); 5 | const baseModel = require('models/base.js'); 6 | 7 | class statisMockModel extends baseModel { 8 | getName() { 9 | return 'statis_mock'; 10 | } 11 | 12 | getSchema() { 13 | return { 14 | interface_id: { type: Number, required: true }, 15 | project_id: { type: Number, required: true }, 16 | group_id: { type: Number, required: true }, 17 | time: Number, //'时间戳' 18 | ip: String, 19 | date: String 20 | }; 21 | } 22 | 23 | countByGroupId(id){ 24 | return this.model.countDocuments({ 25 | group_id: id 26 | }) 27 | } 28 | 29 | save(data) { 30 | let m = new this.model(data); 31 | return m.save(); 32 | } 33 | 34 | getTotalCount() { 35 | return this.model.countDocuments({}); 36 | } 37 | 38 | async getDayCount(timeInterval) { 39 | let end = timeInterval[1]; 40 | let start = timeInterval[0]; 41 | let data = []; 42 | const cursor = this.model.aggregate([ 43 | { 44 | $match: { 45 | date: { $gt: start, $lte: end } 46 | } 47 | }, 48 | { 49 | $group: { 50 | _id: '$date', //$region is the column name in collection 51 | count: { $sum: 1 } 52 | } 53 | }, 54 | { 55 | $sort: { _id: 1 } 56 | } 57 | ]).cursor({}).exec(); 58 | await cursor.eachAsync(doc => data.push(doc)); 59 | return data; 60 | 61 | } 62 | 63 | list() { 64 | return this.model.find({}).select('date').exec(); 65 | } 66 | 67 | up(id, data) { 68 | data.up_time = yapi.commons.time(); 69 | return this.model.updateOne({ 70 | _id: id 71 | }, data, { runValidators: true }); 72 | } 73 | } 74 | 75 | module.exports = statisMockModel; -------------------------------------------------------------------------------- /exts/yapi-plugin-statistics/statisticsClientPage/StatisChart.js: -------------------------------------------------------------------------------- 1 | /** 2 | * Created by gxl.gao on 2017/10/25. 3 | */ 4 | import React, { Component } from 'react'; 5 | // import PropTypes from 'prop-types' 6 | import axios from 'axios'; 7 | import { LineChart, Line, XAxis, YAxis, CartesianGrid, Tooltip, Legend } from 'recharts'; 8 | import { Spin } from 'antd'; 9 | class StatisChart extends Component { 10 | static propTypes = {}; 11 | 12 | constructor(props) { 13 | super(props); 14 | this.state = { 15 | showLoading: true, 16 | chartDate: { 17 | mockCount: 0, 18 | mockDateList: [] 19 | } 20 | }; 21 | } 22 | 23 | UNSAFE_componentWillMount() { 24 | this.getMockData(); 25 | } 26 | 27 | // 获取mock 请求次数信息 28 | async getMockData() { 29 | let result = await axios.get('/api/plugin/statismock/get'); 30 | if (result.data.errcode === 0) { 31 | let mockStatisData = result.data.data; 32 | this.setState({ 33 | showLoading: false, 34 | chartDate: { ...mockStatisData } 35 | }); 36 | } 37 | } 38 | 39 | render() { 40 | const width = 1050; 41 | const { mockCount, mockDateList } = this.state.chartDate; 42 | 43 | return ( 44 |