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

This commit is contained in:
yhui.yang 2017-07-27 20:11:00 +08:00
commit 7d28140c13
43 changed files with 516 additions and 450 deletions

View File

@ -60,7 +60,7 @@ Footer.defaultProps = {
linkList: [
{
itemTitle: '源码仓库',
itemLink: 'http://gitlab.corp.qunar.com/mfe/yapi.git'
itemLink: 'https://github.com/YMFE/yapi'
}
]

View File

@ -2,6 +2,7 @@
.add-interface-box {
-webkit-box-flex: 1;
min-height: 5rem;
font-size: .14rem;
overflow-x: hidden;
overflow-y: auto;
@ -256,12 +257,12 @@ body {
#req-cover {
height: 330px;
padding: 0 20px;
background-color: #FFF;
// background-color: #FFF;
-webkit-box-flex: 1;
}
#res-cover {
height: 330px;
padding: 0 20px;
background-color: #FFF;
/*background-color: #FFF;*/
-webkit-box-flex: 1;
}

View File

@ -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 })
}
})
}
@ -219,7 +233,12 @@ 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>
</div>
<Card title="HEADERS" noHovering style={{marginTop: 10}} className={Object.keys(headers).length ? '' : 'hidden'}>
<div className="req-row headers">
@ -272,15 +291,17 @@ 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>
<TextArea
value={typeof this.state.res === 'object' ? JSON.stringify(this.state.res, null, 2) : this.state.res.toString()}
style={{margin: 10}}
autosize={{ minRows: 2, maxRows: 6 }}
></TextArea>
</div>
</div>
</div>
</Spin>
</Card>
</div>
)

View File

@ -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>)|&nbsp;|(<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>)|&nbsp;|(<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 () {

View File

@ -1,11 +1,13 @@
import React, { Component } from 'react'
import PropTypes from 'prop-types'
import { connect } from 'react-redux'
import wangEditor from 'wangeditor'
//import wangEditor from 'wangeditor'
import { Tabs } from 'antd'
import { getResParams } from '../../../actions/addInterface.js'
const editor = new wangEditor('#res-cover')
//const editor = new wangEditor('#res-cover')
@connect(
state => {
@ -28,24 +30,41 @@ 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>)|&nbsp;|(<br>)|\s+|<div>|<\/div>/g
editor.customConfig.menus = []
editor.customConfig.onchange = html => {
html = html.replace(reg, '')
this.props.getResParams(html)
//const reg = /(<p>)|(<\/p>)|&nbsp;|(<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 () {

View File

@ -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} />

View File

@ -1,5 +1,9 @@
@import '../../styles/mixin.scss';
.g-doc {
min-height: 5rem;
}
/* .interface-box.css */
.interface-box {
@include row-width-limit;

View File

@ -2,5 +2,6 @@
.g-doc {
@include row-width-limit;
min-height: 5rem;
margin: .24rem auto;
}

View File

@ -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',

View File

@ -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
@ -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

View File

@ -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() {
@ -138,8 +138,8 @@ class Profile extends Component {
userNameEditHtml = <div>
<Input value={_userinfo.username} name="username" onChange={this.changeUserinfo} placeholder="用户名" />
<ButtonGroup className="edit-buttons" >
<Button className="edit-button" onClick={() => { this.handleEdit('usernameEdit', false) }} >Cancel</Button>
<Button 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>
}
@ -154,8 +154,8 @@ class Profile extends Component {
emailEditHtml = <div>
<Input placeholder="Email" value={_userinfo.email} name="email" onChange={this.changeUserinfo} />
<ButtonGroup className="edit-buttons" >
<Button className="edit-button" onClick={() => { this.handleEdit('emailEdit', false) }} >Cancel</Button>
<Button 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>
}
@ -182,8 +182,8 @@ class Profile extends Component {
<Input placeholder="新的密码" type="password" name="password" id="password" />
<Input placeholder="确认密码" type="password" name="verify_pass" id="verify_pass" />
<ButtonGroup className="edit-buttons" >
<Button className="edit-button" onClick={() => { this.handleEdit('secureEdit', false) }}>Cancel</Button>
<Button 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>
}

View File

@ -2,6 +2,7 @@
.g-doc {
margin: .24rem auto;
min-height: 5rem;
}
/* .user-box.css */
@ -21,7 +22,7 @@
.user-list {
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;
@ -33,13 +34,13 @@
}
}
.user-name{
padding: 24px 10px;
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: 5px;
}
@ -50,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;
@ -68,19 +68,18 @@
.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;
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;
}
@ -89,16 +88,16 @@
}
.ant-col-12{
.ant-input{
width: 70%;
margin-right: 24px;
width: 60%;
margin-right: 16px;
}
}
.ant-col-4{
color: rgba(0,0,0,0.85);
padding: 0px 10px;
padding: 0px 16px;
text-indent: .7em;
// background-color: #f1f3f6;
border-left: 5px solid #f1f3f6;
border-left: 4px solid #f1f3f6;
margin-right: 30px;
}
.text{
@ -109,16 +108,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;
}
}

View File

@ -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.server_ip
};
}
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;

View File

@ -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.server_ip
};
}
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;

View File

@ -1,20 +1,18 @@
{
"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"
},
"mail": {
"host": "smtp.163.com",
"port": 465,
"auth": {
"user": "hellosean1025@163.com",
"pass": "helloqunar123"
}
}
"port": "3000",
"webhost": "yapi.local.qunar.com",
"adminAccount": "admin@admin.com",
"db": {
"servername": "127.0.0.1",
"DATABASE": "yapi",
"port": 27017
},
"mail": {
"host": "smtp.mail.com",
"port": 4652,
"auth": {
"user": "****@mail.com",
"pass": "**********"
}
}
}

View File

@ -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';

View File

@ -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.');
}

View File

@ -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);
}
}

View File

@ -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');
}
}

View File

@ -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');
}

View File

@ -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);
});
}

View File

@ -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();
}
};

View File

@ -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);
}
}
};

View File

@ -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();
};

View File

@ -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) {

View File

@ -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 });
}

View File

@ -91,8 +91,6 @@ function createAction(controller, path, method, action) {
} else {
ctx.body = yapi.commons.resReturn(null, 400, 'Without Permission.');
}
});
}

View File

@ -24,16 +24,16 @@ exports.log = (msg, type) => {
switch (type) {
case 'log':
f = console.log;
f = console.log; // eslint-disable-line
break;
case 'warn':
f = console.warn;
f = console.warn; // eslint-disable-line
break;
case 'error':
f = console.error;
f = console.error; // eslint-disable-line
break;
default:
f = console.log;
f = console.log; // eslint-disable-line
break;
}
@ -129,7 +129,7 @@ exports.sendMail = (options, cb) => {
html: options.contents
}, cb);
} catch (e) {
console.error(e.message);
console.error(e.message); // eslint-disable-line
}
};

View File

@ -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'),

View File

@ -1,7 +1,7 @@
import path from 'path';
import fs from 'fs-extra';
import nodemailer from 'nodemailer';
import config from '../../config.json';
import config from '../config.json';
let insts = new Map();
let mail;
@ -35,7 +35,7 @@ function delInst(m) {
try {
insts.delete(m);
} catch (err) {
console.error(err);
console.error(err); // eslint-disable-line
}
}

View File

@ -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);

View File

@ -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();
}

View File

@ -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':

View File

@ -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':

View File

@ -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);
}

View File

@ -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);
});
}

View File

@ -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();
}
}

View File

@ -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;

View File

@ -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;

View File

@ -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',

View File

@ -47,16 +47,16 @@ exports.log = function (msg, type) {
switch (type) {
case 'log':
f = console.log;
f = console.log; // eslint-disable-line
break;
case 'warn':
f = console.warn;
f = console.warn; // eslint-disable-line
break;
case 'error':
f = console.error;
f = console.error; // eslint-disable-line
break;
default:
f = console.log;
f = console.log; // eslint-disable-line
break;
}
@ -151,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
}
};

View File

@ -16,7 +16,7 @@ var _nodemailer = require('nodemailer');
var _nodemailer2 = _interopRequireDefault(_nodemailer);
var _config = require('../../config.json');
var _config = require('../config.json');
var _config2 = _interopRequireDefault(_config);
@ -58,7 +58,7 @@ function delInst(m) {
try {
insts.delete(m);
} catch (err) {
console.error(err);
console.error(err); // eslint-disable-line
}
}

View File

@ -9,28 +9,12 @@
</head>
<body>
<div id="yapi" style="height: 100%;"></div>
<script src="https://cdnjs.cloudflare.com/ajax/libs/ace/1.2.8/ace.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/ace/1.2.8/mode-json.js"></script>
<script src="http://127.0.0.1:4000/yapi/prd/index@dev.js"></script>
<!--
<button id="qsso-login">qsso登录</button>
<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>