refactor(usage): switch breakdown dimension from model to route

Align with gpustack backend commits 7b57cd3b (add route dimension to
usage breakdown) and 51fd25c8 (use model_route_id as models_called):

* group_by, filters, and BreakdownItem now use the `route` dimension;
  `models` filter cascader is replaced with a flat `routes` selector
  (routes have no provider/cluster grouping).
* Tab / group_by option / column header keep the user-facing "模型 / Model"
  wording — only the underlying data dimension changed.
* Drop cluster_name / provider_type columns from the breakdown table;
  drop api_keys_used column per design.
* Fix pre-existing excel export bug in use-export-table — string
  dataIndex was lodash-joined char-by-char ("input_tokens" →
  "i_n_p_u_t..."), array dataIndex was used as a flat key against nested
  rows. Rebuilt around buildSheetMeta that emits a stable field key plus
  a formatMap using _.get(row, path) for nested values. Sheet name kept
  as `models` to match the visible column label.
This commit is contained in:
Yuxing Deng
2026-05-19 16:50:42 +08:00
parent 0274bcb8cd
commit 38107a67fe
15 changed files with 135 additions and 254 deletions
+3 -30
View File
@@ -1,15 +1,10 @@
// columns.ts
import ProviderLogo from '@/pages/maas-provider/components/provider-logo';
import { AutoTooltip } from '@gpustack/core-ui';
import { useIntl } from '@umijs/max';
import { Tag } from 'antd';
import { useMemo } from 'react';
import { BreakdownItem as ListItem } from '../config/types';
interface ColumnsHookProps {
sortOrder: string[];
}
const useModelsColumns = (): Array<{
title: string;
dataIndex: string | string[];
@@ -21,8 +16,8 @@ const useModelsColumns = (): Array<{
return [
{
title: intl.formatMessage({ id: 'common.table.name' }),
dataIndex: ['model', 'identity', 'value', 'model_name'],
key: 'model_name',
dataIndex: ['route', 'label'],
key: 'route_name',
render: (text: string, record: ListItem) => (
<span className="flex items-center">
<AutoTooltip
@@ -32,7 +27,7 @@ const useModelsColumns = (): Array<{
>
<span className="text-primary">{text}</span>
</AutoTooltip>
{record.model?.deleted && (
{record.route?.deleted && (
<Tag
style={{
marginLeft: 8,
@@ -49,28 +44,6 @@ const useModelsColumns = (): Array<{
</span>
)
},
{
title: intl.formatMessage({ id: 'usage.table.cluster' }),
dataIndex: ['model', 'identity', 'value', 'cluster_name'],
key: 'cluster_name',
render: (text: string, record: ListItem) => (
<AutoTooltip ghost>{text || '-'}</AutoTooltip>
)
},
{
title: intl.formatMessage({ id: 'usage.table.provider' }),
dataIndex: ['model', 'identity', 'value', 'provider_type'],
key: 'provider_type',
render: (text: string, record: ListItem) => (
<span className="flex-center gap-8">
<ProviderLogo provider={text || 'deployments'} />
<AutoTooltip ghost style={{ maxWidth: 400 }}>
{text ||
(!text && intl.formatMessage({ id: 'menu.models.deployment' }))}
</AutoTooltip>
</span>
)
},
{
title: intl.formatMessage({ id: 'usage.filter.inputTokens' }),
dataIndex: 'input_tokens',