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:
Apple\Apple
2025-06-08 23:13:45 +08:00
parent 7a83060012
commit 8184357b49
9 changed files with 414 additions and 181 deletions

View File

@@ -7,9 +7,23 @@ import {
timestamp2string,
renderGroup,
renderNumberWithPoint,
renderQuota
renderQuota,
getChannelIcon
} 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 {
Button,
@@ -63,7 +77,12 @@ const ChannelsTable = () => {
type2label[0] = { value: 0, label: t('未知类型'), color: 'grey' };
}
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}
</Tag>
);
@@ -87,25 +106,25 @@ const ChannelsTable = () => {
switch (status) {
case 1:
return (
<Tag size='large' color='green' shape='circle'>
<Tag size='large' color='green' shape='circle' prefixIcon={<CheckCircle size={14} />}>
{t('已启用')}
</Tag>
);
case 2:
return (
<Tag size='large' color='yellow' shape='circle'>
<Tag size='large' color='yellow' shape='circle' prefixIcon={<XCircle size={14} />}>
{t('已禁用')}
</Tag>
);
case 3:
return (
<Tag size='large' color='yellow' shape='circle'>
<Tag size='large' color='yellow' shape='circle' prefixIcon={<AlertCircle size={14} />}>
{t('自动禁用')}
</Tag>
);
default:
return (
<Tag size='large' color='grey' shape='circle'>
<Tag size='large' color='grey' shape='circle' prefixIcon={<HelpCircle size={14} />}>
{t('未知状态')}
</Tag>
);
@@ -117,31 +136,31 @@ const ChannelsTable = () => {
time = time.toFixed(2) + t(' 秒');
if (responseTime === 0) {
return (
<Tag size='large' color='grey' shape='circle'>
<Tag size='large' color='grey' shape='circle' prefixIcon={<TestTube size={14} />}>
{t('未测试')}
</Tag>
);
} else if (responseTime <= 1000) {
return (
<Tag size='large' color='green' shape='circle'>
<Tag size='large' color='green' shape='circle' prefixIcon={<Zap size={14} />}>
{time}
</Tag>
);
} else if (responseTime <= 3000) {
return (
<Tag size='large' color='lime' shape='circle'>
<Tag size='large' color='lime' shape='circle' prefixIcon={<Timer size={14} />}>
{time}
</Tag>
);
} else if (responseTime <= 5000) {
return (
<Tag size='large' color='yellow' shape='circle'>
<Tag size='large' color='yellow' shape='circle' prefixIcon={<Clock size={14} />}>
{time}
</Tag>
);
} else {
return (
<Tag size='large' color='red' shape='circle'>
<Tag size='large' color='red' shape='circle' prefixIcon={<AlertTriangle size={14} />}>
{time}
</Tag>
);
@@ -228,7 +247,7 @@ const ChannelsTable = () => {
<div>
<Space spacing={1}>
<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)}
</Tag>
</Tooltip>
@@ -238,6 +257,7 @@ const ChannelsTable = () => {
type='ghost'
size='large'
shape='circle'
prefixIcon={<Coins size={14} />}
onClick={() => updateChannelBalance(record)}
>
${renderNumberWithPoint(record.balance)}
@@ -249,7 +269,7 @@ const ChannelsTable = () => {
} else {
return (
<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)}
</Tag>
</Tooltip>

View File

@@ -1,5 +1,18 @@
import React, { useEffect, useState } from 'react';
import { useTranslation } from 'react-i18next';
import {
CreditCard,
ShoppingCart,
Settings,
Server,
AlertTriangle,
HelpCircle,
Zap,
Play,
Clock,
Hash,
Key
} from 'lucide-react';
import {
API,
copy,
@@ -20,7 +33,7 @@ import {
renderQuota,
stringToColor,
getLogOther,
renderModelTag,
renderModelTag
} from '../../helpers';
import {
@@ -38,7 +51,7 @@ import {
Card,
Typography,
Divider,
Form,
Form
} from '@douyinfe/semi-ui';
import { ITEMS_PER_PAGE } from '../../constants';
import Paragraph from '@douyinfe/semi-ui/lib/es/typography/paragraph';
@@ -71,37 +84,37 @@ const LogsTable = () => {
switch (type) {
case 1:
return (
<Tag color='cyan' size='large' shape='circle'>
<Tag color='cyan' size='large' shape='circle' prefixIcon={<CreditCard size={14} />}>
{t('充值')}
</Tag>
);
case 2:
return (
<Tag color='lime' size='large' shape='circle'>
<Tag color='lime' size='large' shape='circle' prefixIcon={<ShoppingCart size={14} />}>
{t('消费')}
</Tag>
);
case 3:
return (
<Tag color='orange' size='large' shape='circle'>
<Tag color='orange' size='large' shape='circle' prefixIcon={<Settings size={14} />}>
{t('管理')}
</Tag>
);
case 4:
return (
<Tag color='purple' size='large' shape='circle'>
<Tag color='purple' size='large' shape='circle' prefixIcon={<Server size={14} />}>
{t('系统')}
</Tag>
);
case 5:
return (
<Tag color='red' size='large' shape='circle'>
<Tag color='red' size='large' shape='circle' prefixIcon={<AlertTriangle size={14} />}>
{t('错误')}
</Tag>
);
default:
return (
<Tag color='grey' size='large' shape='circle'>
<Tag color='grey' size='large' shape='circle' prefixIcon={<HelpCircle size={14} />}>
{t('未知')}
</Tag>
);
@@ -111,13 +124,13 @@ const LogsTable = () => {
function renderIsStream(bool) {
if (bool) {
return (
<Tag color='blue' size='large' shape='circle'>
<Tag color='blue' size='large' shape='circle' prefixIcon={<Zap size={14} />}>
{t('流')}
</Tag>
);
} else {
return (
<Tag color='purple' size='large' shape='circle'>
<Tag color='purple' size='large' shape='circle' prefixIcon={<Play size={14} />}>
{t('非流')}
</Tag>
);
@@ -128,21 +141,21 @@ const LogsTable = () => {
const time = parseInt(type);
if (time < 101) {
return (
<Tag color='green' size='large' shape='circle'>
<Tag color='green' size='large' shape='circle' prefixIcon={<Clock size={14} />}>
{' '}
{time} s{' '}
</Tag>
);
} else if (time < 300) {
return (
<Tag color='orange' size='large' shape='circle'>
<Tag color='orange' size='large' shape='circle' prefixIcon={<Clock size={14} />}>
{' '}
{time} s{' '}
</Tag>
);
} else {
return (
<Tag color='red' size='large' shape='circle'>
<Tag color='red' size='large' shape='circle' prefixIcon={<Clock size={14} />}>
{' '}
{time} s{' '}
</Tag>
@@ -155,21 +168,21 @@ const LogsTable = () => {
time = time.toFixed(1);
if (time < 3) {
return (
<Tag color='green' size='large' shape='circle'>
<Tag color='green' size='large' shape='circle' prefixIcon={<Zap size={14} />}>
{' '}
{time} s{' '}
</Tag>
);
} else if (time < 10) {
return (
<Tag color='orange' size='large' shape='circle'>
<Tag color='orange' size='large' shape='circle' prefixIcon={<Zap size={14} />}>
{' '}
{time} s{' '}
</Tag>
);
} else {
return (
<Tag color='red' size='large' shape='circle'>
<Tag color='red' size='large' shape='circle' prefixIcon={<Zap size={14} />}>
{' '}
{time} s{' '}
</Tag>
@@ -356,6 +369,7 @@ const LogsTable = () => {
color={colors[parseInt(text) % colors.length]}
size='large'
shape='circle'
prefixIcon={<Hash size={14} />}
>
{' '}
{text}{' '}
@@ -408,6 +422,7 @@ const LogsTable = () => {
color='grey'
size='large'
shape='circle'
prefixIcon={<Key size={14} />}
onClick={(event) => {
//cancel the row click event
copyText(event, text);

View File

@@ -1,12 +1,38 @@
import React, { useEffect, useState } from 'react';
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 {
API,
copy,
isAdmin,
showError,
showSuccess,
timestamp2string,
timestamp2string
} from '../../helpers';
import {
@@ -22,13 +48,13 @@ import {
Skeleton,
Table,
Tag,
Typography,
Typography
} from '@douyinfe/semi-ui';
import { ITEMS_PER_PAGE } from '../../constants';
import {
IconEyeOpened,
IconSearch,
IconSetting,
IconSetting
} from '@douyinfe/semi-icons';
const { Text } = Typography;
@@ -153,103 +179,103 @@ const LogsTable = () => {
switch (type) {
case 'IMAGINE':
return (
<Tag color='blue' size='large' shape='circle'>
<Tag color='blue' size='large' shape='circle' prefixIcon={<Palette size={14} />}>
{t('绘图')}
</Tag>
);
case 'UPSCALE':
return (
<Tag color='orange' size='large' shape='circle'>
<Tag color='orange' size='large' shape='circle' prefixIcon={<ZoomIn size={14} />}>
{t('放大')}
</Tag>
);
case 'VARIATION':
return (
<Tag color='purple' size='large' shape='circle'>
<Tag color='purple' size='large' shape='circle' prefixIcon={<Shuffle size={14} />}>
{t('变换')}
</Tag>
);
case 'HIGH_VARIATION':
return (
<Tag color='purple' size='large' shape='circle'>
<Tag color='purple' size='large' shape='circle' prefixIcon={<Shuffle size={14} />}>
{t('强变换')}
</Tag>
);
case 'LOW_VARIATION':
return (
<Tag color='purple' size='large' shape='circle'>
<Tag color='purple' size='large' shape='circle' prefixIcon={<Shuffle size={14} />}>
{t('弱变换')}
</Tag>
);
case 'PAN':
return (
<Tag color='cyan' size='large' shape='circle'>
<Tag color='cyan' size='large' shape='circle' prefixIcon={<Move size={14} />}>
{t('平移')}
</Tag>
);
case 'DESCRIBE':
return (
<Tag color='yellow' size='large' shape='circle'>
<Tag color='yellow' size='large' shape='circle' prefixIcon={<FileText size={14} />}>
{t('图生文')}
</Tag>
);
case 'BLEND':
return (
<Tag color='lime' size='large' shape='circle'>
<Tag color='lime' size='large' shape='circle' prefixIcon={<Blend size={14} />}>
{t('图混合')}
</Tag>
);
case 'UPLOAD':
return (
<Tag color='blue' size='large' shape='circle'>
<Tag color='blue' size='large' shape='circle' prefixIcon={<Upload size={14} />}>
上传文件
</Tag>
);
case 'SHORTEN':
return (
<Tag color='pink' size='large' shape='circle'>
<Tag color='pink' size='large' shape='circle' prefixIcon={<Minimize2 size={14} />}>
{t('缩词')}
</Tag>
);
case 'REROLL':
return (
<Tag color='indigo' size='large' shape='circle'>
<Tag color='indigo' size='large' shape='circle' prefixIcon={<RotateCcw size={14} />}>
{t('重绘')}
</Tag>
);
case 'INPAINT':
return (
<Tag color='violet' size='large' shape='circle'>
<Tag color='violet' size='large' shape='circle' prefixIcon={<PaintBucket size={14} />}>
{t('局部重绘-提交')}
</Tag>
);
case 'ZOOM':
return (
<Tag color='teal' size='large' shape='circle'>
<Tag color='teal' size='large' shape='circle' prefixIcon={<Focus size={14} />}>
{t('变焦')}
</Tag>
);
case 'CUSTOM_ZOOM':
return (
<Tag color='teal' size='large' shape='circle'>
<Tag color='teal' size='large' shape='circle' prefixIcon={<Move3D size={14} />}>
{t('自定义变焦-提交')}
</Tag>
);
case 'MODAL':
return (
<Tag color='green' size='large' shape='circle'>
<Tag color='green' size='large' shape='circle' prefixIcon={<Monitor size={14} />}>
{t('窗口处理')}
</Tag>
);
case 'SWAP_FACE':
return (
<Tag color='light-green' size='large' shape='circle'>
<Tag color='light-green' size='large' shape='circle' prefixIcon={<UserCheck size={14} />}>
{t('换脸')}
</Tag>
);
default:
return (
<Tag color='white' size='large' shape='circle'>
<Tag color='white' size='large' shape='circle' prefixIcon={<HelpCircle size={14} />}>
{t('未知')}
</Tag>
);
@@ -260,31 +286,31 @@ const LogsTable = () => {
switch (code) {
case 1:
return (
<Tag color='green' size='large' shape='circle'>
<Tag color='green' size='large' shape='circle' prefixIcon={<CheckCircle size={14} />}>
{t('已提交')}
</Tag>
);
case 21:
return (
<Tag color='lime' size='large' shape='circle'>
<Tag color='lime' size='large' shape='circle' prefixIcon={<Clock size={14} />}>
{t('等待中')}
</Tag>
);
case 22:
return (
<Tag color='orange' size='large' shape='circle'>
<Tag color='orange' size='large' shape='circle' prefixIcon={<Copy size={14} />}>
{t('重复提交')}
</Tag>
);
case 0:
return (
<Tag color='yellow' size='large' shape='circle'>
<Tag color='yellow' size='large' shape='circle' prefixIcon={<FileX size={14} />}>
{t('未提交')}
</Tag>
);
default:
return (
<Tag color='white' size='large' shape='circle'>
<Tag color='white' size='large' shape='circle' prefixIcon={<HelpCircle size={14} />}>
{t('未知')}
</Tag>
);
@@ -295,43 +321,43 @@ const LogsTable = () => {
switch (type) {
case 'SUCCESS':
return (
<Tag color='green' size='large' shape='circle'>
<Tag color='green' size='large' shape='circle' prefixIcon={<CheckCircle size={14} />}>
{t('成功')}
</Tag>
);
case 'NOT_START':
return (
<Tag color='grey' size='large' shape='circle'>
<Tag color='grey' size='large' shape='circle' prefixIcon={<Pause size={14} />}>
{t('未启动')}
</Tag>
);
case 'SUBMITTED':
return (
<Tag color='yellow' size='large' shape='circle'>
<Tag color='yellow' size='large' shape='circle' prefixIcon={<Clock size={14} />}>
{t('队列中')}
</Tag>
);
case 'IN_PROGRESS':
return (
<Tag color='blue' size='large' shape='circle'>
<Tag color='blue' size='large' shape='circle' prefixIcon={<Loader size={14} />}>
{t('执行中')}
</Tag>
);
case 'FAILURE':
return (
<Tag color='red' size='large' shape='circle'>
<Tag color='red' size='large' shape='circle' prefixIcon={<XCircle size={14} />}>
{t('失败')}
</Tag>
);
case 'MODAL':
return (
<Tag color='yellow' size='large' shape='circle'>
<Tag color='yellow' size='large' shape='circle' prefixIcon={<AlertCircle size={14} />}>
{t('窗口等待')}
</Tag>
);
default:
return (
<Tag color='white' size='large' shape='circle'>
<Tag color='white' size='large' shape='circle' prefixIcon={<HelpCircle size={14} />}>
{t('未知')}
</Tag>
);
@@ -361,7 +387,7 @@ const LogsTable = () => {
const color = durationSec > 60 ? 'red' : 'green';
return (
<Tag color={color} size='large' shape='circle'>
<Tag color={color} size='large' shape='circle' prefixIcon={<Clock size={14} />}>
{durationSec} {t('秒')}
</Tag>
);
@@ -397,6 +423,7 @@ const LogsTable = () => {
color={colors[parseInt(text) % colors.length]}
size='large'
shape='circle'
prefixIcon={<Hash size={14} />}
onClick={() => {
copyText(text);
}}

View File

@@ -8,6 +8,14 @@ import {
renderQuota
} from '../../helpers';
import {
CheckCircle,
XCircle,
Minus,
HelpCircle,
Coins
} from 'lucide-react';
import { ITEMS_PER_PAGE } from '../../constants';
import {
Button,
@@ -20,7 +28,7 @@ import {
Space,
Table,
Tag,
Typography,
Typography
} from '@douyinfe/semi-ui';
import {
IconPlus,
@@ -31,7 +39,7 @@ import {
IconDelete,
IconStop,
IconPlay,
IconMore,
IconMore
} from '@douyinfe/semi-icons';
import EditRedemption from '../../pages/Redemption/EditRedemption';
import { useTranslation } from 'react-i18next';
@@ -49,25 +57,25 @@ const RedemptionsTable = () => {
switch (status) {
case 1:
return (
<Tag color='green' size='large' shape='circle'>
<Tag color='green' size='large' shape='circle' prefixIcon={<CheckCircle size={14} />}>
{t('未使用')}
</Tag>
);
case 2:
return (
<Tag color='red' size='large' shape='circle'>
<Tag color='red' size='large' shape='circle' prefixIcon={<XCircle size={14} />}>
{t('已禁用')}
</Tag>
);
case 3:
return (
<Tag color='grey' size='large' shape='circle'>
<Tag color='grey' size='large' shape='circle' prefixIcon={<Minus size={14} />}>
{t('已使用')}
</Tag>
);
default:
return (
<Tag color='black' size='large' shape='circle'>
<Tag color='black' size='large' shape='circle' prefixIcon={<HelpCircle size={14} />}>
{t('未知状态')}
</Tag>
);
@@ -95,7 +103,13 @@ const RedemptionsTable = () => {
title: t('额度'),
dataIndex: 'quota',
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>
);
},
},
{

View File

@@ -1,12 +1,25 @@
import React, { useEffect, useState } from 'react';
import { useTranslation } from 'react-i18next';
import {
Music,
FileText,
HelpCircle,
CheckCircle,
Pause,
Clock,
Play,
XCircle,
Loader,
List,
Hash
} from 'lucide-react';
import {
API,
copy,
isAdmin,
showError,
showSuccess,
timestamp2string,
timestamp2string
} from '../../helpers';
import {
@@ -21,13 +34,13 @@ import {
Skeleton,
Table,
Tag,
Typography,
Typography
} from '@douyinfe/semi-ui';
import { ITEMS_PER_PAGE } from '../../constants';
import {
IconEyeOpened,
IconSearch,
IconSetting,
IconSetting
} from '@douyinfe/semi-icons';
const { Text } = Typography;
@@ -96,7 +109,7 @@ function renderDuration(submit_time, finishTime) {
// 返回带有样式的颜色标签
return (
<Tag color={color} size='large'>
<Tag color={color} size='large' prefixIcon={<Clock size={14} />}>
{durationSec}
</Tag>
);
@@ -187,19 +200,19 @@ const LogsTable = () => {
switch (type) {
case 'MUSIC':
return (
<Tag color='grey' size='large' shape='circle'>
<Tag color='grey' size='large' shape='circle' prefixIcon={<Music size={14} />}>
{t('生成音乐')}
</Tag>
);
case 'LYRICS':
return (
<Tag color='pink' size='large' shape='circle'>
<Tag color='pink' size='large' shape='circle' prefixIcon={<FileText size={14} />}>
{t('生成歌词')}
</Tag>
);
default:
return (
<Tag color='white' size='large' shape='circle'>
<Tag color='white' size='large' shape='circle' prefixIcon={<HelpCircle size={14} />}>
{t('未知')}
</Tag>
);
@@ -210,13 +223,13 @@ const LogsTable = () => {
switch (type) {
case 'suno':
return (
<Tag color='green' size='large' shape='circle'>
<Tag color='green' size='large' shape='circle' prefixIcon={<Music size={14} />}>
Suno
</Tag>
);
default:
return (
<Tag color='white' size='large' shape='circle'>
<Tag color='white' size='large' shape='circle' prefixIcon={<HelpCircle size={14} />}>
{t('未知')}
</Tag>
);
@@ -227,55 +240,55 @@ const LogsTable = () => {
switch (type) {
case 'SUCCESS':
return (
<Tag color='green' size='large' shape='circle'>
<Tag color='green' size='large' shape='circle' prefixIcon={<CheckCircle size={14} />}>
{t('成功')}
</Tag>
);
case 'NOT_START':
return (
<Tag color='grey' size='large' shape='circle'>
<Tag color='grey' size='large' shape='circle' prefixIcon={<Pause size={14} />}>
{t('未启动')}
</Tag>
);
case 'SUBMITTED':
return (
<Tag color='yellow' size='large' shape='circle'>
<Tag color='yellow' size='large' shape='circle' prefixIcon={<Clock size={14} />}>
{t('队列中')}
</Tag>
);
case 'IN_PROGRESS':
return (
<Tag color='blue' size='large' shape='circle'>
<Tag color='blue' size='large' shape='circle' prefixIcon={<Play size={14} />}>
{t('执行中')}
</Tag>
);
case 'FAILURE':
return (
<Tag color='red' size='large' shape='circle'>
<Tag color='red' size='large' shape='circle' prefixIcon={<XCircle size={14} />}>
{t('失败')}
</Tag>
);
case 'QUEUED':
return (
<Tag color='orange' size='large' shape='circle'>
<Tag color='orange' size='large' shape='circle' prefixIcon={<List size={14} />}>
{t('排队中')}
</Tag>
);
case 'UNKNOWN':
return (
<Tag color='white' size='large' shape='circle'>
<Tag color='white' size='large' shape='circle' prefixIcon={<HelpCircle size={14} />}>
{t('未知')}
</Tag>
);
case '':
return (
<Tag color='grey' size='large' shape='circle'>
<Tag color='grey' size='large' shape='circle' prefixIcon={<Loader size={14} />}>
{t('正在提交')}
</Tag>
);
default:
return (
<Tag color='white' size='large' shape='circle'>
<Tag color='white' size='large' shape='circle' prefixIcon={<HelpCircle size={14} />}>
{t('未知')}
</Tag>
);
@@ -320,6 +333,7 @@ const LogsTable = () => {
color={colors[parseInt(text) % colors.length]}
size='large'
shape='circle'
prefixIcon={<Hash size={14} />}
onClick={() => {
copyText(text);
}}

View File

@@ -6,7 +6,8 @@ import {
showSuccess,
timestamp2string,
renderGroup,
renderQuota
renderQuota,
getQuotaPerUnit
} from '../../helpers';
import { ITEMS_PER_PAGE } from '../../constants';
@@ -19,9 +20,20 @@ import {
Space,
SplitButtonGroup,
Table,
Tag,
Tag
} from '@douyinfe/semi-ui';
import {
CheckCircle,
Shield,
XCircle,
Clock,
Gauge,
HelpCircle,
Infinity,
Coins
} from 'lucide-react';
import {
IconPlus,
IconCopy,
@@ -32,7 +44,7 @@ import {
IconDelete,
IconStop,
IconPlay,
IconMore,
IconMore
} from '@douyinfe/semi-icons';
import EditToken from '../../pages/Token/EditToken';
import { useTranslation } from 'react-i18next';
@@ -49,38 +61,38 @@ const TokensTable = () => {
case 1:
if (model_limits_enabled) {
return (
<Tag color='green' size='large' shape='circle'>
<Tag color='green' size='large' shape='circle' prefixIcon={<Shield size={14} />}>
{t('已启用:限制模型')}
</Tag>
);
} else {
return (
<Tag color='green' size='large' shape='circle'>
<Tag color='green' size='large' shape='circle' prefixIcon={<CheckCircle size={14} />}>
{t('已启用')}
</Tag>
);
}
case 2:
return (
<Tag color='red' size='large' shape='circle'>
<Tag color='red' size='large' shape='circle' prefixIcon={<XCircle size={14} />}>
{t('已禁用')}
</Tag>
);
case 3:
return (
<Tag color='yellow' size='large' shape='circle'>
<Tag color='yellow' size='large' shape='circle' prefixIcon={<Clock size={14} />}>
{t('已过期')}
</Tag>
);
case 4:
return (
<Tag color='grey' size='large' shape='circle'>
<Tag color='grey' size='large' shape='circle' prefixIcon={<Gauge size={14} />}>
{t('已耗尽')}
</Tag>
);
default:
return (
<Tag color='black' size='large' shape='circle'>
<Tag color='black' size='large' shape='circle' prefixIcon={<HelpCircle size={14} />}>
{t('未知状态')}
</Tag>
);
@@ -111,21 +123,45 @@ const TokensTable = () => {
title: t('已用额度'),
dataIndex: 'used_quota',
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('剩余额度'),
dataIndex: 'remain_quota',
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 (
<div>
{record.unlimited_quota ? (
<Tag size={'large'} color={'white'} shape='circle'>
<Tag size={'large'} color={'white'} shape='circle' prefixIcon={<Infinity size={14} />}>
{t('无限制')}
</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))}
</Tag>
)}

View File

@@ -1,5 +1,20 @@
import React, { useEffect, useState } from 'react';
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 {
Button,
Card,
@@ -10,7 +25,7 @@ import {
Space,
Table,
Tag,
Typography,
Typography
} from '@douyinfe/semi-ui';
import {
IconPlus,
@@ -22,7 +37,7 @@ import {
IconMore,
IconUserAdd,
IconArrowUp,
IconArrowDown,
IconArrowDown
} from '@douyinfe/semi-icons';
import { ITEMS_PER_PAGE } from '../../constants';
import AddUser from '../../pages/User/AddUser';
@@ -38,25 +53,25 @@ const UsersTable = () => {
switch (role) {
case 1:
return (
<Tag size='large' color='blue' shape='circle'>
<Tag size='large' color='blue' shape='circle' prefixIcon={<User size={14} />}>
{t('普通用户')}
</Tag>
);
case 10:
return (
<Tag color='yellow' size='large' shape='circle'>
<Tag color='yellow' size='large' shape='circle' prefixIcon={<Shield size={14} />}>
{t('管理员')}
</Tag>
);
case 100:
return (
<Tag color='orange' size='large' shape='circle'>
<Tag color='orange' size='large' shape='circle' prefixIcon={<Crown size={14} />}>
{t('超级管理员')}
</Tag>
);
default:
return (
<Tag color='red' size='large' shape='circle'>
<Tag color='red' size='large' shape='circle' prefixIcon={<HelpCircle size={14} />}>
{t('未知身份')}
</Tag>
);
@@ -66,16 +81,16 @@ const UsersTable = () => {
const renderStatus = (status) => {
switch (status) {
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:
return (
<Tag size='large' color='red' shape='circle'>
<Tag size='large' color='red' shape='circle' prefixIcon={<XCircle size={14} />}>
{t('已封禁')}
</Tag>
);
default:
return (
<Tag size='large' color='grey' shape='circle'>
<Tag size='large' color='grey' shape='circle' prefixIcon={<HelpCircle size={14} />}>
{t('未知状态')}
</Tag>
);
@@ -105,13 +120,13 @@ const UsersTable = () => {
return (
<div>
<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)}
</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)}
</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)}
</Tag>
</Space>
@@ -126,13 +141,13 @@ const UsersTable = () => {
return (
<div>
<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)}
</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)}
</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}`}
</Tag>
</Space>
@@ -154,7 +169,7 @@ const UsersTable = () => {
return (
<div>
{record.DeletedAt !== null ? (
<Tag color='red' shape='circle'>{t('已注销')}</Tag>
<Tag color='red' shape='circle' prefixIcon={<Minus size={14} />}>{t('已注销')}</Tag>
) : (
renderStatus(text)
)}