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

This commit is contained in:
wenbo.dong 2017-08-23 21:01:53 +08:00
commit 9550ef4a46
15 changed files with 9728 additions and 3700 deletions

View File

@ -22,8 +22,5 @@ module.exports = {
"comma-dangle": ["error", "never"],
"no-console": ["off"],
"import/no-unresolved": ["error"]
},
"globals": {
"ENV_PARAMS": true
}
}

View File

@ -3,7 +3,8 @@ import { createDevTools } from 'redux-devtools';
import LogMonitor from 'redux-devtools-log-monitor';
import DockMonitor from 'redux-devtools-dock-monitor';
export default createDevTools(
module.exports = createDevTools(
<DockMonitor
toggleVisibilityKey="ctrl-h"
changePositionKey="ctrl-q"
@ -11,4 +12,4 @@ export default createDevTools(
>
<LogMonitor />
</DockMonitor>
);
);

View File

@ -1,120 +0,0 @@
import React, { Component } from 'react'
import { Link } from 'react-router-dom'
import { Row, Col, Menu, AutoComplete, Input, Icon } from 'antd'
import axios from 'axios'
import { connect } from 'react-redux'
import PropTypes from 'prop-types'
import Avatar from './Avatar.js'
const Option = AutoComplete.Option;
@connect(
state => {
console.log(state);
return {
curUid: state.user.uid + '',
curUserName: state.user.userName,
curUserRole: state.user.role
}
}
)
class LeftMenu extends Component {
constructor(props) {
super(props)
this.state = {
dataSource: []
}
this.searchSign = 0;
this._searchSign = 0;
this.interval = null;
}
static propTypes = {
curUid: PropTypes.string,
curUserName: PropTypes.string,
curUserRole: PropTypes.string
}
//延迟搜索
handleSearch = (value) => {
if(!value || value.length < 1) return ;
this.searchSign = this.searchSign + 1;
this.interval && clearInterval(this.interval)
this.interval = setInterval(() => {
if (this.searchSign === this._searchSign) {
this.interval = clearInterval(this.interval)
axios.get('/api/user/search?q=' + value).then((res) => {
if (res.data.errcode === 0) {
this.setState({
dataSource: res.data.data
})
}
})
} else {
this._searchSign = this.searchSign;
}
}, 60)
}
renderOption = (item) => {
return (
<Option key={item.uid} text={item.username} >
<Link to={"/user/profile/" + item.uid} > {item.username} </Link>
</Option>
)
}
render() {
const menus = [{
title: '个人资料',
path: `/user/profile/${this.props.curUid}`
}
]
if(this.props.curUserRole === 'admin'){
menus.push({
title: '用户管理',
path: '/user/list'
})
}
let content = menus.map((menu) => {
return (
<Menu.Item key={'#' + menu.path} >
<Link to={menu.path} >{menu.title}</Link>
</Menu.Item>
)
})
const { dataSource } = this.state;
return (<div className="user-list">
<div className='cur-user'>
<Avatar />
<div className='user-name'><span>用户名 :</span>{`${this.props.curUserName}`}</div>
</div>
<Row type="flex" justify="start" className="search">
<Col span="24">
<div className="certain-category-search-wrapper" style={{ width: "100%" }}>
<AutoComplete
className="certain-category-search"
dropdownClassName="certain-category-search-dropdown"
size="large"
style={{ width: '100%' }}
dataSource={dataSource.map(this.renderOption)}
onSearch={this.handleSearch}
placeholder="搜索用户"
optionLabelProp="text"
>
<Input suffix={<Icon type="search" className="certain-category-icon" />} />
</AutoComplete>
</div>
</Col>
</Row>
<Menu mode='inline' defaultSelectedKeys={[location.hash]} className="user-nav">
{content}
</Menu>
</div>
)
}
}
export default LeftMenu

View File

@ -2,7 +2,6 @@ import './index.scss'
import React, { Component } from 'react'
import { connect } from 'react-redux'
import { Route } from 'react-router-dom'
// import LeftMenu from './LeftMenu.js'
import List from './List.js'
import PropTypes from 'prop-types'
import Profile from './Profile.js'

View File

@ -1,55 +0,0 @@
import './index.scss'
import React, { Component } from 'react'
import { connect } from 'react-redux'
import PropTypes from 'prop-types'
import Header from '../../components/Header/Header.js'
@connect(
state => {
return {
}
},
{
// fetchInterfaceData,
// projectMember,
// closeProjectMember
}
)
class user extends Component {
static propTypes = {
fetchInterfaceData: PropTypes.func,
interfaceData: PropTypes.array,
projectMember: PropTypes.func,
closeProjectMember: PropTypes.func,
modalVisible: PropTypes.bool
}
constructor(props) {
super(props)
}
componentWillMount () {
}
render () {
return (
<div>
<Header />
<section className="user-box">
<InterfaceList projectMember={projectMember} />
<InterfaceMode modalVisible={modalVisible} closeProjectMember={this.props.closeProjectMember} />
<InterfaceTable data={interfaceData} />
</section>
</div>
)
}
}
export default Interface

View File

@ -2,11 +2,7 @@ import Header from '../components/Header/Header.js'
import Home from './Home/Home.js'
import Login from './Login/LoginContainer.js'
import Group from './Group/Group.js'
import Interface from './Interface/Interface.js'
import Project from './Project/Project.js'
import News from './News/News.js'
import AddInterface from './AddInterface/AddInterface.js'
import DevTools from './DevTools/DevTools.js'
import Follows from './Follows/Follows.js'
import AddProject from './AddProject/AddProject.js'
@ -15,11 +11,7 @@ export {
Home,
Login,
Group,
Interface,
Project,
AddInterface,
News,
DevTools,
Follows,
AddProject
}

View File

@ -3,17 +3,28 @@ import ReactDOM from 'react-dom'
import App from './Application'
import { Provider } from 'react-redux'
import createStore from './reducer/create';
import { DevTools } from './containers';
import './styles/theme.less'
const store = createStore();
if (process.env.NODE_ENV === 'production') {
ReactDOM.render(
<Provider store={store}>
<div>
<App />
</div>
</Provider>,
document.getElementById('yapi')
)
} else {
const DevTools = require('./containers/DevTools/DevTools.js')
ReactDOM.render(
<Provider store={store}>
<div>
<App />
<DevTools />
</div>
</Provider>,
document.getElementById('yapi')
)
}
ReactDOM.render(
<Provider store={store}>
<div>
<App />
<DevTools />
</div>
</Provider>,
document.getElementById('yapi')
)

View File

@ -8,15 +8,13 @@ export default function createStore(initialState = {}) {
const middleware = [thunkMiddleware, promiseMiddleware, messageMiddleware];
let finalCreateStore;
if (ENV_PARAMS.development) {
if (process.env.NODE_ENV === 'production') {
finalCreateStore = applyMiddleware(...middleware)(_createStore);
} else {
finalCreateStore = compose(
applyMiddleware(...middleware),
window.devToolsExtension ? window.devToolsExtension() : require('../containers/DevTools/DevTools').default.instrument()
window.devToolsExtension ? window.devToolsExtension() : require('../containers/DevTools/DevTools').instrument()
)(_createStore);
} else {
finalCreateStore = applyMiddleware(...middleware)(_createStore);
}
const store = finalCreateStore(reducer, initialState);

9668
npm-shrinkwrap.json generated Normal file

File diff suppressed because it is too large Load Diff

3476
package-lock.json generated

File diff suppressed because it is too large Load Diff

View File

@ -46,7 +46,7 @@
"eslint-plugin-import": "^2.2.0",
"eslint-plugin-react": "^7.1.0",
"express": "^4.15.3",
"extract-text-webpack-plugin": "^1.0.1",
"extract-text-webpack-plugin": "2.0.0",
"fast-sass-loader": "^1.2.5",
"fs-extra": "^3.0.1",
"gulp": "^3.9.1",
@ -58,6 +58,7 @@
"jsonwebtoken": "^7.4.1",
"koa": "^2.0.0",
"koa-bodyparser": "^3.2.0",
"koa-compress": "^2.0.0",
"koa-logger": "^3.0.0",
"koa-mysql-session": "0.0.2",
"koa-router": "^7.0.1",
@ -83,10 +84,8 @@
"rc-scroll-anim": "^1.0.7",
"react": "^15.6.1",
"react-dom": "^15.6.1",
"react-monaco-editor": "^0.8.1",
"react-redux": "^5.0.5",
"react-router-dom": "^4.1.1",
"react-router-redux": "^4.0.8",
"react-scripts": "1.0.10",
"redux": "^3.7.1",
"redux-promise": "^0.5.3",
@ -101,9 +100,7 @@
"universal-cookie": "^2.0.8",
"url": "^0.11.0",
"validate-commit-msg": "^2.12.2",
"wangeditor": "^3.0.4",
"ykit-config-antd": "^0.1.3",
"ykit-config-react": "^0.4.4"
"ykit-config-antd": "^0.1.3"
},
"devDependencies": {
"babel-plugin-import": "^1.3.1",

View File

@ -10,6 +10,7 @@ import router from './router.js';
import websockify from 'koa-websocket';
import websocket from './websocket.js'
var compress = require('koa-compress')
yapi.connect = dbModule.connect();
const app = websockify(new Koa());
@ -23,6 +24,11 @@ app.use(router.allowedMethods());
websocket(app);
app.use(compress({
threshold: 2048,
flush: require('zlib').Z_SYNC_FLUSH
}))
app.use( async (ctx, next) => {
if( /^\/(?!api)[a-zA-Z0-9\/\-_]*$/.test(ctx.path) ){
ctx.path = "/"
@ -34,7 +40,7 @@ app.use( async (ctx, next) => {
})
app.use(koaStatic(
yapi.path.join(yapi.WEBROOT, 'static'),
{index: indexFile}
{index: indexFile, gzip: true}
));
app.listen(yapi.WEBCONFIG.port);

View File

@ -53,6 +53,8 @@ function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { de
_yapi2.default.commons = _commons2.default;
var compress = require('koa-compress');
_yapi2.default.connect = _db2.default.connect();
var app = (0, _koaWebsocket2.default)(new _koa2.default());
var indexFile = process.argv[2] === 'dev' ? 'dev.html' : 'index.html';
@ -64,8 +66,13 @@ app.use(_router2.default.allowedMethods());
(0, _websocket2.default)(app);
app.use(compress({
threshold: 2048,
flush: require('zlib').Z_SYNC_FLUSH
}));
app.use(function () {
var _ref = (0, _asyncToGenerator3.default)( /*#__PURE__*/_regenerator2.default.mark(function _callee(ctx, next) {
var _ref = (0, _asyncToGenerator3.default)(_regenerator2.default.mark(function _callee(ctx, next) {
return _regenerator2.default.wrap(function _callee$(_context) {
while (1) {
switch (_context.prev = _context.next) {
@ -99,7 +106,7 @@ app.use(function () {
return _ref.apply(this, arguments);
};
}());
app.use((0, _koaStatic2.default)(_yapi2.default.path.join(_yapi2.default.WEBROOT, 'static'), { index: indexFile }));
app.use((0, _koaStatic2.default)(_yapi2.default.path.join(_yapi2.default.WEBROOT, 'static'), { index: indexFile, gzip: true }));
app.listen(_yapi2.default.WEBCONFIG.port);
_commons2.default.log('the server is start at port ' + _yapi2.default.WEBCONFIG.port);

View File

@ -5,7 +5,7 @@
<meta name="viewport" content="width=device-width, initial-scale=1, shrink-to-fit=no">
<title>YAPI-高效、易用、功能强大的api管理平台</title>
<script>
document.write('<script src="prd/assets.js?v=' + Math.random() + '"><\/script>');
document.write('<script src="/prd/assets.js?v=' + Math.random() + '"><\/script>');
</script>

21
ykit.js
View File

@ -9,19 +9,22 @@ var assetsPluginInstance = new AssetsPlugin({
function handleCommonsChunk(webpackConfig) {
var commonsChunk = {
//filename: 'scripts/[name]@[chunkhash][ext]',
vendors: {
lib: ['react', 'redux',
'redux-thunk',
'react-dom',
'redux-promise',
'react-router',
'react-router-dom',
'prop-types'
],
lib2: [
'prop-types',
'axios',
'moment'
],
lib2: [
'brace',
'mockjs',
'json5'
]
}
},
@ -93,19 +96,19 @@ module.exports = {
var ENV_PARAMS = {};
switch (this.env) {
case 'local':
ENV_PARAMS = { development: true };
ENV_PARAMS = 'dev';
break;
case 'dev':
ENV_PARAMS = { development: true };
ENV_PARAMS = 'dev';
break;
case 'prd':
ENV_PARAMS = { development: false };
ENV_PARAMS = 'production';
break;
default:
}
baseConfig.plugins.push(new this.webpack.DefinePlugin({
ENV_PARAMS: JSON.stringify(ENV_PARAMS)
'process.env.NODE_ENV': JSON.stringify(ENV_PARAMS)
}))
//初始化配置