From d58cf68cdc139150ce0ca0b4b8e4ff26a2642ec6 Mon Sep 17 00:00:00 2001 From: fengsilin Date: Tue, 24 Mar 2026 11:33:22 +0800 Subject: [PATCH] feat: add channel pricing and pricing tag API helpers Co-Authored-By: Claude Opus 4.6 --- web/src/helpers/api.js | 63 ++++++++++++++++++++++++++++++++++++------ 1 file changed, 54 insertions(+), 9 deletions(-) diff --git a/web/src/helpers/api.js b/web/src/helpers/api.js index 361d7e0..7f5d52a 100644 --- a/web/src/helpers/api.js +++ b/web/src/helpers/api.js @@ -307,28 +307,38 @@ export async function onLinuxDOOAuthClicked( export async function onCustomOAuthClicked(provider, options = {}) { const state = await prepareOAuthState(options); if (!state) return; - + try { const redirect_uri = `${window.location.origin}/oauth/${provider.slug}`; - + // Check if authorization_endpoint is a full URL or relative path let authUrl; - if (provider.authorization_endpoint.startsWith('http://') || - provider.authorization_endpoint.startsWith('https://')) { + if ( + provider.authorization_endpoint.startsWith('http://') || + provider.authorization_endpoint.startsWith('https://') + ) { authUrl = new URL(provider.authorization_endpoint); } else { // Relative path - this is a configuration error, show error message - console.error('Custom OAuth authorization_endpoint must be a full URL:', provider.authorization_endpoint); - showError('OAuth 配置错误:授权端点必须是完整的 URL(以 http:// 或 https:// 开头)'); + console.error( + 'Custom OAuth authorization_endpoint must be a full URL:', + provider.authorization_endpoint, + ); + showError( + 'OAuth 配置错误:授权端点必须是完整的 URL(以 http:// 或 https:// 开头)', + ); return; } - + authUrl.searchParams.set('client_id', provider.client_id); authUrl.searchParams.set('redirect_uri', redirect_uri); authUrl.searchParams.set('response_type', 'code'); - authUrl.searchParams.set('scope', provider.scopes || 'openid profile email'); + authUrl.searchParams.set( + 'scope', + provider.scopes || 'openid profile email', + ); authUrl.searchParams.set('state', state); - + window.open(authUrl.toString()); } catch (error) { console.error('Failed to initiate custom OAuth:', error); @@ -364,3 +374,38 @@ export function getChannelModels(type) { } return []; } + +// 渠道定价 API +export const channelPricingApi = { + // 获取所有渠道定价 + getAll: (page = 1, pageSize = 10) => + API.get(`/api/channel_pricing/?p=${page}&page_size=${pageSize}`), + + // 获取渠道定价(带标签) + getWithTags: (page = 1, pageSize = 10) => + API.get(`/api/channel_pricing/with_tags?p=${page}&page_size=${pageSize}`), + + // 获取指定模型的渠道定价 + getByModel: (modelName) => API.get(`/api/channel_pricing/model/${modelName}`), + + // 创建/更新渠道定价 + create: (data) => API.post('/api/channel_pricing/', data), + + // 批量创建 + batchCreate: (items) => API.post('/api/channel_pricing/batch', { items }), + + // 删除 + delete: (id) => API.delete(`/api/channel_pricing/${id}`), + + // 复制全局定价 + copyGlobal: (channelId, overwrite = false) => + API.post(`/api/channel_pricing/copy_global/${channelId}`, { overwrite }), +}; + +// 定价标签 API +export const pricingTagApi = { + getAll: () => API.get('/api/pricing_tag/'), + create: (data) => API.post('/api/pricing_tag/', data), + update: (id, data) => API.put(`/api/pricing_tag/${id}`, data), + delete: (id) => API.delete(`/api/pricing_tag/${id}`), +};