feat: add plugin module

This commit is contained in:
suxiaoxin 2017-09-05 10:24:13 +08:00
parent 3b5997ea95
commit 9895dd5d0f
16 changed files with 187 additions and 17 deletions

View File

@ -40,4 +40,5 @@ module.exports = {
"strict": 0,
"comma-dangle": ["error", "never"]
}
};
};

View File

@ -31,6 +31,7 @@
"/fekit_modules/*",
"/node_modules/*",
"/bower_components/*",
"/plugins/*",
"/dev/*",
"/prd/*"
]

View File

@ -7,8 +7,7 @@ import PropTypes from "prop-types";
import { withRouter } from 'react-router';
import { logoSVG, getImgPath } from '../../common.js';
import { changeMenuItem } from '../../reducer/modules/menu'
import Qsso from '../../components/Qsso/Qsso.js'
import Plugins from '../../plugin.js'
const HomeGuest = () => (
<div className="g-body">
<div className="m-bg">
@ -37,7 +36,11 @@ const HomeGuest = () => (
<div className="detail">高效易用功能强大的API管理平台<br /><span className="desc">旨在为开发产品测试人员提供更优雅的接口管理服务</span></div>
<div className="btn-group">
<Link to="/login"><Button type="primary" className="btn-home btn-login">登录 / 注册</Button></Link>
<Button className="btn-home btn-home-normal" id="qsso-login">QSSO 登录</Button>
{Plugins.third_login.component != null ?
<Plugins.third_login.component />
: null
}
</div>
</div>
</Col>
@ -181,7 +184,7 @@ class Home extends Component {
}
componentDidMount() {
Qsso.attach('qsso-login', '/api/user/login_by_token')
}
static propTypes = {
introList: PropTypes.array,

View File

@ -68,6 +68,8 @@ $color-bg-lightblue: #c6e2ff;
&:hover, &:focus {
background-color: #f6f9fc;
}
background-color: #fff;
cursor: pointer;
}
}

View File

@ -6,7 +6,7 @@ import { loginActions } from '../../reducer/modules/user';
import { withRouter } from 'react-router'
const FormItem = Form.Item;
import './Login.scss'
import Qsso from '../../components/Qsso/Qsso.js'
// import Qsso from '../../components/Qsso/Qsso.js'
const formItemStyle = {
marginBottom: '.16rem'
@ -54,7 +54,7 @@ class Login extends Component {
}
componentDidMount() {
Qsso.attach('qsso-login','/api/user/login_by_token')
//Qsso.attach('qsso-login','/api/user/login_by_token')
}

View File

@ -1,3 +1,4 @@
import './plugin'
import React from 'react'
import ReactDOM from 'react-dom'
import App from './Application'

34
client/plugin.js Normal file
View File

@ -0,0 +1,34 @@
const config = process.env.config;
var hooks = {
'third_login': {
type: 'single',
component: null
},
'add_interface': {
type: 'mulit',
component: []
}
};
function bindHook(name, component) {
if (!name) throw new Error('缺少hookname');
if (name in hooks === false) {
throw new Error('不存在的hookname');
}
if (hooks[name].type === 'multi') {
hooks[name].component.push(component);
} else {
hooks[name].component = component;
}
}
if (config.plugins && Array.isArray(config.plugins)) {
config.plugins.forEach(plugin => {
let pluginModule = require(`/Users/sean/qunar/yapi/yapi/node_modules/yapi-plugin-${plugin}/client.js`);
pluginModule(bindHook);
})
}
module.exports = hooks;

View File

@ -1,3 +1,3 @@
{
"watch": ["server/"]
"watch": ["server/", "common/", "plugins"]
}

19
plugins/qsso/client.js Normal file
View File

@ -0,0 +1,19 @@
import React from 'react';
const Qsso = require('./Qsso.js');
class QssoComponent extends React.Component{
componentDidMount(){
Qsso.attach('qsso-login', '/api/user/login_by_token')
}
render(){
return <button id="qsso-login" className="btn-home btn-home-normal" >QSSO 登录</button>
}
}
module.exports = function(bindHook){
bindHook('third_login', QssoComponent);
};

28
plugins/qsso/server.js Normal file
View File

@ -0,0 +1,28 @@
const request = require('request');
module.exports = function () {
this.bindHook('third_login', () => {
return {
request: (token) => {
return new Promise((resolve, reject) => {
request('http://qsso.corp.qunar.com/api/verifytoken.php?token=' + token, function (error, response, body) {
if (!error && response.statusCode == 200) {
let result = JSON.parse(body);
if (result && result.ret === true) {
let ret = {
email: result.userId + '@qunar.com',
username: result.data.userInfo.name
};
resolve(ret);
} else {
reject(result);
}
}
reject(error);
});
});
},
tokenField: 'token'
};
})
}

View File

@ -9,12 +9,14 @@ const bodyParser = require('koa-bodyparser');
const router = require('./router.js');
const websockify = require('koa-websocket');
const websocket = require('./websocket.js');
const plugins = require('./plugin.js');
yapi.connect = dbModule.connect();
const app = websockify(new Koa());
let indexFile = process.argv[2] === 'dev' ? 'dev.html' : 'index.html';
yapi.connect = dbModule.connect();
const app = websockify(new Koa());
yapi.app = app;
plugins();
app.use(mockServer);
app.use(bodyParser({multipart: true}));
app.use(router.routes());

View File

@ -109,7 +109,8 @@ class userController extends baseController {
}
async loginByToken(ctx) {
let config = this.thirdQunarLogin();
//let config = this.thirdQunarLogin();
let config = yapi.emitHook('third_login');
let token = ctx.request.body[config.tokenField] || ctx.request.query[config.tokenField];
try {

11
server/plugin.js Normal file
View File

@ -0,0 +1,11 @@
const yapi = require('./yapi.js');
const plugin_path = yapi.path.join(yapi.WEBROOT, 'plugins')
module.exports = function(){
if(yapi.WEBCONFIG.plugins && Array.isArray(yapi.WEBCONFIG.plugins)){
yapi.WEBCONFIG.plugins.forEach(plugin=>{
let pluginModule = require(yapi.path.join(plugin_path, 'qsso/server.js'));
pluginModule.call(yapi)
})
}
}

View File

@ -39,6 +39,48 @@ function delInst(m) {
}
}
var hooks = {
'third_login': {
type: 'single',
listener: null
},
'add_interface': {
type: 'mulit',
listener: []
}
};
function bindHook(name, listener){
if(!name) throw new Error('缺少hookname');
if(name in hooks === false){
throw new Error('不存在的hookname');
}
if(hooks[name].type === 'multi'){
hooks[name].listener.push(listener);
}else{
hooks[name].listener = listener;
}
}
function emitHook(name){
if(!name) throw new Error('缺少hookname');
if(name in hooks === false){
throw new Error('不存在的hookname');
}
if(hooks[name] && typeof hooks[name] === 'object'){
if(hooks[name].type === 'single' && typeof hooks[name].listener === 'function'){
return hooks[name].listener.call();
}
if(Array.isArray(hooks[name.listener])){
hooks[name].listener.forEach(listener=>{
listener.call()
})
}
}
}
let r = {
fs: fs,
path: path,
@ -49,7 +91,9 @@ let r = {
WEBCONFIG: WEBCONFIG,
getInst: getInst,
delInst: delInst,
getInsts: insts
getInsts: insts,
emitHook: emitHook,
bindHook: bindHook
};
if (mail) r.mail = mail;
module.exports = r;

31
ykit.js
View File

@ -1,12 +1,32 @@
var path = require('path');
var fs = require('fs');
var AssetsPlugin = require('assets-webpack-plugin')
var CompressionPlugin = require('compression-webpack-plugin')
var config = require('../config.json');
var assetsPluginInstance = new AssetsPlugin({
filename: 'static/prd/assets.js',
processOutput: function (assets) {
return 'window.WEBPACK_ASSETS = ' + JSON.stringify(assets);
}
})
});
function fileExist (filePath){
try {
return fs.statSync(filePath).isFile();
} catch (err) {
return false;
}
};
function initPlugins(){
if(config.plugins && Array.isArray(config.plugins)){
config.plugins = config.plugins.filter(item=>{
return fileExist(path.resolve(__dirname, 'node_modules/yapi-plugin-' + item + '/client.js'))
})
}
}
initPlugins();
var compressPlugin = new CompressionPlugin({
asset: "[path].gz[query]",
@ -93,7 +113,8 @@ module.exports = {
defaultQuery.plugins.push('transform-decorators-legacy');
defaultQuery.plugins.push(["import", { libraryName: "antd"}])
return defaultQuery;
}
},
exclude: /node_modules(?!\/yapi\-plugin\-)/
}
}],
// devtool: 'cheap-source-map',
@ -119,13 +140,15 @@ module.exports = {
}
baseConfig.plugins.push(new this.webpack.DefinePlugin({
'process.env.NODE_ENV': JSON.stringify(ENV_PARAMS)
'process.env.NODE_ENV': JSON.stringify(ENV_PARAMS),
'process.env.config': JSON.stringify(config)
}))
//初始化配置
baseConfig.devtool = 'cheap-module-eval-source-map'
baseConfig.context = path.resolve(__dirname, './client');
baseConfig.resolve.alias.common = '/common';
baseConfig.resolve.alias.plugins = '/node_modules';
baseConfig.output.prd.path = 'static/prd';
baseConfig.output.prd.publicPath = '';
baseConfig.output.prd.filename = '[name]@[chunkhash][ext]'
@ -151,7 +174,7 @@ module.exports = {
})
baseConfig.module.preLoaders.push({
test: /\.(js|jsx)$/,
exclude: /node_modules/,
exclude: /node_modules|plugins/,
loader: "eslint-loader"
});