create-pactor-app 1.22.0 → 1.23.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.
@@ -0,0 +1,69 @@
1
+ # 登录页 DSL:内联在 sitemap 中下发(public 页,匿名可见)。
2
+ # 登录 / 登出是普通 HTTP 调用,用内置 request 动作表达;
3
+ # 登录成功整页重载,sitemap 端点按已登录会话重新裁剪内容。
4
+ dsl: "1.0"
5
+ page:
6
+ id: login
7
+ title: 登录
8
+
9
+ state:
10
+ submitting: false
11
+
12
+ body:
13
+ type: Form
14
+ events:
15
+ onSubmit:
16
+ - action: setState
17
+ params: { submitting: true }
18
+ - id: loginResult
19
+ action: request
20
+ params:
21
+ method: POST
22
+ url: http://localhost:9011/api/auth/login
23
+ body:
24
+ username: ${event.username}
25
+ password: ${event.password}
26
+ - action: setState
27
+ params: { submitting: false }
28
+ - action: if
29
+ params:
30
+ condition: ${actions.loginResult.token}
31
+ then:
32
+ - action: app.reload
33
+ params: { to: / }
34
+ else:
35
+ - action: message
36
+ params:
37
+ messageType: error
38
+ text: 登录失败:用户名或密码错误
39
+ children:
40
+ - type: Alert
41
+ props:
42
+ variant: info
43
+ message: 演示账号 admin / pactor123,guest / guest123
44
+ description: admin 可见「报表」菜单(report:view);guest 仅可见首页。登录后 sitemap 按角色重新下发。
45
+ style: { marginBottom: 16 }
46
+ - type: Input
47
+ props:
48
+ name: username
49
+ label: 用户名
50
+ placeholder: 请输入用户名
51
+ rules:
52
+ - { required: true, message: 请输入用户名 }
53
+ - type: Input
54
+ props:
55
+ name: password
56
+ label: 密码
57
+ type: password
58
+ placeholder: 请输入密码
59
+ rules:
60
+ - { required: true, message: 请输入密码 }
61
+ - type: Flex
62
+ props: { justify: end }
63
+ children:
64
+ - type: Button
65
+ props:
66
+ text: 登 录
67
+ variant: primary
68
+ submit: true
69
+ loading: ${state.submitting}
@@ -0,0 +1,23 @@
1
+ # 月报详情页 DSL:内联在 sitemap 中下发(需 report:view)。
2
+ # 隐藏页(不出现在菜单),经列表页跳转进入;${route.params.id} 演示路径参数。
3
+ dsl: "1.0"
4
+ page:
5
+ id: monthly-detail
6
+ title: 月报详情
7
+
8
+ body:
9
+ type: Page
10
+ props: { title: 月报详情 }
11
+ children:
12
+ - type: Alert
13
+ props:
14
+ variant: info
15
+ message: 路径参数演示:id = ${route.params.id}
16
+ description: 隐藏页(不出现在菜单),经列表页跳转进入。
17
+ style: { marginBottom: 16 }
18
+ - type: Button
19
+ props: { text: 返回月报 }
20
+ events:
21
+ onClick:
22
+ - action: navigate
23
+ params: { to: /reports/monthly }
@@ -0,0 +1,41 @@
1
+ # 月报页 DSL:懒加载页——sitemap 中仅声明 id / path / version(monthly@7),
2
+ # 本文件由 /api/pages/monthly 按需下发(见 src/server/sitemap.ts 的 lazyPages)。
3
+ dsl: "1.0"
4
+ page:
5
+ id: monthly
6
+ title: 月报
7
+
8
+ body:
9
+ type: Page
10
+ props: { title: 本月经营月报 }
11
+ children:
12
+ - type: Flex
13
+ props: { gap: 16, style: { marginBottom: 16 } }
14
+ children:
15
+ - type: Card
16
+ props: { title: 营收 }
17
+ children:
18
+ - type: Statistic
19
+ props: { title: 本月(万元), value: 128.6 }
20
+ - type: Card
21
+ props: { title: 新增客户 }
22
+ children:
23
+ - type: Statistic
24
+ props: { title: 本月(家), value: 342 }
25
+ - type: Card
26
+ props: { title: 转化率 }
27
+ children:
28
+ - type: Statistic
29
+ props: { title: 本月(%), value: 23.8 }
30
+ - type: Alert
31
+ props:
32
+ variant: success
33
+ message: 本页 DSL 由 /api/pages/monthly 懒加载下发
34
+ description: sitemap 中该页仅声明 id / path / version(monthly@7),点击进入时才请求页面 DSL。
35
+ style: { marginBottom: 16 }
36
+ - type: Button
37
+ props: { text: 查看详情(隐藏页 + 路径参数) }
38
+ events:
39
+ onClick:
40
+ - action: navigate
41
+ params: { to: /reports/monthly/2026-09 }
@@ -0,0 +1,23 @@
1
+ # 注册页 DSL:内联在 sitemap 中下发(public 页,匿名可见)。
2
+ # 演示环境不开放注册,仅作多 public 页示例。
3
+ dsl: "1.0"
4
+ page:
5
+ id: register
6
+ title: 注册
7
+
8
+ body:
9
+ type: Page
10
+ props: { title: 注册 }
11
+ children:
12
+ - type: Alert
13
+ props:
14
+ variant: warning
15
+ message: 演示环境不开放注册
16
+ description: 请使用登录页的演示账号体验不同角色的菜单差异。
17
+ style: { marginBottom: 16 }
18
+ - type: Button
19
+ props: { text: 返回登录, variant: primary }
20
+ events:
21
+ onClick:
22
+ - action: navigate
23
+ params: { to: /login }
@@ -0,0 +1,85 @@
1
+ # 用户列表页 DSL:由 /api/pages/users 懒加载下发(见 src/server/sitemap.ts)。
2
+ # 数据来自 /api/users(接口侧鉴权,需登录且具备 user:view 权限)。
3
+ dsl: "1.0"
4
+ page:
5
+ id: users
6
+ title: 用户列表
7
+ permission: user:view
8
+
9
+ state:
10
+ keyword: ""
11
+ role: ""
12
+
13
+ dataSources:
14
+ users:
15
+ type: http
16
+ autoLoad: true
17
+ request:
18
+ method: GET
19
+ url: http://localhost:9011/api/users
20
+ params:
21
+ keyword: ${state.keyword}
22
+ role: ${state.role}
23
+
24
+ body:
25
+ type: Page
26
+ props: { title: 用户列表 }
27
+ children:
28
+ - type: Card
29
+ props: { title: 筛选 }
30
+ children:
31
+ - type: Form
32
+ props: { layout: inline }
33
+ events:
34
+ onSubmit:
35
+ - action: setState
36
+ params:
37
+ keyword: ${event.keyword}
38
+ role: ${event.role}
39
+ - action: reload
40
+ params: { dataSource: users }
41
+ children:
42
+ - type: Input
43
+ props: { name: keyword, label: 关键词, placeholder: 姓名 / 用户名 }
44
+ - type: Select
45
+ props:
46
+ name: role
47
+ label: 角色
48
+ placeholder: 请选择角色
49
+ options:
50
+ - { label: 管理员, value: admin }
51
+ - { label: 成员, value: member }
52
+ - { label: 访客, value: guest }
53
+ - type: Button
54
+ props: { text: 查询, variant: primary, submit: true }
55
+ - type: Card
56
+ props: { title: 用户数据 }
57
+ children:
58
+ - type: Table
59
+ props:
60
+ dataSource: ${data.users}
61
+ loading: ${dataStatus.users.loading}
62
+ rowKey: id
63
+ pagination: { pageSize: 5 }
64
+ columns:
65
+ - { title: 姓名, dataIndex: name }
66
+ - { title: 用户名, dataIndex: username }
67
+ - title: 角色
68
+ dataIndex: role
69
+ cell:
70
+ type: Badge
71
+ props:
72
+ text: ${row.role}
73
+ variant: secondary
74
+ - { title: 邮箱, dataIndex: email }
75
+ - { title: 创建时间, dataIndex: createdAt }
76
+ - title: 操作
77
+ cell:
78
+ type: Button
79
+ props: { text: 查看, variant: primary, size: small }
80
+ events:
81
+ onClick:
82
+ - action: message
83
+ params:
84
+ messageType: info
85
+ text: 用户 ${row.name}(${row.username})
@@ -0,0 +1,148 @@
1
+ # Sitemap 入口数据(design/dynamic-page.md 方案 B):元数据 + 布局 + 页面 + 菜单全量。
2
+ # 本文件是会话无关的超集;可见性由 src/server/sitemap.ts 按会话裁剪:
3
+ # public: true → 匿名可见(登录/注册页)
4
+ # permission: x → 需登录且具备对应权限
5
+ # 无标记 → 需登录
6
+ # 页面 DSL 按 id 约定从 pages/<id>.page.yaml 加载;lazy: true 不随 sitemap
7
+ # 内联下发,客户端经 /api/pages/{id} 懒加载。updatedAt / user / permissions
8
+ # 为会话动态字段,由服务端在响应时注入。
9
+
10
+ id: site
11
+ resourceType: sitemap
12
+ version: 13
13
+ dslVersion: "1.0"
14
+ app: { name: 动态页面 Starter }
15
+ layout: admin
16
+ auth: { loginPath: /login }
17
+
18
+ pages:
19
+ - { id: login, path: /login, title: 登录, version: 1, public: true }
20
+ - { id: register, path: /register, title: 注册, version: 1, public: true }
21
+ - { id: home, path: /, title: 首页, version: 3 }
22
+ - { id: users, path: /users, title: 用户列表, version: 1, permission: user:view, lazy: true }
23
+ - { id: monthly, path: /reports/monthly, title: 月报, version: 7, permission: report:view, lazy: true }
24
+ - { id: monthly-detail, path: /reports/monthly/:id, title: 月报详情, version: 2, permission: report:view }
25
+
26
+ menus:
27
+ - { id: login, type: page, pageId: login, title: 登录, layout: login, public: true, hidden: true }
28
+ - { id: register, type: page, pageId: register, title: 注册, layout: login, public: true, hidden: true }
29
+ - { id: home, type: page, pageId: home, title: 首页, icon: home, layout: admin, order: 1 }
30
+ - { id: users, type: page, pageId: users, title: 用户列表, icon: users, layout: admin, permission: user:view, order: 2 }
31
+ - id: reports
32
+ type: group
33
+ title: 报表
34
+ icon: chart
35
+ order: 3
36
+ children:
37
+ - { id: monthly, type: page, pageId: monthly, title: 报表中心, icon: chart, layout: admin, permission: report:view }
38
+ - { id: monthly-detail, type: page, pageId: monthly-detail, title: 月报详情, layout: admin, hidden: true, activeMenu: monthly, permission: report:view }
39
+ - { id: help, type: link, title: 帮助, path: https://github.com/, external: true, permission: report:view, order: 4 }
40
+
41
+ # 布局 DSL(PageOutlet 为页面内容出口)。
42
+ # 布局 body 内 ${data.session.*} 由客户端注入的 session dataSource 提供
43
+ #(user / app / menus);${route.params.pathname} 为当前路径(客户端注入)。
44
+ # 登录 / 登出是普通 HTTP 调用,DSL 用内置 request 动作表达(跨域绝对地址,
45
+ # 客户端 httpHooks 自动改写进项目内代理前缀),无需客户端注册服务。
46
+ layouts:
47
+ # 管理端外壳:左侧 SitemapMenu 导航 + 顶栏用户菜单 + PageOutlet
48
+ admin:
49
+ dsl: "1.0"
50
+ body:
51
+ type: Flex
52
+ props: { gap: 0, direction: horizontal, style: { height: 100vh } }
53
+ children:
54
+ - type: Flex
55
+ props:
56
+ direction: vertical
57
+ style:
58
+ width: 224
59
+ flexShrink: 0
60
+ borderRight: 1px solid var(--border)
61
+ children:
62
+ - type: Flex
63
+ props:
64
+ style:
65
+ padding: 16px 16px
66
+ fontWeight: 600
67
+ borderBottom: 1px solid var(--border)
68
+ children:
69
+ - type: Text
70
+ props: { text: "${data.session.app.name}" }
71
+ - type: SitemapMenu
72
+ props:
73
+ items: ${data.session.menus}
74
+ collapsible: true
75
+ events:
76
+ onSelect:
77
+ - action: navigate
78
+ params: { to: "${event}" }
79
+ - type: Flex
80
+ props:
81
+ direction: vertical
82
+ style: { flex: 1, minWidth: 0 }
83
+ children:
84
+ - type: Flex
85
+ props:
86
+ justify: end
87
+ align: center
88
+ style:
89
+ padding: 10px 20px
90
+ borderBottom: 1px solid var(--border)
91
+ children:
92
+ - type: DropdownMenu
93
+ props:
94
+ items:
95
+ - { label: 个人设置, value: settings, icon: settings }
96
+ - { label: 退出登录, value: logout, icon: log-out }
97
+ events:
98
+ onSelect:
99
+ - action: if
100
+ params:
101
+ condition: ${event == 'logout'}
102
+ then:
103
+ - action: request
104
+ params:
105
+ method: POST
106
+ url: http://localhost:9011/api/auth/logout
107
+ - action: app.reload
108
+ params: { to: /login }
109
+ else:
110
+ - action: message
111
+ params: { text: 演示环境未实现个人设置 }
112
+ children:
113
+ - type: Button
114
+ props:
115
+ text: ${data.session.user.name}
116
+ variant: text
117
+ - type: Flex
118
+ props:
119
+ direction: vertical
120
+ style: { flex: 1, minHeight: 0, overflow: auto }
121
+ children:
122
+ - type: PageOutlet
123
+ # 登录 / 注册页外壳:居中卡片
124
+ login:
125
+ dsl: "1.0"
126
+ body:
127
+ type: Flex
128
+ props:
129
+ direction: vertical
130
+ justify: center
131
+ align: center
132
+ style: { minHeight: 100vh, padding: 24 }
133
+ children:
134
+ - type: Flex
135
+ props:
136
+ direction: vertical
137
+ style:
138
+ width: 380
139
+ padding: 24
140
+ border: 1px solid var(--border)
141
+ borderRadius: 12
142
+ children:
143
+ - type: PageOutlet
144
+ # 裸布局:无外壳,页面铺满
145
+ blank:
146
+ dsl: "1.0"
147
+ body:
148
+ type: PageOutlet
@@ -10,10 +10,10 @@
10
10
  "typecheck": "tsc --noEmit"
11
11
  },
12
12
  "dependencies": {
13
- "@pactor-app/core": "^1.20.0",
14
- "@pactor-app/runtime": "^1.20.0",
15
- "@pactor-app/ui": "^1.20.0",
16
- "pactor-app": "^1.20.0",
13
+ "@pactor-app/core": "^1.23.0",
14
+ "@pactor-app/runtime": "^1.23.0",
15
+ "@pactor-app/ui": "^1.23.0",
16
+ "pactor-app": "^1.23.0",
17
17
  "react": "19.2.8",
18
18
  "react-dom": "19.2.8",
19
19
  "react-router-dom": "^7.18.2"