Skip to content

Commit 655c08a

Browse files
authored
Merge pull request #2057 from Azir-11/main
优化错误预览组件及相关内容
2 parents ece982c + 0077544 commit 655c08a

File tree

11 files changed

+242
-136
lines changed

11 files changed

+242
-136
lines changed

server/middleware/jwt.go

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -17,7 +17,7 @@ func JWTAuth() gin.HandlerFunc {
1717
// 我们这里jwt鉴权取头部信息 x-token 登录时回返回token信息 这里前端需要把token存储到cookie或者本地localStorage中 不过需要跟后端协商过期时间 可以约定刷新令牌或者重新登录
1818
token := utils.GetToken(c)
1919
if token == "" {
20-
response.NoAuth("未登录或非法访问", c)
20+
response.NoAuth("未登录或非法访问,请登录", c)
2121
c.Abort()
2222
return
2323
}
@@ -32,7 +32,7 @@ func JWTAuth() gin.HandlerFunc {
3232
claims, err := j.ParseToken(token)
3333
if err != nil {
3434
if errors.Is(err, utils.TokenExpired) {
35-
response.NoAuth("授权已过期", c)
35+
response.NoAuth("登录已过期,请重新登录", c)
3636
utils.ClearToken(c)
3737
c.Abort()
3838
return

web/src/App.vue

Lines changed: 30 additions & 28 deletions
Original file line numberDiff line numberDiff line change
@@ -1,41 +1,43 @@
11
<template>
2-
<div
3-
id="app"
4-
class="bg-gray-50 text-slate-700 dark:text-slate-500 dark:bg-slate-800"
5-
>
2+
<div id="app" class="bg-gray-50 text-slate-700 dark:text-slate-500 dark:bg-slate-800">
63
<el-config-provider :locale="zhCn">
74
<router-view />
5+
<Application />
86
</el-config-provider>
97
</div>
108
</template>
119

1210
<script setup>
13-
import zhCn from 'element-plus/dist/locale/zh-cn.mjs'
14-
import { useAppStore } from '@/pinia'
15-
useAppStore()
16-
defineOptions({
17-
name: 'App'
18-
})
11+
import zhCn from 'element-plus/dist/locale/zh-cn.mjs'
12+
import Application from '@/components/application/index.vue'
13+
import { useAppStore } from '@/pinia'
14+
15+
useAppStore()
16+
defineOptions({
17+
name: 'App'
18+
})
1919
</script>
2020
<style lang="scss">
21-
// 引入初始化样式
22-
#app {
23-
height: 100vh;
24-
overflow: hidden;
25-
font-weight: 400 !important;
26-
}
27-
.el-button {
28-
font-weight: 400 !important;
29-
}
21+
// 引入初始化样式
22+
#app {
23+
height: 100vh;
24+
overflow: hidden;
25+
font-weight: 400 !important;
26+
}
27+
28+
.el-button {
29+
font-weight: 400 !important;
30+
}
31+
32+
.gva-body-h {
33+
min-height: calc(100% - 3rem);
34+
}
3035
31-
.gva-body-h {
32-
min-height: calc(100% - 3rem);
33-
}
36+
.gva-container {
37+
height: calc(100% - 2.5rem);
38+
}
3439
35-
.gva-container {
36-
height: calc(100% - 2.5rem);
37-
}
38-
.gva-container2 {
39-
height: calc(100% - 4.5rem);
40-
}
40+
.gva-container2 {
41+
height: calc(100% - 4.5rem);
42+
}
4143
</style>

web/src/assets/icons/close.svg

Lines changed: 1 addition & 0 deletions
Loading

web/src/assets/icons/idea.svg

Lines changed: 1 addition & 0 deletions
Loading

web/src/assets/icons/lock.svg

Lines changed: 1 addition & 0 deletions
Loading

web/src/assets/icons/server.svg

Lines changed: 1 addition & 0 deletions
Loading

web/src/assets/icons/warn.svg

Lines changed: 1 addition & 0 deletions
Loading
Lines changed: 39 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,39 @@
1+
<template>
2+
<error-preview v-if="showError" :error-data="errorInfo" @close="handleClose" @confirm="handleConfirm" />
3+
</template>
4+
5+
<script setup>
6+
import { ref, onUnmounted } from 'vue'
7+
import { emitter } from '@/utils/bus'
8+
import ErrorPreview from '@/components/errorPreview/index.vue'
9+
10+
const showError = ref(false)
11+
const errorInfo = ref(null)
12+
let cb = null
13+
14+
const showErrorDialog = (data) => {
15+
// 这玩意同时只允许存在一个
16+
if(showError.value) return
17+
18+
errorInfo.value = data
19+
showError.value = true
20+
cb = data?.fn || null
21+
}
22+
23+
const handleClose = () => {
24+
showError.value = false
25+
errorInfo.value = null
26+
cb = null
27+
}
28+
29+
const handleConfirm = (code) => {
30+
cb && cb(code)
31+
handleClose()
32+
}
33+
34+
emitter.on('show-error', showErrorDialog)
35+
36+
onUnmounted(() => {
37+
emitter.off('show-error', showErrorDialog)
38+
})
39+
</script>
Lines changed: 126 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,126 @@
1+
<template>
2+
<div
3+
class="fixed inset-0 bg-black/40 flex items-center justify-center z-[999]"
4+
@click.self="closeModal"
5+
>
6+
<div class="bg-white rounded-xl shadow-dialog w-full max-w-md mx-4 transform transition-all duration-300 ease-in-out">
7+
<!-- 弹窗头部 -->
8+
<div class="p-5 border-b border-gray-100 flex justify-between items-center">
9+
<h3 class="text-lg font-semibold text-gray-800">{{ displayData.title }}</h3>
10+
<button class="text-gray-400 hover:text-gray-600 transition-colors" @click="closeModal">
11+
<close />
12+
</button>
13+
</div>
14+
15+
<!-- 弹窗内容 -->
16+
<div class="p-6">
17+
<!-- 错误类型 -->
18+
<div class="mb-4">
19+
<div class="text-xs font-medium text-gray-500 uppercase mb-2">错误类型</div>
20+
<div class="flex items-center gap-2">
21+
<lock v-if="displayData.icon === 'lock'" class="text-red-500 w-5 h-5" />
22+
<warn v-if="displayData.icon === 'warn'" class="text-red-500 w-5 h-5" />
23+
<server v-if="displayData.icon === 'server'" class="text-red-500 w-5 h-5" />
24+
<span class="font-medium text-gray-800">{{ displayData.type }}</span>
25+
</div>
26+
</div>
27+
28+
<!-- 具体错误 -->
29+
<div class="mb-6">
30+
<div class="text-xs font-medium text-gray-500 uppercase mb-2">具体错误</div>
31+
<div class="bg-gray-100 rounded-lg p-3 text-sm text-gray-700 leading-relaxed">
32+
{{ displayData.message }}
33+
</div>
34+
</div>
35+
36+
<!-- 提示信息 -->
37+
<div v-if="displayData.tips">
38+
<div class="text-xs font-medium text-gray-500 uppercase mb-2">提示</div>
39+
<div class="flex items-center gap-2">
40+
<idea class="text-blue-500 w-5 h-5" />
41+
<p class="text-sm text-gray-600">{{ displayData.tips }}</p>
42+
</div>
43+
</div>
44+
</div>
45+
46+
<!-- 弹窗底部 -->
47+
<div class="py-2 px-4 border-t border-gray-100 flex justify-end">
48+
<button class="px-4 py-2 bg-blue-600 text-white rounded-lg hover:bg-blue-700 transition-colors font-medium text-sm shadow-sm" @click="handleConfirm">
49+
确定
50+
</button>
51+
</div>
52+
</div>
53+
</div>
54+
</template>
55+
56+
<script setup>
57+
import { defineProps, defineEmits, ref, computed, onMounted } from 'vue';
58+
59+
const props = defineProps({
60+
errorData: {
61+
type: Object,
62+
required: true
63+
}
64+
});
65+
66+
const emits = defineEmits(['close', 'confirm']);
67+
68+
const presetErrors = {
69+
500: {
70+
title: '检测到接口错误',
71+
type: '服务器发生内部错误',
72+
icon: 'server',
73+
color: 'text-red-500',
74+
tips: '此类错误内容常见于后台panic,请先查看后台日志,如果影响您正常使用可强制登出清理缓存'
75+
},
76+
404: {
77+
title: '资源未找到',
78+
type: 'Not Found',
79+
icon: 'warn',
80+
color: 'text-orange-500',
81+
tips: '此类错误多为接口未注册(或未重启)或者请求路径(方法)与api路径(方法)不符--如果为自动化代码请检查是否存在空格'
82+
},
83+
401: {
84+
title: '身份认证失败',
85+
type: '身份令牌无效',
86+
icon: 'lock',
87+
color: 'text-purple-500',
88+
tips: '您的身份认证已过期或无效,请重新登录。'
89+
},
90+
'network': {
91+
title: '网络错误',
92+
type: 'Network Error',
93+
icon: 'fa-wifi-slash',
94+
color: 'text-gray-500',
95+
tips: '无法连接到服务器,请检查您的网络连接。'
96+
}
97+
};
98+
99+
const displayData = computed(() => {
100+
const preset = presetErrors[props.errorData.code];
101+
if (preset) {
102+
return {
103+
...preset,
104+
message: props.errorData.message || '没有提供额外信息。'
105+
};
106+
}
107+
108+
return {
109+
title: '未知错误',
110+
type: '检测到请求错误',
111+
icon: 'fa-question-circle',
112+
color: 'text-gray-400',
113+
message: props.errorData.message || '发生了一个未知错误。',
114+
tips: '请检查控制台获取更多信息。'
115+
};
116+
});
117+
118+
const closeModal = () => {
119+
emits('close')
120+
};
121+
122+
const handleConfirm = () => {
123+
emits('confirm', props.errorData.code);
124+
closeModal();
125+
};
126+
</script>

web/src/style/reset.scss

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -393,7 +393,7 @@ fieldset,
393393
table,
394394
th,
395395
td {
396-
border: none;
396+
// border: none;
397397
font-family: 'Helvetica Neue', Helvetica, 'PingFang SC', 'Hiragino Sans GB',
398398
'Microsoft YaHei', '微软雅黑', Arial, sans-serif;
399399
font-size: 14px;

0 commit comments

Comments
 (0)