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
Unverified
Commit
ede0ad11
authored
Mar 18, 2026
by
Seefs
Committed by
GitHub
Mar 18, 2026
Browse files
Options
Browse Files
Download
Plain Diff
Merge pull request #3316 from Honghurumeng/main
fix: 修正 Codex free 账号用量显示到每周窗口
parents
a1a92c19
5bb8fe6a
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 @
ede0ad11
...
...
@@ -43,6 +43,68 @@ const pickStrokeColor = (percent) => {
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
tt
=
typeof
t
===
'function'
?
t
:
(
v
)
=>
v
;
const
s
=
Number
(
seconds
);
...
...
@@ -68,6 +130,10 @@ const formatUnixSeconds = (unixSeconds) => {
const
RateLimitWindowCard
=
({
t
,
title
,
windowData
})
=>
{
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
resetAt
=
windowData
?.
reset_at
;
const
resetAfterSeconds
=
windowData
?.
reset_after_seconds
;
...
...
@@ -83,26 +149,30 @@ const RateLimitWindowCard = ({ t, title, windowData }) => {
</
Text
>
</
div
>
<
div
className=
'mt-2'
>
<
Progress
percent=
{
percent
}
stroke=
{
pickStrokeColor
(
percent
)
}
showInfo=
{
true
}
/>
</
div
>
{
hasWindowData
?
(
<
div
className=
'mt-2'
>
<
Progress
percent=
{
percent
}
stroke=
{
pickStrokeColor
(
percent
)
}
showInfo=
{
true
}
/>
</
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
>
{
tt
(
'已使用:'
)
}
{
percent
}
%
{
hasWindowData
?
`${percent}%`
:
'-'
}
</
div
>
<
div
>
{
tt
(
'距离重置:'
)
}
{
formatDurationSeconds
(
resetAfterSeconds
,
tt
)
}
{
hasWindowData
?
formatDurationSeconds
(
resetAfterSeconds
,
tt
)
:
'-'
}
</
div
>
<
div
>
{
tt
(
'窗口:'
)
}
{
formatDurationSeconds
(
limitWindowSeconds
,
tt
)
}
{
hasWindowData
?
formatDurationSeconds
(
limitWindowSeconds
,
tt
)
:
'-'
}
</
div
>
</
div
>
</
div
>
...
...
@@ -113,9 +183,7 @@ const CodexUsageView = ({ t, record, payload, onCopy, onRefresh }) => {
const
tt
=
typeof
t
===
'function'
?
t
:
(
v
)
=>
v
;
const
data
=
payload
?.
data
??
null
;
const
rateLimit
=
data
?.
rate_limit
??
{};
const
primary
=
rateLimit
?.
primary_window
??
null
;
const
secondary
=
rateLimit
?.
secondary_window
??
null
;
const
{
fiveHourWindow
,
weeklyWindow
}
=
resolveRateLimitWindows
(
data
);
const
allowed
=
!!
rateLimit
?.
allowed
;
const
limitReached
=
!!
rateLimit
?.
limit_reached
;
...
...
@@ -163,12 +231,12 @@ const CodexUsageView = ({ t, record, payload, onCopy, onRefresh }) => {
<
RateLimitWindowCard
t=
{
tt
}
title=
{
tt
(
'5小时窗口'
)
}
windowData=
{
primary
}
windowData=
{
fiveHourWindow
}
/>
<
RateLimitWindowCard
t=
{
tt
}
title=
{
tt
(
'每周窗口'
)
}
windowData=
{
secondary
}
windowData=
{
weeklyWindow
}
/>
</
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