Browse Source

接口错误拦截样式修订

relver
zhangjiming 7 months ago
parent
commit
78222ab1fd
  1. 141
      src/components/dialogs/ErrorModal.vue
  2. 7
      src/eventBus.ts
  3. 19
      src/utils/axios.ts

141
src/components/dialogs/ErrorModal.vue

@ -1,50 +1,73 @@
<template>
<teleport to="body">
<div v-if="showErrorStack" class="error-stack-overlay">
<div class="error-stack-container" :class="typeClass">
<div class="error-stack-container" >
<div class="error-stack-header">
<!-- <div class="icon-wrapper">
<img :src="iconMap[type]" alt="icon" />
</div> -->
<span class="error-stack-title">{{ typeText }}</span>
<span class="error-stack-title" :class="type">{{ title }}</span>
</div>
<div class="error-stack-content">
<p class="error-stack-message">{{ info || "未知错误" }}</p>
<p class="error-stack-message">{{ info || '--' }}</p>
<div class="error-stack-details-wrapper">
<div class="details-header" @click="toggleDetails">
<span class="details-title">详细信息</span>
<span class="details-arrow" :class="{ 'is-expanded': isShow }">
<svg viewBox="0 0 24 24" width="24" height="24">
<path d="M7 10l5 5 5-5" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" />
<path
d="M7 10l5 5 5-5"
fill="none"
stroke="currentColor"
stroke-width="2"
stroke-linecap="round"
/>
</svg>
</span>
</div>
<div class="error-stack-details" v-show="isShow">
<template v-if="detailInfos.length">
<div v-for="(detail, index) in detailInfos" :key="index" class="detail-item">
<span class="detail-label">{{ detail.name }}</span>
<span class="detail-value">{{ detail.description }}</span>
<template v-if="detailInfo && detailInfo.length > 0">
<div class="detail-item">
<!-- <span class="detail-label">{{ detailInfo }}</span> -->
<span class="detail-value">{{ detailInfo }}</span>
</div>
</template>
<div v-else class="empty-details">
<svg class="empty-icon" viewBox="0 0 24 24" width="48" height="48">
<svg
class="empty-icon"
viewBox="0 0 24 24"
width="48"
height="48"
>
<path
d="M12 2C6.48 2 2 6.48 2 12s4.48 10 10 10 10-4.48 10-10S17.52 2 12 2zm0 18c-4.41 0-8-3.59-8-8s3.59-8 8-8 8 3.59 8 8-3.59 8-8 8zm-1-13h2v6h-2zm0 8h2v2h-2z"
fill="currentColor" />
fill="currentColor"
/>
</svg>
<span>暂无详细信息</span>
</div>
</div>
</div>
<div v-if="stackInfo" class="stack-info-trigger" @click="showStackInfo">
<div
v-if="stackInfo"
class="stack-info-trigger"
@click="showStackInfo"
>
<svg viewBox="0 0 24 24" width="20" height="20">
<path d="M12 2L2 7l10 5 10-5-10-5zM2 17l10 5 10-5M2 12l10 5 10-5" fill="none" stroke="currentColor"
stroke-width="2" stroke-linecap="round" />
<path
d="M12 2L2 7l10 5 10-5-10-5zM2 17l10 5 10-5M2 12l10 5 10-5"
fill="none"
stroke="currentColor"
stroke-width="2"
stroke-linecap="round"
/>
</svg>
<span>查看栈错误信息</span>
</div>
</div>
<button :class="['error-stack-close', buttonClass]" @click="closeErrorStack">关闭</button>
<button
:class="['error-stack-close']"
@click="closeErrorStack"
>
关闭
</button>
</div>
</div>
</teleport>
@ -115,6 +138,15 @@
font-size: 32px;
font-weight: 600;
color: var(--theme-color);
&.Info {
color: #333;
}
&.Warn {
color: #fa9d3b;
}
&.Error {
color: #d81212;
}
}
}
@ -176,11 +208,11 @@
border-bottom: none;
}
.detail-label {
flex: 0 0 120px;
font-size: 26px;
color: #6b7280;
}
// .detail-label {
// flex: 0 0 120px;
// font-size: 26px;
// color: #6b7280;
// }
.detail-value {
flex: 1;
@ -263,60 +295,18 @@
<script setup lang="ts">
import { eventBus } from '../../eventBus'
import { onMounted, onUnmounted, ref, computed } from 'vue'
import type { ErrorModalData, ErrorDetail } from '../../eventBus'
import { onMounted, onUnmounted, ref } from 'vue'
import type { ErrorModalData } from '../../eventBus'
import { MsgLevel } from '@/websocket/socket'
// let ErrorIcon = new URL('@/assets/Warn.svg', import.meta.url).href
// let WarnIcon = new URL('@/assets/update-pin-icon.svg', import.meta.url).href
// let NotifyIcon = new URL('@/assets/notify.svg', import.meta.url).href
// let FatalIcon = new URL('@/assets/fatal.svg', import.meta.url).href
const showErrorStack = ref(false)
const title = ref('')
const info = ref('')
const type = ref<'Fatal' | 'Error' | 'Warn' | 'Notify'>('Notify')
const detailInfos = ref<ErrorDetail[]>([])
const type = ref<MsgLevel>('Info')
const detailInfo = ref<string>('')
const isShow = ref(true)
const stackInfo = ref('')
//
const TYPE_MAP = {
Fatal: '严重错误',
Error: '错误',
Warn: '警告',
Notify: '提示',
} as const
//
const typeText = computed(() => {
return TYPE_MAP[type.value as keyof typeof TYPE_MAP] || '未知类型'
})
//
const typeClass = computed(() => {
return {
'error-fatal': type.value === 'Fatal',
'error-error': type.value === 'Error',
'error-warn': type.value === 'Warn',
'error-notify': type.value === 'Notify'
}
})
//
const buttonClass = computed(() => {
return {
'error-fatal-button': type.value === 'Fatal',
'error-error-button': type.value === 'Error',
'error-warn-button': type.value === 'Warn',
'error-notify-button': type.value === 'Notify'
}
})
//
// const iconMap = computed(() => {
// return {
// 'Fatal': FatalIcon,
// 'Error': ErrorIcon,
// 'Warn': WarnIcon,
// 'Notify': NotifyIcon
// }
// })
const toggleDetails = () => {
isShow.value = !isShow.value
@ -330,9 +320,10 @@ onUnmounted(() => {
})
const handleErrorModal = (data: ErrorModalData) => {
console.log('data---', data)
title.value = data.title
info.value = data.info
type.value = data.type
detailInfos.value = data.detailInfos || []
type.value = data.messageLevel
detailInfo.value = data.detailInfo || ''
stackInfo.value = data.stackInfo || ''
showErrorStack.value = true
}
@ -340,7 +331,9 @@ const closeErrorStack = () => {
showErrorStack.value = false
}
const showStackInfo = () => {
eventBus.emit('show-stack-modal', stackInfo.value as unknown as null | undefined)
eventBus.emit(
'show-stack-modal',
stackInfo.value as unknown as null | undefined,
)
}
</script>

7
src/eventBus.ts

@ -1,5 +1,6 @@
// src/eventBus.ts
import mitt from 'mitt'
import { MsgLevel } from './websocket/socket'
export type ErrorDetail = {
name: string
@ -7,10 +8,10 @@ export type ErrorDetail = {
}
export type ErrorModalData = {
type: 'Notify' | 'Warn' | 'Error' | 'Fatal'
messageLevel: MsgLevel
title: string
info: string
detailInfos?: ErrorDetail[]
ecode?: string
detailInfo?: string
stackInfo?: null
}

19
src/utils/axios.ts

@ -50,13 +50,7 @@ apiClient.interceptors.response.use(
return Promise.resolve(response.data)
} else {
console.log('接口出错', response.data)
eventBus.emit('show-error-modal', {
type: response.data.data.type,
info: response.data.data.info,
detailInfos: response.data.data.detailInfos,
ecode: response.data.data.ecode,
stackInfo: response.data.data.stackInfo,
})
eventBus.emit('show-error-modal', response.data.data)
return Promise.reject(response.data)
}
}
@ -64,14 +58,9 @@ apiClient.interceptors.response.use(
},
(error) => {
eventBus.emit('show-error-modal', {
type: 'Error',
info: '网络请求失败',
detailInfos: [
{
name: '错误详情',
description: error.message,
},
],
messageLevel: 'Error',
title: '网络请求失败',
info: error.message
})
return Promise.reject(error)
},

Loading…
Cancel
Save