@@ -14,29 +14,88 @@ const service = axios.create({
14
14
let activeAxios = 0
15
15
let timer
16
16
let loadingInstance
17
+ let isLoadingVisible = false
18
+ let forceCloseTimer
19
+
17
20
const showLoading = (
18
21
option = {
19
22
target : null
20
23
}
21
24
) => {
22
25
const loadDom = document . getElementById ( 'gva-base-load-dom' )
23
26
activeAxios ++
27
+
28
+ // 清除之前的定时器
24
29
if ( timer ) {
25
30
clearTimeout ( timer )
26
31
}
32
+
33
+ // 清除强制关闭定时器
34
+ if ( forceCloseTimer ) {
35
+ clearTimeout ( forceCloseTimer )
36
+ }
37
+
27
38
timer = setTimeout ( ( ) => {
28
- if ( activeAxios > 0 ) {
39
+ // 再次检查activeAxios状态,防止竞态条件
40
+ if ( activeAxios > 0 && ! isLoadingVisible ) {
29
41
if ( ! option . target ) option . target = loadDom
30
42
loadingInstance = ElLoading . service ( option )
43
+ isLoadingVisible = true
44
+
45
+ // 设置强制关闭定时器,防止loading永远不关闭(30秒超时)
46
+ forceCloseTimer = setTimeout ( ( ) => {
47
+ if ( isLoadingVisible && loadingInstance ) {
48
+ console . warn ( 'Loading强制关闭:超时30秒' )
49
+ loadingInstance . close ( )
50
+ isLoadingVisible = false
51
+ activeAxios = 0 // 重置计数器
52
+ }
53
+ } , 30000 )
31
54
}
32
55
} , 400 )
33
56
}
34
57
35
58
const closeLoading = ( ) => {
36
59
activeAxios --
37
60
if ( activeAxios <= 0 ) {
61
+ activeAxios = 0 // 确保不会变成负数
38
62
clearTimeout ( timer )
39
- loadingInstance && loadingInstance . close ( )
63
+
64
+ if ( forceCloseTimer ) {
65
+ clearTimeout ( forceCloseTimer )
66
+ forceCloseTimer = null
67
+ }
68
+
69
+ if ( isLoadingVisible && loadingInstance ) {
70
+ loadingInstance . close ( )
71
+ isLoadingVisible = false
72
+ }
73
+ loadingInstance = null
74
+ }
75
+ }
76
+
77
+ // 全局重置loading状态的函数,用于异常情况
78
+ const resetLoading = ( ) => {
79
+ activeAxios = 0
80
+ isLoadingVisible = false
81
+
82
+ if ( timer ) {
83
+ clearTimeout ( timer )
84
+ timer = null
85
+ }
86
+
87
+ if ( forceCloseTimer ) {
88
+ clearTimeout ( forceCloseTimer )
89
+ forceCloseTimer = null
90
+ }
91
+
92
+ if ( loadingInstance ) {
93
+ try {
94
+ loadingInstance . close ( )
95
+ } catch ( e ) {
96
+ console . warn ( '关闭loading时出错:' , e )
97
+ }
98
+ loadingInstance = null
40
99
}
41
100
}
42
101
// http request 拦截器
@@ -105,6 +164,8 @@ service.interceptors.response.use(
105
164
}
106
165
107
166
if ( ! error . response ) {
167
+ // 网络错误时重置loading状态
168
+ resetLoading ( )
108
169
errorBoxVisible = true
109
170
ElMessageBox . confirm (
110
171
`
@@ -196,4 +257,12 @@ service.interceptors.response.use(
196
257
return error
197
258
}
198
259
)
260
+ // 监听页面卸载事件,确保loading被正确清理
261
+ if ( typeof window !== 'undefined' ) {
262
+ window . addEventListener ( 'beforeunload' , resetLoading )
263
+ window . addEventListener ( 'unload' , resetLoading )
264
+ }
265
+
266
+ // 导出service和resetLoading函数
267
+ export { resetLoading }
199
268
export default service
0 commit comments