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
c5781c69
Commit
c5781c69
authored
Jan 01, 2026
by
IanShaw027
Browse files
fix(merge): 解决与 main 分支的配置冲突
- 合并 main 分支的上游错误日志配置 - 保留调度配置 - 合并 beta header 和 failover 配置
parents
e1a9c1ec
34c10204
Changes
53
Hide whitespace changes
Inline
Side-by-side
backend/internal/service/gemini_token_provider.go
View file @
c5781c69
...
@@ -112,7 +112,7 @@ func (p *GeminiTokenProvider) GetAccessToken(ctx context.Context, account *Accou
...
@@ -112,7 +112,7 @@ func (p *GeminiTokenProvider) GetAccessToken(ctx context.Context, account *Accou
}
}
}
}
detected
,
err
:=
p
.
geminiOAuthService
.
fetchProjectID
(
ctx
,
accessToken
,
proxyURL
)
detected
,
tierID
,
err
:=
p
.
geminiOAuthService
.
fetchProjectID
(
ctx
,
accessToken
,
proxyURL
)
if
err
!=
nil
{
if
err
!=
nil
{
log
.
Printf
(
"[GeminiTokenProvider] Auto-detect project_id failed: %v, fallback to AI Studio API mode"
,
err
)
log
.
Printf
(
"[GeminiTokenProvider] Auto-detect project_id failed: %v, fallback to AI Studio API mode"
,
err
)
return
accessToken
,
nil
return
accessToken
,
nil
...
@@ -123,6 +123,9 @@ func (p *GeminiTokenProvider) GetAccessToken(ctx context.Context, account *Accou
...
@@ -123,6 +123,9 @@ func (p *GeminiTokenProvider) GetAccessToken(ctx context.Context, account *Accou
account
.
Credentials
=
make
(
map
[
string
]
any
)
account
.
Credentials
=
make
(
map
[
string
]
any
)
}
}
account
.
Credentials
[
"project_id"
]
=
detected
account
.
Credentials
[
"project_id"
]
=
detected
if
tierID
!=
""
{
account
.
Credentials
[
"tier_id"
]
=
tierID
}
_
=
p
.
accountRepo
.
Update
(
ctx
,
account
)
_
=
p
.
accountRepo
.
Update
(
ctx
,
account
)
}
}
}
}
...
...
backend/internal/service/group_service.go
View file @
c5781c69
...
@@ -4,7 +4,7 @@ import (
...
@@ -4,7 +4,7 @@ import (
"context"
"context"
"fmt"
"fmt"
infraerrors
"github.com/Wei-Shaw/sub2api/internal/
infrastructure
/errors"
infraerrors
"github.com/Wei-Shaw/sub2api/internal/
pkg
/errors"
"github.com/Wei-Shaw/sub2api/internal/pkg/pagination"
"github.com/Wei-Shaw/sub2api/internal/pkg/pagination"
)
)
...
...
backend/internal/service/proxy_service.go
View file @
c5781c69
...
@@ -4,7 +4,7 @@ import (
...
@@ -4,7 +4,7 @@ import (
"context"
"context"
"fmt"
"fmt"
infraerrors
"github.com/Wei-Shaw/sub2api/internal/
infrastructure
/errors"
infraerrors
"github.com/Wei-Shaw/sub2api/internal/
pkg
/errors"
"github.com/Wei-Shaw/sub2api/internal/pkg/pagination"
"github.com/Wei-Shaw/sub2api/internal/pkg/pagination"
)
)
...
...
backend/internal/service/redeem_service.go
View file @
c5781c69
...
@@ -10,7 +10,7 @@ import (
...
@@ -10,7 +10,7 @@ import (
"time"
"time"
dbent
"github.com/Wei-Shaw/sub2api/ent"
dbent
"github.com/Wei-Shaw/sub2api/ent"
infraerrors
"github.com/Wei-Shaw/sub2api/internal/
infrastructure
/errors"
infraerrors
"github.com/Wei-Shaw/sub2api/internal/
pkg
/errors"
"github.com/Wei-Shaw/sub2api/internal/pkg/pagination"
"github.com/Wei-Shaw/sub2api/internal/pkg/pagination"
)
)
...
...
backend/internal/service/setting_service.go
View file @
c5781c69
...
@@ -9,7 +9,7 @@ import (
...
@@ -9,7 +9,7 @@ import (
"strconv"
"strconv"
"github.com/Wei-Shaw/sub2api/internal/config"
"github.com/Wei-Shaw/sub2api/internal/config"
infraerrors
"github.com/Wei-Shaw/sub2api/internal/
infrastructure
/errors"
infraerrors
"github.com/Wei-Shaw/sub2api/internal/
pkg
/errors"
)
)
var
(
var
(
...
...
backend/internal/service/subscription_service.go
View file @
c5781c69
...
@@ -6,7 +6,7 @@ import (
...
@@ -6,7 +6,7 @@ import (
"log"
"log"
"time"
"time"
infraerrors
"github.com/Wei-Shaw/sub2api/internal/
infrastructure
/errors"
infraerrors
"github.com/Wei-Shaw/sub2api/internal/
pkg
/errors"
"github.com/Wei-Shaw/sub2api/internal/pkg/pagination"
"github.com/Wei-Shaw/sub2api/internal/pkg/pagination"
)
)
...
@@ -490,6 +490,7 @@ func (s *SubscriptionService) CheckAndResetWindows(ctx context.Context, sub *Use
...
@@ -490,6 +490,7 @@ func (s *SubscriptionService) CheckAndResetWindows(ctx context.Context, sub *Use
}
}
// CheckUsageLimits 检查使用限额(返回错误如果超限)
// CheckUsageLimits 检查使用限额(返回错误如果超限)
// 用于中间件的快速预检查,additionalCost 通常为 0
func
(
s
*
SubscriptionService
)
CheckUsageLimits
(
ctx
context
.
Context
,
sub
*
UserSubscription
,
group
*
Group
,
additionalCost
float64
)
error
{
func
(
s
*
SubscriptionService
)
CheckUsageLimits
(
ctx
context
.
Context
,
sub
*
UserSubscription
,
group
*
Group
,
additionalCost
float64
)
error
{
if
!
sub
.
CheckDailyLimit
(
group
,
additionalCost
)
{
if
!
sub
.
CheckDailyLimit
(
group
,
additionalCost
)
{
return
ErrDailyLimitExceeded
return
ErrDailyLimitExceeded
...
...
backend/internal/service/turnstile_service.go
View file @
c5781c69
...
@@ -5,7 +5,7 @@ import (
...
@@ -5,7 +5,7 @@ import (
"fmt"
"fmt"
"log"
"log"
infraerrors
"github.com/Wei-Shaw/sub2api/internal/
infrastructure
/errors"
infraerrors
"github.com/Wei-Shaw/sub2api/internal/
pkg
/errors"
)
)
var
(
var
(
...
...
backend/internal/service/usage_service.go
View file @
c5781c69
...
@@ -5,7 +5,7 @@ import (
...
@@ -5,7 +5,7 @@ import (
"fmt"
"fmt"
"time"
"time"
infraerrors
"github.com/Wei-Shaw/sub2api/internal/
infrastructure
/errors"
infraerrors
"github.com/Wei-Shaw/sub2api/internal/
pkg
/errors"
"github.com/Wei-Shaw/sub2api/internal/pkg/pagination"
"github.com/Wei-Shaw/sub2api/internal/pkg/pagination"
"github.com/Wei-Shaw/sub2api/internal/pkg/usagestats"
"github.com/Wei-Shaw/sub2api/internal/pkg/usagestats"
)
)
...
...
backend/internal/service/user_service.go
View file @
c5781c69
...
@@ -4,7 +4,7 @@ import (
...
@@ -4,7 +4,7 @@ import (
"context"
"context"
"fmt"
"fmt"
infraerrors
"github.com/Wei-Shaw/sub2api/internal/
infrastructure
/errors"
infraerrors
"github.com/Wei-Shaw/sub2api/internal/
pkg
/errors"
"github.com/Wei-Shaw/sub2api/internal/pkg/pagination"
"github.com/Wei-Shaw/sub2api/internal/pkg/pagination"
)
)
...
...
backend/internal/setup/setup.go
View file @
c5781c69
...
@@ -11,7 +11,7 @@ import (
...
@@ -11,7 +11,7 @@ import (
"strconv"
"strconv"
"time"
"time"
"github.com/Wei-Shaw/sub2api/internal/
infrastructure
"
"github.com/Wei-Shaw/sub2api/internal/
repository
"
"github.com/Wei-Shaw/sub2api/internal/service"
"github.com/Wei-Shaw/sub2api/internal/service"
_
"github.com/lib/pq"
_
"github.com/lib/pq"
...
@@ -262,7 +262,7 @@ func initializeDatabase(cfg *SetupConfig) error {
...
@@ -262,7 +262,7 @@ func initializeDatabase(cfg *SetupConfig) error {
migrationCtx
,
cancel
:=
context
.
WithTimeout
(
context
.
Background
(),
60
*
time
.
Second
)
migrationCtx
,
cancel
:=
context
.
WithTimeout
(
context
.
Background
(),
60
*
time
.
Second
)
defer
cancel
()
defer
cancel
()
return
infrastructure
.
ApplyMigrations
(
migrationCtx
,
db
)
return
repository
.
ApplyMigrations
(
migrationCtx
,
db
)
}
}
func
createAdminUser
(
cfg
*
SetupConfig
)
error
{
func
createAdminUser
(
cfg
*
SetupConfig
)
error
{
...
...
deploy/config.example.yaml
View file @
c5781c69
...
@@ -122,6 +122,21 @@ pricing:
...
@@ -122,6 +122,21 @@ pricing:
# Hash check interval in minutes
# Hash check interval in minutes
hash_check_interval_minutes
:
10
hash_check_interval_minutes
:
10
# =============================================================================
# Gateway (Optional)
# =============================================================================
gateway
:
# Wait time (in seconds) for upstream response headers (streaming body not affected)
response_header_timeout
:
300
# Log upstream error response body summary (safe/truncated; does not log request content)
log_upstream_error_body
:
false
# Max bytes to log from upstream error body
log_upstream_error_body_max_bytes
:
2048
# Auto inject anthropic-beta for API-key accounts when needed (default off)
inject_beta_for_apikey
:
false
# Allow failover on selected 400 errors (default off)
failover_on_400
:
false
# =============================================================================
# =============================================================================
# Gemini OAuth (Required for Gemini accounts)
# Gemini OAuth (Required for Gemini accounts)
# =============================================================================
# =============================================================================
...
...
frontend/package-lock.json
View file @
c5781c69
...
@@ -952,6 +952,7 @@
...
@@ -952,6 +952,7 @@
"integrity"
:
"sha512-N2clP5pJhB2YnZJ3PIHFk5RkygRX5WO/5f0WC08tp0wd+sv0rsJk3MqWn3CbNmT2J505a5336jaQj4ph1AdMug=="
,
"integrity"
:
"sha512-N2clP5pJhB2YnZJ3PIHFk5RkygRX5WO/5f0WC08tp0wd+sv0rsJk3MqWn3CbNmT2J505a5336jaQj4ph1AdMug=="
,
"dev"
:
true
,
"dev"
:
true
,
"license"
:
"MIT"
,
"license"
:
"MIT"
,
"peer"
:
true
,
"dependencies"
:
{
"dependencies"
:
{
"undici-types"
:
"~6.21.0"
"undici-types"
:
"~6.21.0"
}
}
...
@@ -1367,6 +1368,7 @@
...
@@ -1367,6 +1368,7 @@
}
}
],
],
"license"
:
"MIT"
,
"license"
:
"MIT"
,
"peer"
:
true
,
"dependencies"
:
{
"dependencies"
:
{
"baseline-browser-mapping"
:
"^2.9.0"
,
"baseline-browser-mapping"
:
"^2.9.0"
,
"caniuse-lite"
:
"^1.0.30001759"
,
"caniuse-lite"
:
"^1.0.30001759"
,
...
@@ -1443,6 +1445,7 @@
...
@@ -1443,6 +1445,7 @@
"resolved"
:
"https://registry.npmmirror.com/chart.js/-/chart.js-4.5.1.tgz"
,
"resolved"
:
"https://registry.npmmirror.com/chart.js/-/chart.js-4.5.1.tgz"
,
"integrity"
:
"sha512-GIjfiT9dbmHRiYi6Nl2yFCq7kkwdkp1W/lp2J99rX0yo9tgJGn3lKQATztIjb5tVtevcBtIdICNWqlq5+E8/Pw=="
,
"integrity"
:
"sha512-GIjfiT9dbmHRiYi6Nl2yFCq7kkwdkp1W/lp2J99rX0yo9tgJGn3lKQATztIjb5tVtevcBtIdICNWqlq5+E8/Pw=="
,
"license"
:
"MIT"
,
"license"
:
"MIT"
,
"peer"
:
true
,
"dependencies"
:
{
"dependencies"
:
{
"@kurkle/color"
:
"^0.3.0"
"@kurkle/color"
:
"^0.3.0"
},
},
...
@@ -2040,6 +2043,7 @@
...
@@ -2040,6 +2043,7 @@
"integrity"
:
"sha512-/imKNG4EbWNrVjoNC/1H5/9GFy+tqjGBHCaSsN+P2RnPqjsLmv6UD3Ej+Kj8nBWaRAwyk7kK5ZUc+OEatnTR3A=="
,
"integrity"
:
"sha512-/imKNG4EbWNrVjoNC/1H5/9GFy+tqjGBHCaSsN+P2RnPqjsLmv6UD3Ej+Kj8nBWaRAwyk7kK5ZUc+OEatnTR3A=="
,
"dev"
:
true
,
"dev"
:
true
,
"license"
:
"MIT"
,
"license"
:
"MIT"
,
"peer"
:
true
,
"bin"
:
{
"bin"
:
{
"jiti"
:
"bin/jiti.js"
"jiti"
:
"bin/jiti.js"
}
}
...
@@ -2348,6 +2352,7 @@
...
@@ -2348,6 +2352,7 @@
}
}
],
],
"license"
:
"MIT"
,
"license"
:
"MIT"
,
"peer"
:
true
,
"dependencies"
:
{
"dependencies"
:
{
"nanoid"
:
"^3.3.11"
,
"nanoid"
:
"^3.3.11"
,
"picocolors"
:
"^1.1.1"
,
"picocolors"
:
"^1.1.1"
,
...
@@ -2821,6 +2826,7 @@
...
@@ -2821,6 +2826,7 @@
"integrity"
:
"sha512-5gTmgEY/sqK6gFXLIsQNH19lWb4ebPDLA4SdLP7dsWkIXHWlG66oPuVvXSGFPppYZz8ZDZq0dYYrbHfBCVUb1Q=="
,
"integrity"
:
"sha512-5gTmgEY/sqK6gFXLIsQNH19lWb4ebPDLA4SdLP7dsWkIXHWlG66oPuVvXSGFPppYZz8ZDZq0dYYrbHfBCVUb1Q=="
,
"dev"
:
true
,
"dev"
:
true
,
"license"
:
"MIT"
,
"license"
:
"MIT"
,
"peer"
:
true
,
"engines"
:
{
"engines"
:
{
"node"
:
">=12"
"node"
:
">=12"
},
},
...
@@ -2854,6 +2860,7 @@
...
@@ -2854,6 +2860,7 @@
"integrity"
:
"sha512-hjcS1mhfuyi4WW8IWtjP7brDrG2cuDZukyrYrSauoXGNgx0S7zceP07adYkJycEr56BOUTNPzbInooiN3fn1qw=="
,
"integrity"
:
"sha512-hjcS1mhfuyi4WW8IWtjP7brDrG2cuDZukyrYrSauoXGNgx0S7zceP07adYkJycEr56BOUTNPzbInooiN3fn1qw=="
,
"devOptional"
:
true
,
"devOptional"
:
true
,
"license"
:
"Apache-2.0"
,
"license"
:
"Apache-2.0"
,
"peer"
:
true
,
"bin"
:
{
"bin"
:
{
"tsc"
:
"bin/tsc"
,
"tsc"
:
"bin/tsc"
,
"tsserver"
:
"bin/tsserver"
"tsserver"
:
"bin/tsserver"
...
@@ -2926,6 +2933,7 @@
...
@@ -2926,6 +2933,7 @@
"integrity"
:
"sha512-o5a9xKjbtuhY6Bi5S3+HvbRERmouabWbyUcpXXUA1u+GNUKoROi9byOJ8M0nHbHYHkYICiMlqxkg1KkYmm25Sw=="
,
"integrity"
:
"sha512-o5a9xKjbtuhY6Bi5S3+HvbRERmouabWbyUcpXXUA1u+GNUKoROi9byOJ8M0nHbHYHkYICiMlqxkg1KkYmm25Sw=="
,
"dev"
:
true
,
"dev"
:
true
,
"license"
:
"MIT"
,
"license"
:
"MIT"
,
"peer"
:
true
,
"dependencies"
:
{
"dependencies"
:
{
"esbuild"
:
"^0.21.3"
,
"esbuild"
:
"^0.21.3"
,
"postcss"
:
"^8.4.43"
,
"postcss"
:
"^8.4.43"
,
...
@@ -3097,6 +3105,7 @@
...
@@ -3097,6 +3105,7 @@
"resolved"
:
"https://registry.npmmirror.com/vue/-/vue-3.5.25.tgz"
,
"resolved"
:
"https://registry.npmmirror.com/vue/-/vue-3.5.25.tgz"
,
"integrity"
:
"sha512-YLVdgv2K13WJ6n+kD5owehKtEXwdwXuj2TTyJMsO7pSeKw2bfRNZGjhB7YzrpbMYj5b5QsUebHpOqR3R3ziy/g=="
,
"integrity"
:
"sha512-YLVdgv2K13WJ6n+kD5owehKtEXwdwXuj2TTyJMsO7pSeKw2bfRNZGjhB7YzrpbMYj5b5QsUebHpOqR3R3ziy/g=="
,
"license"
:
"MIT"
,
"license"
:
"MIT"
,
"peer"
:
true
,
"dependencies"
:
{
"dependencies"
:
{
"@vue/compiler-dom"
:
"3.5.25"
,
"@vue/compiler-dom"
:
"3.5.25"
,
"@vue/compiler-sfc"
:
"3.5.25"
,
"@vue/compiler-sfc"
:
"3.5.25"
,
...
@@ -3190,6 +3199,7 @@
...
@@ -3190,6 +3199,7 @@
"integrity"
:
"sha512-P7OP77b2h/Pmk+lZdJ0YWs+5tJ6J2+uOQPo7tlBnY44QqQSPYvS0qVT4wqDJgwrZaLe47etJLLQRFia71GYITw=="
,
"integrity"
:
"sha512-P7OP77b2h/Pmk+lZdJ0YWs+5tJ6J2+uOQPo7tlBnY44QqQSPYvS0qVT4wqDJgwrZaLe47etJLLQRFia71GYITw=="
,
"dev"
:
true
,
"dev"
:
true
,
"license"
:
"MIT"
,
"license"
:
"MIT"
,
"peer"
:
true
,
"dependencies"
:
{
"dependencies"
:
{
"@volar/typescript"
:
"2.4.15"
,
"@volar/typescript"
:
"2.4.15"
,
"@vue/language-core"
:
"2.2.12"
"@vue/language-core"
:
"2.2.12"
...
...
frontend/src/components/account/AccountStatusIndicator.vue
View file @
c5781c69
...
@@ -83,6 +83,14 @@
...
@@ -83,6 +83,14 @@
></div>
></div>
</div>
</div>
</div>
</div>
<!-- Tier Indicator -->
<span
v-if=
"tierDisplay"
class=
"inline-flex items-center rounded bg-blue-100 px-1.5 py-0.5 text-xs font-medium text-blue-700 dark:bg-blue-900/30 dark:text-blue-400"
>
{{
tierDisplay
}}
</span>
</div>
</div>
</
template
>
</
template
>
...
@@ -140,4 +148,23 @@ const statusText = computed(() => {
...
@@ -140,4 +148,23 @@ const statusText = computed(() => {
return
props
.
account
.
status
return
props
.
account
.
status
})
})
// Computed: tier display
const
tierDisplay
=
computed
(()
=>
{
const
credentials
=
props
.
account
.
credentials
as
Record
<
string
,
any
>
|
undefined
const
tierId
=
credentials
?.
tier_id
if
(
!
tierId
||
tierId
===
'
unknown
'
)
return
null
const
tierMap
:
Record
<
string
,
string
>
=
{
'
free
'
:
'
Free
'
,
'
payg
'
:
'
Pay-as-you-go
'
,
'
pay-as-you-go
'
:
'
Pay-as-you-go
'
,
'
enterprise
'
:
'
Enterprise
'
,
'
LEGACY
'
:
'
Legacy
'
,
'
PRO
'
:
'
Pro
'
,
'
ULTRA
'
:
'
Ultra
'
}
return
tierMap
[
tierId
]
||
tierId
})
</
script
>
</
script
>
Prev
1
2
3
Next
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