merge: 合并主分支改动并保留 ops 监控实现
合并 main 分支的最新改动到 ops 监控分支。 冲突解决策略:保留当前分支的 ops 相关改动,接受主分支的其他改动。 保留的 ops 改动: - 运维监控配置和依赖注入 - 运维监控 API 处理器和中间件 - 运维监控服务层和数据访问层 - 运维监控前端界面和状态管理 接受的主分支改动: - Linux DO OAuth 集成 - 账号过期功能 - IP 地址限制功能 - 用量统计优化 - 其他 bug 修复和功能改进
This commit is contained in:
@@ -233,6 +233,15 @@ export default {
|
||||
sendingCode: 'Sending...',
|
||||
clickToResend: 'Click to resend code',
|
||||
resendCode: 'Resend verification code',
|
||||
linuxdo: {
|
||||
signIn: 'Continue with Linux.do',
|
||||
orContinue: 'or continue with email',
|
||||
callbackTitle: 'Signing you in',
|
||||
callbackProcessing: 'Completing login, please wait...',
|
||||
callbackHint: 'If you are not redirected automatically, go back to the login page and try again.',
|
||||
callbackMissingToken: 'Missing login token, please try again.',
|
||||
backToLogin: 'Back to Login'
|
||||
},
|
||||
oauth: {
|
||||
code: 'Code',
|
||||
state: 'State',
|
||||
@@ -365,6 +374,14 @@ export default {
|
||||
customKeyTooShort: 'Custom key must be at least 16 characters',
|
||||
customKeyInvalidChars: 'Custom key can only contain letters, numbers, underscores, and hyphens',
|
||||
customKeyRequired: 'Please enter a custom key',
|
||||
ipRestriction: 'IP Restriction',
|
||||
ipWhitelist: 'IP Whitelist',
|
||||
ipWhitelistPlaceholder: '192.168.1.100\n10.0.0.0/8',
|
||||
ipWhitelistHint: 'One IP or CIDR per line. Only these IPs can use this key when set.',
|
||||
ipBlacklist: 'IP Blacklist',
|
||||
ipBlacklistPlaceholder: '1.2.3.4\n5.6.0.0/16',
|
||||
ipBlacklistHint: 'One IP or CIDR per line. These IPs will be blocked from using this key.',
|
||||
ipRestrictionEnabled: 'IP restriction enabled',
|
||||
ccSwitchNotInstalled: 'CC-Switch is not installed or the protocol handler is not registered. Please install CC-Switch first or manually copy the API key.',
|
||||
ccsClientSelect: {
|
||||
title: 'Select Client',
|
||||
@@ -380,6 +397,8 @@ export default {
|
||||
usage: {
|
||||
title: 'Usage Records',
|
||||
description: 'View and analyze your API usage history',
|
||||
costDetails: 'Cost Breakdown',
|
||||
tokenDetails: 'Token Breakdown',
|
||||
totalRequests: 'Total Requests',
|
||||
totalTokens: 'Total Tokens',
|
||||
totalCost: 'Total Cost',
|
||||
@@ -423,10 +442,8 @@ export default {
|
||||
exportFailed: 'Failed to export usage data',
|
||||
exportExcelSuccess: 'Usage data exported successfully (Excel format)',
|
||||
exportExcelFailed: 'Failed to export usage data',
|
||||
billingType: 'Billing',
|
||||
balance: 'Balance',
|
||||
subscription: 'Subscription',
|
||||
imageUnit: ' images'
|
||||
imageUnit: ' images',
|
||||
userAgent: 'User-Agent'
|
||||
},
|
||||
|
||||
// Redeem
|
||||
@@ -858,6 +875,15 @@ export default {
|
||||
imagePricing: {
|
||||
title: 'Image Generation Pricing',
|
||||
description: 'Configure pricing for gemini-3-pro-image model. Leave empty to use default prices.'
|
||||
},
|
||||
claudeCode: {
|
||||
title: 'Claude Code Client Restriction',
|
||||
tooltip: 'When enabled, this group only allows official Claude Code clients. Non-Claude Code requests will be rejected or fallback to the specified group.',
|
||||
enabled: 'Claude Code Only',
|
||||
disabled: 'Allow All Clients',
|
||||
fallbackGroup: 'Fallback Group',
|
||||
fallbackHint: 'Non-Claude Code requests will use this group. Leave empty to reject directly.',
|
||||
noFallback: 'No Fallback (Reject)'
|
||||
}
|
||||
},
|
||||
|
||||
@@ -1013,6 +1039,7 @@ export default {
|
||||
groups: 'Groups',
|
||||
usageWindows: 'Usage Windows',
|
||||
lastUsed: 'Last Used',
|
||||
expiresAt: 'Expires At',
|
||||
actions: 'Actions'
|
||||
},
|
||||
tempUnschedulable: {
|
||||
@@ -1067,12 +1094,16 @@ export default {
|
||||
tokenRefreshed: 'Token refreshed successfully',
|
||||
accountDeleted: 'Account deleted successfully',
|
||||
rateLimitCleared: 'Rate limit cleared successfully',
|
||||
bulkSchedulableEnabled: 'Successfully enabled scheduling for {count} account(s)',
|
||||
bulkSchedulableDisabled: 'Successfully disabled scheduling for {count} account(s)',
|
||||
bulkActions: {
|
||||
selected: '{count} account(s) selected',
|
||||
selectCurrentPage: 'Select this page',
|
||||
clear: 'Clear selection',
|
||||
edit: 'Bulk Edit',
|
||||
delete: 'Bulk Delete'
|
||||
delete: 'Bulk Delete',
|
||||
enableScheduling: 'Enable Scheduling',
|
||||
disableScheduling: 'Disable Scheduling'
|
||||
},
|
||||
bulkEdit: {
|
||||
title: 'Bulk Edit Accounts',
|
||||
@@ -1154,12 +1185,17 @@ export default {
|
||||
interceptWarmupRequests: 'Intercept Warmup Requests',
|
||||
interceptWarmupRequestsDesc:
|
||||
'When enabled, warmup requests like title generation will return mock responses without consuming upstream tokens',
|
||||
autoPauseOnExpired: 'Auto Pause On Expired',
|
||||
autoPauseOnExpiredDesc: 'When enabled, the account will auto pause scheduling after it expires',
|
||||
expired: 'Expired',
|
||||
proxy: 'Proxy',
|
||||
noProxy: 'No Proxy',
|
||||
concurrency: 'Concurrency',
|
||||
priority: 'Priority',
|
||||
priorityHint: 'Higher priority accounts are used first',
|
||||
higherPriorityFirst: 'Higher value means higher priority',
|
||||
priorityHint: 'Lower value accounts are used first',
|
||||
expiresAt: 'Expires At',
|
||||
expiresAtHint: 'Leave empty for no expiration',
|
||||
higherPriorityFirst: 'Lower value means higher priority',
|
||||
mixedScheduling: 'Use in /v1/messages',
|
||||
mixedSchedulingHint: 'Enable to participate in Anthropic/Gemini group scheduling',
|
||||
mixedSchedulingTooltip:
|
||||
@@ -1472,6 +1508,7 @@ export default {
|
||||
testing: 'Testing...',
|
||||
retry: 'Retry',
|
||||
copyOutput: 'Copy output',
|
||||
outputCopied: 'Output copied',
|
||||
startingTestForAccount: 'Starting test for account: {name}',
|
||||
testAccountTypeLabel: 'Account type: {type}',
|
||||
selectTestModel: 'Select Test Model',
|
||||
@@ -1556,6 +1593,7 @@ export default {
|
||||
protocol: 'Protocol',
|
||||
address: 'Address',
|
||||
status: 'Status',
|
||||
accounts: 'Accounts',
|
||||
actions: 'Actions'
|
||||
},
|
||||
testConnection: 'Test Connection',
|
||||
@@ -1695,6 +1733,7 @@ export default {
|
||||
userFilter: 'User',
|
||||
searchUserPlaceholder: 'Search user by email...',
|
||||
searchApiKeyPlaceholder: 'Search API key by name...',
|
||||
searchAccountPlaceholder: 'Search account by name...',
|
||||
selectedUser: 'Selected',
|
||||
user: 'User',
|
||||
account: 'Account',
|
||||
@@ -1705,7 +1744,6 @@ export default {
|
||||
allAccounts: 'All Accounts',
|
||||
allGroups: 'All Groups',
|
||||
allTypes: 'All Types',
|
||||
allBillingTypes: 'All Billing',
|
||||
inputCost: 'Input Cost',
|
||||
outputCost: 'Output Cost',
|
||||
cacheCreationCost: 'Cache Creation Cost',
|
||||
@@ -1714,7 +1752,8 @@ export default {
|
||||
outputTokens: 'Output Tokens',
|
||||
cacheCreationTokens: 'Cache Creation Tokens',
|
||||
cacheReadTokens: 'Cache Read Tokens',
|
||||
failedToLoad: 'Failed to load usage records'
|
||||
failedToLoad: 'Failed to load usage records',
|
||||
ipAddress: 'IP'
|
||||
},
|
||||
|
||||
// Ops Monitoring
|
||||
@@ -2207,6 +2246,26 @@ export default {
|
||||
cloudflareDashboard: 'Cloudflare Dashboard',
|
||||
secretKeyHint: 'Server-side verification key (keep this secret)',
|
||||
secretKeyConfiguredHint: 'Secret key configured. Leave empty to keep the current value.' },
|
||||
linuxdo: {
|
||||
title: 'LinuxDo Connect Login',
|
||||
description: 'Configure LinuxDo Connect OAuth for Sub2API end-user login',
|
||||
enable: 'Enable LinuxDo Login',
|
||||
enableHint: 'Show LinuxDo login on the login/register pages',
|
||||
clientId: 'Client ID',
|
||||
clientIdPlaceholder: 'e.g., hprJ5pC3...',
|
||||
clientIdHint: 'Get this from Connect.Linux.Do',
|
||||
clientSecret: 'Client Secret',
|
||||
clientSecretPlaceholder: '********',
|
||||
clientSecretHint: 'Used by backend to exchange tokens (keep it secret)',
|
||||
clientSecretConfiguredPlaceholder: '********',
|
||||
clientSecretConfiguredHint: 'Secret configured. Leave empty to keep the current value.',
|
||||
redirectUrl: 'Redirect URL',
|
||||
redirectUrlPlaceholder: 'https://your-domain.com/api/v1/auth/oauth/linuxdo/callback',
|
||||
redirectUrlHint:
|
||||
'Must match the redirect URL configured in Connect.Linux.Do (must be an absolute http(s) URL)',
|
||||
quickSetCopy: 'Generate & Copy (current site)',
|
||||
redirectUrlSetAndCopied: 'Redirect URL generated and copied to clipboard'
|
||||
},
|
||||
defaults: {
|
||||
title: 'Default User Settings',
|
||||
description: 'Default values for new users',
|
||||
@@ -2471,7 +2530,7 @@ export default {
|
||||
},
|
||||
accountPriority: {
|
||||
title: '⚖️ 4. Priority (Optional)',
|
||||
description: '<div style="line-height: 1.7;"><p style="margin-bottom: 12px;">Set the account call priority.</p><div style="padding: 8px 12px; background: #eff6ff; border-left: 3px solid #3b82f6; border-radius: 4px; font-size: 13px; margin-bottom: 12px;"><b>📊 Priority Rules:</b><ul style="margin: 8px 0 0 16px;"><li>Higher number = higher priority</li><li>System uses high-priority accounts first</li><li>Same priority = random selection</li></ul></div><p style="padding: 8px 12px; background: #f0fdf4; border-left: 3px solid #10b981; border-radius: 4px; font-size: 13px;"><b>💡 Use Case:</b> Set main account to high priority, backup accounts to low priority</p></div>',
|
||||
description: '<div style="line-height: 1.7;"><p style="margin-bottom: 12px;">Set the account call priority.</p><div style="padding: 8px 12px; background: #eff6ff; border-left: 3px solid #3b82f6; border-radius: 4px; font-size: 13px; margin-bottom: 12px;"><b>📊 Priority Rules:</b><ul style="margin: 8px 0 0 16px;"><li>Lower number = higher priority</li><li>System uses low-value accounts first</li><li>Same priority = random selection</li></ul></div><p style="padding: 8px 12px; background: #f0fdf4; border-left: 3px solid #10b981; border-radius: 4px; font-size: 13px;"><b>💡 Use Case:</b> Set main account to lower value, backup accounts to higher value</p></div>',
|
||||
nextBtn: 'Next'
|
||||
},
|
||||
accountGroups: {
|
||||
|
||||
Reference in New Issue
Block a user