kn-cli 1.0.3 → 1.0.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/build/package.json +1 -1
- package/build/webpack.config.js +4 -3
- package/package.json +1 -1
- package/readme.md +10 -32
- package/templates/template_app/frontend_build.sh +16 -3
- package/templates/template_app/package.json +9 -7
- package/templates/template_app/public/src/_reset.less +2 -7
- package/templates/template_app/public/src/_variable.less +5 -0
- package/templates/template_app/public/src/assets/images/loading.svg +22 -34
- package/templates/template_app/public/src/components/Auth/index.jsx +44 -0
- package/templates/template_app/public/src/components/Header/index.jsx +44 -10
- package/templates/template_app/public/src/components/Header/index.less +33 -7
- package/templates/template_app/public/src/components/Layout/App/index.jsx +4 -3
- package/templates/template_app/public/src/components/Layout/App/index.less +1 -5
- package/templates/template_app/public/src/components/Layout/Provider/index.jsx +12 -0
- package/templates/template_app/public/src/components/Layout/index.jsx +2 -1
- package/templates/template_app/public/src/components/Page/PageLoading/index.jsx +13 -3
- package/templates/template_app/public/src/components/Page/PageLoading/index.less +4 -4
- package/templates/template_app/public/src/dictionary/index.js +4 -1
- package/templates/template_app/public/src/hooks/index.jsx +4 -3
- package/templates/template_app/public/src/hooks/useLoading.jsx +42 -0
- package/templates/template_app/public/src/hooks/useNextPage.jsx +89 -0
- package/templates/template_app/public/src/index.jsx +2 -0
- package/templates/template_app/public/src/mock/index.js +1 -0
- package/templates/template_app/public/src/mock/user.js +47 -1
- package/templates/template_app/public/src/mock/utils.js +10 -0
- package/templates/template_app/public/src/pages/index.jsx +160 -1
- package/templates/template_app/public/src/pages/index.less +22 -0
- package/templates/template_app/public/src/pages/login/index.jsx +30 -0
- package/templates/template_app/public/src/pages/user/index.jsx +13 -0
- package/templates/template_app/public/src/provider/app.jsx +34 -3
- package/templates/template_app/public/src/route.jsx +13 -4
- package/templates/template_app/public/src/services/index.js +14 -34
- package/templates/template_app/public/src/services/user.js +13 -0
- package/templates/template_app/public/static/kssoLogin.html +22 -0
- package/templates/template_app/readme.md +2 -2
- package/templates/template_app/webpack.api.js +3 -3
- package/templates/template_app/public/pluginjs/swiper-bundle.min.css +0 -13
- package/templates/template_app/public/pluginjs/swiper-bundle.min.js +0 -14
|
@@ -0,0 +1,89 @@
|
|
|
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,6 +1,6 @@
|
|
|
1
1
|
import {waitTime,REP_SUCCESS} from './utils.js';
|
|
2
2
|
import qs from 'qs';
|
|
3
|
-
|
|
3
|
+
import {GET_REQUEST} from './utils';
|
|
4
4
|
async function GET_USER(req,res){
|
|
5
5
|
const query = qs.parse(req.url.split('?')[1]);
|
|
6
6
|
const {name} = query;
|
|
@@ -19,6 +19,52 @@ async function SET_USER(req,res){
|
|
|
19
19
|
}
|
|
20
20
|
}
|
|
21
21
|
|
|
22
|
+
async function GET_USER_LIST(req,res){
|
|
23
|
+
const {current,pageSize} = GET_REQUEST(req,res);
|
|
24
|
+
const MAX_TOTAL=98;
|
|
25
|
+
let data=[];
|
|
26
|
+
let idx=(current-1)*pageSize;
|
|
27
|
+
|
|
28
|
+
for(let i=0;i<pageSize;i++){
|
|
29
|
+
if(idx>=MAX_TOTAL)break;
|
|
30
|
+
data.push({
|
|
31
|
+
name:`${idx++}小朋友`
|
|
32
|
+
})
|
|
33
|
+
}
|
|
34
|
+
return {
|
|
35
|
+
code:0,
|
|
36
|
+
data:{
|
|
37
|
+
list:data,
|
|
38
|
+
page:{
|
|
39
|
+
pageNum:current,
|
|
40
|
+
pageSize:pageSize,
|
|
41
|
+
total:MAX_TOTAL
|
|
42
|
+
}
|
|
43
|
+
}
|
|
44
|
+
}
|
|
45
|
+
}
|
|
46
|
+
|
|
47
|
+
async function GET_USER_TYPE(req,res){
|
|
48
|
+
let data=[];
|
|
49
|
+
for(let i=0;i<10;i++){
|
|
50
|
+
data.push({
|
|
51
|
+
label:`标题${i}`,
|
|
52
|
+
value:i,
|
|
53
|
+
key:`title${i}`
|
|
54
|
+
})
|
|
55
|
+
}
|
|
56
|
+
return {
|
|
57
|
+
code:0,
|
|
58
|
+
data:data
|
|
59
|
+
}
|
|
60
|
+
}
|
|
61
|
+
|
|
62
|
+
|
|
63
|
+
|
|
64
|
+
|
|
22
65
|
export default {
|
|
66
|
+
'/userType':{get:GET_USER_TYPE},
|
|
67
|
+
'/userList':{get:GET_USER_LIST},
|
|
23
68
|
'/user':{get:GET_USER,post:SET_USER},
|
|
69
|
+
|
|
24
70
|
}
|
|
@@ -1,3 +1,5 @@
|
|
|
1
|
+
import qs from 'qs';
|
|
2
|
+
|
|
1
3
|
export const waitTime = (time = 500) => {
|
|
2
4
|
return new Promise((resolve) => {
|
|
3
5
|
setTimeout(() => {
|
|
@@ -21,3 +23,11 @@ export const REP_500=async (req,res)=>{
|
|
|
21
23
|
// console.log(res);
|
|
22
24
|
return res.status(500).send({})
|
|
23
25
|
}
|
|
26
|
+
|
|
27
|
+
|
|
28
|
+
export const GET_REQUEST=(req)=>{
|
|
29
|
+
if(req.type=='GET'){
|
|
30
|
+
return qs.parse(req.url.split('?')[1]);
|
|
31
|
+
}
|
|
32
|
+
return JSON.parse(req.body);
|
|
33
|
+
}
|
|
@@ -1,8 +1,167 @@
|
|
|
1
1
|
import React, { useEffect, useState, useRef } from 'react';
|
|
2
|
+
import {PullToRefresh ,InfiniteScroll,List} from 'antd-mobile';
|
|
3
|
+
import {useNextPage,useLoading} from '@/hooks';
|
|
4
|
+
import {GET_USER_LIST} from '@/services/user';
|
|
5
|
+
import { useParams, useSearchParams,useNavigate } from 'react-router-dom';
|
|
6
|
+
|
|
7
|
+
import ProviderApp from '@/provider/app';
|
|
8
|
+
import moment from 'moment';
|
|
9
|
+
import ShowToast from '@/components/Toast';
|
|
10
|
+
import {useUserType} from '@/dictionary';
|
|
11
|
+
import {AuthShow} from '@/components/Auth';
|
|
12
|
+
|
|
2
13
|
import styles from './index.less';
|
|
3
14
|
|
|
4
15
|
const Page = () => {
|
|
5
|
-
|
|
16
|
+
const navigate= useNavigate();
|
|
17
|
+
const providerApp = ProviderApp.useContainer();
|
|
18
|
+
const query = useParams();
|
|
19
|
+
const [search] = useSearchParams();
|
|
20
|
+
const request = useNextPage({
|
|
21
|
+
service:GET_USER_LIST,
|
|
22
|
+
})
|
|
23
|
+
const [list,setList]= useState([]);
|
|
24
|
+
const loading = useLoading();
|
|
25
|
+
const loadingCanTouch = useLoading({canTouch:true});
|
|
26
|
+
|
|
27
|
+
const emUserType= useUserType();
|
|
28
|
+
|
|
29
|
+
useEffect(()=>{
|
|
30
|
+
let ret=[];
|
|
31
|
+
request?.data?.forEach(page=>{
|
|
32
|
+
try{
|
|
33
|
+
ret = [...ret,...page];
|
|
34
|
+
}catch(ex){
|
|
35
|
+
console.error(ex)
|
|
36
|
+
debugger;
|
|
37
|
+
}
|
|
38
|
+
})
|
|
39
|
+
setList(ret);
|
|
40
|
+
|
|
41
|
+
},[request.data])
|
|
42
|
+
|
|
43
|
+
|
|
44
|
+
const onReset= async ()=>{
|
|
45
|
+
return request.reset();
|
|
46
|
+
}
|
|
47
|
+
|
|
48
|
+
const onNextPage= async ()=>{
|
|
49
|
+
if(loading.loading>0){
|
|
50
|
+
return;
|
|
51
|
+
}
|
|
52
|
+
loading.setLoading(true)
|
|
53
|
+
let dom = document.querySelector('#wall');
|
|
54
|
+
dom.scrollTop-=200;
|
|
55
|
+
await request.nextPage();
|
|
56
|
+
loading.setLoading(false)
|
|
57
|
+
return true;
|
|
58
|
+
}
|
|
59
|
+
const refresh=async ()=>{
|
|
60
|
+
loading.setLoading(true)
|
|
61
|
+
await request.refresh();
|
|
62
|
+
loading.setLoading(false);
|
|
63
|
+
}
|
|
64
|
+
useEffect(()=>{
|
|
65
|
+
refresh();
|
|
66
|
+
},[]);
|
|
67
|
+
|
|
68
|
+
return (
|
|
69
|
+
<section id="wall" className={styles.wall}>
|
|
70
|
+
<PullToRefresh className={styles.wrap}
|
|
71
|
+
onRefresh={async () => {
|
|
72
|
+
await onReset();
|
|
73
|
+
return true;
|
|
74
|
+
}}
|
|
75
|
+
>
|
|
76
|
+
<List header='导航栏'>
|
|
77
|
+
<List.Item key='navShow' onClick={()=>{
|
|
78
|
+
providerApp.setNav({visible:!providerApp.nav.visible});
|
|
79
|
+
}}>隐藏/隐藏导航栏</List.Item>
|
|
80
|
+
|
|
81
|
+
<List.Item key='navTitle' onClick={()=>{
|
|
82
|
+
providerApp.setNav({title:moment().format('YYYY-MM-DD HH:mm:ss')});
|
|
83
|
+
}}>修改标题</List.Item>
|
|
84
|
+
|
|
85
|
+
<List.Item key='navSyncTitle' onClick={()=>{
|
|
86
|
+
providerApp.setNav({syncDocumentTitle:!providerApp.nav.syncDocumentTitle});
|
|
87
|
+
}}>开启/关闭同步导航栏和网页标签标题</List.Item>
|
|
88
|
+
|
|
89
|
+
</List>
|
|
90
|
+
|
|
91
|
+
<List header='路由'>
|
|
92
|
+
<List.Item key='query'>动态路由id:{query.id}</List.Item>
|
|
93
|
+
<List.Item key='search'>url search:{search.toString()}</List.Item>
|
|
94
|
+
</List>
|
|
95
|
+
|
|
96
|
+
<List header='登录态'>
|
|
97
|
+
<List.Item key='loginStatus'>登录状态:{providerApp?.user?.id?`已登录:${providerApp?.user?.id}`:'未登录'}</List.Item>
|
|
98
|
+
{
|
|
99
|
+
providerApp?.user?.id?
|
|
100
|
+
<List.Item key='logout' onClick={()=>{
|
|
101
|
+
providerApp.logout()}
|
|
102
|
+
}>注销</List.Item>:
|
|
103
|
+
<List.Item key='login' onClick={async ()=>{
|
|
104
|
+
loading.setLoading(true);
|
|
105
|
+
await providerApp.login();
|
|
106
|
+
loading.setLoading(false)
|
|
107
|
+
}
|
|
108
|
+
}>登录</List.Item>
|
|
109
|
+
}
|
|
110
|
+
<List.Item key='toUserPage' onClick={()=>{
|
|
111
|
+
navigate('/user');
|
|
112
|
+
}}>前往用户信息页面</List.Item>
|
|
113
|
+
|
|
114
|
+
<AuthShow name='normal'><List.Item key='user'>用户登录完才能看到这行</List.Item></AuthShow>
|
|
115
|
+
</List>
|
|
116
|
+
|
|
117
|
+
<List header='消息框'>
|
|
118
|
+
<List.Item key='toast' onClick={()=>{ShowToast(`现在时间:${moment().format('HH:mm:ss')}`)}}>Toast</List.Item>
|
|
119
|
+
</List>
|
|
120
|
+
|
|
121
|
+
<List header='Loading'>
|
|
122
|
+
<List.Item key='loading' onClick={async ()=>{
|
|
123
|
+
loading.setLoading(true);
|
|
124
|
+
await new Promise(resolve=>{
|
|
125
|
+
setTimeout(resolve,3000);
|
|
126
|
+
});
|
|
127
|
+
loading.setLoading(false);
|
|
128
|
+
}}>打开全局loading-持续3秒(阻止其它交互)</List.Item>
|
|
129
|
+
<List.Item key='loadingCanTouch' onClick={async ()=>{
|
|
130
|
+
loadingCanTouch.setLoading(true);
|
|
131
|
+
await new Promise(resolve=>{
|
|
132
|
+
setTimeout(resolve,3000);
|
|
133
|
+
});
|
|
134
|
+
loadingCanTouch.setLoading(false);
|
|
135
|
+
}}>打开全局loading-持续3秒(不阻止交互)</List.Item>
|
|
136
|
+
</List>
|
|
137
|
+
|
|
138
|
+
<List header='字典'>
|
|
139
|
+
{
|
|
140
|
+
emUserType.isReady()&&emUserType.getList().map(item=>{
|
|
141
|
+
return <List.Item key={item.key} data-value={item.value} onClick={ (e)=>{
|
|
142
|
+
let value = e.currentTarget.getAttribute('data-value');
|
|
143
|
+
let item = emUserType.getData({id:value});
|
|
144
|
+
ShowToast(`${JSON.stringify(item)}`)
|
|
145
|
+
}}>{item.label}</List.Item>
|
|
146
|
+
})
|
|
147
|
+
}
|
|
148
|
+
</List>
|
|
149
|
+
|
|
150
|
+
<List header='下拉刷新,滚动加载案例'>
|
|
151
|
+
{
|
|
152
|
+
list.map((item,idx)=>{
|
|
153
|
+
return (
|
|
154
|
+
<List.Item key={item.name}>{item.name}-{item.resetCount}</List.Item>
|
|
155
|
+
)
|
|
156
|
+
})
|
|
157
|
+
}
|
|
158
|
+
</List>
|
|
159
|
+
|
|
160
|
+
</PullToRefresh>
|
|
161
|
+
<InfiniteScroll threshold={40} loadMore={onNextPage} hasMore={request.pagination.more} />
|
|
162
|
+
|
|
163
|
+
</section>
|
|
164
|
+
)
|
|
6
165
|
}
|
|
7
166
|
|
|
8
167
|
export default Page;
|
|
@@ -0,0 +1,22 @@
|
|
|
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
|
+
}
|
|
@@ -0,0 +1,30 @@
|
|
|
1
|
+
import React, { useEffect, useState, useRef } from 'react';
|
|
2
|
+
import { useParams, useSearchParams,useNavigate } from 'react-router-dom';
|
|
3
|
+
import ProviderApp from '@/provider/app';
|
|
4
|
+
|
|
5
|
+
import Link from '@/components/Link';
|
|
6
|
+
const Page = () => {
|
|
7
|
+
const navigate= useNavigate();
|
|
8
|
+
const [search] = useSearchParams();
|
|
9
|
+
const providerApp = ProviderApp.useContainer();
|
|
10
|
+
|
|
11
|
+
const kssoLogin=async ()=>{
|
|
12
|
+
let code = search.get('code');
|
|
13
|
+
if(code){
|
|
14
|
+
//ksso auth登录
|
|
15
|
+
const req = await providerApp.login(code);
|
|
16
|
+
if(req){
|
|
17
|
+
navigate('/');//回到首页
|
|
18
|
+
}
|
|
19
|
+
}
|
|
20
|
+
}
|
|
21
|
+
useEffect(kssoLogin,[])
|
|
22
|
+
return (
|
|
23
|
+
<div>
|
|
24
|
+
<p>您未登录,当前是登录页</p>
|
|
25
|
+
<Link href={'/'}>点击返回首页</Link>
|
|
26
|
+
</div>
|
|
27
|
+
)
|
|
28
|
+
}
|
|
29
|
+
|
|
30
|
+
export default Page;
|
|
@@ -0,0 +1,13 @@
|
|
|
1
|
+
import React, { useEffect, useState, useRef } from 'react';
|
|
2
|
+
import Link from '@/components/Link';
|
|
3
|
+
|
|
4
|
+
const Page = () => {
|
|
5
|
+
return (
|
|
6
|
+
<div>
|
|
7
|
+
<p>用户信息页:用户已登录才可以看到本页,不然会跳转登录页面</p>
|
|
8
|
+
<Link href={'/'}>点击返回首页</Link>
|
|
9
|
+
</div>
|
|
10
|
+
)
|
|
11
|
+
}
|
|
12
|
+
|
|
13
|
+
export default Page;
|
|
@@ -1,14 +1,45 @@
|
|
|
1
1
|
import { useState,useMemo } from 'react';
|
|
2
2
|
import { createContainer } from "unstated-next"
|
|
3
|
-
|
|
3
|
+
import {useDelay} from '@/hooks';
|
|
4
|
+
import {logout as apiLogout} from '@/services';
|
|
4
5
|
const useApp=() =>{
|
|
5
6
|
const [loading,setLoading] = useState(true);
|
|
7
|
+
const [nav,setNavConfig] = useState({visible:true,syncDocumentTitle:false});
|
|
8
|
+
const [user,setUser] = useState(null);
|
|
9
|
+
|
|
10
|
+
const delay = useDelay();
|
|
11
|
+
|
|
12
|
+
const isLogin=async ()=>{
|
|
13
|
+
await delay.wait(2000);
|
|
14
|
+
return user?true:false;
|
|
15
|
+
}
|
|
16
|
+
const login=async (code)=>{
|
|
17
|
+
await delay.wait(2000);
|
|
18
|
+
setUser({id:'1001',auth:['normal','admin']});
|
|
19
|
+
return true;
|
|
20
|
+
}
|
|
21
|
+
const logout=async ()=>{
|
|
22
|
+
apiLogout();
|
|
23
|
+
setUser(null);
|
|
24
|
+
}
|
|
25
|
+
|
|
26
|
+
|
|
27
|
+
const setNav=(config)=>{
|
|
28
|
+
setNavConfig({...nav,...config});
|
|
29
|
+
}
|
|
6
30
|
const action=useMemo(()=>{
|
|
7
31
|
return {
|
|
8
32
|
loading,
|
|
9
|
-
setLoading
|
|
33
|
+
setLoading,
|
|
34
|
+
isLogin,
|
|
35
|
+
login,
|
|
36
|
+
nav,
|
|
37
|
+
setNav,
|
|
38
|
+
logout,
|
|
39
|
+
setUser,
|
|
40
|
+
user
|
|
10
41
|
}
|
|
11
|
-
},[loading]);
|
|
42
|
+
},[loading,nav,setNav,user,setUser,isLogin]);
|
|
12
43
|
|
|
13
44
|
return action
|
|
14
45
|
}
|
|
@@ -1,11 +1,20 @@
|
|
|
1
1
|
import React from 'react';
|
|
2
|
-
import { Routes, Route} from 'react-router-dom';
|
|
2
|
+
import { Routes, Route, Navigate} from 'react-router-dom';
|
|
3
3
|
import Home from '@/pages/index.jsx';
|
|
4
|
-
import
|
|
4
|
+
import Login from '@/pages/login';
|
|
5
|
+
import User from '@/pages/user';
|
|
6
|
+
import {LayoutApp,LayoutProvider} from '@/components/Layout';
|
|
7
|
+
import {AuthLogin} from '@/components/Auth';
|
|
5
8
|
export const RouteList = (
|
|
6
9
|
<Routes>
|
|
7
|
-
<Route path='/' element={<
|
|
8
|
-
<Route path='/' element={<
|
|
10
|
+
<Route path='/' element={<LayoutProvider />}>
|
|
11
|
+
<Route path='/' element={<LayoutApp />}>
|
|
12
|
+
|
|
13
|
+
<Route path='/' element={<Navigate to='/demo/1001?type=test&name=demo' />} />
|
|
14
|
+
<Route path='/demo/:id' element={<Home />} />
|
|
15
|
+
<Route path='/user' element={<AuthLogin><User /></AuthLogin>} />
|
|
16
|
+
</Route>
|
|
17
|
+
<Route path='/login' element={<Login />} />
|
|
9
18
|
</Route>
|
|
10
19
|
</Routes>
|
|
11
20
|
);
|
|
@@ -1,44 +1,35 @@
|
|
|
1
1
|
import Axios from 'axios';
|
|
2
2
|
import qs from 'qs';
|
|
3
3
|
const axios = Axios.create();
|
|
4
|
-
|
|
5
4
|
console.log(`========API_ROOT:${API_HOST}========`);
|
|
6
|
-
export const API_ROOT = API_HOST;
|
|
7
5
|
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
return '';
|
|
12
|
-
}
|
|
13
|
-
if (v && v.constructor === Array && v.length <= 0) {
|
|
14
|
-
// 处理空数组丢失
|
|
15
|
-
return '';
|
|
16
|
-
}
|
|
17
|
-
return v;
|
|
18
|
-
}
|
|
6
|
+
export const API_ROOT = API_HOST;
|
|
7
|
+
const tokenMode='header';//header,cookie
|
|
8
|
+
const tokenName='token';
|
|
19
9
|
|
|
20
10
|
let Modal = {
|
|
21
11
|
error: (options) => {
|
|
22
12
|
alert(options.content);
|
|
23
|
-
// ShowAlert({ label: options.title, text: `${options.content}` });
|
|
24
13
|
},
|
|
25
14
|
};
|
|
26
15
|
|
|
27
16
|
let jwt = '';
|
|
28
|
-
|
|
17
|
+
export const logout = ()=>{
|
|
18
|
+
localStorage.removeItem('jwt');
|
|
19
|
+
jwt='';
|
|
20
|
+
}
|
|
29
21
|
export const setJwt = (value) => {
|
|
30
22
|
localStorage.setItem('jwt', value);
|
|
31
23
|
jwt = value;
|
|
32
24
|
};
|
|
33
25
|
|
|
34
|
-
export const setLogout = (fn) => {
|
|
35
|
-
logout = fn;
|
|
36
|
-
};
|
|
37
26
|
|
|
38
27
|
axios.interceptors.request.use(function (config) {
|
|
39
28
|
const header = { 'X-Requested-With': 'XMLHttpRequest' };
|
|
40
|
-
if
|
|
41
|
-
|
|
29
|
+
if(tokenMode=='header'){
|
|
30
|
+
if (jwt) {
|
|
31
|
+
header[tokenName] = jwt;
|
|
32
|
+
}
|
|
42
33
|
}
|
|
43
34
|
if (config.headers) {
|
|
44
35
|
config.headers = { ...config.headers, ...header };
|
|
@@ -60,7 +51,6 @@ axios.interceptors.response.use(
|
|
|
60
51
|
if (response.config.noInterceptors) {
|
|
61
52
|
return response;
|
|
62
53
|
}
|
|
63
|
-
|
|
64
54
|
if (Number(response.data.code) !== 0) {
|
|
65
55
|
console.log(`${JSON.stringify(response.data)}`);
|
|
66
56
|
Modal.error({ title: `注意`, content: `${response.data.msg}(${response.data.code})` });
|
|
@@ -73,12 +63,6 @@ axios.interceptors.response.use(
|
|
|
73
63
|
}
|
|
74
64
|
// jwt失效
|
|
75
65
|
if (error.response.status === 401) {
|
|
76
|
-
// setJwt('');
|
|
77
|
-
//重新登录
|
|
78
|
-
// Modal.error({
|
|
79
|
-
// title: '提示',
|
|
80
|
-
// content: `请重新登录`,
|
|
81
|
-
// });
|
|
82
66
|
if(logout)logout();
|
|
83
67
|
return;
|
|
84
68
|
} else if (error.response.status === 403) {
|
|
@@ -96,6 +80,9 @@ axios.interceptors.response.use(
|
|
|
96
80
|
}
|
|
97
81
|
);
|
|
98
82
|
|
|
83
|
+
|
|
84
|
+
|
|
85
|
+
|
|
99
86
|
let buffer = {};
|
|
100
87
|
export async function GET_DEFAULT(url, param, options) {
|
|
101
88
|
if (param) param = qs.stringify(param, { arrayFormat: 'indices' });
|
|
@@ -161,13 +148,6 @@ export async function POST_DEFAULT(url, params, method, options) {
|
|
|
161
148
|
return response && response.data ? response.data : null;
|
|
162
149
|
}
|
|
163
150
|
|
|
164
|
-
export async function PUT_DEFAULT(url, params, options) {
|
|
165
|
-
return POST_DEFAULT(url, params, 'PUT', options);
|
|
166
|
-
}
|
|
167
|
-
export async function DELETE_DEFAULT(url, params, options) {
|
|
168
|
-
return POST_DEFAULT(url, params, 'DELETE', options);
|
|
169
|
-
}
|
|
170
|
-
|
|
171
151
|
export async function POST_DEFAULT_CROSS(url, params) {
|
|
172
152
|
let data = {};
|
|
173
153
|
// if (params) params = qs.stringify(params, { arrayFormat: 'indices' });
|
|
@@ -1,6 +1,7 @@
|
|
|
1
1
|
import {GET_DEFAULT,PUT_DEFAULT,POST_DEFAULT,API_ROOT} from './index.js';
|
|
2
2
|
|
|
3
3
|
|
|
4
|
+
|
|
4
5
|
export function GET_USER(){
|
|
5
6
|
return GET_DEFAULT(`${HOST}/user`);
|
|
6
7
|
}
|
|
@@ -10,4 +11,16 @@ export function SET_USER(params={
|
|
|
10
11
|
age:''
|
|
11
12
|
}){
|
|
12
13
|
return POST_DEFAULT(`${HOST}/user`,params)
|
|
14
|
+
}
|
|
15
|
+
|
|
16
|
+
|
|
17
|
+
export function GET_USER_LIST(params={
|
|
18
|
+
current:1,
|
|
19
|
+
pageSize:20
|
|
20
|
+
}){
|
|
21
|
+
return GET_DEFAULT(`${API_ROOT}/userList`,params)
|
|
22
|
+
}
|
|
23
|
+
|
|
24
|
+
export function GET_USER_TYPE(){
|
|
25
|
+
return GET_DEFAULT(`${API_ROOT}/userType`)
|
|
13
26
|
}
|
|
@@ -0,0 +1,22 @@
|
|
|
1
|
+
<!doctype html>
|
|
2
|
+
<html>
|
|
3
|
+
|
|
4
|
+
<head>
|
|
5
|
+
<meta charset="utf-8">
|
|
6
|
+
<meta name="viewport"
|
|
7
|
+
content="width=device-width, initial-scale=1, maximum-scale=1, minimum-scale=1, user-scalable=no,viewport-fit=cover" />
|
|
8
|
+
<meta name="format-detection" content="telephone=no,email=no,adress=no">
|
|
9
|
+
<meta name="apple-touch-fullscreen" content="yes">
|
|
10
|
+
<meta name="apple-mobile-web-app-capable" content="yes">
|
|
11
|
+
<meta name="apple-mobile-web-app-status-bar-style" content="black">
|
|
12
|
+
<title></title>
|
|
13
|
+
<script>
|
|
14
|
+
var url = location.protocol + '//' + location.host+'/#/login';
|
|
15
|
+
location.replace('https://ksso.kingnet.com/oauth2/auth?client_id=填入分配的ID&response_type=code&redirect_uri=' + encodeURIComponent(url));
|
|
16
|
+
</script>
|
|
17
|
+
</head>
|
|
18
|
+
|
|
19
|
+
<body>
|
|
20
|
+
</body>
|
|
21
|
+
|
|
22
|
+
</html>
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
# oa-app
|
|
2
2
|
|
|
3
3
|
### 初始化项目
|
|
4
|
-
|
|
4
|
+
git仓库建立完毕后,执行`sh init.sh`
|
|
5
5
|
|
|
6
6
|
### 本地调试
|
|
7
7
|
kn-cli --dev
|
|
@@ -22,7 +22,7 @@ kn-cli --dev
|
|
|
22
22
|
部署方式:将构建完成的文件夹下的 `release` 内的内容部署到目标服务器
|
|
23
23
|
参考应用:oa-app
|
|
24
24
|
|
|
25
|
-
```
|
|
25
|
+
```
|
|
26
26
|
2. 进入CICD,构建相应环境
|
|
27
27
|
3. 快速发布
|
|
28
28
|
4. 进入域名访问
|
|
@@ -1,15 +1,15 @@
|
|
|
1
1
|
const configs = {
|
|
2
2
|
// 本地研发环境(npm start)
|
|
3
3
|
localdebug: {
|
|
4
|
-
|
|
4
|
+
API_HOST: '/api',
|
|
5
5
|
},
|
|
6
6
|
// cicd构建时研发环境
|
|
7
7
|
dev: {
|
|
8
|
-
|
|
8
|
+
API_HOST: 'http://dev-api.com',
|
|
9
9
|
},
|
|
10
10
|
// cicd构建时生产环境
|
|
11
11
|
prod: {
|
|
12
|
-
|
|
12
|
+
API_HOST: 'http://api.com',
|
|
13
13
|
},
|
|
14
14
|
};
|
|
15
15
|
|