Commit 7b271bb1 by t0ng7u

🎨 refactor(TokensTable): refactor TokensTable UI & UX for clearer data and inline actions

This commit overhauls the `TokensTable` component to deliver a cleaner, more intuitive experience.

Key changes
1. Quota
   • Merged “Used” & “Remaining” into a single “Quota” column.
   • Uses a circular `Progress` with %-label; full details shown on tooltip.

2. Status
   • Tag now embeds a small `Switch` (prefixIcon) to enable/disable a token in-place.
   • Removed enable/disable actions from the old dropdown.

3. Columns & layout
   • Added dedicated “Group” column (moved from Status).
   • Added “Key” column:
     – Read-only `Input` styled like Home page base-URL field.
     – Masked value (`sk-abc********xyz`) by default.
     – Eye button toggles reveal/hide; Copy button copies full key (without modal).
   • Dropped “More” menu; Delete is now a direct button in the action area.

4. Model limits
   • Shows vendor icons inside an `AvatarGroup`; tooltip lists the exact models.

5. IP restriction
   • Displays first IP, extra count as “+N” Tag with tooltip.
   • Unlimited shows white Tag.

6. Cleanup / misc.
   • Removed unused helpers (`getQuotaPerUnit`), icons (`IconMore`, eye/copy duplicates, etc.).
   • Replaced legacy modal view of key with inline input behaviour.
   • Tweaked paddings, themes, sizes to align with design system.

BREAKING CHANGE: Table column order & names have changed; update any tests or docs referencing the old structure.
parent c96bdfbe
......@@ -34,7 +34,7 @@ const ParameterControl = ({
<Typography.Text strong className="text-sm">
Temperature
</Typography.Text>
<Tag size="small" className="!rounded-full">
<Tag size="small" shape='circle'>
{inputs.temperature}
</Tag>
</div>
......@@ -70,7 +70,7 @@ const ParameterControl = ({
<Typography.Text strong className="text-sm">
Top P
</Typography.Text>
<Tag size="small" className="!rounded-full">
<Tag size="small" shape='circle'>
{inputs.top_p}
</Tag>
</div>
......@@ -106,7 +106,7 @@ const ParameterControl = ({
<Typography.Text strong className="text-sm">
Frequency Penalty
</Typography.Text>
<Tag size="small" className="!rounded-full">
<Tag size="small" shape='circle'>
{inputs.frequency_penalty}
</Tag>
</div>
......@@ -142,7 +142,7 @@ const ParameterControl = ({
<Typography.Text strong className="text-sm">
Presence Penalty
</Typography.Text>
<Tag size="small" className="!rounded-full">
<Tag size="small" shape='circle'>
{inputs.presence_penalty}
</Tag>
</div>
......
......@@ -118,25 +118,25 @@ const ChannelSelectorModal = forwardRef(({
switch (status) {
case 1:
return (
<Tag size='large' color='green' shape='circle' prefixIcon={<CheckCircle size={14} />}>
<Tag color='green' shape='circle' prefixIcon={<CheckCircle size={14} />}>
{t('已启用')}
</Tag>
);
case 2:
return (
<Tag size='large' color='red' shape='circle' prefixIcon={<XCircle size={14} />}>
<Tag color='red' shape='circle' prefixIcon={<XCircle size={14} />}>
{t('已禁用')}
</Tag>
);
case 3:
return (
<Tag size='large' color='yellow' shape='circle' prefixIcon={<AlertCircle size={14} />}>
<Tag color='yellow' shape='circle' prefixIcon={<AlertCircle size={14} />}>
{t('自动禁用')}
</Tag>
);
default:
return (
<Tag size='large' color='grey' shape='circle' prefixIcon={<HelpCircle size={14} />}>
<Tag color='grey' shape='circle' prefixIcon={<HelpCircle size={14} />}>
{t('未知状态')}
</Tag>
);
......
......@@ -63,7 +63,6 @@ const ChannelsTable = () => {
}
return (
<Tag
size='large'
color={type2label[type]?.color}
shape='circle'
prefixIcon={getChannelIcon(type)}
......@@ -77,7 +76,6 @@ const ChannelsTable = () => {
return (
<Tag
color='light-blue'
size='large'
shape='circle'
type='light'
>
......@@ -90,25 +88,25 @@ const ChannelsTable = () => {
switch (status) {
case 1:
return (
<Tag size='large' color='green' shape='circle'>
<Tag color='green' shape='circle'>
{t('已启用')}
</Tag>
);
case 2:
return (
<Tag size='large' color='red' shape='circle'>
<Tag color='red' shape='circle'>
{t('已禁用')}
</Tag>
);
case 3:
return (
<Tag size='large' color='yellow' shape='circle'>
<Tag color='yellow' shape='circle'>
{t('自动禁用')}
</Tag>
);
default:
return (
<Tag size='large' color='grey' shape='circle'>
<Tag color='grey' shape='circle'>
{t('未知状态')}
</Tag>
);
......@@ -120,31 +118,31 @@ const ChannelsTable = () => {
time = time.toFixed(2) + t(' 秒');
if (responseTime === 0) {
return (
<Tag size='large' color='grey' shape='circle'>
<Tag color='grey' shape='circle'>
{t('未测试')}
</Tag>
);
} else if (responseTime <= 1000) {
return (
<Tag size='large' color='green' shape='circle'>
<Tag color='green' shape='circle'>
{time}
</Tag>
);
} else if (responseTime <= 3000) {
return (
<Tag size='large' color='lime' shape='circle'>
<Tag color='lime' shape='circle'>
{time}
</Tag>
);
} else if (responseTime <= 5000) {
return (
<Tag size='large' color='yellow' shape='circle'>
<Tag color='yellow' shape='circle'>
{time}
</Tag>
);
} else {
return (
<Tag size='large' color='red' shape='circle'>
<Tag color='red' shape='circle'>
{time}
</Tag>
);
......@@ -331,7 +329,7 @@ const ChannelsTable = () => {
<div>
<Space spacing={1}>
<Tooltip content={t('已用额度')}>
<Tag color='white' type='ghost' size='large' shape='circle'>
<Tag color='white' type='ghost' shape='circle'>
{renderQuota(record.used_quota)}
</Tag>
</Tooltip>
......@@ -339,7 +337,6 @@ const ChannelsTable = () => {
<Tag
color='white'
type='ghost'
size='large'
shape='circle'
onClick={() => updateChannelBalance(record)}
>
......@@ -352,7 +349,7 @@ const ChannelsTable = () => {
} else {
return (
<Tooltip content={t('已用额度')}>
<Tag color='white' type='ghost' size='large' shape='circle'>
<Tag color='white' type='ghost' shape='circle'>
{renderQuota(record.used_quota)}
</Tag>
</Tooltip>
......@@ -1240,7 +1237,7 @@ const ChannelsTable = () => {
tab={
<span className="flex items-center gap-2">
{t('全部')}
<Tag color={activeTypeKey === 'all' ? 'red' : 'grey'} size='small' shape='circle'>
<Tag color={activeTypeKey === 'all' ? 'red' : 'grey'} shape='circle'>
{channelTypeCounts['all'] || 0}
</Tag>
</span>
......@@ -1258,7 +1255,7 @@ const ChannelsTable = () => {
<span className="flex items-center gap-2">
{getChannelIcon(option.value)}
{option.label}
<Tag color={activeTypeKey === key ? 'red' : 'grey'} size='small' shape='circle'>
<Tag color={activeTypeKey === key ? 'red' : 'grey'} shape='circle'>
{count}
</Tag>
</span>
......@@ -1461,7 +1458,7 @@ const ChannelsTable = () => {
const fixChannelsAbilities = async () => {
const res = await API.post(`/api/channel/fix`);
const { success, message, data } = res.data;
const { success, message, data } = res.data;
if (success) {
showSuccess(t('已修复 ${success} 个通道,失败 ${fails} 个通道。').replace('${success}', data.success).replace('${fails}', data.fails));
await refresh();
......@@ -2033,7 +2030,7 @@ const ChannelsTable = () => {
if (isTesting) {
return (
<Tag size='large' color='blue' shape='circle'>
<Tag color='blue' shape='circle'>
{t('测试中')}
</Tag>
);
......@@ -2041,7 +2038,7 @@ const ChannelsTable = () => {
if (!testResult) {
return (
<Tag size='large' color='grey' shape='circle'>
<Tag color='grey' shape='circle'>
{t('未开始')}
</Tag>
);
......@@ -2050,7 +2047,6 @@ const ChannelsTable = () => {
return (
<div className="flex items-center gap-2">
<Tag
size='large'
color={testResult.success ? 'green' : 'red'}
shape='circle'
>
......
......@@ -78,37 +78,37 @@ const LogsTable = () => {
switch (type) {
case 1:
return (
<Tag color='cyan' size='large' shape='circle'>
<Tag color='cyan' shape='circle'>
{t('充值')}
</Tag>
);
case 2:
return (
<Tag color='lime' size='large' shape='circle'>
<Tag color='lime' shape='circle'>
{t('消费')}
</Tag>
);
case 3:
return (
<Tag color='orange' size='large' shape='circle'>
<Tag color='orange' shape='circle'>
{t('管理')}
</Tag>
);
case 4:
return (
<Tag color='purple' size='large' shape='circle'>
<Tag color='purple' shape='circle'>
{t('系统')}
</Tag>
);
case 5:
return (
<Tag color='red' size='large' shape='circle'>
<Tag color='red' shape='circle'>
{t('错误')}
</Tag>
);
default:
return (
<Tag color='grey' size='large' shape='circle'>
<Tag color='grey' shape='circle'>
{t('未知')}
</Tag>
);
......@@ -118,13 +118,13 @@ const LogsTable = () => {
function renderIsStream(bool) {
if (bool) {
return (
<Tag color='blue' size='large' shape='circle'>
<Tag color='blue' shape='circle'>
{t('流')}
</Tag>
);
} else {
return (
<Tag color='purple' size='large' shape='circle'>
<Tag color='purple' shape='circle'>
{t('非流')}
</Tag>
);
......@@ -135,21 +135,21 @@ const LogsTable = () => {
const time = parseInt(type);
if (time < 101) {
return (
<Tag color='green' size='large' shape='circle'>
<Tag color='green' shape='circle'>
{' '}
{time} s{' '}
</Tag>
);
} else if (time < 300) {
return (
<Tag color='orange' size='large' shape='circle'>
<Tag color='orange' shape='circle'>
{' '}
{time} s{' '}
</Tag>
);
} else {
return (
<Tag color='red' size='large' shape='circle'>
<Tag color='red' shape='circle'>
{' '}
{time} s{' '}
</Tag>
......@@ -162,21 +162,21 @@ const LogsTable = () => {
time = time.toFixed(1);
if (time < 3) {
return (
<Tag color='green' size='large' shape='circle'>
<Tag color='green' shape='circle'>
{' '}
{time} s{' '}
</Tag>
);
} else if (time < 10) {
return (
<Tag color='orange' size='large' shape='circle'>
<Tag color='orange' shape='circle'>
{' '}
{time} s{' '}
</Tag>
);
} else {
return (
<Tag color='red' size='large' shape='circle'>
<Tag color='red' shape='circle'>
{' '}
{time} s{' '}
</Tag>
......@@ -363,7 +363,6 @@ const LogsTable = () => {
<Tooltip content={record.channel_name || '[未知]'}>
<Tag
color={colors[parseInt(text) % colors.length]}
size='large'
shape='circle'
>
{' '}
......@@ -415,7 +414,6 @@ const LogsTable = () => {
<div>
<Tag
color='grey'
size='large'
shape='circle'
onClick={(event) => {
//cancel the row click event
......@@ -567,7 +565,6 @@ const LogsTable = () => {
<Tooltip content={text}>
<Tag
color='orange'
size='large'
shape='circle'
onClick={(event) => {
copyText(event, text);
......
......@@ -185,115 +185,115 @@ const LogsTable = () => {
switch (type) {
case 'IMAGINE':
return (
<Tag color='blue' size='large' shape='circle' prefixIcon={<Palette size={14} />}>
<Tag color='blue' shape='circle' prefixIcon={<Palette size={14} />}>
{t('绘图')}
</Tag>
);
case 'UPSCALE':
return (
<Tag color='orange' size='large' shape='circle' prefixIcon={<ZoomIn size={14} />}>
<Tag color='orange' shape='circle' prefixIcon={<ZoomIn size={14} />}>
{t('放大')}
</Tag>
);
case 'VIDEO':
return (
<Tag color='orange' size='large' shape='circle' prefixIcon={<Video size={14} />}>
<Tag color='orange' shape='circle' prefixIcon={<Video size={14} />}>
{t('视频')}
</Tag>
);
case 'EDITS':
return (
<Tag color='orange' size='large' shape='circle' prefixIcon={<Video size={14} />}>
<Tag color='orange' shape='circle' prefixIcon={<Video size={14} />}>
{t('编辑')}
</Tag>
);
case 'VARIATION':
return (
<Tag color='purple' size='large' shape='circle' prefixIcon={<Shuffle size={14} />}>
<Tag color='purple' shape='circle' prefixIcon={<Shuffle size={14} />}>
{t('变换')}
</Tag>
);
case 'HIGH_VARIATION':
return (
<Tag color='purple' size='large' shape='circle' prefixIcon={<Shuffle size={14} />}>
<Tag color='purple' shape='circle' prefixIcon={<Shuffle size={14} />}>
{t('强变换')}
</Tag>
);
case 'LOW_VARIATION':
return (
<Tag color='purple' size='large' shape='circle' prefixIcon={<Shuffle size={14} />}>
<Tag color='purple' shape='circle' prefixIcon={<Shuffle size={14} />}>
{t('弱变换')}
</Tag>
);
case 'PAN':
return (
<Tag color='cyan' size='large' shape='circle' prefixIcon={<Move size={14} />}>
<Tag color='cyan' shape='circle' prefixIcon={<Move size={14} />}>
{t('平移')}
</Tag>
);
case 'DESCRIBE':
return (
<Tag color='yellow' size='large' shape='circle' prefixIcon={<FileText size={14} />}>
<Tag color='yellow' shape='circle' prefixIcon={<FileText size={14} />}>
{t('图生文')}
</Tag>
);
case 'BLEND':
return (
<Tag color='lime' size='large' shape='circle' prefixIcon={<Blend size={14} />}>
<Tag color='lime' shape='circle' prefixIcon={<Blend size={14} />}>
{t('图混合')}
</Tag>
);
case 'UPLOAD':
return (
<Tag color='blue' size='large' shape='circle' prefixIcon={<Upload size={14} />}>
<Tag color='blue' shape='circle' prefixIcon={<Upload size={14} />}>
上传文件
</Tag>
);
case 'SHORTEN':
return (
<Tag color='pink' size='large' shape='circle' prefixIcon={<Minimize2 size={14} />}>
<Tag color='pink' shape='circle' prefixIcon={<Minimize2 size={14} />}>
{t('缩词')}
</Tag>
);
case 'REROLL':
return (
<Tag color='indigo' size='large' shape='circle' prefixIcon={<RotateCcw size={14} />}>
<Tag color='indigo' shape='circle' prefixIcon={<RotateCcw size={14} />}>
{t('重绘')}
</Tag>
);
case 'INPAINT':
return (
<Tag color='violet' size='large' shape='circle' prefixIcon={<PaintBucket size={14} />}>
<Tag color='violet' shape='circle' prefixIcon={<PaintBucket size={14} />}>
{t('局部重绘-提交')}
</Tag>
);
case 'ZOOM':
return (
<Tag color='teal' size='large' shape='circle' prefixIcon={<Focus size={14} />}>
<Tag color='teal' shape='circle' prefixIcon={<Focus size={14} />}>
{t('变焦')}
</Tag>
);
case 'CUSTOM_ZOOM':
return (
<Tag color='teal' size='large' shape='circle' prefixIcon={<Move3D size={14} />}>
<Tag color='teal' shape='circle' prefixIcon={<Move3D size={14} />}>
{t('自定义变焦-提交')}
</Tag>
);
case 'MODAL':
return (
<Tag color='green' size='large' shape='circle' prefixIcon={<Monitor size={14} />}>
<Tag color='green' shape='circle' prefixIcon={<Monitor size={14} />}>
{t('窗口处理')}
</Tag>
);
case 'SWAP_FACE':
return (
<Tag color='light-green' size='large' shape='circle' prefixIcon={<UserCheck size={14} />}>
<Tag color='light-green' shape='circle' prefixIcon={<UserCheck size={14} />}>
{t('换脸')}
</Tag>
);
default:
return (
<Tag color='white' size='large' shape='circle' prefixIcon={<HelpCircle size={14} />}>
<Tag color='white' shape='circle' prefixIcon={<HelpCircle size={14} />}>
{t('未知')}
</Tag>
);
......@@ -304,31 +304,31 @@ const LogsTable = () => {
switch (code) {
case 1:
return (
<Tag color='green' size='large' shape='circle' prefixIcon={<CheckCircle size={14} />}>
<Tag color='green' shape='circle' prefixIcon={<CheckCircle size={14} />}>
{t('已提交')}
</Tag>
);
case 21:
return (
<Tag color='lime' size='large' shape='circle' prefixIcon={<Clock size={14} />}>
<Tag color='lime' shape='circle' prefixIcon={<Clock size={14} />}>
{t('等待中')}
</Tag>
);
case 22:
return (
<Tag color='orange' size='large' shape='circle' prefixIcon={<Copy size={14} />}>
<Tag color='orange' shape='circle' prefixIcon={<Copy size={14} />}>
{t('重复提交')}
</Tag>
);
case 0:
return (
<Tag color='yellow' size='large' shape='circle' prefixIcon={<FileX size={14} />}>
<Tag color='yellow' shape='circle' prefixIcon={<FileX size={14} />}>
{t('未提交')}
</Tag>
);
default:
return (
<Tag color='white' size='large' shape='circle' prefixIcon={<HelpCircle size={14} />}>
<Tag color='white' shape='circle' prefixIcon={<HelpCircle size={14} />}>
{t('未知')}
</Tag>
);
......@@ -339,43 +339,43 @@ const LogsTable = () => {
switch (type) {
case 'SUCCESS':
return (
<Tag color='green' size='large' shape='circle' prefixIcon={<CheckCircle size={14} />}>
<Tag color='green' shape='circle' prefixIcon={<CheckCircle size={14} />}>
{t('成功')}
</Tag>
);
case 'NOT_START':
return (
<Tag color='grey' size='large' shape='circle' prefixIcon={<Pause size={14} />}>
<Tag color='grey' shape='circle' prefixIcon={<Pause size={14} />}>
{t('未启动')}
</Tag>
);
case 'SUBMITTED':
return (
<Tag color='yellow' size='large' shape='circle' prefixIcon={<Clock size={14} />}>
<Tag color='yellow' shape='circle' prefixIcon={<Clock size={14} />}>
{t('队列中')}
</Tag>
);
case 'IN_PROGRESS':
return (
<Tag color='blue' size='large' shape='circle' prefixIcon={<Loader size={14} />}>
<Tag color='blue' shape='circle' prefixIcon={<Loader size={14} />}>
{t('执行中')}
</Tag>
);
case 'FAILURE':
return (
<Tag color='red' size='large' shape='circle' prefixIcon={<XCircle size={14} />}>
<Tag color='red' shape='circle' prefixIcon={<XCircle size={14} />}>
{t('失败')}
</Tag>
);
case 'MODAL':
return (
<Tag color='yellow' size='large' shape='circle' prefixIcon={<AlertCircle size={14} />}>
<Tag color='yellow' shape='circle' prefixIcon={<AlertCircle size={14} />}>
{t('窗口等待')}
</Tag>
);
default:
return (
<Tag color='white' size='large' shape='circle' prefixIcon={<HelpCircle size={14} />}>
<Tag color='white' shape='circle' prefixIcon={<HelpCircle size={14} />}>
{t('未知')}
</Tag>
);
......@@ -405,7 +405,7 @@ const LogsTable = () => {
const color = durationSec > 60 ? 'red' : 'green';
return (
<Tag color={color} size='large' shape='circle' prefixIcon={<Clock size={14} />}>
<Tag color={color} shape='circle' prefixIcon={<Clock size={14} />}>
{durationSec} {t('秒')}
</Tag>
);
......@@ -439,7 +439,6 @@ const LogsTable = () => {
<div>
<Tag
color={colors[parseInt(text) % colors.length]}
size='large'
shape='circle'
prefixIcon={<Hash size={14} />}
onClick={() => {
......
......@@ -76,13 +76,13 @@ const ModelPricing = () => {
switch (type) {
case 1:
return (
<Tag color='teal' size='large' shape='circle'>
<Tag color='teal' shape='circle'>
{t('按次计费')}
</Tag>
);
case 0:
return (
<Tag color='violet' size='large' shape='circle'>
<Tag color='violet' shape='circle'>
{t('按量计费')}
</Tag>
);
......@@ -116,7 +116,6 @@ const ModelPricing = () => {
<Tag
key={endpoint}
color={stringToColor(endpoint)}
size='large'
shape='circle'
>
{endpoint}
......@@ -179,7 +178,7 @@ const ModelPricing = () => {
if (usableGroup[group]) {
if (group === selectedGroup) {
return (
<Tag color='blue' size='large' shape='circle' prefixIcon={<IconVerify />}>
<Tag color='blue' shape='circle' prefixIcon={<IconVerify />}>
{group}
</Tag>
);
......@@ -187,7 +186,6 @@ const ModelPricing = () => {
return (
<Tag
color='blue'
size='large'
shape='circle'
onClick={() => {
setSelectedGroup(group);
......@@ -392,7 +390,6 @@ const ModelPricing = () => {
{category.label}
<Tag
color={activeKey === key ? 'red' : 'grey'}
size='small'
shape='circle'
>
{modelCount}
......@@ -436,7 +433,6 @@ const ModelPricing = () => {
onCompositionEnd={handleCompositionEnd}
onChange={handleChange}
showClear
size="large"
/>
</div>
<Button
......@@ -446,7 +442,6 @@ const ModelPricing = () => {
onClick={() => copyText(selectedRowKeys)}
disabled={selectedRowKeys.length === 0}
className="!bg-blue-500 hover:!bg-blue-600 text-white"
size="large"
>
{t('复制选中模型')}
</Button>
......
......@@ -53,31 +53,31 @@ const RedemptionsTable = () => {
const renderStatus = (status, record) => {
if (isExpired(record)) {
return (
<Tag color='orange' size='large' shape='circle'>{t('已过期')}</Tag>
<Tag color='orange' shape='circle'>{t('已过期')}</Tag>
);
}
switch (status) {
case 1:
return (
<Tag color='green' size='large' shape='circle'>
<Tag color='green' shape='circle'>
{t('未使用')}
</Tag>
);
case 2:
return (
<Tag color='red' size='large' shape='circle'>
<Tag color='red' shape='circle'>
{t('已禁用')}
</Tag>
);
case 3:
return (
<Tag color='grey' size='large' shape='circle'>
<Tag color='grey' shape='circle'>
{t('已使用')}
</Tag>
);
default:
return (
<Tag color='black' size='large' shape='circle'>
<Tag color='black' shape='circle'>
{t('未知状态')}
</Tag>
);
......@@ -107,7 +107,7 @@ const RedemptionsTable = () => {
render: (text, record, index) => {
return (
<div>
<Tag size={'large'} color={'grey'} shape='circle'>
<Tag color='grey' shape='circle'>
{renderQuota(parseInt(text))}
</Tag>
</div>
......
......@@ -106,7 +106,7 @@ function renderDuration(submit_time, finishTime) {
// 返回带有样式的颜色标签
return (
<Tag color={color} size='large' prefixIcon={<Clock size={14} />}>
<Tag color={color} prefixIcon={<Clock size={14} />}>
{durationSec}
</Tag>
);
......@@ -198,31 +198,31 @@ const LogsTable = () => {
switch (type) {
case 'MUSIC':
return (
<Tag color='grey' size='large' shape='circle' prefixIcon={<Music size={14} />}>
<Tag color='grey' shape='circle' prefixIcon={<Music size={14} />}>
{t('生成音乐')}
</Tag>
);
case 'LYRICS':
return (
<Tag color='pink' size='large' shape='circle' prefixIcon={<FileText size={14} />}>
<Tag color='pink' shape='circle' prefixIcon={<FileText size={14} />}>
{t('生成歌词')}
</Tag>
);
case TASK_ACTION_GENERATE:
return (
<Tag color='blue' size='large' shape='circle' prefixIcon={<Sparkles size={14} />}>
<Tag color='blue' shape='circle' prefixIcon={<Sparkles size={14} />}>
{t('图生视频')}
</Tag>
);
case TASK_ACTION_TEXT_GENERATE:
return (
<Tag color='blue' size='large' shape='circle' prefixIcon={<Sparkles size={14} />}>
<Tag color='blue' shape='circle' prefixIcon={<Sparkles size={14} />}>
{t('文生视频')}
</Tag>
);
default:
return (
<Tag color='white' size='large' shape='circle' prefixIcon={<HelpCircle size={14} />}>
<Tag color='white' shape='circle' prefixIcon={<HelpCircle size={14} />}>
{t('未知')}
</Tag>
);
......@@ -233,25 +233,25 @@ const LogsTable = () => {
switch (platform) {
case 'suno':
return (
<Tag color='green' size='large' shape='circle' prefixIcon={<Music size={14} />}>
<Tag color='green' shape='circle' prefixIcon={<Music size={14} />}>
Suno
</Tag>
);
case 'kling':
return (
<Tag color='orange' size='large' shape='circle' prefixIcon={<Video size={14} />}>
<Tag color='orange' shape='circle' prefixIcon={<Video size={14} />}>
Kling
</Tag>
);
case 'jimeng':
return (
<Tag color='purple' size='large' shape='circle' prefixIcon={<Video size={14} />}>
<Tag color='purple' shape='circle' prefixIcon={<Video size={14} />}>
Jimeng
</Tag>
);
default:
return (
<Tag color='white' size='large' shape='circle' prefixIcon={<HelpCircle size={14} />}>
<Tag color='white' shape='circle' prefixIcon={<HelpCircle size={14} />}>
{t('未知')}
</Tag>
);
......@@ -262,55 +262,55 @@ const LogsTable = () => {
switch (type) {
case 'SUCCESS':
return (
<Tag color='green' size='large' shape='circle' prefixIcon={<CheckCircle size={14} />}>
<Tag color='green' shape='circle' prefixIcon={<CheckCircle size={14} />}>
{t('成功')}
</Tag>
);
case 'NOT_START':
return (
<Tag color='grey' size='large' shape='circle' prefixIcon={<Pause size={14} />}>
<Tag color='grey' shape='circle' prefixIcon={<Pause size={14} />}>
{t('未启动')}
</Tag>
);
case 'SUBMITTED':
return (
<Tag color='yellow' size='large' shape='circle' prefixIcon={<Clock size={14} />}>
<Tag color='yellow' shape='circle' prefixIcon={<Clock size={14} />}>
{t('队列中')}
</Tag>
);
case 'IN_PROGRESS':
return (
<Tag color='blue' size='large' shape='circle' prefixIcon={<Play size={14} />}>
<Tag color='blue' shape='circle' prefixIcon={<Play size={14} />}>
{t('执行中')}
</Tag>
);
case 'FAILURE':
return (
<Tag color='red' size='large' shape='circle' prefixIcon={<XCircle size={14} />}>
<Tag color='red' shape='circle' prefixIcon={<XCircle size={14} />}>
{t('失败')}
</Tag>
);
case 'QUEUED':
return (
<Tag color='orange' size='large' shape='circle' prefixIcon={<List size={14} />}>
<Tag color='orange' shape='circle' prefixIcon={<List size={14} />}>
{t('排队中')}
</Tag>
);
case 'UNKNOWN':
return (
<Tag color='white' size='large' shape='circle' prefixIcon={<HelpCircle size={14} />}>
<Tag color='white' shape='circle' prefixIcon={<HelpCircle size={14} />}>
{t('未知')}
</Tag>
);
case '':
return (
<Tag color='grey' size='large' shape='circle' prefixIcon={<Loader size={14} />}>
<Tag color='grey' shape='circle' prefixIcon={<Loader size={14} />}>
{t('正在提交')}
</Tag>
);
default:
return (
<Tag color='white' size='large' shape='circle' prefixIcon={<HelpCircle size={14} />}>
<Tag color='white' shape='circle' prefixIcon={<HelpCircle size={14} />}>
{t('未知')}
</Tag>
);
......
......@@ -54,25 +54,25 @@ const UsersTable = () => {
switch (role) {
case 1:
return (
<Tag size='large' color='blue' shape='circle' prefixIcon={<User size={14} />}>
<Tag color='blue' shape='circle' prefixIcon={<User size={14} />}>
{t('普通用户')}
</Tag>
);
case 10:
return (
<Tag color='yellow' size='large' shape='circle' prefixIcon={<Shield size={14} />}>
<Tag color='yellow' shape='circle' prefixIcon={<Shield size={14} />}>
{t('管理员')}
</Tag>
);
case 100:
return (
<Tag color='orange' size='large' shape='circle' prefixIcon={<Crown size={14} />}>
<Tag color='orange' shape='circle' prefixIcon={<Crown size={14} />}>
{t('超级管理员')}
</Tag>
);
default:
return (
<Tag color='red' size='large' shape='circle' prefixIcon={<HelpCircle size={14} />}>
<Tag color='red' shape='circle' prefixIcon={<HelpCircle size={14} />}>
{t('未知身份')}
</Tag>
);
......@@ -82,16 +82,16 @@ const UsersTable = () => {
const renderStatus = (status) => {
switch (status) {
case 1:
return <Tag size='large' color='green' shape='circle' prefixIcon={<CheckCircle size={14} />}>{t('已激活')}</Tag>;
return <Tag color='green' shape='circle' prefixIcon={<CheckCircle size={14} />}>{t('已激活')}</Tag>;
case 2:
return (
<Tag size='large' color='red' shape='circle' prefixIcon={<XCircle size={14} />}>
<Tag color='red' shape='circle' prefixIcon={<XCircle size={14} />}>
{t('已封禁')}
</Tag>
);
default:
return (
<Tag size='large' color='grey' shape='circle' prefixIcon={<HelpCircle size={14} />}>
<Tag color='grey' shape='circle' prefixIcon={<HelpCircle size={14} />}>
{t('未知状态')}
</Tag>
);
......@@ -117,7 +117,7 @@ const UsersTable = () => {
<Space spacing={2}>
<span>{text}</span>
<Tooltip content={remark} position="top" showArrow>
<Tag color='white' size='large' shape='circle' className="!text-xs">
<Tag color='white' shape='circle' className="!text-xs">
<div className="flex items-center gap-1">
<div className="w-2 h-2 flex-shrink-0 rounded-full" style={{ backgroundColor: '#10b981' }} />
{displayRemark}
......@@ -142,13 +142,13 @@ const UsersTable = () => {
return (
<div>
<Space spacing={1}>
<Tag color='white' size='large' shape='circle' className="!text-xs" prefixIcon={<Coins size={14} />}>
<Tag color='white' shape='circle' className="!text-xs" prefixIcon={<Coins size={14} />}>
{t('剩余')}: {renderQuota(record.quota)}
</Tag>
<Tag color='white' size='large' shape='circle' className="!text-xs" prefixIcon={<Coins size={14} />}>
<Tag color='white' 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" prefixIcon={<Activity size={14} />}>
<Tag color='white' shape='circle' className="!text-xs" prefixIcon={<Activity size={14} />}>
{t('调用')}: {renderNumber(record.request_count)}
</Tag>
</Space>
......@@ -163,13 +163,13 @@ const UsersTable = () => {
return (
<div>
<Space spacing={1}>
<Tag color='white' size='large' shape='circle' className="!text-xs" prefixIcon={<Users size={14} />}>
<Tag color='white' 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" prefixIcon={<DollarSign size={14} />}>
<Tag color='white' 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" prefixIcon={<UserPlus size={14} />}>
<Tag color='white' shape='circle' className="!text-xs" prefixIcon={<UserPlus size={14} />}>
{record.inviter_id === 0 ? t('无邀请人') : `邀请人: ${record.inviter_id}`}
</Tag>
</Space>
......
......@@ -539,7 +539,7 @@ export function stringToColor(str) {
export function renderModelTag(modelName, options = {}) {
const {
color,
size = 'large',
size = 'default',
shape = 'circle',
onClick,
suffixIcon,
......@@ -584,7 +584,7 @@ export function renderText(text, limit) {
export function renderGroup(group) {
if (group === '') {
return (
<Tag size='large' key='default' color='orange' shape='circle'>
<Tag key='default' color='orange' shape='circle'>
{i18next.t('用户分组')}
</Tag>
);
......@@ -603,7 +603,6 @@ export function renderGroup(group) {
<span key={group}>
{groups.map((group) => (
<Tag
size='large'
color={tagColors[group] || stringToColor(group)}
key={group}
shape='circle'
......
......@@ -373,6 +373,9 @@
"搜索令牌的名称 ...": "Search for the name of the token...",
"已用额度": "Quota used",
"剩余额度": "Remaining quota",
"总额度": "Total quota",
"智能熔断": "Smart fallback",
"当前分组为 auto,会自动选择最优分组,当一个组不可用时自动降级到下一个组(熔断机制)": "The current group is auto, it will automatically select the optimal group, and automatically downgrade to the next group when a group is unavailable (breakage mechanism)",
"过期时间": "Expiration time",
"无": "None",
"无限制": "Unlimited",
......@@ -962,6 +965,7 @@
"启用突发备用号池(建议勾选,极大降低故障率)": "Enable burst backup number pool (it is recommended to check this box to greatly reduce the failure rate)",
"查看说明": "View instructions",
"添加令牌": "Create token",
"IP限制": "IP restrictions",
"令牌纬度控制 Midjouney 配置,设置优先级:令牌 > 路径参数 > 系统默认": "Token latitude controls Midjouney configuration, setting priority: token > path parameter > system default",
"启用速率限制": "Enable rate limiting",
"复制BaseURL": "Copy BaseURL",
......
......@@ -1381,7 +1381,7 @@ const Detail = (props) => {
<div className="flex items-center gap-2">
<Bell size={16} />
{t('系统公告')}
<Tag size="small" color="grey" shape="circle">
<Tag color="grey" shape="circle">
{t('显示最新20条')}
</Tag>
</div>
......
......@@ -183,7 +183,7 @@ const Setup = () => {
title={
<div className="flex items-center">
<span className="font-medium">{t('数据库警告')}</span>
<Tag color='orange' size='small' className="ml-2 !rounded-full">
<Tag color='orange' shape='circle' className="ml-2">
SQLite
</Tag>
</div>
......@@ -222,7 +222,7 @@ const Setup = () => {
title={
<div className="flex items-center">
<span className="font-medium">{t('数据库信息')}</span>
<Tag color='blue' size='small' className="ml-2 !rounded-full">
<Tag color='blue' shape='circle' className="ml-2">
MySQL
</Tag>
</div>
......@@ -256,7 +256,7 @@ const Setup = () => {
title={
<div className="flex items-center">
<span className="font-medium">{t('数据库信息')}</span>
<Tag color='green' size='small' className="ml-2 !rounded-full">
<Tag color='green' shape='circle' className="ml-2">
PostgreSQL
</Tag>
</div>
......@@ -425,7 +425,7 @@ const Setup = () => {
<div className="flex-1">
<div className="font-medium text-gray-900 mb-1">{t('对外运营模式')}</div>
<div className="text-sm text-gray-500">{t('适用于为多个用户提供服务的场景')}</div>
<Tag color='blue' size='small' className="!rounded-full mt-2">
<Tag color='blue' shape='circle' className="mt-2">
{t('默认模式')}
</Tag>
</div>
......@@ -443,7 +443,7 @@ const Setup = () => {
<div className="flex-1">
<div className="font-medium text-gray-900 mb-1">{t('自用模式')}</div>
<div className="text-sm text-gray-500">{t('适用于个人使用的场景,不需要设置模型价格')}</div>
<Tag color='green' size='small' className="!rounded-full mt-2">
<Tag color='green' shape='circle' className="mt-2">
{t('无需计费')}
</Tag>
</div>
......@@ -461,7 +461,7 @@ const Setup = () => {
<div className="flex-1">
<div className="font-medium text-gray-900 mb-1">{t('演示站点模式')}</div>
<div className="text-sm text-gray-500">{t('适用于展示系统功能的场景,提供基础功能演示')}</div>
<Tag color='purple' size='small' className="!rounded-full mt-2">
<Tag color='purple' shape='circle' className="mt-2">
{t('演示体验')}
</Tag>
</div>
......@@ -522,8 +522,8 @@ const Setup = () => {
<p>{t('默认模式,适用于为多个用户提供服务的场景。')}</p>
<p>{t('此模式下,系统将计算每次调用的用量,您需要对每个模型都设置价格,如果没有设置价格,用户将无法使用该模型。')}</p>
<div className="mt-3">
<Tag color='blue' className="!rounded-full mr-2">{t('计费模式')}</Tag>
<Tag color='blue' className="!rounded-full">{t('多用户支持')}</Tag>
<Tag color='blue' shape='circle' className="mr-2">{t('计费模式')}</Tag>
<Tag color='blue' shape='circle'>{t('多用户支持')}</Tag>
</div>
</div>
</div>
......@@ -542,8 +542,8 @@ const Setup = () => {
<p>{t('适用于个人使用的场景。')}</p>
<p>{t('不需要设置模型价格,系统将弱化用量计算,您可专注于使用模型。')}</p>
<div className="mt-3">
<Tag color='green' className="!rounded-full mr-2">{t('无需计费')}</Tag>
<Tag color='green' className="!rounded-full">{t('个人使用')}</Tag>
<Tag color='green' shape='circle' className="mr-2">{t('无需计费')}</Tag>
<Tag color='green' shape='circle'>{t('个人使用')}</Tag>
</div>
</div>
</div>
......@@ -562,8 +562,8 @@ const Setup = () => {
<p>{t('适用于展示系统功能的场景。')}</p>
<p>{t('提供基础功能演示,方便用户了解系统特性。')}</p>
<div className="mt-3">
<Tag color='purple' className="!rounded-full mr-2">{t('功能演示')}</Tag>
<Tag color='purple' className="!rounded-full">{t('体验试用')}</Tag>
<Tag color='purple' shape='circle' className="mr-2">{t('功能演示')}</Tag>
<Tag color='purple' shape='circle'>{t('体验试用')}</Tag>
</div>
</div>
</div>
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or sign in to comment