Skip to content

Commit 1676b5c

Browse files
committed
feat: add login page
1 parent f424b38 commit 1676b5c

File tree

16 files changed

+496
-101
lines changed

16 files changed

+496
-101
lines changed

config/config.ts

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,3 @@
1-
import config from './basic';
21
import routes from './routes';
32

43
import { defineConfig } from 'umi';

config/routes.ts

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,12 @@
11
import { IRoute } from 'umi';
22

33
const routes: IRoute[] = [
4+
{
5+
path: '/auth',
6+
exact: true,
7+
layout: false,
8+
component: '@/page/auth',
9+
},
410
{
511
path: '/',
612
exact: false,
@@ -13,6 +19,7 @@ const routes: IRoute[] = [
1319
name: '主页',
1420
component: '@/page/home',
1521
},
22+
1623
{
1724
path: '/api',
1825
exact: true,
@@ -27,6 +34,7 @@ const routes: IRoute[] = [
2734
},
2835
],
2936
},
37+
3038
{ component: '@/page/404' },
3139
];
3240

src/app.tsx

Lines changed: 28 additions & 45 deletions
Original file line numberDiff line numberDiff line change
@@ -1,26 +1,48 @@
11
import React from 'react';
2-
32
import dayjs from 'dayjs';
43
import relativeTime from 'dayjs/plugin/relativeTime';
54
import 'dayjs/locale/zh';
65

76
import { MicroApp, IRoute, request as requestClient, RequestConfig } from 'umi';
87
import { PageContainer } from '@ant-design/pro-layout';
98
// import { BASE_URL } from './constants';
9+
import { loadInitialState } from '@/util';
1010
import proLayout from './layout';
1111

1212
dayjs.locale('zh');
1313
dayjs.extend(relativeTime);
1414

15-
const qiankunApps: Array<QiankunApp> = [];
15+
const qiankunApps: QiankunApp[] = [];
1616

1717
export async function getInitialState(): Promise<InitialState> {
18-
return {
19-
avatar_url: 'https://avatars.githubusercontent.com/u/958063?v=4&s=120',
20-
loginname: 'thonatos',
21-
};
18+
const initialState = loadInitialState();
19+
return initialState;
2220
}
2321

22+
export const layout = proLayout;
23+
24+
export const qiankun = async () => {
25+
try {
26+
// const params = { method: 'get', json: {} };
27+
// const { apps } = await requestClient<{
28+
// apps: QiankunApp[];
29+
// }>(`${BASE_URL}/getFeConfig`, params);
30+
31+
// console.log('===getFeConfig', apps);
32+
33+
// apps
34+
// .filter(({ type }) => type === 'App')
35+
// .sort((appA, appB) => appA.order - appB.order)
36+
// .forEach((app) => qiankunApps.push(app));
37+
38+
return {
39+
apps: [],
40+
};
41+
} catch (error) {
42+
return {};
43+
}
44+
};
45+
2446
export const patchRoutes = ({ routes }: { routes: Array<IRoute> }) => {
2547
const root = routes[0];
2648

@@ -48,49 +70,10 @@ export const patchRoutes = ({ routes }: { routes: Array<IRoute> }) => {
4870
});
4971
};
5072

51-
export const layout = proLayout;
52-
53-
export const qiankun = async () => {
54-
try {
55-
// const params = { method: 'get', json: {} };
56-
// const { apps } = await requestClient<{
57-
// apps: QiankunApp[];
58-
// }>(`${BASE_URL}/getFeConfig`, params);
59-
60-
// console.log('===getFeConfig', apps);
61-
62-
// apps
63-
// .filter(({ type }) => type === 'App')
64-
// .sort((appA, appB) => appA.order - appB.order)
65-
// .forEach((app) => qiankunApps.push(app));
66-
67-
return {
68-
apps: [],
69-
};
70-
} catch (error) {
71-
return {};
72-
}
73-
};
74-
7573
export const request: RequestConfig = {
7674
timeout: 1000,
7775
errorConfig: {},
7876
middlewares: [],
7977
requestInterceptors: [],
8078
responseInterceptors: [],
8179
};
82-
83-
interface QiankunApp {
84-
name: string;
85-
type: string;
86-
path: string;
87-
entry: string;
88-
order: number;
89-
remark?: string;
90-
locale?: string;
91-
}
92-
93-
export interface InitialState {
94-
loginname: string;
95-
avatar_url: string;
96-
}

src/config/index.ts

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,3 @@
1+
import config from '../../config/basic';
2+
3+
export default config;

src/constants/index.ts

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -20,3 +20,8 @@ export const TABS_MAP = {
2020
};
2121

2222
export type TabType = keyof typeof TABS_MAP;
23+
24+
export enum FORM_TYPE {
25+
LOGIN = 'login',
26+
REGISTER = 'register',
27+
}

src/layout.tsx

Lines changed: 25 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -1,25 +1,31 @@
11
import React from 'react';
2-
import { Link } from 'umi';
3-
import { Avatar } from 'antd';
2+
import { Link, history } from 'umi';
3+
import { Avatar, Tooltip } from 'antd';
44

55
import {
66
DefaultFooter,
77
BasicLayoutProps,
88
MenuDataItem,
99
} from '@ant-design/pro-layout';
1010

11-
import { InitialState } from './app';
12-
1311
import config from '../config/basic';
1412
import Brand from './component/Brand';
1513

1614
const RightContent: React.FC<{
17-
data: InitialState;
15+
user?: UserModel;
1816
}> = (props) => {
19-
const { avatar_url } = props.data;
17+
const user = props?.user;
18+
19+
if (!user) {
20+
return null;
21+
}
22+
23+
const { loginname, avatar_url } = user;
2024
return (
2125
<div className="cnode-header-right">
22-
<Avatar shape="square" size="small" src={avatar_url} />
26+
<Tooltip title={loginname}>
27+
<Avatar shape="square" size="small" src={avatar_url} />
28+
</Tooltip>
2329
</div>
2430
);
2531
};
@@ -79,8 +85,7 @@ const layoutConfig = ({
7985

8086
// right
8187
rightContentRender: () => {
82-
const { avatar_url } = initialState;
83-
return <RightContent data={initialState} />;
88+
return <RightContent user={initialState.user} />;
8489
},
8590

8691
// footer
@@ -90,6 +95,17 @@ const layoutConfig = ({
9095
copyright={`${new Date().getFullYear()} - CNodejs.org`}
9196
/>
9297
),
98+
99+
onPageChange: () => {
100+
const { user, token } = initialState || {};
101+
102+
// 非登录页面
103+
if (history.location.pathname !== '/auth') {
104+
if (!user || !token) {
105+
history.push('/auth');
106+
}
107+
}
108+
},
93109
};
94110
};
95111

src/layout/component/UserInfo.tsx

Lines changed: 57 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,57 @@
1+
import React from 'react';
2+
import { useModel } from 'umi';
3+
import { useRequest } from 'ahooks';
4+
import { Avatar, Space } from 'antd';
5+
import ProCard from '@ant-design/pro-card';
6+
7+
import * as API from '@/service/user';
8+
9+
const UserInfo: React.FC<Props> = (props) => {
10+
const { user } = useModel('user');
11+
12+
if (!user) {
13+
return null;
14+
}
15+
16+
const { loginname, avatar_url } = user;
17+
18+
const { data } = useRequest(
19+
async () => {
20+
if (!loginname) {
21+
return;
22+
}
23+
24+
const res = await API.getUserInfo({ loginname });
25+
return res.data;
26+
},
27+
{
28+
refreshDeps: [loginname],
29+
},
30+
);
31+
32+
const renderMore = () => {
33+
if (!data) {
34+
return null;
35+
}
36+
37+
return (
38+
<div style={{ padding: '8px 0' }}>
39+
<span>积分:{data?.score}</span>
40+
</div>
41+
);
42+
};
43+
44+
return (
45+
<ProCard title="个人信息">
46+
<Space size={8}>
47+
<Avatar shape="square" size="small" src={avatar_url} />
48+
<span>{loginname}</span>
49+
</Space>
50+
{renderMore()}
51+
</ProCard>
52+
);
53+
};
54+
55+
export default UserInfo;
56+
57+
interface Props {}

src/layout/index.tsx

Lines changed: 26 additions & 20 deletions
Original file line numberDiff line numberDiff line change
@@ -1,8 +1,9 @@
11
import React from 'react';
22
import ProCard from '@ant-design/pro-card';
33

4-
import { IRoute } from 'umi';
4+
import { IRoute, Link } from 'umi';
55
import { PageContainer } from '@ant-design/pro-layout';
6+
import UserInfo from './component/UserInfo';
67

78
const getCurrentRoute = (route: IRoute, path: string): IRoute | undefined => {
89
let target;
@@ -34,28 +35,31 @@ const Layout: React.FC<React.PropsWithChildren<Props>> = (props) => {
3435
};
3536

3637
if (location.pathname.startsWith('/topic/')) {
37-
return (
38-
<ProCard gutter={16} bordered={false}>
39-
<ProCard bordered={false}>{props.children}</ProCard>
40-
<ProCard
41-
title=""
42-
layout="center"
43-
bordered={false}
44-
colSpan={{
45-
xs: '50px',
46-
sm: '100px',
47-
md: '200px',
48-
lg: '300px',
49-
xl: '400px',
50-
}}
51-
></ProCard>
52-
</ProCard>
53-
);
38+
const topicBreadcrumbName = location.pathname.split('/').pop();
39+
40+
headerConfig = {
41+
title: null,
42+
breadcrumb: {
43+
itemRender: (route: { path: string; breadcrumbName: string }) => {
44+
return <Link to={route.path}>{route.breadcrumbName}</Link>;
45+
},
46+
routes: [
47+
{
48+
path: '/',
49+
breadcrumbName: '主页',
50+
},
51+
{
52+
path: location.pathname,
53+
breadcrumbName: topicBreadcrumbName,
54+
},
55+
],
56+
},
57+
};
5458
}
5559

5660
return (
5761
<PageContainer header={headerConfig}>
58-
<ProCard gutter={16} bordered={false}>
62+
<ProCard gutter={16} bordered={false} ghost>
5963
<ProCard bordered={false}>{props.children}</ProCard>
6064
<ProCard
6165
title=""
@@ -68,7 +72,9 @@ const Layout: React.FC<React.PropsWithChildren<Props>> = (props) => {
6872
lg: '300px',
6973
xl: '400px',
7074
}}
71-
></ProCard>
75+
>
76+
<UserInfo />
77+
</ProCard>
7278
</ProCard>
7379
</PageContainer>
7480
);

src/model/user.ts

Lines changed: 26 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -1,8 +1,29 @@
1-
import { useState } from 'react';
1+
import { useState, useCallback } from 'react';
2+
import { loadInitialState } from '@/util';
23

34
export default () => {
4-
const [user, setUser] = useState<string>();
5-
const login = (name: string) => setUser(name);
6-
const logout = () => setUser('');
7-
return { user, login, logout };
5+
const initialState = loadInitialState();
6+
7+
const [user, setUser] = useState<UserModel | undefined>(initialState.user);
8+
9+
const login = useCallback((data: InitialState, useLocalStorage = false) => {
10+
const { user: userInfo } = data;
11+
12+
if (useLocalStorage) {
13+
window.localStorage.setItem('initialState', JSON.stringify(data));
14+
}
15+
setUser(userInfo);
16+
}, []);
17+
18+
const logout = useCallback(() => {
19+
window.localStorage.removeItem('initialState');
20+
setUser(undefined);
21+
}, []);
22+
23+
const reload = useCallback(() => {
24+
const state = loadInitialState();
25+
setUser(state.user);
26+
}, []);
27+
28+
return { user, login, logout, reload };
829
};

0 commit comments

Comments
 (0)