sync: bring over remaining release/custom-0.1.115 changes
- Extract PublicSettingsInjectionPayload named struct with drift test - Add channel_monitor_default_interval_seconds to SSR injection - Add image_output_price to SupportedModelChip - Simplify AppSidebar buildSelfNavItems (admins see available channels) - Add gateway WARN logs for 503 no-available-accounts branches - Wire ChannelMonitorRunner into provideCleanup for graceful shutdown - Add migrations 130/131 (CC template userid fix + mimicry field cleanup) - Clean up fork-only features (sora, claude max simulation, client affinity) - Remove ~320 obsolete i18n keys - Add codexUsage utility, WechatServiceButton, BulkEditAccountModal - Tidy go.sum
This commit is contained in:
@@ -1665,8 +1665,6 @@ export default {
|
||||
failedToLoadApiKeys: 'Failed to load user API keys',
|
||||
emailRequired: 'Please enter email',
|
||||
concurrencyMin: 'Concurrency must be at least 1',
|
||||
soraStorageQuota: 'Sora Storage Quota',
|
||||
soraStorageQuotaHint: 'In GB, 0 means use group or system default quota',
|
||||
amountRequired: 'Please enter a valid amount',
|
||||
insufficientBalance: 'Insufficient balance',
|
||||
deleteConfirm: "Are you sure you want to delete '{email}'? This action cannot be undone.",
|
||||
@@ -1999,14 +1997,6 @@ export default {
|
||||
enabled: 'Enabled',
|
||||
disabled: 'Disabled'
|
||||
},
|
||||
claudeMaxSimulation: {
|
||||
title: 'Claude Max Usage Simulation',
|
||||
tooltip:
|
||||
'When enabled, for Claude models without upstream cache-write usage, the system deterministically maps tokens to a small input plus 1h cache creation while keeping total tokens unchanged.',
|
||||
enabled: 'Enabled (simulate 1h cache)',
|
||||
disabled: 'Disabled',
|
||||
hint: 'Only token categories in usage billing logs are adjusted. No per-request mapping state is persisted.'
|
||||
},
|
||||
supportedScopes: {
|
||||
title: 'Supported Model Families',
|
||||
tooltip: 'Select the model families this group supports. Unchecked families will not be routed to this group.',
|
||||
@@ -2640,7 +2630,7 @@ export default {
|
||||
resetQuota: 'Reset Quota',
|
||||
quotaLimit: 'Quota Limit',
|
||||
quotaLimitPlaceholder: '0 means unlimited',
|
||||
quotaLimitHint: 'Set daily/weekly/total spending limits (USD). Anthropic API key accounts can also configure client affinity. Changing limits won\'t reset usage.',
|
||||
quotaLimitHint: 'Set daily/weekly/total spending limits (USD). Changing limits won\'t reset usage.',
|
||||
quotaLimitToggle: 'Enable Quota Limit',
|
||||
quotaLimitToggleHint: 'When enabled, account will be paused when usage reaches the set limit',
|
||||
quotaDailyLimit: 'Daily Limit',
|
||||
@@ -2844,7 +2834,7 @@ export default {
|
||||
// Quota control (Anthropic OAuth/SetupToken only)
|
||||
quotaControl: {
|
||||
title: 'Quota Control',
|
||||
hint: 'Configure cost window, session limits, client affinity and other scheduling controls.',
|
||||
hint: 'Configure cost windows, session limits and other scheduling controls.',
|
||||
windowCost: {
|
||||
label: '5h Window Cost Limit',
|
||||
hint: 'Limit account cost usage within the 5-hour window',
|
||||
@@ -2890,7 +2880,7 @@ export default {
|
||||
label: 'TLS Fingerprint Simulation',
|
||||
hint: 'Simulate Node.js/Claude Code client TLS fingerprint',
|
||||
defaultProfile: 'Built-in Default',
|
||||
randomProfile: 'Random'
|
||||
randomProfile: 'Random',
|
||||
},
|
||||
sessionIdMasking: {
|
||||
label: 'Session ID Masking',
|
||||
@@ -2907,25 +2897,7 @@ export default {
|
||||
hint: 'Forward requests to a custom relay service. Proxy URL will be passed as a query parameter.',
|
||||
urlHint: 'Relay service URL (e.g., https://relay.example.com)',
|
||||
},
|
||||
clientAffinity: {
|
||||
label: 'Client Affinity Scheduling',
|
||||
hint: 'When enabled, new sessions prefer accounts previously used by this client to reduce account switching'
|
||||
}
|
||||
},
|
||||
affinityNoClients: 'No affinity clients',
|
||||
affinityClients: '{count} affinity clients:',
|
||||
affinitySection: 'Client Affinity',
|
||||
affinitySectionHint: 'Control how clients are distributed across accounts. Configure zone thresholds to balance load.',
|
||||
affinityToggle: 'Enable Client Affinity',
|
||||
affinityToggleHint: 'New sessions prefer accounts previously used by this client',
|
||||
affinityBase: 'Base Limit (Green Zone)',
|
||||
affinityBasePlaceholder: 'Empty = no limit',
|
||||
affinityBaseHint: 'Max clients in green zone (full priority scheduling)',
|
||||
affinityBaseOffHint: 'No green zone limit. All clients receive full priority scheduling.',
|
||||
affinityBuffer: 'Buffer (Yellow Zone)',
|
||||
affinityBufferPlaceholder: 'e.g. 3',
|
||||
affinityBufferHint: 'Additional clients allowed in the yellow zone (degraded priority)',
|
||||
affinityBufferInfinite: 'Unlimited',
|
||||
expired: 'Expired',
|
||||
proxy: 'Proxy',
|
||||
noProxy: 'No Proxy',
|
||||
@@ -4947,12 +4919,6 @@ export default {
|
||||
integrationDoc: 'Payment Integration Docs',
|
||||
integrationDocHint: 'Covers endpoint specs, idempotency semantics, and code samples'
|
||||
},
|
||||
soraClient: {
|
||||
title: 'Sora Client',
|
||||
description: 'Control whether to show the Sora client entry in the sidebar',
|
||||
enabled: 'Enable Sora Client',
|
||||
enabledHint: 'When enabled, the Sora entry will be shown in the sidebar for users to access Sora features'
|
||||
},
|
||||
customMenu: {
|
||||
title: 'Custom Menu Pages',
|
||||
description: 'Add custom iframe pages to the sidebar navigation. Each page can be visible to regular users or administrators.',
|
||||
@@ -5044,8 +5010,6 @@ export default {
|
||||
field_certSerial: 'Certificate Serial',
|
||||
field_h5AppName: 'H5 App Name',
|
||||
field_h5AppUrl: 'H5 App URL',
|
||||
wxpayConfigHint: 'WeChat Pay usually only needs App ID. Fill MP App ID, H5 App Name, and H5 App URL only when your Official Account or H5 flow specifically requires them.',
|
||||
wxpayAdvancedOptions: 'WeChat Pay Advanced Options',
|
||||
field_secretKey: 'Secret Key',
|
||||
field_publishableKey: 'Publishable Key',
|
||||
field_webhookSecret: 'Webhook Secret',
|
||||
@@ -5076,37 +5040,6 @@ export default {
|
||||
providerKey: 'Provider Type',
|
||||
selectProviderKey: 'Select Provider Type',
|
||||
providerConfig: 'Credentials',
|
||||
paymentGuideTrigger: 'View payment guide',
|
||||
guideOpenLabel: 'Enable: ',
|
||||
guideCallLabel: 'Call: ',
|
||||
guideFallbackLabel: 'Fallback: ',
|
||||
alipayGuideSummary: 'Desktop prefers QR precreate and falls back to cashier; mobile prefers WAP checkout.',
|
||||
alipayGuideFaceToFaceTitle: 'Face-to-face / QR Payment',
|
||||
alipayGuideFaceToFaceOpen: 'Enable face-to-face or QR payment capability.',
|
||||
alipayGuideFaceToFaceCall: 'Desktop orders call alipay.trade.precreate first and render the QR code directly.',
|
||||
alipayGuideFaceToFaceFallback: 'If unavailable or failed, the flow falls back to website checkout automatically.',
|
||||
alipayGuidePagePayTitle: 'Website Payment',
|
||||
alipayGuidePagePayOpen: 'Enable website payment.',
|
||||
alipayGuidePagePayCall: 'When face-to-face is unavailable on desktop, the flow calls alipay.trade.page.pay and still renders the returned link as a QR code.',
|
||||
alipayGuidePagePayFallback: 'The cashier link stays available so users can reopen the checkout page manually.',
|
||||
alipayGuideWapTitle: 'WAP Payment',
|
||||
alipayGuideWapOpen: 'Enable mobile website payment.',
|
||||
alipayGuideWapCall: 'Mobile orders call alipay.trade.wap.pay first and jump to Alipay checkout.',
|
||||
alipayGuideWapFallback: 'If mobile payment is unavailable or fails, the frontend switches to QR payment and shows a notice.',
|
||||
wxpayGuideSummary: 'Desktop prefers Native QR; mobile routes to JSAPI or H5 based on browser context.',
|
||||
wxpayGuideNote: 'The current form defaults to one shared App ID, which fits the common single-subject web, mobile, and Official Account setup.',
|
||||
wxpayGuideNativeTitle: 'Native / QR Payment',
|
||||
wxpayGuideNativeOpen: 'Enable Native or QR payment capability.',
|
||||
wxpayGuideNativeCall: 'Desktop orders use Native by default and the frontend renders the QR payload.',
|
||||
wxpayGuideNativeFallback: 'Mobile flows also fall back here when JSAPI or H5 cannot be used.',
|
||||
wxpayGuideJsapiTitle: 'JSAPI / Official Account',
|
||||
wxpayGuideJsapiOpen: 'Enable Official Account payment and ensure the browser is inside WeChat with an available OpenID.',
|
||||
wxpayGuideJsapiCall: 'Inside WeChat, the app calls JSAPI after authorization and launches WeChat Pay directly.',
|
||||
wxpayGuideJsapiFallback: 'If configuration is missing, the bridge is unavailable, or launch fails, the flow falls back to QR payment.',
|
||||
wxpayGuideH5Title: 'H5 Payment',
|
||||
wxpayGuideH5Open: 'Enable H5 payment.',
|
||||
wxpayGuideH5Call: 'On mobile browsers outside WeChat, the app calls H5 payment when a client IP is available.',
|
||||
wxpayGuideH5Fallback: 'If H5 is unavailable or order creation fails, the flow falls back to QR payment.',
|
||||
noProviders: 'No provider instances configured',
|
||||
supportedTypes: 'Supported Payment Types',
|
||||
supportedTypesHint: 'Comma-separated, e.g. alipay,wxpay',
|
||||
@@ -5205,98 +5138,6 @@ export default {
|
||||
securityWarning: 'Warning: This key provides full admin access. Keep it secure.',
|
||||
usage: 'Usage: Add to request header - x-api-key: <your-admin-api-key>'
|
||||
},
|
||||
soraS3: {
|
||||
title: 'Sora Storage',
|
||||
description: 'Manage Sora media storage profiles with S3 and Google Drive support',
|
||||
newProfile: 'New Profile',
|
||||
reloadProfiles: 'Reload Profiles',
|
||||
empty: 'No storage profiles yet, create one first',
|
||||
createTitle: 'Create Storage Profile',
|
||||
editTitle: 'Edit Storage Profile',
|
||||
selectProvider: 'Select Storage Type',
|
||||
providerS3Desc: 'S3-compatible object storage',
|
||||
providerGDriveDesc: 'Google Drive cloud storage',
|
||||
profileID: 'Profile ID',
|
||||
profileName: 'Profile Name',
|
||||
setActive: 'Set as active after creation',
|
||||
saveProfile: 'Save Profile',
|
||||
activateProfile: 'Activate',
|
||||
profileCreated: 'Storage profile created',
|
||||
profileSaved: 'Storage profile saved',
|
||||
profileDeleted: 'Storage profile deleted',
|
||||
profileActivated: 'Active storage profile switched',
|
||||
profileIDRequired: 'Profile ID is required',
|
||||
profileNameRequired: 'Profile name is required',
|
||||
profileSelectRequired: 'Please select a profile first',
|
||||
endpointRequired: 'S3 endpoint is required when enabled',
|
||||
bucketRequired: 'Bucket is required when enabled',
|
||||
accessKeyRequired: 'Access Key ID is required when enabled',
|
||||
deleteConfirm: 'Delete storage profile {profileID}?',
|
||||
columns: {
|
||||
profile: 'Profile',
|
||||
profileId: 'Profile ID',
|
||||
name: 'Name',
|
||||
provider: 'Type',
|
||||
active: 'Active',
|
||||
endpoint: 'Endpoint',
|
||||
bucket: 'Bucket',
|
||||
storagePath: 'Storage Path',
|
||||
capacityUsage: 'Capacity / Used',
|
||||
capacityUnlimited: 'Unlimited',
|
||||
videoCount: 'Videos',
|
||||
videoCompleted: 'completed',
|
||||
videoInProgress: 'in progress',
|
||||
quota: 'Default Quota',
|
||||
updatedAt: 'Updated At',
|
||||
actions: 'Actions',
|
||||
rootFolder: 'Root folder',
|
||||
testInTable: 'Test',
|
||||
testingInTable: 'Testing...',
|
||||
testTimeout: 'Test timed out (15s)'
|
||||
},
|
||||
enabled: 'Enable Storage',
|
||||
enabledHint: 'When enabled, Sora generated media files will be automatically uploaded',
|
||||
endpoint: 'S3 Endpoint',
|
||||
region: 'Region',
|
||||
bucket: 'Bucket',
|
||||
prefix: 'Object Prefix',
|
||||
accessKeyId: 'Access Key ID',
|
||||
secretAccessKey: 'Secret Access Key',
|
||||
secretConfigured: '(Configured, leave blank to keep)',
|
||||
cdnUrl: 'CDN URL',
|
||||
cdnUrlHint: 'Optional. When configured, files are accessed via CDN URL',
|
||||
forcePathStyle: 'Force Path Style',
|
||||
defaultQuota: 'Default Storage Quota',
|
||||
defaultQuotaHint: 'Default quota when not specified at user or group level. 0 means unlimited',
|
||||
testConnection: 'Test Connection',
|
||||
testing: 'Testing...',
|
||||
testSuccess: 'Connection test successful',
|
||||
testFailed: 'Connection test failed',
|
||||
saved: 'Storage settings saved successfully',
|
||||
saveFailed: 'Failed to save storage settings',
|
||||
gdrive: {
|
||||
authType: 'Authentication Method',
|
||||
serviceAccount: 'Service Account',
|
||||
clientId: 'Client ID',
|
||||
clientSecret: 'Client Secret',
|
||||
clientSecretConfigured: '(Configured, leave blank to keep)',
|
||||
refreshToken: 'Refresh Token',
|
||||
refreshTokenConfigured: '(Configured, leave blank to keep)',
|
||||
serviceAccountJson: 'Service Account JSON',
|
||||
serviceAccountConfigured: '(Configured, leave blank to keep)',
|
||||
folderId: 'Folder ID (optional)',
|
||||
authorize: 'Authorize Google Drive',
|
||||
authorizeHint: 'Get Refresh Token via OAuth2',
|
||||
oauthFieldsRequired: 'Please fill in Client ID and Client Secret first',
|
||||
oauthSuccess: 'Google Drive authorization successful',
|
||||
oauthFailed: 'Google Drive authorization failed',
|
||||
closeWindow: 'This window will close automatically',
|
||||
processing: 'Processing authorization...',
|
||||
testStorage: 'Test Storage',
|
||||
testSuccess: 'Google Drive storage test passed (upload, access, delete all OK)',
|
||||
testFailed: 'Google Drive storage test failed'
|
||||
}
|
||||
},
|
||||
overloadCooldown: {
|
||||
title: '529 Overload Cooldown',
|
||||
description: 'Configure account scheduling pause strategy when upstream returns 529 (overloaded)',
|
||||
@@ -5963,7 +5804,6 @@ export default {
|
||||
wechatOpenInWeChatHint: 'Open the current page inside WeChat, or switch to desktop WeChat QR payment.',
|
||||
wechatScanOnDesktopHint: 'On desktop, use WeChat Scan to pay; on mobile, reopen the current page inside WeChat.',
|
||||
wechatSwitchBrowserHint: 'Switch to desktop WeChat QR payment, or reopen this page in an external browser and retry.',
|
||||
mobilePaymentFallbackToQr: 'This merchant has not enabled mobile payment. The flow has been switched to QR payment automatically.',
|
||||
alipayDesktopUnavailable: 'The desktop Alipay flow could not generate a QR code.',
|
||||
alipayDesktopQrHint: 'Desktop Alipay should render a QR code. Refresh and retry, or make sure the payment page was not blocked.',
|
||||
alipayMobileUnavailable: 'This page could not hand off to Alipay.',
|
||||
|
||||
Reference in New Issue
Block a user