feat(frontend): persist model pricing sources

This commit is contained in:
ZheFox
2026-09-03 20:49:42 +08:00
parent 89b57464d2
commit 7b612b8b5a
8 changed files with 1288 additions and 146 deletions
+130
View File
@@ -323,6 +323,71 @@ export const messages = {
'models.externalCatalog.saved': '外部模型目录代理节点已保存',
'models.externalCatalog.saveFailed': '保存外部模型目录代理节点失败',
'models.externalCatalog.loadFailed': '加载外部模型目录代理节点失败',
'models.pricingSource.label': '价格来源',
'models.pricingSource.choose': '选择来源',
'models.pricingSource.currentTitle': '当前来源:{provider};选择其他来源会立即同步价格',
'models.pricingSource.chooseTitle': '选择来源并立即同步在线价格',
'models.pricingSource.editCurrentTitle': '当前来源:{provider};点击选择或重新同步',
'models.pricingSource.editChooseTitle': '选择并同步在线价格来源',
'models.pricingSource.syncingTitle': '正在同步在线价格',
'models.pricingSource.buttonCurrent': '价格来源 · {provider}',
'models.pricingSource.loading': '加载来源...',
'models.pricingSource.loadingOptions': '正在加载在线价格来源...',
'models.pricingSource.catalogEmpty': 'models.dev 暂无匹配来源',
'models.pricingSource.resyncTitle': '从当前来源重新同步价格',
'models.pricingSource.pendingDatabase': '待保存到数据库',
'models.pricingSource.incompatible': '计价不兼容',
'models.pricingSource.noTokenPrice': '无 Token 价格',
'models.pricingSource.inputPrice': '输入 ${price}',
'models.pricingSource.outputPrice': '输出 ${price}',
'models.pricingSource.sourceGone': '所选价格来源不再提供该模型,请刷新在线目录后重试',
'models.pricingSource.cannotSync': '无法同步',
'models.pricingSource.unsupported': '该来源包含当前计费引擎无法独立结算的{fields}',
'models.pricingSource.noUsablePrice': '该来源没有可用的 Token 价格',
'models.pricingSource.selectedAndSynced': '已选择 {provider} 并同步模型价格',
'models.pricingSource.updateFailed': '更新模型价格来源失败',
'models.pricingSource.syncFailed': '同步失败',
'models.pricingSource.savedNoPriceChange': '已保存 {provider} 为价格来源,当前价格无需更新',
'models.pricingField.reasoning': '推理 Token',
'models.pricingField.inputAudio': '输入音频 Token',
'models.pricingField.outputAudio': '输出音频 Token',
'models.management.selectedCount': '已选 {count} 个',
'models.management.manageSelectedTitle': '管理已选择的 {count} 个模型',
'models.management.batchButtonSelected': '批量操作 ({count})',
'models.management.batchButton': '批量管理',
'models.management.selectCurrentPage': '选择当前页模型',
'models.management.selectModel': '选择模型 {name}',
'models.management.batch.title': '快速筛选与批量操作',
'models.management.batch.description': '默认按每个模型保存在数据库中的在线来源同步,也可手动指定统一来源',
'models.management.batch.providerPlaceholder': '选择在线价格来源',
'models.management.batch.rememberedProvider': '上次选择(按模型)',
'models.management.batch.selectionEmpty': '选择模型后执行批量操作',
'models.management.batch.selectionSummary': '已选择 {selected} 个 · 可同步 {syncable} · 待保存来源 {sourcePending} · 已一致 {unchanged} · 不兼容 {unsupported} · 无在线价格 {unavailable}',
'models.management.batch.state.syncable': '价格可更新',
'models.management.batch.state.sourcePending': '来源待保存',
'models.management.batch.state.unchanged': '价格一致',
'models.management.batch.state.unsupported': '计价不兼容',
'models.management.batch.state.unavailable': '无在线价格',
'models.management.batch.source.noneSelected': '未选择来源',
'models.management.batch.source.noneRecorded': '未记录来源',
'models.management.batch.shortcut.syncable': '当前价格与所选供应商在线价格不同',
'models.management.batch.shortcut.sourcePending': '价格已一致,但来源尚未保存到数据库',
'models.management.batch.shortcut.unchanged': '当前价格与所选供应商在线价格一致',
'models.management.batch.shortcut.unsupported': '在线来源包含当前计费引擎无法独立结算的价格维度',
'models.management.batch.shortcut.unavailable': '所选供应商没有该模型的在线价格',
'models.management.batch.syncButton': '同步价格与来源 ({count})',
'models.management.batch.syncing': '同步中...',
'models.management.batch.confirmTitle': '批量同步价格与来源',
'models.management.batch.confirmMain': '将根据 {provider} 为 {count} 个模型同步在线价格并把价格来源保存到数据库。',
'models.management.batch.confirmSourceOnly': '其中 {count} 个模型价格已一致,只保存来源。',
'models.management.batch.confirmSkipped': '另有 {count} 个模型因价格已一致且来源已保存、计价不兼容或无在线价格而跳过。',
'models.management.batch.confirmUnchanged': '不会修改模型名称、能力或其他配置。',
'models.management.batch.confirmButton': '同步并保存',
'models.management.batch.rememberedProviderLabel': '各模型上次选择的提供商',
'models.management.batch.selectedProviderLabel': '所选供应商',
'models.management.batch.success': '成功同步 {count} 个模型的价格与来源',
'models.management.batch.partialFailure': '{count} 个模型同步失败:{details}',
'models.management.batch.catalogMissingPrice': '在线目录未提供价格配置',
'nav.routing': '调度策略',
'nav.pool': '号池管理',
'nav.standaloneKeys': '独立密钥',
@@ -675,6 +740,71 @@ export const messages = {
'models.externalCatalog.saved': 'External model catalog proxy saved',
'models.externalCatalog.saveFailed': 'Failed to save external model catalog proxy',
'models.externalCatalog.loadFailed': 'Failed to load external model catalog proxy',
'models.pricingSource.label': 'Price source',
'models.pricingSource.choose': 'Choose source',
'models.pricingSource.currentTitle': 'Current source: {provider}. Choosing another source syncs its prices immediately.',
'models.pricingSource.chooseTitle': 'Choose a source and sync its online prices immediately',
'models.pricingSource.editCurrentTitle': 'Current source: {provider}. Click to choose another source or sync again.',
'models.pricingSource.editChooseTitle': 'Choose and sync an online price source',
'models.pricingSource.syncingTitle': 'Syncing online prices',
'models.pricingSource.buttonCurrent': 'Price source · {provider}',
'models.pricingSource.loading': 'Loading sources...',
'models.pricingSource.loadingOptions': 'Loading online price sources...',
'models.pricingSource.catalogEmpty': 'No matching source on models.dev',
'models.pricingSource.resyncTitle': 'Sync prices again from the current source',
'models.pricingSource.pendingDatabase': 'Pending database save',
'models.pricingSource.incompatible': 'Incompatible pricing',
'models.pricingSource.noTokenPrice': 'No token prices',
'models.pricingSource.inputPrice': 'In ${price}',
'models.pricingSource.outputPrice': 'Out ${price}',
'models.pricingSource.sourceGone': 'The selected source no longer provides this model. Refresh the online catalog and try again.',
'models.pricingSource.cannotSync': 'Unable to sync',
'models.pricingSource.unsupported': 'This source includes {fields}, which the current billing engine cannot price independently.',
'models.pricingSource.noUsablePrice': 'This source has no usable token prices.',
'models.pricingSource.selectedAndSynced': 'Selected {provider} and synced the model prices',
'models.pricingSource.updateFailed': 'Failed to update the model price source',
'models.pricingSource.syncFailed': 'Sync failed',
'models.pricingSource.savedNoPriceChange': 'Saved {provider} as the price source; prices were already current',
'models.pricingField.reasoning': 'reasoning tokens',
'models.pricingField.inputAudio': 'input audio tokens',
'models.pricingField.outputAudio': 'output audio tokens',
'models.management.selectedCount': '{count} selected',
'models.management.manageSelectedTitle': 'Manage the {count} selected models',
'models.management.batchButtonSelected': 'Batch actions ({count})',
'models.management.batchButton': 'Batch manage',
'models.management.selectCurrentPage': 'Select models on this page',
'models.management.selectModel': 'Select model {name}',
'models.management.batch.title': 'Filters and batch actions',
'models.management.batch.description': 'Prices sync from each model’s source saved in the database by default, or you can choose one source for all selected models.',
'models.management.batch.providerPlaceholder': 'Choose an online price source',
'models.management.batch.rememberedProvider': 'Saved choice for each model',
'models.management.batch.selectionEmpty': 'Select models to run batch actions',
'models.management.batch.selectionSummary': '{selected} selected · {syncable} to sync · {sourcePending} sources to save · {unchanged} current · {unsupported} incompatible · {unavailable} without online prices',
'models.management.batch.state.syncable': 'Price update available',
'models.management.batch.state.sourcePending': 'Source not saved',
'models.management.batch.state.unchanged': 'Price current',
'models.management.batch.state.unsupported': 'Incompatible pricing',
'models.management.batch.state.unavailable': 'No online price',
'models.management.batch.source.noneSelected': 'No source selected',
'models.management.batch.source.noneRecorded': 'No source saved',
'models.management.batch.shortcut.syncable': 'The current price differs from the selected source',
'models.management.batch.shortcut.sourcePending': 'The price matches, but the source has not been saved to the database',
'models.management.batch.shortcut.unchanged': 'The current price matches the selected source',
'models.management.batch.shortcut.unsupported': 'The online source includes price dimensions the billing engine cannot price independently',
'models.management.batch.shortcut.unavailable': 'The selected source has no online price for this model',
'models.management.batch.syncButton': 'Sync prices and sources ({count})',
'models.management.batch.syncing': 'Syncing...',
'models.management.batch.confirmTitle': 'Sync prices and sources',
'models.management.batch.confirmMain': 'Sync online prices for {count} models from {provider} and save each price source to the database.',
'models.management.batch.confirmSourceOnly': '{count} models already have matching prices, so only their sources will be saved.',
'models.management.batch.confirmSkipped': '{count} models will be skipped because their prices and saved sources already match, their pricing is incompatible, or no online price is available.',
'models.management.batch.confirmUnchanged': 'Model names, capabilities, and other settings will not change.',
'models.management.batch.confirmButton': 'Sync and save',
'models.management.batch.rememberedProviderLabel': 'each model’s saved provider',
'models.management.batch.selectedProviderLabel': 'the selected provider',
'models.management.batch.success': 'Synced prices and sources for {count} models',
'models.management.batch.partialFailure': '{count} models failed to sync: {details}',
'models.management.batch.catalogMissingPrice': 'The online catalog did not provide a price configuration',
'nav.routing': 'Routing',
'nav.pool': 'Pool',
'nav.standaloneKeys': 'Standalone keys',