🎨 refactor: TokensTable UI for clearer quota info & compact controls

• Display remaining-quota percentage instead of used-quota in the Progress indicator
  - 100 % when quota is untouched, shown in green
  - Warn at ≤ 30 % (yellow) and at ≤ 10 % (red)
  - Hide internal label (`showInfo={false}`) and move the percentage text into the Tooltip
  - Switch Progress `size` to `small` for a lighter visual footprint

• Update Tooltip to list used, remaining, total quota and the new percentage value

• Uniformly set `size="small"` on all header Buttons and Form inputs within the table
  — enhances readability and keeps the main content centered

UI/UX improvement only; no backend logic affected.
This commit is contained in:
t0ng7u
2025-07-13 01:02:55 +08:00
parent 31d82a3169
commit 9d2a56bff4
6 changed files with 59 additions and 16 deletions

View File

@@ -1234,9 +1234,7 @@ const LogsTable = () => {
<Space>
<Tag
color='blue'
size='large'
style={{
padding: 15,
fontWeight: 500,
boxShadow: '0 2px 8px rgba(0, 0, 0, 0.1)',
}}
@@ -1246,9 +1244,7 @@ const LogsTable = () => {
</Tag>
<Tag
color='pink'
size='large'
style={{
padding: 15,
fontWeight: 500,
boxShadow: '0 2px 8px rgba(0, 0, 0, 0.1)',
}}
@@ -1258,9 +1254,7 @@ const LogsTable = () => {
</Tag>
<Tag
color='white'
size='large'
style={{
padding: 15,
border: 'none',
boxShadow: '0 2px 8px rgba(0, 0, 0, 0.1)',
fontWeight: 500,
@@ -1276,6 +1270,7 @@ const LogsTable = () => {
type='secondary'
className="w-full md:w-auto"
onClick={() => setCompactMode(!compactMode)}
size="small"
>
{compactMode ? t('自适应列表') : t('紧凑列表')}
</Button>
@@ -1306,6 +1301,7 @@ const LogsTable = () => {
placeholder={[t('开始时间'), t('结束时间')]}
showClear
pure
size="small"
/>
</div>
@@ -1316,6 +1312,7 @@ const LogsTable = () => {
placeholder={t('令牌名称')}
showClear
pure
size="small"
/>
<Form.Input
@@ -1324,6 +1321,7 @@ const LogsTable = () => {
placeholder={t('模型名称')}
showClear
pure
size="small"
/>
<Form.Input
@@ -1332,6 +1330,7 @@ const LogsTable = () => {
placeholder={t('分组')}
showClear
pure
size="small"
/>
{isAdminUser && (
@@ -1342,6 +1341,7 @@ const LogsTable = () => {
placeholder={t('渠道 ID')}
showClear
pure
size="small"
/>
<Form.Input
field='username'
@@ -1349,6 +1349,7 @@ const LogsTable = () => {
placeholder={t('用户名称')}
showClear
pure
size="small"
/>
</>
)}
@@ -1370,6 +1371,7 @@ const LogsTable = () => {
refresh();
}, 0);
}}
size="small"
>
<Form.Select.Option value='0'>
{t('全部')}
@@ -1397,6 +1399,7 @@ const LogsTable = () => {
type='primary'
htmlType='submit'
loading={loading}
size="small"
>
{t('查询')}
</Button>
@@ -1411,6 +1414,7 @@ const LogsTable = () => {
}, 100);
}
}}
size="small"
>
{t('重置')}
</Button>
@@ -1418,6 +1422,7 @@ const LogsTable = () => {
theme='light'
type='tertiary'
onClick={() => setShowColumnSelector(true)}
size="small"
>
{t('列设置')}
</Button>

View File

@@ -522,6 +522,7 @@ const LogsTable = () => {
}
return (
<Button
size="small"
onClick={() => {
setModalImageUrl(text);
setIsModalOpenurl(true);
@@ -834,6 +835,7 @@ const LogsTable = () => {
type='secondary'
className="w-full md:w-auto"
onClick={() => setCompactMode(!compactMode)}
size="small"
>
{compactMode ? t('自适应列表') : t('紧凑列表')}
</Button>
@@ -863,6 +865,7 @@ const LogsTable = () => {
placeholder={[t('开始时间'), t('结束时间')]}
showClear
pure
size="small"
/>
</div>
@@ -873,6 +876,7 @@ const LogsTable = () => {
placeholder={t('任务 ID')}
showClear
pure
size="small"
/>
{/* 渠道 ID - 仅管理员可见 */}
@@ -883,6 +887,7 @@ const LogsTable = () => {
placeholder={t('渠道 ID')}
showClear
pure
size="small"
/>
)}
</div>
@@ -895,6 +900,7 @@ const LogsTable = () => {
type='primary'
htmlType='submit'
loading={loading}
size="small"
>
{t('查询')}
</Button>
@@ -909,6 +915,7 @@ const LogsTable = () => {
}, 100);
}
}}
size="small"
>
{t('重置')}
</Button>
@@ -916,6 +923,7 @@ const LogsTable = () => {
theme='light'
type='tertiary'
onClick={() => setShowColumnSelector(true)}
size="small"
>
{t('列设置')}
</Button>

View File

@@ -428,6 +428,7 @@ const RedemptionsTable = () => {
type='secondary'
className="w-full md:w-auto"
onClick={() => setCompactMode(!compactMode)}
size="small"
>
{compactMode ? t('自适应列表') : t('紧凑列表')}
</Button>
@@ -449,6 +450,7 @@ const RedemptionsTable = () => {
});
setShowEdit(true);
}}
size="small"
>
{t('添加兑换码')}
</Button>
@@ -467,6 +469,7 @@ const RedemptionsTable = () => {
}
await copyText(keys);
}}
size="small"
>
{t('复制所选兑换码到剪贴板')}
</Button>
@@ -492,6 +495,7 @@ const RedemptionsTable = () => {
},
});
}}
size="small"
>
{t('清除失效兑换码')}
</Button>
@@ -519,6 +523,7 @@ const RedemptionsTable = () => {
placeholder={t('关键字(id或者名称)')}
showClear
pure
size="small"
/>
</div>
<div className="flex gap-2 w-full md:w-auto">
@@ -527,6 +532,7 @@ const RedemptionsTable = () => {
htmlType="submit"
loading={loading || searching}
className="flex-1 md:flex-initial md:w-auto"
size="small"
>
{t('查询')}
</Button>
@@ -543,6 +549,7 @@ const RedemptionsTable = () => {
}
}}
className="flex-1 md:flex-initial md:w-auto"
size="small"
>
{t('重置')}
</Button>

View File

@@ -682,6 +682,7 @@ const LogsTable = () => {
type='secondary'
className="w-full md:w-auto"
onClick={() => setCompactMode(!compactMode)}
size="small"
>
{compactMode ? t('自适应列表') : t('紧凑列表')}
</Button>
@@ -711,6 +712,7 @@ const LogsTable = () => {
placeholder={[t('开始时间'), t('结束时间')]}
showClear
pure
size="small"
/>
</div>
@@ -721,6 +723,7 @@ const LogsTable = () => {
placeholder={t('任务 ID')}
showClear
pure
size="small"
/>
{/* 渠道 ID - 仅管理员可见 */}
@@ -731,6 +734,7 @@ const LogsTable = () => {
placeholder={t('渠道 ID')}
showClear
pure
size="small"
/>
)}
</div>
@@ -743,6 +747,7 @@ const LogsTable = () => {
type='primary'
htmlType='submit'
loading={loading}
size="small"
>
{t('查询')}
</Button>
@@ -757,6 +762,7 @@ const LogsTable = () => {
}, 100);
}
}}
size="small"
>
{t('重置')}
</Button>
@@ -764,6 +770,7 @@ const LogsTable = () => {
theme='light'
type='tertiary'
onClick={() => setShowColumnSelector(true)}
size="small"
>
{t('列设置')}
</Button>

View File

@@ -132,7 +132,7 @@ const TokensTable = () => {
key: 'token_key',
render: (text, record) => {
const fullKey = 'sk-' + record.key;
const maskedKey = 'sk-' + record.key.slice(0, 3) + '********' + record.key.slice(-3);
const maskedKey = 'sk-' + record.key.slice(0, 4) + '**********' + record.key.slice(-4);
const revealed = !!showKeys[record.id];
return (
@@ -173,7 +173,7 @@ const TokensTable = () => {
},
},
{
title: t('额度'),
title: t('剩余额度'),
key: 'quota',
render: (text, record) => {
if (record.unlimited_quota) {
@@ -183,12 +183,15 @@ const TokensTable = () => {
const used = parseInt(record.used_quota) || 0;
const remain = parseInt(record.remain_quota) || 0;
const total = used + remain;
const percent = total > 0 ? (used / total) * 100 : 0;
// 计算剩余额度百分比100% 表示额度未使用
const percent = total > 0 ? (remain / total) * 100 : 0;
// 根据剩余百分比动态设置颜色100% 绿色,<=10% 红色,<=30% 黄色,其余默认
const getProgressColor = (pct) => {
if (pct >= 90) return 'var(--semi-color-danger)';
if (pct >= 70) return 'var(--semi-color-warning)';
return undefined; // default color
if (pct === 100) return 'var(--semi-color-success)';
if (pct <= 10) return 'var(--semi-color-danger)';
if (pct <= 30) return 'var(--semi-color-warning)';
return undefined; // 默认颜色
};
return (
@@ -196,7 +199,7 @@ const TokensTable = () => {
content={
<div className='text-xs'>
<div>{t('已用额度')}: {renderQuota(used)}</div>
<div>{t('剩余额度')}: {renderQuota(remain)}</div>
<div>{t('剩余额度')}: {renderQuota(remain)} ({percent.toFixed(0)}%)</div>
<div>{t('总额度')}: {renderQuota(total)}</div>
</div>
}
@@ -205,11 +208,10 @@ const TokensTable = () => {
<Progress
percent={percent}
stroke={getProgressColor(percent)}
showInfo
showInfo={false}
aria-label='quota usage'
format={percent => <span className="text-xs">{percent.toFixed(0)}%</span>}
type="circle"
width={30}
size='small'
/>
</div>
</Tooltip>
@@ -698,6 +700,7 @@ const TokensTable = () => {
type="secondary"
className="w-full md:w-auto"
onClick={() => setCompactMode(!compactMode)}
size="small"
>
{compactMode ? t('自适应列表') : t('紧凑列表')}
</Button>
@@ -718,6 +721,7 @@ const TokensTable = () => {
});
setShowEdit(true);
}}
size="small"
>
{t('添加令牌')}
</Button>
@@ -768,6 +772,7 @@ const TokensTable = () => {
),
});
}}
size="small"
>
{t('复制所选令牌')}
</Button>
@@ -790,6 +795,7 @@ const TokensTable = () => {
onOk: () => batchDeleteTokens(),
});
}}
size="small"
>
{t('删除所选令牌')}
</Button>
@@ -814,6 +820,7 @@ const TokensTable = () => {
placeholder={t('搜索关键字')}
showClear
pure
size="small"
/>
</div>
<div className="relative w-full md:w-56">
@@ -823,6 +830,7 @@ const TokensTable = () => {
placeholder={t('密钥')}
showClear
pure
size="small"
/>
</div>
<div className="flex gap-2 w-full md:w-auto">
@@ -831,6 +839,7 @@ const TokensTable = () => {
htmlType="submit"
loading={loading || searching}
className="flex-1 md:flex-initial md:w-auto"
size="small"
>
{t('查询')}
</Button>
@@ -846,6 +855,7 @@ const TokensTable = () => {
}
}}
className="flex-1 md:flex-initial md:w-auto"
size="small"
>
{t('重置')}
</Button>

View File

@@ -524,6 +524,7 @@ const UsersTable = () => {
type='secondary'
className="w-full md:w-auto"
onClick={() => setCompactMode(!compactMode)}
size="small"
>
{compactMode ? t('自适应列表') : t('紧凑列表')}
</Button>
@@ -541,6 +542,7 @@ const UsersTable = () => {
onClick={() => {
setShowAddUser(true);
}}
size="small"
>
{t('添加用户')}
</Button>
@@ -568,6 +570,7 @@ const UsersTable = () => {
placeholder={t('支持搜索用户的 ID、用户名、显示名称和邮箱地址')}
showClear
pure
size="small"
/>
</div>
<div className="w-full md:w-48">
@@ -585,6 +588,7 @@ const UsersTable = () => {
className="w-full"
showClear
pure
size="small"
/>
</div>
<div className="flex gap-2 w-full md:w-auto">
@@ -593,6 +597,7 @@ const UsersTable = () => {
htmlType="submit"
loading={loading || searching}
className="flex-1 md:flex-initial md:w-auto"
size="small"
>
{t('查询')}
</Button>
@@ -609,6 +614,7 @@ const UsersTable = () => {
}
}}
className="flex-1 md:flex-initial md:w-auto"
size="small"
>
{t('重置')}
</Button>