whistle.mock-plugins 1.1.2-dev.2 → 1.1.3-beta.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/app/cgi-bin/interfaces.js +5 -42
- package/app/public/js/index.js +1 -1
- package/app/public/js/index.js.LICENSE.txt +4 -6
- package/lib/ui-server.js +1 -15
- package/package.json +1 -1
- package/ui/src/index.js +24 -4
- package/ui/src/pages/InterfaceManagementV2.js +334 -0
- package/ui/src/pages/MockDataV2.js +702 -0
- package/ui/src/pages/Settings.js +79 -157
- package/ui/src/del_App.js +0 -24
- package/ui/src/pages/del_FileProxy.js +0 -235
- package/ui/src/pages/del_FilesPage.js +0 -292
- package/ui/src/pages/del_Home.js +0 -128
- package/ui/src/pages/del_HomePage.js +0 -195
- package/ui/src/pages/del_InterfacePage.js +0 -342
- package/ui/src/pages/del_SettingsPage.js +0 -165
- package/ui/src/pages/del_UrlRedirect.js +0 -225
- package/ui/src/pages/del_Welcome.js +0 -155
- package/ui/src/styles/del_feature-card.css +0 -168
- package/ui/src/styles/del_file-proxy.css +0 -301
- package/ui/src/styles/del_home.css +0 -123
- package/ui/src/styles/del_index.css +0 -419
- package/ui/src/styles/del_layout.css +0 -159
- package/ui/src/styles/del_logs-page.css +0 -427
- package/ui/src/styles/del_main-nav.css +0 -52
- package/ui/src/styles/del_page-container.css +0 -11
- package/ui/src/styles/del_url-redirect.css +0 -279
- package/ui/src/styles/del_welcome.css +0 -282
package/ui/src/pages/Settings.js
CHANGED
|
@@ -1,66 +1,61 @@
|
|
|
1
1
|
import React, { useState, useEffect } from 'react';
|
|
2
2
|
import AppLayout from '../components/AppLayout';
|
|
3
|
-
import {
|
|
4
|
-
import { SaveOutlined, UndoOutlined } from '@ant-design/icons';
|
|
3
|
+
import { Card, Switch, message, Typography, Divider } from 'antd';
|
|
5
4
|
import '../styles/settings.css';
|
|
6
5
|
|
|
7
|
-
const { Title, Text } = Typography;
|
|
6
|
+
const { Title, Text, Paragraph } = Typography;
|
|
7
|
+
|
|
8
|
+
// localStorage工具函数
|
|
9
|
+
const getUIVersion = () => {
|
|
10
|
+
try {
|
|
11
|
+
return localStorage.getItem('ui-version') || 'v1';
|
|
12
|
+
} catch (error) {
|
|
13
|
+
console.error('获取UI版本设置失败:', error);
|
|
14
|
+
return 'v1';
|
|
15
|
+
}
|
|
16
|
+
};
|
|
17
|
+
|
|
18
|
+
const setUIVersion = (version) => {
|
|
19
|
+
try {
|
|
20
|
+
localStorage.setItem('ui-version', version);
|
|
21
|
+
return true;
|
|
22
|
+
} catch (error) {
|
|
23
|
+
console.error('保存UI版本设置失败:', error);
|
|
24
|
+
return false;
|
|
25
|
+
}
|
|
26
|
+
};
|
|
8
27
|
|
|
9
28
|
const Settings = () => {
|
|
10
|
-
const [
|
|
11
|
-
const [loading, setLoading] = useState(false);
|
|
12
|
-
const [settings, setSettings] = useState(null);
|
|
29
|
+
const [uiVersion, setUiVersionState] = useState(getUIVersion());
|
|
13
30
|
|
|
14
|
-
//
|
|
31
|
+
// 页面加载时同步localStorage状态
|
|
15
32
|
useEffect(() => {
|
|
16
|
-
|
|
33
|
+
const currentVersion = getUIVersion();
|
|
34
|
+
setUiVersionState(currentVersion);
|
|
17
35
|
}, []);
|
|
18
36
|
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
logRetention: 7,
|
|
26
|
-
enableLogging: true,
|
|
27
|
-
enableAutoRefresh: false,
|
|
28
|
-
maxLogEntries: 10000,
|
|
29
|
-
notificationEnabled: true,
|
|
30
|
-
mockjsEnabled: true,
|
|
31
|
-
responseDelay: 0
|
|
32
|
-
};
|
|
37
|
+
// 处理UI版本切换
|
|
38
|
+
const handleUIVersionChange = (checked) => {
|
|
39
|
+
const newVersion = checked ? 'v2' : 'v1';
|
|
40
|
+
|
|
41
|
+
if (setUIVersion(newVersion)) {
|
|
42
|
+
setUiVersionState(newVersion);
|
|
33
43
|
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
};
|
|
43
|
-
|
|
44
|
-
const handleSave = async (values) => {
|
|
45
|
-
try {
|
|
46
|
-
setLoading(true);
|
|
47
|
-
// 这里假设有一个保存设置的接口
|
|
48
|
-
// 现在只是模拟保存成功
|
|
49
|
-
await new Promise(resolve => setTimeout(resolve, 500));
|
|
44
|
+
// 提示用户刷新页面以应用更改
|
|
45
|
+
message.success({
|
|
46
|
+
content: `已切换到${checked ? '重构后' : '重构前'}版本,页面将自动刷新`,
|
|
47
|
+
duration: 2,
|
|
48
|
+
onClose: () => {
|
|
49
|
+
window.location.reload();
|
|
50
|
+
}
|
|
51
|
+
});
|
|
50
52
|
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
setLoading(false);
|
|
58
|
-
}
|
|
59
|
-
};
|
|
60
|
-
|
|
61
|
-
const handleReset = () => {
|
|
62
|
-
if (settings) {
|
|
63
|
-
form.setFieldsValue(settings);
|
|
53
|
+
// 1秒后自动刷新
|
|
54
|
+
setTimeout(() => {
|
|
55
|
+
window.location.reload();
|
|
56
|
+
}, 1000);
|
|
57
|
+
} else {
|
|
58
|
+
message.error('设置保存失败,请重试');
|
|
64
59
|
}
|
|
65
60
|
};
|
|
66
61
|
|
|
@@ -71,119 +66,46 @@ const Settings = () => {
|
|
|
71
66
|
<div>
|
|
72
67
|
<h1 className="page-title">系统设置</h1>
|
|
73
68
|
<div className="page-description">
|
|
74
|
-
|
|
69
|
+
配置插件的全局设置项和界面选项
|
|
75
70
|
</div>
|
|
76
71
|
</div>
|
|
77
72
|
</div>
|
|
78
73
|
|
|
79
|
-
<
|
|
80
|
-
|
|
81
|
-
|
|
82
|
-
|
|
83
|
-
|
|
84
|
-
|
|
85
|
-
|
|
86
|
-
|
|
87
|
-
|
|
88
|
-
|
|
89
|
-
|
|
90
|
-
|
|
91
|
-
|
|
92
|
-
|
|
93
|
-
|
|
94
|
-
|
|
95
|
-
|
|
96
|
-
label="启用请求日志记录"
|
|
97
|
-
valuePropName="checked"
|
|
98
|
-
>
|
|
99
|
-
<Switch />
|
|
100
|
-
</Form.Item>
|
|
101
|
-
|
|
102
|
-
<Form.Item
|
|
103
|
-
name="logRetention"
|
|
104
|
-
label="日志保留天数"
|
|
105
|
-
rules={[{ required: true, message: '请输入日志保留天数' }]}
|
|
106
|
-
tooltip="超过设定天数的日志将被自动清理"
|
|
107
|
-
>
|
|
108
|
-
<InputNumber min={1} max={90} />
|
|
109
|
-
</Form.Item>
|
|
110
|
-
|
|
111
|
-
<Form.Item
|
|
112
|
-
name="maxLogEntries"
|
|
113
|
-
label="最大日志条数"
|
|
114
|
-
rules={[{ required: true, message: '请输入最大日志条数' }]}
|
|
115
|
-
tooltip="超过设定条数的日志将被清理"
|
|
116
|
-
>
|
|
117
|
-
<InputNumber min={1000} max={100000} step={1000} />
|
|
118
|
-
</Form.Item>
|
|
119
|
-
</Card>
|
|
120
|
-
|
|
121
|
-
<Card title="接口模拟设置" className="settings-card">
|
|
122
|
-
<Form.Item
|
|
123
|
-
name="mockjsEnabled"
|
|
124
|
-
label="启用 Mock.js 数据模拟"
|
|
125
|
-
valuePropName="checked"
|
|
126
|
-
tooltip="使用 Mock.js 生成随机数据"
|
|
127
|
-
>
|
|
128
|
-
<Switch />
|
|
129
|
-
</Form.Item>
|
|
130
|
-
|
|
131
|
-
<Form.Item
|
|
132
|
-
name="responseDelay"
|
|
133
|
-
label="全局响应延迟(毫秒)"
|
|
134
|
-
tooltip="所有接口默认的响应延迟时间"
|
|
135
|
-
>
|
|
136
|
-
<InputNumber min={0} max={10000} />
|
|
137
|
-
</Form.Item>
|
|
138
|
-
|
|
139
|
-
<Form.Item
|
|
140
|
-
name="notificationEnabled"
|
|
141
|
-
label="启用请求匹配通知"
|
|
142
|
-
valuePropName="checked"
|
|
143
|
-
tooltip="接口匹配成功时显示通知"
|
|
144
|
-
>
|
|
145
|
-
<Switch />
|
|
146
|
-
</Form.Item>
|
|
147
|
-
</Card>
|
|
74
|
+
<Card title="界面设置" className="settings-card">
|
|
75
|
+
<div className="setting-item">
|
|
76
|
+
<div className="setting-label">
|
|
77
|
+
<Text strong>UI版本切换</Text>
|
|
78
|
+
<Paragraph type="secondary" style={{ margin: '4px 0 0 0', fontSize: '12px' }}>
|
|
79
|
+
切换使用重构前后的界面版本
|
|
80
|
+
</Paragraph>
|
|
81
|
+
</div>
|
|
82
|
+
<div className="setting-control">
|
|
83
|
+
<Switch
|
|
84
|
+
checked={uiVersion === 'v2'}
|
|
85
|
+
onChange={handleUIVersionChange}
|
|
86
|
+
checkedChildren="重构后"
|
|
87
|
+
unCheckedChildren="重构前"
|
|
88
|
+
/>
|
|
89
|
+
</div>
|
|
90
|
+
</div>
|
|
148
91
|
|
|
149
|
-
<
|
|
150
|
-
<Form.Item
|
|
151
|
-
name="enableAutoRefresh"
|
|
152
|
-
label="启用页面自动刷新"
|
|
153
|
-
valuePropName="checked"
|
|
154
|
-
tooltip="启用后,页面数据将定期自动刷新"
|
|
155
|
-
>
|
|
156
|
-
<Switch />
|
|
157
|
-
</Form.Item>
|
|
158
|
-
|
|
159
|
-
<Form.Item
|
|
160
|
-
name="theme"
|
|
161
|
-
label="界面主题"
|
|
162
|
-
>
|
|
163
|
-
<Input disabled placeholder="暂不支持自定义主题" />
|
|
164
|
-
</Form.Item>
|
|
165
|
-
</Card>
|
|
92
|
+
<Divider />
|
|
166
93
|
|
|
167
|
-
<div
|
|
168
|
-
<
|
|
169
|
-
|
|
170
|
-
|
|
171
|
-
|
|
172
|
-
|
|
173
|
-
>
|
|
174
|
-
|
|
175
|
-
</
|
|
176
|
-
<
|
|
177
|
-
|
|
178
|
-
|
|
179
|
-
|
|
180
|
-
loading={loading}
|
|
181
|
-
>
|
|
182
|
-
保存设置
|
|
183
|
-
</Button>
|
|
184
|
-
</Space>
|
|
94
|
+
<div style={{ padding: '16px 0' }}>
|
|
95
|
+
<Title level={5}>版本说明</Title>
|
|
96
|
+
<div style={{ marginLeft: '16px' }}>
|
|
97
|
+
<Paragraph>
|
|
98
|
+
<Text strong>重构前版本:</Text> 当前稳定版本的功能模块管理和接口管理界面
|
|
99
|
+
</Paragraph>
|
|
100
|
+
<Paragraph>
|
|
101
|
+
<Text strong>重构后版本:</Text> 新设计的界面版本,提供更好的用户体验和功能优化
|
|
102
|
+
</Paragraph>
|
|
103
|
+
<Paragraph type="warning">
|
|
104
|
+
<Text>注意:切换版本后页面将自动刷新以应用更改</Text>
|
|
105
|
+
</Paragraph>
|
|
106
|
+
</div>
|
|
185
107
|
</div>
|
|
186
|
-
</
|
|
108
|
+
</Card>
|
|
187
109
|
</div>
|
|
188
110
|
</AppLayout>
|
|
189
111
|
);
|
package/ui/src/del_App.js
DELETED
|
@@ -1,24 +0,0 @@
|
|
|
1
|
-
import React from 'react';
|
|
2
|
-
import { BrowserRouter as Router, Route, Switch, Redirect } from 'react-router-dom';
|
|
3
|
-
import MockData from './pages/MockData';
|
|
4
|
-
import InterfaceManagement from './pages/InterfaceManagement';
|
|
5
|
-
import Settings from './pages/Settings';
|
|
6
|
-
import './App.css';
|
|
7
|
-
|
|
8
|
-
function App() {
|
|
9
|
-
return (
|
|
10
|
-
<Router>
|
|
11
|
-
<div className="App">
|
|
12
|
-
<Switch>
|
|
13
|
-
<Route exact path="/" component={MockData} />
|
|
14
|
-
<Route exact path="/interface" component={InterfaceManagement} />
|
|
15
|
-
<Route path="/interface/:featureId" component={InterfaceManagement} />
|
|
16
|
-
<Route path="/settings" component={Settings} />
|
|
17
|
-
<Redirect to="/" />
|
|
18
|
-
</Switch>
|
|
19
|
-
</div>
|
|
20
|
-
</Router>
|
|
21
|
-
);
|
|
22
|
-
}
|
|
23
|
-
|
|
24
|
-
export default App;
|
|
@@ -1,235 +0,0 @@
|
|
|
1
|
-
import React, { useState } from 'react';
|
|
2
|
-
import AppLayout from '../components/AppLayout';
|
|
3
|
-
import '../styles/file-proxy.css';
|
|
4
|
-
|
|
5
|
-
const FileProxy = () => {
|
|
6
|
-
const [fileProxies, setFileProxies] = useState([
|
|
7
|
-
{
|
|
8
|
-
id: 1,
|
|
9
|
-
localPath: '/path/to/local/file.json',
|
|
10
|
-
remotePath: '/api/data',
|
|
11
|
-
description: '用户数据接口',
|
|
12
|
-
active: true
|
|
13
|
-
},
|
|
14
|
-
{
|
|
15
|
-
id: 2,
|
|
16
|
-
localPath: '/path/to/local/orders.json',
|
|
17
|
-
remotePath: '/api/orders',
|
|
18
|
-
description: '订单数据接口',
|
|
19
|
-
active: false
|
|
20
|
-
},
|
|
21
|
-
{
|
|
22
|
-
id: 3,
|
|
23
|
-
localPath: '/path/to/local/products.json',
|
|
24
|
-
remotePath: '/api/products',
|
|
25
|
-
description: '商品数据接口',
|
|
26
|
-
active: true
|
|
27
|
-
}
|
|
28
|
-
]);
|
|
29
|
-
|
|
30
|
-
const [isModalOpen, setIsModalOpen] = useState(false);
|
|
31
|
-
const [currentProxy, setCurrentProxy] = useState(null);
|
|
32
|
-
const [localPath, setLocalPath] = useState('');
|
|
33
|
-
const [remotePath, setRemotePath] = useState('');
|
|
34
|
-
const [description, setDescription] = useState('');
|
|
35
|
-
|
|
36
|
-
const openModal = (proxy = null) => {
|
|
37
|
-
if (proxy) {
|
|
38
|
-
setCurrentProxy(proxy);
|
|
39
|
-
setLocalPath(proxy.localPath);
|
|
40
|
-
setRemotePath(proxy.remotePath);
|
|
41
|
-
setDescription(proxy.description);
|
|
42
|
-
} else {
|
|
43
|
-
setCurrentProxy(null);
|
|
44
|
-
setLocalPath('');
|
|
45
|
-
setRemotePath('');
|
|
46
|
-
setDescription('');
|
|
47
|
-
}
|
|
48
|
-
setIsModalOpen(true);
|
|
49
|
-
};
|
|
50
|
-
|
|
51
|
-
const closeModal = () => {
|
|
52
|
-
setIsModalOpen(false);
|
|
53
|
-
};
|
|
54
|
-
|
|
55
|
-
const handleSubmit = (e) => {
|
|
56
|
-
e.preventDefault();
|
|
57
|
-
|
|
58
|
-
if (!localPath || !remotePath) {
|
|
59
|
-
alert('请填写本地文件路径和远程路径');
|
|
60
|
-
return;
|
|
61
|
-
}
|
|
62
|
-
|
|
63
|
-
if (currentProxy) {
|
|
64
|
-
// 编辑现有配置
|
|
65
|
-
setFileProxies(fileProxies.map(proxy =>
|
|
66
|
-
proxy.id === currentProxy.id
|
|
67
|
-
? { ...proxy, localPath, remotePath, description }
|
|
68
|
-
: proxy
|
|
69
|
-
));
|
|
70
|
-
} else {
|
|
71
|
-
// 添加新配置
|
|
72
|
-
const newProxy = {
|
|
73
|
-
id: fileProxies.length > 0 ? Math.max(...fileProxies.map(p => p.id)) + 1 : 1,
|
|
74
|
-
localPath,
|
|
75
|
-
remotePath,
|
|
76
|
-
description,
|
|
77
|
-
active: true
|
|
78
|
-
};
|
|
79
|
-
setFileProxies([...fileProxies, newProxy]);
|
|
80
|
-
}
|
|
81
|
-
|
|
82
|
-
closeModal();
|
|
83
|
-
};
|
|
84
|
-
|
|
85
|
-
const toggleActive = (id) => {
|
|
86
|
-
setFileProxies(fileProxies.map(proxy =>
|
|
87
|
-
proxy.id === id ? { ...proxy, active: !proxy.active } : proxy
|
|
88
|
-
));
|
|
89
|
-
};
|
|
90
|
-
|
|
91
|
-
const deleteProxy = (id) => {
|
|
92
|
-
if (window.confirm('确定要删除此条配置吗?')) {
|
|
93
|
-
setFileProxies(fileProxies.filter(proxy => proxy.id !== id));
|
|
94
|
-
}
|
|
95
|
-
};
|
|
96
|
-
|
|
97
|
-
return (
|
|
98
|
-
<AppLayout>
|
|
99
|
-
<div className="file-proxy-container">
|
|
100
|
-
<div className="page-title-bar">
|
|
101
|
-
<div>
|
|
102
|
-
<h1 className="page-title">文件代理配置</h1>
|
|
103
|
-
<div className="page-description">
|
|
104
|
-
配置文件代理规则,支持本地文件和远程文件
|
|
105
|
-
</div>
|
|
106
|
-
</div>
|
|
107
|
-
<div className="page-actions">
|
|
108
|
-
<button className="add-button" onClick={() => openModal()}>
|
|
109
|
-
添加文件代理
|
|
110
|
-
</button>
|
|
111
|
-
</div>
|
|
112
|
-
</div>
|
|
113
|
-
|
|
114
|
-
<div className="proxy-list-container">
|
|
115
|
-
{fileProxies.length === 0 ? (
|
|
116
|
-
<div className="empty-data">
|
|
117
|
-
<div className="empty-icon">📁</div>
|
|
118
|
-
<div className="empty-text">暂无文件代理配置</div>
|
|
119
|
-
<button className="add-button" onClick={() => openModal()}>
|
|
120
|
-
添加文件代理
|
|
121
|
-
</button>
|
|
122
|
-
</div>
|
|
123
|
-
) : (
|
|
124
|
-
<table className="proxy-table">
|
|
125
|
-
<thead>
|
|
126
|
-
<tr>
|
|
127
|
-
<th>状态</th>
|
|
128
|
-
<th>本地文件路径</th>
|
|
129
|
-
<th>远程路径</th>
|
|
130
|
-
<th>描述</th>
|
|
131
|
-
<th>操作</th>
|
|
132
|
-
</tr>
|
|
133
|
-
</thead>
|
|
134
|
-
<tbody>
|
|
135
|
-
{fileProxies.map(proxy => (
|
|
136
|
-
<tr key={proxy.id} className={proxy.active ? '' : 'inactive'}>
|
|
137
|
-
<td>
|
|
138
|
-
<label className="switch">
|
|
139
|
-
<input
|
|
140
|
-
type="checkbox"
|
|
141
|
-
checked={proxy.active}
|
|
142
|
-
onChange={() => toggleActive(proxy.id)}
|
|
143
|
-
/>
|
|
144
|
-
<span className="slider"></span>
|
|
145
|
-
</label>
|
|
146
|
-
</td>
|
|
147
|
-
<td className="local-path">{proxy.localPath}</td>
|
|
148
|
-
<td>{proxy.remotePath}</td>
|
|
149
|
-
<td>{proxy.description || '-'}</td>
|
|
150
|
-
<td>
|
|
151
|
-
<div className="action-buttons">
|
|
152
|
-
<button
|
|
153
|
-
className="edit-button"
|
|
154
|
-
onClick={() => openModal(proxy)}
|
|
155
|
-
>
|
|
156
|
-
编辑
|
|
157
|
-
</button>
|
|
158
|
-
<button
|
|
159
|
-
className="delete-button"
|
|
160
|
-
onClick={() => deleteProxy(proxy.id)}
|
|
161
|
-
>
|
|
162
|
-
删除
|
|
163
|
-
</button>
|
|
164
|
-
</div>
|
|
165
|
-
</td>
|
|
166
|
-
</tr>
|
|
167
|
-
))}
|
|
168
|
-
</tbody>
|
|
169
|
-
</table>
|
|
170
|
-
)}
|
|
171
|
-
</div>
|
|
172
|
-
|
|
173
|
-
{isModalOpen && (
|
|
174
|
-
<div className="modal-overlay">
|
|
175
|
-
<div className="modal">
|
|
176
|
-
<div className="modal-header">
|
|
177
|
-
<h2>{currentProxy ? '编辑文件代理' : '添加文件代理'}</h2>
|
|
178
|
-
<button className="close-button" onClick={closeModal}>×</button>
|
|
179
|
-
</div>
|
|
180
|
-
<form className="proxy-form" onSubmit={handleSubmit}>
|
|
181
|
-
<div className="form-group">
|
|
182
|
-
<label>本地文件路径</label>
|
|
183
|
-
<div className="file-input-group">
|
|
184
|
-
<input
|
|
185
|
-
type="text"
|
|
186
|
-
value={localPath}
|
|
187
|
-
onChange={(e) => setLocalPath(e.target.value)}
|
|
188
|
-
placeholder="/path/to/local/file.json"
|
|
189
|
-
required
|
|
190
|
-
/>
|
|
191
|
-
<button type="button" className="browse-button">浏览...</button>
|
|
192
|
-
</div>
|
|
193
|
-
<div className="help-text">选择本地文件作为数据源</div>
|
|
194
|
-
</div>
|
|
195
|
-
|
|
196
|
-
<div className="form-group">
|
|
197
|
-
<label>远程路径</label>
|
|
198
|
-
<input
|
|
199
|
-
type="text"
|
|
200
|
-
value={remotePath}
|
|
201
|
-
onChange={(e) => setRemotePath(e.target.value)}
|
|
202
|
-
placeholder="/api/data"
|
|
203
|
-
required
|
|
204
|
-
/>
|
|
205
|
-
<div className="help-text">访问此路径时将返回本地文件内容</div>
|
|
206
|
-
</div>
|
|
207
|
-
|
|
208
|
-
<div className="form-group">
|
|
209
|
-
<label>描述(可选)</label>
|
|
210
|
-
<input
|
|
211
|
-
type="text"
|
|
212
|
-
value={description}
|
|
213
|
-
onChange={(e) => setDescription(e.target.value)}
|
|
214
|
-
placeholder="接口描述"
|
|
215
|
-
/>
|
|
216
|
-
</div>
|
|
217
|
-
|
|
218
|
-
<div className="form-actions">
|
|
219
|
-
<button type="button" className="cancel-button" onClick={closeModal}>
|
|
220
|
-
取消
|
|
221
|
-
</button>
|
|
222
|
-
<button type="submit" className="submit-button">
|
|
223
|
-
{currentProxy ? '保存修改' : '添加代理'}
|
|
224
|
-
</button>
|
|
225
|
-
</div>
|
|
226
|
-
</form>
|
|
227
|
-
</div>
|
|
228
|
-
</div>
|
|
229
|
-
)}
|
|
230
|
-
</div>
|
|
231
|
-
</AppLayout>
|
|
232
|
-
);
|
|
233
|
-
};
|
|
234
|
-
|
|
235
|
-
export default FileProxy;
|