mirror of
https://github.com/YMFE/yapi.git
synced 2025-03-07 14:16:52 +08:00
feat: add plugin module
This commit is contained in:
parent
3b5997ea95
commit
9895dd5d0f
@ -40,4 +40,5 @@ module.exports = {
|
||||
"strict": 0,
|
||||
"comma-dangle": ["error", "never"]
|
||||
}
|
||||
};
|
||||
};
|
||||
|
||||
|
@ -31,6 +31,7 @@
|
||||
"/fekit_modules/*",
|
||||
"/node_modules/*",
|
||||
"/bower_components/*",
|
||||
"/plugins/*",
|
||||
"/dev/*",
|
||||
"/prd/*"
|
||||
]
|
||||
|
@ -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,
|
||||
|
@ -68,6 +68,8 @@ $color-bg-lightblue: #c6e2ff;
|
||||
&:hover, &:focus {
|
||||
background-color: #f6f9fc;
|
||||
}
|
||||
background-color: #fff;
|
||||
cursor: pointer;
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -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')
|
||||
}
|
||||
|
||||
|
||||
|
@ -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
34
client/plugin.js
Normal 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;
|
@ -1,3 +1,3 @@
|
||||
{
|
||||
"watch": ["server/"]
|
||||
"watch": ["server/", "common/", "plugins"]
|
||||
}
|
19
plugins/qsso/client.js
Normal file
19
plugins/qsso/client.js
Normal 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
28
plugins/qsso/server.js
Normal 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'
|
||||
};
|
||||
})
|
||||
}
|
@ -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());
|
||||
|
@ -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
11
server/plugin.js
Normal 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)
|
||||
})
|
||||
}
|
||||
}
|
@ -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
31
ykit.js
@ -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"
|
||||
});
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user