whistle.mock-plugins 1.1.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.
@@ -1,66 +1,61 @@
1
1
  import React, { useState, useEffect } from 'react';
2
2
  import AppLayout from '../components/AppLayout';
3
- import { Form, Input, Button, Switch, Card, message, Divider, Typography, Space, Alert, InputNumber } from 'antd';
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 [form] = Form.useForm();
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
- fetchSettings();
33
+ const currentVersion = getUIVersion();
34
+ setUiVersionState(currentVersion);
17
35
  }, []);
18
36
 
19
- const fetchSettings = async () => {
20
- try {
21
- setLoading(true);
22
- // 这里假设有一个获取设置的接口
23
- // 为了示例,我们使用默认设置
24
- const defaultSettings = {
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
- setSettings(defaultSettings);
35
- form.setFieldsValue(defaultSettings);
36
- } catch (error) {
37
- console.error('获取设置失败:', error);
38
- message.error('获取设置失败');
39
- } finally {
40
- setLoading(false);
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
- setSettings(values);
52
- message.success('设置已保存');
53
- } catch (error) {
54
- console.error('保存设置失败:', error);
55
- message.error('保存设置失败');
56
- } finally {
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
- <Alert
80
- message="设置功能正在开发中"
81
- description="目前部分设置可能不生效,我们正在努力完善此功能"
82
- type="info"
83
- showIcon
84
- style={{ marginBottom: 20 }}
85
- />
86
-
87
- <Form
88
- form={form}
89
- layout="vertical"
90
- onFinish={handleSave}
91
- initialValues={settings || {}}
92
- >
93
- <Card title="日志设置" className="settings-card">
94
- <Form.Item
95
- name="enableLogging"
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
- <Card title="界面设置" className="settings-card">
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 className="settings-actions">
168
- <Space>
169
- <Button
170
- type="default"
171
- icon={<UndoOutlined />}
172
- onClick={handleReset}
173
- >
174
- 重置
175
- </Button>
176
- <Button
177
- type="primary"
178
- icon={<SaveOutlined />}
179
- htmlType="submit"
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
- </Form>
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;