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
7fd94ab7
Commit
7fd94ab7
authored
Dec 19, 2025
by
shaw
Browse files
fix: 修复usage页面未显示缓存写入的问题
parent
078529e5
Changes
4
Hide whitespace changes
Inline
Side-by-side
frontend/src/i18n/locales/en.ts
View file @
7fd94ab7
...
...
@@ -266,6 +266,8 @@ export default {
sync
:
'
Sync
'
,
in
:
'
In
'
,
out
:
'
Out
'
,
cacheRead
:
'
Read
'
,
cacheWrite
:
'
Write
'
,
rate
:
'
Rate
'
,
original
:
'
Original
'
,
billed
:
'
Billed
'
,
...
...
frontend/src/i18n/locales/zh.ts
View file @
7fd94ab7
...
...
@@ -266,6 +266,8 @@ export default {
sync
:
'
同步
'
,
in
:
'
输入
'
,
out
:
'
输出
'
,
cacheRead
:
'
读取
'
,
cacheWrite
:
'
写入
'
,
rate
:
'
倍率
'
,
original
:
'
原始
'
,
billed
:
'
计费
'
,
...
...
frontend/src/views/admin/UsageView.vue
View file @
7fd94ab7
...
...
@@ -194,17 +194,40 @@
</
template
>
<
template
#cell-tokens=
"{ row }"
>
<div
class=
"text-sm"
>
<div
class=
"flex items-center gap-1"
>
<span
class=
"text-gray-500 dark:text-gray-400"
>
{{
t
(
'
usage.in
'
)
}}
</span>
<span
class=
"font-medium text-gray-900 dark:text-white"
>
{{
row
.
input_tokens
.
toLocaleString
()
}}
</span>
<span
class=
"text-gray-400 dark:text-gray-500"
>
/
</span>
<span
class=
"text-gray-500 dark:text-gray-400"
>
{{
t
(
'
usage.out
'
)
}}
</span>
<span
class=
"font-medium text-gray-900 dark:text-white"
>
{{
row
.
output_tokens
.
toLocaleString
()
}}
</span>
<div
class=
"text-sm space-y-1.5"
>
<!-- Input / Output Tokens -->
<div
class=
"flex items-center gap-2"
>
<!-- Input -->
<div
class=
"inline-flex items-center gap-1"
>
<svg
class=
"w-3.5 h-3.5 text-emerald-500"
fill=
"none"
stroke=
"currentColor"
viewBox=
"0 0 24 24"
>
<path
stroke-linecap=
"round"
stroke-linejoin=
"round"
stroke-width=
"2"
d=
"M19 14l-7 7m0 0l-7-7m7 7V3"
/>
</svg>
<span
class=
"font-medium text-gray-900 dark:text-white"
>
{{
row
.
input_tokens
.
toLocaleString
()
}}
</span>
</div>
<!-- Output -->
<div
class=
"inline-flex items-center gap-1"
>
<svg
class=
"w-3.5 h-3.5 text-violet-500"
fill=
"none"
stroke=
"currentColor"
viewBox=
"0 0 24 24"
>
<path
stroke-linecap=
"round"
stroke-linejoin=
"round"
stroke-width=
"2"
d=
"M5 10l7-7m0 0l7 7m-7-7v18"
/>
</svg>
<span
class=
"font-medium text-gray-900 dark:text-white"
>
{{
row
.
output_tokens
.
toLocaleString
()
}}
</span>
</div>
</div>
<div
v-if=
"row.cache_read_tokens > 0"
class=
"flex items-center gap-1 text-blue-600 dark:text-blue-400"
>
<span>
{{
t
(
'
dashboard.cache
'
)
}}
</span>
<span
class=
"font-medium"
>
{{
row
.
cache_read_tokens
.
toLocaleString
()
}}
</span>
<!-- Cache Tokens (Read + Write) -->
<div
v-if=
"row.cache_read_tokens > 0 || row.cache_creation_tokens > 0"
class=
"flex items-center gap-2"
>
<!-- Cache Read -->
<div
v-if=
"row.cache_read_tokens > 0"
class=
"inline-flex items-center gap-1"
>
<svg
class=
"w-3.5 h-3.5 text-sky-500"
fill=
"none"
stroke=
"currentColor"
viewBox=
"0 0 24 24"
>
<path
stroke-linecap=
"round"
stroke-linejoin=
"round"
stroke-width=
"2"
d=
"M5 8h14M5 8a2 2 0 110-4h14a2 2 0 110 4M5 8v10a2 2 0 002 2h10a2 2 0 002-2V8m-9 4h4"
/>
</svg>
<span
class=
"text-sky-600 dark:text-sky-400 font-medium"
>
{{
formatCacheTokens
(
row
.
cache_read_tokens
)
}}
</span>
</div>
<!-- Cache Write -->
<div
v-if=
"row.cache_creation_tokens > 0"
class=
"inline-flex items-center gap-1"
>
<svg
class=
"w-3.5 h-3.5 text-amber-500"
fill=
"none"
stroke=
"currentColor"
viewBox=
"0 0 24 24"
>
<path
stroke-linecap=
"round"
stroke-linejoin=
"round"
stroke-width=
"2"
d=
"M11 5H6a2 2 0 00-2 2v11a2 2 0 002 2h11a2 2 0 002-2v-5m-1.414-9.414a2 2 0 112.828 2.828L11.828 15H9v-2.828l8.586-8.586z"
/>
</svg>
<span
class=
"text-amber-600 dark:text-amber-400 font-medium"
>
{{
formatCacheTokens
(
row
.
cache_creation_tokens
)
}}
</span>
</div>
</div>
</div>
</
template
>
...
...
@@ -457,6 +480,16 @@ const formatTokens = (value: number): string => {
return
value
.
toLocaleString
()
}
// Compact format for cache tokens in table cells
const
formatCacheTokens
=
(
value
:
number
):
string
=>
{
if
(
value
>=
1
_000_000
)
{
return
`
${(
value
/
1
_000_000
).
toFixed
(
1
)}
M`
}
else
if
(
value
>=
1
_000
)
{
return
`
${(
value
/
1
_000
).
toFixed
(
1
)}
K`
}
return
value
.
toLocaleString
()
}
const
formatDateTime
=
(
dateString
:
string
):
string
=>
{
const
date
=
new
Date
(
dateString
)
return
date
.
toLocaleString
(
'
en-US
'
,
{
...
...
@@ -537,7 +570,7 @@ const exportToCSV = () => {
return
}
const
headers
=
[
'
User
'
,
'
API Key
'
,
'
Model
'
,
'
Type
'
,
'
Input Tokens
'
,
'
Output Tokens
'
,
'
Cache Tokens
'
,
'
Total Cost
'
,
'
Billing Type
'
,
'
Duration (ms)
'
,
'
Time
'
]
const
headers
=
[
'
User
'
,
'
API Key
'
,
'
Model
'
,
'
Type
'
,
'
Input Tokens
'
,
'
Output Tokens
'
,
'
Cache
Read Tokens
'
,
'
Cache Write
Tokens
'
,
'
Total Cost
'
,
'
Billing Type
'
,
'
Duration (ms)
'
,
'
Time
'
]
const
rows
=
usageLogs
.
value
.
map
(
log
=>
[
log
.
user
?.
email
||
''
,
log
.
api_key
?.
name
||
''
,
...
...
@@ -546,6 +579,7 @@ const exportToCSV = () => {
log
.
input_tokens
,
log
.
output_tokens
,
log
.
cache_read_tokens
,
log
.
cache_creation_tokens
,
log
.
total_cost
.
toFixed
(
6
),
log
.
billing_type
===
1
?
'
Subscription
'
:
'
Balance
'
,
log
.
duration_ms
,
...
...
frontend/src/views/user/UsageView.vue
View file @
7fd94ab7
...
...
@@ -137,17 +137,40 @@
</
template
>
<
template
#cell-tokens=
"{ row }"
>
<div
class=
"text-sm"
>
<div
class=
"flex items-center gap-1"
>
<span
class=
"text-gray-500 dark:text-gray-400"
>
{{
t
(
'
usage.in
'
)
}}
</span>
<span
class=
"font-medium text-gray-900 dark:text-white"
>
{{
row
.
input_tokens
.
toLocaleString
()
}}
</span>
<span
class=
"text-gray-400 dark:text-gray-500"
>
/
</span>
<span
class=
"text-gray-500 dark:text-gray-400"
>
{{
t
(
'
usage.out
'
)
}}
</span>
<span
class=
"font-medium text-gray-900 dark:text-white"
>
{{
row
.
output_tokens
.
toLocaleString
()
}}
</span>
<div
class=
"text-sm space-y-1.5"
>
<!-- Input / Output Tokens -->
<div
class=
"flex items-center gap-2"
>
<!-- Input -->
<div
class=
"inline-flex items-center gap-1"
>
<svg
class=
"w-3.5 h-3.5 text-emerald-500"
fill=
"none"
stroke=
"currentColor"
viewBox=
"0 0 24 24"
>
<path
stroke-linecap=
"round"
stroke-linejoin=
"round"
stroke-width=
"2"
d=
"M19 14l-7 7m0 0l-7-7m7 7V3"
/>
</svg>
<span
class=
"font-medium text-gray-900 dark:text-white"
>
{{
row
.
input_tokens
.
toLocaleString
()
}}
</span>
</div>
<!-- Output -->
<div
class=
"inline-flex items-center gap-1"
>
<svg
class=
"w-3.5 h-3.5 text-violet-500"
fill=
"none"
stroke=
"currentColor"
viewBox=
"0 0 24 24"
>
<path
stroke-linecap=
"round"
stroke-linejoin=
"round"
stroke-width=
"2"
d=
"M5 10l7-7m0 0l7 7m-7-7v18"
/>
</svg>
<span
class=
"font-medium text-gray-900 dark:text-white"
>
{{
row
.
output_tokens
.
toLocaleString
()
}}
</span>
</div>
</div>
<div
v-if=
"row.cache_read_tokens > 0"
class=
"flex items-center gap-1 text-blue-600 dark:text-blue-400"
>
<span>
{{
t
(
'
dashboard.cache
'
)
}}
</span>
<span
class=
"font-medium"
>
{{
row
.
cache_read_tokens
.
toLocaleString
()
}}
</span>
<!-- Cache Tokens (Read + Write) -->
<div
v-if=
"row.cache_read_tokens > 0 || row.cache_creation_tokens > 0"
class=
"flex items-center gap-2"
>
<!-- Cache Read -->
<div
v-if=
"row.cache_read_tokens > 0"
class=
"inline-flex items-center gap-1"
>
<svg
class=
"w-3.5 h-3.5 text-sky-500"
fill=
"none"
stroke=
"currentColor"
viewBox=
"0 0 24 24"
>
<path
stroke-linecap=
"round"
stroke-linejoin=
"round"
stroke-width=
"2"
d=
"M5 8h14M5 8a2 2 0 110-4h14a2 2 0 110 4M5 8v10a2 2 0 002 2h10a2 2 0 002-2V8m-9 4h4"
/>
</svg>
<span
class=
"text-sky-600 dark:text-sky-400 font-medium"
>
{{
formatCacheTokens
(
row
.
cache_read_tokens
)
}}
</span>
</div>
<!-- Cache Write -->
<div
v-if=
"row.cache_creation_tokens > 0"
class=
"inline-flex items-center gap-1"
>
<svg
class=
"w-3.5 h-3.5 text-amber-500"
fill=
"none"
stroke=
"currentColor"
viewBox=
"0 0 24 24"
>
<path
stroke-linecap=
"round"
stroke-linejoin=
"round"
stroke-width=
"2"
d=
"M11 5H6a2 2 0 00-2 2v11a2 2 0 002 2h11a2 2 0 002-2v-5m-1.414-9.414a2 2 0 112.828 2.828L11.828 15H9v-2.828l8.586-8.586z"
/>
</svg>
<span
class=
"text-amber-600 dark:text-amber-400 font-medium"
>
{{
formatCacheTokens
(
row
.
cache_creation_tokens
)
}}
</span>
</div>
</div>
</div>
</
template
>
...
...
@@ -331,6 +354,16 @@ const formatTokens = (value: number): string => {
return
value
.
toLocaleString
()
}
// Compact format for cache tokens in table cells
const
formatCacheTokens
=
(
value
:
number
):
string
=>
{
if
(
value
>=
1
_000_000
)
{
return
`
${(
value
/
1
_000_000
).
toFixed
(
1
)}
M`
}
else
if
(
value
>=
1
_000
)
{
return
`
${(
value
/
1
_000
).
toFixed
(
1
)}
K`
}
return
value
.
toLocaleString
()
}
const
formatDateTime
=
(
dateString
:
string
):
string
=>
{
const
date
=
new
Date
(
dateString
)
return
date
.
toLocaleString
(
'
en-US
'
,
{
...
...
@@ -415,13 +448,14 @@ const exportToCSV = () => {
return
}
const
headers
=
[
'
Model
'
,
'
Type
'
,
'
Input Tokens
'
,
'
Output Tokens
'
,
'
Cache Tokens
'
,
'
Total Cost
'
,
'
Billing Type
'
,
'
First Token (ms)
'
,
'
Duration (ms)
'
,
'
Time
'
]
const
headers
=
[
'
Model
'
,
'
Type
'
,
'
Input Tokens
'
,
'
Output Tokens
'
,
'
Cache
Read Tokens
'
,
'
Cache Write
Tokens
'
,
'
Total Cost
'
,
'
Billing Type
'
,
'
First Token (ms)
'
,
'
Duration (ms)
'
,
'
Time
'
]
const
rows
=
usageLogs
.
value
.
map
(
log
=>
[
log
.
model
,
log
.
stream
?
'
Stream
'
:
'
Sync
'
,
log
.
input_tokens
,
log
.
output_tokens
,
log
.
cache_read_tokens
,
log
.
cache_creation_tokens
,
log
.
total_cost
.
toFixed
(
6
),
log
.
billing_type
===
1
?
'
Subscription
'
:
'
Balance
'
,
log
.
first_token_ms
??
''
,
...
...
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