This commit is contained in:
wujinliang
2026-08-27 21:48:15 +08:00
parent 550d8add97
commit b47323edf3
53 changed files with 624 additions and 82 deletions
+7
View File
@@ -66,6 +66,13 @@ describe('API error diagnostics', () => {
}
})
it('translates notification recipient error codes into actionable Chinese messages', () => {
expect(getApiErrorDetails(new ApiResponseError('NOTIFICATION_RECIPIENT_FORBIDDEN', 'A0400')).message)
.toBe('角色编码不存在或当前账号无权使用该角色,请检查后重试')
expect(getApiErrorDetails(new ApiResponseError('NOTIFICATION_RECIPIENT_EMPTY', 'A0400')).message)
.toBe('该角色下暂无可接收消息的有效用户,请先为角色分配启用中的成员')
})
it('preserves a backend credential error for an explicit login request', () => {
const error = new ApiResponseError(
'用户名或密码错误',
+11 -2
View File
@@ -53,6 +53,15 @@ let authRefreshHandler: AuthRefreshHandler | null = null
let authSessionExpiredHandler: AuthSessionExpiredHandler | null = null
let activeRefresh: Promise<string> | null = null
const businessErrorMessages: Record<string, string> = {
NOTIFICATION_RECIPIENT_FORBIDDEN: '角色编码不存在或当前账号无权使用该角色,请检查后重试',
NOTIFICATION_RECIPIENT_EMPTY: '该角色下暂无可接收消息的有效用户,请先为角色分配启用中的成员',
}
function friendlyBusinessMessage(message?: string | null) {
return (message && businessErrorMessages[message]) || message || undefined
}
export function registerAuthRefreshHandler(handler: AuthRefreshHandler) {
authRefreshHandler = handler
}
@@ -134,7 +143,7 @@ export function getApiErrorDetails(
? '当前账号无权访问该数据,请联系管理员确认权限'
: error.code.startsWith('S05')
? '服务暂时不可用,请稍后重试'
: error.message
: friendlyBusinessMessage(error.message) || '接口请求失败'
return { message, code: error.code, requestId: error.requestId, traceId: error.traceId }
}
if (axios.isAxiosError(error)) {
@@ -156,7 +165,7 @@ export function getApiErrorDetails(
? '服务暂时不可用,请稍后重试'
: undefined
return {
message: statusMessage || response?.message || response?.error || fallback,
message: statusMessage || friendlyBusinessMessage(response?.message || response?.error) || fallback,
code: response?.code || (error.response?.status ? `HTTP_${error.response.status}` : undefined),
requestId: response?.requestId || undefined,
traceId: response?.traceId || undefined,
+7 -1
View File
@@ -40,11 +40,13 @@ const props = withDefaults(defineProps<{
searchText?: string
resetText?: string
searchOnReset?: boolean
searchOnClear?: boolean
loading?: boolean
}>(), {
searchText: '查询',
resetText: '重置',
searchOnReset: true,
searchOnClear: true,
loading: false,
})
@@ -146,6 +148,10 @@ function search() {
emit('search', model.value)
}
function clearInput() {
if (props.searchOnClear) search()
}
function reset() {
if (props.loading) return
for (const field of props.fields) model.value[field.key] = resetValue(field)
@@ -182,7 +188,7 @@ defineExpose({ search, reset })
clearable
v-bind="field.props"
@update:model-value="updateField(field.key, $event)"
@clear="search"
@clear="clearInput"
@keyup.enter.exact="searchFromTextInput"
>
<template #prefix><Search :size="16" /></template>