yapi-next/vendors/client/components/ModalPostman/index.js
2023-06-27 18:59:45 +08:00

318 lines
8.3 KiB
JavaScript

import React, { Component } from 'react';
import PropTypes from 'prop-types';
import './index.scss';
import { Alert, Modal, Row, Col, Icon, Collapse, Input, Tooltip } from 'antd';
import MockList from './MockList.js';
import MethodsList from './MethodsList.js';
import VariablesSelect from './VariablesSelect.js';
import { trim } from '../../common.js';
const { handleParamsValue } = require('common/utils.js');
const Panel = Collapse.Panel;
// 深拷贝
function deepEqual(state) {
return JSON.parse(JSON.stringify(state));
}
function closeRightTabsAndAddNewTab(arr, index, name, params) {
let newParamsList = [].concat(arr);
newParamsList.splice(index + 1, newParamsList.length - index);
newParamsList.push({
name: '',
params: []
});
let curParams = params || [];
let curname = name || '';
newParamsList[index] = {
...newParamsList[index],
name: curname,
params: curParams
};
return newParamsList;
}
class ModalPostman extends Component {
static propTypes = {
visible: PropTypes.bool,
handleCancel: PropTypes.func,
handleOk: PropTypes.func,
inputValue: PropTypes.any,
envType: PropTypes.string,
id: PropTypes.number
};
constructor(props) {
super(props);
this.state = {
methodsShow: false,
methodsShowMore: false,
methodsList: [],
constantInput: '',
activeKey: '1',
methodsParamsList: [
{
name: '',
params: [],
type: 'dataSource'
}
]
};
}
UNSAFE_componentWillMount() {
let { inputValue } = this.props;
this.setState({
constantInput: inputValue
});
// this.props.inputValue && this.handleConstantsInput(this.props.inputValue, 0);
inputValue && this.handleInitList(inputValue);
}
handleInitList(val) {
val = val.replace(/^\{\{(.+)\}\}$/g, '$1');
let valArr = val.split('|');
if (valArr[0].indexOf('@') >= 0) {
this.setState({
activeKey: '2'
});
} else if (valArr[0].indexOf('$') >= 0) {
this.setState({
activeKey: '3'
});
}
let paramsList = [
{
name: trim(valArr[0]),
params: [],
type: 'dataSource'
}
];
for (let i = 1; i < valArr.length; i++) {
let nameArr = valArr[i].split(':');
let paramArr = nameArr[1] && nameArr[1].split(',');
paramArr =
paramArr &&
paramArr.map(item => {
return trim(item);
});
let item = {
name: trim(nameArr[0]),
params: paramArr || []
};
paramsList.push(item);
}
this.setState(
{
methodsParamsList: paramsList
},
() => {
this.mockClick(valArr.length)();
}
);
}
mockClick(index) {
return (curname, params) => {
let newParamsList = closeRightTabsAndAddNewTab(
this.state.methodsParamsList,
index,
curname,
params
);
this.setState({
methodsParamsList: newParamsList
});
};
}
// 处理常量输入
handleConstantsInput = val => {
val = val.replace(/^\{\{(.+)\}\}$/g, '$1');
this.setState({
constantInput: val
});
this.mockClick(0)(val);
};
handleParamsInput = (e, clickIndex, paramsIndex) => {
let newParamsList = deepEqual(this.state.methodsParamsList);
newParamsList[clickIndex].params[paramsIndex] = e;
this.setState({
methodsParamsList: newParamsList
});
};
// 方法
MethodsListSource = props => {
return (
<MethodsList
click={this.mockClick(props.index)}
clickValue={props.value}
params={props.params}
paramsInput={this.handleParamsInput}
clickIndex={props.index}
/>
);
};
// 处理表达式
handleValue(val) {
return handleParamsValue(val, {});
}
// 处理错误
handleError() {
return (
<Alert
message="请求“变量集”尚未运行,所以我们无法从其响应中提取的值。您可以在测试集合中测试这些变量。"
type="warning"
/>
);
}
// 初始化
setInit() {
let initParamsList = [
{
name: '',
params: [],
type: 'dataSource'
}
];
this.setState({
methodsParamsList: initParamsList
});
}
// 处理取消插入
handleCancel = () => {
this.setInit();
this.props.handleCancel();
};
// 处理插入
handleOk = installValue => {
this.props.handleOk(installValue);
this.setInit();
};
// 处理面板切换
handleCollapse = key => {
this.setState({
activeKey: key
});
};
render() {
const { visible, envType } = this.props;
const { methodsParamsList, constantInput } = this.state;
const outputParams = () => {
let str = '';
let length = methodsParamsList.length;
methodsParamsList.forEach((item, index) => {
let isShow = item.name && length - 2 !== index;
str += item.name;
item.params.forEach((item, index) => {
let isParams = index > 0;
str += isParams ? ' , ' : ' : ';
str += item;
});
str += isShow ? ' | ' : '';
});
return '{{ ' + str + ' }}';
};
return (
<Modal
title={
<p>
<Icon type="edit" /> 高级参数设置
</p>
}
visible={visible}
onOk={() => this.handleOk(outputParams())}
onCancel={this.handleCancel}
wrapClassName="modal-postman"
width={1024}
maskClosable={false}
okText="插入"
>
<Row className="modal-postman-form" type="flex">
{methodsParamsList.map((item, index) => {
return item.type === 'dataSource' ? (
<Col span={8} className="modal-postman-col" key={index}>
<Collapse
className="modal-postman-collapse"
activeKey={this.state.activeKey}
onChange={this.handleCollapse}
bordered={false}
accordion
>
<Panel header={<h3 className="mock-title">常量</h3>} key="1">
<Input
placeholder="基础参数值"
value={constantInput}
onChange={e => this.handleConstantsInput(e.target.value, index)}
/>
</Panel>
<Panel header={<h3 className="mock-title">mock数据</h3>} key="2">
<MockList click={this.mockClick(index)} clickValue={item.name} />
</Panel>
{envType === 'case' && (
<Panel
header={
<h3 className="mock-title">
变量&nbsp;<Tooltip
placement="top"
title="YApi 提供了强大的变量参数功能,你可以在测试的时候使用前面接口的 参数 或 返回值 作为 后面接口的参数,即使接口之间存在依赖,也可以轻松 一键测试~"
>
<Icon type="question-circle-o" />
</Tooltip>
</h3>
}
key="3"
>
<VariablesSelect
id={this.props.id}
click={this.mockClick(index)}
clickValue={item.name}
/>
</Panel>
)}
</Collapse>
</Col>
) : (
<Col span={8} className="modal-postman-col" key={index}>
<this.MethodsListSource index={index} value={item.name} params={item.params} />
</Col>
);
})}
</Row>
<Row className="modal-postman-expression">
<Col span={6}>
<h3 className="title">表达式</h3>
</Col>
<Col span={18}>
<span className="expression-item">{outputParams()}</span>
</Col>
</Row>
<Row className="modal-postman-preview">
<Col span={6}>
<h3 className="title">预览</h3>
</Col>
<Col span={18}>
<h3>{this.handleValue(outputParams()) || (outputParams() && this.handleError())}</h3>
</Col>
</Row>
</Modal>
);
}
}
export default ModalPostman;