错误提示处理
This commit is contained in:
parent
71c8ed68b3
commit
483b4371d5
@ -1,39 +1,44 @@
|
|||||||
<template>
|
<template>
|
||||||
<div v-if="visible" class="error-modal-overlay" @click="handleOverlayClick">
|
<div v-if="visible" class="modal-overlay" @click="handleOverlayClick">
|
||||||
<div class="error-modal" :class="animationClass">
|
<div class="modal" :class="[animationClass, modalTypeClass]">
|
||||||
<!-- 错误图标 -->
|
<!-- 图标 -->
|
||||||
<div class="error-icon">
|
<div class="modal-icon">
|
||||||
<div class="error-circle">
|
<div class="icon-circle" :class="iconCircleClass">
|
||||||
<span class="error-x">✕</span>
|
<span class="icon-symbol" :class="iconSymbolClass">{{ iconSymbol }}</span>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<!-- 标题 -->
|
<!-- 标题 -->
|
||||||
<div class="error-title" v-if="title">{{ title }}</div>
|
<div class="modal-title" v-if="title">{{ title }}</div>
|
||||||
|
|
||||||
<!-- 错误信息 -->
|
<!-- 消息内容 -->
|
||||||
<div class="error-message">{{ message }}</div>
|
<div class="modal-message">{{ message }}</div>
|
||||||
|
|
||||||
<!-- 按钮 -->
|
<!-- 按钮 -->
|
||||||
<div class="error-actions">
|
<div class="modal-actions">
|
||||||
<button class="error-btn" @click="confirm">{{ confirmText }}</button>
|
<button class="modal-btn" :class="buttonClass" @click="confirm">{{ confirmText }}</button>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</template>
|
</template>
|
||||||
|
|
||||||
<script setup>
|
<script setup>
|
||||||
import { ref, onMounted } from 'vue'
|
import { ref, onMounted, computed } from 'vue'
|
||||||
|
|
||||||
const props = defineProps({
|
const props = defineProps({
|
||||||
title: {
|
title: {
|
||||||
type: String,
|
type: String,
|
||||||
default: 'Error'
|
default: 'Notice'
|
||||||
},
|
},
|
||||||
message: {
|
message: {
|
||||||
type: String,
|
type: String,
|
||||||
required: true
|
required: true
|
||||||
},
|
},
|
||||||
|
type: {
|
||||||
|
type: String,
|
||||||
|
default: 'error', // 'error' | 'warning' | 'success' | 'info'
|
||||||
|
validator: (value) => ['error', 'warning', 'success', 'info'].includes(value)
|
||||||
|
},
|
||||||
confirmText: {
|
confirmText: {
|
||||||
type: String,
|
type: String,
|
||||||
default: 'OK'
|
default: 'OK'
|
||||||
@ -41,6 +46,10 @@ const props = defineProps({
|
|||||||
clickToClose: {
|
clickToClose: {
|
||||||
type: Boolean,
|
type: Boolean,
|
||||||
default: true
|
default: true
|
||||||
|
},
|
||||||
|
duration: {
|
||||||
|
type: Number,
|
||||||
|
default: null // 自动关闭时间(毫秒)
|
||||||
}
|
}
|
||||||
})
|
})
|
||||||
|
|
||||||
@ -49,9 +58,35 @@ const emit = defineEmits(['confirm', 'close'])
|
|||||||
const visible = ref(false)
|
const visible = ref(false)
|
||||||
const animationClass = ref('')
|
const animationClass = ref('')
|
||||||
|
|
||||||
|
// 根据类型计算图标和样式
|
||||||
|
const iconSymbol = computed(() => {
|
||||||
|
const symbols = {
|
||||||
|
error: '✕',
|
||||||
|
warning: '⚠',
|
||||||
|
success: '✓',
|
||||||
|
info: 'i'
|
||||||
|
}
|
||||||
|
return symbols[props.type] || symbols.error
|
||||||
|
})
|
||||||
|
|
||||||
|
const modalTypeClass = computed(() => `modal-${props.type}`)
|
||||||
|
|
||||||
|
const iconCircleClass = computed(() => `icon-circle-${props.type}`)
|
||||||
|
|
||||||
|
const iconSymbolClass = computed(() => `icon-symbol-${props.type}`)
|
||||||
|
|
||||||
|
const buttonClass = computed(() => `modal-btn-${props.type}`)
|
||||||
|
|
||||||
const show = () => {
|
const show = () => {
|
||||||
visible.value = true
|
visible.value = true
|
||||||
animationClass.value = 'modal-enter'
|
animationClass.value = 'modal-enter'
|
||||||
|
|
||||||
|
// 如果设置了自动关闭时间
|
||||||
|
if (props.duration && props.duration > 0) {
|
||||||
|
setTimeout(() => {
|
||||||
|
close()
|
||||||
|
}, props.duration)
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
const close = () => {
|
const close = () => {
|
||||||
@ -86,7 +121,8 @@ defineExpose({
|
|||||||
</script>
|
</script>
|
||||||
|
|
||||||
<style scoped>
|
<style scoped>
|
||||||
.error-modal-overlay {
|
/* 基础模态框样式 */
|
||||||
|
.modal-overlay {
|
||||||
position: fixed;
|
position: fixed;
|
||||||
top: 0;
|
top: 0;
|
||||||
left: 0;
|
left: 0;
|
||||||
@ -100,7 +136,7 @@ defineExpose({
|
|||||||
padding: 20px;
|
padding: 20px;
|
||||||
}
|
}
|
||||||
|
|
||||||
.error-modal {
|
.modal {
|
||||||
background: white;
|
background: white;
|
||||||
border-radius: 16px;
|
border-radius: 16px;
|
||||||
box-shadow: 0 20px 25px rgba(0, 0, 0, 0.1), 0 10px 10px rgba(0, 0, 0, 0.04);
|
box-shadow: 0 20px 25px rgba(0, 0, 0, 0.1), 0 10px 10px rgba(0, 0, 0, 0.04);
|
||||||
@ -111,34 +147,32 @@ defineExpose({
|
|||||||
position: relative;
|
position: relative;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* 错误图标 */
|
/* 图标区域 */
|
||||||
.error-icon {
|
.modal-icon {
|
||||||
margin-bottom: 16px;
|
margin-bottom: 16px;
|
||||||
display: flex;
|
display: flex;
|
||||||
justify-content: center;
|
justify-content: center;
|
||||||
}
|
}
|
||||||
|
|
||||||
.error-circle {
|
.icon-circle {
|
||||||
width: 56px;
|
width: 56px;
|
||||||
height: 56px;
|
height: 56px;
|
||||||
border-radius: 50%;
|
border-radius: 50%;
|
||||||
background-color: #FEE2E2;
|
|
||||||
border: 3px solid #FECACA;
|
|
||||||
display: flex;
|
display: flex;
|
||||||
align-items: center;
|
align-items: center;
|
||||||
justify-content: center;
|
justify-content: center;
|
||||||
animation: errorPulse 0.6s ease-out;
|
animation: iconPulse 0.6s ease-out;
|
||||||
|
border: 3px solid;
|
||||||
}
|
}
|
||||||
|
|
||||||
.error-x {
|
.icon-symbol {
|
||||||
color: #DC2626;
|
|
||||||
font-size: 24px;
|
font-size: 24px;
|
||||||
font-weight: bold;
|
font-weight: bold;
|
||||||
line-height: 1;
|
line-height: 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* 标题 */
|
/* 标题 */
|
||||||
.error-title {
|
.modal-title {
|
||||||
font-size: 18px;
|
font-size: 18px;
|
||||||
font-weight: 600;
|
font-weight: 600;
|
||||||
color: #1F2937;
|
color: #1F2937;
|
||||||
@ -146,8 +180,8 @@ defineExpose({
|
|||||||
line-height: 1.4;
|
line-height: 1.4;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* 错误信息 */
|
/* 消息内容 */
|
||||||
.error-message {
|
.modal-message {
|
||||||
font-size: 14px;
|
font-size: 14px;
|
||||||
color: #6B7280;
|
color: #6B7280;
|
||||||
line-height: 1.5;
|
line-height: 1.5;
|
||||||
@ -156,14 +190,12 @@ defineExpose({
|
|||||||
}
|
}
|
||||||
|
|
||||||
/* 按钮区域 */
|
/* 按钮区域 */
|
||||||
.error-actions {
|
.modal-actions {
|
||||||
display: flex;
|
display: flex;
|
||||||
justify-content: center;
|
justify-content: center;
|
||||||
}
|
}
|
||||||
|
|
||||||
.error-btn {
|
.modal-btn {
|
||||||
background-color: #DC2626;
|
|
||||||
color: white;
|
|
||||||
border: none;
|
border: none;
|
||||||
border-radius: 8px;
|
border-radius: 8px;
|
||||||
padding: 10px 32px;
|
padding: 10px 32px;
|
||||||
@ -172,15 +204,99 @@ defineExpose({
|
|||||||
cursor: pointer;
|
cursor: pointer;
|
||||||
transition: all 0.2s;
|
transition: all 0.2s;
|
||||||
min-width: 80px;
|
min-width: 80px;
|
||||||
|
color: white;
|
||||||
}
|
}
|
||||||
|
|
||||||
.error-btn:hover {
|
.modal-btn:active {
|
||||||
|
transform: scale(0.98);
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Error 类型样式 */
|
||||||
|
.modal-error .icon-circle-error {
|
||||||
|
background-color: #FEE2E2;
|
||||||
|
border-color: #FECACA;
|
||||||
|
}
|
||||||
|
|
||||||
|
.modal-error .icon-symbol-error {
|
||||||
|
color: #DC2626;
|
||||||
|
}
|
||||||
|
|
||||||
|
.modal-error .modal-btn-error {
|
||||||
|
background-color: #DC2626;
|
||||||
|
}
|
||||||
|
|
||||||
|
.modal-error .modal-btn-error:hover {
|
||||||
background-color: #B91C1C;
|
background-color: #B91C1C;
|
||||||
}
|
}
|
||||||
|
|
||||||
.error-btn:active {
|
.modal-error .modal-btn-error:active {
|
||||||
background-color: #991B1B;
|
background-color: #991B1B;
|
||||||
transform: scale(0.98);
|
}
|
||||||
|
|
||||||
|
/* Warning 类型样式 */
|
||||||
|
.modal-warning .icon-circle-warning {
|
||||||
|
background-color: #FEF3C7;
|
||||||
|
border-color: #FDE68A;
|
||||||
|
}
|
||||||
|
|
||||||
|
.modal-warning .icon-symbol-warning {
|
||||||
|
color: #D97706;
|
||||||
|
}
|
||||||
|
|
||||||
|
.modal-warning .modal-btn-warning {
|
||||||
|
background-color: #D97706;
|
||||||
|
}
|
||||||
|
|
||||||
|
.modal-warning .modal-btn-warning:hover {
|
||||||
|
background-color: #B45309;
|
||||||
|
}
|
||||||
|
|
||||||
|
.modal-warning .modal-btn-warning:active {
|
||||||
|
background-color: #92400E;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Success 类型样式 */
|
||||||
|
.modal-success .icon-circle-success {
|
||||||
|
background-color: #D1FAE5;
|
||||||
|
border-color: #A7F3D0;
|
||||||
|
}
|
||||||
|
|
||||||
|
.modal-success .icon-symbol-success {
|
||||||
|
color: #059669;
|
||||||
|
}
|
||||||
|
|
||||||
|
.modal-success .modal-btn-success {
|
||||||
|
background-color: #059669;
|
||||||
|
}
|
||||||
|
|
||||||
|
.modal-success .modal-btn-success:hover {
|
||||||
|
background-color: #047857;
|
||||||
|
}
|
||||||
|
|
||||||
|
.modal-success .modal-btn-success:active {
|
||||||
|
background-color: #065F46;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Info 类型样式 */
|
||||||
|
.modal-info .icon-circle-info {
|
||||||
|
background-color: #DBEAFE;
|
||||||
|
border-color: #BFDBFE;
|
||||||
|
}
|
||||||
|
|
||||||
|
.modal-info .icon-symbol-info {
|
||||||
|
color: #2563EB;
|
||||||
|
}
|
||||||
|
|
||||||
|
.modal-info .modal-btn-info {
|
||||||
|
background-color: #2563EB;
|
||||||
|
}
|
||||||
|
|
||||||
|
.modal-info .modal-btn-info:hover {
|
||||||
|
background-color: #1D4ED8;
|
||||||
|
}
|
||||||
|
|
||||||
|
.modal-info .modal-btn-info:active {
|
||||||
|
background-color: #1E40AF;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* 动画效果 */
|
/* 动画效果 */
|
||||||
@ -214,7 +330,7 @@ defineExpose({
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@keyframes errorPulse {
|
@keyframes iconPulse {
|
||||||
0% {
|
0% {
|
||||||
transform: scale(0.8);
|
transform: scale(0.8);
|
||||||
opacity: 0.5;
|
opacity: 0.5;
|
||||||
@ -230,25 +346,25 @@ defineExpose({
|
|||||||
|
|
||||||
/* 响应式设计 */
|
/* 响应式设计 */
|
||||||
@media (max-width: 480px) {
|
@media (max-width: 480px) {
|
||||||
.error-modal {
|
.modal {
|
||||||
max-width: 280px;
|
max-width: 280px;
|
||||||
padding: 20px 16px 16px;
|
padding: 20px 16px 16px;
|
||||||
}
|
}
|
||||||
|
|
||||||
.error-circle {
|
.icon-circle {
|
||||||
width: 48px;
|
width: 48px;
|
||||||
height: 48px;
|
height: 48px;
|
||||||
}
|
}
|
||||||
|
|
||||||
.error-x {
|
.icon-symbol {
|
||||||
font-size: 20px;
|
font-size: 20px;
|
||||||
}
|
}
|
||||||
|
|
||||||
.error-title {
|
.modal-title {
|
||||||
font-size: 16px;
|
font-size: 16px;
|
||||||
}
|
}
|
||||||
|
|
||||||
.error-message {
|
.modal-message {
|
||||||
font-size: 13px;
|
font-size: 13px;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@ -1,6 +1,24 @@
|
|||||||
// HTTP请求配置
|
// HTTP请求配置
|
||||||
import {getApiBaseUrl, getCurrentEnv, getUserAuth, isDebugMode} from './env.js'
|
import {getApiBaseUrl, getCurrentEnv, getUserAuth, isDebugMode} from './env.js'
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 自定义API错误类
|
||||||
|
*/
|
||||||
|
class ApiError extends Error {
|
||||||
|
constructor(message, options = {}) {
|
||||||
|
super(message)
|
||||||
|
this.name = 'ApiError'
|
||||||
|
this.status = options.status || null // HTTP状态码
|
||||||
|
this.errorCode = options.errorCode || null // 业务错误码 (如: 6010)
|
||||||
|
this.errorCodeName = options.errorCodeName || null // 错误码名称 (如: "TEAM_NOT_FOUND")
|
||||||
|
this.errorMsg = options.errorMsg || null // 业务错误消息
|
||||||
|
this.time = options.time || null // API响应时间戳
|
||||||
|
this.extValues = options.extValues || null // 扩展值
|
||||||
|
this.response = options.response || null // 原始响应数据
|
||||||
|
this.type = options.type || 'unknown' // 错误类型: 'http' | 'business' | 'network'
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
const API_BASE_URL = getApiBaseUrl()
|
const API_BASE_URL = getApiBaseUrl()
|
||||||
const NODE_ENV = getCurrentEnv()
|
const NODE_ENV = getCurrentEnv()
|
||||||
const DEBUG_MODE = isDebugMode()
|
const DEBUG_MODE = isDebugMode()
|
||||||
@ -83,7 +101,7 @@ export function setHeadersFromApp(headerInfo) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// 在http.js中添加导出
|
// 在http.js中添加导出
|
||||||
export { COMMON_HEADERS }
|
export { COMMON_HEADERS, ApiError }
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 通用HTTP请求函数
|
* 通用HTTP请求函数
|
||||||
@ -124,7 +142,18 @@ export async function request(url, options = {}) {
|
|||||||
const response = await fetch(fullUrl, config)
|
const response = await fetch(fullUrl, config)
|
||||||
|
|
||||||
if (!response.ok) {
|
if (!response.ok) {
|
||||||
throw new Error(`HTTP Error: ${response.status} ${response.statusText}`)
|
// 尝试解析响应体获取更多错误信息
|
||||||
|
let errorData = await response.json()
|
||||||
|
|
||||||
|
throw new ApiError(`HTTP Error: ${response.status} ${response.statusText}`, {
|
||||||
|
type: 'http',
|
||||||
|
status: response.status,
|
||||||
|
response: errorData,
|
||||||
|
errorCode: errorData.errorCode,
|
||||||
|
errorCodeName: errorData.errorCodeName,
|
||||||
|
errorMsg: errorData.errorMsg,
|
||||||
|
time: errorData.time
|
||||||
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
const result = await response.json()
|
const result = await response.json()
|
||||||
@ -135,7 +164,16 @@ export async function request(url, options = {}) {
|
|||||||
|
|
||||||
// 检查业务状态
|
// 检查业务状态
|
||||||
if (result.status === false) {
|
if (result.status === false) {
|
||||||
throw new Error(result.message || `API Error: ${result.errorCode}`)
|
throw new ApiError(result.errorMsg || result.message || `API Error: ${result.errorCode}`, {
|
||||||
|
type: 'business',
|
||||||
|
errorCode: result.errorCode,
|
||||||
|
errorCodeName: result.errorCodeName,
|
||||||
|
errorMsg: result.errorMsg,
|
||||||
|
time: result.time,
|
||||||
|
extValues: result.extValues,
|
||||||
|
response: result,
|
||||||
|
status: response.status,
|
||||||
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
return result
|
return result
|
||||||
@ -143,6 +181,16 @@ export async function request(url, options = {}) {
|
|||||||
if (DEBUG_MODE) {
|
if (DEBUG_MODE) {
|
||||||
console.error('❌ API Error:', error)
|
console.error('❌ API Error:', error)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// 如果是网络错误或其他未知错误,包装成ApiError
|
||||||
|
if (!(error instanceof ApiError)) {
|
||||||
|
throw new ApiError(error.message || 'Network or unknown error', {
|
||||||
|
type: 'network',
|
||||||
|
originalError: error,
|
||||||
|
code: 'NETWORK_ERROR'
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
throw error
|
throw error
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@ -70,7 +70,33 @@ export const errorModal = new ErrorModalManager()
|
|||||||
|
|
||||||
// 快捷方法 - 替代alert
|
// 快捷方法 - 替代alert
|
||||||
export const showError = (message, title = 'Error') => {
|
export const showError = (message, title = 'Error') => {
|
||||||
return errorModal.show(message, { title })
|
return errorModal.show(message, { title, type: 'error' })
|
||||||
|
}
|
||||||
|
|
||||||
|
// 信息提示
|
||||||
|
export const showInfo = (message, title = 'Info') => {
|
||||||
|
return errorModal.show(message, { title, type: 'info' })
|
||||||
|
}
|
||||||
|
|
||||||
|
// 成功提示
|
||||||
|
export const showSuccess = (message, title = 'Success') => {
|
||||||
|
return errorModal.show(message, { title, type: 'success' })
|
||||||
|
}
|
||||||
|
|
||||||
|
// 警告提示
|
||||||
|
export const showWarning = (message, title = 'Warning') => {
|
||||||
|
return errorModal.show(message, { title, type: 'warning' })
|
||||||
|
}
|
||||||
|
|
||||||
|
// 通用提示方法
|
||||||
|
export const showToast = (message, options = {}) => {
|
||||||
|
const defaultOptions = {
|
||||||
|
title: 'Notice',
|
||||||
|
type: 'info',
|
||||||
|
duration: 3000, // 自动关闭时间
|
||||||
|
...options
|
||||||
|
}
|
||||||
|
return errorModal.show(message, defaultOptions)
|
||||||
}
|
}
|
||||||
|
|
||||||
// 错误处理的专用方法
|
// 错误处理的专用方法
|
||||||
@ -81,14 +107,23 @@ export const handleError = (error) => {
|
|||||||
if (error.errorCode === 1083) {
|
if (error.errorCode === 1083) {
|
||||||
title = 'Service Unavailable'
|
title = 'Service Unavailable'
|
||||||
message = 'Exchange function is not available'
|
message = 'Exchange function is not available'
|
||||||
|
} else if (error.errorCode === 6010) {
|
||||||
|
title = 'Team Not Found'
|
||||||
|
message = 'The team does not exist or has been disbanded'
|
||||||
} else if (error.message && error.message.includes('HTTP Error: 406')) {
|
} else if (error.message && error.message.includes('HTTP Error: 406')) {
|
||||||
title = 'Request Not Acceptable'
|
title = 'Request Not Acceptable'
|
||||||
message = 'Something went wrong, please retry.'
|
message = 'Something went wrong, please retry.'
|
||||||
|
} else if (error.errorMsg) {
|
||||||
|
// 优先使用 errorMsg
|
||||||
|
message = error.errorMsg
|
||||||
|
if (error.errorCodeName) {
|
||||||
|
title = error.errorCodeName.replace(/_/g, ' ').toLowerCase().replace(/\b\w/g, l => l.toUpperCase())
|
||||||
|
}
|
||||||
} else if (error.message) {
|
} else if (error.message) {
|
||||||
message = error.message
|
message = error.message
|
||||||
}
|
}
|
||||||
|
|
||||||
return errorModal.show(message, { title })
|
return errorModal.show(message, { title, type: 'error' })
|
||||||
}
|
}
|
||||||
|
|
||||||
// 确认对话框
|
// 确认对话框
|
||||||
|
|||||||
@ -96,7 +96,8 @@ import { ref, onMounted } from 'vue'
|
|||||||
import { useRouter } from 'vue-router'
|
import { useRouter } from 'vue-router'
|
||||||
import MobileHeader from '../components/MobileHeader.vue'
|
import MobileHeader from '../components/MobileHeader.vue'
|
||||||
import { sendTeamApplyJoin, getWaitApplyRecord, cancelApply } from '../api/wallet.js'
|
import { sendTeamApplyJoin, getWaitApplyRecord, cancelApply } from '../api/wallet.js'
|
||||||
import {showError} from "@/utils/toast.js";
|
import {showError, showWarning, showInfo} from "@/utils/toast.js";
|
||||||
|
import { ApiError } from '@/utils/http.js';
|
||||||
|
|
||||||
const router = useRouter()
|
const router = useRouter()
|
||||||
|
|
||||||
@ -116,6 +117,7 @@ const fetchApplyRecords = async () => {
|
|||||||
} catch (error) {
|
} catch (error) {
|
||||||
console.error('获取申请记录失败:', error)
|
console.error('获取申请记录失败:', error)
|
||||||
applyRecords.value = []
|
applyRecords.value = []
|
||||||
|
showInfo(error.errorMsg)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -138,8 +140,26 @@ const handleCancelApply = async (record) => {
|
|||||||
}
|
}
|
||||||
} catch (error) {
|
} catch (error) {
|
||||||
console.error('撤销申请失败:', error)
|
console.error('撤销申请失败:', error)
|
||||||
|
|
||||||
|
if (error instanceof ApiError) {
|
||||||
|
if (error.type === 'business') {
|
||||||
|
switch (error.errorCode) {
|
||||||
|
case 6404: // 假设的记录不存在错误码
|
||||||
|
showError('申请记录不存在', '撤销失败')
|
||||||
|
break
|
||||||
|
case 6003: // 假设的已处理错误码
|
||||||
|
showError('申请已被处理,无法撤销', '撤销失败')
|
||||||
|
break
|
||||||
|
default:
|
||||||
|
showError(error.errorMsg || error.message || '撤销失败,请重试', '撤销失败')
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
showError('网络错误,请检查网络后重试', '撤销失败')
|
||||||
|
}
|
||||||
|
} else {
|
||||||
showError('撤销失败,请重试')
|
showError('撤销失败,请重试')
|
||||||
}
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
const submitApplication = async () => {
|
const submitApplication = async () => {
|
||||||
@ -167,8 +187,23 @@ const submitApplication = async () => {
|
|||||||
errorMessage.value = response.message || 'Application failed. Please try again.'
|
errorMessage.value = response.message || 'Application failed. Please try again.'
|
||||||
}
|
}
|
||||||
} catch (error) {
|
} catch (error) {
|
||||||
console.error('提交申请失败:', error)
|
// 根据错误类型和错误码做不同处理
|
||||||
errorMessage.value = 'Application failed. Please try again.'
|
if (error instanceof ApiError) {
|
||||||
|
if (error.type === 'business') {
|
||||||
|
showError('business error!' + error.errorMsg)
|
||||||
|
|
||||||
|
} else if (error.type === 'http') {
|
||||||
|
// HTTP错误
|
||||||
|
if (error.status === 406) {
|
||||||
|
showWarning(error.errorMsg)
|
||||||
|
} else {
|
||||||
|
showError(error.message || '未知错误,请重试')
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
// 非 ApiError 类型的错误
|
||||||
|
showError('未知错误,请重试')
|
||||||
|
}
|
||||||
|
}
|
||||||
} finally {
|
} finally {
|
||||||
isLoading.value = false
|
isLoading.value = false
|
||||||
}
|
}
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user