kn-cli 1.0.48 → 1.0.49

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 (29) hide show
  1. package/package.json +1 -1
  2. package/readme.md +3 -0
  3. package/templates/template_admin/package.json +1 -1
  4. package/templates/template_admin/public/src/components/Auth/index.jsx +1 -1
  5. package/templates/template_admin/public/src/components/TopMenu/index.jsx +1 -1
  6. package/templates/template_admin/public/src/dictionary/index.js +26 -90
  7. package/templates/template_admin/public/src/hooks/index.jsx +4 -2
  8. package/templates/template_admin/public/src/pages/material/index.jsx +74 -3
  9. package/templates/template_admin/public/src/pages/video/index.jsx +56 -3
  10. package/templates/template_admin/public/src/provider/app.jsx +1 -1
  11. package/templates/template_admin/public/src/route.jsx +0 -10
  12. package/templates/template_admin/public/src/services/video.js +33 -0
  13. package/templates/template_app/package.json +1 -1
  14. package/templates/template_app/public/src/_reset.less +1 -1
  15. package/templates/template_app/public/src/dictionary/index.js +26 -90
  16. package/templates/template_app/public/src/pages/dictionary/index.jsx +16 -13
  17. package/templates/template_app/public/src/pages/index.jsx +5 -3
  18. package/templates/template_app/public/src/pages/list/index.jsx +7 -0
  19. package/templates/template_app/public/src/pages/login/index.jsx +0 -1
  20. package/templates/template_app/public/src/provider/app.jsx +22 -0
  21. package/templates/template_app/public/src/services/index.js +34 -1
  22. package/templates/template_admin/public/src/hooks/useNextPage.jsx +0 -89
  23. package/templates/template_admin/public/src/pages/checkLogin/index.jsx +0 -13
  24. package/templates/template_admin/public/src/pages/index.jsx +0 -23
  25. package/templates/template_admin/public/src/pages/index.less +0 -22
  26. package/templates/template_admin/public/src/pages/subHome/index.jsx +0 -12
  27. package/templates/template_admin/public/src/pages/subHome2/index.jsx +0 -12
  28. package/templates/template_admin/public/src/pages/subHome3/index.jsx +0 -12
  29. package/templates/template_app/public/src/hooks/useUpdate.jsx +0 -11
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "kn-cli",
3
- "version": "1.0.48",
3
+ "version": "1.0.49",
4
4
  "description": "",
5
5
  "main": "index.js",
6
6
  "scripts": {
package/readme.md CHANGED
@@ -69,6 +69,9 @@ module.exports = {
69
69
  ```
70
70
 
71
71
  # 更新日志
72
+ * 1.0.49
73
+ 更新app和admin模板,主要是编写了使用案例
74
+
72
75
  * 1.0.48
73
76
  1. cli.config增加rules:{compileNpmPackage:[]}配置,用于配置一些需要参与编译的npm包
74
77
  2. 更新app及后管项目的模板
@@ -10,7 +10,7 @@
10
10
  "antd": "~4.24.8",
11
11
  "axios": "~1.1.3",
12
12
  "moment": "~2.29.4",
13
- "kn-hooks": "~0.0.13",
13
+ "kn-hooks": "~0.0.16",
14
14
  "react": "~17.0.2",
15
15
  "react-dom": "~17.0.2",
16
16
  "react-router": "~6.3.0",
@@ -29,7 +29,7 @@ export const AuthLogin=(props)=>{
29
29
  }else{
30
30
  console.log(`[Auth]检查用户登录态失败`)
31
31
  setPass(false);
32
- navigate('/login');
32
+ navigate('/superAdminLogin');
33
33
  }
34
34
  }
35
35
  useEffect(check,[]);
@@ -113,7 +113,7 @@ const TopMenu=(props)=>{
113
113
  const loadMenu=async ()=>{
114
114
  const isLogin= await app.isLogin();
115
115
  if(!isLogin){
116
- navigate('/login')
116
+ navigate('/superAdminLogin')
117
117
  return;
118
118
  }
119
119
  let reqMenu = await GET_MENU();
@@ -1,103 +1,39 @@
1
1
 
2
2
  import React, { useState, useEffect,useMemo} from 'react';
3
3
  import {GET_USER_TYPE} from '@/services/user';
4
+ import {useDictionary} from 'kn-hooks';
5
+ import ShowToast from '@/components/Toast';
6
+ export const SelectOption=(props)=>{
7
+ const {value}=props;
8
+ const name = props['data-keyname'];
9
+ const onClick=(e)=>{
10
+ ShowToast(`点击option name=${name},value=${value},label=${props.children}`)
11
+ if(props.onClick)props.onClick();
12
+ }
13
+ return <hgroup onClick={onClick} key={value} name={name} value={value}>{props.children}</hgroup>
14
+ }
4
15
 
5
- const bookCreater=options=>{
6
- const {
7
- service,
8
- idKey='value',
9
- titleKey='label',
10
- keyName='key',
11
- defaultTypes=null
12
- }=options;
13
-
14
- return (props)=>{
15
- const [types,setTypes]=useState(defaultTypes||null);
16
-
17
- const init=async ()=>{
18
- let ret = await service();
19
- if(+ret?.code===0){
20
- setTypes(ret.data||[]);
21
- }
22
- }
23
- useEffect(()=>{
24
- if(defaultTypes)return;
25
- init();
26
- },[]);
27
-
28
- const getData=({id,title,key}={})=>{
29
- let name='';
30
- if(id){
31
- name=idKey
32
- }
33
- else if(title){
34
- name=titleKey
35
- }
36
- else if(key){
37
- name=keyName;
38
- }
39
-
40
- for(let i=0;i<types.length;i++){
41
- if(''+types[i][name]===''+id){
42
- return types[i];
43
- }
44
- }
45
- return null;
46
- }
16
+ useDictionary.SetConfig({SelectOption})
47
17
 
48
- const getTitle=(id)=>{
49
- if(types){
50
- for(let i=0;i<types.length;i++){
51
- if(''+types[i][idKey]===''+id){
52
- return types[i][titleKey];
53
- }
54
- }
55
- }
56
- return '';
57
- }
58
- const getId=(title)=>{
59
- if(types){
60
- for(let i=0;i<types.length;i++){
61
- if(''+types[i][titleKey]===''+title){
62
- return types[i][idKey];
63
- }
64
- }
65
- }
66
- return '';
67
- }
68
18
 
69
- const isReady=()=>{
70
- return types!==null;
71
- }
72
- const reload=()=>{
73
- if(defaultTypes)return;
74
- init();
75
- }
76
- const getList=()=>{
77
- let ret=[]
78
- for(let i=0;i<types.length;i++){
79
- let item = types[i];
80
- ret.push({
81
- label:item[titleKey],
82
- value:item[idKey],
83
- key:item[keyName]
84
- })
85
- }
86
- return ret;
19
+ export const useUserType = useDictionary.createDictionary({
20
+ api:GET_USER_TYPE,
21
+ afterApi:(response)=>{
22
+ if(response?.code==0){
23
+ let req= response.data.map(item=>{
24
+ const {label,value:id,key:name}=item;
25
+ return {label,id,name}
26
+ });
27
+ return req;
87
28
  }
88
-
89
-
90
- return {types,getTitle,getId,isReady,reload,getData,getList}
29
+ return [];
91
30
  }
92
- }
31
+ });
93
32
 
94
- export const useUserType = bookCreater({
95
- service:GET_USER_TYPE,
96
- })
97
- export const useTaskState=bookCreater({
33
+ export const useTaskState= useDictionary.createDictionary({
98
34
  defaultTypes:[
99
- {label:'进行中',value:'1',key:'run'},
100
- {label:'已完成',value:'5',key:'complete'},
35
+ {label:'进行中',id:'1',name:'run'},
36
+ {label:'已完成',id:'5',name:'complete'},
101
37
  ]
102
38
  });
103
39
 
@@ -5,14 +5,16 @@ import useDelay from './useDelay';
5
5
  import usePreload from './usePreload';
6
6
  import useSearch from './useSearch';
7
7
  import useUpdate from './useUpdate';
8
- import useNextPage from './useNextPage';
9
8
  import useLoading from './useLoading';
9
+ import {usePagination,usePaginationWithForm} from 'kn-hooks';
10
+
10
11
  export {
12
+ usePaginationWithForm,
13
+ usePagination,
11
14
  useImageLoader,
12
15
  useDelay,
13
16
  usePreload,
14
17
  useSearch,
15
18
  useUpdate,
16
- useNextPage,
17
19
  useLoading
18
20
  }
@@ -1,11 +1,82 @@
1
1
  import React, { useEffect, useState, useRef } from 'react';
2
- import { useParams, useSearchParams,useNavigate } from 'react-router-dom';
2
+ import {usePaginationWithForm} from '@/hooks';
3
+ import {GET_LIST} from '@/services/video';
4
+ import {Table,Pagination,Form,Input,Button} from 'antd';
3
5
 
4
6
  const Page = () => {
5
- const query = useParams();
7
+ const [form] = Form.useForm();
6
8
 
9
+ const request = usePaginationWithForm({
10
+ service:GET_LIST,
11
+ pagination:{pageSize:10},
12
+ form:form
13
+ })
14
+
15
+ useEffect(()=>{
16
+ request.update();
17
+ },[])
18
+
19
+ const columns=[{
20
+ dataIndex:'id',
21
+ title:'id',
22
+ render:(_,record,idx)=>{
23
+ return record.id;
24
+ }
25
+ },{
26
+ dataIndex:'value',
27
+ title:'数据值',
28
+ render:(_,record,idx)=>{
29
+ return record.value||'-'
30
+ }
31
+ }];
32
+
33
+ useEffect(()=>{
34
+ console.log(request)
35
+ },[request])
36
+
37
+ const getDataSource=()=>{
38
+ if(request?.data?.length>0){
39
+ let req=request?.data[request.pagination.current-1]||[];
40
+ return req;
41
+ }
42
+ return [];
43
+ }
44
+
45
+ const onPageChange=(current,pageSize)=>{
46
+ debugger;
47
+ request.update({pagination:{current,pageSize}})
48
+ }
49
+ const onSearch=()=>{
50
+ request.update();
51
+ }
52
+ const onReset=()=>{
53
+ request.reset();
54
+ }
7
55
  return (
8
- <p>material</p>
56
+ <section>
57
+ <section style={{display:'flex'}}>
58
+ <Form form={form} >
59
+ <Form.Item name='keywords' label='关键字'>
60
+ <Input />
61
+ </Form.Item>
62
+ </Form>
63
+ <Button onClick={onSearch} type='primary' style={{margin:'0 12px'}}>查询</Button>
64
+ <Button onClick={onReset}>重置</Button>
65
+ </section>
66
+ <Table
67
+ rowKey={'id'}
68
+ loading={!request?.data?.length>0}
69
+ columns={columns}
70
+ dataSource={getDataSource()}
71
+ pagination={false}
72
+ />
73
+ <Pagination
74
+ current={request?.pagination?.current}
75
+ pageSize={request?.pagination?.pageSize}
76
+ onChange={onPageChange}
77
+ total={request?.pagination?.total}
78
+ />
79
+ </section>
9
80
  )
10
81
  }
11
82
 
@@ -1,11 +1,64 @@
1
1
  import React, { useEffect, useState, useRef } from 'react';
2
- import { useParams, useSearchParams,useNavigate } from 'react-router-dom';
2
+ import {usePagination} from '@/hooks';
3
+ import {GET_LIST} from '@/services/video';
4
+ import {Table,Pagination} from 'antd';
3
5
 
4
6
  const Page = () => {
5
- const query = useParams();
7
+ const request = usePagination({
8
+ service:GET_LIST,
9
+ pagination:{pageSize:10}
10
+ })
6
11
 
12
+ useEffect(()=>{
13
+ request.update();
14
+ },[])
15
+
16
+ const columns=[{
17
+ dataIndex:'id',
18
+ title:'id',
19
+ render:(_,record,idx)=>{
20
+ return record.id;
21
+ }
22
+ },{
23
+ dataIndex:'value',
24
+ title:'数据值',
25
+ render:(_,record,idx)=>{
26
+ return record.value||'-'
27
+ }
28
+ }];
29
+
30
+ useEffect(()=>{
31
+ console.log(request)
32
+ },[request])
33
+
34
+ const getDataSource=()=>{
35
+ if(request?.data?.length>0){
36
+ let req=request?.data[request.pagination.current-1]||[];
37
+ return req;
38
+ }
39
+ return [];
40
+ }
41
+
42
+ const onPageChange=(current,pageSize)=>{
43
+ debugger;
44
+ request.update({pagination:{current,pageSize}})
45
+ }
7
46
  return (
8
- <p>video</p>
47
+ <section>
48
+ <Table
49
+ rowKey={'id'}
50
+ loading={!request?.data?.length>0}
51
+ columns={columns}
52
+ dataSource={getDataSource()}
53
+ pagination={false}
54
+ />
55
+ <Pagination
56
+ current={request?.pagination?.current}
57
+ pageSize={request?.pagination?.pageSize}
58
+ onChange={onPageChange}
59
+ total={request?.pagination?.total}
60
+ />
61
+ </section>
9
62
  )
10
63
  }
11
64
 
@@ -87,7 +87,7 @@ const useApp=() =>{
87
87
  setUser(null);
88
88
  setJwt('');
89
89
  localStorage.removeItem('user');
90
- navigate('/login');
90
+ navigate('/superAdminLogin');
91
91
  }
92
92
  setLogout(logout);
93
93
 
@@ -21,12 +21,6 @@ const delayLoader=(loader)=>{
21
21
  })
22
22
  }
23
23
 
24
- // /*webpackChunkName:'subGroup'*/
25
- const Home = React.lazy(()=>import('@/pages/index.jsx'));
26
- const SubHome = React.lazy(()=>import('@/pages/subHome'));
27
- const SubHome2 = React.lazy(()=>import('@/pages/subHome2'));
28
- const SubHome3 = React.lazy(()=>import('@/pages/subHome3'));
29
- const CheckLogin = React.lazy(()=>import('@/pages/checkLogin'));
30
24
 
31
25
 
32
26
  const Video = React.lazy(()=>import('@/pages/video'));
@@ -66,10 +60,6 @@ export const RouteList = (
66
60
  <Route path='/user' element={<User />} />
67
61
  <Route path='/userData' element={<UserData />} />
68
62
 
69
- {/* <Route path='/home/sub' element={<SubHome />} />
70
- <Route path='/home/sub/:id' element={<Suspense fallback={<PageLoading />}><SubHome2 /></Suspense>} />
71
- <Route path='/home/sub3/:id' element={<SubHome3 />} />
72
- <Route path='/checkLogin' element={<AuthLogin><CheckLogin /></AuthLogin>} /> */}
73
63
  </Route>
74
64
  </Route>
75
65
  </Routes>
@@ -0,0 +1,33 @@
1
+
2
+
3
+ export function GET_LIST(params={
4
+ current:1,
5
+ pageSize:10,
6
+ keywords:''
7
+ }){
8
+ const {current,pageSize,keywords='-'}=params;
9
+ let list=[];
10
+ for(let i=0;i<200;i++){
11
+ list.push({
12
+ id:i,
13
+ value:`item-${i}-${keywords}`,
14
+ })
15
+ }
16
+ let total=200;
17
+ let startIdx = (current-1)*pageSize;
18
+ let data = list.splice(startIdx,pageSize);
19
+ let req= {
20
+ code:0,
21
+ data,
22
+ page:{
23
+ current,
24
+ pageSize,
25
+ total
26
+ }
27
+ };
28
+ return new Promise(resolve=>{
29
+ setTimeout(()=>{
30
+ resolve(req)
31
+ },500)
32
+ })
33
+ }
@@ -9,7 +9,7 @@
9
9
  "dependencies": {
10
10
  "antd-mobile": "~5.28.0",
11
11
  "axios": "~1.1.3",
12
- "kn-hooks": "~0.0.13",
12
+ "kn-hooks": "~0.0.16",
13
13
  "moment": "~2.29.4",
14
14
  "react": "~17.0.2",
15
15
  "react-dom": "~17.0.2",
@@ -64,7 +64,7 @@ a,div,p,span,section,hgroup{
64
64
 
65
65
  * {
66
66
  font-family: -apple-system, BlinkMacSystemFont, 'Segoe UI', 'PingFang SC', 'Hiragino Sans GB', 'Microsoft YaHei', 'Helvetica Neue', Helvetica, Arial, sans-serif, 'Apple Color Emoji', 'Segoe UI Emoji', 'Segoe UI Symbol';
67
- position: relative;
67
+ // position: relative;
68
68
  -webkit-tap-highlight-color: rgba(0, 0, 0, 0);
69
69
  -webkit-text-size-adjust: none;
70
70
  -webkit-box-sizing: border-box;
@@ -1,103 +1,39 @@
1
1
 
2
2
  import React, { useState, useEffect,useMemo} from 'react';
3
3
  import {GET_USER_TYPE} from '@/services/user';
4
+ import {useDictionary} from 'kn-hooks';
5
+ import ShowToast from '@/components/Toast';
6
+ export const SelectOption=(props)=>{
7
+ const {value}=props;
8
+ const name = props['data-keyname'];
9
+ const onClick=(e)=>{
10
+ ShowToast(`点击option name=${name},value=${value},label=${props.children}`)
11
+ if(props.onClick)props.onClick();
12
+ }
13
+ return <hgroup onClick={onClick} key={value} name={name} value={value}>{props.children}</hgroup>
14
+ }
4
15
 
5
- const bookCreater=options=>{
6
- const {
7
- service,
8
- idKey='value',
9
- titleKey='label',
10
- keyName='key',
11
- defaultTypes=null
12
- }=options;
13
-
14
- return (props)=>{
15
- const [types,setTypes]=useState(defaultTypes||null);
16
-
17
- const init=async ()=>{
18
- let ret = await service();
19
- if(+ret?.code===0){
20
- setTypes(ret.data||[]);
21
- }
22
- }
23
- useEffect(()=>{
24
- if(defaultTypes)return;
25
- init();
26
- },[]);
27
-
28
- const getData=({id,title,key}={})=>{
29
- let name='';
30
- if(id){
31
- name=idKey
32
- }
33
- else if(title){
34
- name=titleKey
35
- }
36
- else if(key){
37
- name=keyName;
38
- }
39
-
40
- for(let i=0;i<types.length;i++){
41
- if(''+types[i][name]===''+id){
42
- return types[i];
43
- }
44
- }
45
- return null;
46
- }
16
+ useDictionary.SetConfig({SelectOption})
47
17
 
48
- const getTitle=(id)=>{
49
- if(types){
50
- for(let i=0;i<types.length;i++){
51
- if(''+types[i][idKey]===''+id){
52
- return types[i][titleKey];
53
- }
54
- }
55
- }
56
- return '';
57
- }
58
- const getId=(title)=>{
59
- if(types){
60
- for(let i=0;i<types.length;i++){
61
- if(''+types[i][titleKey]===''+title){
62
- return types[i][idKey];
63
- }
64
- }
65
- }
66
- return '';
67
- }
68
18
 
69
- const isReady=()=>{
70
- return types!==null;
71
- }
72
- const reload=()=>{
73
- if(defaultTypes)return;
74
- init();
75
- }
76
- const getList=()=>{
77
- let ret=[]
78
- for(let i=0;i<types.length;i++){
79
- let item = types[i];
80
- ret.push({
81
- label:item[titleKey],
82
- value:item[idKey],
83
- key:item[keyName]
84
- })
85
- }
86
- return ret;
19
+ export const useUserType = useDictionary.createDictionary({
20
+ api:GET_USER_TYPE,
21
+ afterApi:(response)=>{
22
+ if(response?.code==0){
23
+ let req= response.data.map(item=>{
24
+ const {label,value:id,key:name}=item;
25
+ return {label,id,name}
26
+ });
27
+ return req;
87
28
  }
88
-
89
-
90
- return {types,getTitle,getId,isReady,reload,getData,getList}
29
+ return [];
91
30
  }
92
- }
31
+ });
93
32
 
94
- export const useUserType = bookCreater({
95
- service:GET_USER_TYPE,
96
- })
97
- export const useTaskState=bookCreater({
33
+ export const useTaskState= useDictionary.createDictionary({
98
34
  defaultTypes:[
99
- {label:'进行中',value:'1',key:'run'},
100
- {label:'已完成',value:'5',key:'complete'},
35
+ {label:'进行中',id:'1',name:'run'},
36
+ {label:'已完成',id:'5',name:'complete'},
101
37
  ]
102
38
  });
103
39
 
@@ -1,25 +1,28 @@
1
- import React, { useEffect, useState, useRef } from 'react';
1
+ import React, { useEffect } from 'react';
2
2
  import {List} from 'antd-mobile';
3
- import {useUserType} from '@/dictionary';
4
- import ShowToast from '@/components/Toast';
5
-
6
-
3
+ import {useUserType,useTaskState} from '@/dictionary';
7
4
  import styles from './index.less';
5
+ import ProviderApp from '@/provider/app';
8
6
 
9
7
  const Page = () => {
8
+ const providerApp = ProviderApp.useContainer();
9
+
10
10
  const emUserType= useUserType();
11
+ const emUseTaskState = useTaskState();
11
12
 
13
+ useEffect(()=>{
14
+ providerApp.setNav({title:'字典工具'})
15
+ },[])
12
16
  return (
13
17
  <section id="wall" className={styles.wall}>
14
- <List header='字典'>
18
+ <List header='emUseTaskState'>
19
+ {
20
+ emUseTaskState.isReady()&&emUseTaskState.selectOptions
21
+ }
22
+ </List>
23
+ <List header='emUserType'>
15
24
  {
16
- emUserType.isReady()&&emUserType.getList().map(item=>{
17
- return <List.Item key={item.key} data-value={item.value} onClick={ (e)=>{
18
- let value = e.currentTarget.getAttribute('data-value');
19
- let item = emUserType.getData({id:value});
20
- ShowToast(`${JSON.stringify(item)}`)
21
- }}>{item.label}</List.Item>
22
- })
25
+ emUserType.isReady()&&emUserType.selectOptions
23
26
  }
24
27
  </List>
25
28
 
@@ -1,4 +1,4 @@
1
- import React from 'react';
1
+ import React, { useEffect } from 'react';
2
2
  import {PullToRefresh ,List} from 'antd-mobile';
3
3
  import {useLoading} from '@/hooks';
4
4
  import { useParams, useSearchParams,useNavigate } from 'react-router-dom';
@@ -17,7 +17,9 @@ const Page = () => {
17
17
  const [search] = useSearchParams();
18
18
  const loading = useLoading();
19
19
  const loadingCanTouch = useLoading({canTouch:true});
20
-
20
+ useEffect(()=>{
21
+ providerApp.setNav({title:'APP演示'})
22
+ },[])
21
23
  return (
22
24
  <section id="wall" className={styles.wall}>
23
25
  <PullToRefresh className={styles.wrap}
@@ -92,7 +94,7 @@ const Page = () => {
92
94
  </List>
93
95
 
94
96
  <List header='其它'>
95
- <List.Item key='dictionary' onClick={()=>{navigate('/dictionary')}}>字典</List.Item>
97
+ <List.Item key='dictionary' onClick={()=>{navigate('/dictionary')}}>字典工具</List.Item>
96
98
  </List>
97
99
 
98
100
  </PullToRefresh>
@@ -2,17 +2,24 @@ import React, { useEffect, useState, useRef } from 'react';
2
2
  import {PullToRefresh ,InfiniteScroll,List} from 'antd-mobile';
3
3
  import {usePagination,useLoading} from '@/hooks';
4
4
  import {GET_USER_LIST} from '@/services/user';
5
+ import ProviderApp from '@/provider/app';
5
6
 
6
7
 
7
8
  import styles from './index.less';
8
9
 
9
10
  const Page = () => {
11
+ const providerApp = ProviderApp.useContainer();
12
+
10
13
  const request = usePagination({
11
14
  service:GET_USER_LIST,
12
15
  })
13
16
  const [list,setList]= useState([]);
14
17
  const loading = useLoading();
15
18
 
19
+ useEffect(()=>{
20
+ providerApp.setNav({title:'下拉刷新和滚动加载'})
21
+ },[])
22
+
16
23
 
17
24
  useEffect(()=>{
18
25
  let ret=[];
@@ -7,7 +7,6 @@ const Page = () => {
7
7
  const navigate= useNavigate();
8
8
  const [search] = useSearchParams();
9
9
  const providerApp = ProviderApp.useContainer();
10
-
11
10
  const kssoLogin=async ()=>{
12
11
  let code = search.get('code');
13
12
  if(code){
@@ -1,7 +1,16 @@
1
+ /**
2
+ * @module ProviderApp
3
+ */
1
4
  import { useState,useMemo } from 'react';
2
5
  import { createContainer } from "unstated-next"
3
6
  import {useDelay} from '@/hooks';
4
7
  import {logout as apiLogout} from '@/services';
8
+
9
+ /**
10
+ * @function
11
+ * @description app状态管理的Provider
12
+ * @returns {UseAppResult}
13
+ */
5
14
  const useApp=() =>{
6
15
  const [loading,setLoading] = useState(true);
7
16
  const [nav,setNavConfig] = useState({visible:true,syncDocumentTitle:false});
@@ -44,6 +53,19 @@ const useApp=() =>{
44
53
  return action
45
54
  }
46
55
 
56
+ /**
57
+ * @typedef UseAppResult
58
+ * @property {boolean} loading=true - loading状态
59
+ * @property {function} setLoading - 设置loading状态
60
+ * @property {Promise<boolean>} isLogin - 用户是否已登录
61
+ * @property {Promise<boolean>} login - 触发登录
62
+ * @property {Promise<boolean>} logout - 触发注销
63
+ * @property {Object} nav={visible:true} - 导航栏配置
64
+ * @property {function} setNav - 设置导航栏配置
65
+ * @property {function} setUser - 设置用户信息
66
+ * @property {Object} user=null - 用户信息
67
+ */
68
+
47
69
  const App = createContainer(useApp);
48
70
 
49
71
  export default App;
@@ -1,3 +1,6 @@
1
+ /**
2
+ * @module Services
3
+ */
1
4
  import Axios from 'axios';
2
5
  import qs from 'qs';
3
6
  const axios = Axios.create();
@@ -82,8 +85,23 @@ axios.interceptors.response.use(
82
85
 
83
86
 
84
87
 
88
+ /**
89
+ * @typedef RequestOptions
90
+ * @description 发送请求的扩展信息
91
+ * @property {number|boolean} ttl=false - 接口缓存周期,开启后默认为2秒,ttl单位为毫秒
92
+ * @property {string|boolean} noInterceptors=false - 关闭拦截类型,'all'为关闭包括401、403在内的所有异常,默认情况下只拦截response.code不为0的情况
93
+ *
94
+ */
85
95
 
86
96
  let buffer = {};
97
+ /**
98
+ * @function
99
+ * @description 发送一个GET请求
100
+ * @param {string} url - 请求地址
101
+ * @param {Object} param - 请求的参数
102
+ * @param {RequestOptions} options - 扩展参数
103
+ * @returns {Promise<Object>}
104
+ */
87
105
  export async function GET_DEFAULT(url, param, options) {
88
106
  if (param) param = qs.stringify(param, { arrayFormat: 'indices' });
89
107
  let now = Date.now();
@@ -116,6 +134,10 @@ export async function GET_DEFAULT(url, param, options) {
116
134
  return response && response.data ? response.data : null;
117
135
  }
118
136
 
137
+ /**
138
+ * @function
139
+ * @description 带允许cookie跨域的GET_DEFAULT
140
+ */
119
141
  export async function GET_DEFAULT_CROSS(url, param) {
120
142
  if (param) param = qs.stringify(param, { arrayFormat: 'indices' });
121
143
 
@@ -129,6 +151,14 @@ export async function GET_DEFAULT_CROSS(url, param) {
129
151
  return response && response.data ? response.data : null;
130
152
  }
131
153
 
154
+ /**
155
+ * @function
156
+ * @description 发送一个POST请求
157
+ * @param {string} url - 请求地址
158
+ * @param {Object} param - 请求的参数
159
+ * @param {RequestOptions} options - 扩展参数
160
+ * @returns {Promise<Object>}
161
+ */
132
162
  export async function POST_DEFAULT(url, params, method, options) {
133
163
  let data = params;
134
164
  // if (params) params = qs.stringify(params, { arrayFormat: 'indices' });
@@ -147,7 +177,10 @@ export async function POST_DEFAULT(url, params, method, options) {
147
177
  });
148
178
  return response && response.data ? response.data : null;
149
179
  }
150
-
180
+ /**
181
+ * @function
182
+ * @description 带cookie跨域的POST_DEFAULT
183
+ */
151
184
  export async function POST_DEFAULT_CROSS(url, params) {
152
185
  let data = {};
153
186
  // if (params) params = qs.stringify(params, { arrayFormat: 'indices' });
@@ -1,89 +0,0 @@
1
- import { useState,useRef } from 'react';
2
-
3
-
4
- const DEFAULT_PAGE_SIZE=20;
5
- const DEFAULT_PAGE_CURRENT=1;
6
-
7
- const useNextPage=(props)=>{
8
- const [search,setSearch] = useState(props.initSearch||{});
9
- const [service] = useState(()=>props.service);
10
- const [beforeService] = useState(()=>props.beforeService);
11
- const [pagination,setPagination] = useState(()=>{
12
- let temp = {
13
- current:DEFAULT_PAGE_CURRENT,
14
- pageSize:DEFAULT_PAGE_SIZE,
15
- total:0,
16
- startIdx:0,
17
- more:false,
18
- ...props.pagination
19
- };
20
- temp.startIdx = (temp.current-1)*temp.pageSize;
21
- return temp;
22
- });
23
- const resetCount = useRef(0);
24
- const [data,setData] = useState([]);
25
-
26
- const reset= async ()=>{
27
- resetCount.current++;
28
- let page = {...pagination};
29
- page.current =1;
30
- return refresh({pageValue:page})
31
- }
32
- const nextPage= async ()=>{
33
- if(!pagination.more){
34
- return false;
35
- }
36
- let page = {...pagination};
37
- page.current= +page.current+1;
38
- return refresh({pageValue:page})
39
- }
40
- const refresh= async ({searchValue,pageValue}={})=>{
41
- searchValue = searchValue || search;
42
- pageValue = pageValue || pagination;
43
- searchValue = {...search,...searchValue};
44
- pageValue = {...pagination,...pageValue};
45
-
46
- const {current,pageSize} = pageValue;
47
- let params = {...searchValue,current:current,pageSize:pageSize};
48
- if(beforeService)params=beforeService(params);
49
- if(!params)return;
50
-
51
- setSearch(searchValue);
52
-
53
- let ret = await service(params);
54
- if(ret?.code==0){
55
- const {page} = ret.data;
56
- const current= +(page.pageNum||DEFAULT_PAGE_CURRENT);
57
- const pageSize= +(page.pageSize||DEFAULT_PAGE_SIZE);
58
- const total= +page.total;
59
- const startIdx= (current-1)*pageSize;
60
- const more = current*pageSize<total;
61
- setPagination({
62
- current,pageSize,total,startIdx,more
63
- })
64
- if(ret.data.list){
65
- ret.data.list.map(item=>{
66
- item.resetCount = resetCount.current;
67
- })
68
- let newData = current==1?[]:data;
69
- newData[current-1] = ret.data.list;
70
- setData([...newData])
71
- }
72
- }
73
- return ret;
74
- }
75
-
76
-
77
- return {
78
- pagination,
79
- search,
80
- setSearch,
81
- refresh,
82
- reset,
83
- nextPage,
84
- data,
85
- };
86
-
87
- }
88
-
89
- export default useNextPage;
@@ -1,13 +0,0 @@
1
- import React, { useEffect } from 'react';
2
- import ProviderApp from '@/provider/app';
3
-
4
- const Page = () => {
5
- const providerApp = ProviderApp.useContainer();
6
- return (
7
- <div>
8
- <p>当前用户态:{JSON.stringify(providerApp.user)}</p>
9
- </div>
10
- )
11
- }
12
-
13
- export default Page;
@@ -1,23 +0,0 @@
1
- import React, { useEffect, useState, useRef } from 'react';
2
- import { useParams, useSearchParams,useNavigate } from 'react-router-dom';
3
-
4
- import ProviderApp from '@/provider/app';
5
-
6
- import {Button} from 'antd';
7
-
8
- import styles from './index.less';
9
-
10
- const Page = () => {
11
- const navigate= useNavigate();
12
- const providerApp = ProviderApp.useContainer();
13
- const query = useParams();
14
- const [search] = useSearchParams();
15
-
16
- return (
17
- <section id="wall" className={styles.wall}>
18
- <Button type='primary'>i am home {JSON.stringify(query)}</Button>
19
- </section>
20
- )
21
- }
22
-
23
- export default Page;
@@ -1,22 +0,0 @@
1
-
2
- .wall{
3
- width: 100%;
4
- height: 100%;
5
- overflow-y: auto;
6
- }
7
- .wrap{
8
- height:100%;
9
- width:100%;
10
- }
11
- .item{
12
- font-size: 40px;
13
- }
14
- .tips{
15
- font-size: 36px;
16
- }
17
-
18
- .btnGroup{
19
- :global(.adm-button ){
20
- margin-bottom: 24px;
21
- }
22
- }
@@ -1,12 +0,0 @@
1
- import React, { useEffect, useState, useRef } from 'react';
2
- import { useParams, useSearchParams,useNavigate } from 'react-router-dom';
3
-
4
- const Page = () => {
5
- const query = useParams();
6
-
7
- return (
8
- <p>subHome1 {JSON.stringify(query)}</p>
9
- )
10
- }
11
-
12
- export default Page;
@@ -1,12 +0,0 @@
1
- import React, { useEffect, useState, useRef } from 'react';
2
- import { useParams, useSearchParams,useNavigate } from 'react-router-dom';
3
-
4
- const Page = () => {
5
- const query = useParams();
6
-
7
- return (
8
- <p>subHome2 {JSON.stringify(query)}</p>
9
- )
10
- }
11
-
12
- export default Page;
@@ -1,12 +0,0 @@
1
- import React, { useEffect, useState, useRef } from 'react';
2
- import { useParams, useSearchParams,useNavigate } from 'react-router-dom';
3
-
4
- const Page = () => {
5
- const query = useParams();
6
-
7
- return (
8
- <p>subHome3 {JSON.stringify(query)}</p>
9
- )
10
- }
11
-
12
- export default Page;
@@ -1,11 +0,0 @@
1
- import { useState, useMemo } from 'react';
2
-
3
- const useUpdate=()=>{
4
- const [count,setCount] = useState(1);
5
- const action = useMemo(()=>{
6
- return [count,()=>{setCount(count+1)}]
7
- },[count,setCount])
8
- return action;
9
- }
10
-
11
- export default useUpdate;