feat: 获取项目token值

This commit is contained in:
gaoxiaolin.gao 2018-02-09 20:02:24 +08:00
parent 87902b93d1
commit a58ae58c89
12 changed files with 290 additions and 5 deletions

View File

@ -1,4 +1,13 @@
### v1.3.6
#### Feature
* 增加导出公共接口功能
* 增加复制接口路径按钮
* 每个项目有以后都有一个唯一的token
* antd升级到3
### v1.3.5
#### Feature

View File

@ -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">

View File

@ -31,6 +31,10 @@
.ace_print-margin{
display: none;
}
.interface-url-icon{
padding-left: 8px;
}
.colBody{
.query-icon {
display: inline-block;

View File

@ -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>
)
}
}

View File

@ -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;
}
}

View File

@ -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 }
})
}
}

View File

@ -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",

View File

@ -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;

View File

@ -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

View File

@ -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
View 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;

View File

@ -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": [
{