Complete main UI #37
2
src/ant-design.d.ts
vendored
2
src/ant-design.d.ts
vendored
@@ -2,6 +2,7 @@ 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 { TablePaginationConfig } from 'antd/lib'
|
||||||
import { ColumnsType, FilterValue, SorterResult, SortOrder } from 'antd/es/table/interface'
|
import { ColumnsType, FilterValue, SorterResult, SortOrder } from 'antd/es/table/interface'
|
||||||
|
import { CheckboxChangeEvent } from 'antd/es/checkbox'
|
||||||
|
|
||||||
declare global {
|
declare global {
|
||||||
type IconComponent =
|
type IconComponent =
|
||||||
@@ -14,4 +15,5 @@ declare global {
|
|||||||
type _FilterValue = FilterValue
|
type _FilterValue = FilterValue
|
||||||
type _SorterResult<T> = SorterResult<T>
|
type _SorterResult<T> = SorterResult<T>
|
||||||
type _SortOrder = SortOrder
|
type _SortOrder = SortOrder
|
||||||
|
type _CheckboxChangeEvent = CheckboxChangeEvent
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,5 +1,5 @@
|
|||||||
.flex-box {
|
.flex-box {
|
||||||
* {
|
> * {
|
||||||
flex: 1;
|
flex: 1;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
9
src/global.d.ts
vendored
9
src/global.d.ts
vendored
@@ -161,11 +161,18 @@ interface PageParam {
|
|||||||
sortOrder?: string
|
sortOrder?: string
|
||||||
}
|
}
|
||||||
|
|
||||||
|
interface GetSysLogParams extends PageParam {
|
||||||
|
searchRequestUrl?: string
|
||||||
|
searchRegex?: boolean
|
||||||
|
searchStartTime?: string
|
||||||
|
searchEndTime?: string
|
||||||
|
}
|
||||||
|
|
||||||
interface TableParams {
|
interface TableParams {
|
||||||
pagination?: _TablePaginationConfig
|
pagination?: _TablePaginationConfig
|
||||||
sortField?: React.Key | readonly React.Key[]
|
sortField?: React.Key | readonly React.Key[]
|
||||||
sortOrder?: _SortOrder
|
sortOrder?: _SortOrder
|
||||||
filters?: Record<string, FilterVal | null>
|
filters?: Record<string, _FilterValue | null>
|
||||||
}
|
}
|
||||||
|
|
||||||
interface SysLogGetVo {
|
interface SysLogGetVo {
|
||||||
|
|||||||
@@ -1,15 +1,17 @@
|
|||||||
import React, { useState } from 'react'
|
import React from 'react'
|
||||||
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 { COLOR_FONT_SECONDARY, DATABASE_SELECT_SUCCESS } from '@/constants/common.constants.ts'
|
import {
|
||||||
|
COLOR_ERROR_SECONDARY,
|
||||||
|
COLOR_FONT_SECONDARY,
|
||||||
|
DATABASE_SELECT_SUCCESS
|
||||||
|
} from '@/constants/common.constants.ts'
|
||||||
import HideScrollbar from '@/components/common/HideScrollbar.tsx'
|
import HideScrollbar from '@/components/common/HideScrollbar.tsx'
|
||||||
import { getLocalTime } from '@/utils/common.ts'
|
import { getLocalTime } from '@/utils/common.ts'
|
||||||
import useMessage from 'antd/es/message/useMessage'
|
import FlexBox from '@/components/common/FlexBox'
|
||||||
import FlexBox from '@/components/common/FlexBox.tsx'
|
|
||||||
|
|
||||||
const Log: React.FC = () => {
|
const Log: React.FC = () => {
|
||||||
const [message, contextHolder] = useMessage()
|
|
||||||
const [logData, setLogData] = useState<SysLogGetVo[]>([])
|
const [logData, setLogData] = useState<SysLogGetVo[]>([])
|
||||||
const [loading, setLoading] = useState(false)
|
const [loading, setLoading] = useState(false)
|
||||||
const [tableParams, setTableParams] = useState<TableParams>({
|
const [tableParams, setTableParams] = useState<TableParams>({
|
||||||
@@ -19,6 +21,10 @@ const Log: React.FC = () => {
|
|||||||
position: ['bottomCenter']
|
position: ['bottomCenter']
|
||||||
}
|
}
|
||||||
})
|
})
|
||||||
|
const [searchRequestUrl, setSearchRequestUrl] = useState('')
|
||||||
|
const [useRegex, setUseRegex] = useState(false)
|
||||||
|
const [isRegexLegal, setIsRegexLegal] = useState(true)
|
||||||
|
const [timeRange, setTimeRange] = useState<[string, string]>()
|
||||||
|
|
||||||
const dataColumns: _ColumnsType<SysLogGetVo> = [
|
const dataColumns: _ColumnsType<SysLogGetVo> = [
|
||||||
{
|
{
|
||||||
@@ -102,7 +108,12 @@ const Log: React.FC = () => {
|
|||||||
title: '异常',
|
title: '异常',
|
||||||
dataIndex: 'exception',
|
dataIndex: 'exception',
|
||||||
render: (value: boolean, record) => (value ? record.exceptionInfo : '无'),
|
render: (value: boolean, record) => (value ? record.exceptionInfo : '无'),
|
||||||
align: 'center'
|
align: 'center',
|
||||||
|
onCell: () => ({
|
||||||
|
style: {
|
||||||
|
wordBreak: 'break-word'
|
||||||
|
}
|
||||||
|
})
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
title: '用户代理',
|
title: '用户代理',
|
||||||
@@ -140,28 +151,87 @@ const Log: React.FC = () => {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
const handleOnSearchUrlChange = (e: React.ChangeEvent<HTMLInputElement>) => {
|
||||||
|
setSearchRequestUrl(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 handleOnSearchUrlKeyDown = (e: React.KeyboardEvent) => {
|
||||||
|
if (e.key === 'Enter') {
|
||||||
|
getLog()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
const handleOnUseRegexChange = (e: _CheckboxChangeEvent) => {
|
||||||
|
setUseRegex(e.target.checked)
|
||||||
|
if (e.target.checked) {
|
||||||
|
try {
|
||||||
|
RegExp(searchRequestUrl)
|
||||||
|
setIsRegexLegal(
|
||||||
|
!(searchRequestUrl.includes('{}') || searchRequestUrl.includes('[]'))
|
||||||
|
)
|
||||||
|
} catch (e) {
|
||||||
|
setIsRegexLegal(false)
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
setIsRegexLegal(true)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
const handleOnDateRangeChange = (_dates: unknown, dateStrings: [string, string]) => {
|
||||||
|
if (dateStrings[0] && dateStrings[1]) {
|
||||||
|
setTimeRange([
|
||||||
|
new Date(dateStrings[0]).toISOString(),
|
||||||
|
new Date(dateStrings[1]).toISOString()
|
||||||
|
])
|
||||||
|
} else {
|
||||||
|
setTimeRange(undefined)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
const handleOnQueryBtnClick = () => {
|
||||||
|
getLog()
|
||||||
|
}
|
||||||
|
|
||||||
const getLog = () => {
|
const getLog = () => {
|
||||||
if (loading) {
|
if (loading) {
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (!isRegexLegal) {
|
||||||
|
void message.error({
|
||||||
|
content: '非法正则表达式'
|
||||||
|
})
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
setLoading(true)
|
setLoading(true)
|
||||||
|
|
||||||
void r_getSysLog(
|
void r_getSysLog({
|
||||||
tableParams.sortField && tableParams.sortOrder
|
currentPage: tableParams.pagination?.current,
|
||||||
? {
|
pageSize: tableParams.pagination?.pageSize,
|
||||||
currentPage: tableParams.pagination?.current,
|
sortField:
|
||||||
pageSize: tableParams.pagination?.pageSize,
|
tableParams.sortField && tableParams.sortOrder
|
||||||
sortField: tableParams.sortField as string,
|
? (tableParams.sortField as string)
|
||||||
sortOrder: tableParams.sortOrder,
|
: undefined,
|
||||||
...tableParams.filters
|
sortOrder:
|
||||||
}
|
tableParams.sortField && tableParams.sortOrder ? tableParams.sortOrder : undefined,
|
||||||
: {
|
searchRequestUrl: searchRequestUrl.trim().length ? searchRequestUrl : undefined,
|
||||||
currentPage: tableParams.pagination?.current,
|
searchRegex: useRegex ? useRegex : undefined,
|
||||||
pageSize: tableParams.pagination?.pageSize,
|
searchStartTime: timeRange && timeRange[0],
|
||||||
...tableParams.filters
|
searchEndTime: timeRange && timeRange[1],
|
||||||
}
|
...tableParams.filters
|
||||||
)
|
})
|
||||||
.then((res) => {
|
.then((res) => {
|
||||||
const data = res.data
|
const data = res.data
|
||||||
if (data.code === DATABASE_SELECT_SUCCESS) {
|
if (data.code === DATABASE_SELECT_SUCCESS) {
|
||||||
@@ -198,14 +268,13 @@ const Log: React.FC = () => {
|
|||||||
return (
|
return (
|
||||||
<>
|
<>
|
||||||
<FitFullScreen>
|
<FitFullScreen>
|
||||||
{contextHolder}
|
|
||||||
<HideScrollbar
|
<HideScrollbar
|
||||||
style={{ padding: 30 }}
|
style={{ padding: 30 }}
|
||||||
isShowVerticalScrollbar
|
isShowVerticalScrollbar
|
||||||
autoHideWaitingTime={500}
|
autoHideWaitingTime={500}
|
||||||
>
|
>
|
||||||
<FlexBox gap={20}>
|
<FlexBox gap={20}>
|
||||||
<FlexBox direction={'horizontal'}>
|
<FlexBox direction={'horizontal'} gap={10}>
|
||||||
<Card style={{ overflow: 'inherit' }}>
|
<Card style={{ overflow: 'inherit' }}>
|
||||||
<AntdInput
|
<AntdInput
|
||||||
addonBefore={
|
addonBefore={
|
||||||
@@ -219,14 +288,39 @@ const Log: React.FC = () => {
|
|||||||
</span>
|
</span>
|
||||||
}
|
}
|
||||||
suffix={
|
suffix={
|
||||||
<AntdTooltip title={'正则表达式'}>
|
<>
|
||||||
<AntdCheckbox>.*</AntdCheckbox>
|
{!isRegexLegal ? (
|
||||||
</AntdTooltip>
|
<span style={{ color: COLOR_ERROR_SECONDARY }}>
|
||||||
|
非法表达式
|
||||||
|
</span>
|
||||||
|
) : undefined}
|
||||||
|
<AntdCheckbox
|
||||||
|
checked={useRegex}
|
||||||
|
onChange={handleOnUseRegexChange}
|
||||||
|
>
|
||||||
|
<AntdTooltip title={'正则表达式'}>.*</AntdTooltip>
|
||||||
|
</AntdCheckbox>
|
||||||
|
</>
|
||||||
}
|
}
|
||||||
|
allowClear
|
||||||
|
value={searchRequestUrl}
|
||||||
|
onChange={handleOnSearchUrlChange}
|
||||||
|
onKeyDown={handleOnSearchUrlKeyDown}
|
||||||
|
status={isRegexLegal ? undefined : 'error'}
|
||||||
/>
|
/>
|
||||||
</Card>
|
</Card>
|
||||||
<Card style={{ overflow: 'inherit', flex: 'auto' }}>
|
<Card style={{ overflow: 'inherit', flex: '0 0 auto' }}>
|
||||||
<AntdDatePicker.RangePicker showTime />
|
<AntdDatePicker.RangePicker
|
||||||
|
showTime
|
||||||
|
allowClear
|
||||||
|
changeOnBlur
|
||||||
|
onChange={handleOnDateRangeChange}
|
||||||
|
/>
|
||||||
|
</Card>
|
||||||
|
<Card style={{ overflow: 'inherit', flex: '0 0 auto' }}>
|
||||||
|
<AntdButton onClick={handleOnQueryBtnClick} type={'primary'}>
|
||||||
|
查询
|
||||||
|
</AntdButton>
|
||||||
</Card>
|
</Card>
|
||||||
</FlexBox>
|
</FlexBox>
|
||||||
<Card>
|
<Card>
|
||||||
|
|||||||
@@ -1,5 +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 = (param: PageParam) =>
|
export const r_getSysLog = (param: GetSysLogParams) =>
|
||||||
request.get<PageVo<SysLogGetVo>>(URL_API_SYS_LOG, { ...param })
|
request.get<PageVo<SysLogGetVo>>(URL_API_SYS_LOG, { ...param })
|
||||||
|
|||||||
Reference in New Issue
Block a user