mirror of
https://github.com/YMFE/yapi.git
synced 2025-03-07 14:16:52 +08:00
feat: 获取项目token值
This commit is contained in:
parent
87902b93d1
commit
a58ae58c89
@ -1,4 +1,13 @@
|
||||
|
||||
### v1.3.6
|
||||
|
||||
#### Feature
|
||||
|
||||
* 增加导出公共接口功能
|
||||
* 增加复制接口路径按钮
|
||||
* 每个项目有以后都有一个唯一的token
|
||||
* antd升级到3
|
||||
|
||||
### v1.3.5
|
||||
|
||||
#### Feature
|
||||
|
@ -2,13 +2,14 @@ import './View.scss'
|
||||
import React, { PureComponent as Component } from 'react'
|
||||
import { connect } from 'react-redux'
|
||||
import PropTypes from 'prop-types'
|
||||
import { Table, Icon, Row, Col } from 'antd'
|
||||
import { Table, Icon, Row, Col, Tooltip, message } from 'antd'
|
||||
import { Link } from 'react-router-dom'
|
||||
import AceEditor from 'client/components/AceEditor/AceEditor';
|
||||
import { formatTime } from '../../../../common.js';
|
||||
import ErrMsg from '../../../../components/ErrMsg/ErrMsg.js';
|
||||
import variable from '../../../../constants/variable';
|
||||
import constants from '../../../../constants/variable.js'
|
||||
import copy from 'copy-to-clipboard';
|
||||
|
||||
const HTTP_METHOD = constants.HTTP_METHOD;
|
||||
|
||||
@ -25,7 +26,8 @@ class View extends Component {
|
||||
constructor(props) {
|
||||
super(props);
|
||||
this.state = {
|
||||
init: true
|
||||
init: true,
|
||||
enter: false
|
||||
}
|
||||
}
|
||||
static propTypes = {
|
||||
@ -167,6 +169,23 @@ class View extends Component {
|
||||
}
|
||||
}
|
||||
|
||||
enterItem =() =>{
|
||||
this.setState({
|
||||
enter: true
|
||||
})
|
||||
}
|
||||
|
||||
leaveItem = () =>{
|
||||
this.setState({
|
||||
enter: false
|
||||
})
|
||||
}
|
||||
|
||||
copyUrl = (url) =>{
|
||||
copy(url)
|
||||
message.success('已经成功复制到剪切板');
|
||||
}
|
||||
|
||||
|
||||
render() {
|
||||
const dataSource = [];
|
||||
@ -279,9 +298,12 @@ class View extends Component {
|
||||
</Row>
|
||||
<Row className="row">
|
||||
<Col span={4} className="colKey">接口路径:</Col>
|
||||
<Col span={18} className="colValue">
|
||||
<Col span={18} className="colValue" onMouseEnter={this.enterItem} onMouseLeave={this.leaveItem}>
|
||||
<span style={{ color: methodColor.color, backgroundColor: methodColor.bac }} className="colValue tag-method">{this.props.curData.method}</span>
|
||||
<span className="colValue">{this.props.currProject.basepath}{this.props.curData.path}</span>
|
||||
<Tooltip title="复制路径">
|
||||
<Icon type='copy' className="interface-url-icon" onClick={() => this.copyUrl(this.props.curData.path) } style={{ display: this.state.enter ? 'inline-block' : 'none' }}/>
|
||||
</Tooltip>
|
||||
</Col>
|
||||
</Row>
|
||||
<Row className="row">
|
||||
|
@ -31,6 +31,10 @@
|
||||
.ace_print-margin{
|
||||
display: none;
|
||||
}
|
||||
|
||||
.interface-url-icon{
|
||||
padding-left: 8px;
|
||||
}
|
||||
.colBody{
|
||||
.query-icon {
|
||||
display: inline-block;
|
||||
|
@ -1,13 +1,75 @@
|
||||
import React, {Component} from 'react'
|
||||
import PropTypes from 'prop-types'
|
||||
import './ProjectToken.scss'
|
||||
import { getToken, updateToken } from '../../../../reducer/modules/project';
|
||||
import { connect } from 'react-redux';
|
||||
import { Icon, Tooltip, message, Modal } from 'antd';
|
||||
import copy from 'copy-to-clipboard';
|
||||
const confirm = Modal.confirm;
|
||||
|
||||
|
||||
|
||||
@connect(
|
||||
state => {
|
||||
return {
|
||||
token: state.project.token
|
||||
}
|
||||
},
|
||||
{
|
||||
getToken,
|
||||
updateToken
|
||||
}
|
||||
)
|
||||
class ProjectToken extends Component {
|
||||
|
||||
static propTypes = {
|
||||
projectId: PropTypes.number,
|
||||
getToken: PropTypes.func,
|
||||
token: PropTypes.string,
|
||||
updateToken: PropTypes.func
|
||||
}
|
||||
|
||||
async componentDidMount() {
|
||||
await this.props.getToken(this.props.projectId);
|
||||
|
||||
}
|
||||
|
||||
copyToken = () => {
|
||||
copy(this.props.token)
|
||||
message.success('已经成功复制到剪切板');
|
||||
}
|
||||
|
||||
updateToken = () =>{
|
||||
let that = this;
|
||||
confirm({
|
||||
title: '重新生成key',
|
||||
content: '重新生成之后,之前的key将无法使用,确认重新生成吗?',
|
||||
okText: "确认",
|
||||
cancelText: "取消",
|
||||
async onOk() {
|
||||
await that.props.updateToken(that.props.projectId);
|
||||
message.success('更新成功');
|
||||
},
|
||||
onCancel() {}
|
||||
});
|
||||
}
|
||||
|
||||
|
||||
render() {
|
||||
|
||||
return (
|
||||
<div className="project-token"></div>
|
||||
<div className="project-token">
|
||||
<div className="token">
|
||||
<span>key值: <span className="token-message">{this.props.token}</span></span>
|
||||
<Tooltip title="复制">
|
||||
<Icon className="token-btn" type="copy" onClick={this.copyToken}/>
|
||||
</Tooltip>
|
||||
<Tooltip title="刷新">
|
||||
<Icon className="token-btn" type="reload" onClick={this.updateToken} />
|
||||
</Tooltip>
|
||||
</div>
|
||||
|
||||
</div>
|
||||
)
|
||||
}
|
||||
}
|
||||
|
@ -2,4 +2,21 @@
|
||||
background: #fff;
|
||||
padding: 15px;
|
||||
min-height: 4.68rem;
|
||||
|
||||
.token{
|
||||
padding: 16px;
|
||||
font-size: 16px;
|
||||
font-weight: 500;
|
||||
}
|
||||
|
||||
.token-message{
|
||||
padding: 8px;
|
||||
margin-right: 8px;
|
||||
background-color: #fafafa;
|
||||
|
||||
}
|
||||
|
||||
.token-btn{
|
||||
margin-right: 8px;
|
||||
}
|
||||
}
|
@ -14,6 +14,8 @@ const GET_PEOJECT_MEMBER = 'yapi/project/GET_PEOJECT_MEMBER';
|
||||
const ADD_PROJECT_MEMBER = 'yapi/project/ADD_PROJECT_MEMBER';
|
||||
const DEL_PROJECT_MEMBER = 'yapi/project/DEL_PROJECT_MEMBER';
|
||||
const CHANGE_PROJECT_MEMBER = 'yapi/project/CHANGE_PROJECT_MEMBER';
|
||||
const GET_TOKEN = 'yapi/project/GET_TOKEN';
|
||||
const UPDATE_TOKEN = 'yapi/project/UPDATE_TOKEN';
|
||||
|
||||
// Reducer
|
||||
const initialState = {
|
||||
@ -25,6 +27,7 @@ const initialState = {
|
||||
tableLoading: true,
|
||||
total: 0,
|
||||
currPage: 1,
|
||||
token: '',
|
||||
currProject: {
|
||||
}
|
||||
};
|
||||
@ -54,6 +57,19 @@ export default (state = initialState, action) => {
|
||||
case PROJECT_DEL: {
|
||||
return state;
|
||||
}
|
||||
|
||||
case GET_TOKEN: {
|
||||
return {
|
||||
...state,
|
||||
token: action.payload.data.data
|
||||
}
|
||||
}
|
||||
case UPDATE_TOKEN: {
|
||||
return {
|
||||
...state,
|
||||
token: action.payload.data.data.token
|
||||
}
|
||||
}
|
||||
default:
|
||||
return state;
|
||||
}
|
||||
@ -209,3 +225,23 @@ export async function getProject(id) {
|
||||
payload: result
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
export async function getToken(project_id){
|
||||
return {
|
||||
type: GET_TOKEN,
|
||||
payload: axios.get('/api/project/token', {
|
||||
params: { project_id }
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
export async function updateToken(project_id){
|
||||
return {
|
||||
type: UPDATE_TOKEN,
|
||||
payload: axios.get('/api/project/update_token', {
|
||||
params: { project_id }
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -31,6 +31,7 @@
|
||||
"antd": "^3.1.6",
|
||||
"anujs": "^1.2.8",
|
||||
"axios": "^0.16.2",
|
||||
"copy-to-clipboard": "^3.0.8",
|
||||
"cpu-load": "^1.0.0",
|
||||
"deep-extend": "^0.5.0",
|
||||
"deref": "^0.7.0",
|
||||
|
@ -23,12 +23,17 @@ class openController extends baseController{
|
||||
}
|
||||
}
|
||||
|
||||
async getProjectIdByToken(token){
|
||||
return '111'
|
||||
}
|
||||
|
||||
async projectInterfaceData(ctx){
|
||||
ctx.body = 'projectInterfaceData'
|
||||
}
|
||||
|
||||
async runAutoTest(ctx){
|
||||
let id = ctx.params.id;
|
||||
let token = ctx.params.token;
|
||||
let curEnv = ctx.params.env_name;
|
||||
let colData = await this.interfaceColModel.get(id);
|
||||
let projectId = colData.project_id;
|
||||
|
@ -11,6 +11,8 @@ const commons = require('../utils/commons.js');
|
||||
const userModel = require('../models/user.js');
|
||||
const logModel = require('../models/log.js');
|
||||
const followModel = require('../models/follow.js');
|
||||
const tokenModel = require('../models/token.js');
|
||||
const sha = require('sha.js');
|
||||
|
||||
|
||||
class projectController extends baseController {
|
||||
@ -21,6 +23,7 @@ class projectController extends baseController {
|
||||
this.groupModel = yapi.getInst(groupModel);
|
||||
this.logModel = yapi.getInst(logModel);
|
||||
this.followModel = yapi.getInst(followModel);
|
||||
this.tokenModel = yapi.getInst(tokenModel);
|
||||
|
||||
const id = 'number';
|
||||
const member_uid = ['number'];
|
||||
@ -82,6 +85,12 @@ class projectController extends baseController {
|
||||
"*id": id,
|
||||
"*member_uid": id,
|
||||
role
|
||||
},
|
||||
token: {
|
||||
'*project_id':id
|
||||
},
|
||||
updateToken: {
|
||||
'*project_id':id
|
||||
}
|
||||
|
||||
}
|
||||
@ -197,6 +206,10 @@ class projectController extends baseController {
|
||||
});
|
||||
ctx.body = yapi.commons.resReturn(result);
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
/**
|
||||
* 添加项目成员
|
||||
* @interface /project/add_member
|
||||
@ -695,6 +708,67 @@ class projectController extends baseController {
|
||||
return s.size !== arr.length
|
||||
}
|
||||
|
||||
/**
|
||||
* 获取token数据
|
||||
* @interface /project/token
|
||||
* @method GET
|
||||
* @category project
|
||||
* @foldnumber 10
|
||||
* @param {Number} id 项目id,不能为空
|
||||
* @param {String} q
|
||||
* @return {Object}
|
||||
*/
|
||||
async token(ctx) {
|
||||
try {
|
||||
let project_id = ctx.params.project_id ;
|
||||
let data = await this.tokenModel.get(project_id);
|
||||
let token;
|
||||
if (!data ) {
|
||||
let passsalt = yapi.commons.randStr();
|
||||
token = sha('sha1').update(passsalt).digest('hex').substr(0, 20);
|
||||
await this.tokenModel.save({project_id, token})
|
||||
} else {
|
||||
token = data.token;
|
||||
}
|
||||
|
||||
ctx.body = yapi.commons.resReturn(token);
|
||||
} catch (err) {
|
||||
ctx.body = yapi.commons.resReturn(null, 402, err.message);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 更新token数据
|
||||
* @interface /project/update_token
|
||||
* @method GET
|
||||
* @category project
|
||||
* @foldnumber 10
|
||||
* @param {Number} id 项目id,不能为空
|
||||
* @param {String} q
|
||||
* @return {Object}
|
||||
*/
|
||||
async updateToken(ctx) {
|
||||
try {
|
||||
let project_id = ctx.params.project_id ;
|
||||
let data = await this.tokenModel.get(project_id);
|
||||
let token, result;
|
||||
if (data && data.token ) {
|
||||
let passsalt = yapi.commons.randStr();
|
||||
token = sha('sha1').update(passsalt).digest('hex').substr(0, 20);
|
||||
result = await this.tokenModel.up(project_id, token)
|
||||
result.token = token
|
||||
} else {
|
||||
ctx.body = yapi.commons.resReturn(null, 402, '没有查到token信息');
|
||||
}
|
||||
|
||||
ctx.body = yapi.commons.resReturn(result);
|
||||
} catch (err) {
|
||||
ctx.body = yapi.commons.resReturn(null, 402, err.message);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
/**
|
||||
* 模糊搜索项目名称或者组名称
|
||||
* @interface /project/search
|
||||
|
@ -116,6 +116,11 @@ function setupSql() {
|
||||
uid: 1
|
||||
})
|
||||
|
||||
let tokenCol = mongoose.connection.db.collection('token')
|
||||
tokenCol.createIndex({
|
||||
project_id: 1
|
||||
})
|
||||
|
||||
let followCol = mongoose.connection.db.collection('follow')
|
||||
followCol.createIndex({
|
||||
uid: 1
|
||||
|
38
server/models/token.js
Normal file
38
server/models/token.js
Normal file
@ -0,0 +1,38 @@
|
||||
const yapi = require('../yapi.js');
|
||||
const baseModel = require('./base.js');
|
||||
|
||||
class tokenModel extends baseModel {
|
||||
getName() {
|
||||
return 'token';
|
||||
}
|
||||
|
||||
getSchema() {
|
||||
return {
|
||||
project_id: { type: Number, required: true },
|
||||
token: String
|
||||
};
|
||||
}
|
||||
|
||||
save(data) {
|
||||
let m = new this.model(data);
|
||||
return m.save();
|
||||
}
|
||||
|
||||
get(project_id) {
|
||||
|
||||
return this.model.findOne({
|
||||
project_id: project_id
|
||||
});
|
||||
}
|
||||
|
||||
up(project_id, token){
|
||||
return this.model.update({
|
||||
project_id: project_id
|
||||
}, {
|
||||
token: token
|
||||
})
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
module.exports = tokenModel;
|
@ -239,7 +239,19 @@ let routerConfig = {
|
||||
"action": "upEnv",
|
||||
"path": "up_env",
|
||||
"method": "post"
|
||||
}
|
||||
},
|
||||
{
|
||||
"action": "token",
|
||||
"path": "token",
|
||||
"method": "get"
|
||||
},
|
||||
{
|
||||
"action": "updateToken",
|
||||
"path": "update_token",
|
||||
"method": "get"
|
||||
}
|
||||
|
||||
|
||||
],
|
||||
"interface": [
|
||||
{
|
||||
|
Loading…
Reference in New Issue
Block a user