kn-cli 1.0.93 → 1.0.95

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 (36) hide show
  1. package/package.json +1 -1
  2. package/templates/template_admin/public/src/assets/images/avatars/1.png +0 -0
  3. package/templates/template_admin/public/src/assets/images/avatars/2.png +0 -0
  4. package/templates/template_admin/public/src/assets/images/avatars/3.png +0 -0
  5. package/templates/template_admin/public/src/components/layout/basic/index.less +3 -3
  6. package/templates/template_admin/public/src/components/menu/topMenu/index.jsx +28 -15
  7. package/templates/template_admin/public/src/components/table/index.jsx +62 -0
  8. package/templates/template_admin/public/src/dictionary/index.js +45 -3
  9. package/templates/template_admin/public/src/mock/demo.js +184 -0
  10. package/templates/template_admin/public/src/mock/index.js +5 -2
  11. package/templates/template_admin/public/src/pages/demo/detail/index.jsx +27 -0
  12. package/templates/template_admin/public/src/pages/demo/edit/index.jsx +109 -0
  13. package/templates/template_admin/public/src/pages/demo/index.less +9 -0
  14. package/templates/template_admin/public/src/pages/demo/page1.jsx +161 -0
  15. package/templates/template_admin/public/src/pages/login/index.jsx +5 -4
  16. package/templates/template_admin/public/src/pages/superAdminLogin/index.jsx +9 -2
  17. package/templates/template_admin/public/src/provider/app.jsx +20 -10
  18. package/templates/template_admin/public/src/provider/menu.jsx +58 -173
  19. package/templates/template_admin/public/src/route.jsx +19 -25
  20. package/templates/template_admin/public/src/services/demo.js +54 -0
  21. package/templates/template_admin/public/src/services/index.js +9 -0
  22. package/templates/template_admin/public/src/utils/format.js +51 -0
  23. package/templates/template_admin/public/src/utils/rule.js +274 -0
  24. package/templates/template_admin/readme.md +4 -0
  25. package/templates/template_admin/public/src/mock/auth.js +0 -91
  26. package/templates/template_admin/public/src/mock/user.js +0 -70
  27. package/templates/template_admin/public/src/pages/material/index.jsx +0 -84
  28. package/templates/template_admin/public/src/pages/order/index.jsx +0 -12
  29. package/templates/template_admin/public/src/pages/permission/index.jsx +0 -12
  30. package/templates/template_admin/public/src/pages/suggest/index.jsx +0 -12
  31. package/templates/template_admin/public/src/pages/user/index.jsx +0 -18
  32. package/templates/template_admin/public/src/pages/userData/index.jsx +0 -12
  33. package/templates/template_admin/public/src/pages/video/index.jsx +0 -65
  34. package/templates/template_admin/public/src/services/auth.js +0 -28
  35. package/templates/template_admin/public/src/services/user.js +0 -26
  36. package/templates/template_admin/public/src/services/video.js +0 -33
@@ -0,0 +1,161 @@
1
+ import React, { useEffect, useState, useRef } from 'react';
2
+ // @ts-ignore
3
+ import {Input,Button,Form,Badge,Space,Popconfirm} from 'antd';
4
+ // @ts-ignore
5
+ import { useNavigate } from 'react-router-dom';
6
+ // @ts-ignore
7
+ import moment from 'moment';
8
+
9
+ import Table from '@/components/table';
10
+ import Link from '@/components/link';
11
+ import {usePaginationWithForm} from '@/hooks';
12
+ import {GET_LIST,FormatTableService} from '@/services/demo';
13
+ import {formatText,formatPhone} from '@/utils/format';
14
+ import {useHealthy} from '@/dictionary';
15
+
16
+ import ShowEdit from './edit';
17
+
18
+ // @ts-ignore
19
+ import styles from './index.less';
20
+
21
+ const Page = (props) => {
22
+ const {label=''}= props;
23
+ const [form] = Form.useForm();
24
+ const emHealthy = useHealthy();
25
+ const navigate = useNavigate();
26
+
27
+ const page = usePaginationWithForm({
28
+ service:GET_LIST,
29
+ pagination:{pageSize:10},
30
+ form,
31
+ afterService: [FormatTableService],
32
+ })
33
+
34
+ const columns=[
35
+ {
36
+ dataIndex:'id',
37
+ title:'id',
38
+ width:30,
39
+ render:(text)=>formatText(text)
40
+ },
41
+ {
42
+ dataIndex:'query',
43
+ title:'查询内容',
44
+ width:90,
45
+ render:(text)=>formatText(text)
46
+ },
47
+ {
48
+ dataIndex:'name',
49
+ title:'名称',
50
+ width:90,
51
+ render:(text)=>formatText(text)
52
+ },
53
+ {
54
+ dataIndex:'date',
55
+ title:'时间',
56
+ width:90,
57
+ render:(date)=>date?moment(date).format('YYYY-MM-DD'):'-'
58
+ },
59
+ {
60
+ title: '手机号码',
61
+ dataIndex: 'phone',
62
+ width:100,
63
+ align:'center',
64
+ render:(phone)=>formatPhone(phone)
65
+ },
66
+ {
67
+ title: '状态',
68
+ dataIndex: 'select',
69
+ width:90,
70
+ align:'center',
71
+ render:(state,record,idx)=>{
72
+ state=['normal','abnormal','disabled'][idx%3];
73
+ const colors={
74
+ normal:'green',
75
+ abnormal:'#FAAD14',
76
+ disabled:'red'
77
+ }
78
+ return <Badge
79
+ color={colors[state]}
80
+ text={emHealthy.getLabel(state)}
81
+ />
82
+ }
83
+ },
84
+ {
85
+ title: '操作',
86
+ key: 'option',
87
+ width:80,
88
+ fixed:'right',
89
+ align:'center',
90
+ render: (_, record) => (
91
+ <Space>
92
+ <Link onClick={onDetail.bind(this,record)}>详情</Link>
93
+ <Link onClick={onEdit.bind(this,record)}>编辑</Link>
94
+ <Popconfirm
95
+ title={`确定要${'禁用'}此用户吗?`}
96
+ onConfirm={onDel.bind(this,record)}
97
+ >
98
+ <Link>删除</Link>
99
+ </Popconfirm>
100
+ </Space>
101
+ ),
102
+ },
103
+ ];
104
+
105
+ const onEdit= async (record)=>{
106
+ const req= await ShowEdit({id:record.id});
107
+ if(req){
108
+ onSearch();
109
+ }
110
+ }
111
+ const onDetail= async (record)=>{
112
+
113
+ navigate(`detail/${record.id}`)
114
+ }
115
+ const onDel=()=>{}
116
+
117
+ // 搜索
118
+ const onSearch = () => {
119
+ page.update({ pagination: { current: 1 }, clear: true });
120
+ };
121
+ // 重置
122
+ const onReset = () => {
123
+ page.reset();
124
+ };
125
+ const onPageChange = (current, pageSize) => {
126
+ page.update({ pagination: { current, pageSize }, clear: true });
127
+ };
128
+
129
+ useEffect(() => {
130
+ onSearch();
131
+ }, []);
132
+
133
+ return (
134
+ <section className={styles.contentWrap}>
135
+ <p>页面名称:{label}</p>
136
+ <Form form={form} layout="inline">
137
+ <Form.Item label="关键字" name={'key1'}>
138
+ <Input placeholder="请输入用户组/描述" allowClear />
139
+ </Form.Item>
140
+ <Form.Item label="用户" name={'key2'}>
141
+ <Input placeholder="请输入用户全名" allowClear />
142
+ </Form.Item>
143
+ <Space>
144
+ <Button onClick={onSearch} type="primary">
145
+ 搜索
146
+ </Button>
147
+ <Button onClick={onReset}>重置</Button>
148
+ </Space>
149
+ </Form>
150
+ <Table
151
+ columns={columns}
152
+ pagination={{
153
+ onChange: onPageChange,
154
+ }}
155
+ page={page}
156
+ />
157
+ </section>
158
+ )
159
+ }
160
+
161
+ export default Page;
@@ -1,8 +1,9 @@
1
1
  import React, { useEffect, useState, useRef } from 'react';
2
- import { useParams, useSearchParams,useNavigate } from 'react-router-dom';
2
+ // @ts-ignore
3
+ import { useSearchParams } from 'react-router-dom';
3
4
  import ProviderApp from '@/provider/app';
4
5
 
5
-
6
+ // @ts-ignore
6
7
  import styles from './index.less';
7
8
 
8
9
  const Page = () => {
@@ -15,11 +16,11 @@ const Page = () => {
15
16
  return;
16
17
  }
17
18
  }
18
- useEffect(kssoLogin,[])
19
+ useEffect(()=>{kssoLogin()},[])
19
20
 
20
21
  return (
21
22
  <section className={styles.body}>
22
- 登录跳转中...
23
+ ksso登录跳转中...
23
24
  </section>
24
25
  )
25
26
  }
@@ -1,10 +1,16 @@
1
1
  import React, { useState, useRef } from 'react';
2
- import ProviderApp from '@/provider/app';
3
-
2
+ // @ts-ignore
4
3
  import {Input,Button} from 'antd';
5
4
 
5
+ import ProviderApp from '@/provider/app';
6
+
7
+ // @ts-ignore
6
8
  import styles from './index.less';
7
9
 
10
+ /**
11
+ * 本地模拟账号密码登录的页面
12
+ * @returns
13
+ */
8
14
  const Page = () => {
9
15
  const providerApp = ProviderApp.useContainer();
10
16
  const [username,setUsername]=useState('');
@@ -28,6 +34,7 @@ const Page = () => {
28
34
  const {key:code}= e;
29
35
  if(code.toLocaleLowerCase()=='enter'){
30
36
  if(type=='id'){
37
+ // @ts-ignore
31
38
  refPassword.current.focus();
32
39
  }else{
33
40
  onAccountLogin();
@@ -1,5 +1,5 @@
1
1
  // @ts-ignore
2
- import { useState,useMemo } from 'react';
2
+ import { useState,useMemo, useEffect } from 'react';
3
3
  // @ts-ignore
4
4
  import { useSearchParams,useNavigate } from 'react-router-dom';
5
5
  // @ts-ignore
@@ -7,7 +7,7 @@ import { createContainer } from "unstated-next";
7
7
  // @ts-ignore
8
8
  import {useDelay} from '@/hooks/index';
9
9
  import {setJwt,setLogout} from '@/services';
10
- import {KSSO_LOGIN,LOGIN,LOGOUT} from '@/services/auth';
10
+ import {GET_USER_INFO,Login,KssoLogin} from '@/services/demo';
11
11
  import {jumpUrl} from '@/utils';
12
12
 
13
13
 
@@ -23,7 +23,7 @@ import {jumpUrl} from '@/utils';
23
23
  * @property {(user:object)=>void} setUser - 注销病退回登录界面
24
24
  * @property {object} user - 注销病退回登录界面
25
25
  * @property {()=>Promise<boolean>} kssoLogin - 触发ksso登录
26
- *
26
+ * @property {()=>Promise} updateUserInfo - 更新用户信息
27
27
  */
28
28
 
29
29
 
@@ -67,7 +67,7 @@ const useApp=() =>{
67
67
  if(code){
68
68
  var redirectUri = location.protocol + '//' + location.host + '/#/login';
69
69
  //ksso auth登录
70
- const req = await KSSO_LOGIN({code,redirectUri})
70
+ const req = await KssoLogin({code,redirectUri})
71
71
  if(req?.code==0){
72
72
  const userData = req?.data;
73
73
  setUser(userData);
@@ -89,13 +89,12 @@ const useApp=() =>{
89
89
  return true;
90
90
  }
91
91
  const login=async (username,password)=>{
92
- const req = await LOGIN({username,password});
92
+ const req = await Login({username,password});
93
93
  if(req?.code==0){
94
94
  const userData = req?.data;
95
95
  setUser(userData);
96
96
  setJwt(userData.token);
97
97
  localStorage.setItem('user',JSON.stringify(userData));
98
-
99
98
  let redirect = search.get('redirect');
100
99
  if(redirect){
101
100
  jumpUrl(redirect,{replace:true});
@@ -107,8 +106,16 @@ const useApp=() =>{
107
106
  }
108
107
  return true;
109
108
  }
109
+ const updateUserInfo= async ()=>{
110
+ const req= await GET_USER_INFO();
111
+ if(req?.code==0){
112
+ const userData = req.data;
113
+ setUser(userData);
114
+ localStorage.setItem('user',JSON.stringify(userData));
115
+ }
116
+ }
117
+
110
118
  const logout=async ()=>{
111
- LOGOUT();
112
119
  setUser(null);
113
120
  setJwt('');
114
121
  localStorage.removeItem('user');
@@ -116,7 +123,9 @@ const useApp=() =>{
116
123
  }
117
124
  setLogout(logout);
118
125
 
119
-
126
+ useEffect(()=>{
127
+ console.warn('[user]',user)
128
+ },[user])
120
129
 
121
130
  const setNav=(config)=>{
122
131
  setNavConfig({...nav,...config});
@@ -132,9 +141,10 @@ const useApp=() =>{
132
141
  logout,
133
142
  setUser,
134
143
  user,
135
- kssoLogin
144
+ kssoLogin,
145
+ updateUserInfo
136
146
  }
137
- },[loading,nav,setNav,user,setUser,isLogin,kssoLogin,login]);
147
+ },[loading,nav,setNav,user,setUser,isLogin,kssoLogin,login,updateUserInfo]);
138
148
 
139
149
  return action
140
150
  }
@@ -13,202 +13,85 @@ import { AppstoreOutlined, MailOutlined } from '@ant-design/icons';
13
13
 
14
14
  const MenuRoute=[
15
15
  {
16
- name:'常用管理',
16
+ name:'普通管理',
17
17
  url:'/',
18
18
  children:[
19
19
  {
20
20
  name:'内容管理',
21
21
  icon:<AppstoreOutlined />,
22
- url:'/content',
22
+ url:'/demo',
23
23
  children:[
24
- {name:'剧集管理',url:'/content/video'},
25
- {name:'素材管理',url:'/content/material'},
24
+ {
25
+ name:'内容管理1',
26
+ url:'/demo/page1',
27
+ children:[
28
+ {hideMenu:true,name:'内容管理1详情',routeTemplate:'/demo/page1/detail/:id'},
29
+ ]
30
+ },
31
+ {
32
+ name:'内容管理2',
33
+ url:'/demo/page2',
34
+ msgCount:5,
35
+ children:[
36
+ {hideMenu:true,name:'内容管理2详情',routeTemplate:'/demo/page2/detail/:id'},
37
+ ]
38
+ },
26
39
  ]
27
-
28
40
  },
29
41
  {
30
42
  name:'数据管理',
31
- icon:<MailOutlined />,
32
- url:'/data',
33
- children:[
34
- {primaryId:'orderData',name:'订单数据',msgCount:3,url:'/data/order'},
35
- {name:'用户数据',url:'/data/userData'},
36
- ]
37
- },
38
- {
39
- name:'用户管理',
40
- url:'/user',
41
- children:[
42
- {name:'账户管理',url:'/user/user'},
43
- {name:'客诉管理',url:'/user/suggest'},
44
- ]
45
- },
46
- ]
47
- },
48
- {
49
- name:'权限管理',
50
- url:'/auth',
51
- children:[
52
- {
53
- name:'权限设置',
54
43
  icon:<AppstoreOutlined />,
55
- url:'/auth/config',
44
+ url:'/demo/data',
56
45
  children:[
57
- {name:'角色配置',url:'/auth/config/permission'},
46
+ {
47
+ name:'数据管理1',
48
+ url:'/demo/data/page1',
49
+ children:[
50
+ {hideMenu:true,name:'数据管理1详情',routeTemplate:'/demo/data/page1/detail/:id'},
51
+ ]
52
+ },
53
+ {
54
+ name:'数据管理2',
55
+ url:'/demo/data/page2',
56
+ msgCount:5,
57
+ children:[
58
+ {hideMenu:true,name:'数据管理1详情',routeTemplate:'/demo/data/page2/detail/:id'},
59
+ ]
60
+ },
58
61
  ]
59
62
  },
60
- ]
61
- }
62
- ]
63
-
64
- const MenuRoute2=[
65
- {
66
- name:'数据管理',
67
- icon:'AppstoreOutlined',
68
- url:'/order',
69
- auth:['super'],
70
- children:[
71
- {
72
- name:'数据管理',
73
- // icon:'AppstoreOutlined',
74
- url:'/order',
75
- // children:[
76
- // {name:'剧集管理',url:'/video'},
77
- // {name:'素材管理',url:'/material'},
78
- // ]
79
-
80
- },
81
- ]
82
- },
83
- {
84
- name:'手机管理',
85
- url:'/device',
86
- icon:'AppstoreOutlined',
87
- children:[]
88
- },
89
- {
90
- name:'服务设置',
91
- url:'/service',
92
- icon:'AppstoreOutlined',
93
- children:[
94
- {
95
- name:'账号管理',
96
- url:'/service/account'
97
- },
98
- // {
99
- // name:'账号健康设置',
100
- // url:'/service/accountHealth'
101
- // },
102
- // {
103
- // name:'排班管理',
104
- // url:'/service/workforce'
105
- // },
106
- // {
107
- // name:'表单设置',
108
- // url:'/service/workforce'
109
- // },
110
-
111
- ]
112
-
113
- },
114
- {
115
- name:'内容管理',
116
- url:'/video',
117
- icon:'AppstoreOutlined',
118
- children:[
119
- {
120
- name:'内容管理',
121
- url:'/video',
122
- // children:[
123
- // {name:'剧集管理',url:'/video'},
124
- // {name:'素材管理',url:'/material'},
125
- // ]
126
-
127
- },
128
- // {
129
- // name:'数据管理',
130
- // icon:'AppstoreOutlined',
131
- // children:[
132
- // {name:'订单数据',url:'/order'},
133
- // {name:'用户数据',url:'/userData'},
134
- // ]
135
- // },
136
- // {
137
- // name:'用户管理',
138
- // icon:'UserOutlined',
139
- // url:'/user'
140
- // },
141
- // {
142
- // name:'客诉管理',
143
- // icon:'CustomerServiceOutlined',
144
- // url:'/suggest'
145
- // },
146
- // {
147
- // name:'权限配置',
148
- // icon:'CrownOutlined',
149
- // url:'/permission'
150
- // },
151
- ]
152
- },
153
- {
154
- name: '权限设置',
155
- url: '/authUser',
156
- icon: 'AppstoreOutlined',
157
- children: [
158
- {
159
- name: '用户管理',
160
- url: '/authUser',
161
- },
162
- {
163
- name: '角色管理',
164
- url: '/authRole',
165
- },
166
- {
167
- name: '用户组',
168
- url: '/authUserGroup',
169
- },
63
+
170
64
  ]
171
65
  },
172
66
  {
173
- name:'消息中心',
174
- url:'/message',
175
- icon:'AppstoreOutlined',
67
+ name:'高级管理',
68
+ url:'/demo/admin',
69
+ auth:['admin'],
176
70
  children:[
177
71
  {
178
- primaryId:'myMessage',
179
- name:'我的消息',
180
- // msgCount:MSG_COUNT++,
181
- url:'/message/my',
182
- },
183
- {
184
- name:'消息设置',
185
- url:'/message/config',
72
+ name:'高级管理',
73
+ icon:<AppstoreOutlined />,
74
+ url:'/demo/admin',
186
75
  children:[
187
76
  {
188
- name:'消息查询-2',
189
- url:'/message/config/2',
190
- },
191
- {
192
- name:'消息查询-3',
193
- url:'/message/config/3',
77
+ name:'权限管理1',
78
+ url:'/demo/admin/page1',
79
+ children:[
80
+ {hideMenu:true,name:'权限管理1-详情',routeTemplate:'/demo/admin/page1/detail/:id'},
81
+ ]
194
82
  },
195
- ]
196
- },
197
- {
198
- name:'消息查询',
199
- url:'/message/query',
200
- children:[
201
83
  {
202
- name:'消息查询-设置',
203
- hideMenu:true,
204
- routeTemplate:'/message/query/:type',
84
+ name:'权限管理2',
85
+ url:'/demo/admin/page2',
86
+ msgCount:5,
87
+ children:[
88
+ {hideMenu:true,name:'权限管理2-详情',routeTemplate:'/demo/admin/page2/detail/:id'},
89
+ ]
205
90
  },
206
91
  ]
207
92
  },
208
-
209
93
  ]
210
-
211
- },
94
+ }
212
95
  ]
213
96
 
214
97
 
@@ -218,6 +101,7 @@ const useProvider=() =>{
218
101
 
219
102
  const curLocation =useLocation();
220
103
 
104
+ const [userAuth,setUserAuth]= useState([]);
221
105
  const [topMenu,setTopMenu]=useState([]);
222
106
  const [leftMenu,setLeftMenu]=useState([]);
223
107
 
@@ -227,11 +111,11 @@ const useProvider=() =>{
227
111
  const reload = async ()=>{
228
112
  routeMenu.setSourceMap([...MenuRoute]);
229
113
  }
230
- const getTopMenu=(userAuth=[])=>{
114
+ const getTopMenu=()=>{
231
115
  const list = routeMenu.getMenu(routeMenu.source,userAuth);
232
116
  setTopMenu(list||[]);
233
117
  }
234
- const getLeftMenu=(userAuth=[])=>{
118
+ const getLeftMenu=()=>{
235
119
  const list = routeMenu.getMenu(routeMenu.source,userAuth);
236
120
  let menus= routeMenu.getOpenMenus(curLocation.pathname);
237
121
 
@@ -254,6 +138,7 @@ const useProvider=() =>{
254
138
  routeMenu.setMenuConfig(params);
255
139
  }
256
140
 
141
+
257
142
  useEffect(()=>{
258
143
  let menus= routeMenu.getOpenMenus(curLocation.pathname);
259
144
  let keys=menus.map(item=>item.key);
@@ -263,11 +148,11 @@ const useProvider=() =>{
263
148
  useEffect(()=>{
264
149
  getTopMenu();
265
150
  getLeftMenu();
266
- },[routeMenu.source,curLocation])
151
+ },[routeMenu.source,curLocation,userAuth])
267
152
 
268
153
 
269
154
 
270
- return {leftMenu,topMenu,reload,selectMenus,findMenuData,setMenuConfig}
155
+ return {leftMenu,topMenu,reload,selectMenus,findMenuData,setMenuConfig,setUserAuth}
271
156
  }
272
157
  const App = createContainer(useProvider);
273
158
 
@@ -25,15 +25,8 @@ const delayLoader=(loader)=>{
25
25
  }
26
26
 
27
27
 
28
-
29
- const Video = React.lazy(()=>import('@/pages/video'));
30
- const Suggest = React.lazy(()=>import('@/pages/suggest'));
31
- const Order = React.lazy(()=>import('@/pages/order'));
32
- const Permission = React.lazy(()=>import('@/pages/permission'));
33
- const Material = React.lazy(()=>import('@/pages/material'));
34
-
35
- const User = React.lazy(()=>import('@/pages/user'));
36
- const UserData = React.lazy(()=>import('@/pages/userData'));
28
+ const Page1 = React.lazy(()=>import('@/pages/demo/page1'));
29
+ const Page1Detail = React.lazy(()=>import('@/pages/demo/detail'));
37
30
 
38
31
  import SuperAdminLogin from '@/pages/superAdminLogin';
39
32
 
@@ -54,22 +47,23 @@ export const RouteList = (
54
47
  </ProviderMenu.Provider>
55
48
  }
56
49
  >
57
- <Route path='/' element={<Navigate to="/content/video"></Navigate> } />
58
- <Route path='/content/video' element={<Video />} />
59
- <Route path='/content/material' element={<Material />} />
60
-
61
-
62
- <Route path='/data' element={<Navigate to="/data/order"></Navigate> } />
63
- <Route path='/data/order' element={<Order />} />
64
- <Route path='/data/userData' element={<UserData />} />
65
-
66
- <Route path='/user' element={<Navigate to="/user/user"></Navigate> } />
67
- <Route path='/user/user' element={<User />} />
68
- <Route path='/user/suggest' element={<Suggest />} />
69
-
70
- <Route path='/auth' element={<Navigate to="/auth/config/permission"></Navigate> } />
71
- <Route path='/auth/config/permission' element={<Permission />} />
72
-
50
+ <Route path='/' element={<Navigate to="/demo/page1"></Navigate> } />
51
+ <Route path='/demo/page1' element={<Page1 label='内容管理1' />} />
52
+ <Route path='/demo/page2' element={<Page1 label='内容管理2' />} />
53
+ <Route path='/demo/page1/detail/:id' element={<Page1Detail />} />
54
+ <Route path='/demo/page2/detail/:id' element={<Page1Detail />} />
55
+
56
+
57
+ <Route path='/demo/data/page1' element={<Page1 label='数据管理1' />} />
58
+ <Route path='/demo/data/page2' element={<Page1 label='数据管理2' />} />
59
+ <Route path='/demo/data/page1/detail/:id' element={<Page1Detail />} />
60
+ <Route path='/demo/data/page2/detail/:id' element={<Page1Detail />} />
61
+
62
+ <Route path='/demo/admin' element={<Navigate to="/demo/admin/page1"></Navigate> } />
63
+ <Route path='/demo/admin/page1' element={<Page1 label='权限管理1' />} />
64
+ <Route path='/demo/admin/page2' element={<Page1 label='权限管理2' />} />
65
+ <Route path='/demo/admin/page1/detail/:id' element={<Page1Detail />} />
66
+ <Route path='/demo/admin/page2/detail/:id' element={<Page1Detail />} />
73
67
 
74
68
 
75
69
  </Route>