|
|
@@ -307,28 +307,38 @@ export async function onLinuxDOOAuthClicked( |
|
|
export async function onCustomOAuthClicked(provider, options = {}) { |
|
|
export async function onCustomOAuthClicked(provider, options = {}) { |
|
|
const state = await prepareOAuthState(options); |
|
|
const state = await prepareOAuthState(options); |
|
|
if (!state) return; |
|
|
if (!state) return; |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
try { |
|
|
try { |
|
|
const redirect_uri = `${window.location.origin}/oauth/${provider.slug}`; |
|
|
const redirect_uri = `${window.location.origin}/oauth/${provider.slug}`; |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
// Check if authorization_endpoint is a full URL or relative path |
|
|
// Check if authorization_endpoint is a full URL or relative path |
|
|
let authUrl; |
|
|
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); |
|
|
authUrl = new URL(provider.authorization_endpoint); |
|
|
} else { |
|
|
} else { |
|
|
// Relative path - this is a configuration error, show error message |
|
|
// 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; |
|
|
return; |
|
|
} |
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
authUrl.searchParams.set('client_id', provider.client_id); |
|
|
authUrl.searchParams.set('client_id', provider.client_id); |
|
|
authUrl.searchParams.set('redirect_uri', redirect_uri); |
|
|
authUrl.searchParams.set('redirect_uri', redirect_uri); |
|
|
authUrl.searchParams.set('response_type', 'code'); |
|
|
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); |
|
|
authUrl.searchParams.set('state', state); |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
window.open(authUrl.toString()); |
|
|
window.open(authUrl.toString()); |
|
|
} catch (error) { |
|
|
} catch (error) { |
|
|
console.error('Failed to initiate custom OAuth:', error); |
|
|
console.error('Failed to initiate custom OAuth:', error); |
|
|
@@ -364,3 +374,38 @@ export function getChannelModels(type) { |
|
|
} |
|
|
} |
|
|
return []; |
|
|
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}`), |
|
|
|
|
|
}; |