mirror of
https://github.com/linux-do/new-api.git
synced 2025-09-19 17:06:38 +08:00
feat: Add logs page-size
This commit is contained in:
parent
7f22d58574
commit
25ec99913b
@ -10,9 +10,13 @@ import (
|
|||||||
|
|
||||||
func GetAllLogs(c *gin.Context) {
|
func GetAllLogs(c *gin.Context) {
|
||||||
p, _ := strconv.Atoi(c.Query("p"))
|
p, _ := strconv.Atoi(c.Query("p"))
|
||||||
|
pageSize, _ := strconv.Atoi(c.Query("page_size"))
|
||||||
if p < 0 {
|
if p < 0 {
|
||||||
p = 0
|
p = 0
|
||||||
}
|
}
|
||||||
|
if pageSize < 0 {
|
||||||
|
pageSize = common.ItemsPerPage
|
||||||
|
}
|
||||||
logType, _ := strconv.Atoi(c.Query("type"))
|
logType, _ := strconv.Atoi(c.Query("type"))
|
||||||
startTimestamp, _ := strconv.ParseInt(c.Query("start_timestamp"), 10, 64)
|
startTimestamp, _ := strconv.ParseInt(c.Query("start_timestamp"), 10, 64)
|
||||||
endTimestamp, _ := strconv.ParseInt(c.Query("end_timestamp"), 10, 64)
|
endTimestamp, _ := strconv.ParseInt(c.Query("end_timestamp"), 10, 64)
|
||||||
@ -20,7 +24,7 @@ func GetAllLogs(c *gin.Context) {
|
|||||||
tokenName := c.Query("token_name")
|
tokenName := c.Query("token_name")
|
||||||
modelName := c.Query("model_name")
|
modelName := c.Query("model_name")
|
||||||
channel, _ := strconv.Atoi(c.Query("channel"))
|
channel, _ := strconv.Atoi(c.Query("channel"))
|
||||||
logs, err := model.GetAllLogs(logType, startTimestamp, endTimestamp, modelName, username, tokenName, p*common.ItemsPerPage, common.ItemsPerPage, channel)
|
logs, err := model.GetAllLogs(logType, startTimestamp, endTimestamp, modelName, username, tokenName, p*pageSize, pageSize, channel)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
c.JSON(http.StatusOK, gin.H{
|
c.JSON(http.StatusOK, gin.H{
|
||||||
"success": false,
|
"success": false,
|
||||||
@ -38,16 +42,23 @@ func GetAllLogs(c *gin.Context) {
|
|||||||
|
|
||||||
func GetUserLogs(c *gin.Context) {
|
func GetUserLogs(c *gin.Context) {
|
||||||
p, _ := strconv.Atoi(c.Query("p"))
|
p, _ := strconv.Atoi(c.Query("p"))
|
||||||
|
pageSize, _ := strconv.Atoi(c.Query("page_size"))
|
||||||
if p < 0 {
|
if p < 0 {
|
||||||
p = 0
|
p = 0
|
||||||
}
|
}
|
||||||
|
if pageSize < 0 {
|
||||||
|
pageSize = common.ItemsPerPage
|
||||||
|
}
|
||||||
|
if pageSize > 100 {
|
||||||
|
pageSize = 100
|
||||||
|
}
|
||||||
userId := c.GetInt("id")
|
userId := c.GetInt("id")
|
||||||
logType, _ := strconv.Atoi(c.Query("type"))
|
logType, _ := strconv.Atoi(c.Query("type"))
|
||||||
startTimestamp, _ := strconv.ParseInt(c.Query("start_timestamp"), 10, 64)
|
startTimestamp, _ := strconv.ParseInt(c.Query("start_timestamp"), 10, 64)
|
||||||
endTimestamp, _ := strconv.ParseInt(c.Query("end_timestamp"), 10, 64)
|
endTimestamp, _ := strconv.ParseInt(c.Query("end_timestamp"), 10, 64)
|
||||||
tokenName := c.Query("token_name")
|
tokenName := c.Query("token_name")
|
||||||
modelName := c.Query("model_name")
|
modelName := c.Query("model_name")
|
||||||
logs, err := model.GetUserLogs(userId, logType, startTimestamp, endTimestamp, modelName, tokenName, p*common.ItemsPerPage, common.ItemsPerPage)
|
logs, err := model.GetUserLogs(userId, logType, startTimestamp, endTimestamp, modelName, tokenName, p*pageSize, pageSize)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
c.JSON(http.StatusOK, gin.H{
|
c.JSON(http.StatusOK, gin.H{
|
||||||
"success": false,
|
"success": false,
|
||||||
|
@ -1,26 +1,13 @@
|
|||||||
import React, {useEffect, useState} from 'react';
|
import React, {useEffect, useState} from 'react';
|
||||||
import {Label} from 'semantic-ui-react';
|
|
||||||
import {API, copy, isAdmin, showError, showSuccess, timestamp2string} from '../helpers';
|
import {API, copy, isAdmin, showError, showSuccess, timestamp2string} from '../helpers';
|
||||||
|
|
||||||
import {Table, Avatar, Tag, Form, Button, Layout, Select, Popover, Modal, Spin, Space} from '@douyinfe/semi-ui';
|
import {Table, Avatar, Tag, Form, Button, Layout, Select, Popover, Modal, Spin, Space} from '@douyinfe/semi-ui';
|
||||||
import {ITEMS_PER_PAGE} from '../constants';
|
import {ITEMS_PER_PAGE} from '../constants';
|
||||||
import {renderNumber, renderQuota, stringToColor} from '../helpers/render';
|
import {renderNumber, renderQuota, stringToColor} from '../helpers/render';
|
||||||
import {
|
|
||||||
IconAt,
|
|
||||||
IconHistogram,
|
|
||||||
IconGift,
|
|
||||||
IconKey,
|
|
||||||
IconUser,
|
|
||||||
IconLayers,
|
|
||||||
IconSetting,
|
|
||||||
IconCreditCard,
|
|
||||||
IconSemiLogo,
|
|
||||||
IconHome,
|
|
||||||
IconMore
|
|
||||||
} from '@douyinfe/semi-icons';
|
|
||||||
import Paragraph from "@douyinfe/semi-ui/lib/es/typography/paragraph";
|
import Paragraph from "@douyinfe/semi-ui/lib/es/typography/paragraph";
|
||||||
|
|
||||||
const {Header} = Layout;
|
const {Header} = Layout;
|
||||||
|
|
||||||
function renderTimestamp(timestamp) {
|
function renderTimestamp(timestamp) {
|
||||||
return (
|
return (
|
||||||
<>
|
<>
|
||||||
@ -221,7 +208,8 @@ const LogsTable = () => {
|
|||||||
title: '详情',
|
title: '详情',
|
||||||
dataIndex: 'content',
|
dataIndex: 'content',
|
||||||
render: (text, record, index) => {
|
render: (text, record, index) => {
|
||||||
return <Paragraph ellipsis={{ rows: 2, showTooltip: { type: 'popover', opts: { style: { width: 240 } } } }} style={{ maxWidth: 240}}>
|
return <Paragraph ellipsis={{rows: 2, showTooltip: {type: 'popover', opts: {style: {width: 240}}}}}
|
||||||
|
style={{maxWidth: 240}}>
|
||||||
{text}
|
{text}
|
||||||
</Paragraph>
|
</Paragraph>
|
||||||
}
|
}
|
||||||
@ -234,6 +222,7 @@ const LogsTable = () => {
|
|||||||
const [loadingStat, setLoadingStat] = useState(false);
|
const [loadingStat, setLoadingStat] = useState(false);
|
||||||
const [activePage, setActivePage] = useState(1);
|
const [activePage, setActivePage] = useState(1);
|
||||||
const [logCount, setLogCount] = useState(ITEMS_PER_PAGE);
|
const [logCount, setLogCount] = useState(ITEMS_PER_PAGE);
|
||||||
|
const [pageSize, setPageSize] = useState(ITEMS_PER_PAGE);
|
||||||
const [searchKeyword, setSearchKeyword] = useState('');
|
const [searchKeyword, setSearchKeyword] = useState('');
|
||||||
const [searching, setSearching] = useState(false);
|
const [searching, setSearching] = useState(false);
|
||||||
const [logType, setLogType] = useState(0);
|
const [logType, setLogType] = useState(0);
|
||||||
@ -327,16 +316,16 @@ const LogsTable = () => {
|
|||||||
// console.log(logCount);
|
// console.log(logCount);
|
||||||
}
|
}
|
||||||
|
|
||||||
const loadLogs = async (startIdx) => {
|
const loadLogs = async (startIdx, pageSize) => {
|
||||||
setLoading(true);
|
setLoading(true);
|
||||||
|
|
||||||
let url = '';
|
let url = '';
|
||||||
let localStartTimestamp = Date.parse(start_timestamp) / 1000;
|
let localStartTimestamp = Date.parse(start_timestamp) / 1000;
|
||||||
let localEndTimestamp = Date.parse(end_timestamp) / 1000;
|
let localEndTimestamp = Date.parse(end_timestamp) / 1000;
|
||||||
if (isAdminUser) {
|
if (isAdminUser) {
|
||||||
url = `/api/log/?p=${startIdx}&type=${logType}&username=${username}&token_name=${token_name}&model_name=${model_name}&start_timestamp=${localStartTimestamp}&end_timestamp=${localEndTimestamp}&channel=${channel}`;
|
url = `/api/log/?p=${startIdx}&page_size=${pageSize}&type=${logType}&username=${username}&token_name=${token_name}&model_name=${model_name}&start_timestamp=${localStartTimestamp}&end_timestamp=${localEndTimestamp}&channel=${channel}`;
|
||||||
} else {
|
} else {
|
||||||
url = `/api/log/self/?p=${startIdx}&type=${logType}&token_name=${token_name}&model_name=${model_name}&start_timestamp=${localStartTimestamp}&end_timestamp=${localEndTimestamp}`;
|
url = `/api/log/self/?p=${startIdx}&page_size=${pageSize}&type=${logType}&token_name=${token_name}&model_name=${model_name}&start_timestamp=${localStartTimestamp}&end_timestamp=${localEndTimestamp}`;
|
||||||
}
|
}
|
||||||
const res = await API.get(url);
|
const res = await API.get(url);
|
||||||
const {success, message, data} = res.data;
|
const {success, message, data} = res.data;
|
||||||
@ -345,7 +334,7 @@ const LogsTable = () => {
|
|||||||
setLogsFormat(data);
|
setLogsFormat(data);
|
||||||
} else {
|
} else {
|
||||||
let newLogs = [...logs];
|
let newLogs = [...logs];
|
||||||
newLogs.splice(startIdx * ITEMS_PER_PAGE, data.length, ...data);
|
newLogs.splice(startIdx * pageSize, data.length, ...data);
|
||||||
setLogsFormat(newLogs);
|
setLogsFormat(newLogs);
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
@ -354,21 +343,32 @@ const LogsTable = () => {
|
|||||||
setLoading(false);
|
setLoading(false);
|
||||||
};
|
};
|
||||||
|
|
||||||
const pageData = logs.slice((activePage - 1) * ITEMS_PER_PAGE, activePage * ITEMS_PER_PAGE);
|
const pageData = logs.slice((activePage - 1) * pageSize, activePage * pageSize);
|
||||||
|
|
||||||
const handlePageChange = page => {
|
const handlePageChange = page => {
|
||||||
setActivePage(page);
|
setActivePage(page);
|
||||||
if (page === Math.ceil(logs.length / ITEMS_PER_PAGE) + 1) {
|
if (page === Math.ceil(logs.length / pageSize) + 1) {
|
||||||
// In this case we have to load more data and then append them.
|
// In this case we have to load more data and then append them.
|
||||||
loadLogs(page - 1).then(r => {
|
loadLogs(page - 1, pageSize).then(r => {
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
const handlePageSizeChange = async (size) => {
|
||||||
|
localStorage.setItem('page-size', size + '')
|
||||||
|
setPageSize(size)
|
||||||
|
setActivePage(1)
|
||||||
|
loadLogs(0, size)
|
||||||
|
.then()
|
||||||
|
.catch((reason) => {
|
||||||
|
showError(reason);
|
||||||
|
})
|
||||||
|
};
|
||||||
|
|
||||||
const refresh = async () => {
|
const refresh = async () => {
|
||||||
// setLoading(true);
|
// setLoading(true);
|
||||||
setActivePage(1);
|
setActivePage(1);
|
||||||
await loadLogs(0);
|
await loadLogs(0, pageSize);
|
||||||
};
|
};
|
||||||
|
|
||||||
const copyText = async (text) => {
|
const copyText = async (text) => {
|
||||||
@ -380,14 +380,25 @@ const LogsTable = () => {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// useEffect(() => {
|
||||||
|
// refresh().then();
|
||||||
|
// }, [logType]);
|
||||||
|
|
||||||
useEffect(() => {
|
useEffect(() => {
|
||||||
refresh().then();
|
// console.log('default effect')
|
||||||
}, [logType]);
|
const localPageSize = parseInt(localStorage.getItem('page-size')) || ITEMS_PER_PAGE;
|
||||||
|
setPageSize(localPageSize)
|
||||||
|
loadLogs(0, localPageSize)
|
||||||
|
.then()
|
||||||
|
.catch((reason) => {
|
||||||
|
showError(reason);
|
||||||
|
});
|
||||||
|
}, []);
|
||||||
|
|
||||||
const searchLogs = async () => {
|
const searchLogs = async () => {
|
||||||
if (searchKeyword === '') {
|
if (searchKeyword === '') {
|
||||||
// if keyword is blank, load files instead.
|
// if keyword is blank, load files instead.
|
||||||
await loadLogs(0);
|
await loadLogs(0, pageSize);
|
||||||
setActivePage(1);
|
setActivePage(1);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
@ -403,39 +414,16 @@ const LogsTable = () => {
|
|||||||
setSearching(false);
|
setSearching(false);
|
||||||
};
|
};
|
||||||
|
|
||||||
const handleKeywordChange = async (e, {value}) => {
|
|
||||||
setSearchKeyword(value.trim());
|
|
||||||
};
|
|
||||||
|
|
||||||
const sortLog = (key) => {
|
|
||||||
if (logs.length === 0) return;
|
|
||||||
setLoading(true);
|
|
||||||
let sortedLogs = [...logs];
|
|
||||||
if (typeof sortedLogs[0][key] === 'string') {
|
|
||||||
sortedLogs.sort((a, b) => {
|
|
||||||
return ('' + a[key]).localeCompare(b[key]);
|
|
||||||
});
|
|
||||||
} else {
|
|
||||||
sortedLogs.sort((a, b) => {
|
|
||||||
if (a[key] === b[key]) return 0;
|
|
||||||
if (a[key] > b[key]) return -1;
|
|
||||||
if (a[key] < b[key]) return 1;
|
|
||||||
});
|
|
||||||
}
|
|
||||||
if (sortedLogs[0].id === logs[0].id) {
|
|
||||||
sortedLogs.reverse();
|
|
||||||
}
|
|
||||||
setLogs(sortedLogs);
|
|
||||||
setLoading(false);
|
|
||||||
};
|
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<>
|
<>
|
||||||
<Layout>
|
<Layout>
|
||||||
<Header>
|
<Header>
|
||||||
<Spin spinning={loadingStat}>
|
<Spin spinning={loadingStat}>
|
||||||
<h3>使用明细(总消耗额度:
|
<h3>使用明细(总消耗额度:
|
||||||
<span onClick={handleEyeClick} style={{cursor: 'pointer', color: 'gray'}}>{showStat?renderQuota(stat.quota):"点击查看"}</span>
|
<span onClick={handleEyeClick} style={{
|
||||||
|
cursor: 'pointer',
|
||||||
|
color: 'gray'
|
||||||
|
}}>{showStat ? renderQuota(stat.quota) : "点击查看"}</span>
|
||||||
)
|
)
|
||||||
</h3>
|
</h3>
|
||||||
</Spin>
|
</Spin>
|
||||||
@ -477,9 +465,13 @@ const LogsTable = () => {
|
|||||||
</Form>
|
</Form>
|
||||||
<Table style={{marginTop: 5}} columns={columns} dataSource={pageData} pagination={{
|
<Table style={{marginTop: 5}} columns={columns} dataSource={pageData} pagination={{
|
||||||
currentPage: activePage,
|
currentPage: activePage,
|
||||||
pageSize: ITEMS_PER_PAGE,
|
pageSize: pageSize,
|
||||||
total: logCount,
|
total: logCount,
|
||||||
pageSizeOpts: [10, 20, 50, 100],
|
pageSizeOpts: [10, 20, 50, 100],
|
||||||
|
showSizeChanger: true,
|
||||||
|
onPageSizeChange: (size) => {
|
||||||
|
handlePageSizeChange(size).then()
|
||||||
|
},
|
||||||
onPageChange: handlePageChange,
|
onPageChange: handlePageChange,
|
||||||
}}/>
|
}}/>
|
||||||
<Select defaultValue="0" style={{width: 120}} onChange={
|
<Select defaultValue="0" style={{width: 120}} onChange={
|
||||||
|
Loading…
Reference in New Issue
Block a user