mirror of
https://github.com/YMFE/yapi.git
synced 2024-12-21 05:19:42 +08:00
Merge branch 'dev' of gitlab.corp.qunar.com:mfe/yapi into dev
This commit is contained in:
commit
2c2d9b47e7
@ -43,9 +43,9 @@ class FootItem extends Component {
|
|||||||
render () {
|
render () {
|
||||||
return (
|
return (
|
||||||
<div className = 'footItem'>
|
<div className = 'footItem'>
|
||||||
<h4><Icon type= { this.props.iconType } style={{ fontSize: 16 }} /> { this.props.title } </h4>
|
<h4><Icon type= { this.props.iconType } style={{ fontSize: 16 }} /> { this.props.title } </h4>
|
||||||
{ this.props.linkList.map(function(item,i){
|
{ this.props.linkList.map(function(item,i){
|
||||||
return (<div key = {i}><a href = { item.itemLink }><span>{ item.itemTitle }</span></a></div>);
|
return (<div key = {i}> <a href = { item.itemLink }><span>{ item.itemTitle }</span></a></div>);
|
||||||
}) }
|
}) }
|
||||||
</div>
|
</div>
|
||||||
);
|
);
|
||||||
|
@ -2,7 +2,7 @@
|
|||||||
@import '../../styles/mixin.scss';
|
@import '../../styles/mixin.scss';
|
||||||
|
|
||||||
.footer{
|
.footer{
|
||||||
// max-width: 12rem;
|
@include wrap-width-limit;
|
||||||
margin: 0px auto;
|
margin: 0px auto;
|
||||||
clear: both;
|
clear: both;
|
||||||
font-size: 12px;
|
font-size: 12px;
|
||||||
@ -48,7 +48,7 @@
|
|||||||
}
|
}
|
||||||
a{
|
a{
|
||||||
font-weight: 200;
|
font-weight: 200;
|
||||||
color: #108ee9;
|
color: #b3bdc1;
|
||||||
&:hover{
|
&:hover{
|
||||||
color: white;
|
color: white;
|
||||||
}
|
}
|
||||||
|
@ -146,15 +146,19 @@ export default class HeaderCom extends Component {
|
|||||||
}
|
}
|
||||||
render () {
|
render () {
|
||||||
const { login, user, msg, uid, curKey } = this.props;
|
const { login, user, msg, uid, curKey } = this.props;
|
||||||
const headerStyle = {
|
const headerImgStyle = login?{}:{
|
||||||
'background': 'url(./image/header-bg-img.jpg) no-repeat',
|
'background': 'url(./image/header-bg-img.jpg) no-repeat',
|
||||||
'backgroundSize':'100% 100%'
|
'backgroundSize':'100% 100%'
|
||||||
}
|
};
|
||||||
|
const headerShadeStyle = login? {
|
||||||
|
'padding':'0'
|
||||||
|
}: {
|
||||||
|
'background': 'linear-gradient(to bottom,rgba(0,0,0,0.6),rgba(0,0,0,0.5))',
|
||||||
|
'padding':'0'
|
||||||
|
};
|
||||||
return (
|
return (
|
||||||
<acticle className={`header-box`} style={headerStyle}>
|
<acticle className={`header-box`} style={headerImgStyle}>
|
||||||
<Header style={{
|
<Header style={headerShadeStyle}>
|
||||||
background: "linear-gradient(to bottom,rgba(0,0,0,0.6),rgba(0,0,0,0.5))"
|
|
||||||
}}>
|
|
||||||
<div className="content">
|
<div className="content">
|
||||||
<div className="logo">
|
<div className="logo">
|
||||||
<Link to="/" onClick={this.relieveLink}>YAPI</Link>
|
<Link to="/" onClick={this.relieveLink}>YAPI</Link>
|
||||||
|
@ -7,20 +7,11 @@ $color-blue-deeper: #34495E;
|
|||||||
$color-grey-deep : #929aac;
|
$color-grey-deep : #929aac;
|
||||||
$color-black-light : #404040;
|
$color-black-light : #404040;
|
||||||
/* .header-box.css */
|
/* .header-box.css */
|
||||||
|
|
||||||
//.light{
|
|
||||||
// background-color: #f7fafc;
|
|
||||||
// color: $color-blue;
|
|
||||||
//}
|
|
||||||
//.dark {
|
|
||||||
// background-color: $color-black-light;
|
|
||||||
// color: $color-white;
|
|
||||||
//}
|
|
||||||
.header-box {
|
.header-box {
|
||||||
display: block;
|
display: block;
|
||||||
font-size: 0.14rem;
|
font-size: 0.14rem;
|
||||||
z-index: 99;
|
z-index: 99;
|
||||||
// 内容宽度
|
@include wrap-width-limit;
|
||||||
.content {
|
.content {
|
||||||
@include row-width-limit;
|
@include row-width-limit;
|
||||||
margin: 0 auto;
|
margin: 0 auto;
|
||||||
|
@ -52,6 +52,8 @@ $color-white: #fff;
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
.img-container{
|
.img-container{
|
||||||
|
height: 100%;
|
||||||
|
width: 100%;
|
||||||
padding-right: .15rem;
|
padding-right: .15rem;
|
||||||
//background-image: url("#{$imgUrl}demo-img.png");
|
//background-image: url("#{$imgUrl}demo-img.png");
|
||||||
img{
|
img{
|
||||||
|
@ -1,7 +1,7 @@
|
|||||||
import React, { Component } from 'react'
|
import React, { Component } from 'react'
|
||||||
import PropTypes from 'prop-types'
|
import PropTypes from 'prop-types'
|
||||||
import { connect } from 'react-redux'
|
import { connect } from 'react-redux'
|
||||||
import { Button, Input, Select, Card } from 'antd'
|
import { Button, Input, Select, Card, Alert } from 'antd'
|
||||||
import { autobind } from 'core-decorators';
|
import { autobind } from 'core-decorators';
|
||||||
import crossRequest from 'cross-request';
|
import crossRequest from 'cross-request';
|
||||||
import { withRouter } from 'react-router';
|
import { withRouter } from 'react-router';
|
||||||
@ -167,6 +167,10 @@ export default class InterfaceTest extends Component {
|
|||||||
this.setState({ params });
|
this.setState({ params });
|
||||||
}
|
}
|
||||||
|
|
||||||
|
hasCrossRequestPlugin() {
|
||||||
|
const dom = document.getElementById('y-request');
|
||||||
|
return dom.getAttribute('key') === 'yapi';
|
||||||
|
}
|
||||||
|
|
||||||
render () {
|
render () {
|
||||||
|
|
||||||
@ -175,10 +179,29 @@ export default class InterfaceTest extends Component {
|
|||||||
const search = URL.format({
|
const search = URL.format({
|
||||||
query
|
query
|
||||||
});
|
});
|
||||||
|
const hasPlugin = this.hasCrossRequestPlugin();
|
||||||
|
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<div className="interface-test">
|
<div className="interface-test">
|
||||||
|
<div style={{padding: '0 20%'}}>
|
||||||
|
{ hasPlugin ? '' :
|
||||||
|
<Alert
|
||||||
|
message={
|
||||||
|
<div>
|
||||||
|
温馨提示:当前正在使用接口测试服务,请安装我们为您免费提供的
|
||||||
|
<a
|
||||||
|
target="blank"
|
||||||
|
href="https://chrome.google.com/webstore/detail/cross-request/cmnlfmgbjmaciiopcgodlhpiklaghbok?hl=en-US"
|
||||||
|
>
|
||||||
|
测试增强插件 [点击获取]!
|
||||||
|
</a>
|
||||||
|
</div>
|
||||||
|
}
|
||||||
|
type="warning"
|
||||||
|
/>
|
||||||
|
}
|
||||||
|
</div>
|
||||||
<div className="interface-name">{interfaceName}</div>
|
<div className="interface-name">{interfaceName}</div>
|
||||||
<div className="req-part">
|
<div className="req-part">
|
||||||
<div className="req-row href">
|
<div className="req-row href">
|
||||||
|
@ -12,9 +12,10 @@ $color-black-lighter: #404040;
|
|||||||
display: -webkit-box;
|
display: -webkit-box;
|
||||||
-webkit-box-orient: vertical;
|
-webkit-box-orient: vertical;
|
||||||
.main-one{
|
.main-one{
|
||||||
|
@include wrap-width-limit;
|
||||||
.home-des{
|
.home-des{
|
||||||
color: $color-blue-grey-lighter;
|
color: $color-blue-grey-lighter;
|
||||||
padding: .5rem 0 0;
|
padding: .4rem 0 0;
|
||||||
.title{
|
.title{
|
||||||
font-size: .6rem;
|
font-size: .6rem;
|
||||||
}
|
}
|
||||||
@ -26,7 +27,7 @@ $color-black-lighter: #404040;
|
|||||||
color: $color-white;
|
color: $color-white;
|
||||||
}
|
}
|
||||||
.img-container{
|
.img-container{
|
||||||
margin-bottom: -.2rem;
|
margin-bottom: -.3rem;
|
||||||
img{
|
img{
|
||||||
width: 100%;
|
width: 100%;
|
||||||
height: 100%;
|
height: 100%;
|
||||||
@ -75,6 +76,7 @@ $color-black-lighter: #404040;
|
|||||||
.main-part{
|
.main-part{
|
||||||
padding: .9rem .5rem;
|
padding: .9rem .5rem;
|
||||||
height: 5.8rem;
|
height: 5.8rem;
|
||||||
|
@include wrap-width-limit;
|
||||||
&:nth-child(odd){
|
&:nth-child(odd){
|
||||||
background-color: $color-blue-lighter;
|
background-color: $color-blue-lighter;
|
||||||
}
|
}
|
||||||
@ -83,6 +85,7 @@ $color-black-lighter: #404040;
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
.feat-part{
|
.feat-part{
|
||||||
|
@include wrap-width-limit;
|
||||||
padding: .9rem .5rem;
|
padding: .9rem .5rem;
|
||||||
background-color: $color-white;
|
background-color: $color-white;
|
||||||
p{
|
p{
|
||||||
|
@ -37,14 +37,15 @@
|
|||||||
}
|
}
|
||||||
.group-operate {
|
.group-operate {
|
||||||
height: 48px;
|
height: 48px;
|
||||||
min-width: 263px;
|
|
||||||
padding: 10px 6px;
|
padding: 10px 6px;
|
||||||
background: #eee;
|
background: #eee;
|
||||||
|
display: flex;
|
||||||
|
justify-content: space-around;
|
||||||
.search {
|
.search {
|
||||||
display: inline-block;
|
|
||||||
margin-right: 6px;
|
margin-right: 6px;
|
||||||
width: 162px;
|
flex-grow: 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
.group-list {
|
.group-list {
|
||||||
max-height: 650px;
|
max-height: 650px;
|
||||||
|
@ -138,8 +138,8 @@ class Profile extends Component {
|
|||||||
userNameEditHtml = <div>
|
userNameEditHtml = <div>
|
||||||
<Input value={_userinfo.username} name="username" onChange={this.changeUserinfo} placeholder="用户名" />
|
<Input value={_userinfo.username} name="username" onChange={this.changeUserinfo} placeholder="用户名" />
|
||||||
<ButtonGroup className="edit-buttons" >
|
<ButtonGroup className="edit-buttons" >
|
||||||
<Button className="edit-button" onClick={() => { this.handleEdit('usernameEdit', false) }} >Cancel</Button>
|
<Button size={'small'} className="edit-button" onClick={() => { this.handleEdit('usernameEdit', false) }} >Cancel</Button>
|
||||||
<Button className="edit-button" onClick={ () => { this.updateUserinfo('username')} } type="primary">OK</Button>
|
<Button size={'small'} className="edit-button" onClick={ () => { this.updateUserinfo('username')} } type="primary">OK</Button>
|
||||||
</ButtonGroup>
|
</ButtonGroup>
|
||||||
</div>
|
</div>
|
||||||
}
|
}
|
||||||
@ -154,8 +154,8 @@ class Profile extends Component {
|
|||||||
emailEditHtml = <div>
|
emailEditHtml = <div>
|
||||||
<Input placeholder="Email" value={_userinfo.email} name="email" onChange={this.changeUserinfo} />
|
<Input placeholder="Email" value={_userinfo.email} name="email" onChange={this.changeUserinfo} />
|
||||||
<ButtonGroup className="edit-buttons" >
|
<ButtonGroup className="edit-buttons" >
|
||||||
<Button className="edit-button" onClick={() => { this.handleEdit('emailEdit', false) }} >Cancel</Button>
|
<Button size={'small'} className="edit-button" onClick={() => { this.handleEdit('emailEdit', false) }} >Cancel</Button>
|
||||||
<Button className="edit-button" type="primary" onClick={ () => { this.updateUserinfo('email')} }>OK</Button>
|
<Button size={'small'} className="edit-button" type="primary" onClick={ () => { this.updateUserinfo('email')} }>OK</Button>
|
||||||
</ButtonGroup>
|
</ButtonGroup>
|
||||||
</div>
|
</div>
|
||||||
}
|
}
|
||||||
@ -175,15 +175,15 @@ class Profile extends Component {
|
|||||||
}
|
}
|
||||||
|
|
||||||
if (this.state.secureEdit === false) {
|
if (this.state.secureEdit === false) {
|
||||||
secureEditHtml = <Button type="primary" onClick={() => { this.handleEdit('secureEdit', true) }}>密码修改</Button>
|
secureEditHtml = <Button size={'small'} icon="edit" onClick={() => { this.handleEdit('secureEdit', true) }}>修改</Button>
|
||||||
} else {
|
} else {
|
||||||
secureEditHtml = <div>
|
secureEditHtml = <div>
|
||||||
<Input style={{display: this.state.userinfo.role === 'admin' ? 'none': ''}} placeholder="旧的密码" type="password" name="old_password" id="old_password" />
|
<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="password" id="password" />
|
||||||
<Input placeholder="确认密码" type="password" name="verify_pass" id="verify_pass" />
|
<Input placeholder="确认密码" type="password" name="verify_pass" id="verify_pass" />
|
||||||
<ButtonGroup className="edit-buttons" >
|
<ButtonGroup className="edit-buttons" >
|
||||||
<Button className="edit-button" onClick={() => { this.handleEdit('secureEdit', false) }}>Cancel</Button>
|
<Button size={'small'} className="edit-button" onClick={() => { this.handleEdit('secureEdit', false) }}>Cancel</Button>
|
||||||
<Button className="edit-button" onClick={this.updatePassword} type="primary">OK</Button>
|
<Button size={'small'} className="edit-button" onClick={this.updatePassword} type="primary">OK</Button>
|
||||||
</ButtonGroup>
|
</ButtonGroup>
|
||||||
</div>
|
</div>
|
||||||
}
|
}
|
||||||
@ -228,7 +228,7 @@ class Profile extends Component {
|
|||||||
</Row>
|
</Row>
|
||||||
|
|
||||||
<Row className="user-item" type="flex" justify="start">
|
<Row className="user-item" type="flex" justify="start">
|
||||||
<Col span={4}>安全</Col>
|
<Col span={4}>密码</Col>
|
||||||
<Col span={12}>
|
<Col span={12}>
|
||||||
{secureEditHtml}
|
{secureEditHtml}
|
||||||
</Col>
|
</Col>
|
||||||
|
@ -24,15 +24,22 @@
|
|||||||
border-radius:5px;
|
border-radius:5px;
|
||||||
margin-top: 15px;
|
margin-top: 15px;
|
||||||
.search{
|
.search{
|
||||||
margin: 5px;
|
padding: 5px;
|
||||||
|
background-color: #eee;
|
||||||
}
|
}
|
||||||
ul{border:none}
|
ul{border:none}
|
||||||
|
.ant-menu-item{
|
||||||
|
font-size: 14px;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
.user-name{
|
.user-name{
|
||||||
padding: 10px 0px;
|
padding: 24px 0px;
|
||||||
text-align: center;
|
text-align: center;
|
||||||
background-color: #34495e;
|
background-color: #34495e;
|
||||||
color: white;
|
color: white;
|
||||||
|
font-size: 16px;
|
||||||
|
border-top-left-radius:5px;
|
||||||
|
border-top-right-radius: 5px;
|
||||||
span{
|
span{
|
||||||
margin-right: 10px;
|
margin-right: 10px;
|
||||||
}
|
}
|
||||||
@ -62,17 +69,27 @@
|
|||||||
-webkit-box-flex: 1;
|
-webkit-box-flex: 1;
|
||||||
margin-top: 15px;
|
margin-top: 15px;
|
||||||
margin-left: 15px;
|
margin-left: 15px;
|
||||||
padding: 10px 30px;
|
padding: 24px;
|
||||||
box-shadow: 0 2px 4px 0 rgba(0,0,0,0.20);
|
box-shadow: 0 2px 4px 0 rgba(0,0,0,0.20);
|
||||||
background: #FFF;
|
background: #FFF;
|
||||||
border-radius:5px;
|
border-radius:5px;
|
||||||
|
.ant-btn-group{
|
||||||
|
margin-top: 12px;
|
||||||
|
}
|
||||||
.user-item {
|
.user-item {
|
||||||
min-height:35px;
|
min-height:35px;
|
||||||
line-height:35px;
|
line-height:35px;
|
||||||
margin: 5px;
|
margin: 5px;
|
||||||
|
margin-left: 0px;
|
||||||
margin-bottom:10px;
|
margin-bottom:10px;
|
||||||
border-bottom: 1px solid #f1f3f6;
|
border-bottom: 1px solid #f1f3f6;
|
||||||
padding-bottom: 10px;
|
padding-bottom: 10px;
|
||||||
|
#old_password,#password,#verify_pass{
|
||||||
|
margin-top: 20px;
|
||||||
|
}
|
||||||
|
#old_password{
|
||||||
|
margin-top: 0px;
|
||||||
|
}
|
||||||
.ant-col-4{
|
.ant-col-4{
|
||||||
color: black;
|
color: black;
|
||||||
padding: 0px 10px;
|
padding: 0px 10px;
|
||||||
@ -90,13 +107,13 @@
|
|||||||
cursor: pointer
|
cursor: pointer
|
||||||
}
|
}
|
||||||
|
|
||||||
.edit-buttons{
|
// .edit-buttons{
|
||||||
margin:10px;
|
// margin:10px;
|
||||||
}
|
// }
|
||||||
|
|
||||||
.edit-button{
|
// .edit-button{
|
||||||
margin: 5px;
|
// margin: 5px;
|
||||||
}
|
// }
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -2,3 +2,7 @@
|
|||||||
max-width: 11.7rem;
|
max-width: 11.7rem;
|
||||||
min-width: 9.7rem;
|
min-width: 9.7rem;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@mixin wrap-width-limit {
|
||||||
|
min-width: 10.7rem;
|
||||||
|
}
|
||||||
|
21
config_example.json
Normal file
21
config_example.json
Normal file
@ -0,0 +1,21 @@
|
|||||||
|
{
|
||||||
|
"port": "3000",
|
||||||
|
"webhost": "yapi.local.qunar.com",
|
||||||
|
"adminAccount": "admin@admin.com",
|
||||||
|
"db": {
|
||||||
|
"servername": "127.0.0.1",
|
||||||
|
"DATABASE": "yapi",
|
||||||
|
"port": 27017,
|
||||||
|
"user": "test1",
|
||||||
|
"pass": "test1"
|
||||||
|
},
|
||||||
|
"mail": {
|
||||||
|
"host": "smtp.163.com",
|
||||||
|
"port": 465,
|
||||||
|
"from": "***@163.com",
|
||||||
|
"auth": {
|
||||||
|
"user": "***@163.com",
|
||||||
|
"pass": "*****"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
@ -1,35 +0,0 @@
|
|||||||
### 1.User
|
|
||||||
- /user/get //获取用户个人信息
|
|
||||||
- /user/list //获取用户列表,需要提供分页功能
|
|
||||||
- /user/del //删除用户
|
|
||||||
- /user/up //更新用户个人信息
|
|
||||||
- /uesr/login //登录
|
|
||||||
- /user/reg //注册
|
|
||||||
- /user/login/status //获取用户登录状态
|
|
||||||
|
|
||||||
### 2.Group
|
|
||||||
- /group/list //获取项目分组列表
|
|
||||||
- /group/add //添加
|
|
||||||
- /group/up //更新
|
|
||||||
- /group/del //删除
|
|
||||||
|
|
||||||
### 3.Project
|
|
||||||
- /project/list/:group_id
|
|
||||||
- /project/add //添加项目
|
|
||||||
- /project/up //编辑项目
|
|
||||||
- /project/del //删除项目
|
|
||||||
- /project/add_member //添加项目成员
|
|
||||||
- /project/del_member //删除项目成员
|
|
||||||
- /project/get //获取一个项目详细信息
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
### 4.interface
|
|
||||||
- /interface/list/:project_id
|
|
||||||
- /interface/add
|
|
||||||
- /interface/up
|
|
||||||
- /interface/del
|
|
||||||
- /interface/mock //执行用户定义的mock,返回mock结果
|
|
||||||
|
|
||||||
### 5. mock服务器
|
|
||||||
用户修改host指到yapi服务器,yapi服务器收到请求后根据domain/basepath 找到相对应的项目,根据req信息,找到对应的接口,执行用户定义的mock数据,返回给用户相应的结果
|
|
@ -1,93 +0,0 @@
|
|||||||
### 数据库字典
|
|
||||||
### 数据库基于mongodb
|
|
||||||
#### 1.User数据表,表名:user
|
|
||||||
```json
|
|
||||||
{
|
|
||||||
_id: (int)
|
|
||||||
username: (string)
|
|
||||||
password: (sha1)
|
|
||||||
passsalt: (string)
|
|
||||||
email : (string)
|
|
||||||
role : (string)
|
|
||||||
add_time: (int)
|
|
||||||
up_time: (int)
|
|
||||||
}
|
|
||||||
````
|
|
||||||
|
|
||||||
#### 2.Project 数据表,表名:project
|
|
||||||
```json
|
|
||||||
{
|
|
||||||
_id: (int)
|
|
||||||
uid : (int)
|
|
||||||
name: (string)
|
|
||||||
basepath: (string)
|
|
||||||
desc: (string)
|
|
||||||
group_id: (int)
|
|
||||||
members: [
|
|
||||||
... //成员uid
|
|
||||||
]
|
|
||||||
prd_host: (string)//网站上线的domain,可用来获取mock数据
|
|
||||||
env:(object){
|
|
||||||
'local环境' : 'http://127.0.0.1'
|
|
||||||
}
|
|
||||||
add_time: (int)
|
|
||||||
up_time: (int)
|
|
||||||
}
|
|
||||||
````
|
|
||||||
|
|
||||||
#### 3.api 数据表,表名:interface
|
|
||||||
```json
|
|
||||||
{
|
|
||||||
_id: (int)
|
|
||||||
uid: (int) //负责人uid
|
|
||||||
path: (string)
|
|
||||||
group_id: (int)
|
|
||||||
status: (int)
|
|
||||||
desc : (string)
|
|
||||||
add_time: (int)
|
|
||||||
up_time : (int)
|
|
||||||
req_headers:(Object){
|
|
||||||
"header_name":(Object){
|
|
||||||
default_value: (string),
|
|
||||||
desc: (string),
|
|
||||||
mock: (string)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
req_params_type: (form|raw)
|
|
||||||
req_params: (Object){
|
|
||||||
"key" : (Object){
|
|
||||||
default_value: (string),
|
|
||||||
desc: (string),
|
|
||||||
mock: (string)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
res_header: (Object){
|
|
||||||
"header_name":(Object){
|
|
||||||
default_value: (string),
|
|
||||||
desc: (string),
|
|
||||||
mock: (string)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
res_body_type: (text|json),
|
|
||||||
res_body: (Object){
|
|
||||||
"key":(Object){
|
|
||||||
default_value: (string),
|
|
||||||
desc: (string),
|
|
||||||
mock: (string)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
```
|
|
||||||
|
|
||||||
#### 4.项目分组,表名: group
|
|
||||||
```json
|
|
||||||
{
|
|
||||||
_id: (int),
|
|
||||||
uid: (int),
|
|
||||||
group_name: (string),
|
|
||||||
group_desc: (string),
|
|
||||||
add_time: (int),
|
|
||||||
up_time: (int)
|
|
||||||
}
|
|
||||||
```
|
|
32
gulpfile.js
32
gulpfile.js
@ -12,14 +12,14 @@ const SRC = 'server/**/*.js';
|
|||||||
|
|
||||||
function generateBabel(status) {
|
function generateBabel(status) {
|
||||||
const babelProcess = babel({
|
const babelProcess = babel({
|
||||||
presets: ['es2015', "stage-3"],
|
presets: ['es2015', 'stage-3'],
|
||||||
plugins: ['transform-runtime']
|
plugins: ['transform-runtime']
|
||||||
});
|
});
|
||||||
|
|
||||||
babelProcess.on('error', function (e) {
|
babelProcess.on('error', function (e) {
|
||||||
const restart = status ? status.count < 2 : true;
|
const restart = status ? status.count < 2 : true;
|
||||||
|
|
||||||
console.error(e);
|
console.error(e); // eslint-disable-line
|
||||||
output('error', 'babel 编译失败!', restart);
|
output('error', 'babel 编译失败!', restart);
|
||||||
|
|
||||||
if (status) {
|
if (status) {
|
||||||
@ -39,7 +39,13 @@ function excuteCmd(cmd, args, opts) {
|
|||||||
});
|
});
|
||||||
|
|
||||||
command.stderr.on('data', data => {
|
command.stderr.on('data', data => {
|
||||||
output('log', `${NAME} ${data.toString()}`, true);
|
const message = data.toString();
|
||||||
|
|
||||||
|
output('log', `${NAME} ${message}`, true);
|
||||||
|
|
||||||
|
if (~message.indexOf('building complete')) {
|
||||||
|
waitingSpinner();
|
||||||
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
return command;
|
return command;
|
||||||
@ -50,12 +56,12 @@ function output(type, message, restart = false) {
|
|||||||
|
|
||||||
if (type === 'success') {
|
if (type === 'success') {
|
||||||
message = '✔ ' + message;
|
message = '✔ ' + message;
|
||||||
console.log(chalk.green(message));
|
console.log(chalk.green(message)); // eslint-disable-line
|
||||||
} else if (type === 'error') {
|
} else if (type === 'error') {
|
||||||
message = '✖ ' + message;
|
message = '✖ ' + message;
|
||||||
console.log(chalk.red(message));
|
console.log(chalk.red(message)); // eslint-disable-line
|
||||||
} else {
|
} else {
|
||||||
console.log(message);
|
console.log(message); // eslint-disable-line
|
||||||
}
|
}
|
||||||
if (restart) {
|
if (restart) {
|
||||||
spinner.start();
|
spinner.start();
|
||||||
@ -63,6 +69,7 @@ function output(type, message, restart = false) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
function waitingSpinner() {
|
function waitingSpinner() {
|
||||||
|
spinner.stop();
|
||||||
spinner = ora({
|
spinner = ora({
|
||||||
text: '等待文件变更...',
|
text: '等待文件变更...',
|
||||||
spinner: 'circleQuarters',
|
spinner: 'circleQuarters',
|
||||||
@ -71,7 +78,7 @@ function waitingSpinner() {
|
|||||||
}
|
}
|
||||||
|
|
||||||
gulp.task('removeDist', [], function () {
|
gulp.task('removeDist', [], function () {
|
||||||
return fs.removeSync(DIST)
|
return fs.removeSync(DIST);
|
||||||
});
|
});
|
||||||
|
|
||||||
gulp.task('initialBuild', ['removeDist'], () => {
|
gulp.task('initialBuild', ['removeDist'], () => {
|
||||||
@ -95,9 +102,14 @@ gulp.task('initialBuild', ['removeDist'], () => {
|
|||||||
});
|
});
|
||||||
|
|
||||||
gulp.task('default', ['initialBuild'], () => {
|
gulp.task('default', ['initialBuild'], () => {
|
||||||
gulp.watch(SRC, (event) => {
|
gulp.watch('client/**/*', event => {
|
||||||
let originFilePath = path.relative(path.join(__dirname, 'server'), event.path)
|
spinner.stop();
|
||||||
let distPath = path.resolve(DIST, path.join(originFilePath))
|
spinner = ora(`正在编译 ${event.path}`).start();
|
||||||
|
});
|
||||||
|
|
||||||
|
gulp.watch(SRC, event => {
|
||||||
|
let originFilePath = path.relative(path.join(__dirname, 'server'), event.path);
|
||||||
|
let distPath = path.resolve(DIST, path.join(originFilePath));
|
||||||
spinner.text = `正在编译 ${event.path}...`;
|
spinner.text = `正在编译 ${event.path}...`;
|
||||||
|
|
||||||
gulp.src(event.path).pipe(generateBabel())
|
gulp.src(event.path).pipe(generateBabel())
|
||||||
|
@ -1,18 +0,0 @@
|
|||||||
module.exports = {
|
|
||||||
'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': '**********'
|
|
||||||
}
|
|
||||||
}
|
|
||||||
};
|
|
@ -1,20 +1,19 @@
|
|||||||
import yapi from '../yapi.js'
|
import yapi from '../yapi.js';
|
||||||
import projectModel from '../models/project.js'
|
import projectModel from '../models/project.js';
|
||||||
import userModel from '../models/user.js'
|
import userModel from '../models/user.js';
|
||||||
const jwt = require('jsonwebtoken');
|
const jwt = require('jsonwebtoken');
|
||||||
|
|
||||||
|
class baseController {
|
||||||
class baseController{
|
constructor(ctx) {
|
||||||
constructor(ctx){
|
|
||||||
this.ctx = ctx;
|
this.ctx = ctx;
|
||||||
//网站上线后,role对象key是不能修改的,value可以修改
|
//网站上线后,role对象key是不能修改的,value可以修改
|
||||||
this.roles = {
|
this.roles = {
|
||||||
admin: 'Admin',
|
admin: 'Admin',
|
||||||
member: '网站会员'
|
member: '网站会员'
|
||||||
}
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
async init(ctx){
|
async init(ctx) {
|
||||||
this.$user = null;
|
this.$user = null;
|
||||||
let ignoreRouter = [
|
let ignoreRouter = [
|
||||||
'/user/login_by_token',
|
'/user/login_by_token',
|
||||||
@ -22,73 +21,93 @@ class baseController{
|
|||||||
'/user/reg',
|
'/user/reg',
|
||||||
'/user/status',
|
'/user/status',
|
||||||
'/user/logout'
|
'/user/logout'
|
||||||
]
|
];
|
||||||
if(ignoreRouter.indexOf(ctx.path) > -1){
|
if (ignoreRouter.indexOf(ctx.path) > -1) {
|
||||||
this.$auth = true;
|
this.$auth = true;
|
||||||
}else{
|
} else {
|
||||||
await this.checkLogin(ctx)
|
await this.checkLogin(ctx);
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
getUid(ctx){
|
getUid() {
|
||||||
return parseInt(this.$uid, 10);
|
return parseInt(this.$uid, 10);
|
||||||
}
|
}
|
||||||
|
|
||||||
async checkLogin(ctx){
|
async checkLogin(ctx) {
|
||||||
let token = ctx.cookies.get('_yapi_token');
|
let token = ctx.cookies.get('_yapi_token');
|
||||||
let uid = ctx.cookies.get('_yapi_uid');
|
let uid = ctx.cookies.get('_yapi_uid');
|
||||||
try{
|
|
||||||
if(!token || !uid) return false;
|
try {
|
||||||
|
if (!token || !uid) return false;
|
||||||
let userInst = yapi.getInst(userModel); //创建user实体
|
let userInst = yapi.getInst(userModel); //创建user实体
|
||||||
let result = await userInst.findById(uid);
|
let result = await userInst.findById(uid);
|
||||||
let decoded = jwt.verify(token, result.passsalt)
|
let decoded = jwt.verify(token, result.passsalt);
|
||||||
if(decoded.uid == uid){
|
|
||||||
|
if (decoded.uid == uid) {
|
||||||
this.$uid = uid;
|
this.$uid = uid;
|
||||||
this.$auth = true;
|
this.$auth = true;
|
||||||
this.$user = result;
|
this.$user = result;
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
return false;
|
return false;
|
||||||
}catch(e){
|
} catch (e) {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
async getLoginStatus(ctx){
|
async getLoginStatus(ctx) {
|
||||||
if(await this.checkLogin(ctx) === true){
|
if (await this.checkLogin(ctx) === true) {
|
||||||
return ctx.body = yapi.commons.resReturn(yapi.commons.fieldSelect(this.$user,['_id','username','email', 'up_time', 'add_time']));
|
return ctx.body = yapi.commons.resReturn(yapi.commons.fieldSelect(this.$user, ['_id', 'username', 'email', 'up_time', 'add_time']));
|
||||||
}
|
}
|
||||||
return ctx.body = yapi.commons.resReturn(null, 300 , 'Please login.');
|
return ctx.body = yapi.commons.resReturn(null, 300, 'Please login.');
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
getRole(){
|
getRole() {
|
||||||
return this.$user.role;
|
return this.$user.role;
|
||||||
}
|
}
|
||||||
|
|
||||||
async jungeProjectAuth(id){
|
async jungeProjectAuth(id) {
|
||||||
let model = yapi.getInst(projectModel);
|
let model = yapi.getInst(projectModel);
|
||||||
if(this.getRole() === 'admin') return true;
|
|
||||||
if(!id) return false;
|
if (this.getRole() === 'admin') {
|
||||||
let result = await model.get(id);
|
|
||||||
if(result.uid === this.getUid()){
|
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (!id) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
let result = await model.get(id);
|
||||||
|
|
||||||
|
if (result.uid === this.getUid()) {
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
async jungeMemberAuth(id, member_uid){
|
async jungeMemberAuth(id, member_uid) {
|
||||||
let model = yapi.getInst(projectModel);
|
let model = yapi.getInst(projectModel);
|
||||||
if(this.getRole() === 'admin') return true;
|
|
||||||
if(!id || !member_uid) return false;
|
if (this.getRole() === 'admin') {
|
||||||
let result = await model.checkMemberRepeat(id, member_uid);
|
|
||||||
if(result > 0){
|
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (!id || !member_uid) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
let result = await model.checkMemberRepeat(id, member_uid);
|
||||||
|
|
||||||
|
if (result > 0) {
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
module.exports = baseController
|
module.exports = baseController;
|
@ -1,14 +1,12 @@
|
|||||||
import groupModel from '../models/group.js'
|
import groupModel from '../models/group.js';
|
||||||
import yapi from '../yapi.js'
|
import yapi from '../yapi.js';
|
||||||
import baseController from './base.js'
|
import baseController from './base.js';
|
||||||
import projectModel from '../models/project.js'
|
import projectModel from '../models/project.js';
|
||||||
|
|
||||||
//
|
class groupController extends baseController {
|
||||||
class groupController extends baseController{
|
constructor(ctx) {
|
||||||
constructor(ctx){
|
super(ctx);
|
||||||
super(ctx)
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 添加项目分组
|
* 添加项目分组
|
||||||
@ -23,37 +21,45 @@ class groupController extends baseController{
|
|||||||
*/
|
*/
|
||||||
async add(ctx) {
|
async add(ctx) {
|
||||||
let params = ctx.request.body;
|
let params = ctx.request.body;
|
||||||
|
|
||||||
params = yapi.commons.handleParams(params, {
|
params = yapi.commons.handleParams(params, {
|
||||||
group_name: 'string',
|
group_name: 'string',
|
||||||
group_desc: 'string'
|
group_desc: 'string'
|
||||||
})
|
});
|
||||||
if(this.getRole() !== 'admin'){
|
|
||||||
return ctx.body = yapi.commons.resReturn(null,401,'没有权限');
|
if (this.getRole() !== 'admin') {
|
||||||
|
return ctx.body = yapi.commons.resReturn(null, 401, '没有权限');
|
||||||
}
|
}
|
||||||
if(!params.group_name){
|
|
||||||
|
if (!params.group_name) {
|
||||||
return ctx.body = yapi.commons.resReturn(null, 400, '项目分组名不能为空');
|
return ctx.body = yapi.commons.resReturn(null, 400, '项目分组名不能为空');
|
||||||
}
|
}
|
||||||
var groupInst = yapi.getInst(groupModel);
|
|
||||||
|
let groupInst = yapi.getInst(groupModel);
|
||||||
var checkRepeat = await groupInst.checkRepeat(params.group_name);
|
|
||||||
if(checkRepeat > 0){
|
let checkRepeat = await groupInst.checkRepeat(params.group_name);
|
||||||
return ctx.body = yapi.commons.resReturn(null, 401, '项目分组名已存在');
|
|
||||||
|
if (checkRepeat > 0) {
|
||||||
|
return ctx.body = yapi.commons.resReturn(null, 401, '项目分组名已存在');
|
||||||
}
|
}
|
||||||
|
|
||||||
let data = {
|
let data = {
|
||||||
group_name: params.group_name,
|
group_name: params.group_name,
|
||||||
group_desc: params.group_desc,
|
group_desc: params.group_desc,
|
||||||
uid: this.getUid(),
|
uid: this.getUid(),
|
||||||
add_time: yapi.commons.time(),
|
add_time: yapi.commons.time(),
|
||||||
up_time: yapi.commons.time()
|
up_time: yapi.commons.time()
|
||||||
}
|
};
|
||||||
try{
|
|
||||||
|
try {
|
||||||
let result = await groupInst.save(data);
|
let result = await groupInst.save(data);
|
||||||
|
|
||||||
result = yapi.commons.fieldSelect(result, ['_id', 'group_name', 'group_desc', 'uid']);
|
result = yapi.commons.fieldSelect(result, ['_id', 'group_name', 'group_desc', 'uid']);
|
||||||
ctx.body = yapi.commons.resReturn(result);
|
ctx.body = yapi.commons.resReturn(result);
|
||||||
}catch(e){
|
} catch (e) {
|
||||||
ctx.body = yapi.commons.resReturn(null, 402, e.message)
|
ctx.body = yapi.commons.resReturn(null, 402, e.message);
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -65,14 +71,13 @@ class groupController extends baseController{
|
|||||||
* @returns {Object}
|
* @returns {Object}
|
||||||
* @example ./api/group/list.json
|
* @example ./api/group/list.json
|
||||||
*/
|
*/
|
||||||
|
|
||||||
async list(ctx) {
|
async list(ctx) {
|
||||||
try{
|
try {
|
||||||
var groupInst = yapi.getInst(groupModel);
|
var groupInst = yapi.getInst(groupModel);
|
||||||
let result = await groupInst.list();
|
let result = await groupInst.list();
|
||||||
ctx.body = yapi.commons.resReturn(result)
|
ctx.body = yapi.commons.resReturn(result);
|
||||||
}catch(e){
|
} catch (e) {
|
||||||
ctx.body = yapi.commons.resReturn(null, 402, e.message)
|
ctx.body = yapi.commons.resReturn(null, 402, e.message);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -86,27 +91,30 @@ class groupController extends baseController{
|
|||||||
* @returns {Object}
|
* @returns {Object}
|
||||||
* @example ./api/group/del.json
|
* @example ./api/group/del.json
|
||||||
*/
|
*/
|
||||||
|
async del(ctx) {
|
||||||
|
if (this.getRole() !== 'admin') {
|
||||||
|
return ctx.body = yapi.commons.resReturn(null, 401, '没有权限');
|
||||||
|
}
|
||||||
|
|
||||||
async del(ctx){
|
try {
|
||||||
if(this.getRole() !== 'admin'){
|
let groupInst = yapi.getInst(groupModel);
|
||||||
return ctx.body = yapi.commons.resReturn(null,401,'没有权限');
|
let projectInst = yapi.getInst(projectModel);
|
||||||
}
|
let id = ctx.request.body.id;
|
||||||
try{
|
|
||||||
var groupInst = yapi.getInst(groupModel);
|
if (!id) {
|
||||||
var projectInst = yapi.getInst(projectModel);
|
|
||||||
let id = ctx.request.body.id;
|
|
||||||
if(!id){
|
|
||||||
return ctx.body = yapi.commons.resReturn(null, 402, 'id不能为空');
|
return ctx.body = yapi.commons.resReturn(null, 402, 'id不能为空');
|
||||||
}
|
}
|
||||||
let count = await projectInst.countByGroupId(id);
|
|
||||||
if(count > 0){
|
let count = await projectInst.countByGroupId(id);
|
||||||
|
|
||||||
|
if (count > 0) {
|
||||||
return ctx.body = yapi.commons.resReturn(null, 403, '请先删除该分组下的项目');
|
return ctx.body = yapi.commons.resReturn(null, 403, '请先删除该分组下的项目');
|
||||||
}
|
}
|
||||||
|
|
||||||
let result = await groupInst.del(id);
|
let result = await groupInst.del(id);
|
||||||
ctx.body = yapi.commons.resReturn(result)
|
ctx.body = yapi.commons.resReturn(result);
|
||||||
}catch(err){
|
} catch (err) {
|
||||||
ctx.body = yapi.commons.resReturn(null, 402, e.message)
|
ctx.body = yapi.commons.resReturn(null, 402, err.message);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -122,33 +130,32 @@ class groupController extends baseController{
|
|||||||
* @returns {Object}
|
* @returns {Object}
|
||||||
* @example ./api/group/up.json
|
* @example ./api/group/up.json
|
||||||
*/
|
*/
|
||||||
|
async up(ctx) {
|
||||||
async up(ctx){
|
if (this.getRole() !== 'admin') {
|
||||||
if(this.getRole() !== 'admin'){
|
return ctx.body = yapi.commons.resReturn(null, 401, '没有权限');
|
||||||
return ctx.body = yapi.commons.resReturn(null,401,'没有权限');
|
|
||||||
}
|
}
|
||||||
try{
|
|
||||||
|
try {
|
||||||
|
|
||||||
ctx.request.body = yapi.commons.handleParams(ctx.request.body, {
|
ctx.request.body = yapi.commons.handleParams(ctx.request.body, {
|
||||||
id: 'number',
|
id: 'number',
|
||||||
group_name: 'string',
|
group_name: 'string',
|
||||||
group_desc: 'string'
|
group_desc: 'string'
|
||||||
})
|
});
|
||||||
var groupInst = yapi.getInst(groupModel);
|
let groupInst = yapi.getInst(groupModel);
|
||||||
let id = ctx.request.body.id;
|
let id = ctx.request.body.id;
|
||||||
let data = {};
|
let data = {};
|
||||||
ctx.request.body.group_name && (data.group_name = ctx.request.body.group_name)
|
ctx.request.body.group_name && (data.group_name = ctx.request.body.group_name);
|
||||||
ctx.request.body.group_desc && (data.group_desc = ctx.request.body.group_desc)
|
ctx.request.body.group_desc && (data.group_desc = ctx.request.body.group_desc);
|
||||||
if(Object.keys(data).length === 0 ){
|
if (Object.keys(data).length === 0) {
|
||||||
ctx.body = yapi.commons.resReturn(null, 404, '分组名和分组描述不能为空');
|
ctx.body = yapi.commons.resReturn(null, 404, '分组名和分组描述不能为空');
|
||||||
}
|
}
|
||||||
let result = await groupInst.up(id, data);
|
let result = await groupInst.up(id, data);
|
||||||
ctx.body = yapi.commons.resReturn(result)
|
ctx.body = yapi.commons.resReturn(result);
|
||||||
}catch(err){
|
} catch (err) {
|
||||||
ctx.body = yapi.commons.resReturn(null, 402, e.message)
|
ctx.body = yapi.commons.resReturn(null, 402, err.message);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
module.exports = groupController;
|
||||||
module.exports = groupController
|
|
@ -115,7 +115,7 @@ exports.sendMail = (options, cb) => {
|
|||||||
|
|
||||||
try {
|
try {
|
||||||
yapi.mail.sendMail({
|
yapi.mail.sendMail({
|
||||||
from: yapi.WEBCONFIG.mail.auth.user,
|
from: yapi.WEBCONFIG.mail.from,
|
||||||
to: options.to,
|
to: options.to,
|
||||||
subject: 'yapi平台',
|
subject: 'yapi平台',
|
||||||
html: options.contents
|
html: options.contents
|
||||||
|
@ -2,7 +2,10 @@ import path from 'path';
|
|||||||
import fs from 'fs-extra';
|
import fs from 'fs-extra';
|
||||||
import config from '../config.js';
|
import config from '../config.js';
|
||||||
|
|
||||||
let configPath = path.join(path.resolve(__dirname, '../../'), 'runtime', 'config.json');
|
let runtimePath = config.runtime_path;
|
||||||
|
fs.ensureDirSync( runtimePath );
|
||||||
|
fs.ensureDirSync( path.join(runtimePath, 'log'));
|
||||||
|
let configPath = path.join(runtimePath, 'config.json')
|
||||||
|
|
||||||
fs.writeFileSync(configPath,
|
fs.writeFileSync(configPath,
|
||||||
JSON.stringify(config, null, '\t'),
|
JSON.stringify(config, null, '\t'),
|
||||||
|
@ -1,18 +1,17 @@
|
|||||||
import path from 'path';
|
import path from 'path';
|
||||||
import fs from 'fs-extra';
|
import fs from 'fs-extra';
|
||||||
import nodemailer from 'nodemailer';
|
import nodemailer from 'nodemailer';
|
||||||
import config from '../runtime/config.json';
|
import config from '../../config.json';
|
||||||
|
|
||||||
let insts = new Map();
|
let insts = new Map();
|
||||||
let mail;
|
let mail;
|
||||||
|
|
||||||
const WEBROOT = path.resolve(__dirname, '..'); //路径
|
const WEBROOT = path.resolve(__dirname, '..'); //路径
|
||||||
const WEBROOT_SERVER = __dirname;
|
const WEBROOT_SERVER = __dirname;
|
||||||
const WEBROOT_RUNTIME = path.join(WEBROOT, 'runtime');
|
const WEBROOT_RUNTIME = path.resolve(__dirname, '../..');
|
||||||
const WEBROOT_LOG = path.join(WEBROOT_RUNTIME, 'log');
|
const WEBROOT_LOG = path.join(WEBROOT_RUNTIME, 'log');
|
||||||
const WEBCONFIG = config;
|
const WEBCONFIG = config;
|
||||||
|
|
||||||
fs.ensureDirSync(WEBROOT_RUNTIME);
|
|
||||||
fs.ensureDirSync(WEBROOT_LOG);
|
fs.ensureDirSync(WEBROOT_LOG);
|
||||||
|
|
||||||
if (WEBCONFIG.mail) {
|
if (WEBCONFIG.mail) {
|
||||||
|
@ -1,20 +0,0 @@
|
|||||||
'use strict';
|
|
||||||
|
|
||||||
module.exports = {
|
|
||||||
'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': '**********'
|
|
||||||
}
|
|
||||||
}
|
|
||||||
};
|
|
@ -141,7 +141,7 @@ exports.sendMail = function (options, cb) {
|
|||||||
|
|
||||||
try {
|
try {
|
||||||
_yapi2.default.mail.sendMail({
|
_yapi2.default.mail.sendMail({
|
||||||
from: _yapi2.default.WEBCONFIG.mail.auth.user,
|
from: _yapi2.default.WEBCONFIG.mail.from,
|
||||||
to: options.to,
|
to: options.to,
|
||||||
subject: 'yapi平台',
|
subject: 'yapi平台',
|
||||||
html: options.contents
|
html: options.contents
|
||||||
|
@ -18,6 +18,9 @@ var _config2 = _interopRequireDefault(_config);
|
|||||||
|
|
||||||
function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }
|
function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }
|
||||||
|
|
||||||
var configPath = _path2.default.join(_path2.default.resolve(__dirname, '../../'), 'runtime', 'config.json');
|
var runtimePath = _config2.default.runtime_path;
|
||||||
|
_fsExtra2.default.ensureDirSync(runtimePath);
|
||||||
|
_fsExtra2.default.ensureDirSync(_path2.default.join(runtimePath, 'log'));
|
||||||
|
var configPath = _path2.default.join(runtimePath, 'config.json');
|
||||||
|
|
||||||
_fsExtra2.default.writeFileSync(configPath, (0, _stringify2.default)(_config2.default, null, '\t'), { encoding: 'utf8' });
|
_fsExtra2.default.writeFileSync(configPath, (0, _stringify2.default)(_config2.default, null, '\t'), { encoding: 'utf8' });
|
@ -16,7 +16,7 @@ var _nodemailer = require('nodemailer');
|
|||||||
|
|
||||||
var _nodemailer2 = _interopRequireDefault(_nodemailer);
|
var _nodemailer2 = _interopRequireDefault(_nodemailer);
|
||||||
|
|
||||||
var _config = require('../runtime/config.json');
|
var _config = require('../../config.json');
|
||||||
|
|
||||||
var _config2 = _interopRequireDefault(_config);
|
var _config2 = _interopRequireDefault(_config);
|
||||||
|
|
||||||
@ -27,11 +27,10 @@ var mail = void 0;
|
|||||||
|
|
||||||
var WEBROOT = _path2.default.resolve(__dirname, '..'); //路径
|
var WEBROOT = _path2.default.resolve(__dirname, '..'); //路径
|
||||||
var WEBROOT_SERVER = __dirname;
|
var WEBROOT_SERVER = __dirname;
|
||||||
var WEBROOT_RUNTIME = _path2.default.join(WEBROOT, 'runtime');
|
var WEBROOT_RUNTIME = _path2.default.resolve(__dirname, '../..');
|
||||||
var WEBROOT_LOG = _path2.default.join(WEBROOT_RUNTIME, 'log');
|
var WEBROOT_LOG = _path2.default.join(WEBROOT_RUNTIME, 'log');
|
||||||
var WEBCONFIG = _config2.default;
|
var WEBCONFIG = _config2.default;
|
||||||
|
|
||||||
_fsExtra2.default.ensureDirSync(WEBROOT_RUNTIME);
|
|
||||||
_fsExtra2.default.ensureDirSync(WEBROOT_LOG);
|
_fsExtra2.default.ensureDirSync(WEBROOT_LOG);
|
||||||
|
|
||||||
if (WEBCONFIG.mail) {
|
if (WEBCONFIG.mail) {
|
||||||
|
39
service.sh
Normal file
39
service.sh
Normal file
@ -0,0 +1,39 @@
|
|||||||
|
#!/bin/bash
|
||||||
|
|
||||||
|
prog="/var/soft/node-v6.11.1-linux-x64/bin/pm2"
|
||||||
|
app="/home/q/www/yapi.beta.corp.qunar.com/webapp/server_dist/app.js"
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
start() {
|
||||||
|
echo "Starting Server..."
|
||||||
|
eval "$prog start $app --name=yapi"
|
||||||
|
}
|
||||||
|
|
||||||
|
stop() {
|
||||||
|
echo "Stopping Server..."
|
||||||
|
eval "$prog stop yapi"
|
||||||
|
}
|
||||||
|
|
||||||
|
restart() {
|
||||||
|
echo "Restart Server..."
|
||||||
|
eval "$prog restart yapi"
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
case "$1" in
|
||||||
|
start)
|
||||||
|
start && exit 0
|
||||||
|
;;
|
||||||
|
stop)
|
||||||
|
stop || exit 0
|
||||||
|
;;
|
||||||
|
restart)
|
||||||
|
restart || exit 0
|
||||||
|
;;
|
||||||
|
*)
|
||||||
|
echo $"Usage: $0 {start|stop|restart}"
|
||||||
|
exit 2
|
||||||
|
esac
|
Loading…
Reference in New Issue
Block a user