@yyp92-cli/template-react-pc 1.4.0 → 2.1.0
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/CHANGELOG.md +18 -0
- package/package.json +1 -1
- package/template/README.md +6 -0
- package/template/package.json +2 -3
- package/template/pnpm-lock.yaml +719 -732
- package/template/src/antdTheme/darkTheme.ts +285 -1
- package/template/src/antdTheme/lightTheme.ts +272 -54
- package/template/src/components/layout/footer/index.tsx +1 -1
- package/template/src/components/layout/header/index.tsx +16 -5
- package/template/src/components/layout/index.tsx +8 -20
- package/template/src/components/layout/side/index.tsx +1 -1
- package/template/src/components/layout-horizontal/header/index.tsx +16 -6
- package/template/src/components/layout-horizontal/index.tsx +6 -17
- package/template/src/components/layout-horizontal/side/index.tsx +1 -3
- package/template/src/components/login/index.tsx +2 -2
- package/template/src/global/constants.ts +1 -0
- package/template/src/pages/home/index.tsx +1 -1
- package/template/src/service/request/index.ts +9 -7
- package/template/src/store/antdToken.ts +35 -0
- package/template/src/store/login.ts +5 -3
- package/template/src/store/menus.ts +3 -1
- package/template/src/store/permission.ts +3 -1
- package/template/src/store/token.ts +4 -2
|
@@ -1,9 +1,10 @@
|
|
|
1
|
-
import React, { useEffect } from 'react'
|
|
1
|
+
import React, { useEffect, useState } from 'react'
|
|
2
2
|
import { ConfigProvider } from 'antd'
|
|
3
3
|
import dayjs from 'dayjs';
|
|
4
4
|
import 'dayjs/locale/zh-cn';
|
|
5
|
-
import zhCN from 'antd/locale/zh_CN'
|
|
6
|
-
import {
|
|
5
|
+
import zhCN from 'antd/locale/zh_CN'
|
|
6
|
+
import { antdTokenStore } from '@/store/antdToken'
|
|
7
|
+
import { getDarkTheme } from '@/utils'
|
|
7
8
|
import Content from './content'
|
|
8
9
|
|
|
9
10
|
import styles from './index.module.scss'
|
|
@@ -13,36 +14,23 @@ interface LayoutProps {
|
|
|
13
14
|
}
|
|
14
15
|
|
|
15
16
|
const Layout: React.FC<LayoutProps> = ({ }) => {
|
|
17
|
+
const {antdToken} = antdTokenStore()
|
|
18
|
+
|
|
16
19
|
useEffect(() => {
|
|
17
|
-
getDarkTheme(
|
|
20
|
+
getDarkTheme(false)
|
|
18
21
|
dayjs.locale('zh-cn')
|
|
19
22
|
}, [])
|
|
20
23
|
|
|
21
24
|
|
|
22
25
|
// ********** 操作 **********
|
|
23
|
-
// 主题切换
|
|
24
|
-
const getDarkTheme = (theme: number) => {
|
|
25
|
-
// 获取根元素
|
|
26
|
-
const root = document.documentElement;
|
|
27
|
-
|
|
28
|
-
if (theme != 1) {
|
|
29
|
-
// 修改 data-theme 属性的值为 "light"
|
|
30
|
-
root.setAttribute('data-theme', 'light');
|
|
31
|
-
return
|
|
32
|
-
}
|
|
33
|
-
|
|
34
|
-
// 修改 data-theme 属性的值为 "dark"
|
|
35
|
-
root.setAttribute('data-theme', 'dark');
|
|
36
|
-
}
|
|
37
26
|
|
|
38
27
|
|
|
39
28
|
// ********** 渲染 **********
|
|
40
|
-
|
|
41
29
|
return (
|
|
42
30
|
<div className={styles.layout}>
|
|
43
31
|
<ConfigProvider
|
|
44
32
|
// 主题
|
|
45
|
-
theme={
|
|
33
|
+
theme={antdToken}
|
|
46
34
|
locale={zhCN}
|
|
47
35
|
|
|
48
36
|
button={{
|
|
@@ -3,8 +3,12 @@ import {useNavigate} from 'react-router-dom'
|
|
|
3
3
|
import { Avatar, Button, Dropdown, Switch, Tooltip } from 'antd'
|
|
4
4
|
import type { MenuProps } from 'antd'
|
|
5
5
|
import { FullscreenExitOutlined, FullscreenOutlined, UserOutlined } from '@ant-design/icons'
|
|
6
|
-
import {
|
|
7
|
-
import {
|
|
6
|
+
import { getDarkTheme } from '@/utils'
|
|
7
|
+
import { userInfoStore } from '@/store/login'
|
|
8
|
+
import { antdTokenStore } from '@/store/antdToken'
|
|
9
|
+
import { tokenStore } from '@/store/token'
|
|
10
|
+
import { menusStore } from '@/store/menus'
|
|
11
|
+
import { permissionStore } from '@/store/permission'
|
|
8
12
|
import {Side} from '../side'
|
|
9
13
|
|
|
10
14
|
import styles from './index.module.scss'
|
|
@@ -15,15 +19,20 @@ interface HeaderProps {
|
|
|
15
19
|
|
|
16
20
|
export const Header: React.FC<HeaderProps> = ({}) => {
|
|
17
21
|
const navigate = useNavigate()
|
|
22
|
+
const {clearUserInfo} = userInfoStore()
|
|
23
|
+
const {setAntdToken} = antdTokenStore()
|
|
24
|
+
const {clearToken} = tokenStore()
|
|
25
|
+
const {clearMenus} = menusStore()
|
|
26
|
+
const {clearPermissions} = permissionStore()
|
|
18
27
|
const [isFullScreen, setIsFullScreen] = useState<boolean>(false)
|
|
19
28
|
|
|
20
29
|
|
|
21
30
|
// ********* 操作 *********
|
|
22
31
|
const handleLogout = () => {
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
32
|
+
clearToken()
|
|
33
|
+
clearUserInfo()
|
|
34
|
+
clearMenus()
|
|
35
|
+
clearPermissions()
|
|
27
36
|
|
|
28
37
|
navigate('/login')
|
|
29
38
|
}
|
|
@@ -45,6 +54,7 @@ export const Header: React.FC<HeaderProps> = ({}) => {
|
|
|
45
54
|
|
|
46
55
|
const handleChangeTheme = (checked: boolean) => {
|
|
47
56
|
getDarkTheme(checked)
|
|
57
|
+
setAntdToken(checked)
|
|
48
58
|
}
|
|
49
59
|
|
|
50
60
|
|
|
@@ -3,7 +3,8 @@ import { ConfigProvider } from 'antd'
|
|
|
3
3
|
import dayjs from 'dayjs';
|
|
4
4
|
import 'dayjs/locale/zh-cn';
|
|
5
5
|
import zhCN from 'antd/locale/zh_CN';
|
|
6
|
-
import {
|
|
6
|
+
import { getDarkTheme } from '@/utils'
|
|
7
|
+
import { antdTokenStore } from '@/store/antdToken'
|
|
7
8
|
import Content from './content'
|
|
8
9
|
|
|
9
10
|
import styles from './index.module.scss'
|
|
@@ -13,27 +14,15 @@ interface LayoutProps {
|
|
|
13
14
|
}
|
|
14
15
|
|
|
15
16
|
const Layout: React.FC<LayoutProps> = ({ }) => {
|
|
17
|
+
const {antdToken} = antdTokenStore()
|
|
18
|
+
|
|
16
19
|
useEffect(() => {
|
|
17
|
-
getDarkTheme(
|
|
20
|
+
getDarkTheme(false)
|
|
18
21
|
dayjs.locale('zh-cn')
|
|
19
22
|
}, [])
|
|
20
23
|
|
|
21
24
|
|
|
22
25
|
// ********** 操作 **********
|
|
23
|
-
// 主题切换
|
|
24
|
-
const getDarkTheme = (theme: number) => {
|
|
25
|
-
// 获取根元素
|
|
26
|
-
const root = document.documentElement;
|
|
27
|
-
|
|
28
|
-
if (theme != 1) {
|
|
29
|
-
// 修改 data-theme 属性的值为 "light"
|
|
30
|
-
root.setAttribute('data-theme', 'light');
|
|
31
|
-
return
|
|
32
|
-
}
|
|
33
|
-
|
|
34
|
-
// 修改 data-theme 属性的值为 "dark"
|
|
35
|
-
root.setAttribute('data-theme', 'dark');
|
|
36
|
-
}
|
|
37
26
|
|
|
38
27
|
|
|
39
28
|
// ********** 渲染 **********
|
|
@@ -42,7 +31,7 @@ const Layout: React.FC<LayoutProps> = ({ }) => {
|
|
|
42
31
|
<div className={styles.layout}>
|
|
43
32
|
<ConfigProvider
|
|
44
33
|
// 主题
|
|
45
|
-
theme={
|
|
34
|
+
theme={antdToken}
|
|
46
35
|
locale={zhCN}
|
|
47
36
|
|
|
48
37
|
button={{
|
|
@@ -4,8 +4,6 @@ import type { MenuProps } from 'antd';
|
|
|
4
4
|
import {useNavigate, useLocation} from 'react-router-dom'
|
|
5
5
|
import {ComponentMap} from '@/router/router'
|
|
6
6
|
import { menusStore } from '@/store/menus'
|
|
7
|
-
import { localCache } from '@/utils'
|
|
8
|
-
import { LOGIN_TOKEN } from '@/global/constants'
|
|
9
7
|
|
|
10
8
|
import styles from './index.module.scss'
|
|
11
9
|
|
|
@@ -86,7 +84,7 @@ export const Side: React.FC<SideProps> = ({}) => {
|
|
|
86
84
|
alt="logo"
|
|
87
85
|
/>
|
|
88
86
|
|
|
89
|
-
<span
|
|
87
|
+
<span>后台管理系统</span>
|
|
90
88
|
</div>
|
|
91
89
|
|
|
92
90
|
<Menu
|
|
@@ -52,11 +52,11 @@ const Login: React.FC<LoginProps> = ({}) => {
|
|
|
52
52
|
const onFinish = async (values: any) => {
|
|
53
53
|
console.log('Success:', values)
|
|
54
54
|
|
|
55
|
-
if (values.username === '
|
|
55
|
+
if (values.username === 'admin' && values.password === '123456') {
|
|
56
56
|
setPermissions(defaultList)
|
|
57
57
|
setToken('111')
|
|
58
58
|
setUserInfo({
|
|
59
|
-
userName: '
|
|
59
|
+
userName: 'admin',
|
|
60
60
|
userId: '001'
|
|
61
61
|
})
|
|
62
62
|
|
|
@@ -2,9 +2,11 @@ import axios from 'axios'
|
|
|
2
2
|
import { notification, message } from 'antd'
|
|
3
3
|
import type { AxiosRequestConfig, AxiosError, AxiosResponse } from 'axios'
|
|
4
4
|
import type { MyInternalAxiosRequestConfig } from './type'
|
|
5
|
-
import { localCache } from '@/utils/cache'
|
|
6
|
-
import { LOGIN_TOKEN, USER_INFO, PERMISSION, MENUS } from '@/global/constants'
|
|
7
5
|
import router from '@/router/router'
|
|
6
|
+
import { userInfoStore } from '@/store/login'
|
|
7
|
+
import { tokenStore } from '@/store/token'
|
|
8
|
+
import { menusStore } from '@/store/menus'
|
|
9
|
+
import { permissionStore } from '@/store/permission'
|
|
8
10
|
|
|
9
11
|
// * 存储待取消的请求:key 是请求唯一标识,value 是 AbortController 实例
|
|
10
12
|
const pendingRequests = new Map()
|
|
@@ -67,10 +69,10 @@ const removePendingRequest = (config: AxiosRequestConfig) => {
|
|
|
67
69
|
// * Token 过期处理函数
|
|
68
70
|
function handleTokenExpired() {
|
|
69
71
|
// 1. 清除本地存储的 Token(避免死循环)
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
|
|
72
|
+
userInfoStore.getState().clearUserInfo()
|
|
73
|
+
tokenStore.getState().clearToken()
|
|
74
|
+
menusStore.getState().clearMenus()
|
|
75
|
+
permissionStore.getState().clearPermissions()
|
|
74
76
|
|
|
75
77
|
// 排除登录页,避免死循环
|
|
76
78
|
const currentPath = window.location.pathname
|
|
@@ -103,7 +105,7 @@ instance.interceptors.request.use(
|
|
|
103
105
|
addPendingRequest(config)
|
|
104
106
|
}
|
|
105
107
|
|
|
106
|
-
const token =
|
|
108
|
+
const token = tokenStore.getState().token
|
|
107
109
|
|
|
108
110
|
if (config.headers && token) {
|
|
109
111
|
config.headers.Authorization = `Bearer ${token}`
|
|
@@ -0,0 +1,35 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* * 用户信息
|
|
3
|
+
*/
|
|
4
|
+
import { create } from 'zustand'
|
|
5
|
+
import { persist } from 'zustand/middleware'
|
|
6
|
+
import { ANTDTOKEN} from '@/global/constants'
|
|
7
|
+
import { lightToken } from '@/antdTheme/lightTheme'
|
|
8
|
+
import { darkToken } from '@/antdTheme/darkTheme'
|
|
9
|
+
|
|
10
|
+
type AntdTokenStoreState = {
|
|
11
|
+
antdToken: any
|
|
12
|
+
}
|
|
13
|
+
|
|
14
|
+
type AntdTokenStoreActions = {
|
|
15
|
+
setAntdToken: (
|
|
16
|
+
antdToken: AntdTokenStoreState['antdToken']
|
|
17
|
+
) => void,
|
|
18
|
+
}
|
|
19
|
+
|
|
20
|
+
type AntdTokenStore = AntdTokenStoreState & AntdTokenStoreActions
|
|
21
|
+
|
|
22
|
+
export const antdTokenStore = create<AntdTokenStore>()(
|
|
23
|
+
persist(
|
|
24
|
+
(set) => ({
|
|
25
|
+
antdToken: {},
|
|
26
|
+
setAntdToken: (isDark) => {
|
|
27
|
+
const antdToken = isDark ? darkToken : lightToken
|
|
28
|
+
return set({antdToken})
|
|
29
|
+
},
|
|
30
|
+
}),
|
|
31
|
+
{
|
|
32
|
+
name: ANTDTOKEN
|
|
33
|
+
}
|
|
34
|
+
)
|
|
35
|
+
)
|
|
@@ -7,15 +7,16 @@ import { USER_INFO} from '@/global/constants'
|
|
|
7
7
|
|
|
8
8
|
type UserInfoStoreState = {
|
|
9
9
|
userInfo: {
|
|
10
|
-
userId
|
|
11
|
-
userName
|
|
10
|
+
userId?: string,
|
|
11
|
+
userName?: string
|
|
12
12
|
}
|
|
13
13
|
}
|
|
14
14
|
|
|
15
15
|
type UserInfoStoreActions = {
|
|
16
16
|
setUserInfo: (
|
|
17
17
|
userInfo: UserInfoStoreState['userInfo']
|
|
18
|
-
) => void
|
|
18
|
+
) => void,
|
|
19
|
+
clearUserInfo: () => void
|
|
19
20
|
}
|
|
20
21
|
|
|
21
22
|
type UserInfoStore = UserInfoStoreState & UserInfoStoreActions
|
|
@@ -28,6 +29,7 @@ export const userInfoStore = create<UserInfoStore>()(
|
|
|
28
29
|
userId: '111'
|
|
29
30
|
},
|
|
30
31
|
setUserInfo: (userInfo) => set({userInfo}),
|
|
32
|
+
clearUserInfo: () => set({userInfo: {}})
|
|
31
33
|
}),
|
|
32
34
|
{
|
|
33
35
|
name: USER_INFO
|
|
@@ -11,6 +11,7 @@ type MenusStoreState = {
|
|
|
11
11
|
|
|
12
12
|
type MenusStoreActions = {
|
|
13
13
|
setMenus: (menus: string[]) => void,
|
|
14
|
+
clearMenus: () => void
|
|
14
15
|
}
|
|
15
16
|
|
|
16
17
|
type MenusStore = MenusStoreState & MenusStoreActions
|
|
@@ -19,7 +20,8 @@ export const menusStore = create<MenusStore>()(
|
|
|
19
20
|
persist(
|
|
20
21
|
(set) => ({
|
|
21
22
|
menus: [],
|
|
22
|
-
setMenus: (menus) => set({menus})
|
|
23
|
+
setMenus: (menus) => set({menus}),
|
|
24
|
+
clearMenus: () => set({menus: []}),
|
|
23
25
|
}),
|
|
24
26
|
{
|
|
25
27
|
name: MENUS
|
|
@@ -11,6 +11,7 @@ type PermissionStoreState = {
|
|
|
11
11
|
|
|
12
12
|
type PermissionStoreActions = {
|
|
13
13
|
setPermissions: (permissions: string[]) => void,
|
|
14
|
+
clearPermissions: () => void
|
|
14
15
|
}
|
|
15
16
|
|
|
16
17
|
type PermissionStore = PermissionStoreState & PermissionStoreActions
|
|
@@ -19,7 +20,8 @@ export const permissionStore = create<PermissionStore>()(
|
|
|
19
20
|
persist(
|
|
20
21
|
(set) => ({
|
|
21
22
|
permissions: [],
|
|
22
|
-
setPermissions: (permissions) => set({permissions})
|
|
23
|
+
setPermissions: (permissions) => set({permissions}),
|
|
24
|
+
clearPermissions: () => set({permissions: []}),
|
|
23
25
|
}),
|
|
24
26
|
{
|
|
25
27
|
name: PERMISSION
|
|
@@ -10,7 +10,8 @@ type UserInfoStoreState = {
|
|
|
10
10
|
}
|
|
11
11
|
|
|
12
12
|
type UserInfoStoreActions = {
|
|
13
|
-
setToken: (token: string) => void
|
|
13
|
+
setToken: (token: string) => void,
|
|
14
|
+
clearToken: () => void
|
|
14
15
|
}
|
|
15
16
|
|
|
16
17
|
type UserInfoStore = UserInfoStoreState & UserInfoStoreActions
|
|
@@ -19,7 +20,8 @@ export const tokenStore = create<UserInfoStore>()(
|
|
|
19
20
|
persist(
|
|
20
21
|
(set) => ({
|
|
21
22
|
token: '',
|
|
22
|
-
setToken: (token) => set({token})
|
|
23
|
+
setToken: (token) => set({token}),
|
|
24
|
+
clearToken: () => set({token: ''})
|
|
23
25
|
}),
|
|
24
26
|
{
|
|
25
27
|
name: LOGIN_TOKEN
|