From 3ad4fd239cce5eb4b4b0fde50f9cc7ca511dc6ff Mon Sep 17 00:00:00 2001 From: "wenbo.dong" Date: Wed, 13 Sep 2017 15:08:51 +0800 Subject: [PATCH 01/11] =?UTF-8?q?fix:=20=E9=80=89=E6=8B=A9=E5=A7=93?= =?UTF-8?q?=E5=90=8D=E6=97=B6=E5=AE=9A=E4=BD=8D=E5=88=B0=E6=88=90=E5=91=98?= =?UTF-8?q?=E5=8D=B3=E5=8F=AF=E6=B7=BB=E5=8A=A0?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../UsernameAutoComplete/UsernameAutoComplete.js | 11 ++--------- 1 file changed, 2 insertions(+), 9 deletions(-) diff --git a/client/components/UsernameAutoComplete/UsernameAutoComplete.js b/client/components/UsernameAutoComplete/UsernameAutoComplete.js index 05c4ec6f..6f8e9235 100644 --- a/client/components/UsernameAutoComplete/UsernameAutoComplete.js +++ b/client/components/UsernameAutoComplete/UsernameAutoComplete.js @@ -91,15 +91,8 @@ class UsernameAutoComplete extends Component { dataSource: userList }); if (userList.length) { - userList.forEach((item) => { - if (item.username === this.state.changeName) { - // 每次取回搜索值后,没选择时默认选择第一位 - this.changeState(userList[0].id, userList[0].username); - } else { - // 有候选词但没有对应输入框中的字符串,此时应清空候选 uid 和 username - this.changeState(-1, ''); - } - }); + // 每次取回搜索值后,没选择时默认选择第一位 + this.changeState(userList[0].id, userList[0].username); } else { // 如果没有搜索结果,则清空候选 uid 和 username this.changeState(-1, ''); From 9e68f423d0449385f69fba2a6795ce88aafd7aff Mon Sep 17 00:00:00 2001 From: suxiaoxin Date: Wed, 13 Sep 2017 17:09:06 +0800 Subject: [PATCH 02/11] =?UTF-8?q?fix:=20=E6=97=A0=E6=95=B0=E4=B8=AAbug?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- client/Application.js | 1 + client/components/Header/Header.scss | 1 - client/containers/AddProject/AddProject.js | 19 ++++- .../containers/Group/GroupList/GroupList.js | 77 ++++++++++--------- .../Group/ProjectList/ProjectList.js | 20 +++-- .../Group/ProjectList/ProjectList.scss | 15 ++++ .../InterfaceList/InterfaceEditForm.js | 26 +++++-- client/index.js | 1 + plugins/yapi-plugin-demo/client.js | 4 +- server/controllers/group.js | 15 +++- server/controllers/interface.js | 15 +++- 11 files changed, 135 insertions(+), 59 deletions(-) diff --git a/client/Application.js b/client/Application.js index 52d1c2cb..327266dd 100644 --- a/client/Application.js +++ b/client/Application.js @@ -10,6 +10,7 @@ import Loading from './components/Loading/Loading'; import { checkLoginState } from './reducer/modules/user'; import { requireAuthentication } from './components/AuthenticatedComponent'; + const LOADING_STATUS = 0; @connect( diff --git a/client/components/Header/Header.scss b/client/components/Header/Header.scss index 4b9afa38..72559255 100644 --- a/client/components/Header/Header.scss +++ b/client/components/Header/Header.scss @@ -1,4 +1,3 @@ -@import '../../styles/common.scss'; @import '../../styles/mixin.scss'; .nav-tooltip { diff --git a/client/containers/AddProject/AddProject.js b/client/containers/AddProject/AddProject.js index b3d80554..28f1b551 100644 --- a/client/containers/AddProject/AddProject.js +++ b/client/containers/AddProject/AddProject.js @@ -32,7 +32,8 @@ const formItemLayout = { @connect( state => { return { - groupList: state.group.groupList + groupList: state.group.groupList, + currGroup: state.group.currGroup } }, { @@ -46,12 +47,14 @@ class ProjectList extends Component { constructor(props) { super(props); this.state = { - groupList: [] + groupList: [], + currGroupId: null } } static propTypes = { groupList: PropTypes.array, form: PropTypes.object, + currGroup: PropTypes.object, addProject: PropTypes.func, history: PropTypes.object, setBreadcrumb: PropTypes.func, @@ -88,7 +91,15 @@ class ProjectList extends Component { async componentWillMount() { this.props.setBreadcrumb([{name: '新建项目'}]); - await this.props.fetchGroupList(); + if(!this.props.currGroup._id){ + await this.props.fetchGroupList(); + } + if(this.props.groupList.length === 0){ + return null; + } + this.setState({ + currGroupId: this.props.currGroup._id ? this.props.currGroup._id : this.props.groupList[0]._id + }) this.setState({groupList: this.props.groupList}); } @@ -114,7 +125,7 @@ class ProjectList extends Component { label="所属分组" > {getFieldDecorator('group', { - initialValue: this.state.groupList.length > 0? this.state.groupList[0]._id.toString() : null , + initialValue: this.state.currGroupId+'' , rules: [{ required: true, message: '请选择项目所属的分组!' }] diff --git a/client/containers/Group/GroupList/GroupList.js b/client/containers/Group/GroupList/GroupList.js index a331bc03..8699b038 100644 --- a/client/containers/Group/GroupList/GroupList.js +++ b/client/containers/Group/GroupList/GroupList.js @@ -1,10 +1,10 @@ import React, { Component } from 'react' import PropTypes from 'prop-types' import { connect } from 'react-redux' -import { Button, Icon, Modal,Alert, Input, message, Menu, Row, Col } from 'antd' +import { Button, Icon, Modal, Alert, Input, message, Menu, Row, Col } from 'antd' import { autobind } from 'core-decorators'; import axios from 'axios'; -import { withRouter } from 'react-router'; +import { withRouter, Link } from 'react-router-dom'; const { TextArea } = Input; const Search = Input.Search; const TYPE_EDIT = 'edit'; @@ -63,18 +63,18 @@ export default class GroupList extends Component { const groupId = !isNaN(this.props.match.params.groupId) ? parseInt(this.props.match.params.groupId) : 0; await this.props.fetchGroupList(); let currGroup = this.props.groupList[0] || { group_name: '', group_desc: '' }; - if(this.props.groupList.length && groupId){ - for(let i = 0;i { + showConfirm = () => { let that = this; confirm({ - title: "确认删除 "+that.props.currGroup.group_name+" 分组吗?", - content:
+ title: "确认删除 " + that.props.currGroup.group_name + " 分组吗?", + content:
-
+

请输入分组名称确认此操作:

, onOk() { let groupName = document.getElementById('group_name').value; - if(that.props.currGroup.group_name !== groupName){ + if (that.props.currGroup.group_name !== groupName) { message.error('分组名称有误') - return new Promise((resolve, reject)=>{ + return new Promise((resolve, reject) => { reject('error') }) - }else{ + } else { that.deleteGroup() } @@ -198,14 +198,14 @@ export default class GroupList extends Component { async deleteGroup() { const self = this; const { currGroup } = self.props; - const res = await axios.post('/api/group/del', {id: currGroup._id}) + const res = await axios.post('/api/group/del', { id: currGroup._id }) if (res.data.errcode) { message.error(res.data.errmsg); } else { message.success('删除成功') await self.props.fetchGroupList() const currGroup = self.props.groupList[0] || { group_name: '', group_desc: '' }; - self.setState({groupList: self.props.groupList}); + self.setState({ groupList: self.props.groupList }); self.props.setCurrGroup(currGroup) } } @@ -215,17 +215,17 @@ export default class GroupList extends Component { const v = value || e.target.value; const { groupList } = this.props; if (v === '') { - this.setState({groupList}) + this.setState({ groupList }) } else { - this.setState({groupList: groupList.filter(group => new RegExp(v, 'i').test(group.group_name))}) + this.setState({ groupList: groupList.filter(group => new RegExp(v, 'i').test(group.group_name)) }) } } - render () { + render() { const { currGroup } = this.props; - const delmark = this.showModal(TYPE_EDIT)}/> - const editmark = {this.showConfirm()}} type="delete" title="删除分组"/> - + const delmark = this.showModal(TYPE_EDIT)} /> + const editmark = { this.showConfirm() }} type="delete" title="删除分组" /> + const addmark = return ( @@ -235,10 +235,13 @@ export default class GroupList extends Component {
{currGroup.group_name}
{ - this.props.curUserRole === "admin"?(editmark):'' + this.props.curUserRole === "admin" ? (editmark) : '' } { - this.props.curUserRole === "admin"?(delmark):'' + this.props.curUserRole === "admin" ? (delmark) : '' + } + { + this.props.curUserRole === 'admin' ? (addmark) : '' }
@@ -246,11 +249,11 @@ export default class GroupList extends Component {
- this.searchGroup(null, v)}/> + this.searchGroup(null, v)} />
- { - this.props.curUserRole === "admin"?():'' - } + + +
简介:
- + diff --git a/client/containers/Group/ProjectList/ProjectList.js b/client/containers/Group/ProjectList/ProjectList.js index 1049978b..c43fde6c 100644 --- a/client/containers/Group/ProjectList/ProjectList.js +++ b/client/containers/Group/ProjectList/ProjectList.js @@ -1,7 +1,8 @@ import React, { Component } from 'react'; import PropTypes from 'prop-types'; import { connect } from 'react-redux'; -import { Row, Col } from 'antd'; +import { Row, Col, Button } from 'antd'; +import { Link } from 'react-router-dom'; import { addProject, fetchProjectList, delProject, changeUpdateModal } from '../../../reducer/modules/project'; import ProjectCard from '../../../components/ProjectCard/ProjectCard.js'; import ErrMsg from '../../../components/ErrMsg/ErrMsg.js'; @@ -10,7 +11,7 @@ import { setBreadcrumb } from '../../../reducer/modules/user'; import './ProjectList.scss' -@connect( +@connect( state => { return { projectList: state.project.projectList, @@ -75,7 +76,7 @@ class ProjectList extends Component { } componentWillReceiveProps(nextProps) { - this.props.setBreadcrumb([{name: '分组: ' + (nextProps.currGroup.group_name || '')}]); + this.props.setBreadcrumb([{name: '' + (nextProps.currGroup.group_name || '')}]); // 切换分组 if (this.props.currGroup !== nextProps.currGroup) { @@ -99,8 +100,17 @@ class ProjectList extends Component { render() { const projectData = this.state.projectData; - return ( -
+ return ( +
+ + + {this.props.currGroup.group_name}分组 共 {projectData.length} 个项目 + + + + + + {projectData.length ? projectData.map((item, index) => { return ( diff --git a/client/containers/Group/ProjectList/ProjectList.scss b/client/containers/Group/ProjectList/ProjectList.scss index 804bd706..6735604d 100644 --- a/client/containers/Group/ProjectList/ProjectList.scss +++ b/client/containers/Group/ProjectList/ProjectList.scss @@ -3,6 +3,7 @@ margin-bottom: 0; } + .m-panel{ background-color: #fff; padding: 24px; @@ -12,6 +13,20 @@ margin-top: 0; } +.project-list{ + .project-list-header{ + background: #eee; + height: 48px; + line-height: 40px; + border-radius: 4px; + text-align: right; + padding: 7px 15px; + margin-bottom: 15px; + } +} + + + .ant-input-group-wrapper { width: 100%; } diff --git a/client/containers/Project/Interface/InterfaceList/InterfaceEditForm.js b/client/containers/Project/Interface/InterfaceList/InterfaceEditForm.js index 4a8e966c..d521ce0d 100644 --- a/client/containers/Project/Interface/InterfaceList/InterfaceEditForm.js +++ b/client/containers/Project/Interface/InterfaceList/InterfaceEditForm.js @@ -100,14 +100,14 @@ class InterfaceEditForm extends Component { this.props.form.validateFields((err, values) => { if (!err) { if (values.res_body_type === 'json') { - if(validJson(this.state.res_body) === false){ - return message.error('返回json格式有问题,请检查!') + if(this.state.res_body && validJson(this.state.res_body) === false){ + return message.error('返回body json格式有问题,请检查!') } - values.res_body = this.state.res_body + values.res_body = this.state.res_body; } if (values.req_body_type === 'json') { - if(validJson(this.state.req_body_other) === false){ - return message.error('请求json格式有问题,请检查!') + if(this.state.req_body_other && validJson(this.state.req_body_other) === false){ + return message.error('响应Body json格式有问题,请检查!'); } values.req_body_other = this.state.req_body_other; } @@ -316,7 +316,7 @@ class InterfaceEditForm extends Component { const requestBodyTpl = (data, index) => { return - + {getFieldDecorator('req_body_form[' + index + '].name', { initialValue: data.name })( @@ -328,8 +328,18 @@ class InterfaceEditForm extends Component { initialValue: data.type })( + )} + + + {getFieldDecorator('req_body_form[' + index + '].required', { + initialValue: data.required + })( + )} diff --git a/client/index.js b/client/index.js index 8a76bdb5..43af5e06 100644 --- a/client/index.js +++ b/client/index.js @@ -5,6 +5,7 @@ import App from './Application' import { Provider } from 'react-redux' import createStore from './reducer/create'; import './styles/theme.less' +import './styles/common.scss'; const store = createStore(); if (process.env.NODE_ENV === 'production') { ReactDOM.render( diff --git a/plugins/yapi-plugin-demo/client.js b/plugins/yapi-plugin-demo/client.js index 0188be40..7d62c908 100644 --- a/plugins/yapi-plugin-demo/client.js +++ b/plugins/yapi-plugin-demo/client.js @@ -1,3 +1,3 @@ module.exports = function(){ - -} \ No newline at end of file + return null; +}; \ No newline at end of file diff --git a/server/controllers/group.js b/server/controllers/group.js index 4013098b..b4c3a7de 100644 --- a/server/controllers/group.js +++ b/server/controllers/group.js @@ -282,7 +282,20 @@ class groupController extends baseController { try { var groupInst = yapi.getInst(groupModel); let result = await groupInst.list(); - ctx.body = yapi.commons.resReturn(result); + let newResult = []; + if(result && result.length > 0){ + for(let i=0; i< result.length; i++){ + result[i] = result[i].toObject(); + result[i].role = await this.checkAuth(result[i]._id, 'group', 'edit'); + if(result[i].role){ + newResult.unshift(result[i]); + }else{ + newResult.push(result[i]); + } + } + } + + ctx.body = yapi.commons.resReturn(newResult); } catch (e) { ctx.body = yapi.commons.resReturn(null, 402, e.message); } diff --git a/server/controllers/interface.js b/server/controllers/interface.js index 0cdaa16f..7513d0fc 100644 --- a/server/controllers/interface.js +++ b/server/controllers/interface.js @@ -76,9 +76,22 @@ class interfaceController extends baseController { return ctx.body = yapi.commons.resReturn(null, 400, '接口请求路径不能为空'); } - if (!yapi.commons.verifyPath(params.path)) { + let http_path = url.parse(params.path); + + if (!yapi.commons.verifyPath(http_path.path)) { return ctx.body = yapi.commons.resReturn(null, 400, '接口path第一位必须是/,最后一位不能为/'); } + + params.req_query = params.req_query || []; + if(!params.req_query){ + params.req_query = []; + Object.keys(http_path.query).forEach((item)=>{ + params.req_query.push({ + name: item + }) + }) + } + let checkRepeat = await this.Model.checkRepeat(params.project_id, params.path, params.method); From 3ca71f22349543e89ca51fb467f45815d0c43184 Mon Sep 17 00:00:00 2001 From: suxiaoxin Date: Wed, 13 Sep 2017 17:17:18 +0800 Subject: [PATCH 03/11] =?UTF-8?q?opti:=20=E4=BC=98=E5=8C=96=E9=A1=B9?= =?UTF-8?q?=E7=9B=AE=E5=88=97=E8=A1=A8header?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- client/containers/Group/GroupList/GroupList.js | 14 +++++--------- client/containers/Group/ProjectList/ProjectList.js | 2 +- .../containers/Group/ProjectList/ProjectList.scss | 5 +++-- 3 files changed, 9 insertions(+), 12 deletions(-) diff --git a/client/containers/Group/GroupList/GroupList.js b/client/containers/Group/GroupList/GroupList.js index 8699b038..b8306441 100644 --- a/client/containers/Group/GroupList/GroupList.js +++ b/client/containers/Group/GroupList/GroupList.js @@ -1,10 +1,10 @@ import React, { Component } from 'react' import PropTypes from 'prop-types' import { connect } from 'react-redux' -import { Button, Icon, Modal, Alert, Input, message, Menu, Row, Col } from 'antd' +import { Icon, Modal, Alert, Input, message, Menu, Row, Col } from 'antd' import { autobind } from 'core-decorators'; import axios from 'axios'; -import { withRouter, Link } from 'react-router-dom'; +import { withRouter } from 'react-router-dom'; const { TextArea } = Input; const Search = Input.Search; const TYPE_EDIT = 'edit'; @@ -223,9 +223,9 @@ export default class GroupList extends Component { render() { const { currGroup } = this.props; - const delmark = this.showModal(TYPE_EDIT)} /> - const editmark = { this.showConfirm() }} type="delete" title="删除分组" /> - const addmark = + const delmark = this.showModal(TYPE_EDIT)} /> + const editmark = { this.showConfirm() }} type="delete" title="删除分组" /> + const addmark = return ( @@ -251,10 +251,6 @@ export default class GroupList extends Component {
this.searchGroup(null, v)} />
- - - -
+
{this.props.currGroup.group_name}分组 共 {projectData.length} 个项目 diff --git a/client/containers/Group/ProjectList/ProjectList.scss b/client/containers/Group/ProjectList/ProjectList.scss index 6735604d..bc1b1b62 100644 --- a/client/containers/Group/ProjectList/ProjectList.scss +++ b/client/containers/Group/ProjectList/ProjectList.scss @@ -16,11 +16,12 @@ .project-list{ .project-list-header{ background: #eee; - height: 48px; + height: 64px; line-height: 40px; border-radius: 4px; text-align: right; - padding: 7px 15px; + padding: 12px 15px; + font-weight: bold; margin-bottom: 15px; } } From 43d2ab36209ddf2ed420a49051d8172f8d09a07b Mon Sep 17 00:00:00 2001 From: suxiaoxin Date: Wed, 13 Sep 2017 17:28:31 +0800 Subject: [PATCH 04/11] =?UTF-8?q?opti:=20=E4=BC=98=E5=8C=96=E9=A1=B9?= =?UTF-8?q?=E7=9B=AE=E6=8F=8F=E8=BF=B0?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../Project/Setting/ProjectMessage/ProjectMessage.js | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/client/containers/Project/Setting/ProjectMessage/ProjectMessage.js b/client/containers/Project/Setting/ProjectMessage/ProjectMessage.js index ac940a45..5b940f66 100644 --- a/client/containers/Project/Setting/ProjectMessage/ProjectMessage.js +++ b/client/containers/Project/Setting/ProjectMessage/ProjectMessage.js @@ -328,7 +328,7 @@ class ProjectMessage extends Component {

{this.state.currGroup + ' / ' + projectMsg.name}

-

{projectMsg.desc}

+ {/*

{projectMsg.desc}

*/}

@@ -403,10 +403,10 @@ class ProjectMessage extends Component { {getFieldDecorator('desc', { initialValue: initFormValues.desc, rules: [{ - required: false, message: '描述不超过100字!', max: 100 + required: false }] })( -