feat(web): refresh rate limits timestamp and tpm settlement display

This commit is contained in:
2026-05-12 03:43:00 +08:00
parent b609640a9f
commit d69aaed444
4 changed files with 47 additions and 21 deletions
+4 -3
View File
@@ -137,9 +137,10 @@ export function AdminPage(props: {
<PlatformManagementPanel
baseModels={props.data.baseModels}
message={props.operationMessage}
networkProxyConfig={props.data.networkProxyConfig}
modelRateLimits={props.data.modelRateLimits}
platformModels={props.data.models}
networkProxyConfig={props.data.networkProxyConfig}
modelRateLimits={props.data.modelRateLimits}
modelRateLimitsUpdatedAt={props.data.modelRateLimitsUpdatedAt}
platformModels={props.data.models}
platforms={props.data.platforms}
pricingRuleSets={props.data.pricingRuleSets}
providers={props.data.providers}
@@ -22,9 +22,10 @@ import { ModelCatalogCard } from './ModelCatalogCard';
export function PlatformManagementPanel(props: {
baseModels: BaseModelCatalogItem[];
message: string;
modelRateLimits: ModelRateLimitStatus[];
networkProxyConfig: { globalHttpProxy?: string; globalHttpProxySet: boolean; globalHttpProxySource?: string } | null;
message: string;
modelRateLimits: ModelRateLimitStatus[];
modelRateLimitsUpdatedAt: number | null;
networkProxyConfig: { globalHttpProxy?: string; globalHttpProxySet: boolean; globalHttpProxySource?: string } | null;
platforms: IntegrationPlatform[];
platformModels: PlatformModel[];
pricingRuleSets: PricingRuleSet[];
@@ -200,11 +201,16 @@ export function PlatformManagementPanel(props: {
providerMap={providerMap}
onModelQueryChange={setModelQuery}
now={now}
onPlatformChange={setSelectedPlatformId}
/>
) : (
<RateLimitStatusTable statuses={props.modelRateLimits} platformMap={platformMap} now={now} />
)}
onPlatformChange={setSelectedPlatformId}
/>
) : (
<RateLimitStatusTable
now={now}
platformMap={platformMap}
statuses={props.modelRateLimits}
updatedAt={props.modelRateLimitsUpdatedAt}
/>
)}
{props.message && <p className="formMessage">{props.message}</p>}
</CardContent>
</Card>
@@ -572,7 +578,7 @@ function PlatformModelTable(props: {
);
}
function RateLimitStatusTable(props: { statuses: ModelRateLimitStatus[]; platformMap: Map<string, IntegrationPlatform>; now: number }) {
function RateLimitStatusTable(props: { statuses: ModelRateLimitStatus[]; platformMap: Map<string, IntegrationPlatform>; now: number; updatedAt: number | null }) {
if (!props.statuses.length) {
return <EmptyState title="暂无限流状态" description="模型产生请求后会在这里显示实时 RPM、TPM 和并发窗口。" />;
}
@@ -580,7 +586,7 @@ function RateLimitStatusTable(props: { statuses: ModelRateLimitStatus[]; platfor
<section className="platformLimitView">
<div className="platformLimitHeader">
<span><Gauge size={15} /></span>
<small> 3 TPM + </small>
<small> 3 TPM + {formatTimeOfDay(props.updatedAt)}</small>
</div>
<div className="platformLimitTableViewport">
<Table className="platformDataTable platformLimitTable">
@@ -1195,15 +1201,26 @@ function rateLimitMetricText(metric: string) {
}
function metricCell(metric: ModelRateLimitStatus['rpm'], includeReserved = false) {
if (!metric.limited) return <span className="rateMetricCell"><strong>{formatLimit(metric.currentValue)} / </strong><small></small></span>;
if (!metric.limited) return <span className="rateMetricCell"><strong>{formatLimit(metric.currentValue)} / </strong><small>{includeReserved ? reservedMetricText(metric) : '未配置上限'}</small></span>;
return (
<span className="rateMetricCell">
<strong>{formatLimit(metric.currentValue)} / {formatLimit(metric.limitValue)}</strong>
<small>{includeReserved && metric.reservedValue > 0 ? `已用 ${formatLimit(metric.usedValue)} · 预占 ${formatLimit(metric.reservedValue)}` : `窗口 ${formatPercent(metric.ratio)}`}</small>
<small>{includeReserved ? reservedMetricText(metric) : `窗口 ${formatPercent(metric.ratio)}`}</small>
</span>
);
}
function reservedMetricText(metric: ModelRateLimitStatus['rpm']) {
return `已结算 ${formatLimit(metric.usedValue)} + 预占 ${formatLimit(metric.reservedValue)}`;
}
function formatTimeOfDay(timestamp: number | null) {
if (!timestamp) return '暂无';
const date = new Date(timestamp);
const pad = (value: number) => String(value).padStart(2, '0');
return `${pad(date.getHours())}:${pad(date.getMinutes())}:${pad(date.getSeconds())}`;
}
function modelRuntimeStatusCell(status: ModelRateLimitStatus, now: number) {
const modelCooldownMs = cooldownRemainingMs(status.modelCooldownUntil, now);
const platformCooldownMs = cooldownRemainingMs(status.platformCooldownUntil, now);