@robsun/create-keystone-app 0.2.4 → 0.2.5
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/template/.claude/skills/keystone-dev/SKILL.md +5 -4
- package/template/.claude/skills/keystone-dev/TEMPLATES.md +63 -14
- package/template/.codex/skills/keystone-dev/SKILL.md +5 -4
- package/template/.codex/skills/keystone-dev/TEMPLATES.md +63 -14
- package/template/apps/web/package.json +1 -1
- package/template/pnpm-lock.yaml +5 -6
package/package.json
CHANGED
|
@@ -67,8 +67,9 @@ apps/server/internal/modules/{name}/
|
|
|
67
67
|
|
|
68
68
|
## 注册步骤
|
|
69
69
|
|
|
70
|
-
|
|
70
|
+
生成代码后需完成以下注册(**缺一不可**):
|
|
71
71
|
|
|
72
|
-
1.
|
|
73
|
-
2.
|
|
74
|
-
3.
|
|
72
|
+
1. **前端导入** `main.tsx`: `import './modules/{name}'`
|
|
73
|
+
2. **前端启用** `app.config.ts`: 添加到 `modules.enabled` 数组 ⚠️ **必须,否则菜单不显示**
|
|
74
|
+
3. **后端注册** `manifest.go`: `import {name}module "app/internal/modules/{name}"` + `Register({name}module.NewModule())`
|
|
75
|
+
4. **后端启用** `config.yaml`: 添加到 `modules.enabled`
|
|
@@ -29,23 +29,58 @@ registerModule({ name: '{name}', routes })
|
|
|
29
29
|
|
|
30
30
|
### List.tsx (ProTable)
|
|
31
31
|
```tsx
|
|
32
|
+
import { useEffect, useState } from 'react'
|
|
32
33
|
import { ProTable } from '@robsun/keystone-web-core'
|
|
33
|
-
import {
|
|
34
|
-
import type { PaginatedResponse } from '@robsun/keystone-web-core'
|
|
34
|
+
import type { PaginatedData } from '@robsun/keystone-web-core'
|
|
35
35
|
import type { {Entity} } from '../types'
|
|
36
|
+
import { list{Entity} } from '../services/api'
|
|
37
|
+
|
|
38
|
+
const INITIAL_DATA: PaginatedData<{Entity}> = {
|
|
39
|
+
items: [],
|
|
40
|
+
total: 0,
|
|
41
|
+
page: 1,
|
|
42
|
+
page_size: 10,
|
|
43
|
+
}
|
|
36
44
|
|
|
37
45
|
export function Component() {
|
|
46
|
+
const [loading, setLoading] = useState(false)
|
|
47
|
+
const [data, setData] = useState(INITIAL_DATA)
|
|
48
|
+
|
|
38
49
|
const columns = [
|
|
39
50
|
{ title: 'ID', dataIndex: 'id' },
|
|
40
51
|
{ title: '名称', dataIndex: 'name' },
|
|
41
52
|
]
|
|
42
53
|
|
|
43
|
-
const fetchData = async (
|
|
44
|
-
|
|
45
|
-
|
|
54
|
+
const fetchData = async (page = data.page, pageSize = data.page_size) => {
|
|
55
|
+
setLoading(true)
|
|
56
|
+
try {
|
|
57
|
+
const result = await list{Entity}({ page, page_size: pageSize })
|
|
58
|
+
setData(result)
|
|
59
|
+
} finally {
|
|
60
|
+
setLoading(false)
|
|
61
|
+
}
|
|
46
62
|
}
|
|
47
63
|
|
|
48
|
-
|
|
64
|
+
useEffect(() => {
|
|
65
|
+
void fetchData()
|
|
66
|
+
}, [])
|
|
67
|
+
|
|
68
|
+
return (
|
|
69
|
+
<ProTable
|
|
70
|
+
columns={columns}
|
|
71
|
+
dataSource={data.items}
|
|
72
|
+
rowKey="id"
|
|
73
|
+
loading={loading}
|
|
74
|
+
pagination={{
|
|
75
|
+
current: data.page,
|
|
76
|
+
pageSize: data.page_size,
|
|
77
|
+
total: data.total,
|
|
78
|
+
onChange: (page, pageSize) => {
|
|
79
|
+
void fetchData(page, pageSize)
|
|
80
|
+
},
|
|
81
|
+
}}
|
|
82
|
+
/>
|
|
83
|
+
)
|
|
49
84
|
}
|
|
50
85
|
```
|
|
51
86
|
|
|
@@ -79,16 +114,30 @@ export function Component() {
|
|
|
79
114
|
|
|
80
115
|
### services/api.ts
|
|
81
116
|
```typescript
|
|
82
|
-
import { api } from '@robsun/keystone-web-core'
|
|
83
|
-
import type { ApiResponse, PaginatedResponse } from '@robsun/keystone-web-core'
|
|
117
|
+
import { api, type ApiResponse, type PaginatedData, type PaginationParams } from '@robsun/keystone-web-core'
|
|
84
118
|
import type { {Entity} } from '../types'
|
|
85
119
|
|
|
86
|
-
|
|
87
|
-
|
|
88
|
-
|
|
89
|
-
|
|
90
|
-
|
|
91
|
-
|
|
120
|
+
// 注意:使用 api 而非 apiClient,响应格式为 { data: { ... } }
|
|
121
|
+
export const list{Entity} = async (params: PaginationParams = {}) => {
|
|
122
|
+
const { data } = await api.get<ApiResponse<PaginatedData<{Entity}>>>(
|
|
123
|
+
'/{module}/{resources}',
|
|
124
|
+
{ params }
|
|
125
|
+
)
|
|
126
|
+
return data.data
|
|
127
|
+
}
|
|
128
|
+
|
|
129
|
+
export const create{Entity} = async (payload: Partial<{Entity}>) => {
|
|
130
|
+
const { data } = await api.post<ApiResponse<{Entity}>>('/{module}/{resources}', payload)
|
|
131
|
+
return data.data
|
|
132
|
+
}
|
|
133
|
+
|
|
134
|
+
export const update{Entity} = async (id: number, payload: Partial<{Entity}>) => {
|
|
135
|
+
const { data } = await api.patch<ApiResponse<{Entity}>>(`/{module}/{resources}/${id}`, payload)
|
|
136
|
+
return data.data
|
|
137
|
+
}
|
|
138
|
+
|
|
139
|
+
export const delete{Entity} = async (id: number) => {
|
|
140
|
+
await api.delete<ApiResponse<{ id: number }>>(`/{module}/{resources}/${id}`)
|
|
92
141
|
}
|
|
93
142
|
```
|
|
94
143
|
|
|
@@ -67,8 +67,9 @@ apps/server/internal/modules/{name}/
|
|
|
67
67
|
|
|
68
68
|
## 注册步骤
|
|
69
69
|
|
|
70
|
-
|
|
70
|
+
生成代码后需完成以下注册(**缺一不可**):
|
|
71
71
|
|
|
72
|
-
1.
|
|
73
|
-
2.
|
|
74
|
-
3.
|
|
72
|
+
1. **前端导入** `main.tsx`: `import './modules/{name}'`
|
|
73
|
+
2. **前端启用** `app.config.ts`: 添加到 `modules.enabled` 数组 ⚠️ **必须,否则菜单不显示**
|
|
74
|
+
3. **后端注册** `manifest.go`: `import {name}module "app/internal/modules/{name}"` + `Register({name}module.NewModule())`
|
|
75
|
+
4. **后端启用** `config.yaml`: 添加到 `modules.enabled`
|
|
@@ -29,23 +29,58 @@ registerModule({ name: '{name}', routes })
|
|
|
29
29
|
|
|
30
30
|
### List.tsx (ProTable)
|
|
31
31
|
```tsx
|
|
32
|
+
import { useEffect, useState } from 'react'
|
|
32
33
|
import { ProTable } from '@robsun/keystone-web-core'
|
|
33
|
-
import {
|
|
34
|
-
import type { PaginatedResponse } from '@robsun/keystone-web-core'
|
|
34
|
+
import type { PaginatedData } from '@robsun/keystone-web-core'
|
|
35
35
|
import type { {Entity} } from '../types'
|
|
36
|
+
import { list{Entity} } from '../services/api'
|
|
37
|
+
|
|
38
|
+
const INITIAL_DATA: PaginatedData<{Entity}> = {
|
|
39
|
+
items: [],
|
|
40
|
+
total: 0,
|
|
41
|
+
page: 1,
|
|
42
|
+
page_size: 10,
|
|
43
|
+
}
|
|
36
44
|
|
|
37
45
|
export function Component() {
|
|
46
|
+
const [loading, setLoading] = useState(false)
|
|
47
|
+
const [data, setData] = useState(INITIAL_DATA)
|
|
48
|
+
|
|
38
49
|
const columns = [
|
|
39
50
|
{ title: 'ID', dataIndex: 'id' },
|
|
40
51
|
{ title: '名称', dataIndex: 'name' },
|
|
41
52
|
]
|
|
42
53
|
|
|
43
|
-
const fetchData = async (
|
|
44
|
-
|
|
45
|
-
|
|
54
|
+
const fetchData = async (page = data.page, pageSize = data.page_size) => {
|
|
55
|
+
setLoading(true)
|
|
56
|
+
try {
|
|
57
|
+
const result = await list{Entity}({ page, page_size: pageSize })
|
|
58
|
+
setData(result)
|
|
59
|
+
} finally {
|
|
60
|
+
setLoading(false)
|
|
61
|
+
}
|
|
46
62
|
}
|
|
47
63
|
|
|
48
|
-
|
|
64
|
+
useEffect(() => {
|
|
65
|
+
void fetchData()
|
|
66
|
+
}, [])
|
|
67
|
+
|
|
68
|
+
return (
|
|
69
|
+
<ProTable
|
|
70
|
+
columns={columns}
|
|
71
|
+
dataSource={data.items}
|
|
72
|
+
rowKey="id"
|
|
73
|
+
loading={loading}
|
|
74
|
+
pagination={{
|
|
75
|
+
current: data.page,
|
|
76
|
+
pageSize: data.page_size,
|
|
77
|
+
total: data.total,
|
|
78
|
+
onChange: (page, pageSize) => {
|
|
79
|
+
void fetchData(page, pageSize)
|
|
80
|
+
},
|
|
81
|
+
}}
|
|
82
|
+
/>
|
|
83
|
+
)
|
|
49
84
|
}
|
|
50
85
|
```
|
|
51
86
|
|
|
@@ -79,16 +114,30 @@ export function Component() {
|
|
|
79
114
|
|
|
80
115
|
### services/api.ts
|
|
81
116
|
```typescript
|
|
82
|
-
import { api } from '@robsun/keystone-web-core'
|
|
83
|
-
import type { ApiResponse, PaginatedResponse } from '@robsun/keystone-web-core'
|
|
117
|
+
import { api, type ApiResponse, type PaginatedData, type PaginationParams } from '@robsun/keystone-web-core'
|
|
84
118
|
import type { {Entity} } from '../types'
|
|
85
119
|
|
|
86
|
-
|
|
87
|
-
|
|
88
|
-
|
|
89
|
-
|
|
90
|
-
|
|
91
|
-
|
|
120
|
+
// 注意:使用 api 而非 apiClient,响应格式为 { data: { ... } }
|
|
121
|
+
export const list{Entity} = async (params: PaginationParams = {}) => {
|
|
122
|
+
const { data } = await api.get<ApiResponse<PaginatedData<{Entity}>>>(
|
|
123
|
+
'/{module}/{resources}',
|
|
124
|
+
{ params }
|
|
125
|
+
)
|
|
126
|
+
return data.data
|
|
127
|
+
}
|
|
128
|
+
|
|
129
|
+
export const create{Entity} = async (payload: Partial<{Entity}>) => {
|
|
130
|
+
const { data } = await api.post<ApiResponse<{Entity}>>('/{module}/{resources}', payload)
|
|
131
|
+
return data.data
|
|
132
|
+
}
|
|
133
|
+
|
|
134
|
+
export const update{Entity} = async (id: number, payload: Partial<{Entity}>) => {
|
|
135
|
+
const { data } = await api.patch<ApiResponse<{Entity}>>(`/{module}/{resources}/${id}`, payload)
|
|
136
|
+
return data.data
|
|
137
|
+
}
|
|
138
|
+
|
|
139
|
+
export const delete{Entity} = async (id: number) => {
|
|
140
|
+
await api.delete<ApiResponse<{ id: number }>>(`/{module}/{resources}/${id}`)
|
|
92
141
|
}
|
|
93
142
|
```
|
|
94
143
|
|
package/template/pnpm-lock.yaml
CHANGED
|
@@ -27,8 +27,8 @@ importers:
|
|
|
27
27
|
specifier: ^6.1.0
|
|
28
28
|
version: 6.1.0(react-dom@19.2.3(react@19.2.3))(react@19.2.3)
|
|
29
29
|
'@robsun/keystone-web-core':
|
|
30
|
-
specifier: 0.1.
|
|
31
|
-
version: 0.1.
|
|
30
|
+
specifier: 0.1.9
|
|
31
|
+
version: 0.1.9(@ant-design/icons@6.1.0(react-dom@19.2.3(react@19.2.3))(react@19.2.3))(@types/react@19.2.7)(antd@6.1.3(react-dom@19.2.3(react@19.2.3))(react@19.2.3))(react-dom@19.2.3(react@19.2.3))(react-router-dom@7.11.0(react-dom@19.2.3(react@19.2.3))(react@19.2.3))(react@19.2.3)(use-sync-external-store@1.6.0(react@19.2.3))(vite@7.3.0(@types/node@24.10.4)(jiti@2.6.1)(lightningcss@1.30.2)(yaml@2.8.2))
|
|
32
32
|
antd:
|
|
33
33
|
specifier: ^6.0.1
|
|
34
34
|
version: 6.1.3(react-dom@19.2.3(react@19.2.3))(react@19.2.3)
|
|
@@ -924,8 +924,8 @@ packages:
|
|
|
924
924
|
react: '>=16.9.0'
|
|
925
925
|
react-dom: '>=16.9.0'
|
|
926
926
|
|
|
927
|
-
'@robsun/keystone-web-core@0.1.
|
|
928
|
-
resolution: {integrity: sha512-
|
|
927
|
+
'@robsun/keystone-web-core@0.1.9':
|
|
928
|
+
resolution: {integrity: sha512-zbN6yiq3p/wwVOZvGj5YI6lT+xXCyWx87QIsM3IXnNyMxJl4OLRvv1xXN3u6K4uQpp2q+no4CeYLAfRwFIKNNw==}
|
|
929
929
|
peerDependencies:
|
|
930
930
|
'@ant-design/icons': ^6.1.0
|
|
931
931
|
antd: ^6.0.1
|
|
@@ -3744,7 +3744,7 @@ snapshots:
|
|
|
3744
3744
|
react: 19.2.3
|
|
3745
3745
|
react-dom: 19.2.3(react@19.2.3)
|
|
3746
3746
|
|
|
3747
|
-
'@robsun/keystone-web-core@0.1.
|
|
3747
|
+
'@robsun/keystone-web-core@0.1.9(@ant-design/icons@6.1.0(react-dom@19.2.3(react@19.2.3))(react@19.2.3))(@types/react@19.2.7)(antd@6.1.3(react-dom@19.2.3(react@19.2.3))(react@19.2.3))(react-dom@19.2.3(react@19.2.3))(react-router-dom@7.11.0(react-dom@19.2.3(react@19.2.3))(react@19.2.3))(react@19.2.3)(use-sync-external-store@1.6.0(react@19.2.3))(vite@7.3.0(@types/node@24.10.4)(jiti@2.6.1)(lightningcss@1.30.2)(yaml@2.8.2))':
|
|
3748
3748
|
dependencies:
|
|
3749
3749
|
'@ant-design/icons': 6.1.0(react-dom@19.2.3(react@19.2.3))(react@19.2.3)
|
|
3750
3750
|
'@vitejs/plugin-react': 5.1.2(vite@7.3.0(@types/node@24.10.4)(jiti@2.6.1)(lightningcss@1.30.2)(yaml@2.8.2))
|
|
@@ -6027,4 +6027,3 @@ snapshots:
|
|
|
6027
6027
|
use-sync-external-store: 1.6.0(react@19.2.3)
|
|
6028
6028
|
|
|
6029
6029
|
zwitch@2.0.4: {}
|
|
6030
|
-
|