@yuku123/z-team-component 0.2.26 → 0.2.29

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,4591 +0,0 @@
1
- import { jsx as e, jsxs as n, Fragment as Be } from "react/jsx-runtime";
2
- import { lazy as Ct, Suspense as Tt, useState as x, useRef as Ke, useEffect as W } from "react";
3
- import { useLocation as _t, useNavigate as be, useParams as ht, Routes as pt, Route as re, Navigate as mt, useSearchParams as At } from "react-router-dom";
4
- import { Button as A, Breadcrumb as zt, Space as z, Row as Q, Col as M, Typography as le, Alert as J, Card as P, Table as K, Drawer as ke, Descriptions as O, Tag as v, Tooltip as me, message as I, Modal as fe, Statistic as H, Input as B, Select as X, Tabs as ve, Form as R, Upload as Rt, Popconfirm as We, Spin as Oe, Radio as ne, InputNumber as $e, Empty as gt } from "antd";
5
- import { InboxOutlined as Et, ExclamationCircleOutlined as ft, ReloadOutlined as ee, SettingOutlined as Ot, ProjectOutlined as Pe, UserOutlined as yt, AuditOutlined as je, RobotOutlined as Fe, ApiOutlined as Ge, AppstoreOutlined as Pt, ThunderboltOutlined as Ie, BarChartOutlined as Mt, ScheduleOutlined as Lt, FileTextOutlined as Ve, ExperimentOutlined as $t, PlayCircleOutlined as Me, CopyOutlined as bt, GlobalOutlined as xt, NodeIndexOutlined as Nt, UndoOutlined as Dt, FileSearchOutlined as Bt, VideoCameraOutlined as Qe, SearchOutlined as wt, EyeOutlined as jt, CodeOutlined as Se, InfoCircleOutlined as Ft, FunctionOutlined as Te, ImportOutlined as qe, CloudUploadOutlined as et, FileAddOutlined as qt, PlusOutlined as St, EditOutlined as Ut, PauseCircleOutlined as Ht, CheckCircleOutlined as Je, DeleteOutlined as Kt, SaveOutlined as It, ArrowLeftOutlined as kt, SendOutlined as Wt } from "@ant-design/icons";
6
- import "@yuku123/z-frontend-common";
7
- import Xe from "axios";
8
- const Z = (t) => {
9
- const a = Ct(t);
10
- return (r) => /* @__PURE__ */ e(Tt, { fallback: null, children: /* @__PURE__ */ e(a, { ...r }) });
11
- }, ce = Z(() => import("./index-EPyR_fx0.js").then((t) => t.E)), Gt = Z(() => import("./index-Da7ls5q6.js")), Vt = Z(() => import("./index-bbwTcNjB.js")), Jt = Z(() => import("./index-CTD7k9dP.js")), Xt = Z(() => import("./index-Dao4uqQd.js")), Yt = Z(() => import("./index-D5u3BjCZ.js"));
12
- Z(() => import("./index-C01UUprh.js"));
13
- const Zt = Z(() => import("./index-CcFJEYgr.js")), Qt = Z(() => import("./index-UsGqMo11.js")), en = Z(() => import("./index-BkX0I2aB.js")), tn = Z(() => import("./index-CiMxCTOS.js")), nn = Z(() => import("./index-BafC42Cl.js")), rn = Z(() => import("./index-C2aPiQSz.js"));
14
- function lr({ forcedMode: t }) {
15
- const { pathname: a } = _t(), r = a.replace(/\/+$/, "") || "/";
16
- return t === "system" ? /* @__PURE__ */ e(ce, { forcedChatMode: "system" }) : t === "rpa" ? /* @__PURE__ */ e(ce, { forcedChatMode: "rpa" }) : t === "dev" ? /* @__PURE__ */ e(ce, { forcedChatMode: "dev" }) : r === "/workspace" ? /* @__PURE__ */ e(ce, {}) : r === "/workspace/phone" ? /* @__PURE__ */ e(Gt, {}) : r === "/workspace/from-ticket" ? /* @__PURE__ */ e(Vt, {}) : r === "/workspace/from-scenario" ? /* @__PURE__ */ e(Jt, {}) : r === "/workspace/build-by-form" ? /* @__PURE__ */ e(Xt, {}) : r === "/scenario" ? /* @__PURE__ */ e(Yt, {}) : r === "/admin" ? /* @__PURE__ */ e(ce, {}) : r === "/welcome" ? /* @__PURE__ */ e(Qt, {}) : r === "/portal" ? /* @__PURE__ */ e(en, {}) : r === "/chatdemo" ? /* @__PURE__ */ e(Zt, {}) : r === "/embed/chat" || r.startsWith("/embed/chat/") ? /* @__PURE__ */ e(rn, {}) : r === "/change-log" ? /* @__PURE__ */ e(tn, {}) : r === "/docs" ? /* @__PURE__ */ e(nn, {}) : /* @__PURE__ */ e(ce, {});
17
- }
18
- function ln(t) {
19
- if (!t || typeof t != "string") return null;
20
- const a = t.split(".");
21
- if (a.length !== 3) return null;
22
- try {
23
- let r = a[1].replace(/-/g, "+").replace(/_/g, "/");
24
- const f = r.length % 4;
25
- f && (r += "=".repeat(4 - f));
26
- const i = atob(r), u = Uint8Array.from(i, (g) => g.charCodeAt(0)), l = new TextDecoder().decode(u), h = JSON.parse(l);
27
- return h && typeof h == "object" && !Array.isArray(h) ? h : null;
28
- } catch {
29
- return null;
30
- }
31
- }
32
- function an(t, a = 30) {
33
- const r = ln(t);
34
- return !r || typeof r.exp != "number" ? !0 : Date.now() / 1e3 > r.exp - a;
35
- }
36
- let tt = !1;
37
- const on = [
38
- "/ctc/authn/login",
39
- "/ctc/authn/register",
40
- "/ctc/authn/send-code",
41
- "/ctc/authn/register-phone",
42
- "/ctc/authn/reset-password",
43
- "/ctc/authn/phone-login",
44
- "/ctc/authn/verify",
45
- "/ctc/ac/login",
46
- "/auth/login",
47
- "/auth/register",
48
- "/auth/reset-password",
49
- "/uc/login",
50
- "/uc/register",
51
- "/uc/phone-login",
52
- "/sso/login",
53
- "/sso/callback"
54
- ];
55
- function sn(t) {
56
- return on.some((a) => t.includes(a));
57
- }
58
- function nt(t) {
59
- if (tt || typeof window > "u" || window.location.pathname.startsWith("/login")) return;
60
- tt = !0;
61
- try {
62
- localStorage.removeItem("token"), localStorage.removeItem("userInfo");
63
- } catch {
64
- }
65
- console.warn(`[Auth] ${t}, 跳转到 /login`);
66
- const a = window.location.pathname + window.location.search, r = encodeURIComponent(a);
67
- window.location.href = `/login?redirect=${r}`;
68
- }
69
- function cn(t) {
70
- if (t && typeof t == "object" && "code" in t && "data" in t) {
71
- const a = t;
72
- return (typeof a.success == "boolean" ? a.success : typeof a.code == "number" && a.code >= 200 && a.code < 300) ? a.data : Promise.reject(new Error(a.message || "请求失败"));
73
- }
74
- return t;
75
- }
76
- function dn(t, a = {}) {
77
- const { tokenKey: r = "token", userInfoKey: f = "userInfo" } = a;
78
- t.interceptors.request.use((i) => {
79
- const u = localStorage.getItem(r);
80
- if (u && an(u))
81
- return nt(`请求前检测到 token 已过期 (${i.url || ""})`), Promise.reject(new Xe.CanceledError("token expired"));
82
- try {
83
- const l = localStorage.getItem(f);
84
- if (l) {
85
- const h = JSON.parse(l), g = h.tenantCode || "default", w = h.domainCode || "default", _ = h.id ?? h.userId, y = (i.method || "get").toLowerCase();
86
- if (typeof i.url == "string" && i.url.includes("/ctc/ac/") && (i.params = { ...i.params || {} }, i.params.tenantCode || (i.params.tenantCode = g), i.params.domainCode || (i.params.domainCode = w)), _ != null && (i.headers["X-User-Id"] = String(_)), y !== "get" && y !== "delete" && i.data && typeof i.data == "object") {
87
- const m = i.data;
88
- m.tenantCode == null && (m.tenantCode = g), m.domainCode == null && (m.domainCode = w);
89
- }
90
- }
91
- } catch {
92
- }
93
- return i;
94
- }), t.interceptors.response.use(
95
- (i) => cn(i.data),
96
- (i) => {
97
- var h, g;
98
- const u = (h = i.response) == null ? void 0 : h.status, l = ((g = i.config) == null ? void 0 : g.url) || "";
99
- return u === 401 ? sn(l) ? console.warn(`[401] 公开接口返回 401 (不是 token 问题): ${l}`) : nt(`接口 ${l} 返回 401`) : u === 403 ? console.warn("[403] 没有权限访问该资源:", l) : u === 404 ? console.warn("[404] 接口不存在:", l) : u === 500 && console.error("[500] 服务器内部错误:", l), Promise.reject(i);
100
- }
101
- );
102
- }
103
- function Ye(t = {}) {
104
- const a = Xe.create({
105
- baseURL: t.baseURL ?? "/api",
106
- timeout: t.timeout ?? 1e4,
107
- withCredentials: !0
108
- // Cookie 模式:浏览器自动携带 Cookie
109
- });
110
- return dn(a, {
111
- tokenKey: t.tokenKey,
112
- userInfoKey: t.userInfoKey
113
- }), a;
114
- }
115
- const N = Ye(), ar = Ye(), ie = {
116
- pink: {
117
- bg: "#ec4899",
118
- fg: "#ffffff",
119
- soft: "#fce7f3",
120
- gradient: "linear-gradient(135deg, #ec4899 0%, #be185d 100%)"
121
- },
122
- blue: {
123
- bg: "#3b82f6",
124
- fg: "#ffffff",
125
- soft: "#dbeafe",
126
- gradient: "linear-gradient(135deg, #3b82f6 0%, #1e40af 100%)"
127
- },
128
- green: {
129
- bg: "#10b981",
130
- fg: "#ffffff",
131
- soft: "#d1fae5",
132
- gradient: "linear-gradient(135deg, #10b981 0%, #047857 100%)"
133
- },
134
- orange: {
135
- bg: "#f97316",
136
- fg: "#ffffff",
137
- soft: "#ffedd5",
138
- gradient: "linear-gradient(135deg, #f97316 0%, #c2410c 100%)"
139
- },
140
- violet: {
141
- bg: "#8b5cf6",
142
- fg: "#ffffff",
143
- soft: "#ede9fe",
144
- gradient: "linear-gradient(135deg, #8b5cf6 0%, #6d28d9 100%)"
145
- },
146
- cyan: {
147
- bg: "#06b6d4",
148
- fg: "#ffffff",
149
- soft: "#cffafe",
150
- gradient: "linear-gradient(135deg, #06b6d4 0%, #0e7490 100%)"
151
- },
152
- red: {
153
- bg: "#ef4444",
154
- fg: "#ffffff",
155
- soft: "#fee2e2",
156
- gradient: "linear-gradient(135deg, #ef4444 0%, #b91c1c 100%)"
157
- },
158
- yellow: {
159
- bg: "#eab308",
160
- fg: "#1f2937",
161
- soft: "#fef3c7",
162
- gradient: "linear-gradient(135deg, #eab308 0%, #a16207 100%)"
163
- }
164
- }, Ee = {
165
- surfaceAlt: "#fafbfc",
166
- // 次级表面 (表格 hover 等)
167
- border: "#e5e7eb",
168
- // 默认边框 (比 antd 默认淡, 更现代)
169
- text: "#111827",
170
- // 主文本
171
- textMuted: "#6b7280"
172
- }, ye = {
173
- sm: 8,
174
- md: 12,
175
- lg: 16
176
- }, ge = {
177
- sm: "0 1px 2px 0 rgba(15, 23, 42, 0.04), 0 1px 3px 0 rgba(15, 23, 42, 0.06)",
178
- md: "0 2px 4px -1px rgba(15, 23, 42, 0.04), 0 4px 8px -1px rgba(15, 23, 42, 0.08)",
179
- lg: "0 4px 6px -2px rgba(15, 23, 42, 0.05), 0 12px 16px -4px rgba(15, 23, 42, 0.10)"
180
- }, se = {
181
- 2: 8,
182
- 3: 12,
183
- 4: 16,
184
- 5: 20
185
- };
186
- function _e({
187
- icon: t,
188
- label: a,
189
- value: r,
190
- suffix: f,
191
- color: i = "blue",
192
- trend: u,
193
- href: l,
194
- loading: h = !1,
195
- precision: g = 0
196
- }) {
197
- const w = ie[i] || ie.blue, [_, y] = x(0), m = Ke(0);
198
- W(() => {
199
- if (h || r == null) return;
200
- const S = m.current, p = Number(r) || 0;
201
- if (S === p) {
202
- y(p);
203
- return;
204
- }
205
- const o = 600, C = performance.now();
206
- let L;
207
- const G = (U) => {
208
- const b = Math.min(1, (U - C) / o), d = 1 - Math.pow(1 - b, 3), E = S + (p - S) * d;
209
- y(E), b < 1 ? L = requestAnimationFrame(G) : m.current = p;
210
- };
211
- return L = requestAnimationFrame(G), () => L && cancelAnimationFrame(L);
212
- }, [r, h]);
213
- const s = () => {
214
- l && typeof window < "u" && (window.location.href = l);
215
- }, c = h ? "--" : Number(_).toLocaleString("zh-CN", {
216
- minimumFractionDigits: g,
217
- maximumFractionDigits: g
218
- }), k = u != null ? Number(u) : null, $ = k != null && k >= 0;
219
- return /* @__PURE__ */ n(
220
- "div",
221
- {
222
- onClick: s,
223
- style: {
224
- position: "relative",
225
- background: w.gradient,
226
- borderRadius: ye.lg,
227
- padding: se[5],
228
- color: w.fg,
229
- cursor: l ? "pointer" : "default",
230
- boxShadow: ge.md,
231
- overflow: "hidden",
232
- transition: "transform 200ms ease, box-shadow 200ms ease",
233
- minHeight: 110,
234
- display: "flex",
235
- flexDirection: "column",
236
- justifyContent: "space-between"
237
- },
238
- onMouseEnter: (S) => {
239
- S.currentTarget.style.transform = "translateY(-2px)", S.currentTarget.style.boxShadow = ge.lg;
240
- },
241
- onMouseLeave: (S) => {
242
- S.currentTarget.style.transform = "translateY(0)", S.currentTarget.style.boxShadow = ge.md;
243
- },
244
- children: [
245
- /* @__PURE__ */ e(
246
- "div",
247
- {
248
- style: {
249
- position: "absolute",
250
- top: -32,
251
- right: -32,
252
- width: 96,
253
- height: 96,
254
- borderRadius: "50%",
255
- background: "rgba(255, 255, 255, 0.15)",
256
- pointerEvents: "none"
257
- }
258
- }
259
- ),
260
- /* @__PURE__ */ n("div", { style: {
261
- display: "flex",
262
- alignItems: "center",
263
- gap: se[2],
264
- position: "relative"
265
- }, children: [
266
- /* @__PURE__ */ e("div", { style: {
267
- width: 36,
268
- height: 36,
269
- borderRadius: ye.sm,
270
- background: "rgba(255, 255, 255, 0.20)",
271
- backdropFilter: "blur(8px)",
272
- display: "flex",
273
- alignItems: "center",
274
- justifyContent: "center",
275
- fontSize: 18
276
- }, children: t }),
277
- /* @__PURE__ */ e("div", { style: {
278
- fontSize: 13,
279
- fontWeight: 500,
280
- opacity: 0.92
281
- }, children: a })
282
- ] }),
283
- /* @__PURE__ */ n("div", { style: {
284
- display: "flex",
285
- alignItems: "baseline",
286
- gap: se[2],
287
- position: "relative",
288
- marginTop: se[3]
289
- }, children: [
290
- /* @__PURE__ */ e("div", { style: {
291
- fontSize: 30,
292
- fontWeight: 700,
293
- lineHeight: 1.1,
294
- letterSpacing: "-0.02em",
295
- fontVariantNumeric: "tabular-nums"
296
- }, children: c }),
297
- f && /* @__PURE__ */ e("div", { style: { fontSize: 14, opacity: 0.85, fontWeight: 500 }, children: f }),
298
- k != null && /* @__PURE__ */ n("div", { style: {
299
- marginLeft: "auto",
300
- fontSize: 12,
301
- fontWeight: 600,
302
- padding: "2px 8px",
303
- borderRadius: 999,
304
- background: $ ? "rgba(255, 255, 255, 0.22)" : "rgba(0, 0, 0, 0.18)",
305
- display: "flex",
306
- alignItems: "center",
307
- gap: 2
308
- }, children: [
309
- /* @__PURE__ */ e("span", { style: { fontSize: 10 }, children: $ ? "▲" : "▼" }),
310
- Math.abs(k).toFixed(1),
311
- "%"
312
- ] })
313
- ] })
314
- ]
315
- }
316
- );
317
- }
318
- function un({ color: t = "blue", label: a, size: r = 8 }) {
319
- const f = ie[t] || ie.blue;
320
- return /* @__PURE__ */ n("span", { style: {
321
- display: "inline-flex",
322
- alignItems: "center",
323
- gap: 8,
324
- fontSize: 14,
325
- fontWeight: 600,
326
- color: "#111827"
327
- }, children: [
328
- /* @__PURE__ */ e("span", { style: {
329
- width: r,
330
- height: r,
331
- borderRadius: "50%",
332
- background: f.bg,
333
- boxShadow: `0 0 0 3px ${f.soft}`,
334
- flexShrink: 0
335
- } }),
336
- a && /* @__PURE__ */ e("span", { children: a })
337
- ] });
338
- }
339
- function hn({
340
- color: t = "blue",
341
- title: a,
342
- subtitle: r,
343
- moreText: f = "全部",
344
- moreHref: i,
345
- onMore: u
346
- }) {
347
- return /* @__PURE__ */ n("div", { style: {
348
- display: "flex",
349
- alignItems: "center",
350
- justifyContent: "space-between",
351
- marginBottom: 16
352
- }, children: [
353
- /* @__PURE__ */ n("div", { style: { display: "flex", alignItems: "baseline", gap: 12 }, children: [
354
- /* @__PURE__ */ e(un, { color: t, label: a, size: 10 }),
355
- r && /* @__PURE__ */ e("span", { style: {
356
- fontSize: 13,
357
- color: "#6b7280",
358
- fontWeight: 400
359
- }, children: r })
360
- ] }),
361
- (i || u) && /* @__PURE__ */ n(
362
- "a",
363
- {
364
- href: i,
365
- onClick: (l) => {
366
- u && (l.preventDefault(), u());
367
- },
368
- style: {
369
- fontSize: 13,
370
- color: "#6b7280",
371
- textDecoration: "none",
372
- display: "inline-flex",
373
- alignItems: "center",
374
- gap: 4,
375
- cursor: "pointer",
376
- transition: "color 150ms ease"
377
- },
378
- onMouseEnter: (l) => {
379
- l.currentTarget.style.color = "#7c3aed";
380
- },
381
- onMouseLeave: (l) => {
382
- l.currentTarget.style.color = "#6b7280";
383
- },
384
- children: [
385
- f,
386
- /* @__PURE__ */ e("span", { style: { fontSize: 12 }, children: "›" })
387
- ]
388
- }
389
- )
390
- ] });
391
- }
392
- function pn({
393
- title: t,
394
- description: a,
395
- icon: r,
396
- cover: f,
397
- color: i = "violet",
398
- tags: u = [],
399
- meta: l,
400
- href: h,
401
- extra: g
402
- }) {
403
- const w = ie[i] || ie.violet, [_, y] = x(!1);
404
- return /* @__PURE__ */ n(
405
- "div",
406
- {
407
- onClick: () => {
408
- h && typeof window < "u" && (window.location.href = h);
409
- },
410
- onMouseEnter: () => y(!0),
411
- onMouseLeave: () => y(!1),
412
- style: {
413
- background: "#ffffff",
414
- borderRadius: ye.lg,
415
- overflow: "hidden",
416
- cursor: h ? "pointer" : "default",
417
- boxShadow: _ ? ge.lg : ge.sm,
418
- transform: _ ? "translateY(-2px)" : "translateY(0)",
419
- transition: "transform 200ms ease, box-shadow 200ms ease",
420
- border: "1px solid #f1f5f9",
421
- display: "flex",
422
- flexDirection: "column"
423
- },
424
- children: [
425
- /* @__PURE__ */ n("div", { style: {
426
- position: "relative",
427
- aspectRatio: "16 / 9",
428
- background: f ? "#f1f5f9" : w.gradient,
429
- display: "flex",
430
- alignItems: "center",
431
- justifyContent: "center",
432
- overflow: "hidden"
433
- }, children: [
434
- f ? /* @__PURE__ */ e(
435
- "img",
436
- {
437
- src: f,
438
- alt: t,
439
- style: {
440
- width: "100%",
441
- height: "100%",
442
- objectFit: "cover"
443
- }
444
- }
445
- ) : /* @__PURE__ */ e("div", { style: {
446
- fontSize: 48,
447
- color: "rgba(255, 255, 255, 0.9)",
448
- display: "flex"
449
- }, children: r }),
450
- !f && /* @__PURE__ */ e("div", { style: {
451
- position: "absolute",
452
- top: -24,
453
- right: -24,
454
- width: 80,
455
- height: 80,
456
- borderRadius: "50%",
457
- background: "rgba(255, 255, 255, 0.15)"
458
- } }),
459
- g && /* @__PURE__ */ e("div", { style: {
460
- position: "absolute",
461
- top: 8,
462
- right: 8
463
- }, children: g })
464
- ] }),
465
- /* @__PURE__ */ n("div", { style: {
466
- padding: se[4],
467
- display: "flex",
468
- flexDirection: "column",
469
- gap: se[2],
470
- flex: 1
471
- }, children: [
472
- u.length > 0 && /* @__PURE__ */ e("div", { style: {
473
- display: "flex",
474
- flexWrap: "wrap",
475
- gap: 6
476
- }, children: u.slice(0, 3).map((s, c) => {
477
- const k = ie[s.color] || ie.blue;
478
- return /* @__PURE__ */ e(
479
- "span",
480
- {
481
- style: {
482
- fontSize: 11,
483
- fontWeight: 500,
484
- padding: "2px 8px",
485
- borderRadius: 999,
486
- background: k.soft,
487
- color: k.bg
488
- },
489
- children: s.label
490
- },
491
- c
492
- );
493
- }) }),
494
- /* @__PURE__ */ e("div", { style: {
495
- fontSize: 15,
496
- fontWeight: 600,
497
- color: "#111827",
498
- lineHeight: 1.3,
499
- overflow: "hidden",
500
- textOverflow: "ellipsis",
501
- display: "-webkit-box",
502
- WebkitLineClamp: 1,
503
- WebkitBoxOrient: "vertical"
504
- }, children: t }),
505
- a && /* @__PURE__ */ e("div", { style: {
506
- fontSize: 12,
507
- color: "#6b7280",
508
- lineHeight: 1.5,
509
- overflow: "hidden",
510
- textOverflow: "ellipsis",
511
- display: "-webkit-box",
512
- WebkitLineClamp: 2,
513
- WebkitBoxOrient: "vertical",
514
- minHeight: 36
515
- }, children: a }),
516
- l && /* @__PURE__ */ e("div", { style: {
517
- fontSize: 11,
518
- color: "#9ca3af",
519
- marginTop: "auto",
520
- paddingTop: se[2],
521
- borderTop: "1px dashed #f1f5f9"
522
- }, children: l })
523
- ] })
524
- ]
525
- }
526
- );
527
- }
528
- function mn({
529
- tag: t,
530
- title: a,
531
- description: r,
532
- buttonText: f,
533
- buttonHref: i,
534
- onButtonClick: u
535
- }) {
536
- return /* @__PURE__ */ n("div", { style: {
537
- position: "relative",
538
- borderRadius: ye.lg,
539
- padding: "40px 48px",
540
- background: "linear-gradient(135deg, #0f172a 0%, #1e293b 50%, #312e81 100%)",
541
- color: "#ffffff",
542
- overflow: "hidden",
543
- boxShadow: ge.lg
544
- }, children: [
545
- /* @__PURE__ */ e("div", { style: {
546
- position: "absolute",
547
- top: -64,
548
- right: -64,
549
- width: 200,
550
- height: 200,
551
- borderRadius: "50%",
552
- background: "radial-gradient(circle, rgba(139, 92, 246, 0.4) 0%, transparent 70%)",
553
- pointerEvents: "none"
554
- } }),
555
- /* @__PURE__ */ e("div", { style: {
556
- position: "absolute",
557
- bottom: -48,
558
- left: "30%",
559
- width: 160,
560
- height: 160,
561
- borderRadius: "50%",
562
- background: "radial-gradient(circle, rgba(59, 130, 246, 0.3) 0%, transparent 70%)",
563
- pointerEvents: "none"
564
- } }),
565
- /* @__PURE__ */ n("div", { style: {
566
- position: "relative",
567
- display: "flex",
568
- alignItems: "center",
569
- justifyContent: "space-between",
570
- gap: 32,
571
- flexWrap: "wrap"
572
- }, children: [
573
- /* @__PURE__ */ n("div", { style: { flex: 1, minWidth: 240 }, children: [
574
- t && /* @__PURE__ */ e("div", { style: {
575
- fontSize: 11,
576
- fontWeight: 600,
577
- letterSpacing: "0.12em",
578
- color: "#a5b4fc",
579
- textTransform: "uppercase",
580
- marginBottom: 12
581
- }, children: t }),
582
- /* @__PURE__ */ e("div", { style: {
583
- fontSize: 24,
584
- fontWeight: 700,
585
- lineHeight: 1.3,
586
- marginBottom: 8
587
- }, children: a }),
588
- r && /* @__PURE__ */ e("div", { style: {
589
- fontSize: 14,
590
- color: "rgba(255, 255, 255, 0.7)",
591
- lineHeight: 1.6,
592
- maxWidth: 540
593
- }, children: r })
594
- ] }),
595
- f && (i || u) && /* @__PURE__ */ n(
596
- "a",
597
- {
598
- href: i || "#",
599
- onClick: (l) => {
600
- u && (l.preventDefault(), u());
601
- },
602
- style: {
603
- display: "inline-flex",
604
- alignItems: "center",
605
- gap: 8,
606
- padding: "12px 24px",
607
- background: "linear-gradient(135deg, #10b981 0%, #059669 100%)",
608
- color: "#ffffff",
609
- borderRadius: 999,
610
- fontSize: 14,
611
- fontWeight: 600,
612
- textDecoration: "none",
613
- boxShadow: "0 4px 12px rgba(16, 185, 129, 0.4)",
614
- transition: "transform 150ms ease, box-shadow 150ms ease",
615
- whiteSpace: "nowrap"
616
- },
617
- onMouseEnter: (l) => {
618
- l.currentTarget.style.transform = "translateY(-1px)", l.currentTarget.style.boxShadow = "0 6px 16px rgba(16, 185, 129, 0.5)";
619
- },
620
- onMouseLeave: (l) => {
621
- l.currentTarget.style.transform = "translateY(0)", l.currentTarget.style.boxShadow = "0 4px 12px rgba(16, 185, 129, 0.4)";
622
- },
623
- children: [
624
- f,
625
- /* @__PURE__ */ e("span", { children: "→" })
626
- ]
627
- }
628
- )
629
- ] })
630
- ] });
631
- }
632
- function gn({
633
- icon: t,
634
- title: a = "暂无数据",
635
- description: r,
636
- actionText: f,
637
- onAction: i,
638
- size: u = "md",
639
- style: l
640
- }) {
641
- const h = { sm: 24, md: 40, lg: 64 }, g = { sm: 14, md: 16, lg: 20 };
642
- return /* @__PURE__ */ n(
643
- "div",
644
- {
645
- role: "status",
646
- "aria-live": "polite",
647
- style: {
648
- padding: h[u] || h.md,
649
- textAlign: "center",
650
- background: "#ffffff",
651
- borderRadius: ye.md,
652
- border: "1px dashed #e5e7eb",
653
- ...l
654
- },
655
- children: [
656
- /* @__PURE__ */ e("div", { style: {
657
- display: "inline-flex",
658
- alignItems: "center",
659
- justifyContent: "center",
660
- width: 56,
661
- height: 56,
662
- borderRadius: "50%",
663
- background: Ee.surfaceAlt,
664
- marginBottom: 16,
665
- fontSize: 28,
666
- color: "#9ca3af"
667
- }, children: t || /* @__PURE__ */ e(Et, {}) }),
668
- /* @__PURE__ */ e("div", { style: {
669
- fontSize: g[u],
670
- fontWeight: 600,
671
- color: Ee.text,
672
- marginBottom: r ? 6 : 16
673
- }, children: a }),
674
- r && /* @__PURE__ */ e("div", { style: {
675
- fontSize: 13,
676
- color: Ee.textMuted,
677
- lineHeight: 1.6,
678
- maxWidth: 360,
679
- margin: "0 auto 16px"
680
- }, children: r }),
681
- f && i && /* @__PURE__ */ e(
682
- A,
683
- {
684
- type: "primary",
685
- onClick: i,
686
- style: {
687
- background: "linear-gradient(135deg, #7c3aed 0%, #6d28d9 100%)",
688
- border: "none",
689
- minHeight: 36
690
- },
691
- children: f
692
- }
693
- )
694
- ]
695
- }
696
- );
697
- }
698
- function fn({
699
- error: t,
700
- title: a = "加载失败",
701
- description: r,
702
- onRetry: f,
703
- retryText: i = "重新加载",
704
- variant: u = "inline",
705
- style: l
706
- }) {
707
- var m;
708
- const h = u === "full", g = (m = t == null ? void 0 : t.response) == null ? void 0 : m.data, w = g && typeof g == "object" && (typeof g.message == "string" && g.message || typeof g.msg == "string" && g.msg) || null, _ = w || (typeof t == "string" ? t : (t == null ? void 0 : t.message) || (t == null ? void 0 : t.msg) || (t ? String(t) : null)), y = r || (w ? `原因: ${w}` : _ ? `原因: ${_}。请检查网络或稍后重试。` : "请检查网络或稍后重试。");
709
- return /* @__PURE__ */ n(
710
- "div",
711
- {
712
- role: "alert",
713
- "aria-live": "assertive",
714
- style: {
715
- padding: h ? "48px 24px" : "20px 24px",
716
- background: h ? "#ffffff" : "#fef2f2",
717
- border: h ? `1px dashed ${Ee.border}` : "1px solid #fecaca",
718
- borderRadius: ye.md,
719
- textAlign: h ? "center" : "left",
720
- display: "flex",
721
- flexDirection: h ? "column" : "row",
722
- alignItems: h ? "center" : "flex-start",
723
- gap: h ? 12 : 16,
724
- ...l
725
- },
726
- children: [
727
- /* @__PURE__ */ e("div", { style: {
728
- display: "inline-flex",
729
- alignItems: "center",
730
- justifyContent: "center",
731
- width: h ? 56 : 36,
732
- height: h ? 56 : 36,
733
- borderRadius: "50%",
734
- background: h ? "#fef2f2" : "#ffffff",
735
- color: "#dc2626",
736
- fontSize: h ? 28 : 18,
737
- flexShrink: 0
738
- }, children: /* @__PURE__ */ e(ft, {}) }),
739
- /* @__PURE__ */ n("div", { style: { flex: 1, minWidth: 0 }, children: [
740
- /* @__PURE__ */ e("div", { style: {
741
- fontSize: h ? 16 : 14,
742
- fontWeight: 600,
743
- color: "#991b1b",
744
- marginBottom: 4
745
- }, children: a }),
746
- /* @__PURE__ */ e("div", { style: {
747
- fontSize: 13,
748
- color: "#7f1d1d",
749
- lineHeight: 1.6,
750
- wordBreak: "break-word"
751
- }, children: y }),
752
- f && /* @__PURE__ */ e(
753
- A,
754
- {
755
- type: "primary",
756
- danger: !0,
757
- icon: /* @__PURE__ */ e(ee, {}),
758
- onClick: f,
759
- size: h ? "middle" : "small",
760
- style: { marginTop: 12 },
761
- children: i
762
- }
763
- )
764
- ] })
765
- ]
766
- }
767
- );
768
- }
769
- function xe({
770
- title: t,
771
- subtitle: a,
772
- breadcrumb: r,
773
- extra: f,
774
- back: i,
775
- onBack: u
776
- }) {
777
- const l = be();
778
- return /* @__PURE__ */ e("div", { style: {
779
- marginBottom: 12,
780
- paddingBottom: 10,
781
- borderBottom: "1px solid #f1f5f9"
782
- }, children: /* @__PURE__ */ n("div", { style: {
783
- display: "flex",
784
- alignItems: "center",
785
- justifyContent: "space-between",
786
- gap: 12,
787
- flexWrap: "wrap"
788
- }, children: [
789
- /* @__PURE__ */ n("div", { style: {
790
- display: "flex",
791
- alignItems: "center",
792
- gap: 10,
793
- minWidth: 0,
794
- flexWrap: "wrap"
795
- }, children: [
796
- i && /* @__PURE__ */ e(
797
- "button",
798
- {
799
- onClick: () => {
800
- u ? u() : l(-1);
801
- },
802
- "aria-label": "返回上一页",
803
- style: {
804
- width: 28,
805
- height: 28,
806
- borderRadius: 6,
807
- border: "1px solid #e5e7eb",
808
- background: "#ffffff",
809
- color: "#6b7280",
810
- cursor: "pointer",
811
- display: "inline-flex",
812
- alignItems: "center",
813
- justifyContent: "center",
814
- fontSize: 13,
815
- transition: "all 150ms ease",
816
- flexShrink: 0
817
- },
818
- onMouseEnter: (g) => {
819
- g.currentTarget.style.background = "#f8fafc", g.currentTarget.style.color = "#111827", g.currentTarget.style.borderColor = "#7c3aed";
820
- },
821
- onMouseLeave: (g) => {
822
- g.currentTarget.style.background = "#ffffff", g.currentTarget.style.color = "#6b7280", g.currentTarget.style.borderColor = "#e5e7eb";
823
- },
824
- children: "←"
825
- }
826
- ),
827
- r && r.length > 0 ? /* @__PURE__ */ e(
828
- zt,
829
- {
830
- items: r.map((g, w) => {
831
- const _ = w === r.length - 1;
832
- return {
833
- title: g.href && !_ ? /* @__PURE__ */ e("a", { onClick: (y) => {
834
- y.preventDefault(), l(g.href);
835
- }, children: g.label }) : /* @__PURE__ */ e("span", { style: _ ? {
836
- fontWeight: 600,
837
- color: "#111827"
838
- } : void 0, children: g.label })
839
- };
840
- })
841
- }
842
- ) : t && /* @__PURE__ */ e("span", { role: "heading", "aria-level": 1, style: {
843
- fontSize: 15,
844
- fontWeight: 600,
845
- color: "#111827",
846
- lineHeight: 1.4
847
- }, children: t }),
848
- a && /* @__PURE__ */ e("span", { title: a, style: {
849
- fontSize: 12,
850
- color: "#94a3b8",
851
- lineHeight: 1.4,
852
- whiteSpace: "nowrap",
853
- overflow: "hidden",
854
- textOverflow: "ellipsis",
855
- maxWidth: 360
856
- }, children: a })
857
- ] }),
858
- f && /* @__PURE__ */ e("div", { style: {
859
- display: "flex",
860
- gap: 8,
861
- flexShrink: 0
862
- }, children: f })
863
- ] }) });
864
- }
865
- function yn({ left: t, right: a, extra: r }) {
866
- return /* @__PURE__ */ n(
867
- "div",
868
- {
869
- style: {
870
- display: "flex",
871
- alignItems: "center",
872
- justifyContent: "space-between",
873
- gap: 12,
874
- marginBottom: 12,
875
- flexWrap: "wrap"
876
- },
877
- children: [
878
- /* @__PURE__ */ e(z, { size: 8, wrap: !0, children: t }),
879
- /* @__PURE__ */ n(z, { size: 8, wrap: !0, children: [
880
- a,
881
- r
882
- ] })
883
- ]
884
- }
885
- );
886
- }
887
- const Ae = Ye({ baseURL: "/api", timeout: 1e4 }), ze = (t) => t ? typeof t.total == "number" ? t.total : Array.isArray(t) ? t.length : Array.isArray(t.records) ? t.records.length : Array.isArray(t.data) ? t.data.length : 0 : 0, bn = [
888
- {
889
- key: "ai",
890
- color: "violet",
891
- title: "智能中心",
892
- subtitle: "Agent · 模型 · MCP · 技能",
893
- icon: /* @__PURE__ */ e(Fe, {}),
894
- href: "/ai/agent/app",
895
- items: [
896
- {
897
- title: "Agent 应用",
898
- description: "创建和管理 AI Agent 应用, 支持多种 LLM 模型",
899
- icon: /* @__PURE__ */ e(Fe, {}),
900
- color: "violet",
901
- tags: [{ label: "AI", color: "violet" }, { label: "推荐", color: "orange" }],
902
- meta: "12 个应用"
903
- },
904
- {
905
- title: "多 Agent 实例",
906
- description: "多 Agent 协同执行, 支持 ZBOT / Hermes / Claude Code / OpenCode",
907
- icon: /* @__PURE__ */ e(Ge, {}),
908
- color: "blue",
909
- tags: [{ label: "AI", color: "blue" }],
910
- meta: "5 种引擎"
911
- },
912
- {
913
- title: "模板市场",
914
- description: "精选 AI 应用模板, 一键复制即可使用",
915
- icon: /* @__PURE__ */ e(Pt, {}),
916
- color: "pink",
917
- tags: [{ label: "模板", color: "pink" }],
918
- meta: "24 个模板"
919
- },
920
- {
921
- title: "技能市场",
922
- description: "为 Agent 装配技能, 拓展能力边界",
923
- icon: /* @__PURE__ */ e(Ie, {}),
924
- color: "orange",
925
- tags: [{ label: "扩展", color: "orange" }]
926
- }
927
- ]
928
- },
929
- // 运维中心已迁出独立平台 z-ops (2026-09-24, github.com/z-opc-foundation/z-ops)
930
- {
931
- key: "task",
932
- color: "green",
933
- title: "任务中心",
934
- subtitle: "仪表盘 · 任务 · 项目",
935
- icon: /* @__PURE__ */ e(Pe, {}),
936
- href: "/task/dashboard",
937
- items: [
938
- {
939
- title: "任务仪表盘",
940
- description: "实时任务执行情况, 成功率与时长统计",
941
- icon: /* @__PURE__ */ e(Mt, {}),
942
- color: "green",
943
- tags: [{ label: "看板", color: "green" }]
944
- },
945
- {
946
- title: "任务列表",
947
- description: "所有定时/手动任务, 支持 Cron 表达式",
948
- icon: /* @__PURE__ */ e(Lt, {}),
949
- color: "blue",
950
- tags: [{ label: "调度", color: "blue" }]
951
- },
952
- {
953
- title: "项目管理",
954
- description: "项目维度组织任务, 支持里程碑",
955
- icon: /* @__PURE__ */ e(Pe, {}),
956
- color: "violet",
957
- tags: [{ label: "项目", color: "violet" }]
958
- }
959
- ]
960
- },
961
- {
962
- key: "workflow",
963
- color: "orange",
964
- title: "流程中心",
965
- subtitle: "审批 · 待办 · 我的",
966
- icon: /* @__PURE__ */ e(je, {}),
967
- href: "/workflow/dashboard",
968
- items: [
969
- {
970
- title: "流程仪表盘",
971
- description: "流程实例统计与效率分析",
972
- icon: /* @__PURE__ */ e(je, {}),
973
- color: "orange",
974
- tags: [{ label: "审批", color: "orange" }]
975
- },
976
- {
977
- title: "待办任务",
978
- description: "我的待审批任务, 实时推送",
979
- icon: /* @__PURE__ */ e(Ve, {}),
980
- color: "red",
981
- tags: [{ label: "待办", color: "red" }]
982
- }
983
- ]
984
- }
985
- ], ir = () => {
986
- const [t, a] = x({
987
- configCount: null,
988
- projectCount: null,
989
- userCount: null,
990
- roleCount: null
991
- });
992
- return W(() => {
993
- let r = !0;
994
- const f = [
995
- Ae.get("/config/list", { params: { pageSize: 1 } }).then((i) => ze(i)).then((i) => r && a((u) => ({ ...u, configCount: i }))).catch(() => r && a((i) => ({ ...i, configCount: 0 }))),
996
- Ae.get("/project/user/list").then((i) => ze(i)).then((i) => r && a((u) => ({ ...u, projectCount: i }))).catch(() => r && a((i) => ({ ...i, projectCount: 0 }))),
997
- Ae.get("/ctc/ac/accounts", { params: { pageSize: 1 } }).then((i) => ze(i)).then((i) => r && a((u) => ({ ...u, userCount: i }))).catch(() => r && a((i) => ({ ...i, userCount: 0 }))),
998
- Ae.get("/ctc/authz/roles/list").then((i) => ze(i)).then((i) => r && a((u) => ({ ...u, roleCount: i }))).catch(() => r && a((i) => ({ ...i, roleCount: 0 })))
999
- ];
1000
- return () => {
1001
- r = !1, f.forEach((i) => {
1002
- var u;
1003
- return (u = i == null ? void 0 : i.catch) == null ? void 0 : u.call(i, () => {
1004
- });
1005
- });
1006
- };
1007
- }, []), /* @__PURE__ */ n("div", { children: [
1008
- /* @__PURE__ */ e(
1009
- xe,
1010
- {
1011
- title: "统一管理平台",
1012
- subtitle: "一站式企业级应用管理平台 · 整合配置 / 任务 / 工作流 / 用户 / 调度 等核心模块",
1013
- breadcrumb: [{ label: "首页" }]
1014
- }
1015
- ),
1016
- /* @__PURE__ */ n(Q, { gutter: [16, 16], children: [
1017
- /* @__PURE__ */ e(M, { xs: 24, sm: 12, md: 12, lg: 6, children: /* @__PURE__ */ e(
1018
- _e,
1019
- {
1020
- icon: /* @__PURE__ */ e(Ot, {}),
1021
- label: "配置中心",
1022
- value: t.configCount,
1023
- suffix: "条",
1024
- color: "violet",
1025
- trend: 12.5,
1026
- href: "/config/list"
1027
- }
1028
- ) }),
1029
- /* @__PURE__ */ e(M, { xs: 24, sm: 12, md: 12, lg: 6, children: /* @__PURE__ */ e(
1030
- _e,
1031
- {
1032
- icon: /* @__PURE__ */ e(Pe, {}),
1033
- label: "我的项目",
1034
- value: t.projectCount,
1035
- suffix: "个",
1036
- color: "blue",
1037
- trend: 8.3,
1038
- href: "/project/list"
1039
- }
1040
- ) }),
1041
- /* @__PURE__ */ e(M, { xs: 24, sm: 12, md: 12, lg: 6, children: /* @__PURE__ */ e(
1042
- _e,
1043
- {
1044
- icon: /* @__PURE__ */ e(yt, {}),
1045
- label: "账号数",
1046
- value: t.userCount,
1047
- suffix: "人",
1048
- color: "green",
1049
- trend: -2.1,
1050
- href: "/ctc/4a/account"
1051
- }
1052
- ) }),
1053
- /* @__PURE__ */ e(M, { xs: 24, sm: 12, md: 12, lg: 6, children: /* @__PURE__ */ e(
1054
- _e,
1055
- {
1056
- icon: /* @__PURE__ */ e(je, {}),
1057
- label: "角色数",
1058
- value: t.roleCount,
1059
- suffix: "个",
1060
- color: "orange",
1061
- trend: 4.7,
1062
- href: "/ctc/4a/role"
1063
- }
1064
- ) })
1065
- ] }),
1066
- bn.map((r) => /* @__PURE__ */ n("div", { style: { marginBottom: 32 }, children: [
1067
- /* @__PURE__ */ e(
1068
- hn,
1069
- {
1070
- color: r.color,
1071
- title: r.title,
1072
- subtitle: r.subtitle,
1073
- moreHref: r.href
1074
- }
1075
- ),
1076
- /* @__PURE__ */ e(Q, { gutter: [16, 16], children: r.items.map((f, i) => /* @__PURE__ */ e(
1077
- M,
1078
- {
1079
- xs: 24,
1080
- sm: 12,
1081
- md: 12,
1082
- lg: 6,
1083
- xl: 6,
1084
- xxl: 6,
1085
- children: /* @__PURE__ */ e(
1086
- pn,
1087
- {
1088
- title: f.title,
1089
- description: f.description,
1090
- icon: f.icon,
1091
- color: f.color,
1092
- tags: f.tags,
1093
- meta: f.meta,
1094
- href: r.href
1095
- }
1096
- )
1097
- },
1098
- i
1099
- )) })
1100
- ] }, r.key)),
1101
- /* @__PURE__ */ e(
1102
- mn,
1103
- {
1104
- tag: "FOR ENGINEERS",
1105
- title: "把 Z-One Company 接入你的工作流",
1106
- description: "通过 OpenAPI、Webhook 与 SDK,把统一管理平台的能力嵌入到你的业务系统中。支持配置查询、任务触发、流程审批等 200+ 接口。",
1107
- buttonText: "查看开发文档",
1108
- buttonHref: "/z-tool/webide"
1109
- }
1110
- )
1111
- ] });
1112
- };
1113
- let xn = "/api";
1114
- function vt() {
1115
- return Xe.create({ baseURL: xn, timeout: 15e3, withCredentials: !0 });
1116
- }
1117
- const Ce = vt(), wn = vt();
1118
- wn.interceptors.request.use((t) => t);
1119
- Ce.interceptors.request.use((t) => t);
1120
- const Le = "/mock-platform", V = (t, a) => Ce.get(`${Le}${t}`, { params: a }).then((r) => r.data), q = (t, a, r) => Ce.post(`${Le}${t}`, a, { params: r }).then((f) => f.data), Re = (t, a, r) => Ce.put(`${Le}${t}`, a, { params: r }).then((f) => f.data), de = (t, a) => Ce.delete(`${Le}${t}`, { params: a }).then((r) => r.data), j = {
1121
- stats: () => V("/stats"),
1122
- environments: {
1123
- list: () => V("/environments/list"),
1124
- create: (t) => q("/environments", t),
1125
- update: (t, a) => Re("/environments", a, { envCode: t }),
1126
- delete: (t) => de("/environments", { envCode: t })
1127
- },
1128
- endpoints: {
1129
- list: (t, a, r) => V("/endpoints/list", { envCode: t, scenarioCode: a, status: r }),
1130
- get: (t) => V("/endpoints/byCode", { mockCode: t }),
1131
- create: (t) => q("/endpoints", t),
1132
- update: (t, a) => Re("/endpoints", a, { mockCode: t }),
1133
- delete: (t) => de("/endpoints", { mockCode: t }),
1134
- toggle: (t, a) => q("/endpoints/toggle", null, { mockCode: t, status: a })
1135
- },
1136
- scenarios: {
1137
- list: () => V("/scenarios/list"),
1138
- get: (t) => V("/scenarios/byCode", { scenarioCode: t }),
1139
- create: (t) => q("/scenarios", t),
1140
- update: (t, a) => Re("/scenarios", a, { scenarioCode: t }),
1141
- delete: (t) => de("/scenarios", { scenarioCode: t }),
1142
- reset: (t) => q("/scenarios/reset", null, { scenarioCode: t }),
1143
- instances: (t) => V("/scenarios/instances", { scenarioCode: t })
1144
- },
1145
- cases: {
1146
- list: () => V("/cases/list"),
1147
- get: (t) => V("/cases/byCode", { caseCode: t }),
1148
- create: (t) => q("/cases", t),
1149
- update: (t, a) => Re("/cases", a, { caseCode: t }),
1150
- delete: (t) => de("/cases", { caseCode: t }),
1151
- run: (t) => q("/cases/run", null, { caseCode: t }),
1152
- runBatch: (t) => q("/cases/run-batch", { caseCodes: t })
1153
- },
1154
- recordings: {
1155
- list: () => V("/recordings/list"),
1156
- get: (t) => V("/recordings/byCode", { recordingCode: t }),
1157
- requests: (t) => V("/recordings/requests", { recordingCode: t }),
1158
- start: (t, a, r) => q("/recordings/start", {
1159
- recordingCode: t,
1160
- recordingName: a,
1161
- targetUrl: r
1162
- }),
1163
- stop: (t) => q("/recordings/stop", null, { recordingCode: t }),
1164
- export: (t, a) => q("/recordings/export", { recordingCode: t, projectCode: a }),
1165
- import: (t, a) => q("/recordings/import", { recordingCode: t, projectCode: a }),
1166
- playback: (t, a) => q("/recordings/playback", { recordingCode: t, targetUrl: a }),
1167
- delete: (t) => de("/recordings", { recordingCode: t })
1168
- },
1169
- requestLogs: {
1170
- list: (t) => V("/request-logs/list", t),
1171
- stats: () => V("/request-logs/stats"),
1172
- clear: (t) => de("/request-logs/clear", { limit: t })
1173
- },
1174
- curl: {
1175
- parse: (t) => q("/curl/parse", { curlText: t }),
1176
- run: (t) => q("/curl/run", { curlText: t }),
1177
- importAsCase: (t) => q("/curl/import-as-case", t),
1178
- importAsEndpoint: (t) => q("/curl/import-as-endpoint", t)
1179
- },
1180
- openapi: {
1181
- parse: (t) => q("/openapi/parse", { content: t }),
1182
- importBatch: (t) => q("/openapi/import-batch", t),
1183
- sample: (t) => V("/openapi/sample", { format: t })
1184
- }
1185
- }, { Text: ae, Paragraph: Sn } = le, rt = { GET: "green", POST: "blue", PUT: "orange", DELETE: "red", PATCH: "purple" };
1186
- function Ue({ activeEnvCode: t }) {
1187
- const [a, r] = x([]), [f, i] = x(!1), [u, l] = x(null), [h, g] = x(!1), [w, _] = x(null);
1188
- W(() => {
1189
- y();
1190
- }, [t]);
1191
- const y = async () => {
1192
- i(!0), l(null);
1193
- try {
1194
- const c = await j.endpoints.list(t);
1195
- r(Array.isArray(c) ? c : []);
1196
- } catch (c) {
1197
- l((c == null ? void 0 : c.message) || "API unavailable"), r([]);
1198
- } finally {
1199
- i(!1);
1200
- }
1201
- }, m = (c) => `${window.location.origin}/api/mock/${c.env_code || t || "default"}${c.path || ""}`, s = [
1202
- {
1203
- title: "路径",
1204
- dataIndex: "path",
1205
- key: "path",
1206
- width: 280,
1207
- render: (c, k) => /* @__PURE__ */ n(z, { children: [
1208
- /* @__PURE__ */ e(v, { color: rt[k.method] || "default", children: k.method }),
1209
- /* @__PURE__ */ e(ae, { code: !0, copyable: { text: c }, children: c })
1210
- ] })
1211
- },
1212
- { title: "编码", dataIndex: "mock_code", key: "mock_code", width: 160 },
1213
- {
1214
- title: "优先级",
1215
- dataIndex: "priority",
1216
- key: "priority",
1217
- width: 80,
1218
- align: "center",
1219
- render: (c) => /* @__PURE__ */ n(v, { color: "blue", children: [
1220
- "P",
1221
- c || 5
1222
- ] })
1223
- },
1224
- { title: "状态码", dataIndex: "status_code", key: "status_code", width: 80, align: "center" },
1225
- {
1226
- title: "延迟",
1227
- dataIndex: "delay_ms",
1228
- key: "delay_ms",
1229
- width: 80,
1230
- align: "center",
1231
- render: (c) => c > 0 ? /* @__PURE__ */ n(ae, { type: "warning", children: [
1232
- c,
1233
- "ms"
1234
- ] }) : /* @__PURE__ */ e(ae, { type: "secondary", children: "-" })
1235
- },
1236
- {
1237
- title: "故障",
1238
- dataIndex: "fault_type",
1239
- key: "fault_type",
1240
- width: 110,
1241
- render: (c) => c && c !== "NONE" ? /* @__PURE__ */ e(v, { color: "red", children: c }) : /* @__PURE__ */ e(ae, { type: "secondary", children: "-" })
1242
- },
1243
- {
1244
- title: "场景",
1245
- dataIndex: "scenario_code",
1246
- key: "scenario_code",
1247
- width: 130,
1248
- render: (c) => c ? /* @__PURE__ */ e(v, { color: "purple", children: c }) : /* @__PURE__ */ e(ae, { type: "secondary", children: "-" })
1249
- },
1250
- {
1251
- title: "命中",
1252
- dataIndex: "hit_count",
1253
- key: "hit_count",
1254
- width: 80,
1255
- align: "center",
1256
- render: (c) => /* @__PURE__ */ e(ae, { strong: !0, children: c || 0 })
1257
- },
1258
- {
1259
- title: "状态",
1260
- dataIndex: "status",
1261
- key: "status",
1262
- width: 100,
1263
- align: "center",
1264
- render: (c) => c === 1 ? /* @__PURE__ */ e(v, { color: "green", children: "启用" }) : /* @__PURE__ */ e(v, { children: "禁用" })
1265
- },
1266
- {
1267
- title: "操作",
1268
- key: "action",
1269
- width: 160,
1270
- fixed: "right",
1271
- render: (c, k) => /* @__PURE__ */ n(z, { size: "small", children: [
1272
- /* @__PURE__ */ e(me, { title: "预览响应", children: /* @__PURE__ */ e(
1273
- A,
1274
- {
1275
- size: "small",
1276
- type: "link",
1277
- icon: /* @__PURE__ */ e(Me, {}),
1278
- onClick: () => {
1279
- _(k), g(!0);
1280
- },
1281
- children: "预览"
1282
- }
1283
- ) }),
1284
- /* @__PURE__ */ e(me, { title: "复制URL", children: /* @__PURE__ */ e(
1285
- A,
1286
- {
1287
- size: "small",
1288
- type: "link",
1289
- icon: /* @__PURE__ */ e(bt, {}),
1290
- onClick: () => {
1291
- navigator.clipboard.writeText(m(k)), I.success("已复制");
1292
- }
1293
- }
1294
- ) })
1295
- ] })
1296
- }
1297
- ];
1298
- return /* @__PURE__ */ n("div", { children: [
1299
- u && /* @__PURE__ */ e(
1300
- J,
1301
- {
1302
- type: "warning",
1303
- showIcon: !0,
1304
- style: { marginBottom: 16 },
1305
- title: "后端 API 暂未连接",
1306
- description: u
1307
- }
1308
- ),
1309
- /* @__PURE__ */ n(Q, { gutter: 16, style: { marginBottom: 16 }, children: [
1310
- /* @__PURE__ */ e(M, { span: 6, children: /* @__PURE__ */ n(P, { children: [
1311
- /* @__PURE__ */ e("strong", { children: "总端点" }),
1312
- /* @__PURE__ */ e("div", { style: { fontSize: 22 }, children: a.length })
1313
- ] }) }),
1314
- /* @__PURE__ */ e(M, { span: 6, children: /* @__PURE__ */ n(P, { children: [
1315
- /* @__PURE__ */ e("strong", { children: "已启用" }),
1316
- /* @__PURE__ */ e("div", { style: { fontSize: 22, color: "#52c41a" }, children: a.filter((c) => c.status === 1).length })
1317
- ] }) }),
1318
- /* @__PURE__ */ e(M, { span: 6, children: /* @__PURE__ */ n(P, { children: [
1319
- /* @__PURE__ */ e("strong", { children: "已禁用" }),
1320
- /* @__PURE__ */ e("div", { style: { fontSize: 22, color: "#ff4d4f" }, children: a.filter((c) => c.status === 0).length })
1321
- ] }) }),
1322
- /* @__PURE__ */ e(M, { span: 6, children: /* @__PURE__ */ n(P, { children: [
1323
- /* @__PURE__ */ e("strong", { children: "总命中" }),
1324
- /* @__PURE__ */ e("div", { style: {
1325
- fontSize: 22,
1326
- color: "#1890ff"
1327
- }, children: a.reduce((c, k) => c + (k.hit_count || 0), 0) })
1328
- ] }) })
1329
- ] }),
1330
- /* @__PURE__ */ e(z, { style: { marginBottom: 16 }, children: /* @__PURE__ */ e(A, { icon: /* @__PURE__ */ e(ee, {}), onClick: y, children: "刷新" }) }),
1331
- /* @__PURE__ */ e(
1332
- K,
1333
- {
1334
- dataSource: a,
1335
- columns: s,
1336
- rowKey: "id",
1337
- loading: f,
1338
- pagination: { pageSize: 10 },
1339
- scroll: { x: 1300 },
1340
- size: "small"
1341
- }
1342
- ),
1343
- /* @__PURE__ */ e(
1344
- ke,
1345
- {
1346
- title: /* @__PURE__ */ n(z, { children: [
1347
- /* @__PURE__ */ e($t, {}),
1348
- "端点详情: ",
1349
- w == null ? void 0 : w.mock_code
1350
- ] }),
1351
- open: h,
1352
- onClose: () => g(!1),
1353
- size: "large",
1354
- children: w && /* @__PURE__ */ n("div", { children: [
1355
- /* @__PURE__ */ n(O, { column: 2, size: "small", bordered: !0, style: { marginBottom: 16 }, children: [
1356
- /* @__PURE__ */ e(O.Item, { label: "编码", children: w.mock_code }),
1357
- /* @__PURE__ */ e(O.Item, { label: "名称", children: w.mock_name }),
1358
- /* @__PURE__ */ e(O.Item, { label: "方法", children: /* @__PURE__ */ e(v, { color: rt[w.method], children: w.method }) }),
1359
- /* @__PURE__ */ e(O.Item, { label: "环境", children: w.env_code }),
1360
- /* @__PURE__ */ e(O.Item, { label: "路径", span: 2, children: w.path }),
1361
- /* @__PURE__ */ e(O.Item, { label: "状态码", children: w.status_code }),
1362
- /* @__PURE__ */ n(O.Item, { label: "延迟", children: [
1363
- w.delay_ms,
1364
- "ms"
1365
- ] }),
1366
- /* @__PURE__ */ n(O.Item, { label: "优先级", children: [
1367
- "P",
1368
- w.priority
1369
- ] }),
1370
- /* @__PURE__ */ e(O.Item, { label: "命中", children: w.hit_count || 0 }),
1371
- /* @__PURE__ */ e(O.Item, { label: "故障", children: w.fault_type && w.fault_type !== "NONE" ? /* @__PURE__ */ e(v, { color: "red", children: w.fault_type }) : /* @__PURE__ */ e(ae, { type: "secondary", children: "-" }) }),
1372
- /* @__PURE__ */ e(O.Item, { label: "场景", children: w.scenario_code || "-" }),
1373
- /* @__PURE__ */ e(O.Item, { label: "状态", span: 2, children: w.status === 1 ? /* @__PURE__ */ e(v, { color: "green", children: "启用" }) : /* @__PURE__ */ e(v, { children: "禁用" }) }),
1374
- /* @__PURE__ */ e(O.Item, { label: "完整 URL", span: 2, children: /* @__PURE__ */ e(ae, { copyable: !0, children: m(w) }) })
1375
- ] }),
1376
- /* @__PURE__ */ e(Sn, { strong: !0, children: "响应模板:" }),
1377
- /* @__PURE__ */ e("pre", { style: {
1378
- background: "#f5f5f5",
1379
- padding: 12,
1380
- borderRadius: 4,
1381
- maxHeight: 350,
1382
- overflow: "auto",
1383
- fontSize: 13,
1384
- fontFamily: "monospace",
1385
- whiteSpace: "pre-wrap",
1386
- wordBreak: "break-all"
1387
- }, children: w.response_template })
1388
- ] })
1389
- }
1390
- )
1391
- ] });
1392
- }
1393
- const { Text: Ne } = le, In = { MOCK: "green", REAL: "blue", MIXED: "orange" };
1394
- function He({ onEnvChange: t }) {
1395
- const [a, r] = x([]), [f, i] = x(!1);
1396
- W(() => {
1397
- u();
1398
- }, []);
1399
- const u = async () => {
1400
- i(!0);
1401
- try {
1402
- const h = await j.environments.list();
1403
- r(Array.isArray(h) ? h : []);
1404
- } catch (h) {
1405
- I.warning("加载环境列表失败: " + (h == null ? void 0 : h.message));
1406
- } finally {
1407
- i(!1);
1408
- }
1409
- };
1410
- return /* @__PURE__ */ n("div", { children: [
1411
- /* @__PURE__ */ e(
1412
- J,
1413
- {
1414
- type: "info",
1415
- showIcon: !0,
1416
- style: { marginBottom: 16 },
1417
- message: "环境隔离 - 控制 Mock 与真实服务的切换",
1418
- description: /* @__PURE__ */ n("div", { children: [
1419
- /* @__PURE__ */ n("div", { children: [
1420
- /* @__PURE__ */ e(v, { color: "green", children: "MOCK" }),
1421
- " 完全拦截,仅返回 Mock 数据"
1422
- ] }),
1423
- /* @__PURE__ */ n("div", { children: [
1424
- /* @__PURE__ */ e(v, { color: "blue", children: "REAL" }),
1425
- " 全部代理到 base_url(适合压测、回归测试)"
1426
- ] }),
1427
- /* @__PURE__ */ n("div", { children: [
1428
- /* @__PURE__ */ e(v, { color: "orange", children: "MIXED" }),
1429
- " Mock 优先,未匹配时转发到 base_url(开发联调)"
1430
- ] })
1431
- ] })
1432
- }
1433
- ),
1434
- /* @__PURE__ */ e(z, { style: { marginBottom: 16 }, children: /* @__PURE__ */ e(A, { icon: /* @__PURE__ */ e(ee, {}), onClick: u, children: "刷新" }) }),
1435
- /* @__PURE__ */ e(
1436
- K,
1437
- {
1438
- dataSource: a,
1439
- columns: [
1440
- {
1441
- title: "环境编码",
1442
- dataIndex: "env_code",
1443
- key: "env_code",
1444
- width: 140,
1445
- render: (h) => /* @__PURE__ */ e(Ne, { code: !0, children: h })
1446
- },
1447
- { title: "环境名称", dataIndex: "env_name", key: "env_name", width: 160 },
1448
- {
1449
- title: "类型",
1450
- dataIndex: "env_type",
1451
- key: "env_type",
1452
- width: 240,
1453
- render: (h) => /* @__PURE__ */ e(v, { color: In[h] || "default", children: h })
1454
- },
1455
- {
1456
- title: "真实服务地址",
1457
- dataIndex: "base_url",
1458
- key: "base_url",
1459
- render: (h) => h ? /* @__PURE__ */ e(Ne, { copyable: !0, children: h }) : /* @__PURE__ */ e(Ne, { type: "secondary", children: "-" })
1460
- },
1461
- {
1462
- title: "默认",
1463
- dataIndex: "is_default",
1464
- key: "is_default",
1465
- width: 90,
1466
- align: "center",
1467
- render: (h) => h === 1 ? /* @__PURE__ */ e(v, { color: "gold", children: "默认" }) : "-"
1468
- },
1469
- {
1470
- title: "描述",
1471
- dataIndex: "description",
1472
- key: "description",
1473
- width: 220,
1474
- render: (h) => h || "-"
1475
- },
1476
- {
1477
- title: "操作",
1478
- key: "action",
1479
- width: 120,
1480
- render: (h, g) => /* @__PURE__ */ e(z, { size: "small", children: /* @__PURE__ */ e(
1481
- A,
1482
- {
1483
- size: "small",
1484
- type: "link",
1485
- icon: /* @__PURE__ */ e(xt, {}),
1486
- onClick: () => {
1487
- t && t(g.env_code);
1488
- },
1489
- children: "切换"
1490
- }
1491
- ) })
1492
- }
1493
- ],
1494
- rowKey: "id",
1495
- loading: f,
1496
- pagination: { pageSize: 10 },
1497
- size: "small"
1498
- }
1499
- )
1500
- ] });
1501
- }
1502
- const { Text: kn } = le;
1503
- function vn() {
1504
- const [t, a] = x([]), [r, f] = x(!1), [i, u] = x(!1), [l, h] = x(null);
1505
- W(() => {
1506
- g();
1507
- }, []);
1508
- const g = async () => {
1509
- f(!0);
1510
- try {
1511
- const m = await j.scenarios.list();
1512
- a(Array.isArray(m) ? m : []);
1513
- } catch {
1514
- I.warning("加载场景列表失败");
1515
- } finally {
1516
- f(!1);
1517
- }
1518
- }, w = async (m) => {
1519
- try {
1520
- await j.scenarios.reset(m), I.success("已重置所有实例状态");
1521
- } catch {
1522
- I.error("重置失败");
1523
- }
1524
- }, _ = async (m) => {
1525
- try {
1526
- const s = await j.scenarios.instances(m);
1527
- h({ code: m, list: s }), u(!0);
1528
- } catch {
1529
- I.error("加载失败");
1530
- }
1531
- };
1532
- return /* @__PURE__ */ n("div", { children: [
1533
- /* @__PURE__ */ e(
1534
- J,
1535
- {
1536
- type: "info",
1537
- showIcon: !0,
1538
- style: { marginBottom: 16 },
1539
- title: "场景状态机 (Scenario)",
1540
- description: "用状态机驱动 Mock 集合,模拟完整业务流程(如:未登录→登录中→已登录→下单→已支付→完成)。实例通过 X-Session-Id 或 X-Trace-Id 区分,每个实例独立维护当前状态。"
1541
- }
1542
- ),
1543
- /* @__PURE__ */ e(z, { style: { marginBottom: 16 }, children: /* @__PURE__ */ e(A, { icon: /* @__PURE__ */ e(ee, {}), onClick: g, children: "刷新" }) }),
1544
- /* @__PURE__ */ e(
1545
- K,
1546
- {
1547
- dataSource: t,
1548
- columns: [
1549
- {
1550
- title: "场景编码",
1551
- dataIndex: "scenario_code",
1552
- key: "scenario_code",
1553
- width: 160,
1554
- render: (m) => /* @__PURE__ */ e(kn, { code: !0, children: m })
1555
- },
1556
- { title: "场景名称", dataIndex: "scenario_name", key: "scenario_name", width: 200 },
1557
- {
1558
- title: "初始状态",
1559
- dataIndex: "initial_state",
1560
- key: "initial_state",
1561
- width: 140,
1562
- render: (m) => /* @__PURE__ */ e(v, { color: "blue", children: m })
1563
- },
1564
- {
1565
- title: "描述",
1566
- dataIndex: "description",
1567
- key: "description",
1568
- width: 240,
1569
- render: (m) => m || "-"
1570
- },
1571
- {
1572
- title: "操作",
1573
- key: "action",
1574
- width: 200,
1575
- fixed: "right",
1576
- render: (m, s) => /* @__PURE__ */ n(z, { size: "small", children: [
1577
- /* @__PURE__ */ e(
1578
- A,
1579
- {
1580
- size: "small",
1581
- type: "link",
1582
- icon: /* @__PURE__ */ e(Nt, {}),
1583
- onClick: () => _(s.scenario_code),
1584
- children: "实例"
1585
- }
1586
- ),
1587
- /* @__PURE__ */ e(
1588
- A,
1589
- {
1590
- size: "small",
1591
- type: "link",
1592
- icon: /* @__PURE__ */ e(Dt, {}),
1593
- onClick: () => w(s.scenario_code),
1594
- children: "重置"
1595
- }
1596
- )
1597
- ] })
1598
- }
1599
- ],
1600
- rowKey: "id",
1601
- loading: r,
1602
- pagination: { pageSize: 10 },
1603
- scroll: { x: 1100 },
1604
- size: "small"
1605
- }
1606
- ),
1607
- /* @__PURE__ */ e(
1608
- fe,
1609
- {
1610
- title: `场景实例: ${l == null ? void 0 : l.code}`,
1611
- open: i,
1612
- onCancel: () => u(!1),
1613
- footer: /* @__PURE__ */ e(A, { onClick: () => u(!1), children: "关闭" }),
1614
- size: "large",
1615
- children: l && /* @__PURE__ */ e(
1616
- K,
1617
- {
1618
- dataSource: Array.isArray(l.list) ? l.list : [],
1619
- columns: [
1620
- { title: "实例标识", dataIndex: "instance_key", key: "instance_key" },
1621
- {
1622
- title: "当前状态",
1623
- dataIndex: "current_state",
1624
- key: "current_state",
1625
- render: (m) => /* @__PURE__ */ e(v, { color: "blue", children: m })
1626
- },
1627
- { title: "最后变更", dataIndex: "update_time", key: "update_time" }
1628
- ],
1629
- rowKey: (m, s) => m.instance_key || s,
1630
- pagination: !1,
1631
- size: "small"
1632
- }
1633
- )
1634
- }
1635
- )
1636
- ] });
1637
- }
1638
- const { Text: oe } = le, De = { PASS: "green", FAIL: "red", SKIP: "default" }, Cn = { P0: "red", P1: "orange", P2: "blue", P3: "default" };
1639
- function Tn() {
1640
- const [t, a] = x([]), [r, f] = x(!1), [i, u] = x([]), [l, h] = x(!1), [g, w] = x(null), [_, y] = x(null), [m, s] = x(!1);
1641
- W(() => {
1642
- c();
1643
- }, []);
1644
- const c = async () => {
1645
- f(!0);
1646
- try {
1647
- const p = await j.cases.list();
1648
- a(Array.isArray(p) ? p : []);
1649
- } catch {
1650
- I.warning("加载用例列表失败");
1651
- } finally {
1652
- f(!1);
1653
- }
1654
- }, k = async (p) => {
1655
- try {
1656
- const o = await j.cases.run(p.case_code);
1657
- w(o), h(!0), (o == null ? void 0 : o.status) === "PASS" ? I.success("用例通过") : I.error("用例失败: " + ((o == null ? void 0 : o.error) || (o == null ? void 0 : o.actualStatus))), c();
1658
- } catch (o) {
1659
- I.error("执行失败: " + (o == null ? void 0 : o.message));
1660
- }
1661
- }, $ = async () => {
1662
- if (i.length === 0) {
1663
- I.warning("请先选择用例");
1664
- return;
1665
- }
1666
- try {
1667
- const p = await j.cases.runBatch(i);
1668
- y(p), s(!0), I.success(`批量执行完成: ${p == null ? void 0 : p.pass} 通过, ${p == null ? void 0 : p.fail} 失败`), c();
1669
- } catch {
1670
- I.error("批量执行失败");
1671
- }
1672
- }, S = [
1673
- {
1674
- title: "用例编码",
1675
- dataIndex: "case_code",
1676
- key: "case_code",
1677
- width: 180,
1678
- render: (p) => /* @__PURE__ */ e(oe, { code: !0, children: p })
1679
- },
1680
- { title: "名称", dataIndex: "case_name", key: "case_name", width: 220 },
1681
- {
1682
- title: "分组",
1683
- dataIndex: "case_group",
1684
- key: "case_group",
1685
- width: 130,
1686
- render: (p) => p ? /* @__PURE__ */ e(v, { children: p }) : "-"
1687
- },
1688
- {
1689
- title: "方法",
1690
- dataIndex: "request_method",
1691
- key: "request_method",
1692
- width: 80,
1693
- render: (p) => /* @__PURE__ */ e(v, { color: "blue", children: p })
1694
- },
1695
- {
1696
- title: "路径",
1697
- dataIndex: "request_url",
1698
- key: "request_url",
1699
- ellipsis: !0,
1700
- render: (p) => /* @__PURE__ */ e(oe, { code: !0, children: p })
1701
- },
1702
- {
1703
- title: "优先级",
1704
- dataIndex: "priority",
1705
- key: "priority",
1706
- width: 80,
1707
- align: "center",
1708
- render: (p) => /* @__PURE__ */ e(v, { color: Cn[p], children: p || "P1" })
1709
- },
1710
- {
1711
- title: "上次结果",
1712
- dataIndex: "last_run_result",
1713
- key: "last_run_result",
1714
- width: 100,
1715
- align: "center",
1716
- render: (p) => p ? /* @__PURE__ */ e(v, { color: De[p], children: p }) : "-"
1717
- },
1718
- {
1719
- title: "统计",
1720
- key: "stats",
1721
- width: 130,
1722
- align: "center",
1723
- render: (p, o) => /* @__PURE__ */ n(z, { size: "small", children: [
1724
- /* @__PURE__ */ e(oe, { type: "success", children: o.pass_count || 0 }),
1725
- "/",
1726
- /* @__PURE__ */ e(oe, { type: "danger", children: o.fail_count || 0 }),
1727
- /* @__PURE__ */ n(oe, { type: "secondary", children: [
1728
- "(",
1729
- o.run_count || 0,
1730
- ")"
1731
- ] })
1732
- ] })
1733
- },
1734
- {
1735
- title: "操作",
1736
- key: "action",
1737
- width: 120,
1738
- fixed: "right",
1739
- render: (p, o) => /* @__PURE__ */ e(z, { size: "small", children: /* @__PURE__ */ e(
1740
- A,
1741
- {
1742
- size: "small",
1743
- type: "link",
1744
- icon: /* @__PURE__ */ e(Me, {}),
1745
- onClick: () => k(o),
1746
- children: "运行"
1747
- }
1748
- ) })
1749
- }
1750
- ];
1751
- return /* @__PURE__ */ n("div", { children: [
1752
- /* @__PURE__ */ e(
1753
- J,
1754
- {
1755
- type: "info",
1756
- showIcon: !0,
1757
- style: { marginBottom: 16 },
1758
- title: "测试用例库",
1759
- description: "对 Mock 接口进行断言验证。支持 7 种断言类型:STATUS / HEADER / BODY / JSON_PATH / REGEX / SCHEMA / RESPONSE_TIME。支持单条运行与批量运行,自动统计通过/失败次数。"
1760
- }
1761
- ),
1762
- /* @__PURE__ */ n(z, { style: { marginBottom: 16 }, children: [
1763
- /* @__PURE__ */ e(A, { icon: /* @__PURE__ */ e(ee, {}), onClick: c, children: "刷新" }),
1764
- /* @__PURE__ */ n(
1765
- A,
1766
- {
1767
- type: "primary",
1768
- icon: /* @__PURE__ */ e(Me, {}),
1769
- onClick: $,
1770
- disabled: i.length === 0,
1771
- children: [
1772
- "批量运行 (",
1773
- i.length,
1774
- ")"
1775
- ]
1776
- }
1777
- )
1778
- ] }),
1779
- /* @__PURE__ */ e(
1780
- K,
1781
- {
1782
- dataSource: t,
1783
- columns: S,
1784
- rowKey: "id",
1785
- loading: r,
1786
- rowSelection: {
1787
- selectedRowKeys: i,
1788
- // 批量执行收的是 **case_code 列表**(后端按 case_code 查行),
1789
- // 原来这里存的是 rowKey(=id) ⇒ 批量执行永远查不到行。
1790
- onChange: (p, o) => u(o.map((C) => C.case_code))
1791
- },
1792
- pagination: { pageSize: 10 },
1793
- scroll: { x: 1300 },
1794
- size: "small"
1795
- }
1796
- ),
1797
- /* @__PURE__ */ e(
1798
- ke,
1799
- {
1800
- title: /* @__PURE__ */ n(z, { children: [
1801
- /* @__PURE__ */ e(Bt, {}),
1802
- "用例执行结果"
1803
- ] }),
1804
- open: l,
1805
- onClose: () => h(!1),
1806
- size: "large",
1807
- children: g && /* @__PURE__ */ n("div", { children: [
1808
- /* @__PURE__ */ n(Q, { gutter: 16, style: { marginBottom: 16 }, children: [
1809
- /* @__PURE__ */ e(M, { span: 8, children: /* @__PURE__ */ e(P, { children: /* @__PURE__ */ e(
1810
- H,
1811
- {
1812
- title: "结果",
1813
- value: g.status,
1814
- styles: { content: { color: De[g.status] === "green" ? "#52c41a" : "#ff4d4f" } }
1815
- }
1816
- ) }) }),
1817
- /* @__PURE__ */ e(M, { span: 8, children: /* @__PURE__ */ e(P, { children: /* @__PURE__ */ e(H, { title: "实际状态码", value: g.actualStatus || "-" }) }) }),
1818
- /* @__PURE__ */ e(M, { span: 8, children: /* @__PURE__ */ e(P, { children: /* @__PURE__ */ e(H, { title: "耗时(ms)", value: g.durationMs || 0 }) }) })
1819
- ] }),
1820
- /* @__PURE__ */ n(O, { column: 1, size: "small", bordered: !0, style: { marginBottom: 16 }, children: [
1821
- /* @__PURE__ */ e(O.Item, { label: "用例编码", children: g.caseCode }),
1822
- /* @__PURE__ */ e(O.Item, { label: "用例名称", children: g.caseName }),
1823
- /* @__PURE__ */ e(O.Item, { label: "错误信息", children: g.error || "-" })
1824
- ] }),
1825
- g.assertionResults && /* @__PURE__ */ n(Be, { children: [
1826
- /* @__PURE__ */ e(oe, { strong: !0, children: "断言详情:" }),
1827
- /* @__PURE__ */ e(
1828
- K,
1829
- {
1830
- style: { marginTop: 8 },
1831
- dataSource: g.assertionResults,
1832
- columns: [
1833
- { title: "断言类型", dataIndex: "type", key: "type", width: 110 },
1834
- { title: "表达式", dataIndex: "expression", key: "expression" },
1835
- { title: "期望值", dataIndex: "expected", key: "expected" },
1836
- { title: "实际值", dataIndex: "actual", key: "actual" },
1837
- {
1838
- title: "结果",
1839
- dataIndex: "passed",
1840
- key: "passed",
1841
- width: 80,
1842
- render: (p) => p ? /* @__PURE__ */ e(v, { color: "green", children: "PASS" }) : /* @__PURE__ */ e(v, { color: "red", children: "FAIL" })
1843
- }
1844
- ],
1845
- pagination: !1,
1846
- size: "small"
1847
- }
1848
- )
1849
- ] }),
1850
- /* @__PURE__ */ e(oe, { strong: !0, style: { marginTop: 16, display: "block" }, children: "响应体:" }),
1851
- /* @__PURE__ */ e("pre", { style: {
1852
- background: "#f5f5f5",
1853
- padding: 12,
1854
- borderRadius: 4,
1855
- maxHeight: 250,
1856
- overflow: "auto",
1857
- fontSize: 12,
1858
- fontFamily: "monospace",
1859
- whiteSpace: "pre-wrap",
1860
- wordBreak: "break-all"
1861
- }, children: g.responseBody || "(empty)" })
1862
- ] })
1863
- }
1864
- ),
1865
- /* @__PURE__ */ e(
1866
- fe,
1867
- {
1868
- title: `批量执行结果 (${(_ == null ? void 0 : _.total) || 0} 条)`,
1869
- open: m,
1870
- onCancel: () => s(!1),
1871
- footer: /* @__PURE__ */ e(A, { onClick: () => s(!1), children: "关闭" }),
1872
- size: "large",
1873
- children: _ && /* @__PURE__ */ n(Be, { children: [
1874
- /* @__PURE__ */ n(Q, { gutter: 16, style: { marginBottom: 16 }, children: [
1875
- /* @__PURE__ */ e(M, { span: 6, children: /* @__PURE__ */ e(P, { children: /* @__PURE__ */ e(H, { title: "总数", value: _.total }) }) }),
1876
- /* @__PURE__ */ e(M, { span: 6, children: /* @__PURE__ */ e(P, { children: /* @__PURE__ */ e(
1877
- H,
1878
- {
1879
- title: "通过",
1880
- value: _.pass,
1881
- styles: { content: { color: "#52c41a" } }
1882
- }
1883
- ) }) }),
1884
- /* @__PURE__ */ e(M, { span: 6, children: /* @__PURE__ */ e(P, { children: /* @__PURE__ */ e(
1885
- H,
1886
- {
1887
- title: "失败",
1888
- value: _.fail,
1889
- styles: { content: { color: "#ff4d4f" } }
1890
- }
1891
- ) }) }),
1892
- /* @__PURE__ */ e(M, { span: 6, children: /* @__PURE__ */ e(P, { children: /* @__PURE__ */ e(
1893
- H,
1894
- {
1895
- title: "通过率",
1896
- value: `${_.total > 0 ? Math.round(_.pass / _.total * 100) : 0}%`
1897
- }
1898
- ) }) })
1899
- ] }),
1900
- /* @__PURE__ */ e(
1901
- K,
1902
- {
1903
- dataSource: _.results || [],
1904
- columns: [
1905
- { title: "编码", dataIndex: "caseCode", key: "caseCode", width: 180 },
1906
- { title: "名称", dataIndex: "caseName", key: "caseName" },
1907
- {
1908
- title: "结果",
1909
- dataIndex: "status",
1910
- key: "status",
1911
- width: 80,
1912
- render: (p) => /* @__PURE__ */ e(v, { color: De[p], children: p })
1913
- },
1914
- { title: "耗时", dataIndex: "durationMs", key: "durationMs", width: 80, align: "center" },
1915
- { title: "错误", dataIndex: "error", key: "error", ellipsis: !0 }
1916
- ],
1917
- pagination: !1,
1918
- size: "small",
1919
- rowKey: "caseCode"
1920
- }
1921
- )
1922
- ] })
1923
- }
1924
- )
1925
- ] });
1926
- }
1927
- const { Text: ue } = le, lt = {
1928
- IDLE: "default",
1929
- RECORDING: "red",
1930
- STOPPED: "green",
1931
- EXPIRED: "gray"
1932
- };
1933
- function _n() {
1934
- const [t, a] = x([]), [r, f] = x(!1), [i, u] = x(!1), [l, h] = x(null), [g, w] = x([]);
1935
- W(() => {
1936
- _();
1937
- }, []);
1938
- const _ = async () => {
1939
- f(!0);
1940
- try {
1941
- const s = await j.recordings.list();
1942
- a(Array.isArray(s) ? s : []);
1943
- } catch {
1944
- I.warning("加载录制列表失败");
1945
- } finally {
1946
- f(!1);
1947
- }
1948
- }, y = async (s) => {
1949
- try {
1950
- const c = await j.recordings.requests(s.recording_code);
1951
- h(s), w(Array.isArray(c) ? c : []), u(!0);
1952
- } catch {
1953
- I.error("加载失败");
1954
- }
1955
- };
1956
- return /* @__PURE__ */ n("div", { children: [
1957
- /* @__PURE__ */ e(
1958
- J,
1959
- {
1960
- type: "info",
1961
- showIcon: !0,
1962
- style: { marginBottom: 16 },
1963
- message: "流量录制与回放",
1964
- description: /* @__PURE__ */ n("div", { children: [
1965
- /* @__PURE__ */ n("div", { children: [
1966
- "• 开启录制后,所有 ",
1967
- /* @__PURE__ */ e(ue, { code: !0, children: "/api/mock/{envCode}/**" }),
1968
- " 请求会被捕获到数据库"
1969
- ] }),
1970
- /* @__PURE__ */ e("div", { children: "• 停止录制后,可一键转为 Mock endpoints(用于离线测试)" }),
1971
- /* @__PURE__ */ e("div", { children: "• 支持回放录制到目标服务(验证录制有效 / 跨环境验证)" })
1972
- ] })
1973
- }
1974
- ),
1975
- /* @__PURE__ */ e(z, { style: { marginBottom: 16 }, children: /* @__PURE__ */ e(A, { icon: /* @__PURE__ */ e(ee, {}), onClick: _, children: "刷新" }) }),
1976
- /* @__PURE__ */ e(
1977
- K,
1978
- {
1979
- dataSource: t,
1980
- columns: [
1981
- {
1982
- title: "编码",
1983
- dataIndex: "recording_code",
1984
- key: "recording_code",
1985
- width: 180,
1986
- render: (s) => /* @__PURE__ */ e(ue, { code: !0, children: s })
1987
- },
1988
- { title: "名称", dataIndex: "recording_name", key: "recording_name", width: 200 },
1989
- {
1990
- title: "状态",
1991
- dataIndex: "record_status",
1992
- key: "record_status",
1993
- width: 110,
1994
- render: (s) => /* @__PURE__ */ e(v, { color: lt[s], children: s })
1995
- },
1996
- {
1997
- title: "请求数",
1998
- dataIndex: "total_requests",
1999
- key: "total_requests",
2000
- width: 90,
2001
- align: "center"
2002
- },
2003
- {
2004
- title: "目标 URL",
2005
- dataIndex: "target_url",
2006
- key: "target_url",
2007
- ellipsis: !0,
2008
- render: (s) => s ? /* @__PURE__ */ e(ue, { copyable: { text: s }, children: s }) : "-"
2009
- },
2010
- { title: "开始时间", dataIndex: "start_time", key: "start_time", width: 170 },
2011
- { title: "结束时间", dataIndex: "end_time", key: "end_time", width: 170 },
2012
- {
2013
- title: "操作",
2014
- key: "action",
2015
- width: 120,
2016
- fixed: "right",
2017
- render: (s, c) => /* @__PURE__ */ e(z, { size: "small", children: /* @__PURE__ */ e(
2018
- A,
2019
- {
2020
- size: "small",
2021
- type: "link",
2022
- icon: /* @__PURE__ */ e(Qe, {}),
2023
- onClick: () => y(c),
2024
- children: "详情"
2025
- }
2026
- ) })
2027
- }
2028
- ],
2029
- rowKey: "id",
2030
- loading: r,
2031
- pagination: { pageSize: 10 },
2032
- scroll: { x: 1300 },
2033
- size: "small"
2034
- }
2035
- ),
2036
- /* @__PURE__ */ e(
2037
- ke,
2038
- {
2039
- title: /* @__PURE__ */ n(z, { children: [
2040
- /* @__PURE__ */ e(Qe, {}),
2041
- "录制详情: ",
2042
- l == null ? void 0 : l.recording_code
2043
- ] }),
2044
- open: i,
2045
- onClose: () => u(!1),
2046
- size: "large",
2047
- children: l && /* @__PURE__ */ n("div", { children: [
2048
- /* @__PURE__ */ n(O, { column: 2, size: "small", bordered: !0, style: { marginBottom: 16 }, children: [
2049
- /* @__PURE__ */ e(O.Item, { label: "编码", children: l.recording_code }),
2050
- /* @__PURE__ */ e(O.Item, { label: "名称", children: l.recording_name }),
2051
- /* @__PURE__ */ e(O.Item, { label: "状态", children: /* @__PURE__ */ e(v, { color: lt[l.record_status], children: l.record_status }) }),
2052
- /* @__PURE__ */ e(O.Item, { label: "请求数", children: l.total_requests }),
2053
- /* @__PURE__ */ e(O.Item, { label: "目标 URL", span: 2, children: /* @__PURE__ */ e(ue, { copyable: !0, children: l.target_url }) }),
2054
- /* @__PURE__ */ e(O.Item, { label: "开始", children: l.start_time }),
2055
- /* @__PURE__ */ e(O.Item, { label: "结束", children: l.end_time || "(录制中)" })
2056
- ] }),
2057
- /* @__PURE__ */ n(ue, { strong: !0, children: [
2058
- "请求列表 (共 ",
2059
- g.length,
2060
- " 条):"
2061
- ] }),
2062
- /* @__PURE__ */ e(
2063
- K,
2064
- {
2065
- style: { marginTop: 8 },
2066
- dataSource: g,
2067
- columns: [
2068
- { title: "#", dataIndex: "sequence", key: "sequence", width: 50 },
2069
- {
2070
- title: "方法",
2071
- dataIndex: "request_method",
2072
- key: "request_method",
2073
- width: 80,
2074
- render: (s) => /* @__PURE__ */ e(v, { color: "blue", children: s })
2075
- },
2076
- {
2077
- title: "URL",
2078
- dataIndex: "request_url",
2079
- key: "request_url",
2080
- ellipsis: !0,
2081
- render: (s) => /* @__PURE__ */ e(ue, { code: !0, children: s })
2082
- },
2083
- {
2084
- title: "响应",
2085
- dataIndex: "response_status",
2086
- key: "response_status",
2087
- width: 80,
2088
- render: (s) => /* @__PURE__ */ e(v, { color: s >= 400 ? "red" : "green", children: s })
2089
- },
2090
- {
2091
- title: "耗时",
2092
- dataIndex: "response_time",
2093
- key: "response_time",
2094
- width: 80,
2095
- render: (s) => `${s || 0}ms`
2096
- }
2097
- ],
2098
- pagination: { pageSize: 10 },
2099
- size: "small",
2100
- rowKey: "id"
2101
- }
2102
- )
2103
- ] })
2104
- }
2105
- )
2106
- ] });
2107
- }
2108
- const { Text: he } = le, An = { MOCK: "green", PROXY: "blue", 404: "red", 502: "orange" };
2109
- function zn() {
2110
- const [t, a] = x([]), [r, f] = x(null), [i, u] = x(!1), [l, h] = x(null), [g, w] = x(!1), [_, y] = x(""), [m, s] = x();
2111
- W(() => {
2112
- c();
2113
- }, []);
2114
- const c = async () => {
2115
- u(!0);
2116
- try {
2117
- const [S, p] = await Promise.all([
2118
- j.requestLogs.list({
2119
- path: _ || void 0,
2120
- matched: m,
2121
- limit: 100
2122
- }),
2123
- j.requestLogs.stats().catch(() => null)
2124
- ]);
2125
- a(Array.isArray(S) ? S : []), f(p);
2126
- } catch {
2127
- I.warning("加载失败");
2128
- } finally {
2129
- u(!1);
2130
- }
2131
- }, k = (S) => {
2132
- h(S), w(!0);
2133
- }, $ = [
2134
- {
2135
- title: "时间",
2136
- dataIndex: "create_time",
2137
- key: "create_time",
2138
- width: 170,
2139
- render: (S) => S ? new Date(S).toLocaleString() : "-"
2140
- },
2141
- {
2142
- title: "环境",
2143
- dataIndex: "env_code",
2144
- key: "env_code",
2145
- width: 100,
2146
- render: (S) => /* @__PURE__ */ e(v, { children: S })
2147
- },
2148
- {
2149
- title: "方法",
2150
- dataIndex: "request_method",
2151
- key: "request_method",
2152
- width: 80,
2153
- render: (S) => /* @__PURE__ */ e(v, { color: "blue", children: S })
2154
- },
2155
- {
2156
- title: "路径",
2157
- dataIndex: "request_path",
2158
- key: "request_path",
2159
- ellipsis: !0,
2160
- render: (S) => /* @__PURE__ */ e(he, { code: !0, children: S })
2161
- },
2162
- {
2163
- title: "状态",
2164
- dataIndex: "response_status",
2165
- key: "response_status",
2166
- width: 90,
2167
- align: "center",
2168
- render: (S) => S ? /* @__PURE__ */ e(v, { color: S >= 400 ? "red" : "green", children: S }) : "-"
2169
- },
2170
- {
2171
- title: "匹配",
2172
- dataIndex: "matched",
2173
- key: "matched",
2174
- width: 90,
2175
- align: "center",
2176
- render: (S) => S === 1 ? /* @__PURE__ */ e(v, { color: "green", children: "命中" }) : /* @__PURE__ */ e(v, { color: "red", children: "未匹配" })
2177
- },
2178
- {
2179
- title: "回退",
2180
- dataIndex: "fallback_type",
2181
- key: "fallback_type",
2182
- width: 100,
2183
- render: (S) => S ? /* @__PURE__ */ e(v, { color: An[S], children: S }) : "-"
2184
- },
2185
- {
2186
- title: "耗时",
2187
- dataIndex: "duration_ms",
2188
- key: "duration_ms",
2189
- width: 80,
2190
- align: "center",
2191
- render: (S) => `${S || 0}ms`
2192
- },
2193
- {
2194
- title: "Mock",
2195
- dataIndex: "mock_code",
2196
- key: "mock_code",
2197
- width: 160,
2198
- ellipsis: !0,
2199
- render: (S) => S ? /* @__PURE__ */ e(he, { code: !0, children: S }) : "-"
2200
- },
2201
- {
2202
- title: "操作",
2203
- key: "action",
2204
- width: 80,
2205
- render: (S, p) => /* @__PURE__ */ e(
2206
- A,
2207
- {
2208
- size: "small",
2209
- type: "link",
2210
- icon: /* @__PURE__ */ e(jt, {}),
2211
- onClick: () => k(p),
2212
- children: "详情"
2213
- }
2214
- )
2215
- }
2216
- ];
2217
- return /* @__PURE__ */ n("div", { children: [
2218
- /* @__PURE__ */ e(
2219
- J,
2220
- {
2221
- type: "info",
2222
- showIcon: !0,
2223
- style: { marginBottom: 16 },
2224
- title: "Mock 请求日志 - 排查未匹配请求",
2225
- description: "每一次请求都会留痕。包括请求/响应体、是否匹配 Mock、回退类型、耗时、场景状态等。便于排查“为什么这个请求没有 Mock 命中”问题。"
2226
- }
2227
- ),
2228
- r && /* @__PURE__ */ n(Q, { gutter: 16, style: { marginBottom: 16 }, children: [
2229
- /* @__PURE__ */ e(M, { span: 6, children: /* @__PURE__ */ e(P, { children: /* @__PURE__ */ e(H, { title: "总请求数", value: r.total || 0 }) }) }),
2230
- /* @__PURE__ */ e(M, { span: 6, children: /* @__PURE__ */ e(P, { children: /* @__PURE__ */ e(
2231
- H,
2232
- {
2233
- title: "Mock 命中",
2234
- value: r.matched || 0,
2235
- styles: { content: { color: "#52c41a" } }
2236
- }
2237
- ) }) }),
2238
- /* @__PURE__ */ e(M, { span: 6, children: /* @__PURE__ */ e(P, { children: /* @__PURE__ */ e(
2239
- H,
2240
- {
2241
- title: "未匹配",
2242
- value: r.unmatched || 0,
2243
- styles: { content: { color: "#ff4d4f" } }
2244
- }
2245
- ) }) }),
2246
- /* @__PURE__ */ e(M, { span: 6, children: /* @__PURE__ */ e(P, { children: /* @__PURE__ */ e(
2247
- H,
2248
- {
2249
- title: "命中率",
2250
- value: `${r.total > 0 ? Math.round(r.matched / r.total * 100) : 0}%`
2251
- }
2252
- ) }) })
2253
- ] }),
2254
- /* @__PURE__ */ n(z, { style: { marginBottom: 16 }, children: [
2255
- /* @__PURE__ */ e(
2256
- B,
2257
- {
2258
- placeholder: "搜索路径",
2259
- prefix: /* @__PURE__ */ e(wt, {}),
2260
- allowClear: !0,
2261
- style: { width: 240 },
2262
- value: _,
2263
- onChange: (S) => y(S.target.value),
2264
- onPressEnter: c
2265
- }
2266
- ),
2267
- /* @__PURE__ */ e(
2268
- X,
2269
- {
2270
- placeholder: "匹配状态",
2271
- allowClear: !0,
2272
- style: { width: 140 },
2273
- value: m,
2274
- onChange: s,
2275
- options: [
2276
- { value: 1, label: "已命中" },
2277
- { value: 0, label: "未匹配" }
2278
- ]
2279
- }
2280
- ),
2281
- /* @__PURE__ */ e(A, { icon: /* @__PURE__ */ e(ee, {}), onClick: c, children: "查询" })
2282
- ] }),
2283
- /* @__PURE__ */ e(
2284
- K,
2285
- {
2286
- dataSource: t,
2287
- columns: $,
2288
- rowKey: "id",
2289
- loading: i,
2290
- pagination: { pageSize: 20 },
2291
- scroll: { x: 1300 },
2292
- size: "small"
2293
- }
2294
- ),
2295
- /* @__PURE__ */ e(
2296
- ke,
2297
- {
2298
- title: "请求详情",
2299
- open: g,
2300
- onClose: () => w(!1),
2301
- size: "large",
2302
- children: l && /* @__PURE__ */ n("div", { children: [
2303
- /* @__PURE__ */ n(O, { column: 2, size: "small", bordered: !0, style: { marginBottom: 16 }, children: [
2304
- /* @__PURE__ */ e(O.Item, { label: "环境", children: l.env_code }),
2305
- /* @__PURE__ */ e(O.Item, { label: "方法", children: /* @__PURE__ */ e(
2306
- v,
2307
- {
2308
- color: "blue",
2309
- children: l.request_method
2310
- }
2311
- ) }),
2312
- /* @__PURE__ */ e(O.Item, { label: "路径", span: 2, children: /* @__PURE__ */ e(
2313
- he,
2314
- {
2315
- code: !0,
2316
- children: l.request_path
2317
- }
2318
- ) }),
2319
- /* @__PURE__ */ e(O.Item, { label: "状态码", children: /* @__PURE__ */ e(
2320
- v,
2321
- {
2322
- color: l.response_status >= 400 ? "red" : "green",
2323
- children: l.response_status
2324
- }
2325
- ) }),
2326
- /* @__PURE__ */ n(O.Item, { label: "耗时", children: [
2327
- l.duration_ms,
2328
- "ms"
2329
- ] }),
2330
- /* @__PURE__ */ e(O.Item, { label: "匹配", children: l.matched === 1 ? /* @__PURE__ */ e(v, { color: "green", children: "命中" }) : /* @__PURE__ */ e(v, { color: "red", children: "未匹配" }) }),
2331
- /* @__PURE__ */ e(O.Item, { label: "回退", children: l.fallback_type || "-" }),
2332
- /* @__PURE__ */ e(O.Item, { label: "Mock", span: 2, children: l.mock_code || "-" }),
2333
- /* @__PURE__ */ e(
2334
- O.Item,
2335
- {
2336
- label: "场景状态",
2337
- span: 2,
2338
- children: l.scenario_state || "-"
2339
- }
2340
- ),
2341
- /* @__PURE__ */ e(O.Item, { label: "客户端 IP", children: l.client_ip || "-" }),
2342
- /* @__PURE__ */ e(O.Item, { label: "User-Agent", ellipsis: !0, children: l.user_agent || "-" }),
2343
- /* @__PURE__ */ e(O.Item, { label: "时间", span: 2, children: l.create_time ? new Date(l.create_time).toLocaleString() : "-" })
2344
- ] }),
2345
- /* @__PURE__ */ e(he, { strong: !0, children: "请求头:" }),
2346
- /* @__PURE__ */ e("pre", { style: {
2347
- background: "#f5f5f5",
2348
- padding: 12,
2349
- borderRadius: 4,
2350
- maxHeight: 150,
2351
- overflow: "auto",
2352
- fontSize: 12,
2353
- fontFamily: "monospace",
2354
- whiteSpace: "pre-wrap"
2355
- }, children: l.request_headers || "(无)" }),
2356
- /* @__PURE__ */ e(he, { strong: !0, style: { marginTop: 12, display: "block" }, children: "请求体:" }),
2357
- /* @__PURE__ */ e("pre", { style: {
2358
- background: "#f5f5f5",
2359
- padding: 12,
2360
- borderRadius: 4,
2361
- maxHeight: 200,
2362
- overflow: "auto",
2363
- fontSize: 12,
2364
- fontFamily: "monospace",
2365
- whiteSpace: "pre-wrap",
2366
- wordBreak: "break-all"
2367
- }, children: l.request_body || "(无)" }),
2368
- /* @__PURE__ */ e(he, { strong: !0, style: { marginTop: 12, display: "block" }, children: "响应体:" }),
2369
- /* @__PURE__ */ e("pre", { style: {
2370
- background: "#f5f5f5",
2371
- padding: 12,
2372
- borderRadius: 4,
2373
- maxHeight: 300,
2374
- overflow: "auto",
2375
- fontSize: 12,
2376
- fontFamily: "monospace",
2377
- whiteSpace: "pre-wrap",
2378
- wordBreak: "break-all"
2379
- }, children: l.response_body || "(无)" })
2380
- ] })
2381
- }
2382
- )
2383
- ] });
2384
- }
2385
- const { Text: te } = le, at = [
2386
- { key: "endpoints", label: "Mock 端点", component: Ue },
2387
- { key: "environments", label: "环境 (MOCK/REAL/MIXED)", component: He },
2388
- { key: "scenarios", label: "场景状态机", component: vn },
2389
- { key: "cases", label: "测试用例", component: Tn },
2390
- { key: "recordings", label: "录制回放", component: _n },
2391
- { key: "request-logs", label: "请求日志", component: zn }
2392
- ];
2393
- function Rn() {
2394
- var _;
2395
- const [t, a] = x("endpoints"), [r, f] = x([]), [i, u] = x("default"), [l, h] = x(null);
2396
- W(() => {
2397
- g(), w();
2398
- }, []);
2399
- const g = async () => {
2400
- try {
2401
- const y = await j.environments.list(), m = Array.isArray(y) ? y : [];
2402
- if (f(m), m.length > 0 && !m.find((s) => s.env_code === i)) {
2403
- const s = m.find((c) => c.is_default === 1) || m[0];
2404
- u(s.env_code);
2405
- }
2406
- } catch {
2407
- }
2408
- }, w = async () => {
2409
- try {
2410
- const y = await j.stats();
2411
- h(y);
2412
- } catch {
2413
- }
2414
- };
2415
- return (_ = at.find((y) => y.key === t)) == null || _.component, /* @__PURE__ */ n("div", { children: [
2416
- /* @__PURE__ */ e(
2417
- xe,
2418
- {
2419
- title: "Mock 平台",
2420
- subtitle: "WireMock 级 · Mock 端点管理、环境隔离、场景状态机、测试用例库、录制回放、请求日志"
2421
- }
2422
- ),
2423
- /* @__PURE__ */ e(
2424
- ve,
2425
- {
2426
- activeKey: t,
2427
- onChange: a,
2428
- type: "card",
2429
- tabBarExtraContent: /* @__PURE__ */ n(z, { size: "large", wrap: !0, children: [
2430
- /* @__PURE__ */ n(z, { children: [
2431
- /* @__PURE__ */ e(xt, {}),
2432
- /* @__PURE__ */ e(te, { children: "当前环境:" }),
2433
- /* @__PURE__ */ e(
2434
- X,
2435
- {
2436
- value: i,
2437
- onChange: u,
2438
- style: { width: 200 },
2439
- options: r.map((y) => ({
2440
- value: y.env_code,
2441
- label: `${y.env_name || y.env_code} (${y.env_type})`
2442
- }))
2443
- }
2444
- )
2445
- ] }),
2446
- l && /* @__PURE__ */ n(z, { size: "large", children: [
2447
- /* @__PURE__ */ n(te, { type: "secondary", children: [
2448
- "端点: ",
2449
- /* @__PURE__ */ e(te, { strong: !0, children: l.totalEndpoints })
2450
- ] }),
2451
- /* @__PURE__ */ n(te, { type: "secondary", children: [
2452
- "启用: ",
2453
- /* @__PURE__ */ e(
2454
- te,
2455
- {
2456
- strong: !0,
2457
- style: { color: "#52c41a" },
2458
- children: l.activeEndpoints
2459
- }
2460
- )
2461
- ] }),
2462
- /* @__PURE__ */ n(te, { type: "secondary", children: [
2463
- "场景: ",
2464
- /* @__PURE__ */ e(te, { strong: !0, children: l.totalScenarios })
2465
- ] }),
2466
- /* @__PURE__ */ n(te, { type: "secondary", children: [
2467
- "用例: ",
2468
- /* @__PURE__ */ e(te, { strong: !0, children: l.totalCases })
2469
- ] })
2470
- ] }),
2471
- /* @__PURE__ */ e(A, { icon: /* @__PURE__ */ e(ee, {}), onClick: () => {
2472
- g(), w();
2473
- }, children: "刷新" })
2474
- ] }),
2475
- items: at.map((y) => ({
2476
- key: y.key,
2477
- label: y.label,
2478
- children: y.component === Ue ? /* @__PURE__ */ e(Ue, { activeEnvCode: i }) : y.component === He ? /* @__PURE__ */ e(He, { onEnvChange: (m) => {
2479
- u(m), I.success(`已切换到环境: ${m}`);
2480
- } }) : /* @__PURE__ */ e(y.component, {})
2481
- }))
2482
- }
2483
- )
2484
- ] });
2485
- }
2486
- const or = /* @__PURE__ */ Object.freeze(/* @__PURE__ */ Object.defineProperty({
2487
- __proto__: null,
2488
- default: Rn
2489
- }, Symbol.toStringTag, { value: "Module" })), { Text: we, Paragraph: sr } = le, it = [
2490
- {
2491
- group: "基础数据",
2492
- icon: /* @__PURE__ */ e(Se, {}),
2493
- items: [
2494
- { syntax: "@uuid", desc: "随机 UUID", example: "a3f2e1b7-8c4d-4e6f-9a1b-2c3d4e5f6a7b" },
2495
- { syntax: "@int(1, 100)", desc: "随机整数(含边界)", example: "42" },
2496
- { syntax: "@int", desc: "随机整数(0-1000)", example: "731" },
2497
- { syntax: "@boolean", desc: "随机布尔", example: "true" },
2498
- { syntax: '@pick("a","b","c")', desc: "从列表随机取一项", example: '"b"' }
2499
- ]
2500
- },
2501
- {
2502
- group: "时间相关",
2503
- icon: /* @__PURE__ */ e(Te, {}),
2504
- items: [
2505
- { syntax: "@datetime", desc: "当前时间 (yyyy-MM-dd HH:mm:ss)", example: "2026-06-17 22:30:15" },
2506
- { syntax: "@date", desc: "当前日期 (yyyy-MM-dd)", example: "2026-06-17" },
2507
- { syntax: "@time", desc: "当前时间戳 (毫秒)", example: "1718639415000" },
2508
- { syntax: "@timestamp", desc: "Unix 秒级时间戳", example: "1718639415" }
2509
- ]
2510
- },
2511
- {
2512
- group: "文本生成",
2513
- icon: /* @__PURE__ */ e(Te, {}),
2514
- items: [
2515
- { syntax: "@name", desc: "随机中文姓名", example: "张伟" },
2516
- { syntax: "@firstName", desc: "随机名", example: "伟" },
2517
- { syntax: "@lastName", desc: "随机姓", example: "张" },
2518
- { syntax: "@email", desc: "随机邮箱", example: "zhangwei@example.com" },
2519
- { syntax: "@phone", desc: "随机手机号(中国)", example: "13812345678" },
2520
- { syntax: "@idCard", desc: "随机身份证号", example: "110101199003078234" },
2521
- { syntax: "@word", desc: "随机英文单词", example: "horizon" },
2522
- { syntax: "@sentence(5, 10)", desc: "随机句子 (5-10 词)", example: "The quick brown fox jumps." },
2523
- { syntax: "@paragraph(3, 5)", desc: "随机段落 (3-5 句)", example: "..." }
2524
- ]
2525
- },
2526
- {
2527
- group: "序列与状态",
2528
- icon: /* @__PURE__ */ e(Te, {}),
2529
- items: [
2530
- { syntax: "@sequence(1)", desc: "自增序号(每次调用 +1,1 起始)", example: "1, 2, 3, ..." },
2531
- { syntax: "@sequence(100, 5)", desc: "自增序号(100 起始,步长 5)", example: "100, 105, 110, ..." }
2532
- ]
2533
- },
2534
- {
2535
- group: "请求上下文",
2536
- icon: /* @__PURE__ */ e(Te, {}),
2537
- items: [
2538
- { syntax: "#path.id", desc: "从 URL 路径取值 /users/123 → 123", example: "123" },
2539
- { syntax: "#query.page", desc: "从 query string 取值 ?page=2", example: "2" },
2540
- { syntax: "#header.X-Token", desc: "从请求头取值", example: "abc.def.ghi" },
2541
- { syntax: "#body.username", desc: "从请求体 JSON 取值", example: '"alice"' }
2542
- ]
2543
- }
2544
- ];
2545
- function cr({ onInsert: t, form: a, formField: r = "responseTemplate" }) {
2546
- const [f, i] = x(""), u = (y) => {
2547
- var m;
2548
- try {
2549
- (m = navigator.clipboard) == null || m.writeText(y);
2550
- } catch {
2551
- }
2552
- if (t)
2553
- t(y);
2554
- else if (a) {
2555
- const s = a.getFieldValue(r) || "";
2556
- a.setFieldsValue({ [r]: s + (s.endsWith(`
2557
- `) || !s ? "" : " ") + y });
2558
- }
2559
- I.success(`已插入: ${y}`);
2560
- }, l = (y) => {
2561
- var m;
2562
- try {
2563
- (m = navigator.clipboard) == null || m.writeText(y), I.success("已复制到剪贴板");
2564
- } catch {
2565
- I.warning("复制失败,请手动选择");
2566
- }
2567
- }, h = f.toLowerCase(), g = it.map((y) => ({
2568
- ...y,
2569
- items: y.items.filter(
2570
- (m) => !h || m.syntax.toLowerCase().includes(h) || m.desc.toLowerCase().includes(h) || m.example.toLowerCase().includes(h)
2571
- )
2572
- })).filter((y) => y.items.length > 0), w = it.reduce((y, m) => y + m.items.length, 0), _ = g.reduce((y, m) => y + m.items.length, 0);
2573
- return /* @__PURE__ */ n(
2574
- P,
2575
- {
2576
- size: "small",
2577
- title: /* @__PURE__ */ n(z, { children: [
2578
- /* @__PURE__ */ e(Se, {}),
2579
- /* @__PURE__ */ e(we, { strong: !0, children: "模板表达式" }),
2580
- /* @__PURE__ */ n(v, { color: "blue", children: [
2581
- _,
2582
- "/",
2583
- w
2584
- ] }),
2585
- /* @__PURE__ */ e(me, { title: "点击按钮即可插入到上方响应模板;点击 syntax 文本可复制", children: /* @__PURE__ */ e(Ft, { style: { color: "#999" } }) })
2586
- ] }),
2587
- extra: /* @__PURE__ */ e(
2588
- B,
2589
- {
2590
- size: "small",
2591
- placeholder: "搜索 @ 表达式",
2592
- prefix: /* @__PURE__ */ e(wt, {}),
2593
- value: f,
2594
- onChange: (y) => i(y.target.value),
2595
- style: { width: 180 },
2596
- allowClear: !0
2597
- }
2598
- ),
2599
- style: { marginTop: 8, background: "#fafafa" },
2600
- styles: { body: { padding: 12, maxHeight: 320, overflow: "auto" } },
2601
- children: [
2602
- g.length === 0 && /* @__PURE__ */ e(we, { type: "secondary", style: { display: "block", textAlign: "center", padding: 16 }, children: "没有匹配的表达式" }),
2603
- g.map((y) => /* @__PURE__ */ n("div", { style: { marginBottom: 12 }, children: [
2604
- /* @__PURE__ */ n(z, { size: 4, style: { marginBottom: 6 }, children: [
2605
- y.icon,
2606
- /* @__PURE__ */ e(we, { strong: !0, style: { fontSize: 13 }, children: y.group }),
2607
- /* @__PURE__ */ e(v, { children: y.items.length })
2608
- ] }),
2609
- /* @__PURE__ */ e(Q, { gutter: [8, 8], children: y.items.map((m) => /* @__PURE__ */ e(M, { span: 24, children: /* @__PURE__ */ n(
2610
- "div",
2611
- {
2612
- style: {
2613
- display: "flex",
2614
- alignItems: "center",
2615
- padding: "6px 8px",
2616
- background: "#fff",
2617
- border: "1px solid #f0f0f0",
2618
- borderRadius: 4,
2619
- gap: 8
2620
- },
2621
- children: [
2622
- /* @__PURE__ */ e(me, { title: "点击复制", children: /* @__PURE__ */ e(
2623
- we,
2624
- {
2625
- code: !0,
2626
- style: { cursor: "pointer", minWidth: 140, fontSize: 12 },
2627
- onClick: () => l(m.syntax),
2628
- children: m.syntax
2629
- }
2630
- ) }),
2631
- /* @__PURE__ */ e(we, { type: "secondary", style: { fontSize: 12, flex: 1 }, children: m.desc }),
2632
- /* @__PURE__ */ e(v, { color: "default", style: { margin: 0, fontFamily: "monospace" }, children: m.example }),
2633
- /* @__PURE__ */ e(me, { title: "插入到响应模板", children: /* @__PURE__ */ e(
2634
- A,
2635
- {
2636
- size: "small",
2637
- type: "text",
2638
- icon: /* @__PURE__ */ e(bt, {}),
2639
- onClick: () => u(m.syntax)
2640
- }
2641
- ) })
2642
- ]
2643
- }
2644
- ) }, m.syntax)) })
2645
- ] }, y.group))
2646
- ]
2647
- }
2648
- );
2649
- }
2650
- const { TextArea: ot } = B, { Text: pe, Paragraph: En } = le;
2651
- function dr({ open: t, onClose: a, onSuccess: r, envOptions: f = [] }) {
2652
- const [i, u] = x(""), [l, h] = x(null), [g, w] = x(null), [_, y] = x(!1), [m, s] = x(null), [c, k] = x(!1), [$, S] = x("import"), [p] = R.useForm(), [o] = R.useForm(), C = () => {
2653
- u(""), h(null), w(null), s(null), p.resetFields(), o.resetFields();
2654
- }, L = () => {
2655
- C(), a();
2656
- }, G = async () => {
2657
- var E, T, D, Y;
2658
- if (!i.trim()) {
2659
- I.warning("请先粘贴 curl 命令");
2660
- return;
2661
- }
2662
- w(null), h(null), s(null);
2663
- try {
2664
- const F = await j.curl.parse(i);
2665
- F.success ? (h(F.data), p.setFieldsValue({
2666
- caseName: `from-curl-${((E = F.data) == null ? void 0 : E.method) || "GET"}-${(((T = F.data) == null ? void 0 : T.path) || "").replace(/\W+/g, "-")}`,
2667
- caseGroup: "imported",
2668
- envCode: f[0] || "default"
2669
- }), o.setFieldsValue({
2670
- mockName: `mock-${((D = F.data) == null ? void 0 : D.method) || "GET"}-${(((Y = F.data) == null ? void 0 : Y.path) || "").replace(/\W+/g, "-")}`,
2671
- envCode: f[0] || "default",
2672
- projectCode: "default",
2673
- responseTemplate: `{
2674
- "code": 0,
2675
- "message": "ok",
2676
- "data": {}
2677
- }`
2678
- })) : w(F.message || "解析失败");
2679
- } catch (F) {
2680
- w(String((F == null ? void 0 : F.message) || F));
2681
- }
2682
- }, U = async () => {
2683
- if (!i.trim()) {
2684
- I.warning("请先粘贴 curl 命令");
2685
- return;
2686
- }
2687
- y(!0), s(null);
2688
- try {
2689
- const E = await j.curl.run(i);
2690
- s(E);
2691
- } catch (E) {
2692
- s({ success: !1, error: String((E == null ? void 0 : E.message) || E) });
2693
- } finally {
2694
- y(!1);
2695
- }
2696
- }, b = async () => {
2697
- if (!l) {
2698
- I.warning("请先解析");
2699
- return;
2700
- }
2701
- let E;
2702
- try {
2703
- E = await p.validateFields();
2704
- } catch {
2705
- return;
2706
- }
2707
- k(!0);
2708
- try {
2709
- const T = await j.curl.importAsCase({
2710
- curl: i,
2711
- caseName: E.caseName,
2712
- caseGroup: E.caseGroup,
2713
- envCode: E.envCode
2714
- });
2715
- T.success ? (I.success(`已导入测试用例: ${T.caseCode}`), r && r("case", T), L()) : I.error(T.message || "导入失败");
2716
- } catch (T) {
2717
- I.error(String((T == null ? void 0 : T.message) || T));
2718
- } finally {
2719
- k(!1);
2720
- }
2721
- }, d = async () => {
2722
- if (!l) {
2723
- I.warning("请先解析");
2724
- return;
2725
- }
2726
- let E;
2727
- try {
2728
- E = await o.validateFields();
2729
- } catch {
2730
- return;
2731
- }
2732
- k(!0);
2733
- try {
2734
- const T = await j.curl.importAsEndpoint({
2735
- curl: i,
2736
- mockName: E.mockName,
2737
- envCode: E.envCode,
2738
- projectCode: E.projectCode,
2739
- responseTemplate: E.responseTemplate
2740
- });
2741
- T.success ? (I.success(`已导入 Mock 端点: ${T.mockCode}`), r && r("endpoint", T), L()) : I.error(T.message || "导入失败");
2742
- } catch (T) {
2743
- I.error(String((T == null ? void 0 : T.message) || T));
2744
- } finally {
2745
- k(!1);
2746
- }
2747
- };
2748
- return /* @__PURE__ */ n(
2749
- fe,
2750
- {
2751
- title: /* @__PURE__ */ n(z, { children: [
2752
- /* @__PURE__ */ e(Se, {}),
2753
- " 粘贴 curl 一键导入"
2754
- ] }),
2755
- open: t,
2756
- onCancel: L,
2757
- footer: null,
2758
- size: "large",
2759
- destroyOnHidden: !0,
2760
- children: [
2761
- /* @__PURE__ */ e(En, { type: "secondary", style: { marginBottom: 12 }, children: "从浏览器 DevTools / Postman / 终端复制 curl 命令,粘贴到下方即可解析、试跑、入库。" }),
2762
- /* @__PURE__ */ e(
2763
- ot,
2764
- {
2765
- value: i,
2766
- onChange: (E) => u(E.target.value),
2767
- placeholder: `curl -X POST 'https://api.example.com/v1/users/login' \\
2768
- -H 'Content-Type: application/json' \\
2769
- -H 'Authorization: Bearer xxx' \\
2770
- -d '{"username":"alice","password":"123456"}'`,
2771
- autoSize: { minRows: 4, maxRows: 10 },
2772
- style: { fontFamily: "Menlo, Monaco, monospace", fontSize: 12 }
2773
- }
2774
- ),
2775
- /* @__PURE__ */ n(z, { style: { marginTop: 12 }, children: [
2776
- /* @__PURE__ */ e(A, { icon: /* @__PURE__ */ e(Ve, {}), onClick: G, type: "primary", ghost: !0, children: "解析" }),
2777
- /* @__PURE__ */ e(A, { icon: /* @__PURE__ */ e(Ie, {}), onClick: U, loading: _, children: "直接执行(试跑)" })
2778
- ] }),
2779
- g && /* @__PURE__ */ e(J, { type: "error", showIcon: !0, style: { marginTop: 12 }, title: "解析失败", description: g }),
2780
- l && /* @__PURE__ */ e(P, { size: "small", style: { marginTop: 16 }, title: "解析结果", children: /* @__PURE__ */ n(O, { column: 1, size: "small", bordered: !0, children: [
2781
- /* @__PURE__ */ e(O.Item, { label: "Method", children: /* @__PURE__ */ e(v, { color: On(l.method), children: l.method }) }),
2782
- /* @__PURE__ */ e(O.Item, { label: "URL", children: /* @__PURE__ */ e(pe, { code: !0, copyable: !0, children: l.url }) }),
2783
- /* @__PURE__ */ e(O.Item, { label: "Path", children: /* @__PURE__ */ e(pe, { code: !0, children: l.path }) }),
2784
- l.query && /* @__PURE__ */ e(O.Item, { label: "Query", children: /* @__PURE__ */ e(pe, { code: !0, children: l.query }) }),
2785
- /* @__PURE__ */ e(O.Item, { label: "Headers", children: Object.keys(l.headers || {}).length === 0 ? /* @__PURE__ */ e(pe, { type: "secondary", children: "(无)" }) : /* @__PURE__ */ e("div", { children: Object.entries(l.headers).map(([E, T]) => /* @__PURE__ */ n("div", { children: [
2786
- /* @__PURE__ */ n(pe, { strong: !0, children: [
2787
- E,
2788
- ":"
2789
- ] }),
2790
- " ",
2791
- /* @__PURE__ */ e(pe, { code: !0, children: T })
2792
- ] }, E)) }) }),
2793
- l.body && /* @__PURE__ */ e(O.Item, { label: "Body", children: /* @__PURE__ */ e("pre", { style: {
2794
- background: "#f5f5f5",
2795
- padding: 8,
2796
- margin: 0,
2797
- fontSize: 12,
2798
- maxHeight: 200,
2799
- overflow: "auto"
2800
- }, children: l.body }) })
2801
- ] }) }),
2802
- m && /* @__PURE__ */ n(P, { size: "small", style: { marginTop: 16 }, title: /* @__PURE__ */ n(z, { children: [
2803
- /* @__PURE__ */ e(Ie, {}),
2804
- /* @__PURE__ */ e("span", { children: "试跑结果" }),
2805
- m.success ? /* @__PURE__ */ n(v, { color: "green", children: [
2806
- m.status,
2807
- " · ",
2808
- m.durationMs,
2809
- "ms · ",
2810
- m.bodySize,
2811
- "B"
2812
- ] }) : /* @__PURE__ */ e(v, { color: "red", children: "FAILED" })
2813
- ] }), children: [
2814
- m.error && /* @__PURE__ */ e(J, { type: "error", showIcon: !0, title: m.error }),
2815
- m.body != null && /* @__PURE__ */ e("pre", { style: {
2816
- background: "#f5f5f5",
2817
- padding: 8,
2818
- margin: 0,
2819
- fontSize: 12,
2820
- maxHeight: 240,
2821
- overflow: "auto"
2822
- }, children: m.body })
2823
- ] }),
2824
- l && /* @__PURE__ */ e(
2825
- ve,
2826
- {
2827
- activeKey: $,
2828
- onChange: S,
2829
- style: { marginTop: 16 },
2830
- items: [
2831
- {
2832
- key: "import",
2833
- label: /* @__PURE__ */ n("span", { children: [
2834
- /* @__PURE__ */ e(qe, {}),
2835
- " 导入为测试用例"
2836
- ] }),
2837
- children: /* @__PURE__ */ n(R, { form: p, layout: "vertical", children: [
2838
- /* @__PURE__ */ n(Q, { gutter: 16, children: [
2839
- /* @__PURE__ */ e(M, { span: 12, children: /* @__PURE__ */ e(R.Item, { name: "caseName", label: "用例名称", rules: [{ required: !0 }], children: /* @__PURE__ */ e(B, {}) }) }),
2840
- /* @__PURE__ */ e(M, { span: 6, children: /* @__PURE__ */ e(R.Item, { name: "caseGroup", label: "用例分组", children: /* @__PURE__ */ e(B, {}) }) }),
2841
- /* @__PURE__ */ e(M, { span: 6, children: /* @__PURE__ */ e(R.Item, { name: "envCode", label: "环境", children: f.length > 0 ? /* @__PURE__ */ e(X, { options: f.map((E) => ({ value: E, label: E })) }) : /* @__PURE__ */ e(B, {}) }) })
2842
- ] }),
2843
- /* @__PURE__ */ e(
2844
- A,
2845
- {
2846
- type: "primary",
2847
- onClick: b,
2848
- loading: c,
2849
- icon: /* @__PURE__ */ e(qe, {}),
2850
- children: "保存为测试用例"
2851
- }
2852
- )
2853
- ] })
2854
- },
2855
- {
2856
- key: "mock",
2857
- label: /* @__PURE__ */ n("span", { children: [
2858
- /* @__PURE__ */ e(Se, {}),
2859
- " 导入为 Mock 端点"
2860
- ] }),
2861
- children: /* @__PURE__ */ n(R, { form: o, layout: "vertical", children: [
2862
- /* @__PURE__ */ n(Q, { gutter: 16, children: [
2863
- /* @__PURE__ */ e(M, { span: 12, children: /* @__PURE__ */ e(R.Item, { name: "mockName", label: "Mock 名称", rules: [{ required: !0 }], children: /* @__PURE__ */ e(B, {}) }) }),
2864
- /* @__PURE__ */ e(M, { span: 6, children: /* @__PURE__ */ e(R.Item, { name: "envCode", label: "环境", children: f.length > 0 ? /* @__PURE__ */ e(X, { options: f.map((E) => ({ value: E, label: E })) }) : /* @__PURE__ */ e(B, {}) }) }),
2865
- /* @__PURE__ */ e(M, { span: 6, children: /* @__PURE__ */ e(R.Item, { name: "projectCode", label: "项目", children: /* @__PURE__ */ e(B, {}) }) })
2866
- ] }),
2867
- /* @__PURE__ */ e(R.Item, { name: "responseTemplate", label: "响应模板 (JSON)", children: /* @__PURE__ */ e(
2868
- ot,
2869
- {
2870
- autoSize: { minRows: 3, maxRows: 8 },
2871
- style: { fontFamily: "Menlo, Monaco, monospace" }
2872
- }
2873
- ) }),
2874
- /* @__PURE__ */ e(
2875
- A,
2876
- {
2877
- type: "primary",
2878
- onClick: d,
2879
- loading: c,
2880
- icon: /* @__PURE__ */ e(Se, {}),
2881
- children: "保存为 Mock 端点"
2882
- }
2883
- )
2884
- ] })
2885
- }
2886
- ]
2887
- }
2888
- )
2889
- ]
2890
- }
2891
- );
2892
- }
2893
- function On(t) {
2894
- return { GET: "blue", POST: "green", PUT: "orange", DELETE: "red", PATCH: "purple" }[t] || "default";
2895
- }
2896
- const { TextArea: st } = B;
2897
- function ur({ open: t, onClose: a, onSuccess: r, envOptions: f = [] }) {
2898
- const [i, u] = x("paste"), [l, h] = x(""), [g, w] = x(null), [_, y] = x(null), [m, s] = x(!1), [c, k] = x([]), [$, S] = x(!1), [p] = R.useForm(), o = Ke(null), C = () => {
2899
- h(""), w(null), y(null), k([]), p.resetFields();
2900
- }, L = () => {
2901
- C(), a();
2902
- }, G = async () => {
2903
- if (!l.trim()) {
2904
- I.warning("请先粘贴或上传 API 规约");
2905
- return;
2906
- }
2907
- y(null), s(!0);
2908
- try {
2909
- const T = await j.openapi.parse(l);
2910
- T.success ? (w(T), k((T.endpoints || []).map((D, Y) => Y)), p.setFieldsValue({
2911
- envCode: f[0] || "default",
2912
- projectCode: "default",
2913
- defaultResponse: `{
2914
- "code": 0,
2915
- "message": "ok",
2916
- "data": {}
2917
- }`,
2918
- defaultStatus: 200,
2919
- priority: 5,
2920
- tagPrefix: "openapi-import"
2921
- }), I.success(`识别为 ${T.format},共 ${T.count} 个端点`)) : y(T.message || "解析失败");
2922
- } catch (T) {
2923
- y(String((T == null ? void 0 : T.message) || T));
2924
- } finally {
2925
- s(!1);
2926
- }
2927
- }, U = async (T) => {
2928
- try {
2929
- const D = await j.openapi.sample(T);
2930
- D.success && (h(D.content), I.success(`已加载 ${D.format} 示例`));
2931
- } catch (D) {
2932
- I.error("加载示例失败: " + D.message);
2933
- }
2934
- }, b = (T) => {
2935
- const D = new FileReader();
2936
- return D.onload = (Y) => {
2937
- var F;
2938
- h(String(((F = Y.target) == null ? void 0 : F.result) || "")), I.success(`已读取 ${T.name}(${(T.size / 1024).toFixed(1)}KB)`);
2939
- }, D.onerror = () => I.error("文件读取失败"), D.readAsText(T), !1;
2940
- }, d = async () => {
2941
- if (!g) {
2942
- I.warning("请先解析");
2943
- return;
2944
- }
2945
- let T;
2946
- try {
2947
- T = await p.validateFields();
2948
- } catch {
2949
- return;
2950
- }
2951
- S(!0);
2952
- try {
2953
- const D = (g.endpoints || []).map((F, Ze) => ({
2954
- method: F.method,
2955
- path: F.path
2956
- })).filter((F, Ze) => c.includes(Ze)), Y = await j.openapi.importBatch({
2957
- content: l,
2958
- selected: D,
2959
- envCode: T.envCode,
2960
- projectCode: T.projectCode,
2961
- defaultResponse: T.defaultResponse,
2962
- defaultStatus: T.defaultStatus,
2963
- priority: T.priority,
2964
- tagPrefix: T.tagPrefix
2965
- });
2966
- Y.success ? (I.success(`已导入 ${Y.imported} 个 Mock 端点${Y.failed > 0 ? `,失败 ${Y.failed}` : ""}`), r && r(Y), L()) : I.error(Y.message || "导入失败");
2967
- } catch (D) {
2968
- I.error(String((D == null ? void 0 : D.message) || D));
2969
- } finally {
2970
- S(!1);
2971
- }
2972
- }, E = [
2973
- {
2974
- title: "Method",
2975
- dataIndex: "method",
2976
- width: 90,
2977
- render: (T) => /* @__PURE__ */ e(v, { color: Pn(T), children: T })
2978
- },
2979
- { title: "Path", dataIndex: "path", width: 240, ellipsis: !0 },
2980
- { title: "Summary", dataIndex: "summary", ellipsis: !0 },
2981
- {
2982
- title: "Tags",
2983
- dataIndex: "tags",
2984
- width: 160,
2985
- render: (T) => (T || []).map((D) => /* @__PURE__ */ e(v, { children: D }, D))
2986
- },
2987
- {
2988
- title: "Params",
2989
- dataIndex: "parameters",
2990
- width: 80,
2991
- render: (T) => (T == null ? void 0 : T.length) || 0,
2992
- align: "center"
2993
- },
2994
- {
2995
- // `ApiSpecParser.ParsedEndpoint` 是 **POJO**(public 字段)⇒ 被全局 SNAKE_CASE 改名
2996
- title: "示例",
2997
- dataIndex: "response_example",
2998
- width: 80,
2999
- render: (T) => T ? /* @__PURE__ */ e(v, { color: "green", children: "有" }) : /* @__PURE__ */ e(v, { children: "无" })
3000
- }
3001
- ];
3002
- return /* @__PURE__ */ n(
3003
- fe,
3004
- {
3005
- title: /* @__PURE__ */ n(z, { children: [
3006
- /* @__PURE__ */ e(et, {}),
3007
- " 批量导入 API 规约"
3008
- ] }),
3009
- open: t,
3010
- onCancel: L,
3011
- footer: null,
3012
- size: "large",
3013
- destroyOnHidden: !0,
3014
- children: [
3015
- /* @__PURE__ */ e(
3016
- ve,
3017
- {
3018
- activeKey: i,
3019
- onChange: u,
3020
- items: [
3021
- {
3022
- key: "paste",
3023
- label: /* @__PURE__ */ n("span", { children: [
3024
- /* @__PURE__ */ e(Ve, {}),
3025
- " 粘贴 JSON"
3026
- ] }),
3027
- children: /* @__PURE__ */ n("div", { children: [
3028
- /* @__PURE__ */ e(
3029
- st,
3030
- {
3031
- value: l,
3032
- onChange: (T) => h(T.target.value),
3033
- placeholder: "粘贴 OpenAPI 3.x / Swagger 2.0 / Postman v2.1 JSON 内容…",
3034
- autoSize: { minRows: 6, maxRows: 16 },
3035
- style: { fontFamily: "Menlo, Monaco, monospace", fontSize: 12 }
3036
- }
3037
- ),
3038
- /* @__PURE__ */ n(z, { style: { marginTop: 8 }, children: [
3039
- /* @__PURE__ */ e(A, { size: "small", onClick: () => U("openapi3"), children: "加载 OpenAPI 3 示例" }),
3040
- /* @__PURE__ */ e(A, { size: "small", onClick: () => U("swagger2"), children: "加载 Swagger 2 示例" }),
3041
- /* @__PURE__ */ e(A, { size: "small", onClick: () => U("postman"), children: "加载 Postman 示例" })
3042
- ] })
3043
- ] })
3044
- },
3045
- {
3046
- key: "upload",
3047
- label: /* @__PURE__ */ n("span", { children: [
3048
- /* @__PURE__ */ e(qt, {}),
3049
- " 上传文件"
3050
- ] }),
3051
- children: /* @__PURE__ */ n(
3052
- Rt.Dragger,
3053
- {
3054
- ref: o,
3055
- accept: ".json,.yaml,.yml,application/json,text/yaml",
3056
- beforeUpload: b,
3057
- showUploadList: !1,
3058
- style: { padding: 24 },
3059
- children: [
3060
- /* @__PURE__ */ e("p", { className: "ant-upload-drag-icon", children: /* @__PURE__ */ e(et, { style: { fontSize: 48, color: "#1890ff" } }) }),
3061
- /* @__PURE__ */ e("p", { className: "ant-upload-text", children: "点击或拖拽 JSON / YAML 文件到此处" }),
3062
- /* @__PURE__ */ e("p", { className: "ant-upload-hint", children: "支持 OpenAPI 3.x / Swagger 2.0 / Postman v2.1" })
3063
- ]
3064
- }
3065
- )
3066
- }
3067
- ]
3068
- }
3069
- ),
3070
- /* @__PURE__ */ n(z, { style: { marginTop: 12 }, children: [
3071
- /* @__PURE__ */ e(A, { type: "primary", icon: /* @__PURE__ */ e(Ie, {}), onClick: G, loading: m, children: "解析" }),
3072
- g && /* @__PURE__ */ e(v, { color: "blue", children: g.format }),
3073
- g && /* @__PURE__ */ n(v, { children: [
3074
- "共 ",
3075
- g.count,
3076
- " 个端点,已选 ",
3077
- c.length
3078
- ] })
3079
- ] }),
3080
- _ && /* @__PURE__ */ e(J, { type: "error", showIcon: !0, style: { marginTop: 12 }, title: "解析失败", description: _ }),
3081
- g && /* @__PURE__ */ e(P, { size: "small", style: { marginTop: 16 }, title: "预览(可勾选要导入的)", children: /* @__PURE__ */ e(
3082
- K,
3083
- {
3084
- size: "small",
3085
- dataSource: g.endpoints || [],
3086
- columns: E,
3087
- rowKey: (T, D) => D,
3088
- rowSelection: {
3089
- selectedRowKeys: c,
3090
- onChange: k
3091
- },
3092
- pagination: { pageSize: 8 },
3093
- scroll: { y: 280 }
3094
- }
3095
- ) }),
3096
- g && /* @__PURE__ */ e(P, { size: "small", style: { marginTop: 16 }, title: "导入配置", children: /* @__PURE__ */ n(R, { form: p, layout: "vertical", children: [
3097
- /* @__PURE__ */ n(Q, { gutter: 16, children: [
3098
- /* @__PURE__ */ e(M, { span: 6, children: /* @__PURE__ */ e(R.Item, { name: "envCode", label: "环境", rules: [{ required: !0 }], children: f.length > 0 ? /* @__PURE__ */ e(X, { options: f.map((T) => ({ value: T, label: T })) }) : /* @__PURE__ */ e(B, {}) }) }),
3099
- /* @__PURE__ */ e(M, { span: 6, children: /* @__PURE__ */ e(R.Item, { name: "projectCode", label: "项目", children: /* @__PURE__ */ e(B, {}) }) }),
3100
- /* @__PURE__ */ e(M, { span: 4, children: /* @__PURE__ */ e(R.Item, { name: "defaultStatus", label: "默认状态码", children: /* @__PURE__ */ e(B, { type: "number" }) }) }),
3101
- /* @__PURE__ */ e(M, { span: 4, children: /* @__PURE__ */ e(R.Item, { name: "priority", label: "优先级", children: /* @__PURE__ */ e(B, { type: "number" }) }) }),
3102
- /* @__PURE__ */ e(M, { span: 4, children: /* @__PURE__ */ e(R.Item, { name: "tagPrefix", label: "Tag 前缀", children: /* @__PURE__ */ e(B, {}) }) })
3103
- ] }),
3104
- /* @__PURE__ */ e(R.Item, { name: "defaultResponse", label: "默认响应(无 example 时使用)", children: /* @__PURE__ */ e(
3105
- st,
3106
- {
3107
- autoSize: { minRows: 3, maxRows: 6 },
3108
- style: { fontFamily: "Menlo, Monaco, monospace" }
3109
- }
3110
- ) }),
3111
- /* @__PURE__ */ n(
3112
- A,
3113
- {
3114
- type: "primary",
3115
- size: "large",
3116
- icon: /* @__PURE__ */ e(qe, {}),
3117
- onClick: d,
3118
- loading: $,
3119
- disabled: c.length === 0,
3120
- children: [
3121
- "批量导入 ",
3122
- c.length,
3123
- " 个端点"
3124
- ]
3125
- }
3126
- )
3127
- ] }) })
3128
- ]
3129
- }
3130
- );
3131
- }
3132
- function Pn(t) {
3133
- return { GET: "blue", POST: "green", PUT: "orange", DELETE: "red", PATCH: "purple" }[t] || "default";
3134
- }
3135
- const Mn = {
3136
- STANDARD_JSON: { label: "标准 JSON", color: "blue" },
3137
- RSS_XML: { label: "RSS 2.0", color: "orange" },
3138
- ATOM_XML: { label: "Atom 1.0", color: "gold" },
3139
- CUSTOM_SCRIPT: { label: "自定义脚本", color: "purple" },
3140
- INTERNAL_BEAN: { label: "内部 Bean", color: "cyan" }
3141
- }, Ln = {
3142
- PENDING_VERIFY: { color: "default", text: "待验证" },
3143
- VERIFIED: { color: "green", text: "已验证" },
3144
- INVALID_AUTH: { color: "red", text: "鉴权失败" },
3145
- FATAL: { color: "red", text: "永久失败" },
3146
- DISABLED: { color: "default", text: "已停用" }
3147
- }, ct = {
3148
- PENDING: { color: "default" },
3149
- RUNNING: { color: "processing" },
3150
- SUCCESS: { color: "green" },
3151
- EMPTY: { color: "default" },
3152
- FAILED: { color: "red" },
3153
- FATAL: { color: "red" }
3154
- };
3155
- function $n() {
3156
- const t = be(), [a, r] = x([]), [f, i] = x(!1), [u, l] = x(null), [h, g] = x([]), [w, _] = x({}), [y, m] = x(null), [s, c] = x([]), k = async () => {
3157
- i(!0);
3158
- try {
3159
- const b = await N.get("/subscribe/subscription/list");
3160
- b && b.success !== !1 && r(Array.isArray(b.data) ? b.data : Array.isArray(b) ? b : []);
3161
- } catch (b) {
3162
- I.error("获取订阅列表失败: " + ((b == null ? void 0 : b.message) || ""));
3163
- } finally {
3164
- i(!1);
3165
- }
3166
- };
3167
- W(() => {
3168
- k();
3169
- }, []);
3170
- const $ = (b) => {
3171
- fe.confirm({
3172
- title: "确认删除",
3173
- icon: /* @__PURE__ */ e(ft, {}),
3174
- content: `确定要删除订阅 "${b.name}" 吗? 运行历史会保留.`,
3175
- onOk: async () => {
3176
- try {
3177
- const d = await N.delete(`/subscribe/subscription/${b.id}`);
3178
- d && d.success !== !1 ? (I.success("删除成功"), k()) : I.error((d == null ? void 0 : d.message) || "删除失败");
3179
- } catch (d) {
3180
- I.error("删除失败: " + ((d == null ? void 0 : d.message) || ""));
3181
- }
3182
- }
3183
- });
3184
- }, S = async (b) => {
3185
- try {
3186
- const d = await N.post(`/subscribe/subscription/${b}/enable`);
3187
- d && d.success !== !1 ? (I.success("已启用"), k()) : I.error((d == null ? void 0 : d.message) || "启用失败");
3188
- } catch (d) {
3189
- I.error("启用失败: " + ((d == null ? void 0 : d.message) || ""));
3190
- }
3191
- }, p = async (b) => {
3192
- try {
3193
- const d = await N.post(`/subscribe/subscription/${b}/disable`);
3194
- d && d.success !== !1 ? (I.success("已停用"), k()) : I.error((d == null ? void 0 : d.message) || "停用失败");
3195
- } catch (d) {
3196
- I.error("停用失败: " + ((d == null ? void 0 : d.message) || ""));
3197
- }
3198
- }, o = async (b) => {
3199
- fe.confirm({
3200
- title: "手动触发",
3201
- content: `将立即执行一次 "${b.name}" 的抽取, 同步返回 runId.`,
3202
- onOk: async () => {
3203
- try {
3204
- const d = await N.post(`/subscribe/subscription/${b.id}/trigger?triggerBy=ceo`);
3205
- if (d && (d.data !== void 0 || d.success !== !1)) {
3206
- const E = d.data ?? d;
3207
- I.success(`已触发, runId = ${E}`), L(b);
3208
- } else
3209
- I.error((d == null ? void 0 : d.message) || "触发失败");
3210
- } catch (d) {
3211
- I.error("触发失败: " + ((d == null ? void 0 : d.message) || ""));
3212
- }
3213
- }
3214
- });
3215
- }, C = async (b) => {
3216
- try {
3217
- const d = await N.post(`/subscribe/subscription/${b.id}/dry-run`);
3218
- l({ sub: b, result: (d == null ? void 0 : d.data) ?? d });
3219
- } catch (d) {
3220
- l({ sub: b, result: { success: !1, errorMessage: (d == null ? void 0 : d.message) || "请求失败" } });
3221
- }
3222
- }, L = async (b) => {
3223
- try {
3224
- const d = await N.get(`/subscribe/run/list?subscriptionId=${b.id}&limit=20`), E = (d == null ? void 0 : d.data) ?? d ?? [];
3225
- g(Array.isArray(E) ? E : []), m(null), _({}), c([]), l({ sub: b, tab: "runs" });
3226
- } catch {
3227
- I.error("获取运行历史失败");
3228
- }
3229
- }, G = async (b) => {
3230
- if (w[b]) {
3231
- m(b);
3232
- return;
3233
- }
3234
- try {
3235
- const d = await N.get(`/subscribe/run/${b}/items?limit=200`), E = (d == null ? void 0 : d.data) ?? d ?? [];
3236
- _((T) => ({ ...T, [b]: Array.isArray(E) ? E : [] })), m(b);
3237
- } catch {
3238
- I.error("获取抽取项失败");
3239
- }
3240
- };
3241
- return /* @__PURE__ */ n("div", { children: [
3242
- /* @__PURE__ */ e(
3243
- xe,
3244
- {
3245
- title: "订阅中心 - 数据源订阅",
3246
- subtitle: "负责把三方 / 内部 / RSS 等数据源按 Cron 定时抽取, 归一化后落到本地"
3247
- }
3248
- ),
3249
- /* @__PURE__ */ n(P, { extra: /* @__PURE__ */ n(z, { children: [
3250
- /* @__PURE__ */ e(A, { icon: /* @__PURE__ */ e(ee, {}), onClick: k, children: "刷新" }),
3251
- /* @__PURE__ */ e(
3252
- A,
3253
- {
3254
- type: "primary",
3255
- icon: /* @__PURE__ */ e(St, {}),
3256
- onClick: () => t("/subscribe/new"),
3257
- children: "新建订阅"
3258
- }
3259
- )
3260
- ] }), children: [
3261
- /* @__PURE__ */ e(
3262
- J,
3263
- {
3264
- type: "info",
3265
- showIcon: !0,
3266
- style: { marginBottom: 16 },
3267
- message: "订阅中心负责把三方 / 内部 / RSS 等数据源按 Cron 定时抽取, 归一化后落到本地, 供 CEO 立项和 Agent 协作使用."
3268
- }
3269
- ),
3270
- /* @__PURE__ */ e(
3271
- K,
3272
- {
3273
- rowKey: "id",
3274
- columns: [
3275
- {
3276
- title: "ID",
3277
- dataIndex: "id",
3278
- width: 70
3279
- },
3280
- {
3281
- title: "名称",
3282
- dataIndex: "name",
3283
- render: (b, d) => /* @__PURE__ */ n(z, { orientation: "vertical", size: 0, children: [
3284
- /* @__PURE__ */ e("span", { style: { fontWeight: 500 }, children: b }),
3285
- d.description && /* @__PURE__ */ e("span", { style: { color: "#999", fontSize: 12 }, children: d.description })
3286
- ] })
3287
- },
3288
- {
3289
- title: "数据源",
3290
- dataIndex: "sourceType",
3291
- width: 90,
3292
- render: (b) => /* @__PURE__ */ e(v, { children: b })
3293
- },
3294
- {
3295
- title: "抽取器",
3296
- dataIndex: "extractorType",
3297
- width: 140,
3298
- render: (b) => {
3299
- const d = Mn[b] || { label: b, color: "default" };
3300
- return /* @__PURE__ */ e(v, { color: d.color, children: d.label });
3301
- }
3302
- },
3303
- {
3304
- title: "Cron",
3305
- dataIndex: "cronExpr",
3306
- width: 150,
3307
- render: (b) => /* @__PURE__ */ e("code", { style: { fontSize: 12 }, children: b })
3308
- },
3309
- {
3310
- title: "状态",
3311
- dataIndex: "status",
3312
- width: 110,
3313
- render: (b) => {
3314
- const d = Ln[b] || { color: "default", text: b };
3315
- return /* @__PURE__ */ e(v, { color: d.color, children: d.text });
3316
- }
3317
- },
3318
- {
3319
- title: "启用",
3320
- dataIndex: "enabled",
3321
- width: 80,
3322
- render: (b, d) => b ? /* @__PURE__ */ e(v, { color: "green", children: "是" }) : /* @__PURE__ */ e(v, { children: "否" })
3323
- },
3324
- {
3325
- title: "最近 run",
3326
- dataIndex: "lastStatus",
3327
- width: 110,
3328
- render: (b, d) => {
3329
- var E;
3330
- return b ? /* @__PURE__ */ e(me, { title: d.lastError || "", children: /* @__PURE__ */ e(v, { color: ((E = ct[b]) == null ? void 0 : E.color) || "default", children: b }) }) : /* @__PURE__ */ e("span", { style: { color: "#ccc" }, children: "-" });
3331
- }
3332
- },
3333
- {
3334
- title: "累计",
3335
- width: 130,
3336
- render: (b, d) => /* @__PURE__ */ n(z, { size: 4, children: [
3337
- /* @__PURE__ */ n(v, { color: "green", children: [
3338
- "✓ ",
3339
- d.successCountTotal || 0
3340
- ] }),
3341
- /* @__PURE__ */ n(v, { color: "red", children: [
3342
- "✗ ",
3343
- d.failCountTotal || 0
3344
- ] })
3345
- ] })
3346
- },
3347
- {
3348
- title: "操作",
3349
- width: 280,
3350
- fixed: "right",
3351
- render: (b, d) => /* @__PURE__ */ n(z, { size: 4, wrap: !0, children: [
3352
- /* @__PURE__ */ e(
3353
- A,
3354
- {
3355
- type: "link",
3356
- size: "small",
3357
- icon: /* @__PURE__ */ e(Ut, {}),
3358
- onClick: () => t(`/subscribe/edit/${d.id}`),
3359
- children: "编辑"
3360
- }
3361
- ),
3362
- /* @__PURE__ */ e(
3363
- A,
3364
- {
3365
- type: "link",
3366
- size: "small",
3367
- icon: /* @__PURE__ */ e(Ie, {}),
3368
- onClick: () => C(d),
3369
- children: "试运行"
3370
- }
3371
- ),
3372
- /* @__PURE__ */ e(
3373
- A,
3374
- {
3375
- type: "link",
3376
- size: "small",
3377
- icon: /* @__PURE__ */ e(Me, {}),
3378
- onClick: () => o(d),
3379
- children: "触发"
3380
- }
3381
- ),
3382
- /* @__PURE__ */ e(
3383
- A,
3384
- {
3385
- type: "link",
3386
- size: "small",
3387
- onClick: () => L(d),
3388
- children: "历史"
3389
- }
3390
- ),
3391
- d.enabled ? /* @__PURE__ */ e(
3392
- A,
3393
- {
3394
- type: "link",
3395
- size: "small",
3396
- icon: /* @__PURE__ */ e(Ht, {}),
3397
- onClick: () => p(d.id),
3398
- children: "停用"
3399
- }
3400
- ) : /* @__PURE__ */ e(
3401
- A,
3402
- {
3403
- type: "link",
3404
- size: "small",
3405
- icon: /* @__PURE__ */ e(Je, {}),
3406
- onClick: () => S(d.id),
3407
- children: "启用"
3408
- }
3409
- ),
3410
- /* @__PURE__ */ e(We, { title: "确认删除?", onConfirm: () => $(d), okText: "删除", cancelText: "取消", children: /* @__PURE__ */ e(A, { type: "link", size: "small", danger: !0, icon: /* @__PURE__ */ e(Kt, {}), children: "删除" }) })
3411
- ] })
3412
- }
3413
- ],
3414
- dataSource: a,
3415
- loading: f,
3416
- scroll: { x: 1400 },
3417
- size: "middle",
3418
- pagination: { pageSize: 20, showSizeChanger: !0, showTotal: (b) => `共 ${b} 条` }
3419
- }
3420
- )
3421
- ] }),
3422
- /* @__PURE__ */ e(
3423
- ke,
3424
- {
3425
- title: u != null && u.sub ? `试运行 - ${u.sub.name}` : "运行历史",
3426
- open: !!u,
3427
- onClose: () => l(null),
3428
- size: "large",
3429
- children: (u == null ? void 0 : u.tab) === "runs" ? /* @__PURE__ */ e(
3430
- ve,
3431
- {
3432
- activeKey: y ? "items" : "list",
3433
- onChange: (b) => b === "list" && m(null),
3434
- items: [
3435
- {
3436
- key: "list",
3437
- label: `运行列表 (${h.length})`,
3438
- children: /* @__PURE__ */ e(
3439
- K,
3440
- {
3441
- rowKey: "id",
3442
- size: "small",
3443
- dataSource: h,
3444
- pagination: !1,
3445
- onRow: (b) => ({ onClick: () => G(b.id) }),
3446
- columns: [
3447
- { title: "runId", dataIndex: "id", width: 70 },
3448
- {
3449
- title: "计划",
3450
- dataIndex: "scheduledAt",
3451
- width: 160,
3452
- render: (b) => b ? new Date(b).toLocaleString() : "-"
3453
- },
3454
- { title: "耗时(ms)", dataIndex: "durationMs", width: 90 },
3455
- {
3456
- title: "状态",
3457
- dataIndex: "status",
3458
- width: 90,
3459
- render: (b) => {
3460
- var d;
3461
- return /* @__PURE__ */ e(v, { color: (d = ct[b]) == null ? void 0 : d.color, children: b });
3462
- }
3463
- },
3464
- {
3465
- title: "拉取/成功/重复/死信",
3466
- width: 200,
3467
- render: (b, d) => `${d.fetchedCount} / ${d.successCount} / ${d.duplicateCount || 0} / ${d.deadLetterCount}`
3468
- },
3469
- {
3470
- title: "错误",
3471
- dataIndex: "errorMessage",
3472
- render: (b) => b ? /* @__PURE__ */ e("span", { style: { color: "#cf1322", fontSize: 12 }, children: b }) : "-"
3473
- }
3474
- ]
3475
- }
3476
- )
3477
- },
3478
- {
3479
- key: "items",
3480
- label: y ? `run#${y} 抽取项` : "抽取项",
3481
- disabled: !y,
3482
- children: /* @__PURE__ */ n(z, { orientation: "vertical", style: { width: "100%" }, children: [
3483
- /* @__PURE__ */ n(z, { children: [
3484
- /* @__PURE__ */ n(v, { color: "blue", children: [
3485
- "已选 ",
3486
- s.length,
3487
- " 条"
3488
- ] }),
3489
- /* @__PURE__ */ n(
3490
- A,
3491
- {
3492
- size: "small",
3493
- type: "primary",
3494
- icon: /* @__PURE__ */ e(Pe, {}),
3495
- disabled: s.length === 0,
3496
- onClick: () => {
3497
- const b = s.join(",");
3498
- t(`/project/new?subscriptionId=${u.sub.id}&itemIds=${b}`);
3499
- },
3500
- children: [
3501
- "用所选 ",
3502
- s.length,
3503
- " 条立项"
3504
- ]
3505
- }
3506
- )
3507
- ] }),
3508
- /* @__PURE__ */ e(
3509
- K,
3510
- {
3511
- rowKey: "id",
3512
- size: "small",
3513
- dataSource: w[y] || [],
3514
- pagination: { pageSize: 20 },
3515
- rowSelection: {
3516
- selectedRowKeys: s,
3517
- onChange: c
3518
- },
3519
- columns: [
3520
- { title: "id", dataIndex: "dedupKey", width: 180, ellipsis: !0 },
3521
- {
3522
- title: "title",
3523
- dataIndex: "normalized",
3524
- render: (b) => {
3525
- try {
3526
- return JSON.parse(b).title || "(无标题)";
3527
- } catch {
3528
- return b;
3529
- }
3530
- }
3531
- },
3532
- {
3533
- title: "link",
3534
- dataIndex: "normalized",
3535
- render: (b) => {
3536
- try {
3537
- const d = JSON.parse(b);
3538
- return d.link ? /* @__PURE__ */ e("a", { href: d.link, target: "_blank", children: "↗" }) : "-";
3539
- } catch {
3540
- return "-";
3541
- }
3542
- }
3543
- },
3544
- {
3545
- title: "状态",
3546
- dataIndex: "status",
3547
- width: 110,
3548
- render: (b) => /* @__PURE__ */ e(v, { children: b })
3549
- }
3550
- ]
3551
- }
3552
- )
3553
- ] })
3554
- }
3555
- ]
3556
- }
3557
- ) : /* @__PURE__ */ e(Nn, { result: u == null ? void 0 : u.result })
3558
- }
3559
- )
3560
- ] });
3561
- }
3562
- function Nn({ result: t }) {
3563
- return t ? t.success ? /* @__PURE__ */ n(z, { orientation: "vertical", style: { width: "100%" }, size: "middle", children: [
3564
- /* @__PURE__ */ e(P, { size: "small", title: "调用结果", children: /* @__PURE__ */ n(z, { size: "large", wrap: !0, children: [
3565
- /* @__PURE__ */ n("span", { children: [
3566
- /* @__PURE__ */ e("b", { children: "HTTP:" }),
3567
- " ",
3568
- t.httpStatus || "-"
3569
- ] }),
3570
- /* @__PURE__ */ n("span", { children: [
3571
- /* @__PURE__ */ e("b", { children: "耗时:" }),
3572
- " ",
3573
- t.latencyMs,
3574
- "ms"
3575
- ] }),
3576
- /* @__PURE__ */ n("span", { children: [
3577
- /* @__PURE__ */ e("b", { children: "大小:" }),
3578
- " ",
3579
- t.responseSize,
3580
- "B"
3581
- ] }),
3582
- /* @__PURE__ */ n("span", { children: [
3583
- /* @__PURE__ */ e("b", { children: "样本:" }),
3584
- " ",
3585
- t.sampleCount,
3586
- " 条"
3587
- ] })
3588
- ] }) }),
3589
- t.firstItem && /* @__PURE__ */ e(P, { size: "small", title: "第一条样本 (归一化后)", children: /* @__PURE__ */ e(
3590
- "pre",
3591
- {
3592
- style: { background: "#f5f5f5", padding: 12, borderRadius: 4, maxHeight: 300, overflow: "auto" },
3593
- children: JSON.stringify(t.firstItem, null, 2)
3594
- }
3595
- ) }),
3596
- t.responsePreview && /* @__PURE__ */ e(P, { size: "small", title: "响应预览 (前 4KB)", children: /* @__PURE__ */ e("pre", { style: {
3597
- background: "#f5f5f5",
3598
- padding: 12,
3599
- borderRadius: 4,
3600
- maxHeight: 300,
3601
- overflow: "auto",
3602
- fontSize: 12
3603
- }, children: t.responsePreview }) }),
3604
- t.fieldErrors && t.fieldErrors.length > 0 && /* @__PURE__ */ e(J, { type: "warning", showIcon: !0, message: "字段问题", description: /* @__PURE__ */ e("ul", { children: t.fieldErrors.map((a, r) => /* @__PURE__ */ e("li", { children: a }, r)) }) })
3605
- ] }) : /* @__PURE__ */ e(J, { type: "error", showIcon: !0, title: "试运行失败", description: t.errorMessage || "未知错误" }) : null;
3606
- }
3607
- const Dn = [
3608
- { value: "STANDARD_JSON", label: "标准 JSON (按统一契约返回的 JSON)" },
3609
- { value: "RSS_XML", label: "RSS 2.0 (XML feed)" },
3610
- { value: "ATOM_XML", label: "Atom 1.0 (XML feed)" },
3611
- { value: "CUSTOM_SCRIPT", label: "自定义脚本 (z-script 平台)" },
3612
- { value: "INTERNAL_BEAN", label: "内部 Bean (我们自己的模块, 暂未启用)" }
3613
- ], Bn = [
3614
- { value: "NONE", label: "无鉴权" },
3615
- { value: "BEARER", label: "Bearer (Authorization: Bearer xxx)" },
3616
- { value: "API_KEY", label: "API Key (Authorization: xxx)" },
3617
- { value: "BASIC", label: "Basic (user:password base64)" }
3618
- ], jn = [
3619
- { label: "每 5 分钟", value: "0 */5 * * * ?" },
3620
- { label: "每 15 分钟", value: "0 */15 * * * ?" },
3621
- { label: "每小时", value: "0 0 * * * ?" },
3622
- { label: "每 6 小时", value: "0 0 */6 * * ?" },
3623
- { label: "每天 8 点", value: "0 0 8 * * ?" }
3624
- ];
3625
- function dt() {
3626
- const { id: t } = ht(), a = be(), r = !!t, [f] = R.useForm(), [i, u] = x(!1), [l, h] = x(!1), [g, w] = x([]), [_, y] = x([]), m = R.useWatch("sourceType", f), s = R.useWatch("extractorType", f), c = R.useWatch("authType", f);
3627
- W(() => {
3628
- k(), $(), r && S();
3629
- }, [t]);
3630
- const k = async () => {
3631
- try {
3632
- const o = await N.get("/secret/list"), C = (o == null ? void 0 : o.data) ?? o ?? [];
3633
- w(Array.isArray(C) ? C : []);
3634
- } catch {
3635
- }
3636
- }, $ = async () => {
3637
- try {
3638
- const o = await N.get("/script/list"), C = (o == null ? void 0 : o.data) ?? o ?? [];
3639
- y(Array.isArray(C) ? C.filter((L) => L.status === 1) : []);
3640
- } catch {
3641
- }
3642
- }, S = async () => {
3643
- u(!0);
3644
- try {
3645
- const o = await N.get(`/subscribe/subscription/${t}`), C = (o == null ? void 0 : o.data) ?? o;
3646
- C && f.setFieldsValue({
3647
- ...C,
3648
- enabled: C.enabled === 1 || C.enabled === !0
3649
- });
3650
- } catch (o) {
3651
- I.error("加载订阅失败: " + ((o == null ? void 0 : o.message) || ""));
3652
- } finally {
3653
- u(!1);
3654
- }
3655
- }, p = async () => {
3656
- try {
3657
- const o = await f.validateFields();
3658
- h(!0);
3659
- const C = {
3660
- ...o,
3661
- enabled: o.enabled ? 1 : 0
3662
- };
3663
- let L;
3664
- if (r ? L = await N.put("/subscribe/subscription", C) : L = await N.post("/subscribe/subscription", C), L && L.success === !1) {
3665
- I.error(L.message || "保存失败");
3666
- return;
3667
- }
3668
- I.success(r ? "已更新 (注意: 修改 cron / url / 抽取器后会自动重置为 PENDING_VERIFY)" : "已创建, 已自动验证"), a("/subscribe/list");
3669
- } catch (o) {
3670
- o != null && o.errorFields ? I.warning("请检查表单") : I.error("保存失败: " + ((o == null ? void 0 : o.message) || ""));
3671
- } finally {
3672
- h(!1);
3673
- }
3674
- };
3675
- return /* @__PURE__ */ n("div", { style: { padding: 24 }, children: [
3676
- /* @__PURE__ */ e(
3677
- xe,
3678
- {
3679
- title: r ? `编辑订阅 #${t}` : "新建订阅",
3680
- subtitle: "配置数据源、抽取器、鉴权与调度策略",
3681
- back: !0,
3682
- extra: /* @__PURE__ */ n(z, { children: [
3683
- /* @__PURE__ */ e(A, { onClick: () => a("/subscribe/list"), children: "取消" }),
3684
- /* @__PURE__ */ e(A, { type: "primary", icon: /* @__PURE__ */ e(It, {}), loading: l, onClick: p, children: "保存 (自动验证)" })
3685
- ] })
3686
- }
3687
- ),
3688
- /* @__PURE__ */ e(P, { children: /* @__PURE__ */ e(Oe, { spinning: i, children: /* @__PURE__ */ n(
3689
- R,
3690
- {
3691
- form: f,
3692
- layout: "vertical",
3693
- initialValues: {
3694
- sourceType: "HTTP",
3695
- httpMethod: "GET",
3696
- authType: "NONE",
3697
- extractorType: "STANDARD_JSON",
3698
- enabled: !0,
3699
- minIntervalSec: 60,
3700
- maxItemsPerRun: 1e3,
3701
- timeoutMs: 15e3
3702
- },
3703
- children: [
3704
- /* @__PURE__ */ n(P, { type: "inner", title: "基本信息", style: { marginBottom: 16 }, children: [
3705
- /* @__PURE__ */ e(R.Item, { label: "名称", name: "name", rules: [{ required: !0, message: "请输入名称" }], children: /* @__PURE__ */ e(B, { placeholder: "例如: GitHub PR 通知" }) }),
3706
- /* @__PURE__ */ e(R.Item, { label: "说明", name: "description", children: /* @__PURE__ */ e(B.TextArea, { rows: 2, placeholder: "(可选)" }) })
3707
- ] }),
3708
- /* @__PURE__ */ n(P, { type: "inner", title: "数据源", style: { marginBottom: 16 }, children: [
3709
- /* @__PURE__ */ e(R.Item, { label: "数据源形态", name: "sourceType", rules: [{ required: !0 }], children: /* @__PURE__ */ n(ne.Group, { children: [
3710
- /* @__PURE__ */ e(ne.Button, { value: "HTTP", children: "HTTP / HTTPS" }),
3711
- /* @__PURE__ */ e(ne.Button, { value: "INTERNAL", disabled: !0, children: "内部 Bean" })
3712
- ] }) }),
3713
- m === "HTTP" && /* @__PURE__ */ n(Be, { children: [
3714
- /* @__PURE__ */ e(
3715
- R.Item,
3716
- {
3717
- label: "目标 URL",
3718
- name: "targetUrl",
3719
- rules: [{ required: !0, message: "请输入 URL" }],
3720
- children: /* @__PURE__ */ e(B, { placeholder: "https://api.github.com/repos/.../pulls?state=open" })
3721
- }
3722
- ),
3723
- /* @__PURE__ */ n(z, { size: "large", style: { width: "100%" }, children: [
3724
- /* @__PURE__ */ e(R.Item, { label: "HTTP 方法", name: "httpMethod", children: /* @__PURE__ */ e(X, { style: { width: 120 }, options: [
3725
- { value: "GET", label: "GET" },
3726
- { value: "POST", label: "POST" },
3727
- { value: "PUT", label: "PUT" }
3728
- ] }) }),
3729
- /* @__PURE__ */ e(R.Item, { label: "超时 (ms)", name: "timeoutMs", children: /* @__PURE__ */ e($e, { min: 1e3, max: 12e4, step: 1e3 }) })
3730
- ] }),
3731
- /* @__PURE__ */ e(R.Item, { label: "自定义 HTTP 头 (JSON)", name: "httpHeaders", children: /* @__PURE__ */ e(B.TextArea, { rows: 2, placeholder: '{"X-Trace-Id":"abc"}' }) }),
3732
- /* @__PURE__ */ e(R.Item, { label: "请求体 (POST/PUT)", name: "requestBody", children: /* @__PURE__ */ e(B.TextArea, { rows: 3, placeholder: "(可选)" }) })
3733
- ] })
3734
- ] }),
3735
- /* @__PURE__ */ n(P, { type: "inner", title: "鉴权 (从 z-mist 拉取 secret)", style: { marginBottom: 16 }, children: [
3736
- /* @__PURE__ */ e(R.Item, { label: "鉴权方式", name: "authType", children: /* @__PURE__ */ e(X, { options: Bn }) }),
3737
- c && c !== "NONE" && /* @__PURE__ */ e(
3738
- R.Item,
3739
- {
3740
- label: "z-mist 凭据引用",
3741
- name: "authSecretKey",
3742
- extra: "从密钥中心 (z-mist) 选一个 secret; secret 的解密值会作为 secret 注入",
3743
- children: /* @__PURE__ */ e(
3744
- X,
3745
- {
3746
- showSearch: !0,
3747
- allowClear: !0,
3748
- placeholder: "选择 secret (key)",
3749
- options: g.map((o) => ({
3750
- value: o.secretKey,
3751
- label: `${o.secretKey}${o.secretName ? " (" + o.secretName + ")" : ""}`
3752
- }))
3753
- }
3754
- )
3755
- }
3756
- )
3757
- ] }),
3758
- /* @__PURE__ */ n(P, { type: "inner", title: "抽取器", style: { marginBottom: 16 }, children: [
3759
- /* @__PURE__ */ e(
3760
- R.Item,
3761
- {
3762
- label: "抽取器类型",
3763
- name: "extractorType",
3764
- rules: [{ required: !0 }],
3765
- extra: "STANDARD_JSON/RSS_XML/ATOM_XML 直接解析; CUSTOM_SCRIPT 调 z-script 平台",
3766
- children: /* @__PURE__ */ e(X, { options: Dn })
3767
- }
3768
- ),
3769
- s === "CUSTOM_SCRIPT" && /* @__PURE__ */ e(
3770
- R.Item,
3771
- {
3772
- label: "z-script 脚本",
3773
- name: "extractorScriptCode",
3774
- rules: [{ required: !0, message: "请选择脚本" }],
3775
- extra: "在 智能中心 > 脚本中心 维护脚本. 脚本返回 { items: [...], nextCursor: '...' }",
3776
- children: /* @__PURE__ */ e(
3777
- X,
3778
- {
3779
- showSearch: !0,
3780
- placeholder: "选择已启用的脚本",
3781
- options: _.map((o) => ({
3782
- value: o.scriptCode,
3783
- label: `${o.scriptCode} (${o.dslType})${o.scriptName ? " - " + o.scriptName : ""}`
3784
- }))
3785
- }
3786
- )
3787
- }
3788
- )
3789
- ] }),
3790
- /* @__PURE__ */ n(P, { type: "inner", title: "调度", style: { marginBottom: 16 }, children: [
3791
- /* @__PURE__ */ e(
3792
- R.Item,
3793
- {
3794
- label: "Cron 表达式",
3795
- name: "cronExpr",
3796
- rules: [{ required: !0, message: "请输入 Cron" }],
3797
- extra: "Quartz 兼容, 例如 0 */5 * * * ? = 每 5 分钟",
3798
- children: /* @__PURE__ */ e(B, { addonAfter: /* @__PURE__ */ e(
3799
- X,
3800
- {
3801
- style: { width: 140 },
3802
- placeholder: "常用",
3803
- options: jn,
3804
- onChange: (o) => f.setFieldValue("cronExpr", o),
3805
- value: null
3806
- }
3807
- ) })
3808
- }
3809
- ),
3810
- /* @__PURE__ */ n(z, { size: "large", children: [
3811
- /* @__PURE__ */ e(R.Item, { label: "启用", name: "enabled", valuePropName: "checked", children: /* @__PURE__ */ n(ne.Group, { children: [
3812
- /* @__PURE__ */ e(ne.Button, { value: !0, children: "启用" }),
3813
- /* @__PURE__ */ e(ne.Button, { value: !1, children: "停用" })
3814
- ] }) }),
3815
- /* @__PURE__ */ e(
3816
- R.Item,
3817
- {
3818
- label: "最小间隔 (秒)",
3819
- name: "minIntervalSec",
3820
- extra: "距上次 run 至少 N 秒",
3821
- children: /* @__PURE__ */ e($e, { min: 0, max: 3600 })
3822
- }
3823
- ),
3824
- /* @__PURE__ */ e(R.Item, { label: "单次最多条数", name: "maxItemsPerRun", children: /* @__PURE__ */ e($e, { min: 1, max: 1e4 }) })
3825
- ] })
3826
- ] }),
3827
- /* @__PURE__ */ e(
3828
- J,
3829
- {
3830
- type: "success",
3831
- showIcon: !0,
3832
- title: "保存后会自动 dry-run: 真实 HTTP 一次, 把响应喂给抽取器, 失败时订阅进入 INVALID_AUTH 状态, 不会自动调度."
3833
- }
3834
- )
3835
- ]
3836
- }
3837
- ) }) })
3838
- ] });
3839
- }
3840
- const Fn = {
3841
- PENDING: "default",
3842
- RUNNING: "processing",
3843
- SUCCESS: "green",
3844
- EMPTY: "default",
3845
- FAILED: "red",
3846
- FATAL: "red"
3847
- };
3848
- function qn() {
3849
- const [t, a] = x([]), [r, f] = x(null), [i, u] = x([]), [l, h] = x([]), [g, w] = x(null), [_, y] = x(!1);
3850
- W(() => {
3851
- m();
3852
- }, []), W(() => {
3853
- r && s(r);
3854
- }, [r]);
3855
- const m = async () => {
3856
- try {
3857
- const p = await N.get("/subscribe/subscription/list"), o = (p == null ? void 0 : p.data) ?? p ?? [];
3858
- a(Array.isArray(o) ? o : []), Array.isArray(o) && o.length > 0 && f(o[0].id);
3859
- } catch {
3860
- I.error("加载订阅列表失败");
3861
- }
3862
- }, s = async (p) => {
3863
- y(!0);
3864
- try {
3865
- const o = await N.get(`/subscribe/run/list?subscriptionId=${p}&limit=50`), C = (o == null ? void 0 : o.data) ?? o ?? [];
3866
- u(Array.isArray(C) ? C : []);
3867
- } catch {
3868
- I.error("加载运行历史失败");
3869
- } finally {
3870
- y(!1);
3871
- }
3872
- }, c = async (p) => {
3873
- w(p);
3874
- try {
3875
- const o = await N.get(`/subscribe/run/${p}/items?limit=200`), C = (o == null ? void 0 : o.data) ?? o ?? [];
3876
- h(Array.isArray(C) ? C : []);
3877
- } catch {
3878
- I.error("加载抽取项失败");
3879
- }
3880
- }, k = i.reduce((p, o) => p + (o.successCount || 0), 0), $ = i.reduce((p, o) => p + (o.deadLetterCount || 0), 0), S = i.reduce((p, o) => p + (o.duplicateCount || 0), 0);
3881
- return /* @__PURE__ */ n("div", { children: [
3882
- /* @__PURE__ */ e(
3883
- xe,
3884
- {
3885
- title: "订阅中心 - 运行历史",
3886
- subtitle: "查看各订阅的抽取运行记录与统计"
3887
- }
3888
- ),
3889
- /* @__PURE__ */ e(
3890
- yn,
3891
- {
3892
- left: /* @__PURE__ */ e(
3893
- X,
3894
- {
3895
- style: { width: 280 },
3896
- placeholder: "选择订阅",
3897
- value: r,
3898
- onChange: f,
3899
- options: t.map((p) => ({ value: p.id, label: p.name })),
3900
- showSearch: !0,
3901
- optionFilterProp: "label"
3902
- }
3903
- ),
3904
- right: /* @__PURE__ */ n("a", { onClick: () => r && s(r), children: [
3905
- /* @__PURE__ */ e(ee, {}),
3906
- " 刷新"
3907
- ] })
3908
- }
3909
- ),
3910
- /* @__PURE__ */ n(P, { children: [
3911
- /* @__PURE__ */ n(Q, { gutter: 16, style: { marginBottom: 16 }, children: [
3912
- /* @__PURE__ */ e(M, { span: 6, children: /* @__PURE__ */ e(P, { children: /* @__PURE__ */ e(H, { title: "run 总数", value: i.length }) }) }),
3913
- /* @__PURE__ */ e(M, { span: 6, children: /* @__PURE__ */ e(P, { children: /* @__PURE__ */ e(
3914
- H,
3915
- {
3916
- title: "成功条数",
3917
- value: k,
3918
- styles: { content: { color: "#3f8600" } }
3919
- }
3920
- ) }) }),
3921
- /* @__PURE__ */ e(M, { span: 6, children: /* @__PURE__ */ e(P, { children: /* @__PURE__ */ e(
3922
- H,
3923
- {
3924
- title: "死信条数",
3925
- value: $,
3926
- styles: { content: { color: "#cf1322" } }
3927
- }
3928
- ) }) }),
3929
- /* @__PURE__ */ e(M, { span: 6, children: /* @__PURE__ */ e(P, { children: /* @__PURE__ */ e(H, { title: "重复跳过", value: S }) }) })
3930
- ] }),
3931
- /* @__PURE__ */ n(Q, { gutter: 16, children: [
3932
- /* @__PURE__ */ e(M, { span: 12, children: /* @__PURE__ */ e(P, { type: "inner", title: `运行列表 (${i.length})`, size: "small", children: /* @__PURE__ */ e(
3933
- K,
3934
- {
3935
- rowKey: "id",
3936
- size: "small",
3937
- loading: _,
3938
- dataSource: i,
3939
- pagination: { pageSize: 10 },
3940
- onRow: (p) => ({
3941
- onClick: () => c(p.id),
3942
- style: { cursor: "pointer", background: p.id === g ? "#e6f7ff" : "" }
3943
- }),
3944
- columns: [
3945
- { title: "ID", dataIndex: "id", width: 60 },
3946
- {
3947
- title: "计划",
3948
- dataIndex: "scheduledAt",
3949
- width: 150,
3950
- render: (p) => p ? new Date(p).toLocaleString() : "-"
3951
- },
3952
- { title: "耗时", dataIndex: "durationMs", width: 80 },
3953
- {
3954
- title: "状态",
3955
- dataIndex: "status",
3956
- width: 80,
3957
- render: (p) => /* @__PURE__ */ e(v, { color: Fn[p], children: p })
3958
- },
3959
- {
3960
- title: "拉取/成功/死信",
3961
- width: 150,
3962
- render: (p, o) => `${o.fetchedCount} / ${o.successCount} / ${o.deadLetterCount}`
3963
- }
3964
- ]
3965
- }
3966
- ) }) }),
3967
- /* @__PURE__ */ e(M, { span: 12, children: /* @__PURE__ */ e(
3968
- P,
3969
- {
3970
- type: "inner",
3971
- title: g ? `run#${g} 抽取项 (${l.length})` : "抽取项",
3972
- size: "small",
3973
- children: l.length === 0 ? /* @__PURE__ */ e(gt, { description: g ? "该 run 无抽取项" : "点击左侧 run 查看抽取项" }) : /* @__PURE__ */ e(
3974
- K,
3975
- {
3976
- rowKey: "id",
3977
- size: "small",
3978
- dataSource: l,
3979
- pagination: { pageSize: 10 },
3980
- columns: [
3981
- { title: "id", dataIndex: "dedupKey", width: 160, ellipsis: !0 },
3982
- {
3983
- title: "title",
3984
- dataIndex: "normalized",
3985
- render: (p) => {
3986
- try {
3987
- return JSON.parse(p).title || "(无标题)";
3988
- } catch {
3989
- return p;
3990
- }
3991
- }
3992
- },
3993
- {
3994
- title: "link",
3995
- dataIndex: "normalized",
3996
- width: 60,
3997
- render: (p) => {
3998
- try {
3999
- const o = JSON.parse(p);
4000
- return o.link ? /* @__PURE__ */ e("a", { href: o.link, target: "_blank", children: "↗" }) : "-";
4001
- } catch {
4002
- return "-";
4003
- }
4004
- }
4005
- },
4006
- {
4007
- title: "状态",
4008
- dataIndex: "status",
4009
- width: 100,
4010
- render: (p) => /* @__PURE__ */ e(v, { children: p })
4011
- }
4012
- ]
4013
- }
4014
- )
4015
- }
4016
- ) })
4017
- ] })
4018
- ] })
4019
- ] });
4020
- }
4021
- function Un() {
4022
- return /* @__PURE__ */ n(pt, { children: [
4023
- /* @__PURE__ */ e(re, { index: !0, element: /* @__PURE__ */ e(mt, { to: "list", replace: !0 }) }),
4024
- /* @__PURE__ */ e(re, { path: "list", element: /* @__PURE__ */ e($n, {}) }),
4025
- /* @__PURE__ */ e(re, { path: "new", element: /* @__PURE__ */ e(dt, {}) }),
4026
- /* @__PURE__ */ e(re, { path: "edit/:id", element: /* @__PURE__ */ e(dt, {}) }),
4027
- /* @__PURE__ */ e(re, { path: "runs", element: /* @__PURE__ */ e(qn, {}) })
4028
- ] });
4029
- }
4030
- const hr = /* @__PURE__ */ Object.freeze(/* @__PURE__ */ Object.defineProperty({
4031
- __proto__: null,
4032
- default: Un
4033
- }, Symbol.toStringTag, { value: "Module" })), Hn = {
4034
- OPEN: { color: "blue", text: "待开始" },
4035
- IN_PROGRESS: { color: "green", text: "进行中" },
4036
- COMPLETED: { color: "default", text: "已完成" },
4037
- ARCHIVED: { color: "default", text: "已归档" }
4038
- };
4039
- function Kn() {
4040
- const t = be(), [a, r] = x("mine"), [f, i] = x([]), [u, l] = x(!1), [h, g] = x(null), w = async () => {
4041
- l(!0), g(null);
4042
- try {
4043
- const s = a === "mine" ? "/project/list/mine?limit=100" : `/project/list/by-status?status=${a}&limit=100`, c = await N.get(s), k = (c == null ? void 0 : c.data) ?? c ?? [];
4044
- i(Array.isArray(k) ? k : []);
4045
- } catch (s) {
4046
- g((s == null ? void 0 : s.message) || (s == null ? void 0 : s.msg) || "加载失败");
4047
- } finally {
4048
- l(!1);
4049
- }
4050
- };
4051
- W(() => {
4052
- w();
4053
- }, [a]);
4054
- const _ = async (s) => {
4055
- try {
4056
- const c = await N.post(`/project/${s}/status?status=COMPLETED`);
4057
- c && c.success !== !1 && (I.success("已标记完成"), w());
4058
- } catch (c) {
4059
- I.error("操作失败: " + ((c == null ? void 0 : c.message) || ""));
4060
- }
4061
- }, y = [
4062
- { title: "ID", dataIndex: "id", width: 60 },
4063
- {
4064
- title: "名称",
4065
- dataIndex: "name",
4066
- render: (s, c) => /* @__PURE__ */ n(z, { orientation: "vertical", size: 0, children: [
4067
- /* @__PURE__ */ e("a", { onClick: () => t(`/project/${c.id}`), style: { fontWeight: 500 }, children: s }),
4068
- c.description && /* @__PURE__ */ e("span", { style: { color: "#999", fontSize: 12 }, children: c.description })
4069
- ] })
4070
- },
4071
- { title: "来源", dataIndex: "sourceType", width: 100, render: (s) => /* @__PURE__ */ e(v, { children: s }) },
4072
- {
4073
- title: "订阅",
4074
- dataIndex: "sourceSubscriptionId",
4075
- width: 80,
4076
- render: (s) => s ? `#${s}` : /* @__PURE__ */ e("span", { style: { color: "#ccc" }, children: "-" })
4077
- },
4078
- {
4079
- title: "状态",
4080
- dataIndex: "status",
4081
- width: 100,
4082
- render: (s) => {
4083
- const c = Hn[s] || { color: "default", text: s };
4084
- return /* @__PURE__ */ e(v, { color: c.color, children: c.text });
4085
- }
4086
- },
4087
- { title: "消息数", dataIndex: "messageCount", width: 80 },
4088
- {
4089
- title: "上下文",
4090
- width: 130,
4091
- render: (s, c) => /* @__PURE__ */ n(v, { color: "blue", children: [
4092
- c.contextSize || 0,
4093
- "B"
4094
- ] })
4095
- },
4096
- {
4097
- title: "最近活动",
4098
- dataIndex: "lastMessageAt",
4099
- width: 150,
4100
- render: (s) => s ? new Date(s).toLocaleString() : /* @__PURE__ */ e("span", { style: { color: "#ccc" }, children: "-" })
4101
- },
4102
- {
4103
- title: "操作",
4104
- width: 160,
4105
- render: (s, c) => /* @__PURE__ */ n(z, { size: 4, children: [
4106
- /* @__PURE__ */ e(A, { type: "link", size: "small", onClick: () => t(`/project/${c.id}`), children: "对话" }),
4107
- c.status !== "COMPLETED" && c.status !== "ARCHIVED" && /* @__PURE__ */ e(
4108
- We,
4109
- {
4110
- title: "标记为已完成?",
4111
- onConfirm: () => _(c.id),
4112
- okButtonProps: { danger: !0 },
4113
- children: /* @__PURE__ */ e(A, { type: "link", size: "small", icon: /* @__PURE__ */ e(Je, {}), children: "完成" })
4114
- }
4115
- )
4116
- ] })
4117
- }
4118
- ], m = !u && !h && f.length === 0;
4119
- return /* @__PURE__ */ n("div", { children: [
4120
- /* @__PURE__ */ e(
4121
- xe,
4122
- {
4123
- title: "项目中心",
4124
- subtitle: "管理由 CEO 立项的项目与 Agent 对话上下文",
4125
- breadcrumb: [{ label: "项目中心" }]
4126
- }
4127
- ),
4128
- h && !u && /* @__PURE__ */ e("div", { style: { marginBottom: 16 }, children: /* @__PURE__ */ e(fn, { error: h, onRetry: w }) }),
4129
- /* @__PURE__ */ n("div", { style: {
4130
- background: "#ffffff",
4131
- borderRadius: 16,
4132
- padding: 20,
4133
- boxShadow: "0 1px 3px rgba(15, 23, 42, 0.04), 0 1px 2px rgba(15, 23, 42, 0.06)"
4134
- }, children: [
4135
- /* @__PURE__ */ e(
4136
- ve,
4137
- {
4138
- activeKey: a,
4139
- onChange: r,
4140
- tabBarExtraContent: /* @__PURE__ */ n(z, { children: [
4141
- /* @__PURE__ */ e(A, { icon: /* @__PURE__ */ e(ee, {}), onClick: w, loading: u, children: "刷新" }),
4142
- /* @__PURE__ */ e(
4143
- A,
4144
- {
4145
- type: "primary",
4146
- icon: /* @__PURE__ */ e(St, {}),
4147
- onClick: () => t("/project/new"),
4148
- children: "新建项目"
4149
- }
4150
- )
4151
- ] }),
4152
- items: [
4153
- { key: "mine", label: "我的进行中" },
4154
- { key: "OPEN", label: "待开始" },
4155
- { key: "IN_PROGRESS", label: "进行中" },
4156
- { key: "COMPLETED", label: "已完成" }
4157
- ]
4158
- }
4159
- ),
4160
- m ? /* @__PURE__ */ e(
4161
- gn,
4162
- {
4163
- title: "还没有项目",
4164
- description: "立项一个项目, 让 Agent 围绕目标持续推进对话与任务",
4165
- actionText: "新建第一个项目",
4166
- onAction: () => t("/project/new")
4167
- }
4168
- ) : /* @__PURE__ */ e(
4169
- K,
4170
- {
4171
- rowKey: "id",
4172
- columns: y,
4173
- dataSource: f,
4174
- loading: u,
4175
- size: "middle",
4176
- pagination: { pageSize: 20 }
4177
- }
4178
- )
4179
- ] })
4180
- ] });
4181
- }
4182
- const Wn = [
4183
- { value: "general", label: "通用助手" },
4184
- { value: "analyst", label: "分析师" },
4185
- { value: "writer", label: "写手" },
4186
- { value: "pm", label: "产品经理" },
4187
- { value: "ops", label: "运营" }
4188
- ];
4189
- function Gn() {
4190
- const t = be(), [a] = At(), [r] = R.useForm(), [f, i] = x(!1), [u, l] = x("from-subscribe"), [h, g] = x([]), [w, _] = x([]), [y, m] = x(!1), [s, c] = x([]), [k, $] = x(null);
4191
- W(() => {
4192
- const C = a.get("subscriptionId"), L = a.get("itemIds");
4193
- C && ($(Number(C)), r.setFieldValue("sourceSubscriptionId", Number(C)), p(C)), L && c(L.split(",").map(Number).filter(Boolean));
4194
- }, [a]), W(() => {
4195
- S();
4196
- }, []);
4197
- const S = async () => {
4198
- try {
4199
- const C = await N.get("/subscribe/subscription/list"), L = (C == null ? void 0 : C.data) ?? C ?? [];
4200
- g(Array.isArray(L) ? L.filter((G) => G.status === "VERIFIED") : []);
4201
- } catch {
4202
- }
4203
- }, p = async (C) => {
4204
- m(!0);
4205
- try {
4206
- const L = await N.get(`/subscribe/run/list?subscriptionId=${C}&limit=1`), G = (L == null ? void 0 : L.data) ?? L ?? [];
4207
- if (G.length === 0) {
4208
- _([]);
4209
- return;
4210
- }
4211
- const U = G[0], b = await N.get(`/subscribe/run/${U.id}/items?limit=100`), d = (b == null ? void 0 : b.data) ?? b ?? [];
4212
- _(Array.isArray(d) ? d : []);
4213
- } catch {
4214
- I.error("加载抽取项失败");
4215
- } finally {
4216
- m(!1);
4217
- }
4218
- };
4219
- return /* @__PURE__ */ e("div", { style: { padding: 24 }, children: /* @__PURE__ */ e(
4220
- P,
4221
- {
4222
- title: /* @__PURE__ */ n(z, { children: [
4223
- /* @__PURE__ */ e(A, { type: "text", icon: /* @__PURE__ */ e(kt, {}), onClick: () => t("/project/list") }),
4224
- /* @__PURE__ */ e(Ge, {}),
4225
- "新建项目 (立项)"
4226
- ] }),
4227
- extra: /* @__PURE__ */ n(z, { children: [
4228
- /* @__PURE__ */ e(A, { onClick: () => t("/project/list"), children: "取消" }),
4229
- /* @__PURE__ */ e(
4230
- A,
4231
- {
4232
- type: "primary",
4233
- icon: /* @__PURE__ */ e(It, {}),
4234
- loading: f,
4235
- onClick: async () => {
4236
- try {
4237
- const C = await r.validateFields();
4238
- if (u === "from-subscribe" && s.length === 0) {
4239
- I.warning("请至少选 1 个 item");
4240
- return;
4241
- }
4242
- i(!0);
4243
- const L = {
4244
- ...C,
4245
- sourceItemIds: u === "from-subscribe" ? s.map(String) : null
4246
- }, G = u === "from-subscribe" ? "/project/create-from-items" : "/project/create-manual", U = await N.post(G, L);
4247
- if (U && U.success !== !1) {
4248
- const b = U.data ?? U;
4249
- I.success("立项成功"), t(`/project/${b.id}`);
4250
- } else
4251
- I.error((U == null ? void 0 : U.message) || "立项失败");
4252
- } catch (C) {
4253
- C != null && C.errorFields || I.error("立项失败: " + ((C == null ? void 0 : C.message) || ""));
4254
- } finally {
4255
- i(!1);
4256
- }
4257
- },
4258
- children: "立项"
4259
- }
4260
- )
4261
- ] }),
4262
- children: /* @__PURE__ */ n(R, { form: r, layout: "vertical", initialValues: { agentRole: "general" }, children: [
4263
- /* @__PURE__ */ e(R.Item, { label: "来源", children: /* @__PURE__ */ n(ne.Group, { value: u, onChange: (C) => l(C.target.value), children: [
4264
- /* @__PURE__ */ e(ne.Button, { value: "from-subscribe", children: "从订阅线索立项 (主路径)" }),
4265
- /* @__PURE__ */ e(ne.Button, { value: "manual", children: "手动立项 (无源数据)" })
4266
- ] }) }),
4267
- /* @__PURE__ */ e(R.Item, { label: "项目名称", name: "name", rules: [{ required: !0, message: "请输入名称" }], children: /* @__PURE__ */ e(B, { placeholder: "例如: 跟进 GitHub 高优 Issue" }) }),
4268
- /* @__PURE__ */ e(R.Item, { label: "项目描述", name: "description", children: /* @__PURE__ */ e(B.TextArea, { rows: 2, placeholder: "(可选) 这个项目要解决什么?" }) }),
4269
- u === "from-subscribe" && /* @__PURE__ */ n(P, { type: "inner", title: "源数据", style: { marginBottom: 16 }, children: [
4270
- /* @__PURE__ */ e(
4271
- R.Item,
4272
- {
4273
- label: "选择订阅",
4274
- name: "sourceSubscriptionId",
4275
- rules: [{ required: !0, message: "请选订阅" }],
4276
- children: /* @__PURE__ */ e(
4277
- X,
4278
- {
4279
- placeholder: "选择订阅 (拉取最近一次 run 的 items)",
4280
- options: h.map((C) => ({ value: C.id, label: `#${C.id} ${C.name}` })),
4281
- onChange: (C) => {
4282
- $(C), p(C), c([]);
4283
- }
4284
- }
4285
- )
4286
- }
4287
- ),
4288
- k && /* @__PURE__ */ n(Oe, { spinning: y, children: [
4289
- /* @__PURE__ */ n("div", { style: { marginBottom: 8 }, children: [
4290
- /* @__PURE__ */ n(v, { color: "blue", children: [
4291
- "已选 ",
4292
- s.length,
4293
- " / ",
4294
- w.length
4295
- ] }),
4296
- /* @__PURE__ */ e(
4297
- A,
4298
- {
4299
- size: "small",
4300
- onClick: () => c(w.map((C) => C.id)),
4301
- children: "全选"
4302
- }
4303
- ),
4304
- /* @__PURE__ */ e(
4305
- A,
4306
- {
4307
- size: "small",
4308
- onClick: () => c([]),
4309
- style: { marginLeft: 4 },
4310
- children: "清空"
4311
- }
4312
- )
4313
- ] }),
4314
- /* @__PURE__ */ e(
4315
- K,
4316
- {
4317
- rowKey: "id",
4318
- size: "small",
4319
- dataSource: w,
4320
- pagination: { pageSize: 10 },
4321
- rowSelection: {
4322
- selectedRowKeys: s,
4323
- onChange: c
4324
- },
4325
- columns: [
4326
- { title: "id", dataIndex: "dedupKey", width: 160, ellipsis: !0 },
4327
- {
4328
- title: "title",
4329
- dataIndex: "normalized",
4330
- render: (C) => {
4331
- try {
4332
- return JSON.parse(C).title || "(无)";
4333
- } catch {
4334
- return C;
4335
- }
4336
- }
4337
- },
4338
- {
4339
- title: "fetched",
4340
- dataIndex: "fetchedAt",
4341
- width: 150,
4342
- render: (C) => C ? new Date(C).toLocaleString() : "-"
4343
- }
4344
- ]
4345
- }
4346
- )
4347
- ] })
4348
- ] }),
4349
- /* @__PURE__ */ n(P, { type: "inner", title: "Agent 配置", style: { marginBottom: 16 }, children: [
4350
- /* @__PURE__ */ e(R.Item, { label: "Agent 角色", name: "agentRole", extra: "决定 system prompt 的语气 / 视角", children: /* @__PURE__ */ e(X, { options: Wn }) }),
4351
- /* @__PURE__ */ e(
4352
- R.Item,
4353
- {
4354
- label: "模型 (可选)",
4355
- name: "modelCode",
4356
- extra: "留空走默认 (智能中心 LLM 凭证里第一个 enabled)",
4357
- children: /* @__PURE__ */ e(B, { placeholder: "例如: gpt-4 / deepseek-chat" })
4358
- }
4359
- )
4360
- ] }),
4361
- /* @__PURE__ */ e(
4362
- J,
4363
- {
4364
- type: "info",
4365
- showIcon: !0,
4366
- title: "立项后源数据会被快照 (context_snapshot), 后续订阅更新不会影响项目上下文."
4367
- }
4368
- )
4369
- ] })
4370
- }
4371
- ) });
4372
- }
4373
- const ut = {
4374
- USER: { color: "blue", icon: /* @__PURE__ */ e(yt, {}), label: "CEO" },
4375
- ASSISTANT: { color: "purple", icon: /* @__PURE__ */ e(Fe, {}), label: "Agent" },
4376
- SYSTEM: { color: "default", icon: null, label: "系统" }
4377
- }, Vn = {
4378
- OPEN: { color: "blue", text: "待开始" },
4379
- IN_PROGRESS: { color: "green", text: "进行中" },
4380
- COMPLETED: { color: "default", text: "已完成" },
4381
- ARCHIVED: { color: "default", text: "已归档" }
4382
- };
4383
- function Jn() {
4384
- const { id: t } = ht(), a = be(), [r, f] = x(null), [i, u] = x([]), [l, h] = x(""), [g, w] = x(!1), _ = Ke(null);
4385
- W(() => {
4386
- t && y();
4387
- }, [t]), W(() => {
4388
- _.current && (_.current.scrollTop = _.current.scrollHeight);
4389
- }, [i]);
4390
- const y = async () => {
4391
- try {
4392
- const [k, $] = await Promise.all([
4393
- N.get(`/project/${t}`),
4394
- N.get(`/project/${t}/messages`)
4395
- ]);
4396
- f((k == null ? void 0 : k.data) ?? k), u(Array.isArray(($ == null ? void 0 : $.data) ?? $) ? ($ == null ? void 0 : $.data) ?? $ : []);
4397
- } catch {
4398
- I.error("加载项目失败");
4399
- }
4400
- }, m = async () => {
4401
- if (!l.trim()) return;
4402
- const k = l.trim();
4403
- h(""), w(!0);
4404
- const $ = { seq: -1, role: "USER", content: k, createdAt: (/* @__PURE__ */ new Date()).toISOString() };
4405
- u((S) => [...S, $]);
4406
- try {
4407
- const S = await N.post(`/project/${t}/chat`, { message: k });
4408
- if (S && S.success !== !1) {
4409
- const o = (S.data ?? S).message;
4410
- u((C) => [...C.filter((G) => G.seq !== -1), ...o ? [o] : []]), setTimeout(y, 100);
4411
- } else
4412
- I.error((S == null ? void 0 : S.message) || "发送失败");
4413
- } catch (S) {
4414
- I.error("发送失败: " + ((S == null ? void 0 : S.message) || ""));
4415
- } finally {
4416
- w(!1);
4417
- }
4418
- }, s = async () => {
4419
- try {
4420
- const k = await N.post(`/project/${t}/status?status=COMPLETED`);
4421
- k && k.success !== !1 && (I.success("已标记完成"), y());
4422
- } catch {
4423
- I.error("操作失败");
4424
- }
4425
- };
4426
- if (!r) return /* @__PURE__ */ e("div", { style: { padding: 24 }, children: /* @__PURE__ */ e(Oe, {}) });
4427
- const c = Vn[r.status] || { color: "default", text: r.status };
4428
- return /* @__PURE__ */ n("div", { style: { padding: 24, height: "calc(100vh - 64px)", display: "flex", flexDirection: "column", gap: 16 }, children: [
4429
- /* @__PURE__ */ n(
4430
- P,
4431
- {
4432
- title: /* @__PURE__ */ n(z, { children: [
4433
- /* @__PURE__ */ e(A, { type: "text", icon: /* @__PURE__ */ e(kt, {}), onClick: () => a("/project/list") }),
4434
- /* @__PURE__ */ e(Ge, {}),
4435
- /* @__PURE__ */ e("span", { style: { fontWeight: 500 }, children: r.name }),
4436
- /* @__PURE__ */ e(v, { color: c.color, children: c.text })
4437
- ] }),
4438
- extra: /* @__PURE__ */ n(z, { children: [
4439
- r.contextSize > 0 && /* @__PURE__ */ n(v, { color: "blue", children: [
4440
- "上下文 ",
4441
- r.contextSize,
4442
- " B"
4443
- ] }),
4444
- /* @__PURE__ */ e(v, { children: r.agentRole }),
4445
- r.modelCode && /* @__PURE__ */ e(v, { color: "purple", children: r.modelCode }),
4446
- r.status !== "COMPLETED" && r.status !== "ARCHIVED" && /* @__PURE__ */ e(We, { title: "标记完成?", onConfirm: s, children: /* @__PURE__ */ e(A, { icon: /* @__PURE__ */ e(Je, {}), children: "标记完成" }) })
4447
- ] }),
4448
- children: [
4449
- r.description && /* @__PURE__ */ e("div", { style: { color: "#666", marginBottom: 8 }, children: r.description }),
4450
- /* @__PURE__ */ n(z, { size: "large", children: [
4451
- /* @__PURE__ */ e(H, { title: "消息数", value: r.messageCount || 0 }),
4452
- r.sourceSubscriptionId && /* @__PURE__ */ e(H, { title: "来源订阅", value: `#${r.sourceSubscriptionId}` }),
4453
- /* @__PURE__ */ e(
4454
- H,
4455
- {
4456
- title: "立项",
4457
- value: r.createdAt ? new Date(r.createdAt).toLocaleString() : "-"
4458
- }
4459
- )
4460
- ] })
4461
- ]
4462
- }
4463
- ),
4464
- /* @__PURE__ */ n(
4465
- P,
4466
- {
4467
- style: { flex: 1, display: "flex", flexDirection: "column" },
4468
- styles: { body: { flex: 1, display: "flex", flexDirection: "column", padding: 0 } },
4469
- children: [
4470
- /* @__PURE__ */ e("div", { ref: _, style: { flex: 1, overflow: "auto", padding: 16, background: "#fafafa" }, children: i.length === 0 ? /* @__PURE__ */ e(gt, { description: "还没有消息, 跟 Agent 说点什么?" }) : /* @__PURE__ */ n(z, { orientation: "vertical", style: { width: "100%" }, size: "middle", children: [
4471
- i.map((k) => {
4472
- const $ = ut[k.role] || ut.SYSTEM, S = k.role === "USER";
4473
- return /* @__PURE__ */ e("div", { style: {
4474
- display: "flex",
4475
- justifyContent: S ? "flex-end" : "flex-start"
4476
- }, children: /* @__PURE__ */ n("div", { style: {
4477
- maxWidth: "70%",
4478
- background: S ? "#1677ff" : "#fff",
4479
- color: S ? "#fff" : "#000",
4480
- border: S ? "none" : "1px solid #e8e8e8",
4481
- borderRadius: 8,
4482
- padding: "10px 14px",
4483
- boxShadow: "0 1px 2px rgba(0,0,0,0.04)"
4484
- }, children: [
4485
- /* @__PURE__ */ e("div", { style: { fontSize: 12, opacity: 0.7, marginBottom: 4 }, children: /* @__PURE__ */ n(z, { size: 4, children: [
4486
- $.icon,
4487
- $.label,
4488
- k.seq > 0 && /* @__PURE__ */ n("span", { children: [
4489
- "#",
4490
- k.seq
4491
- ] }),
4492
- k.latencyMs > 0 && /* @__PURE__ */ n("span", { children: [
4493
- "· ",
4494
- k.latencyMs,
4495
- "ms"
4496
- ] }),
4497
- k.modelCode && /* @__PURE__ */ n("span", { children: [
4498
- "· ",
4499
- k.modelCode
4500
- ] })
4501
- ] }) }),
4502
- /* @__PURE__ */ e("div", { style: { whiteSpace: "pre-wrap", wordBreak: "break-word" }, children: k.content })
4503
- ] }) }, k.id || k.seq);
4504
- }),
4505
- g && /* @__PURE__ */ e("div", { style: { display: "flex", justifyContent: "flex-start" }, children: /* @__PURE__ */ n("div", { style: {
4506
- background: "#fff",
4507
- border: "1px solid #e8e8e8",
4508
- borderRadius: 8,
4509
- padding: "10px 14px"
4510
- }, children: [
4511
- /* @__PURE__ */ e(Oe, { size: "small" }),
4512
- " 思考中..."
4513
- ] }) })
4514
- ] }) }),
4515
- r.status === "COMPLETED" || r.status === "ARCHIVED" ? /* @__PURE__ */ e(
4516
- J,
4517
- {
4518
- style: { margin: 12, marginBottom: 0 },
4519
- type: "info",
4520
- title: "项目已完成 / 归档, 不再接受新消息",
4521
- showIcon: !0
4522
- }
4523
- ) : /* @__PURE__ */ n("div", { style: { borderTop: "1px solid #f0f0f0", padding: 12, display: "flex", gap: 8 }, children: [
4524
- /* @__PURE__ */ e(
4525
- B.TextArea,
4526
- {
4527
- value: l,
4528
- onChange: (k) => h(k.target.value),
4529
- onPressEnter: (k) => {
4530
- k.shiftKey || (k.preventDefault(), m());
4531
- },
4532
- placeholder: "输入消息, Enter 发送 (Shift+Enter 换行)",
4533
- autoSize: { minRows: 1, maxRows: 6 },
4534
- disabled: g
4535
- }
4536
- ),
4537
- /* @__PURE__ */ e(
4538
- A,
4539
- {
4540
- type: "primary",
4541
- icon: /* @__PURE__ */ e(Wt, {}),
4542
- loading: g,
4543
- onClick: m,
4544
- disabled: !l.trim(),
4545
- children: "发送"
4546
- }
4547
- )
4548
- ] })
4549
- ]
4550
- }
4551
- )
4552
- ] });
4553
- }
4554
- function Xn() {
4555
- return /* @__PURE__ */ n(pt, { children: [
4556
- /* @__PURE__ */ e(re, { index: !0, element: /* @__PURE__ */ e(mt, { to: "list", replace: !0 }) }),
4557
- /* @__PURE__ */ e(re, { path: "list", element: /* @__PURE__ */ e(Kn, {}) }),
4558
- /* @__PURE__ */ e(re, { path: "new", element: /* @__PURE__ */ e(Gn, {}) }),
4559
- /* @__PURE__ */ e(re, { path: ":id", element: /* @__PURE__ */ e(Jn, {}) })
4560
- ] });
4561
- }
4562
- const pr = /* @__PURE__ */ Object.freeze(/* @__PURE__ */ Object.defineProperty({
4563
- __proto__: null,
4564
- default: Xn
4565
- }, Symbol.toStringTag, { value: "Module" }));
4566
- export {
4567
- dr as C,
4568
- Ue as E,
4569
- Rn as M,
4570
- ur as O,
4571
- Xn as P,
4572
- _n as R,
4573
- Un as S,
4574
- yn as T,
4575
- lr as Z,
4576
- ar as a,
4577
- xe as b,
4578
- He as c,
4579
- cr as d,
4580
- ir as e,
4581
- zn as f,
4582
- vn as g,
4583
- Tn as h,
4584
- an as i,
4585
- Ye as j,
4586
- or as k,
4587
- hr as l,
4588
- pr as m,
4589
- N as r,
4590
- dn as s
4591
- };