mirror of
https://github.com/YMFE/yapi.git
synced 2025-01-06 12:45:22 +08:00
commit
2e3304d639
@ -37,6 +37,7 @@ module.exports = {
|
||||
"error",
|
||||
"always"
|
||||
],
|
||||
"strict": 0
|
||||
"strict": 0,
|
||||
"comma-dangle": ["error", "never"]
|
||||
}
|
||||
};
|
63
README.md
63
README.md
@ -5,3 +5,66 @@
|
||||
1. npm install
|
||||
2. npm run dev-server
|
||||
|
||||
### 平台特性
|
||||
|
||||
  yapi是一个**高效**、**易用**、**可部署**的API管理平台,旨在为开发、产品、测试人员提供更优雅的接口管理服务。可以帮助开发者轻松创建、发布、维护、监控和保护任意规模的 API,而且yapi为用户提供了优秀的交互体验,开发人员只需利用平台提供的接口数据写入工具以及简单的点击操作就可以实现接口的创建。
|
||||
>
|
||||
|
||||
# 平台介绍
|
||||
## 1 接口管理架构
|
||||
平台以**项目分组** -> **项目** -> **接口**的划分进行接口组织管理。
|
||||
|
||||
### 1.1 项目分组
|
||||
登录之后进到项目首页,左边侧边栏显示的即分组列表。
|
||||
![分组列表](http://upload-images.jianshu.io/upload_images/842107-bf341260ab637b36.png?imageMogr2/auto-orient/strip%7CimageView2/2/w/1240)
|
||||
|
||||
管理员有权限添加或删除分组。
|
||||
![添加分组](http://upload-images.jianshu.io/upload_images/842107-a0d4d9a98003896a.png?imageMogr2/auto-orient/strip%7CimageView2/2/w/1240)
|
||||
|
||||
> 分组名称具有唯一性
|
||||
|
||||
### 1.2 项目
|
||||
选中不同的分组,右边会显示该分组下的项目列表。
|
||||
|
||||
![项目列表](http://upload-images.jianshu.io/upload_images/842107-137bcae58b84715e.png?imageMogr2/auto-orient/strip%7CimageView2/2/w/1240)
|
||||
|
||||
创建项目需要填写项目名称,项目线上域名(添加完成后可配置项目其他环境域名),项目接口基本路径(接口路径前面相同的部分)以及项目描述。
|
||||
![创建项目](http://upload-images.jianshu.io/upload_images/842107-360a50ddb746f73d.png?imageMogr2/auto-orient/strip%7CimageView2/2/w/1240)
|
||||
|
||||
> 项目『线上域名 + 基本路径』具有唯一性
|
||||
|
||||
### 1.3 接口
|
||||
点击项目名称,进入该项目接口列表。
|
||||
![接口列表](http://upload-images.jianshu.io/upload_images/842107-e858005f714f4889.png?imageMogr2/auto-orient/strip%7CimageView2/2/w/1240)
|
||||
|
||||
点击编辑,进入接口详情页(之后接口详情页和编辑也会分开),可以编辑接口或者请求测试真实接口。
|
||||
|
||||
![接口详情](http://upload-images.jianshu.io/upload_images/842107-78c0ea839619d068.png?imageMogr2/auto-orient/strip%7CimageView2/2/w/1240)
|
||||
|
||||
![请求真实接口](http://upload-images.jianshu.io/upload_images/842107-2ee7171d707e91ff.png?imageMogr2/auto-orient/strip%7CimageView2/2/w/1240)
|
||||
|
||||
|
||||
### Mock功能
|
||||
|
||||
  yapi的Mock功能可以根据用户的输入接口信息如协议、URL、接口名、请求头、请求参数、mock规则生成Mock接口,这些接口会自动生成模拟数据,支持复杂的生成逻辑,创建者可以自由构造需要的数据。而且与常见的Mock方式如将Mock写在代码里和JS拦截等相比yapi的Mock在使用场景和效率和复杂度上是相差甚远的,正是由于yapi的Mock是一个第三方平台那么在 团队开发时任何人都可以权限许可下创建、修改接口信息等操作,这对于团队开发是很有好处的。
|
||||
|
||||
####第一步:添加接口
|
||||
通过点击页面上的"+添加接口"
|
||||
|
||||
![接口添加](http://note.youdao.com/yws/api/personal/file/WEB613bd4f29db038f2b41c03dcfceda2b6?method=download&shareKey=29bfc2b855f6f26ce0079baf567e54cc)
|
||||
|
||||
####第二步:输入协议、URL、接口名、请求头、请求参数、mock规则等信息,然后点击右上角的"Mock"按钮。
|
||||
|
||||
![接口详情](http://note.youdao.com/yws/api/personal/file/WEB0759331a53e095d910cfb4024ea657d5?method=download&shareKey=a86046f0bd2353d4763a9c962d747e5b)
|
||||
|
||||
####第三步:当点击"Mock"按钮之后,就会在页面下方生成一个mock结果并产生一个API接口。点击"复制"按钮即可复制,用户拿到接口后就可以发请求了。
|
||||
|
||||
![Mock结果](http://note.youdao.com/yws/api/personal/file/WEB265d4bf7cc979bda06d07639d1b84557?method=download&shareKey=64d41dea0371e38761f494d7899b3b35)
|
||||
|
||||
####第四步:当拿到复制好接口之后就可以发起一个请求了,先将请求的信息填写完善如:请求方法(post、get等)、URL、请求头、请求的数据等。然后就点击"发送",然后在"返回结果"出可以看到接口返回的数据。
|
||||
|
||||
![请求接口](http://note.youdao.com/yws/api/personal/file/WEB1c22d5c4062be5f10be0b1cdfae86621?method=download&shareKey=93be3a4f1fe56219b89ea2c5ba04014d)
|
||||
|
||||
你也可以通过点击"管理成员"来添加和删除项目的成员,便于团队管理。
|
||||
|
||||
![成员管理](http://note.youdao.com/yws/api/personal/file/WEB1b9defdf0cb884f46c2bd6c30ceb02fb?method=download&shareKey=218b9326659208ec564b9fff3ea8c6c3)
|
@ -3,7 +3,8 @@ import {
|
||||
LIST_INTERFACE_CLICK,
|
||||
PROJECT_MEMBER_INTERFACE,
|
||||
DELETE_INTERFACE_DATA,
|
||||
SAVE_INTERFACE_PROJECT_ID
|
||||
SAVE_INTERFACE_PROJECT_ID,
|
||||
GET_INTERFACE_GROUP_LIST
|
||||
} from '../constants/action-types.js'
|
||||
|
||||
export function fetchInterfaceData (value) {
|
||||
@ -38,3 +39,10 @@ export function saveInterfaceProjectId (value) {
|
||||
payload: value
|
||||
}
|
||||
}
|
||||
|
||||
export function getInterfaceGroupList (value) {
|
||||
return {
|
||||
type: GET_INTERFACE_GROUP_LIST,
|
||||
payload: value
|
||||
}
|
||||
}
|
||||
|
@ -60,7 +60,7 @@ Footer.defaultProps = {
|
||||
linkList: [
|
||||
{
|
||||
itemTitle: '源码仓库',
|
||||
itemLink: 'http://gitlab.corp.qunar.com/mfe/yapi.git'
|
||||
itemLink: 'https://github.com/YMFE/yapi'
|
||||
}
|
||||
]
|
||||
|
||||
|
@ -23,6 +23,7 @@
|
||||
}
|
||||
}
|
||||
.footerMask{
|
||||
@include wrap-width-limit;
|
||||
position: absolute;
|
||||
top: 0px;
|
||||
height: 100%;
|
||||
|
@ -195,4 +195,4 @@ export default class HeaderCom extends Component {
|
||||
</acticle>
|
||||
)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -8,10 +8,10 @@ $color-grey-deep : #929aac;
|
||||
$color-black-light : #404040;
|
||||
/* .header-box.css */
|
||||
.header-box {
|
||||
@include wrap-width-limit;
|
||||
display: block;
|
||||
font-size: 0.14rem;
|
||||
z-index: 99;
|
||||
@include wrap-width-limit;
|
||||
.content {
|
||||
@include row-width-limit;
|
||||
margin: 0 auto;
|
||||
|
@ -2,14 +2,9 @@ $color-grey:#979DA7;
|
||||
|
||||
.search-wrapper{
|
||||
.search-input{
|
||||
border:1px solid $color-grey;
|
||||
color: $color-grey;
|
||||
width: 2rem;
|
||||
transition: width 2s;
|
||||
//background-color:rgba(0,0,0,0.5);
|
||||
//transition: width 2s;
|
||||
}
|
||||
.srch-icon{
|
||||
color: $color-grey;
|
||||
font-weight: bold;
|
||||
}
|
||||
}
|
||||
|
@ -5,6 +5,7 @@ export const PROJECT_MEMBER_INTERFACE = 'PROJECT_MEMBER_INTERFACE'
|
||||
export const PUSH_INTERFACE_NAME = 'PUSH_INTERFACE_NAME'
|
||||
export const DELETE_INTERFACE_DATA = 'DELETE_INTERFACE_DATA'
|
||||
export const SAVE_INTERFACE_PROJECT_ID = 'SAVE_INTERFACE_PROJECT_ID'
|
||||
export const GET_INTERFACE_GROUP_LIST = 'GET_INTERFACE_GROUP_LIST'
|
||||
|
||||
// addInterFace
|
||||
export const FETCH_ADD_INTERFACE_INPUT = 'FETCH_ADD_INTERFACE_INPUT'
|
||||
|
@ -37,7 +37,8 @@ const success = () => {
|
||||
method: state.addInterface.method,
|
||||
url: state.addInterface.url,
|
||||
seqGroup: state.addInterface.seqGroup,
|
||||
interfaceName: state.addInterface.interfaceName
|
||||
interfaceName: state.addInterface.interfaceName,
|
||||
server_ip: state.login.server_ip
|
||||
}
|
||||
},
|
||||
{
|
||||
@ -56,6 +57,7 @@ class AddInterface extends Component {
|
||||
static propTypes = {
|
||||
url: PropTypes.string,
|
||||
method: PropTypes.string,
|
||||
server_ip: PropTypes.string,
|
||||
reqParams: PropTypes.string,
|
||||
resParams: PropTypes.string,
|
||||
seqGroup: PropTypes.array,
|
||||
@ -230,6 +232,8 @@ class AddInterface extends Component {
|
||||
this.setLoading()
|
||||
success()
|
||||
this.changeState(true)
|
||||
// 初始化 mock
|
||||
this.mockData()
|
||||
})
|
||||
.catch(e => {
|
||||
console.log(e)
|
||||
@ -238,21 +242,23 @@ class AddInterface extends Component {
|
||||
|
||||
render () {
|
||||
const TabPane = Tabs.TabPane
|
||||
const { server_ip } = this.props
|
||||
const { isLoading, isSave, mockJson='', mockURL } = this.state
|
||||
|
||||
return (
|
||||
<section className="add-interface-box">
|
||||
<div className="content">
|
||||
<Tabs defaultActiveKey="1">
|
||||
<Tabs type="card">
|
||||
<TabPane tab="接口详情" key="1">
|
||||
<Button type="primary" className="save" onClick={this.saveForms}>保存</Button>
|
||||
<Button className="mock" onClick={this.mockData}>Mock</Button>
|
||||
<h3 className="req-title">请求部分</h3>
|
||||
<ReqMethod />
|
||||
<ReqHeader />
|
||||
<ReqParams data={this.props} />
|
||||
<MockUrl mockURL={mockURL} serverIp={server_ip} />
|
||||
<h3 className="req-title">返回部分</h3>
|
||||
<ResParams />
|
||||
<Result isSave={isSave} mockJson={mockJson} />
|
||||
<MockUrl mockURL={mockURL} />
|
||||
<Button type="primary" className="save" onClick={this.saveForms}>保存</Button>
|
||||
</TabPane>
|
||||
<TabPane tab="请求接口" key="3">
|
||||
<InterfaceTest />
|
||||
|
@ -2,9 +2,11 @@
|
||||
|
||||
.add-interface-box {
|
||||
-webkit-box-flex: 1;
|
||||
min-height: 5rem;
|
||||
font-size: .14rem;
|
||||
overflow-x: hidden;
|
||||
overflow-y: auto;
|
||||
font-size: .12rem;
|
||||
|
||||
.content {
|
||||
@include row-width-limit;
|
||||
@ -14,9 +16,33 @@
|
||||
background: #FFF;
|
||||
padding: 10px 20px 50px 20px;
|
||||
|
||||
.ant-tabs-content {
|
||||
padding: 0 0 50px 0;
|
||||
}
|
||||
|
||||
.border {
|
||||
zoom: 1;
|
||||
overflow: hidden;
|
||||
}
|
||||
|
||||
.ant-card-body {
|
||||
padding: 0;
|
||||
}
|
||||
|
||||
.ant-tabs-nav {
|
||||
float: left;
|
||||
}
|
||||
|
||||
.req-title {
|
||||
margin: 40px 0 0 30px;
|
||||
color: #666;
|
||||
font-weight: normal;
|
||||
}
|
||||
|
||||
.save {
|
||||
float: right;
|
||||
margin: 0 0 10px 0;
|
||||
position: absolute;
|
||||
bottom: 0;
|
||||
left: 550px;
|
||||
}
|
||||
|
||||
.mock {
|
||||
@ -26,7 +52,7 @@
|
||||
|
||||
table {
|
||||
width: 100%;
|
||||
border-top: 1px #EEE solid;
|
||||
margin: 20px 0 0 40px;
|
||||
|
||||
th {
|
||||
padding:0 10px;
|
||||
@ -41,13 +67,15 @@
|
||||
}
|
||||
|
||||
.h3 {
|
||||
font-size: .14rem;
|
||||
font-size: .12rem;
|
||||
margin: 0 10px 0 15px;
|
||||
width: 100px;
|
||||
display: inline-block;
|
||||
text-align: right;
|
||||
}
|
||||
|
||||
.url {
|
||||
margin: 0 0 0 15px;
|
||||
width: 61.2%;
|
||||
width: 16%;
|
||||
}
|
||||
}
|
||||
|
||||
@ -63,12 +91,12 @@
|
||||
.req-header {
|
||||
display: -webkit-box;
|
||||
line-height: 32px;
|
||||
margin: 10px 0 0 0;
|
||||
border-top: 1px #EEE solid;
|
||||
margin: 10px 0 0 50px;
|
||||
padding: 15px 0 0 0;
|
||||
|
||||
.req-h3 {
|
||||
line-height: 32px;
|
||||
font-weight: normal;
|
||||
}
|
||||
|
||||
ul {
|
||||
@ -92,21 +120,26 @@
|
||||
}
|
||||
|
||||
.req-save, .res-save {
|
||||
margin: 5px 0 0 107px;
|
||||
margin: 5px 0 0 159px;
|
||||
}
|
||||
|
||||
/* .req-params.css */
|
||||
.req-params {
|
||||
display: -webkit-box;
|
||||
padding: 20px 0 0 0;
|
||||
margin: 20px 0 0 0;
|
||||
border-top: 1px #EEE solid;
|
||||
margin: 20px 0 0 90px;
|
||||
width: 650px;
|
||||
height: 200px;
|
||||
.req-h3 {
|
||||
font-weight: normal;
|
||||
}
|
||||
}
|
||||
|
||||
.res-params-box {
|
||||
display: inline-block;
|
||||
width: 530px;
|
||||
float: left;
|
||||
margin: 30px 0 0 50px;
|
||||
|
||||
/* .req-save.css */
|
||||
.res-params {
|
||||
@ -140,7 +173,7 @@
|
||||
.result {
|
||||
display: inline-block;
|
||||
line-height: 32px;
|
||||
margin: 0 0 0 20px;
|
||||
margin: 29px 0 0 20px;
|
||||
width: 500px;
|
||||
float: left;
|
||||
|
||||
@ -154,8 +187,7 @@
|
||||
padding: 10px;
|
||||
box-sizing: border-box;
|
||||
width: 100%;
|
||||
border: 1px #CCC solid;
|
||||
height: 300px;
|
||||
height: 330px;
|
||||
overflow-x: hidden;
|
||||
overflow-y: auto;
|
||||
line-height: 1.2;
|
||||
@ -176,16 +208,28 @@
|
||||
.mock-url-box {
|
||||
clear: both;
|
||||
padding: 10px 0 0 0;
|
||||
margin: 0 0 0 20px;
|
||||
margin: 10px 0 0 90px;
|
||||
zoom: 1;
|
||||
overflow: hidden;
|
||||
.title {
|
||||
float: left;
|
||||
line-height: 35px;
|
||||
}
|
||||
p {
|
||||
width: 70%;
|
||||
width: 52.8%;
|
||||
height: 35px;
|
||||
line-height: 35px;
|
||||
border: 1px #DDD solid;
|
||||
display: inline-block;
|
||||
vertical-align: -4px;
|
||||
margin: 0 10px 0 0;
|
||||
margin: 0 10px 0 8px;
|
||||
padding: 0 0 0 10px;
|
||||
float: left;
|
||||
}
|
||||
.host {
|
||||
margin: 10px 0 0 80px;
|
||||
}
|
||||
#mock-clipboard {
|
||||
margin: 3px 0 0 0;
|
||||
}
|
||||
}
|
||||
|
||||
@ -215,7 +259,7 @@ body {
|
||||
p, h1, h2, h3, h4, h5, table, pre {
|
||||
line-height: auto;
|
||||
margin: 0;
|
||||
font-size: .14rem;
|
||||
font-size: .12rem;
|
||||
color: #777;
|
||||
font-family: 'Microsoft Yahei';
|
||||
font-weight: normal;
|
||||
@ -254,14 +298,15 @@ body {
|
||||
background-color: #fff;
|
||||
}
|
||||
#req-cover {
|
||||
height: 330px;
|
||||
padding: 0 20px;
|
||||
background-color: #FFF;
|
||||
border: 1px #DDD solid;
|
||||
// background-color: #FFF;
|
||||
-webkit-box-flex: 1;
|
||||
margin: 0 0 0 15px;
|
||||
}
|
||||
#res-cover {
|
||||
background-color: #FFF;
|
||||
height: 330px;
|
||||
padding: 0 20px;
|
||||
background-color: #FFF;
|
||||
-webkit-box-flex: 1;
|
||||
}
|
||||
|
@ -1,7 +1,7 @@
|
||||
import React, { Component } from 'react'
|
||||
import PropTypes from 'prop-types'
|
||||
import { connect } from 'react-redux'
|
||||
import { Button, Input, Select, Card, Alert } from 'antd'
|
||||
import { Button, Input, Select, Card, Alert, Spin } from 'antd'
|
||||
import { autobind } from 'core-decorators';
|
||||
import crossRequest from 'cross-request';
|
||||
import { withRouter } from 'react-router';
|
||||
@ -111,7 +111,8 @@ export default class InterfaceTest extends Component {
|
||||
params,
|
||||
paramsNotJson,
|
||||
headers,
|
||||
currDomain: domains.prd
|
||||
currDomain: domains.prd,
|
||||
loading: false
|
||||
});
|
||||
}
|
||||
|
||||
@ -128,6 +129,8 @@ export default class InterfaceTest extends Component {
|
||||
query
|
||||
});
|
||||
|
||||
this.setState({ loading: true })
|
||||
|
||||
crossRequest({
|
||||
url: href,
|
||||
method,
|
||||
@ -135,7 +138,18 @@ export default class InterfaceTest extends Component {
|
||||
data: params,
|
||||
success: (res, header) => {
|
||||
console.log(header)
|
||||
try {
|
||||
res = JSON.parse(res);
|
||||
} catch (e) {
|
||||
null;
|
||||
}
|
||||
this.setState({res})
|
||||
this.setState({ loading: false })
|
||||
},
|
||||
error: (err, header) => {
|
||||
console.log(header)
|
||||
this.setState({res: err || '请求失败'})
|
||||
this.setState({ loading: false })
|
||||
}
|
||||
})
|
||||
}
|
||||
@ -205,6 +219,11 @@ export default class InterfaceTest extends Component {
|
||||
<div className="interface-name">{interfaceName}</div>
|
||||
<div className="req-part">
|
||||
<div className="req-row href">
|
||||
<InputGroup compact style={{display: 'inline-block', width: 680, border: 0, background: '#fff', marginBottom: -4}}>
|
||||
<Input value="Method" disabled style={{display: 'inline-block', width: 80, border: 0, background: '#fff'}} />
|
||||
<Input value="Domain" disabled style={{display: 'inline-block', width: 300, border: 0, background: '#fff'}} />
|
||||
<Input value="Basepath + Url + [Query]" disabled style={{display: 'inline-block', width: 300, border: 0, background: '#fff'}} />
|
||||
</InputGroup>
|
||||
<InputGroup compact style={{display: 'inline-block', width: 680}}>
|
||||
<Input value={method} disabled style={{display: 'inline-block', width: 80}} />
|
||||
<Select defaultValue="prd" style={{display: 'inline-block', width: 300}} onChange={this.changeDomain}>
|
||||
@ -214,7 +233,13 @@ export default class InterfaceTest extends Component {
|
||||
</Select>
|
||||
<Input value={pathname+search} disabled style={{display: 'inline-block', width: 300}} />
|
||||
</InputGroup>
|
||||
<Button onClick={this.testInterface} type="primary" style={{marginLeft: 10}}>发送</Button>
|
||||
<Button
|
||||
onClick={this.testInterface}
|
||||
type="primary"
|
||||
style={{marginLeft: 10}}
|
||||
loading={this.state.loading}
|
||||
>发送</Button>
|
||||
<span style={{fontSize: 12, color: 'rgba(0, 0, 0, 0.25)'}}>(请求测试真实接口)</span>
|
||||
</div>
|
||||
<Card title="HEADERS" noHovering style={{marginTop: 10}} className={Object.keys(headers).length ? '' : 'hidden'}>
|
||||
<div className="req-row headers">
|
||||
@ -267,15 +292,16 @@ export default class InterfaceTest extends Component {
|
||||
</Card>
|
||||
</div>
|
||||
<Card title="返回结果" noHovering style={{marginTop: 10}}>
|
||||
<div className="res-part">
|
||||
<div>
|
||||
<TextArea
|
||||
value={this.state.res ? JSON.stringify(this.state.res, 2) : ''}
|
||||
style={{margin: 10}}
|
||||
autosize={{ minRows: 2, maxRows: 6 }}
|
||||
></TextArea>
|
||||
<Spin spinning={this.state.loading}>
|
||||
<div className="res-part">
|
||||
<div style={{padding: 10}}>
|
||||
<TextArea
|
||||
value={typeof this.state.res === 'object' ? JSON.stringify(this.state.res, null, 2) : this.state.res.toString()}
|
||||
autosize={{ minRows: 2, maxRows: 6 }}
|
||||
></TextArea>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</Spin>
|
||||
</Card>
|
||||
</div>
|
||||
)
|
||||
|
@ -10,7 +10,8 @@ const success = () => {
|
||||
|
||||
class MockUrl extends Component {
|
||||
static propTypes = {
|
||||
mockURL: PropTypes.string
|
||||
mockURL: PropTypes.string,
|
||||
serverIp: PropTypes.string
|
||||
}
|
||||
|
||||
constructor(props) {
|
||||
@ -34,10 +35,13 @@ class MockUrl extends Component {
|
||||
}
|
||||
|
||||
render () {
|
||||
const { serverIp } = this.props
|
||||
return (
|
||||
<section className="mock-url-box">
|
||||
<span className="title">mock地址 : </span>
|
||||
<p id="mock-p">{this.props.mockURL}</p>
|
||||
<Button type="primary" id="mock-clipboard">复制</Button>
|
||||
<div className="host">请配置host ***.***.***.*** { serverIp }</div>
|
||||
</section>
|
||||
)
|
||||
}
|
||||
|
@ -57,7 +57,6 @@ class ReqHeader extends Component {
|
||||
return (
|
||||
<section>
|
||||
<div className="req-header">
|
||||
<strong className="req-h3">请求头部 :</strong>
|
||||
<ul>
|
||||
{ getReqList(this) }
|
||||
</ul>
|
||||
|
@ -114,7 +114,7 @@ class ReqList extends Component {
|
||||
console.log(name)
|
||||
return (
|
||||
<li>
|
||||
<em className="title">头部标签</em>
|
||||
<em className="title">头部标签 : </em>
|
||||
<Select value={name} style={{ width: 220 }} onChange={this.handleChange} size="large">
|
||||
<Option value="">选择请求头</Option>
|
||||
<Option value="Accept">Accept</Option>
|
||||
@ -123,7 +123,7 @@ class ReqList extends Component {
|
||||
<Option value="Accept-Language">Accept-Language</Option>
|
||||
<Option value="Accept-Ranges">Accept-Ranges</Option>
|
||||
</Select>
|
||||
<em className="title">头部内容</em>
|
||||
<em className="title">头部内容 : </em>
|
||||
<Input value={value} placeholder="Basic usage" className="req-content" size="large" onInput={this.handleBlur} />
|
||||
<Icon className="dynamic-delete-button" type="minus-circle-o" onClick={this.deleteReqHeader} />
|
||||
</li>
|
||||
|
@ -63,10 +63,9 @@ class ReqMethod extends Component {
|
||||
<table>
|
||||
<tbody>
|
||||
<tr>
|
||||
<th>协议 :</th>
|
||||
<td>
|
||||
<span className="h3">请求方式</span>
|
||||
<Select value={method} style={{ width: 220 }} onChange={this.handleChange} size="large">
|
||||
<span className="h3">请求方式 : </span>
|
||||
<Select value={method} style={{ width: 180 }} onChange={this.handleChange} size="large">
|
||||
<Option value="POST">POST</Option>
|
||||
<Option value="GET">GET</Option>
|
||||
<Option value="PUT">PUT</Option>
|
||||
@ -75,8 +74,8 @@ class ReqMethod extends Component {
|
||||
</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<th>URL :</th>
|
||||
<td>
|
||||
<span className="h3">URL : </span>
|
||||
<Input
|
||||
placeholder="填写 URL"
|
||||
className="url"
|
||||
@ -87,8 +86,8 @@ class ReqMethod extends Component {
|
||||
</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<th>名称 :</th>
|
||||
<td>
|
||||
<span className="h3">名称 : </span>
|
||||
<Input
|
||||
placeholder="接口名称"
|
||||
className="url"
|
||||
|
@ -1,10 +1,10 @@
|
||||
import React, { Component } from 'react'
|
||||
import PropTypes from 'prop-types'
|
||||
import { connect } from 'react-redux'
|
||||
import wangEditor from 'wangeditor'
|
||||
// import wangEditor from 'wangeditor'
|
||||
import { getReqParams } from '../../../actions/addInterface.js'
|
||||
|
||||
const editor = new wangEditor('#req-cover')
|
||||
//const editor = new wangEditor('#req-cover')
|
||||
|
||||
@connect(
|
||||
state => {
|
||||
@ -27,25 +27,41 @@ class ReqParams extends Component {
|
||||
super(props)
|
||||
}
|
||||
|
||||
initParams () {
|
||||
const { reqParams } = this.props
|
||||
if (reqParams) {
|
||||
editor.txt.html(reqParams)
|
||||
}
|
||||
}
|
||||
// initParams () {
|
||||
// const { reqParams } = this.props
|
||||
// if (reqParams) {
|
||||
// editor.txt.html(reqParams)
|
||||
// }
|
||||
// }
|
||||
|
||||
componentDidMount () {
|
||||
const reg = /(<p>)|(<\/p>)| |(<br>)|\s+/g
|
||||
let json = ''
|
||||
editor.customConfig.menus = []
|
||||
editor.customConfig.onchange = html => {
|
||||
json = html.replace(reg, '')
|
||||
this.props.getReqParams(json)
|
||||
function json_parse(json){
|
||||
try{
|
||||
return JSON.stringify(JSON.parse(json), null, "\t");
|
||||
}catch(e){
|
||||
return json
|
||||
}
|
||||
}
|
||||
setTimeout(() => {
|
||||
this.initParams()
|
||||
}, 500)
|
||||
editor.create()
|
||||
let editor2 = this.editor = window.ace.edit("req-cover")
|
||||
editor2.getSession().setMode("ace/mode/json");
|
||||
setTimeout( () => {
|
||||
editor2.setValue(json_parse(this.props.reqParams))
|
||||
} ,400)
|
||||
|
||||
editor2.getSession().on('change', ()=> {
|
||||
this.props.getReqParams(editor2.getValue())
|
||||
});
|
||||
// const reg = /(<p>)|(<\/p>)| |(<br>)|\s+/g
|
||||
// let json = ''
|
||||
// editor.customConfig.menus = []
|
||||
// editor.customConfig.onchange = html => {
|
||||
// json = html.replace(reg, '')
|
||||
// this.props.getReqParams(json)
|
||||
// }
|
||||
// setTimeout(() => {
|
||||
// this.initParams()
|
||||
// }, 500)
|
||||
// editor.create()
|
||||
}
|
||||
|
||||
render () {
|
||||
|
@ -1,11 +1,13 @@
|
||||
import React, { Component } from 'react'
|
||||
import PropTypes from 'prop-types'
|
||||
import { connect } from 'react-redux'
|
||||
import wangEditor from 'wangeditor'
|
||||
import { Tabs } from 'antd'
|
||||
// import wangEditor from 'wangeditor'
|
||||
import { Card } from 'antd'
|
||||
import { getResParams } from '../../../actions/addInterface.js'
|
||||
|
||||
const editor = new wangEditor('#res-cover')
|
||||
//const editor = new wangEditor('#res-cover')
|
||||
|
||||
|
||||
|
||||
@connect(
|
||||
state => {
|
||||
@ -28,35 +30,49 @@ class ResParams extends Component {
|
||||
super(props)
|
||||
}
|
||||
|
||||
initResParams () {
|
||||
const { resParams } = this.props
|
||||
if (resParams) {
|
||||
editor.txt.html(resParams)
|
||||
}
|
||||
}
|
||||
// initResParams () {
|
||||
// const { resParams } = this.props
|
||||
// if (resParams) {
|
||||
// editor.txt.html(resParams)
|
||||
// }
|
||||
// }
|
||||
|
||||
componentDidMount () {
|
||||
const reg = /(<p>)|(<\/p>)| |(<br>)|\s+|<div>|<\/div>/g
|
||||
editor.customConfig.menus = []
|
||||
editor.customConfig.onchange = html => {
|
||||
html = html.replace(reg, '')
|
||||
this.props.getResParams(html)
|
||||
//const reg = /(<p>)|(<\/p>)| |(<br>)|\s+|<div>|<\/div>/g
|
||||
//editor.customConfig.menus = []
|
||||
// editor.customConfig.onchange = html => {
|
||||
// html = html.replace(reg, '')
|
||||
// this.props.getResParams(html)
|
||||
// }
|
||||
// setTimeout(() => {
|
||||
// this.initResParams()
|
||||
// }, 400)
|
||||
//editor.create()
|
||||
|
||||
function json_parse(json){
|
||||
try{
|
||||
return JSON.stringify(JSON.parse(json), null, "\t");
|
||||
}catch(e){
|
||||
return json
|
||||
}
|
||||
}
|
||||
setTimeout(() => {
|
||||
this.initResParams()
|
||||
}, 400)
|
||||
editor.create()
|
||||
|
||||
let editor2 = this.editor = window.ace.edit("res-cover")
|
||||
editor2.getSession().setMode("ace/mode/json");
|
||||
editor2.getSession().on('change', ()=> {
|
||||
this.props.getResParams(editor2.getValue())
|
||||
});
|
||||
setTimeout( () => {
|
||||
editor2.setValue(json_parse(this.props.resParams))
|
||||
} ,400)
|
||||
}
|
||||
|
||||
render () {
|
||||
const TabPane = Tabs.TabPane
|
||||
return (
|
||||
<section className="res-params-box">
|
||||
<Tabs defaultActiveKey="1">
|
||||
<TabPane tab="返回参数" key="1">
|
||||
<div id="res-cover"></div>
|
||||
</TabPane>
|
||||
</Tabs>
|
||||
<Card title="返回 Mock" style={{ width: 500 }}>
|
||||
<div id="res-cover"></div>
|
||||
</Card>
|
||||
</section>
|
||||
)
|
||||
}
|
||||
|
@ -1,5 +1,5 @@
|
||||
import React, { Component } from 'react'
|
||||
import { Tabs } from 'antd'
|
||||
import { Card } from 'antd'
|
||||
import { connect } from 'react-redux'
|
||||
import PropTypes from 'prop-types'
|
||||
|
||||
@ -25,16 +25,13 @@ class Result extends Component {
|
||||
}
|
||||
|
||||
render () {
|
||||
const TabPane = Tabs.TabPane
|
||||
const { mockJson } = this.props
|
||||
|
||||
return (
|
||||
<div className="result">
|
||||
<Tabs defaultActiveKey="1">
|
||||
<TabPane tab="成功结果" key="1">
|
||||
<pre>{mockJson}</pre>
|
||||
</TabPane>
|
||||
</Tabs>
|
||||
<Card title="Mock 结果" style={{ width: 500 }}>
|
||||
<pre>{mockJson}</pre>
|
||||
</Card>
|
||||
</div>
|
||||
)
|
||||
}
|
||||
|
@ -52,7 +52,6 @@ $color-black-lighter: #404040;
|
||||
@include row-width-limit;
|
||||
margin: 1rem auto 0;
|
||||
.user-des{
|
||||
@include row-width-limit;
|
||||
margin: 0 auto .5rem;
|
||||
text-align: center;
|
||||
.title{
|
||||
@ -74,9 +73,9 @@ $color-black-lighter: #404040;
|
||||
}
|
||||
}
|
||||
.main-part{
|
||||
padding: .9rem .5rem;
|
||||
height: 5.8rem;
|
||||
@include wrap-width-limit;
|
||||
padding: .9rem 0;
|
||||
height: 5.8rem;
|
||||
&:nth-child(odd){
|
||||
background-color: $color-blue-lighter;
|
||||
}
|
||||
@ -86,7 +85,7 @@ $color-black-lighter: #404040;
|
||||
}
|
||||
.feat-part{
|
||||
@include wrap-width-limit;
|
||||
padding: .9rem .5rem;
|
||||
padding: .9rem 0;
|
||||
background-color: $color-white;
|
||||
p{
|
||||
display: flex;
|
||||
|
@ -78,7 +78,7 @@ class Interface extends Component {
|
||||
render () {
|
||||
const { interfaceData, projectMember, modalVisible } = this.props
|
||||
return (
|
||||
<div>
|
||||
<div className="g-doc">
|
||||
<section className="interface-box">
|
||||
<InterfaceList projectMember={projectMember} />
|
||||
<InterfaceMode modalVisible={modalVisible} closeProjectMember={this.props.closeProjectMember} />
|
||||
|
@ -1,5 +1,9 @@
|
||||
@import '../../styles/mixin.scss';
|
||||
|
||||
.g-doc {
|
||||
min-height: 5rem;
|
||||
}
|
||||
|
||||
/* .interface-box.css */
|
||||
.interface-box {
|
||||
@include row-width-limit;
|
||||
@ -41,6 +45,16 @@
|
||||
}
|
||||
.tags {
|
||||
margin: 10px 0 0 0;
|
||||
span {
|
||||
border-radius: 4px;
|
||||
padding: 4px 11px;
|
||||
margin: 0 10px 0 0;
|
||||
}
|
||||
.anticon {
|
||||
font-size: 17px;
|
||||
margin: 0 0 0 6px;
|
||||
vertical-align: 3px;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -1,44 +1,88 @@
|
||||
import React, { Component } from 'react'
|
||||
import { Modal, Input, Button } from 'antd'
|
||||
import PropTypes from 'prop-types'
|
||||
// import axios from 'axios'
|
||||
import axios from 'axios'
|
||||
import { autobind } from 'core-decorators'
|
||||
import ModeTag from './ModeTags'
|
||||
|
||||
// Tags
|
||||
const ModeTags = () => {
|
||||
const list = [1, 2, 3, 4]
|
||||
return (
|
||||
<article className="users">
|
||||
<p>项目成员</p>
|
||||
<div className="tags">
|
||||
{
|
||||
list.map((value, key) => {
|
||||
return <ModeTag key={key} />
|
||||
})
|
||||
}
|
||||
</div>
|
||||
</article>
|
||||
)
|
||||
}
|
||||
|
||||
class InterfaceMode extends Component {
|
||||
static propTypes = {
|
||||
modalVisible: PropTypes.bool,
|
||||
closeProjectMember: PropTypes.func
|
||||
closeProjectMember: PropTypes.func,
|
||||
memberList: PropTypes.array
|
||||
}
|
||||
|
||||
constructor(props) {
|
||||
super(props)
|
||||
this.state = {
|
||||
memberList: [],
|
||||
userName: ''
|
||||
}
|
||||
}
|
||||
|
||||
componentDidMount () {
|
||||
// axios.get({
|
||||
// url: '',
|
||||
// params: {}
|
||||
// })
|
||||
// .then(() => {
|
||||
this.getMemberList()
|
||||
}
|
||||
|
||||
// })
|
||||
@autobind
|
||||
getMemberList () {
|
||||
const params = {
|
||||
id: this.getInterfaceId()
|
||||
}
|
||||
axios.get('/project/get_member_list', { params })
|
||||
.then(data => {
|
||||
console.log(data)
|
||||
this.setState({
|
||||
'memberList': data.data.data
|
||||
})
|
||||
})
|
||||
.catch(err => {
|
||||
console.log(err)
|
||||
})
|
||||
}
|
||||
|
||||
@autobind
|
||||
closeMember (id) {
|
||||
const params = {
|
||||
member_uid: id,
|
||||
id: this.getInterfaceId()
|
||||
}
|
||||
|
||||
axios.post('/project/del_member', params)
|
||||
.then(() => {
|
||||
this.getMemberList()
|
||||
})
|
||||
.catch(err => {
|
||||
console.log(err)
|
||||
})
|
||||
}
|
||||
|
||||
@autobind
|
||||
addNewUser () {
|
||||
const { userName } = this.state
|
||||
const params = { q: userName}
|
||||
axios.get('/user/search', { params })
|
||||
.then(data => {
|
||||
const member_uid = data.data.data[0].uid
|
||||
const params = {id: this.getInterfaceId(), member_uid}
|
||||
axios.post('/project/add_member', params)
|
||||
.then( () => {
|
||||
this.getMemberList()
|
||||
})
|
||||
.catch (err => {
|
||||
console.log(err)
|
||||
})
|
||||
})
|
||||
.catch (err => {
|
||||
console.log(err)
|
||||
})
|
||||
}
|
||||
|
||||
@autobind
|
||||
injectValue (e) {
|
||||
this.setState({
|
||||
userName: e.target.value
|
||||
})
|
||||
}
|
||||
|
||||
handleOk (closeProjectMember) {
|
||||
@ -49,10 +93,18 @@ class InterfaceMode extends Component {
|
||||
closeProjectMember()
|
||||
}
|
||||
|
||||
getInterfaceId () {
|
||||
const reg = /Interface\/(\d+)/g
|
||||
const url = location.href
|
||||
url.match(reg)
|
||||
return RegExp.$1
|
||||
}
|
||||
|
||||
render() {
|
||||
const { modalVisible, closeProjectMember } = this.props
|
||||
const handleOk = this.handleOk.bind(this, closeProjectMember)
|
||||
const handleCancel = this.handleCancel.bind(this, closeProjectMember)
|
||||
const { memberList } = this.state
|
||||
|
||||
return (
|
||||
<Modal
|
||||
@ -63,11 +115,19 @@ class InterfaceMode extends Component {
|
||||
className="interface-mode-box"
|
||||
>
|
||||
<div className="add-user">
|
||||
<Input placeholder="Basic usage" size="large" />
|
||||
<Button>添加新成员</Button>
|
||||
<Input placeholder="Basic usage" size="large" onBlur={this.injectValue} />
|
||||
<Button onClick={this.addNewUser}>添 加</Button>
|
||||
</div>
|
||||
|
||||
<ModeTags />
|
||||
<article className="users">
|
||||
<p>项目成员</p>
|
||||
<div className="tags">
|
||||
{
|
||||
memberList.map((value, key) => {
|
||||
return <ModeTag key={key} value={value} closeMember={this.closeMember} getMemberList={this.getMemberList} />
|
||||
})
|
||||
}
|
||||
</div>
|
||||
</article>
|
||||
</Modal>
|
||||
)
|
||||
}
|
||||
|
@ -1,25 +1,33 @@
|
||||
import React, { Component } from 'react'
|
||||
import { Tag } from 'antd'
|
||||
// import PropTypes from 'prop-types'
|
||||
import { autobind } from 'core-decorators'
|
||||
import PropTypes from 'prop-types'
|
||||
import { Icon } from 'antd'
|
||||
|
||||
class ModeTags extends Component {
|
||||
// static propTypes = {
|
||||
// closeProjectMember: PropTypes.func,
|
||||
// }
|
||||
static propTypes = {
|
||||
value: PropTypes.object,
|
||||
_id: PropTypes.number,
|
||||
closeMember: PropTypes.func
|
||||
}
|
||||
|
||||
constructor(props) {
|
||||
super(props)
|
||||
}
|
||||
|
||||
@autobind
|
||||
closeTags () {
|
||||
|
||||
const { closeMember, value: { _id } } = this.props
|
||||
closeMember(_id)
|
||||
}
|
||||
|
||||
render() {
|
||||
// const { userName } = this.props
|
||||
|
||||
const { value: { username='', _id } } = this.props
|
||||
console.log(this.props, _id, username)
|
||||
return (
|
||||
<Tag closable onClose={this.closeTags}>小花</Tag>
|
||||
<span onClick={this.closeTags}>
|
||||
{username}
|
||||
<Icon className="dynamic-delete-button" type="minus-circle-o" />
|
||||
</span>
|
||||
)
|
||||
}
|
||||
}
|
||||
|
@ -1,13 +1,12 @@
|
||||
import React, { Component } from 'react'
|
||||
import PropTypes from 'prop-types'
|
||||
import { connect } from 'react-redux'
|
||||
import { Button, Icon, Modal, Input, message, Menu, Row, Col } from 'antd'
|
||||
import { Button, Icon, Popconfirm, Modal, Input, message, Menu, Row, Col } from 'antd'
|
||||
import { autobind } from 'core-decorators';
|
||||
import axios from 'axios';
|
||||
import { withRouter } from 'react-router';
|
||||
const { TextArea } = Input;
|
||||
const Search = Input.Search;
|
||||
const confirm = Modal.confirm;
|
||||
const TYPE_EDIT = 'edit';
|
||||
|
||||
import {
|
||||
@ -164,21 +163,15 @@ export default class GroupList extends Component {
|
||||
deleteGroup() {
|
||||
const self = this;
|
||||
const { currGroup } = self.props;
|
||||
confirm({
|
||||
title: `你确定要删除分组 ${currGroup.group_name}?`,
|
||||
content: `分组简介:${currGroup.group_desc}`,
|
||||
onOk() {
|
||||
axios.post('/group/del', {id: currGroup._id}).then(res => {
|
||||
if (res.data.errcode) {
|
||||
message.error(res.data.errmsg);
|
||||
} else {
|
||||
message.success('删除成功');
|
||||
self.props.fetchGroupList().then(() => {
|
||||
const currGroup = self.props.groupList[0] || { group_name: '', group_desc: '' };
|
||||
self.setState({groupList: self.props.groupList});
|
||||
self.props.setCurrGroup(currGroup)
|
||||
});
|
||||
}
|
||||
axios.post('/group/del', {id: currGroup._id}).then(res => {
|
||||
if (res.data.errcode) {
|
||||
message.error(res.data.errmsg);
|
||||
} else {
|
||||
message.success('删除成功');
|
||||
self.props.fetchGroupList().then(() => {
|
||||
const currGroup = self.props.groupList[0] || { group_name: '', group_desc: '' };
|
||||
self.setState({groupList: self.props.groupList});
|
||||
self.props.setCurrGroup(currGroup)
|
||||
});
|
||||
}
|
||||
});
|
||||
@ -205,7 +198,9 @@ export default class GroupList extends Component {
|
||||
<div className="curr-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="delete-group" type="delete" title="删除分组" onClick={this.deleteGroup}/>
|
||||
<Popconfirm title={`你确定要删除分组 ${currGroup.group_name}?`} onConfirm={this.deleteGroup}>
|
||||
<Icon className="delete-group" type="delete" title="删除分组"/>
|
||||
</Popconfirm>
|
||||
</div>
|
||||
<div className="curr-group-desc" title={currGroup.group_desc}>简介:{currGroup.group_desc}</div>
|
||||
</div>
|
||||
|
@ -2,5 +2,6 @@
|
||||
|
||||
.g-doc {
|
||||
@include row-width-limit;
|
||||
min-height: 5rem;
|
||||
margin: .24rem auto;
|
||||
}
|
||||
|
@ -19,8 +19,6 @@ const deleteConfirm = (id, props) => {
|
||||
const { delProject, currGroup, fetchProjectList } = props;
|
||||
const handle = () => {
|
||||
delProject(id).then((res) => {
|
||||
console.log(res);
|
||||
console.log(fetchProjectList, currGroup._id);
|
||||
if (res.payload.data.errcode == 0) {
|
||||
message.success('删除成功!')
|
||||
fetchProjectList(currGroup._id).then((res) => {
|
||||
@ -43,6 +41,13 @@ const getColumns = (data, props) => {
|
||||
render: (text, record) => {
|
||||
return <Link to={`/Interface/${record._id}`}>{text}</Link>
|
||||
}
|
||||
},{
|
||||
title: 'Mock链接',
|
||||
key: 'domain',
|
||||
render: (item) => {
|
||||
return 'http://'+ item.prd_host + item.basepath;
|
||||
}
|
||||
|
||||
}, {
|
||||
title: '创建人',
|
||||
dataIndex: 'owner',
|
||||
@ -66,7 +71,7 @@ const getColumns = (data, props) => {
|
||||
<span>
|
||||
<a onClick={() => changeUpdateModal(true, index)}>修改</a>
|
||||
<span className="ant-divider" />
|
||||
<Popconfirm title="你确定要删除项目吗?" onConfirm={deleteConfirm(id, props)} okText="删除" cancelText="取消">
|
||||
<Popconfirm title="你确定要删除项目吗?" onConfirm={deleteConfirm(id, props)} okText="确定" cancelText="取消">
|
||||
<a href="#">删除</a>
|
||||
</Popconfirm>
|
||||
</span>
|
||||
|
@ -1,9 +1,8 @@
|
||||
.m-container{
|
||||
background-color: #fff;
|
||||
padding: 16px 24px;
|
||||
padding: 24px;
|
||||
box-shadow: 0 2px 4px 0 rgba(0,0,0,0.20);
|
||||
border-radius: 4px;
|
||||
text-align: right;
|
||||
}
|
||||
|
||||
.m-table {
|
||||
|
@ -39,7 +39,7 @@ class LeftMenu extends Component {
|
||||
this.interval = setInterval(() => {
|
||||
if (this.searchSign === this._searchSign) {
|
||||
this.interval = clearInterval(this.interval)
|
||||
axios.get('/user/search?q=' + value).then((res) => {
|
||||
axios.get('/user/search?q=' + value).then((res) => {
|
||||
if (res.data.errcode === 0) {
|
||||
this.setState({
|
||||
dataSource: res.data.data
|
||||
@ -83,7 +83,7 @@ class LeftMenu extends Component {
|
||||
const { dataSource } = this.state;
|
||||
return (<div className="user-list">
|
||||
<div className='cur-user'>
|
||||
<div className='user-name'><span>用户名 : </span>{`${this.props.curUserName}`}</div>
|
||||
<div className='user-name'><span>用户名 :</span>{`${this.props.curUserName}`}</div>
|
||||
</div>
|
||||
<Row type="flex" justify="start" className="search">
|
||||
<Col span="24">
|
||||
@ -103,7 +103,7 @@ class LeftMenu extends Component {
|
||||
</div>
|
||||
</Col>
|
||||
</Row>
|
||||
<Menu mode='inline' defaultSelectedKeys={[location.hash]}>
|
||||
<Menu mode='inline' defaultSelectedKeys={[location.hash]} className="user-nav">
|
||||
{content}
|
||||
</Menu>
|
||||
</div>
|
||||
@ -111,4 +111,4 @@ class LeftMenu extends Component {
|
||||
}
|
||||
}
|
||||
|
||||
export default LeftMenu
|
||||
export default LeftMenu
|
||||
|
@ -108,7 +108,7 @@ class List extends Component {
|
||||
<span>
|
||||
<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 title="确认删除此用户?" onConfirm={() => {this.confirm(item._id)}} okText="确定" cancelText="取消">
|
||||
<a href="#">删除</a>
|
||||
</Popconfirm>
|
||||
</span>
|
||||
|
@ -22,7 +22,7 @@ class Profile extends Component {
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
|
||||
componentDidMount(){
|
||||
@ -51,7 +51,7 @@ class Profile extends Component {
|
||||
let value = this.state._userinfo[name];
|
||||
let params = {uid: state.userinfo.uid}
|
||||
params[name] = value;
|
||||
|
||||
|
||||
axios.post('/user/update', params).then( (res)=>{
|
||||
let data = res.data;
|
||||
if(data.errcode === 0){
|
||||
@ -66,7 +66,7 @@ class Profile extends Component {
|
||||
}else{
|
||||
message.error(data.errmsg)
|
||||
}
|
||||
|
||||
|
||||
}, (err) => {
|
||||
message.error(err.message)
|
||||
} )
|
||||
@ -104,8 +104,8 @@ class Profile extends Component {
|
||||
password: password,
|
||||
old_password: old_password
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
axios.post('/user/change_password', params).then( (res)=>{
|
||||
let data = res.data;
|
||||
if(data.errcode === 0){
|
||||
@ -114,11 +114,11 @@ class Profile extends Component {
|
||||
}else{
|
||||
message.error(data.errmsg)
|
||||
}
|
||||
|
||||
|
||||
}, (err) => {
|
||||
message.error(err.message)
|
||||
} )
|
||||
|
||||
|
||||
}
|
||||
|
||||
render() {
|
||||
@ -132,14 +132,14 @@ class Profile extends Component {
|
||||
userNameEditHtml = <div >
|
||||
<span className="text">{userinfo.username}</span>
|
||||
{/*<span className="text-button" onClick={() => { this.handleEdit('usernameEdit', true) }}><Icon type="edit" />修改</span>*/}
|
||||
<Button size={'small'} icon="edit" onClick={() => { this.handleEdit('usernameEdit', true) }}>修改</Button>
|
||||
<Button icon="edit" onClick={() => { this.handleEdit('usernameEdit', true) }}>修改</Button>
|
||||
</div>
|
||||
} else {
|
||||
userNameEditHtml = <div>
|
||||
<Input value={_userinfo.username} name="username" onChange={this.changeUserinfo} placeholder="用户名" />
|
||||
<ButtonGroup className="edit-buttons" >
|
||||
<Button size={'small'} className="edit-button" onClick={() => { this.handleEdit('usernameEdit', false) }} >Cancel</Button>
|
||||
<Button size={'small'} className="edit-button" onClick={ () => { this.updateUserinfo('username')} } type="primary">OK</Button>
|
||||
<Button className="edit-button" onClick={() => { this.handleEdit('usernameEdit', false) }} >取消</Button>
|
||||
<Button className="edit-button" onClick={ () => { this.updateUserinfo('username')} } type="primary">确定</Button>
|
||||
</ButtonGroup>
|
||||
</div>
|
||||
}
|
||||
@ -148,14 +148,14 @@ class Profile extends Component {
|
||||
emailEditHtml = <div >
|
||||
<span className="text">{userinfo.email}</span>
|
||||
{/*<span className="text-button" onClick={() => { this.handleEdit('emailEdit', true) }} ><Icon type="edit" />修改</span>*/}
|
||||
<Button size={'small'} icon="edit" onClick={() => { this.handleEdit('emailEdit', true) }}>修改</Button>
|
||||
<Button icon="edit" onClick={() => { this.handleEdit('emailEdit', true) }}>修改</Button>
|
||||
</div>
|
||||
} else {
|
||||
emailEditHtml = <div>
|
||||
<Input placeholder="Email" value={_userinfo.email} name="email" onChange={this.changeUserinfo} />
|
||||
<ButtonGroup className="edit-buttons" >
|
||||
<Button size={'small'} className="edit-button" onClick={() => { this.handleEdit('emailEdit', false) }} >Cancel</Button>
|
||||
<Button size={'small'} className="edit-button" type="primary" onClick={ () => { this.updateUserinfo('email')} }>OK</Button>
|
||||
<Button className="edit-button" onClick={() => { this.handleEdit('emailEdit', false) }} >取消</Button>
|
||||
<Button className="edit-button" type="primary" onClick={ () => { this.updateUserinfo('email')} }>确定</Button>
|
||||
</ButtonGroup>
|
||||
</div>
|
||||
}
|
||||
@ -164,7 +164,7 @@ class Profile extends Component {
|
||||
roleEditHtml = <div>
|
||||
<span className="text">{roles[userinfo.role]}</span>
|
||||
{/*<span className="text-button" onClick={() => { this.handleEdit('roleEdit', true) }} ><Icon type="edit" />修改</span>*/}
|
||||
<Button size={'small'} icon="edit" onClick={() => { this.handleEdit('roleEdit', true) }}>修改</Button>
|
||||
<Button icon="edit" onClick={() => { this.handleEdit('roleEdit', true) }}>修改</Button>
|
||||
</div>
|
||||
} else {
|
||||
roleEditHtml = <Select defaultValue={_userinfo.role} onChange={ this.changeRole} style={{ width: 150 }} >
|
||||
@ -175,15 +175,15 @@ class Profile extends Component {
|
||||
}
|
||||
|
||||
if (this.state.secureEdit === false) {
|
||||
secureEditHtml = <Button size={'small'} icon="edit" onClick={() => { this.handleEdit('secureEdit', true) }}>修改</Button>
|
||||
secureEditHtml = <Button icon="edit" onClick={() => { this.handleEdit('secureEdit', true) }}>修改</Button>
|
||||
} else {
|
||||
secureEditHtml = <div>
|
||||
<Input style={{display: this.state.userinfo.role === 'admin' ? 'none': ''}} placeholder="旧的密码" type="password" name="old_password" id="old_password" />
|
||||
<Input placeholder="新的密码" type="password" name="password" id="password" />
|
||||
<Input placeholder="确认密码" type="password" name="verify_pass" id="verify_pass" />
|
||||
<ButtonGroup className="edit-buttons" >
|
||||
<Button size={'small'} className="edit-button" onClick={() => { this.handleEdit('secureEdit', false) }}>Cancel</Button>
|
||||
<Button size={'small'} className="edit-button" onClick={this.updatePassword} type="primary">OK</Button>
|
||||
<Button className="edit-button" onClick={() => { this.handleEdit('secureEdit', false) }}>取消</Button>
|
||||
<Button className="edit-button" onClick={this.updatePassword} type="primary">确定</Button>
|
||||
</ButtonGroup>
|
||||
</div>
|
||||
}
|
||||
|
@ -6,6 +6,7 @@ import LeftMenu from './LeftMenu.js'
|
||||
import List from './List.js'
|
||||
import PropTypes from 'prop-types'
|
||||
import Profile from './Profile.js'
|
||||
import { Row, Col } from 'antd';
|
||||
|
||||
@connect()
|
||||
class User extends Component {
|
||||
@ -22,19 +23,22 @@ class User extends Component {
|
||||
}
|
||||
|
||||
render () {
|
||||
|
||||
|
||||
|
||||
|
||||
return (
|
||||
<div>
|
||||
<section className="user-box">
|
||||
|
||||
<LeftMenu />
|
||||
<Route path={this.props.match.path + '/list'} component={List} />
|
||||
<Route path={this.props.match.path + '/profile/:uid'} component={Profile} />
|
||||
</section>
|
||||
<div className="g-doc">
|
||||
<Row gutter={16} className="user-box">
|
||||
<Col span={6}>
|
||||
<LeftMenu />
|
||||
</Col>
|
||||
<Col span={18}>
|
||||
<Route path={this.props.match.path + '/list'} component={List} />
|
||||
<Route path={this.props.match.path + '/profile/:uid'} component={Profile} />
|
||||
</Col>
|
||||
</Row>
|
||||
</div>
|
||||
)
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
export default User
|
||||
export default User
|
||||
|
@ -1,5 +1,10 @@
|
||||
@import '../../styles/mixin.scss';
|
||||
|
||||
.g-doc {
|
||||
margin: .24rem auto;
|
||||
min-height: 5rem;
|
||||
}
|
||||
|
||||
/* .user-box.css */
|
||||
.user-box {
|
||||
@include row-width-limit;
|
||||
@ -15,10 +20,9 @@
|
||||
|
||||
|
||||
.user-list {
|
||||
width: 216px;
|
||||
box-shadow: 0 2px 4px 0 rgba(0,0,0,0.20);
|
||||
background: #FFF;
|
||||
border-radius:5px;
|
||||
border-radius:4px;
|
||||
margin-top: 15px;
|
||||
.search{
|
||||
padding: 5px;
|
||||
@ -30,15 +34,15 @@
|
||||
}
|
||||
}
|
||||
.user-name{
|
||||
padding: 24px 0px;
|
||||
text-align: center;
|
||||
padding: .24rem;
|
||||
// text-align: center;
|
||||
background-color: #34495e;
|
||||
color: white;
|
||||
font-size: 16px;
|
||||
border-top-left-radius:5px;
|
||||
border-top-right-radius: 5px;
|
||||
border-top-left-radius: 4px;
|
||||
border-top-right-radius: 4px;
|
||||
span{
|
||||
margin-right: 10px;
|
||||
margin-right: 5px;
|
||||
}
|
||||
}
|
||||
.router-content{
|
||||
@ -47,8 +51,7 @@
|
||||
.user-table {
|
||||
-webkit-box-flex: 1;
|
||||
padding: 24px;
|
||||
margin-left: 15px;
|
||||
border-radius:5px;
|
||||
border-radius: 4px;
|
||||
box-shadow: 0 2px 4px 0 rgba(0,0,0,0.20);
|
||||
background: #FFF;
|
||||
margin-top: 15px;
|
||||
@ -65,35 +68,38 @@
|
||||
.user-profile {
|
||||
-webkit-box-flex: 1;
|
||||
margin-top: 15px;
|
||||
margin-left: 15px;
|
||||
padding: 24px;
|
||||
box-shadow: 0 2px 4px 0 rgba(0,0,0,0.20);
|
||||
background: #FFF;
|
||||
border-radius:5px;
|
||||
.ant-btn-group{
|
||||
margin-top: 12px;
|
||||
}
|
||||
border-radius: .04rem;
|
||||
.user-item {
|
||||
min-height:35px;
|
||||
line-height:35px;
|
||||
margin: 5px;
|
||||
margin-left: 0px;
|
||||
margin-bottom:10px;
|
||||
margin-bottom: 16px;
|
||||
border-bottom: 1px solid #f1f3f6;
|
||||
padding-bottom: 10px;
|
||||
padding-bottom: 16px;
|
||||
#old_password,#password,#verify_pass{
|
||||
margin-top: 20px;
|
||||
}
|
||||
#old_password{
|
||||
margin-top: 0px;
|
||||
}
|
||||
.ant-col-12{
|
||||
.ant-input{
|
||||
width: 60%;
|
||||
margin-right: 16px;
|
||||
}
|
||||
}
|
||||
.ant-col-4{
|
||||
color: black;
|
||||
padding: 0px 10px;
|
||||
color: rgba(0,0,0,0.85);
|
||||
padding: 0px 16px;
|
||||
text-indent: .7em;
|
||||
// background-color: #f1f3f6;
|
||||
border-left: 5px solid #f1f3f6;
|
||||
border-left: 4px solid #f1f3f6;
|
||||
margin-right: 30px;
|
||||
white-space: nowrap;
|
||||
}
|
||||
.text{
|
||||
padding-right: 15px;
|
||||
@ -103,16 +109,11 @@
|
||||
color: #657289;
|
||||
cursor: pointer
|
||||
}
|
||||
|
||||
// .edit-buttons{
|
||||
// margin:10px;
|
||||
// }
|
||||
|
||||
// .edit-button{
|
||||
// margin: 5px;
|
||||
// }
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
.user-nav {
|
||||
border-bottom-left-radius: .04rem;
|
||||
border-bottom-right-radius: .04rem;
|
||||
}
|
||||
}
|
||||
|
@ -3,14 +3,16 @@ import {
|
||||
LIST_INTERFACE_CLICK,
|
||||
PROJECT_MEMBER_INTERFACE,
|
||||
DELETE_INTERFACE_DATA,
|
||||
SAVE_INTERFACE_PROJECT_ID
|
||||
SAVE_INTERFACE_PROJECT_ID,
|
||||
GET_INTERFACE_GROUP_LIST
|
||||
} from '../../constants/action-types.js'
|
||||
|
||||
const initialState = {
|
||||
interfaceData: [],
|
||||
modalVisible: false,
|
||||
interfaceName: '',
|
||||
projectId: ''
|
||||
projectId: '',
|
||||
memberList: []
|
||||
}
|
||||
|
||||
export default (state = initialState, action) => {
|
||||
@ -40,6 +42,11 @@ export default (state = initialState, action) => {
|
||||
...state,
|
||||
projectId: action.payload
|
||||
}
|
||||
case GET_INTERFACE_GROUP_LIST:
|
||||
return {
|
||||
...state,
|
||||
projectId: action.payload
|
||||
}
|
||||
default:
|
||||
return state
|
||||
}
|
||||
|
@ -26,7 +26,8 @@ export default (state = initialState, action) => {
|
||||
isLogin: (action.payload.data.errcode == 0),
|
||||
loginState: (action.payload.data.errcode == 0)?MEMBER_STATUS:GUEST_STATUS,
|
||||
userName: action.payload.data.data ? action.payload.data.data.username : null,
|
||||
uid: action.payload.data.data ? action.payload.data.data._id : null
|
||||
uid: action.payload.data.data ? action.payload.data.data._id : null,
|
||||
server_ip: action.payload.data.data ? action.payload.data.data.server_ip:null
|
||||
};
|
||||
}
|
||||
case LOGIN: {
|
||||
@ -36,7 +37,8 @@ export default (state = initialState, action) => {
|
||||
isLogin: true,
|
||||
loginState: MEMBER_STATUS,
|
||||
uid: action.payload.data.data.uid,
|
||||
userName: action.payload.data.data.username
|
||||
userName: action.payload.data.data.username,
|
||||
server_ip: action.payload.data.data.server_ip
|
||||
};
|
||||
} else {
|
||||
return state;
|
||||
|
@ -3,14 +3,16 @@ import {
|
||||
LIST_INTERFACE_CLICK,
|
||||
PROJECT_MEMBER_INTERFACE,
|
||||
DELETE_INTERFACE_DATA,
|
||||
SAVE_INTERFACE_PROJECT_ID
|
||||
SAVE_INTERFACE_PROJECT_ID,
|
||||
GET_INTERFACE_GROUP_LIST
|
||||
} from '../../constants/action-types.js'
|
||||
|
||||
const initialState = {
|
||||
interfaceData: [],
|
||||
modalVisible: false,
|
||||
interfaceName: '',
|
||||
projectId: ''
|
||||
projectId: '',
|
||||
memberList: []
|
||||
}
|
||||
|
||||
export default (state = initialState, action) => {
|
||||
@ -40,6 +42,11 @@ export default (state = initialState, action) => {
|
||||
...state,
|
||||
projectId: action.payload
|
||||
}
|
||||
case GET_INTERFACE_GROUP_LIST:
|
||||
return {
|
||||
...state,
|
||||
projectId: action.payload
|
||||
}
|
||||
default:
|
||||
return state
|
||||
}
|
||||
|
@ -26,7 +26,8 @@ export default (state = initialState, action) => {
|
||||
isLogin: (action.payload.data.errcode == 0),
|
||||
loginState: (action.payload.data.errcode == 0)?MEMBER_STATUS:GUEST_STATUS,
|
||||
userName: action.payload.data.data ? action.payload.data.data.username : null,
|
||||
uid: action.payload.data.data ? action.payload.data.data._id : null
|
||||
uid: action.payload.data.data ? action.payload.data.data._id : null,
|
||||
server_ip: action.payload.data.data ? action.payload.data.data.server_ip:null
|
||||
};
|
||||
}
|
||||
case LOGIN: {
|
||||
@ -36,7 +37,8 @@ export default (state = initialState, action) => {
|
||||
isLogin: true,
|
||||
loginState: MEMBER_STATUS,
|
||||
uid: action.payload.data.data.uid,
|
||||
userName: action.payload.data.data.username
|
||||
userName: action.payload.data.data.username,
|
||||
server_ip: action.payload.data.data.server_ip
|
||||
};
|
||||
} else {
|
||||
return state;
|
||||
|
@ -4,5 +4,5 @@
|
||||
}
|
||||
|
||||
@mixin wrap-width-limit {
|
||||
min-width: 10.7rem;
|
||||
min-width: 9.7rem;
|
||||
}
|
||||
|
21
config.json
Normal file
21
config.json
Normal file
@ -0,0 +1,21 @@
|
||||
{
|
||||
"port": "3000",
|
||||
"webhost": "yapi.local.qunar.com",
|
||||
"adminAccount": "admin@admin.com",
|
||||
"db": {
|
||||
"servername": "10.86.40.194",
|
||||
"DATABASE": "yapi",
|
||||
"port": 27017,
|
||||
"user": "test1",
|
||||
"pass": "test1",
|
||||
"server_ip": "192.222.193.50"
|
||||
},
|
||||
"mail": {
|
||||
"host": "smtp.163.com",
|
||||
"port": 465,
|
||||
"auth": {
|
||||
"user": "hellosean1025@163.com",
|
||||
"pass": "helloqunar123"
|
||||
}
|
||||
}
|
||||
}
|
@ -1,6 +1,7 @@
|
||||
{
|
||||
"port": "3000",
|
||||
"webhost": "yapi.local.qunar.com",
|
||||
"server_ip": "192.168.1.1",
|
||||
"adminAccount": "admin@admin.com",
|
||||
"db": {
|
||||
"servername": "127.0.0.1",
|
||||
|
16
gulpfile.js
16
gulpfile.js
@ -11,6 +11,8 @@ const DIST = 'server_dist/';
|
||||
const SRC = 'server/**/*.js';
|
||||
|
||||
function generateBabel(status) {
|
||||
|
||||
// 返回一个新的 babel 插件
|
||||
const babelProcess = babel({
|
||||
presets: ['es2015', 'stage-3'],
|
||||
plugins: ['transform-runtime']
|
||||
@ -43,6 +45,9 @@ function excuteCmd(cmd, args, opts) {
|
||||
|
||||
output('log', `${NAME} ${message}`, true);
|
||||
|
||||
// ykit 成功编译时会输出带有 build complete 字样的 log
|
||||
// 此时停止正在编译的提示
|
||||
// 换为等待文件变更的提示
|
||||
if (~message.indexOf('building complete')) {
|
||||
waitingSpinner();
|
||||
}
|
||||
@ -102,14 +107,22 @@ gulp.task('initialBuild', ['removeDist'], () => {
|
||||
});
|
||||
|
||||
gulp.task('default', ['initialBuild'], () => {
|
||||
|
||||
// 若 client/ 下的文件发生变动则显示正在编译的提示
|
||||
// 并在编译完成之后停止
|
||||
gulp.watch('client/**/*', event => {
|
||||
spinner.stop();
|
||||
spinner = ora(`正在编译 ${event.path}`).start();
|
||||
});
|
||||
|
||||
gulp.watch(SRC, event => {
|
||||
|
||||
// 获取变更文件相对于 server/ 的路径
|
||||
// 此路径用于 gulp.dest() 写入新文件
|
||||
let originFilePath = path.relative(path.join(__dirname, 'server'), event.path);
|
||||
let distPath = path.resolve(DIST, path.join(originFilePath));
|
||||
|
||||
// 编译提示
|
||||
spinner.text = `正在编译 ${event.path}...`;
|
||||
|
||||
gulp.src(event.path).pipe(generateBabel())
|
||||
@ -121,12 +134,14 @@ gulp.task('default', ['initialBuild'], () => {
|
||||
});
|
||||
});
|
||||
|
||||
// 全量编译后端代码
|
||||
gulp.task('buildNode', () => {
|
||||
return gulp.src(SRC)
|
||||
.pipe(generateBabel())
|
||||
.pipe(gulp.dest(DIST));
|
||||
});
|
||||
|
||||
// 仅监测后端代码并实时编译
|
||||
gulp.task('watchNode', ['buildNode'], () => {
|
||||
return watch(SRC, {
|
||||
verbose: true,
|
||||
@ -136,6 +151,7 @@ gulp.task('watchNode', ['buildNode'], () => {
|
||||
.pipe(gulp.dest(DIST));
|
||||
});
|
||||
|
||||
// 编译前后端
|
||||
gulp.task('build', () => {
|
||||
let status = {
|
||||
count: 0
|
||||
|
@ -4,7 +4,6 @@ yapi.commons = commons;
|
||||
import dbModule from './utils/db.js';
|
||||
import mockServer from './middleware/mockServer.js';
|
||||
import Koa from 'koa';
|
||||
import convert from 'koa-convert';
|
||||
import koaStatic from 'koa-static';
|
||||
import bodyParser from 'koa-bodyparser';
|
||||
import router from './router.js';
|
||||
|
@ -60,7 +60,9 @@ class baseController {
|
||||
|
||||
async getLoginStatus(ctx) {
|
||||
if (await this.checkLogin(ctx) === true) {
|
||||
return ctx.body = yapi.commons.resReturn(yapi.commons.fieldSelect(this.$user, ['_id', 'username', 'email', 'up_time', 'add_time']));
|
||||
let result = yapi.commons.fieldSelect(this.$user, ['_id', 'username', 'email', 'up_time', 'add_time']);
|
||||
result.server_ip = yapi.WEBCONFIG.server_ip;
|
||||
return ctx.body = yapi.commons.resReturn(result);
|
||||
}
|
||||
return ctx.body = yapi.commons.resReturn(null, 300, 'Please login.');
|
||||
}
|
||||
|
@ -1,10 +1,10 @@
|
||||
import interfaceModel from '../models/interface.js'
|
||||
import baseController from './base.js'
|
||||
import yapi from '../yapi.js'
|
||||
import interfaceModel from '../models/interface.js';
|
||||
import baseController from './base.js';
|
||||
import yapi from '../yapi.js';
|
||||
|
||||
class interfaceController extends baseController{
|
||||
constructor(ctx){
|
||||
super(ctx)
|
||||
class interfaceController extends baseController {
|
||||
constructor(ctx) {
|
||||
super(ctx);
|
||||
this.Model = yapi.getInst(interfaceModel);
|
||||
}
|
||||
|
||||
@ -35,37 +35,39 @@ class interfaceController extends baseController{
|
||||
* @returns {Object}
|
||||
* @example ./api/interface/add.json
|
||||
*/
|
||||
async add(ctx){
|
||||
async add(ctx) {
|
||||
let params = ctx.request.body;
|
||||
|
||||
params = yapi.commons.handleParams(params, {
|
||||
project_id: 'number',
|
||||
title: 'string',
|
||||
path: 'string',
|
||||
method: 'string',
|
||||
desc: 'string'
|
||||
})
|
||||
});
|
||||
params.method = params.method || 'GET';
|
||||
params.method = params.method.toUpperCase()
|
||||
params.method = params.method.toUpperCase();
|
||||
params.res_body_type = params.res_body_type ? params.res_body_type.toLowerCase() : 'json';
|
||||
if(!params.project_id){
|
||||
|
||||
if (!params.project_id) {
|
||||
return ctx.body = yapi.commons.resReturn(null, 400, '项目id不能为空');
|
||||
}
|
||||
|
||||
if(!params.path){
|
||||
if (!params.path) {
|
||||
return ctx.body = yapi.commons.resReturn(null, 400, '接口请求路径不能为空');
|
||||
}
|
||||
|
||||
if(!yapi.commons.verifyPath(params.path)){
|
||||
return ctx.body = yapi.commons.resReturn(null, 400, '接口path第一位必须是/,最后一位不能为/')
|
||||
if (!yapi.commons.verifyPath(params.path)) {
|
||||
return ctx.body = yapi.commons.resReturn(null, 400, '接口path第一位必须是/,最后一位不能为/');
|
||||
}
|
||||
|
||||
|
||||
let checkRepeat = await this.Model.checkRepeat(params.project_id, params.path, params.method);
|
||||
|
||||
if(checkRepeat > 0){
|
||||
return ctx.body = yapi.commons.resReturn(null, 401, '已存在的接口:' + params.path + '[' + params.method + ']');
|
||||
}
|
||||
if (checkRepeat > 0) {
|
||||
return ctx.body = yapi.commons.resReturn(null, 401, '已存在的接口:' + params.path + '[' + params.method + ']');
|
||||
}
|
||||
|
||||
try{
|
||||
try {
|
||||
let data = {
|
||||
project_id: params.project_id,
|
||||
title: params.title,
|
||||
@ -74,20 +76,24 @@ class interfaceController extends baseController{
|
||||
method: params.method,
|
||||
req_headers: params.req_headers,
|
||||
req_params_type: params.req_params_type,
|
||||
res_body: params.res_body,
|
||||
res_body: params.res_body,
|
||||
res_body_type: params.res_body_type,
|
||||
uid: this.getUid(),
|
||||
add_time: yapi.commons.time(),
|
||||
up_time: yapi.commons.time()
|
||||
};
|
||||
|
||||
if (params.req_params_form) {
|
||||
data.req_params_form = params.req_params_form;
|
||||
}
|
||||
if (params.req_params_other) {
|
||||
data.req_params_other = params.req_params_other;
|
||||
}
|
||||
|
||||
if(params.req_params_form) data.req_params_form = params.req_params_form;
|
||||
if(params.req_params_other) data.req_params_other = params.req_params_other;
|
||||
|
||||
let result = await this.Model.save(data);
|
||||
ctx.body = yapi.commons.resReturn(result);
|
||||
}catch(e){
|
||||
ctx.body = yapi.commons.resReturn(null, 402, e.message)
|
||||
} catch (e) {
|
||||
ctx.body = yapi.commons.resReturn(null, 402, e.message);
|
||||
}
|
||||
}
|
||||
|
||||
@ -101,16 +107,18 @@ class interfaceController extends baseController{
|
||||
* @returns {Object}
|
||||
* @example ./api/interface/get.json
|
||||
*/
|
||||
async get(ctx){
|
||||
async get(ctx) {
|
||||
let params = ctx.request.query;
|
||||
if(!params.id){
|
||||
|
||||
if (!params.id) {
|
||||
return ctx.body = yapi.commons.resReturn(null, 400, '接口id不能为空');
|
||||
}
|
||||
try{
|
||||
|
||||
try {
|
||||
let result = await this.Model.get(params.id);
|
||||
ctx.body = yapi.commons.resReturn(result);
|
||||
}catch(e){
|
||||
ctx.body = yapi.commons.resReturn(null, 402, e.message)
|
||||
} catch (e) {
|
||||
ctx.body = yapi.commons.resReturn(null, 402, e.message);
|
||||
}
|
||||
}
|
||||
|
||||
@ -124,17 +132,18 @@ class interfaceController extends baseController{
|
||||
* @returns {Object}
|
||||
* @example ./api/interface/list.json
|
||||
*/
|
||||
|
||||
async list(ctx){
|
||||
async list(ctx) {
|
||||
let project_id = ctx.request.query.project_id;
|
||||
if(!project_id){
|
||||
|
||||
if (!project_id) {
|
||||
return ctx.body = yapi.commons.resReturn(null, 400, '项目id不能为空');
|
||||
}
|
||||
try{
|
||||
|
||||
try {
|
||||
let result = await this.Model.list(project_id);
|
||||
ctx.body = yapi.commons.resReturn(result)
|
||||
}catch(err){
|
||||
ctx.body = yapi.commons.resReturn(null, 402, e.message)
|
||||
ctx.body = yapi.commons.resReturn(result);
|
||||
} catch (err) {
|
||||
ctx.body = yapi.commons.resReturn(null, 402, err.message);
|
||||
}
|
||||
}
|
||||
|
||||
@ -165,55 +174,76 @@ class interfaceController extends baseController{
|
||||
* @example ./api/interface/up.json
|
||||
*/
|
||||
|
||||
async up(ctx){
|
||||
async up(ctx) {
|
||||
let params = ctx.request.body;
|
||||
|
||||
params = yapi.commons.handleParams(params, {
|
||||
title: 'string',
|
||||
path: 'string',
|
||||
method: 'string',
|
||||
desc: 'string'
|
||||
})
|
||||
});
|
||||
params.method = params.method || 'GET';
|
||||
params.method = params.method.toUpperCase()
|
||||
params.method = params.method.toUpperCase();
|
||||
|
||||
let id = ctx.request.body.id;
|
||||
if(!id){
|
||||
|
||||
if (!id) {
|
||||
return ctx.body = yapi.commons.resReturn(null, 400, '接口id不能为空');
|
||||
}
|
||||
let interfaceData = await this.Model.get(id);
|
||||
|
||||
if(params.path && !yapi.commons.verifyPath(params.path)){
|
||||
return ctx.body = yapi.commons.resReturn(null, 400, '接口path第一位必须是/,最后一位不能为/')
|
||||
if (params.path && !yapi.commons.verifyPath(params.path)) {
|
||||
return ctx.body = yapi.commons.resReturn(null, 400, '接口path第一位必须是/,最后一位不能为/');
|
||||
}
|
||||
|
||||
if(params.path && params.path !== interfaceData.path && params.method !== interfaceData.method){
|
||||
let checkRepeat = await this.Model.checkRepeat(interfaceData.project_id,params.path, params.method);
|
||||
if(checkRepeat > 0){
|
||||
return ctx.body = yapi.commons.resReturn(null, 401, '已存在的接口:' + params.path + '[' + params.method + ']');
|
||||
|
||||
if (params.path && params.path !== interfaceData.path && params.method !== interfaceData.method) {
|
||||
let checkRepeat = await this.Model.checkRepeat(interfaceData.project_id, params.path, params.method);
|
||||
if (checkRepeat > 0) {
|
||||
return ctx.body = yapi.commons.resReturn(null, 401, '已存在的接口:' + params.path + '[' + params.method + ']');
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
let data = {
|
||||
up_time: yapi.commons.time()
|
||||
};
|
||||
|
||||
if (params.path) {
|
||||
data.path = params.path;
|
||||
}
|
||||
if (params.title) {
|
||||
data.title = params.title;
|
||||
}
|
||||
if (params.desc) {
|
||||
data.desc = params.desc;
|
||||
}
|
||||
if (params.method) {
|
||||
data.method = params.method;
|
||||
}
|
||||
|
||||
if(params.path) data.path = params.path;
|
||||
if(params.title) data.title = params.title;
|
||||
if(params.desc) data.desc = params.desc;
|
||||
if(params.method) data.method = params.method;
|
||||
if (params.req_headers) {
|
||||
data.req_headers = params.req_headers;
|
||||
}
|
||||
|
||||
if(params.req_headers) data.req_headers = params.req_headers;
|
||||
if (params.req_params_form) {
|
||||
data.req_params_form = params.req_params_form;
|
||||
}
|
||||
if (params.req_params_other) {
|
||||
data.req_params_other = params.req_params_other;
|
||||
}
|
||||
|
||||
if(params.req_params_form) data.req_params_form = params.req_params_form;
|
||||
if(params.req_params_other) data.req_params_other = params.req_params_other;
|
||||
|
||||
if(params.res_body_type) data.res_body_type = params.res_body_type;
|
||||
if(params.res_body) data.res_body = params.res_body;
|
||||
if (params.res_body_type) {
|
||||
data.res_body_type = params.res_body_type;
|
||||
}
|
||||
if (params.res_body) {
|
||||
data.res_body = params.res_body;
|
||||
}
|
||||
|
||||
try{
|
||||
try {
|
||||
let result = await this.Model.up(id, data);
|
||||
ctx.body = yapi.commons.resReturn(result)
|
||||
}catch(e){
|
||||
ctx.body = yapi.commons.resReturn(null, 402, e.message)
|
||||
ctx.body = yapi.commons.resReturn(result);
|
||||
} catch (e) {
|
||||
ctx.body = yapi.commons.resReturn(null, 402, e.message);
|
||||
}
|
||||
|
||||
}
|
||||
@ -229,27 +259,27 @@ class interfaceController extends baseController{
|
||||
* @example ./api/interface/del.json
|
||||
*/
|
||||
|
||||
async del(ctx){
|
||||
try{
|
||||
let id = ctx.request.body.id;
|
||||
|
||||
if(!id){
|
||||
async del(ctx) {
|
||||
try {
|
||||
let id = ctx.request.body.id;
|
||||
|
||||
if (!id) {
|
||||
return ctx.body = yapi.commons.resReturn(null, 400, '接口id不能为空');
|
||||
}
|
||||
|
||||
let data = await this.Model.get(ctx.request.body.id);
|
||||
|
||||
if(data.uid != this.getUid()){
|
||||
if(await this.jungeProjectAuth(data.project_id) !== true){
|
||||
if (data.uid != this.getUid()) {
|
||||
if (await this.jungeProjectAuth(data.project_id) !== true) {
|
||||
return ctx.body = yapi.commons.resReturn(null, 405, '没有权限');
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
let result = await this.Model.del(id);
|
||||
ctx.body = yapi.commons.resReturn(result)
|
||||
}catch(err){
|
||||
ctx.body = yapi.commons.resReturn(null, 402, err.message)
|
||||
ctx.body = yapi.commons.resReturn(result);
|
||||
} catch (err) {
|
||||
ctx.body = yapi.commons.resReturn(null, 402, err.message);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -28,19 +28,20 @@ class logController extends baseController {
|
||||
page = ctx.request.query.page || 1,
|
||||
limit = ctx.request.query.limit || 10;
|
||||
|
||||
if(!uid){
|
||||
if (!uid) {
|
||||
return ctx.body = yapi.commons.resReturn(null, 400, '用户id不能为空');
|
||||
}
|
||||
|
||||
try {
|
||||
let result = await this.Model.listWithPaging(uid, page, limit);
|
||||
let count = await this.Model.listCount(uid);
|
||||
|
||||
ctx.body = yapi.commons.resReturn({
|
||||
total: Math.ceil(count / limit),
|
||||
list: result
|
||||
})
|
||||
} catch(err) {
|
||||
ctx.body = yapi.commons.resReturn(null, 402, e.message)
|
||||
});
|
||||
} catch (err) {
|
||||
ctx.body = yapi.commons.resReturn(null, 402, err.message);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -1,32 +1,32 @@
|
||||
import projectModel from '../models/project.js'
|
||||
import yapi from '../yapi.js'
|
||||
import baseController from './base.js'
|
||||
import interfaceModel from '../models/interface.js'
|
||||
import groupModel from '../models/group'
|
||||
import commons from '../utils/commons.js'
|
||||
import userModel from '../models/user.js'
|
||||
import projectModel from '../models/project.js';
|
||||
import yapi from '../yapi.js';
|
||||
import baseController from './base.js';
|
||||
import interfaceModel from '../models/interface.js';
|
||||
import groupModel from '../models/group';
|
||||
import commons from '../utils/commons.js';
|
||||
import userModel from '../models/user.js';
|
||||
|
||||
class projectController extends baseController {
|
||||
|
||||
constructor(ctx){
|
||||
super(ctx)
|
||||
constructor(ctx) {
|
||||
super(ctx);
|
||||
this.Model = yapi.getInst(projectModel);
|
||||
this.groupModel = yapi.getInst(groupModel);
|
||||
}
|
||||
|
||||
handleBasepath(basepath){
|
||||
if(!basepath) return false;
|
||||
if(basepath[0] !== '/') basepath = '/' + basepath;
|
||||
if(basepath[basepath.length -1] === '/') basepath = basepath.substr(0, basepath.length -1)
|
||||
if(!yapi.commons.verifyPath(basepath)){
|
||||
handleBasepath(basepath) {
|
||||
if (!basepath) return false;
|
||||
if (basepath[0] !== '/') basepath = '/' + basepath;
|
||||
if (basepath[basepath.length - 1] === '/') basepath = basepath.substr(0, basepath.length - 1);
|
||||
if (!yapi.commons.verifyPath(basepath)) {
|
||||
return false;
|
||||
}
|
||||
return basepath;
|
||||
}
|
||||
|
||||
verifyDomain(domain){
|
||||
if(!domain) return false;
|
||||
if(/^[a-zA-Z0-9\-_\.]+?\.[a-zA-Z0-9\-_\.]*?[a-zA-Z]{2,6}$/.test(domain)){
|
||||
verifyDomain(domain) {
|
||||
if (!domain) return false;
|
||||
if (/^[a-zA-Z0-9\-_\.]+?\.[a-zA-Z0-9\-_\.]*?[a-zA-Z]{2,6}$/.test(domain)) {
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
@ -56,38 +56,40 @@ class projectController extends baseController {
|
||||
protocol: 'string',
|
||||
group_id: 'number',
|
||||
desc: 'string'
|
||||
})
|
||||
if(!params.group_id){
|
||||
});
|
||||
if (!params.group_id) {
|
||||
return ctx.body = yapi.commons.resReturn(null, 400, '项目分组id不能为空');
|
||||
}
|
||||
|
||||
if(!params.name){
|
||||
if (!params.name) {
|
||||
return ctx.body = yapi.commons.resReturn(null, 400, '项目名不能为空');
|
||||
}
|
||||
|
||||
let checkRepeat = await this.Model.checkNameRepeat(params.name);
|
||||
if(checkRepeat > 0){
|
||||
return ctx.body = yapi.commons.resReturn(null, 401, '已存在的项目名');
|
||||
|
||||
if (checkRepeat > 0) {
|
||||
return ctx.body = yapi.commons.resReturn(null, 401, '已存在的项目名');
|
||||
}
|
||||
|
||||
if(!params.basepath){
|
||||
if (!params.basepath) {
|
||||
return ctx.body = yapi.commons.resReturn(null, 400, '项目basepath不能为空');
|
||||
}
|
||||
if(!params.prd_host){
|
||||
if (!params.prd_host) {
|
||||
return ctx.body = yapi.commons.resReturn(null, 400, '项目domain不能为空');
|
||||
}
|
||||
|
||||
if((params.basepath = this.handleBasepath(params.basepath)) === false){
|
||||
return ctx.body = yapi.commons.resReturn(null, 401, 'basepath格式有误')
|
||||
if ((params.basepath = this.handleBasepath(params.basepath)) === false) {
|
||||
return ctx.body = yapi.commons.resReturn(null, 401, 'basepath格式有误');
|
||||
}
|
||||
|
||||
if(!this.verifyDomain(params.prd_host)){
|
||||
return ctx.body = yapi.commons.resReturn(null, 401, '线上域名格式有误')
|
||||
if (!this.verifyDomain(params.prd_host)) {
|
||||
return ctx.body = yapi.commons.resReturn(null, 401, '线上域名格式有误');
|
||||
}
|
||||
|
||||
let checkRepeatDomain = await this.Model.checkDomainRepeat(params.prd_host, params.basepath);
|
||||
if(checkRepeatDomain > 0){
|
||||
return ctx.body = yapi.commons.resReturn(null, 401, '已存在domain和basepath');
|
||||
|
||||
if (checkRepeatDomain > 0) {
|
||||
return ctx.body = yapi.commons.resReturn(null, 401, '已存在domain和basepath');
|
||||
}
|
||||
|
||||
let data = {
|
||||
@ -101,78 +103,78 @@ class projectController extends baseController {
|
||||
group_id: params.group_id,
|
||||
add_time: yapi.commons.time(),
|
||||
up_time: yapi.commons.time()
|
||||
}
|
||||
};
|
||||
|
||||
try{
|
||||
try {
|
||||
let result = await this.Model.save(data);
|
||||
ctx.body = yapi.commons.resReturn(result);
|
||||
}catch(e){
|
||||
ctx.body = yapi.commons.resReturn(null, 402, e.message)
|
||||
} catch (e) {
|
||||
ctx.body = yapi.commons.resReturn(null, 402, e.message);
|
||||
}
|
||||
|
||||
}
|
||||
/**
|
||||
* 添加项目
|
||||
* @interface /project/add_member
|
||||
* @method POST
|
||||
* @category project
|
||||
* @foldnumber 10
|
||||
* @param {Number} id 项目id,不能为空
|
||||
* @param {String} member_uid 项目成员uid,不能为空
|
||||
* @returns {Object}
|
||||
* @example ./api/project/add_member.json
|
||||
*/
|
||||
async addMember(ctx){
|
||||
/**
|
||||
* 添加项目
|
||||
* @interface /project/add_member
|
||||
* @method POST
|
||||
* @category project
|
||||
* @foldnumber 10
|
||||
* @param {Number} id 项目id,不能为空
|
||||
* @param {String} member_uid 项目成员uid,不能为空
|
||||
* @returns {Object}
|
||||
* @example ./api/project/add_member.json
|
||||
*/
|
||||
async addMember(ctx) {
|
||||
let params = ctx.request.body;
|
||||
if(!params.member_uid){
|
||||
if (!params.member_uid) {
|
||||
return ctx.body = yapi.commons.resReturn(null, 400, '项目成员uid不能为空');
|
||||
}
|
||||
if(!params.id){
|
||||
if (!params.id) {
|
||||
return ctx.body = yapi.commons.resReturn(null, 400, '项目id不能为空');
|
||||
}
|
||||
|
||||
var check = await this.Model.checkMemberRepeat(params.id, params.member_uid);
|
||||
if(check > 0){
|
||||
return ctx.body = yapi.commons.resReturn(null, 400, '项目成员已存在');
|
||||
if (check > 0) {
|
||||
return ctx.body = yapi.commons.resReturn(null, 400, '项目成员已存在');
|
||||
}
|
||||
try{
|
||||
try {
|
||||
let result = await this.Model.addMember(params.id, params.member_uid);
|
||||
ctx.body = yapi.commons.resReturn(result);
|
||||
}catch(e){
|
||||
ctx.body = yapi.commons.resReturn(null, 402, e.message)
|
||||
} catch (e) {
|
||||
ctx.body = yapi.commons.resReturn(null, 402, e.message);
|
||||
}
|
||||
|
||||
}
|
||||
/**
|
||||
* 添加项目
|
||||
* @interface /project/del_member
|
||||
* @method POST
|
||||
* @category project
|
||||
* @foldnumber 10
|
||||
* @param {Number} id 项目id,不能为空
|
||||
* @param {member_uid} uid 项目成员uid,不能为空
|
||||
* @returns {Object}
|
||||
* @example ./api/project/del_member.json
|
||||
*/
|
||||
/**
|
||||
* 添加项目
|
||||
* @interface /project/del_member
|
||||
* @method POST
|
||||
* @category project
|
||||
* @foldnumber 10
|
||||
* @param {Number} id 项目id,不能为空
|
||||
* @param {member_uid} uid 项目成员uid,不能为空
|
||||
* @returns {Object}
|
||||
* @example ./api/project/del_member.json
|
||||
*/
|
||||
|
||||
async delMember(ctx){
|
||||
async delMember(ctx) {
|
||||
let params = ctx.request.body;
|
||||
if(!params.member_uid){
|
||||
if (!params.member_uid) {
|
||||
return ctx.body = yapi.commons.resReturn(null, 400, '项目成员uid不能为空');
|
||||
}
|
||||
if(!params.id){
|
||||
if (!params.id) {
|
||||
return ctx.body = yapi.commons.resReturn(null, 400, '项目id不能为空');
|
||||
}
|
||||
var check = await this.Model.checkMemberRepeat(params.id, params.member_uid);
|
||||
if(check === 0){
|
||||
return ctx.body = yapi.commons.resReturn(null, 400, '项目成员不存在');
|
||||
if (check === 0) {
|
||||
return ctx.body = yapi.commons.resReturn(null, 400, '项目成员不存在');
|
||||
}
|
||||
|
||||
try{
|
||||
try {
|
||||
let result = await this.Model.delMember(params.id, params.member_uid);
|
||||
ctx.body = yapi.commons.resReturn(result);
|
||||
}catch(e){
|
||||
ctx.body = yapi.commons.resReturn(null, 402, e.message)
|
||||
} catch (e) {
|
||||
ctx.body = yapi.commons.resReturn(null, 402, e.message);
|
||||
}
|
||||
}
|
||||
|
||||
@ -189,7 +191,7 @@ class projectController extends baseController {
|
||||
|
||||
async getMemberList(ctx) {
|
||||
let params = ctx.request.query;
|
||||
if(!params.id) {
|
||||
if (!params.id) {
|
||||
return ctx.body = yapi.commons.resReturn(null, 400, '项目id不能为空');
|
||||
}
|
||||
|
||||
@ -199,32 +201,32 @@ class projectController extends baseController {
|
||||
let result = await userInst.findByUids(project.members);
|
||||
|
||||
ctx.body = yapi.commons.resReturn(result);
|
||||
} catch(e) {
|
||||
} catch (e) {
|
||||
ctx.body = yapi.commons.resReturn(null, 402, e.message);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 添加项目
|
||||
* @interface /project/get
|
||||
* @method GET
|
||||
* @category project
|
||||
* @foldnumber 10
|
||||
* @param {Number} id 项目id,不能为空
|
||||
* @returns {Object}
|
||||
* @example ./api/project/get.json
|
||||
*/
|
||||
/**
|
||||
* 添加项目
|
||||
* @interface /project/get
|
||||
* @method GET
|
||||
* @category project
|
||||
* @foldnumber 10
|
||||
* @param {Number} id 项目id,不能为空
|
||||
* @returns {Object}
|
||||
* @example ./api/project/get.json
|
||||
*/
|
||||
|
||||
async get(ctx){
|
||||
async get(ctx) {
|
||||
let params = ctx.request.query;
|
||||
if(!params.id){
|
||||
if (!params.id) {
|
||||
return ctx.body = yapi.commons.resReturn(null, 400, '项目id不能为空');
|
||||
}
|
||||
try{
|
||||
try {
|
||||
let result = await this.Model.get(params.id);
|
||||
ctx.body = yapi.commons.resReturn(result);
|
||||
}catch(e){
|
||||
ctx.body = yapi.commons.resReturn(null, 402, e.message)
|
||||
} catch (e) {
|
||||
ctx.body = yapi.commons.resReturn(null, 402, e.message);
|
||||
}
|
||||
}
|
||||
|
||||
@ -246,31 +248,31 @@ class projectController extends baseController {
|
||||
page = ctx.request.query.page || 1,
|
||||
limit = ctx.request.query.limit || 10;
|
||||
|
||||
if(!group_id){
|
||||
if (!group_id) {
|
||||
return ctx.body = yapi.commons.resReturn(null, 400, '项目分组id不能为空');
|
||||
}
|
||||
|
||||
try{
|
||||
try {
|
||||
let result = await this.Model.listWithPaging(group_id, page, limit);
|
||||
let count = await this.Model.listCount(group_id);
|
||||
let uids = [];
|
||||
result.forEach( (item)=> {
|
||||
if(uids.indexOf(item.uid) === -1){
|
||||
uids.push(item.uid)
|
||||
result.forEach((item) => {
|
||||
if (uids.indexOf(item.uid) === -1) {
|
||||
uids.push(item.uid);
|
||||
}
|
||||
|
||||
} )
|
||||
});
|
||||
let _users = {}, users = await yapi.getInst(userModel).findByUids(uids);
|
||||
users.forEach((item)=> {
|
||||
users.forEach((item) => {
|
||||
_users[item._id] = item;
|
||||
} )
|
||||
});
|
||||
ctx.body = yapi.commons.resReturn({
|
||||
total: Math.ceil(count / limit),
|
||||
list: result,
|
||||
userinfo: _users
|
||||
})
|
||||
}catch(e){
|
||||
ctx.body = yapi.commons.resReturn(null, 402, e.message)
|
||||
});
|
||||
} catch (e) {
|
||||
ctx.body = yapi.commons.resReturn(null, 402, e.message);
|
||||
}
|
||||
}
|
||||
|
||||
@ -285,25 +287,25 @@ class projectController extends baseController {
|
||||
* @example ./api/project/del.json
|
||||
*/
|
||||
|
||||
async del(ctx){
|
||||
try{
|
||||
async del(ctx) {
|
||||
try {
|
||||
let id = ctx.request.body.id;
|
||||
if(!id){
|
||||
if (!id) {
|
||||
return ctx.body = yapi.commons.resReturn(null, 400, '项目id不能为空');
|
||||
}
|
||||
let interfaceInst = yapi.getInst(interfaceModel);
|
||||
let count = await interfaceInst.countByProjectId(id);
|
||||
if(count > 0){
|
||||
if (count > 0) {
|
||||
return ctx.body = yapi.commons.resReturn(null, 400, '请先删除该项目下所有接口');
|
||||
}
|
||||
|
||||
if(await this.jungeProjectAuth(id) !== true){
|
||||
if (await this.jungeProjectAuth(id) !== true) {
|
||||
return ctx.body = yapi.commons.resReturn(null, 405, '没有权限');
|
||||
}
|
||||
let result = await this.Model.del(id);
|
||||
ctx.body = yapi.commons.resReturn(result);
|
||||
}catch(err){
|
||||
ctx.body = yapi.commons.resReturn(null, 402, e.message)
|
||||
} catch (err) {
|
||||
ctx.body = yapi.commons.resReturn(null, 402, err.message);
|
||||
}
|
||||
}
|
||||
|
||||
@ -325,8 +327,8 @@ class projectController extends baseController {
|
||||
* @example ./api/project/up.json
|
||||
*/
|
||||
|
||||
async up(ctx){
|
||||
try{
|
||||
async up(ctx) {
|
||||
try {
|
||||
let id = ctx.request.body.id;
|
||||
let params = ctx.request.body;
|
||||
params = yapi.commons.handleParams(params, {
|
||||
@ -336,65 +338,65 @@ class projectController extends baseController {
|
||||
protocol: 'string',
|
||||
group_id: 'number',
|
||||
desc: 'string'
|
||||
})
|
||||
if(!id){
|
||||
});
|
||||
if (!id) {
|
||||
return ctx.body = yapi.commons.resReturn(null, 405, '项目id不能为空');
|
||||
}
|
||||
|
||||
if(await this.jungeMemberAuth(id, this.getUid()) !== true){
|
||||
if (await this.jungeMemberAuth(id, this.getUid()) !== true) {
|
||||
return ctx.body = yapi.commons.resReturn(null, 405, '没有权限');
|
||||
}
|
||||
|
||||
let projectData = await this.Model.get(id);
|
||||
|
||||
if((params.basepath = this.handleBasepath(params.basepath)) === false){
|
||||
return ctx.body = yapi.commons.resReturn(null, 401, 'basepath格式有误')
|
||||
if ((params.basepath = this.handleBasepath(params.basepath)) === false) {
|
||||
return ctx.body = yapi.commons.resReturn(null, 401, 'basepath格式有误');
|
||||
}
|
||||
|
||||
if(!this.verifyDomain(params.prd_host)){
|
||||
return ctx.body = yapi.commons.resReturn(null, 401, '线上域名格式有误')
|
||||
if (!this.verifyDomain(params.prd_host)) {
|
||||
return ctx.body = yapi.commons.resReturn(null, 401, '线上域名格式有误');
|
||||
}
|
||||
|
||||
if(projectData.name === params.name){
|
||||
if (projectData.name === params.name) {
|
||||
delete params.name;
|
||||
}
|
||||
if(projectData.basepath === params.basepath && projectData.prd_host === params.prd_host){
|
||||
delete params.basepath
|
||||
delete params.prd_host
|
||||
if (projectData.basepath === params.basepath && projectData.prd_host === params.prd_host) {
|
||||
delete params.basepath;
|
||||
delete params.prd_host;
|
||||
}
|
||||
|
||||
if(params.name){
|
||||
if (params.name) {
|
||||
let checkRepeat = await this.Model.checkNameRepeat(params.name);
|
||||
if(checkRepeat > 0){
|
||||
return ctx.body = yapi.commons.resReturn(null, 401, '已存在的项目名');
|
||||
if (checkRepeat > 0) {
|
||||
return ctx.body = yapi.commons.resReturn(null, 401, '已存在的项目名');
|
||||
}
|
||||
}
|
||||
|
||||
if(params.basepath && params.prd_host){
|
||||
if (params.basepath && params.prd_host) {
|
||||
let checkRepeatDomain = await this.Model.checkDomainRepeat(params.prd_host, params.basepath);
|
||||
if(checkRepeatDomain > 0){
|
||||
return ctx.body = yapi.commons.resReturn(null, 401, '已存在domain和basepath');
|
||||
if (checkRepeatDomain > 0) {
|
||||
return ctx.body = yapi.commons.resReturn(null, 401, '已存在domain和basepath');
|
||||
}
|
||||
}
|
||||
|
||||
let data= {
|
||||
let data = {
|
||||
uid: this.getUid(),
|
||||
up_time: yapi.commons.time()
|
||||
}
|
||||
};
|
||||
|
||||
if(params.name) data.name = params.name;
|
||||
if(params.desc) data.desc = params.desc;
|
||||
if(params.prd_host && params.basepath){
|
||||
if (params.name) data.name = params.name;
|
||||
if (params.desc) data.desc = params.desc;
|
||||
if (params.prd_host && params.basepath) {
|
||||
data.prd_host = params.prd_host;
|
||||
data.basepath = params.basepath;
|
||||
}
|
||||
if(params.protocol) data.protocol = params.protocol;
|
||||
if(params.env) data.env = params.env;
|
||||
if (params.protocol) data.protocol = params.protocol;
|
||||
if (params.env) data.env = params.env;
|
||||
|
||||
let result = await this.Model.up(id, data);
|
||||
ctx.body = yapi.commons.resReturn(result)
|
||||
}catch(e){
|
||||
ctx.body = yapi.commons.resReturn(null, 402, e.message)
|
||||
ctx.body = yapi.commons.resReturn(result);
|
||||
} catch (e) {
|
||||
ctx.body = yapi.commons.resReturn(null, 402, e.message);
|
||||
}
|
||||
}
|
||||
|
||||
@ -412,11 +414,11 @@ class projectController extends baseController {
|
||||
const { q } = ctx.request.query;
|
||||
|
||||
if (!q) {
|
||||
return ctx.body = yapi.commons.resReturn(void 0, 400, 'No keyword.')
|
||||
return ctx.body = yapi.commons.resReturn(void 0, 400, 'No keyword.');
|
||||
}
|
||||
|
||||
if (!yapi.commons.validateSearchKeyword(q)) {
|
||||
return ctx.body = yapi.commons.resReturn(void 0, 400, 'Bad query.')
|
||||
return ctx.body = yapi.commons.resReturn(void 0, 400, 'Bad query.');
|
||||
}
|
||||
|
||||
let projectList = await this.Model.search(q);
|
||||
@ -436,7 +438,7 @@ class projectController extends baseController {
|
||||
let groupRules = [
|
||||
'_id',
|
||||
'uid',
|
||||
{ key: 'group_name', alias: 'groupName'},
|
||||
{ key: 'group_name', alias: 'groupName' },
|
||||
{ key: 'group_desc', alias: 'groupDesc' },
|
||||
{ key: 'add_time', alias: 'addTime' },
|
||||
{ key: 'up_time', alias: 'upTime' }
|
||||
@ -450,7 +452,7 @@ class projectController extends baseController {
|
||||
group: groupList
|
||||
};
|
||||
|
||||
return ctx.body = yapi.commons.resReturn(queryList, 0, 'ok')
|
||||
return ctx.body = yapi.commons.resReturn(queryList, 0, 'ok');
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -1,15 +1,14 @@
|
||||
import userModel from '../models/user.js'
|
||||
import yapi from '../yapi.js'
|
||||
import baseController from './base.js'
|
||||
import mongoose from 'mongoose'
|
||||
import request from 'request'
|
||||
import common from '../utils/commons.js'
|
||||
import userModel from '../models/user.js';
|
||||
import yapi from '../yapi.js';
|
||||
import baseController from './base.js';
|
||||
import request from 'request';
|
||||
import common from '../utils/commons.js';
|
||||
|
||||
const jwt = require('jsonwebtoken');
|
||||
|
||||
class userController extends baseController {
|
||||
constructor(ctx) {
|
||||
super(ctx)
|
||||
super(ctx);
|
||||
this.Model = yapi.getInst(userModel);
|
||||
}
|
||||
/**
|
||||
@ -41,14 +40,15 @@ class userController extends baseController {
|
||||
if (!result) {
|
||||
return ctx.body = yapi.commons.resReturn(null, 404, '该用户不存在');
|
||||
} else if (yapi.commons.generatePassword(password, result.passsalt) === result.password) {
|
||||
this.setLoginCookie(result._id, result.passsalt)
|
||||
this.setLoginCookie(result._id, result.passsalt);
|
||||
|
||||
return ctx.body = yapi.commons.resReturn({
|
||||
username: result.username,
|
||||
uid: result._id,
|
||||
email: result.email,
|
||||
add_time: result.add_time,
|
||||
up_time: result.up_time
|
||||
up_time: result.up_time,
|
||||
server_ip: yapi.WEBCONFIG.server_ip
|
||||
|
||||
}, 0, 'logout success...');
|
||||
} else {
|
||||
@ -72,7 +72,6 @@ class userController extends baseController {
|
||||
ctx.body = yapi.commons.resReturn('ok');
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* 第三方登录需要提供一个request方法和 token字段,暂时只支持qunar第三方
|
||||
* @return {email: String, username: String}
|
||||
@ -88,45 +87,45 @@ class userController extends baseController {
|
||||
let ret = {
|
||||
email: result.userId + '@qunar.com',
|
||||
username: result.data.userInfo.name
|
||||
}
|
||||
resolve(ret)
|
||||
};
|
||||
resolve(ret);
|
||||
} else {
|
||||
reject(result)
|
||||
reject(result);
|
||||
}
|
||||
}
|
||||
reject(error)
|
||||
})
|
||||
})
|
||||
reject(error);
|
||||
});
|
||||
});
|
||||
},
|
||||
tokenField: 'token'
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
|
||||
|
||||
async loginByToken(ctx) {
|
||||
let config = this.thirdQunarLogin();
|
||||
|
||||
let token = ctx.request.body[config.tokenField] || ctx.request.query[config.tokenField];
|
||||
|
||||
try {
|
||||
let ret = await config.request(token);
|
||||
let login = await this.handleThirdLogin(ret.email, ret.username);
|
||||
|
||||
if (login === true) {
|
||||
yapi.commons.log('login success');
|
||||
ctx.redirect('/')
|
||||
ctx.redirect('/');
|
||||
}
|
||||
} catch (e) {
|
||||
yapi.commons.log(e.message, 'error')
|
||||
ctx.redirect('/')
|
||||
yapi.commons.log(e.message, 'error');
|
||||
ctx.redirect('/');
|
||||
}
|
||||
}
|
||||
|
||||
async handleThirdLogin(email, username) {
|
||||
let user, data, passsalt;
|
||||
var userInst = yapi.getInst(userModel);
|
||||
let userInst = yapi.getInst(userModel);
|
||||
|
||||
try {
|
||||
user = await userInst.findByEmail(email);
|
||||
|
||||
if (!user || !user._id) {
|
||||
passsalt = yapi.commons.randStr();
|
||||
data = {
|
||||
@ -137,18 +136,18 @@ class userController extends baseController {
|
||||
role: 'member',
|
||||
add_time: yapi.commons.time(),
|
||||
up_time: yapi.commons.time()
|
||||
}
|
||||
};
|
||||
user = await userInst.save(data);
|
||||
yapi.commons.sendMail({
|
||||
to: email,
|
||||
contents: `<h3>亲爱的用户:</h3><p>您好,感谢使用YApi,系统检测您是第一次用Qsso账号登录YApi服务,您的Email是: ${email} ,初始化密码为:${passsalt}</p>`
|
||||
})
|
||||
});
|
||||
}
|
||||
|
||||
this.setLoginCookie(user._id, user.passsalt)
|
||||
this.setLoginCookie(user._id, user.passsalt);
|
||||
return true;
|
||||
} catch (e) {
|
||||
console.error("third_login:", e.message)
|
||||
console.error('third_login:', e.message); // eslint-disable-line
|
||||
return false;
|
||||
}
|
||||
}
|
||||
@ -205,27 +204,23 @@ class userController extends baseController {
|
||||
}
|
||||
}
|
||||
|
||||
async forgetPassword(ctx) {
|
||||
async forgetPassword() { }
|
||||
|
||||
}
|
||||
|
||||
async resetPassword(ctx) {
|
||||
|
||||
}
|
||||
async resetPassword() { }
|
||||
|
||||
setLoginCookie(uid, passsalt) {
|
||||
let token = jwt.sign({ uid: uid }, passsalt, { expiresIn: '7 days' });
|
||||
|
||||
this.ctx.cookies.set('_yapi_token', token, {
|
||||
expires: yapi.commons.expireDate(7),
|
||||
httpOnly: true
|
||||
})
|
||||
});
|
||||
this.ctx.cookies.set('_yapi_uid', uid, {
|
||||
expires: yapi.commons.expireDate(7),
|
||||
httpOnly: true
|
||||
})
|
||||
});
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* 用户注册接口
|
||||
* @interface /user/reg
|
||||
@ -239,23 +234,25 @@ class userController extends baseController {
|
||||
* @example ./api/user/login.json
|
||||
*/
|
||||
async reg(ctx) { //注册
|
||||
var userInst = yapi.getInst(userModel);
|
||||
let userInst = yapi.getInst(userModel);
|
||||
let params = ctx.request.body; //获取请求的参数,检查是否存在用户名和密码
|
||||
|
||||
params = yapi.commons.handleParams(params, {
|
||||
username: 'string',
|
||||
password: 'string',
|
||||
email: 'string'
|
||||
})
|
||||
});
|
||||
|
||||
if (!params.email) {
|
||||
return ctx.body = yapi.commons.resReturn(null, 400, '邮箱不能为空');
|
||||
}
|
||||
|
||||
if (!params.password) {
|
||||
return ctx.body = yapi.commons.resReturn(null, 400, '密码不能为空');
|
||||
}
|
||||
|
||||
var checkRepeat = await userInst.checkRepeat(params.email);//然后检查是否已经存在该用户
|
||||
let checkRepeat = await userInst.checkRepeat(params.email);//然后检查是否已经存在该用户
|
||||
|
||||
if (checkRepeat > 0) {
|
||||
return ctx.body = yapi.commons.resReturn(null, 401, '该email已经注册');
|
||||
}
|
||||
@ -269,14 +266,16 @@ class userController extends baseController {
|
||||
role: 'member',
|
||||
add_time: yapi.commons.time(),
|
||||
up_time: yapi.commons.time()
|
||||
}
|
||||
};
|
||||
|
||||
if (!data.username) {
|
||||
data.username = data.email.substr(0, data.email.indexOf('@'));
|
||||
}
|
||||
|
||||
try {
|
||||
let user = await userInst.save(data);
|
||||
this.setLoginCookie(user._id, user.passsalt)
|
||||
|
||||
this.setLoginCookie(user._id, user.passsalt);
|
||||
ctx.body = yapi.commons.resReturn({
|
||||
uid: user._id,
|
||||
email: user.email,
|
||||
@ -288,13 +287,12 @@ class userController extends baseController {
|
||||
yapi.commons.sendMail({
|
||||
to: user.email,
|
||||
contents: `<h3>亲爱的用户:</h3><p>您好,感谢使用YApi,您的账号 ${params.email} 已经注册成功</p>`
|
||||
})
|
||||
});
|
||||
} catch (e) {
|
||||
ctx.body = yapi.commons.resReturn(null, 401, e.message);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* 获取用户列表
|
||||
* @interface /user/list
|
||||
@ -306,11 +304,10 @@ class userController extends baseController {
|
||||
* @returns {Object}
|
||||
* @example
|
||||
*/
|
||||
|
||||
async list(ctx){
|
||||
async list(ctx) {
|
||||
let page = ctx.request.query.page || 1,
|
||||
limit = ctx.request.query.limit || 10;
|
||||
|
||||
|
||||
const userInst = yapi.getInst(userModel);
|
||||
try {
|
||||
let user = await userInst.listWithPaging(page, limit);
|
||||
@ -319,8 +316,8 @@ class userController extends baseController {
|
||||
total: Math.ceil(count / limit),
|
||||
list: user
|
||||
});
|
||||
} catch(e) {
|
||||
return ctx.body = yapi.commons.resReturn(null,402,e.message);
|
||||
} catch (e) {
|
||||
return ctx.body = yapi.commons.resReturn(null, 402, e.message);
|
||||
}
|
||||
}
|
||||
|
||||
@ -334,19 +331,22 @@ class userController extends baseController {
|
||||
* @returns {Object}
|
||||
* @example
|
||||
*/
|
||||
|
||||
async findById(ctx) { //根据id获取用户信息
|
||||
try {
|
||||
var userInst = yapi.getInst(userModel);
|
||||
let userInst = yapi.getInst(userModel);
|
||||
let id = ctx.request.query.id;
|
||||
|
||||
if (!id) {
|
||||
return ctx.body = yapi.commons.resReturn(null, 400, 'uid不能为空');
|
||||
}
|
||||
|
||||
let result = await userInst.findById(id);
|
||||
if(!result){
|
||||
return ctx.body = yapi.commons.resReturn(null,402,"不存在的用户");
|
||||
|
||||
if (!result) {
|
||||
return ctx.body = yapi.commons.resReturn(null, 402, '不存在的用户');
|
||||
}
|
||||
return ctx.body = yapi.commons.resReturn({
|
||||
|
||||
return ctx.body = yapi.commons.resReturn({
|
||||
uid: result._id,
|
||||
username: result.username,
|
||||
email: result.email,
|
||||
@ -354,8 +354,8 @@ class userController extends baseController {
|
||||
add_time: result.add_time,
|
||||
up_time: result.up_time
|
||||
});
|
||||
}catch(e){
|
||||
return ctx.body = yapi.commons.resReturn(null,402,e.message);
|
||||
} catch (e) {
|
||||
return ctx.body = yapi.commons.resReturn(null, 402, e.message);
|
||||
}
|
||||
}
|
||||
|
||||
@ -370,16 +370,20 @@ class userController extends baseController {
|
||||
* @example
|
||||
*/
|
||||
async del(ctx) { //根据id删除一个用户
|
||||
try {
|
||||
try {
|
||||
if (this.getRole() !== 'admin') {
|
||||
return ctx.body = yapi.commons.resReturn(null, 402, 'Without permission.');
|
||||
}
|
||||
var userInst = yapi.getInst(userModel);
|
||||
|
||||
let userInst = yapi.getInst(userModel);
|
||||
let id = ctx.request.body.id;
|
||||
|
||||
if (!id) {
|
||||
return ctx.body = yapi.commons.resReturn(null, 400, 'uid不能为空');
|
||||
}
|
||||
|
||||
let result = await userInst.del(id);
|
||||
|
||||
ctx.body = yapi.commons.resReturn(result);
|
||||
} catch (e) {
|
||||
ctx.body = yapi.commons.resReturn(null, 402, e.message);
|
||||
@ -399,30 +403,36 @@ class userController extends baseController {
|
||||
* @returns {Object}
|
||||
* @example
|
||||
*/
|
||||
async update(ctx){ //更新用户信息
|
||||
try{
|
||||
async update(ctx) { //更新用户信息
|
||||
try {
|
||||
let params = ctx.request.body;
|
||||
|
||||
params = yapi.commons.handleParams(params, {
|
||||
username: 'string',
|
||||
email: 'string'
|
||||
})
|
||||
if(this.getRole() !== 'admin' && params.uid != this.getUid()){
|
||||
return ctx.body = yapi.commons.resReturn(null,401,'没有权限');
|
||||
});
|
||||
|
||||
if (this.getRole() !== 'admin' && params.uid != this.getUid()) {
|
||||
return ctx.body = yapi.commons.resReturn(null, 401, '没有权限');
|
||||
}
|
||||
var userInst = yapi.getInst(userModel);
|
||||
|
||||
let userInst = yapi.getInst(userModel);
|
||||
let id = params.uid;
|
||||
|
||||
if (!id) {
|
||||
return ctx.body = yapi.commons.resReturn(null, 400, 'uid不能为空');
|
||||
}
|
||||
let data ={
|
||||
|
||||
let data = {
|
||||
up_time: yapi.commons.time()
|
||||
};
|
||||
if(this.getRole() === 'admin'){
|
||||
params.role && (data.role = params.role)
|
||||
|
||||
if (this.getRole() === 'admin') {
|
||||
params.role && (data.role = params.role);
|
||||
}
|
||||
params.username && (data.username = params.username)
|
||||
params.email && (data.email = params.email)
|
||||
|
||||
params.username && (data.username = params.username);
|
||||
params.email && (data.email = params.email);
|
||||
|
||||
if (data.email) {
|
||||
var checkRepeat = await userInst.checkRepeat(data.email);//然后检查是否已经存在该用户
|
||||
@ -431,8 +441,8 @@ class userController extends baseController {
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
let result = await userInst.update(id, data);
|
||||
|
||||
ctx.body = yapi.commons.resReturn(result);
|
||||
} catch (e) {
|
||||
ctx.body = yapi.commons.resReturn(null, 402, e.message);
|
||||
@ -480,7 +490,7 @@ class userController extends baseController {
|
||||
];
|
||||
|
||||
let filteredRes = common.filterRes(queryList, rules);
|
||||
console.log(queryList)
|
||||
console.log(queryList); // eslint-disable-line
|
||||
|
||||
return ctx.body = yapi.commons.resReturn(filteredRes, 0, 'ok');
|
||||
}
|
||||
|
@ -7,7 +7,6 @@ import userModel from './models/user.js';
|
||||
yapi.commons = commons;
|
||||
yapi.connect = dbModule.connect();
|
||||
|
||||
|
||||
function install() {
|
||||
let exist = yapi.commons.fileExist(yapi.path.join(yapi.WEBROOT_RUNTIME, 'init.lock'));
|
||||
|
||||
@ -34,10 +33,10 @@ function setupSql() {
|
||||
|
||||
result.then(function () {
|
||||
fs.ensureFileSync(yapi.path.join(yapi.WEBROOT_RUNTIME, 'init.lock'));
|
||||
console.log(`初始化管理员账号 "${yapi.WEBCONFIG.adminAccount}" 成功`);
|
||||
console.log(`初始化管理员账号 "${yapi.WEBCONFIG.adminAccount}" 成功`); // eslint-disable-line
|
||||
process.exit(0);
|
||||
}, function (err) {
|
||||
console.log(`初始化管理员账号 "${yapi.WEBCONFIG.adminAccount}" 失败, ${err.message}`);
|
||||
console.log(`初始化管理员账号 "${yapi.WEBCONFIG.adminAccount}" 失败, ${err.message}`); // eslint-disable-line
|
||||
process.exit(0);
|
||||
});
|
||||
}
|
||||
|
@ -1,4 +1,4 @@
|
||||
const jwt = require('jsonwebtoken');
|
||||
// const jwt = require('jsonwebtoken');
|
||||
//检查token是否过期
|
||||
|
||||
module.exports = async ( ctx, next ) => {
|
||||
@ -14,4 +14,4 @@ module.exports = async ( ctx, next ) => {
|
||||
// ctx.throw(401, 'invalid token');
|
||||
// }
|
||||
await next();
|
||||
}
|
||||
};
|
||||
|
@ -1,66 +1,70 @@
|
||||
import yapi from '../yapi.js';
|
||||
import projectModel from '../models/project.js'
|
||||
import interfaceModel from '../models/interface.js'
|
||||
import Mock from 'mockjs'
|
||||
import projectModel from '../models/project.js';
|
||||
import interfaceModel from '../models/interface.js';
|
||||
import Mock from 'mockjs';
|
||||
|
||||
module.exports = async (ctx, next) => {
|
||||
yapi.commons.log('Server Recevie Request...')
|
||||
yapi.commons.log('Server Recevie Request...');
|
||||
|
||||
let hostname = ctx.hostname;
|
||||
let config = yapi.WEBCONFIG;
|
||||
if(ctx.hostname === config.webhost){
|
||||
if(next) await next();
|
||||
|
||||
if (ctx.hostname === config.webhost) {
|
||||
if (next) await next();
|
||||
return true;
|
||||
}
|
||||
yapi.commons.log('MockServer Running...')
|
||||
|
||||
yapi.commons.log('MockServer Running...');
|
||||
let projectInst = yapi.getInst(projectModel), projects;
|
||||
try{
|
||||
|
||||
try {
|
||||
projects = await projectInst.getByDomain(hostname);
|
||||
}catch(e){
|
||||
} catch (e) {
|
||||
return ctx.body = yapi.commons.resReturn(null, 403, e.message);
|
||||
}
|
||||
|
||||
|
||||
let matchProject = [], maxBasepath = 0;
|
||||
|
||||
for(let i=0, l = projects.length; i< l; i++){
|
||||
|
||||
for (let i = 0, l = projects.length; i < l; i++) {
|
||||
let project = projects[i];
|
||||
|
||||
if(ctx.path && ctx.path.indexOf(project.basepath) === 0){
|
||||
|
||||
if (ctx.path && ctx.path.indexOf(project.basepath) === 0) {
|
||||
matchProject.push(project);
|
||||
if(project.basepath.length > maxBasepath){
|
||||
|
||||
if (project.basepath.length > maxBasepath) {
|
||||
maxBasepath = project.basepath.length;
|
||||
matchProject = project;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if(matchProject === false){
|
||||
if (matchProject === false) {
|
||||
return ctx.body = yapi.commons.resReturn(null, 400, '不存在的domain');
|
||||
}
|
||||
|
||||
let project = matchProject, interfaceData;
|
||||
let interfaceInst = yapi.getInst(interfaceModel);
|
||||
try{
|
||||
interfaceData = await interfaceInst.getByPath(project._id, ctx.path.substr(project.basepath.length));
|
||||
|
||||
if(!interfaceData || interfaceData.length === 0){
|
||||
try {
|
||||
interfaceData = await interfaceInst.getByPath(project._id, ctx.path.substr(project.basepath.length));
|
||||
|
||||
if (!interfaceData || interfaceData.length === 0) {
|
||||
return ctx.body = yapi.commons.resReturn(null, 404, '不存在的api');
|
||||
}
|
||||
|
||||
if(interfaceData.length > 1){
|
||||
if (interfaceData.length > 1) {
|
||||
return ctx.body = yapi.commons.resReturn(null, 405, '存在多个api,请检查数据库');
|
||||
}
|
||||
|
||||
interfaceData = interfaceData[0];
|
||||
|
||||
if(interfaceData.res_body_type === 'json'){
|
||||
|
||||
if (interfaceData.res_body_type === 'json') {
|
||||
return ctx.body = Mock.mock(
|
||||
yapi.commons.json_parse(interfaceData.res_body)
|
||||
);
|
||||
}
|
||||
return ctx.body = interfaceData.res_body;
|
||||
}catch(e){
|
||||
} catch (e) {
|
||||
return ctx.body = yapi.commons.resReturn(null, 409, e.message);
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
};
|
@ -1,6 +1,6 @@
|
||||
module.exports = async (ctx, next) => {
|
||||
let path = ctx.path;
|
||||
console.log(path)
|
||||
console.log(ctx.hostname)
|
||||
if(next) await next();
|
||||
}
|
||||
console.log(path); // eslint-disable-line
|
||||
console.log(ctx.hostname); // eslint-disable-line
|
||||
if (next) await next();
|
||||
};
|
@ -1,5 +1,4 @@
|
||||
import yapi from '../yapi.js';
|
||||
import mongoose from 'mongoose';
|
||||
import baseModel from './base.js';
|
||||
|
||||
class groupModel extends baseModel {
|
||||
@ -29,7 +28,7 @@ class groupModel extends baseModel {
|
||||
}
|
||||
|
||||
list() {
|
||||
return this.model.find().select("group_name _id group_desc add_time up_time").exec();
|
||||
return this.model.find().select('group_name _id group_desc add_time up_time').exec();
|
||||
}
|
||||
|
||||
del(id) {
|
||||
|
@ -82,10 +82,11 @@ class interfaceModel extends baseModel {
|
||||
_id: id
|
||||
});
|
||||
}
|
||||
|
||||
up(id, data) {
|
||||
data.up_time = yapi.commons.time();
|
||||
return this.model.update({
|
||||
_id: id,
|
||||
_id: id
|
||||
}, data, { runValidators: true });
|
||||
}
|
||||
}
|
||||
|
@ -96,7 +96,7 @@ class projectModel extends baseModel {
|
||||
up(id, data) {
|
||||
data.up_time = yapi.commons.time();
|
||||
return this.model.update({
|
||||
_id: id,
|
||||
_id: id
|
||||
}, data, { runValidators: true });
|
||||
}
|
||||
|
||||
|
@ -91,8 +91,6 @@ function createAction(controller, path, method, action) {
|
||||
} else {
|
||||
ctx.body = yapi.commons.resReturn(null, 400, 'Without Permission.');
|
||||
}
|
||||
|
||||
|
||||
});
|
||||
}
|
||||
|
||||
|
@ -23,10 +23,18 @@ exports.log = (msg, type) => {
|
||||
let f;
|
||||
|
||||
switch (type) {
|
||||
case 'log': f = console.log; break;
|
||||
case 'warn': f = console.warn; break;
|
||||
case 'error': f = console.error; break;
|
||||
default: f = console.log; break;
|
||||
case 'log':
|
||||
f = console.log; // eslint-disable-line
|
||||
break;
|
||||
case 'warn':
|
||||
f = console.warn; // eslint-disable-line
|
||||
break;
|
||||
case 'error':
|
||||
f = console.error; // eslint-disable-line
|
||||
break;
|
||||
default:
|
||||
f = console.log; // eslint-disable-line
|
||||
break;
|
||||
}
|
||||
|
||||
f(type + ':', msg);
|
||||
@ -121,7 +129,7 @@ exports.sendMail = (options, cb) => {
|
||||
html: options.contents
|
||||
}, cb);
|
||||
} catch (e) {
|
||||
console.error(e.message);
|
||||
console.error(e.message); // eslint-disable-line
|
||||
}
|
||||
};
|
||||
|
||||
@ -204,8 +212,10 @@ exports.handleParams = (params, keys) => {
|
||||
var filter = keys[key];
|
||||
if (params[key]) {
|
||||
switch (filter) {
|
||||
case 'string': params[key] = trim(params[key] + ''); break;
|
||||
case 'number': params[key] = parseInt(params[key], 10); break;
|
||||
case 'string': params[key] = trim(params[key] + '');
|
||||
break;
|
||||
case 'number': params[key] = parseInt(params[key], 10);
|
||||
break;
|
||||
default: params[key] = trim(params + '');
|
||||
}
|
||||
}
|
||||
|
@ -2,8 +2,8 @@ import mongoose from 'mongoose';
|
||||
import yapi from '../yapi.js';
|
||||
import autoIncrement from 'mongoose-auto-increment';
|
||||
|
||||
function model(model, schema){
|
||||
if(schema instanceof mongoose.Schema === false){
|
||||
function model(model, schema) {
|
||||
if (schema instanceof mongoose.Schema === false) {
|
||||
schema = new mongoose.Schema(schema);
|
||||
}
|
||||
|
||||
@ -12,20 +12,20 @@ function model(model, schema){
|
||||
return yapi.connect.model(model, schema, model);
|
||||
}
|
||||
|
||||
function connect(){
|
||||
function connect() {
|
||||
mongoose.Promise = global.Promise;
|
||||
|
||||
let config = yapi.WEBCONFIG;
|
||||
let options = {};
|
||||
|
||||
if(config.user){
|
||||
options.user = config.db.user,
|
||||
if (config.user) {
|
||||
options.user = config.db.user;
|
||||
options.pass = config.db.pass;
|
||||
}
|
||||
|
||||
|
||||
let db = mongoose.connect(`mongodb://${config.db.servername}:${config.db.port}/${config.db.DATABASE}`, options);
|
||||
|
||||
db.then(function (res) {
|
||||
db.then(function () {
|
||||
yapi.commons.log('mongodb load success...');
|
||||
}, function (err) {
|
||||
yapi.commons.log(err, 'Mongo connect error');
|
||||
@ -37,7 +37,7 @@ function connect(){
|
||||
|
||||
yapi.db = model;
|
||||
|
||||
module.exports = {
|
||||
module.exports = {
|
||||
model: model,
|
||||
connect: connect
|
||||
};
|
@ -3,9 +3,9 @@ import fs from 'fs-extra';
|
||||
import config from '../config.js';
|
||||
|
||||
let runtimePath = config.runtime_path;
|
||||
fs.ensureDirSync( runtimePath );
|
||||
fs.ensureDirSync( path.join(runtimePath, 'log'));
|
||||
let configPath = path.join(runtimePath, 'config.json')
|
||||
fs.ensureDirSync(runtimePath);
|
||||
fs.ensureDirSync(path.join(runtimePath, 'log'));
|
||||
let configPath = path.join(runtimePath, 'config.json');
|
||||
|
||||
fs.writeFileSync(configPath,
|
||||
JSON.stringify(config, null, '\t'),
|
||||
|
@ -35,7 +35,7 @@ function delInst(m) {
|
||||
try {
|
||||
insts.delete(m);
|
||||
} catch (err) {
|
||||
console.error(err);
|
||||
console.error(err); // eslint-disable-line
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -20,10 +20,6 @@ var _koa = require('koa');
|
||||
|
||||
var _koa2 = _interopRequireDefault(_koa);
|
||||
|
||||
var _koaConvert = require('koa-convert');
|
||||
|
||||
var _koaConvert2 = _interopRequireDefault(_koaConvert);
|
||||
|
||||
var _koaStatic = require('koa-static');
|
||||
|
||||
var _koaStatic2 = _interopRequireDefault(_koaStatic);
|
||||
|
@ -154,6 +154,7 @@ var baseController = function () {
|
||||
key: 'getLoginStatus',
|
||||
value: function () {
|
||||
var _ref3 = (0, _asyncToGenerator3.default)(_regenerator2.default.mark(function _callee3(ctx) {
|
||||
var result;
|
||||
return _regenerator2.default.wrap(function _callee3$(_context3) {
|
||||
while (1) {
|
||||
switch (_context3.prev = _context3.next) {
|
||||
@ -165,16 +166,19 @@ var baseController = function () {
|
||||
_context3.t0 = _context3.sent;
|
||||
|
||||
if (!(_context3.t0 === true)) {
|
||||
_context3.next = 5;
|
||||
_context3.next = 7;
|
||||
break;
|
||||
}
|
||||
|
||||
return _context3.abrupt('return', ctx.body = _yapi2.default.commons.resReturn(_yapi2.default.commons.fieldSelect(this.$user, ['_id', 'username', 'email', 'up_time', 'add_time'])));
|
||||
result = _yapi2.default.commons.fieldSelect(this.$user, ['_id', 'username', 'email', 'up_time', 'add_time']);
|
||||
|
||||
case 5:
|
||||
result.server_ip = _yapi2.default.WEBCONFIG.server_ip;
|
||||
return _context3.abrupt('return', ctx.body = _yapi2.default.commons.resReturn(result));
|
||||
|
||||
case 7:
|
||||
return _context3.abrupt('return', ctx.body = _yapi2.default.commons.resReturn(null, 300, 'Please login.'));
|
||||
|
||||
case 6:
|
||||
case 8:
|
||||
case 'end':
|
||||
return _context3.stop();
|
||||
}
|
||||
|
@ -94,6 +94,7 @@ var interfaceController = function (_baseController) {
|
||||
case 0:
|
||||
params = ctx.request.body;
|
||||
|
||||
|
||||
params = _yapi2.default.commons.handleParams(params, {
|
||||
project_id: 'number',
|
||||
title: 'string',
|
||||
@ -160,8 +161,12 @@ var interfaceController = function (_baseController) {
|
||||
};
|
||||
|
||||
|
||||
if (params.req_params_form) data.req_params_form = params.req_params_form;
|
||||
if (params.req_params_other) data.req_params_other = params.req_params_other;
|
||||
if (params.req_params_form) {
|
||||
data.req_params_form = params.req_params_form;
|
||||
}
|
||||
if (params.req_params_other) {
|
||||
data.req_params_other = params.req_params_other;
|
||||
}
|
||||
|
||||
_context.next = 22;
|
||||
return this.Model.save(data);
|
||||
@ -301,7 +306,7 @@ var interfaceController = function (_baseController) {
|
||||
_context3.prev = 10;
|
||||
_context3.t0 = _context3['catch'](3);
|
||||
|
||||
ctx.body = _yapi2.default.commons.resReturn(null, 402, e.message);
|
||||
ctx.body = _yapi2.default.commons.resReturn(null, 402, _context3.t0.message);
|
||||
|
||||
case 13:
|
||||
case 'end':
|
||||
@ -356,6 +361,7 @@ var interfaceController = function (_baseController) {
|
||||
case 0:
|
||||
params = ctx.request.body;
|
||||
|
||||
|
||||
params = _yapi2.default.commons.handleParams(params, {
|
||||
title: 'string',
|
||||
path: 'string',
|
||||
@ -364,6 +370,7 @@ var interfaceController = function (_baseController) {
|
||||
});
|
||||
params.method = params.method || 'GET';
|
||||
params.method = params.method.toUpperCase();
|
||||
|
||||
id = ctx.request.body.id;
|
||||
|
||||
if (id) {
|
||||
@ -412,18 +419,36 @@ var interfaceController = function (_baseController) {
|
||||
};
|
||||
|
||||
|
||||
if (params.path) data.path = params.path;
|
||||
if (params.title) data.title = params.title;
|
||||
if (params.desc) data.desc = params.desc;
|
||||
if (params.method) data.method = params.method;
|
||||
if (params.path) {
|
||||
data.path = params.path;
|
||||
}
|
||||
if (params.title) {
|
||||
data.title = params.title;
|
||||
}
|
||||
if (params.desc) {
|
||||
data.desc = params.desc;
|
||||
}
|
||||
if (params.method) {
|
||||
data.method = params.method;
|
||||
}
|
||||
|
||||
if (params.req_headers) data.req_headers = params.req_headers;
|
||||
if (params.req_headers) {
|
||||
data.req_headers = params.req_headers;
|
||||
}
|
||||
|
||||
if (params.req_params_form) data.req_params_form = params.req_params_form;
|
||||
if (params.req_params_other) data.req_params_other = params.req_params_other;
|
||||
if (params.req_params_form) {
|
||||
data.req_params_form = params.req_params_form;
|
||||
}
|
||||
if (params.req_params_other) {
|
||||
data.req_params_other = params.req_params_other;
|
||||
}
|
||||
|
||||
if (params.res_body_type) data.res_body_type = params.res_body_type;
|
||||
if (params.res_body) data.res_body = params.res_body;
|
||||
if (params.res_body_type) {
|
||||
data.res_body_type = params.res_body_type;
|
||||
}
|
||||
if (params.res_body) {
|
||||
data.res_body = params.res_body;
|
||||
}
|
||||
|
||||
_context4.prev = 28;
|
||||
_context4.next = 31;
|
||||
|
@ -103,6 +103,7 @@ var logController = function (_baseController) {
|
||||
case 9:
|
||||
count = _context.sent;
|
||||
|
||||
|
||||
ctx.body = _yapi2.default.commons.resReturn({
|
||||
total: Math.ceil(count / limit),
|
||||
list: result
|
||||
@ -114,7 +115,7 @@ var logController = function (_baseController) {
|
||||
_context.prev = 13;
|
||||
_context.t0 = _context['catch'](3);
|
||||
|
||||
ctx.body = _yapi2.default.commons.resReturn(null, 402, e.message);
|
||||
ctx.body = _yapi2.default.commons.resReturn(null, 402, _context.t0.message);
|
||||
|
||||
case 16:
|
||||
case 'end':
|
||||
|
@ -711,7 +711,7 @@ var projectController = function (_baseController) {
|
||||
_context7.prev = 21;
|
||||
_context7.t1 = _context7['catch'](0);
|
||||
|
||||
ctx.body = _yapi2.default.commons.resReturn(null, 402, e.message);
|
||||
ctx.body = _yapi2.default.commons.resReturn(null, 402, _context7.t1.message);
|
||||
|
||||
case 24:
|
||||
case 'end':
|
||||
|
@ -44,10 +44,6 @@ var _base = require('./base.js');
|
||||
|
||||
var _base2 = _interopRequireDefault(_base);
|
||||
|
||||
var _mongoose = require('mongoose');
|
||||
|
||||
var _mongoose2 = _interopRequireDefault(_mongoose);
|
||||
|
||||
var _request2 = require('request');
|
||||
|
||||
var _request3 = _interopRequireDefault(_request2);
|
||||
@ -141,7 +137,8 @@ var userController = function (_baseController) {
|
||||
uid: result._id,
|
||||
email: result.email,
|
||||
add_time: result.add_time,
|
||||
up_time: result.up_time
|
||||
up_time: result.up_time,
|
||||
server_ip: _yapi2.default.WEBCONFIG.server_ip
|
||||
|
||||
}, 0, 'logout success...'));
|
||||
|
||||
@ -254,6 +251,7 @@ var userController = function (_baseController) {
|
||||
case 8:
|
||||
login = _context3.sent;
|
||||
|
||||
|
||||
if (login === true) {
|
||||
_yapi2.default.commons.log('login success');
|
||||
ctx.redirect('/');
|
||||
@ -335,7 +333,7 @@ var userController = function (_baseController) {
|
||||
_context4.prev = 17;
|
||||
_context4.t0 = _context4['catch'](2);
|
||||
|
||||
console.error("third_login:", _context4.t0.message);
|
||||
console.error('third_login:', _context4.t0.message); // eslint-disable-line
|
||||
return _context4.abrupt('return', false);
|
||||
|
||||
case 21:
|
||||
@ -468,7 +466,7 @@ var userController = function (_baseController) {
|
||||
}, {
|
||||
key: 'forgetPassword',
|
||||
value: function () {
|
||||
var _ref6 = (0, _asyncToGenerator3.default)(_regenerator2.default.mark(function _callee6(ctx) {
|
||||
var _ref6 = (0, _asyncToGenerator3.default)(_regenerator2.default.mark(function _callee6() {
|
||||
return _regenerator2.default.wrap(function _callee6$(_context6) {
|
||||
while (1) {
|
||||
switch (_context6.prev = _context6.next) {
|
||||
@ -480,7 +478,7 @@ var userController = function (_baseController) {
|
||||
}, _callee6, this);
|
||||
}));
|
||||
|
||||
function forgetPassword(_x7) {
|
||||
function forgetPassword() {
|
||||
return _ref6.apply(this, arguments);
|
||||
}
|
||||
|
||||
@ -489,7 +487,7 @@ var userController = function (_baseController) {
|
||||
}, {
|
||||
key: 'resetPassword',
|
||||
value: function () {
|
||||
var _ref7 = (0, _asyncToGenerator3.default)(_regenerator2.default.mark(function _callee7(ctx) {
|
||||
var _ref7 = (0, _asyncToGenerator3.default)(_regenerator2.default.mark(function _callee7() {
|
||||
return _regenerator2.default.wrap(function _callee7$(_context7) {
|
||||
while (1) {
|
||||
switch (_context7.prev = _context7.next) {
|
||||
@ -501,7 +499,7 @@ var userController = function (_baseController) {
|
||||
}, _callee7, this);
|
||||
}));
|
||||
|
||||
function resetPassword(_x8) {
|
||||
function resetPassword() {
|
||||
return _ref7.apply(this, arguments);
|
||||
}
|
||||
|
||||
@ -511,6 +509,7 @@ var userController = function (_baseController) {
|
||||
key: 'setLoginCookie',
|
||||
value: function setLoginCookie(uid, passsalt) {
|
||||
var token = jwt.sign({ uid: uid }, passsalt, { expiresIn: '7 days' });
|
||||
|
||||
this.ctx.cookies.set('_yapi_token', token, {
|
||||
expires: _yapi2.default.commons.expireDate(7),
|
||||
httpOnly: true
|
||||
@ -594,9 +593,11 @@ var userController = function (_baseController) {
|
||||
up_time: _yapi2.default.commons.time()
|
||||
};
|
||||
|
||||
|
||||
if (!data.username) {
|
||||
data.username = data.email.substr(0, data.email.indexOf('@'));
|
||||
}
|
||||
|
||||
_context8.prev = 15;
|
||||
_context8.next = 18;
|
||||
return userInst.save(data);
|
||||
@ -604,8 +605,8 @@ var userController = function (_baseController) {
|
||||
case 18:
|
||||
user = _context8.sent;
|
||||
|
||||
this.setLoginCookie(user._id, user.passsalt);
|
||||
|
||||
this.setLoginCookie(user._id, user.passsalt);
|
||||
ctx.body = _yapi2.default.commons.resReturn({
|
||||
uid: user._id,
|
||||
email: user.email,
|
||||
@ -635,7 +636,7 @@ var userController = function (_baseController) {
|
||||
}, _callee8, this, [[15, 24]]);
|
||||
}));
|
||||
|
||||
function reg(_x9) {
|
||||
function reg(_x7) {
|
||||
return _ref8.apply(this, arguments);
|
||||
}
|
||||
|
||||
@ -694,7 +695,7 @@ var userController = function (_baseController) {
|
||||
}, _callee9, this, [[2, 12]]);
|
||||
}));
|
||||
|
||||
function list(_x10) {
|
||||
function list(_x8) {
|
||||
return _ref9.apply(this, arguments);
|
||||
}
|
||||
|
||||
@ -744,7 +745,7 @@ var userController = function (_baseController) {
|
||||
break;
|
||||
}
|
||||
|
||||
return _context10.abrupt('return', ctx.body = _yapi2.default.commons.resReturn(null, 402, "不存在的用户"));
|
||||
return _context10.abrupt('return', ctx.body = _yapi2.default.commons.resReturn(null, 402, '不存在的用户'));
|
||||
|
||||
case 10:
|
||||
return _context10.abrupt('return', ctx.body = _yapi2.default.commons.resReturn({
|
||||
@ -769,7 +770,7 @@ var userController = function (_baseController) {
|
||||
}, _callee10, this, [[0, 13]]);
|
||||
}));
|
||||
|
||||
function findById(_x11) {
|
||||
function findById(_x9) {
|
||||
return _ref10.apply(this, arguments);
|
||||
}
|
||||
|
||||
@ -823,6 +824,7 @@ var userController = function (_baseController) {
|
||||
case 9:
|
||||
result = _context11.sent;
|
||||
|
||||
|
||||
ctx.body = _yapi2.default.commons.resReturn(result);
|
||||
_context11.next = 16;
|
||||
break;
|
||||
@ -841,7 +843,7 @@ var userController = function (_baseController) {
|
||||
}, _callee11, this, [[0, 13]]);
|
||||
}));
|
||||
|
||||
function del(_x12) {
|
||||
function del(_x10) {
|
||||
return _ref11.apply(this, arguments);
|
||||
}
|
||||
|
||||
@ -874,6 +876,7 @@ var userController = function (_baseController) {
|
||||
_context12.prev = 0;
|
||||
params = ctx.request.body;
|
||||
|
||||
|
||||
params = _yapi2.default.commons.handleParams(params, {
|
||||
username: 'string',
|
||||
email: 'string'
|
||||
@ -899,13 +902,14 @@ var userController = function (_baseController) {
|
||||
|
||||
case 9:
|
||||
data = {
|
||||
|
||||
up_time: _yapi2.default.commons.time()
|
||||
};
|
||||
|
||||
|
||||
if (this.getRole() === 'admin') {
|
||||
params.role && (data.role = params.role);
|
||||
}
|
||||
|
||||
params.username && (data.username = params.username);
|
||||
params.email && (data.email = params.email);
|
||||
|
||||
@ -934,6 +938,7 @@ var userController = function (_baseController) {
|
||||
case 21:
|
||||
result = _context12.sent;
|
||||
|
||||
|
||||
ctx.body = _yapi2.default.commons.resReturn(result);
|
||||
_context12.next = 28;
|
||||
break;
|
||||
@ -952,7 +957,7 @@ var userController = function (_baseController) {
|
||||
}, _callee12, this, [[0, 25]]);
|
||||
}));
|
||||
|
||||
function update(_x13) {
|
||||
function update(_x11) {
|
||||
return _ref12.apply(this, arguments);
|
||||
}
|
||||
|
||||
@ -1014,7 +1019,7 @@ var userController = function (_baseController) {
|
||||
}];
|
||||
filteredRes = _commons2.default.filterRes(queryList, rules);
|
||||
|
||||
console.log(queryList);
|
||||
console.log(queryList); // eslint-disable-line
|
||||
|
||||
return _context13.abrupt('return', ctx.body = _yapi2.default.commons.resReturn(filteredRes, 0, 'ok'));
|
||||
|
||||
@ -1026,7 +1031,7 @@ var userController = function (_baseController) {
|
||||
}, _callee13, this);
|
||||
}));
|
||||
|
||||
function search(_x14) {
|
||||
function search(_x12) {
|
||||
return _ref13.apply(this, arguments);
|
||||
}
|
||||
|
||||
|
@ -51,10 +51,10 @@ function setupSql() {
|
||||
|
||||
result.then(function () {
|
||||
_fsExtra2.default.ensureFileSync(_yapi2.default.path.join(_yapi2.default.WEBROOT_RUNTIME, 'init.lock'));
|
||||
console.log('\u521D\u59CB\u5316\u7BA1\u7406\u5458\u8D26\u53F7 "' + _yapi2.default.WEBCONFIG.adminAccount + '" \u6210\u529F');
|
||||
console.log('\u521D\u59CB\u5316\u7BA1\u7406\u5458\u8D26\u53F7 "' + _yapi2.default.WEBCONFIG.adminAccount + '" \u6210\u529F'); // eslint-disable-line
|
||||
process.exit(0);
|
||||
}, function (err) {
|
||||
console.log('\u521D\u59CB\u5316\u7BA1\u7406\u5458\u8D26\u53F7 "' + _yapi2.default.WEBCONFIG.adminAccount + '" \u5931\u8D25, ' + err.message);
|
||||
console.log('\u521D\u59CB\u5316\u7BA1\u7406\u5458\u8D26\u53F7 "' + _yapi2.default.WEBCONFIG.adminAccount + '" \u5931\u8D25, ' + err.message); // eslint-disable-line
|
||||
process.exit(0);
|
||||
});
|
||||
}
|
||||
|
@ -1,16 +1,16 @@
|
||||
'use strict';
|
||||
"use strict";
|
||||
|
||||
var _regenerator = require('babel-runtime/regenerator');
|
||||
var _regenerator = require("babel-runtime/regenerator");
|
||||
|
||||
var _regenerator2 = _interopRequireDefault(_regenerator);
|
||||
|
||||
var _asyncToGenerator2 = require('babel-runtime/helpers/asyncToGenerator');
|
||||
var _asyncToGenerator2 = require("babel-runtime/helpers/asyncToGenerator");
|
||||
|
||||
var _asyncToGenerator3 = _interopRequireDefault(_asyncToGenerator2);
|
||||
|
||||
function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }
|
||||
|
||||
var jwt = require('jsonwebtoken');
|
||||
// const jwt = require('jsonwebtoken');
|
||||
//检查token是否过期
|
||||
|
||||
module.exports = function () {
|
||||
@ -23,7 +23,7 @@ module.exports = function () {
|
||||
return next();
|
||||
|
||||
case 2:
|
||||
case 'end':
|
||||
case "end":
|
||||
return _context.stop();
|
||||
}
|
||||
}
|
||||
|
@ -35,6 +35,7 @@ module.exports = function () {
|
||||
switch (_context.prev = _context.next) {
|
||||
case 0:
|
||||
_yapi2.default.commons.log('Server Recevie Request...');
|
||||
|
||||
hostname = ctx.hostname;
|
||||
config = _yapi2.default.WEBCONFIG;
|
||||
|
||||
@ -55,6 +56,7 @@ module.exports = function () {
|
||||
return _context.abrupt('return', true);
|
||||
|
||||
case 8:
|
||||
|
||||
_yapi2.default.commons.log('MockServer Running...');
|
||||
projectInst = _yapi2.default.getInst(_project3.default), projects = void 0;
|
||||
_context.prev = 10;
|
||||
@ -81,6 +83,7 @@ module.exports = function () {
|
||||
|
||||
if (ctx.path && ctx.path.indexOf(_project.basepath) === 0) {
|
||||
matchProject.push(_project);
|
||||
|
||||
if (_project.basepath.length > maxBasepath) {
|
||||
maxBasepath = _project.basepath.length;
|
||||
matchProject = _project;
|
||||
|
@ -19,8 +19,8 @@ module.exports = function () {
|
||||
case 0:
|
||||
path = ctx.path;
|
||||
|
||||
console.log(path);
|
||||
console.log(ctx.hostname);
|
||||
console.log(path); // eslint-disable-line
|
||||
console.log(ctx.hostname); // eslint-disable-line
|
||||
|
||||
if (!next) {
|
||||
_context.next = 6;
|
||||
|
@ -24,10 +24,6 @@ var _yapi = require('../yapi.js');
|
||||
|
||||
var _yapi2 = _interopRequireDefault(_yapi);
|
||||
|
||||
var _mongoose = require('mongoose');
|
||||
|
||||
var _mongoose2 = _interopRequireDefault(_mongoose);
|
||||
|
||||
var _base = require('./base.js');
|
||||
|
||||
var _base2 = _interopRequireDefault(_base);
|
||||
@ -74,7 +70,7 @@ var groupModel = function (_baseModel) {
|
||||
}, {
|
||||
key: 'list',
|
||||
value: function list() {
|
||||
return this.model.find().select("group_name _id group_desc add_time up_time").exec();
|
||||
return this.model.find().select('group_name _id group_desc add_time up_time').exec();
|
||||
}
|
||||
}, {
|
||||
key: 'del',
|
||||
|
@ -47,13 +47,17 @@ exports.log = function (msg, type) {
|
||||
|
||||
switch (type) {
|
||||
case 'log':
|
||||
f = console.log;break;
|
||||
f = console.log; // eslint-disable-line
|
||||
break;
|
||||
case 'warn':
|
||||
f = console.warn;break;
|
||||
f = console.warn; // eslint-disable-line
|
||||
break;
|
||||
case 'error':
|
||||
f = console.error;break;
|
||||
f = console.error; // eslint-disable-line
|
||||
break;
|
||||
default:
|
||||
f = console.log;break;
|
||||
f = console.log; // eslint-disable-line
|
||||
break;
|
||||
}
|
||||
|
||||
f(type + ':', msg);
|
||||
@ -147,7 +151,7 @@ exports.sendMail = function (options, cb) {
|
||||
html: options.contents
|
||||
}, cb);
|
||||
} catch (e) {
|
||||
console.error(e.message);
|
||||
console.error(e.message); // eslint-disable-line
|
||||
}
|
||||
};
|
||||
|
||||
@ -231,9 +235,11 @@ exports.handleParams = function (params, keys) {
|
||||
if (params[key]) {
|
||||
switch (filter) {
|
||||
case 'string':
|
||||
params[key] = trim(params[key] + '');break;
|
||||
params[key] = trim(params[key] + '');
|
||||
break;
|
||||
case 'number':
|
||||
params[key] = parseInt(params[key], 10);break;
|
||||
params[key] = parseInt(params[key], 10);
|
||||
break;
|
||||
default:
|
||||
params[key] = trim(params + '');
|
||||
}
|
||||
|
@ -31,12 +31,13 @@ function connect() {
|
||||
var options = {};
|
||||
|
||||
if (config.user) {
|
||||
options.user = config.db.user, options.pass = config.db.pass;
|
||||
options.user = config.db.user;
|
||||
options.pass = config.db.pass;
|
||||
}
|
||||
|
||||
var db = _mongoose2.default.connect('mongodb://' + config.db.servername + ':' + config.db.port + '/' + config.db.DATABASE, options);
|
||||
|
||||
db.then(function (res) {
|
||||
db.then(function () {
|
||||
_yapi2.default.commons.log('mongodb load success...');
|
||||
}, function (err) {
|
||||
_yapi2.default.commons.log(err, 'Mongo connect error');
|
||||
|
@ -58,7 +58,7 @@ function delInst(m) {
|
||||
try {
|
||||
insts.delete(m);
|
||||
} catch (err) {
|
||||
console.error(err);
|
||||
console.error(err); // eslint-disable-line
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -5,32 +5,22 @@
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1, shrink-to-fit=no">
|
||||
<title>my yApi</title>
|
||||
<link rel="stylesheet" href="http://127.0.0.1:4000/yapi/prd/index@dev.css">
|
||||
<script src="https://qsso.corp.qunar.com/lib/qsso-auth.js"></script>
|
||||
</head>
|
||||
<body>
|
||||
<div id="yapi" style="height: 100%;"></div>
|
||||
|
||||
|
||||
|
||||
<script src="http://127.0.0.1:4000/yapi/prd/manifest@dev.js"></script>
|
||||
<script src="http://127.0.0.1:4000/yapi/prd/lib2@dev.js"></script>
|
||||
<script src="http://127.0.0.1:4000/yapi/prd/lib@dev.js"></script>
|
||||
<script src="http://127.0.0.1:4000/yapi/prd/index@dev.js"></script>
|
||||
|
||||
<!--
|
||||
<button id="qsso-login">qsso登录</button>
|
||||
<script src="/lib/ace-1.2.8.js"></script>
|
||||
<script src="/lib/mode-json-1.2.8.js"></script>
|
||||
<script src="https://qsso.corp.qunar.com/lib/qsso-auth.js"></script>
|
||||
|
||||
<script>
|
||||
QSSO.attach('qsso-login','/user/login_by_token');
|
||||
var xhr = new XMLHttpRequest();
|
||||
xhr.open('GET', '/user/status')
|
||||
xhr.onload = function(e){
|
||||
if(this.status == 200){
|
||||
alert(this.responseText)
|
||||
}
|
||||
}
|
||||
xhr.send()
|
||||
|
||||
</script>
|
||||
|
||||
|
||||
<html>
|
||||
|
||||
-->
|
||||
</body>
|
||||
</html>
|
||||
|
@ -6,17 +6,37 @@
|
||||
<title>my yApi</title>
|
||||
<script>
|
||||
document.write('<script src="prd/assets.js?v=' + Math.random() + '"><\/script>');
|
||||
console.log(window)
|
||||
</script>
|
||||
|
||||
|
||||
|
||||
|
||||
<script>
|
||||
document.write('<link rel="stylesheet" href="/prd/' + window.WEBPACK_ASSETS['index.js'].css + '" />');
|
||||
</script>
|
||||
|
||||
<script src="https://qsso.corp.qunar.com/lib/qsso-auth.js"></script>
|
||||
</head>
|
||||
<body>
|
||||
<div id="yapi" style="height: 100%;"></div>
|
||||
|
||||
|
||||
<script>
|
||||
document.write('<script src="/prd/' + window.WEBPACK_ASSETS['manifest'].js + '"><\/script>');
|
||||
</script>
|
||||
<script>
|
||||
document.write('<script src="/prd/' + window.WEBPACK_ASSETS['lib2'].js + '"><\/script>');
|
||||
</script>
|
||||
<script>
|
||||
document.write('<script src="/prd/' + window.WEBPACK_ASSETS['lib'].js + '"><\/script>');
|
||||
</script>
|
||||
|
||||
<script>
|
||||
document.write('<script src="/prd/' + window.WEBPACK_ASSETS['index.js'].js + '"><\/script>');
|
||||
</script>
|
||||
|
||||
<script src="/lib/ace-1.2.8.js"></script>
|
||||
<script src="/lib/mode-json-1.2.8.js"></script>
|
||||
<script src="https://qsso.corp.qunar.com/lib/qsso-auth.js"></script>
|
||||
</body>
|
||||
</html>
|
||||
|
14
static/lib/ace-1.2.8.js
Normal file
14
static/lib/ace-1.2.8.js
Normal file
File diff suppressed because one or more lines are too long
1
static/lib/mode-json-1.2.8.js
Normal file
1
static/lib/mode-json-1.2.8.js
Normal file
File diff suppressed because one or more lines are too long
17
ykit.js
17
ykit.js
@ -22,6 +22,23 @@ module.exports = {
|
||||
exports: [
|
||||
'./index.js'
|
||||
],
|
||||
commonsChunk: {
|
||||
//filename: 'scripts/[name]@[chunkhash][ext]',
|
||||
vendors: {
|
||||
lib: ['react', 'redux',
|
||||
'redux-thunk',
|
||||
'react-dom',
|
||||
'redux-promise',
|
||||
'react-router-dom',
|
||||
'prop-types',
|
||||
'axios',
|
||||
'moment'
|
||||
],
|
||||
lib2: [
|
||||
'antd'
|
||||
]
|
||||
}
|
||||
},
|
||||
modifyWebpackConfig: function (baseConfig) {
|
||||
|
||||
baseConfig.devtool = 'cheap-module-eval-source-map'
|
||||
|
Loading…
Reference in New Issue
Block a user