@yuku123/z-team-component 0.2.17 → 0.2.19

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (26) hide show
  1. package/dist/{InvitationManagementPage-CTgn0tf-.js → InvitationManagementPage-CXABWAsC.js} +2 -2
  2. package/dist/{OnboardingPage-FN8Mg9i0.js → OnboardingPage-CVW00fMq.js} +2 -2
  3. package/dist/ProjectApp-BlLiCgpN.js +4591 -0
  4. package/dist/{admin-logs-B3p1jIeE.js → admin-logs-1ld3lzCM.js} +2 -2
  5. package/dist/{api-CIGuIfdo.js → api-CPLNBlG6.js} +1 -1
  6. package/dist/{api-BkSWNAM_.js → api-DrwVSH9U.js} +943 -934
  7. package/dist/{createWorkspaceWsHandler-822Tptix.js → createWorkspaceWsHandler-oFqLJfnn.js} +4 -4
  8. package/dist/{index-BNHo3niK.js → index-C_jearbI.js} +6 -6
  9. package/dist/{index-BHcef-pw.js → index-CemLwRut.js} +2 -2
  10. package/dist/{index-DbVJnp5X.js → index-DD0zq3u0.js} +10 -10
  11. package/dist/{index-B3OgBWh8.js → index-DMrKqSMi.js} +4 -4
  12. package/dist/{index-Qhv4ref1.js → index-DNVCGr--.js} +3050 -3046
  13. package/dist/{index-CvXZQlEE.js → index-Di4T51xg.js} +1 -1
  14. package/dist/{index-B0p7DzVF.js → index-DxbG5SaU.js} +4 -4
  15. package/dist/{index-B_N4L56c.js → index-NP9NEJg7.js} +3 -3
  16. package/dist/{index-CDZy45aP.js → index-fsVYzhZa.js} +3 -3
  17. package/dist/{index-DO49FCgT.js → index-qnwzFacI.js} +7 -7
  18. package/dist/{index-76RVTeAj.js → index-wJ5boaks.js} +3 -3
  19. package/dist/index.js +1 -1
  20. package/dist/{instance-7Mb0oDT8.js → instance-0k79E34u.js} +1 -1
  21. package/dist/pages.js +1 -1
  22. package/dist/{send-default-agent-team-message-BykzwG_j.js → send-default-agent-team-message-CscqcSGe.js} +1 -1
  23. package/dist/{sso-user-CUVLEnLU.js → sso-user-SBawWc0G.js} +1 -1
  24. package/dist/{useAppStore-Ci1GOrxH.js → useAppStore-jVuolAFy.js} +1 -1
  25. package/package.json +1 -1
  26. package/dist/ProjectApp-B9eTcYMd.js +0 -5417
@@ -0,0 +1,4591 @@
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-DD0zq3u0.js").then((t) => t.I)), Gt = Z(() => import("./index-C_jearbI.js")), Vt = Z(() => import("./index-NP9NEJg7.js")), Jt = Z(() => import("./index-DMrKqSMi.js")), Xt = Z(() => import("./index-DxbG5SaU.js")), Yt = Z(() => import("./index-CemLwRut.js"));
12
+ Z(() => import("./index-DNVCGr--.js").then((t) => t.p));
13
+ const Zt = Z(() => import("./index-CcFJEYgr.js")), Qt = Z(() => import("./index-BmK_rWsV.js")), en = Z(() => import("./index-BkX0I2aB.js")), tn = Z(() => import("./index-Di4T51xg.js")), nn = Z(() => import("./index-C1C2qyDr.js")), rn = Z(() => import("./index-wJ5boaks.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
+ };