@yuku123/z-frontend-common 0.2.9 → 1.1.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 (75) hide show
  1. package/LICENSE +25 -0
  2. package/README.md +55 -42
  3. package/dist/PagedTable-DyjNokXN.js +1211 -0
  4. package/dist/index.js +310 -0
  5. package/dist/ui.js +27 -0
  6. package/package.json +52 -44
  7. package/src/components/ErrorBoundary/index.jsx +24 -77
  8. package/src/components/Layout/index.jsx +141 -38
  9. package/src/components/LoginPage/index.jsx +47 -21
  10. package/src/components/StatusTag/index.jsx +14 -12
  11. package/src/components/ui/CategoryDot.jsx +38 -0
  12. package/src/components/ui/DarkBanner.jsx +142 -0
  13. package/src/components/ui/EChartsChart.jsx +82 -0
  14. package/src/components/ui/EmptyState.jsx +94 -0
  15. package/src/components/ui/ErrorState.jsx +114 -0
  16. package/src/components/ui/FeatureCard.jsx +205 -0
  17. package/src/components/ui/GradientStatCard.jsx +196 -0
  18. package/src/components/ui/LoadingState.jsx +116 -0
  19. package/src/components/ui/PageHeader.jsx +143 -0
  20. package/src/components/ui/PagedTable.jsx +83 -0
  21. package/src/components/ui/SearchInput.jsx +111 -0
  22. package/src/components/ui/SectionHeader.jsx +76 -0
  23. package/src/components/ui/StatusBadge.jsx +66 -0
  24. package/src/components/ui/TableToolbar.jsx +58 -0
  25. package/src/components/ui/index.js +36 -0
  26. package/src/components/ui/tokens.js +224 -0
  27. package/src/index.js +33 -37
  28. package/src/services/request.js +74 -4
  29. package/dist/z-frontend-common.css +0 -1
  30. package/dist/z-frontend-common.es.js +0 -51275
  31. package/dist/z-frontend-common.umd.js +0 -459
  32. package/src/components/Ctc/Layout.jsx +0 -330
  33. package/src/components/Ctc/Layout.module.css +0 -145
  34. package/src/components/Ctc/agentTeam/index.tsx +0 -308
  35. package/src/components/Ctc/login/AuthPage.module.css +0 -26
  36. package/src/components/Ctc/login/AuthPage.tsx +0 -235
  37. package/src/components/Ctc/login/index.less +0 -49
  38. package/src/components/Ctc/login/index.tsx +0 -142
  39. package/src/components/Ctc/uc/UCLogin.tsx +0 -31
  40. package/src/components/Ctc/uc/UCPhoneLogin.tsx +0 -62
  41. package/src/components/Ctc/uc/UCRegister.tsx +0 -37
  42. package/src/components/Ctc/uc/UCResetPassword.tsx +0 -69
  43. package/src/components/Ctc/uc/index.tsx +0 -15
  44. package/src/components/Ctc/userPanel/index.tsx +0 -999
  45. package/src/components/Ctc/webide/index.tsx +0 -272
  46. package/src/components/LowCode/LowCodeModel.jsx +0 -962
  47. package/src/components/LowCode/LowCodePage.jsx +0 -31
  48. package/src/components/LowCode/LowCodeRuntime.jsx +0 -335
  49. package/src/components/LowCode/MaterializePage.jsx +0 -235
  50. package/src/components/LowCode/index.js +0 -1
  51. package/src/components/MockPlatform/CurlImportModal.jsx +0 -362
  52. package/src/components/MockPlatform/EndpointsTab.jsx +0 -509
  53. package/src/components/MockPlatform/EnvironmentsTab.jsx +0 -212
  54. package/src/components/MockPlatform/MockTemplateHelper.jsx +0 -200
  55. package/src/components/MockPlatform/OpenApiImportModal.jsx +0 -305
  56. package/src/components/MockPlatform/RecordingsTab.jsx +0 -397
  57. package/src/components/MockPlatform/RequestLogsTab.jsx +0 -239
  58. package/src/components/MockPlatform/ScenariosTab.jsx +0 -236
  59. package/src/components/MockPlatform/TestCasesTab.jsx +0 -462
  60. package/src/components/MockPlatform/index.jsx +0 -127
  61. package/src/components/Overview.jsx +0 -74
  62. package/src/dev.jsx +0 -28
  63. package/src/services/agentTeam.js +0 -7
  64. package/src/services/api.js +0 -84
  65. package/src/services/ctcAc.js +0 -7
  66. package/src/services/ctcAcDomain.js +0 -7
  67. package/src/services/ctcAuthorization.js +0 -7
  68. package/src/services/ctcSurl.js +0 -7
  69. package/src/services/ctcUser.js +0 -7
  70. package/src/services/job.js +0 -7
  71. package/src/services/metaApp.js +0 -7
  72. package/src/services/privateConfig.js +0 -7
  73. package/src/services/webide.js +0 -6
  74. package/src/services/workspace.js +0 -21
  75. 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
- }