feat:增加提取页面

This commit is contained in:
tiantang 2023-07-09 23:50:38 +08:00
parent 25395415c1
commit 3419ee5df5
6 changed files with 19135 additions and 12435 deletions

View File

@ -31,8 +31,8 @@ class Body extends Component<HttpProps<BodyData>,HttpState<BodyData>>{
body
<div>
<MonacoEditor
width="800"
height="600"
width="100%"
height="400"
language="javascript"
theme="vs-dark"
value={code}

View File

@ -1,11 +1,309 @@
import {Component} from "react";
import React, {ChangeEvent, Component, useContext, useEffect, useRef, useState} from "react";
import {Dropdown, Form, Input, InputRef, LabeledValue, MenuProps, Select, Space, Table} from "antd";
import {FormInstance} from "antd/es/form";
import style from "@/component/step/http/Http.module.less";
import {PlusOutlined} from "@ant-design/icons";
class Check extends Component<any,any>{
render() {
return <div>
type EditableTableProps = Parameters<typeof Table>[0];
type ColumnTypes = Exclude<EditableTableProps['columns'], undefined>;
const EditableContext = React.createContext<FormInstance<any> | null>(null);
Check
</div>;
interface EditableRowProps {
index: number;
}
type HandleSave = (record: DataType) => void;
interface EditableCellProps {
title: React.ReactNode;
editable: boolean;
children: React.ReactNode;
dataIndex: keyof DataType;
record: DataType;
handleSave: HandleSave
}
interface DataType {
key: number
obj: React.Key
condition: CheckEnum
check: string
}
enum SelectAddEnum {
ADD,
IMPORT
}
// 函数方法枚举
enum CheckEnum {
Comparison,
outweigh,
outweighEqual,
less,
lessEqual,
NotEqual,
contain,
notContain,
exist,
absent,
list,
notList,
interval,
notInterval
}
const FuncList = ["对象比较", '大于', "大于等于", "小于", "小于等于", '不等于', "包含", "不包含", "存在", "不存在", "属于集合", "不属于集合", "区间范围", "非区间范围"]
const FuncSelectItem: LabeledValue[] = []
// const Func
for (let func in FuncList) {
FuncSelectItem.push({
value: func,
label: FuncList[func]
})
}
const EditableRow: React.FC<EditableRowProps> = ({index, ...props}) => {
const [form] = Form.useForm();
return (
<Form form={form} component={false}>
<EditableContext.Provider value={form}>
<tr {...props} />
</EditableContext.Provider>
</Form>
);
};
const EditableCell: React.FC<EditableCellProps> = ({
title,
editable,
children,
dataIndex,
record,
handleSave,
...restProps
}) => {
const [editing, setEditing] = useState(false);
const inputRef = useRef<InputRef>(null);
const form = useContext(EditableContext)!;
useEffect(() => {
if (editing) {
inputRef.current!.focus();
}
}, [editing]);
const toggleEdit = () => {
setEditing(!editing);
form.setFieldsValue({[dataIndex]: record[dataIndex]});
};
const save = async () => {
try {
const values = await form.validateFields();
toggleEdit();
handleSave({...record, ...values});
} catch (errInfo) {
console.log('Save failed:', errInfo);
}
};
let childNode = children;
if (editable) {
childNode = editing ? (
<Form.Item
style={{margin: 0}}
name={dataIndex}
rules={[
{
required: true,
message: `${title} 不能为空`,
},
]}
>
<Input ref={inputRef} onPressEnter={save} onBlur={save}/>
</Form.Item>
) : (
<div className={style.HttpEditable} style={{paddingRight: 24}} onClick={toggleEdit}>
{children}
</div>
);
}
return <td {...restProps}>{childNode}</td>;
};
const addSelectItem: MenuProps['items'] = [
{
key: SelectAddEnum.ADD,
label: (
<div></div>
),
},
{
key: SelectAddEnum.IMPORT,
label: (
<div></div>
),
}
]
const Check = () => {
const [dataSource, setDataSource] = useState<DataType[]>([
{
key: 0,
condition: CheckEnum.lessEqual,
check: '',
obj: '',
},
]);
const [count, setCount] = useState(1);
const handleDelete = (key: React.Key) => {
const newData = dataSource.filter((item) => item.key !== key);
setDataSource(newData);
};
// 用户操作
const TitleSelectClick: MenuProps['onClick'] = ({key}) => {
const SelectKey = Number(key)
switch (SelectKey) {
case SelectAddEnum.ADD:
handleAdd()
break
case SelectAddEnum.IMPORT:
console.log("import")
break
default:
break
}
console.log(key)
}
const funcChange = (key: number, value: number) => {
console.log(key, value)
const data = dataSource[Number(key)]
console.log(data)
data.condition = Number(value)
handleSave(data)
}
const paramsRender = (type: CheckEnum, value: DataType, handleSave: HandleSave) => {
return <div>123123</div>
}
const defaultColumns: (ColumnTypes[number] & { editable?: boolean; dataIndex: string })[] = [
{
title: '校验对象',
dataIndex: 'index',
width: '300px',
editable: true,
},
{
title: '检查条件',
dataIndex: 'index',
width: "200px",
render: (_, record:DataType) => {
return (<div>
<Select
defaultValue={String(CheckEnum.absent)}
style={{width: "100%"}}
onChange={(value: number) => funcChange(record.key, value)}
options={FuncSelectItem}
/>
</div>)
}
},
{
title: '校验内容',
dataIndex: 'index',
render: (_, record: DataType) => {
return (<div key={record.condition}>
{paramsRender(Number(record.condition), record, handleSave)}
</div>)
}
},
{
width: "80px",
title: () => {
return (
<div className={style.HttpHandleAdd}>
<Dropdown menu={{items: addSelectItem, onClick: TitleSelectClick}}>
<Space>
<div>
<PlusOutlined/>
</div>
</Space>
</Dropdown>
</div>
)
},
dataIndex: 'index',
render: (_, record: DataType) =>
dataSource.length >= 1 ? (
<span className={style.HttpHandleAdd} onClick={() => handleDelete(record.key)}></span>
) : null,
},
];
const handleAdd = () => {
const newData: DataType = {
key: count,
obj: '0',
condition: CheckEnum.absent,
check: ''
};
setDataSource([...dataSource, newData]);
setCount(count + 1);
};
const handleSave = (row: DataType) => {
const newData = [...dataSource];
const index = newData.findIndex((item) => row.key === item.key);
const item = newData[index];
newData.splice(index, 1, {
...item,
...row,
});
setDataSource(newData);
};
const components = {
body: {
row: EditableRow,
cell: EditableCell,
},
};
const columns = defaultColumns.map((col) => {
if (!col.editable) {
return col;
}
return {
...col,
onCell: (record: DataType) => ({
record,
editable: col.editable,
dataIndex: col.dataIndex,
title: col.title,
handleSave,
}),
};
});
return <div>
<Table
components={components}
rowClassName={() => 'editable-row'}
bordered
dataSource={dataSource}
columns={columns as ColumnTypes}
/>
</div>
}
export default Check

View File

@ -1,11 +1,367 @@
import {Component} from "react";
import React, {ChangeEvent, useContext, useEffect, useRef, useState} from "react";
import style from "@/component/step/http/Http.module.less";
import type {LabeledValue} from 'antd';
import {Dropdown, Form, Input, InputRef, MenuProps, Select, Space, Table} from "antd";
import {PlusOutlined} from "@ant-design/icons";
import {FormInstance} from "antd/es/form";
class Extract extends Component<any,any>{
render() {
return <div>
type EditableTableProps = Parameters<typeof Table>[0];
type ColumnTypes = Exclude<EditableTableProps['columns'], undefined>;
const EditableContext = React.createContext<FormInstance<any> | null>(null);
interface EditableRowProps {
index: number;
}
type HandleSave = (record: DataType) => void;
interface EditableCellProps {
title: React.ReactNode;
editable: boolean;
children: React.ReactNode;
dataIndex: keyof DataType;
record: DataType;
handleSave:HandleSave
Extract
</div>;
}
interface handleData{
data:string
expression:string
mate:string
}
interface DataType {
key:number
var: React.Key
handle:handleData
func: number
params: string
}
enum SelectAddEnum {
ADD,
IMPORT
}
// 函数方法枚举
enum FuncEnum {
JSON,
recursionJSON,
REGAll,
XML,
TEXTREG,
XMLDICT,
ALL
}
const FuncList = ["JSON提取",'递归JSON提取',"文本正则全量提取","XML提取","文本正则提取",'XML提取含属性',"全量提取"]
const FuncSelectItem:LabeledValue[] = []
// const Func
for (let func in FuncList) {
FuncSelectItem.push({
value:func,
label:FuncList[func]
})
}
const EditableRow: React.FC<EditableRowProps> = ({index, ...props}) => {
const [form] = Form.useForm();
return (
<Form form={form} component={false}>
<EditableContext.Provider value={form}>
<tr {...props} />
</EditableContext.Provider>
</Form>
);
};
const EditableCell: React.FC<EditableCellProps> = ({
title,
editable,
children,
dataIndex,
record,
handleSave,
...restProps
}) => {
const [editing, setEditing] = useState(false);
const inputRef = useRef<InputRef>(null);
const form = useContext(EditableContext)!;
useEffect(() => {
if (editing) {
inputRef.current!.focus();
}
}, [editing]);
const toggleEdit = () => {
setEditing(!editing);
form.setFieldsValue({[dataIndex]: record[dataIndex]});
};
const save = async () => {
try {
const values = await form.validateFields();
toggleEdit();
handleSave({...record, ...values});
} catch (errInfo) {
console.log('Save failed:', errInfo);
}
};
let childNode = children;
if (editable) {
childNode = editing ? (
<Form.Item
style={{margin: 0}}
name={dataIndex}
rules={[
{
required: true,
message: `${title} 不能为空`,
},
]}
>
<Input ref={inputRef} onPressEnter={save} onBlur={save}/>
</Form.Item>
) : (
<div className={style.HttpEditable} style={{paddingRight: 24}} onClick={toggleEdit}>
{children}
</div>
);
}
return <td {...restProps}>{childNode}</td>;
};
const addSelectItem: MenuProps['items'] = [
{
key: SelectAddEnum.ADD,
label: (
<div></div>
),
},
{
key: SelectAddEnum.IMPORT,
label: (
<div></div>
),
}
]
const Extract = () =>{
const [dataSource, setDataSource] = useState<DataType[]>([
{
key:0,
var: '0',
func: FuncEnum.JSON,
handle:{
data:"",
expression:"",
mate:"",
},
params: '',
},
]);
const [count, setCount] = useState(2);
const handleDelete = (key: React.Key) => {
const newData = dataSource.filter((item) => item.key !== key);
setDataSource(newData);
};
// 用户操作
const TitleSelectClick: MenuProps['onClick'] = ({key}) => {
const SelectKey = Number(key)
switch (SelectKey) {
case SelectAddEnum.ADD:
handleAdd()
break
case SelectAddEnum.IMPORT:
console.log("import")
break
default:
break
}
console.log(key)
}
const funcChange =(key:string,value: number)=>{
console.log(key,value)
const data = dataSource[Number(key)]
data.func = Number(value)
handleSave(data)
}
const paramsRender=(type:FuncEnum,value:DataType,handleSave:HandleSave) =>{
const dataChange = (data:ChangeEvent<HTMLInputElement>)=>{
value.handle.data = data.target.value
handleSave(value)
}
const expressionChange = (data:ChangeEvent<HTMLInputElement>)=>{
value.handle.expression = data.target.value
handleSave(value)
}
const mateChange = (data:ChangeEvent<HTMLInputElement>)=>{
value.handle.mate = data.target.value
handleSave(value)
}
switch (Number(type)) {
case FuncEnum.ALL:
return <div>
<Input style={{width:"50%"}} placeholder="处理对象" onChange={(e)=>dataChange(e)} value={value.handle.data} />
<Input style={{width:"50%"}} placeholder="提取表达式" value={value.handle.expression}/>
</div>
case FuncEnum.JSON:
return <div key={type}>
<Input style={{width:"50%"}} onChange={(e)=>dataChange(e)} placeholder="处理对象" value={value.handle.data} />
<Input style={{width:"50%"}} onChange={(e)=>expressionChange(e)} placeholder="提取表达式" value={value.handle.expression}/>
</div>
case FuncEnum.recursionJSON:
return <div key={type}>
<Input style={{width:"50%"}} onChange={(e)=>dataChange(e)} placeholder="处理对象" value={value.handle.data} />
<Input style={{width:"50%"}} onChange={(e)=>expressionChange(e)} placeholder="提取表达式" value={value.handle.expression}/>
</div>
case FuncEnum.REGAll:
return <div key={type}>
<Input style={{width:"33.3%"}} onChange={(e)=>dataChange(e)} placeholder="处理对象" value={value.handle.data} />
<Input style={{width:"33.3%"}} onChange={(e)=>expressionChange(e)} placeholder="提取表达式" value={value.handle.expression}/>
<Input style={{width:"33.3%"}} onChange={(e)=>mateChange(e)} placeholder="第几个匹配项" value={value.handle.mate}/>
</div>
case FuncEnum.TEXTREG:
return <div key={type}>
<Input style={{width:"33.3%"}} onChange={(e)=>dataChange(e)} placeholder="处理对象" value={value.handle.data} />
<Input style={{width:"33.3%"}} onChange={(e)=>expressionChange(e)} placeholder="提取表达式" value={value.handle.expression}/>
<Input style={{width:"33.3%"}} onChange={(e)=>mateChange(e)} placeholder="第几个匹配项" value={value.handle.mate}/>
</div>
case FuncEnum.XML:
return <div key={type}>
<Input style={{width:"50%"}} onChange={(e)=>dataChange(e)} placeholder="处理对象" value={value.handle.data} />
<Input style={{width:"50%"}} onChange={(e)=>expressionChange(e)} placeholder="提取表达式" value={value.handle.expression}/>
</div>
case FuncEnum.XMLDICT:
return <div key={type}>
<Input style={{width:"50%"}} onChange={(e)=>dataChange(e)} placeholder="处理对象" value={value.handle.data} />
<Input style={{width:"50%"}} onChange={(e)=>expressionChange(e)} placeholder="提取表达式" value={value.handle.expression}/>
</div>
default:
break
}
}
const defaultColumns: (ColumnTypes[number] & { editable?: boolean; dataIndex: string })[] = [
{
title: '出参变量名',
dataIndex: 'index',
width: '300px',
editable: true,
},
{
title: '函数',
dataIndex: 'index',
width: "200px",
render: (_, record) =>{
return (<div>
<Select
defaultValue={String(FuncEnum.JSON)}
style={{ width: "100%" }}
onChange={(value:number)=>funcChange(record.func,value)}
options={FuncSelectItem}
/>
</div>)
}
},
{
title: '参数',
dataIndex: 'index',
render: (_, record:DataType) =>{
return (<div key={record.func}>
{paramsRender(Number(record.func),record,handleSave)}
</div>)
}
},
{
width: "80px",
title: () => {
return (
<div className={style.HttpHandleAdd}>
<Dropdown menu={{items: addSelectItem, onClick: TitleSelectClick}}>
<Space>
<div>
<PlusOutlined/>
</div>
</Space>
</Dropdown>
</div>
)
},
dataIndex: 'index',
render: (_, record :DataType) =>
dataSource.length >= 1 ? (
<span className={style.HttpHandleAdd} onClick={() => handleDelete(record.key)}></span>
) : null,
},
];
const handleAdd = () => {
const newData: DataType = {
key: count,
var: '0',
func: FuncEnum.JSON,
handle:{
data:"",
expression:"",
mate:"",
},
params: ''
};
setDataSource([...dataSource, newData]);
setCount(count + 1);
};
const handleSave = (row: DataType) => {
const newData = [...dataSource];
const index = newData.findIndex((item) => row.key === item.key);
const item = newData[index];
newData.splice(index, 1, {
...item,
...row,
});
setDataSource(newData);
};
const components = {
body: {
row: EditableRow,
cell: EditableCell,
},
};
const columns = defaultColumns.map((col) => {
if (!col.editable) {
return col;
}
return {
...col,
onCell: (record: DataType) => ({
record,
editable: col.editable,
dataIndex: col.dataIndex,
title: col.title,
handleSave,
}),
};
});
return <div>
<Table
components={components}
rowClassName={() => 'editable-row'}
bordered
dataSource={dataSource}
columns={columns as ColumnTypes}
/>
</div>;
}
export default Extract

View File

@ -33,6 +33,7 @@ enum SelectAddEnum {
ADD,
IMPORT
}
interface EditableCellProps {
title: React.ReactNode;
editable: boolean;
@ -100,7 +101,7 @@ const EditableCell: React.FC<EditableCellProps> = ({
},
]}
>
<Input ref={inputRef} onPressEnter={save} onBlur={save}/>
<Input ref={inputRef} placeholder={`编辑 ${title}`} onPressEnter={save} onBlur={save}/>
</Form.Item>
) : (
<div className={style.HttpEditable} style={{paddingRight: 24}} onClick={toggleEdit}>
@ -150,7 +151,7 @@ const Headers: React.FC = () => {
// 用户操作
const TitleSelectClick: MenuProps['onClick'] = ({key}) => {
const SelectKey = Number(key)
switch (SelectKey){
switch (SelectKey) {
case SelectAddEnum.ADD:
handleAdd()
break

View File

@ -131,7 +131,7 @@ class HttpEditComponent extends Component<stepProps, State> {
return (<div>
{this.HttpMetod()}
<div className={style.HttpTab}>
<Tabs defaultActiveKey="Body" type="editable-card" items={this.items()} onChange={this.tabChange}/>
<Tabs defaultActiveKey="Check" items={this.items()} onChange={this.tabChange}/>
</div>
</div>)
}

File diff suppressed because it is too large Load Diff