feat(usage): add account cost to breakdown sub-table and admin usage log
- UserBreakdownItem: add AccountCost field + SQL aggregation - UserBreakdownSubTable: add orange account cost column - Admin usage table: add account_cost column (after cost, default visible) - Column settings: add account_cost toggle option
This commit is contained in:
@@ -168,8 +168,9 @@ type UserBreakdownItem struct {
|
||||
Email string `json:"email"`
|
||||
Requests int64 `json:"requests"`
|
||||
TotalTokens int64 `json:"total_tokens"`
|
||||
Cost float64 `json:"cost"` // 标准计费
|
||||
ActualCost float64 `json:"actual_cost"` // 实际扣除
|
||||
Cost float64 `json:"cost"` // 标准计费
|
||||
ActualCost float64 `json:"actual_cost"` // 实际扣除
|
||||
AccountCost float64 `json:"account_cost"` // 账号成本
|
||||
}
|
||||
|
||||
// UserBreakdownDimension specifies the dimension to filter for user breakdown.
|
||||
|
||||
@@ -3157,7 +3157,8 @@ func (r *usageLogRepository) GetUserBreakdownStats(ctx context.Context, startTim
|
||||
COUNT(*) as requests,
|
||||
COALESCE(SUM(ul.input_tokens + ul.output_tokens + ul.cache_creation_tokens + ul.cache_read_tokens), 0) as total_tokens,
|
||||
COALESCE(SUM(ul.total_cost), 0) as cost,
|
||||
COALESCE(SUM(ul.actual_cost), 0) as actual_cost
|
||||
COALESCE(SUM(ul.actual_cost), 0) as actual_cost,
|
||||
COALESCE(SUM(COALESCE(ul.account_stats_cost, ul.total_cost) * COALESCE(ul.account_rate_multiplier, 1)), 0) as account_cost
|
||||
FROM usage_logs ul
|
||||
LEFT JOIN users u ON u.id = ul.user_id
|
||||
WHERE ul.created_at >= $1 AND ul.created_at < $2
|
||||
@@ -3228,6 +3229,7 @@ func (r *usageLogRepository) GetUserBreakdownStats(ctx context.Context, startTim
|
||||
&row.TotalTokens,
|
||||
&row.Cost,
|
||||
&row.ActualCost,
|
||||
&row.AccountCost,
|
||||
); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
@@ -160,6 +160,12 @@
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<template #cell-account_cost="{ row }">
|
||||
<span class="text-sm font-medium text-orange-500 dark:text-orange-400">
|
||||
${{ accountBilled(row).toFixed(6) }}
|
||||
</span>
|
||||
</template>
|
||||
|
||||
<template #cell-first_token="{ row }">
|
||||
<span v-if="row.first_token_ms != null" class="text-sm text-gray-600 dark:text-gray-400">{{ formatDuration(row.first_token_ms) }}</span>
|
||||
<span v-else class="text-sm text-gray-400 dark:text-gray-500">-</span>
|
||||
|
||||
@@ -25,6 +25,9 @@
|
||||
<td class="py-1 text-right text-green-600 dark:text-green-400">
|
||||
${{ formatCost(user.actual_cost) }}
|
||||
</td>
|
||||
<td class="py-1 text-right text-orange-500 dark:text-orange-400">
|
||||
${{ formatCost(user.account_cost) }}
|
||||
</td>
|
||||
<td class="py-1 pr-1 text-right text-gray-400 dark:text-gray-500">
|
||||
${{ formatCost(user.cost) }}
|
||||
</td>
|
||||
|
||||
@@ -1245,6 +1245,7 @@ export interface UserBreakdownItem {
|
||||
total_tokens: number
|
||||
cost: number
|
||||
actual_cost: number
|
||||
account_cost: number
|
||||
}
|
||||
|
||||
export interface UserUsageTrendPoint {
|
||||
|
||||
@@ -533,6 +533,7 @@ const allColumns = computed(() => [
|
||||
{ key: 'billing_mode', label: t('admin.usage.billingMode'), sortable: false },
|
||||
{ key: 'tokens', label: t('usage.tokens'), sortable: false },
|
||||
{ key: 'cost', label: t('usage.cost'), sortable: false },
|
||||
{ key: 'account_cost', label: t('usage.accountCost'), sortable: false },
|
||||
{ key: 'first_token', label: t('usage.firstToken'), sortable: false },
|
||||
{ key: 'duration', label: t('usage.duration'), sortable: false },
|
||||
{ key: 'created_at', label: t('usage.time'), sortable: true },
|
||||
|
||||
Reference in New Issue
Block a user