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,
|
"strict": 0,
|
||||||
"comma-dangle": ["error", "never"]
|
"comma-dangle": ["error", "never"]
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -31,6 +31,7 @@
|
|||||||
"/fekit_modules/*",
|
"/fekit_modules/*",
|
||||||
"/node_modules/*",
|
"/node_modules/*",
|
||||||
"/bower_components/*",
|
"/bower_components/*",
|
||||||
|
"/plugins/*",
|
||||||
"/dev/*",
|
"/dev/*",
|
||||||
"/prd/*"
|
"/prd/*"
|
||||||
]
|
]
|
||||||
|
@ -7,8 +7,7 @@ import PropTypes from "prop-types";
|
|||||||
import { withRouter } from 'react-router';
|
import { withRouter } from 'react-router';
|
||||||
import { logoSVG, getImgPath } from '../../common.js';
|
import { logoSVG, getImgPath } from '../../common.js';
|
||||||
import { changeMenuItem } from '../../reducer/modules/menu'
|
import { changeMenuItem } from '../../reducer/modules/menu'
|
||||||
import Qsso from '../../components/Qsso/Qsso.js'
|
import Plugins from '../../plugin.js'
|
||||||
|
|
||||||
const HomeGuest = () => (
|
const HomeGuest = () => (
|
||||||
<div className="g-body">
|
<div className="g-body">
|
||||||
<div className="m-bg">
|
<div className="m-bg">
|
||||||
@ -37,7 +36,11 @@ const HomeGuest = () => (
|
|||||||
<div className="detail">高效、易用、功能强大的API管理平台<br /><span className="desc">旨在为开发、产品、测试人员提供更优雅的接口管理服务</span></div>
|
<div className="detail">高效、易用、功能强大的API管理平台<br /><span className="desc">旨在为开发、产品、测试人员提供更优雅的接口管理服务</span></div>
|
||||||
<div className="btn-group">
|
<div className="btn-group">
|
||||||
<Link to="/login"><Button type="primary" className="btn-home btn-login">登录 / 注册</Button></Link>
|
<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>
|
||||||
</div>
|
</div>
|
||||||
</Col>
|
</Col>
|
||||||
@ -181,7 +184,7 @@ class Home extends Component {
|
|||||||
}
|
}
|
||||||
|
|
||||||
componentDidMount() {
|
componentDidMount() {
|
||||||
Qsso.attach('qsso-login', '/api/user/login_by_token')
|
|
||||||
}
|
}
|
||||||
static propTypes = {
|
static propTypes = {
|
||||||
introList: PropTypes.array,
|
introList: PropTypes.array,
|
||||||
|
@ -68,6 +68,8 @@ $color-bg-lightblue: #c6e2ff;
|
|||||||
&:hover, &:focus {
|
&:hover, &:focus {
|
||||||
background-color: #f6f9fc;
|
background-color: #f6f9fc;
|
||||||
}
|
}
|
||||||
|
background-color: #fff;
|
||||||
|
cursor: pointer;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -6,7 +6,7 @@ import { loginActions } from '../../reducer/modules/user';
|
|||||||
import { withRouter } from 'react-router'
|
import { withRouter } from 'react-router'
|
||||||
const FormItem = Form.Item;
|
const FormItem = Form.Item;
|
||||||
import './Login.scss'
|
import './Login.scss'
|
||||||
import Qsso from '../../components/Qsso/Qsso.js'
|
// import Qsso from '../../components/Qsso/Qsso.js'
|
||||||
|
|
||||||
const formItemStyle = {
|
const formItemStyle = {
|
||||||
marginBottom: '.16rem'
|
marginBottom: '.16rem'
|
||||||
@ -54,7 +54,7 @@ class Login extends Component {
|
|||||||
}
|
}
|
||||||
|
|
||||||
componentDidMount() {
|
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 React from 'react'
|
||||||
import ReactDOM from 'react-dom'
|
import ReactDOM from 'react-dom'
|
||||||
import App from './Application'
|
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 router = require('./router.js');
|
||||||
const websockify = require('koa-websocket');
|
const websockify = require('koa-websocket');
|
||||||
const websocket = require('./websocket.js');
|
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';
|
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(mockServer);
|
||||||
app.use(bodyParser({multipart: true}));
|
app.use(bodyParser({multipart: true}));
|
||||||
app.use(router.routes());
|
app.use(router.routes());
|
||||||
|
@ -109,7 +109,8 @@ class userController extends baseController {
|
|||||||
}
|
}
|
||||||
|
|
||||||
async loginByToken(ctx) {
|
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];
|
let token = ctx.request.body[config.tokenField] || ctx.request.query[config.tokenField];
|
||||||
|
|
||||||
try {
|
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 = {
|
let r = {
|
||||||
fs: fs,
|
fs: fs,
|
||||||
path: path,
|
path: path,
|
||||||
@ -49,7 +91,9 @@ let r = {
|
|||||||
WEBCONFIG: WEBCONFIG,
|
WEBCONFIG: WEBCONFIG,
|
||||||
getInst: getInst,
|
getInst: getInst,
|
||||||
delInst: delInst,
|
delInst: delInst,
|
||||||
getInsts: insts
|
getInsts: insts,
|
||||||
|
emitHook: emitHook,
|
||||||
|
bindHook: bindHook
|
||||||
};
|
};
|
||||||
if (mail) r.mail = mail;
|
if (mail) r.mail = mail;
|
||||||
module.exports = r;
|
module.exports = r;
|
31
ykit.js
31
ykit.js
@ -1,12 +1,32 @@
|
|||||||
var path = require('path');
|
var path = require('path');
|
||||||
|
var fs = require('fs');
|
||||||
var AssetsPlugin = require('assets-webpack-plugin')
|
var AssetsPlugin = require('assets-webpack-plugin')
|
||||||
var CompressionPlugin = require('compression-webpack-plugin')
|
var CompressionPlugin = require('compression-webpack-plugin')
|
||||||
|
var config = require('../config.json');
|
||||||
var assetsPluginInstance = new AssetsPlugin({
|
var assetsPluginInstance = new AssetsPlugin({
|
||||||
filename: 'static/prd/assets.js',
|
filename: 'static/prd/assets.js',
|
||||||
processOutput: function (assets) {
|
processOutput: function (assets) {
|
||||||
return 'window.WEBPACK_ASSETS = ' + JSON.stringify(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({
|
var compressPlugin = new CompressionPlugin({
|
||||||
asset: "[path].gz[query]",
|
asset: "[path].gz[query]",
|
||||||
@ -93,7 +113,8 @@ module.exports = {
|
|||||||
defaultQuery.plugins.push('transform-decorators-legacy');
|
defaultQuery.plugins.push('transform-decorators-legacy');
|
||||||
defaultQuery.plugins.push(["import", { libraryName: "antd"}])
|
defaultQuery.plugins.push(["import", { libraryName: "antd"}])
|
||||||
return defaultQuery;
|
return defaultQuery;
|
||||||
}
|
},
|
||||||
|
exclude: /node_modules(?!\/yapi\-plugin\-)/
|
||||||
}
|
}
|
||||||
}],
|
}],
|
||||||
// devtool: 'cheap-source-map',
|
// devtool: 'cheap-source-map',
|
||||||
@ -119,13 +140,15 @@ module.exports = {
|
|||||||
}
|
}
|
||||||
|
|
||||||
baseConfig.plugins.push(new this.webpack.DefinePlugin({
|
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.devtool = 'cheap-module-eval-source-map'
|
||||||
baseConfig.context = path.resolve(__dirname, './client');
|
baseConfig.context = path.resolve(__dirname, './client');
|
||||||
baseConfig.resolve.alias.common = '/common';
|
baseConfig.resolve.alias.common = '/common';
|
||||||
|
baseConfig.resolve.alias.plugins = '/node_modules';
|
||||||
baseConfig.output.prd.path = 'static/prd';
|
baseConfig.output.prd.path = 'static/prd';
|
||||||
baseConfig.output.prd.publicPath = '';
|
baseConfig.output.prd.publicPath = '';
|
||||||
baseConfig.output.prd.filename = '[name]@[chunkhash][ext]'
|
baseConfig.output.prd.filename = '[name]@[chunkhash][ext]'
|
||||||
@ -151,7 +174,7 @@ module.exports = {
|
|||||||
})
|
})
|
||||||
baseConfig.module.preLoaders.push({
|
baseConfig.module.preLoaders.push({
|
||||||
test: /\.(js|jsx)$/,
|
test: /\.(js|jsx)$/,
|
||||||
exclude: /node_modules/,
|
exclude: /node_modules|plugins/,
|
||||||
loader: "eslint-loader"
|
loader: "eslint-loader"
|
||||||
});
|
});
|
||||||
|
|
||||||
|
Loading…
Reference in New Issue
Block a user