Skip to content
GitLab
Menu
Projects
Groups
Snippets
Loading...
Help
Help
Support
Community forum
Keyboard shortcuts
?
Submit feedback
Sign in / Register
Toggle navigation
Menu
Open sidebar
陈曦
sub2api
Commits
33bae6f4
Commit
33bae6f4
authored
Mar 05, 2026
by
shaw
Browse files
fix: Cache Token拆分为缓存创建和缓存读取
parent
32d619a5
Changes
9
Show whitespace changes
Inline
Side-by-side
backend/internal/pkg/usagestats/usage_log_types.go
View file @
33bae6f4
...
@@ -61,7 +61,8 @@ type TrendDataPoint struct {
...
@@ -61,7 +61,8 @@ type TrendDataPoint struct {
Requests
int64
`json:"requests"`
Requests
int64
`json:"requests"`
InputTokens
int64
`json:"input_tokens"`
InputTokens
int64
`json:"input_tokens"`
OutputTokens
int64
`json:"output_tokens"`
OutputTokens
int64
`json:"output_tokens"`
CacheTokens
int64
`json:"cache_tokens"`
CacheCreationTokens
int64
`json:"cache_creation_tokens"`
CacheReadTokens
int64
`json:"cache_read_tokens"`
TotalTokens
int64
`json:"total_tokens"`
TotalTokens
int64
`json:"total_tokens"`
Cost
float64
`json:"cost"`
// 标准计费
Cost
float64
`json:"cost"`
// 标准计费
ActualCost
float64
`json:"actual_cost"`
// 实际扣除
ActualCost
float64
`json:"actual_cost"`
// 实际扣除
...
@@ -73,6 +74,8 @@ type ModelStat struct {
...
@@ -73,6 +74,8 @@ type ModelStat struct {
Requests
int64
`json:"requests"`
Requests
int64
`json:"requests"`
InputTokens
int64
`json:"input_tokens"`
InputTokens
int64
`json:"input_tokens"`
OutputTokens
int64
`json:"output_tokens"`
OutputTokens
int64
`json:"output_tokens"`
CacheCreationTokens
int64
`json:"cache_creation_tokens"`
CacheReadTokens
int64
`json:"cache_read_tokens"`
TotalTokens
int64
`json:"total_tokens"`
TotalTokens
int64
`json:"total_tokens"`
Cost
float64
`json:"cost"`
// 标准计费
Cost
float64
`json:"cost"`
// 标准计费
ActualCost
float64
`json:"actual_cost"`
// 实际扣除
ActualCost
float64
`json:"actual_cost"`
// 实际扣除
...
...
backend/internal/repository/usage_log_repo.go
View file @
33bae6f4
...
@@ -1363,7 +1363,8 @@ func (r *usageLogRepository) GetUserUsageTrendByUserID(ctx context.Context, user
...
@@ -1363,7 +1363,8 @@ func (r *usageLogRepository) GetUserUsageTrendByUserID(ctx context.Context, user
COUNT(*) as requests,
COUNT(*) as requests,
COALESCE(SUM(input_tokens), 0) as input_tokens,
COALESCE(SUM(input_tokens), 0) as input_tokens,
COALESCE(SUM(output_tokens), 0) as output_tokens,
COALESCE(SUM(output_tokens), 0) as output_tokens,
COALESCE(SUM(cache_creation_tokens + cache_read_tokens), 0) as cache_tokens,
COALESCE(SUM(cache_creation_tokens), 0) as cache_creation_tokens,
COALESCE(SUM(cache_read_tokens), 0) as cache_read_tokens,
COALESCE(SUM(input_tokens + output_tokens + cache_creation_tokens + cache_read_tokens), 0) as total_tokens,
COALESCE(SUM(input_tokens + output_tokens + cache_creation_tokens + cache_read_tokens), 0) as total_tokens,
COALESCE(SUM(total_cost), 0) as cost,
COALESCE(SUM(total_cost), 0) as cost,
COALESCE(SUM(actual_cost), 0) as actual_cost
COALESCE(SUM(actual_cost), 0) as actual_cost
...
@@ -1401,6 +1402,8 @@ func (r *usageLogRepository) GetUserModelStats(ctx context.Context, userID int64
...
@@ -1401,6 +1402,8 @@ func (r *usageLogRepository) GetUserModelStats(ctx context.Context, userID int64
COUNT(*) as requests,
COUNT(*) as requests,
COALESCE(SUM(input_tokens), 0) as input_tokens,
COALESCE(SUM(input_tokens), 0) as input_tokens,
COALESCE(SUM(output_tokens), 0) as output_tokens,
COALESCE(SUM(output_tokens), 0) as output_tokens,
COALESCE(SUM(cache_creation_tokens), 0) as cache_creation_tokens,
COALESCE(SUM(cache_read_tokens), 0) as cache_read_tokens,
COALESCE(SUM(input_tokens + output_tokens + cache_creation_tokens + cache_read_tokens), 0) as total_tokens,
COALESCE(SUM(input_tokens + output_tokens + cache_creation_tokens + cache_read_tokens), 0) as total_tokens,
COALESCE(SUM(total_cost), 0) as cost,
COALESCE(SUM(total_cost), 0) as cost,
COALESCE(SUM(actual_cost), 0) as actual_cost
COALESCE(SUM(actual_cost), 0) as actual_cost
...
@@ -1664,7 +1667,8 @@ func (r *usageLogRepository) GetUsageTrendWithFilters(ctx context.Context, start
...
@@ -1664,7 +1667,8 @@ func (r *usageLogRepository) GetUsageTrendWithFilters(ctx context.Context, start
COUNT(*) as requests,
COUNT(*) as requests,
COALESCE(SUM(input_tokens), 0) as input_tokens,
COALESCE(SUM(input_tokens), 0) as input_tokens,
COALESCE(SUM(output_tokens), 0) as output_tokens,
COALESCE(SUM(output_tokens), 0) as output_tokens,
COALESCE(SUM(cache_creation_tokens + cache_read_tokens), 0) as cache_tokens,
COALESCE(SUM(cache_creation_tokens), 0) as cache_creation_tokens,
COALESCE(SUM(cache_read_tokens), 0) as cache_read_tokens,
COALESCE(SUM(input_tokens + output_tokens + cache_creation_tokens + cache_read_tokens), 0) as total_tokens,
COALESCE(SUM(input_tokens + output_tokens + cache_creation_tokens + cache_read_tokens), 0) as total_tokens,
COALESCE(SUM(total_cost), 0) as cost,
COALESCE(SUM(total_cost), 0) as cost,
COALESCE(SUM(actual_cost), 0) as actual_cost
COALESCE(SUM(actual_cost), 0) as actual_cost
...
@@ -1747,7 +1751,8 @@ func (r *usageLogRepository) getUsageTrendFromAggregates(ctx context.Context, st
...
@@ -1747,7 +1751,8 @@ func (r *usageLogRepository) getUsageTrendFromAggregates(ctx context.Context, st
total_requests as requests,
total_requests as requests,
input_tokens,
input_tokens,
output_tokens,
output_tokens,
(cache_creation_tokens + cache_read_tokens) as cache_tokens,
cache_creation_tokens,
cache_read_tokens,
(input_tokens + output_tokens + cache_creation_tokens + cache_read_tokens) as total_tokens,
(input_tokens + output_tokens + cache_creation_tokens + cache_read_tokens) as total_tokens,
total_cost as cost,
total_cost as cost,
actual_cost
actual_cost
...
@@ -1762,7 +1767,8 @@ func (r *usageLogRepository) getUsageTrendFromAggregates(ctx context.Context, st
...
@@ -1762,7 +1767,8 @@ func (r *usageLogRepository) getUsageTrendFromAggregates(ctx context.Context, st
total_requests as requests,
total_requests as requests,
input_tokens,
input_tokens,
output_tokens,
output_tokens,
(cache_creation_tokens + cache_read_tokens) as cache_tokens,
cache_creation_tokens,
cache_read_tokens,
(input_tokens + output_tokens + cache_creation_tokens + cache_read_tokens) as total_tokens,
(input_tokens + output_tokens + cache_creation_tokens + cache_read_tokens) as total_tokens,
total_cost as cost,
total_cost as cost,
actual_cost
actual_cost
...
@@ -1806,6 +1812,8 @@ func (r *usageLogRepository) GetModelStatsWithFilters(ctx context.Context, start
...
@@ -1806,6 +1812,8 @@ func (r *usageLogRepository) GetModelStatsWithFilters(ctx context.Context, start
COUNT(*) as requests,
COUNT(*) as requests,
COALESCE(SUM(input_tokens), 0) as input_tokens,
COALESCE(SUM(input_tokens), 0) as input_tokens,
COALESCE(SUM(output_tokens), 0) as output_tokens,
COALESCE(SUM(output_tokens), 0) as output_tokens,
COALESCE(SUM(cache_creation_tokens), 0) as cache_creation_tokens,
COALESCE(SUM(cache_read_tokens), 0) as cache_read_tokens,
COALESCE(SUM(input_tokens + output_tokens + cache_creation_tokens + cache_read_tokens), 0) as total_tokens,
COALESCE(SUM(input_tokens + output_tokens + cache_creation_tokens + cache_read_tokens), 0) as total_tokens,
COALESCE(SUM(total_cost), 0) as cost,
COALESCE(SUM(total_cost), 0) as cost,
%s
%s
...
@@ -2622,7 +2630,8 @@ func scanTrendRows(rows *sql.Rows) ([]TrendDataPoint, error) {
...
@@ -2622,7 +2630,8 @@ func scanTrendRows(rows *sql.Rows) ([]TrendDataPoint, error) {
&
row
.
Requests
,
&
row
.
Requests
,
&
row
.
InputTokens
,
&
row
.
InputTokens
,
&
row
.
OutputTokens
,
&
row
.
OutputTokens
,
&
row
.
CacheTokens
,
&
row
.
CacheCreationTokens
,
&
row
.
CacheReadTokens
,
&
row
.
TotalTokens
,
&
row
.
TotalTokens
,
&
row
.
Cost
,
&
row
.
Cost
,
&
row
.
ActualCost
,
&
row
.
ActualCost
,
...
@@ -2646,6 +2655,8 @@ func scanModelStatsRows(rows *sql.Rows) ([]ModelStat, error) {
...
@@ -2646,6 +2655,8 @@ func scanModelStatsRows(rows *sql.Rows) ([]ModelStat, error) {
&
row
.
Requests
,
&
row
.
Requests
,
&
row
.
InputTokens
,
&
row
.
InputTokens
,
&
row
.
OutputTokens
,
&
row
.
OutputTokens
,
&
row
.
CacheCreationTokens
,
&
row
.
CacheReadTokens
,
&
row
.
TotalTokens
,
&
row
.
TotalTokens
,
&
row
.
Cost
,
&
row
.
Cost
,
&
row
.
ActualCost
,
&
row
.
ActualCost
,
...
...
backend/internal/repository/usage_log_repo_request_type_test.go
View file @
33bae6f4
...
@@ -125,7 +125,7 @@ func TestUsageLogRepositoryGetUsageTrendWithFiltersRequestTypePriority(t *testin
...
@@ -125,7 +125,7 @@ func TestUsageLogRepositoryGetUsageTrendWithFiltersRequestTypePriority(t *testin
mock
.
ExpectQuery
(
"AND
\\
(request_type =
\\
$3 OR
\\
(request_type = 0 AND stream = TRUE AND openai_ws_mode = FALSE
\\
)
\\
)"
)
.
mock
.
ExpectQuery
(
"AND
\\
(request_type =
\\
$3 OR
\\
(request_type = 0 AND stream = TRUE AND openai_ws_mode = FALSE
\\
)
\\
)"
)
.
WithArgs
(
start
,
end
,
requestType
)
.
WithArgs
(
start
,
end
,
requestType
)
.
WillReturnRows
(
sqlmock
.
NewRows
([]
string
{
"date"
,
"requests"
,
"input_tokens"
,
"output_tokens"
,
"cache_tokens"
,
"total_tokens"
,
"cost"
,
"actual_cost"
}))
WillReturnRows
(
sqlmock
.
NewRows
([]
string
{
"date"
,
"requests"
,
"input_tokens"
,
"output_tokens"
,
"cache_
creation_tokens"
,
"cache_read_
tokens"
,
"total_tokens"
,
"cost"
,
"actual_cost"
}))
trend
,
err
:=
repo
.
GetUsageTrendWithFilters
(
context
.
Background
(),
start
,
end
,
"day"
,
0
,
0
,
0
,
0
,
""
,
&
requestType
,
&
stream
,
nil
)
trend
,
err
:=
repo
.
GetUsageTrendWithFilters
(
context
.
Background
(),
start
,
end
,
"day"
,
0
,
0
,
0
,
0
,
""
,
&
requestType
,
&
stream
,
nil
)
require
.
NoError
(
t
,
err
)
require
.
NoError
(
t
,
err
)
...
@@ -144,7 +144,7 @@ func TestUsageLogRepositoryGetModelStatsWithFiltersRequestTypePriority(t *testin
...
@@ -144,7 +144,7 @@ func TestUsageLogRepositoryGetModelStatsWithFiltersRequestTypePriority(t *testin
mock
.
ExpectQuery
(
"AND
\\
(request_type =
\\
$3 OR
\\
(request_type = 0 AND openai_ws_mode = TRUE
\\
)
\\
)"
)
.
mock
.
ExpectQuery
(
"AND
\\
(request_type =
\\
$3 OR
\\
(request_type = 0 AND openai_ws_mode = TRUE
\\
)
\\
)"
)
.
WithArgs
(
start
,
end
,
requestType
)
.
WithArgs
(
start
,
end
,
requestType
)
.
WillReturnRows
(
sqlmock
.
NewRows
([]
string
{
"model"
,
"requests"
,
"input_tokens"
,
"output_tokens"
,
"total_tokens"
,
"cost"
,
"actual_cost"
}))
WillReturnRows
(
sqlmock
.
NewRows
([]
string
{
"model"
,
"requests"
,
"input_tokens"
,
"output_tokens"
,
"cache_creation_tokens"
,
"cache_read_tokens"
,
"total_tokens"
,
"cost"
,
"actual_cost"
}))
stats
,
err
:=
repo
.
GetModelStatsWithFilters
(
context
.
Background
(),
start
,
end
,
0
,
0
,
0
,
0
,
&
requestType
,
&
stream
,
nil
)
stats
,
err
:=
repo
.
GetModelStatsWithFilters
(
context
.
Background
(),
start
,
end
,
0
,
0
,
0
,
0
,
&
requestType
,
&
stream
,
nil
)
require
.
NoError
(
t
,
err
)
require
.
NoError
(
t
,
err
)
...
...
frontend/src/components/charts/TokenUsageTrend.vue
View file @
33bae6f4
...
@@ -63,7 +63,8 @@ const chartColors = computed(() => ({
...
@@ -63,7 +63,8 @@ const chartColors = computed(() => ({
grid
:
isDarkMode
.
value
?
'
#374151
'
:
'
#e5e7eb
'
,
grid
:
isDarkMode
.
value
?
'
#374151
'
:
'
#e5e7eb
'
,
input
:
'
#3b82f6
'
,
input
:
'
#3b82f6
'
,
output
:
'
#10b981
'
,
output
:
'
#10b981
'
,
cache
:
'
#f59e0b
'
cacheCreation
:
'
#f59e0b
'
,
cacheRead
:
'
#06b6d4
'
}))
}))
const
chartData
=
computed
(()
=>
{
const
chartData
=
computed
(()
=>
{
...
@@ -89,10 +90,18 @@ const chartData = computed(() => {
...
@@ -89,10 +90,18 @@ const chartData = computed(() => {
tension
:
0.3
tension
:
0.3
},
},
{
{
label
:
'
Cache
'
,
label
:
'
Cache Creation
'
,
data
:
props
.
trendData
.
map
((
d
)
=>
d
.
cache_tokens
),
data
:
props
.
trendData
.
map
((
d
)
=>
d
.
cache_creation_tokens
),
borderColor
:
chartColors
.
value
.
cache
,
borderColor
:
chartColors
.
value
.
cacheCreation
,
backgroundColor
:
`
${
chartColors
.
value
.
cache
}
20`
,
backgroundColor
:
`
${
chartColors
.
value
.
cacheCreation
}
20`
,
fill
:
true
,
tension
:
0.3
},
{
label
:
'
Cache Read
'
,
data
:
props
.
trendData
.
map
((
d
)
=>
d
.
cache_read_tokens
),
borderColor
:
chartColors
.
value
.
cacheRead
,
backgroundColor
:
`
${
chartColors
.
value
.
cacheRead
}
20`
,
fill
:
true
,
fill
:
true
,
tension
:
0.3
tension
:
0.3
}
}
...
...
frontend/src/i18n/locales/en.ts
View file @
33bae6f4
...
@@ -133,6 +133,8 @@ export default {
...
@@ -133,6 +133,8 @@ export default {
requests
:
'
Requests
'
,
requests
:
'
Requests
'
,
inputTokens
:
'
Input Tokens
'
,
inputTokens
:
'
Input Tokens
'
,
outputTokens
:
'
Output Tokens
'
,
outputTokens
:
'
Output Tokens
'
,
cacheCreationTokens
:
'
Cache Creation
'
,
cacheReadTokens
:
'
Cache Read
'
,
totalTokens
:
'
Total Tokens
'
,
totalTokens
:
'
Total Tokens
'
,
cost
:
'
Cost
'
,
cost
:
'
Cost
'
,
// Status
// Status
...
@@ -155,11 +157,19 @@ export default {
...
@@ -155,11 +157,19 @@ export default {
subscriptionExpires
:
'
Subscription Expires
'
,
subscriptionExpires
:
'
Subscription Expires
'
,
// Usage stat cells
// Usage stat cells
todayRequests
:
'
Today Requests
'
,
todayRequests
:
'
Today Requests
'
,
todayInputTokens
:
'
Today Input
'
,
todayOutputTokens
:
'
Today Output
'
,
todayTokens
:
'
Today Tokens
'
,
todayTokens
:
'
Today Tokens
'
,
todayCacheCreation
:
'
Today Cache Creation
'
,
todayCacheRead
:
'
Today Cache Read
'
,
todayCost
:
'
Today Cost
'
,
todayCost
:
'
Today Cost
'
,
rpmTpm
:
'
RPM / TPM
'
,
rpmTpm
:
'
RPM / TPM
'
,
totalRequests
:
'
Total Requests
'
,
totalRequests
:
'
Total Requests
'
,
totalInputTokens
:
'
Total Input
'
,
totalOutputTokens
:
'
Total Output
'
,
totalTokensLabel
:
'
Total Tokens
'
,
totalTokensLabel
:
'
Total Tokens
'
,
totalCacheCreation
:
'
Total Cache Creation
'
,
totalCacheRead
:
'
Total Cache Read
'
,
totalCost
:
'
Total Cost
'
,
totalCost
:
'
Total Cost
'
,
avgDuration
:
'
Avg Duration
'
,
avgDuration
:
'
Avg Duration
'
,
// Messages
// Messages
...
...
frontend/src/i18n/locales/zh.ts
View file @
33bae6f4
...
@@ -133,6 +133,8 @@ export default {
...
@@ -133,6 +133,8 @@ export default {
requests
:
'
请求数
'
,
requests
:
'
请求数
'
,
inputTokens
:
'
输入 Tokens
'
,
inputTokens
:
'
输入 Tokens
'
,
outputTokens
:
'
输出 Tokens
'
,
outputTokens
:
'
输出 Tokens
'
,
cacheCreationTokens
:
'
缓存创建
'
,
cacheReadTokens
:
'
缓存读取
'
,
totalTokens
:
'
总 Tokens
'
,
totalTokens
:
'
总 Tokens
'
,
cost
:
'
费用
'
,
cost
:
'
费用
'
,
// Status
// Status
...
@@ -155,11 +157,19 @@ export default {
...
@@ -155,11 +157,19 @@ export default {
subscriptionExpires
:
'
订阅到期
'
,
subscriptionExpires
:
'
订阅到期
'
,
// Usage stat cells
// Usage stat cells
todayRequests
:
'
今日请求
'
,
todayRequests
:
'
今日请求
'
,
todayInputTokens
:
'
今日输入
'
,
todayOutputTokens
:
'
今日输出
'
,
todayTokens
:
'
今日 Tokens
'
,
todayTokens
:
'
今日 Tokens
'
,
todayCacheCreation
:
'
今日缓存创建
'
,
todayCacheRead
:
'
今日缓存读取
'
,
todayCost
:
'
今日费用
'
,
todayCost
:
'
今日费用
'
,
rpmTpm
:
'
RPM / TPM
'
,
rpmTpm
:
'
RPM / TPM
'
,
totalRequests
:
'
累计请求
'
,
totalRequests
:
'
累计请求
'
,
totalInputTokens
:
'
累计输入
'
,
totalOutputTokens
:
'
累计输出
'
,
totalTokensLabel
:
'
累计 Tokens
'
,
totalTokensLabel
:
'
累计 Tokens
'
,
totalCacheCreation
:
'
累计缓存创建
'
,
totalCacheRead
:
'
累计缓存读取
'
,
totalCost
:
'
累计费用
'
,
totalCost
:
'
累计费用
'
,
avgDuration
:
'
平均耗时
'
,
avgDuration
:
'
平均耗时
'
,
// Messages
// Messages
...
...
frontend/src/types/index.ts
View file @
33bae6f4
...
@@ -1098,7 +1098,8 @@ export interface TrendDataPoint {
...
@@ -1098,7 +1098,8 @@ export interface TrendDataPoint {
requests
:
number
requests
:
number
input_tokens
:
number
input_tokens
:
number
output_tokens
:
number
output_tokens
:
number
cache_tokens
:
number
cache_creation_tokens
:
number
cache_read_tokens
:
number
total_tokens
:
number
total_tokens
:
number
cost
:
number
// 标准计费
cost
:
number
// 标准计费
actual_cost
:
number
// 实际扣除
actual_cost
:
number
// 实际扣除
...
@@ -1109,6 +1110,8 @@ export interface ModelStat {
...
@@ -1109,6 +1110,8 @@ export interface ModelStat {
requests
:
number
requests
:
number
input_tokens
:
number
input_tokens
:
number
output_tokens
:
number
output_tokens
:
number
cache_creation_tokens
:
number
cache_read_tokens
:
number
total_tokens
:
number
total_tokens
:
number
cost
:
number
// 标准计费
cost
:
number
// 标准计费
actual_cost
:
number
// 实际扣除
actual_cost
:
number
// 实际扣除
...
...
frontend/src/views/KeyUsageView.vue
View file @
33bae6f4
...
@@ -302,6 +302,8 @@
...
@@ -302,6 +302,8 @@
<th
class=
"px-4 py-3 text-right text-xs font-semibold uppercase tracking-wider text-gray-500 dark:text-dark-400"
>
{{ t('keyUsage.requests') }}
</th>
<th
class=
"px-4 py-3 text-right text-xs font-semibold uppercase tracking-wider text-gray-500 dark:text-dark-400"
>
{{ t('keyUsage.requests') }}
</th>
<th
class=
"px-4 py-3 text-right text-xs font-semibold uppercase tracking-wider text-gray-500 dark:text-dark-400"
>
{{ t('keyUsage.inputTokens') }}
</th>
<th
class=
"px-4 py-3 text-right text-xs font-semibold uppercase tracking-wider text-gray-500 dark:text-dark-400"
>
{{ t('keyUsage.inputTokens') }}
</th>
<th
class=
"px-4 py-3 text-right text-xs font-semibold uppercase tracking-wider text-gray-500 dark:text-dark-400"
>
{{ t('keyUsage.outputTokens') }}
</th>
<th
class=
"px-4 py-3 text-right text-xs font-semibold uppercase tracking-wider text-gray-500 dark:text-dark-400"
>
{{ t('keyUsage.outputTokens') }}
</th>
<th
class=
"px-4 py-3 text-right text-xs font-semibold uppercase tracking-wider text-gray-500 dark:text-dark-400"
>
{{ t('keyUsage.cacheCreationTokens') }}
</th>
<th
class=
"px-4 py-3 text-right text-xs font-semibold uppercase tracking-wider text-gray-500 dark:text-dark-400"
>
{{ t('keyUsage.cacheReadTokens') }}
</th>
<th
class=
"px-4 py-3 text-right text-xs font-semibold uppercase tracking-wider text-gray-500 dark:text-dark-400"
>
{{ t('keyUsage.totalTokens') }}
</th>
<th
class=
"px-4 py-3 text-right text-xs font-semibold uppercase tracking-wider text-gray-500 dark:text-dark-400"
>
{{ t('keyUsage.totalTokens') }}
</th>
<th
class=
"px-4 py-3 text-right text-xs font-semibold uppercase tracking-wider text-gray-500 dark:text-dark-400"
>
{{ t('keyUsage.cost') }}
</th>
<th
class=
"px-4 py-3 text-right text-xs font-semibold uppercase tracking-wider text-gray-500 dark:text-dark-400"
>
{{ t('keyUsage.cost') }}
</th>
</tr>
</tr>
...
@@ -316,6 +318,8 @@
...
@@ -316,6 +318,8 @@
<td
class=
"px-4 py-3 text-sm tabular-nums text-right text-gray-700 dark:text-dark-200"
>
{{ fmtNum(m.requests) }}
</td>
<td
class=
"px-4 py-3 text-sm tabular-nums text-right text-gray-700 dark:text-dark-200"
>
{{ fmtNum(m.requests) }}
</td>
<td
class=
"px-4 py-3 text-sm tabular-nums text-right text-gray-700 dark:text-dark-200"
>
{{ fmtNum(m.input_tokens) }}
</td>
<td
class=
"px-4 py-3 text-sm tabular-nums text-right text-gray-700 dark:text-dark-200"
>
{{ fmtNum(m.input_tokens) }}
</td>
<td
class=
"px-4 py-3 text-sm tabular-nums text-right text-gray-700 dark:text-dark-200"
>
{{ fmtNum(m.output_tokens) }}
</td>
<td
class=
"px-4 py-3 text-sm tabular-nums text-right text-gray-700 dark:text-dark-200"
>
{{ fmtNum(m.output_tokens) }}
</td>
<td
class=
"px-4 py-3 text-sm tabular-nums text-right text-gray-700 dark:text-dark-200"
>
{{ fmtNum(m.cache_creation_tokens) }}
</td>
<td
class=
"px-4 py-3 text-sm tabular-nums text-right text-gray-700 dark:text-dark-200"
>
{{ fmtNum(m.cache_read_tokens) }}
</td>
<td
class=
"px-4 py-3 text-sm tabular-nums text-right text-gray-700 dark:text-dark-200"
>
{{ fmtNum(m.total_tokens) }}
</td>
<td
class=
"px-4 py-3 text-sm tabular-nums text-right text-gray-700 dark:text-dark-200"
>
{{ fmtNum(m.total_tokens) }}
</td>
<td
class=
"px-4 py-3 text-sm tabular-nums text-right font-medium text-gray-900 dark:text-white"
>
{{ usd(m.actual_cost != null ? m.actual_cost : m.cost) }}
</td>
<td
class=
"px-4 py-3 text-sm tabular-nums text-right font-medium text-gray-900 dark:text-white"
>
{{ usd(m.actual_cost != null ? m.actual_cost : m.cost) }}
</td>
</tr>
</tr>
...
@@ -694,11 +698,19 @@ const usageStatCells = computed<StatCell[]>(() => {
...
@@ -694,11 +698,19 @@ const usageStatCells = computed<StatCell[]>(() => {
return
[
return
[
{
label
:
t
(
'
keyUsage.todayRequests
'
),
value
:
fmtNum
(
today
.
requests
)
},
{
label
:
t
(
'
keyUsage.todayRequests
'
),
value
:
fmtNum
(
today
.
requests
)
},
{
label
:
t
(
'
keyUsage.todayInputTokens
'
),
value
:
fmtNum
(
today
.
input_tokens
)
},
{
label
:
t
(
'
keyUsage.todayOutputTokens
'
),
value
:
fmtNum
(
today
.
output_tokens
)
},
{
label
:
t
(
'
keyUsage.todayTokens
'
),
value
:
fmtNum
(
today
.
total_tokens
)
},
{
label
:
t
(
'
keyUsage.todayTokens
'
),
value
:
fmtNum
(
today
.
total_tokens
)
},
{
label
:
t
(
'
keyUsage.todayCacheCreation
'
),
value
:
fmtNum
(
today
.
cache_creation_tokens
)
},
{
label
:
t
(
'
keyUsage.todayCacheRead
'
),
value
:
fmtNum
(
today
.
cache_read_tokens
)
},
{
label
:
t
(
'
keyUsage.todayCost
'
),
value
:
usd
(
today
.
actual_cost
)
},
{
label
:
t
(
'
keyUsage.todayCost
'
),
value
:
usd
(
today
.
actual_cost
)
},
{
label
:
t
(
'
keyUsage.rpmTpm
'
),
value
:
`
${
usage
.
rpm
||
0
}
/
${
usage
.
tpm
||
0
}
`
},
{
label
:
t
(
'
keyUsage.rpmTpm
'
),
value
:
`
${
usage
.
rpm
||
0
}
/
${
usage
.
tpm
||
0
}
`
},
{
label
:
t
(
'
keyUsage.totalRequests
'
),
value
:
fmtNum
(
total
.
requests
)
},
{
label
:
t
(
'
keyUsage.totalRequests
'
),
value
:
fmtNum
(
total
.
requests
)
},
{
label
:
t
(
'
keyUsage.totalInputTokens
'
),
value
:
fmtNum
(
total
.
input_tokens
)
},
{
label
:
t
(
'
keyUsage.totalOutputTokens
'
),
value
:
fmtNum
(
total
.
output_tokens
)
},
{
label
:
t
(
'
keyUsage.totalTokensLabel
'
),
value
:
fmtNum
(
total
.
total_tokens
)
},
{
label
:
t
(
'
keyUsage.totalTokensLabel
'
),
value
:
fmtNum
(
total
.
total_tokens
)
},
{
label
:
t
(
'
keyUsage.totalCacheCreation
'
),
value
:
fmtNum
(
total
.
cache_creation_tokens
)
},
{
label
:
t
(
'
keyUsage.totalCacheRead
'
),
value
:
fmtNum
(
total
.
cache_read_tokens
)
},
{
label
:
t
(
'
keyUsage.totalCost
'
),
value
:
usd
(
total
.
actual_cost
)
},
{
label
:
t
(
'
keyUsage.totalCost
'
),
value
:
usd
(
total
.
actual_cost
)
},
{
label
:
t
(
'
keyUsage.avgDuration
'
),
value
:
usage
.
average_duration_ms
?
`
${
Math
.
round
(
usage
.
average_duration_ms
)}
ms`
:
'
-
'
},
{
label
:
t
(
'
keyUsage.avgDuration
'
),
value
:
usage
.
average_duration_ms
?
`
${
Math
.
round
(
usage
.
average_duration_ms
)}
ms`
:
'
-
'
},
]
]
...
...
frontend/src/views/user/UsageView.vue
View file @
33bae6f4
...
@@ -113,6 +113,9 @@
...
@@ -113,6 +113,9 @@
<!-- Actions -->
<!-- Actions -->
<div
class=
"ml-auto flex items-center gap-3"
>
<div
class=
"ml-auto flex items-center gap-3"
>
<button
@
click=
"applyFilters"
:disabled=
"loading"
class=
"btn btn-secondary"
>
{{
t
(
'
common.refresh
'
)
}}
</button>
<button
@
click=
"resetFilters"
class=
"btn btn-secondary"
>
<button
@
click=
"resetFilters"
class=
"btn btn-secondary"
>
{{
t
(
'
common.reset
'
)
}}
{{
t
(
'
common.reset
'
)
}}
</button>
</button>
...
...
Write
Preview
Markdown
is supported
0%
Try again
or
attach a new file
.
Attach a file
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Cancel
Please
register
or
sign in
to comment