Complete main UI #37
6
src/ant-design.d.ts
vendored
6
src/ant-design.d.ts
vendored
@@ -1,8 +1,14 @@
|
|||||||
import * as React from 'react'
|
import * as React from 'react'
|
||||||
import { CustomIconComponentProps } from '@ant-design/icons/es/components/Icon'
|
import { CustomIconComponentProps } from '@ant-design/icons/es/components/Icon'
|
||||||
|
import { TablePaginationConfig } from 'antd/lib'
|
||||||
|
import { FilterValue } from 'antd/es/table/interface'
|
||||||
|
|
||||||
declare global {
|
declare global {
|
||||||
type IconComponent =
|
type IconComponent =
|
||||||
| React.ComponentType<CustomIconComponentProps | React.SVGProps<SVGSVGElement>>
|
| React.ComponentType<CustomIconComponentProps | React.SVGProps<SVGSVGElement>>
|
||||||
| React.ForwardRefExoticComponent<CustomIconComponentProps>
|
| React.ForwardRefExoticComponent<CustomIconComponentProps>
|
||||||
|
|
||||||
|
type PaginationConfig = TablePaginationConfig
|
||||||
|
|
||||||
|
type FilterVal = FilterValue
|
||||||
}
|
}
|
||||||
|
|||||||
16
src/assets/css/pages/system-framework.scss
Normal file
16
src/assets/css/pages/system-framework.scss
Normal file
@@ -0,0 +1,16 @@
|
|||||||
|
@use "@/assets/css/constants" as constants;
|
||||||
|
@use "@/assets/css/mixins" as mixins;
|
||||||
|
|
||||||
|
body {
|
||||||
|
background-color: constants.$background-color;
|
||||||
|
}
|
||||||
|
|
||||||
|
.left-panel {
|
||||||
|
background-color: constants.$origin-color;
|
||||||
|
}
|
||||||
|
|
||||||
|
.right-panel {
|
||||||
|
flex: 1;
|
||||||
|
width: 0;
|
||||||
|
background-color: constants.$background-color;
|
||||||
|
}
|
||||||
@@ -4,9 +4,9 @@ import '@/assets/css/components/common/card.scss'
|
|||||||
interface CardProps
|
interface CardProps
|
||||||
extends React.DetailedHTMLProps<React.HTMLAttributes<HTMLDivElement>, HTMLDivElement> {}
|
extends React.DetailedHTMLProps<React.HTMLAttributes<HTMLDivElement>, HTMLDivElement> {}
|
||||||
|
|
||||||
const Card: React.FC<CardProps> = (props) => {
|
const Card = forwardRef<HTMLDivElement, CardProps>((props, ref) => {
|
||||||
const { className, ..._props } = props
|
const { className, ..._props } = props
|
||||||
return <div className={`card-box${className ? ` ${className}` : ''}`} {..._props} />
|
return <div className={`card-box${className ? ` ${className}` : ''}`} {..._props} ref={ref} />
|
||||||
}
|
})
|
||||||
|
|
||||||
export default Card
|
export default Card
|
||||||
|
|||||||
48
src/global.d.ts
vendored
48
src/global.d.ts
vendored
@@ -61,13 +61,13 @@ interface UserWithPowerInfoVo {
|
|||||||
id: string
|
id: string
|
||||||
username: string
|
username: string
|
||||||
locking: boolean
|
locking: boolean
|
||||||
expiration: Date
|
expiration: string
|
||||||
credentialsExpiration: Date
|
credentialsExpiration: string
|
||||||
enable: number
|
enable: number
|
||||||
lastLoginTime: Date
|
lastLoginTime: string
|
||||||
lastLoginIp: string
|
lastLoginIp: string
|
||||||
createTime: Date
|
createTime: string
|
||||||
updateTime: Date
|
updateTime: string
|
||||||
userInfo: UserInfoVo
|
userInfo: UserInfoVo
|
||||||
modules: ModuleVo[]
|
modules: ModuleVo[]
|
||||||
menus: MenuVo[]
|
menus: MenuVo[]
|
||||||
@@ -79,13 +79,13 @@ interface UserWithRoleInfoVo {
|
|||||||
id: string
|
id: string
|
||||||
username: string
|
username: string
|
||||||
locking: boolean
|
locking: boolean
|
||||||
expiration: Date
|
expiration: string
|
||||||
credentialsExpiration: Date
|
credentialsExpiration: string
|
||||||
enable: number
|
enable: number
|
||||||
lastLoginTime: Date
|
lastLoginTime: string
|
||||||
lastLoginIp: string
|
lastLoginIp: string
|
||||||
createTime: Date
|
createTime: string
|
||||||
updateTime: Date
|
updateTime: string
|
||||||
userInfo: UserInfoVo
|
userInfo: UserInfoVo
|
||||||
roles: RoleVo[]
|
roles: RoleVo[]
|
||||||
groups: GroupVo[]
|
groups: GroupVo[]
|
||||||
@@ -146,20 +146,40 @@ interface LoginForm {
|
|||||||
password: string
|
password: string
|
||||||
}
|
}
|
||||||
|
|
||||||
|
interface PageVo<T> {
|
||||||
|
current: number
|
||||||
|
pages: number
|
||||||
|
size: number
|
||||||
|
total: number
|
||||||
|
records: T[]
|
||||||
|
}
|
||||||
|
|
||||||
|
interface PageParam {
|
||||||
|
currentPage?: number
|
||||||
|
pageSize?: number
|
||||||
|
}
|
||||||
|
|
||||||
|
interface TableParams {
|
||||||
|
pagination?: PaginationConfig
|
||||||
|
sortField?: string
|
||||||
|
sortOrder?: string
|
||||||
|
filters?: Record<string, FilterVal | null>
|
||||||
|
}
|
||||||
|
|
||||||
interface SysLogGetVo {
|
interface SysLogGetVo {
|
||||||
id: string
|
id: string
|
||||||
logType: string
|
logType: string
|
||||||
operateUserId: string
|
operateUserId: string
|
||||||
operateTime: Date
|
operateTime: string
|
||||||
requestUri: string
|
requestUri: string
|
||||||
requestMethod: string
|
requestMethod: string
|
||||||
requestParams: string
|
requestParams: string
|
||||||
requestIp: string
|
requestIp: string
|
||||||
requestServerAddress: string
|
requestServerAddress: string
|
||||||
isException: boolean
|
exception: boolean
|
||||||
exceptionInfo: string
|
exceptionInfo: string
|
||||||
startTime: Date
|
startTime: string
|
||||||
endTime: Date
|
endTime: string
|
||||||
executeTime: number
|
executeTime: number
|
||||||
userAgent: string
|
userAgent: string
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,8 +1,7 @@
|
|||||||
import React from 'react'
|
import React from 'react'
|
||||||
import { notification } from 'antd'
|
import { notification } from 'antd'
|
||||||
import moment from 'moment'
|
|
||||||
import '@/assets/css/pages/login.scss'
|
import '@/assets/css/pages/login.scss'
|
||||||
import { setToken } from '@/utils/common'
|
import { getLocalTime, setToken } from '@/utils/common'
|
||||||
import { getUserInfo, login } from '@/utils/auth'
|
import { getUserInfo, login } from '@/utils/auth'
|
||||||
import {
|
import {
|
||||||
SYSTEM_LOGIN_SUCCESS,
|
SYSTEM_LOGIN_SUCCESS,
|
||||||
@@ -44,10 +43,8 @@ const Login: React.FC = () => {
|
|||||||
<br />
|
<br />
|
||||||
<span>
|
<span>
|
||||||
上次登录:
|
上次登录:
|
||||||
{moment(user.lastLoginTime).format(
|
{getLocalTime(user.lastLoginTime)}【
|
||||||
'yyyy-MM-DD HH:mm:ssZ'
|
{user.lastLoginIp}】
|
||||||
)}
|
|
||||||
【{user.lastLoginIp}】
|
|
||||||
</span>
|
</span>
|
||||||
</>
|
</>
|
||||||
),
|
),
|
||||||
|
|||||||
@@ -1,6 +1,6 @@
|
|||||||
import React from 'react'
|
import React from 'react'
|
||||||
import system from '@/router/system'
|
import system from '@/router/system'
|
||||||
import '@/assets/css/pages/tools-framework.scss'
|
import '@/assets/css/pages/system-framework.scss'
|
||||||
import FitFullScreen from '@/components/common/FitFullScreen'
|
import FitFullScreen from '@/components/common/FitFullScreen'
|
||||||
import Sidebar from '@/components/common/sidebar'
|
import Sidebar from '@/components/common/sidebar'
|
||||||
import SidebarItemList from '@/components/common/sidebar/SidebarItemList'
|
import SidebarItemList from '@/components/common/sidebar/SidebarItemList'
|
||||||
|
|||||||
@@ -1,31 +1,140 @@
|
|||||||
import React, { useState } from 'react'
|
import React, { useState } from 'react'
|
||||||
|
import { ColumnsType, FilterValue, SorterResult } from 'antd/es/table/interface'
|
||||||
|
import { TablePaginationConfig } from 'antd/lib'
|
||||||
import FitFullScreen from '@/components/common/FitFullScreen.tsx'
|
import FitFullScreen from '@/components/common/FitFullScreen.tsx'
|
||||||
import Card from '@/components/common/Card'
|
import Card from '@/components/common/Card'
|
||||||
import { r_getSysLog } from '@/services/system.tsx'
|
import { r_getSysLog } from '@/services/system.tsx'
|
||||||
import { DATABASE_SELECT_SUCCESS } from '@/constants/common.constants.ts'
|
import { DATABASE_SELECT_SUCCESS } from '@/constants/common.constants.ts'
|
||||||
|
import HideScrollbar from '@/components/common/HideScrollbar.tsx'
|
||||||
|
import { getLocalTime } from '@/utils/common.ts'
|
||||||
|
|
||||||
const Log: React.FC = () => {
|
const Log: React.FC = () => {
|
||||||
const [logList, setLogList] = useState<SysLogGetVo[]>([])
|
const tableCardRef = useRef<HTMLDivElement>(null)
|
||||||
|
const [logData, setLogData] = useState<SysLogGetVo[]>([])
|
||||||
|
const [loading, setLoading] = useState(false)
|
||||||
|
const [tableParams, setTableParams] = useState<TableParams>({
|
||||||
|
pagination: {
|
||||||
|
current: 1,
|
||||||
|
pageSize: 20,
|
||||||
|
position: ['bottomCenter']
|
||||||
|
}
|
||||||
|
})
|
||||||
|
|
||||||
|
const dataColumns: ColumnsType<SysLogGetVo> = [
|
||||||
|
{ title: '类型', dataIndex: 'logType' },
|
||||||
|
{
|
||||||
|
title: '操作者',
|
||||||
|
dataIndex: 'operateUserId'
|
||||||
|
},
|
||||||
|
{
|
||||||
|
title: '操作时间',
|
||||||
|
dataIndex: 'operateTime',
|
||||||
|
render: (value) => getLocalTime(value)
|
||||||
|
},
|
||||||
|
{
|
||||||
|
title: '请求 Uri',
|
||||||
|
dataIndex: 'requestUri'
|
||||||
|
},
|
||||||
|
{
|
||||||
|
title: '请求方式',
|
||||||
|
dataIndex: 'requestMethod'
|
||||||
|
},
|
||||||
|
{
|
||||||
|
title: '请求参数',
|
||||||
|
dataIndex: 'requestParams'
|
||||||
|
},
|
||||||
|
{
|
||||||
|
title: '请求 IP',
|
||||||
|
dataIndex: 'requestIp'
|
||||||
|
},
|
||||||
|
{
|
||||||
|
title: '请求服务器地址',
|
||||||
|
dataIndex: 'requestServerAddress'
|
||||||
|
},
|
||||||
|
{
|
||||||
|
title: '异常信息',
|
||||||
|
dataIndex: 'exceptionInfo'
|
||||||
|
},
|
||||||
|
{
|
||||||
|
title: '执行时间',
|
||||||
|
dataIndex: 'executeTime',
|
||||||
|
render: (value) => `${value}ms`
|
||||||
|
},
|
||||||
|
{
|
||||||
|
title: '用户代理',
|
||||||
|
dataIndex: 'userAgent'
|
||||||
|
}
|
||||||
|
]
|
||||||
|
|
||||||
|
const handleOnTableChange = (
|
||||||
|
pagination: TablePaginationConfig,
|
||||||
|
filters: Record<string, FilterValue | null>,
|
||||||
|
sorter: SorterResult<SysLogGetVo> | SorterResult<SysLogGetVo>[]
|
||||||
|
) => {
|
||||||
|
setTableParams({ pagination, filters, ...sorter })
|
||||||
|
|
||||||
|
if (pagination.pageSize !== tableParams.pagination?.pageSize) {
|
||||||
|
setLogData([])
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
const getLog = () => {
|
const getLog = () => {
|
||||||
r_getSysLog().then((res) => {
|
if (loading) {
|
||||||
const data = res.data
|
return
|
||||||
if (data.code === DATABASE_SELECT_SUCCESS) {
|
}
|
||||||
data.data && setLogList(data.data)
|
|
||||||
}
|
r_getSysLog({
|
||||||
|
currentPage: tableParams.pagination?.current,
|
||||||
|
pageSize: tableParams.pagination?.pageSize
|
||||||
})
|
})
|
||||||
|
.then((res) => {
|
||||||
|
const data = res.data
|
||||||
|
if (data.code === DATABASE_SELECT_SUCCESS) {
|
||||||
|
data.data && setLogData(data.data.records)
|
||||||
|
data.data &&
|
||||||
|
setTableParams({
|
||||||
|
...tableParams,
|
||||||
|
pagination: {
|
||||||
|
...tableParams.pagination,
|
||||||
|
total: data.data.total
|
||||||
|
}
|
||||||
|
})
|
||||||
|
}
|
||||||
|
})
|
||||||
|
.finally(() => {
|
||||||
|
setLoading(false)
|
||||||
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
useEffect(() => {
|
useEffect(() => {
|
||||||
getLog()
|
getLog()
|
||||||
}, [])
|
}, [
|
||||||
|
JSON.stringify(tableParams.filters),
|
||||||
|
JSON.stringify(tableParams.sortField),
|
||||||
|
JSON.stringify(tableParams.sortOrder),
|
||||||
|
JSON.stringify(tableParams.pagination?.pageSize),
|
||||||
|
JSON.stringify(tableParams.pagination?.current)
|
||||||
|
])
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<>
|
<>
|
||||||
<FitFullScreen style={{ padding: '20px' }}>
|
<FitFullScreen>
|
||||||
<Card>
|
<HideScrollbar
|
||||||
<AntdTable dataSource={logList} />
|
style={{ padding: 30 }}
|
||||||
</Card>
|
isShowVerticalScrollbar
|
||||||
|
autoHideWaitingTime={500}
|
||||||
|
>
|
||||||
|
<Card ref={tableCardRef}>
|
||||||
|
<AntdTable
|
||||||
|
dataSource={logData}
|
||||||
|
columns={dataColumns}
|
||||||
|
rowKey={(record) => record.id}
|
||||||
|
pagination={tableParams.pagination}
|
||||||
|
loading={loading}
|
||||||
|
onChange={handleOnTableChange}
|
||||||
|
/>
|
||||||
|
</Card>
|
||||||
|
</HideScrollbar>
|
||||||
</FitFullScreen>
|
</FitFullScreen>
|
||||||
</>
|
</>
|
||||||
)
|
)
|
||||||
|
|||||||
@@ -1,4 +1,5 @@
|
|||||||
import request from '@/services/index'
|
import request from '@/services/index'
|
||||||
import { URL_API_SYS_LOG } from '@/constants/urls.constants'
|
import { URL_API_SYS_LOG } from '@/constants/urls.constants'
|
||||||
|
|
||||||
export const r_getSysLog = () => request.get<SysLogGetVo[]>(URL_API_SYS_LOG)
|
export const r_getSysLog = (param: PageParam) =>
|
||||||
|
request.get<PageVo<SysLogGetVo>>(URL_API_SYS_LOG, { ...param })
|
||||||
|
|||||||
@@ -1,4 +1,5 @@
|
|||||||
import { STORAGE_TOKEN_KEY, STORAGE_USER_INFO_KEY } from '@/constants/common.constants'
|
import { STORAGE_TOKEN_KEY, STORAGE_USER_INFO_KEY } from '@/constants/common.constants'
|
||||||
|
import moment from 'moment'
|
||||||
|
|
||||||
export const getQueryVariable = (variable: string) => {
|
export const getQueryVariable = (variable: string) => {
|
||||||
const query = window.location.search.substring(1)
|
const query = window.location.search.substring(1)
|
||||||
@@ -139,3 +140,7 @@ const randomColor = (start: number, end: number) => {
|
|||||||
export const getRedirectUrl = (path: string, redirectUrl: string): string => {
|
export const getRedirectUrl = (path: string, redirectUrl: string): string => {
|
||||||
return `${path}?redirect=${encodeURIComponent(redirectUrl)}`
|
return `${path}?redirect=${encodeURIComponent(redirectUrl)}`
|
||||||
}
|
}
|
||||||
|
|
||||||
|
export const getLocalTime = (utcTime: string, format: string = 'yyyy-MM-DD HH:mm:ssZ') => {
|
||||||
|
return moment.utc(utcTime).local().format(format)
|
||||||
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user