juzhiyuan commented on a change in pull request #218:
URL: 
https://github.com/apache/incubator-apisix-dashboard/pull/218#discussion_r431536233



##########
File path: src/pages/Routes/Create.tsx
##########
@@ -0,0 +1,69 @@
+import React, { useState } from 'react';
+import { Card, Steps } from 'antd';
+import { PageHeaderWrapper } from '@ant-design/pro-layout';
+import Step1 from './components/Step1';
+import styles from './Create.less';
+
+const { Step } = Steps;
+
+const Create: React.FC = () => {
+  const [step1PageData, setStep1PageData] = 
useState<RoutesModule.Step1PageDataProps>({

Review comment:
       too long... `step1` would be ok..

##########
File path: src/pages/Routes/Create.tsx
##########
@@ -0,0 +1,69 @@
+import React, { useState } from 'react';
+import { Card, Steps } from 'antd';
+import { PageHeaderWrapper } from '@ant-design/pro-layout';
+import Step1 from './components/Step1';
+import styles from './Create.less';
+
+const { Step } = Steps;
+
+const Create: React.FC = () => {
+  const [step1PageData, setStep1PageData] = 
useState<RoutesModule.Step1PageDataProps>({
+    apiName: '',
+    protocol: '',

Review comment:
       Array

##########
File path: src/locales/zh-CN/menu.ts
##########
@@ -53,4 +53,6 @@ export default {
   'menu.ssl.edit': '编辑',
   'menu.ssl.create': '创建',
   'menu.settings': '设置',
+  'menu.routes': 'Routes',

Review comment:
       路由

##########
File path: src/pages/Routes/Create.tsx
##########
@@ -0,0 +1,69 @@
+import React, { useState } from 'react';
+import { Card, Steps } from 'antd';
+import { PageHeaderWrapper } from '@ant-design/pro-layout';
+import Step1 from './components/Step1';
+import styles from './Create.less';
+
+const { Step } = Steps;
+
+const Create: React.FC = () => {
+  const [step1PageData, setStep1PageData] = 
useState<RoutesModule.Step1PageDataProps>({
+    apiName: '',
+    protocol: '',
+    hosts: [],
+    requestPath: '',
+    httpMethods: [],
+    advancedConfig: [],
+  });
+
+  const [currentStep, setCurrentStep] = useState(0);
+  const [stepHeader, setStepHeader] = useState(['定义API请求', '定义API后端服务', '插件', 
'预览']);
+  const pageData = {
+    step1PageData,
+  };
+
+  const handleChange = (step: number, data: RoutesModule.Step1PageDataProps) 
=> {
+    switch (step) {
+      case 0:
+        setStep1PageData({ ...step1PageData, ...data });
+        break;
+      case 1:
+        // TODO: base on data show different step
+        setCurrentStep(1);
+        setStepHeader(['定义API请求', '定义API后端服务', '预览']);
+        break;
+      default:

Review comment:
       removed

##########
File path: src/pages/Routes/Create.tsx
##########
@@ -0,0 +1,69 @@
+import React, { useState } from 'react';
+import { Card, Steps } from 'antd';
+import { PageHeaderWrapper } from '@ant-design/pro-layout';
+import Step1 from './components/Step1';
+import styles from './Create.less';
+
+const { Step } = Steps;
+
+const Create: React.FC = () => {
+  const [step1PageData, setStep1PageData] = 
useState<RoutesModule.Step1PageDataProps>({
+    apiName: '',
+    protocol: '',
+    hosts: [],
+    requestPath: '',
+    httpMethods: [],
+    advancedConfig: [],
+  });
+
+  const [currentStep, setCurrentStep] = useState(0);
+  const [stepHeader, setStepHeader] = useState(['定义API请求', '定义API后端服务', '插件', 
'预览']);
+  const pageData = {

Review comment:
       data is ok

##########
File path: src/pages/Routes/components/Step1/index.tsx
##########
@@ -0,0 +1,312 @@
+import React, { useState } from 'react';
+import {
+  Form,
+  Button,
+  Divider,
+  Input,
+  Checkbox,
+  Row,
+  Col,
+  Table,
+  Space,
+  Modal,
+  Select,
+} from 'antd';
+import styles from '../../Create.less';
+
+const { TextArea } = Input;
+const { Option } = Select;
+
+const formItemLayout = {
+  labelCol: {
+    span: 6,
+  },
+  wrapperCol: {
+    span: 18,
+  },
+};
+
+const Step1: React.FC<RoutesModule.StepProps> = ({ pageData, onChange }) => {
+  const { step1PageData } = pageData;
+  const [form] = Form.useForm();
+  const [modalVisible, setModalVisible] = useState(false);
+  const [editModalData, setEditModalData] = useState();
+
+  const handleAdd = () => {
+    setModalVisible(true);
+  };
+
+  const handleEdit = (text: any, record: any) => {
+    setEditModalData(record);
+  };
+
+  const handleDelete = (text: any, record: any) => {
+    const { advancedConfig } = step1PageData;
+    const filteredAdvancedConfig = advancedConfig.filter((item) => item.key 
!== record.key);
+    onChange({ advancedConfig: filteredAdvancedConfig });
+  };
+
+  const columns = [
+    {
+      title: '参数位置',
+      dataIndex: 'paramsLocation',
+      key: 'paramsLocation',
+    },
+    {
+      title: '参数名称',
+      dataIndex: 'paramsName',
+      key: 'paramsName',
+    },
+    {
+      title: '表达式',
+      dataIndex: 'paramsExpresstion',
+      key: 'paramsExpresstion',
+    },
+    {
+      title: '参数值',
+      dataIndex: 'paramsValue',
+      key: 'paramsValue',
+    },
+    {
+      title: '备注',
+      dataIndex: 'remark',
+      key: 'remark',
+    },
+    {
+      title: '操作',
+      key: 'action',
+      render: (text: any, record: any) => (
+        <Space size="middle">
+          <a onClick={() => handleEdit(text, record)}>编辑</a>
+          <a onClick={() => handleDelete(text, record)}>移除</a>
+        </Space>
+      ),
+    },
+  ];
+
+  const addHost = () => {
+    const { hosts } = step1PageData;
+    onChange({
+      hosts: hosts.concat([
+        {
+          host: '',
+          port: '',

Review comment:
       ,

##########
File path: src/pages/Routes/components/Step1/index.tsx
##########
@@ -0,0 +1,312 @@
+import React, { useState } from 'react';
+import {
+  Form,
+  Button,
+  Divider,
+  Input,
+  Checkbox,
+  Row,
+  Col,
+  Table,
+  Space,
+  Modal,
+  Select,
+} from 'antd';
+import styles from '../../Create.less';
+
+const { TextArea } = Input;
+const { Option } = Select;
+
+const formItemLayout = {
+  labelCol: {
+    span: 6,
+  },
+  wrapperCol: {
+    span: 18,
+  },
+};
+
+const Step1: React.FC<RoutesModule.StepProps> = ({ pageData, onChange }) => {
+  const { step1PageData } = pageData;

Review comment:
       ,

##########
File path: src/pages/Routes/typing.d.ts
##########
@@ -0,0 +1,32 @@
+declare namespace RoutesModule {
+  interface Step1ModalProps {
+    paramsLocation: string;
+    paramsName: string;
+    paramsExpresstion: string;
+    paramsValue: string;
+    remark?: string;
+    key: string;
+  }
+
+  interface Step1HostProps {
+    host: string;
+    port: string;
+    priority: string;

Review comment:
       ,

##########
File path: src/pages/Routes/typing.d.ts
##########
@@ -0,0 +1,32 @@
+declare namespace RoutesModule {
+  interface Step1ModalProps {
+    paramsLocation: string;
+    paramsName: string;
+    paramsExpresstion: string;
+    paramsValue: string;
+    remark?: string;
+    key: string;
+  }
+
+  interface Step1HostProps {
+    host: string;
+    port: string;
+    priority: string;
+  }
+
+  interface Step1PageDataProps {
+    apiName: string;
+    protocol: string;
+    hosts: Step1HostProps[];
+    requestPath: string;
+    httpMethods: [];
+    advancedConfig: Step1ModalProps[];
+  }
+
+  interface StepProps {
+    pageData: {
+      step1PageData: Step1PageDataProps;
+    };
+    onChange(data: any): void;

Review comment:
       `onChange<T>(data: T): void`

##########
File path: src/pages/Routes/Create.tsx
##########
@@ -0,0 +1,69 @@
+import React, { useState } from 'react';
+import { Card, Steps } from 'antd';
+import { PageHeaderWrapper } from '@ant-design/pro-layout';
+import Step1 from './components/Step1';
+import styles from './Create.less';
+
+const { Step } = Steps;
+
+const Create: React.FC = () => {
+  const [step1PageData, setStep1PageData] = 
useState<RoutesModule.Step1PageDataProps>({
+    apiName: '',
+    protocol: '',
+    hosts: [],
+    requestPath: '',

Review comment:
       `path: []`

##########
File path: src/pages/Routes/components/Step1/index.tsx
##########
@@ -0,0 +1,312 @@
+import React, { useState } from 'react';
+import {
+  Form,
+  Button,
+  Divider,
+  Input,
+  Checkbox,
+  Row,
+  Col,
+  Table,
+  Space,
+  Modal,
+  Select,
+} from 'antd';
+import styles from '../../Create.less';
+
+const { TextArea } = Input;
+const { Option } = Select;
+
+const formItemLayout = {
+  labelCol: {
+    span: 6,
+  },
+  wrapperCol: {
+    span: 18,
+  },
+};
+
+const Step1: React.FC<RoutesModule.StepProps> = ({ pageData, onChange }) => {
+  const { step1PageData } = pageData;
+  const [form] = Form.useForm();
+  const [modalVisible, setModalVisible] = useState(false);
+  const [editModalData, setEditModalData] = useState();
+
+  const handleAdd = () => {
+    setModalVisible(true);
+  };
+
+  const handleEdit = (text: any, record: any) => {
+    setEditModalData(record);
+  };
+
+  const handleDelete = (text: any, record: any) => {
+    const { advancedConfig } = step1PageData;
+    const filteredAdvancedConfig = advancedConfig.filter((item) => item.key 
!== record.key);
+    onChange({ advancedConfig: filteredAdvancedConfig });
+  };
+
+  const columns = [
+    {
+      title: '参数位置',
+      dataIndex: 'paramsLocation',
+      key: 'paramsLocation',
+    },
+    {
+      title: '参数名称',
+      dataIndex: 'paramsName',
+      key: 'paramsName',
+    },
+    {
+      title: '表达式',
+      dataIndex: 'paramsExpresstion',
+      key: 'paramsExpresstion',
+    },
+    {
+      title: '参数值',
+      dataIndex: 'paramsValue',
+      key: 'paramsValue',
+    },
+    {
+      title: '备注',
+      dataIndex: 'remark',
+      key: 'remark',
+    },
+    {
+      title: '操作',
+      key: 'action',
+      render: (text: any, record: any) => (
+        <Space size="middle">
+          <a onClick={() => handleEdit(text, record)}>编辑</a>
+          <a onClick={() => handleDelete(text, record)}>移除</a>
+        </Space>
+      ),
+    },
+  ];
+
+  const addHost = () => {
+    const { hosts } = step1PageData;
+    onChange({
+      hosts: hosts.concat([
+        {
+          host: '',
+          port: '',
+          priority: '',
+        },
+      ]),
+    });
+  };
+
+  const renderHosts = () =>
+    step1PageData.hosts?.map((item, index) => (
+      <Row
+        key={Math.random().toString(36).slice(2)}
+        style={{ marginBottom: '10px' }}
+        gutter={[16, 16]}
+      >
+        <Col span={8}>
+          <Input placeholder="IP/HOST" />
+        </Col>
+        <Col span={4}>
+          <Input placeholder="PORT" />
+        </Col>
+        <Col span={4}>
+          <Input />
+        </Col>
+        <Col span={4}>
+          <Space>
+            <Button
+              type="primary"
+              danger
+              onClick={() => {
+                const { hosts } = step1PageData;
+                hosts.splice(index, 1);
+                onChange({ hosts });
+              }}
+            >
+              删除
+            </Button>
+          </Space>
+        </Col>
+      </Row>
+    ));
+
+  const renderNameAndDesc = () => (
+    <>
+      <div>名称及其描述</div>
+      <Divider />
+      <Form {...formItemLayout} form={form} layout="horizontal" 
className={styles.stepForm}>
+        <Form.Item
+          label="API名称"
+          name="APIName"
+          rules={[{ required: true, message: '请输入API名称' }]}
+        >
+          <Input placeholder="请输入API名称" />
+        </Form.Item>
+        <Form.Item label="描述" name="desc">
+          <TextArea placeholder="请输入描述" />
+        </Form.Item>
+      </Form>
+    </>
+  );
+
+  const renderBaseRequestConfig = () => (
+    <>
+      <div>请求基础定义</div>
+      <Divider />
+      <Form {...formItemLayout} form={form} layout="horizontal" 
className={styles.stepForm}>
+        <Form.Item label="协议" name="protocol" rules={[{ required: true, 
message: '请勾选协议' }]}>
+          <Checkbox.Group style={{ width: '100%' }}>
+            <Row>
+              {['HTTP', 'HTTPS', 'WebSocket'].map((item) => (
+                <Col span={6} key={item}>
+                  <Checkbox value={item}>{item}</Checkbox>
+                </Col>
+              ))}
+            </Row>
+          </Checkbox.Group>
+        </Form.Item>
+        <Form.Item label="IP/HOST" rules={[{ required: true, message: 
'请输入HOST' }]}>
+          {renderHosts()}
+          <Button onClick={addHost} type="primary">
+            增加
+          </Button>
+        </Form.Item>
+        <Form.Item label="请求PATH" name="path" rules={[{ required: true, 
message: '请输入PATH' }]}>
+          <Input placeholder="请输入PATH" />
+        </Form.Item>
+        <Form.Item
+          label="HTTP Methods"
+          name="httpMethods"
+          rules={[{ required: true, message: '请勾选HTTP Methods' }]}
+        >
+          <Checkbox.Group style={{ width: '100%' }}>
+            <Row>
+              {['ANY', 'GET', 'HEAD', 'POST', 'PUT', 'DELETE', 'OPTIONS', 
'PATCH'].map((item) => (
+                <Col span={6} key={item}>
+                  <Checkbox value={item}>{item}</Checkbox>
+                </Col>
+              ))}
+            </Row>
+          </Checkbox.Group>
+        </Form.Item>
+      </Form>
+    </>
+  );
+
+  const renderModal = () => {
+    const [modalForm] = Form.useForm();
+    const validateModalFields = modalForm.validateFields;
+    const { resetFields } = modalForm;
+    const handleOk = () => {
+      validateModalFields().then((value) => {
+        const { advancedConfig } = step1PageData;
+        onChange({
+          advancedConfig: advancedConfig.concat({
+            ...(value as RoutesModule.Step1ModalProps),
+            key: Math.random().toString(36).slice(2),
+          }),
+        });
+      });
+    };
+
+    const handleCancel = () => {
+      setModalVisible(false);
+    };
+
+    const handleAfterClose = () => {
+      resetFields();
+    };
+    return (
+      <>
+        <Modal
+          title="新增"
+          centered
+          visible={modalVisible}
+          afterClose={handleAfterClose}
+          onOk={handleOk}
+          onCancel={handleCancel}
+          destroyOnClose
+        >
+          <Form
+            name="basic"
+            form={modalForm}
+            labelCol={{ span: 4 }}
+            wrapperCol={{ span: 20 }}
+            initialValues={editModalData}
+          >
+            <Form.Item
+              label="参数位置"
+              name="paramsLocation"
+              rules={[{ required: true, message: '请选择参数位置' }]}
+            >
+              <Select>
+                <Option value="header">header</Option>
+                <Option value="query">query</Option>
+                <Option value="params">params</Option>
+              </Select>
+            </Form.Item>
+            <Form.Item
+              label="参数名称"
+              name="paramsName"
+              rules={[{ required: true, message: '请输入参数名称' }]}
+            >
+              <Input />
+            </Form.Item>
+            <Form.Item
+              label="表达式"
+              name="paramsExpresstion"
+              rules={[{ required: true, message: '请选择表达式' }]}
+            >
+              <Select>
+                <Option value=">">大于</Option>
+                <Option value="<">小于</Option>
+                <Option value="=">等于</Option>

Review comment:
       ,

##########
File path: src/pages/Routes/Create.tsx
##########
@@ -0,0 +1,69 @@
+import React, { useState } from 'react';
+import { Card, Steps } from 'antd';
+import { PageHeaderWrapper } from '@ant-design/pro-layout';
+import Step1 from './components/Step1';
+import styles from './Create.less';
+
+const { Step } = Steps;
+
+const Create: React.FC = () => {
+  const [step1PageData, setStep1PageData] = 
useState<RoutesModule.Step1PageDataProps>({
+    apiName: '',
+    protocol: '',
+    hosts: [],
+    requestPath: '',
+    httpMethods: [],
+    advancedConfig: [],

Review comment:
       高级路由匹配:`advancedMatchingRules`

##########
File path: src/pages/Routes/components/Step1/index.tsx
##########
@@ -0,0 +1,312 @@
+import React, { useState } from 'react';
+import {
+  Form,
+  Button,
+  Divider,
+  Input,
+  Checkbox,
+  Row,
+  Col,
+  Table,
+  Space,
+  Modal,
+  Select,
+} from 'antd';
+import styles from '../../Create.less';
+
+const { TextArea } = Input;
+const { Option } = Select;
+
+const formItemLayout = {
+  labelCol: {
+    span: 6,
+  },
+  wrapperCol: {
+    span: 18,
+  },
+};
+
+const Step1: React.FC<RoutesModule.StepProps> = ({ pageData, onChange }) => {
+  const { step1PageData } = pageData;
+  const [form] = Form.useForm();
+  const [modalVisible, setModalVisible] = useState(false);
+  const [editModalData, setEditModalData] = useState();
+
+  const handleAdd = () => {
+    setModalVisible(true);
+  };
+
+  const handleEdit = (text: any, record: any) => {
+    setEditModalData(record);
+  };
+
+  const handleDelete = (text: any, record: any) => {
+    const { advancedConfig } = step1PageData;
+    const filteredAdvancedConfig = advancedConfig.filter((item) => item.key 
!== record.key);
+    onChange({ advancedConfig: filteredAdvancedConfig });
+  };
+
+  const columns = [
+    {
+      title: '参数位置',
+      dataIndex: 'paramsLocation',
+      key: 'paramsLocation',
+    },
+    {
+      title: '参数名称',
+      dataIndex: 'paramsName',
+      key: 'paramsName',
+    },
+    {
+      title: '表达式',
+      dataIndex: 'paramsExpresstion',
+      key: 'paramsExpresstion',
+    },
+    {
+      title: '参数值',
+      dataIndex: 'paramsValue',
+      key: 'paramsValue',
+    },
+    {
+      title: '备注',
+      dataIndex: 'remark',
+      key: 'remark',
+    },
+    {
+      title: '操作',
+      key: 'action',
+      render: (text: any, record: any) => (
+        <Space size="middle">
+          <a onClick={() => handleEdit(text, record)}>编辑</a>
+          <a onClick={() => handleDelete(text, record)}>移除</a>
+        </Space>
+      ),
+    },
+  ];
+
+  const addHost = () => {
+    const { hosts } = step1PageData;
+    onChange({
+      hosts: hosts.concat([
+        {
+          host: '',
+          port: '',
+          priority: '',
+        },
+      ]),
+    });
+  };
+
+  const renderHosts = () =>
+    step1PageData.hosts?.map((item, index) => (
+      <Row
+        key={Math.random().toString(36).slice(2)}
+        style={{ marginBottom: '10px' }}
+        gutter={[16, 16]}
+      >
+        <Col span={8}>
+          <Input placeholder="IP/HOST" />
+        </Col>
+        <Col span={4}>
+          <Input placeholder="PORT" />
+        </Col>
+        <Col span={4}>
+          <Input />
+        </Col>
+        <Col span={4}>
+          <Space>
+            <Button
+              type="primary"
+              danger
+              onClick={() => {
+                const { hosts } = step1PageData;
+                hosts.splice(index, 1);
+                onChange({ hosts });
+              }}
+            >
+              删除
+            </Button>
+          </Space>
+        </Col>
+      </Row>
+    ));
+
+  const renderNameAndDesc = () => (
+    <>
+      <div>名称及其描述</div>
+      <Divider />
+      <Form {...formItemLayout} form={form} layout="horizontal" 
className={styles.stepForm}>
+        <Form.Item
+          label="API名称"
+          name="APIName"
+          rules={[{ required: true, message: '请输入API名称' }]}
+        >
+          <Input placeholder="请输入API名称" />
+        </Form.Item>
+        <Form.Item label="描述" name="desc">
+          <TextArea placeholder="请输入描述" />
+        </Form.Item>
+      </Form>
+    </>
+  );
+
+  const renderBaseRequestConfig = () => (
+    <>
+      <div>请求基础定义</div>
+      <Divider />
+      <Form {...formItemLayout} form={form} layout="horizontal" 
className={styles.stepForm}>
+        <Form.Item label="协议" name="protocol" rules={[{ required: true, 
message: '请勾选协议' }]}>
+          <Checkbox.Group style={{ width: '100%' }}>
+            <Row>
+              {['HTTP', 'HTTPS', 'WebSocket'].map((item) => (
+                <Col span={6} key={item}>
+                  <Checkbox value={item}>{item}</Checkbox>
+                </Col>
+              ))}
+            </Row>
+          </Checkbox.Group>
+        </Form.Item>
+        <Form.Item label="IP/HOST" rules={[{ required: true, message: 
'请输入HOST' }]}>
+          {renderHosts()}
+          <Button onClick={addHost} type="primary">
+            增加
+          </Button>
+        </Form.Item>
+        <Form.Item label="请求PATH" name="path" rules={[{ required: true, 
message: '请输入PATH' }]}>
+          <Input placeholder="请输入PATH" />
+        </Form.Item>
+        <Form.Item
+          label="HTTP Methods"
+          name="httpMethods"
+          rules={[{ required: true, message: '请勾选HTTP Methods' }]}
+        >
+          <Checkbox.Group style={{ width: '100%' }}>
+            <Row>
+              {['ANY', 'GET', 'HEAD', 'POST', 'PUT', 'DELETE', 'OPTIONS', 
'PATCH'].map((item) => (
+                <Col span={6} key={item}>
+                  <Checkbox value={item}>{item}</Checkbox>
+                </Col>
+              ))}
+            </Row>
+          </Checkbox.Group>
+        </Form.Item>
+      </Form>
+    </>
+  );
+
+  const renderModal = () => {
+    const [modalForm] = Form.useForm();
+    const validateModalFields = modalForm.validateFields;
+    const { resetFields } = modalForm;
+    const handleOk = () => {
+      validateModalFields().then((value) => {
+        const { advancedConfig } = step1PageData;
+        onChange({
+          advancedConfig: advancedConfig.concat({
+            ...(value as RoutesModule.Step1ModalProps),
+            key: Math.random().toString(36).slice(2),
+          }),
+        });
+      });
+    };
+
+    const handleCancel = () => {
+      setModalVisible(false);
+    };
+
+    const handleAfterClose = () => {
+      resetFields();
+    };
+    return (
+      <>
+        <Modal
+          title="新增"
+          centered
+          visible={modalVisible}
+          afterClose={handleAfterClose}
+          onOk={handleOk}
+          onCancel={handleCancel}
+          destroyOnClose
+        >
+          <Form
+            name="basic"
+            form={modalForm}
+            labelCol={{ span: 4 }}
+            wrapperCol={{ span: 20 }}
+            initialValues={editModalData}
+          >
+            <Form.Item
+              label="参数位置"
+              name="paramsLocation"
+              rules={[{ required: true, message: '请选择参数位置' }]}
+            >
+              <Select>

Review comment:
       cookie

##########
File path: src/pages/Routes/Create.tsx
##########
@@ -0,0 +1,69 @@
+import React, { useState } from 'react';
+import { Card, Steps } from 'antd';
+import { PageHeaderWrapper } from '@ant-design/pro-layout';
+import Step1 from './components/Step1';
+import styles from './Create.less';
+
+const { Step } = Steps;
+
+const Create: React.FC = () => {
+  const [step1PageData, setStep1PageData] = 
useState<RoutesModule.Step1PageDataProps>({
+    apiName: '',
+    protocol: '',
+    hosts: [],
+    requestPath: '',
+    httpMethods: [],
+    advancedConfig: [],
+  });
+
+  const [currentStep, setCurrentStep] = useState(0);
+  const [stepHeader, setStepHeader] = useState(['定义API请求', '定义API后端服务', '插件', 
'预览']);
+  const pageData = {
+    step1PageData,
+  };
+
+  const handleChange = (step: number, data: RoutesModule.Step1PageDataProps) 
=> {
+    switch (step) {
+      case 0:
+        setStep1PageData({ ...step1PageData, ...data });
+        break;
+      case 1:
+        // TODO: base on data show different step
+        setCurrentStep(1);
+        setStepHeader(['定义API请求', '定义API后端服务', '预览']);
+        break;
+      default:
+    }
+  };
+
+  const renderStep = () => {
+    return (
+      <>
+        {Boolean(currentStep === 0) && (
+          <Step1
+            key={Math.random().toString(36).slice(2)}
+            pageData={pageData}
+            onChange={(data: RoutesModule.Step1PageDataProps) => 
handleChange(currentStep, data)}
+          />
+        )}
+      </>
+    );
+  };
+
+  return (
+    <PageHeaderWrapper content="">

Review comment:
       content?

##########
File path: src/pages/Routes/Create.tsx
##########
@@ -0,0 +1,69 @@
+import React, { useState } from 'react';
+import { Card, Steps } from 'antd';
+import { PageHeaderWrapper } from '@ant-design/pro-layout';
+import Step1 from './components/Step1';
+import styles from './Create.less';
+
+const { Step } = Steps;
+
+const Create: React.FC = () => {
+  const [step1PageData, setStep1PageData] = 
useState<RoutesModule.Step1PageDataProps>({
+    apiName: '',

Review comment:
       name

##########
File path: src/pages/Routes/typing.d.ts
##########
@@ -0,0 +1,32 @@
+declare namespace RoutesModule {
+  interface Step1ModalProps {
+    paramsLocation: string;
+    paramsName: string;
+    paramsExpresstion: string;
+    paramsValue: string;
+    remark?: string;
+    key: string;
+  }
+
+  interface Step1HostProps {
+    host: string;
+    port: string;
+    priority: string;
+  }
+
+  interface Step1PageDataProps {
+    apiName: string;
+    protocol: string;
+    hosts: Step1HostProps[];
+    requestPath: string;
+    httpMethods: [];
+    advancedConfig: Step1ModalProps[];
+  }
+
+  interface StepProps {
+    pageData: {
+      step1PageData: Step1PageDataProps;
+    };
+    onChange(data: any): void;

Review comment:
       ,

##########
File path: src/pages/Routes/Create.tsx
##########
@@ -0,0 +1,69 @@
+import React, { useState } from 'react';
+import { Card, Steps } from 'antd';
+import { PageHeaderWrapper } from '@ant-design/pro-layout';
+import Step1 from './components/Step1';
+import styles from './Create.less';
+
+const { Step } = Steps;
+
+const Create: React.FC = () => {
+  const [step1PageData, setStep1PageData] = 
useState<RoutesModule.Step1PageDataProps>({
+    apiName: '',
+    protocol: '',
+    hosts: [],
+    requestPath: '',
+    httpMethods: [],
+    advancedConfig: [],
+  });
+
+  const [currentStep, setCurrentStep] = useState(0);
+  const [stepHeader, setStepHeader] = useState(['定义API请求', '定义API后端服务', '插件', 
'预览']);

Review comment:
       add space around `api`

##########
File path: src/pages/Routes/Create.tsx
##########
@@ -0,0 +1,69 @@
+import React, { useState } from 'react';
+import { Card, Steps } from 'antd';
+import { PageHeaderWrapper } from '@ant-design/pro-layout';
+import Step1 from './components/Step1';
+import styles from './Create.less';
+
+const { Step } = Steps;
+
+const Create: React.FC = () => {
+  const [step1PageData, setStep1PageData] = 
useState<RoutesModule.Step1PageDataProps>({
+    apiName: '',
+    protocol: '',
+    hosts: [],
+    requestPath: '',
+    httpMethods: [],
+    advancedConfig: [],
+  });
+
+  const [currentStep, setCurrentStep] = useState(0);
+  const [stepHeader, setStepHeader] = useState(['定义API请求', '定义API后端服务', '插件', 
'预览']);
+  const pageData = {
+    step1PageData,
+  };
+
+  const handleChange = (step: number, data: RoutesModule.Step1PageDataProps) 
=> {
+    switch (step) {
+      case 0:

Review comment:
       `setCurrentStep(0)`

##########
File path: src/pages/Routes/Create.tsx
##########
@@ -0,0 +1,69 @@
+import React, { useState } from 'react';
+import { Card, Steps } from 'antd';
+import { PageHeaderWrapper } from '@ant-design/pro-layout';
+import Step1 from './components/Step1';
+import styles from './Create.less';
+
+const { Step } = Steps;
+
+const Create: React.FC = () => {
+  const [step1PageData, setStep1PageData] = 
useState<RoutesModule.Step1PageDataProps>({

Review comment:
       or step1Data

##########
File path: src/pages/Routes/Create.tsx
##########
@@ -0,0 +1,69 @@
+import React, { useState } from 'react';
+import { Card, Steps } from 'antd';
+import { PageHeaderWrapper } from '@ant-design/pro-layout';
+import Step1 from './components/Step1';
+import styles from './Create.less';
+
+const { Step } = Steps;
+
+const Create: React.FC = () => {
+  const [step1PageData, setStep1PageData] = 
useState<RoutesModule.Step1PageDataProps>({
+    apiName: '',
+    protocol: '',
+    hosts: [],
+    requestPath: '',
+    httpMethods: [],
+    advancedConfig: [],
+  });
+
+  const [currentStep, setCurrentStep] = useState(0);
+  const [stepHeader, setStepHeader] = useState(['定义API请求', '定义API后端服务', '插件', 
'预览']);

Review comment:
       插件配置

##########
File path: src/pages/Routes/Create.tsx
##########
@@ -0,0 +1,69 @@
+import React, { useState } from 'react';
+import { Card, Steps } from 'antd';
+import { PageHeaderWrapper } from '@ant-design/pro-layout';
+import Step1 from './components/Step1';
+import styles from './Create.less';
+
+const { Step } = Steps;
+
+const Create: React.FC = () => {
+  const [step1PageData, setStep1PageData] = 
useState<RoutesModule.Step1PageDataProps>({
+    apiName: '',
+    protocol: '',
+    hosts: [],
+    requestPath: '',
+    httpMethods: [],
+    advancedConfig: [],
+  });
+
+  const [currentStep, setCurrentStep] = useState(0);
+  const [stepHeader, setStepHeader] = useState(['定义API请求', '定义API后端服务', '插件', 
'预览']);
+  const pageData = {
+    step1PageData,
+  };
+
+  const handleChange = (step: number, data: RoutesModule.Step1PageDataProps) 
=> {
+    switch (step) {
+      case 0:
+        setStep1PageData({ ...step1PageData, ...data });
+        break;
+      case 1:
+        // TODO: base on data show different step
+        setCurrentStep(1);
+        setStepHeader(['定义API请求', '定义API后端服务', '预览']);
+        break;
+      default:
+    }
+  };
+
+  const renderStep = () => {
+    return (
+      <>
+        {Boolean(currentStep === 0) && (
+          <Step1
+            key={Math.random().toString(36).slice(2)}
+            pageData={pageData}
+            onChange={(data: RoutesModule.Step1PageDataProps) => 
handleChange(currentStep, data)}
+          />
+        )}
+      </>
+    );
+  };
+
+  return (
+    <PageHeaderWrapper content="">
+      <Card bordered={false}>
+        <>

Review comment:
       ?

##########
File path: src/pages/Routes/Create.tsx
##########
@@ -0,0 +1,69 @@
+import React, { useState } from 'react';
+import { Card, Steps } from 'antd';
+import { PageHeaderWrapper } from '@ant-design/pro-layout';
+import Step1 from './components/Step1';
+import styles from './Create.less';
+
+const { Step } = Steps;
+
+const Create: React.FC = () => {
+  const [step1PageData, setStep1PageData] = 
useState<RoutesModule.Step1PageDataProps>({
+    apiName: '',
+    protocol: '',
+    hosts: [],
+    requestPath: '',
+    httpMethods: [],
+    advancedConfig: [],
+  });
+
+  const [currentStep, setCurrentStep] = useState(0);
+  const [stepHeader, setStepHeader] = useState(['定义API请求', '定义API后端服务', '插件', 
'预览']);
+  const pageData = {
+    step1PageData,
+  };
+
+  const handleChange = (step: number, data: RoutesModule.Step1PageDataProps) 
=> {
+    switch (step) {
+      case 0:
+        setStep1PageData({ ...step1PageData, ...data });
+        break;
+      case 1:
+        // TODO: base on data show different step
+        setCurrentStep(1);
+        setStepHeader(['定义API请求', '定义API后端服务', '预览']);
+        break;
+      default:
+    }
+  };
+
+  const renderStep = () => {
+    return (
+      <>
+        {Boolean(currentStep === 0) && (
+          <Step1
+            key={Math.random().toString(36).slice(2)}
+            pageData={pageData}
+            onChange={(data: RoutesModule.Step1PageDataProps) => 
handleChange(currentStep, data)}

Review comment:
       why not pass the target step to handleChange?

##########
File path: src/pages/Routes/components/Step1/index.tsx
##########
@@ -0,0 +1,312 @@
+import React, { useState } from 'react';
+import {
+  Form,
+  Button,
+  Divider,
+  Input,
+  Checkbox,
+  Row,
+  Col,
+  Table,
+  Space,
+  Modal,
+  Select,
+} from 'antd';
+import styles from '../../Create.less';
+
+const { TextArea } = Input;
+const { Option } = Select;
+
+const formItemLayout = {
+  labelCol: {
+    span: 6,
+  },
+  wrapperCol: {
+    span: 18,
+  },
+};
+
+const Step1: React.FC<RoutesModule.StepProps> = ({ pageData, onChange }) => {
+  const { step1PageData } = pageData;
+  const [form] = Form.useForm();
+  const [modalVisible, setModalVisible] = useState(false);
+  const [editModalData, setEditModalData] = useState();
+
+  const handleAdd = () => {
+    setModalVisible(true);
+  };
+
+  const handleEdit = (text: any, record: any) => {
+    setEditModalData(record);
+  };
+
+  const handleDelete = (text: any, record: any) => {

Review comment:
       handleRemove

##########
File path: src/pages/Routes/Create.tsx
##########
@@ -0,0 +1,69 @@
+import React, { useState } from 'react';
+import { Card, Steps } from 'antd';
+import { PageHeaderWrapper } from '@ant-design/pro-layout';
+import Step1 from './components/Step1';
+import styles from './Create.less';
+
+const { Step } = Steps;
+
+const Create: React.FC = () => {
+  const [step1PageData, setStep1PageData] = 
useState<RoutesModule.Step1PageDataProps>({
+    apiName: '',
+    protocol: '',
+    hosts: [],
+    requestPath: '',
+    httpMethods: [],
+    advancedConfig: [],
+  });
+
+  const [currentStep, setCurrentStep] = useState(0);
+  const [stepHeader, setStepHeader] = useState(['定义API请求', '定义API后端服务', '插件', 
'预览']);
+  const pageData = {
+    step1PageData,
+  };
+
+  const handleChange = (step: number, data: RoutesModule.Step1PageDataProps) 
=> {
+    switch (step) {
+      case 0:
+        setStep1PageData({ ...step1PageData, ...data });
+        break;
+      case 1:
+        // TODO: base on data show different step
+        setCurrentStep(1);
+        setStepHeader(['定义API请求', '定义API后端服务', '预览']);
+        break;
+      default:
+    }
+  };
+
+  const renderStep = () => {
+    return (
+      <>
+        {Boolean(currentStep === 0) && (
+          <Step1
+            key={Math.random().toString(36).slice(2)}

Review comment:
       key is not needed

##########
File path: src/pages/Routes/Create.tsx
##########
@@ -0,0 +1,69 @@
+import React, { useState } from 'react';
+import { Card, Steps } from 'antd';
+import { PageHeaderWrapper } from '@ant-design/pro-layout';
+import Step1 from './components/Step1';
+import styles from './Create.less';
+
+const { Step } = Steps;
+
+const Create: React.FC = () => {
+  const [step1PageData, setStep1PageData] = 
useState<RoutesModule.Step1PageDataProps>({
+    apiName: '',
+    protocol: '',
+    hosts: [],
+    requestPath: '',
+    httpMethods: [],
+    advancedConfig: [],
+  });
+
+  const [currentStep, setCurrentStep] = useState(0);
+  const [stepHeader, setStepHeader] = useState(['定义API请求', '定义API后端服务', '插件', 
'预览']);
+  const pageData = {
+    step1PageData,
+  };
+
+  const handleChange = (step: number, data: RoutesModule.Step1PageDataProps) 
=> {
+    switch (step) {
+      case 0:
+        setStep1PageData({ ...step1PageData, ...data });
+        break;
+      case 1:
+        // TODO: base on data show different step
+        setCurrentStep(1);
+        setStepHeader(['定义API请求', '定义API后端服务', '预览']);
+        break;
+      default:
+    }
+  };
+
+  const renderStep = () => {
+    return (
+      <>
+        {Boolean(currentStep === 0) && (
+          <Step1
+            key={Math.random().toString(36).slice(2)}
+            pageData={pageData}

Review comment:
       data is ok

##########
File path: src/pages/Routes/components/Step1/index.tsx
##########
@@ -0,0 +1,312 @@
+import React, { useState } from 'react';
+import {
+  Form,
+  Button,
+  Divider,
+  Input,
+  Checkbox,
+  Row,
+  Col,
+  Table,
+  Space,
+  Modal,
+  Select,
+} from 'antd';
+import styles from '../../Create.less';
+
+const { TextArea } = Input;
+const { Option } = Select;
+
+const formItemLayout = {
+  labelCol: {
+    span: 6,
+  },
+  wrapperCol: {
+    span: 18,
+  },
+};
+
+const Step1: React.FC<RoutesModule.StepProps> = ({ pageData, onChange }) => {
+  const { step1PageData } = pageData;
+  const [form] = Form.useForm();
+  const [modalVisible, setModalVisible] = useState(false);
+  const [editModalData, setEditModalData] = useState();
+
+  const handleAdd = () => {
+    setModalVisible(true);
+  };
+
+  const handleEdit = (text: any, record: any) => {
+    setEditModalData(record);
+  };
+
+  const handleDelete = (text: any, record: any) => {
+    const { advancedConfig } = step1PageData;
+    const filteredAdvancedConfig = advancedConfig.filter((item) => item.key 
!== record.key);
+    onChange({ advancedConfig: filteredAdvancedConfig });
+  };
+
+  const columns = [
+    {
+      title: '参数位置',
+      dataIndex: 'paramsLocation',
+      key: 'paramsLocation',
+    },
+    {
+      title: '参数名称',
+      dataIndex: 'paramsName',
+      key: 'paramsName',
+    },
+    {
+      title: '表达式',
+      dataIndex: 'paramsExpresstion',
+      key: 'paramsExpresstion',
+    },
+    {
+      title: '参数值',
+      dataIndex: 'paramsValue',
+      key: 'paramsValue',
+    },
+    {
+      title: '备注',
+      dataIndex: 'remark',
+      key: 'remark',
+    },
+    {
+      title: '操作',
+      key: 'action',
+      render: (text: any, record: any) => (
+        <Space size="middle">
+          <a onClick={() => handleEdit(text, record)}>编辑</a>
+          <a onClick={() => handleDelete(text, record)}>移除</a>
+        </Space>
+      ),
+    },
+  ];
+
+  const addHost = () => {
+    const { hosts } = step1PageData;

Review comment:
       you can destruct params from `step1Data` on the top level;

##########
File path: src/pages/Routes/components/Step1/index.tsx
##########
@@ -0,0 +1,312 @@
+import React, { useState } from 'react';
+import {
+  Form,
+  Button,
+  Divider,
+  Input,
+  Checkbox,
+  Row,
+  Col,
+  Table,
+  Space,
+  Modal,
+  Select,
+} from 'antd';
+import styles from '../../Create.less';
+
+const { TextArea } = Input;
+const { Option } = Select;
+
+const formItemLayout = {
+  labelCol: {
+    span: 6,
+  },
+  wrapperCol: {
+    span: 18,
+  },
+};
+
+const Step1: React.FC<RoutesModule.StepProps> = ({ pageData, onChange }) => {
+  const { step1PageData } = pageData;
+  const [form] = Form.useForm();
+  const [modalVisible, setModalVisible] = useState(false);
+  const [editModalData, setEditModalData] = useState();
+
+  const handleAdd = () => {
+    setModalVisible(true);
+  };
+
+  const handleEdit = (text: any, record: any) => {
+    setEditModalData(record);
+  };
+
+  const handleDelete = (text: any, record: any) => {
+    const { advancedConfig } = step1PageData;
+    const filteredAdvancedConfig = advancedConfig.filter((item) => item.key 
!== record.key);
+    onChange({ advancedConfig: filteredAdvancedConfig });
+  };
+
+  const columns = [
+    {
+      title: '参数位置',
+      dataIndex: 'paramsLocation',
+      key: 'paramsLocation',
+    },
+    {
+      title: '参数名称',
+      dataIndex: 'paramsName',
+      key: 'paramsName',
+    },
+    {
+      title: '表达式',
+      dataIndex: 'paramsExpresstion',
+      key: 'paramsExpresstion',
+    },
+    {
+      title: '参数值',
+      dataIndex: 'paramsValue',
+      key: 'paramsValue',
+    },
+    {
+      title: '备注',
+      dataIndex: 'remark',
+      key: 'remark',
+    },
+    {
+      title: '操作',
+      key: 'action',
+      render: (text: any, record: any) => (

Review comment:
       , 
   

##########
File path: src/pages/Routes/components/Step1/index.tsx
##########
@@ -0,0 +1,312 @@
+import React, { useState } from 'react';
+import {
+  Form,
+  Button,
+  Divider,
+  Input,
+  Checkbox,
+  Row,
+  Col,
+  Table,
+  Space,
+  Modal,
+  Select,
+} from 'antd';
+import styles from '../../Create.less';
+
+const { TextArea } = Input;
+const { Option } = Select;
+
+const formItemLayout = {
+  labelCol: {
+    span: 6,
+  },
+  wrapperCol: {
+    span: 18,
+  },
+};
+
+const Step1: React.FC<RoutesModule.StepProps> = ({ pageData, onChange }) => {
+  const { step1PageData } = pageData;
+  const [form] = Form.useForm();
+  const [modalVisible, setModalVisible] = useState(false);
+  const [editModalData, setEditModalData] = useState();
+
+  const handleAdd = () => {
+    setModalVisible(true);
+  };
+
+  const handleEdit = (text: any, record: any) => {
+    setEditModalData(record);
+  };
+
+  const handleDelete = (text: any, record: any) => {

Review comment:
       typings

##########
File path: src/pages/Routes/components/Step1/index.tsx
##########
@@ -0,0 +1,312 @@
+import React, { useState } from 'react';
+import {
+  Form,
+  Button,
+  Divider,
+  Input,
+  Checkbox,
+  Row,
+  Col,
+  Table,
+  Space,
+  Modal,
+  Select,
+} from 'antd';
+import styles from '../../Create.less';
+
+const { TextArea } = Input;
+const { Option } = Select;
+
+const formItemLayout = {
+  labelCol: {
+    span: 6,
+  },
+  wrapperCol: {
+    span: 18,
+  },
+};
+
+const Step1: React.FC<RoutesModule.StepProps> = ({ pageData, onChange }) => {
+  const { step1PageData } = pageData;
+  const [form] = Form.useForm();
+  const [modalVisible, setModalVisible] = useState(false);
+  const [editModalData, setEditModalData] = useState();

Review comment:
       set typing for this state

##########
File path: src/pages/Routes/components/Step1/index.tsx
##########
@@ -0,0 +1,312 @@
+import React, { useState } from 'react';
+import {
+  Form,
+  Button,
+  Divider,
+  Input,
+  Checkbox,
+  Row,
+  Col,
+  Table,
+  Space,
+  Modal,
+  Select,
+} from 'antd';
+import styles from '../../Create.less';
+
+const { TextArea } = Input;
+const { Option } = Select;
+
+const formItemLayout = {
+  labelCol: {
+    span: 6,
+  },
+  wrapperCol: {
+    span: 18,
+  },
+};
+
+const Step1: React.FC<RoutesModule.StepProps> = ({ pageData, onChange }) => {
+  const { step1PageData } = pageData;
+  const [form] = Form.useForm();
+  const [modalVisible, setModalVisible] = useState(false);
+  const [editModalData, setEditModalData] = useState();
+
+  const handleAdd = () => {
+    setModalVisible(true);
+  };
+
+  const handleEdit = (text: any, record: any) => {
+    setEditModalData(record);
+  };
+
+  const handleDelete = (text: any, record: any) => {
+    const { advancedConfig } = step1PageData;
+    const filteredAdvancedConfig = advancedConfig.filter((item) => item.key 
!== record.key);
+    onChange({ advancedConfig: filteredAdvancedConfig });
+  };
+
+  const columns = [
+    {
+      title: '参数位置',
+      dataIndex: 'paramsLocation',
+      key: 'paramsLocation',
+    },
+    {
+      title: '参数名称',
+      dataIndex: 'paramsName',
+      key: 'paramsName',
+    },
+    {
+      title: '表达式',
+      dataIndex: 'paramsExpresstion',
+      key: 'paramsExpresstion',
+    },
+    {
+      title: '参数值',
+      dataIndex: 'paramsValue',
+      key: 'paramsValue',
+    },
+    {
+      title: '备注',
+      dataIndex: 'remark',
+      key: 'remark',
+    },
+    {
+      title: '操作',
+      key: 'action',
+      render: (text: any, record: any) => (
+        <Space size="middle">
+          <a onClick={() => handleEdit(text, record)}>编辑</a>
+          <a onClick={() => handleDelete(text, record)}>移除</a>
+        </Space>
+      ),
+    },
+  ];
+
+  const addHost = () => {
+    const { hosts } = step1PageData;
+    onChange({
+      hosts: hosts.concat([
+        {
+          host: '',
+          port: '',
+          priority: '',
+        },
+      ]),
+    });
+  };
+
+  const renderHosts = () =>
+    step1PageData.hosts?.map((item, index) => (
+      <Row
+        key={Math.random().toString(36).slice(2)}
+        style={{ marginBottom: '10px' }}
+        gutter={[16, 16]}
+      >
+        <Col span={8}>
+          <Input placeholder="IP/HOST" />
+        </Col>
+        <Col span={4}>
+          <Input placeholder="PORT" />
+        </Col>
+        <Col span={4}>
+          <Input />
+        </Col>
+        <Col span={4}>
+          <Space>
+            <Button
+              type="primary"
+              danger
+              onClick={() => {
+                const { hosts } = step1PageData;
+                hosts.splice(index, 1);
+                onChange({ hosts });
+              }}
+            >
+              删除
+            </Button>
+          </Space>
+        </Col>
+      </Row>
+    ));
+
+  const renderNameAndDesc = () => (
+    <>
+      <div>名称及其描述</div>
+      <Divider />
+      <Form {...formItemLayout} form={form} layout="horizontal" 
className={styles.stepForm}>
+        <Form.Item
+          label="API名称"
+          name="APIName"
+          rules={[{ required: true, message: '请输入API名称' }]}
+        >
+          <Input placeholder="请输入API名称" />
+        </Form.Item>
+        <Form.Item label="描述" name="desc">
+          <TextArea placeholder="请输入描述" />
+        </Form.Item>
+      </Form>
+    </>
+  );
+
+  const renderBaseRequestConfig = () => (
+    <>
+      <div>请求基础定义</div>
+      <Divider />
+      <Form {...formItemLayout} form={form} layout="horizontal" 
className={styles.stepForm}>
+        <Form.Item label="协议" name="protocol" rules={[{ required: true, 
message: '请勾选协议' }]}>
+          <Checkbox.Group style={{ width: '100%' }}>
+            <Row>
+              {['HTTP', 'HTTPS', 'WebSocket'].map((item) => (
+                <Col span={6} key={item}>
+                  <Checkbox value={item}>{item}</Checkbox>
+                </Col>
+              ))}
+            </Row>
+          </Checkbox.Group>
+        </Form.Item>
+        <Form.Item label="IP/HOST" rules={[{ required: true, message: 
'请输入HOST' }]}>
+          {renderHosts()}
+          <Button onClick={addHost} type="primary">
+            增加
+          </Button>
+        </Form.Item>
+        <Form.Item label="请求PATH" name="path" rules={[{ required: true, 
message: '请输入PATH' }]}>
+          <Input placeholder="请输入PATH" />
+        </Form.Item>
+        <Form.Item
+          label="HTTP Methods"

Review comment:
       ,

##########
File path: src/pages/Routes/components/Step1/index.tsx
##########
@@ -0,0 +1,312 @@
+import React, { useState } from 'react';
+import {
+  Form,
+  Button,
+  Divider,
+  Input,
+  Checkbox,
+  Row,
+  Col,
+  Table,
+  Space,
+  Modal,
+  Select,
+} from 'antd';
+import styles from '../../Create.less';
+
+const { TextArea } = Input;
+const { Option } = Select;
+
+const formItemLayout = {
+  labelCol: {
+    span: 6,
+  },
+  wrapperCol: {
+    span: 18,
+  },
+};
+
+const Step1: React.FC<RoutesModule.StepProps> = ({ pageData, onChange }) => {
+  const { step1PageData } = pageData;
+  const [form] = Form.useForm();
+  const [modalVisible, setModalVisible] = useState(false);
+  const [editModalData, setEditModalData] = useState();
+
+  const handleAdd = () => {
+    setModalVisible(true);
+  };
+
+  const handleEdit = (text: any, record: any) => {
+    setEditModalData(record);
+  };
+
+  const handleDelete = (text: any, record: any) => {
+    const { advancedConfig } = step1PageData;
+    const filteredAdvancedConfig = advancedConfig.filter((item) => item.key 
!== record.key);
+    onChange({ advancedConfig: filteredAdvancedConfig });
+  };
+
+  const columns = [
+    {
+      title: '参数位置',
+      dataIndex: 'paramsLocation',
+      key: 'paramsLocation',
+    },
+    {
+      title: '参数名称',
+      dataIndex: 'paramsName',
+      key: 'paramsName',
+    },
+    {
+      title: '表达式',
+      dataIndex: 'paramsExpresstion',
+      key: 'paramsExpresstion',
+    },
+    {
+      title: '参数值',
+      dataIndex: 'paramsValue',
+      key: 'paramsValue',
+    },
+    {
+      title: '备注',
+      dataIndex: 'remark',
+      key: 'remark',
+    },
+    {
+      title: '操作',
+      key: 'action',
+      render: (text: any, record: any) => (
+        <Space size="middle">
+          <a onClick={() => handleEdit(text, record)}>编辑</a>
+          <a onClick={() => handleDelete(text, record)}>移除</a>
+        </Space>
+      ),
+    },
+  ];
+
+  const addHost = () => {
+    const { hosts } = step1PageData;
+    onChange({
+      hosts: hosts.concat([
+        {
+          host: '',
+          port: '',
+          priority: '',
+        },
+      ]),
+    });
+  };
+
+  const renderHosts = () =>
+    step1PageData.hosts?.map((item, index) => (
+      <Row
+        key={Math.random().toString(36).slice(2)}
+        style={{ marginBottom: '10px' }}
+        gutter={[16, 16]}
+      >
+        <Col span={8}>
+          <Input placeholder="IP/HOST" />
+        </Col>
+        <Col span={4}>
+          <Input placeholder="PORT" />
+        </Col>
+        <Col span={4}>
+          <Input />
+        </Col>
+        <Col span={4}>
+          <Space>
+            <Button
+              type="primary"
+              danger
+              onClick={() => {
+                const { hosts } = step1PageData;
+                hosts.splice(index, 1);
+                onChange({ hosts });
+              }}
+            >
+              删除
+            </Button>
+          </Space>
+        </Col>
+      </Row>
+    ));
+
+  const renderNameAndDesc = () => (
+    <>
+      <div>名称及其描述</div>
+      <Divider />
+      <Form {...formItemLayout} form={form} layout="horizontal" 
className={styles.stepForm}>
+        <Form.Item
+          label="API名称"
+          name="APIName"
+          rules={[{ required: true, message: '请输入API名称' }]}
+        >
+          <Input placeholder="请输入API名称" />
+        </Form.Item>
+        <Form.Item label="描述" name="desc">
+          <TextArea placeholder="请输入描述" />
+        </Form.Item>
+      </Form>
+    </>
+  );
+
+  const renderBaseRequestConfig = () => (
+    <>
+      <div>请求基础定义</div>
+      <Divider />
+      <Form {...formItemLayout} form={form} layout="horizontal" 
className={styles.stepForm}>
+        <Form.Item label="协议" name="protocol" rules={[{ required: true, 
message: '请勾选协议' }]}>
+          <Checkbox.Group style={{ width: '100%' }}>
+            <Row>
+              {['HTTP', 'HTTPS', 'WebSocket'].map((item) => (
+                <Col span={6} key={item}>
+                  <Checkbox value={item}>{item}</Checkbox>
+                </Col>
+              ))}
+            </Row>
+          </Checkbox.Group>
+        </Form.Item>
+        <Form.Item label="IP/HOST" rules={[{ required: true, message: 
'请输入HOST' }]}>
+          {renderHosts()}
+          <Button onClick={addHost} type="primary">
+            增加
+          </Button>
+        </Form.Item>
+        <Form.Item label="请求PATH" name="path" rules={[{ required: true, 
message: '请输入PATH' }]}>
+          <Input placeholder="请输入PATH" />
+        </Form.Item>
+        <Form.Item
+          label="HTTP Methods"
+          name="httpMethods"
+          rules={[{ required: true, message: '请勾选HTTP Methods' }]}

Review comment:
       ,

##########
File path: src/pages/Routes/components/Step1/index.tsx
##########
@@ -0,0 +1,312 @@
+import React, { useState } from 'react';
+import {
+  Form,
+  Button,
+  Divider,
+  Input,
+  Checkbox,
+  Row,
+  Col,
+  Table,
+  Space,
+  Modal,
+  Select,
+} from 'antd';
+import styles from '../../Create.less';
+
+const { TextArea } = Input;
+const { Option } = Select;
+
+const formItemLayout = {
+  labelCol: {
+    span: 6,
+  },
+  wrapperCol: {
+    span: 18,
+  },
+};
+
+const Step1: React.FC<RoutesModule.StepProps> = ({ pageData, onChange }) => {
+  const { step1PageData } = pageData;
+  const [form] = Form.useForm();
+  const [modalVisible, setModalVisible] = useState(false);
+  const [editModalData, setEditModalData] = useState();
+
+  const handleAdd = () => {
+    setModalVisible(true);
+  };
+
+  const handleEdit = (text: any, record: any) => {
+    setEditModalData(record);
+  };
+
+  const handleDelete = (text: any, record: any) => {
+    const { advancedConfig } = step1PageData;
+    const filteredAdvancedConfig = advancedConfig.filter((item) => item.key 
!== record.key);
+    onChange({ advancedConfig: filteredAdvancedConfig });
+  };
+
+  const columns = [
+    {
+      title: '参数位置',
+      dataIndex: 'paramsLocation',
+      key: 'paramsLocation',
+    },
+    {
+      title: '参数名称',
+      dataIndex: 'paramsName',
+      key: 'paramsName',
+    },
+    {
+      title: '表达式',
+      dataIndex: 'paramsExpresstion',
+      key: 'paramsExpresstion',
+    },
+    {
+      title: '参数值',
+      dataIndex: 'paramsValue',
+      key: 'paramsValue',
+    },
+    {
+      title: '备注',
+      dataIndex: 'remark',
+      key: 'remark',
+    },
+    {
+      title: '操作',
+      key: 'action',
+      render: (text: any, record: any) => (
+        <Space size="middle">
+          <a onClick={() => handleEdit(text, record)}>编辑</a>
+          <a onClick={() => handleDelete(text, record)}>移除</a>
+        </Space>
+      ),
+    },
+  ];
+
+  const addHost = () => {
+    const { hosts } = step1PageData;
+    onChange({
+      hosts: hosts.concat([
+        {
+          host: '',
+          port: '',
+          priority: '',
+        },
+      ]),
+    });
+  };
+
+  const renderHosts = () =>
+    step1PageData.hosts?.map((item, index) => (
+      <Row
+        key={Math.random().toString(36).slice(2)}
+        style={{ marginBottom: '10px' }}
+        gutter={[16, 16]}
+      >
+        <Col span={8}>
+          <Input placeholder="IP/HOST" />
+        </Col>
+        <Col span={4}>
+          <Input placeholder="PORT" />
+        </Col>
+        <Col span={4}>
+          <Input />

Review comment:
       权重

##########
File path: src/pages/Routes/components/Step1/index.tsx
##########
@@ -0,0 +1,312 @@
+import React, { useState } from 'react';
+import {
+  Form,
+  Button,
+  Divider,
+  Input,
+  Checkbox,
+  Row,
+  Col,
+  Table,
+  Space,
+  Modal,
+  Select,
+} from 'antd';
+import styles from '../../Create.less';
+
+const { TextArea } = Input;
+const { Option } = Select;
+
+const formItemLayout = {
+  labelCol: {
+    span: 6,
+  },
+  wrapperCol: {
+    span: 18,
+  },
+};
+
+const Step1: React.FC<RoutesModule.StepProps> = ({ pageData, onChange }) => {
+  const { step1PageData } = pageData;
+  const [form] = Form.useForm();
+  const [modalVisible, setModalVisible] = useState(false);
+  const [editModalData, setEditModalData] = useState();
+
+  const handleAdd = () => {
+    setModalVisible(true);
+  };
+
+  const handleEdit = (text: any, record: any) => {
+    setEditModalData(record);
+  };
+
+  const handleDelete = (text: any, record: any) => {
+    const { advancedConfig } = step1PageData;
+    const filteredAdvancedConfig = advancedConfig.filter((item) => item.key 
!== record.key);
+    onChange({ advancedConfig: filteredAdvancedConfig });
+  };
+
+  const columns = [
+    {
+      title: '参数位置',
+      dataIndex: 'paramsLocation',
+      key: 'paramsLocation',
+    },
+    {
+      title: '参数名称',
+      dataIndex: 'paramsName',
+      key: 'paramsName',
+    },
+    {
+      title: '表达式',
+      dataIndex: 'paramsExpresstion',
+      key: 'paramsExpresstion',
+    },
+    {
+      title: '参数值',
+      dataIndex: 'paramsValue',
+      key: 'paramsValue',
+    },
+    {
+      title: '备注',
+      dataIndex: 'remark',
+      key: 'remark',
+    },
+    {
+      title: '操作',
+      key: 'action',
+      render: (text: any, record: any) => (
+        <Space size="middle">
+          <a onClick={() => handleEdit(text, record)}>编辑</a>
+          <a onClick={() => handleDelete(text, record)}>移除</a>
+        </Space>
+      ),
+    },
+  ];
+
+  const addHost = () => {
+    const { hosts } = step1PageData;
+    onChange({
+      hosts: hosts.concat([
+        {
+          host: '',
+          port: '',
+          priority: '',

Review comment:
       ,

##########
File path: src/pages/Routes/components/Step1/index.tsx
##########
@@ -0,0 +1,312 @@
+import React, { useState } from 'react';
+import {
+  Form,
+  Button,
+  Divider,
+  Input,
+  Checkbox,
+  Row,
+  Col,
+  Table,
+  Space,
+  Modal,
+  Select,
+} from 'antd';
+import styles from '../../Create.less';
+
+const { TextArea } = Input;
+const { Option } = Select;
+
+const formItemLayout = {
+  labelCol: {
+    span: 6,
+  },
+  wrapperCol: {
+    span: 18,
+  },
+};
+
+const Step1: React.FC<RoutesModule.StepProps> = ({ pageData, onChange }) => {
+  const { step1PageData } = pageData;
+  const [form] = Form.useForm();
+  const [modalVisible, setModalVisible] = useState(false);
+  const [editModalData, setEditModalData] = useState();
+
+  const handleAdd = () => {
+    setModalVisible(true);
+  };
+
+  const handleEdit = (text: any, record: any) => {

Review comment:
       what's text?

##########
File path: src/pages/Routes/components/Step1/index.tsx
##########
@@ -0,0 +1,312 @@
+import React, { useState } from 'react';
+import {
+  Form,
+  Button,
+  Divider,
+  Input,
+  Checkbox,
+  Row,
+  Col,
+  Table,
+  Space,
+  Modal,
+  Select,
+} from 'antd';
+import styles from '../../Create.less';
+
+const { TextArea } = Input;
+const { Option } = Select;
+
+const formItemLayout = {
+  labelCol: {
+    span: 6,
+  },
+  wrapperCol: {
+    span: 18,
+  },
+};
+
+const Step1: React.FC<RoutesModule.StepProps> = ({ pageData, onChange }) => {
+  const { step1PageData } = pageData;
+  const [form] = Form.useForm();
+  const [modalVisible, setModalVisible] = useState(false);
+  const [editModalData, setEditModalData] = useState();
+
+  const handleAdd = () => {
+    setModalVisible(true);
+  };
+
+  const handleEdit = (text: any, record: any) => {
+    setEditModalData(record);
+  };
+
+  const handleDelete = (text: any, record: any) => {
+    const { advancedConfig } = step1PageData;

Review comment:
       ,

##########
File path: src/pages/Routes/components/Step1/index.tsx
##########
@@ -0,0 +1,312 @@
+import React, { useState } from 'react';
+import {
+  Form,
+  Button,
+  Divider,
+  Input,
+  Checkbox,
+  Row,
+  Col,
+  Table,
+  Space,
+  Modal,
+  Select,
+} from 'antd';
+import styles from '../../Create.less';
+
+const { TextArea } = Input;
+const { Option } = Select;
+
+const formItemLayout = {
+  labelCol: {
+    span: 6,
+  },
+  wrapperCol: {
+    span: 18,
+  },
+};
+
+const Step1: React.FC<RoutesModule.StepProps> = ({ pageData, onChange }) => {
+  const { step1PageData } = pageData;
+  const [form] = Form.useForm();
+  const [modalVisible, setModalVisible] = useState(false);
+  const [editModalData, setEditModalData] = useState();
+
+  const handleAdd = () => {
+    setModalVisible(true);
+  };
+
+  const handleEdit = (text: any, record: any) => {
+    setEditModalData(record);
+  };
+
+  const handleDelete = (text: any, record: any) => {
+    const { advancedConfig } = step1PageData;
+    const filteredAdvancedConfig = advancedConfig.filter((item) => item.key 
!== record.key);
+    onChange({ advancedConfig: filteredAdvancedConfig });
+  };
+
+  const columns = [
+    {
+      title: '参数位置',
+      dataIndex: 'paramsLocation',
+      key: 'paramsLocation',
+    },
+    {
+      title: '参数名称',
+      dataIndex: 'paramsName',
+      key: 'paramsName',
+    },
+    {
+      title: '表达式',
+      dataIndex: 'paramsExpresstion',
+      key: 'paramsExpresstion',
+    },
+    {
+      title: '参数值',
+      dataIndex: 'paramsValue',
+      key: 'paramsValue',
+    },
+    {
+      title: '备注',
+      dataIndex: 'remark',
+      key: 'remark',
+    },
+    {
+      title: '操作',
+      key: 'action',
+      render: (text: any, record: any) => (
+        <Space size="middle">
+          <a onClick={() => handleEdit(text, record)}>编辑</a>
+          <a onClick={() => handleDelete(text, record)}>移除</a>
+        </Space>
+      ),
+    },
+  ];
+
+  const addHost = () => {
+    const { hosts } = step1PageData;
+    onChange({
+      hosts: hosts.concat([
+        {
+          host: '',
+          port: '',
+          priority: '',
+        },
+      ]),
+    });
+  };
+
+  const renderHosts = () =>
+    step1PageData.hosts?.map((item, index) => (
+      <Row
+        key={Math.random().toString(36).slice(2)}
+        style={{ marginBottom: '10px' }}
+        gutter={[16, 16]}
+      >
+        <Col span={8}>
+          <Input placeholder="IP/HOST" />
+        </Col>
+        <Col span={4}>
+          <Input placeholder="PORT" />
+        </Col>
+        <Col span={4}>
+          <Input />
+        </Col>
+        <Col span={4}>
+          <Space>
+            <Button
+              type="primary"
+              danger
+              onClick={() => {
+                const { hosts } = step1PageData;
+                hosts.splice(index, 1);
+                onChange({ hosts });
+              }}
+            >
+              删除
+            </Button>
+          </Space>
+        </Col>
+      </Row>
+    ));
+
+  const renderNameAndDesc = () => (

Review comment:
       meta

##########
File path: src/pages/Routes/components/Step1/index.tsx
##########
@@ -0,0 +1,312 @@
+import React, { useState } from 'react';
+import {
+  Form,
+  Button,
+  Divider,
+  Input,
+  Checkbox,
+  Row,
+  Col,
+  Table,
+  Space,
+  Modal,
+  Select,
+} from 'antd';
+import styles from '../../Create.less';
+
+const { TextArea } = Input;
+const { Option } = Select;
+
+const formItemLayout = {
+  labelCol: {
+    span: 6,
+  },
+  wrapperCol: {
+    span: 18,
+  },
+};
+
+const Step1: React.FC<RoutesModule.StepProps> = ({ pageData, onChange }) => {
+  const { step1PageData } = pageData;
+  const [form] = Form.useForm();
+  const [modalVisible, setModalVisible] = useState(false);
+  const [editModalData, setEditModalData] = useState();
+
+  const handleAdd = () => {
+    setModalVisible(true);
+  };
+
+  const handleEdit = (text: any, record: any) => {
+    setEditModalData(record);
+  };
+
+  const handleDelete = (text: any, record: any) => {
+    const { advancedConfig } = step1PageData;
+    const filteredAdvancedConfig = advancedConfig.filter((item) => item.key 
!== record.key);
+    onChange({ advancedConfig: filteredAdvancedConfig });
+  };
+
+  const columns = [
+    {
+      title: '参数位置',
+      dataIndex: 'paramsLocation',
+      key: 'paramsLocation',
+    },
+    {
+      title: '参数名称',
+      dataIndex: 'paramsName',
+      key: 'paramsName',
+    },
+    {
+      title: '表达式',
+      dataIndex: 'paramsExpresstion',
+      key: 'paramsExpresstion',
+    },
+    {
+      title: '参数值',
+      dataIndex: 'paramsValue',
+      key: 'paramsValue',
+    },
+    {
+      title: '备注',
+      dataIndex: 'remark',
+      key: 'remark',
+    },
+    {
+      title: '操作',
+      key: 'action',
+      render: (text: any, record: any) => (
+        <Space size="middle">
+          <a onClick={() => handleEdit(text, record)}>编辑</a>
+          <a onClick={() => handleDelete(text, record)}>移除</a>
+        </Space>
+      ),
+    },
+  ];
+
+  const addHost = () => {
+    const { hosts } = step1PageData;
+    onChange({
+      hosts: hosts.concat([
+        {
+          host: '',
+          port: '',
+          priority: '',
+        },
+      ]),
+    });
+  };
+
+  const renderHosts = () =>
+    step1PageData.hosts?.map((item, index) => (

Review comment:
       ,  

##########
File path: src/pages/Routes/components/Step1/index.tsx
##########
@@ -0,0 +1,312 @@
+import React, { useState } from 'react';
+import {
+  Form,
+  Button,
+  Divider,
+  Input,
+  Checkbox,
+  Row,
+  Col,
+  Table,
+  Space,
+  Modal,
+  Select,
+} from 'antd';
+import styles from '../../Create.less';
+
+const { TextArea } = Input;
+const { Option } = Select;
+
+const formItemLayout = {
+  labelCol: {
+    span: 6,
+  },
+  wrapperCol: {
+    span: 18,
+  },
+};
+
+const Step1: React.FC<RoutesModule.StepProps> = ({ pageData, onChange }) => {
+  const { step1PageData } = pageData;
+  const [form] = Form.useForm();
+  const [modalVisible, setModalVisible] = useState(false);
+  const [editModalData, setEditModalData] = useState();
+
+  const handleAdd = () => {
+    setModalVisible(true);
+  };
+
+  const handleEdit = (text: any, record: any) => {

Review comment:
       any for record is incompatible

##########
File path: src/pages/Routes/components/Step1/index.tsx
##########
@@ -0,0 +1,312 @@
+import React, { useState } from 'react';
+import {
+  Form,
+  Button,
+  Divider,
+  Input,
+  Checkbox,
+  Row,
+  Col,
+  Table,
+  Space,
+  Modal,
+  Select,
+} from 'antd';
+import styles from '../../Create.less';
+
+const { TextArea } = Input;
+const { Option } = Select;
+
+const formItemLayout = {
+  labelCol: {
+    span: 6,
+  },
+  wrapperCol: {
+    span: 18,
+  },
+};
+
+const Step1: React.FC<RoutesModule.StepProps> = ({ pageData, onChange }) => {
+  const { step1PageData } = pageData;
+  const [form] = Form.useForm();
+  const [modalVisible, setModalVisible] = useState(false);
+  const [editModalData, setEditModalData] = useState();
+
+  const handleAdd = () => {
+    setModalVisible(true);
+  };
+
+  const handleEdit = (text: any, record: any) => {
+    setEditModalData(record);
+  };
+
+  const handleDelete = (text: any, record: any) => {
+    const { advancedConfig } = step1PageData;
+    const filteredAdvancedConfig = advancedConfig.filter((item) => item.key 
!== record.key);
+    onChange({ advancedConfig: filteredAdvancedConfig });
+  };
+
+  const columns = [
+    {
+      title: '参数位置',
+      dataIndex: 'paramsLocation',
+      key: 'paramsLocation',
+    },
+    {
+      title: '参数名称',
+      dataIndex: 'paramsName',
+      key: 'paramsName',
+    },
+    {
+      title: '表达式',
+      dataIndex: 'paramsExpresstion',
+      key: 'paramsExpresstion',
+    },
+    {
+      title: '参数值',
+      dataIndex: 'paramsValue',
+      key: 'paramsValue',
+    },
+    {
+      title: '备注',
+      dataIndex: 'remark',
+      key: 'remark',
+    },
+    {
+      title: '操作',
+      key: 'action',
+      render: (text: any, record: any) => (
+        <Space size="middle">
+          <a onClick={() => handleEdit(text, record)}>编辑</a>
+          <a onClick={() => handleDelete(text, record)}>移除</a>
+        </Space>
+      ),
+    },
+  ];
+
+  const addHost = () => {
+    const { hosts } = step1PageData;
+    onChange({
+      hosts: hosts.concat([
+        {
+          host: '',
+          port: '',
+          priority: '',
+        },
+      ]),
+    });
+  };
+
+  const renderHosts = () =>
+    step1PageData.hosts?.map((item, index) => (
+      <Row
+        key={Math.random().toString(36).slice(2)}

Review comment:
       host + key

##########
File path: src/pages/Routes/components/Step1/index.tsx
##########
@@ -0,0 +1,312 @@
+import React, { useState } from 'react';
+import {
+  Form,
+  Button,
+  Divider,
+  Input,
+  Checkbox,
+  Row,
+  Col,
+  Table,
+  Space,
+  Modal,
+  Select,
+} from 'antd';
+import styles from '../../Create.less';
+
+const { TextArea } = Input;
+const { Option } = Select;
+
+const formItemLayout = {
+  labelCol: {
+    span: 6,
+  },
+  wrapperCol: {
+    span: 18,
+  },
+};
+
+const Step1: React.FC<RoutesModule.StepProps> = ({ pageData, onChange }) => {
+  const { step1PageData } = pageData;
+  const [form] = Form.useForm();
+  const [modalVisible, setModalVisible] = useState(false);
+  const [editModalData, setEditModalData] = useState();
+
+  const handleAdd = () => {
+    setModalVisible(true);
+  };
+
+  const handleEdit = (text: any, record: any) => {
+    setEditModalData(record);
+  };
+
+  const handleDelete = (text: any, record: any) => {
+    const { advancedConfig } = step1PageData;
+    const filteredAdvancedConfig = advancedConfig.filter((item) => item.key 
!== record.key);
+    onChange({ advancedConfig: filteredAdvancedConfig });
+  };
+
+  const columns = [
+    {
+      title: '参数位置',
+      dataIndex: 'paramsLocation',
+      key: 'paramsLocation',
+    },
+    {
+      title: '参数名称',
+      dataIndex: 'paramsName',
+      key: 'paramsName',
+    },
+    {
+      title: '表达式',
+      dataIndex: 'paramsExpresstion',
+      key: 'paramsExpresstion',
+    },
+    {
+      title: '参数值',
+      dataIndex: 'paramsValue',
+      key: 'paramsValue',
+    },
+    {
+      title: '备注',
+      dataIndex: 'remark',
+      key: 'remark',
+    },
+    {
+      title: '操作',
+      key: 'action',
+      render: (text: any, record: any) => (
+        <Space size="middle">
+          <a onClick={() => handleEdit(text, record)}>编辑</a>
+          <a onClick={() => handleDelete(text, record)}>移除</a>
+        </Space>
+      ),
+    },
+  ];
+
+  const addHost = () => {
+    const { hosts } = step1PageData;
+    onChange({
+      hosts: hosts.concat([
+        {
+          host: '',
+          port: '',
+          priority: '',
+        },
+      ]),
+    });
+  };
+
+  const renderHosts = () =>
+    step1PageData.hosts?.map((item, index) => (
+      <Row
+        key={Math.random().toString(36).slice(2)}
+        style={{ marginBottom: '10px' }}
+        gutter={[16, 16]}
+      >
+        <Col span={8}>
+          <Input placeholder="IP/HOST" />
+        </Col>
+        <Col span={4}>
+          <Input placeholder="PORT" />
+        </Col>
+        <Col span={4}>
+          <Input />
+        </Col>
+        <Col span={4}>
+          <Space>
+            <Button
+              type="primary"
+              danger
+              onClick={() => {
+                const { hosts } = step1PageData;

Review comment:
       ,

##########
File path: src/pages/Routes/components/Step1/index.tsx
##########
@@ -0,0 +1,312 @@
+import React, { useState } from 'react';
+import {
+  Form,
+  Button,
+  Divider,
+  Input,
+  Checkbox,
+  Row,
+  Col,
+  Table,
+  Space,
+  Modal,
+  Select,
+} from 'antd';
+import styles from '../../Create.less';
+
+const { TextArea } = Input;
+const { Option } = Select;
+
+const formItemLayout = {
+  labelCol: {
+    span: 6,
+  },
+  wrapperCol: {
+    span: 18,
+  },
+};
+
+const Step1: React.FC<RoutesModule.StepProps> = ({ pageData, onChange }) => {
+  const { step1PageData } = pageData;
+  const [form] = Form.useForm();
+  const [modalVisible, setModalVisible] = useState(false);
+  const [editModalData, setEditModalData] = useState();
+
+  const handleAdd = () => {
+    setModalVisible(true);
+  };
+
+  const handleEdit = (text: any, record: any) => {
+    setEditModalData(record);
+  };
+
+  const handleDelete = (text: any, record: any) => {
+    const { advancedConfig } = step1PageData;
+    const filteredAdvancedConfig = advancedConfig.filter((item) => item.key 
!== record.key);
+    onChange({ advancedConfig: filteredAdvancedConfig });
+  };
+
+  const columns = [
+    {
+      title: '参数位置',
+      dataIndex: 'paramsLocation',
+      key: 'paramsLocation',
+    },
+    {
+      title: '参数名称',
+      dataIndex: 'paramsName',
+      key: 'paramsName',
+    },
+    {
+      title: '表达式',
+      dataIndex: 'paramsExpresstion',
+      key: 'paramsExpresstion',
+    },
+    {
+      title: '参数值',
+      dataIndex: 'paramsValue',
+      key: 'paramsValue',
+    },
+    {
+      title: '备注',
+      dataIndex: 'remark',
+      key: 'remark',
+    },
+    {
+      title: '操作',
+      key: 'action',
+      render: (text: any, record: any) => (
+        <Space size="middle">
+          <a onClick={() => handleEdit(text, record)}>编辑</a>
+          <a onClick={() => handleDelete(text, record)}>移除</a>
+        </Space>
+      ),
+    },
+  ];
+
+  const addHost = () => {
+    const { hosts } = step1PageData;
+    onChange({
+      hosts: hosts.concat([
+        {
+          host: '',
+          port: '',
+          priority: '',
+        },
+      ]),
+    });
+  };
+
+  const renderHosts = () =>
+    step1PageData.hosts?.map((item, index) => (
+      <Row
+        key={Math.random().toString(36).slice(2)}
+        style={{ marginBottom: '10px' }}
+        gutter={[16, 16]}
+      >
+        <Col span={8}>
+          <Input placeholder="IP/HOST" />
+        </Col>
+        <Col span={4}>
+          <Input placeholder="PORT" />
+        </Col>
+        <Col span={4}>
+          <Input />
+        </Col>
+        <Col span={4}>
+          <Space>
+            <Button
+              type="primary"
+              danger
+              onClick={() => {
+                const { hosts } = step1PageData;
+                hosts.splice(index, 1);

Review comment:
       ,

##########
File path: src/pages/Routes/components/Step1/index.tsx
##########
@@ -0,0 +1,312 @@
+import React, { useState } from 'react';
+import {
+  Form,
+  Button,
+  Divider,
+  Input,
+  Checkbox,
+  Row,
+  Col,
+  Table,
+  Space,
+  Modal,
+  Select,
+} from 'antd';
+import styles from '../../Create.less';
+
+const { TextArea } = Input;
+const { Option } = Select;
+
+const formItemLayout = {
+  labelCol: {
+    span: 6,
+  },
+  wrapperCol: {
+    span: 18,
+  },
+};
+
+const Step1: React.FC<RoutesModule.StepProps> = ({ pageData, onChange }) => {
+  const { step1PageData } = pageData;
+  const [form] = Form.useForm();
+  const [modalVisible, setModalVisible] = useState(false);
+  const [editModalData, setEditModalData] = useState();
+
+  const handleAdd = () => {
+    setModalVisible(true);
+  };
+
+  const handleEdit = (text: any, record: any) => {
+    setEditModalData(record);
+  };
+
+  const handleDelete = (text: any, record: any) => {
+    const { advancedConfig } = step1PageData;
+    const filteredAdvancedConfig = advancedConfig.filter((item) => item.key 
!== record.key);
+    onChange({ advancedConfig: filteredAdvancedConfig });
+  };
+
+  const columns = [
+    {
+      title: '参数位置',
+      dataIndex: 'paramsLocation',
+      key: 'paramsLocation',
+    },
+    {
+      title: '参数名称',
+      dataIndex: 'paramsName',
+      key: 'paramsName',
+    },
+    {
+      title: '表达式',
+      dataIndex: 'paramsExpresstion',
+      key: 'paramsExpresstion',
+    },
+    {
+      title: '参数值',
+      dataIndex: 'paramsValue',
+      key: 'paramsValue',
+    },
+    {
+      title: '备注',
+      dataIndex: 'remark',
+      key: 'remark',
+    },
+    {
+      title: '操作',
+      key: 'action',
+      render: (text: any, record: any) => (
+        <Space size="middle">
+          <a onClick={() => handleEdit(text, record)}>编辑</a>
+          <a onClick={() => handleDelete(text, record)}>移除</a>
+        </Space>
+      ),
+    },
+  ];
+
+  const addHost = () => {
+    const { hosts } = step1PageData;
+    onChange({
+      hosts: hosts.concat([
+        {
+          host: '',
+          port: '',
+          priority: '',
+        },
+      ]),
+    });
+  };
+
+  const renderHosts = () =>
+    step1PageData.hosts?.map((item, index) => (
+      <Row
+        key={Math.random().toString(36).slice(2)}
+        style={{ marginBottom: '10px' }}
+        gutter={[16, 16]}
+      >
+        <Col span={8}>
+          <Input placeholder="IP/HOST" />
+        </Col>
+        <Col span={4}>
+          <Input placeholder="PORT" />
+        </Col>
+        <Col span={4}>
+          <Input />
+        </Col>
+        <Col span={4}>
+          <Space>
+            <Button
+              type="primary"
+              danger
+              onClick={() => {
+                const { hosts } = step1PageData;
+                hosts.splice(index, 1);
+                onChange({ hosts });
+              }}
+            >
+              删除
+            </Button>
+          </Space>
+        </Col>
+      </Row>
+    ));
+
+  const renderNameAndDesc = () => (
+    <>
+      <div>名称及其描述</div>
+      <Divider />
+      <Form {...formItemLayout} form={form} layout="horizontal" 
className={styles.stepForm}>
+        <Form.Item
+          label="API名称"
+          name="APIName"
+          rules={[{ required: true, message: '请输入API名称' }]}
+        >
+          <Input placeholder="请输入API名称" />
+        </Form.Item>
+        <Form.Item label="描述" name="desc">
+          <TextArea placeholder="请输入描述" />
+        </Form.Item>
+      </Form>
+    </>
+  );
+
+  const renderBaseRequestConfig = () => (
+    <>
+      <div>请求基础定义</div>
+      <Divider />
+      <Form {...formItemLayout} form={form} layout="horizontal" 
className={styles.stepForm}>
+        <Form.Item label="协议" name="protocol" rules={[{ required: true, 
message: '请勾选协议' }]}>
+          <Checkbox.Group style={{ width: '100%' }}>
+            <Row>
+              {['HTTP', 'HTTPS', 'WebSocket'].map((item) => (
+                <Col span={6} key={item}>
+                  <Checkbox value={item}>{item}</Checkbox>
+                </Col>
+              ))}
+            </Row>
+          </Checkbox.Group>
+        </Form.Item>
+        <Form.Item label="IP/HOST" rules={[{ required: true, message: 
'请输入HOST' }]}>
+          {renderHosts()}
+          <Button onClick={addHost} type="primary">
+            增加
+          </Button>
+        </Form.Item>
+        <Form.Item label="请求PATH" name="path" rules={[{ required: true, 
message: '请输入PATH' }]}>
+          <Input placeholder="请输入PATH" />
+        </Form.Item>
+        <Form.Item
+          label="HTTP Methods"
+          name="httpMethods"
+          rules={[{ required: true, message: '请勾选HTTP Methods' }]}
+        >
+          <Checkbox.Group style={{ width: '100%' }}>
+            <Row>
+              {['ANY', 'GET', 'HEAD', 'POST', 'PUT', 'DELETE', 'OPTIONS', 
'PATCH'].map((item) => (
+                <Col span={6} key={item}>
+                  <Checkbox value={item}>{item}</Checkbox>
+                </Col>
+              ))}
+            </Row>
+          </Checkbox.Group>
+        </Form.Item>
+      </Form>
+    </>
+  );
+
+  const renderModal = () => {
+    const [modalForm] = Form.useForm();
+    const validateModalFields = modalForm.validateFields;
+    const { resetFields } = modalForm;
+    const handleOk = () => {
+      validateModalFields().then((value) => {
+        const { advancedConfig } = step1PageData;
+        onChange({
+          advancedConfig: advancedConfig.concat({
+            ...(value as RoutesModule.Step1ModalProps),
+            key: Math.random().toString(36).slice(2),
+          }),
+        });
+      });
+    };
+
+    const handleCancel = () => {
+      setModalVisible(false);
+    };
+
+    const handleAfterClose = () => {
+      resetFields();
+    };
+    return (
+      <>
+        <Modal
+          title="新增"
+          centered
+          visible={modalVisible}
+          afterClose={handleAfterClose}
+          onOk={handleOk}
+          onCancel={handleCancel}
+          destroyOnClose
+        >
+          <Form
+            name="basic"

Review comment:
       ,

##########
File path: src/pages/Routes/components/Step1/index.tsx
##########
@@ -0,0 +1,312 @@
+import React, { useState } from 'react';
+import {
+  Form,
+  Button,
+  Divider,
+  Input,
+  Checkbox,
+  Row,
+  Col,
+  Table,
+  Space,
+  Modal,
+  Select,
+} from 'antd';
+import styles from '../../Create.less';
+
+const { TextArea } = Input;
+const { Option } = Select;
+
+const formItemLayout = {
+  labelCol: {
+    span: 6,
+  },
+  wrapperCol: {
+    span: 18,
+  },
+};
+
+const Step1: React.FC<RoutesModule.StepProps> = ({ pageData, onChange }) => {
+  const { step1PageData } = pageData;
+  const [form] = Form.useForm();
+  const [modalVisible, setModalVisible] = useState(false);
+  const [editModalData, setEditModalData] = useState();
+
+  const handleAdd = () => {
+    setModalVisible(true);
+  };
+
+  const handleEdit = (text: any, record: any) => {
+    setEditModalData(record);
+  };
+
+  const handleDelete = (text: any, record: any) => {
+    const { advancedConfig } = step1PageData;
+    const filteredAdvancedConfig = advancedConfig.filter((item) => item.key 
!== record.key);
+    onChange({ advancedConfig: filteredAdvancedConfig });
+  };
+
+  const columns = [
+    {
+      title: '参数位置',
+      dataIndex: 'paramsLocation',
+      key: 'paramsLocation',
+    },
+    {
+      title: '参数名称',
+      dataIndex: 'paramsName',
+      key: 'paramsName',
+    },
+    {
+      title: '表达式',
+      dataIndex: 'paramsExpresstion',
+      key: 'paramsExpresstion',
+    },
+    {
+      title: '参数值',
+      dataIndex: 'paramsValue',
+      key: 'paramsValue',
+    },
+    {
+      title: '备注',
+      dataIndex: 'remark',
+      key: 'remark',
+    },
+    {
+      title: '操作',
+      key: 'action',
+      render: (text: any, record: any) => (
+        <Space size="middle">
+          <a onClick={() => handleEdit(text, record)}>编辑</a>
+          <a onClick={() => handleDelete(text, record)}>移除</a>
+        </Space>
+      ),
+    },
+  ];
+
+  const addHost = () => {
+    const { hosts } = step1PageData;
+    onChange({
+      hosts: hosts.concat([
+        {
+          host: '',
+          port: '',
+          priority: '',
+        },
+      ]),
+    });
+  };
+
+  const renderHosts = () =>
+    step1PageData.hosts?.map((item, index) => (
+      <Row
+        key={Math.random().toString(36).slice(2)}
+        style={{ marginBottom: '10px' }}
+        gutter={[16, 16]}
+      >
+        <Col span={8}>
+          <Input placeholder="IP/HOST" />
+        </Col>
+        <Col span={4}>
+          <Input placeholder="PORT" />
+        </Col>
+        <Col span={4}>
+          <Input />
+        </Col>
+        <Col span={4}>
+          <Space>
+            <Button
+              type="primary"
+              danger
+              onClick={() => {
+                const { hosts } = step1PageData;
+                hosts.splice(index, 1);
+                onChange({ hosts });
+              }}
+            >
+              删除
+            </Button>
+          </Space>
+        </Col>
+      </Row>
+    ));
+
+  const renderNameAndDesc = () => (
+    <>
+      <div>名称及其描述</div>
+      <Divider />
+      <Form {...formItemLayout} form={form} layout="horizontal" 
className={styles.stepForm}>
+        <Form.Item
+          label="API名称"

Review comment:
       space

##########
File path: src/pages/Routes/components/Step1/index.tsx
##########
@@ -0,0 +1,312 @@
+import React, { useState } from 'react';
+import {
+  Form,
+  Button,
+  Divider,
+  Input,
+  Checkbox,
+  Row,
+  Col,
+  Table,
+  Space,
+  Modal,
+  Select,
+} from 'antd';
+import styles from '../../Create.less';
+
+const { TextArea } = Input;
+const { Option } = Select;
+
+const formItemLayout = {
+  labelCol: {
+    span: 6,
+  },
+  wrapperCol: {
+    span: 18,
+  },
+};
+
+const Step1: React.FC<RoutesModule.StepProps> = ({ pageData, onChange }) => {
+  const { step1PageData } = pageData;
+  const [form] = Form.useForm();
+  const [modalVisible, setModalVisible] = useState(false);
+  const [editModalData, setEditModalData] = useState();
+
+  const handleAdd = () => {
+    setModalVisible(true);
+  };
+
+  const handleEdit = (text: any, record: any) => {
+    setEditModalData(record);
+  };
+
+  const handleDelete = (text: any, record: any) => {
+    const { advancedConfig } = step1PageData;
+    const filteredAdvancedConfig = advancedConfig.filter((item) => item.key 
!== record.key);
+    onChange({ advancedConfig: filteredAdvancedConfig });
+  };
+
+  const columns = [
+    {
+      title: '参数位置',
+      dataIndex: 'paramsLocation',
+      key: 'paramsLocation',
+    },
+    {
+      title: '参数名称',
+      dataIndex: 'paramsName',
+      key: 'paramsName',
+    },
+    {
+      title: '表达式',
+      dataIndex: 'paramsExpresstion',
+      key: 'paramsExpresstion',
+    },
+    {
+      title: '参数值',
+      dataIndex: 'paramsValue',
+      key: 'paramsValue',
+    },
+    {
+      title: '备注',
+      dataIndex: 'remark',
+      key: 'remark',
+    },
+    {
+      title: '操作',
+      key: 'action',
+      render: (text: any, record: any) => (
+        <Space size="middle">
+          <a onClick={() => handleEdit(text, record)}>编辑</a>
+          <a onClick={() => handleDelete(text, record)}>移除</a>
+        </Space>
+      ),
+    },
+  ];
+
+  const addHost = () => {
+    const { hosts } = step1PageData;
+    onChange({
+      hosts: hosts.concat([
+        {
+          host: '',
+          port: '',
+          priority: '',
+        },
+      ]),
+    });
+  };
+
+  const renderHosts = () =>
+    step1PageData.hosts?.map((item, index) => (
+      <Row
+        key={Math.random().toString(36).slice(2)}
+        style={{ marginBottom: '10px' }}
+        gutter={[16, 16]}
+      >
+        <Col span={8}>
+          <Input placeholder="IP/HOST" />
+        </Col>
+        <Col span={4}>
+          <Input placeholder="PORT" />
+        </Col>
+        <Col span={4}>
+          <Input />
+        </Col>
+        <Col span={4}>
+          <Space>
+            <Button
+              type="primary"
+              danger
+              onClick={() => {
+                const { hosts } = step1PageData;
+                hosts.splice(index, 1);
+                onChange({ hosts });
+              }}
+            >
+              删除
+            </Button>
+          </Space>
+        </Col>
+      </Row>
+    ));
+
+  const renderNameAndDesc = () => (
+    <>
+      <div>名称及其描述</div>
+      <Divider />
+      <Form {...formItemLayout} form={form} layout="horizontal" 
className={styles.stepForm}>
+        <Form.Item
+          label="API名称"
+          name="APIName"
+          rules={[{ required: true, message: '请输入API名称' }]}

Review comment:
       , 
   

##########
File path: src/pages/Routes/typing.d.ts
##########
@@ -0,0 +1,32 @@
+declare namespace RoutesModule {
+  interface Step1ModalProps {
+    paramsLocation: string;
+    paramsName: string;
+    paramsExpresstion: string;
+    paramsValue: string;
+    remark?: string;
+    key: string;
+  }
+
+  interface Step1HostProps {
+    host: string;
+    port: string;
+    priority: string;
+  }
+
+  interface Step1PageDataProps {
+    apiName: string;
+    protocol: string;

Review comment:
       ,.

##########
File path: src/pages/Routes/components/Step1/index.tsx
##########
@@ -0,0 +1,312 @@
+import React, { useState } from 'react';
+import {
+  Form,
+  Button,
+  Divider,
+  Input,
+  Checkbox,
+  Row,
+  Col,
+  Table,
+  Space,
+  Modal,
+  Select,
+} from 'antd';
+import styles from '../../Create.less';
+
+const { TextArea } = Input;
+const { Option } = Select;
+
+const formItemLayout = {
+  labelCol: {
+    span: 6,
+  },
+  wrapperCol: {
+    span: 18,
+  },
+};
+
+const Step1: React.FC<RoutesModule.StepProps> = ({ pageData, onChange }) => {
+  const { step1PageData } = pageData;
+  const [form] = Form.useForm();
+  const [modalVisible, setModalVisible] = useState(false);
+  const [editModalData, setEditModalData] = useState();
+
+  const handleAdd = () => {
+    setModalVisible(true);
+  };
+
+  const handleEdit = (text: any, record: any) => {
+    setEditModalData(record);
+  };
+
+  const handleDelete = (text: any, record: any) => {
+    const { advancedConfig } = step1PageData;
+    const filteredAdvancedConfig = advancedConfig.filter((item) => item.key 
!== record.key);
+    onChange({ advancedConfig: filteredAdvancedConfig });
+  };
+
+  const columns = [
+    {
+      title: '参数位置',
+      dataIndex: 'paramsLocation',
+      key: 'paramsLocation',
+    },
+    {
+      title: '参数名称',
+      dataIndex: 'paramsName',
+      key: 'paramsName',
+    },
+    {
+      title: '表达式',
+      dataIndex: 'paramsExpresstion',
+      key: 'paramsExpresstion',
+    },
+    {
+      title: '参数值',
+      dataIndex: 'paramsValue',
+      key: 'paramsValue',
+    },
+    {
+      title: '备注',
+      dataIndex: 'remark',
+      key: 'remark',
+    },
+    {
+      title: '操作',
+      key: 'action',
+      render: (text: any, record: any) => (
+        <Space size="middle">
+          <a onClick={() => handleEdit(text, record)}>编辑</a>
+          <a onClick={() => handleDelete(text, record)}>移除</a>
+        </Space>
+      ),
+    },
+  ];
+
+  const addHost = () => {
+    const { hosts } = step1PageData;
+    onChange({
+      hosts: hosts.concat([
+        {
+          host: '',
+          port: '',
+          priority: '',
+        },
+      ]),
+    });
+  };
+
+  const renderHosts = () =>
+    step1PageData.hosts?.map((item, index) => (
+      <Row
+        key={Math.random().toString(36).slice(2)}
+        style={{ marginBottom: '10px' }}
+        gutter={[16, 16]}
+      >
+        <Col span={8}>
+          <Input placeholder="IP/HOST" />
+        </Col>
+        <Col span={4}>
+          <Input placeholder="PORT" />
+        </Col>
+        <Col span={4}>
+          <Input />
+        </Col>
+        <Col span={4}>
+          <Space>
+            <Button
+              type="primary"
+              danger
+              onClick={() => {
+                const { hosts } = step1PageData;
+                hosts.splice(index, 1);
+                onChange({ hosts });
+              }}
+            >
+              删除
+            </Button>
+          </Space>
+        </Col>
+      </Row>
+    ));
+
+  const renderNameAndDesc = () => (
+    <>
+      <div>名称及其描述</div>
+      <Divider />
+      <Form {...formItemLayout} form={form} layout="horizontal" 
className={styles.stepForm}>
+        <Form.Item
+          label="API名称"
+          name="APIName"

Review comment:
       name

##########
File path: src/pages/Routes/components/Step1/index.tsx
##########
@@ -0,0 +1,312 @@
+import React, { useState } from 'react';
+import {
+  Form,
+  Button,
+  Divider,
+  Input,
+  Checkbox,
+  Row,
+  Col,
+  Table,
+  Space,
+  Modal,
+  Select,
+} from 'antd';
+import styles from '../../Create.less';
+
+const { TextArea } = Input;
+const { Option } = Select;
+
+const formItemLayout = {
+  labelCol: {
+    span: 6,
+  },
+  wrapperCol: {
+    span: 18,
+  },
+};
+
+const Step1: React.FC<RoutesModule.StepProps> = ({ pageData, onChange }) => {
+  const { step1PageData } = pageData;
+  const [form] = Form.useForm();
+  const [modalVisible, setModalVisible] = useState(false);
+  const [editModalData, setEditModalData] = useState();
+
+  const handleAdd = () => {
+    setModalVisible(true);
+  };
+
+  const handleEdit = (text: any, record: any) => {
+    setEditModalData(record);
+  };
+
+  const handleDelete = (text: any, record: any) => {
+    const { advancedConfig } = step1PageData;
+    const filteredAdvancedConfig = advancedConfig.filter((item) => item.key 
!== record.key);
+    onChange({ advancedConfig: filteredAdvancedConfig });
+  };
+
+  const columns = [
+    {
+      title: '参数位置',
+      dataIndex: 'paramsLocation',
+      key: 'paramsLocation',
+    },
+    {
+      title: '参数名称',
+      dataIndex: 'paramsName',
+      key: 'paramsName',
+    },
+    {
+      title: '表达式',
+      dataIndex: 'paramsExpresstion',
+      key: 'paramsExpresstion',
+    },
+    {
+      title: '参数值',
+      dataIndex: 'paramsValue',
+      key: 'paramsValue',
+    },
+    {
+      title: '备注',
+      dataIndex: 'remark',
+      key: 'remark',
+    },
+    {
+      title: '操作',
+      key: 'action',
+      render: (text: any, record: any) => (
+        <Space size="middle">
+          <a onClick={() => handleEdit(text, record)}>编辑</a>
+          <a onClick={() => handleDelete(text, record)}>移除</a>
+        </Space>
+      ),
+    },
+  ];
+
+  const addHost = () => {
+    const { hosts } = step1PageData;
+    onChange({
+      hosts: hosts.concat([
+        {
+          host: '',
+          port: '',
+          priority: '',
+        },
+      ]),
+    });
+  };
+
+  const renderHosts = () =>
+    step1PageData.hosts?.map((item, index) => (
+      <Row
+        key={Math.random().toString(36).slice(2)}
+        style={{ marginBottom: '10px' }}
+        gutter={[16, 16]}
+      >
+        <Col span={8}>
+          <Input placeholder="IP/HOST" />
+        </Col>
+        <Col span={4}>
+          <Input placeholder="PORT" />
+        </Col>
+        <Col span={4}>
+          <Input />
+        </Col>
+        <Col span={4}>
+          <Space>
+            <Button
+              type="primary"
+              danger
+              onClick={() => {
+                const { hosts } = step1PageData;
+                hosts.splice(index, 1);
+                onChange({ hosts });
+              }}
+            >
+              删除
+            </Button>
+          </Space>
+        </Col>
+      </Row>
+    ));
+
+  const renderNameAndDesc = () => (
+    <>
+      <div>名称及其描述</div>
+      <Divider />
+      <Form {...formItemLayout} form={form} layout="horizontal" 
className={styles.stepForm}>
+        <Form.Item
+          label="API名称"
+          name="APIName"
+          rules={[{ required: true, message: '请输入API名称' }]}
+        >
+          <Input placeholder="请输入API名称" />

Review comment:
       ,

##########
File path: src/pages/Routes/typing.d.ts
##########
@@ -0,0 +1,32 @@
+declare namespace RoutesModule {
+  interface Step1ModalProps {
+    paramsLocation: string;
+    paramsName: string;
+    paramsExpresstion: string;
+    paramsValue: string;
+    remark?: string;

Review comment:
       ,

##########
File path: src/pages/Routes/components/Step1/index.tsx
##########
@@ -0,0 +1,312 @@
+import React, { useState } from 'react';
+import {
+  Form,
+  Button,
+  Divider,
+  Input,
+  Checkbox,
+  Row,
+  Col,
+  Table,
+  Space,
+  Modal,
+  Select,
+} from 'antd';
+import styles from '../../Create.less';
+
+const { TextArea } = Input;
+const { Option } = Select;
+
+const formItemLayout = {
+  labelCol: {
+    span: 6,
+  },
+  wrapperCol: {
+    span: 18,
+  },
+};
+
+const Step1: React.FC<RoutesModule.StepProps> = ({ pageData, onChange }) => {
+  const { step1PageData } = pageData;
+  const [form] = Form.useForm();
+  const [modalVisible, setModalVisible] = useState(false);
+  const [editModalData, setEditModalData] = useState();
+
+  const handleAdd = () => {
+    setModalVisible(true);
+  };
+
+  const handleEdit = (text: any, record: any) => {
+    setEditModalData(record);
+  };
+
+  const handleDelete = (text: any, record: any) => {
+    const { advancedConfig } = step1PageData;
+    const filteredAdvancedConfig = advancedConfig.filter((item) => item.key 
!== record.key);
+    onChange({ advancedConfig: filteredAdvancedConfig });
+  };
+
+  const columns = [
+    {
+      title: '参数位置',
+      dataIndex: 'paramsLocation',
+      key: 'paramsLocation',
+    },
+    {
+      title: '参数名称',
+      dataIndex: 'paramsName',
+      key: 'paramsName',
+    },
+    {
+      title: '表达式',
+      dataIndex: 'paramsExpresstion',
+      key: 'paramsExpresstion',
+    },
+    {
+      title: '参数值',
+      dataIndex: 'paramsValue',
+      key: 'paramsValue',
+    },
+    {
+      title: '备注',
+      dataIndex: 'remark',
+      key: 'remark',
+    },
+    {
+      title: '操作',
+      key: 'action',
+      render: (text: any, record: any) => (
+        <Space size="middle">
+          <a onClick={() => handleEdit(text, record)}>编辑</a>
+          <a onClick={() => handleDelete(text, record)}>移除</a>
+        </Space>
+      ),
+    },
+  ];
+
+  const addHost = () => {
+    const { hosts } = step1PageData;
+    onChange({
+      hosts: hosts.concat([
+        {
+          host: '',
+          port: '',
+          priority: '',
+        },
+      ]),
+    });
+  };
+
+  const renderHosts = () =>
+    step1PageData.hosts?.map((item, index) => (
+      <Row
+        key={Math.random().toString(36).slice(2)}
+        style={{ marginBottom: '10px' }}
+        gutter={[16, 16]}
+      >
+        <Col span={8}>
+          <Input placeholder="IP/HOST" />
+        </Col>
+        <Col span={4}>
+          <Input placeholder="PORT" />
+        </Col>
+        <Col span={4}>
+          <Input />
+        </Col>
+        <Col span={4}>
+          <Space>
+            <Button
+              type="primary"
+              danger
+              onClick={() => {
+                const { hosts } = step1PageData;
+                hosts.splice(index, 1);
+                onChange({ hosts });
+              }}
+            >
+              删除
+            </Button>
+          </Space>
+        </Col>
+      </Row>
+    ));
+
+  const renderNameAndDesc = () => (
+    <>
+      <div>名称及其描述</div>
+      <Divider />
+      <Form {...formItemLayout} form={form} layout="horizontal" 
className={styles.stepForm}>
+        <Form.Item
+          label="API名称"
+          name="APIName"
+          rules={[{ required: true, message: '请输入API名称' }]}
+        >
+          <Input placeholder="请输入API名称" />
+        </Form.Item>
+        <Form.Item label="描述" name="desc">
+          <TextArea placeholder="请输入描述" />
+        </Form.Item>
+      </Form>
+    </>
+  );
+
+  const renderBaseRequestConfig = () => (
+    <>
+      <div>请求基础定义</div>
+      <Divider />
+      <Form {...formItemLayout} form={form} layout="horizontal" 
className={styles.stepForm}>
+        <Form.Item label="协议" name="protocol" rules={[{ required: true, 
message: '请勾选协议' }]}>
+          <Checkbox.Group style={{ width: '100%' }}>
+            <Row>
+              {['HTTP', 'HTTPS', 'WebSocket'].map((item) => (
+                <Col span={6} key={item}>
+                  <Checkbox value={item}>{item}</Checkbox>
+                </Col>
+              ))}
+            </Row>
+          </Checkbox.Group>
+        </Form.Item>
+        <Form.Item label="IP/HOST" rules={[{ required: true, message: 
'请输入HOST' }]}>
+          {renderHosts()}
+          <Button onClick={addHost} type="primary">
+            增加
+          </Button>
+        </Form.Item>
+        <Form.Item label="请求PATH" name="path" rules={[{ required: true, 
message: '请输入PATH' }]}>

Review comment:
       PATH

##########
File path: src/pages/Routes/typing.d.ts
##########
@@ -0,0 +1,32 @@
+declare namespace RoutesModule {
+  interface Step1ModalProps {
+    paramsLocation: string;
+    paramsName: string;
+    paramsExpresstion: string;

Review comment:
       type

##########
File path: src/pages/Routes/typing.d.ts
##########
@@ -0,0 +1,32 @@
+declare namespace RoutesModule {
+  interface Step1ModalProps {
+    paramsLocation: string;
+    paramsName: string;
+    paramsExpresstion: string;
+    paramsValue: string;
+    remark?: string;
+    key: string;
+  }
+
+  interface Step1HostProps {
+    host: string;
+    port: string;
+    priority: string;
+  }
+
+  interface Step1PageDataProps {
+    apiName: string;
+    protocol: string;
+    hosts: Step1HostProps[];
+    requestPath: string;

Review comment:
       ,

##########
File path: src/pages/Routes/components/Step1/index.tsx
##########
@@ -0,0 +1,312 @@
+import React, { useState } from 'react';
+import {
+  Form,
+  Button,
+  Divider,
+  Input,
+  Checkbox,
+  Row,
+  Col,
+  Table,
+  Space,
+  Modal,
+  Select,
+} from 'antd';
+import styles from '../../Create.less';
+
+const { TextArea } = Input;
+const { Option } = Select;
+
+const formItemLayout = {
+  labelCol: {
+    span: 6,
+  },
+  wrapperCol: {
+    span: 18,
+  },
+};
+
+const Step1: React.FC<RoutesModule.StepProps> = ({ pageData, onChange }) => {
+  const { step1PageData } = pageData;
+  const [form] = Form.useForm();
+  const [modalVisible, setModalVisible] = useState(false);
+  const [editModalData, setEditModalData] = useState();
+
+  const handleAdd = () => {
+    setModalVisible(true);
+  };
+
+  const handleEdit = (text: any, record: any) => {
+    setEditModalData(record);
+  };
+
+  const handleDelete = (text: any, record: any) => {
+    const { advancedConfig } = step1PageData;
+    const filteredAdvancedConfig = advancedConfig.filter((item) => item.key 
!== record.key);
+    onChange({ advancedConfig: filteredAdvancedConfig });
+  };
+
+  const columns = [
+    {
+      title: '参数位置',
+      dataIndex: 'paramsLocation',
+      key: 'paramsLocation',
+    },
+    {
+      title: '参数名称',
+      dataIndex: 'paramsName',
+      key: 'paramsName',
+    },
+    {
+      title: '表达式',
+      dataIndex: 'paramsExpresstion',
+      key: 'paramsExpresstion',
+    },
+    {
+      title: '参数值',
+      dataIndex: 'paramsValue',
+      key: 'paramsValue',
+    },
+    {
+      title: '备注',
+      dataIndex: 'remark',
+      key: 'remark',
+    },
+    {
+      title: '操作',
+      key: 'action',
+      render: (text: any, record: any) => (
+        <Space size="middle">
+          <a onClick={() => handleEdit(text, record)}>编辑</a>
+          <a onClick={() => handleDelete(text, record)}>移除</a>
+        </Space>
+      ),
+    },
+  ];
+
+  const addHost = () => {
+    const { hosts } = step1PageData;
+    onChange({
+      hosts: hosts.concat([
+        {
+          host: '',
+          port: '',
+          priority: '',
+        },
+      ]),
+    });
+  };
+
+  const renderHosts = () =>
+    step1PageData.hosts?.map((item, index) => (
+      <Row
+        key={Math.random().toString(36).slice(2)}
+        style={{ marginBottom: '10px' }}
+        gutter={[16, 16]}
+      >
+        <Col span={8}>
+          <Input placeholder="IP/HOST" />
+        </Col>
+        <Col span={4}>
+          <Input placeholder="PORT" />
+        </Col>
+        <Col span={4}>
+          <Input />
+        </Col>
+        <Col span={4}>
+          <Space>
+            <Button
+              type="primary"
+              danger
+              onClick={() => {
+                const { hosts } = step1PageData;
+                hosts.splice(index, 1);
+                onChange({ hosts });
+              }}
+            >
+              删除
+            </Button>
+          </Space>
+        </Col>
+      </Row>
+    ));
+
+  const renderNameAndDesc = () => (
+    <>
+      <div>名称及其描述</div>
+      <Divider />
+      <Form {...formItemLayout} form={form} layout="horizontal" 
className={styles.stepForm}>
+        <Form.Item
+          label="API名称"
+          name="APIName"
+          rules={[{ required: true, message: '请输入API名称' }]}
+        >
+          <Input placeholder="请输入API名称" />
+        </Form.Item>
+        <Form.Item label="描述" name="desc">
+          <TextArea placeholder="请输入描述" />
+        </Form.Item>
+      </Form>
+    </>
+  );
+
+  const renderBaseRequestConfig = () => (
+    <>
+      <div>请求基础定义</div>
+      <Divider />
+      <Form {...formItemLayout} form={form} layout="horizontal" 
className={styles.stepForm}>
+        <Form.Item label="协议" name="protocol" rules={[{ required: true, 
message: '请勾选协议' }]}>
+          <Checkbox.Group style={{ width: '100%' }}>
+            <Row>
+              {['HTTP', 'HTTPS', 'WebSocket'].map((item) => (
+                <Col span={6} key={item}>
+                  <Checkbox value={item}>{item}</Checkbox>
+                </Col>
+              ))}
+            </Row>
+          </Checkbox.Group>
+        </Form.Item>
+        <Form.Item label="IP/HOST" rules={[{ required: true, message: 
'请输入HOST' }]}>
+          {renderHosts()}
+          <Button onClick={addHost} type="primary">
+            增加
+          </Button>
+        </Form.Item>
+        <Form.Item label="请求PATH" name="path" rules={[{ required: true, 
message: '请输入PATH' }]}>
+          <Input placeholder="请输入PATH" />
+        </Form.Item>
+        <Form.Item
+          label="HTTP Methods"
+          name="httpMethods"
+          rules={[{ required: true, message: '请勾选HTTP Methods' }]}
+        >
+          <Checkbox.Group style={{ width: '100%' }}>
+            <Row>
+              {['ANY', 'GET', 'HEAD', 'POST', 'PUT', 'DELETE', 'OPTIONS', 
'PATCH'].map((item) => (
+                <Col span={6} key={item}>
+                  <Checkbox value={item}>{item}</Checkbox>
+                </Col>
+              ))}
+            </Row>
+          </Checkbox.Group>
+        </Form.Item>
+      </Form>
+    </>
+  );
+
+  const renderModal = () => {
+    const [modalForm] = Form.useForm();
+    const validateModalFields = modalForm.validateFields;
+    const { resetFields } = modalForm;
+    const handleOk = () => {
+      validateModalFields().then((value) => {
+        const { advancedConfig } = step1PageData;
+        onChange({
+          advancedConfig: advancedConfig.concat({
+            ...(value as RoutesModule.Step1ModalProps),
+            key: Math.random().toString(36).slice(2),
+          }),
+        });
+      });
+    };
+
+    const handleCancel = () => {
+      setModalVisible(false);
+    };
+
+    const handleAfterClose = () => {
+      resetFields();
+    };
+    return (
+      <>
+        <Modal
+          title="新增"
+          centered
+          visible={modalVisible}
+          afterClose={handleAfterClose}
+          onOk={handleOk}
+          onCancel={handleCancel}
+          destroyOnClose
+        >
+          <Form
+            name="basic"
+            form={modalForm}
+            labelCol={{ span: 4 }}
+            wrapperCol={{ span: 20 }}
+            initialValues={editModalData}
+          >
+            <Form.Item
+              label="参数位置"
+              name="paramsLocation"
+              rules={[{ required: true, message: '请选择参数位置' }]}
+            >
+              <Select>
+                <Option value="header">header</Option>
+                <Option value="query">query</Option>
+                <Option value="params">params</Option>
+              </Select>
+            </Form.Item>
+            <Form.Item
+              label="参数名称"
+              name="paramsName"
+              rules={[{ required: true, message: '请输入参数名称' }]}
+            >
+              <Input />
+            </Form.Item>
+            <Form.Item
+              label="表达式"
+              name="paramsExpresstion"
+              rules={[{ required: true, message: '请选择表达式' }]}
+            >
+              <Select>
+                <Option value=">">大于</Option>
+                <Option value="<">小于</Option>
+                <Option value="=">等于</Option>
+              </Select>
+            </Form.Item>
+            <Form.Item
+              label="参数值"
+              name="paramsValue"
+              rules={[{ required: true, message: '请输入参数值' }]}
+            >
+              <Input />
+            </Form.Item>
+            <Form.Item label="备注" name="remark">
+              <TextArea placeholder="请输入备注" />
+            </Form.Item>
+          </Form>
+        </Modal>
+      </>
+    );
+  };
+
+  const renderAdvancedConfig = () => (
+    <>
+      <div>高级路由匹配条件</div>
+      <Divider />
+      <div key="div">

Review comment:
       remove key

##########
File path: src/pages/Routes/typing.d.ts
##########
@@ -0,0 +1,32 @@
+declare namespace RoutesModule {
+  interface Step1ModalProps {
+    paramsLocation: string;

Review comment:
       ,

##########
File path: src/pages/Routes/typing.d.ts
##########
@@ -0,0 +1,32 @@
+declare namespace RoutesModule {
+  interface Step1ModalProps {
+    paramsLocation: string;
+    paramsName: string;
+    paramsExpresstion: string;
+    paramsValue: string;
+    remark?: string;
+    key: string;
+  }
+
+  interface Step1HostProps {
+    host: string;
+    port: string;

Review comment:
       ,




----------------------------------------------------------------
This is an automated message from the Apache Git Service.
To respond to the message, please log on to GitHub and use the
URL above to go to the specific comment.

For queries about this service, please contact Infrastructure at:
us...@infra.apache.org


Reply via email to