openxiangda 1.0.67 → 1.0.69

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 (23) hide show
  1. package/package.json +1 -1
  2. package/templates/openxiangda-react-spa/AGENTS.md +26 -19
  3. package/templates/openxiangda-react-spa/src/app/navigation.ts +165 -0
  4. package/templates/openxiangda-react-spa/src/app/router.tsx +20 -62
  5. package/templates/openxiangda-react-spa/src/app/starter-content.ts +182 -0
  6. package/templates/openxiangda-react-spa/src/layouts/AdminShell.tsx +94 -217
  7. package/templates/openxiangda-react-spa/src/layouts/PublicShell.tsx +6 -6
  8. package/templates/openxiangda-react-spa/src/layouts/UserShell.tsx +15 -15
  9. package/templates/openxiangda-react-spa/src/pages/admin/AdminDashboardPage.tsx +193 -0
  10. package/templates/openxiangda-react-spa/src/pages/admin/DataCenterPage.tsx +96 -0
  11. package/templates/openxiangda-react-spa/src/pages/admin/ServiceCenterPage.tsx +100 -0
  12. package/templates/openxiangda-react-spa/src/pages/admin/TaskCenterPage.tsx +135 -0
  13. package/templates/openxiangda-react-spa/src/pages/defaults/DataRoutePage.tsx +22 -25
  14. package/templates/openxiangda-react-spa/src/pages/defaults/FilePreviewRoutePage.tsx +41 -45
  15. package/templates/openxiangda-react-spa/src/pages/defaults/FormRoutePage.tsx +22 -30
  16. package/templates/openxiangda-react-spa/src/pages/portal/UserPortalPage.tsx +47 -42
  17. package/templates/openxiangda-react-spa/src/pages/public/PublicHomePage.tsx +30 -31
  18. package/templates/openxiangda-react-spa/src/pages/states/NotFoundPage.tsx +7 -7
  19. package/templates/openxiangda-react-spa/src/resources/menus/menus.json +32 -5
  20. package/templates/openxiangda-react-spa/src/resources/roles/roles.json +2 -2
  21. package/templates/openxiangda-react-spa/src/shared/mac-admin.tsx +2 -2
  22. package/templates/openxiangda-react-spa/src/shared/ui.tsx +13 -0
  23. package/templates/openxiangda-react-spa/src/pages/admin/RuntimeWorkspacePage.tsx +0 -219
@@ -1,58 +1,68 @@
1
- import { FileSearch, LockKeyhole, ShieldCheck, Ticket } from "lucide-react";
1
+ import { ExternalLink, LockKeyhole, ShieldCheck } from "lucide-react";
2
2
  import { useParams } from "react-router-dom";
3
3
 
4
- import {
5
- MacDiagnosticPanel,
6
- MacPageHeader,
7
- MacPanel,
8
- MacStatePage,
9
- MacStatusPill,
10
- } from "@/shared/mac-admin";
11
4
  import {
12
5
  defaultPageOverrides,
13
6
  resolveDefaultPageOverride,
14
7
  } from "@/runtime/default-page-overrides";
8
+ import {
9
+ PageHeader,
10
+ Panel,
11
+ PrimaryButton,
12
+ StatePage,
13
+ StatusPill,
14
+ } from "@/shared/ui";
15
+
16
+ const servicePrefix = process.env.APP_SERVICE_PREFIX || "/service";
15
17
 
16
18
  export function FilePreviewRoutePage() {
17
19
  const params = useParams();
18
20
  const ticket = new URLSearchParams(window.location.search).get("ticket") || "";
19
21
  const appType = params.appType || process.env.OPENXIANGDA_APP_TYPE || process.env.APP_TYPE || "";
20
22
  const Override = resolveDefaultPageOverride(defaultPageOverrides, "file-preview");
23
+ const previewUrl = ticket
24
+ ? `${servicePrefix.replace(/\/+$/, "")}/file/preview-by-ticket/${encodeURIComponent(ticket)}`
25
+ : "";
26
+
21
27
  const defaultNode = ticket ? (
22
28
  <div className="min-w-0 space-y-5">
23
- <MacPageHeader
24
- description="轻量 runtime 内置文件预览入口。后续平台文件元数据协议稳定后,可在这里直接接入预览器或通过 override 替换整页。"
25
- eyebrow="File Preview"
29
+ <PageHeader
30
+ actions={
31
+ <PrimaryButton onClick={() => window.open(previewUrl, "_blank", "noopener,noreferrer")}>
32
+ <ExternalLink size={17} />
33
+ 新窗口打开
34
+ </PrimaryButton>
35
+ }
36
+ description="通过安全链接打开文件内容。若浏览器无法直接预览,可在新窗口中打开或下载。"
26
37
  meta={
27
38
  <>
28
- <MacStatusPill tone="blue">ticket</MacStatusPill>
29
- <MacStatusPill tone="emerald">同域校验</MacStatusPill>
30
- <MacStatusPill tone="amber">可 override</MacStatusPill>
39
+ <StatusPill tone="blue">文件预览</StatusPill>
40
+ <StatusPill tone="emerald">安全访问</StatusPill>
31
41
  </>
32
42
  }
33
43
  title="文件预览"
34
44
  />
35
- <MacPanel title="预览状态" description="当前 ticket 已进入 runtime,但文件内容预览仍等待平台文件接口接入。">
36
- <div className="grid gap-4 md:grid-cols-[220px_minmax(0,1fr)]">
37
- <div className="grid min-h-44 place-items-center rounded-2xl border border-dashed border-slate-300 bg-slate-50 text-slate-500">
38
- <FileSearch size={44} />
39
- </div>
40
- <div className="min-w-0 space-y-3">
41
- <Info label="ticket" value={ticket} />
42
- <Info label="appType" value={appType || "--"} />
43
- <Info label="preview" value="waiting for file metadata API" />
44
- </div>
45
- </div>
46
- </MacPanel>
47
- <MacDiagnosticPanel data={{ appType, ticket, kind: "file-preview" }} title="文件预览上下文" />
45
+ <Panel className="min-h-[70vh] overflow-hidden p-0">
46
+ <iframe
47
+ className="min-h-[70vh] w-full border-0 bg-white"
48
+ src={previewUrl}
49
+ title="文件预览"
50
+ />
51
+ </Panel>
48
52
  </div>
49
53
  ) : (
50
- <MacStatePage
51
- description="当前链接没有携带有效 ticket。请从平台文件字段或业务页面重新打开预览。"
54
+ <StatePage
55
+ actions={
56
+ <PrimaryButton onClick={() => window.history.back()}>
57
+ <ShieldCheck size={17} />
58
+ 返回上一页
59
+ </PrimaryButton>
60
+ }
61
+ description="当前链接已失效或缺少必要的访问凭证。请从业务页面重新打开文件。"
52
62
  fullScreen
53
63
  icon={<LockKeyhole size={24} />}
54
- status="TICKET"
55
- title="文件预览 ticket 无效"
64
+ status="INVALID"
65
+ title="文件链接不可用"
56
66
  />
57
67
  );
58
68
 
@@ -68,17 +78,3 @@ export function FilePreviewRoutePage() {
68
78
  </main>
69
79
  );
70
80
  }
71
-
72
- function Info({ label, value }: { label: string; value: string }) {
73
- return (
74
- <div className="flex min-w-0 items-center gap-3 rounded-2xl bg-slate-50 px-4 py-3">
75
- <span className="grid h-9 w-9 shrink-0 place-items-center rounded-xl bg-blue-50 text-blue-700">
76
- {label === "ticket" ? <Ticket size={17} /> : <ShieldCheck size={17} />}
77
- </span>
78
- <span className="min-w-0">
79
- <span className="block text-xs font-medium text-slate-500">{label}</span>
80
- <span className="block truncate text-sm font-semibold text-slate-950">{value}</span>
81
- </span>
82
- </div>
83
- );
84
- }
@@ -6,13 +6,12 @@ import { normalizeRuntimeFormSchema } from "openxiangda/runtime";
6
6
  import { useOpenXiangda, useRuntimeAuth } from "openxiangda/runtime/react";
7
7
 
8
8
  import {
9
- MacDiagnosticPanel,
10
- MacPageHeader,
11
- MacPanel,
12
- MacPrimaryButton,
13
- MacStatePage,
14
- MacStatusPill,
15
- } from "@/shared/mac-admin";
9
+ PageHeader,
10
+ Panel,
11
+ PrimaryButton,
12
+ StatePage,
13
+ StatusPill,
14
+ } from "@/shared/ui";
16
15
  import {
17
16
  defaultPageOverrides,
18
17
  resolveDefaultPageOverride,
@@ -90,7 +89,7 @@ export function FormRoutePage({ mode }: { mode: Mode }) {
90
89
  const pageCopy = useMemo(() => resolvePageCopy(overrideKind, mode), [mode, overrideKind]);
91
90
 
92
91
  if (error) return <DefaultErrorState error={error} />;
93
- if (!schema) return <DefaultLoadingState description="正在读取表单配置、字段权限和默认值。" title="加载默认页" />;
92
+ if (!schema) return <DefaultLoadingState description="正在读取页面配置和当前用户权限。" title="正在加载" />;
94
93
 
95
94
  const Override = resolveDefaultPageOverride(defaultPageOverrides, overrideKind, formUuid);
96
95
  const defaultNode = (
@@ -112,19 +111,17 @@ export function FormRoutePage({ mode }: { mode: Mode }) {
112
111
 
113
112
  return (
114
113
  <div className="min-w-0 space-y-5">
115
- <MacPageHeader
114
+ <PageHeader
116
115
  description={pageCopy.description}
117
- eyebrow={pageCopy.eyebrow}
118
116
  meta={
119
117
  <>
120
- <MacStatusPill tone={isProcessForm ? "amber" : "blue"}>{isProcessForm ? "流程表单" : "普通表单"}</MacStatusPill>
121
- <MacStatusPill tone="emerald">后端权限兜底</MacStatusPill>
122
- <MacStatusPill tone="violet">override ready</MacStatusPill>
118
+ <StatusPill tone={isProcessForm ? "amber" : "blue"}>{isProcessForm ? "流程办理" : "业务申请"}</StatusPill>
119
+ <StatusPill tone="emerald">权限已校验</StatusPill>
123
120
  </>
124
121
  }
125
122
  title={pageCopy.title}
126
123
  />
127
- <MacPanel className="min-w-0 overflow-hidden">
124
+ <Panel className="min-w-0 overflow-hidden">
128
125
  {Override ? (
129
126
  <Override
130
127
  appType={appType}
@@ -137,15 +134,14 @@ export function FormRoutePage({ mode }: { mode: Mode }) {
137
134
  ) : (
138
135
  defaultNode
139
136
  )}
140
- </MacPanel>
141
- <MacDiagnosticPanel data={{ appType, formInstId, formUuid, kind: overrideKind }} title="默认页上下文" />
137
+ </Panel>
142
138
  </div>
143
139
  );
144
140
  }
145
141
 
146
142
  function DefaultLoadingState({ description, title }: { description: string; title: string }) {
147
143
  return (
148
- <MacStatePage
144
+ <StatePage
149
145
  description={description}
150
146
  icon={<FileText size={24} />}
151
147
  status="LOADING"
@@ -165,8 +161,8 @@ function DefaultErrorState({ error }: { error: PageError }) {
165
161
 
166
162
  if (error.type === "unauthenticated") {
167
163
  return (
168
- <MacStatePage
169
- actions={<MacPrimaryButton onClick={() => void auth.redirectToLogin({ replace: true })}>去登录</MacPrimaryButton>}
164
+ <StatePage
165
+ actions={<PrimaryButton onClick={() => void auth.redirectToLogin({ replace: true })}>去登录</PrimaryButton>}
170
166
  description="当前没有有效登录态,正在跳转到登录页。"
171
167
  icon={<LogIn size={24} />}
172
168
  status="401"
@@ -176,11 +172,11 @@ function DefaultErrorState({ error }: { error: PageError }) {
176
172
  }
177
173
 
178
174
  return (
179
- <MacStatePage
175
+ <StatePage
180
176
  description={error.message || "请确认当前用户是否拥有表单、流程或数据访问权限。"}
181
177
  icon={error.type === "forbidden" ? <Shield size={24} /> : <Workflow size={24} />}
182
178
  status={error.type === "forbidden" ? "403" : String(error.status || "ERROR")}
183
- title={error.type === "forbidden" ? "无权访问默认页" : "默认页加载失败"}
179
+ title={error.type === "forbidden" ? "无权访问当前页面" : "页面加载失败"}
184
180
  />
185
181
  );
186
182
  }
@@ -188,29 +184,25 @@ function DefaultErrorState({ error }: { error: PageError }) {
188
184
  function resolvePageCopy(kind: DefaultPageKind, mode: Mode) {
189
185
  if (kind === "process-submit") {
190
186
  return {
191
- description: "使用 SDK 内置提交页发起流程,审批预览和字段权限由后端接口决定。",
192
- eyebrow: "Process Submit",
187
+ description: "填写并提交流程申请,提交后可继续查看办理进度。",
193
188
  title: "发起流程",
194
189
  };
195
190
  }
196
191
  if (kind === "process-detail" || mode === "process") {
197
192
  return {
198
- description: "查看流程详情、审批动作和流程节点信息,操作权限由后端判定。",
199
- eyebrow: "Process Detail",
193
+ description: "查看流程内容、办理进度和可执行操作。",
200
194
  title: "流程详情",
201
195
  };
202
196
  }
203
197
  if (kind === "form-detail") {
204
198
  return {
205
- description: "查看表单详情、变更记录和字段权限状态。",
206
- eyebrow: "Form Detail",
199
+ description: "查看业务记录详情和相关信息。",
207
200
  title: "表单详情",
208
201
  };
209
202
  }
210
203
  return {
211
- description: "使用 SDK 内置提交页提交普通表单,提交成功后跳转到详情页。",
212
- eyebrow: "Form Submit",
213
- title: "发起表单",
204
+ description: "填写并提交业务申请,提交成功后可查看记录详情。",
205
+ title: "发起申请",
214
206
  };
215
207
  }
216
208
 
@@ -1,66 +1,71 @@
1
- import { ArrowRight, FileText, Inbox, Search, Sparkles } from "lucide-react";
1
+ import { ArrowRight, FileText, Inbox, Search, ShieldCheck } from "lucide-react";
2
2
 
3
+ import { portalEntries, recentActivities } from "@/app/starter-content";
3
4
  import {
4
- MacListItem,
5
- MacMetricCard,
6
- MacPageHeader,
7
- MacPanel,
8
- MacStatusPill,
9
- } from "@/shared/mac-admin";
5
+ ListItem,
6
+ MetricCard,
7
+ PageHeader,
8
+ Panel,
9
+ StatusPill,
10
+ } from "@/shared/ui";
10
11
 
11
- const entries = [
12
- { desc: "打开常用表单和流程", icon: FileText, title: "发起申请", tone: "blue" as const },
13
- { desc: "处理审批与办理任务", icon: Inbox, title: "我的待办", tone: "amber" as const },
14
- { desc: "查看有权限的数据列表", icon: Search, title: "数据查询", tone: "emerald" as const },
15
- ];
12
+ const icons = [FileText, Inbox, Search];
16
13
 
17
14
  export function UserPortalPage() {
18
15
  return (
19
16
  <div className="min-w-0 space-y-5">
20
- <MacPageHeader
21
- description="面向普通用户的入口页,和后台共享同一套登录、权限与 SDK。你可以把这里替换成业务门户、移动端入口或任务中心。"
22
- eyebrow="User Portal"
17
+ <PageHeader
18
+ description="普通用户可以在这里发起申请、查看事项进度,并查询自己有权限访问的数据。"
23
19
  meta={
24
20
  <>
25
- <MacStatusPill tone="emerald">真实用户身份</MacStatusPill>
26
- <MacStatusPill tone="blue">页面 code 权限</MacStatusPill>
27
- <MacStatusPill tone="violet">可自定义路由</MacStatusPill>
21
+ <StatusPill tone="emerald">已登录</StatusPill>
22
+ <StatusPill tone="blue">服务入口</StatusPill>
23
+ <StatusPill tone="violet">我的事项</StatusPill>
28
24
  </>
29
25
  }
30
26
  title="用户门户"
31
27
  />
28
+
32
29
  <section className="grid gap-4 md:grid-cols-3">
33
- {entries.map(entry => (
34
- <MacMetricCard
30
+ {portalEntries.map((entry, index) => (
31
+ <MetricCard
35
32
  caption={entry.desc}
36
- icon={entry.icon}
37
- key={entry.title}
38
- label={entry.title}
33
+ icon={icons[index]}
34
+ key={entry.label}
35
+ label={entry.label}
39
36
  tone={entry.tone}
40
37
  value={<span className="text-base">进入</span>}
41
38
  />
42
39
  ))}
43
40
  </section>
44
- <MacPanel title="最近任务" description="示例内容来自 starter,真实项目可以接入流程待办或业务表单。">
45
- <div className="grid gap-3 md:grid-cols-2">
46
- {entries.map(entry => (
47
- <MacListItem key={entry.title} tone={entry.tone}>
48
- <div className="flex items-center justify-between gap-3">
49
- <div className="min-w-0">
50
- <div className="truncate text-sm font-semibold text-slate-950">{entry.title}</div>
51
- <div className="mt-1 truncate text-xs text-slate-500">{entry.desc}</div>
41
+
42
+ <section className="grid gap-5 lg:grid-cols-[minmax(0,1fr)_360px]">
43
+ <Panel title="我的事项" description="常用事项会集中展示,便于持续跟进。">
44
+ <div className="grid gap-3 md:grid-cols-2">
45
+ {portalEntries.map(entry => (
46
+ <ListItem key={entry.label} tone={entry.tone}>
47
+ <div className="flex items-center justify-between gap-3">
48
+ <div className="min-w-0">
49
+ <div className="truncate text-sm font-semibold text-slate-950">{entry.label}</div>
50
+ <div className="mt-1 truncate text-xs text-slate-500">{entry.desc}</div>
51
+ </div>
52
+ <ArrowRight className="shrink-0 text-slate-400" size={17} />
52
53
  </div>
53
- <ArrowRight className="shrink-0 text-slate-400" size={17} />
54
- </div>
55
- </MacListItem>
56
- ))}
57
- <MacListItem icon={<Sparkles size={17} />} tone="violet">
58
- <div className="text-sm leading-6 text-slate-600">
59
- AI 可以通过一次性登录链接,以不同真实用户身份验证门户权限和页面状态。
60
- </div>
61
- </MacListItem>
62
- </div>
63
- </MacPanel>
54
+ </ListItem>
55
+ ))}
56
+ </div>
57
+ </Panel>
58
+
59
+ <Panel title="最近动态">
60
+ <div className="space-y-3">
61
+ {recentActivities.slice(0, 3).map(activity => (
62
+ <ListItem icon={<ShieldCheck size={17} />} key={activity} tone="emerald">
63
+ <div className="text-sm leading-6 text-slate-600">{activity}</div>
64
+ </ListItem>
65
+ ))}
66
+ </div>
67
+ </Panel>
68
+ </section>
64
69
  </div>
65
70
  );
66
71
  }
@@ -1,50 +1,49 @@
1
1
  import { FileCheck2, Globe2, LockKeyhole, MessageSquareText } from "lucide-react";
2
2
 
3
+ import { publicServices } from "@/app/starter-content";
3
4
  import {
4
- MacListItem,
5
- MacPageHeader,
6
- MacPanel,
7
- MacStatusPill,
8
- } from "@/shared/mac-admin";
5
+ ListItem,
6
+ PageHeader,
7
+ Panel,
8
+ StatusPill,
9
+ } from "@/shared/ui";
10
+
11
+ const icons = [Globe2, FileCheck2, LockKeyhole];
9
12
 
10
13
  export function PublicHomePage() {
11
14
  return (
12
15
  <div className="min-w-0 space-y-5">
13
- <MacPageHeader
14
- description="公开表单、公开查询和 ticket 状态页都在 PublicShell 下实现,不再依赖旧平台导航参数。公开链路仍需要后端接口校验。"
15
- eyebrow="Public Runtime"
16
+ <PageHeader
17
+ description="这里用于承载无需登录即可访问的说明、登记、查询或邀请链接。"
16
18
  meta={
17
19
  <>
18
- <MacStatusPill tone="blue">guest</MacStatusPill>
19
- <MacStatusPill tone="emerald">publicAccess</MacStatusPill>
20
- <MacStatusPill tone="amber">ticket 状态</MacStatusPill>
20
+ <StatusPill tone="blue">公开说明</StatusPill>
21
+ <StatusPill tone="emerald">公开登记</StatusPill>
22
+ <StatusPill tone="amber">安全链接</StatusPill>
21
23
  </>
22
24
  }
23
- title="公开访问"
25
+ title="公开服务"
24
26
  />
25
- <MacPanel title="公开链路" description="这些是 starter 默认提供的公开页能力方向。">
27
+ <Panel title="可用服务" description="把面向外部用户或访客的入口集中展示,降低访问成本。">
26
28
  <div className="grid gap-3 md:grid-cols-3">
27
- <MacListItem icon={<Globe2 size={17} />} tone="blue">
28
- <div className="text-sm font-semibold text-slate-950">公开页面</div>
29
- <div className="mt-1 text-xs text-slate-500">用于无需登录的说明、查询或入口。</div>
30
- </MacListItem>
31
- <MacListItem icon={<FileCheck2 size={17} />} tone="emerald">
32
- <div className="text-sm font-semibold text-slate-950">公开表单</div>
33
- <div className="mt-1 text-xs text-slate-500">通过后端公开访问策略提交数据。</div>
34
- </MacListItem>
35
- <MacListItem icon={<LockKeyhole size={17} />} tone="amber">
36
- <div className="text-sm font-semibold text-slate-950">Ticket 校验</div>
37
- <div className="mt-1 text-xs text-slate-500">文件预览、邀请链接等短期凭证入口。</div>
38
- </MacListItem>
29
+ {publicServices.map((service, index) => {
30
+ const Icon = icons[index];
31
+ return (
32
+ <ListItem icon={<Icon size={17} />} key={service.label} tone={service.tone}>
33
+ <div className="text-sm font-semibold text-slate-950">{service.label}</div>
34
+ <div className="mt-1 text-xs leading-5 text-slate-500">{service.desc}</div>
35
+ </ListItem>
36
+ );
37
+ })}
39
38
  </div>
40
- </MacPanel>
41
- <MacPanel title="公开提示">
42
- <MacListItem icon={<MessageSquareText size={17} />} tone="violet">
39
+ </Panel>
40
+ <Panel title="访问说明">
41
+ <ListItem icon={<MessageSquareText size={17} />} tone="violet">
43
42
  <div className="text-sm leading-6 text-slate-600">
44
- 公开访问不是绕过权限。默认模板只负责展示与路由,最终是否允许访问仍由平台接口和公开访问配置决定。
43
+ 公开页面适合发布说明、收集反馈和提供一次性访问入口。涉及敏感数据时,仍应通过后端权限和短期凭证控制访问范围。
45
44
  </div>
46
- </MacListItem>
47
- </MacPanel>
45
+ </ListItem>
46
+ </Panel>
48
47
  </div>
49
48
  );
50
49
  }
@@ -1,27 +1,27 @@
1
1
  import { Compass, Home } from "lucide-react";
2
2
  import { useParams } from "react-router-dom";
3
3
 
4
- import { MacPrimaryButton, MacSecondaryButton, MacStatePage } from "@/shared/mac-admin";
4
+ import { PrimaryButton, SecondaryButton, StatePage } from "@/shared/ui";
5
5
 
6
6
  export function NotFoundPage() {
7
7
  const { appType = process.env.OPENXIANGDA_APP_TYPE || "" } = useParams();
8
8
  const home = appType ? `/view/${appType}/admin` : "/";
9
9
 
10
10
  return (
11
- <MacStatePage
11
+ <StatePage
12
12
  actions={
13
13
  <>
14
- <MacSecondaryButton onClick={() => window.history.back()}>
14
+ <SecondaryButton onClick={() => window.history.back()}>
15
15
  <Compass size={17} />
16
16
  返回上一页
17
- </MacSecondaryButton>
18
- <MacPrimaryButton onClick={() => window.location.assign(home)}>
17
+ </SecondaryButton>
18
+ <PrimaryButton onClick={() => window.location.assign(home)}>
19
19
  <Home size={17} />
20
20
  返回入口
21
- </MacPrimaryButton>
21
+ </PrimaryButton>
22
22
  </>
23
23
  }
24
- description="请检查当前 React Router 路由、页面 code 或平台 route resolver 配置。"
24
+ description="当前访问的页面不存在,可能是链接已变更或你没有从正确入口进入。"
25
25
  fullScreen
26
26
  icon={<Compass size={24} />}
27
27
  status="404"
@@ -1,14 +1,41 @@
1
1
  {
2
2
  "menus": [
3
3
  {
4
- "code": "runtime_workspace",
5
- "name": "运行时工作台",
4
+ "code": "admin_dashboard",
5
+ "name": "业务工作台",
6
6
  "type": "nav",
7
7
  "routeCode": "admin.dashboard",
8
8
  "path": "/view/:appType/admin",
9
9
  "icon": "LayoutDashboard",
10
10
  "sortOrder": 10
11
11
  },
12
+ {
13
+ "code": "task_center",
14
+ "name": "待办中心",
15
+ "type": "nav",
16
+ "routeCode": "admin.tasks",
17
+ "path": "/view/:appType/admin/tasks",
18
+ "icon": "Inbox",
19
+ "sortOrder": 20
20
+ },
21
+ {
22
+ "code": "service_center",
23
+ "name": "服务入口",
24
+ "type": "nav",
25
+ "routeCode": "admin.services",
26
+ "path": "/view/:appType/admin/services",
27
+ "icon": "ClipboardList",
28
+ "sortOrder": 30
29
+ },
30
+ {
31
+ "code": "data_center",
32
+ "name": "数据中心",
33
+ "type": "nav",
34
+ "routeCode": "admin.data",
35
+ "path": "/view/:appType/admin/data",
36
+ "icon": "Database",
37
+ "sortOrder": 40
38
+ },
12
39
  {
13
40
  "code": "user_portal",
14
41
  "name": "用户门户",
@@ -16,16 +43,16 @@
16
43
  "routeCode": "portal.home",
17
44
  "path": "/view/:appType/portal",
18
45
  "icon": "Home",
19
- "sortOrder": 20
46
+ "sortOrder": 50
20
47
  },
21
48
  {
22
49
  "code": "public_home",
23
- "name": "公开访问",
50
+ "name": "公开服务",
24
51
  "type": "nav",
25
52
  "routeCode": "public.home",
26
53
  "path": "/view/:appType/public",
27
54
  "icon": "Globe",
28
- "sortOrder": 30
55
+ "sortOrder": 60
29
56
  }
30
57
  ]
31
58
  }
@@ -3,12 +3,12 @@
3
3
  {
4
4
  "code": "app_admin",
5
5
  "name": "应用管理员",
6
- "description": "可访问 mac-admin 后台与全部 React SPA 路由"
6
+ "description": "可访问业务工作台、待办中心、服务入口、数据中心和门户页面"
7
7
  },
8
8
  {
9
9
  "code": "app_user",
10
10
  "name": "普通用户",
11
- "description": "可访问用户门户和被授权的业务页面"
11
+ "description": "可访问用户门户和被授权的业务服务"
12
12
  }
13
13
  ]
14
14
  }
@@ -282,7 +282,7 @@ export function MacListItem({
282
282
 
283
283
  export function MacDiagnosticPanel({
284
284
  data,
285
- title = "调试信息",
285
+ title = "详细信息",
286
286
  }: {
287
287
  data: unknown;
288
288
  title?: string;
@@ -291,7 +291,7 @@ export function MacDiagnosticPanel({
291
291
  <details className="group rounded-2xl border border-slate-200/80 bg-white/70 p-4">
292
292
  <summary className="cursor-pointer select-none text-sm font-semibold text-slate-700">
293
293
  {title}
294
- <span className="ml-2 text-xs font-normal text-slate-400">展开查看 runtime payload</span>
294
+ <span className="ml-2 text-xs font-normal text-slate-400">展开查看完整内容</span>
295
295
  </summary>
296
296
  <pre className="ox-scrollbar mt-4 max-h-96 overflow-auto rounded-2xl bg-slate-950 p-4 text-xs leading-6 text-slate-100">
297
297
  {JSON.stringify(data, null, 2)}
@@ -0,0 +1,13 @@
1
+ export {
2
+ MacListItem as ListItem,
3
+ MacMetricCard as MetricCard,
4
+ MacPageHeader as PageHeader,
5
+ MacPanel as Panel,
6
+ MacPrimaryButton as PrimaryButton,
7
+ MacSecondaryButton as SecondaryButton,
8
+ MacStatePage as StatePage,
9
+ MacStatusPill as StatusPill,
10
+ MacTrendBars as TrendBars,
11
+ cn,
12
+ type MacTone as AppTone,
13
+ } from "./mac-admin";