修复token余额不足时仍能继续使用功能的问题
根因:后端扣费用的是 fallback_amount=200(最低消费),用户剩14个token 时 14<200 导致扣费失败,但原有逻辑只在 remaining<=0 时才终止会话和 通知前端,remaining=14>0 时扣费失败被静默忽略。 修复: - 后端 voice_chat_router.py:扣费失败时(charge 返回 success=false) 始终终止事件循环并发送 error 事件,不再只判断 remaining<=0 - 后端 chat_router.py:文字聊天扣费失败时也发送 error 事件通知前端 - 前端 chatStore.js:token_update 消息带 warning 字段时(扣费失败), 标记 _realtimeTokenExhausted=true,断开 WebSocket,阻止继续使用 Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
This commit is contained in:
parent
ab26e64af6
commit
f8e70e3fd5
@ -274,11 +274,11 @@ async def websocket_chat_endpoint(websocket: WebSocket, user_id: str):
|
||||
)
|
||||
# 余额耗尽时通知前端
|
||||
remaining = charge_result.get("available_tokens", 0)
|
||||
if remaining <= 0:
|
||||
await websocket.send_text(json.dumps({
|
||||
# 扣费失败时也通知前端
|
||||
await websocket.send_text(json.dumps({
|
||||
"type": "error",
|
||||
"error": "insufficient_tokens",
|
||||
"message": "Token不足,请充值",
|
||||
"message": "Token不足(剩余" + str(remaining) + "),请充值",
|
||||
"available_tokens": remaining,
|
||||
"timestamp": datetime.now().isoformat()
|
||||
}))
|
||||
|
||||
@ -1264,8 +1264,8 @@ async def receive_events_loop(
|
||||
}))
|
||||
except Exception:
|
||||
pass
|
||||
# 余额耗尽时终止事件循环,防止火山引擎继续消费
|
||||
if remaining <= 0:
|
||||
# 扣费失败时终止事件循环(余额不够最低消费也要停)
|
||||
if True:
|
||||
logger.warning(
|
||||
f"[VOICE_TOKEN_EXHAUSTED] user_id={user_id} mode={charge_mode} "
|
||||
f"remaining={remaining}, breaking event loop and closing"
|
||||
|
||||
@ -1013,6 +1013,7 @@ export const useChatStore = defineStore('chat', () => {
|
||||
case 'token_update':
|
||||
{
|
||||
const remaining = data.remaining_tokens ?? data.data?.remaining_tokens ?? null
|
||||
const warning = data.warning || data.data?.warning
|
||||
if (remaining !== null) {
|
||||
console.log('[ChatStore] Token update:', remaining, 'remaining')
|
||||
// 余额耗尽时标记并断开
|
||||
@ -1024,16 +1025,21 @@ export const useChatStore = defineStore('chat', () => {
|
||||
resetAudioState()
|
||||
break
|
||||
}
|
||||
// 扣费失败(余额不够最低消费)也标记耗尽
|
||||
if (warning) {
|
||||
console.warn('[ChatStore] Token charge failed:', warning, 'remaining:', remaining)
|
||||
_realtimeTokenExhausted = true
|
||||
ElMessage.error(`Token不足(剩余${remaining}),实时通话已结束`)
|
||||
disconnectRealtimeWebSocket()
|
||||
resetAudioState()
|
||||
break
|
||||
}
|
||||
// 充值后恢复:余额恢复时重置耗尽标记和 AI 处理状态
|
||||
_realtimeTokenExhausted = false
|
||||
if (isAiProcessing.value) {
|
||||
isAiProcessing.value = false
|
||||
}
|
||||
}
|
||||
const warning = data.warning || data.data?.warning
|
||||
if (warning) {
|
||||
console.warn('[ChatStore] Token warning:', warning)
|
||||
}
|
||||
}
|
||||
break
|
||||
case 'error':
|
||||
|
||||
Loading…
Reference in New Issue
Block a user