@yuku123/z-frontend-common 0.2.9 → 1.1.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (75) hide show
  1. package/LICENSE +25 -0
  2. package/README.md +55 -42
  3. package/dist/PagedTable-DyjNokXN.js +1211 -0
  4. package/dist/index.js +310 -0
  5. package/dist/ui.js +27 -0
  6. package/package.json +52 -44
  7. package/src/components/ErrorBoundary/index.jsx +24 -77
  8. package/src/components/Layout/index.jsx +141 -38
  9. package/src/components/LoginPage/index.jsx +47 -21
  10. package/src/components/StatusTag/index.jsx +14 -12
  11. package/src/components/ui/CategoryDot.jsx +38 -0
  12. package/src/components/ui/DarkBanner.jsx +142 -0
  13. package/src/components/ui/EChartsChart.jsx +82 -0
  14. package/src/components/ui/EmptyState.jsx +94 -0
  15. package/src/components/ui/ErrorState.jsx +114 -0
  16. package/src/components/ui/FeatureCard.jsx +205 -0
  17. package/src/components/ui/GradientStatCard.jsx +196 -0
  18. package/src/components/ui/LoadingState.jsx +116 -0
  19. package/src/components/ui/PageHeader.jsx +143 -0
  20. package/src/components/ui/PagedTable.jsx +83 -0
  21. package/src/components/ui/SearchInput.jsx +111 -0
  22. package/src/components/ui/SectionHeader.jsx +76 -0
  23. package/src/components/ui/StatusBadge.jsx +66 -0
  24. package/src/components/ui/TableToolbar.jsx +58 -0
  25. package/src/components/ui/index.js +36 -0
  26. package/src/components/ui/tokens.js +224 -0
  27. package/src/index.js +33 -37
  28. package/src/services/request.js +74 -4
  29. package/dist/z-frontend-common.css +0 -1
  30. package/dist/z-frontend-common.es.js +0 -51275
  31. package/dist/z-frontend-common.umd.js +0 -459
  32. package/src/components/Ctc/Layout.jsx +0 -330
  33. package/src/components/Ctc/Layout.module.css +0 -145
  34. package/src/components/Ctc/agentTeam/index.tsx +0 -308
  35. package/src/components/Ctc/login/AuthPage.module.css +0 -26
  36. package/src/components/Ctc/login/AuthPage.tsx +0 -235
  37. package/src/components/Ctc/login/index.less +0 -49
  38. package/src/components/Ctc/login/index.tsx +0 -142
  39. package/src/components/Ctc/uc/UCLogin.tsx +0 -31
  40. package/src/components/Ctc/uc/UCPhoneLogin.tsx +0 -62
  41. package/src/components/Ctc/uc/UCRegister.tsx +0 -37
  42. package/src/components/Ctc/uc/UCResetPassword.tsx +0 -69
  43. package/src/components/Ctc/uc/index.tsx +0 -15
  44. package/src/components/Ctc/userPanel/index.tsx +0 -999
  45. package/src/components/Ctc/webide/index.tsx +0 -272
  46. package/src/components/LowCode/LowCodeModel.jsx +0 -962
  47. package/src/components/LowCode/LowCodePage.jsx +0 -31
  48. package/src/components/LowCode/LowCodeRuntime.jsx +0 -335
  49. package/src/components/LowCode/MaterializePage.jsx +0 -235
  50. package/src/components/LowCode/index.js +0 -1
  51. package/src/components/MockPlatform/CurlImportModal.jsx +0 -362
  52. package/src/components/MockPlatform/EndpointsTab.jsx +0 -509
  53. package/src/components/MockPlatform/EnvironmentsTab.jsx +0 -212
  54. package/src/components/MockPlatform/MockTemplateHelper.jsx +0 -200
  55. package/src/components/MockPlatform/OpenApiImportModal.jsx +0 -305
  56. package/src/components/MockPlatform/RecordingsTab.jsx +0 -397
  57. package/src/components/MockPlatform/RequestLogsTab.jsx +0 -239
  58. package/src/components/MockPlatform/ScenariosTab.jsx +0 -236
  59. package/src/components/MockPlatform/TestCasesTab.jsx +0 -462
  60. package/src/components/MockPlatform/index.jsx +0 -127
  61. package/src/components/Overview.jsx +0 -74
  62. package/src/dev.jsx +0 -28
  63. package/src/services/agentTeam.js +0 -7
  64. package/src/services/api.js +0 -84
  65. package/src/services/ctcAc.js +0 -7
  66. package/src/services/ctcAcDomain.js +0 -7
  67. package/src/services/ctcAuthorization.js +0 -7
  68. package/src/services/ctcSurl.js +0 -7
  69. package/src/services/ctcUser.js +0 -7
  70. package/src/services/job.js +0 -7
  71. package/src/services/metaApp.js +0 -7
  72. package/src/services/privateConfig.js +0 -7
  73. package/src/services/webide.js +0 -6
  74. package/src/services/workspace.js +0 -21
  75. package/src/utils/request.ts +0 -102
package/dist/index.js ADDED
@@ -0,0 +1,310 @@
1
+ import { C as xe, D as we, E as Ie, a as ke, b as Ce, F as be, G as Re, L as ve, P as ze, c as Me, R as Le, S as Ee, d as Oe, e as Be, T as je, f as Te, g as Ke, h as $e, l as De, n as Pe, p as qe, r as Fe, s as He, i as We } from "./PagedTable-DyjNokXN.js";
2
+ import { jsxs as h, jsx as r } from "react/jsx-runtime";
3
+ import { Layout as I, Spin as B, Menu as j, Dropdown as T, Avatar as K, Button as k, Tooltip as $, Card as D, Alert as P, Form as S, Input as v, message as p, Tag as q, Result as F } from "antd";
4
+ import { MenuUnfoldOutlined as H, MenuFoldOutlined as W, DownOutlined as N, LoginOutlined as G, UserOutlined as J, LockOutlined as Q } from "@ant-design/icons";
5
+ import { useNavigate as X, useLocation as Y, Outlet as Z } from "react-router-dom";
6
+ import { useState as z, Component as _ } from "react";
7
+ import U from "axios";
8
+ const { Header: V, Sider: A, Content: ee } = I;
9
+ function te(t, e = 0.85) {
10
+ const o = /^#?([0-9a-f]{6})$/i.exec(t || "");
11
+ if (!o) return t;
12
+ const d = parseInt(o[1], 16), u = Math.max(0, Math.min(255, Math.round((d >> 16 & 255) * e))), n = Math.max(0, Math.min(255, Math.round((d >> 8 & 255) * e))), a = Math.max(0, Math.min(255, Math.round((d & 255) * e)));
13
+ return "#" + (u << 16 | n << 8 | a).toString(16).padStart(6, "0");
14
+ }
15
+ function re({
16
+ menuItems: t = [],
17
+ appTitle: e = "One Company",
18
+ appShort: o = "OC",
19
+ appVersion: d,
20
+ appIcon: u,
21
+ appUser: n,
22
+ loginPath: a,
23
+ headerExtra: g,
24
+ loading: x = !1
25
+ }) {
26
+ const [i, m] = z(!1), y = X(), c = Y(), E = ({ key: f }) => {
27
+ y(f);
28
+ }, b = () => {
29
+ if (a) return a;
30
+ const f = t && t[0], l = f && f.key;
31
+ return typeof l == "string" && l.endsWith("/home") ? l.slice(0, -4) + "login" : "/login";
32
+ }, R = (f, l = []) => {
33
+ for (const s of f || [])
34
+ s != null && s.key && l.push(s.key), s != null && s.children && R(s.children, l);
35
+ return l;
36
+ }, O = (() => {
37
+ const f = R(t), l = c.pathname;
38
+ return f.filter((s) => l === s || l.startsWith(s + "/")).sort((s, w) => w.length - s.length)[0] || l;
39
+ })();
40
+ return /* @__PURE__ */ h(I, { style: { minHeight: "100vh" }, children: [
41
+ /* @__PURE__ */ h(A, { trigger: null, collapsible: !0, collapsed: i, children: [
42
+ /* @__PURE__ */ r("div", { style: {
43
+ height: 64,
44
+ display: "flex",
45
+ alignItems: "center",
46
+ justifyContent: "center"
47
+ }, children: (() => {
48
+ if (i) {
49
+ if (u) {
50
+ const { icon: f, color: l = "#7c3aed", label: s = e } = u, w = /* @__PURE__ */ r("div", { style: {
51
+ width: 36,
52
+ height: 36,
53
+ borderRadius: 9,
54
+ background: `linear-gradient(135deg, ${l}, ${te(l, 0.7)})`,
55
+ display: "flex",
56
+ alignItems: "center",
57
+ justifyContent: "center",
58
+ color: "#fff",
59
+ fontSize: 20,
60
+ boxShadow: "0 2px 6px rgba(0,0,0,0.25)",
61
+ overflow: "hidden"
62
+ }, children: f });
63
+ return /* @__PURE__ */ r($, { title: s, placement: "right", children: w });
64
+ }
65
+ return o;
66
+ }
67
+ return /* @__PURE__ */ h("span", { style: { color: "#fff", fontWeight: 600, fontSize: 16, whiteSpace: "nowrap" }, children: [
68
+ e,
69
+ d && /* @__PURE__ */ h("span", { style: {
70
+ color: "rgba(255,255,255,0.55)",
71
+ fontWeight: 400,
72
+ fontSize: 12,
73
+ marginLeft: 4
74
+ }, children: [
75
+ "@",
76
+ d
77
+ ] })
78
+ ] });
79
+ })() }),
80
+ x ? /* @__PURE__ */ r("div", { style: { padding: 16, textAlign: "center" }, children: /* @__PURE__ */ r(B, { size: "small" }) }) : /* @__PURE__ */ r(
81
+ j,
82
+ {
83
+ theme: "dark",
84
+ mode: "inline",
85
+ selectedKeys: [O],
86
+ items: t,
87
+ onClick: E
88
+ }
89
+ )
90
+ ] }),
91
+ /* @__PURE__ */ h(I, { children: [
92
+ /* @__PURE__ */ h(V, { style: {
93
+ height: 48,
94
+ lineHeight: "48px",
95
+ padding: "0 16px",
96
+ background: "#fff",
97
+ display: "flex",
98
+ alignItems: "center",
99
+ justifyContent: "space-between",
100
+ borderBottom: "1px solid #f1f5f9"
101
+ }, children: [
102
+ /* @__PURE__ */ r("span", { onClick: () => m(!i), style: { fontSize: 18, cursor: "pointer" }, children: i ? /* @__PURE__ */ r(H, {}) : /* @__PURE__ */ r(W, {}) }),
103
+ /* @__PURE__ */ h("div", { style: { display: "flex", alignItems: "center", gap: 12 }, children: [
104
+ n && /* @__PURE__ */ r(
105
+ T,
106
+ {
107
+ menu: {
108
+ items: [
109
+ { key: "profile", label: `${n.name}(${n.role || "用户"})`, disabled: !0 },
110
+ { type: "divider" },
111
+ {
112
+ key: "logout",
113
+ label: "退出登录",
114
+ onClick: () => {
115
+ localStorage.removeItem("token"), localStorage.removeItem("userInfo"), window.location.href = b();
116
+ }
117
+ }
118
+ ]
119
+ },
120
+ placement: "bottomRight",
121
+ children: /* @__PURE__ */ h("span", { style: { cursor: "pointer", display: "inline-flex", alignItems: "center", gap: 6 }, children: [
122
+ /* @__PURE__ */ r(K, { size: 28, style: { background: "#7c3aed" }, children: (n.name || "?").slice(0, 1).toUpperCase() }),
123
+ /* @__PURE__ */ r("span", { style: { fontSize: 13, color: "#0f172a" }, children: n.name }),
124
+ /* @__PURE__ */ r(N, { style: { fontSize: 10, color: "#94a3b8" } })
125
+ ] })
126
+ }
127
+ ),
128
+ !n && /* @__PURE__ */ r(
129
+ k,
130
+ {
131
+ type: "primary",
132
+ size: "small",
133
+ icon: /* @__PURE__ */ r(G, {}),
134
+ onClick: () => {
135
+ window.location.href = b();
136
+ },
137
+ children: "登录"
138
+ }
139
+ ),
140
+ g
141
+ ] })
142
+ ] }),
143
+ /* @__PURE__ */ r(ee, { style: { margin: 16, padding: 24, background: "#fff", minHeight: 280 }, children: /* @__PURE__ */ r(Z, {}) })
144
+ ] })
145
+ ] });
146
+ }
147
+ function ne(t) {
148
+ return t && typeof t == "object" && "code" in t && "data" in t ? t.code !== 200 ? Promise.reject(new Error(t.message || "请求失败")) : t.data : t;
149
+ }
150
+ function oe(t, e = {}) {
151
+ const {
152
+ tokenKey: o = "token",
153
+ userInfoKey: d = "userInfo",
154
+ unauthorizedRedirect: u = "/login"
155
+ } = e;
156
+ return t.interceptors.request.use((n) => {
157
+ const a = localStorage.getItem(o);
158
+ return a && (n.headers.Authorization = `Bearer ${a}`), n;
159
+ }), t.interceptors.response.use(
160
+ (n) => ne(n.data),
161
+ (n) => {
162
+ var g;
163
+ const a = (g = n.response) == null ? void 0 : g.status;
164
+ return a === 401 ? (localStorage.removeItem(o), localStorage.removeItem(d), window.location.href = u) : a === 403 ? console.error("没有权限访问该资源") : a === 500 && console.error("服务器内部错误"), Promise.reject(n);
165
+ }
166
+ ), t;
167
+ }
168
+ function C(t = {}) {
169
+ const e = U.create({
170
+ baseURL: t.baseURL ?? "/api",
171
+ timeout: t.timeout ?? 1e4
172
+ });
173
+ return oe(e, {
174
+ tokenKey: t.tokenKey,
175
+ userInfoKey: t.userInfoKey,
176
+ unauthorizedRedirect: t.unauthorizedRedirect
177
+ });
178
+ }
179
+ const M = C(), se = C();
180
+ function ae({
181
+ title: t = "统一管理平台",
182
+ mockAuth: e,
183
+ loginApi: o = "/auth/login",
184
+ redirectUrl: d = "/",
185
+ onSuccess: u
186
+ }) {
187
+ const [n, a] = z(!1), g = (i) => {
188
+ localStorage.setItem("token", e ? "mock-" + e.username : (i == null ? void 0 : i.token) || "token"), localStorage.setItem("userInfo", JSON.stringify(i || {})), p.success("登录成功" + (e ? "(mock 模式,待 CTC/SSO 接入)" : "")), u ? u(i) : window.location.href = d;
189
+ }, x = async (i) => {
190
+ var m, y;
191
+ a(!0);
192
+ try {
193
+ if (e) {
194
+ i.username === e.username && i.password === e.password ? g(e.user) : p.error("用户名或密码错误");
195
+ return;
196
+ }
197
+ const c = await M.post(o, i);
198
+ c != null && c.token ? (localStorage.setItem("token", c.token), localStorage.setItem("userInfo", JSON.stringify(c.user || c)), p.success("登录成功"), u ? u(c) : window.location.href = d) : p.error("登录失败:未获取到 token");
199
+ } catch (c) {
200
+ p.error(((y = (m = c.response) == null ? void 0 : m.data) == null ? void 0 : y.message) || c.message || "登录失败");
201
+ } finally {
202
+ a(!1);
203
+ }
204
+ };
205
+ return /* @__PURE__ */ r("div", { style: {
206
+ height: "100vh",
207
+ display: "flex",
208
+ justifyContent: "center",
209
+ alignItems: "center",
210
+ background: "#f0f2f5"
211
+ }, children: /* @__PURE__ */ h(D, { title: t, style: { width: 400 }, children: [
212
+ e && /* @__PURE__ */ r(
213
+ P,
214
+ {
215
+ type: "info",
216
+ showIcon: !0,
217
+ style: { marginBottom: 16 },
218
+ message: `Mock 模式:用户名 ${e.username} / 密码 ${e.password}`
219
+ }
220
+ ),
221
+ /* @__PURE__ */ h(S, { onFinish: x, size: "large", children: [
222
+ /* @__PURE__ */ r(S.Item, { name: "username", rules: [{ required: !0, message: "请输入用户名" }], children: /* @__PURE__ */ r(v, { prefix: /* @__PURE__ */ r(J, {}), placeholder: "用户名" }) }),
223
+ /* @__PURE__ */ r(S.Item, { name: "password", rules: [{ required: !0, message: "请输入密码" }], children: /* @__PURE__ */ r(v.Password, { prefix: /* @__PURE__ */ r(Q, {}), placeholder: "密码" }) }),
224
+ /* @__PURE__ */ r(S.Item, { children: /* @__PURE__ */ r(k, { type: "primary", htmlType: "submit", loading: n, block: !0, children: "登 录" }) })
225
+ ] })
226
+ ] }) });
227
+ }
228
+ const L = {
229
+ 1: { color: "green", text: "正常" },
230
+ 0: { color: "red", text: "禁用" },
231
+ pending: { color: "orange", text: "待处理" },
232
+ approved: { color: "blue", text: "已通过" },
233
+ rejected: { color: "red", text: "已拒绝" }
234
+ };
235
+ function ie({ status: t, map: e }) {
236
+ const o = (e == null ? void 0 : e[t]) || L[t] || { color: "default", text: String(t) };
237
+ return /* @__PURE__ */ r(q, { color: o.color, children: o.text });
238
+ }
239
+ class le extends _ {
240
+ constructor(e) {
241
+ super(e), this.state = { hasError: !1, error: null, errorInfo: null }, this.handleReset = () => {
242
+ this.setState({ hasError: !1, error: null, errorInfo: null }), typeof this.props.onReset == "function" && this.props.onReset();
243
+ };
244
+ }
245
+ static getDerivedStateFromError(e) {
246
+ return { hasError: !0, error: e };
247
+ }
248
+ componentDidCatch(e, o) {
249
+ console.error("[ErrorBoundary] caught error:", e, o), this.setState({ errorInfo: o });
250
+ }
251
+ render() {
252
+ var e;
253
+ return this.state.hasError ? /* @__PURE__ */ r(
254
+ F,
255
+ {
256
+ status: "error",
257
+ title: "页面出错了",
258
+ subTitle: String(((e = this.state.error) == null ? void 0 : e.message) || this.state.error),
259
+ extra: /* @__PURE__ */ r(k, { type: "primary", onClick: this.handleReset, children: "重试" })
260
+ }
261
+ ) : this.props.children;
262
+ }
263
+ }
264
+ const me = {
265
+ AppLayout: re,
266
+ StatusTag: ie,
267
+ defaultStatusMap: L,
268
+ LoginPage: ae,
269
+ ErrorBoundary: le,
270
+ request: M,
271
+ authRequest: se,
272
+ createRequest: C
273
+ };
274
+ export {
275
+ re as AppLayout,
276
+ xe as CategoryDot,
277
+ we as DarkBanner,
278
+ Ie as EChartsChart,
279
+ ke as EmptyState,
280
+ le as ErrorBoundary,
281
+ Ce as ErrorState,
282
+ be as FeatureCard,
283
+ Re as GradientStatCard,
284
+ ve as LoadingState,
285
+ ae as LoginPage,
286
+ ze as PageHeader,
287
+ Me as PagedTable,
288
+ Le as RefreshButton,
289
+ Ee as SearchInput,
290
+ Oe as SectionHeader,
291
+ Be as StatusBadge,
292
+ ie as StatusTag,
293
+ je as TableToolbar,
294
+ Te as antdTheme,
295
+ se as authRequest,
296
+ Ke as brand,
297
+ C as createRequest,
298
+ me as default,
299
+ L as defaultStatusMap,
300
+ $e as fontSize,
301
+ De as lift,
302
+ Pe as neutral,
303
+ qe as palette,
304
+ Fe as radius,
305
+ M as request,
306
+ oe as setupInterceptors,
307
+ He as shadow,
308
+ We as space,
309
+ ne as unwrapResponse
310
+ };
package/dist/ui.js ADDED
@@ -0,0 +1,27 @@
1
+ import { C as e, D as t, E as r, a as d, b as n, F as o, G as S, L as h, P as i, c as l, R as g, S as p, d as u, e as C, T as b, f, g as T, h as c, l as E, n as m, p as B, r as D, s as P, i as y } from "./PagedTable-DyjNokXN.js";
2
+ export {
3
+ e as CategoryDot,
4
+ t as DarkBanner,
5
+ r as EChartsChart,
6
+ d as EmptyState,
7
+ n as ErrorState,
8
+ o as FeatureCard,
9
+ S as GradientStatCard,
10
+ h as LoadingState,
11
+ i as PageHeader,
12
+ l as PagedTable,
13
+ g as RefreshButton,
14
+ p as SearchInput,
15
+ u as SectionHeader,
16
+ C as StatusBadge,
17
+ b as TableToolbar,
18
+ f as antdTheme,
19
+ T as brand,
20
+ c as fontSize,
21
+ E as lift,
22
+ m as neutral,
23
+ B as palette,
24
+ D as radius,
25
+ P as shadow,
26
+ y as space
27
+ };
package/package.json CHANGED
@@ -1,64 +1,72 @@
1
1
  {
2
2
  "name": "@yuku123/z-frontend-common",
3
- "version": "0.2.9",
4
- "private": false,
5
- "description": "z-opc 共享前端组件库 - AppLayout / StatusTag / LoginPage / ErrorBoundary + 统一 createRequest 工厂",
6
- "keywords": [
7
- "react",
8
- "antd",
9
- "vite",
10
- "frontend",
11
- "z-opc"
12
- ],
13
- "license": "MIT",
14
- "author": {
15
- "name": "zifang",
16
- "email": "1340947819@qq.com"
17
- },
18
- "homepage": "https://github.com/yuku123/z-opc-frontend/tree/main/packages/z-frontend-common#readme",
19
- "repository": {
20
- "type": "git",
21
- "url": "https://github.com/yuku123/z-opc-frontend.git",
22
- "directory": "packages/z-frontend-common"
23
- },
24
- "bugs": {
25
- "url": "https://github.com/yuku123/z-opc-frontend/issues"
26
- },
27
- "main": "./dist/z-frontend-common.umd.js",
28
- "module": "./dist/z-frontend-common.es.js",
3
+ "version": "1.1.0",
4
+ "description": "z-opc 全仓共享前端基座 — AppLayout(§1/§11/§12/§15/§16) + LoginPage(mockAuth 双模式) + EmptyState/StatusTag/ErrorBoundary + createRequest 工厂。lead 008 前端开发规范唯一承载仓",
5
+ "type": "module",
6
+ "main": "./dist/index.js",
7
+ "module": "./dist/index.js",
29
8
  "types": "./dist/index.d.ts",
30
9
  "exports": {
31
10
  ".": {
32
- "import": "./dist/z-frontend-common.es.js",
33
- "require": "./dist/z-frontend-common.umd.js"
11
+ "types": "./dist/index.d.ts",
12
+ "default": "./dist/index.js"
13
+ },
14
+ "./ui": {
15
+ "default": "./dist/ui.js"
34
16
  }
35
17
  },
36
18
  "files": [
37
19
  "dist",
38
- "src",
39
- "README.md"
20
+ "src"
40
21
  ],
41
- "publishConfig": {
42
- "access": "public",
43
- "registry": "https://registry.npmjs.org/"
44
- },
45
22
  "scripts": {
46
- "dev": "vite --port 3099",
47
23
  "build": "vite build",
48
- "preview": "vite preview"
49
- },
50
- "peerDependencies": {
51
- "react": "^19.2.0",
52
- "react-dom": "^19.2.0",
53
- "antd": "^6.3.3",
54
- "react-router-dom": "^7.13.1"
24
+ "dev": "vite build --watch",
25
+ "prepublishOnly": "vite build"
55
26
  },
56
27
  "dependencies": {
57
28
  "axios": "^1.16.1"
58
29
  },
30
+ "peerDependencies": {
31
+ "@ant-design/icons": "^6.0.0",
32
+ "antd": "^6.0.0",
33
+ "react": "^19.0.0",
34
+ "react-dom": "^19.0.0",
35
+ "react-router-dom": "^7.0.0"
36
+ },
59
37
  "devDependencies": {
38
+ "@ant-design/icons": "^6.1.0",
39
+ "@types/react": "^19.2.0",
40
+ "@types/react-dom": "^19.2.0",
60
41
  "@vitejs/plugin-react": "^4.2.1",
61
- "vite": "^6.2.0"
42
+ "antd": "^6.3.3",
43
+ "axios": "^1.16.1",
44
+ "react": "^19.2.0",
45
+ "react-dom": "^19.2.0",
46
+ "react-router-dom": "^7.13.1",
47
+ "vite": "^6.2.6"
48
+ },
49
+ "repository": {
50
+ "type": "git",
51
+ "url": "git+https://github.com/z-opc-foundation/z-frontend-common.git"
62
52
  },
63
- "style": "./dist/z-frontend-common.css"
53
+ "bugs": {
54
+ "url": "https://github.com/z-opc-foundation/z-frontend-common/issues"
55
+ },
56
+ "homepage": "https://github.com/z-opc-foundation/z-frontend-common#readme",
57
+ "keywords": [
58
+ "react",
59
+ "antd",
60
+ "vite",
61
+ "z-opc",
62
+ "frontend-common",
63
+ "applayout",
64
+ "admin-shell"
65
+ ],
66
+ "author": "yuku123",
67
+ "license": "MIT",
68
+ "publishConfig": {
69
+ "registry": "https://registry.npmjs.org/",
70
+ "access": "public"
71
+ }
64
72
  }
@@ -1,93 +1,40 @@
1
- import React from 'react'
2
- import {Alert, Button, Space} from 'antd'
3
- import {BugOutlined, ReloadOutlined} from '@ant-design/icons'
1
+ import { Component } from 'react'
2
+ import { Button, Result } from 'antd'
4
3
 
5
4
  /**
6
- * React Error Boundary — 捕获子组件的 render/lifecycle/effect 异常,
7
- * 用 fallback UI 替代冒泡到整棵 React 树导致整体卸载。
8
- *
9
- * 用法:
10
- * <ErrorBoundary fallbackTitle="流程编辑器加载失败">
11
- * <WorkflowEditor />
12
- * </ErrorBoundary>
5
+ * 兜底错误边界(0.1.1 契约保留):render 崩了显示错误 + 重置按钮。
6
+ * props: children + 可选 onReset(点「重试」时回调,缺省只清内部态)。
13
7
  */
14
- export default class ErrorBoundary extends React.Component {
8
+ export default class ErrorBoundary extends Component {
15
9
  constructor(props) {
16
10
  super(props)
17
- this.state = {hasError: false, error: null, errorInfo: null}
11
+ this.state = { hasError: false, error: null, errorInfo: null }
12
+ this.handleReset = () => {
13
+ this.setState({ hasError: false, error: null, errorInfo: null })
14
+ typeof this.props.onReset === 'function' && this.props.onReset()
15
+ }
18
16
  }
19
17
 
20
18
  static getDerivedStateFromError(error) {
21
- return {hasError: true, error}
22
- }
23
-
24
- componentDidCatch(error, errorInfo) {
25
- // eslint-disable-next-line no-console
26
- console.error('[ErrorBoundary] caught error:', error, errorInfo)
27
- this.setState({errorInfo})
19
+ return { hasError: true, error }
28
20
  }
29
21
 
30
- handleReset = () => {
31
- this.setState({hasError: false, error: null, errorInfo: null})
32
- if (typeof this.props.onReset === 'function') {
33
- this.props.onReset()
34
- }
22
+ componentDidCatch(error, info) {
23
+ console.error('[ErrorBoundary] caught error:', error, info)
24
+ this.setState({ errorInfo: info })
35
25
  }
36
26
 
37
27
  render() {
38
- if (!this.state.hasError) {
39
- return this.props.children
40
- }
41
-
42
- const {fallbackTitle = '组件加载失败', fallbackDescription, showReload = true} = this.props
43
- const errMsg = (this.state.error && (this.state.error.message || String(this.state.error))) || '未知错误'
44
-
45
- return (
46
- <div
47
- style={{
48
- padding: 24,
49
- background: '#fff2f0',
50
- border: '1px solid #ffccc7',
51
- borderRadius: 8,
52
- minHeight: 200,
53
- }}
54
- >
55
- <Alert
56
- type="error"
57
- showIcon
58
- icon={<BugOutlined/>}
59
- message={fallbackTitle}
60
- description={
61
- <div>
62
- <div style={{marginBottom: 8}}>
63
- {fallbackDescription || '当前组件发生了异常,已被错误边界捕获。其他功能仍可正常使用。'}
64
- </div>
65
- <div
66
- style={{
67
- fontFamily: 'Menlo, Monaco, Consolas, monospace',
68
- fontSize: 12,
69
- color: '#cf1322',
70
- background: '#fff',
71
- padding: 8,
72
- borderRadius: 4,
73
- border: '1px solid #ffccc7',
74
- wordBreak: 'break-word',
75
- whiteSpace: 'pre-wrap',
76
- }}
77
- >
78
- {errMsg}
79
- </div>
80
- </div>
81
- }
28
+ if (this.state.hasError) {
29
+ return (
30
+ <Result
31
+ status="error"
32
+ title="页面出错了"
33
+ subTitle={String(this.state.error?.message || this.state.error)}
34
+ extra={<Button type="primary" onClick={this.handleReset}>重试</Button>}
82
35
  />
83
- {showReload && (
84
- <Space style={{marginTop: 16}}>
85
- <Button icon={<ReloadOutlined/>} onClick={this.handleReset}>
86
- 重试
87
- </Button>
88
- </Space>
89
- )}
90
- </div>
91
- )
36
+ )
37
+ }
38
+ return this.props.children
92
39
  }
93
40
  }