openxiangda 1.0.39 → 1.0.40

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 (52) hide show
  1. package/README.md +2 -2
  2. package/openxiangda-skills/SKILL.md +6 -3
  3. package/openxiangda-skills/references/best-practices.md +29 -5
  4. package/openxiangda-skills/references/component-guide.md +79 -45
  5. package/openxiangda-skills/references/forms/component-registry.md +33 -1
  6. package/openxiangda-skills/skills/openxiangda-core/SKILL.md +2 -2
  7. package/openxiangda-skills/skills/openxiangda-form/SKILL.md +9 -2
  8. package/openxiangda-skills/skills/openxiangda-page/SKILL.md +5 -3
  9. package/package.json +1 -1
  10. package/packages/sdk/dist/runtime/index.cjs +546 -0
  11. package/packages/sdk/dist/runtime/index.cjs.map +1 -1
  12. package/packages/sdk/dist/runtime/index.mjs +546 -0
  13. package/packages/sdk/dist/runtime/index.mjs.map +1 -1
  14. package/packages/sdk/src/build-source/scripts/build-forms.mjs +5 -1
  15. package/templates/sy-lowcode-app-workspace/.cursor/rules/openxiangda-form.mdc +4 -0
  16. package/templates/sy-lowcode-app-workspace/.cursor/rules/openxiangda-page.mdc +2 -0
  17. package/templates/sy-lowcode-app-workspace/.cursor/rules/openxiangda.mdc +3 -0
  18. package/templates/sy-lowcode-app-workspace/.qoder/rules/openxiangda-form.md +4 -0
  19. package/templates/sy-lowcode-app-workspace/.qoder/rules/openxiangda-page.md +2 -0
  20. package/templates/sy-lowcode-app-workspace/.qoder/rules/openxiangda.md +3 -0
  21. package/templates/sy-lowcode-app-workspace/AGENTS.md +5 -0
  22. package/templates/sy-lowcode-app-workspace/examples/best-practices/README.md +8 -0
  23. package/templates/sy-lowcode-app-workspace/examples/best-practices/catalog.json +32 -0
  24. package/templates/sy-lowcode-app-workspace/examples/best-practices/decision-guide.md +20 -0
  25. package/templates/sy-lowcode-app-workspace/examples/best-practices/design-style.md +48 -0
  26. package/templates/sy-lowcode-app-workspace/examples/best-practices/src/pages/glass-home-dashboard/App.tsx +8 -0
  27. package/templates/sy-lowcode-app-workspace/examples/best-practices/src/pages/glass-home-dashboard/GlassHomeDashboard.tsx +232 -0
  28. package/templates/sy-lowcode-app-workspace/examples/best-practices/src/pages/glass-home-dashboard/index.tsx +10 -0
  29. package/templates/sy-lowcode-app-workspace/examples/best-practices/src/pages/glass-home-dashboard/page.config.ts +14 -0
  30. package/templates/sy-lowcode-app-workspace/examples/best-practices/src/pages/glass-home-dashboard/styles.css +196 -0
  31. package/templates/sy-lowcode-app-workspace/examples/best-practices/src/pages/mint-analytics-dashboard/App.tsx +8 -0
  32. package/templates/sy-lowcode-app-workspace/examples/best-practices/src/pages/mint-analytics-dashboard/MintAnalyticsDashboard.tsx +279 -0
  33. package/templates/sy-lowcode-app-workspace/examples/best-practices/src/pages/mint-analytics-dashboard/index.tsx +10 -0
  34. package/templates/sy-lowcode-app-workspace/examples/best-practices/src/pages/mint-analytics-dashboard/page.config.ts +14 -0
  35. package/templates/sy-lowcode-app-workspace/examples/best-practices/src/pages/mint-analytics-dashboard/styles.css +163 -0
  36. package/templates/sy-lowcode-app-workspace/examples/best-practices/src/pages/ops-monitor-dashboard/App.tsx +8 -0
  37. package/templates/sy-lowcode-app-workspace/examples/best-practices/src/pages/ops-monitor-dashboard/OpsMonitorDashboard.tsx +306 -0
  38. package/templates/sy-lowcode-app-workspace/examples/best-practices/src/pages/ops-monitor-dashboard/index.tsx +10 -0
  39. package/templates/sy-lowcode-app-workspace/examples/best-practices/src/pages/ops-monitor-dashboard/page.config.ts +14 -0
  40. package/templates/sy-lowcode-app-workspace/examples/best-practices/src/pages/ops-monitor-dashboard/styles.css +248 -0
  41. package/templates/sy-lowcode-app-workspace/examples/best-practices/src/pages/work-order-list-drawer/App.tsx +8 -0
  42. package/templates/sy-lowcode-app-workspace/examples/best-practices/src/pages/work-order-list-drawer/WorkOrderListDrawerPage.tsx +371 -0
  43. package/templates/sy-lowcode-app-workspace/examples/best-practices/src/pages/work-order-list-drawer/index.tsx +10 -0
  44. package/templates/sy-lowcode-app-workspace/examples/best-practices/src/pages/work-order-list-drawer/page.config.ts +14 -0
  45. package/templates/sy-lowcode-app-workspace/examples/best-practices/src/pages/work-order-list-drawer/styles.css +182 -0
  46. package/templates/sy-lowcode-app-workspace/examples/best-practices/src/shared/components/admin-ui-templates/DashboardPrimitives.tsx +832 -0
  47. package/templates/sy-lowcode-app-workspace/examples/best-practices/src/shared/components/admin-ui-templates/chartOptions.ts +140 -0
  48. package/templates/sy-lowcode-app-workspace/examples/best-practices/src/shared/components/admin-ui-templates/sampleData.ts +466 -0
  49. package/templates/sy-lowcode-app-workspace/examples/best-practices/src/shared/components/admin-ui-templates/styles.css +874 -0
  50. package/templates/sy-lowcode-app-workspace/examples/best-practices/src/shared/components/admin-ui-templates/types.ts +150 -0
  51. package/templates/sy-lowcode-app-workspace/src/forms/README.md +4 -0
  52. package/templates/sy-lowcode-app-workspace/src/main.tsx +4 -0
@@ -260,12 +260,16 @@ import { createRoot } from 'react-dom/client';
260
260
  import { StyleProvider } from '@ant-design/cssinjs';
261
261
  import { App as AntdApp, ConfigProvider, message } from 'antd';
262
262
  import zhCN from 'antd/locale/zh_CN';
263
+ import dayjs from 'dayjs';
264
+ import 'dayjs/locale/zh-cn';
263
265
  import * as SyFormComponentsModule from 'openxiangda';
264
266
  import { antdTheme, legacyAntdTheme } from 'openxiangda/antd-theme';
265
267
  import 'antd-mobile/es/global';
266
268
  import '../src/index.css';
267
269
 
268
270
  const runtimeVersion = '${runtimeVersionPlaceholder}';
271
+ dayjs.locale('zh-cn');
272
+
269
273
  const roots = new WeakMap();
270
274
  const portalContainerCleanups = new WeakMap();
271
275
  const { StandardFormPage, defineFormSchema } = SyFormComponentsModule;
@@ -454,7 +458,7 @@ function installAntdStaticHolder(el, portalContainer, cssIsolation) {
454
458
  holderRender: (children) => {
455
459
  if (!el.isConnected) {
456
460
  return (
457
- <ConfigProvider prefixCls={antdOptions.prefixCls} iconPrefixCls={antdOptions.iconPrefixCls} theme={antdOptions.theme}>
461
+ <ConfigProvider locale={zhCN} prefixCls={antdOptions.prefixCls} iconPrefixCls={antdOptions.iconPrefixCls} theme={antdOptions.theme}>
458
462
  {children}
459
463
  </ConfigProvider>
460
464
  );
@@ -11,10 +11,14 @@ Editing files under `src/forms/<formCode>/`. Use the **`openxiangda-form`** skil
11
11
  Structure: `schema.ts`(`defineFormSchema()` default export — fields / options / rules / top-level FormEffect[])+ `page.tsx`(presentation only).
12
12
 
13
13
  Pitfalls:
14
+ - 表单录入组件优先级:OpenXiangda 平台字段组件 → `antd` / `antd-mobile` wrapper → custom business component only when neither fits.
15
+ - `schema.ts` defines fields and platform components; `page.tsx` is presentation-only and should render the OpenXiangda standard form/runtime instead of assembling raw controls.
16
+ - `src/forms/**` must not contain raw native `<input>` / `<select>` / `<textarea>` / file input, hand-written pickers/uploaders, or hand-written user/department selectors.
14
17
  - 选项字段(Select/MultiSelect/Radio/Checkbox/Cascade)必须有 `options`。
15
18
  - 跨表数据 → `SelectField` + `optionSource.type: "linkedForm"`,禁止 `AssociationFormField`。
16
19
  - 顶层 `schema.rules` 仅 `FormEffect[]`(when/then),校验放字段 `rules`。
17
20
  - 平台系统字段(创建人/修改人/创建时间…)由平台维护,不要重复。
18
21
  - 派生 / 隐式权限键 → `behavior: "HIDDEN"` + `valueSync`。
22
+ - Missing platform component capability → `openxiangda feedback submit --yes`, then use an `antd` / `antd-mobile` wrapper as temporary workaround and tell the user the fingerprint.
19
23
 
20
24
  Publish: `openxiangda workspace publish --profile <name> --form <formCode>`(先 `--dry-run`)。
@@ -14,6 +14,8 @@ Strong defaults:
14
14
  - 正式入口 (admin / portal) MUST be app-shell: `entry: { mode: "app-shell", hidePlatformNav: true, defaultRoute: "<home>" }`.
15
15
  - Default `cssIsolation: "none"` + native Tailwind utilities. Don't use `bg-card` / `text-muted-foreground` shadcn tokens.
16
16
  - List pages: use `DataManagementList` + pagination + structured `filterGroup`. Never `pageSize=10000` + browser-side filter.
17
+ - Filters, search bars, modals, drawers, and inline edits: use OpenXiangda platform components for platform data fields; otherwise use `antd` / `antd-mobile`.
18
+ - AI-authored `src/pages/**` must not contain raw native `<input>` / `<select>` / `<textarea>` / file input, hand-written pickers/uploaders, or hand-written user/department selectors.
17
19
  - External APIs: `src/resources/connectors/` + `sdk.connector.call()`. Joined read-only: `src/resources/data-views/` + `sdk.dataView.query()`. Notifications: `src/resources/notifications/` + `sdk.notification`.
18
20
 
19
21
  Publish: `openxiangda workspace publish --profile <name> --page <pageCode>` (first `--dry-run`).
@@ -29,6 +29,8 @@ This is a `sy-lowcode-app-workspace` managed by the `openxiangda` CLI. See [AGEN
29
29
  - `.openxiangda/state.json` is the authoritative profile → appType → resource-ID map; CLI maintains it, do not hand-edit.
30
30
  - User tokens live in `~/.openxiangda/profiles.json`; shared env in `~/.openxiangda/.env`.
31
31
  - Form fields need user-facing `placeholder`; use `SelectField` / `RadioField` for enums, `linkedForm` SelectField for cross-form sources.
32
+ - Form-entry component priority: OpenXiangda platform components → `antd` / `antd-mobile` wrappers → custom business component only when neither fits.
33
+ - Proactively run `openxiangda feedback submit --yes` for platform defects, missing capabilities, unclear rules, repeated workarounds, AI uncertainty, and user-visible UX gaps; tell the user what was reported and the fingerprint.
32
34
  - Pages default to `cssIsolation: "none"` + native Tailwind utilities; formal entries must be app-shell.
33
35
 
34
36
  ## Never
@@ -41,6 +43,7 @@ This is a `sy-lowcode-app-workspace` managed by the `openxiangda` CLI. See [AGEN
41
43
  - ❌ Use `openxiangda form create` / `form publish` / `page publish` as the normal page generation path.
42
44
  - ❌ Store tokens / AK / SK / third-party secrets in project files.
43
45
  - ❌ `npm publish` — this workspace is `"private": true`, not an npm package.
46
+ - ❌ Raw native form controls in AI-authored `src/forms/**` / `src/pages/**`: `<input>`, `<select>`, `<textarea>`, file input, hand-written pickers/uploaders, hand-written user/department selectors.
44
47
 
45
48
  ## When unsure
46
49
 
@@ -18,11 +18,15 @@ src/forms/<formCode>/
18
18
 
19
19
  ## Common pitfalls (high signal)
20
20
 
21
+ - 表单录入组件优先级:OpenXiangda 平台字段组件 → `antd` / `antd-mobile` 包装 → 必要时自定义业务组件。
22
+ - `schema.ts` 定义字段与平台组件;`page.tsx` 只做展示布局,优先渲染 OpenXiangda 标准表单 / runtime,不要拼原生控件。
23
+ - `src/forms/**` 禁止直接写原生 `<input>` / `<select>` / `<textarea>` / `<input type="file">`、手写 picker/uploader、手写人员/部门选择器。
21
24
  - 选项字段(Select / MultiSelect / Radio / Checkbox / Cascade)必须有 `options`,不要给空。
22
25
  - 跨表数据 → `SelectField` + `optionSource.type: "linkedForm"`,**禁止** `AssociationFormField`。
23
26
  - 顶层 `schema.rules` 仅用于 `FormEffect[]`(`when` / `then`),**不要**写成校验数组;校验放字段 `rules`。
24
27
  - 平台系统字段(创建人 / 修改人 / 创建时间 / 修改时间 / 部门)由平台自动维护,**不要重复创建**。
25
28
  - 隐式权限键 / 派生键 → `behavior: "HIDDEN"` + `valueSync`。
29
+ - 平台字段缺能力时,先 `openxiangda feedback submit --yes` 反馈能力缺口,再用 `antd` / `antd-mobile` 包装做临时 workaround,并告诉用户 fingerprint。
26
30
 
27
31
  ## Publish
28
32
 
@@ -25,6 +25,8 @@ src/pages/<pageCode>/
25
25
  - 正式入口(管理后台 / PC 门户 / 移动门户)必须 `entry: { mode: "app-shell", hidePlatformNav: true, defaultRoute: "<home>" }`。
26
26
  - 默认 `cssIsolation: "none"` + 原生 Tailwind utilities(`bg-white`, `border-slate-200`, `grid-cols-[240px_1fr]`),不要 `bg-card` / `text-muted-foreground` 这些未配置的 shadcn token。
27
27
  - 列表页:用 `DataManagementList` 模式 + 分页 + 结构化 `filterGroup`,**不要** `pageSize=10000` 然后前端过滤。
28
+ - 筛选、搜索、弹窗、抽屉、行内编辑:平台数据字段优先 OpenXiangda 平台组件;普通 UI 控件用 `antd` / `antd-mobile`。
29
+ - AI-authored `src/pages/**` 禁止直接写原生 `<input>` / `<select>` / `<textarea>` / file input、手写 picker/uploader、手写人员/部门选择器。
28
30
  - 外部接口:`src/resources/connectors/` + `sdk.connector.call()`;多表只读联表:`src/resources/data-views/` + `sdk.dataView.query()`;通知:`src/resources/notifications/` + `sdk.notification`。
29
31
 
30
32
  ## Publish
@@ -29,6 +29,8 @@ This is a `sy-lowcode-app-workspace` managed by the `openxiangda` CLI. Read [AGE
29
29
  - `.openxiangda/state.json` 是 profile 到 appType / 资源 ID 的权威映射,由 CLI 维护,不要手改。
30
30
  - 用户 token 在 `~/.openxiangda/profiles.json`;共享 env 在 `~/.openxiangda/.env`。
31
31
  - 表单字段必须有 user-facing `placeholder`;选项使用 `SelectField` / `RadioField`,跨表用 `linkedForm` SelectField。
32
+ - 表单录入组件顺序:OpenXiangda 平台组件 → `antd` / `antd-mobile` 包装 → 必要时自定义业务组件。
33
+ - 发现平台缺陷、能力缺口、规则不清、反复 workaround、AI 不确定点、用户可见体验问题时,主动 `openxiangda feedback submit --yes`;提交后告诉用户反馈内容和 fingerprint。
32
34
  - 页面默认 `cssIsolation: "none"` + 原生 Tailwind utilities;正式入口必须是 app-shell。
33
35
 
34
36
  ## Never
@@ -41,6 +43,7 @@ This is a `sy-lowcode-app-workspace` managed by the `openxiangda` CLI. Read [AGE
41
43
  - ❌ `openxiangda form create` / `form publish` / `page publish` 当作页面生成方式(仅底层修复)。
42
44
  - ❌ 把 token / AK / SK / 第三方密钥写进项目文件。
43
45
  - ❌ `npm publish` — 本工作区 `"private": true`,不发 npm 包。
46
+ - ❌ 在 AI 生成的 `src/forms/**` / `src/pages/**` 直接写原生 `<input>` / `<select>` / `<textarea>` / file input、手写 picker/uploader、手写人员/部门选择器。
44
47
 
45
48
  ## When unsure
46
49
 
@@ -35,6 +35,8 @@
35
35
  - ✅ 共享环境(`APP_OSS_*`、反馈机器人等)在 `~/.openxiangda/.env`,项目 `.env` 仅做 per-workspace override。
36
36
  - ✅ 多 profile(dev / prod / ...)资源 ID 互不复用;每个 profile 的 `appType` / `formUuid` / `pageId` / `workflowId` / `automationId` 独立维护。
37
37
  - ✅ 改已有应用前先 `openxiangda app snapshot APP_XXX --profile <name> --json`。
38
+ - ✅ 表单录入组件选择顺序:OpenXiangda 平台表单组件 → `antd` / `antd-mobile` 包装 → 只有两者都不满足时才写自定义业务组件。
39
+ - ✅ 发现平台缺陷、能力缺口、规则不清、反复 workaround、AI 不确定点、用户可见体验问题时,主动 `openxiangda feedback submit --yes`;发送后告诉用户反馈内容和 fingerprint。
38
40
 
39
41
  ## 严禁
40
42
 
@@ -45,12 +47,15 @@
45
47
  - ❌ 改一个文件就 `workspace publish` 全量。
46
48
  - ❌ 把 token、AK、SK、第三方密钥写进项目文件。
47
49
  - ❌ `npm publish` —— 这个工作区是 `"private": true` 的应用工作区,不是要发到 npm 的 package。
50
+ - ❌ 在 AI 生成的 `src/forms/**` / `src/pages/**` 里直接写原生 `<input>` / `<select>` / `<textarea>` / `<input type="file">`、手写 picker、手写 uploader、手写人员/部门选择器。原生控件只允许出现在 OpenXiangda SDK / 平台组件内部。
48
51
 
49
52
  ## 表单 / 页面写作约束(高频踩坑)
50
53
 
51
54
  - 表单字段:可见字段必须有用户能看懂的 `placeholder`;`tips` 只用于特殊约束。
55
+ - 表单录入:优先在 `schema.ts` 使用 `TextField` / `SelectField` / `DateField` / `UserSelectField` / `AttachmentField` 等平台字段;`page.tsx` 只做展示布局,不要拼原生控件。
52
56
  - 表单选项:用 `SelectField` / `RadioField` 表枚举;跨表数据用 `SelectField` + `optionSource.type: "linkedForm"`(数据量大时加 `remoteSearch: true` + `searchFieldId`)。**禁止**新建 `AssociationFormField`。
53
57
  - 权限隐式键、计算字段、同步字段:在 schema 中保留 `behavior: "HIDDEN"`,由可见字段通过 `valueSync` 派生,不要让用户填裸 ID。
58
+ - 页面筛选 / 弹窗 / 抽屉 / 行内编辑:平台数据字段优先平台组件;普通 UI 控件用 `antd` / `antd-mobile`,不要用原生表单控件。
54
59
  - 页面默认 `cssIsolation: "none"` + 原生 Tailwind utilities(`bg-white`、`border-slate-200`、`grid-cols-[240px_1fr]` 等),不要用 `bg-card` / `text-muted-foreground` 这类未配置的 shadcn token。
55
60
  - 列表页用 `DataManagementList` 模式 + 分页 + 结构化 `filterGroup`,不要 `pageSize=10000` 然后前端过滤。
56
61
  - 正式入口(管理后台 / PC 门户 / 移动门户)必须是 app-shell:`page.config.ts` 里 `entry: { mode: "app-shell", hidePlatformNav: true, defaultRoute: "<home>" }`。
@@ -7,6 +7,8 @@ They are copied by `workspace init`, but they are not scanned by
7
7
  Copy the pieces you need into `src/`:
8
8
 
9
9
  ```bash
10
+ cp -R examples/best-practices/src/shared/components/admin-ui-templates src/shared/components/
11
+ cp -R examples/best-practices/src/pages/work-order-list-drawer src/pages/
10
12
  cp -R examples/best-practices/src/domain/service-ticket src/domain/
11
13
  cp -R examples/best-practices/src/shared/services/service-ticket.ts src/shared/services/
12
14
  cp -R examples/best-practices/src/pages/service-ticket-ops src/pages/
@@ -27,6 +29,12 @@ Run `pnpm examples:check` after editing examples, and run the normal
27
29
  - Use workflow only for real approval tasks.
28
30
  - Query with pagination and structured conditions. Avoid large page sizes,
29
31
  client-side filtering, and broad `searchKeyWord` queries.
32
+ - For admin UI, choose one optional default from `glass-home-dashboard`,
33
+ `mint-analytics-dashboard`, `ops-monitor-dashboard`, or
34
+ `work-order-list-drawer`; use `work-order-list-drawer` as the default CRUD
35
+ list pattern.
36
+ - Keep record detail and all create/edit/process forms in drawers or modals;
37
+ do not keep a permanent right-side detail column on data-management pages.
30
38
 
31
39
  Read `decision-guide.md`, `module-structure.md`, and `design-style.md` before
32
40
  using any template.
@@ -3,6 +3,38 @@
3
3
  "publishedByDefault": false,
4
4
  "copyInto": "src/",
5
5
  "templates": [
6
+ {
7
+ "code": "glass-home-dashboard",
8
+ "type": "page-ui-template",
9
+ "path": "src/pages/glass-home-dashboard",
10
+ "uiTemplate": "glass-home-dashboard",
11
+ "recommendedFor": ["经营首页", "管理驾驶舱", "轻量门户首页"],
12
+ "description": "Default light-blue glass dashboard shell with sidebar, top search, welcome banner, quick actions, KPI cards, charts, ranking, activity feed, query states, and drawer form actions."
13
+ },
14
+ {
15
+ "code": "mint-analytics-dashboard",
16
+ "type": "page-ui-template",
17
+ "path": "src/pages/mint-analytics-dashboard",
18
+ "uiTemplate": "mint-analytics-dashboard",
19
+ "recommendedFor": ["数据分析", "BI 概览", "经营日报"],
20
+ "description": "Mint analytics dashboard with high-density metrics, line/bar/donut charts, notices, todos, business summary, system health, query states, and drawer form actions."
21
+ },
22
+ {
23
+ "code": "ops-monitor-dashboard",
24
+ "type": "page-ui-template",
25
+ "path": "src/pages/ops-monitor-dashboard",
26
+ "uiTemplate": "ops-monitor-dashboard",
27
+ "recommendedFor": ["运营监控", "任务中心", "系统健康度", "告警中心"],
28
+ "description": "Blue-purple operations monitor with realtime trends, animated metric cards, task progress, health score, device status, alerts, quick actions, query states, and drawer form actions."
29
+ },
30
+ {
31
+ "code": "work-order-list-drawer",
32
+ "type": "page-ui-template",
33
+ "path": "src/pages/work-order-list-drawer",
34
+ "uiTemplate": "work-order-list-drawer",
35
+ "recommendedFor": ["CRUD 列表", "工单管理", "审批处理", "数据管理页"],
36
+ "description": "Default restrained admin list template with filters, toolbar, status stats, table, loading/empty/error branches, and right-side overlay drawers for detail, create, edit, and process forms."
37
+ },
6
38
  {
7
39
  "code": "customer-profile",
8
40
  "type": "form",
@@ -12,6 +12,26 @@ Use `DataManagementList` for list/search/export/batch-management pages. Extend
12
12
  it with row actions, custom renderers, and drawers instead of rebuilding
13
13
  pagination, export, and filters from scratch.
14
14
 
15
+ ## Default Admin UI Templates
16
+
17
+ The UI templates are recommended starting points, not mandatory styles. Choose
18
+ one based on the page's primary job:
19
+
20
+ - `work-order-list-drawer`: default for CRUD, approval handling, work orders,
21
+ ticket lists, and data-management pages. Detail, create, edit, and process
22
+ forms use right-side overlay drawers; do not reserve a permanent right detail
23
+ column that squeezes the table.
24
+ - `glass-home-dashboard`: default for a friendly PC admin home page, management
25
+ portal, or first-screen business overview.
26
+ - `mint-analytics-dashboard`: default for analysis-heavy dashboards, weekly
27
+ business reviews, BI-like reports, and data-summary pages.
28
+ - `ops-monitor-dashboard`: default for realtime operations, task execution,
29
+ alerts, system health, and monitoring centers.
30
+
31
+ When a page combines list management and a dashboard, start from
32
+ `work-order-list-drawer` if users spend most time operating rows. Start from a
33
+ dashboard template only when the main job is reading metrics.
34
+
15
35
  ## State Flow Is Not Workflow
16
36
 
17
37
  Most business "processes" are lifecycle state changes:
@@ -2,6 +2,50 @@
2
2
 
3
3
  OpenXiangda business apps should feel like focused operational tools.
4
4
 
5
+ ## Default Admin UI Templates
6
+
7
+ These templates are polished defaults for B-end admin pages. They are optional
8
+ starting points, not hard product constraints.
9
+
10
+ ### `glass-home-dashboard`
11
+
12
+ - Use for PC admin home pages, management portals, and general business
13
+ dashboards.
14
+ - Visual direction: light blue glass surface, soft sidebar, translucent panels,
15
+ welcoming banner, KPI cards with small trends, quick actions, chart blocks,
16
+ ranking, activity feed, and target progress.
17
+ - Keep density medium. The first viewport should make the platform identity,
18
+ navigation, search, and key metrics obvious.
19
+
20
+ ### `mint-analytics-dashboard`
21
+
22
+ - Use for BI-style analysis, business reviews, operational reports, and weekly
23
+ summary pages.
24
+ - Visual direction: low-saturation mint green, tighter metric cards, structured
25
+ chart grid, notification and todo panels, business summary, and health score.
26
+ - Keep labels short and chart containers stable. Favor comparison, trend, and
27
+ distribution charts over decorative widgets.
28
+
29
+ ### `ops-monitor-dashboard`
30
+
31
+ - Use for realtime monitoring, operations centers, task execution, system
32
+ health, and alert pages.
33
+ - Visual direction: blue-purple accent, stronger status hierarchy, realtime
34
+ traffic chart, task progress bars, system rings, device state, alert list, and
35
+ subtle CSS motion.
36
+ - Do not add GSAP or other animation dependencies by default. Use lightweight
37
+ CSS transitions unless a product requirement needs a true timeline engine.
38
+
39
+ ### `work-order-list-drawer`
40
+
41
+ - Use as the default CRUD/data-management template for tickets, approvals,
42
+ orders, assets, and record operations.
43
+ - Layout: fixed app shell, compact filters, toolbar, status stat cards, dense
44
+ table, pagination, and right-side overlay drawer.
45
+ - Detail, create, edit, approve, reject, and process forms open in `Drawer` or
46
+ `Modal`. Do not put a permanent form/detail column beside the table, because
47
+ it narrows the main working area and makes table operations less stable.
48
+
5
49
  ## Interaction Defaults
6
50
 
7
51
  - Every async page has loading, refreshing, empty, error, and submit-pending
@@ -9,6 +53,8 @@ OpenXiangda business apps should feel like focused operational tools.
9
53
  - List refresh should keep existing rows visible and show a small refresh state.
10
54
  - Mutating actions need confirmation, pending feedback, success feedback, and a
11
55
  failure refresh or rollback path.
56
+ - Detail, create, edit, approval, and processing workflows should use an overlay
57
+ `Drawer` or `Modal` with fixed header, scrollable body, and footer actions.
12
58
  - Mobile actions should use a bottom action area, drawer, or action sheet; do
13
59
  not copy a dense PC table toolbar to mobile.
14
60
 
@@ -19,6 +65,8 @@ OpenXiangda business apps should feel like focused operational tools.
19
65
  - Use status tags, responsibility fields, and latest action summaries for
20
66
  lifecycle data.
21
67
  - Do not build marketing-style hero pages for business tools.
68
+ - Do not nest cards inside cards. Use panels for page regions, and use cards
69
+ only for repeated items, modals/drawers, or genuinely framed controls.
22
70
 
23
71
  ## Styling Rules
24
72
 
@@ -0,0 +1,8 @@
1
+ import "@/shared/components/admin-ui-templates/styles.css";
2
+ import "./styles.css";
3
+
4
+ import { GlassHomeDashboard } from "./GlassHomeDashboard";
5
+
6
+ export default function App() {
7
+ return <GlassHomeDashboard />;
8
+ }
@@ -0,0 +1,232 @@
1
+ import { App as AntdApp, Button, Select, Space, Tag } from "antd";
2
+ import { useMemo, useState } from "react";
3
+
4
+ import { QueryState } from "@/shared/components/QueryState";
5
+ import {
6
+ ActivityList,
7
+ AdminShell,
8
+ AdminTopbar,
9
+ DashboardChart,
10
+ HealthScore,
11
+ MetricCard,
12
+ Panel,
13
+ QuickActionGrid,
14
+ RankingList,
15
+ TemplateActionDrawer,
16
+ } from "@/shared/components/admin-ui-templates/DashboardPrimitives";
17
+ import {
18
+ createDonutOption,
19
+ createLineAreaOption,
20
+ } from "@/shared/components/admin-ui-templates/chartOptions";
21
+ import {
22
+ activities,
23
+ glassMetrics,
24
+ quickActions,
25
+ rankingItems,
26
+ standardNavItems,
27
+ } from "@/shared/components/admin-ui-templates/sampleData";
28
+ import type {
29
+ DrawerMode,
30
+ QuickAction,
31
+ } from "@/shared/components/admin-ui-templates/types";
32
+
33
+ type ViewState = "ready" | "loading" | "empty" | "error";
34
+ type RangeKey = "7" | "30" | "90";
35
+
36
+ const labels = ["03-04", "03-05", "03-06", "03-07", "03-08", "03-09", "03-10"];
37
+
38
+ export function GlassHomeDashboard() {
39
+ const { message } = AntdApp.useApp();
40
+ const [activeNav, setActiveNav] = useState("home");
41
+ const [range, setRange] = useState<RangeKey>("7");
42
+ const [viewState, setViewState] = useState<ViewState>("ready");
43
+ const [drawerAction, setDrawerAction] = useState<QuickAction | null>(null);
44
+ const [drawerMode, setDrawerMode] = useState<DrawerMode>("create");
45
+
46
+ const lineOption = useMemo(
47
+ () =>
48
+ createLineAreaOption({
49
+ colors: ["#3b82f6", "#10b981"],
50
+ labels,
51
+ primaryName: "销售额(元)",
52
+ secondaryName: "订单数(笔)",
53
+ primary: range === "7" ? [72, 48, 70, 66, 88, 76, 98] : [48, 66, 74, 82, 92, 88, 108],
54
+ secondary: range === "7" ? [42, 28, 45, 35, 54, 39, 50] : [30, 43, 52, 59, 68, 62, 76],
55
+ }),
56
+ [range],
57
+ );
58
+
59
+ const donutOption = useMemo(
60
+ () =>
61
+ createDonutOption({
62
+ centerLabel: "总销售额",
63
+ centerValue: "¥632,316",
64
+ data: [
65
+ { name: "官网商城 35.6%", value: 35.6, color: "#3b82f6" },
66
+ { name: "移动端 28.3%", value: 28.3, color: "#10b981" },
67
+ { name: "合作伙伴 17.8%", value: 17.8, color: "#8b5cf6" },
68
+ { name: "线下门店 11.6%", value: 11.6, color: "#fb923c" },
69
+ { name: "其他渠道 6.7%", value: 6.7, color: "#cbd5e1" },
70
+ ],
71
+ }),
72
+ [],
73
+ );
74
+
75
+ function refresh() {
76
+ setViewState("loading");
77
+ window.setTimeout(() => {
78
+ setViewState("ready");
79
+ message.success("数据已刷新");
80
+ }, 500);
81
+ }
82
+
83
+ function openActionDrawer(action: QuickAction, mode: DrawerMode = "create") {
84
+ setDrawerAction(action);
85
+ setDrawerMode(mode);
86
+ }
87
+
88
+ const topbar = (
89
+ <AdminTopbar
90
+ title="首页"
91
+ searchPlaceholder="搜索功能、数据、报表"
92
+ userName="管理员"
93
+ extra={
94
+ <Space size={8}>
95
+ <Button onClick={refresh}>刷新</Button>
96
+ <Select<ViewState>
97
+ size="small"
98
+ value={viewState}
99
+ onChange={setViewState}
100
+ options={[
101
+ { value: "ready", label: "正常" },
102
+ { value: "loading", label: "加载" },
103
+ { value: "empty", label: "空态" },
104
+ { value: "error", label: "错误" },
105
+ ]}
106
+ />
107
+ </Space>
108
+ }
109
+ />
110
+ );
111
+
112
+ return (
113
+ <AdminShell
114
+ variant="glass"
115
+ activeKey={activeNav}
116
+ navItems={standardNavItems}
117
+ brandTitle="未来数据管理平台"
118
+ brandSubtitle="企业级数据决策中台"
119
+ topbar={topbar}
120
+ onNavChange={setActiveNav}
121
+ >
122
+ {viewState !== "ready" ? (
123
+ <Panel className="bp-glass-state-panel">
124
+ <QueryState
125
+ loading={viewState === "loading"}
126
+ empty={viewState === "empty"}
127
+ error={viewState === "error" ? "模拟接口异常,请点击重试恢复。" : null}
128
+ onRetry={() => setViewState("ready")}
129
+ />
130
+ </Panel>
131
+ ) : (
132
+ <>
133
+ <section className="bp-glass-hero-grid">
134
+ <Panel className="bp-glass-hero">
135
+ <div className="bp-glass-hero__copy">
136
+ <h1>晚上好,超级管理员 👋</h1>
137
+ <p>欢迎使用未来科技管理平台,今天是 2026年03月10日 星期二</p>
138
+ <div className="bp-glass-hero__pills">
139
+ <Tag color="blue">今日访问 1,268</Tag>
140
+ <Tag color="red">待办事项 8</Tag>
141
+ <Tag color="purple">系统消息 12</Tag>
142
+ </div>
143
+ </div>
144
+ <div className="bp-glass-hero__visual" aria-hidden="true">
145
+ <i className="card card-a" />
146
+ <i className="card card-b" />
147
+ <i className="card card-c" />
148
+ <i className="wave" />
149
+ </div>
150
+ </Panel>
151
+ <Panel title="快捷操作" extra={<Button size="small">自定义</Button>}>
152
+ <QuickActionGrid
153
+ actions={quickActions}
154
+ onAction={(action) => openActionDrawer(action)}
155
+ />
156
+ </Panel>
157
+ </section>
158
+
159
+ <section className="bp-glass-metrics">
160
+ {glassMetrics.map((metric) => (
161
+ <MetricCard key={metric.id} metric={metric} />
162
+ ))}
163
+ </section>
164
+
165
+ <section className="bp-glass-main-grid">
166
+ <Panel
167
+ title="数据概览"
168
+ className="bp-glass-chart-panel"
169
+ extra={
170
+ <Space size={4}>
171
+ {(["7", "30", "90"] as RangeKey[]).map((item) => (
172
+ <Button
173
+ key={item}
174
+ size="small"
175
+ type={range === item ? "primary" : "text"}
176
+ onClick={() => setRange(item)}
177
+ >
178
+ 近{item}天
179
+ </Button>
180
+ ))}
181
+ </Space>
182
+ }
183
+ >
184
+ <div className="bp-glass-chart-split">
185
+ <DashboardChart option={lineOption} height={255} />
186
+ <DashboardChart option={donutOption} height={255} />
187
+ </div>
188
+ </Panel>
189
+ <div className="bp-glass-side-stack">
190
+ <Panel title="排行榜">
191
+ <RankingList items={rankingItems} />
192
+ </Panel>
193
+ <Panel title="最近动态">
194
+ <ActivityList items={activities} />
195
+ </Panel>
196
+ </div>
197
+ </section>
198
+
199
+ <section className="bp-glass-bottom-grid">
200
+ <Panel title="目标达成">
201
+ <div className="bp-glass-targets">
202
+ {glassMetrics.slice(0, 4).map((item, index) => (
203
+ <div key={item.id}>
204
+ <span>{item.label}目标</span>
205
+ <strong>{index === 1 ? "55.1%" : "52.7%"}</strong>
206
+ <div>
207
+ <i style={{ width: `${index === 1 ? 55 : 52}%` }} />
208
+ </div>
209
+ </div>
210
+ ))}
211
+ </div>
212
+ </Panel>
213
+ <Panel title="系统健康度">
214
+ <HealthScore value={98} />
215
+ </Panel>
216
+ </section>
217
+ </>
218
+ )}
219
+
220
+ <TemplateActionDrawer
221
+ open={Boolean(drawerAction)}
222
+ title={drawerAction ? `${drawerAction.label}` : "新建事项"}
223
+ mode={drawerMode}
224
+ onClose={() => setDrawerAction(null)}
225
+ onSubmit={() => {
226
+ setDrawerAction(null);
227
+ message.success("表单已保存");
228
+ }}
229
+ />
230
+ </AdminShell>
231
+ );
232
+ }
@@ -0,0 +1,10 @@
1
+ import { createReactPage } from "openxiangda/runtime";
2
+
3
+ import App from "./App";
4
+
5
+ const page = createReactPage(App);
6
+
7
+ export const mount = page.mount;
8
+ export const update = page.update;
9
+ export const unmount = page.unmount;
10
+ export default page;
@@ -0,0 +1,14 @@
1
+ import { definePageConfig } from "@/types/app-workspace.types";
2
+
3
+ export default definePageConfig({
4
+ code: "glass_home_dashboard",
5
+ name: "浅蓝玻璃经营首页",
6
+ description: "后台管理浅蓝玻璃拟态首页模板",
7
+ route: { pathKey: "glass_home_dashboard" },
8
+ entry: {
9
+ mode: "app-shell",
10
+ hidePlatformNav: true,
11
+ defaultRoute: "home",
12
+ },
13
+ menu: { name: "浅蓝玻璃经营首页" },
14
+ });