Skip to content
Toggle navigation
P
Projects
G
Groups
S
Snippets
Help
phsl
/
new-api
This project
Loading...
Sign in
Toggle navigation
Go to a project
Project
Repository
Issues
0
Merge Requests
0
Pipelines
Wiki
Snippets
Members
Activity
Graph
Charts
Create a new issue
Jobs
Commits
Issue Boards
Files
Commits
Branches
Tags
Contributors
Graph
Compare
Charts
Commit
5bb8fe6a
authored
Mar 18, 2026
by
reed
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
fix: 修正 Codex free 账号用量显示到每周窗口
parent
a1a92c19
Hide whitespace changes
Inline
Side-by-side
Showing
1 changed file
with
83 additions
and
15 deletions
+83
-15
web/src/components/table/channels/modals/CodexUsageModal.jsx
+83
-15
No files found.
web/src/components/table/channels/modals/CodexUsageModal.jsx
View file @
5bb8fe6a
...
@@ -43,6 +43,68 @@ const pickStrokeColor = (percent) => {
...
@@ -43,6 +43,68 @@ const pickStrokeColor = (percent) => {
return
'#3b82f6'
;
return
'#3b82f6'
;
};
};
const
normalizePlanType
=
(
value
)
=>
{
if
(
value
==
null
)
return
''
;
return
String
(
value
).
trim
().
toLowerCase
();
};
const
getWindowDurationSeconds
=
(
windowData
)
=>
{
const
value
=
Number
(
windowData
?.
limit_window_seconds
);
if
(
!
Number
.
isFinite
(
value
)
||
value
<=
0
)
return
null
;
return
value
;
};
const
classifyWindowByDuration
=
(
windowData
)
=>
{
const
seconds
=
getWindowDurationSeconds
(
windowData
);
if
(
seconds
==
null
)
return
null
;
return
seconds
>=
24
*
60
*
60
?
'weekly'
:
'fiveHour'
;
};
const
resolveRateLimitWindows
=
(
data
)
=>
{
const
rateLimit
=
data
?.
rate_limit
??
{};
const
primary
=
rateLimit
?.
primary_window
??
null
;
const
secondary
=
rateLimit
?.
secondary_window
??
null
;
const
windows
=
[
primary
,
secondary
].
filter
(
Boolean
);
const
planType
=
normalizePlanType
(
data
?.
plan_type
??
rateLimit
?.
plan_type
);
let
fiveHourWindow
=
null
;
let
weeklyWindow
=
null
;
for
(
const
windowData
of
windows
)
{
const
bucket
=
classifyWindowByDuration
(
windowData
);
if
(
bucket
===
'fiveHour'
&&
!
fiveHourWindow
)
{
fiveHourWindow
=
windowData
;
continue
;
}
if
(
bucket
===
'weekly'
&&
!
weeklyWindow
)
{
weeklyWindow
=
windowData
;
}
}
if
(
planType
===
'free'
)
{
if
(
!
weeklyWindow
)
{
weeklyWindow
=
primary
??
secondary
??
null
;
}
return
{
fiveHourWindow
:
null
,
weeklyWindow
};
}
if
(
!
fiveHourWindow
&&
!
weeklyWindow
)
{
return
{
fiveHourWindow
:
primary
??
null
,
weeklyWindow
:
secondary
??
null
,
};
}
if
(
!
fiveHourWindow
)
{
fiveHourWindow
=
windows
.
find
((
windowData
)
=>
windowData
!==
weeklyWindow
)
??
null
;
}
if
(
!
weeklyWindow
)
{
weeklyWindow
=
windows
.
find
((
windowData
)
=>
windowData
!==
fiveHourWindow
)
??
null
;
}
return
{
fiveHourWindow
,
weeklyWindow
};
};
const
formatDurationSeconds
=
(
seconds
,
t
)
=>
{
const
formatDurationSeconds
=
(
seconds
,
t
)
=>
{
const
tt
=
typeof
t
===
'function'
?
t
:
(
v
)
=>
v
;
const
tt
=
typeof
t
===
'function'
?
t
:
(
v
)
=>
v
;
const
s
=
Number
(
seconds
);
const
s
=
Number
(
seconds
);
...
@@ -68,6 +130,10 @@ const formatUnixSeconds = (unixSeconds) => {
...
@@ -68,6 +130,10 @@ const formatUnixSeconds = (unixSeconds) => {
const
RateLimitWindowCard
=
({
t
,
title
,
windowData
})
=>
{
const
RateLimitWindowCard
=
({
t
,
title
,
windowData
})
=>
{
const
tt
=
typeof
t
===
'function'
?
t
:
(
v
)
=>
v
;
const
tt
=
typeof
t
===
'function'
?
t
:
(
v
)
=>
v
;
const
hasWindowData
=
!!
windowData
&&
typeof
windowData
===
'object'
&&
Object
.
keys
(
windowData
).
length
>
0
;
const
percent
=
clampPercent
(
windowData
?.
used_percent
??
0
);
const
percent
=
clampPercent
(
windowData
?.
used_percent
??
0
);
const
resetAt
=
windowData
?.
reset_at
;
const
resetAt
=
windowData
?.
reset_at
;
const
resetAfterSeconds
=
windowData
?.
reset_after_seconds
;
const
resetAfterSeconds
=
windowData
?.
reset_after_seconds
;
...
@@ -83,26 +149,30 @@ const RateLimitWindowCard = ({ t, title, windowData }) => {
...
@@ -83,26 +149,30 @@ const RateLimitWindowCard = ({ t, title, windowData }) => {
</
Text
>
</
Text
>
</
div
>
</
div
>
<
div
className=
'mt-2'
>
{
hasWindowData
?
(
<
Progress
<
div
className=
'mt-2'
>
percent=
{
percent
}
<
Progress
stroke=
{
pickStrokeColor
(
percent
)
}
percent=
{
percent
}
showInfo=
{
true
}
stroke=
{
pickStrokeColor
(
percent
)
}
/>
showInfo=
{
true
}
</
div
>
/>
</
div
>
)
:
(
<
div
className=
'mt-3 text-sm text-semi-color-text-2'
>
-
</
div
>
)
}
<
div
className=
'mt-1 flex flex-wrap items-center gap-2 text-xs text-semi-color-text-2'
>
<
div
className=
'mt-1 flex flex-wrap items-center gap-2 text-xs text-semi-color-text-2'
>
<
div
>
<
div
>
{
tt
(
'已使用:'
)
}
{
tt
(
'已使用:'
)
}
{
percent
}
%
{
hasWindowData
?
`${percent}%`
:
'-'
}
</
div
>
</
div
>
<
div
>
<
div
>
{
tt
(
'距离重置:'
)
}
{
tt
(
'距离重置:'
)
}
{
formatDurationSeconds
(
resetAfterSeconds
,
tt
)
}
{
hasWindowData
?
formatDurationSeconds
(
resetAfterSeconds
,
tt
)
:
'-'
}
</
div
>
</
div
>
<
div
>
<
div
>
{
tt
(
'窗口:'
)
}
{
tt
(
'窗口:'
)
}
{
formatDurationSeconds
(
limitWindowSeconds
,
tt
)
}
{
hasWindowData
?
formatDurationSeconds
(
limitWindowSeconds
,
tt
)
:
'-'
}
</
div
>
</
div
>
</
div
>
</
div
>
</
div
>
</
div
>
...
@@ -113,9 +183,7 @@ const CodexUsageView = ({ t, record, payload, onCopy, onRefresh }) => {
...
@@ -113,9 +183,7 @@ const CodexUsageView = ({ t, record, payload, onCopy, onRefresh }) => {
const
tt
=
typeof
t
===
'function'
?
t
:
(
v
)
=>
v
;
const
tt
=
typeof
t
===
'function'
?
t
:
(
v
)
=>
v
;
const
data
=
payload
?.
data
??
null
;
const
data
=
payload
?.
data
??
null
;
const
rateLimit
=
data
?.
rate_limit
??
{};
const
rateLimit
=
data
?.
rate_limit
??
{};
const
{
fiveHourWindow
,
weeklyWindow
}
=
resolveRateLimitWindows
(
data
);
const
primary
=
rateLimit
?.
primary_window
??
null
;
const
secondary
=
rateLimit
?.
secondary_window
??
null
;
const
allowed
=
!!
rateLimit
?.
allowed
;
const
allowed
=
!!
rateLimit
?.
allowed
;
const
limitReached
=
!!
rateLimit
?.
limit_reached
;
const
limitReached
=
!!
rateLimit
?.
limit_reached
;
...
@@ -163,12 +231,12 @@ const CodexUsageView = ({ t, record, payload, onCopy, onRefresh }) => {
...
@@ -163,12 +231,12 @@ const CodexUsageView = ({ t, record, payload, onCopy, onRefresh }) => {
<
RateLimitWindowCard
<
RateLimitWindowCard
t=
{
tt
}
t=
{
tt
}
title=
{
tt
(
'5小时窗口'
)
}
title=
{
tt
(
'5小时窗口'
)
}
windowData=
{
primary
}
windowData=
{
fiveHourWindow
}
/>
/>
<
RateLimitWindowCard
<
RateLimitWindowCard
t=
{
tt
}
t=
{
tt
}
title=
{
tt
(
'每周窗口'
)
}
title=
{
tt
(
'每周窗口'
)
}
windowData=
{
secondary
}
windowData=
{
weeklyWindow
}
/>
/>
</
div
>
</
div
>
...
...
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