@yuku123/z-frontend-common 0.2.3 → 0.2.5
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/dist/z-frontend-common.es.js +47259 -4698
- package/dist/z-frontend-common.umd.js +430 -19
- package/package.json +1 -1
- package/src/components/Ctc/Layout.jsx +10 -8
- package/src/components/Ctc/agentTeam/index.tsx +1 -1
- package/src/components/Ctc/login/index.tsx +1 -1
- package/src/components/Ctc/userPanel/index.tsx +3 -2
- package/src/components/LowCode/LowCodeModel.jsx +3 -3
- package/src/components/LowCode/LowCodeRuntime.jsx +3 -3
- package/src/components/MockPlatform/CurlImportModal.jsx +3 -3
- package/src/components/MockPlatform/EndpointsTab.jsx +1 -1
- package/src/components/MockPlatform/EnvironmentsTab.jsx +1 -1
- package/src/components/MockPlatform/OpenApiImportModal.jsx +2 -2
- package/src/components/MockPlatform/RecordingsTab.jsx +2 -2
- package/src/components/MockPlatform/RequestLogsTab.jsx +3 -3
- package/src/components/MockPlatform/ScenariosTab.jsx +1 -1
- package/src/components/MockPlatform/TestCasesTab.jsx +4 -4
package/package.json
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import React, {useEffect, useRef, useState} from 'react'
|
|
2
|
-
import {
|
|
2
|
+
import {useLocation, useNavigate} from 'react-router-dom'
|
|
3
3
|
import {Avatar, Cascader, Divider, Dropdown, Layout as AntLayout, Menu, Space, Typography,} from 'antd'
|
|
4
4
|
import {
|
|
5
5
|
AppstoreOutlined,
|
|
@@ -25,7 +25,7 @@ import {getCurrentUser} from '../../services/api'
|
|
|
25
25
|
const {Header, Sider, Content} = AntLayout
|
|
26
26
|
const {Text} = Typography
|
|
27
27
|
|
|
28
|
-
const Layout = ({compact = false} = {}) => {
|
|
28
|
+
const Layout = ({compact = false, children} = {}) => {
|
|
29
29
|
const location = useLocation()
|
|
30
30
|
const navigate = useNavigate()
|
|
31
31
|
const [collapsed, setCollapsed] = useState(false)
|
|
@@ -174,11 +174,15 @@ const Layout = ({compact = false} = {}) => {
|
|
|
174
174
|
navigate(`/ctc/${key}`)
|
|
175
175
|
}
|
|
176
176
|
|
|
177
|
+
// compact=true: 由主壳 App.jsx 提供 Layout, 这里只渲染 children (passthrough)
|
|
178
|
+
// compact=false: 独立运行时, 自己提供完整 Layout (Header + Sider + Content)
|
|
179
|
+
if (compact) {
|
|
180
|
+
return <>{children}</>
|
|
181
|
+
}
|
|
182
|
+
|
|
177
183
|
return (
|
|
178
184
|
<AntLayout className={styles.layout}>
|
|
179
|
-
{
|
|
180
|
-
/* 顶部导航栏 (compact 模式: 由主壳 App.jsx 提供) */
|
|
181
|
-
<>
|
|
185
|
+
{/* 顶部导航栏 */}
|
|
182
186
|
<Header className={styles.header}>
|
|
183
187
|
<div className={styles.logo}>
|
|
184
188
|
<span className={styles.logoText}>Z-CTC 统一用户中心</span>
|
|
@@ -288,8 +292,6 @@ const Layout = ({compact = false} = {}) => {
|
|
|
288
292
|
</Space>
|
|
289
293
|
</div>
|
|
290
294
|
</Header>
|
|
291
|
-
</>
|
|
292
|
-
)}
|
|
293
295
|
|
|
294
296
|
<AntLayout className={styles.mainLayout}>
|
|
295
297
|
{/* 侧边菜单 */}
|
|
@@ -318,7 +320,7 @@ const Layout = ({compact = false} = {}) => {
|
|
|
318
320
|
|
|
319
321
|
{/* 主内容区 */}
|
|
320
322
|
<Content className={styles.content}>
|
|
321
|
-
|
|
323
|
+
{children}
|
|
322
324
|
</Content>
|
|
323
325
|
</AntLayout>
|
|
324
326
|
</AntLayout>
|
|
@@ -295,7 +295,7 @@ export default function AgentTeamIM() {
|
|
|
295
295
|
style={{marginTop: 16}}
|
|
296
296
|
type="info"
|
|
297
297
|
showIcon
|
|
298
|
-
|
|
298
|
+
title="说明"
|
|
299
299
|
description={
|
|
300
300
|
<span>
|
|
301
301
|
完整 STOMP 客户端 (含订阅 Topic、ACK、消息历史) 见 <code>z-agent/z-agent-team/z-agent-team-frontend</code>。
|
|
@@ -85,7 +85,7 @@ const Login: React.FC = () => {
|
|
|
85
85
|
<Tabs activeKey={type} centered items={[{key: 'account', label: '账户密码登录'}]}/>
|
|
86
86
|
|
|
87
87
|
{status === 'error' && (
|
|
88
|
-
<Alert
|
|
88
|
+
<Alert title="账户或密码错误" type="error" showIcon style={{marginBottom: 16}}/>
|
|
89
89
|
)}
|
|
90
90
|
|
|
91
91
|
<Form
|
|
@@ -1,5 +1,6 @@
|
|
|
1
1
|
import {useEffect, useRef, useState} from 'react'
|
|
2
|
-
import {
|
|
2
|
+
import {Avatar, Badge, Button, Empty, Form, Input, Modal, Popconfirm, Space, Spin, Tag, Tooltip, Tree} from 'antd'
|
|
3
|
+
import AntApp from 'antd/es/app'
|
|
3
4
|
import type {DataNode} from 'antd/es/tree'
|
|
4
5
|
import {
|
|
5
6
|
CheckCircleOutlined,
|
|
@@ -52,7 +53,7 @@ const STATUS_COLOR: Record<string, string> = {
|
|
|
52
53
|
}
|
|
53
54
|
|
|
54
55
|
export default function UserPanel() {
|
|
55
|
-
const {message} =
|
|
56
|
+
const {message} = AntApp.useApp()
|
|
56
57
|
const userInfoStr = localStorage.getItem('userInfo') || '{}'
|
|
57
58
|
let userInfo: any = {}
|
|
58
59
|
try {
|
|
@@ -463,7 +463,7 @@ export default function LowCodeModel() {
|
|
|
463
463
|
<Alert
|
|
464
464
|
type="info"
|
|
465
465
|
showIcon
|
|
466
|
-
|
|
466
|
+
title="提示: 点击实体的「画布编辑」进入拖拽式建模: 从左侧面板拖字段类型到中间, 拖拽字段行可重排, 右侧编辑属性。"
|
|
467
467
|
style={{marginBottom: 16}}
|
|
468
468
|
/>
|
|
469
469
|
<Spin spinning={loading}>
|
|
@@ -493,7 +493,7 @@ export default function LowCodeModel() {
|
|
|
493
493
|
onCancel={() => setEntityModalOpen(false)}
|
|
494
494
|
onOk={handleSubmitEntity}
|
|
495
495
|
width={760}
|
|
496
|
-
|
|
496
|
+
destroyOnHidden
|
|
497
497
|
>
|
|
498
498
|
<EntityForm form={entityForm} editing={editingEntity}/>
|
|
499
499
|
</Modal>
|
|
@@ -522,7 +522,7 @@ export default function LowCodeModel() {
|
|
|
522
522
|
}
|
|
523
523
|
}}
|
|
524
524
|
width="85%"
|
|
525
|
-
|
|
525
|
+
destroyOnHidden
|
|
526
526
|
extra={
|
|
527
527
|
<Space>
|
|
528
528
|
<Button onClick={handleProvision} icon={<DatabaseOutlined/>}>
|
|
@@ -137,7 +137,7 @@ export default function LowCodeRuntime() {
|
|
|
137
137
|
<Alert
|
|
138
138
|
type="warning"
|
|
139
139
|
showIcon
|
|
140
|
-
|
|
140
|
+
title={`实体 ${entityCodeParam} 未定义`}
|
|
141
141
|
description={`请先在 模型编辑器 (路径 /form/_model?appCode=${appCode}) 中定义实体, 然后刷新此页.`}
|
|
142
142
|
/>
|
|
143
143
|
</Card>
|
|
@@ -282,7 +282,7 @@ export default function LowCodeRuntime() {
|
|
|
282
282
|
<Alert
|
|
283
283
|
type="info"
|
|
284
284
|
showIcon
|
|
285
|
-
|
|
285
|
+
title={`App=${appCode} · Tenant=${tenantCode} · 字段数=${fields.length}`}
|
|
286
286
|
style={{marginBottom: 16}}
|
|
287
287
|
/>
|
|
288
288
|
<Spin spinning={loading}>
|
|
@@ -309,7 +309,7 @@ export default function LowCodeRuntime() {
|
|
|
309
309
|
onCancel={() => setModalOpen(false)}
|
|
310
310
|
onOk={handleSubmit}
|
|
311
311
|
width={680}
|
|
312
|
-
|
|
312
|
+
destroyOnHidden
|
|
313
313
|
>
|
|
314
314
|
<Form form={form} layout="vertical">
|
|
315
315
|
{fields.map(f => (
|
|
@@ -178,7 +178,7 @@ export default function CurlImportModal({open, onClose, onSuccess, envOptions =
|
|
|
178
178
|
onCancel={handleClose}
|
|
179
179
|
footer={null}
|
|
180
180
|
width={900}
|
|
181
|
-
|
|
181
|
+
destroyOnHidden
|
|
182
182
|
>
|
|
183
183
|
<Paragraph type="secondary" style={{marginBottom: 12}}>
|
|
184
184
|
从浏览器 DevTools / Postman / 终端复制 curl 命令,粘贴到下方即可解析、试跑、入库。
|
|
@@ -202,7 +202,7 @@ export default function CurlImportModal({open, onClose, onSuccess, envOptions =
|
|
|
202
202
|
</Space>
|
|
203
203
|
|
|
204
204
|
{parseError && (
|
|
205
|
-
<Alert type="error" showIcon style={{marginTop: 12}}
|
|
205
|
+
<Alert type="error" showIcon style={{marginTop: 12}} title="解析失败" description={parseError}/>
|
|
206
206
|
)}
|
|
207
207
|
|
|
208
208
|
{parseResult && (
|
|
@@ -262,7 +262,7 @@ export default function CurlImportModal({open, onClose, onSuccess, envOptions =
|
|
|
262
262
|
: <Tag color="red">FAILED</Tag>}
|
|
263
263
|
</Space>
|
|
264
264
|
}>
|
|
265
|
-
{runResult.error && <Alert type="error" showIcon
|
|
265
|
+
{runResult.error && <Alert type="error" showIcon title={runResult.error}/>}
|
|
266
266
|
{runResult.body != null && (
|
|
267
267
|
<pre style={{
|
|
268
268
|
background: '#f5f5f5',
|
|
@@ -226,7 +226,7 @@ export default function EndpointsTab({activeEnvCode}) {
|
|
|
226
226
|
<div>
|
|
227
227
|
{mockError && (
|
|
228
228
|
<Alert type="warning" showIcon style={{marginBottom: 16}}
|
|
229
|
-
|
|
229
|
+
title="后端 API 暂未连接" description={mockError}/>
|
|
230
230
|
)}
|
|
231
231
|
|
|
232
232
|
<Row gutter={16} style={{marginBottom: 16}}>
|
|
@@ -139,7 +139,7 @@ export default function EnvironmentsTab({onEnvChange}) {
|
|
|
139
139
|
return (
|
|
140
140
|
<div>
|
|
141
141
|
<Alert type="info" showIcon style={{marginBottom: 16}}
|
|
142
|
-
|
|
142
|
+
title="环境隔离 - 控制 Mock 与真实服务的切换"
|
|
143
143
|
description={
|
|
144
144
|
<div>
|
|
145
145
|
<div><Tag color="green">MOCK</Tag> 完全拦截,仅返回 Mock 数据</div>
|
|
@@ -163,7 +163,7 @@ export default function OpenApiImportModal({open, onClose, onSuccess, envOptions
|
|
|
163
163
|
onCancel={handleClose}
|
|
164
164
|
footer={null}
|
|
165
165
|
width={1100}
|
|
166
|
-
|
|
166
|
+
destroyOnHidden
|
|
167
167
|
>
|
|
168
168
|
<Tabs
|
|
169
169
|
activeKey={activeTab}
|
|
@@ -227,7 +227,7 @@ export default function OpenApiImportModal({open, onClose, onSuccess, envOptions
|
|
|
227
227
|
</Space>
|
|
228
228
|
|
|
229
229
|
{parseError && (
|
|
230
|
-
<Alert type="error" showIcon style={{marginTop: 12}}
|
|
230
|
+
<Alert type="error" showIcon style={{marginTop: 12}} title="解析失败" description={parseError}/>
|
|
231
231
|
)}
|
|
232
232
|
|
|
233
233
|
{parsed && (
|
|
@@ -239,7 +239,7 @@ export default function RecordingsTab() {
|
|
|
239
239
|
return (
|
|
240
240
|
<div>
|
|
241
241
|
<Alert type="info" showIcon style={{marginBottom: 16}}
|
|
242
|
-
|
|
242
|
+
title="流量录制与回放"
|
|
243
243
|
description={
|
|
244
244
|
<div>
|
|
245
245
|
<div>• 开启录制后,所有 <Text code>/api/mock/{envCode}/**</Text> 请求会被捕获到数据库
|
|
@@ -369,7 +369,7 @@ export default function RecordingsTab() {
|
|
|
369
369
|
</Space>
|
|
370
370
|
</Form>
|
|
371
371
|
<Alert type="info" showIcon style={{marginBottom: 12}}
|
|
372
|
-
|
|
372
|
+
title={`从录制中识别出 ${exportDrafts.length} 个去重后的 Mock endpoint,已默认全选`}/>
|
|
373
373
|
<Table
|
|
374
374
|
size="small"
|
|
375
375
|
dataSource={exportDrafts}
|
|
@@ -124,7 +124,7 @@ export default function RequestLogsTab() {
|
|
|
124
124
|
return (
|
|
125
125
|
<div>
|
|
126
126
|
<Alert type="info" showIcon style={{marginBottom: 16}}
|
|
127
|
-
|
|
127
|
+
title="Mock 请求日志 - 排查未匹配请求"
|
|
128
128
|
description="每一次请求都会留痕。包括请求/响应体、是否匹配 Mock、回退类型、耗时、场景状态等。便于排查“为什么这个请求没有 Mock 命中”问题。"
|
|
129
129
|
/>
|
|
130
130
|
|
|
@@ -132,9 +132,9 @@ export default function RequestLogsTab() {
|
|
|
132
132
|
<Row gutter={16} style={{marginBottom: 16}}>
|
|
133
133
|
<Col span={6}><Card><Statistic title="总请求数" value={stats.total || 0}/></Card></Col>
|
|
134
134
|
<Col span={6}><Card><Statistic title="Mock 命中" value={stats.matched || 0}
|
|
135
|
-
|
|
135
|
+
styles={{content: {color: '#52c41a'}}}/></Card></Col>
|
|
136
136
|
<Col span={6}><Card><Statistic title="未匹配" value={stats.unmatched || 0}
|
|
137
|
-
|
|
137
|
+
styles={{content: {color: '#ff4d4f'}}}/></Card></Col>
|
|
138
138
|
<Col span={6}><Card><Statistic title="命中率"
|
|
139
139
|
value={`${stats.total > 0 ? Math.round((stats.matched / stats.total) * 100) : 0}%`}/></Card></Col>
|
|
140
140
|
</Row>
|
|
@@ -156,7 +156,7 @@ export default function ScenariosTab() {
|
|
|
156
156
|
return (
|
|
157
157
|
<div>
|
|
158
158
|
<Alert type="info" showIcon style={{marginBottom: 16}}
|
|
159
|
-
|
|
159
|
+
title="场景状态机 (Scenario)"
|
|
160
160
|
description="用状态机驱动 Mock 集合,模拟完整业务流程(如:未登录→登录中→已登录→下单→已支付→完成)。实例通过 X-Session-Id 或 X-Trace-Id 区分,每个实例独立维护当前状态。"
|
|
161
161
|
/>
|
|
162
162
|
|
|
@@ -220,7 +220,7 @@ export default function TestCasesTab() {
|
|
|
220
220
|
return (
|
|
221
221
|
<div>
|
|
222
222
|
<Alert type="info" showIcon style={{marginBottom: 16}}
|
|
223
|
-
|
|
223
|
+
title="测试用例库"
|
|
224
224
|
description="对 Mock 接口进行断言验证。支持 7 种断言类型:STATUS / HEADER / BODY / JSON_PATH / REGEX / SCHEMA / RESPONSE_TIME。支持单条运行与批量运行,自动统计通过/失败次数。"
|
|
225
225
|
/>
|
|
226
226
|
|
|
@@ -357,7 +357,7 @@ export default function TestCasesTab() {
|
|
|
357
357
|
<Statistic
|
|
358
358
|
title="结果"
|
|
359
359
|
value={result.status}
|
|
360
|
-
|
|
360
|
+
styles={{content: {color: STATUS_COLORS[result.status] === 'green' ? '#52c41a' : '#ff4d4f'}}}
|
|
361
361
|
/>
|
|
362
362
|
</Card>
|
|
363
363
|
</Col>
|
|
@@ -425,9 +425,9 @@ export default function TestCasesTab() {
|
|
|
425
425
|
<Row gutter={16} style={{marginBottom: 16}}>
|
|
426
426
|
<Col span={6}><Card><Statistic title="总数" value={batchResult.total}/></Card></Col>
|
|
427
427
|
<Col span={6}><Card><Statistic title="通过" value={batchResult.pass}
|
|
428
|
-
|
|
428
|
+
styles={{content: {color: '#52c41a'}}}/></Card></Col>
|
|
429
429
|
<Col span={6}><Card><Statistic title="失败" value={batchResult.fail}
|
|
430
|
-
|
|
430
|
+
styles={{content: {color: '#ff4d4f'}}}/></Card></Col>
|
|
431
431
|
<Col span={6}><Card><Statistic title="通过率"
|
|
432
432
|
value={`${batchResult.total > 0 ? Math.round((batchResult.pass / batchResult.total) * 100) : 0}%`}/></Card></Col>
|
|
433
433
|
</Row>
|