-
-
Notifications
You must be signed in to change notification settings - Fork 6.8k
Expand file tree
/
Copy pathindex.js
More file actions
163 lines (151 loc) · 5.14 KB
/
Copy pathindex.js
File metadata and controls
163 lines (151 loc) · 5.14 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
import { useState, useEffect } from 'react';
import { showError } from 'utils/common';
import Table from '@mui/material/Table';
import TableBody from '@mui/material/TableBody';
import TableContainer from '@mui/material/TableContainer';
import PerfectScrollbar from 'react-perfect-scrollbar';
import TablePagination from '@mui/material/TablePagination';
import LinearProgress from '@mui/material/LinearProgress';
import ButtonGroup from '@mui/material/ButtonGroup';
import Toolbar from '@mui/material/Toolbar';
import { Button, Card, Stack, Container, Typography, Box } from '@mui/material';
import LogTableRow from './component/TableRow';
import LogTableHead from './component/TableHead';
import TableToolBar from './component/TableToolBar';
import { API } from 'utils/api';
import { isAdmin } from 'utils/common';
import { ITEMS_PER_PAGE } from 'constants';
import { IconRefresh, IconSearch } from '@tabler/icons-react';
export default function Log() {
const originalKeyword = {
p: 0,
username: '',
token_name: '',
model_name: '',
start_timestamp: 0,
end_timestamp: new Date().getTime() / 1000 + 3600,
type: 0,
channel: ''
};
const [logs, setLogs] = useState([]);
const [activePage, setActivePage] = useState(0);
const [searching, setSearching] = useState(false);
const [searchKeyword, setSearchKeyword] = useState(originalKeyword);
const [logCount, setLogCount] = useState(0);
const [initPage, setInitPage] = useState(true);
const userIsAdmin = isAdmin();
const loadLogs = async (startIdx) => {
setSearching(true);
const url = userIsAdmin ? '/api/log/' : '/api/log/self/';
const query = searchKeyword;
query.p = startIdx;
if (!userIsAdmin) {
delete query.username;
delete query.channel;
}
const res = await API.get(url, { params: query });
const { success, message, data, total } = res.data;
if (success) {
if (startIdx === 0) {
setLogs(data);
} else {
let newLogs = [...logs];
newLogs.splice(startIdx * ITEMS_PER_PAGE, data.length, ...data);
setLogs(newLogs);
}
if (total !== undefined) {
setLogCount(total);
}
} else {
showError(message);
}
setSearching(false);
};
const onPaginationChange = (event, newPage) => {
(async () => {
const pageStart = newPage * ITEMS_PER_PAGE;
const pageEnd = pageStart + ITEMS_PER_PAGE;
if (logs.slice(pageStart, pageEnd).length < ITEMS_PER_PAGE && pageStart < logCount) {
// Page data not yet loaded, fetch it from the backend.
await loadLogs(newPage);
}
setActivePage(newPage);
})();
};
const searchLogs = async (event) => {
event.preventDefault();
await loadLogs(0);
setActivePage(0);
return;
};
const handleSearchKeyword = (event) => {
setSearchKeyword({ ...searchKeyword, [event.target.name]: event.target.value });
};
// 处理刷新
const handleRefresh = () => {
setInitPage(true);
};
useEffect(() => {
setSearchKeyword(originalKeyword);
setActivePage(0);
loadLogs(0)
.then()
.catch((reason) => {
showError(reason);
});
setInitPage(false);
}, [initPage]);
return (
<>
<Stack direction="row" alignItems="center" justifyContent="space-between" mb={2.5}>
<Typography variant="h4">日志</Typography>
</Stack>
<Card>
<Box component="form" onSubmit={searchLogs} noValidate sx={{marginTop: 2}}>
<TableToolBar filterName={searchKeyword} handleFilterName={handleSearchKeyword} userIsAdmin={userIsAdmin} />
</Box>
<Toolbar
sx={{
textAlign: 'right',
height: 50,
display: 'flex',
justifyContent: 'space-between',
p: (theme) => theme.spacing(0, 1, 0, 3)
}}
>
<Container>
<ButtonGroup variant="outlined" aria-label="outlined small primary button group" sx={{marginBottom: 2}}>
<Button onClick={handleRefresh} startIcon={<IconRefresh width={'18px'} />}>
刷新/清除搜索条件
</Button>
<Button onClick={searchLogs} startIcon={<IconSearch width={'18px'} />}>
搜索
</Button>
</ButtonGroup>
</Container>
</Toolbar>
{searching && <LinearProgress />}
<PerfectScrollbar component="div">
<TableContainer sx={{ overflow: 'unset' }}>
<Table sx={{ minWidth: 800 }}>
<LogTableHead userIsAdmin={userIsAdmin} />
<TableBody>
{logs.slice(activePage * ITEMS_PER_PAGE, (activePage + 1) * ITEMS_PER_PAGE).map((row, index) => (
<LogTableRow item={row} key={`${row.id}_${index}`} userIsAdmin={userIsAdmin} />
))}
</TableBody>
</Table>
</TableContainer>
</PerfectScrollbar>
<TablePagination
page={activePage}
component="div"
count={logCount}
rowsPerPage={ITEMS_PER_PAGE}
onPageChange={onPaginationChange}
rowsPerPageOptions={[ITEMS_PER_PAGE]}
/>
</Card>
</>
);
}