Merge branch 'dev' of gitlab.corp.qunar.com:mfe/yapi into dev

This commit is contained in:
sean 2017-07-26 11:26:32 +08:00
commit a486469e02
25 changed files with 273 additions and 142 deletions

View File

@ -1,74 +0,0 @@
import {
FETCH_ADD_INTERFACE_INPUT,
FETCH_ADD_INTERFACE_TAG_VALUE,
FETCH_ADD_INTERFACE_HEADER_VALUE,
ADD_INTERFACE_SEQ_HEADER,
DELETE_INTERFACE_SEQ_HEADER,
GET_INTERFACE_REQ_PARAMS,
GET_INTERFACE_RES_PARAMS,
PUSH_INTERFACE_NAME,
PUSH_INTERFACE_METHOD
} from '../constants/action-types.js'
export function pushInputValue (value) {
return {
type: FETCH_ADD_INTERFACE_INPUT,
payload: value
};
}
export function reqTagValue (value) {
return {
type: FETCH_ADD_INTERFACE_TAG_VALUE,
payload: value
};
}
export function reqHeaderValue (value) {
return {
type: FETCH_ADD_INTERFACE_HEADER_VALUE,
payload: value
};
}
export function addReqHeader (value) {
return {
type: ADD_INTERFACE_SEQ_HEADER,
payload: value
};
}
export function deleteReqHeader (value) {
return {
type: DELETE_INTERFACE_SEQ_HEADER,
payload: value
};
}
export function getReqParams (value) {
return {
type: GET_INTERFACE_REQ_PARAMS,
payload: value
};
}
export function getResParams (value) {
return {
type: GET_INTERFACE_RES_PARAMS,
payload: value
};
}
export function pushInterfaceName (value) {
return {
type: PUSH_INTERFACE_NAME,
payload: value
}
}
export function pushInterfaceMethod (value) {
return {
type: PUSH_INTERFACE_METHOD,
payload: value
}
}

View File

@ -7,8 +7,10 @@ import {
GET_INTERFACE_REQ_PARAMS, GET_INTERFACE_REQ_PARAMS,
GET_INTERFACE_RES_PARAMS, GET_INTERFACE_RES_PARAMS,
PUSH_INTERFACE_NAME, PUSH_INTERFACE_NAME,
PUSH_INTERFACE_METHOD PUSH_INTERFACE_METHOD,
FETCH_INTERFACE_PROJECT
} from '../constants/action-types.js' } from '../constants/action-types.js'
import axios from 'axios'
export function pushInputValue (value) { export function pushInputValue (value) {
return { return {
@ -72,3 +74,10 @@ export function pushInterfaceMethod (value) {
payload: value payload: value
} }
} }
export function fetchInterfaceProject(id) {
return {
type: FETCH_INTERFACE_PROJECT,
payload: axios.get('/project/get', { params: {id}})
}
}

View File

@ -11,7 +11,6 @@ import axios from 'axios';
const checkLoginState = () => { const checkLoginState = () => {
return(dispatch)=> { return(dispatch)=> {
axios.get('/user/status').then((res) => { axios.get('/user/status').then((res) => {
console.log(res);
dispatch({ dispatch({
type: GET_LOGIN_STATE, type: GET_LOGIN_STATE,
payload: res payload: res

View File

@ -31,7 +31,7 @@ export default class Srch extends Component{
} }
onSelect = (value) => { onSelect = (value) => {
if( value.split(":")[0] == "group" ){ if( value.split(":")[0] == "分组" ){
this.props.history.push('/group/'+value.split(":")[1].trim()); this.props.history.push('/group/'+value.split(":")[1].trim());
} else { } else {
this.props.history.push('/project/'+value.split("(")[1].slice(0,-1)); this.props.history.push('/project/'+value.split("(")[1].slice(0,-1));
@ -45,7 +45,7 @@ export default class Srch extends Component{
const dataSource = []; const dataSource = [];
for(let title in res.data.data){ for(let title in res.data.data){
res.data.data[title].map(item => { res.data.data[title].map(item => {
title == "group" ? dataSource.push( title+": "+item.groupName ): dataSource.push( title+": "+item.name+"("+item._id+")" ); title == "group" ? dataSource.push( "分组"+": "+item.groupName ): dataSource.push( "项目"+": "+item.name+"("+item._id+")" );
}) })
} }
this.setState({ this.setState({
@ -84,8 +84,13 @@ export default class Srch extends Component{
> >
<Input <Input
prefix={<Icon type="search" className="srch-icon" />} prefix={<Icon type="search" className="srch-icon" />}
size="large" style={{ width: 200 }} size="large"
placeholder="search group/project" style={{
// width: 200,
// borderColor:"#AAA",
// borderWidth:"1px",
}}
placeholder="搜索分组/项目"
className="search-input" className="search-input"
/> />
</AutoComplete> </AutoComplete>

View File

@ -2,10 +2,14 @@ $color-grey:#979DA7;
.search-wrapper{ .search-wrapper{
.search-input{ .search-input{
border:1px solid #AAA; border:1px solid $color-grey;
background-color: rgba(255,255,255,0.5); color: $color-grey;
width: 2rem;
transition: width 2s;
//background-color:rgba(0,0,0,0.5);
} }
.srch-icon{ .srch-icon{
color: $color-grey; color: $color-grey;
font-weight: bold;
} }
} }

View File

@ -14,6 +14,7 @@ export const DELETE_INTERFACE_SEQ_HEADER = 'DELETE_INTERFACE_SEQ_HEADER'
export const GET_INTERFACE_REQ_PARAMS = 'GET_INTERFACE_REQ_PARAMS' export const GET_INTERFACE_REQ_PARAMS = 'GET_INTERFACE_REQ_PARAMS'
export const GET_INTERFACE_RES_PARAMS = 'GET_INTERFACE_RES_PARAMS' export const GET_INTERFACE_RES_PARAMS = 'GET_INTERFACE_RES_PARAMS'
export const PUSH_INTERFACE_METHOD = 'PUSH_INTERFACE_METHOD' export const PUSH_INTERFACE_METHOD = 'PUSH_INTERFACE_METHOD'
export const FETCH_INTERFACE_PROJECT = 'FETCH_INTERFACE_PROJECT'
// group // group
export const FETCH_GROUP_LIST = 'FETCH_GROUP_LIST' export const FETCH_GROUP_LIST = 'FETCH_GROUP_LIST'

View File

@ -10,13 +10,16 @@ import ReqHeader from './ReqHeader/ReqHeader.js'
import ReqParams from './ReqParams/ReqParams.js' import ReqParams from './ReqParams/ReqParams.js'
import ResParams from './ResParams/ResParams.js' import ResParams from './ResParams/ResParams.js'
import Result from './Result/Result.js' import Result from './Result/Result.js'
import { import InterfaceTest from './InterfaceTest/InterfaceTest.js'
import {
saveForms, saveForms,
getResParams, getResParams,
getReqParams, getReqParams,
addReqHeader, addReqHeader,
pushInputValue, pushInputValue,
pushInterfaceName pushInterfaceName,
fetchInterfaceProject,
pushInterfaceMethod
} from '../../actions/addInterface.js' } from '../../actions/addInterface.js'
const success = () => { const success = () => {
@ -40,7 +43,9 @@ const success = () => {
getResParams, getResParams,
addReqHeader, addReqHeader,
pushInputValue, pushInputValue,
pushInterfaceName pushInterfaceName,
fetchInterfaceProject,
pushInterfaceMethod
} }
) )
@ -105,12 +110,14 @@ class AddInterface extends Component {
editState (data) { editState (data) {
const props = this.props const props = this.props
const { path, title, req_params_other, res_body, req_headers} = data const { path, title, req_params_other, res_body, req_headers, project_id, method } = data
props.pushInputValue(path) props.pushInputValue(path)
props.pushInterfaceMethod(method)
props.pushInterfaceName(title) props.pushInterfaceName(title)
props.getReqParams(req_params_other) props.getReqParams(req_params_other)
props.getResParams(res_body) props.getResParams(res_body)
props.addReqHeader(req_headers) props.addReqHeader(req_headers)
props.fetchInterfaceProject(project_id)
} }
initInterfaceData (interfaceId) { initInterfaceData (interfaceId) {
@ -204,7 +211,9 @@ class AddInterface extends Component {
<Result isSave={isSave} /> <Result isSave={isSave} />
</TabPane> </TabPane>
<TabPane tab="Mock" key="2">mock</TabPane> <TabPane tab="Mock" key="2">mock</TabPane>
<TabPane tab="测试" key="3">测试</TabPane> <TabPane tab="测试" key="3">
<InterfaceTest />
</TabPane>
</Tabs> </Tabs>
</div> </div>
<div className={`loading ${isLoading}`}></div> <div className={`loading ${isLoading}`}></div>
@ -214,5 +223,3 @@ class AddInterface extends Component {
} }
export default AddInterface export default AddInterface

View File

@ -0,0 +1,120 @@
import React, { Component } from 'react'
import PropTypes from 'prop-types'
import { connect } from 'react-redux'
import { Button, Input } from 'antd'
import { autobind } from 'core-decorators';
import crossRequest from 'cross-request';
import { withRouter } from 'react-router';
import URL from 'url';
import {
} from '../../../actions/group.js'
import './InterfaceTest.scss'
@connect(
state => ({
reqParams: state.addInterface.reqParams,
method: state.addInterface.method,
url: state.addInterface.url,
seqGroup: state.addInterface.seqGroup,
interfaceName: state.addInterface.interfaceName,
interfaceProject: state.addInterface.project
}),
{
}
)
@withRouter
export default class InterfaceTest extends Component {
static propTypes = {
reqParams: PropTypes.string,
method: PropTypes.string,
url: PropTypes.string,
interfaceName: PropTypes.string,
seqGroup: PropTypes.array,
match: PropTypes.object,
interfaceProject: PropTypes.object
}
state = {
res: {},
header: {}
}
constructor(props) {
super(props)
}
componentWillMount() {
}
@autobind
testInterface() {
crossRequest({
url: 'http://petstore.swagger.io/v2/swagger.json',
method: 'GET',
data: {
a:1
},
success: (res, header) => {
this.setState({res})
console.log(header)
}
})
}
render () {
const { method, url, seqGroup, interfaceName, interfaceProject } = this.props;
const { prd_host, basepath, protocol } = interfaceProject;
const reqParams = JSON.parse(this.props.reqParams);
let query = {};
if (method === 'GET') {
Object.keys(reqParams).forEach(key => {
const value = typeof reqParams[key] === 'object' ? JSON.stringify(reqParams) : reqParams.toString();
query[key] = value;
})
}
const href = URL.format({
protocol: protocol || 'http',
host: prd_host,
pathname: URL.resolve(basepath, url),
query
});
return (
<div>
<div>接口名{interfaceName}</div>
<div>
METHOD: <Input value={method} disabled />
URL: <Input value={href} />
HEADERS: <Input value={JSON.stringify(seqGroup, 2)} />
请求参数
<div>
{
Object.keys(reqParams).map((key, index) => {
const value = typeof reqParams[key] === 'object' ? JSON.stringify(reqParams) : reqParams.toString();
return (
<div key={index}>
<Input value={key} style={{display: 'inline-block', width: 200}} />{' = '}
<Input value={value} style={{display: 'inline-block', width: 200}} />
</div>
)
})
}
</div>
</div>
<Button onClick={this.testInterface}>发送跨域请求</Button>
<div>
返回结果
{JSON.stringify(this.state.res, 2)}
</div>
</div>
)
}
}

View File

@ -40,7 +40,7 @@ const HomeGuest = (props) => (
<div className="feat-part"> <div className="feat-part">
<div className="container"> <div className="container">
<OverPack <OverPack
playScale="0.3" playScale={[0.3,0.1]}
> >
<TweenOne <TweenOne
key="feat-motion-one" key="feat-motion-one"
@ -52,13 +52,13 @@ const HomeGuest = (props) => (
<Row key="feat-motion-row"> <Row key="feat-motion-row">
<QueueAnim <QueueAnim
delay = {200} delay = {200}
interval ={100} interval ={200}
type = "bottom" leaveReverse={true}
ease = 'easeOutQuad' ease = 'easeOutQuad'
animConfig ={{ opacity:[1,0],y: '+=30' }} animConfig ={{ opacity:[1,0],y: '+=30' }}
key="feat-motion-queue" key="feat-motion-queue"
> >
<Col span={8} className="feat-wrapper" key="feat-wrapper-1"> <Col span={6} className="feat-wrapper" key="feat-wrapper-1">
<div className="feat-img"> <div className="feat-img">
<Icon type="api" /> <Icon type="api" />
</div> </div>
@ -66,7 +66,7 @@ const HomeGuest = (props) => (
接口管理 接口管理
</p> </p>
</Col> </Col>
<Col span={8} className="feat-wrapper" key="feat-wrapper-2"> <Col span={6} className="feat-wrapper" key="feat-wrapper-2">
<div className="feat-img"> <div className="feat-img">
<Icon type="link" /> <Icon type="link" />
</div> </div>
@ -74,7 +74,7 @@ const HomeGuest = (props) => (
支持Mock 支持Mock
</p> </p>
</Col> </Col>
<Col span={8} className="feat-wrapper" key="feat-wrapper-3"> <Col span={6} className="feat-wrapper" key="feat-wrapper-3">
<div className="feat-img"> <div className="feat-img">
<Icon type="team" /> <Icon type="team" />
</div> </div>
@ -82,6 +82,14 @@ const HomeGuest = (props) => (
团队协作 团队协作
</p> </p>
</Col> </Col>
<Col span={6} className="feat-wrapper" key="feat-wrapper-4">
<div className="feat-img">
<Icon type="desktop" />
</div>
<p className="feat-title">
可部署
</p>
</Col>
</QueueAnim> </QueueAnim>
</Row> </Row>
</OverPack> </OverPack>
@ -132,7 +140,7 @@ class Home extends Component {
<div className="user-home"> <div className="user-home">
<div className="user-des"> <div className="user-des">
<p className="title">YAPI</p> <p className="title">YAPI</p>
<p className="des">一个高效易用功能强大的api管理系统</p> <p className="des">一个高效易用可部署的Api管理系统</p>
<div className="btn"> <div className="btn">
<Button type="primary" size="large"> <Button type="primary" size="large">
<Link to="/group" onClick={this.toStart}>开始</Link> <Link to="/group" onClick={this.toStart}>开始</Link>

View File

@ -111,43 +111,48 @@ $color-black-lighter: #404040;
height:100%; height:100%;
position: relative; position: relative;
} }
.feat-wrapper{ .feat-wrapper {
display: flex; display: flex;
flex-direction: column; flex-direction: column;
align-items: center; align-items: center;
justify-content: center; justify-content: center;
text-align: center; text-align: center;
.feat-img{ .feat-img {
height: 1.2rem; height: 1.2rem;
width: 1.2rem; width: 1.2rem;
border-radius: 100%; border-radius: 100%;
margin-bottom: .2rem; margin-bottom: .2rem;
color: $color-white; color: $color-white;
i{ i {
line-height: 1.2rem; line-height: 1.2rem;
font-size: .6rem; font-size: .6rem;
} }
} }
.feat-title{ .feat-title {
font-size: .16rem; font-size: .16rem;
line-height: .3rem; line-height: .3rem;
color: #333; color: #333;
} }
&:first-child{ &:first-child {
.feat-img{ .feat-img {
background-color: rgb(248, 88, 96); background-color: rgb(248, 88, 96);
} }
} }
&:nth-child(2){ &:nth-child(2) {
.feat-img{ .feat-img {
background-color: #f9bb13; background-color: #f9bb13;
} }
} }
&:nth-child(3){ &:nth-child(3) {
.feat-img{ .feat-img {
background-color: #20ab8e; background-color: #20ab8e;
} }
} }
&:nth-child(4) {
.feat-img {
background-color: rgb(66, 165, 245);
}
}
} }
} }

View File

@ -75,6 +75,9 @@ class InterfaceTable extends Component {
<Button type="primary"> <Button type="primary">
<Link to={`/AddInterface/edit/${data._id}`}>编辑</Link> <Link to={`/AddInterface/edit/${data._id}`}>编辑</Link>
</Button> </Button>
<Button type="primary">
<Link to={`/AddInterface/edit/${data._id}`}>测试</Link>
</Button>
<Button type="danger" onClick={deleteInterface}>删除</Button> <Button type="danger" onClick={deleteInterface}>删除</Button>
</span> </span>
) )

View File

@ -68,11 +68,9 @@ export default class GroupList extends Component {
this.props.history.replace(`${currGroup.group_name}`); this.props.history.replace(`${currGroup.group_name}`);
} }
} }
console.log(groupName);
}else if(!groupName && this.props.groupList.length){ }else if(!groupName && this.props.groupList.length){
this.props.history.push(`/group/${this.props.groupList[0].group_name}`); this.props.history.push(`/group/${this.props.groupList[0].group_name}`);
} }
console.log(currGroup);
this.setState({groupList: this.props.groupList}); this.setState({groupList: this.props.groupList});
this.props.setCurrGroup(currGroup) this.props.setCurrGroup(currGroup)
}); });
@ -205,11 +203,11 @@ export default class GroupList extends Component {
<div className="group-bar"> <div className="group-bar">
<div className="curr-group"> <div className="curr-group">
<div className="curr-group-name"> <div className="curr-group-name">
{currGroup.group_name} <div className="text" title={currGroup.group_name}>{currGroup.group_name}</div>
<Icon className="edit-group" type="edit" title="编辑分组" onClick={() => this.showModal(TYPE_EDIT)}/> <Icon className="edit-group" type="edit" title="编辑分组" onClick={() => this.showModal(TYPE_EDIT)}/>
<Icon className="delete-group" type="delete" title="删除分组" onClick={this.deleteGroup}/> <Icon className="delete-group" type="delete" title="删除分组" onClick={this.deleteGroup}/>
</div> </div>
<div className="curr-group-desc">简介{currGroup.group_desc}</div> <div className="curr-group-desc" title={currGroup.group_desc}>简介{currGroup.group_desc}</div>
</div> </div>
<div className="group-operate"> <div className="group-operate">
<div className="search"> <div className="search">
@ -268,7 +266,7 @@ export default class GroupList extends Component {
<Row gutter={6} className="modal-input"> <Row gutter={6} className="modal-input">
<Col span="5"><div className="label">简介</div></Col> <Col span="5"><div className="label">简介</div></Col>
<Col span="15"> <Col span="15">
<Input placeholder="请输入分组描述" value={this.state.currGroupDesc} onChange={(e) => this.inputNewGroupDesc(e, TYPE_EDIT)}></Input> <TextArea rows={3} placeholder="请输入分组描述" value={this.state.currGroupDesc} onChange={(e) => this.inputNewGroupDesc(e, TYPE_EDIT)}></TextArea>
</Col> </Col>
</Row> </Row>
</Modal> </Modal>

View File

@ -5,12 +5,25 @@
border-radius: 4px 4px 0 0; border-radius: 4px 4px 0 0;
padding: 32px 24px; padding: 32px 24px;
.curr-group-name { .curr-group-name {
.text {
display: inline-block;
overflow:hidden;
white-space:nowrap;
text-overflow:ellipsis;
max-width: 150px;
}
color: #fff; color: #fff;
font-size: 24px; font-size: 24px;
} }
.curr-group-desc { .curr-group-desc {
color: #fff; color: #fff;
font-size: 12px; font-size: 12px;
max-height: 54px;
text-overflow:ellipsis;
overflow:hidden;
-webkit-line-clamp: 3;
-webkit-box-orient: vertical;
display: -webkit-box;
} }
.delete-group, .edit-group { .delete-group, .edit-group {
font-size: 18px; font-size: 18px;

View File

@ -41,7 +41,7 @@ const getColumns = (data, props) => {
dataIndex: 'name', dataIndex: 'name',
key: 'name', key: 'name',
render: (text, record) => { render: (text, record) => {
return <Link to={`Interface/${record._id}`}>{text}</Link> return <Link to={`/Interface/${record._id}`}>{text}</Link>
} }
}, { }, {
title: '创建人', title: '创建人',

View File

@ -141,8 +141,9 @@ class UpDateModal extends Component {
// can use data-binding to set // can use data-binding to set
form.setFieldsValue({ form.setFieldsValue({
envs: envs.filter(key => { envs: envs.filter(key => {
const realKey = key._id ? key._id : key
console.log(key); console.log(key);
return key._id !== id; return realKey !== id;
}) })
}); });
} }
@ -183,7 +184,7 @@ class UpDateModal extends Component {
getFieldDecorator('envs', { initialValue: envMessage }); getFieldDecorator('envs', { initialValue: envMessage });
const envs = getFieldValue('envs'); const envs = getFieldValue('envs');
const formItems = envs.map((k, index) => { const formItems = envs.map((k, index) => {
// console.log(k); console.log(k);
const secondIndex = 'next' + index; // 为保证key的唯一性 const secondIndex = 'next' + index; // 为保证key的唯一性
return ( return (
<Row key={index} type="flex" justify="space-between" align={index === 0 ? 'middle' : 'top'}> <Row key={index} type="flex" justify="space-between" align={index === 0 ? 'middle' : 'top'}>
@ -229,7 +230,7 @@ class UpDateModal extends Component {
> >
{getFieldDecorator(`envs-domain-${index}`, { {getFieldDecorator(`envs-domain-${index}`, {
validateTrigger: ['onChange', 'onBlur'], validateTrigger: ['onChange', 'onBlur'],
initialValue: envMessage.length !== 0 ? k.domain.split('\/\/')[1] : '', initialValue: envMessage.length !== 0 && k.domain ? k.domain.split('\/\/')[1] : '',
rules: [{ rules: [{
required: false, required: false,
whitespace: true, whitespace: true,
@ -269,7 +270,7 @@ class UpDateModal extends Component {
<Icon <Icon
className="dynamic-delete-button" className="dynamic-delete-button"
type="minus-circle-o" type="minus-circle-o"
onClick={() => this.remove(k._id)} onClick={() => this.remove(k._id ? k._id : k)}
/> />
) : null} ) : null}
</Col> </Col>

View File

@ -10,7 +10,7 @@ const Option = AutoComplete.Option;
state => { state => {
console.log(state); console.log(state);
return { return {
curUid: state.user.curUid curUid: state.login.uid + ''
} }
} }
) )

View File

@ -4,7 +4,6 @@ import { Link } from 'react-router-dom'
//import PropTypes from 'prop-types' //import PropTypes from 'prop-types'
import { import {
Table, Table,
Button,
Popconfirm, Popconfirm,
message message
} from 'antd' } from 'antd'
@ -79,11 +78,13 @@ class List extends Component {
let columns = [{ let columns = [{
title: 'UID', title: 'UID',
dataIndex: '_id', dataIndex: '_id',
key: '_id' key: '_id',
width: 70
}, { }, {
title: '用户名', title: '用户名',
dataIndex: 'username', dataIndex: 'username',
key: 'username' key: 'username',
width: 150
}, { }, {
title: 'Email', title: 'Email',
dataIndex: 'email', dataIndex: 'email',
@ -91,20 +92,24 @@ class List extends Component {
}, { }, {
title: '用户角色', title: '用户角色',
dataIndex: 'role', dataIndex: 'role',
key: 'role' key: 'role',
width:110
}, { }, {
title: '更新日期', title: '更新日期',
dataIndex: 'up_time', dataIndex: 'up_time',
key: 'up_time' key: 'up_time',
width: 180
}, { }, {
title: '功能', title: '功能',
key: 'action', key: 'action',
width:80,
render: (item) => { render: (item) => {
return ( return (
<span> <span>
<Button type="primary"><Link to={"/user/profile/" + item._id} > 查看 </Link></Button> <Link to={"/user/profile/" + item._id} >查看</Link>
<span className="ant-divider" />
<Popconfirm placement="leftTop" title="确认删除此用户?" onConfirm={() => {this.confirm(item._id)}} okText="Yes" cancelText="No"> <Popconfirm placement="leftTop" title="确认删除此用户?" onConfirm={() => {this.confirm(item._id)}} okText="Yes" cancelText="No">
<Button type="danger">删除</Button> <a href="#">删除</a>
</Popconfirm> </Popconfirm>
</span> </span>
) )
@ -128,7 +133,7 @@ class List extends Component {
return ( return (
<section className="user-table"> <section className="user-table">
<Table columns={columns} pagination={pageConfig} dataSource={data} /> <Table bordered={true} columns={columns} pagination={pageConfig} dataSource={data} />
</section> </section>
) )

View File

@ -4,10 +4,11 @@
display: -webkit-box; display: -webkit-box;
-webkit-box-flex: 1; -webkit-box-flex: 1;
margin: .88rem auto 0 auto; margin: .88rem auto 0 auto;
font-size: 0.14rem; // font-size: 0.14rem;
min-height:500px; min-height:433px;
margin-top: 84px; margin-top: 40px;
margin-bottom: 55px;
@ -16,6 +17,7 @@
box-shadow: 0 2px 4px 0 rgba(0,0,0,0.20); box-shadow: 0 2px 4px 0 rgba(0,0,0,0.20);
background: #FFF; background: #FFF;
border-radius:5px; border-radius:5px;
margin-top: 15px;
.search{ .search{
margin: 5px; margin: 5px;
} }
@ -29,20 +31,22 @@
border-radius:5px; border-radius:5px;
box-shadow: 0 2px 4px 0 rgba(0,0,0,0.20); box-shadow: 0 2px 4px 0 rgba(0,0,0,0.20);
background: #FFF; background: #FFF;
margin-top: 15px;
.ant-table-wrapper table { .ant-table-wrapper table {
font-size: .14rem; // font-size: .14rem;
button { a {
margin: 0 10px 0 0; // font-size: 12px;
} }
} }
} }
.user-profile { .user-profile {
-webkit-box-flex: 1; -webkit-box-flex: 1;
margin-top: 15px; margin-top: 15px;
margin-left: 15px; margin-left: 15px;
padding: 10px; padding: 10px 30px;
box-shadow: 0 2px 4px 0 rgba(0,0,0,0.20); box-shadow: 0 2px 4px 0 rgba(0,0,0,0.20);
background: #FFF; background: #FFF;
border-radius:5px; border-radius:5px;
@ -51,9 +55,21 @@
line-height:35px; line-height:35px;
margin: 5px; margin: 5px;
margin-bottom:10px; margin-bottom:10px;
border-bottom: 1px solid #f1f3f6;
padding-bottom: 10px;
.ant-col-4{
color: black;
padding: 0px 10px;
text-indent: .7em;
// background-color: #f1f3f6;
border-left: 5px solid #f1f3f6;
margin-right: 30px;
}
.text{
padding-right: 15px;
}
.text-button{ .text-button{
font-size: 12px; // font-size: 12px;
color: #657289; color: #657289;
cursor: pointer cursor: pointer
} }

View File

@ -25,7 +25,8 @@ export default (state = initialState, action) => {
...state, ...state,
isLogin: (action.payload.data.errcode == 0), isLogin: (action.payload.data.errcode == 0),
loginState: (action.payload.data.errcode == 0)?MEMBER_STATUS:GUEST_STATUS, loginState: (action.payload.data.errcode == 0)?MEMBER_STATUS:GUEST_STATUS,
userName: action.payload.data.data ? action.payload.data.data.username : null userName: action.payload.data.data ? action.payload.data.data.username : null,
uid: action.payload.data.data ? action.payload.data.data._id : null
}; };
} }
case LOGIN: { case LOGIN: {

View File

@ -7,7 +7,8 @@ import {
GET_INTERFACE_REQ_PARAMS, GET_INTERFACE_REQ_PARAMS,
GET_INTERFACE_RES_PARAMS, GET_INTERFACE_RES_PARAMS,
PUSH_INTERFACE_NAME, PUSH_INTERFACE_NAME,
PUSH_INTERFACE_METHOD PUSH_INTERFACE_METHOD,
FETCH_INTERFACE_PROJECT
} from '../../constants/action-types.js' } from '../../constants/action-types.js'
const initialState = { const initialState = {
@ -23,7 +24,8 @@ const initialState = {
} }
], ],
reqParams: '', reqParams: '',
resParams: '' resParams: '',
project: {}
} }
export default (state = initialState, action) => { export default (state = initialState, action) => {
@ -73,6 +75,11 @@ export default (state = initialState, action) => {
...state, ...state,
method: action.payload method: action.payload
} }
case FETCH_INTERFACE_PROJECT:
return {
...state,
project: action.payload.data.data
}
default: default:
return state return state
} }

View File

@ -25,7 +25,8 @@ export default (state = initialState, action) => {
...state, ...state,
isLogin: (action.payload.data.errcode == 0), isLogin: (action.payload.data.errcode == 0),
loginState: (action.payload.data.errcode == 0)?MEMBER_STATUS:GUEST_STATUS, loginState: (action.payload.data.errcode == 0)?MEMBER_STATUS:GUEST_STATUS,
userName: action.payload.data.data ? action.payload.data.data.username : null userName: action.payload.data.data ? action.payload.data.data.username : null,
uid: action.payload.data.data ? action.payload.data.data._id : null
}; };
} }
case LOGIN: { case LOGIN: {

View File

@ -20,6 +20,7 @@
"babel-plugin-transform-decorators-legacy": "^1.3.4", "babel-plugin-transform-decorators-legacy": "^1.3.4",
"copy-webpack-plugin": "^4.0.1", "copy-webpack-plugin": "^4.0.1",
"core-decorators": "^0.17.0", "core-decorators": "^0.17.0",
"cross-request": "^1.0.1",
"fs-extra": "^3.0.1", "fs-extra": "^3.0.1",
"jsoneditor": "^5.9.3", "jsoneditor": "^5.9.3",
"jsonwebtoken": "^7.4.1", "jsonwebtoken": "^7.4.1",
@ -51,6 +52,7 @@
"sha1": "^1.1.1", "sha1": "^1.1.1",
"string-replace-webpack-plugin": "^0.1.3", "string-replace-webpack-plugin": "^0.1.3",
"universal-cookie": "^2.0.8", "universal-cookie": "^2.0.8",
"url": "^0.11.0",
"wangeditor": "^3.0.4", "wangeditor": "^3.0.4",
"ykit-config-antd": "^0.1.3", "ykit-config-antd": "^0.1.3",
"ykit-config-react": "^0.4.4" "ykit-config-react": "^0.4.4"

View File

@ -26,7 +26,7 @@ class projectController extends baseController {
verifyDomain(domain){ verifyDomain(domain){
if(!domain) return false; if(!domain) return false;
if(/^[a-zA-Z0-9\-_\.]+[a-zA-Z]{2,6}$/.test(domain)){ if(/^[a-zA-Z0-9\-_\.]+?\.[a-zA-Z0-9\-_\.]*?[a-zA-Z]{2,6}$/.test(domain)){
return true; return true;
} }
return false; return false;
@ -332,7 +332,7 @@ class projectController extends baseController {
let projectData = await this.Model.get(id); let projectData = await this.Model.get(id);
if(params.basepath = (this.handleBasepath(params.basepath)) === false){ if((params.basepath = this.handleBasepath(params.basepath)) === false){
return ctx.body = yapi.commons.resReturn(null, 401, 'basepath格式有误') return ctx.body = yapi.commons.resReturn(null, 401, 'basepath格式有误')
} }

View File

@ -86,7 +86,7 @@ var projectController = function (_baseController) {
key: 'verifyDomain', key: 'verifyDomain',
value: function verifyDomain(domain) { value: function verifyDomain(domain) {
if (!domain) return false; if (!domain) return false;
if (/^[a-zA-Z0-9\-_\.]+[a-zA-Z]{2,6}$/.test(domain)) { if (/^[a-zA-Z0-9\-_\.]+?\.[a-zA-Z0-9\-_\.]*?[a-zA-Z]{2,6}$/.test(domain)) {
return true; return true;
} }
return false; return false;
@ -778,7 +778,7 @@ var projectController = function (_baseController) {
case 12: case 12:
projectData = _context8.sent; projectData = _context8.sent;
if (!(params.basepath = this.handleBasepath(params.basepath) === false)) { if (!((params.basepath = this.handleBasepath(params.basepath)) === false)) {
_context8.next = 15; _context8.next = 15;
break; break;
} }