feat: gemini audio input billing

This commit is contained in:
creamlike1024
2025-06-07 12:26:23 +08:00
parent f17b4f0760
commit 9496dac448
8 changed files with 386 additions and 260 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>
@@ -609,21 +615,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={{
@@ -662,25 +668,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>
@@ -700,7 +706,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) => {
@@ -715,10 +721,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) =>
@@ -916,27 +919,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) {
@@ -1002,6 +1005,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({
@@ -1051,7 +1057,7 @@ const LogsTable = () => {
const handlePageChange = (page) => {
setActivePage(page);
loadLogs(page, pageSize, logType).then((r) => { });
loadLogs(page, pageSize, logType).then((r) => {});
};
const handlePageSizeChange = async (size) => {
@@ -1100,9 +1106,9 @@ const LogsTable = () => {
<>
{renderColumnSelector()}
<Card
className="!rounded-2xl overflow-hidden mb-4"
className='!rounded-2xl overflow-hidden mb-4'
title={
<div className="flex flex-col w-full">
<div className='flex flex-col w-full'>
<Spin spinning={loadingStat}>
<Space>
<Tag
@@ -1145,15 +1151,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) => {
@@ -1169,7 +1175,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));
@@ -1189,7 +1195,7 @@ const LogsTable = () => {
placeholder={t('令牌名称')}
value={token_name}
onChange={(value) => handleInputChange(value, 'token_name')}
className="!rounded-full"
className='!rounded-full'
showClear
/>
@@ -1198,7 +1204,7 @@ const LogsTable = () => {
placeholder={t('模型名称')}
value={model_name}
onChange={(value) => handleInputChange(value, 'model_name')}
className="!rounded-full"
className='!rounded-full'
showClear
/>
@@ -1207,7 +1213,7 @@ const LogsTable = () => {
placeholder={t('分组')}
value={group}
onChange={(value) => handleInputChange(value, 'group')}
className="!rounded-full"
className='!rounded-full'
showClear
/>
@@ -1218,7 +1224,7 @@ const LogsTable = () => {
placeholder={t('渠道 ID')}
value={channel}
onChange={(value) => handleInputChange(value, 'channel')}
className="!rounded-full"
className='!rounded-full'
showClear
/>
<Input
@@ -1226,7 +1232,7 @@ const LogsTable = () => {
placeholder={t('用户名称')}
value={username}
onChange={(value) => handleInputChange(value, 'username')}
className="!rounded-full"
className='!rounded-full'
showClear
/>
</>
@@ -1234,14 +1240,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>
@@ -1250,7 +1256,7 @@ const LogsTable = () => {
type='tertiary'
icon={<IconSetting />}
onClick={() => setShowColumnSelector(true)}
className="!rounded-full"
className='!rounded-full'
>
{t('列设置')}
</Button>
@@ -1268,8 +1274,8 @@ const LogsTable = () => {
dataSource={logs}
rowKey='key'
loading={loading}
className="rounded-xl overflow-hidden"
size="middle"
className='rounded-xl overflow-hidden'
size='middle'
pagination={{
formatPageText: (page) =>
t('第 {{start}} - {{end}} 条,共 {{total}} 条', {