@pactor-app/skills 1.33.0 → 1.34.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.
- package/package.json +1 -1
- package/pactor-prd/SKILL.md +3 -3
- package/pactor-prd/references/page-templates.md +1 -1
- package/pactor-prd/template/app/api/data/[...parts]/route.ts +42 -0
- package/pactor-prd/template/next-env.d.ts +2 -2
- package/pactor-prd/template/package.json +4 -4
- package/pactor-prd/template/pnpm-lock.yaml +97 -97
- package/pactor-prd/template/src/pactor/mocks/data-list-mock.ts +84 -0
- package/pactor-prd/template/src/pactor/services.ts +15 -0
- package/pactor-prd/template/src/server/yaml/models/data-list.yaml +344 -0
- package/pactor-prd/template/src/server/yaml/sitemap.yaml +21 -0
package/package.json
CHANGED
package/pactor-prd/SKILL.md
CHANGED
|
@@ -30,7 +30,7 @@ version: 1.3.0
|
|
|
30
30
|
3. **样式与原产品一致**:主题令牌(含深浅色)、自定义 CSS(如登录页)、换肤入口全部移植对齐,见 `references/theme-and-style.md`
|
|
31
31
|
4. **功能与原产品一致**:线框图描述的筛选/搜索/跳转/弹窗/提交等交互必须经 events/actions 闭环可用,禁止只画静态骨架;错误分支(校验失败提示等)也要实现
|
|
32
32
|
5. **表单一律用 `Form` 组件**:凡是一组「字段 + 校验 + 提交」的表单——独立表单页、页面内嵌的配置面板(如树/列表右侧的编辑表单)、弹窗/抽屉表单、**搜索栏(关键词 + 查询/重置 的筛选区,用 `Form layout: inline`)**——都必须用 `Form` 包裹,字段经 `props.name` 绑定,校验用字段级 `rules`(required + message),提交用 `submit: true` 的 Button 触发 `onSubmit`;**禁止**散放 `Input`/`Select` + `setState` 攒草稿 + `if` 动作手写校验。上下结构的字段一律用 `Field` 包裹:label、必填星号(`required: true`)、行右提示(`labelHint`)由 `Field` 渲染,控件上只留 `name`/`rules` 等(`Form layout: inline` 的搜索栏除外,label 直接挂控件);禁止手写 `Text("*") + Label` 拼标签。回填联动(如点击列表/树节点填充表单)用 `form.setValues` 动作,不要绑 `${state.x}` 到字段 value;即点即生效的 ChipFilter 快筛行没有提交语义,不属于表单
|
|
33
|
-
6. **列表页操作列规范**:操作列按钮样式统一 `Button variant: link`;「编辑」与「新建」指向同一个表单(同一路由页或同一弹窗),唯一区别是编辑以行数据预填(路由页 `initialValues: ${data.detail}`,弹窗/内嵌面板 `form.setValues`);**数据列表页(搜索 + 表格 +
|
|
33
|
+
6. **列表页操作列规范**:操作列按钮样式统一 `Button variant: link`;「编辑」与「新建」指向同一个表单(同一路由页或同一弹窗),唯一区别是编辑以行数据预填(路由页 `initialValues: ${data.detail}`,弹窗/内嵌面板 `form.setValues`);**数据列表页(搜索 + 表格 + 新建/编辑)以 `template/src/server/yaml/models/data-list.yaml` 为标准骨架生成**(结构与要点见 `references/page-templates.md`「数据列表标准模型」)
|
|
34
34
|
7. **文案以线框图为准**:标题、按钮、空态文案逐字取自线框图/PRD
|
|
35
35
|
8. DSL 语法细节(组件 props、表达式、动作)以 `pactor-dsl` skill 与 packages/ui 当前导出为准,本 skill 只约定流程与产出物
|
|
36
36
|
|
|
@@ -57,7 +57,7 @@ version: 1.3.0
|
|
|
57
57
|
- **整体复制 `template/`** 为新项目起点;不要用 `pnpm create pactor-app` 替代
|
|
58
58
|
- 工程名:README 产品名 → kebab-case 英文名,创建前确认一次
|
|
59
59
|
- `pnpm install` + dev 验证;核对 `references/project-structure.md`
|
|
60
|
-
- 参考模块 provider/route
|
|
60
|
+
- 参考模块 provider/route 作样板;`yaml/models/` 是页面骨架目录(按模块目录结构存放,已注册 sitemap、菜单「页面骨架」分组可直接预览),生成时复制到目标模块目录改字段与文案;**全站生成完成后删除**参考模块、models/ 及对应 mock
|
|
61
61
|
|
|
62
62
|
**增量**
|
|
63
63
|
|
|
@@ -69,7 +69,7 @@ version: 1.3.0
|
|
|
69
69
|
- **新建工程**:清单一行 = 一个文件 `yaml/<模块>/<page-id>.yaml`(或工程既定 A/B 规则);`mkdir` 模块目录;N = P0/P1 行数
|
|
70
70
|
- **增量**:仅 **add** 新建文件;**update** 改已有 yaml;**deprecate** 删文件并改 sitemap(须用户确认)
|
|
71
71
|
- 校验见 `page-inventory-and-files.md`(全量)或 `incremental-wireframe-delta.md`(增量)
|
|
72
|
-
- 按 `references/component-mapping.md` 映射组件;按 `references/page-templates.md`
|
|
72
|
+
- 按 `references/component-mapping.md` 映射组件;按 `references/page-templates.md` 选列表/详情/表单模板(**数据列表页直接复制 `yaml/models/data-list.yaml` 替换占位符**);表单一律 `Form` 包裹
|
|
73
73
|
- 同步更新 `sitemap.yaml` 的 `pages` + `menus`(hidden 详情/编辑带 `activeMenu`)
|
|
74
74
|
- 每页 dataSources 全部 `type: http`;交互 events + actions 闭环
|
|
75
75
|
|
|
@@ -6,7 +6,7 @@
|
|
|
6
6
|
|
|
7
7
|
## 数据列表标准模型(搜索 Form + 表格 + 抽屉新建/编辑)
|
|
8
8
|
|
|
9
|
-
从成熟实现提取的完整闭环:搜索过滤、新建/编辑共用抽屉表单(分区 + 条件显隐 + 预填)、操作列 link
|
|
9
|
+
从成熟实现提取的完整闭环:搜索过滤、新建/编辑共用抽屉表单(分区 + 条件显隐 + 预填)、操作列 link 按钮。**完整可拷贝的骨架文件:`template/src/server/yaml/models/data-list.yaml`**(已注册进模板 sitemap 的可运行示例,菜单「页面骨架 / 数据列表」直接预览;复制后替换页面信息、字段、接口名与文案即可,配套 mock 为 `template/src/pactor/mocks/data-list-mock.ts`)。结构照抄,字段按线框图替换:
|
|
10
10
|
|
|
11
11
|
```yaml
|
|
12
12
|
dsl: "1.0"
|
|
@@ -27,6 +27,8 @@ const ROUTE_TABLE: Record<string, string> = {
|
|
|
27
27
|
costs: "cost.list",
|
|
28
28
|
audit: "audit.list",
|
|
29
29
|
"audit-operators": "audit.operators",
|
|
30
|
+
"data-list": "dataList.list",
|
|
31
|
+
"ops/data-list-save": "dataList.save",
|
|
30
32
|
"ops/model-usage": "ops.modelUsage",
|
|
31
33
|
"ops/provider-usage": "ops.providerUsage",
|
|
32
34
|
"ops/client-usage": "ops.clientUsage",
|
|
@@ -43,6 +45,7 @@ const DETAIL_TABLE: Record<string, string> = {
|
|
|
43
45
|
"call-logs": "callLog.detail",
|
|
44
46
|
costs: "cost.detail",
|
|
45
47
|
audit: "audit.detail",
|
|
48
|
+
"data-list": "dataList.detail",
|
|
46
49
|
};
|
|
47
50
|
|
|
48
51
|
const SUB_TABLE: Record<string, string> = {
|
|
@@ -114,5 +117,44 @@ export async function GET(
|
|
|
114
117
|
});
|
|
115
118
|
}
|
|
116
119
|
|
|
120
|
+
/** 写操作(ops 前缀的保存类接口,如骨架示例的新建/编辑提交) */
|
|
121
|
+
export async function POST(
|
|
122
|
+
request: Request,
|
|
123
|
+
context: RouteContext<"/api/data/[...parts]">,
|
|
124
|
+
) {
|
|
125
|
+
const store = await cookies();
|
|
126
|
+
const user = findUserBySession(store.get(SESSION_COOKIE)?.value);
|
|
127
|
+
if (!user) {
|
|
128
|
+
return Response.json(
|
|
129
|
+
{ error: "未登录" },
|
|
130
|
+
{ status: 401, headers: corsHeaders(request) },
|
|
131
|
+
);
|
|
132
|
+
}
|
|
133
|
+
|
|
134
|
+
const { parts } = await context.params;
|
|
135
|
+
if (parts[0] !== "ops") {
|
|
136
|
+
return Response.json(
|
|
137
|
+
{ error: "仅 ops 接口支持 POST" },
|
|
138
|
+
{ status: 405, headers: corsHeaders(request) },
|
|
139
|
+
);
|
|
140
|
+
}
|
|
141
|
+
const resolved = resolveService(parts);
|
|
142
|
+
if (!resolved) {
|
|
143
|
+
return Response.json(
|
|
144
|
+
{ error: `未知数据接口: /api/data/${parts.join("/")}` },
|
|
145
|
+
{ status: 404, headers: corsHeaders(request) },
|
|
146
|
+
);
|
|
147
|
+
}
|
|
148
|
+
|
|
149
|
+
const body = (await request.json().catch(() => ({}))) as Record<
|
|
150
|
+
string,
|
|
151
|
+
unknown
|
|
152
|
+
>;
|
|
153
|
+
const result = await pactorServices[resolved.service](body);
|
|
154
|
+
return Response.json(result ?? null, {
|
|
155
|
+
headers: { "cache-control": "no-store", ...corsHeaders(request) },
|
|
156
|
+
});
|
|
157
|
+
}
|
|
158
|
+
|
|
117
159
|
/** 预检(跨源带凭据 / 自定义头时) */
|
|
118
160
|
export const OPTIONS = corsPreflight;
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
/// <reference types="next" />
|
|
2
2
|
/// <reference types="next/image-types/global" />
|
|
3
|
-
import "./.next/
|
|
4
|
-
import "./.next/
|
|
3
|
+
import "./.next/types/routes.d.ts";
|
|
4
|
+
import "./.next/types/root-params.d.ts";
|
|
5
5
|
|
|
6
6
|
// NOTE: This file should not be edited
|
|
7
7
|
// see https://nextjs.org/docs/app/api-reference/config/typescript for more information.
|
|
@@ -11,12 +11,12 @@
|
|
|
11
11
|
"build:test": "node scripts/build.mjs test"
|
|
12
12
|
},
|
|
13
13
|
"dependencies": {
|
|
14
|
-
"@pactor-app/core": "^1.
|
|
15
|
-
"@pactor-app/runtime": "^1.
|
|
16
|
-
"@pactor-app/ui": "^1.
|
|
14
|
+
"@pactor-app/core": "^1.34.0",
|
|
15
|
+
"@pactor-app/runtime": "^1.34.0",
|
|
16
|
+
"@pactor-app/ui": "^1.34.0",
|
|
17
17
|
"lucide-react": "1.45.0",
|
|
18
18
|
"next": "16.3.5",
|
|
19
|
-
"pactor-app": "^1.
|
|
19
|
+
"pactor-app": "^1.34.0",
|
|
20
20
|
"react": "19.2.8",
|
|
21
21
|
"react-dom": "19.2.8",
|
|
22
22
|
"yaml": "^2.9.1"
|
|
@@ -9,14 +9,14 @@ importers:
|
|
|
9
9
|
.:
|
|
10
10
|
dependencies:
|
|
11
11
|
'@pactor-app/core':
|
|
12
|
-
specifier: ^1.
|
|
13
|
-
version: 1.
|
|
12
|
+
specifier: ^1.33.0
|
|
13
|
+
version: 1.33.0
|
|
14
14
|
'@pactor-app/runtime':
|
|
15
|
-
specifier: ^1.
|
|
16
|
-
version: 1.
|
|
15
|
+
specifier: ^1.33.0
|
|
16
|
+
version: 1.33.0(react@19.2.8)
|
|
17
17
|
'@pactor-app/ui':
|
|
18
|
-
specifier: ^1.
|
|
19
|
-
version: 1.
|
|
18
|
+
specifier: ^1.33.0
|
|
19
|
+
version: 1.33.0(@date-fns/tz@1.5.0)(@types/react-dom@19.3.0(@types/react@19.3.0))(@types/react@19.3.0)(react-dom@19.2.8(react@19.2.8))(react-router-dom@7.18.4(react-dom@19.2.8(react@19.2.8))(react@19.2.8))(react@19.2.8)
|
|
20
20
|
lucide-react:
|
|
21
21
|
specifier: 1.45.0
|
|
22
22
|
version: 1.45.0(react@19.2.8)
|
|
@@ -24,8 +24,8 @@ importers:
|
|
|
24
24
|
specifier: 16.3.5
|
|
25
25
|
version: 16.3.5(@babel/core@7.29.7)(@types/node@20.19.43)(react-dom@19.2.8(react@19.2.8))(react@19.2.8)
|
|
26
26
|
pactor-app:
|
|
27
|
-
specifier: ^1.
|
|
28
|
-
version: 1.
|
|
27
|
+
specifier: ^1.33.0
|
|
28
|
+
version: 1.33.0(@date-fns/tz@1.5.0)(@types/react-dom@19.3.0(@types/react@19.3.0))(@types/react@19.3.0)(react-dom@19.2.8(react@19.2.8))(react-router-dom@7.18.4(react-dom@19.2.8(react@19.2.8))(react@19.2.8))(react@19.2.8)(vite@8.3.1(@types/node@20.19.43)(jiti@2.7.0)(yaml@2.9.1))
|
|
29
29
|
react:
|
|
30
30
|
specifier: 19.2.8
|
|
31
31
|
version: 19.2.8
|
|
@@ -501,73 +501,73 @@ packages:
|
|
|
501
501
|
'@oxc-project/types@0.151.0':
|
|
502
502
|
resolution: {integrity: sha512-J1yXrIlNDZVzE3ada310xeAw7nH8yCAyLPuUIsjKatFPmfn5bS1oW+cM+QsGOtVWd5nhSpbwZWx/rue+r5Z+PA==}
|
|
503
503
|
|
|
504
|
-
'@pactor-app/app@1.
|
|
505
|
-
resolution: {integrity: sha512
|
|
504
|
+
'@pactor-app/app@1.33.0':
|
|
505
|
+
resolution: {integrity: sha512-/T3AnTgV3J9gvtwP48uSqp951GJFVt09758RyU3BQMnw3ZJXnLaqfUNMiZ6UlXkd8x32Cfpq3SqbJQRVB1fYlg==}
|
|
506
506
|
engines: {node: '>=18'}
|
|
507
507
|
peerDependencies:
|
|
508
508
|
react: '>=18'
|
|
509
509
|
react-dom: '>=18'
|
|
510
510
|
react-router-dom: '>=6'
|
|
511
511
|
|
|
512
|
-
'@pactor-app/chat@1.
|
|
513
|
-
resolution: {integrity: sha512-
|
|
512
|
+
'@pactor-app/chat@1.33.0':
|
|
513
|
+
resolution: {integrity: sha512-tj3pOA8JXXDzC0jVHr1MQduAuYExP76M0AAsba55mqQ7N64fb2zJDUzMPxYiuv8z9bMr8acKpuOGi/a2tO5hEQ==}
|
|
514
514
|
engines: {node: '>=18'}
|
|
515
515
|
peerDependencies:
|
|
516
516
|
react: '>=18'
|
|
517
517
|
|
|
518
|
-
'@pactor-app/cli@1.
|
|
519
|
-
resolution: {integrity: sha512-
|
|
518
|
+
'@pactor-app/cli@1.33.0':
|
|
519
|
+
resolution: {integrity: sha512-x8+DLqH93Vd0Lkd2zc4stuuc+z0kp++sEnaV49LIktccKBTXNIe6q1BaF8vIX14HrPtSpTtuiMnnlwNR2Nsx/A==}
|
|
520
520
|
engines: {node: '>=18'}
|
|
521
521
|
hasBin: true
|
|
522
522
|
|
|
523
|
-
'@pactor-app/core@1.
|
|
524
|
-
resolution: {integrity: sha512-
|
|
523
|
+
'@pactor-app/core@1.33.0':
|
|
524
|
+
resolution: {integrity: sha512-XTdm/f7Xom1ifPKwhpvy8WR5cVyLstAtrNAOWcJhs4AdOwYkmuk1MeznRp66Yl9bTJyzhJCEVhsZ7telb0HS6Q==}
|
|
525
525
|
engines: {node: '>=18'}
|
|
526
526
|
|
|
527
|
-
'@pactor-app/expression@1.
|
|
528
|
-
resolution: {integrity: sha512-
|
|
527
|
+
'@pactor-app/expression@1.33.0':
|
|
528
|
+
resolution: {integrity: sha512-0Z3JUf3NLpEfHUhvzUunmEEZ3B+hEHTz+ATF4RpDVbBVnjmQBdwNcXw1/ybt1I9sJ3eDPOQQtejonsrCX0VzQA==}
|
|
529
529
|
engines: {node: '>=18'}
|
|
530
530
|
|
|
531
|
-
'@pactor-app/markdown@1.
|
|
532
|
-
resolution: {integrity: sha512-
|
|
531
|
+
'@pactor-app/markdown@1.33.0':
|
|
532
|
+
resolution: {integrity: sha512-C6u8wZKD4ayRZND4k6HbTz7SDiqb+Pwxwu9xYgYVwRBDugLWVBIfZGSZNThoXcJRumcP5EEsQKeIuNkXbt541g==}
|
|
533
533
|
engines: {node: '>=18'}
|
|
534
534
|
peerDependencies:
|
|
535
535
|
react: '>=18'
|
|
536
536
|
|
|
537
|
-
'@pactor-app/permission@1.
|
|
538
|
-
resolution: {integrity: sha512-
|
|
537
|
+
'@pactor-app/permission@1.33.0':
|
|
538
|
+
resolution: {integrity: sha512-CYfW3pfqI6bml5woxTtvlFE/l5ZBeQZe+x1mJigy3dc9gThMVdPKSc9b541RP6Km93tKOz2LK8HOhoE4SlvaxQ==}
|
|
539
539
|
engines: {node: '>=18'}
|
|
540
540
|
|
|
541
|
-
'@pactor-app/resource@1.
|
|
542
|
-
resolution: {integrity: sha512-
|
|
541
|
+
'@pactor-app/resource@1.33.0':
|
|
542
|
+
resolution: {integrity: sha512-ezcM72IFOvHdlUCnQmLiJenVX0Ij/B51hJB87nisJbrDmj3HfPKFoDr1UcRgU5aSlR/yt9Dp/TGTIF4Em7sesQ==}
|
|
543
543
|
engines: {node: '>=18'}
|
|
544
544
|
|
|
545
|
-
'@pactor-app/router@1.
|
|
546
|
-
resolution: {integrity: sha512
|
|
545
|
+
'@pactor-app/router@1.33.0':
|
|
546
|
+
resolution: {integrity: sha512-vhtyczWSzJTe/7rcAK4LsKIdwWEP2vT21fpyNkYzcjIUOXVe2SHmPDu7bmQdW5yB5hQz0IQPkyeLI9HI4xJrcw==}
|
|
547
547
|
engines: {node: '>=18'}
|
|
548
548
|
peerDependencies:
|
|
549
549
|
react: '>=18'
|
|
550
550
|
react-router-dom: '>=6'
|
|
551
551
|
|
|
552
|
-
'@pactor-app/runtime@1.
|
|
553
|
-
resolution: {integrity: sha512-
|
|
552
|
+
'@pactor-app/runtime@1.33.0':
|
|
553
|
+
resolution: {integrity: sha512-JZOTgoo0jeSG5+gp1bpD1Rey4ZDCwBo2IQ6w6tp5SFI9LOOsXxdg8hy2wpX1fQAuS6iO2AtVRIIWbNesghIeTg==}
|
|
554
554
|
engines: {node: '>=18'}
|
|
555
555
|
peerDependencies:
|
|
556
556
|
react: '>=18'
|
|
557
557
|
|
|
558
|
-
'@pactor-app/schema@1.
|
|
559
|
-
resolution: {integrity: sha512-
|
|
558
|
+
'@pactor-app/schema@1.33.0':
|
|
559
|
+
resolution: {integrity: sha512-2J7uvpwUUcwFB01I+xc0w18B9LWMqyL9l1B6Kog5sU/oWsn4pFcQ/bncBKYpW3UW4FVGFz5AVeyN4Rd+uPIcWQ==}
|
|
560
560
|
engines: {node: '>=18'}
|
|
561
561
|
|
|
562
|
-
'@pactor-app/ui@1.
|
|
563
|
-
resolution: {integrity: sha512-
|
|
562
|
+
'@pactor-app/ui@1.33.0':
|
|
563
|
+
resolution: {integrity: sha512-mhpWWkRfKraQaPQPN1ZuTFQdb4tf/WwWdfa3ULqFf6u+lp+8b1FrsW7cNY7lbElN46e+BgobR2fG+Yy9LurJ3w==}
|
|
564
564
|
engines: {node: '>=18'}
|
|
565
565
|
peerDependencies:
|
|
566
566
|
react: '>=18'
|
|
567
567
|
react-dom: '>=18'
|
|
568
568
|
|
|
569
|
-
'@pactor-app/vite-plugin@1.
|
|
570
|
-
resolution: {integrity: sha512
|
|
569
|
+
'@pactor-app/vite-plugin@1.33.0':
|
|
570
|
+
resolution: {integrity: sha512-9bNPV95H7h0/DVv5Vc431mLUkuRGX9nnwRdhoUGdcSPkReGJrTH2866i4t8w0ODtUpZ3rD9AexgatpNBlw8NvA==}
|
|
571
571
|
engines: {node: '>=18'}
|
|
572
572
|
peerDependencies:
|
|
573
573
|
vite: '>=5'
|
|
@@ -2529,8 +2529,8 @@ packages:
|
|
|
2529
2529
|
resolution: {integrity: sha512-R4nPAVTAU0B9D35/Gk3uJf/7XYbQcyohSKdvAxIRSNghFl4e71hVoGnBNQz9cWaXxO2I10KTC+3jMdvvoKw6dQ==}
|
|
2530
2530
|
engines: {node: '>=6'}
|
|
2531
2531
|
|
|
2532
|
-
pactor-app@1.
|
|
2533
|
-
resolution: {integrity: sha512-
|
|
2532
|
+
pactor-app@1.33.0:
|
|
2533
|
+
resolution: {integrity: sha512-BJxBNIG40chRob0veFRAXTKkplnIipZOP4MkKJ52Udn3wYQ9srey2sAr0/S+LtjRSL0P+/rjWeTuqyoJOeVlrQ==}
|
|
2534
2534
|
engines: {node: '>=18'}
|
|
2535
2535
|
peerDependencies:
|
|
2536
2536
|
react: '>=18'
|
|
@@ -3613,16 +3613,16 @@ snapshots:
|
|
|
3613
3613
|
|
|
3614
3614
|
'@oxc-project/types@0.151.0': {}
|
|
3615
3615
|
|
|
3616
|
-
'@pactor-app/app@1.
|
|
3616
|
+
'@pactor-app/app@1.33.0(@date-fns/tz@1.5.0)(@types/react-dom@19.3.0(@types/react@19.3.0))(@types/react@19.3.0)(react-dom@19.2.8(react@19.2.8))(react-router-dom@7.18.4(react-dom@19.2.8(react@19.2.8))(react@19.2.8))(react@19.2.8)':
|
|
3617
3617
|
dependencies:
|
|
3618
|
-
'@pactor-app/core': 1.
|
|
3619
|
-
'@pactor-app/expression': 1.
|
|
3620
|
-
'@pactor-app/permission': 1.
|
|
3621
|
-
'@pactor-app/resource': 1.
|
|
3622
|
-
'@pactor-app/router': 1.
|
|
3623
|
-
'@pactor-app/runtime': 1.
|
|
3624
|
-
'@pactor-app/schema': 1.
|
|
3625
|
-
'@pactor-app/ui': 1.
|
|
3618
|
+
'@pactor-app/core': 1.33.0
|
|
3619
|
+
'@pactor-app/expression': 1.33.0
|
|
3620
|
+
'@pactor-app/permission': 1.33.0
|
|
3621
|
+
'@pactor-app/resource': 1.33.0
|
|
3622
|
+
'@pactor-app/router': 1.33.0(react-router-dom@7.18.4(react-dom@19.2.8(react@19.2.8))(react@19.2.8))(react@19.2.8)
|
|
3623
|
+
'@pactor-app/runtime': 1.33.0(react@19.2.8)
|
|
3624
|
+
'@pactor-app/schema': 1.33.0
|
|
3625
|
+
'@pactor-app/ui': 1.33.0(@date-fns/tz@1.5.0)(@types/react-dom@19.3.0(@types/react@19.3.0))(@types/react@19.3.0)(react-dom@19.2.8(react@19.2.8))(react-router-dom@7.18.4(react-dom@19.2.8(react@19.2.8))(react@19.2.8))(react@19.2.8)
|
|
3626
3626
|
react: 19.2.8
|
|
3627
3627
|
react-dom: 19.2.8(react@19.2.8)
|
|
3628
3628
|
react-router-dom: 7.18.4(react-dom@19.2.8(react@19.2.8))(react@19.2.8)
|
|
@@ -3632,13 +3632,13 @@ snapshots:
|
|
|
3632
3632
|
- '@types/react-dom'
|
|
3633
3633
|
- supports-color
|
|
3634
3634
|
|
|
3635
|
-
'@pactor-app/chat@1.
|
|
3635
|
+
'@pactor-app/chat@1.33.0(@date-fns/tz@1.5.0)(@types/react-dom@19.3.0(@types/react@19.3.0))(@types/react@19.3.0)(react-dom@19.2.8(react@19.2.8))(react-router-dom@7.18.4(react-dom@19.2.8(react@19.2.8))(react@19.2.8))(react@19.2.8)':
|
|
3636
3636
|
dependencies:
|
|
3637
|
-
'@pactor-app/core': 1.
|
|
3638
|
-
'@pactor-app/markdown': 1.
|
|
3639
|
-
'@pactor-app/permission': 1.
|
|
3640
|
-
'@pactor-app/runtime': 1.
|
|
3641
|
-
'@pactor-app/ui': 1.
|
|
3637
|
+
'@pactor-app/core': 1.33.0
|
|
3638
|
+
'@pactor-app/markdown': 1.33.0(@types/react@19.3.0)(react@19.2.8)
|
|
3639
|
+
'@pactor-app/permission': 1.33.0
|
|
3640
|
+
'@pactor-app/runtime': 1.33.0(react@19.2.8)
|
|
3641
|
+
'@pactor-app/ui': 1.33.0(@date-fns/tz@1.5.0)(@types/react-dom@19.3.0(@types/react@19.3.0))(@types/react@19.3.0)(react-dom@19.2.8(react@19.2.8))(react-router-dom@7.18.4(react-dom@19.2.8(react@19.2.8))(react@19.2.8))(react@19.2.8)
|
|
3642
3642
|
react: 19.2.8
|
|
3643
3643
|
transitivePeerDependencies:
|
|
3644
3644
|
- '@date-fns/tz'
|
|
@@ -3648,22 +3648,22 @@ snapshots:
|
|
|
3648
3648
|
- react-router-dom
|
|
3649
3649
|
- supports-color
|
|
3650
3650
|
|
|
3651
|
-
'@pactor-app/cli@1.
|
|
3651
|
+
'@pactor-app/cli@1.33.0':
|
|
3652
3652
|
dependencies:
|
|
3653
|
-
'@pactor-app/core': 1.
|
|
3654
|
-
'@pactor-app/expression': 1.
|
|
3655
|
-
'@pactor-app/schema': 1.
|
|
3653
|
+
'@pactor-app/core': 1.33.0
|
|
3654
|
+
'@pactor-app/expression': 1.33.0
|
|
3655
|
+
'@pactor-app/schema': 1.33.0
|
|
3656
3656
|
yaml: 2.9.1
|
|
3657
3657
|
|
|
3658
|
-
'@pactor-app/core@1.
|
|
3658
|
+
'@pactor-app/core@1.33.0': {}
|
|
3659
3659
|
|
|
3660
|
-
'@pactor-app/expression@1.
|
|
3660
|
+
'@pactor-app/expression@1.33.0':
|
|
3661
3661
|
dependencies:
|
|
3662
|
-
'@pactor-app/core': 1.
|
|
3662
|
+
'@pactor-app/core': 1.33.0
|
|
3663
3663
|
|
|
3664
|
-
'@pactor-app/markdown@1.
|
|
3664
|
+
'@pactor-app/markdown@1.33.0(@types/react@19.3.0)(react@19.2.8)':
|
|
3665
3665
|
dependencies:
|
|
3666
|
-
'@pactor-app/core': 1.
|
|
3666
|
+
'@pactor-app/core': 1.33.0
|
|
3667
3667
|
katex: 0.18.9
|
|
3668
3668
|
react: 19.2.8
|
|
3669
3669
|
react-markdown: 10.1.0(@types/react@19.3.0)(react@19.2.8)
|
|
@@ -3675,41 +3675,41 @@ snapshots:
|
|
|
3675
3675
|
- '@types/react'
|
|
3676
3676
|
- supports-color
|
|
3677
3677
|
|
|
3678
|
-
'@pactor-app/permission@1.
|
|
3678
|
+
'@pactor-app/permission@1.33.0':
|
|
3679
3679
|
dependencies:
|
|
3680
|
-
'@pactor-app/core': 1.
|
|
3680
|
+
'@pactor-app/core': 1.33.0
|
|
3681
3681
|
|
|
3682
|
-
'@pactor-app/resource@1.
|
|
3682
|
+
'@pactor-app/resource@1.33.0':
|
|
3683
3683
|
dependencies:
|
|
3684
|
-
'@pactor-app/core': 1.
|
|
3684
|
+
'@pactor-app/core': 1.33.0
|
|
3685
3685
|
|
|
3686
|
-
'@pactor-app/router@1.
|
|
3686
|
+
'@pactor-app/router@1.33.0(react-router-dom@7.18.4(react-dom@19.2.8(react@19.2.8))(react@19.2.8))(react@19.2.8)':
|
|
3687
3687
|
dependencies:
|
|
3688
|
-
'@pactor-app/core': 1.
|
|
3689
|
-
'@pactor-app/permission': 1.
|
|
3688
|
+
'@pactor-app/core': 1.33.0
|
|
3689
|
+
'@pactor-app/permission': 1.33.0
|
|
3690
3690
|
react: 19.2.8
|
|
3691
3691
|
react-router-dom: 7.18.4(react-dom@19.2.8(react@19.2.8))(react@19.2.8)
|
|
3692
3692
|
|
|
3693
|
-
'@pactor-app/runtime@1.
|
|
3693
|
+
'@pactor-app/runtime@1.33.0(react@19.2.8)':
|
|
3694
3694
|
dependencies:
|
|
3695
|
-
'@pactor-app/core': 1.
|
|
3696
|
-
'@pactor-app/expression': 1.
|
|
3697
|
-
'@pactor-app/schema': 1.
|
|
3695
|
+
'@pactor-app/core': 1.33.0
|
|
3696
|
+
'@pactor-app/expression': 1.33.0
|
|
3697
|
+
'@pactor-app/schema': 1.33.0
|
|
3698
3698
|
react: 19.2.8
|
|
3699
3699
|
|
|
3700
|
-
'@pactor-app/schema@1.
|
|
3700
|
+
'@pactor-app/schema@1.33.0':
|
|
3701
3701
|
dependencies:
|
|
3702
|
-
'@pactor-app/core': 1.
|
|
3702
|
+
'@pactor-app/core': 1.33.0
|
|
3703
3703
|
ajv: 8.20.0
|
|
3704
3704
|
|
|
3705
|
-
'@pactor-app/ui@1.
|
|
3705
|
+
'@pactor-app/ui@1.33.0(@date-fns/tz@1.5.0)(@types/react-dom@19.3.0(@types/react@19.3.0))(@types/react@19.3.0)(react-dom@19.2.8(react@19.2.8))(react-router-dom@7.18.4(react-dom@19.2.8(react@19.2.8))(react@19.2.8))(react@19.2.8)':
|
|
3706
3706
|
dependencies:
|
|
3707
3707
|
'@base-ui/react': 1.8.0(@date-fns/tz@1.5.0)(@types/react@19.3.0)(date-fns@4.4.0)(react-dom@19.2.8(react@19.2.8))(react@19.2.8)
|
|
3708
|
-
'@pactor-app/core': 1.
|
|
3709
|
-
'@pactor-app/markdown': 1.
|
|
3710
|
-
'@pactor-app/permission': 1.
|
|
3711
|
-
'@pactor-app/router': 1.
|
|
3712
|
-
'@pactor-app/runtime': 1.
|
|
3708
|
+
'@pactor-app/core': 1.33.0
|
|
3709
|
+
'@pactor-app/markdown': 1.33.0(@types/react@19.3.0)(react@19.2.8)
|
|
3710
|
+
'@pactor-app/permission': 1.33.0
|
|
3711
|
+
'@pactor-app/router': 1.33.0(react-router-dom@7.18.4(react-dom@19.2.8(react@19.2.8))(react@19.2.8))(react@19.2.8)
|
|
3712
|
+
'@pactor-app/runtime': 1.33.0(react@19.2.8)
|
|
3713
3713
|
class-variance-authority: 0.7.1
|
|
3714
3714
|
clsx: 2.1.1
|
|
3715
3715
|
cmdk: 1.1.1(@types/react-dom@19.3.0(@types/react@19.3.0))(@types/react@19.3.0)(react-dom@19.2.8(react@19.2.8))(react@19.2.8)
|
|
@@ -3734,10 +3734,10 @@ snapshots:
|
|
|
3734
3734
|
- react-router-dom
|
|
3735
3735
|
- supports-color
|
|
3736
3736
|
|
|
3737
|
-
'@pactor-app/vite-plugin@1.
|
|
3737
|
+
'@pactor-app/vite-plugin@1.33.0(vite@8.3.1(@types/node@20.19.43)(jiti@2.7.0)(yaml@2.9.1))':
|
|
3738
3738
|
dependencies:
|
|
3739
|
-
'@pactor-app/core': 1.
|
|
3740
|
-
'@pactor-app/schema': 1.
|
|
3739
|
+
'@pactor-app/core': 1.33.0
|
|
3740
|
+
'@pactor-app/schema': 1.33.0
|
|
3741
3741
|
vite: 8.3.1(@types/node@20.19.43)(jiti@2.7.0)(yaml@2.9.1)
|
|
3742
3742
|
yaml: 2.9.1
|
|
3743
3743
|
|
|
@@ -5996,21 +5996,21 @@ snapshots:
|
|
|
5996
5996
|
|
|
5997
5997
|
p-try@2.2.0: {}
|
|
5998
5998
|
|
|
5999
|
-
pactor-app@1.
|
|
6000
|
-
dependencies:
|
|
6001
|
-
'@pactor-app/app': 1.
|
|
6002
|
-
'@pactor-app/chat': 1.
|
|
6003
|
-
'@pactor-app/cli': 1.
|
|
6004
|
-
'@pactor-app/core': 1.
|
|
6005
|
-
'@pactor-app/expression': 1.
|
|
6006
|
-
'@pactor-app/markdown': 1.
|
|
6007
|
-
'@pactor-app/permission': 1.
|
|
6008
|
-
'@pactor-app/resource': 1.
|
|
6009
|
-
'@pactor-app/router': 1.
|
|
6010
|
-
'@pactor-app/runtime': 1.
|
|
6011
|
-
'@pactor-app/schema': 1.
|
|
6012
|
-
'@pactor-app/ui': 1.
|
|
6013
|
-
'@pactor-app/vite-plugin': 1.
|
|
5999
|
+
pactor-app@1.33.0(@date-fns/tz@1.5.0)(@types/react-dom@19.3.0(@types/react@19.3.0))(@types/react@19.3.0)(react-dom@19.2.8(react@19.2.8))(react-router-dom@7.18.4(react-dom@19.2.8(react@19.2.8))(react@19.2.8))(react@19.2.8)(vite@8.3.1(@types/node@20.19.43)(jiti@2.7.0)(yaml@2.9.1)):
|
|
6000
|
+
dependencies:
|
|
6001
|
+
'@pactor-app/app': 1.33.0(@date-fns/tz@1.5.0)(@types/react-dom@19.3.0(@types/react@19.3.0))(@types/react@19.3.0)(react-dom@19.2.8(react@19.2.8))(react-router-dom@7.18.4(react-dom@19.2.8(react@19.2.8))(react@19.2.8))(react@19.2.8)
|
|
6002
|
+
'@pactor-app/chat': 1.33.0(@date-fns/tz@1.5.0)(@types/react-dom@19.3.0(@types/react@19.3.0))(@types/react@19.3.0)(react-dom@19.2.8(react@19.2.8))(react-router-dom@7.18.4(react-dom@19.2.8(react@19.2.8))(react@19.2.8))(react@19.2.8)
|
|
6003
|
+
'@pactor-app/cli': 1.33.0
|
|
6004
|
+
'@pactor-app/core': 1.33.0
|
|
6005
|
+
'@pactor-app/expression': 1.33.0
|
|
6006
|
+
'@pactor-app/markdown': 1.33.0(@types/react@19.3.0)(react@19.2.8)
|
|
6007
|
+
'@pactor-app/permission': 1.33.0
|
|
6008
|
+
'@pactor-app/resource': 1.33.0
|
|
6009
|
+
'@pactor-app/router': 1.33.0(react-router-dom@7.18.4(react-dom@19.2.8(react@19.2.8))(react@19.2.8))(react@19.2.8)
|
|
6010
|
+
'@pactor-app/runtime': 1.33.0(react@19.2.8)
|
|
6011
|
+
'@pactor-app/schema': 1.33.0
|
|
6012
|
+
'@pactor-app/ui': 1.33.0(@date-fns/tz@1.5.0)(@types/react-dom@19.3.0(@types/react@19.3.0))(@types/react@19.3.0)(react-dom@19.2.8(react@19.2.8))(react-router-dom@7.18.4(react-dom@19.2.8(react@19.2.8))(react@19.2.8))(react@19.2.8)
|
|
6013
|
+
'@pactor-app/vite-plugin': 1.33.0(vite@8.3.1(@types/node@20.19.43)(jiti@2.7.0)(yaml@2.9.1))
|
|
6014
6014
|
react: 19.2.8
|
|
6015
6015
|
react-dom: 19.2.8(react@19.2.8)
|
|
6016
6016
|
react-router-dom: 7.18.4(react-dom@19.2.8(react@19.2.8))(react@19.2.8)
|
|
@@ -0,0 +1,84 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* 数据列表骨架示例 mock(对应 yaml/models/data-list.yaml)。
|
|
3
|
+
* query / get / save 注册为 dataList.* 服务;生成业务列表页时复制本文件
|
|
4
|
+
* 改名并替换字段;接入真实后端后删除。
|
|
5
|
+
*/
|
|
6
|
+
|
|
7
|
+
export interface DataListItem {
|
|
8
|
+
id: string;
|
|
9
|
+
name: string;
|
|
10
|
+
code: string;
|
|
11
|
+
/** 基础 | 高级(高级显示扩展说明字段,演示条件显隐) */
|
|
12
|
+
type: string;
|
|
13
|
+
extra: string;
|
|
14
|
+
sort: number;
|
|
15
|
+
/** 启用 | 禁用 */
|
|
16
|
+
status: string;
|
|
17
|
+
}
|
|
18
|
+
|
|
19
|
+
const ITEMS: DataListItem[] = [
|
|
20
|
+
{ id: "1", name: "示例记录甲", code: "DEMO_ALPHA", type: "基础", extra: "", sort: 1, status: "启用" },
|
|
21
|
+
{ id: "2", name: "示例记录乙", code: "DEMO_BETA", type: "高级", extra: "高级类型的扩展配置", sort: 2, status: "启用" },
|
|
22
|
+
{ id: "3", name: "示例记录丙", code: "DEMO_GAMMA", type: "基础", extra: "", sort: 3, status: "禁用" },
|
|
23
|
+
{ id: "4", name: "示例记录丁", code: "DEMO_DELTA", type: "高级", extra: "", sort: 4, status: "启用" },
|
|
24
|
+
];
|
|
25
|
+
|
|
26
|
+
let seq = ITEMS.length;
|
|
27
|
+
|
|
28
|
+
export interface DataListQuery {
|
|
29
|
+
keyword?: string;
|
|
30
|
+
status?: string;
|
|
31
|
+
}
|
|
32
|
+
|
|
33
|
+
/** 列表查询:items + total + 筛选选项(filters 由接口下发,搜索栏/表单的 Select 直接消费) */
|
|
34
|
+
export function queryDataList(params: DataListQuery) {
|
|
35
|
+
const keyword = (params.keyword ?? "").trim().toLowerCase();
|
|
36
|
+
const status = params.status ?? "all";
|
|
37
|
+
const items = ITEMS.filter(
|
|
38
|
+
(it) =>
|
|
39
|
+
(status === "all" || it.status === status) &&
|
|
40
|
+
(keyword === "" ||
|
|
41
|
+
it.name.toLowerCase().includes(keyword) ||
|
|
42
|
+
it.code.toLowerCase().includes(keyword)),
|
|
43
|
+
);
|
|
44
|
+
return {
|
|
45
|
+
items,
|
|
46
|
+
total: items.length,
|
|
47
|
+
filters: {
|
|
48
|
+
status: [
|
|
49
|
+
{ label: "全部", value: "all" },
|
|
50
|
+
{ label: "启用", value: "启用" },
|
|
51
|
+
{ label: "禁用", value: "禁用" },
|
|
52
|
+
],
|
|
53
|
+
type: [
|
|
54
|
+
{ label: "基础", value: "基础" },
|
|
55
|
+
{ label: "高级", value: "高级" },
|
|
56
|
+
],
|
|
57
|
+
},
|
|
58
|
+
};
|
|
59
|
+
}
|
|
60
|
+
|
|
61
|
+
/** 编辑预填;空 id(新建)返回空对象,Form initialValues 各字段即空 */
|
|
62
|
+
export function getDataListItem(id: string): Partial<DataListItem> {
|
|
63
|
+
return ITEMS.find((it) => it.id === id) ?? {};
|
|
64
|
+
}
|
|
65
|
+
|
|
66
|
+
/** 新建 / 编辑保存(upsert,按 id 区分) */
|
|
67
|
+
export function saveDataListItem(body: Partial<DataListItem>) {
|
|
68
|
+
if (body.id) {
|
|
69
|
+
const idx = ITEMS.findIndex((it) => it.id === body.id);
|
|
70
|
+
if (idx >= 0) ITEMS[idx] = { ...ITEMS[idx], ...body, id: body.id } as DataListItem;
|
|
71
|
+
return { ok: true, id: body.id };
|
|
72
|
+
}
|
|
73
|
+
const id = String(++seq);
|
|
74
|
+
ITEMS.push({
|
|
75
|
+
id,
|
|
76
|
+
name: body.name ?? "",
|
|
77
|
+
code: body.code ?? "",
|
|
78
|
+
type: body.type ?? "基础",
|
|
79
|
+
extra: body.extra ?? "",
|
|
80
|
+
sort: body.sort ?? 0,
|
|
81
|
+
status: body.status ?? "启用",
|
|
82
|
+
});
|
|
83
|
+
return { ok: true, id };
|
|
84
|
+
}
|
|
@@ -28,6 +28,11 @@ import {
|
|
|
28
28
|
import { getCallLog, queryCallLogs } from "./mocks/call-logs-mock";
|
|
29
29
|
import { getCost, queryCosts } from "./mocks/costs-mock";
|
|
30
30
|
import { getAudit, listAuditOperators, queryAudits } from "./mocks/audit-mock";
|
|
31
|
+
import {
|
|
32
|
+
getDataListItem,
|
|
33
|
+
queryDataList,
|
|
34
|
+
saveDataListItem,
|
|
35
|
+
} from "./mocks/data-list-mock";
|
|
31
36
|
import {
|
|
32
37
|
queryAvailability,
|
|
33
38
|
queryClientUsage,
|
|
@@ -182,4 +187,14 @@ export const pactorServices: Record<string, ServiceHandler> = {
|
|
|
182
187
|
queryClientUsage({ start: opt(params.start), end: opt(params.end) }),
|
|
183
188
|
"ops.availability": (params) =>
|
|
184
189
|
queryAvailability({ start: opt(params.start), end: opt(params.end) }),
|
|
190
|
+
|
|
191
|
+
// 数据列表骨架示例(yaml/models/data-list.yaml);生成业务列表页时成组复制改名
|
|
192
|
+
"dataList.list": (params) =>
|
|
193
|
+
queryDataList({
|
|
194
|
+
keyword: str(params.keyword),
|
|
195
|
+
status: str(params.status) || "all",
|
|
196
|
+
}),
|
|
197
|
+
"dataList.detail": (params) => getDataListItem(str(params.code)),
|
|
198
|
+
"dataList.save": (params) =>
|
|
199
|
+
saveDataListItem(params as Parameters<typeof saveDataListItem>[0]),
|
|
185
200
|
};
|
|
@@ -0,0 +1,344 @@
|
|
|
1
|
+
# 数据列表标准骨架 —— 「搜索 + 表格 + 抽屉新建/编辑」数据列表页的复制起点。
|
|
2
|
+
# 本页已注册进 sitemap.yaml(菜单「页面骨架 / 数据列表」,路径 /models/data-list),
|
|
3
|
+
# 在模板工程中可直接运行预览;生成业务列表页时复制本文件到 yaml/<模块>/ 下,
|
|
4
|
+
# 替换页面信息、字段、接口名(data-list → 业务资源名)与文案。
|
|
5
|
+
# 结构与交互约定见 skills/pactor-prd/references/page-templates.md「数据列表标准模型」。
|
|
6
|
+
dsl: "1.0"
|
|
7
|
+
page:
|
|
8
|
+
id: data-list
|
|
9
|
+
title: 数据列表
|
|
10
|
+
name: dataList
|
|
11
|
+
state:
|
|
12
|
+
# 搜索条件镜像:Form submit 后写入,驱动列表请求参数
|
|
13
|
+
keyword: ""
|
|
14
|
+
status: all
|
|
15
|
+
editingId: ""
|
|
16
|
+
# 表单条件显隐镜像(onValuesChange 写入;按页面需要增减,可多个)
|
|
17
|
+
fType: ""
|
|
18
|
+
dataSources:
|
|
19
|
+
list:
|
|
20
|
+
type: http
|
|
21
|
+
autoLoad: true
|
|
22
|
+
request:
|
|
23
|
+
method: GET
|
|
24
|
+
url: /api/data/data-list
|
|
25
|
+
params:
|
|
26
|
+
keyword: ${state.keyword}
|
|
27
|
+
status: ${state.status}
|
|
28
|
+
editing: # 编辑预填;autoLoad: false,打开抽屉前手动 reload
|
|
29
|
+
type: http
|
|
30
|
+
autoLoad: false
|
|
31
|
+
request:
|
|
32
|
+
method: GET
|
|
33
|
+
url: /api/data/data-list/${state.editingId}
|
|
34
|
+
body:
|
|
35
|
+
type: Page
|
|
36
|
+
children:
|
|
37
|
+
- type: Breadcrumb
|
|
38
|
+
props:
|
|
39
|
+
items:
|
|
40
|
+
- label: 页面骨架
|
|
41
|
+
- label: 数据列表
|
|
42
|
+
# 标题行:左标题 + 副标题,右新建按钮
|
|
43
|
+
- type: Flex
|
|
44
|
+
props:
|
|
45
|
+
justify: space-between
|
|
46
|
+
align: center
|
|
47
|
+
children:
|
|
48
|
+
- type: Flex
|
|
49
|
+
props:
|
|
50
|
+
direction: vertical
|
|
51
|
+
gap: 2
|
|
52
|
+
children:
|
|
53
|
+
- type: Typography
|
|
54
|
+
props:
|
|
55
|
+
variant: h3
|
|
56
|
+
text: 数据列表
|
|
57
|
+
- type: Typography
|
|
58
|
+
props:
|
|
59
|
+
variant: muted
|
|
60
|
+
text: 标准列表示例:搜索 + 表格 + 抽屉新建/编辑,复制本页生成业务列表。
|
|
61
|
+
- type: Button
|
|
62
|
+
props:
|
|
63
|
+
text: + 新建记录
|
|
64
|
+
variant: primary
|
|
65
|
+
events:
|
|
66
|
+
onClick:
|
|
67
|
+
- action: setState # 清空编辑态与显隐镜像
|
|
68
|
+
params:
|
|
69
|
+
editingId: ""
|
|
70
|
+
fType: ""
|
|
71
|
+
- action: reload # 清空 editing 数据(editingId 为空 → mock 返回空对象)
|
|
72
|
+
params:
|
|
73
|
+
dataSource: editing
|
|
74
|
+
- action: overlay.open # 锚点 &entityDrawer 在此定义,表格行内用 *entityDrawer 引用
|
|
75
|
+
params:
|
|
76
|
+
overlay: &entityDrawer
|
|
77
|
+
type: drawer
|
|
78
|
+
title: "${state.editingId == '' ? '新建记录' : '编辑记录'}"
|
|
79
|
+
width: 720
|
|
80
|
+
content:
|
|
81
|
+
type: Form
|
|
82
|
+
props:
|
|
83
|
+
name: entityForm
|
|
84
|
+
layout: vertical
|
|
85
|
+
initialValues: ${data.editing}
|
|
86
|
+
events:
|
|
87
|
+
# 条件显隐字段镜像到 state(其他字段变化时保持原值)
|
|
88
|
+
onValuesChange:
|
|
89
|
+
- action: setState
|
|
90
|
+
params:
|
|
91
|
+
fType: "${event.type != null ? event.type : state.fType}"
|
|
92
|
+
onSubmit:
|
|
93
|
+
- action: request
|
|
94
|
+
params:
|
|
95
|
+
method: POST
|
|
96
|
+
url: /api/data/ops/data-list-save
|
|
97
|
+
body:
|
|
98
|
+
id: ${state.editingId}
|
|
99
|
+
name: ${event.name}
|
|
100
|
+
code: ${event.code}
|
|
101
|
+
type: ${event.type}
|
|
102
|
+
extra: ${event.extra}
|
|
103
|
+
sort: ${event.sort}
|
|
104
|
+
status: ${event.status}
|
|
105
|
+
- action: message
|
|
106
|
+
params:
|
|
107
|
+
messageType: success
|
|
108
|
+
text: 已保存(演示)
|
|
109
|
+
- action: overlay.close
|
|
110
|
+
children:
|
|
111
|
+
# 分区结构:标题 → 分割线 → 字段组(不用 Card);多个分区重复此结构
|
|
112
|
+
- type: Flex
|
|
113
|
+
props:
|
|
114
|
+
direction: vertical
|
|
115
|
+
gap: middle
|
|
116
|
+
children:
|
|
117
|
+
- type: Text
|
|
118
|
+
props:
|
|
119
|
+
text: 基本信息
|
|
120
|
+
strong: true
|
|
121
|
+
- type: Separator
|
|
122
|
+
- type: Flex
|
|
123
|
+
props:
|
|
124
|
+
direction: vertical
|
|
125
|
+
gap: small
|
|
126
|
+
children:
|
|
127
|
+
- type: Field
|
|
128
|
+
props:
|
|
129
|
+
label: 名称
|
|
130
|
+
required: true
|
|
131
|
+
children:
|
|
132
|
+
- type: Input
|
|
133
|
+
props:
|
|
134
|
+
name: name
|
|
135
|
+
placeholder: 请输入名称
|
|
136
|
+
rules:
|
|
137
|
+
- required: true
|
|
138
|
+
message: 请输入名称
|
|
139
|
+
# 编辑时禁用关键字段
|
|
140
|
+
- type: Field
|
|
141
|
+
props:
|
|
142
|
+
label: 编码
|
|
143
|
+
required: true
|
|
144
|
+
children:
|
|
145
|
+
- type: Input
|
|
146
|
+
props:
|
|
147
|
+
name: code
|
|
148
|
+
placeholder: 大写字母 + 下划线,如 DEMO_ITEM
|
|
149
|
+
disabled: ${state.editingId != ''}
|
|
150
|
+
rules:
|
|
151
|
+
- required: true
|
|
152
|
+
message: 请输入编码
|
|
153
|
+
# 成对字段用 Grid 两列
|
|
154
|
+
- type: Grid
|
|
155
|
+
props:
|
|
156
|
+
columns: 2
|
|
157
|
+
gap: 16
|
|
158
|
+
children:
|
|
159
|
+
- type: Field
|
|
160
|
+
props:
|
|
161
|
+
label: 类型
|
|
162
|
+
required: true
|
|
163
|
+
children:
|
|
164
|
+
- type: Select
|
|
165
|
+
props:
|
|
166
|
+
name: type
|
|
167
|
+
placeholder: 请选择类型
|
|
168
|
+
options: ${data.list.filters.type}
|
|
169
|
+
rules:
|
|
170
|
+
- required: true
|
|
171
|
+
message: 请选择类型
|
|
172
|
+
- type: Field
|
|
173
|
+
props:
|
|
174
|
+
label: 状态
|
|
175
|
+
children:
|
|
176
|
+
- type: Select
|
|
177
|
+
props:
|
|
178
|
+
name: status
|
|
179
|
+
value: 启用
|
|
180
|
+
options: ${data.list.filters.status}
|
|
181
|
+
- type: Grid
|
|
182
|
+
props:
|
|
183
|
+
columns: 2
|
|
184
|
+
gap: 16
|
|
185
|
+
children:
|
|
186
|
+
- type: Field
|
|
187
|
+
props:
|
|
188
|
+
label: 排序
|
|
189
|
+
children:
|
|
190
|
+
- type: NumberInput
|
|
191
|
+
props:
|
|
192
|
+
name: sort
|
|
193
|
+
className: w-full
|
|
194
|
+
min: 0
|
|
195
|
+
precision: 0
|
|
196
|
+
# 条件显隐字段:依赖镜像 state
|
|
197
|
+
- when: ${state.fType == '高级'}
|
|
198
|
+
type: Field
|
|
199
|
+
props:
|
|
200
|
+
label: 扩展说明
|
|
201
|
+
children:
|
|
202
|
+
- type: Input
|
|
203
|
+
props:
|
|
204
|
+
name: extra
|
|
205
|
+
placeholder: 高级类型的扩展配置说明
|
|
206
|
+
# 底部按钮:取消关抽屉,保存触发 Form onSubmit
|
|
207
|
+
- type: Flex
|
|
208
|
+
props:
|
|
209
|
+
justify: end
|
|
210
|
+
gap: small
|
|
211
|
+
className: mt-4
|
|
212
|
+
children:
|
|
213
|
+
- type: Button
|
|
214
|
+
props:
|
|
215
|
+
text: 取消
|
|
216
|
+
events:
|
|
217
|
+
onClick:
|
|
218
|
+
- action: overlay.close
|
|
219
|
+
- type: Button
|
|
220
|
+
props:
|
|
221
|
+
text: 保存
|
|
222
|
+
variant: primary
|
|
223
|
+
submit: true
|
|
224
|
+
htmlType: submit
|
|
225
|
+
- action: reload # overlay.open 阻塞到关闭,关闭后刷新列表
|
|
226
|
+
params:
|
|
227
|
+
dataSource: list
|
|
228
|
+
# 搜索栏:Form(layout: inline) + Field 包裹控件
|
|
229
|
+
- type: Card
|
|
230
|
+
children:
|
|
231
|
+
- type: Form
|
|
232
|
+
props:
|
|
233
|
+
name: search
|
|
234
|
+
layout: inline
|
|
235
|
+
events:
|
|
236
|
+
onSubmit:
|
|
237
|
+
- action: setState
|
|
238
|
+
params:
|
|
239
|
+
keyword: ${event.keyword}
|
|
240
|
+
status: ${event.status}
|
|
241
|
+
- action: reload
|
|
242
|
+
params:
|
|
243
|
+
dataSource: list
|
|
244
|
+
children:
|
|
245
|
+
- type: Field
|
|
246
|
+
props:
|
|
247
|
+
label: 编码/名称
|
|
248
|
+
children:
|
|
249
|
+
- type: Input
|
|
250
|
+
props:
|
|
251
|
+
name: keyword
|
|
252
|
+
placeholder: 支持模糊查询
|
|
253
|
+
- type: Field
|
|
254
|
+
props:
|
|
255
|
+
label: 状态
|
|
256
|
+
children:
|
|
257
|
+
- type: Select
|
|
258
|
+
props:
|
|
259
|
+
name: status
|
|
260
|
+
placeholder: 请选择状态
|
|
261
|
+
options: ${data.list.filters.status} # 选项由接口下发
|
|
262
|
+
# 按钮也放进 Field:label 为 U+00A0 不间断空格(普通空格会被压缩),与左侧控件基线对齐
|
|
263
|
+
- type: Field
|
|
264
|
+
props:
|
|
265
|
+
label: " "
|
|
266
|
+
children:
|
|
267
|
+
- type: Flex
|
|
268
|
+
props:
|
|
269
|
+
gap: small
|
|
270
|
+
align: center
|
|
271
|
+
children:
|
|
272
|
+
- type: Button
|
|
273
|
+
props:
|
|
274
|
+
text: 查询
|
|
275
|
+
submit: true
|
|
276
|
+
htmlType: submit
|
|
277
|
+
- type: Button
|
|
278
|
+
props:
|
|
279
|
+
text: 重置
|
|
280
|
+
events:
|
|
281
|
+
onClick:
|
|
282
|
+
- action: form.setValues
|
|
283
|
+
params:
|
|
284
|
+
form: search
|
|
285
|
+
values:
|
|
286
|
+
keyword: ""
|
|
287
|
+
status: all
|
|
288
|
+
- action: setState
|
|
289
|
+
params:
|
|
290
|
+
keyword: ""
|
|
291
|
+
status: all
|
|
292
|
+
- action: reload
|
|
293
|
+
params:
|
|
294
|
+
dataSource: list
|
|
295
|
+
# 表格:名称列/操作列按钮统一 variant: link size: small
|
|
296
|
+
- type: Table
|
|
297
|
+
props:
|
|
298
|
+
dataSource: ${data.list.items}
|
|
299
|
+
rowKey: id
|
|
300
|
+
pagination: false
|
|
301
|
+
className: mt-4
|
|
302
|
+
columns:
|
|
303
|
+
- title: 名称
|
|
304
|
+
cell:
|
|
305
|
+
type: Button
|
|
306
|
+
props:
|
|
307
|
+
text: ${row.name}
|
|
308
|
+
variant: link
|
|
309
|
+
size: small
|
|
310
|
+
events:
|
|
311
|
+
onClick: &editRow # 行点击 = 编辑,锚点在此定义
|
|
312
|
+
- action: setState # 写入编辑 id + 显隐镜像(取自行数据,不等 editing 接口)
|
|
313
|
+
params:
|
|
314
|
+
editingId: ${row.id}
|
|
315
|
+
fType: ${row.type}
|
|
316
|
+
- action: reload
|
|
317
|
+
params:
|
|
318
|
+
dataSource: editing
|
|
319
|
+
- action: overlay.open
|
|
320
|
+
params:
|
|
321
|
+
overlay: *entityDrawer
|
|
322
|
+
- action: reload
|
|
323
|
+
params:
|
|
324
|
+
dataSource: list
|
|
325
|
+
- title: 编码
|
|
326
|
+
dataIndex: code
|
|
327
|
+
- title: 类型
|
|
328
|
+
dataIndex: type
|
|
329
|
+
- title: 状态
|
|
330
|
+
dataIndex: status
|
|
331
|
+
- title: 操作
|
|
332
|
+
cell:
|
|
333
|
+
type: Button
|
|
334
|
+
props:
|
|
335
|
+
text: 编辑
|
|
336
|
+
variant: link
|
|
337
|
+
size: small
|
|
338
|
+
events:
|
|
339
|
+
onClick: *editRow # 与名称列同一动作
|
|
340
|
+
- type: Text
|
|
341
|
+
props:
|
|
342
|
+
text: 共 ${data.list.total} 条
|
|
343
|
+
type: secondary
|
|
344
|
+
className: mt-3
|
|
@@ -49,6 +49,14 @@ pages:
|
|
|
49
49
|
}
|
|
50
50
|
# 模块二:模型路由 / 路由(卡片式列表 + 单页纵向详情 + 单页表单)
|
|
51
51
|
- { id: route-list, path: /routes, title: 路由, version: 1, lazy: true }
|
|
52
|
+
# 页面骨架:数据列表标准模型(搜索 + 表格 + 抽屉新建/编辑),可复制生成业务列表页
|
|
53
|
+
- {
|
|
54
|
+
id: data-list,
|
|
55
|
+
path: /models/data-list,
|
|
56
|
+
title: 数据列表,
|
|
57
|
+
version: 1,
|
|
58
|
+
lazy: true,
|
|
59
|
+
}
|
|
52
60
|
- {
|
|
53
61
|
id: route-create,
|
|
54
62
|
path: /routes/new,
|
|
@@ -116,6 +124,19 @@ menus:
|
|
|
116
124
|
title: 路由,
|
|
117
125
|
layout: admin,
|
|
118
126
|
}
|
|
127
|
+
- id: skeletons
|
|
128
|
+
type: group
|
|
129
|
+
title: 页面骨架
|
|
130
|
+
icon: folder
|
|
131
|
+
order: 4
|
|
132
|
+
children:
|
|
133
|
+
- {
|
|
134
|
+
id: data-list,
|
|
135
|
+
type: page,
|
|
136
|
+
pageId: data-list,
|
|
137
|
+
title: 数据列表,
|
|
138
|
+
layout: admin,
|
|
139
|
+
}
|
|
119
140
|
# 隐藏页(不出现在菜单,经列表页跳转进入;activeMenu 保持所属菜单高亮)
|
|
120
141
|
- {
|
|
121
142
|
id: provider-create,
|