front/src/utils/rbac-error-handler.ts
zzh c6a4484448 feat: 查价价卡展示贸易条款与产品分组,并优化 H5/登录与顾问体验
销售产品可配置 DDP/DDU;查价返回分组与贸易条款并展示在价卡上。

Co-authored-by: Cursor <cursoragent@cursor.com>
2026-07-30 11:48:36 +08:00

85 lines
2.6 KiB
TypeScript

import { Message } from '@arco-design/web-vue'
import { ApiError } from '@/api/rbac/generated/core/ApiError'
import router from '@/router'
import { useRbacUserStore } from '@/store/modules/rbac-user'
import { resolvePostLogoutLogin } from '@/utils/login-portal'
/**
* 全局错误处理器
*/
export function handleApiError(error: any): void {
if (error instanceof ApiError) {
const { status, body } = error
// 尝试从响应体中提取 message
let errorMessage = '请求失败'
if (body) {
// 后端可能返回的格式:{ message: '错误信息' } 或 { Message: '错误信息' }
errorMessage = body.message || body.Message || body.error || body.Error || errorMessage
}
switch (status) {
case 400:
Message.error(errorMessage || '请求参数错误')
break
case 401:
Message.error('未授权,请重新登录')
{
const rbacUserStore = useRbacUserStore()
const loginType = rbacUserStore.resolveLoginTypeForRedirect()
const currentPath = router.currentRoute.value.fullPath
localStorage.removeItem('token')
localStorage.removeItem('userInfo')
// 清除所有RBAC相关存储
localStorage.removeItem('rbac_token')
localStorage.removeItem('rbac_access_token')
localStorage.removeItem('rbac_refresh_token')
localStorage.removeItem('rbac_token_expires_at')
localStorage.removeItem('rbac_userInfo')
const target = resolvePostLogoutLogin({
loginType,
path: currentPath,
})
if (target.path) {
router.replace({ path: target.path, query: target.query })
} else {
router.replace({ name: target.name, query: target.query })
}
}
break
case 403:
Message.error(errorMessage || '没有权限访问')
break
case 404:
Message.error(errorMessage || '请求的资源不存在')
break
case 500:
Message.error(errorMessage || '服务器错误')
break
default:
Message.error(errorMessage)
}
} else if (error?.message) {
Message.error(error.message)
} else {
Message.error('未知错误')
}
}
/**
* 包装异步函数,自动处理错误
*/
export function withErrorHandler<T extends (...args: any[]) => Promise<any>>(
fn: T
): (...args: Parameters<T>) => Promise<ReturnType<T> | undefined> {
return async (...args: Parameters<T>) => {
try {
return await fn(...args)
} catch (error) {
handleApiError(error)
return undefined
}
}
}