@yuku123/z-frontend-common 0.2.9 → 1.0.0

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.
Files changed (57) hide show
  1. package/LICENSE +25 -0
  2. package/README.md +55 -42
  3. package/dist/index.js +1 -0
  4. package/package.json +49 -44
  5. package/src/components/ErrorBoundary/index.jsx +24 -77
  6. package/src/components/Layout/index.jsx +141 -38
  7. package/src/components/LoginPage/index.jsx +47 -21
  8. package/src/components/StatusTag/index.jsx +14 -12
  9. package/src/index.js +32 -38
  10. package/src/services/request.js +74 -4
  11. package/dist/z-frontend-common.css +0 -1
  12. package/dist/z-frontend-common.es.js +0 -51275
  13. package/dist/z-frontend-common.umd.js +0 -459
  14. package/src/components/Ctc/Layout.jsx +0 -330
  15. package/src/components/Ctc/Layout.module.css +0 -145
  16. package/src/components/Ctc/agentTeam/index.tsx +0 -308
  17. package/src/components/Ctc/login/AuthPage.module.css +0 -26
  18. package/src/components/Ctc/login/AuthPage.tsx +0 -235
  19. package/src/components/Ctc/login/index.less +0 -49
  20. package/src/components/Ctc/login/index.tsx +0 -142
  21. package/src/components/Ctc/uc/UCLogin.tsx +0 -31
  22. package/src/components/Ctc/uc/UCPhoneLogin.tsx +0 -62
  23. package/src/components/Ctc/uc/UCRegister.tsx +0 -37
  24. package/src/components/Ctc/uc/UCResetPassword.tsx +0 -69
  25. package/src/components/Ctc/uc/index.tsx +0 -15
  26. package/src/components/Ctc/userPanel/index.tsx +0 -999
  27. package/src/components/Ctc/webide/index.tsx +0 -272
  28. package/src/components/LowCode/LowCodeModel.jsx +0 -962
  29. package/src/components/LowCode/LowCodePage.jsx +0 -31
  30. package/src/components/LowCode/LowCodeRuntime.jsx +0 -335
  31. package/src/components/LowCode/MaterializePage.jsx +0 -235
  32. package/src/components/LowCode/index.js +0 -1
  33. package/src/components/MockPlatform/CurlImportModal.jsx +0 -362
  34. package/src/components/MockPlatform/EndpointsTab.jsx +0 -509
  35. package/src/components/MockPlatform/EnvironmentsTab.jsx +0 -212
  36. package/src/components/MockPlatform/MockTemplateHelper.jsx +0 -200
  37. package/src/components/MockPlatform/OpenApiImportModal.jsx +0 -305
  38. package/src/components/MockPlatform/RecordingsTab.jsx +0 -397
  39. package/src/components/MockPlatform/RequestLogsTab.jsx +0 -239
  40. package/src/components/MockPlatform/ScenariosTab.jsx +0 -236
  41. package/src/components/MockPlatform/TestCasesTab.jsx +0 -462
  42. package/src/components/MockPlatform/index.jsx +0 -127
  43. package/src/components/Overview.jsx +0 -74
  44. package/src/dev.jsx +0 -28
  45. package/src/services/agentTeam.js +0 -7
  46. package/src/services/api.js +0 -84
  47. package/src/services/ctcAc.js +0 -7
  48. package/src/services/ctcAcDomain.js +0 -7
  49. package/src/services/ctcAuthorization.js +0 -7
  50. package/src/services/ctcSurl.js +0 -7
  51. package/src/services/ctcUser.js +0 -7
  52. package/src/services/job.js +0 -7
  53. package/src/services/metaApp.js +0 -7
  54. package/src/services/privateConfig.js +0 -7
  55. package/src/services/webide.js +0 -6
  56. package/src/services/workspace.js +0 -21
  57. package/src/utils/request.ts +0 -102
@@ -1,362 +0,0 @@
1
- import {useState} from 'react'
2
- import {
3
- Alert,
4
- Button,
5
- Card,
6
- Col,
7
- Descriptions,
8
- Form,
9
- Input,
10
- message,
11
- Modal,
12
- Row,
13
- Select,
14
- Space,
15
- Tabs,
16
- Tag,
17
- Typography
18
- } from 'antd'
19
- import {CodeOutlined, FileTextOutlined, ImportOutlined, ThunderboltOutlined} from '@ant-design/icons'
20
- import {mockPlatformApi} from '@/services/api'
21
-
22
- const {TextArea} = Input
23
- const {Text, Paragraph} = Typography
24
-
25
- /**
26
- * Curl 一键导入对话框
27
- * - 粘贴 curl → 自动解析为 method/url/headers/body
28
- * - "直接执行":先试跑(不落库)
29
- * - "导入为测试用例":落库为 MockTestCase
30
- * - "导入为 Mock 端点":落库为 MockEndpoint
31
- * - 复用 MockPlatformController /api/mock-platform/curl/* 端点
32
- */
33
- export default function CurlImportModal({open, onClose, onSuccess, envOptions = []}) {
34
- const [curlText, setCurlText] = useState('')
35
- const [parseResult, setParseResult] = useState(null)
36
- const [parseError, setParseError] = useState(null)
37
- const [running, setRunning] = useState(false)
38
- const [runResult, setRunResult] = useState(null)
39
- const [importing, setImporting] = useState(false)
40
- const [activeTab, setActiveTab] = useState('import')
41
- const [caseForm] = Form.useForm()
42
- const [epForm] = Form.useForm()
43
-
44
- const reset = () => {
45
- setCurlText('')
46
- setParseResult(null)
47
- setParseError(null)
48
- setRunResult(null)
49
- caseForm.resetFields()
50
- epForm.resetFields()
51
- }
52
-
53
- const handleClose = () => {
54
- reset()
55
- onClose()
56
- }
57
-
58
- const handleParse = async () => {
59
- if (!curlText.trim()) {
60
- message.warning('请先粘贴 curl 命令');
61
- return
62
- }
63
- setParseError(null)
64
- setParseResult(null)
65
- setRunResult(null)
66
- try {
67
- const res = await mockPlatformApi.curl.parse(curlText)
68
- if (res.success) {
69
- setParseResult(res.data)
70
- // 自动预填表单
71
- caseForm.setFieldsValue({
72
- caseName: `from-curl-${(res.data?.method || 'GET')}-${(res.data?.path || '').replace(/\W+/g, '-')}`,
73
- caseGroup: 'imported',
74
- envCode: envOptions[0] || 'default',
75
- })
76
- epForm.setFieldsValue({
77
- mockName: `mock-${(res.data?.method || 'GET')}-${(res.data?.path || '').replace(/\W+/g, '-')}`,
78
- envCode: envOptions[0] || 'default',
79
- projectCode: 'default',
80
- responseTemplate: '{\n "code": 0,\n "message": "ok",\n "data": {}\n}',
81
- })
82
- } else {
83
- setParseError(res.message || '解析失败')
84
- }
85
- } catch (e) {
86
- setParseError(String(e?.message || e))
87
- }
88
- }
89
-
90
- const handleRun = async () => {
91
- if (!curlText.trim()) {
92
- message.warning('请先粘贴 curl 命令');
93
- return
94
- }
95
- setRunning(true)
96
- setRunResult(null)
97
- try {
98
- const res = await mockPlatformApi.curl.run(curlText)
99
- setRunResult(res)
100
- } catch (e) {
101
- setRunResult({success: false, error: String(e?.message || e)})
102
- } finally {
103
- setRunning(false)
104
- }
105
- }
106
-
107
- const handleImportAsCase = async () => {
108
- if (!parseResult) {
109
- message.warning('请先解析');
110
- return
111
- }
112
- let values
113
- try {
114
- values = await caseForm.validateFields()
115
- } catch {
116
- return
117
- }
118
- setImporting(true)
119
- try {
120
- const res = await mockPlatformApi.curl.importAsCase({
121
- curl: curlText,
122
- caseName: values.caseName,
123
- caseGroup: values.caseGroup,
124
- envCode: values.envCode,
125
- })
126
- if (res.success) {
127
- message.success(`已导入测试用例: ${res.caseCode}`)
128
- onSuccess && onSuccess('case', res)
129
- handleClose()
130
- } else {
131
- message.error(res.message || '导入失败')
132
- }
133
- } catch (e) {
134
- message.error(String(e?.message || e))
135
- } finally {
136
- setImporting(false)
137
- }
138
- }
139
-
140
- const handleImportAsEndpoint = async () => {
141
- if (!parseResult) {
142
- message.warning('请先解析');
143
- return
144
- }
145
- let values
146
- try {
147
- values = await epForm.validateFields()
148
- } catch {
149
- return
150
- }
151
- setImporting(true)
152
- try {
153
- const res = await mockPlatformApi.curl.importAsEndpoint({
154
- curl: curlText,
155
- mockName: values.mockName,
156
- envCode: values.envCode,
157
- projectCode: values.projectCode,
158
- responseTemplate: values.responseTemplate,
159
- })
160
- if (res.success) {
161
- message.success(`已导入 Mock 端点: ${res.mockCode}`)
162
- onSuccess && onSuccess('endpoint', res)
163
- handleClose()
164
- } else {
165
- message.error(res.message || '导入失败')
166
- }
167
- } catch (e) {
168
- message.error(String(e?.message || e))
169
- } finally {
170
- setImporting(false)
171
- }
172
- }
173
-
174
- return (
175
- <Modal
176
- title={<Space><CodeOutlined/> 粘贴 curl 一键导入</Space>}
177
- open={open}
178
- onCancel={handleClose}
179
- footer={null}
180
- width={900}
181
- destroyOnHidden
182
- >
183
- <Paragraph type="secondary" style={{marginBottom: 12}}>
184
- 从浏览器 DevTools / Postman / 终端复制 curl 命令,粘贴到下方即可解析、试跑、入库。
185
- </Paragraph>
186
-
187
- <TextArea
188
- value={curlText}
189
- onChange={(e) => setCurlText(e.target.value)}
190
- placeholder={`curl -X POST 'https://api.example.com/v1/users/login' \\\n -H 'Content-Type: application/json' \\\n -H 'Authorization: Bearer xxx' \\\n -d '{"username":"alice","password":"123456"}'`}
191
- autoSize={{minRows: 4, maxRows: 10}}
192
- style={{fontFamily: 'Menlo, Monaco, monospace', fontSize: 12}}
193
- />
194
-
195
- <Space style={{marginTop: 12}}>
196
- <Button icon={<FileTextOutlined/>} onClick={handleParse} type="primary" ghost>
197
- 解析
198
- </Button>
199
- <Button icon={<ThunderboltOutlined/>} onClick={handleRun} loading={running}>
200
- 直接执行(试跑)
201
- </Button>
202
- </Space>
203
-
204
- {parseError && (
205
- <Alert type="error" showIcon style={{marginTop: 12}} title="解析失败" description={parseError}/>
206
- )}
207
-
208
- {parseResult && (
209
- <Card size="small" style={{marginTop: 16}} title="解析结果">
210
- <Descriptions column={1} size="small" bordered>
211
- <Descriptions.Item label="Method">
212
- <Tag color={methodColor(parseResult.method)}>{parseResult.method}</Tag>
213
- </Descriptions.Item>
214
- <Descriptions.Item label="URL">
215
- <Text code copyable>{parseResult.url}</Text>
216
- </Descriptions.Item>
217
- <Descriptions.Item label="Path">
218
- <Text code>{parseResult.path}</Text>
219
- </Descriptions.Item>
220
- {parseResult.query && (
221
- <Descriptions.Item label="Query">
222
- <Text code>{parseResult.query}</Text>
223
- </Descriptions.Item>
224
- )}
225
- <Descriptions.Item label="Headers">
226
- {Object.keys(parseResult.headers || {}).length === 0
227
- ? <Text type="secondary">(无)</Text>
228
- : (
229
- <div>
230
- {Object.entries(parseResult.headers).map(([k, v]) => (
231
- <div key={k}><Text strong>{k}:</Text> <Text code>{v}</Text></div>
232
- ))}
233
- </div>
234
- )}
235
- </Descriptions.Item>
236
- {parseResult.body && (
237
- <Descriptions.Item label="Body">
238
- <pre style={{
239
- background: '#f5f5f5',
240
- padding: 8,
241
- margin: 0,
242
- fontSize: 12,
243
- maxHeight: 200,
244
- overflow: 'auto'
245
- }}>
246
- {parseResult.body}
247
- </pre>
248
- </Descriptions.Item>
249
- )}
250
- </Descriptions>
251
- </Card>
252
- )}
253
-
254
- {runResult && (
255
- <Card size="small" style={{marginTop: 16}} title={
256
- <Space>
257
- <ThunderboltOutlined/>
258
- <span>试跑结果</span>
259
- {runResult.success
260
- ? <Tag color="green">{runResult.status} · {runResult.durationMs}ms
261
- · {runResult.bodySize}B</Tag>
262
- : <Tag color="red">FAILED</Tag>}
263
- </Space>
264
- }>
265
- {runResult.error && <Alert type="error" showIcon title={runResult.error}/>}
266
- {runResult.body != null && (
267
- <pre style={{
268
- background: '#f5f5f5',
269
- padding: 8,
270
- margin: 0,
271
- fontSize: 12,
272
- maxHeight: 240,
273
- overflow: 'auto'
274
- }}>
275
- {runResult.body}
276
- </pre>
277
- )}
278
- </Card>
279
- )}
280
-
281
- {parseResult && (
282
- <Tabs
283
- activeKey={activeTab}
284
- onChange={setActiveTab}
285
- style={{marginTop: 16}}
286
- items={[
287
- {
288
- key: 'import',
289
- label: <span><ImportOutlined/> 导入为测试用例</span>,
290
- children: (
291
- <Form form={caseForm} layout="vertical">
292
- <Row gutter={16}>
293
- <Col span={12}>
294
- <Form.Item name="caseName" label="用例名称" rules={[{required: true}]}>
295
- <Input/>
296
- </Form.Item>
297
- </Col>
298
- <Col span={6}>
299
- <Form.Item name="caseGroup" label="用例分组">
300
- <Input/>
301
- </Form.Item>
302
- </Col>
303
- <Col span={6}>
304
- <Form.Item name="envCode" label="环境">
305
- {envOptions.length > 0
306
- ? <Select options={envOptions.map(e => ({value: e, label: e}))}/>
307
- : <Input/>}
308
- </Form.Item>
309
- </Col>
310
- </Row>
311
- <Button type="primary" onClick={handleImportAsCase} loading={importing}
312
- icon={<ImportOutlined/>}>
313
- 保存为测试用例
314
- </Button>
315
- </Form>
316
- ),
317
- },
318
- {
319
- key: 'mock',
320
- label: <span><CodeOutlined/> 导入为 Mock 端点</span>,
321
- children: (
322
- <Form form={epForm} layout="vertical">
323
- <Row gutter={16}>
324
- <Col span={12}>
325
- <Form.Item name="mockName" label="Mock 名称" rules={[{required: true}]}>
326
- <Input/>
327
- </Form.Item>
328
- </Col>
329
- <Col span={6}>
330
- <Form.Item name="envCode" label="环境">
331
- {envOptions.length > 0
332
- ? <Select options={envOptions.map(e => ({value: e, label: e}))}/>
333
- : <Input/>}
334
- </Form.Item>
335
- </Col>
336
- <Col span={6}>
337
- <Form.Item name="projectCode" label="项目">
338
- <Input/>
339
- </Form.Item>
340
- </Col>
341
- </Row>
342
- <Form.Item name="responseTemplate" label="响应模板 (JSON)">
343
- <TextArea autoSize={{minRows: 3, maxRows: 8}}
344
- style={{fontFamily: 'Menlo, Monaco, monospace'}}/>
345
- </Form.Item>
346
- <Button type="primary" onClick={handleImportAsEndpoint} loading={importing}
347
- icon={<CodeOutlined/>}>
348
- 保存为 Mock 端点
349
- </Button>
350
- </Form>
351
- ),
352
- },
353
- ]}
354
- />
355
- )}
356
- </Modal>
357
- )
358
- }
359
-
360
- function methodColor(method) {
361
- return {GET: 'blue', POST: 'green', PUT: 'orange', DELETE: 'red', PATCH: 'purple'}[method] || 'default'
362
- }