✨ feat: Add lucide-react icons to all table Tag components
- Add semantic icons to ChannelsTable.js for channel status, response time, and quota display - Add status and quota icons to TokensTable.js for better visual distinction - Add status and quota icons to RedemptionsTable.js for redemption code management - Add role, status, and statistics icons to UsersTable.js for user management - Import appropriate lucide-react icons for each table component - Enhance UI consistency and user experience across all table interfaces Icons added include: - Status indicators: CheckCircle, XCircle, AlertCircle, HelpCircle - Performance metrics: Zap, Timer, Clock, AlertTriangle, TestTube - Financial data: Coins, DollarSign - User roles: User, Shield, Crown - Activity tracking: Activity, Users, UserPlus This improves visual clarity and makes table data more intuitive to understand.
This commit is contained in:
@@ -7,9 +7,23 @@ import {
|
|||||||
timestamp2string,
|
timestamp2string,
|
||||||
renderGroup,
|
renderGroup,
|
||||||
renderNumberWithPoint,
|
renderNumberWithPoint,
|
||||||
renderQuota
|
renderQuota,
|
||||||
|
getChannelIcon
|
||||||
} from '../../helpers/index.js';
|
} from '../../helpers/index.js';
|
||||||
|
|
||||||
|
import {
|
||||||
|
CheckCircle,
|
||||||
|
XCircle,
|
||||||
|
AlertCircle,
|
||||||
|
HelpCircle,
|
||||||
|
TestTube,
|
||||||
|
Zap,
|
||||||
|
Timer,
|
||||||
|
Clock,
|
||||||
|
AlertTriangle,
|
||||||
|
Coins
|
||||||
|
} from 'lucide-react';
|
||||||
|
|
||||||
import { CHANNEL_OPTIONS, ITEMS_PER_PAGE } from '../../constants/index.js';
|
import { CHANNEL_OPTIONS, ITEMS_PER_PAGE } from '../../constants/index.js';
|
||||||
import {
|
import {
|
||||||
Button,
|
Button,
|
||||||
@@ -63,7 +77,12 @@ const ChannelsTable = () => {
|
|||||||
type2label[0] = { value: 0, label: t('未知类型'), color: 'grey' };
|
type2label[0] = { value: 0, label: t('未知类型'), color: 'grey' };
|
||||||
}
|
}
|
||||||
return (
|
return (
|
||||||
<Tag size='large' color={type2label[type]?.color} shape='circle'>
|
<Tag
|
||||||
|
size='large'
|
||||||
|
color={type2label[type]?.color}
|
||||||
|
shape='circle'
|
||||||
|
prefixIcon={getChannelIcon(type)}
|
||||||
|
>
|
||||||
{type2label[type]?.label}
|
{type2label[type]?.label}
|
||||||
</Tag>
|
</Tag>
|
||||||
);
|
);
|
||||||
@@ -87,25 +106,25 @@ const ChannelsTable = () => {
|
|||||||
switch (status) {
|
switch (status) {
|
||||||
case 1:
|
case 1:
|
||||||
return (
|
return (
|
||||||
<Tag size='large' color='green' shape='circle'>
|
<Tag size='large' color='green' shape='circle' prefixIcon={<CheckCircle size={14} />}>
|
||||||
{t('已启用')}
|
{t('已启用')}
|
||||||
</Tag>
|
</Tag>
|
||||||
);
|
);
|
||||||
case 2:
|
case 2:
|
||||||
return (
|
return (
|
||||||
<Tag size='large' color='yellow' shape='circle'>
|
<Tag size='large' color='yellow' shape='circle' prefixIcon={<XCircle size={14} />}>
|
||||||
{t('已禁用')}
|
{t('已禁用')}
|
||||||
</Tag>
|
</Tag>
|
||||||
);
|
);
|
||||||
case 3:
|
case 3:
|
||||||
return (
|
return (
|
||||||
<Tag size='large' color='yellow' shape='circle'>
|
<Tag size='large' color='yellow' shape='circle' prefixIcon={<AlertCircle size={14} />}>
|
||||||
{t('自动禁用')}
|
{t('自动禁用')}
|
||||||
</Tag>
|
</Tag>
|
||||||
);
|
);
|
||||||
default:
|
default:
|
||||||
return (
|
return (
|
||||||
<Tag size='large' color='grey' shape='circle'>
|
<Tag size='large' color='grey' shape='circle' prefixIcon={<HelpCircle size={14} />}>
|
||||||
{t('未知状态')}
|
{t('未知状态')}
|
||||||
</Tag>
|
</Tag>
|
||||||
);
|
);
|
||||||
@@ -117,31 +136,31 @@ const ChannelsTable = () => {
|
|||||||
time = time.toFixed(2) + t(' 秒');
|
time = time.toFixed(2) + t(' 秒');
|
||||||
if (responseTime === 0) {
|
if (responseTime === 0) {
|
||||||
return (
|
return (
|
||||||
<Tag size='large' color='grey' shape='circle'>
|
<Tag size='large' color='grey' shape='circle' prefixIcon={<TestTube size={14} />}>
|
||||||
{t('未测试')}
|
{t('未测试')}
|
||||||
</Tag>
|
</Tag>
|
||||||
);
|
);
|
||||||
} else if (responseTime <= 1000) {
|
} else if (responseTime <= 1000) {
|
||||||
return (
|
return (
|
||||||
<Tag size='large' color='green' shape='circle'>
|
<Tag size='large' color='green' shape='circle' prefixIcon={<Zap size={14} />}>
|
||||||
{time}
|
{time}
|
||||||
</Tag>
|
</Tag>
|
||||||
);
|
);
|
||||||
} else if (responseTime <= 3000) {
|
} else if (responseTime <= 3000) {
|
||||||
return (
|
return (
|
||||||
<Tag size='large' color='lime' shape='circle'>
|
<Tag size='large' color='lime' shape='circle' prefixIcon={<Timer size={14} />}>
|
||||||
{time}
|
{time}
|
||||||
</Tag>
|
</Tag>
|
||||||
);
|
);
|
||||||
} else if (responseTime <= 5000) {
|
} else if (responseTime <= 5000) {
|
||||||
return (
|
return (
|
||||||
<Tag size='large' color='yellow' shape='circle'>
|
<Tag size='large' color='yellow' shape='circle' prefixIcon={<Clock size={14} />}>
|
||||||
{time}
|
{time}
|
||||||
</Tag>
|
</Tag>
|
||||||
);
|
);
|
||||||
} else {
|
} else {
|
||||||
return (
|
return (
|
||||||
<Tag size='large' color='red' shape='circle'>
|
<Tag size='large' color='red' shape='circle' prefixIcon={<AlertTriangle size={14} />}>
|
||||||
{time}
|
{time}
|
||||||
</Tag>
|
</Tag>
|
||||||
);
|
);
|
||||||
@@ -228,7 +247,7 @@ const ChannelsTable = () => {
|
|||||||
<div>
|
<div>
|
||||||
<Space spacing={1}>
|
<Space spacing={1}>
|
||||||
<Tooltip content={t('已用额度')}>
|
<Tooltip content={t('已用额度')}>
|
||||||
<Tag color='white' type='ghost' size='large' shape='circle'>
|
<Tag color='white' type='ghost' size='large' shape='circle' prefixIcon={<Coins size={14} />}>
|
||||||
{renderQuota(record.used_quota)}
|
{renderQuota(record.used_quota)}
|
||||||
</Tag>
|
</Tag>
|
||||||
</Tooltip>
|
</Tooltip>
|
||||||
@@ -238,6 +257,7 @@ const ChannelsTable = () => {
|
|||||||
type='ghost'
|
type='ghost'
|
||||||
size='large'
|
size='large'
|
||||||
shape='circle'
|
shape='circle'
|
||||||
|
prefixIcon={<Coins size={14} />}
|
||||||
onClick={() => updateChannelBalance(record)}
|
onClick={() => updateChannelBalance(record)}
|
||||||
>
|
>
|
||||||
${renderNumberWithPoint(record.balance)}
|
${renderNumberWithPoint(record.balance)}
|
||||||
@@ -249,7 +269,7 @@ const ChannelsTable = () => {
|
|||||||
} else {
|
} else {
|
||||||
return (
|
return (
|
||||||
<Tooltip content={t('已用额度')}>
|
<Tooltip content={t('已用额度')}>
|
||||||
<Tag color='white' type='ghost' size='large' shape='circle'>
|
<Tag color='white' type='ghost' size='large' shape='circle' prefixIcon={<Coins size={14} />}>
|
||||||
{renderQuota(record.used_quota)}
|
{renderQuota(record.used_quota)}
|
||||||
</Tag>
|
</Tag>
|
||||||
</Tooltip>
|
</Tooltip>
|
||||||
|
|||||||
@@ -1,5 +1,18 @@
|
|||||||
import React, { useEffect, useState } from 'react';
|
import React, { useEffect, useState } from 'react';
|
||||||
import { useTranslation } from 'react-i18next';
|
import { useTranslation } from 'react-i18next';
|
||||||
|
import {
|
||||||
|
CreditCard,
|
||||||
|
ShoppingCart,
|
||||||
|
Settings,
|
||||||
|
Server,
|
||||||
|
AlertTriangle,
|
||||||
|
HelpCircle,
|
||||||
|
Zap,
|
||||||
|
Play,
|
||||||
|
Clock,
|
||||||
|
Hash,
|
||||||
|
Key
|
||||||
|
} from 'lucide-react';
|
||||||
import {
|
import {
|
||||||
API,
|
API,
|
||||||
copy,
|
copy,
|
||||||
@@ -20,7 +33,7 @@ import {
|
|||||||
renderQuota,
|
renderQuota,
|
||||||
stringToColor,
|
stringToColor,
|
||||||
getLogOther,
|
getLogOther,
|
||||||
renderModelTag,
|
renderModelTag
|
||||||
} from '../../helpers';
|
} from '../../helpers';
|
||||||
|
|
||||||
import {
|
import {
|
||||||
@@ -38,7 +51,7 @@ import {
|
|||||||
Card,
|
Card,
|
||||||
Typography,
|
Typography,
|
||||||
Divider,
|
Divider,
|
||||||
Form,
|
Form
|
||||||
} from '@douyinfe/semi-ui';
|
} from '@douyinfe/semi-ui';
|
||||||
import { ITEMS_PER_PAGE } from '../../constants';
|
import { ITEMS_PER_PAGE } from '../../constants';
|
||||||
import Paragraph from '@douyinfe/semi-ui/lib/es/typography/paragraph';
|
import Paragraph from '@douyinfe/semi-ui/lib/es/typography/paragraph';
|
||||||
@@ -71,37 +84,37 @@ const LogsTable = () => {
|
|||||||
switch (type) {
|
switch (type) {
|
||||||
case 1:
|
case 1:
|
||||||
return (
|
return (
|
||||||
<Tag color='cyan' size='large' shape='circle'>
|
<Tag color='cyan' size='large' shape='circle' prefixIcon={<CreditCard size={14} />}>
|
||||||
{t('充值')}
|
{t('充值')}
|
||||||
</Tag>
|
</Tag>
|
||||||
);
|
);
|
||||||
case 2:
|
case 2:
|
||||||
return (
|
return (
|
||||||
<Tag color='lime' size='large' shape='circle'>
|
<Tag color='lime' size='large' shape='circle' prefixIcon={<ShoppingCart size={14} />}>
|
||||||
{t('消费')}
|
{t('消费')}
|
||||||
</Tag>
|
</Tag>
|
||||||
);
|
);
|
||||||
case 3:
|
case 3:
|
||||||
return (
|
return (
|
||||||
<Tag color='orange' size='large' shape='circle'>
|
<Tag color='orange' size='large' shape='circle' prefixIcon={<Settings size={14} />}>
|
||||||
{t('管理')}
|
{t('管理')}
|
||||||
</Tag>
|
</Tag>
|
||||||
);
|
);
|
||||||
case 4:
|
case 4:
|
||||||
return (
|
return (
|
||||||
<Tag color='purple' size='large' shape='circle'>
|
<Tag color='purple' size='large' shape='circle' prefixIcon={<Server size={14} />}>
|
||||||
{t('系统')}
|
{t('系统')}
|
||||||
</Tag>
|
</Tag>
|
||||||
);
|
);
|
||||||
case 5:
|
case 5:
|
||||||
return (
|
return (
|
||||||
<Tag color='red' size='large' shape='circle'>
|
<Tag color='red' size='large' shape='circle' prefixIcon={<AlertTriangle size={14} />}>
|
||||||
{t('错误')}
|
{t('错误')}
|
||||||
</Tag>
|
</Tag>
|
||||||
);
|
);
|
||||||
default:
|
default:
|
||||||
return (
|
return (
|
||||||
<Tag color='grey' size='large' shape='circle'>
|
<Tag color='grey' size='large' shape='circle' prefixIcon={<HelpCircle size={14} />}>
|
||||||
{t('未知')}
|
{t('未知')}
|
||||||
</Tag>
|
</Tag>
|
||||||
);
|
);
|
||||||
@@ -111,13 +124,13 @@ const LogsTable = () => {
|
|||||||
function renderIsStream(bool) {
|
function renderIsStream(bool) {
|
||||||
if (bool) {
|
if (bool) {
|
||||||
return (
|
return (
|
||||||
<Tag color='blue' size='large' shape='circle'>
|
<Tag color='blue' size='large' shape='circle' prefixIcon={<Zap size={14} />}>
|
||||||
{t('流')}
|
{t('流')}
|
||||||
</Tag>
|
</Tag>
|
||||||
);
|
);
|
||||||
} else {
|
} else {
|
||||||
return (
|
return (
|
||||||
<Tag color='purple' size='large' shape='circle'>
|
<Tag color='purple' size='large' shape='circle' prefixIcon={<Play size={14} />}>
|
||||||
{t('非流')}
|
{t('非流')}
|
||||||
</Tag>
|
</Tag>
|
||||||
);
|
);
|
||||||
@@ -128,21 +141,21 @@ const LogsTable = () => {
|
|||||||
const time = parseInt(type);
|
const time = parseInt(type);
|
||||||
if (time < 101) {
|
if (time < 101) {
|
||||||
return (
|
return (
|
||||||
<Tag color='green' size='large' shape='circle'>
|
<Tag color='green' size='large' shape='circle' prefixIcon={<Clock size={14} />}>
|
||||||
{' '}
|
{' '}
|
||||||
{time} s{' '}
|
{time} s{' '}
|
||||||
</Tag>
|
</Tag>
|
||||||
);
|
);
|
||||||
} else if (time < 300) {
|
} else if (time < 300) {
|
||||||
return (
|
return (
|
||||||
<Tag color='orange' size='large' shape='circle'>
|
<Tag color='orange' size='large' shape='circle' prefixIcon={<Clock size={14} />}>
|
||||||
{' '}
|
{' '}
|
||||||
{time} s{' '}
|
{time} s{' '}
|
||||||
</Tag>
|
</Tag>
|
||||||
);
|
);
|
||||||
} else {
|
} else {
|
||||||
return (
|
return (
|
||||||
<Tag color='red' size='large' shape='circle'>
|
<Tag color='red' size='large' shape='circle' prefixIcon={<Clock size={14} />}>
|
||||||
{' '}
|
{' '}
|
||||||
{time} s{' '}
|
{time} s{' '}
|
||||||
</Tag>
|
</Tag>
|
||||||
@@ -155,21 +168,21 @@ const LogsTable = () => {
|
|||||||
time = time.toFixed(1);
|
time = time.toFixed(1);
|
||||||
if (time < 3) {
|
if (time < 3) {
|
||||||
return (
|
return (
|
||||||
<Tag color='green' size='large' shape='circle'>
|
<Tag color='green' size='large' shape='circle' prefixIcon={<Zap size={14} />}>
|
||||||
{' '}
|
{' '}
|
||||||
{time} s{' '}
|
{time} s{' '}
|
||||||
</Tag>
|
</Tag>
|
||||||
);
|
);
|
||||||
} else if (time < 10) {
|
} else if (time < 10) {
|
||||||
return (
|
return (
|
||||||
<Tag color='orange' size='large' shape='circle'>
|
<Tag color='orange' size='large' shape='circle' prefixIcon={<Zap size={14} />}>
|
||||||
{' '}
|
{' '}
|
||||||
{time} s{' '}
|
{time} s{' '}
|
||||||
</Tag>
|
</Tag>
|
||||||
);
|
);
|
||||||
} else {
|
} else {
|
||||||
return (
|
return (
|
||||||
<Tag color='red' size='large' shape='circle'>
|
<Tag color='red' size='large' shape='circle' prefixIcon={<Zap size={14} />}>
|
||||||
{' '}
|
{' '}
|
||||||
{time} s{' '}
|
{time} s{' '}
|
||||||
</Tag>
|
</Tag>
|
||||||
@@ -356,6 +369,7 @@ const LogsTable = () => {
|
|||||||
color={colors[parseInt(text) % colors.length]}
|
color={colors[parseInt(text) % colors.length]}
|
||||||
size='large'
|
size='large'
|
||||||
shape='circle'
|
shape='circle'
|
||||||
|
prefixIcon={<Hash size={14} />}
|
||||||
>
|
>
|
||||||
{' '}
|
{' '}
|
||||||
{text}{' '}
|
{text}{' '}
|
||||||
@@ -408,6 +422,7 @@ const LogsTable = () => {
|
|||||||
color='grey'
|
color='grey'
|
||||||
size='large'
|
size='large'
|
||||||
shape='circle'
|
shape='circle'
|
||||||
|
prefixIcon={<Key size={14} />}
|
||||||
onClick={(event) => {
|
onClick={(event) => {
|
||||||
//cancel the row click event
|
//cancel the row click event
|
||||||
copyText(event, text);
|
copyText(event, text);
|
||||||
|
|||||||
@@ -1,12 +1,38 @@
|
|||||||
import React, { useEffect, useState } from 'react';
|
import React, { useEffect, useState } from 'react';
|
||||||
import { useTranslation } from 'react-i18next';
|
import { useTranslation } from 'react-i18next';
|
||||||
|
import {
|
||||||
|
Palette,
|
||||||
|
ZoomIn,
|
||||||
|
Shuffle,
|
||||||
|
Move,
|
||||||
|
FileText,
|
||||||
|
Blend,
|
||||||
|
Upload,
|
||||||
|
Minimize2,
|
||||||
|
RotateCcw,
|
||||||
|
PaintBucket,
|
||||||
|
Focus,
|
||||||
|
Move3D,
|
||||||
|
Monitor,
|
||||||
|
UserCheck,
|
||||||
|
HelpCircle,
|
||||||
|
CheckCircle,
|
||||||
|
Clock,
|
||||||
|
Copy,
|
||||||
|
FileX,
|
||||||
|
Pause,
|
||||||
|
XCircle,
|
||||||
|
Loader,
|
||||||
|
AlertCircle,
|
||||||
|
Hash
|
||||||
|
} from 'lucide-react';
|
||||||
import {
|
import {
|
||||||
API,
|
API,
|
||||||
copy,
|
copy,
|
||||||
isAdmin,
|
isAdmin,
|
||||||
showError,
|
showError,
|
||||||
showSuccess,
|
showSuccess,
|
||||||
timestamp2string,
|
timestamp2string
|
||||||
} from '../../helpers';
|
} from '../../helpers';
|
||||||
|
|
||||||
import {
|
import {
|
||||||
@@ -22,13 +48,13 @@ import {
|
|||||||
Skeleton,
|
Skeleton,
|
||||||
Table,
|
Table,
|
||||||
Tag,
|
Tag,
|
||||||
Typography,
|
Typography
|
||||||
} from '@douyinfe/semi-ui';
|
} from '@douyinfe/semi-ui';
|
||||||
import { ITEMS_PER_PAGE } from '../../constants';
|
import { ITEMS_PER_PAGE } from '../../constants';
|
||||||
import {
|
import {
|
||||||
IconEyeOpened,
|
IconEyeOpened,
|
||||||
IconSearch,
|
IconSearch,
|
||||||
IconSetting,
|
IconSetting
|
||||||
} from '@douyinfe/semi-icons';
|
} from '@douyinfe/semi-icons';
|
||||||
|
|
||||||
const { Text } = Typography;
|
const { Text } = Typography;
|
||||||
@@ -153,103 +179,103 @@ const LogsTable = () => {
|
|||||||
switch (type) {
|
switch (type) {
|
||||||
case 'IMAGINE':
|
case 'IMAGINE':
|
||||||
return (
|
return (
|
||||||
<Tag color='blue' size='large' shape='circle'>
|
<Tag color='blue' size='large' shape='circle' prefixIcon={<Palette size={14} />}>
|
||||||
{t('绘图')}
|
{t('绘图')}
|
||||||
</Tag>
|
</Tag>
|
||||||
);
|
);
|
||||||
case 'UPSCALE':
|
case 'UPSCALE':
|
||||||
return (
|
return (
|
||||||
<Tag color='orange' size='large' shape='circle'>
|
<Tag color='orange' size='large' shape='circle' prefixIcon={<ZoomIn size={14} />}>
|
||||||
{t('放大')}
|
{t('放大')}
|
||||||
</Tag>
|
</Tag>
|
||||||
);
|
);
|
||||||
case 'VARIATION':
|
case 'VARIATION':
|
||||||
return (
|
return (
|
||||||
<Tag color='purple' size='large' shape='circle'>
|
<Tag color='purple' size='large' shape='circle' prefixIcon={<Shuffle size={14} />}>
|
||||||
{t('变换')}
|
{t('变换')}
|
||||||
</Tag>
|
</Tag>
|
||||||
);
|
);
|
||||||
case 'HIGH_VARIATION':
|
case 'HIGH_VARIATION':
|
||||||
return (
|
return (
|
||||||
<Tag color='purple' size='large' shape='circle'>
|
<Tag color='purple' size='large' shape='circle' prefixIcon={<Shuffle size={14} />}>
|
||||||
{t('强变换')}
|
{t('强变换')}
|
||||||
</Tag>
|
</Tag>
|
||||||
);
|
);
|
||||||
case 'LOW_VARIATION':
|
case 'LOW_VARIATION':
|
||||||
return (
|
return (
|
||||||
<Tag color='purple' size='large' shape='circle'>
|
<Tag color='purple' size='large' shape='circle' prefixIcon={<Shuffle size={14} />}>
|
||||||
{t('弱变换')}
|
{t('弱变换')}
|
||||||
</Tag>
|
</Tag>
|
||||||
);
|
);
|
||||||
case 'PAN':
|
case 'PAN':
|
||||||
return (
|
return (
|
||||||
<Tag color='cyan' size='large' shape='circle'>
|
<Tag color='cyan' size='large' shape='circle' prefixIcon={<Move size={14} />}>
|
||||||
{t('平移')}
|
{t('平移')}
|
||||||
</Tag>
|
</Tag>
|
||||||
);
|
);
|
||||||
case 'DESCRIBE':
|
case 'DESCRIBE':
|
||||||
return (
|
return (
|
||||||
<Tag color='yellow' size='large' shape='circle'>
|
<Tag color='yellow' size='large' shape='circle' prefixIcon={<FileText size={14} />}>
|
||||||
{t('图生文')}
|
{t('图生文')}
|
||||||
</Tag>
|
</Tag>
|
||||||
);
|
);
|
||||||
case 'BLEND':
|
case 'BLEND':
|
||||||
return (
|
return (
|
||||||
<Tag color='lime' size='large' shape='circle'>
|
<Tag color='lime' size='large' shape='circle' prefixIcon={<Blend size={14} />}>
|
||||||
{t('图混合')}
|
{t('图混合')}
|
||||||
</Tag>
|
</Tag>
|
||||||
);
|
);
|
||||||
case 'UPLOAD':
|
case 'UPLOAD':
|
||||||
return (
|
return (
|
||||||
<Tag color='blue' size='large' shape='circle'>
|
<Tag color='blue' size='large' shape='circle' prefixIcon={<Upload size={14} />}>
|
||||||
上传文件
|
上传文件
|
||||||
</Tag>
|
</Tag>
|
||||||
);
|
);
|
||||||
case 'SHORTEN':
|
case 'SHORTEN':
|
||||||
return (
|
return (
|
||||||
<Tag color='pink' size='large' shape='circle'>
|
<Tag color='pink' size='large' shape='circle' prefixIcon={<Minimize2 size={14} />}>
|
||||||
{t('缩词')}
|
{t('缩词')}
|
||||||
</Tag>
|
</Tag>
|
||||||
);
|
);
|
||||||
case 'REROLL':
|
case 'REROLL':
|
||||||
return (
|
return (
|
||||||
<Tag color='indigo' size='large' shape='circle'>
|
<Tag color='indigo' size='large' shape='circle' prefixIcon={<RotateCcw size={14} />}>
|
||||||
{t('重绘')}
|
{t('重绘')}
|
||||||
</Tag>
|
</Tag>
|
||||||
);
|
);
|
||||||
case 'INPAINT':
|
case 'INPAINT':
|
||||||
return (
|
return (
|
||||||
<Tag color='violet' size='large' shape='circle'>
|
<Tag color='violet' size='large' shape='circle' prefixIcon={<PaintBucket size={14} />}>
|
||||||
{t('局部重绘-提交')}
|
{t('局部重绘-提交')}
|
||||||
</Tag>
|
</Tag>
|
||||||
);
|
);
|
||||||
case 'ZOOM':
|
case 'ZOOM':
|
||||||
return (
|
return (
|
||||||
<Tag color='teal' size='large' shape='circle'>
|
<Tag color='teal' size='large' shape='circle' prefixIcon={<Focus size={14} />}>
|
||||||
{t('变焦')}
|
{t('变焦')}
|
||||||
</Tag>
|
</Tag>
|
||||||
);
|
);
|
||||||
case 'CUSTOM_ZOOM':
|
case 'CUSTOM_ZOOM':
|
||||||
return (
|
return (
|
||||||
<Tag color='teal' size='large' shape='circle'>
|
<Tag color='teal' size='large' shape='circle' prefixIcon={<Move3D size={14} />}>
|
||||||
{t('自定义变焦-提交')}
|
{t('自定义变焦-提交')}
|
||||||
</Tag>
|
</Tag>
|
||||||
);
|
);
|
||||||
case 'MODAL':
|
case 'MODAL':
|
||||||
return (
|
return (
|
||||||
<Tag color='green' size='large' shape='circle'>
|
<Tag color='green' size='large' shape='circle' prefixIcon={<Monitor size={14} />}>
|
||||||
{t('窗口处理')}
|
{t('窗口处理')}
|
||||||
</Tag>
|
</Tag>
|
||||||
);
|
);
|
||||||
case 'SWAP_FACE':
|
case 'SWAP_FACE':
|
||||||
return (
|
return (
|
||||||
<Tag color='light-green' size='large' shape='circle'>
|
<Tag color='light-green' size='large' shape='circle' prefixIcon={<UserCheck size={14} />}>
|
||||||
{t('换脸')}
|
{t('换脸')}
|
||||||
</Tag>
|
</Tag>
|
||||||
);
|
);
|
||||||
default:
|
default:
|
||||||
return (
|
return (
|
||||||
<Tag color='white' size='large' shape='circle'>
|
<Tag color='white' size='large' shape='circle' prefixIcon={<HelpCircle size={14} />}>
|
||||||
{t('未知')}
|
{t('未知')}
|
||||||
</Tag>
|
</Tag>
|
||||||
);
|
);
|
||||||
@@ -260,31 +286,31 @@ const LogsTable = () => {
|
|||||||
switch (code) {
|
switch (code) {
|
||||||
case 1:
|
case 1:
|
||||||
return (
|
return (
|
||||||
<Tag color='green' size='large' shape='circle'>
|
<Tag color='green' size='large' shape='circle' prefixIcon={<CheckCircle size={14} />}>
|
||||||
{t('已提交')}
|
{t('已提交')}
|
||||||
</Tag>
|
</Tag>
|
||||||
);
|
);
|
||||||
case 21:
|
case 21:
|
||||||
return (
|
return (
|
||||||
<Tag color='lime' size='large' shape='circle'>
|
<Tag color='lime' size='large' shape='circle' prefixIcon={<Clock size={14} />}>
|
||||||
{t('等待中')}
|
{t('等待中')}
|
||||||
</Tag>
|
</Tag>
|
||||||
);
|
);
|
||||||
case 22:
|
case 22:
|
||||||
return (
|
return (
|
||||||
<Tag color='orange' size='large' shape='circle'>
|
<Tag color='orange' size='large' shape='circle' prefixIcon={<Copy size={14} />}>
|
||||||
{t('重复提交')}
|
{t('重复提交')}
|
||||||
</Tag>
|
</Tag>
|
||||||
);
|
);
|
||||||
case 0:
|
case 0:
|
||||||
return (
|
return (
|
||||||
<Tag color='yellow' size='large' shape='circle'>
|
<Tag color='yellow' size='large' shape='circle' prefixIcon={<FileX size={14} />}>
|
||||||
{t('未提交')}
|
{t('未提交')}
|
||||||
</Tag>
|
</Tag>
|
||||||
);
|
);
|
||||||
default:
|
default:
|
||||||
return (
|
return (
|
||||||
<Tag color='white' size='large' shape='circle'>
|
<Tag color='white' size='large' shape='circle' prefixIcon={<HelpCircle size={14} />}>
|
||||||
{t('未知')}
|
{t('未知')}
|
||||||
</Tag>
|
</Tag>
|
||||||
);
|
);
|
||||||
@@ -295,43 +321,43 @@ const LogsTable = () => {
|
|||||||
switch (type) {
|
switch (type) {
|
||||||
case 'SUCCESS':
|
case 'SUCCESS':
|
||||||
return (
|
return (
|
||||||
<Tag color='green' size='large' shape='circle'>
|
<Tag color='green' size='large' shape='circle' prefixIcon={<CheckCircle size={14} />}>
|
||||||
{t('成功')}
|
{t('成功')}
|
||||||
</Tag>
|
</Tag>
|
||||||
);
|
);
|
||||||
case 'NOT_START':
|
case 'NOT_START':
|
||||||
return (
|
return (
|
||||||
<Tag color='grey' size='large' shape='circle'>
|
<Tag color='grey' size='large' shape='circle' prefixIcon={<Pause size={14} />}>
|
||||||
{t('未启动')}
|
{t('未启动')}
|
||||||
</Tag>
|
</Tag>
|
||||||
);
|
);
|
||||||
case 'SUBMITTED':
|
case 'SUBMITTED':
|
||||||
return (
|
return (
|
||||||
<Tag color='yellow' size='large' shape='circle'>
|
<Tag color='yellow' size='large' shape='circle' prefixIcon={<Clock size={14} />}>
|
||||||
{t('队列中')}
|
{t('队列中')}
|
||||||
</Tag>
|
</Tag>
|
||||||
);
|
);
|
||||||
case 'IN_PROGRESS':
|
case 'IN_PROGRESS':
|
||||||
return (
|
return (
|
||||||
<Tag color='blue' size='large' shape='circle'>
|
<Tag color='blue' size='large' shape='circle' prefixIcon={<Loader size={14} />}>
|
||||||
{t('执行中')}
|
{t('执行中')}
|
||||||
</Tag>
|
</Tag>
|
||||||
);
|
);
|
||||||
case 'FAILURE':
|
case 'FAILURE':
|
||||||
return (
|
return (
|
||||||
<Tag color='red' size='large' shape='circle'>
|
<Tag color='red' size='large' shape='circle' prefixIcon={<XCircle size={14} />}>
|
||||||
{t('失败')}
|
{t('失败')}
|
||||||
</Tag>
|
</Tag>
|
||||||
);
|
);
|
||||||
case 'MODAL':
|
case 'MODAL':
|
||||||
return (
|
return (
|
||||||
<Tag color='yellow' size='large' shape='circle'>
|
<Tag color='yellow' size='large' shape='circle' prefixIcon={<AlertCircle size={14} />}>
|
||||||
{t('窗口等待')}
|
{t('窗口等待')}
|
||||||
</Tag>
|
</Tag>
|
||||||
);
|
);
|
||||||
default:
|
default:
|
||||||
return (
|
return (
|
||||||
<Tag color='white' size='large' shape='circle'>
|
<Tag color='white' size='large' shape='circle' prefixIcon={<HelpCircle size={14} />}>
|
||||||
{t('未知')}
|
{t('未知')}
|
||||||
</Tag>
|
</Tag>
|
||||||
);
|
);
|
||||||
@@ -361,7 +387,7 @@ const LogsTable = () => {
|
|||||||
const color = durationSec > 60 ? 'red' : 'green';
|
const color = durationSec > 60 ? 'red' : 'green';
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<Tag color={color} size='large' shape='circle'>
|
<Tag color={color} size='large' shape='circle' prefixIcon={<Clock size={14} />}>
|
||||||
{durationSec} {t('秒')}
|
{durationSec} {t('秒')}
|
||||||
</Tag>
|
</Tag>
|
||||||
);
|
);
|
||||||
@@ -397,6 +423,7 @@ const LogsTable = () => {
|
|||||||
color={colors[parseInt(text) % colors.length]}
|
color={colors[parseInt(text) % colors.length]}
|
||||||
size='large'
|
size='large'
|
||||||
shape='circle'
|
shape='circle'
|
||||||
|
prefixIcon={<Hash size={14} />}
|
||||||
onClick={() => {
|
onClick={() => {
|
||||||
copyText(text);
|
copyText(text);
|
||||||
}}
|
}}
|
||||||
|
|||||||
@@ -8,6 +8,14 @@ import {
|
|||||||
renderQuota
|
renderQuota
|
||||||
} from '../../helpers';
|
} from '../../helpers';
|
||||||
|
|
||||||
|
import {
|
||||||
|
CheckCircle,
|
||||||
|
XCircle,
|
||||||
|
Minus,
|
||||||
|
HelpCircle,
|
||||||
|
Coins
|
||||||
|
} from 'lucide-react';
|
||||||
|
|
||||||
import { ITEMS_PER_PAGE } from '../../constants';
|
import { ITEMS_PER_PAGE } from '../../constants';
|
||||||
import {
|
import {
|
||||||
Button,
|
Button,
|
||||||
@@ -20,7 +28,7 @@ import {
|
|||||||
Space,
|
Space,
|
||||||
Table,
|
Table,
|
||||||
Tag,
|
Tag,
|
||||||
Typography,
|
Typography
|
||||||
} from '@douyinfe/semi-ui';
|
} from '@douyinfe/semi-ui';
|
||||||
import {
|
import {
|
||||||
IconPlus,
|
IconPlus,
|
||||||
@@ -31,7 +39,7 @@ import {
|
|||||||
IconDelete,
|
IconDelete,
|
||||||
IconStop,
|
IconStop,
|
||||||
IconPlay,
|
IconPlay,
|
||||||
IconMore,
|
IconMore
|
||||||
} from '@douyinfe/semi-icons';
|
} from '@douyinfe/semi-icons';
|
||||||
import EditRedemption from '../../pages/Redemption/EditRedemption';
|
import EditRedemption from '../../pages/Redemption/EditRedemption';
|
||||||
import { useTranslation } from 'react-i18next';
|
import { useTranslation } from 'react-i18next';
|
||||||
@@ -49,25 +57,25 @@ const RedemptionsTable = () => {
|
|||||||
switch (status) {
|
switch (status) {
|
||||||
case 1:
|
case 1:
|
||||||
return (
|
return (
|
||||||
<Tag color='green' size='large' shape='circle'>
|
<Tag color='green' size='large' shape='circle' prefixIcon={<CheckCircle size={14} />}>
|
||||||
{t('未使用')}
|
{t('未使用')}
|
||||||
</Tag>
|
</Tag>
|
||||||
);
|
);
|
||||||
case 2:
|
case 2:
|
||||||
return (
|
return (
|
||||||
<Tag color='red' size='large' shape='circle'>
|
<Tag color='red' size='large' shape='circle' prefixIcon={<XCircle size={14} />}>
|
||||||
{t('已禁用')}
|
{t('已禁用')}
|
||||||
</Tag>
|
</Tag>
|
||||||
);
|
);
|
||||||
case 3:
|
case 3:
|
||||||
return (
|
return (
|
||||||
<Tag color='grey' size='large' shape='circle'>
|
<Tag color='grey' size='large' shape='circle' prefixIcon={<Minus size={14} />}>
|
||||||
{t('已使用')}
|
{t('已使用')}
|
||||||
</Tag>
|
</Tag>
|
||||||
);
|
);
|
||||||
default:
|
default:
|
||||||
return (
|
return (
|
||||||
<Tag color='black' size='large' shape='circle'>
|
<Tag color='black' size='large' shape='circle' prefixIcon={<HelpCircle size={14} />}>
|
||||||
{t('未知状态')}
|
{t('未知状态')}
|
||||||
</Tag>
|
</Tag>
|
||||||
);
|
);
|
||||||
@@ -95,7 +103,13 @@ const RedemptionsTable = () => {
|
|||||||
title: t('额度'),
|
title: t('额度'),
|
||||||
dataIndex: 'quota',
|
dataIndex: 'quota',
|
||||||
render: (text, record, index) => {
|
render: (text, record, index) => {
|
||||||
return <div>{renderQuota(parseInt(text))}</div>;
|
return (
|
||||||
|
<div>
|
||||||
|
<Tag size={'large'} color={'grey'} shape='circle' prefixIcon={<Coins size={14} />}>
|
||||||
|
{renderQuota(parseInt(text))}
|
||||||
|
</Tag>
|
||||||
|
</div>
|
||||||
|
);
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
|
|||||||
@@ -1,12 +1,25 @@
|
|||||||
import React, { useEffect, useState } from 'react';
|
import React, { useEffect, useState } from 'react';
|
||||||
import { useTranslation } from 'react-i18next';
|
import { useTranslation } from 'react-i18next';
|
||||||
|
import {
|
||||||
|
Music,
|
||||||
|
FileText,
|
||||||
|
HelpCircle,
|
||||||
|
CheckCircle,
|
||||||
|
Pause,
|
||||||
|
Clock,
|
||||||
|
Play,
|
||||||
|
XCircle,
|
||||||
|
Loader,
|
||||||
|
List,
|
||||||
|
Hash
|
||||||
|
} from 'lucide-react';
|
||||||
import {
|
import {
|
||||||
API,
|
API,
|
||||||
copy,
|
copy,
|
||||||
isAdmin,
|
isAdmin,
|
||||||
showError,
|
showError,
|
||||||
showSuccess,
|
showSuccess,
|
||||||
timestamp2string,
|
timestamp2string
|
||||||
} from '../../helpers';
|
} from '../../helpers';
|
||||||
|
|
||||||
import {
|
import {
|
||||||
@@ -21,13 +34,13 @@ import {
|
|||||||
Skeleton,
|
Skeleton,
|
||||||
Table,
|
Table,
|
||||||
Tag,
|
Tag,
|
||||||
Typography,
|
Typography
|
||||||
} from '@douyinfe/semi-ui';
|
} from '@douyinfe/semi-ui';
|
||||||
import { ITEMS_PER_PAGE } from '../../constants';
|
import { ITEMS_PER_PAGE } from '../../constants';
|
||||||
import {
|
import {
|
||||||
IconEyeOpened,
|
IconEyeOpened,
|
||||||
IconSearch,
|
IconSearch,
|
||||||
IconSetting,
|
IconSetting
|
||||||
} from '@douyinfe/semi-icons';
|
} from '@douyinfe/semi-icons';
|
||||||
|
|
||||||
const { Text } = Typography;
|
const { Text } = Typography;
|
||||||
@@ -96,7 +109,7 @@ function renderDuration(submit_time, finishTime) {
|
|||||||
|
|
||||||
// 返回带有样式的颜色标签
|
// 返回带有样式的颜色标签
|
||||||
return (
|
return (
|
||||||
<Tag color={color} size='large'>
|
<Tag color={color} size='large' prefixIcon={<Clock size={14} />}>
|
||||||
{durationSec} 秒
|
{durationSec} 秒
|
||||||
</Tag>
|
</Tag>
|
||||||
);
|
);
|
||||||
@@ -187,19 +200,19 @@ const LogsTable = () => {
|
|||||||
switch (type) {
|
switch (type) {
|
||||||
case 'MUSIC':
|
case 'MUSIC':
|
||||||
return (
|
return (
|
||||||
<Tag color='grey' size='large' shape='circle'>
|
<Tag color='grey' size='large' shape='circle' prefixIcon={<Music size={14} />}>
|
||||||
{t('生成音乐')}
|
{t('生成音乐')}
|
||||||
</Tag>
|
</Tag>
|
||||||
);
|
);
|
||||||
case 'LYRICS':
|
case 'LYRICS':
|
||||||
return (
|
return (
|
||||||
<Tag color='pink' size='large' shape='circle'>
|
<Tag color='pink' size='large' shape='circle' prefixIcon={<FileText size={14} />}>
|
||||||
{t('生成歌词')}
|
{t('生成歌词')}
|
||||||
</Tag>
|
</Tag>
|
||||||
);
|
);
|
||||||
default:
|
default:
|
||||||
return (
|
return (
|
||||||
<Tag color='white' size='large' shape='circle'>
|
<Tag color='white' size='large' shape='circle' prefixIcon={<HelpCircle size={14} />}>
|
||||||
{t('未知')}
|
{t('未知')}
|
||||||
</Tag>
|
</Tag>
|
||||||
);
|
);
|
||||||
@@ -210,13 +223,13 @@ const LogsTable = () => {
|
|||||||
switch (type) {
|
switch (type) {
|
||||||
case 'suno':
|
case 'suno':
|
||||||
return (
|
return (
|
||||||
<Tag color='green' size='large' shape='circle'>
|
<Tag color='green' size='large' shape='circle' prefixIcon={<Music size={14} />}>
|
||||||
Suno
|
Suno
|
||||||
</Tag>
|
</Tag>
|
||||||
);
|
);
|
||||||
default:
|
default:
|
||||||
return (
|
return (
|
||||||
<Tag color='white' size='large' shape='circle'>
|
<Tag color='white' size='large' shape='circle' prefixIcon={<HelpCircle size={14} />}>
|
||||||
{t('未知')}
|
{t('未知')}
|
||||||
</Tag>
|
</Tag>
|
||||||
);
|
);
|
||||||
@@ -227,55 +240,55 @@ const LogsTable = () => {
|
|||||||
switch (type) {
|
switch (type) {
|
||||||
case 'SUCCESS':
|
case 'SUCCESS':
|
||||||
return (
|
return (
|
||||||
<Tag color='green' size='large' shape='circle'>
|
<Tag color='green' size='large' shape='circle' prefixIcon={<CheckCircle size={14} />}>
|
||||||
{t('成功')}
|
{t('成功')}
|
||||||
</Tag>
|
</Tag>
|
||||||
);
|
);
|
||||||
case 'NOT_START':
|
case 'NOT_START':
|
||||||
return (
|
return (
|
||||||
<Tag color='grey' size='large' shape='circle'>
|
<Tag color='grey' size='large' shape='circle' prefixIcon={<Pause size={14} />}>
|
||||||
{t('未启动')}
|
{t('未启动')}
|
||||||
</Tag>
|
</Tag>
|
||||||
);
|
);
|
||||||
case 'SUBMITTED':
|
case 'SUBMITTED':
|
||||||
return (
|
return (
|
||||||
<Tag color='yellow' size='large' shape='circle'>
|
<Tag color='yellow' size='large' shape='circle' prefixIcon={<Clock size={14} />}>
|
||||||
{t('队列中')}
|
{t('队列中')}
|
||||||
</Tag>
|
</Tag>
|
||||||
);
|
);
|
||||||
case 'IN_PROGRESS':
|
case 'IN_PROGRESS':
|
||||||
return (
|
return (
|
||||||
<Tag color='blue' size='large' shape='circle'>
|
<Tag color='blue' size='large' shape='circle' prefixIcon={<Play size={14} />}>
|
||||||
{t('执行中')}
|
{t('执行中')}
|
||||||
</Tag>
|
</Tag>
|
||||||
);
|
);
|
||||||
case 'FAILURE':
|
case 'FAILURE':
|
||||||
return (
|
return (
|
||||||
<Tag color='red' size='large' shape='circle'>
|
<Tag color='red' size='large' shape='circle' prefixIcon={<XCircle size={14} />}>
|
||||||
{t('失败')}
|
{t('失败')}
|
||||||
</Tag>
|
</Tag>
|
||||||
);
|
);
|
||||||
case 'QUEUED':
|
case 'QUEUED':
|
||||||
return (
|
return (
|
||||||
<Tag color='orange' size='large' shape='circle'>
|
<Tag color='orange' size='large' shape='circle' prefixIcon={<List size={14} />}>
|
||||||
{t('排队中')}
|
{t('排队中')}
|
||||||
</Tag>
|
</Tag>
|
||||||
);
|
);
|
||||||
case 'UNKNOWN':
|
case 'UNKNOWN':
|
||||||
return (
|
return (
|
||||||
<Tag color='white' size='large' shape='circle'>
|
<Tag color='white' size='large' shape='circle' prefixIcon={<HelpCircle size={14} />}>
|
||||||
{t('未知')}
|
{t('未知')}
|
||||||
</Tag>
|
</Tag>
|
||||||
);
|
);
|
||||||
case '':
|
case '':
|
||||||
return (
|
return (
|
||||||
<Tag color='grey' size='large' shape='circle'>
|
<Tag color='grey' size='large' shape='circle' prefixIcon={<Loader size={14} />}>
|
||||||
{t('正在提交')}
|
{t('正在提交')}
|
||||||
</Tag>
|
</Tag>
|
||||||
);
|
);
|
||||||
default:
|
default:
|
||||||
return (
|
return (
|
||||||
<Tag color='white' size='large' shape='circle'>
|
<Tag color='white' size='large' shape='circle' prefixIcon={<HelpCircle size={14} />}>
|
||||||
{t('未知')}
|
{t('未知')}
|
||||||
</Tag>
|
</Tag>
|
||||||
);
|
);
|
||||||
@@ -320,6 +333,7 @@ const LogsTable = () => {
|
|||||||
color={colors[parseInt(text) % colors.length]}
|
color={colors[parseInt(text) % colors.length]}
|
||||||
size='large'
|
size='large'
|
||||||
shape='circle'
|
shape='circle'
|
||||||
|
prefixIcon={<Hash size={14} />}
|
||||||
onClick={() => {
|
onClick={() => {
|
||||||
copyText(text);
|
copyText(text);
|
||||||
}}
|
}}
|
||||||
|
|||||||
@@ -6,7 +6,8 @@ import {
|
|||||||
showSuccess,
|
showSuccess,
|
||||||
timestamp2string,
|
timestamp2string,
|
||||||
renderGroup,
|
renderGroup,
|
||||||
renderQuota
|
renderQuota,
|
||||||
|
getQuotaPerUnit
|
||||||
} from '../../helpers';
|
} from '../../helpers';
|
||||||
|
|
||||||
import { ITEMS_PER_PAGE } from '../../constants';
|
import { ITEMS_PER_PAGE } from '../../constants';
|
||||||
@@ -19,9 +20,20 @@ import {
|
|||||||
Space,
|
Space,
|
||||||
SplitButtonGroup,
|
SplitButtonGroup,
|
||||||
Table,
|
Table,
|
||||||
Tag,
|
Tag
|
||||||
} from '@douyinfe/semi-ui';
|
} from '@douyinfe/semi-ui';
|
||||||
|
|
||||||
|
import {
|
||||||
|
CheckCircle,
|
||||||
|
Shield,
|
||||||
|
XCircle,
|
||||||
|
Clock,
|
||||||
|
Gauge,
|
||||||
|
HelpCircle,
|
||||||
|
Infinity,
|
||||||
|
Coins
|
||||||
|
} from 'lucide-react';
|
||||||
|
|
||||||
import {
|
import {
|
||||||
IconPlus,
|
IconPlus,
|
||||||
IconCopy,
|
IconCopy,
|
||||||
@@ -32,7 +44,7 @@ import {
|
|||||||
IconDelete,
|
IconDelete,
|
||||||
IconStop,
|
IconStop,
|
||||||
IconPlay,
|
IconPlay,
|
||||||
IconMore,
|
IconMore
|
||||||
} from '@douyinfe/semi-icons';
|
} from '@douyinfe/semi-icons';
|
||||||
import EditToken from '../../pages/Token/EditToken';
|
import EditToken from '../../pages/Token/EditToken';
|
||||||
import { useTranslation } from 'react-i18next';
|
import { useTranslation } from 'react-i18next';
|
||||||
@@ -49,38 +61,38 @@ const TokensTable = () => {
|
|||||||
case 1:
|
case 1:
|
||||||
if (model_limits_enabled) {
|
if (model_limits_enabled) {
|
||||||
return (
|
return (
|
||||||
<Tag color='green' size='large' shape='circle'>
|
<Tag color='green' size='large' shape='circle' prefixIcon={<Shield size={14} />}>
|
||||||
{t('已启用:限制模型')}
|
{t('已启用:限制模型')}
|
||||||
</Tag>
|
</Tag>
|
||||||
);
|
);
|
||||||
} else {
|
} else {
|
||||||
return (
|
return (
|
||||||
<Tag color='green' size='large' shape='circle'>
|
<Tag color='green' size='large' shape='circle' prefixIcon={<CheckCircle size={14} />}>
|
||||||
{t('已启用')}
|
{t('已启用')}
|
||||||
</Tag>
|
</Tag>
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
case 2:
|
case 2:
|
||||||
return (
|
return (
|
||||||
<Tag color='red' size='large' shape='circle'>
|
<Tag color='red' size='large' shape='circle' prefixIcon={<XCircle size={14} />}>
|
||||||
{t('已禁用')}
|
{t('已禁用')}
|
||||||
</Tag>
|
</Tag>
|
||||||
);
|
);
|
||||||
case 3:
|
case 3:
|
||||||
return (
|
return (
|
||||||
<Tag color='yellow' size='large' shape='circle'>
|
<Tag color='yellow' size='large' shape='circle' prefixIcon={<Clock size={14} />}>
|
||||||
{t('已过期')}
|
{t('已过期')}
|
||||||
</Tag>
|
</Tag>
|
||||||
);
|
);
|
||||||
case 4:
|
case 4:
|
||||||
return (
|
return (
|
||||||
<Tag color='grey' size='large' shape='circle'>
|
<Tag color='grey' size='large' shape='circle' prefixIcon={<Gauge size={14} />}>
|
||||||
{t('已耗尽')}
|
{t('已耗尽')}
|
||||||
</Tag>
|
</Tag>
|
||||||
);
|
);
|
||||||
default:
|
default:
|
||||||
return (
|
return (
|
||||||
<Tag color='black' size='large' shape='circle'>
|
<Tag color='black' size='large' shape='circle' prefixIcon={<HelpCircle size={14} />}>
|
||||||
{t('未知状态')}
|
{t('未知状态')}
|
||||||
</Tag>
|
</Tag>
|
||||||
);
|
);
|
||||||
@@ -111,21 +123,45 @@ const TokensTable = () => {
|
|||||||
title: t('已用额度'),
|
title: t('已用额度'),
|
||||||
dataIndex: 'used_quota',
|
dataIndex: 'used_quota',
|
||||||
render: (text, record, index) => {
|
render: (text, record, index) => {
|
||||||
return <div>{renderQuota(parseInt(text))}</div>;
|
return (
|
||||||
|
<div>
|
||||||
|
<Tag size={'large'} color={'grey'} shape='circle' prefixIcon={<Coins size={14} />}>
|
||||||
|
{renderQuota(parseInt(text))}
|
||||||
|
</Tag>
|
||||||
|
</div>
|
||||||
|
);
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
title: t('剩余额度'),
|
title: t('剩余额度'),
|
||||||
dataIndex: 'remain_quota',
|
dataIndex: 'remain_quota',
|
||||||
render: (text, record, index) => {
|
render: (text, record, index) => {
|
||||||
|
const getQuotaColor = (quotaValue) => {
|
||||||
|
const quotaPerUnit = getQuotaPerUnit();
|
||||||
|
const dollarAmount = quotaValue / quotaPerUnit;
|
||||||
|
|
||||||
|
if (dollarAmount <= 0) {
|
||||||
|
return 'red';
|
||||||
|
} else if (dollarAmount <= 100) {
|
||||||
|
return 'yellow';
|
||||||
|
} else {
|
||||||
|
return 'green';
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<div>
|
<div>
|
||||||
{record.unlimited_quota ? (
|
{record.unlimited_quota ? (
|
||||||
<Tag size={'large'} color={'white'} shape='circle'>
|
<Tag size={'large'} color={'white'} shape='circle' prefixIcon={<Infinity size={14} />}>
|
||||||
{t('无限制')}
|
{t('无限制')}
|
||||||
</Tag>
|
</Tag>
|
||||||
) : (
|
) : (
|
||||||
<Tag size={'large'} color={'light-blue'} shape='circle'>
|
<Tag
|
||||||
|
size={'large'}
|
||||||
|
color={getQuotaColor(parseInt(text))}
|
||||||
|
shape='circle'
|
||||||
|
prefixIcon={<Coins size={14} />}
|
||||||
|
>
|
||||||
{renderQuota(parseInt(text))}
|
{renderQuota(parseInt(text))}
|
||||||
</Tag>
|
</Tag>
|
||||||
)}
|
)}
|
||||||
|
|||||||
@@ -1,5 +1,20 @@
|
|||||||
import React, { useEffect, useState } from 'react';
|
import React, { useEffect, useState } from 'react';
|
||||||
import { API, showError, showSuccess, renderGroup, renderNumber, renderQuota } from '../../helpers';
|
import { API, showError, showSuccess, renderGroup, renderNumber, renderQuota } from '../../helpers';
|
||||||
|
|
||||||
|
import {
|
||||||
|
User,
|
||||||
|
Shield,
|
||||||
|
Crown,
|
||||||
|
HelpCircle,
|
||||||
|
CheckCircle,
|
||||||
|
XCircle,
|
||||||
|
Minus,
|
||||||
|
Coins,
|
||||||
|
Activity,
|
||||||
|
Users,
|
||||||
|
DollarSign,
|
||||||
|
UserPlus
|
||||||
|
} from 'lucide-react';
|
||||||
import {
|
import {
|
||||||
Button,
|
Button,
|
||||||
Card,
|
Card,
|
||||||
@@ -10,7 +25,7 @@ import {
|
|||||||
Space,
|
Space,
|
||||||
Table,
|
Table,
|
||||||
Tag,
|
Tag,
|
||||||
Typography,
|
Typography
|
||||||
} from '@douyinfe/semi-ui';
|
} from '@douyinfe/semi-ui';
|
||||||
import {
|
import {
|
||||||
IconPlus,
|
IconPlus,
|
||||||
@@ -22,7 +37,7 @@ import {
|
|||||||
IconMore,
|
IconMore,
|
||||||
IconUserAdd,
|
IconUserAdd,
|
||||||
IconArrowUp,
|
IconArrowUp,
|
||||||
IconArrowDown,
|
IconArrowDown
|
||||||
} from '@douyinfe/semi-icons';
|
} from '@douyinfe/semi-icons';
|
||||||
import { ITEMS_PER_PAGE } from '../../constants';
|
import { ITEMS_PER_PAGE } from '../../constants';
|
||||||
import AddUser from '../../pages/User/AddUser';
|
import AddUser from '../../pages/User/AddUser';
|
||||||
@@ -38,25 +53,25 @@ const UsersTable = () => {
|
|||||||
switch (role) {
|
switch (role) {
|
||||||
case 1:
|
case 1:
|
||||||
return (
|
return (
|
||||||
<Tag size='large' color='blue' shape='circle'>
|
<Tag size='large' color='blue' shape='circle' prefixIcon={<User size={14} />}>
|
||||||
{t('普通用户')}
|
{t('普通用户')}
|
||||||
</Tag>
|
</Tag>
|
||||||
);
|
);
|
||||||
case 10:
|
case 10:
|
||||||
return (
|
return (
|
||||||
<Tag color='yellow' size='large' shape='circle'>
|
<Tag color='yellow' size='large' shape='circle' prefixIcon={<Shield size={14} />}>
|
||||||
{t('管理员')}
|
{t('管理员')}
|
||||||
</Tag>
|
</Tag>
|
||||||
);
|
);
|
||||||
case 100:
|
case 100:
|
||||||
return (
|
return (
|
||||||
<Tag color='orange' size='large' shape='circle'>
|
<Tag color='orange' size='large' shape='circle' prefixIcon={<Crown size={14} />}>
|
||||||
{t('超级管理员')}
|
{t('超级管理员')}
|
||||||
</Tag>
|
</Tag>
|
||||||
);
|
);
|
||||||
default:
|
default:
|
||||||
return (
|
return (
|
||||||
<Tag color='red' size='large' shape='circle'>
|
<Tag color='red' size='large' shape='circle' prefixIcon={<HelpCircle size={14} />}>
|
||||||
{t('未知身份')}
|
{t('未知身份')}
|
||||||
</Tag>
|
</Tag>
|
||||||
);
|
);
|
||||||
@@ -66,16 +81,16 @@ const UsersTable = () => {
|
|||||||
const renderStatus = (status) => {
|
const renderStatus = (status) => {
|
||||||
switch (status) {
|
switch (status) {
|
||||||
case 1:
|
case 1:
|
||||||
return <Tag size='large' color='green' shape='circle'>{t('已激活')}</Tag>;
|
return <Tag size='large' color='green' shape='circle' prefixIcon={<CheckCircle size={14} />}>{t('已激活')}</Tag>;
|
||||||
case 2:
|
case 2:
|
||||||
return (
|
return (
|
||||||
<Tag size='large' color='red' shape='circle'>
|
<Tag size='large' color='red' shape='circle' prefixIcon={<XCircle size={14} />}>
|
||||||
{t('已封禁')}
|
{t('已封禁')}
|
||||||
</Tag>
|
</Tag>
|
||||||
);
|
);
|
||||||
default:
|
default:
|
||||||
return (
|
return (
|
||||||
<Tag size='large' color='grey' shape='circle'>
|
<Tag size='large' color='grey' shape='circle' prefixIcon={<HelpCircle size={14} />}>
|
||||||
{t('未知状态')}
|
{t('未知状态')}
|
||||||
</Tag>
|
</Tag>
|
||||||
);
|
);
|
||||||
@@ -105,13 +120,13 @@ const UsersTable = () => {
|
|||||||
return (
|
return (
|
||||||
<div>
|
<div>
|
||||||
<Space spacing={1}>
|
<Space spacing={1}>
|
||||||
<Tag color='white' size='large' shape='circle' className="!text-xs">
|
<Tag color='white' size='large' shape='circle' className="!text-xs" prefixIcon={<Coins size={14} />}>
|
||||||
{t('剩余')}: {renderQuota(record.quota)}
|
{t('剩余')}: {renderQuota(record.quota)}
|
||||||
</Tag>
|
</Tag>
|
||||||
<Tag color='white' size='large' shape='circle' className="!text-xs">
|
<Tag color='white' size='large' shape='circle' className="!text-xs" prefixIcon={<Coins size={14} />}>
|
||||||
{t('已用')}: {renderQuota(record.used_quota)}
|
{t('已用')}: {renderQuota(record.used_quota)}
|
||||||
</Tag>
|
</Tag>
|
||||||
<Tag color='white' size='large' shape='circle' className="!text-xs">
|
<Tag color='white' size='large' shape='circle' className="!text-xs" prefixIcon={<Activity size={14} />}>
|
||||||
{t('调用')}: {renderNumber(record.request_count)}
|
{t('调用')}: {renderNumber(record.request_count)}
|
||||||
</Tag>
|
</Tag>
|
||||||
</Space>
|
</Space>
|
||||||
@@ -126,13 +141,13 @@ const UsersTable = () => {
|
|||||||
return (
|
return (
|
||||||
<div>
|
<div>
|
||||||
<Space spacing={1}>
|
<Space spacing={1}>
|
||||||
<Tag color='white' size='large' shape='circle' className="!text-xs">
|
<Tag color='white' size='large' shape='circle' className="!text-xs" prefixIcon={<Users size={14} />}>
|
||||||
{t('邀请')}: {renderNumber(record.aff_count)}
|
{t('邀请')}: {renderNumber(record.aff_count)}
|
||||||
</Tag>
|
</Tag>
|
||||||
<Tag color='white' size='large' shape='circle' className="!text-xs">
|
<Tag color='white' size='large' shape='circle' className="!text-xs" prefixIcon={<DollarSign size={14} />}>
|
||||||
{t('收益')}: {renderQuota(record.aff_history_quota)}
|
{t('收益')}: {renderQuota(record.aff_history_quota)}
|
||||||
</Tag>
|
</Tag>
|
||||||
<Tag color='white' size='large' shape='circle' className="!text-xs">
|
<Tag color='white' size='large' shape='circle' className="!text-xs" prefixIcon={<UserPlus size={14} />}>
|
||||||
{record.inviter_id === 0 ? t('无邀请人') : `邀请人: ${record.inviter_id}`}
|
{record.inviter_id === 0 ? t('无邀请人') : `邀请人: ${record.inviter_id}`}
|
||||||
</Tag>
|
</Tag>
|
||||||
</Space>
|
</Space>
|
||||||
@@ -154,7 +169,7 @@ const UsersTable = () => {
|
|||||||
return (
|
return (
|
||||||
<div>
|
<div>
|
||||||
{record.DeletedAt !== null ? (
|
{record.DeletedAt !== null ? (
|
||||||
<Tag color='red' shape='circle'>{t('已注销')}</Tag>
|
<Tag color='red' shape='circle' prefixIcon={<Minus size={14} />}>{t('已注销')}</Tag>
|
||||||
) : (
|
) : (
|
||||||
renderStatus(text)
|
renderStatus(text)
|
||||||
)}
|
)}
|
||||||
|
|||||||
@@ -24,6 +24,13 @@ import {
|
|||||||
XAI,
|
XAI,
|
||||||
Ollama,
|
Ollama,
|
||||||
Doubao,
|
Doubao,
|
||||||
|
Suno,
|
||||||
|
Xinference,
|
||||||
|
OpenRouter,
|
||||||
|
Dify,
|
||||||
|
Coze,
|
||||||
|
SiliconCloud,
|
||||||
|
FastGPT
|
||||||
} from '@lobehub/icons';
|
} from '@lobehub/icons';
|
||||||
|
|
||||||
import {
|
import {
|
||||||
@@ -40,6 +47,7 @@ import {
|
|||||||
User,
|
User,
|
||||||
Settings,
|
Settings,
|
||||||
CircleUser,
|
CircleUser,
|
||||||
|
Users
|
||||||
} from 'lucide-react';
|
} from 'lucide-react';
|
||||||
|
|
||||||
// 侧边栏图标颜色映射
|
// 侧边栏图标颜色映射
|
||||||
@@ -308,6 +316,88 @@ export const getModelCategories = (() => {
|
|||||||
};
|
};
|
||||||
})();
|
})();
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 根据渠道类型返回对应的厂商图标
|
||||||
|
* @param {number} channelType - 渠道类型值
|
||||||
|
* @returns {JSX.Element|null} - 对应的厂商图标组件
|
||||||
|
*/
|
||||||
|
export function getChannelIcon(channelType) {
|
||||||
|
const iconSize = 14;
|
||||||
|
|
||||||
|
switch (channelType) {
|
||||||
|
case 1: // OpenAI
|
||||||
|
case 3: // Azure OpenAI
|
||||||
|
return <OpenAI size={iconSize} />;
|
||||||
|
case 2: // Midjourney Proxy
|
||||||
|
case 5: // Midjourney Proxy Plus
|
||||||
|
return <Midjourney size={iconSize} />;
|
||||||
|
case 36: // Suno API
|
||||||
|
return <Suno size={iconSize} />;
|
||||||
|
case 4: // Ollama
|
||||||
|
return <Ollama size={iconSize} />;
|
||||||
|
case 14: // Anthropic Claude
|
||||||
|
case 33: // AWS Claude
|
||||||
|
return <Claude.Color size={iconSize} />;
|
||||||
|
case 41: // Vertex AI
|
||||||
|
return <Gemini.Color size={iconSize} />;
|
||||||
|
case 34: // Cohere
|
||||||
|
return <Cohere.Color size={iconSize} />;
|
||||||
|
case 39: // Cloudflare
|
||||||
|
return <Cloudflare.Color size={iconSize} />;
|
||||||
|
case 43: // DeepSeek
|
||||||
|
return <DeepSeek.Color size={iconSize} />;
|
||||||
|
case 15: // 百度文心千帆
|
||||||
|
case 46: // 百度文心千帆V2
|
||||||
|
return <Wenxin.Color size={iconSize} />;
|
||||||
|
case 17: // 阿里通义千问
|
||||||
|
return <Qwen.Color size={iconSize} />;
|
||||||
|
case 18: // 讯飞星火认知
|
||||||
|
return <Spark.Color size={iconSize} />;
|
||||||
|
case 16: // 智谱 ChatGLM
|
||||||
|
case 26: // 智谱 GLM-4V
|
||||||
|
return <Zhipu.Color size={iconSize} />;
|
||||||
|
case 24: // Google Gemini
|
||||||
|
case 11: // Google PaLM2
|
||||||
|
return <Gemini.Color size={iconSize} />;
|
||||||
|
case 47: // Xinference
|
||||||
|
return <Xinference.Color size={iconSize} />;
|
||||||
|
case 25: // Moonshot
|
||||||
|
return <Moonshot size={iconSize} />;
|
||||||
|
case 20: // OpenRouter
|
||||||
|
return <OpenRouter size={iconSize} />;
|
||||||
|
case 19: // 360 智脑
|
||||||
|
return <Ai360.Color size={iconSize} />;
|
||||||
|
case 23: // 腾讯混元
|
||||||
|
return <Hunyuan.Color size={iconSize} />;
|
||||||
|
case 31: // 零一万物
|
||||||
|
return <Yi.Color size={iconSize} />;
|
||||||
|
case 35: // MiniMax
|
||||||
|
return <Minimax.Color size={iconSize} />;
|
||||||
|
case 37: // Dify
|
||||||
|
return <Dify.Color size={iconSize} />;
|
||||||
|
case 38: // Jina
|
||||||
|
return <Jina size={iconSize} />;
|
||||||
|
case 40: // SiliconCloud
|
||||||
|
return <SiliconCloud.Color size={iconSize} />;
|
||||||
|
case 42: // Mistral AI
|
||||||
|
return <Mistral.Color size={iconSize} />;
|
||||||
|
case 45: // 字节火山方舟、豆包通用
|
||||||
|
return <Doubao.Color size={iconSize} />;
|
||||||
|
case 48: // xAI
|
||||||
|
return <XAI size={iconSize} />;
|
||||||
|
case 49: // Coze
|
||||||
|
return <Coze size={iconSize} />;
|
||||||
|
case 8: // 自定义渠道
|
||||||
|
case 22: // 知识库:FastGPT
|
||||||
|
return <FastGPT.Color size={iconSize} />;
|
||||||
|
case 21: // 知识库:AI Proxy
|
||||||
|
case 44: // 嵌入模型:MokaAI M3E
|
||||||
|
default:
|
||||||
|
return null; // 未知类型或自定义渠道不显示图标
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
// 颜色列表
|
// 颜色列表
|
||||||
const colors = [
|
const colors = [
|
||||||
'amber',
|
'amber',
|
||||||
@@ -490,7 +580,7 @@ export function renderText(text, limit) {
|
|||||||
export function renderGroup(group) {
|
export function renderGroup(group) {
|
||||||
if (group === '') {
|
if (group === '') {
|
||||||
return (
|
return (
|
||||||
<Tag size='large' key='default' color='orange' shape='circle'>
|
<Tag size='large' key='default' color='orange' shape='circle' prefixIcon={<Users size={14} />}>
|
||||||
{i18next.t('用户分组')}
|
{i18next.t('用户分组')}
|
||||||
</Tag>
|
</Tag>
|
||||||
);
|
);
|
||||||
@@ -513,13 +603,14 @@ export function renderGroup(group) {
|
|||||||
color={tagColors[group] || stringToColor(group)}
|
color={tagColors[group] || stringToColor(group)}
|
||||||
key={group}
|
key={group}
|
||||||
shape='circle'
|
shape='circle'
|
||||||
|
prefixIcon={<Users size={14} />}
|
||||||
onClick={async (event) => {
|
onClick={async (event) => {
|
||||||
event.stopPropagation();
|
event.stopPropagation();
|
||||||
if (await copy(group)) {
|
if (await copy(group)) {
|
||||||
showSuccess(i18next.t('已复制:') + group);
|
showSuccess(i18next.t('已复制:') + group);
|
||||||
} else {
|
} else {
|
||||||
Modal.error({
|
Modal.error({
|
||||||
title: t('无法复制到剪贴板,请手动复制'),
|
title: i18next.t('无法复制到剪贴板,请手动复制'),
|
||||||
content: group,
|
content: group,
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
@@ -956,23 +1047,23 @@ export function renderModelPrice(
|
|||||||
const extraServices = [
|
const extraServices = [
|
||||||
webSearch && webSearchCallCount > 0
|
webSearch && webSearchCallCount > 0
|
||||||
? i18next.t(
|
? i18next.t(
|
||||||
' + Web搜索 {{count}}次 / 1K 次 * ${{price}} * 分组倍率 {{ratio}}',
|
' + Web搜索 {{count}}次 / 1K 次 * ${{price}} * 分组倍率 {{ratio}}',
|
||||||
{
|
{
|
||||||
count: webSearchCallCount,
|
count: webSearchCallCount,
|
||||||
price: webSearchPrice,
|
price: webSearchPrice,
|
||||||
ratio: groupRatio,
|
ratio: groupRatio,
|
||||||
},
|
},
|
||||||
)
|
)
|
||||||
: '',
|
: '',
|
||||||
fileSearch && fileSearchCallCount > 0
|
fileSearch && fileSearchCallCount > 0
|
||||||
? i18next.t(
|
? i18next.t(
|
||||||
' + 文件搜索 {{count}}次 / 1K 次 * ${{price}} * 分组倍率 {{ratio}}',
|
' + 文件搜索 {{count}}次 / 1K 次 * ${{price}} * 分组倍率 {{ratio}}',
|
||||||
{
|
{
|
||||||
count: fileSearchCallCount,
|
count: fileSearchCallCount,
|
||||||
price: fileSearchPrice,
|
price: fileSearchPrice,
|
||||||
ratio: groupRatio,
|
ratio: groupRatio,
|
||||||
},
|
},
|
||||||
)
|
)
|
||||||
: '',
|
: '',
|
||||||
].join('');
|
].join('');
|
||||||
|
|
||||||
@@ -1156,10 +1247,10 @@ export function renderAudioModelPrice(
|
|||||||
let audioPrice =
|
let audioPrice =
|
||||||
(audioInputTokens / 1000000) * inputRatioPrice * audioRatio * groupRatio +
|
(audioInputTokens / 1000000) * inputRatioPrice * audioRatio * groupRatio +
|
||||||
(audioCompletionTokens / 1000000) *
|
(audioCompletionTokens / 1000000) *
|
||||||
inputRatioPrice *
|
inputRatioPrice *
|
||||||
audioRatio *
|
audioRatio *
|
||||||
audioCompletionRatio *
|
audioCompletionRatio *
|
||||||
groupRatio;
|
groupRatio;
|
||||||
let price = textPrice + audioPrice;
|
let price = textPrice + audioPrice;
|
||||||
return (
|
return (
|
||||||
<>
|
<>
|
||||||
@@ -1215,27 +1306,27 @@ export function renderAudioModelPrice(
|
|||||||
<p>
|
<p>
|
||||||
{cacheTokens > 0
|
{cacheTokens > 0
|
||||||
? i18next.t(
|
? i18next.t(
|
||||||
'文字提示 {{nonCacheInput}} tokens / 1M tokens * ${{price}} + 缓存 {{cacheInput}} tokens / 1M tokens * ${{cachePrice}} + 文字补全 {{completion}} tokens / 1M tokens * ${{compPrice}} = ${{total}}',
|
'文字提示 {{nonCacheInput}} tokens / 1M tokens * ${{price}} + 缓存 {{cacheInput}} tokens / 1M tokens * ${{cachePrice}} + 文字补全 {{completion}} tokens / 1M tokens * ${{compPrice}} = ${{total}}',
|
||||||
{
|
{
|
||||||
nonCacheInput: inputTokens - cacheTokens,
|
nonCacheInput: inputTokens - cacheTokens,
|
||||||
cacheInput: cacheTokens,
|
cacheInput: cacheTokens,
|
||||||
cachePrice: inputRatioPrice * cacheRatio,
|
cachePrice: inputRatioPrice * cacheRatio,
|
||||||
price: inputRatioPrice,
|
price: inputRatioPrice,
|
||||||
completion: completionTokens,
|
completion: completionTokens,
|
||||||
compPrice: completionRatioPrice,
|
compPrice: completionRatioPrice,
|
||||||
total: textPrice.toFixed(6),
|
total: textPrice.toFixed(6),
|
||||||
},
|
},
|
||||||
)
|
)
|
||||||
: i18next.t(
|
: i18next.t(
|
||||||
'文字提示 {{input}} tokens / 1M tokens * ${{price}} + 文字补全 {{completion}} tokens / 1M tokens * ${{compPrice}} = ${{total}}',
|
'文字提示 {{input}} tokens / 1M tokens * ${{price}} + 文字补全 {{completion}} tokens / 1M tokens * ${{compPrice}} = ${{total}}',
|
||||||
{
|
{
|
||||||
input: inputTokens,
|
input: inputTokens,
|
||||||
price: inputRatioPrice,
|
price: inputRatioPrice,
|
||||||
completion: completionTokens,
|
completion: completionTokens,
|
||||||
compPrice: completionRatioPrice,
|
compPrice: completionRatioPrice,
|
||||||
total: textPrice.toFixed(6),
|
total: textPrice.toFixed(6),
|
||||||
},
|
},
|
||||||
)}
|
)}
|
||||||
</p>
|
</p>
|
||||||
<p>
|
<p>
|
||||||
{i18next.t(
|
{i18next.t(
|
||||||
@@ -1372,33 +1463,33 @@ export function renderClaudeModelPrice(
|
|||||||
<p>
|
<p>
|
||||||
{cacheTokens > 0 || cacheCreationTokens > 0
|
{cacheTokens > 0 || cacheCreationTokens > 0
|
||||||
? i18next.t(
|
? i18next.t(
|
||||||
'提示 {{nonCacheInput}} tokens / 1M tokens * ${{price}} + 缓存 {{cacheInput}} tokens / 1M tokens * ${{cachePrice}} + 缓存创建 {{cacheCreationInput}} tokens / 1M tokens * ${{cacheCreationPrice}} + 补全 {{completion}} tokens / 1M tokens * ${{compPrice}} * 分组 {{ratio}} = ${{total}}',
|
'提示 {{nonCacheInput}} tokens / 1M tokens * ${{price}} + 缓存 {{cacheInput}} tokens / 1M tokens * ${{cachePrice}} + 缓存创建 {{cacheCreationInput}} tokens / 1M tokens * ${{cacheCreationPrice}} + 补全 {{completion}} tokens / 1M tokens * ${{compPrice}} * 分组 {{ratio}} = ${{total}}',
|
||||||
{
|
{
|
||||||
nonCacheInput: nonCachedTokens,
|
nonCacheInput: nonCachedTokens,
|
||||||
cacheInput: cacheTokens,
|
cacheInput: cacheTokens,
|
||||||
cacheRatio: cacheRatio,
|
cacheRatio: cacheRatio,
|
||||||
cacheCreationInput: cacheCreationTokens,
|
cacheCreationInput: cacheCreationTokens,
|
||||||
cacheCreationRatio: cacheCreationRatio,
|
cacheCreationRatio: cacheCreationRatio,
|
||||||
cachePrice: cacheRatioPrice,
|
cachePrice: cacheRatioPrice,
|
||||||
cacheCreationPrice: cacheCreationRatioPrice,
|
cacheCreationPrice: cacheCreationRatioPrice,
|
||||||
price: inputRatioPrice,
|
price: inputRatioPrice,
|
||||||
completion: completionTokens,
|
completion: completionTokens,
|
||||||
compPrice: completionRatioPrice,
|
compPrice: completionRatioPrice,
|
||||||
ratio: groupRatio,
|
ratio: groupRatio,
|
||||||
total: price.toFixed(6),
|
total: price.toFixed(6),
|
||||||
},
|
},
|
||||||
)
|
)
|
||||||
: i18next.t(
|
: i18next.t(
|
||||||
'提示 {{input}} tokens / 1M tokens * ${{price}} + 补全 {{completion}} tokens / 1M tokens * ${{compPrice}} * 分组 {{ratio}} = ${{total}}',
|
'提示 {{input}} tokens / 1M tokens * ${{price}} + 补全 {{completion}} tokens / 1M tokens * ${{compPrice}} * 分组 {{ratio}} = ${{total}}',
|
||||||
{
|
{
|
||||||
input: inputTokens,
|
input: inputTokens,
|
||||||
price: inputRatioPrice,
|
price: inputRatioPrice,
|
||||||
completion: completionTokens,
|
completion: completionTokens,
|
||||||
compPrice: completionRatioPrice,
|
compPrice: completionRatioPrice,
|
||||||
ratio: groupRatio,
|
ratio: groupRatio,
|
||||||
total: price.toFixed(6),
|
total: price.toFixed(6),
|
||||||
},
|
},
|
||||||
)}
|
)}
|
||||||
</p>
|
</p>
|
||||||
<p>{i18next.t('仅供参考,以实际扣费为准')}</p>
|
<p>{i18next.t('仅供参考,以实际扣费为准')}</p>
|
||||||
</article>
|
</article>
|
||||||
|
|||||||
@@ -73,6 +73,7 @@ code {
|
|||||||
.semi-page-item,
|
.semi-page-item,
|
||||||
.semi-navigation-item,
|
.semi-navigation-item,
|
||||||
.semi-tag-closable,
|
.semi-tag-closable,
|
||||||
|
.semi-input-wrapper,
|
||||||
.semi-datepicker-range-input {
|
.semi-datepicker-range-input {
|
||||||
border-radius: 9999px !important;
|
border-radius: 9999px !important;
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user