feat: Integrate i18n support and enhance UI text localization
- Added internationalization (i18n) support across various components, enabling dynamic language switching and improved user experience. - Updated multiple components to utilize translation functions for labels, buttons, and messages, ensuring consistent language display. - Enhanced the user interface by refining text elements in the ChannelsTable, LogsTable, and various settings pages, improving clarity and accessibility. - Adjusted CSS styles for better responsiveness and layout consistency across different screen sizes.
This commit is contained in:
@@ -1,4 +1,5 @@
|
||||
import React, { useEffect, useState } from 'react';
|
||||
import { useTranslation } from 'react-i18next';
|
||||
import {
|
||||
API,
|
||||
copy,
|
||||
@@ -40,8 +41,8 @@ function renderTimestamp(timestamp) {
|
||||
}
|
||||
|
||||
const MODE_OPTIONS = [
|
||||
{ key: 'all', text: '全部用户', value: 'all' },
|
||||
{ key: 'self', text: '当前用户', value: 'self' },
|
||||
{ key: 'all', text: 'all', value: 'all' },
|
||||
{ key: 'self', text: 'current user', value: 'self' },
|
||||
];
|
||||
|
||||
const colors = [
|
||||
@@ -62,123 +63,92 @@ const colors = [
|
||||
'yellow',
|
||||
];
|
||||
|
||||
function renderType(type) {
|
||||
switch (type) {
|
||||
case 1:
|
||||
const LogsTable = () => {
|
||||
const { t } = useTranslation();
|
||||
|
||||
function renderType(type) {
|
||||
switch (type) {
|
||||
case 1:
|
||||
return <Tag color='cyan' size='large'>{t('充值')}</Tag>;
|
||||
case 2:
|
||||
return <Tag color='lime' size='large'>{t('消费')}</Tag>;
|
||||
case 3:
|
||||
return <Tag color='orange' size='large'>{t('管理')}</Tag>;
|
||||
case 4:
|
||||
return <Tag color='purple' size='large'>{t('系统')}</Tag>;
|
||||
default:
|
||||
return <Tag color='black' size='large'>{t('未知')}</Tag>;
|
||||
}
|
||||
}
|
||||
|
||||
function renderIsStream(bool) {
|
||||
if (bool) {
|
||||
return <Tag color='blue' size='large'>{t('流')}</Tag>;
|
||||
} else {
|
||||
return <Tag color='purple' size='large'>{t('非流')}</Tag>;
|
||||
}
|
||||
}
|
||||
|
||||
function renderUseTime(type) {
|
||||
const time = parseInt(type);
|
||||
if (time < 101) {
|
||||
return (
|
||||
<Tag color='cyan' size='large'>
|
||||
<Tag color='green' size='large'>
|
||||
{' '}
|
||||
充值{' '}
|
||||
{time} s{' '}
|
||||
</Tag>
|
||||
);
|
||||
case 2:
|
||||
return (
|
||||
<Tag color='lime' size='large'>
|
||||
{' '}
|
||||
消费{' '}
|
||||
</Tag>
|
||||
);
|
||||
case 3:
|
||||
} else if (time < 300) {
|
||||
return (
|
||||
<Tag color='orange' size='large'>
|
||||
{' '}
|
||||
管理{' '}
|
||||
{time} s{' '}
|
||||
</Tag>
|
||||
);
|
||||
case 4:
|
||||
} else {
|
||||
return (
|
||||
<Tag color='purple' size='large'>
|
||||
<Tag color='red' size='large'>
|
||||
{' '}
|
||||
系统{' '}
|
||||
{time} s{' '}
|
||||
</Tag>
|
||||
);
|
||||
default:
|
||||
}
|
||||
}
|
||||
|
||||
function renderFirstUseTime(type) {
|
||||
let time = parseFloat(type) / 1000.0;
|
||||
time = time.toFixed(1);
|
||||
if (time < 3) {
|
||||
return (
|
||||
<Tag color='black' size='large'>
|
||||
<Tag color='green' size='large'>
|
||||
{' '}
|
||||
未知{' '}
|
||||
{time} s{' '}
|
||||
</Tag>
|
||||
);
|
||||
}
|
||||
}
|
||||
} else if (time < 10) {
|
||||
return (
|
||||
<Tag color='orange' size='large'>
|
||||
{' '}
|
||||
{time} s{' '}
|
||||
</Tag>
|
||||
);
|
||||
} else {
|
||||
return (
|
||||
<Tag color='red' size='large'>
|
||||
{' '}
|
||||
{time} s{' '}
|
||||
</Tag>
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
function renderIsStream(bool) {
|
||||
if (bool) {
|
||||
return (
|
||||
<Tag color='blue' size='large'>
|
||||
流
|
||||
</Tag>
|
||||
);
|
||||
} else {
|
||||
return (
|
||||
<Tag color='purple' size='large'>
|
||||
非流
|
||||
</Tag>
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
function renderUseTime(type) {
|
||||
const time = parseInt(type);
|
||||
if (time < 101) {
|
||||
return (
|
||||
<Tag color='green' size='large'>
|
||||
{' '}
|
||||
{time} s{' '}
|
||||
</Tag>
|
||||
);
|
||||
} else if (time < 300) {
|
||||
return (
|
||||
<Tag color='orange' size='large'>
|
||||
{' '}
|
||||
{time} s{' '}
|
||||
</Tag>
|
||||
);
|
||||
} else {
|
||||
return (
|
||||
<Tag color='red' size='large'>
|
||||
{' '}
|
||||
{time} s{' '}
|
||||
</Tag>
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
function renderFirstUseTime(type) {
|
||||
let time = parseFloat(type) / 1000.0;
|
||||
time = time.toFixed(1);
|
||||
if (time < 3) {
|
||||
return (
|
||||
<Tag color='green' size='large'>
|
||||
{' '}
|
||||
{time} s{' '}
|
||||
</Tag>
|
||||
);
|
||||
} else if (time < 10) {
|
||||
return (
|
||||
<Tag color='orange' size='large'>
|
||||
{' '}
|
||||
{time} s{' '}
|
||||
</Tag>
|
||||
);
|
||||
} else {
|
||||
return (
|
||||
<Tag color='red' size='large'>
|
||||
{' '}
|
||||
{time} s{' '}
|
||||
</Tag>
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
const LogsTable = () => {
|
||||
const columns = [
|
||||
{
|
||||
title: '时间',
|
||||
title: t('时间'),
|
||||
dataIndex: 'timestamp2string',
|
||||
},
|
||||
{
|
||||
title: '渠道',
|
||||
title: t('渠道'),
|
||||
dataIndex: 'channel',
|
||||
className: isAdmin() ? 'tableShow' : 'tableHiddle',
|
||||
render: (text, record, index) => {
|
||||
@@ -204,7 +174,7 @@ const LogsTable = () => {
|
||||
},
|
||||
},
|
||||
{
|
||||
title: '用户',
|
||||
title: t('用户'),
|
||||
dataIndex: 'username',
|
||||
className: isAdmin() ? 'tableShow' : 'tableHiddle',
|
||||
render: (text, record, index) => {
|
||||
@@ -226,7 +196,7 @@ const LogsTable = () => {
|
||||
},
|
||||
},
|
||||
{
|
||||
title: '令牌',
|
||||
title: t('令牌'),
|
||||
dataIndex: 'token_name',
|
||||
render: (text, record, index) => {
|
||||
return record.type === 0 || record.type === 2 ? (
|
||||
@@ -239,7 +209,7 @@ const LogsTable = () => {
|
||||
}}
|
||||
>
|
||||
{' '}
|
||||
{text}{' '}
|
||||
{t(text)}{' '}
|
||||
</Tag>
|
||||
</div>
|
||||
) : (
|
||||
@@ -248,14 +218,14 @@ const LogsTable = () => {
|
||||
},
|
||||
},
|
||||
{
|
||||
title: '类型',
|
||||
title: t('类型'),
|
||||
dataIndex: 'type',
|
||||
render: (text, record, index) => {
|
||||
return <>{renderType(text)}</>;
|
||||
},
|
||||
},
|
||||
{
|
||||
title: '模型',
|
||||
title: t('模型'),
|
||||
dataIndex: 'model_name',
|
||||
render: (text, record, index) => {
|
||||
return record.type === 0 || record.type === 2 ? (
|
||||
@@ -277,7 +247,7 @@ const LogsTable = () => {
|
||||
},
|
||||
},
|
||||
{
|
||||
title: '用时/首字',
|
||||
title: t('用时/首字'),
|
||||
dataIndex: 'use_time',
|
||||
render: (text, record, index) => {
|
||||
if (record.is_stream) {
|
||||
@@ -304,7 +274,7 @@ const LogsTable = () => {
|
||||
},
|
||||
},
|
||||
{
|
||||
title: '提示',
|
||||
title: t('提示'),
|
||||
dataIndex: 'prompt_tokens',
|
||||
render: (text, record, index) => {
|
||||
return record.type === 0 || record.type === 2 ? (
|
||||
@@ -315,7 +285,7 @@ const LogsTable = () => {
|
||||
},
|
||||
},
|
||||
{
|
||||
title: '补全',
|
||||
title: t('补全'),
|
||||
dataIndex: 'completion_tokens',
|
||||
render: (text, record, index) => {
|
||||
return parseInt(text) > 0 &&
|
||||
@@ -327,7 +297,7 @@ const LogsTable = () => {
|
||||
},
|
||||
},
|
||||
{
|
||||
title: '花费',
|
||||
title: t('花费'),
|
||||
dataIndex: 'quota',
|
||||
render: (text, record, index) => {
|
||||
return record.type === 0 || record.type === 2 ? (
|
||||
@@ -338,11 +308,11 @@ const LogsTable = () => {
|
||||
},
|
||||
},
|
||||
{
|
||||
title: '重试',
|
||||
title: t('重试'),
|
||||
dataIndex: 'retry',
|
||||
className: isAdmin() ? 'tableShow' : 'tableHiddle',
|
||||
render: (text, record, index) => {
|
||||
let content = '渠道:' + record.channel;
|
||||
let content = t('渠道') + `:${record.channel}`;
|
||||
if (record.other !== '') {
|
||||
let other = JSON.parse(record.other);
|
||||
if (other === null) {
|
||||
@@ -357,7 +327,7 @@ const LogsTable = () => {
|
||||
// channel id array
|
||||
let useChannel = other.admin_info.use_channel;
|
||||
let useChannelStr = useChannel.join('->');
|
||||
content = `渠道:${useChannelStr}`;
|
||||
content = t('渠道') + `:${useChannelStr}`;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -365,7 +335,7 @@ const LogsTable = () => {
|
||||
},
|
||||
},
|
||||
{
|
||||
title: '详情',
|
||||
title: t('详情'),
|
||||
dataIndex: 'content',
|
||||
render: (text, record, index) => {
|
||||
let other = getLogOther(record.other);
|
||||
@@ -493,13 +463,13 @@ const LogsTable = () => {
|
||||
const { success, message, data } = res.data;
|
||||
if (success) {
|
||||
Modal.info({
|
||||
title: '用户信息',
|
||||
title: t('用户信息'),
|
||||
content: (
|
||||
<div style={{ padding: 12 }}>
|
||||
<p>用户名: {data.username}</p>
|
||||
<p>余额: {renderQuota(data.quota)}</p>
|
||||
<p>已用额度:{renderQuota(data.used_quota)}</p>
|
||||
<p>请求次数:{renderNumber(data.request_count)}</p>
|
||||
<p>{t('用户名')}: {data.username}</p>
|
||||
<p>{t('余额')}: {renderQuota(data.quota)}</p>
|
||||
<p>{t('已用额度')}:{renderQuota(data.used_quota)}</p>
|
||||
<p>{t('请求次数')}:{renderNumber(data.request_count)}</p>
|
||||
</div>
|
||||
),
|
||||
centered: true,
|
||||
@@ -537,26 +507,26 @@ const LogsTable = () => {
|
||||
}
|
||||
if (other?.ws || other?.audio) {
|
||||
expandDataLocal.push({
|
||||
key: '语音输入',
|
||||
key: t('语音输入'),
|
||||
value: other.audio_input,
|
||||
});
|
||||
expandDataLocal.push({
|
||||
key: '语音输出',
|
||||
key: t('语音输出'),
|
||||
value: other.audio_output,
|
||||
});
|
||||
expandDataLocal.push({
|
||||
key: '文字输入',
|
||||
key: t('文字输入'),
|
||||
value: other.text_input,
|
||||
});
|
||||
expandDataLocal.push({
|
||||
key: '文字输出',
|
||||
key: t('文字输出'),
|
||||
value: other.text_output,
|
||||
});
|
||||
}
|
||||
expandDataLocal.push({
|
||||
key: '日志详情',
|
||||
key: t('日志详情'),
|
||||
value: logs[i].content,
|
||||
})
|
||||
});
|
||||
if (logs[i].type === 2) {
|
||||
let content = '';
|
||||
if (other?.ws || other?.audio) {
|
||||
@@ -583,7 +553,7 @@ const LogsTable = () => {
|
||||
);
|
||||
}
|
||||
expandDataLocal.push({
|
||||
key: '计费过程',
|
||||
key: t('计费过程'),
|
||||
value: content,
|
||||
});
|
||||
}
|
||||
@@ -676,7 +646,7 @@ const LogsTable = () => {
|
||||
<Spin spinning={loadingStat}>
|
||||
<Space>
|
||||
<Tag color='green' size='large' style={{ padding: 15 }}>
|
||||
总消耗额度: {renderQuota(stat.quota)}
|
||||
{t('总消耗额度')}: {renderQuota(stat.quota)}
|
||||
</Tag>
|
||||
<Tag color='blue' size='large' style={{ padding: 15 }}>
|
||||
RPM: {stat.rpm}
|
||||
@@ -691,25 +661,25 @@ const LogsTable = () => {
|
||||
<>
|
||||
<Form.Input
|
||||
field='token_name'
|
||||
label='令牌名称'
|
||||
label={t('令牌名称')}
|
||||
style={{ width: 176 }}
|
||||
value={token_name}
|
||||
placeholder={'可选值'}
|
||||
placeholder={t('可选值')}
|
||||
name='token_name'
|
||||
onChange={(value) => handleInputChange(value, 'token_name')}
|
||||
/>
|
||||
<Form.Input
|
||||
field='model_name'
|
||||
label='模型名称'
|
||||
label={t('模型名称')}
|
||||
style={{ width: 176 }}
|
||||
value={model_name}
|
||||
placeholder='可选值'
|
||||
placeholder={t('可选值')}
|
||||
name='model_name'
|
||||
onChange={(value) => handleInputChange(value, 'model_name')}
|
||||
/>
|
||||
<Form.DatePicker
|
||||
field='start_timestamp'
|
||||
label='起始时间'
|
||||
label={t('起始时间')}
|
||||
style={{ width: 272 }}
|
||||
initValue={start_timestamp}
|
||||
value={start_timestamp}
|
||||
@@ -720,7 +690,7 @@ const LogsTable = () => {
|
||||
<Form.DatePicker
|
||||
field='end_timestamp'
|
||||
fluid
|
||||
label='结束时间'
|
||||
label={t('结束时间')}
|
||||
style={{ width: 272 }}
|
||||
initValue={end_timestamp}
|
||||
value={end_timestamp}
|
||||
@@ -732,26 +702,26 @@ const LogsTable = () => {
|
||||
<>
|
||||
<Form.Input
|
||||
field='channel'
|
||||
label='渠道 ID'
|
||||
label={t('渠道 ID')}
|
||||
style={{ width: 176 }}
|
||||
value={channel}
|
||||
placeholder='可选值'
|
||||
placeholder={t('可选值')}
|
||||
name='channel'
|
||||
onChange={(value) => handleInputChange(value, 'channel')}
|
||||
/>
|
||||
<Form.Input
|
||||
field='username'
|
||||
label='用户名称'
|
||||
label={t('用户名称')}
|
||||
style={{ width: 176 }}
|
||||
value={username}
|
||||
placeholder={'可选值'}
|
||||
placeholder={t('可选值')}
|
||||
name='username'
|
||||
onChange={(value) => handleInputChange(value, 'username')}
|
||||
/>
|
||||
</>
|
||||
)}
|
||||
<Button
|
||||
label='查询'
|
||||
label={t('查询')}
|
||||
type='primary'
|
||||
htmlType='submit'
|
||||
className='btn-margin-right'
|
||||
@@ -759,7 +729,7 @@ const LogsTable = () => {
|
||||
loading={loading}
|
||||
style={{ marginTop: 24 }}
|
||||
>
|
||||
查询
|
||||
{t('查询')}
|
||||
</Button>
|
||||
<Form.Section></Form.Section>
|
||||
</>
|
||||
@@ -773,11 +743,11 @@ const LogsTable = () => {
|
||||
loadLogs(0, pageSize, parseInt(value));
|
||||
}}
|
||||
>
|
||||
<Select.Option value='0'>全部</Select.Option>
|
||||
<Select.Option value='1'>充值</Select.Option>
|
||||
<Select.Option value='2'>消费</Select.Option>
|
||||
<Select.Option value='3'>管理</Select.Option>
|
||||
<Select.Option value='4'>系统</Select.Option>
|
||||
<Select.Option value='0'>{t('全部')}</Select.Option>
|
||||
<Select.Option value='1'>{t('充值')}</Select.Option>
|
||||
<Select.Option value='2'>{t('消费')}</Select.Option>
|
||||
<Select.Option value='3'>{t('管理')}</Select.Option>
|
||||
<Select.Option value='4'>{t('系统')}</Select.Option>
|
||||
</Select>
|
||||
</div>
|
||||
<Table
|
||||
|
||||
Reference in New Issue
Block a user