Add user manager. Optimize code.

This commit is contained in:
2023-11-01 18:21:05 +08:00
parent b548fb8083
commit e68cff4612
11 changed files with 127 additions and 24 deletions

View File

@@ -1,9 +1,9 @@
import React from 'react'
import Icon from '@ant-design/icons'
import { getLoginStatus, getNickName, logout } from '@/utils/auth'
import { getRedirectUrl } from '@/utils/common'
import { notification } from 'antd'
import { COLOR_ERROR } from '@/constants/common.constants.ts'
import { getLoginStatus, getNickname, logout } from '@/utils/auth'
import { getRedirectUrl } from '@/utils/common'
import { COLOR_ERROR } from '@/constants/common.constants'
const SidebarFooter: React.FC = () => {
const matches = useMatches()
@@ -11,7 +11,7 @@ const SidebarFooter: React.FC = () => {
const location = useLocation()
const navigate = useNavigate()
const [exiting, setExiting] = useState(false)
const [nickName, setNickName] = useState('')
const [nickname, setNickname] = useState('')
const handleClickAvatar = () => {
if (getLoginStatus()) {
@@ -42,8 +42,8 @@ const SidebarFooter: React.FC = () => {
useEffect(() => {
if (getLoginStatus()) {
void getNickName().then((nickName) => {
setNickName(nickName)
void getNickname().then((nickname) => {
setNickname(nickname)
})
}
}, [loginStatus])
@@ -60,7 +60,7 @@ const SidebarFooter: React.FC = () => {
</NavLink>
</span>
<span hidden={!getLoginStatus()} className={'text'}>
{nickName}
{nickname}
</span>
<div
hidden={!getLoginStatus()}

View File

@@ -2,3 +2,4 @@ export const URL_API_LOGIN = '/login'
export const URL_API_TOKEN = '/token'
export const URL_API_LOGOUT = '/logout'
export const URL_API_USER_INFO = '/system/user/info'
export const URL_API_USER_LIST = '/system/user'

30
src/global.d.ts vendored
View File

@@ -75,10 +75,26 @@ type UserWithPowerInfoVo = {
operations: OperationVo[]
}
type UserWithRoleInfoVo = {
id: string
username: string
locking: boolean
expiration: Date
credentialsExpiration: Date
enable: number
lastLoginTime: Date
lastLoginIp: string
createTime: Date
updateTime: Date
userInfo: UserInfoVo
roles: RoleVo[]
groups: GroupVo[]
}
type UserInfoVo = {
id: string
userId: string
nickName: string
nickname: string
avatar: string
email: string
}
@@ -113,6 +129,18 @@ type OperationVo = {
elementId: number
}
type RoleVo = {
id: string
name: string
enable: boolean
}
type GroupVo = {
id: string
name: string
enable: boolean
}
type LoginForm = {
username: string
password: string

View File

@@ -4,7 +4,7 @@ import zh_CN from 'antd/locale/zh_CN'
import '@/assets/css/base.scss'
import '@/assets/css/common.scss'
import App from './App'
import { COLOR_MAIN } from '@/constants/common.constants.ts'
import { COLOR_MAIN } from '@/constants/common.constants'
ReactDOM.createRoot(document.getElementById('root')!).render(
<React.StrictMode>

View File

@@ -39,7 +39,7 @@ const Login: React.FC = () => {
description: (
<>
<span>
<strong>{user.userInfo.nickName}</strong>
<strong>{user.userInfo.nickname}</strong>
</span>
<br />
<span>

View File

@@ -7,6 +7,7 @@ import Sidebar from '@/components/common/sidebar'
import SidebarItemList from '@/components/common/sidebar/SidebarItemList'
import SidebarItem from '@/components/common/sidebar/SidebarItem'
import SidebarSeparate from '@/components/common/sidebar/SidebarSeparate'
import LoadingMask from '@/components/common/LoadingMask'
const ToolsFramework: React.FC = () => {
const sidebarScrollRef = useRef<SidebarScrollElement>(null)
@@ -63,7 +64,15 @@ const ToolsFramework: React.FC = () => {
</Sidebar>
</div>
<div className={'right-panel'}>
<Suspense
fallback={
<>
<LoadingMask />
</>
}
>
<Outlet />
</Suspense>
</div>
</FitFullScreen>
</>

View File

@@ -5,7 +5,8 @@ import FitFullScreen from '@/components/common/FitFullScreen'
import Sidebar from '@/components/common/sidebar'
import SidebarItemList from '@/components/common/sidebar/SidebarItemList'
import SidebarItem from '@/components/common/sidebar/SidebarItem'
import { hasPathPermission } from '@/utils/auth.ts'
import { hasPathPermission } from '@/utils/auth'
import LoadingMask from '@/components/common/LoadingMask'
const ToolsFramework: React.FC = () => {
return (
@@ -42,7 +43,15 @@ const ToolsFramework: React.FC = () => {
</Sidebar>
</div>
<div className={'right-panel'}>
<Suspense
fallback={
<>
<LoadingMask />
</>
}
>
<Outlet />
</Suspense>
</div>
</FitFullScreen>
</>

View File

@@ -1,7 +1,50 @@
import React from 'react'
import { r_getUserList } from '@/services/user'
import { COLOR_BACKGROUND, DATABASE_SELECT_SUCCESS } from '@/constants/common.constants'
import { ColumnsType } from 'antd/es/table/interface'
const User: React.FC = () => {
return <></>
const [userList, setUserList] = useState<UserWithRoleInfoVo[]>([])
const tableColumns: ColumnsType<UserWithRoleInfoVo> = [
{
dataIndex: 'id',
title: 'ID'
},
{
dataIndex: ['userInfo', 'avatar'],
title: '头像',
render: (value) => (
<AntdAvatar
src={<img src={`data:image/png;base64,${value}`} alt={'avatar'} />}
style={{ background: COLOR_BACKGROUND }}
/>
)
},
{
dataIndex: 'username',
title: '用户名'
},
{
dataIndex: ['userInfo', 'nickname'],
title: '昵称'
}
]
useEffect(() => {
r_getUserList().then((res) => {
const data = res.data
if (data.code === DATABASE_SELECT_SUCCESS) {
data.data && setUserList(data.data)
}
})
}, [])
return (
<>
<AntdTable dataSource={userList} columns={tableColumns} rowKey={'id'} />
</>
)
}
export default User

10
src/services/auth.tsx Normal file
View File

@@ -0,0 +1,10 @@
import request from '@/services'
import { URL_API_LOGIN, URL_API_LOGOUT } from '@/constants/urls.constants'
export const r_login = (username: string, password: string) =>
request.post<TokenVo>(URL_API_LOGIN, {
username,
password
})
export const r_logout = () => request.post(URL_API_LOGOUT)

6
src/services/user.tsx Normal file
View File

@@ -0,0 +1,6 @@
import request from '@/services'
import { URL_API_USER_INFO, URL_API_USER_LIST } from '@/constants/urls.constants'
export const r_getInfo = () => request.get<UserWithPowerInfoVo>(URL_API_USER_INFO)
export const r_getUserList = () => request.get<UserWithRoleInfoVo[]>(URL_API_USER_LIST)

View File

@@ -1,23 +1,20 @@
import { getCaptcha, getLocalStorage, removeToken, setLocalStorage } from './common'
import request from '@/services'
import { r_login, r_logout } from '@/services/auth'
import { r_getInfo } from '@/services/user'
import {
STORAGE_TOKEN_KEY,
STORAGE_USER_INFO_KEY,
DATABASE_SELECT_SUCCESS
} from '@/constants/common.constants'
import { URL_API_LOGIN, URL_API_LOGOUT, URL_API_USER_INFO } from '@/constants/urls.constants'
let captcha: Captcha
export const login = async (username: string, password: string) => {
return await request.post<TokenVo>(URL_API_LOGIN, {
username,
password
})
return await r_login(username, password)
}
export const logout = async () => {
return request.post(URL_API_LOGOUT).finally(() => {
return r_logout().finally(() => {
removeToken()
})
}
@@ -40,7 +37,7 @@ export const getUserInfo = async (): Promise<UserWithPowerInfoVo> => {
export const requestUserInfo = async () => {
let user: UserWithPowerInfoVo | null
await request.get<UserWithPowerInfoVo>(URL_API_USER_INFO).then((value) => {
await r_getInfo().then((value) => {
const response = value.data
if (response.code === DATABASE_SELECT_SUCCESS) {
user = response.data
@@ -56,10 +53,10 @@ export const requestUserInfo = async () => {
})
}
export const getNickName = async () => {
export const getNickname = async () => {
const user = await getUserInfo()
return user.userInfo.nickName
return user.userInfo.nickname
}
export const getUsername = async () => {