fix: 添加混合渠道警告确认框和过滤 prompt_cache_retention 参数
- 前端: EditAccountModal 和 CreateAccountModal 添加 409 mixed_channel_warning 处理 - 前端: 弹出确认框让用户确认混合渠道风险 - 后端: 过滤 OpenAI 请求中的 prompt_cache_retention 参数(上游不支持) - 添加中英文翻译 Co-authored-by: factory-droid[bot] <138933559+factory-droid[bot]@users.noreply.github.com>
This commit is contained in:
@@ -649,6 +649,12 @@ func (s *OpenAIGatewayService) Forward(ctx context.Context, c *gin.Context, acco
|
|||||||
bodyModified = true
|
bodyModified = true
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Remove prompt_cache_retention (not supported by upstream OpenAI API)
|
||||||
|
if _, has := reqBody["prompt_cache_retention"]; has {
|
||||||
|
delete(reqBody, "prompt_cache_retention")
|
||||||
|
bodyModified = true
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// Re-serialize body only if modified
|
// Re-serialize body only if modified
|
||||||
|
|||||||
@@ -2157,6 +2157,46 @@ const handleClose = () => {
|
|||||||
emit('close')
|
emit('close')
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Helper function to create account with mixed channel warning handling
|
||||||
|
const doCreateAccount = async (payload: any, confirmMixedChannelRisk = false) => {
|
||||||
|
if (confirmMixedChannelRisk) {
|
||||||
|
payload.confirm_mixed_channel_risk = true
|
||||||
|
}
|
||||||
|
|
||||||
|
submitting.value = true
|
||||||
|
try {
|
||||||
|
await adminAPI.accounts.create(payload)
|
||||||
|
appStore.showSuccess(t('admin.accounts.accountCreated'))
|
||||||
|
emit('created')
|
||||||
|
handleClose()
|
||||||
|
} catch (error: any) {
|
||||||
|
// Handle 409 mixed_channel_warning - show confirmation dialog
|
||||||
|
if (error.response?.status === 409 && error.response?.data?.error === 'mixed_channel_warning') {
|
||||||
|
const details = error.response.data.details || {}
|
||||||
|
const groupName = details.group_name || 'Unknown'
|
||||||
|
const currentPlatform = details.current_platform || 'Unknown'
|
||||||
|
const otherPlatform = details.other_platform || 'Unknown'
|
||||||
|
|
||||||
|
const confirmMessage = t('admin.accounts.mixedChannelWarning', {
|
||||||
|
groupName,
|
||||||
|
currentPlatform,
|
||||||
|
otherPlatform
|
||||||
|
})
|
||||||
|
|
||||||
|
if (confirm(confirmMessage)) {
|
||||||
|
// Retry with confirmation flag
|
||||||
|
submitting.value = false
|
||||||
|
await doCreateAccount(payload, true)
|
||||||
|
return
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
appStore.showError(error.response?.data?.detail || t('admin.accounts.failedToCreate'))
|
||||||
|
}
|
||||||
|
} finally {
|
||||||
|
submitting.value = false
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
const handleSubmit = async () => {
|
const handleSubmit = async () => {
|
||||||
// For OAuth-based type, handle OAuth flow (goes to step 2)
|
// For OAuth-based type, handle OAuth flow (goes to step 2)
|
||||||
if (isOAuthFlow.value) {
|
if (isOAuthFlow.value) {
|
||||||
@@ -2213,21 +2253,11 @@ const handleSubmit = async () => {
|
|||||||
|
|
||||||
form.credentials = credentials
|
form.credentials = credentials
|
||||||
|
|
||||||
submitting.value = true
|
await doCreateAccount({
|
||||||
try {
|
...form,
|
||||||
await adminAPI.accounts.create({
|
group_ids: form.group_ids,
|
||||||
...form,
|
auto_pause_on_expired: autoPauseOnExpired.value
|
||||||
group_ids: form.group_ids,
|
})
|
||||||
auto_pause_on_expired: autoPauseOnExpired.value
|
|
||||||
})
|
|
||||||
appStore.showSuccess(t('admin.accounts.accountCreated'))
|
|
||||||
emit('created')
|
|
||||||
handleClose()
|
|
||||||
} catch (error: any) {
|
|
||||||
appStore.showError(error.response?.data?.detail || t('admin.accounts.failedToCreate'))
|
|
||||||
} finally {
|
|
||||||
submitting.value = false
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
const goBackToBasicInfo = () => {
|
const goBackToBasicInfo = () => {
|
||||||
|
|||||||
@@ -8,7 +8,7 @@
|
|||||||
<form
|
<form
|
||||||
v-if="account"
|
v-if="account"
|
||||||
id="edit-account-form"
|
id="edit-account-form"
|
||||||
@submit.prevent="handleSubmit"
|
@submit.prevent="() => handleSubmit()"
|
||||||
class="space-y-5"
|
class="space-y-5"
|
||||||
>
|
>
|
||||||
<div>
|
<div>
|
||||||
@@ -1294,12 +1294,17 @@ const handleClose = () => {
|
|||||||
emit('close')
|
emit('close')
|
||||||
}
|
}
|
||||||
|
|
||||||
const handleSubmit = async () => {
|
const handleSubmit = async (confirmMixedChannelRisk = false) => {
|
||||||
if (!props.account) return
|
if (!props.account) return
|
||||||
|
|
||||||
submitting.value = true
|
submitting.value = true
|
||||||
try {
|
try {
|
||||||
const updatePayload: Record<string, unknown> = { ...form }
|
const updatePayload: Record<string, unknown> = { ...form }
|
||||||
|
|
||||||
|
// Add confirmation flag if user confirmed mixed channel risk
|
||||||
|
if (confirmMixedChannelRisk) {
|
||||||
|
updatePayload.confirm_mixed_channel_risk = true
|
||||||
|
}
|
||||||
// 后端期望 proxy_id: 0 表示清除代理,而不是 null
|
// 后端期望 proxy_id: 0 表示清除代理,而不是 null
|
||||||
if (updatePayload.proxy_id === null) {
|
if (updatePayload.proxy_id === null) {
|
||||||
updatePayload.proxy_id = 0
|
updatePayload.proxy_id = 0
|
||||||
@@ -1415,7 +1420,28 @@ const handleSubmit = async () => {
|
|||||||
emit('updated')
|
emit('updated')
|
||||||
handleClose()
|
handleClose()
|
||||||
} catch (error: any) {
|
} catch (error: any) {
|
||||||
appStore.showError(error.response?.data?.message || error.response?.data?.detail || t('admin.accounts.failedToUpdate'))
|
// Handle 409 mixed_channel_warning - show confirmation dialog
|
||||||
|
if (error.response?.status === 409 && error.response?.data?.error === 'mixed_channel_warning') {
|
||||||
|
const details = error.response.data.details || {}
|
||||||
|
const groupName = details.group_name || 'Unknown'
|
||||||
|
const currentPlatform = details.current_platform || 'Unknown'
|
||||||
|
const otherPlatform = details.other_platform || 'Unknown'
|
||||||
|
|
||||||
|
const confirmMessage = t('admin.accounts.mixedChannelWarning', {
|
||||||
|
groupName,
|
||||||
|
currentPlatform,
|
||||||
|
otherPlatform
|
||||||
|
})
|
||||||
|
|
||||||
|
if (confirm(confirmMessage)) {
|
||||||
|
// Retry with confirmation flag
|
||||||
|
submitting.value = false
|
||||||
|
await handleSubmit(true)
|
||||||
|
return
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
appStore.showError(error.response?.data?.message || error.response?.data?.detail || t('admin.accounts.failedToUpdate'))
|
||||||
|
}
|
||||||
} finally {
|
} finally {
|
||||||
submitting.value = false
|
submitting.value = false
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1306,6 +1306,7 @@ export default {
|
|||||||
accountUpdated: 'Account updated successfully',
|
accountUpdated: 'Account updated successfully',
|
||||||
failedToCreate: 'Failed to create account',
|
failedToCreate: 'Failed to create account',
|
||||||
failedToUpdate: 'Failed to update account',
|
failedToUpdate: 'Failed to update account',
|
||||||
|
mixedChannelWarning: 'Warning: Group "{groupName}" contains both {currentPlatform} and {otherPlatform} accounts. Mixing different channels may cause thinking block signature validation issues, which will fallback to non-thinking mode. Are you sure you want to continue?',
|
||||||
pleaseEnterAccountName: 'Please enter account name',
|
pleaseEnterAccountName: 'Please enter account name',
|
||||||
pleaseEnterApiKey: 'Please enter API Key',
|
pleaseEnterApiKey: 'Please enter API Key',
|
||||||
apiKeyIsRequired: 'API Key is required',
|
apiKeyIsRequired: 'API Key is required',
|
||||||
|
|||||||
@@ -1439,6 +1439,7 @@ export default {
|
|||||||
accountUpdated: '账号更新成功',
|
accountUpdated: '账号更新成功',
|
||||||
failedToCreate: '创建账号失败',
|
failedToCreate: '创建账号失败',
|
||||||
failedToUpdate: '更新账号失败',
|
failedToUpdate: '更新账号失败',
|
||||||
|
mixedChannelWarning: '警告:分组 "{groupName}" 中同时包含 {currentPlatform} 和 {otherPlatform} 账号。混合使用不同渠道可能导致 thinking block 签名验证问题,会自动回退到非 thinking 模式。确定要继续吗?',
|
||||||
pleaseEnterAccountName: '请输入账号名称',
|
pleaseEnterAccountName: '请输入账号名称',
|
||||||
pleaseEnterApiKey: '请输入 API Key',
|
pleaseEnterApiKey: '请输入 API Key',
|
||||||
apiKeyIsRequired: 'API Key 是必需的',
|
apiKeyIsRequired: 'API Key 是必需的',
|
||||||
|
|||||||
Reference in New Issue
Block a user