Add role table

This commit is contained in:
2023-11-10 11:57:55 +08:00
parent cece8b2a83
commit 66c88fec48
8 changed files with 313 additions and 16 deletions

2
src/ant-design.d.ts vendored
View File

@@ -3,6 +3,7 @@ import { CustomIconComponentProps } from '@ant-design/icons/es/components/Icon'
import { TablePaginationConfig } from 'antd/lib'
import { ColumnsType, FilterValue, SorterResult, SortOrder } from 'antd/es/table/interface'
import { CheckboxChangeEvent } from 'antd/es/checkbox'
import type { DataNode } from 'antd/es/tree'
declare global {
type IconComponent =
@@ -16,4 +17,5 @@ declare global {
type _SorterResult<T> = SorterResult<T>
type _SortOrder = SortOrder
type _CheckboxChangeEvent = CheckboxChangeEvent
type _DataNode = DataNode
}

View File

@@ -4,3 +4,4 @@ export const URL_API_LOGOUT = '/logout'
export const URL_API_SYS_LOG = '/system/log'
export const URL_API_USER_INFO = '/system/user/info'
export const URL_API_USER_LIST = '/system/user'
export const URL_API_SYS_ROLE = '/system/role'

31
src/global.d.ts vendored
View File

@@ -111,6 +111,7 @@ interface MenuVo {
url: string
powerId: number
parentId: number
moduleId: number
}
interface ElementVo {
@@ -161,13 +162,6 @@ interface PageParam {
sortOrder?: string
}
interface GetSysLogParams extends PageParam {
searchRequestUrl?: string
searchRegex?: boolean
searchStartTime?: string
searchEndTime?: string
}
interface TableParams {
pagination?: _TablePaginationConfig
sortField?: React.Key | readonly React.Key[]
@@ -175,6 +169,13 @@ interface TableParams {
filters?: Record<string, _FilterValue | null>
}
interface GetSysLogParams extends PageParam {
searchRequestUrl?: string
searchRegex?: boolean
searchStartTime?: string
searchEndTime?: string
}
interface SysLogGetVo {
id: string
logType: string
@@ -193,3 +194,19 @@ interface SysLogGetVo {
userAgent: string
operateUsername: string
}
interface GetRoleParams extends PageParam {
searchName?: string
searchRegex?: boolean
}
interface RoleWithPowerGetVo {
id: string
name: string
enable: string
modules: ModuleVo[]
menus: MenuVo[]
elements: ElementVo[]
operations: OperationVo[]
tree: _DataNode[]
}

View File

@@ -8,7 +8,10 @@ import { COLOR_MAIN } from '@/constants/common.constants'
ReactDOM.createRoot(document.getElementById('root')!).render(
<React.StrictMode>
<AntdConfigProvider theme={{ token: { colorPrimary: COLOR_MAIN } }} locale={zh_CN}>
<AntdConfigProvider
theme={{ token: { colorPrimary: COLOR_MAIN, colorBgContainer: 'transparent' } }}
locale={zh_CN}
>
<App />
</AntdConfigProvider>
</React.StrictMode>

View File

@@ -1,14 +1,14 @@
import React from 'react'
import FitFullScreen from '@/components/common/FitFullScreen.tsx'
import FitFullScreen from '@/components/common/FitFullScreen'
import Card from '@/components/common/Card'
import { r_getSysLog } from '@/services/system.tsx'
import { r_getSysLog } from '@/services/system'
import {
COLOR_ERROR_SECONDARY,
COLOR_FONT_SECONDARY,
DATABASE_SELECT_SUCCESS
} from '@/constants/common.constants.ts'
import HideScrollbar from '@/components/common/HideScrollbar.tsx'
import { getLocalTime } from '@/utils/common.ts'
} from '@/constants/common.constants'
import HideScrollbar from '@/components/common/HideScrollbar'
import { getLocalTime } from '@/utils/common'
import FlexBox from '@/components/common/FlexBox'
const Log: React.FC = () => {

View File

@@ -1,7 +1,265 @@
import React from 'react'
import React, { useState } from 'react'
import FitFullScreen from '@/components/common/FitFullScreen'
import HideScrollbar from '@/components/common/HideScrollbar'
import FlexBox from '@/components/common/FlexBox'
import Card from '@/components/common/Card'
import { r_getRole } from '@/services/system.tsx'
import { DATABASE_SELECT_SUCCESS } from '@/constants/common.constants.ts'
const Role: React.FC = () => {
return <></>
const [roleData, setRoleData] = useState<RoleWithPowerGetVo[]>([])
const [loading, setLoading] = useState(false)
const [tableParams, setTableParams] = useState<TableParams>({
pagination: {
current: 1,
pageSize: 20,
position: ['bottomCenter']
}
})
const [searchName, setSearchName] = useState('')
const [useRegex, setUseRegex] = useState(false)
const [isRegexLegal, setIsRegexLegal] = useState(true)
const dataColumns: _ColumnsType<RoleWithPowerGetVo> = [
{
title: '名称',
dataIndex: 'name',
width: '20%'
},
{
title: '权限',
dataIndex: 'tree',
render: (value: _DataNode[]) => <AntdTree treeData={value} />
},
{
title: '状态',
dataIndex: 'enable',
width: '0',
align: 'center',
render: (value) =>
value ? <AntdTag color={'success'}></AntdTag> : <AntdTag></AntdTag>
}
]
const handleOnTableChange = (
pagination: _TablePaginationConfig,
filters: Record<string, _FilterValue | null>,
sorter: _SorterResult<RoleWithPowerGetVo> | _SorterResult<RoleWithPowerGetVo>[]
) => {
if (Array.isArray(sorter)) {
setTableParams({
pagination,
filters,
sortField: sorter.map((value) => value.field).join(',')
})
} else {
setTableParams({
pagination,
filters,
sortField: sorter.field,
sortOrder: sorter.order
})
}
if (pagination.pageSize !== tableParams.pagination?.pageSize) {
setRoleData([])
}
}
const handleOnSearchNameChange = (e: React.ChangeEvent<HTMLInputElement>) => {
setSearchName(e.target.value)
if (useRegex) {
try {
RegExp(e.target.value)
setIsRegexLegal(!(e.target.value.includes('{}') || e.target.value.includes('[]')))
} catch (e) {
setIsRegexLegal(false)
}
} else {
setIsRegexLegal(true)
}
}
const handleOnSearchNameKeyDown = (e: React.KeyboardEvent) => {
if (e.key === 'Enter') {
getRole()
}
}
const handleOnUseRegexChange = (e: _CheckboxChangeEvent) => {
setUseRegex(e.target.checked)
if (e.target.checked) {
try {
RegExp(searchName)
setIsRegexLegal(!(searchName.includes('{}') || searchName.includes('[]')))
} catch (e) {
setIsRegexLegal(false)
}
} else {
setIsRegexLegal(true)
}
}
const handleOnQueryBtnClick = () => {
getRole()
}
const getRole = () => {
if (loading) {
return
}
if (!isRegexLegal) {
void message.error({
content: '非法正则表达式'
})
return
}
setLoading(true)
void r_getRole({
currentPage: tableParams.pagination?.current,
pageSize: tableParams.pagination?.pageSize,
sortField:
tableParams.sortField && tableParams.sortOrder
? (tableParams.sortField as string)
: undefined,
sortOrder:
tableParams.sortField && tableParams.sortOrder ? tableParams.sortOrder : undefined,
searchName: searchName.trim().length ? searchName : undefined,
searchRegex: useRegex ? useRegex : undefined,
...tableParams.filters
})
.then((res) => {
const data = res.data
if (data.code === DATABASE_SELECT_SUCCESS) {
const records = data.data?.records
records?.map((value) => {
const menuMap = new Map<number, _DataNode[]>()
const elementMap = new Map<number, _DataNode[]>()
const operationMap = new Map<number, _DataNode[]>()
value.operations.forEach((operation) => {
if (
operationMap.has(operation.elementId) &&
operationMap.get(operation.elementId) !== null
) {
operationMap
.get(operation.elementId)
?.push({ title: operation.name, key: operation.powerId })
} else {
operationMap.set(operation.elementId, [
{ title: operation.name, key: operation.powerId }
])
}
})
value.elements.forEach((element) => {
if (
elementMap.has(element.menuId) &&
elementMap.get(element.menuId) !== null
) {
elementMap.get(element.menuId)?.push({
title: element.name,
key: element.powerId,
children: operationMap.get(element.id)
})
} else {
elementMap.set(element.menuId, [
{
title: element.name,
key: element.powerId,
children: operationMap.get(element.id)
}
])
}
})
value.menus.forEach((menu) => {
if (menuMap.has(menu.moduleId) && menuMap.get(menu.moduleId) !== null) {
menuMap.get(menu.moduleId)?.push({
title: menu.name,
key: menu.powerId,
children: elementMap.get(menu.id)
})
} else {
menuMap.set(menu.moduleId, [
{
title: menu.name,
key: menu.powerId,
children: elementMap.get(menu.id)
}
])
}
})
value.tree = value.modules.map((module) => ({
title: module.name,
key: module.powerId,
children: menuMap.get(module.id)
}))
return value
})
records && setRoleData(records)
data.data &&
setTableParams({
...tableParams,
pagination: {
...tableParams.pagination,
total: data.data.total
}
})
} else {
void message.error({
content: '获取失败,请稍后重试'
})
}
})
.finally(() => {
setLoading(false)
})
}
useEffect(() => {
getRole()
}, [
JSON.stringify(tableParams.filters),
JSON.stringify(tableParams.sortField),
JSON.stringify(tableParams.sortOrder),
JSON.stringify(tableParams.pagination?.pageSize),
JSON.stringify(tableParams.pagination?.current)
])
return (
<>
<FitFullScreen>
<HideScrollbar
style={{ padding: 30 }}
isShowVerticalScrollbar
autoHideWaitingTime={500}
>
<FlexBox gap={20}>
<FlexBox direction={'horizontal'} gap={10}></FlexBox>
<Card>
<AntdTable
dataSource={roleData}
columns={dataColumns}
rowKey={(record) => record.id}
pagination={tableParams.pagination}
loading={loading}
onChange={handleOnTableChange}
/>
</Card>
</FlexBox>
</HideScrollbar>
</FitFullScreen>
</>
)
}
export default Role

View File

@@ -1,5 +1,8 @@
import request from '@/services/index'
import { URL_API_SYS_LOG } from '@/constants/urls.constants'
import { URL_API_SYS_LOG, URL_API_SYS_ROLE } from '@/constants/urls.constants'
export const r_getSysLog = (param: GetSysLogParams) =>
request.get<PageVo<SysLogGetVo>>(URL_API_SYS_LOG, { ...param })
export const r_getRole = (parm: GetRoleParams) =>
request.get<PageVo<RoleWithPowerGetVo>>(URL_API_SYS_ROLE, { ...parm })

View File

@@ -144,3 +144,16 @@ export const getRedirectUrl = (path: string, redirectUrl: string): string => {
export const getLocalTime = (utcTime: string, format: string = 'yyyy-MM-DD HH:mm:ssZ') => {
return moment.utc(utcTime).local().format(format)
}
export const floorNumber = (num: number, digits: number) => {
if (digits > 0) {
return Math.floor(num / Math.pow(10, digits - 1)) * Math.pow(10, digits - 1)
} else {
const regExpMatchArray = num.toString().match(new RegExp('^\\d\\.\\d{' + -digits + '}'))
if (regExpMatchArray !== null) {
return parseFloat(regExpMatchArray[0]).toFixed(-digits)
} else {
return num
}
}
}