Merge branch 'gemini-audio-billing' into alpha

This commit is contained in:
creamlike1024
2025-06-07 12:32:20 +08:00
8 changed files with 480 additions and 287 deletions

View File

@@ -20,7 +20,7 @@ import {
renderQuota,
stringToColor,
getLogOther,
renderModelTag
renderModelTag,
} from '../../helpers';
import {
@@ -40,15 +40,11 @@ import {
Typography,
Divider,
Input,
DatePicker
DatePicker,
} from '@douyinfe/semi-ui';
import { ITEMS_PER_PAGE } from '../../constants';
import Paragraph from '@douyinfe/semi-ui/lib/es/typography/paragraph';
import {
IconSetting,
IconSearch,
IconForward
} from '@douyinfe/semi-icons';
import { IconSetting, IconSearch, IconForward } from '@douyinfe/semi-icons';
const { Text } = Typography;
@@ -201,8 +197,8 @@ const LogsTable = () => {
if (!modelMapped) {
return renderModelTag(record.model_name, {
onClick: (event) => {
copyText(event, record.model_name).then((r) => { });
}
copyText(event, record.model_name).then((r) => {});
},
});
} else {
return (
@@ -212,20 +208,26 @@ const LogsTable = () => {
content={
<div style={{ padding: 10 }}>
<Space vertical align={'start'}>
<div className="flex items-center">
<Text strong style={{ marginRight: 8 }}>{t('请求并计费模型')}:</Text>
<div className='flex items-center'>
<Text strong style={{ marginRight: 8 }}>
{t('请求并计费模型')}:
</Text>
{renderModelTag(record.model_name, {
onClick: (event) => {
copyText(event, record.model_name).then((r) => { });
}
copyText(event, record.model_name).then((r) => {});
},
})}
</div>
<div className="flex items-center">
<Text strong style={{ marginRight: 8 }}>{t('实际模型')}:</Text>
<div className='flex items-center'>
<Text strong style={{ marginRight: 8 }}>
{t('实际模型')}:
</Text>
{renderModelTag(other.upstream_model_name, {
onClick: (event) => {
copyText(event, other.upstream_model_name).then((r) => { });
}
copyText(event, other.upstream_model_name).then(
(r) => {},
);
},
})}
</div>
</Space>
@@ -234,9 +236,13 @@ const LogsTable = () => {
>
{renderModelTag(record.model_name, {
onClick: (event) => {
copyText(event, record.model_name).then((r) => { });
copyText(event, record.model_name).then((r) => {});
},
suffixIcon: <IconForward style={{ width: '0.9em', height: '0.9em', opacity: 0.75 }} />
suffixIcon: (
<IconForward
style={{ width: '0.9em', height: '0.9em', opacity: 0.75 }}
/>
),
})}
</Popover>
</Space>
@@ -597,21 +603,21 @@ const LogsTable = () => {
}
let content = other?.claude
? renderClaudeModelPriceSimple(
other.model_ratio,
other.model_price,
other.group_ratio,
other.cache_tokens || 0,
other.cache_ratio || 1.0,
other.cache_creation_tokens || 0,
other.cache_creation_ratio || 1.0,
)
other.model_ratio,
other.model_price,
other.group_ratio,
other.cache_tokens || 0,
other.cache_ratio || 1.0,
other.cache_creation_tokens || 0,
other.cache_creation_ratio || 1.0,
)
: renderModelPriceSimple(
other.model_ratio,
other.model_price,
other.group_ratio,
other.cache_tokens || 0,
other.cache_ratio || 1.0,
);
other.model_ratio,
other.model_price,
other.group_ratio,
other.cache_tokens || 0,
other.cache_ratio || 1.0,
);
return (
<Paragraph
ellipsis={{
@@ -650,25 +656,25 @@ const LogsTable = () => {
visible={showColumnSelector}
onCancel={() => setShowColumnSelector(false)}
footer={
<div className="flex justify-end">
<div className='flex justify-end'>
<Button
theme="light"
theme='light'
onClick={() => initDefaultColumns()}
className="!rounded-full"
className='!rounded-full'
>
{t('重置')}
</Button>
<Button
theme="light"
theme='light'
onClick={() => setShowColumnSelector(false)}
className="!rounded-full"
className='!rounded-full'
>
{t('取消')}
</Button>
<Button
type='primary'
onClick={() => setShowColumnSelector(false)}
className="!rounded-full"
className='!rounded-full'
>
{t('确定')}
</Button>
@@ -688,7 +694,7 @@ const LogsTable = () => {
</Checkbox>
</div>
<div
className="flex flex-wrap max-h-96 overflow-y-auto rounded-lg p-4"
className='flex flex-wrap max-h-96 overflow-y-auto rounded-lg p-4'
style={{ border: '1px solid var(--semi-color-border)' }}
>
{allColumns.map((column) => {
@@ -703,10 +709,7 @@ const LogsTable = () => {
}
return (
<div
key={column.key}
className="w-1/2 mb-4 pr-2"
>
<div key={column.key} className='w-1/2 mb-4 pr-2'>
<Checkbox
checked={!!visibleColumns[column.key]}
onChange={(e) =>
@@ -904,27 +907,27 @@ const LogsTable = () => {
key: t('日志详情'),
value: other?.claude
? renderClaudeLogContent(
other?.model_ratio,
other.completion_ratio,
other.model_price,
other.group_ratio,
other.cache_ratio || 1.0,
other.cache_creation_ratio || 1.0,
)
other?.model_ratio,
other.completion_ratio,
other.model_price,
other.group_ratio,
other.cache_ratio || 1.0,
other.cache_creation_ratio || 1.0,
)
: renderLogContent(
other?.model_ratio,
other.completion_ratio,
other.model_price,
other.group_ratio,
other?.user_group_ratio,
false,
1.0,
undefined,
other.web_search || false,
other.web_search_call_count || 0,
other.file_search || false,
other.file_search_call_count || 0,
),
other?.model_ratio,
other.completion_ratio,
other.model_price,
other.group_ratio,
other?.user_group_ratio,
false,
1.0,
undefined,
other.web_search || false,
other.web_search_call_count || 0,
other.file_search || false,
other.file_search_call_count || 0,
),
});
}
if (logs[i].type === 2) {
@@ -990,6 +993,9 @@ const LogsTable = () => {
other?.file_search || false,
other?.file_search_call_count || 0,
other?.file_search_price || 0,
other?.audio_input_seperate_price || false,
other?.audio_input_token_count || 0,
other?.audio_input_price || 0,
);
}
expandDataLocal.push({
@@ -1039,7 +1045,7 @@ const LogsTable = () => {
const handlePageChange = (page) => {
setActivePage(page);
loadLogs(page, pageSize, logType).then((r) => { });
loadLogs(page, pageSize, logType).then((r) => {});
};
const handlePageSizeChange = async (size) => {
@@ -1086,16 +1092,18 @@ const LogsTable = () => {
// 检查是否有任何记录有展开内容
const hasExpandableRows = () => {
return logs.some(log => expandData[log.key] && expandData[log.key].length > 0);
return logs.some(
(log) => expandData[log.key] && expandData[log.key].length > 0,
);
};
return (
<>
{renderColumnSelector()}
<Card
className="!rounded-2xl mb-4"
className='!rounded-2xl mb-4'
title={
<div className="flex flex-col w-full">
<div className='flex flex-col w-full'>
<Spin spinning={loadingStat}>
<Space>
<Tag
@@ -1138,15 +1146,15 @@ const LogsTable = () => {
</Space>
</Spin>
<Divider margin="12px" />
<Divider margin='12px' />
{/* 搜索表单区域 */}
<div className="flex flex-col gap-4">
<div className="grid grid-cols-1 md:grid-cols-2 lg:grid-cols-4 gap-4">
<div className='flex flex-col gap-4'>
<div className='grid grid-cols-1 md:grid-cols-2 lg:grid-cols-4 gap-4'>
{/* 时间选择器 */}
<div className="col-span-1 lg:col-span-2">
<div className='col-span-1 lg:col-span-2'>
<DatePicker
className="w-full"
className='w-full'
value={[start_timestamp, end_timestamp]}
type='dateTimeRange'
onChange={(value) => {
@@ -1162,7 +1170,7 @@ const LogsTable = () => {
<Select
value={logType.toString()}
placeholder={t('日志类型')}
className="!rounded-full"
className='!rounded-full'
onChange={(value) => {
setLogType(parseInt(value));
loadLogs(0, pageSize, parseInt(value));
@@ -1182,7 +1190,7 @@ const LogsTable = () => {
placeholder={t('令牌名称')}
value={token_name}
onChange={(value) => handleInputChange(value, 'token_name')}
className="!rounded-full"
className='!rounded-full'
showClear
/>
@@ -1191,7 +1199,7 @@ const LogsTable = () => {
placeholder={t('模型名称')}
value={model_name}
onChange={(value) => handleInputChange(value, 'model_name')}
className="!rounded-full"
className='!rounded-full'
showClear
/>
@@ -1200,7 +1208,7 @@ const LogsTable = () => {
placeholder={t('分组')}
value={group}
onChange={(value) => handleInputChange(value, 'group')}
className="!rounded-full"
className='!rounded-full'
showClear
/>
@@ -1211,7 +1219,7 @@ const LogsTable = () => {
placeholder={t('渠道 ID')}
value={channel}
onChange={(value) => handleInputChange(value, 'channel')}
className="!rounded-full"
className='!rounded-full'
showClear
/>
<Input
@@ -1219,7 +1227,7 @@ const LogsTable = () => {
placeholder={t('用户名称')}
value={username}
onChange={(value) => handleInputChange(value, 'username')}
className="!rounded-full"
className='!rounded-full'
showClear
/>
</>
@@ -1227,14 +1235,14 @@ const LogsTable = () => {
</div>
{/* 操作按钮区域 */}
<div className="flex justify-between items-center pt-2">
<div className='flex justify-between items-center pt-2'>
<div></div>
<div className="flex gap-2">
<div className='flex gap-2'>
<Button
type='primary'
onClick={refresh}
loading={loading}
className="!rounded-full"
className='!rounded-full'
>
{t('查询')}
</Button>
@@ -1243,7 +1251,7 @@ const LogsTable = () => {
type='tertiary'
icon={<IconSetting />}
onClick={() => setShowColumnSelector(true)}
className="!rounded-full"
className='!rounded-full'
>
{t('列设置')}
</Button>
@@ -1259,14 +1267,14 @@ const LogsTable = () => {
columns={getVisibleColumns()}
{...(hasExpandableRows() && {
expandedRowRender: expandRowRender,
expandRowByClick: true
expandRowByClick: true,
})}
dataSource={logs}
rowKey='key'
loading={loading}
scroll={{ x: 'max-content' }}
className="rounded-xl overflow-hidden"
size="middle"
className='rounded-xl overflow-hidden'
size='middle'
pagination={{
formatPageText: (page) =>
t('第 {{start}} - {{end}} 条,共 {{total}} 条', {