mirror of
https://github.com/songquanpeng/one-api.git
synced 2025-12-12 11:15:57 +08:00
Compare commits
11 Commits
v0.6.11-al
...
v0.6.11-pr
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
4dbc2ad86d | ||
|
|
94479c2800 | ||
|
|
614903b524 | ||
|
|
1dc255c219 | ||
|
|
15c27e4b12 | ||
|
|
a910d3ba25 | ||
|
|
34f889437d | ||
|
|
a56cb4a2d5 | ||
|
|
95009b254a | ||
|
|
20c30a060b | ||
|
|
ca334a5502 |
@@ -126,10 +126,10 @@ var ValidThemes = map[string]bool{
|
|||||||
// All duration's unit is seconds
|
// All duration's unit is seconds
|
||||||
// Shouldn't larger then RateLimitKeyExpirationDuration
|
// Shouldn't larger then RateLimitKeyExpirationDuration
|
||||||
var (
|
var (
|
||||||
GlobalApiRateLimitNum = env.Int("GLOBAL_API_RATE_LIMIT", 240)
|
GlobalApiRateLimitNum = env.Int("GLOBAL_API_RATE_LIMIT", 480)
|
||||||
GlobalApiRateLimitDuration int64 = 3 * 60
|
GlobalApiRateLimitDuration int64 = 3 * 60
|
||||||
|
|
||||||
GlobalWebRateLimitNum = env.Int("GLOBAL_WEB_RATE_LIMIT", 120)
|
GlobalWebRateLimitNum = env.Int("GLOBAL_WEB_RATE_LIMIT", 240)
|
||||||
GlobalWebRateLimitDuration int64 = 3 * 60
|
GlobalWebRateLimitDuration int64 = 3 * 60
|
||||||
|
|
||||||
UploadRateLimitNum = 10
|
UploadRateLimitNum = 10
|
||||||
|
|||||||
@@ -7,7 +7,6 @@
|
|||||||
"history": "^5.3.0",
|
"history": "^5.3.0",
|
||||||
"i18next": "^24.2.2",
|
"i18next": "^24.2.2",
|
||||||
"i18next-browser-languagedetector": "^8.0.2",
|
"i18next-browser-languagedetector": "^8.0.2",
|
||||||
"i18next-http-backend": "^3.0.2",
|
|
||||||
"marked": "^4.1.1",
|
"marked": "^4.1.1",
|
||||||
"moment": "^2.30.1",
|
"moment": "^2.30.1",
|
||||||
"react": "^18.2.0",
|
"react": "^18.2.0",
|
||||||
|
|||||||
@@ -328,6 +328,7 @@ const LogsTable = () => {
|
|||||||
<Form.Input
|
<Form.Input
|
||||||
fluid
|
fluid
|
||||||
label={t('log.table.token_name')}
|
label={t('log.table.token_name')}
|
||||||
|
size={'small'}
|
||||||
width={3}
|
width={3}
|
||||||
value={token_name}
|
value={token_name}
|
||||||
placeholder={t('log.table.token_name_placeholder')}
|
placeholder={t('log.table.token_name_placeholder')}
|
||||||
@@ -337,6 +338,7 @@ const LogsTable = () => {
|
|||||||
<Form.Input
|
<Form.Input
|
||||||
fluid
|
fluid
|
||||||
label={t('log.table.model_name')}
|
label={t('log.table.model_name')}
|
||||||
|
size={'small'}
|
||||||
width={3}
|
width={3}
|
||||||
value={model_name}
|
value={model_name}
|
||||||
placeholder={t('log.table.model_name_placeholder')}
|
placeholder={t('log.table.model_name_placeholder')}
|
||||||
@@ -346,6 +348,7 @@ const LogsTable = () => {
|
|||||||
<Form.Input
|
<Form.Input
|
||||||
fluid
|
fluid
|
||||||
label={t('log.table.start_time')}
|
label={t('log.table.start_time')}
|
||||||
|
size={'small'}
|
||||||
width={4}
|
width={4}
|
||||||
value={start_timestamp}
|
value={start_timestamp}
|
||||||
type='datetime-local'
|
type='datetime-local'
|
||||||
@@ -355,6 +358,7 @@ const LogsTable = () => {
|
|||||||
<Form.Input
|
<Form.Input
|
||||||
fluid
|
fluid
|
||||||
label={t('log.table.end_time')}
|
label={t('log.table.end_time')}
|
||||||
|
size={'small'}
|
||||||
width={4}
|
width={4}
|
||||||
value={end_timestamp}
|
value={end_timestamp}
|
||||||
type='datetime-local'
|
type='datetime-local'
|
||||||
@@ -364,6 +368,7 @@ const LogsTable = () => {
|
|||||||
<Form.Button
|
<Form.Button
|
||||||
fluid
|
fluid
|
||||||
label={t('log.buttons.query')}
|
label={t('log.buttons.query')}
|
||||||
|
size={'small'}
|
||||||
width={2}
|
width={2}
|
||||||
onClick={refresh}
|
onClick={refresh}
|
||||||
>
|
>
|
||||||
@@ -376,6 +381,7 @@ const LogsTable = () => {
|
|||||||
<Form.Input
|
<Form.Input
|
||||||
fluid
|
fluid
|
||||||
label={t('log.table.channel_id')}
|
label={t('log.table.channel_id')}
|
||||||
|
size={'small'}
|
||||||
width={3}
|
width={3}
|
||||||
value={channel}
|
value={channel}
|
||||||
placeholder={t('log.table.channel_id_placeholder')}
|
placeholder={t('log.table.channel_id_placeholder')}
|
||||||
@@ -385,6 +391,7 @@ const LogsTable = () => {
|
|||||||
<Form.Input
|
<Form.Input
|
||||||
fluid
|
fluid
|
||||||
label={t('log.table.username')}
|
label={t('log.table.username')}
|
||||||
|
size={'small'}
|
||||||
width={3}
|
width={3}
|
||||||
value={username}
|
value={username}
|
||||||
placeholder={t('log.table.username_placeholder')}
|
placeholder={t('log.table.username_placeholder')}
|
||||||
|
|||||||
@@ -415,9 +415,9 @@ const TokensTable = () => {
|
|||||||
</Table.Cell>
|
</Table.Cell>
|
||||||
<Table.Cell>
|
<Table.Cell>
|
||||||
<div>
|
<div>
|
||||||
<Button.Group color='green' size={'mini'}>
|
<Button.Group color='green' size={'tiny'}>
|
||||||
<Button
|
<Button
|
||||||
size={'mini'}
|
size={'tiny'}
|
||||||
positive
|
positive
|
||||||
onClick={async () => await onCopy('', token.key)}
|
onClick={async () => await onCopy('', token.key)}
|
||||||
>
|
>
|
||||||
@@ -430,9 +430,9 @@ const TokensTable = () => {
|
|||||||
trigger={<></>}
|
trigger={<></>}
|
||||||
/>
|
/>
|
||||||
</Button.Group>{' '}
|
</Button.Group>{' '}
|
||||||
<Button.Group color='blue' size={'mini'}>
|
<Button.Group color='olive' size={'tiny'}>
|
||||||
<Button
|
<Button
|
||||||
size={'mini'}
|
size={'tiny'}
|
||||||
positive
|
positive
|
||||||
onClick={() => onOpenLink('', token.key)}
|
onClick={() => onOpenLink('', token.key)}
|
||||||
>
|
>
|
||||||
@@ -456,7 +456,7 @@ const TokensTable = () => {
|
|||||||
hoverable
|
hoverable
|
||||||
>
|
>
|
||||||
<Button
|
<Button
|
||||||
size={'mini'}
|
size={'tiny'}
|
||||||
negative
|
negative
|
||||||
onClick={() => {
|
onClick={() => {
|
||||||
manageToken(token.id, 'delete', idx);
|
manageToken(token.id, 'delete', idx);
|
||||||
@@ -466,7 +466,7 @@ const TokensTable = () => {
|
|||||||
</Button>
|
</Button>
|
||||||
</Popup>
|
</Popup>
|
||||||
<Button
|
<Button
|
||||||
size={'mini'}
|
size={'tiny'}
|
||||||
onClick={() => {
|
onClick={() => {
|
||||||
manageToken(
|
manageToken(
|
||||||
token.id,
|
token.id,
|
||||||
@@ -480,7 +480,7 @@ const TokensTable = () => {
|
|||||||
: t('token.buttons.enable')}
|
: t('token.buttons.enable')}
|
||||||
</Button>
|
</Button>
|
||||||
<Button
|
<Button
|
||||||
size={'mini'}
|
size={'tiny'}
|
||||||
as={Link}
|
as={Link}
|
||||||
to={'/token/edit/' + token.id}
|
to={'/token/edit/' + token.id}
|
||||||
>
|
>
|
||||||
|
|||||||
@@ -1,7 +1,7 @@
|
|||||||
export const toastConstants = {
|
export const toastConstants = {
|
||||||
SUCCESS_TIMEOUT: 1500,
|
SUCCESS_TIMEOUT: 5000,
|
||||||
INFO_TIMEOUT: 3000,
|
INFO_TIMEOUT: 8000,
|
||||||
ERROR_TIMEOUT: 5000,
|
ERROR_TIMEOUT: 10000,
|
||||||
WARNING_TIMEOUT: 10000,
|
WARNING_TIMEOUT: 10000,
|
||||||
NOTICE_TIMEOUT: 20000
|
NOTICE_TIMEOUT: 20000,
|
||||||
};
|
};
|
||||||
|
|||||||
@@ -1,10 +1,10 @@
|
|||||||
import i18n from 'i18next';
|
import i18n from 'i18next';
|
||||||
import { initReactI18next } from 'react-i18next';
|
import {initReactI18next} from 'react-i18next';
|
||||||
import Backend from 'i18next-http-backend';
|
|
||||||
import LanguageDetector from 'i18next-browser-languagedetector';
|
import LanguageDetector from 'i18next-browser-languagedetector';
|
||||||
|
import zhTranslation from './locales/zh/translation.json';
|
||||||
|
import enTranslation from './locales/en/translation.json';
|
||||||
|
|
||||||
i18n
|
i18n
|
||||||
.use(Backend)
|
|
||||||
.use(LanguageDetector)
|
.use(LanguageDetector)
|
||||||
.use(initReactI18next)
|
.use(initReactI18next)
|
||||||
.init({
|
.init({
|
||||||
@@ -15,9 +15,14 @@ i18n
|
|||||||
escapeValue: false,
|
escapeValue: false,
|
||||||
},
|
},
|
||||||
|
|
||||||
backend: {
|
resources: {
|
||||||
loadPath: '/locales/{{lng}}/{{ns}}.json',
|
zh: {
|
||||||
},
|
translation: zhTranslation
|
||||||
|
},
|
||||||
|
en: {
|
||||||
|
translation: enTranslation
|
||||||
|
}
|
||||||
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
export default i18n;
|
export default i18n;
|
||||||
|
|||||||
@@ -85,7 +85,8 @@
|
|||||||
"test_all_started": "Channel testing started successfully, please refresh page to see results.",
|
"test_all_started": "Channel testing started successfully, please refresh page to see results.",
|
||||||
"delete_disabled_success": "Deleted all disabled channels, total: {{count}}",
|
"delete_disabled_success": "Deleted all disabled channels, total: {{count}}",
|
||||||
"balance_update_success": "Channel {{name}} balance updated successfully!",
|
"balance_update_success": "Channel {{name}} balance updated successfully!",
|
||||||
"all_balance_updated": "All enabled channel balances have been updated!"
|
"all_balance_updated": "All enabled channel balances have been updated!",
|
||||||
|
"operation_success": "Operation completed successfully!"
|
||||||
},
|
},
|
||||||
"edit": {
|
"edit": {
|
||||||
"title_edit": "Update Channel Information",
|
"title_edit": "Update Channel Information",
|
||||||
@@ -165,7 +166,7 @@
|
|||||||
"expired_time": "Expiry Time",
|
"expired_time": "Expiry Time",
|
||||||
"actions": "Actions",
|
"actions": "Actions",
|
||||||
"no_name": "None",
|
"no_name": "None",
|
||||||
"never_expire": "Never Expires",
|
"never_expire": "never",
|
||||||
"unlimited": "Unlimited",
|
"unlimited": "Unlimited",
|
||||||
"status_enabled": "Enabled",
|
"status_enabled": "Enabled",
|
||||||
"status_disabled": "Disabled",
|
"status_disabled": "Disabled",
|
||||||
@@ -85,7 +85,8 @@
|
|||||||
"test_all_started": "已成功开始测试渠道,请刷新页面查看结果。",
|
"test_all_started": "已成功开始测试渠道,请刷新页面查看结果。",
|
||||||
"delete_disabled_success": "已删除所有禁用渠道,共计 {{count}} 个",
|
"delete_disabled_success": "已删除所有禁用渠道,共计 {{count}} 个",
|
||||||
"balance_update_success": "渠道 {{name}} 余额更新成功!",
|
"balance_update_success": "渠道 {{name}} 余额更新成功!",
|
||||||
"all_balance_updated": "已更新完毕所有已启用渠道余额!"
|
"all_balance_updated": "已更新完毕所有已启用渠道余额!",
|
||||||
|
"operation_success": "操作成功完成!"
|
||||||
},
|
},
|
||||||
"edit": {
|
"edit": {
|
||||||
"title_edit": "更新渠道信息",
|
"title_edit": "更新渠道信息",
|
||||||
@@ -54,10 +54,16 @@ const About = () => {
|
|||||||
style={{ width: '100%', height: '100vh', border: 'none' }}
|
style={{ width: '100%', height: '100vh', border: 'none' }}
|
||||||
/>
|
/>
|
||||||
) : (
|
) : (
|
||||||
<div
|
<div className='dashboard-container'>
|
||||||
style={{ fontSize: 'larger' }}
|
<Card fluid className='chart-card'>
|
||||||
dangerouslySetInnerHTML={{ __html: about }}
|
<Card.Content>
|
||||||
></div>
|
<div
|
||||||
|
style={{ fontSize: 'larger' }}
|
||||||
|
dangerouslySetInnerHTML={{ __html: about }}
|
||||||
|
></div>
|
||||||
|
</Card.Content>
|
||||||
|
</Card>
|
||||||
|
</div>
|
||||||
)}
|
)}
|
||||||
</>
|
</>
|
||||||
)}
|
)}
|
||||||
|
|||||||
@@ -207,6 +207,9 @@ const EditChannel = () => {
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
let localInputs = { ...inputs };
|
let localInputs = { ...inputs };
|
||||||
|
if (localInputs.key === 'undefined|undefined|undefined') {
|
||||||
|
localInputs.key = ''; // prevent potential bug
|
||||||
|
}
|
||||||
if (localInputs.base_url && localInputs.base_url.endsWith('/')) {
|
if (localInputs.base_url && localInputs.base_url.endsWith('/')) {
|
||||||
localInputs.base_url = localInputs.base_url.slice(
|
localInputs.base_url = localInputs.base_url.slice(
|
||||||
0,
|
0,
|
||||||
@@ -622,6 +625,21 @@ const EditChannel = () => {
|
|||||||
/>
|
/>
|
||||||
</Form.Field>
|
</Form.Field>
|
||||||
))}
|
))}
|
||||||
|
{inputs.type === 37 && (
|
||||||
|
<Form.Field>
|
||||||
|
<Form.Input
|
||||||
|
label='Account ID'
|
||||||
|
name='user_id'
|
||||||
|
required
|
||||||
|
placeholder={
|
||||||
|
'请输入 Account ID,例如:d8d7c61dbc334c32d3ced580e4bf42b4'
|
||||||
|
}
|
||||||
|
onChange={handleConfigChange}
|
||||||
|
value={config.user_id}
|
||||||
|
autoComplete=''
|
||||||
|
/>
|
||||||
|
</Form.Field>
|
||||||
|
)}
|
||||||
{inputs.type !== 33 && !isEdit && (
|
{inputs.type !== 33 && !isEdit && (
|
||||||
<Form.Checkbox
|
<Form.Checkbox
|
||||||
checked={batch}
|
checked={batch}
|
||||||
|
|||||||
@@ -36,7 +36,7 @@
|
|||||||
box-shadow: 0 2px 12px rgba(0, 0, 0, 0.04) !important;
|
box-shadow: 0 2px 12px rgba(0, 0, 0, 0.04) !important;
|
||||||
border: none !important;
|
border: none !important;
|
||||||
border-radius: 16px !important;
|
border-radius: 16px !important;
|
||||||
padding-top: 8px!important;
|
padding: 8px!important;
|
||||||
}
|
}
|
||||||
|
|
||||||
.chart-container {
|
.chart-container {
|
||||||
@@ -97,9 +97,9 @@
|
|||||||
}
|
}
|
||||||
|
|
||||||
.settings-tab .active.item {
|
.settings-tab .active.item {
|
||||||
color: #4318FF !important;
|
color: #000 !important;
|
||||||
font-weight: 600 !important;
|
font-weight: 600 !important;
|
||||||
border-color: #4318FF !important;
|
border-color: #000 !important;
|
||||||
}
|
}
|
||||||
|
|
||||||
.ui.tab.segment {
|
.ui.tab.segment {
|
||||||
|
|||||||
@@ -1,19 +1,17 @@
|
|||||||
import React, { useEffect, useState } from 'react';
|
import React, {useEffect, useState} from 'react';
|
||||||
import { useTranslation } from 'react-i18next';
|
import {useTranslation} from 'react-i18next';
|
||||||
import { Card, Grid, Header, Segment, Statistic } from 'semantic-ui-react';
|
import {Card, Grid} from 'semantic-ui-react';
|
||||||
import { API, showError } from '../../helpers';
|
|
||||||
import moment from 'moment';
|
|
||||||
import {
|
import {
|
||||||
LineChart,
|
Bar,
|
||||||
|
BarChart,
|
||||||
|
CartesianGrid,
|
||||||
|
Legend,
|
||||||
Line,
|
Line,
|
||||||
|
LineChart,
|
||||||
|
ResponsiveContainer,
|
||||||
|
Tooltip,
|
||||||
XAxis,
|
XAxis,
|
||||||
YAxis,
|
YAxis,
|
||||||
CartesianGrid,
|
|
||||||
Tooltip,
|
|
||||||
ResponsiveContainer,
|
|
||||||
BarChart,
|
|
||||||
Bar,
|
|
||||||
Legend,
|
|
||||||
} from 'recharts';
|
} from 'recharts';
|
||||||
import axios from 'axios';
|
import axios from 'axios';
|
||||||
import './Dashboard.css';
|
import './Dashboard.css';
|
||||||
@@ -244,7 +242,7 @@ const Dashboard = () => {
|
|||||||
<Card.Content>
|
<Card.Content>
|
||||||
<Card.Header>
|
<Card.Header>
|
||||||
{t('dashboard.charts.requests.title')}
|
{t('dashboard.charts.requests.title')}
|
||||||
<span className='stat-value'>{summaryData.todayRequests}</span>
|
{/* <span className='stat-value'>{summaryData.todayRequests}</span> */}
|
||||||
</Card.Header>
|
</Card.Header>
|
||||||
<div className='chart-container'>
|
<div className='chart-container'>
|
||||||
<ResponsiveContainer
|
<ResponsiveContainer
|
||||||
@@ -273,7 +271,7 @@ const Dashboard = () => {
|
|||||||
t('dashboard.charts.requests.tooltip'),
|
t('dashboard.charts.requests.tooltip'),
|
||||||
]}
|
]}
|
||||||
labelFormatter={(label) =>
|
labelFormatter={(label) =>
|
||||||
`${t('dashboard.tooltip.date')}: ${formatDate(label)}`
|
`${t('dashboard.statistics.tooltip.date')}: ${formatDate(label)}`
|
||||||
}
|
}
|
||||||
/>
|
/>
|
||||||
<Line
|
<Line
|
||||||
@@ -296,9 +294,9 @@ const Dashboard = () => {
|
|||||||
<Card.Content>
|
<Card.Content>
|
||||||
<Card.Header>
|
<Card.Header>
|
||||||
{t('dashboard.charts.quota.title')}
|
{t('dashboard.charts.quota.title')}
|
||||||
<span className='stat-value'>
|
{/* <span className='stat-value'>
|
||||||
${summaryData.todayQuota.toFixed(3)}
|
${summaryData.todayQuota.toFixed(3)}
|
||||||
</span>
|
</span> */}
|
||||||
</Card.Header>
|
</Card.Header>
|
||||||
<div className='chart-container'>
|
<div className='chart-container'>
|
||||||
<ResponsiveContainer
|
<ResponsiveContainer
|
||||||
@@ -327,7 +325,7 @@ const Dashboard = () => {
|
|||||||
t('dashboard.charts.quota.tooltip'),
|
t('dashboard.charts.quota.tooltip'),
|
||||||
]}
|
]}
|
||||||
labelFormatter={(label) =>
|
labelFormatter={(label) =>
|
||||||
`${t('dashboard.tooltip.date')}: ${formatDate(label)}`
|
`${t('dashboard.statistics.tooltip.date')}: ${formatDate(label)}`
|
||||||
}
|
}
|
||||||
/>
|
/>
|
||||||
<Line
|
<Line
|
||||||
@@ -350,7 +348,7 @@ const Dashboard = () => {
|
|||||||
<Card.Content>
|
<Card.Content>
|
||||||
<Card.Header>
|
<Card.Header>
|
||||||
{t('dashboard.charts.tokens.title')}
|
{t('dashboard.charts.tokens.title')}
|
||||||
<span className='stat-value'>{summaryData.todayTokens}</span>
|
{/* <span className='stat-value'>{summaryData.todayTokens}</span> */}
|
||||||
</Card.Header>
|
</Card.Header>
|
||||||
<div className='chart-container'>
|
<div className='chart-container'>
|
||||||
<ResponsiveContainer
|
<ResponsiveContainer
|
||||||
@@ -379,7 +377,7 @@ const Dashboard = () => {
|
|||||||
t('dashboard.charts.tokens.tooltip'),
|
t('dashboard.charts.tokens.tooltip'),
|
||||||
]}
|
]}
|
||||||
labelFormatter={(label) =>
|
labelFormatter={(label) =>
|
||||||
`${t('dashboard.tooltip.date')}: ${formatDate(label)}`
|
`${t('dashboard.statistics.tooltip.date')}: ${formatDate(label)}`
|
||||||
}
|
}
|
||||||
/>
|
/>
|
||||||
<Line
|
<Line
|
||||||
@@ -424,7 +422,7 @@ const Dashboard = () => {
|
|||||||
boxShadow: '0 2px 8px rgba(0,0,0,0.1)',
|
boxShadow: '0 2px 8px rgba(0,0,0,0.1)',
|
||||||
}}
|
}}
|
||||||
labelFormatter={(label) =>
|
labelFormatter={(label) =>
|
||||||
`${t('dashboard.tooltip.date')}: ${formatDate(label)}`
|
`${t('dashboard.statistics.tooltip.date')}: ${formatDate(label)}`
|
||||||
}
|
}
|
||||||
/>
|
/>
|
||||||
<Legend
|
<Legend
|
||||||
|
|||||||
Reference in New Issue
Block a user