Skip to content
项目
群组
代码片段
帮助
当前项目
正在载入...
登录 / 注册
切换导航面板
B
basic-vue-admin
概览
概览
详情
活动
周期分析
版本库
存储库
文件
提交
分支
标签
贡献者
分支图
比较
统计图
问题
0
议题
0
列表
看板
标记
里程碑
合并请求
0
合并请求
0
CI / CD
CI / CD
流水线
作业
日程表
图表
维基
Wiki
代码片段
代码片段
成员
成员
折叠边栏
关闭边栏
活动
图像
聊天
创建新问题
作业
提交
问题看板
Open sidebar
Basic
basic-vue-admin
Commits
136cbb1e
Unverified
提交
136cbb1e
authored
3月 19, 2022
作者:
Captain
提交者:
GitHub
3月 19, 2022
浏览文件
操作
浏览文件
下载
电子邮件补丁
差异文件
feat: add request retry (#1553)
上级
78535bdd
隐藏空白字符变更
内嵌
并排
正在显示
11 个修改的文件
包含
111 行增加
和
3 行删除
+111
-3
user.ts
mock/sys/user.ts
+8
-0
user.ts
src/api/sys/user.ts
+14
-0
demo.ts
src/locales/lang/en/routes/demo.ts
+1
-0
demo.ts
src/locales/lang/zh-CN/routes/demo.ts
+1
-0
feat.ts
src/router/routes/modules/demo/feat.ts
+9
-0
Axios.ts
src/utils/http/axios/Axios.ts
+4
-1
axiosRetry.ts
src/utils/http/axios/axiosRetry.ts
+28
-0
axiosTransform.ts
src/utils/http/axios/axiosTransform.ts
+1
-1
index.ts
src/utils/http/axios/index.ts
+15
-1
index.vue
src/views/demo/feat/request-demo/index.vue
+23
-0
axios.d.ts
types/axios.d.ts
+7
-0
没有找到文件。
mock/sys/user.ts
浏览文件 @
136cbb1e
...
@@ -111,4 +111,12 @@ export default [
...
@@ -111,4 +111,12 @@ export default [
return
resultSuccess
(
undefined
,
{
message
:
'Token has been destroyed'
});
return
resultSuccess
(
undefined
,
{
message
:
'Token has been destroyed'
});
},
},
},
},
{
url
:
'/basic-api/testRetry'
,
statusCode
:
405
,
method
:
'get'
,
response
:
()
=>
{
return
resultError
(
'Error!'
);
},
},
]
as
MockMethod
[];
]
as
MockMethod
[];
src/api/sys/user.ts
浏览文件 @
136cbb1e
...
@@ -8,6 +8,7 @@ enum Api {
...
@@ -8,6 +8,7 @@ enum Api {
Logout
=
'/logout'
,
Logout
=
'/logout'
,
GetUserInfo
=
'/getUserInfo'
,
GetUserInfo
=
'/getUserInfo'
,
GetPermCode
=
'/getPermCode'
,
GetPermCode
=
'/getPermCode'
,
TestRetry
=
'/testRetry'
,
}
}
/**
/**
...
@@ -39,3 +40,16 @@ export function getPermCode() {
...
@@ -39,3 +40,16 @@ export function getPermCode() {
export
function
doLogout
()
{
export
function
doLogout
()
{
return
defHttp
.
get
({
url
:
Api
.
Logout
});
return
defHttp
.
get
({
url
:
Api
.
Logout
});
}
}
export
function
testRetry
()
{
return
defHttp
.
get
(
{
url
:
Api
.
TestRetry
},
{
retryRequest
:
{
isOpenRetry
:
true
,
count
:
5
,
waitTime
:
1000
,
},
},
);
}
src/locales/lang/en/routes/demo.ts
浏览文件 @
136cbb1e
...
@@ -92,6 +92,7 @@ export default {
...
@@ -92,6 +92,7 @@ export default {
breadcrumb
:
'Breadcrumbs'
,
breadcrumb
:
'Breadcrumbs'
,
breadcrumbFlat
:
'Flat Mode'
,
breadcrumbFlat
:
'Flat Mode'
,
breadcrumbFlatDetail
:
'Flat mode details'
,
breadcrumbFlatDetail
:
'Flat mode details'
,
requestDemo
:
'Retry request demo'
,
breadcrumbChildren
:
'Level mode'
,
breadcrumbChildren
:
'Level mode'
,
breadcrumbChildrenDetail
:
'Level mode detail'
,
breadcrumbChildrenDetail
:
'Level mode detail'
,
...
...
src/locales/lang/zh-CN/routes/demo.ts
浏览文件 @
136cbb1e
...
@@ -88,6 +88,7 @@ export default {
...
@@ -88,6 +88,7 @@ export default {
ws
:
'websocket测试'
,
ws
:
'websocket测试'
,
breadcrumb
:
'面包屑导航'
,
breadcrumb
:
'面包屑导航'
,
breadcrumbFlat
:
'平级模式'
,
breadcrumbFlat
:
'平级模式'
,
requestDemo
:
'测试请求重试'
,
breadcrumbFlatDetail
:
'平级详情'
,
breadcrumbFlatDetail
:
'平级详情'
,
breadcrumbChildren
:
'层级模式'
,
breadcrumbChildren
:
'层级模式'
,
breadcrumbChildrenDetail
:
'层级详情'
,
breadcrumbChildrenDetail
:
'层级详情'
,
...
...
src/router/routes/modules/demo/feat.ts
浏览文件 @
136cbb1e
...
@@ -32,6 +32,15 @@ const feat: AppRouteModule = {
...
@@ -32,6 +32,15 @@ const feat: AppRouteModule = {
},
},
},
},
{
{
path
:
'request'
,
name
:
'RequestDemo'
,
// @ts-ignore
component
:
()
=>
import
(
'/@/views/demo/feat/request-demo/index.vue'
),
meta
:
{
title
:
t
(
'routes.demo.feat.requestDemo'
),
},
},
{
path
:
'session-timeout'
,
path
:
'session-timeout'
,
name
:
'SessionTimeout'
,
name
:
'SessionTimeout'
,
component
:
()
=>
import
(
'/@/views/demo/feat/session-timeout/index.vue'
),
component
:
()
=>
import
(
'/@/views/demo/feat/session-timeout/index.vue'
),
...
...
src/utils/http/axios/Axios.ts
浏览文件 @
136cbb1e
...
@@ -111,7 +111,10 @@ export class VAxios {
...
@@ -111,7 +111,10 @@ export class VAxios {
// Response result interceptor error capture
// Response result interceptor error capture
responseInterceptorsCatch
&&
responseInterceptorsCatch
&&
isFunction
(
responseInterceptorsCatch
)
&&
isFunction
(
responseInterceptorsCatch
)
&&
this
.
axiosInstance
.
interceptors
.
response
.
use
(
undefined
,
responseInterceptorsCatch
);
this
.
axiosInstance
.
interceptors
.
response
.
use
(
undefined
,
(
error
)
=>
{
// @ts-ignore
responseInterceptorsCatch
(
this
.
axiosInstance
,
error
);
});
}
}
/**
/**
...
...
src/utils/http/axios/axiosRetry.ts
0 → 100644
浏览文件 @
136cbb1e
import
{
AxiosError
,
AxiosInstance
}
from
'axios'
;
/**
* 请求重试机制
*/
export
class
AxiosRetry
{
/**
* 重试
*/
retry
(
AxiosInstance
:
AxiosInstance
,
error
:
AxiosError
)
{
// @ts-ignore
const
{
config
}
=
error
.
response
;
const
{
waitTime
,
count
}
=
config
?.
requestOptions
?.
retryRequest
;
config
.
__retryCount
=
config
.
__retryCount
||
0
;
if
(
config
.
__retryCount
>=
count
)
{
return
Promise
.
reject
(
error
);
}
config
.
__retryCount
+=
1
;
return
this
.
delay
(
waitTime
).
then
(()
=>
AxiosInstance
(
config
));
}
/**
* 延迟
*/
private
delay
(
waitTime
:
number
)
{
return
new
Promise
((
resolve
)
=>
setTimeout
(
resolve
,
waitTime
));
}
}
src/utils/http/axios/axiosTransform.ts
浏览文件 @
136cbb1e
...
@@ -48,5 +48,5 @@ export abstract class AxiosTransform {
...
@@ -48,5 +48,5 @@ export abstract class AxiosTransform {
/**
/**
* @description: 请求之后的拦截器错误处理
* @description: 请求之后的拦截器错误处理
*/
*/
responseInterceptorsCatch
?:
(
error
:
Error
)
=>
void
;
responseInterceptorsCatch
?:
(
axiosInstance
:
AxiosResponse
,
error
:
Error
)
=>
void
;
}
}
src/utils/http/axios/index.ts
浏览文件 @
136cbb1e
...
@@ -17,6 +17,7 @@ import { useErrorLogStoreWithOut } from '/@/store/modules/errorLog';
...
@@ -17,6 +17,7 @@ import { useErrorLogStoreWithOut } from '/@/store/modules/errorLog';
import
{
useI18n
}
from
'/@/hooks/web/useI18n'
;
import
{
useI18n
}
from
'/@/hooks/web/useI18n'
;
import
{
joinTimestamp
,
formatRequestDate
}
from
'./helper'
;
import
{
joinTimestamp
,
formatRequestDate
}
from
'./helper'
;
import
{
useUserStoreWithOut
}
from
'/@/store/modules/user'
;
import
{
useUserStoreWithOut
}
from
'/@/store/modules/user'
;
import
{
AxiosRetry
}
from
'/@/utils/http/axios/axiosRetry'
;
const
globSetting
=
useGlobSetting
();
const
globSetting
=
useGlobSetting
();
const
urlPrefix
=
globSetting
.
urlPrefix
;
const
urlPrefix
=
globSetting
.
urlPrefix
;
...
@@ -158,7 +159,7 @@ const transform: AxiosTransform = {
...
@@ -158,7 +159,7 @@ const transform: AxiosTransform = {
/**
/**
* @description: 响应错误处理
* @description: 响应错误处理
*/
*/
responseInterceptorsCatch
:
(
error
:
any
)
=>
{
responseInterceptorsCatch
:
(
axiosInstance
:
AxiosResponse
,
error
:
any
)
=>
{
const
{
t
}
=
useI18n
();
const
{
t
}
=
useI18n
();
const
errorLogStore
=
useErrorLogStoreWithOut
();
const
errorLogStore
=
useErrorLogStoreWithOut
();
errorLogStore
.
addAjaxErrorInfo
(
error
);
errorLogStore
.
addAjaxErrorInfo
(
error
);
...
@@ -189,6 +190,14 @@ const transform: AxiosTransform = {
...
@@ -189,6 +190,14 @@ const transform: AxiosTransform = {
}
}
checkStatus
(
error
?.
response
?.
status
,
msg
,
errorMessageMode
);
checkStatus
(
error
?.
response
?.
status
,
msg
,
errorMessageMode
);
// 添加自动重试机制 保险起见 只针对GET请求
const
retryRequest
=
new
AxiosRetry
();
const
{
isOpenRetry
}
=
config
.
requestOptions
.
retryRequest
;
config
.
method
?.
toUpperCase
()
===
RequestEnum
.
GET
&&
isOpenRetry
&&
// @ts-ignore
retryRequest
.
retry
(
axiosInstance
,
error
);
return
Promise
.
reject
(
error
);
return
Promise
.
reject
(
error
);
},
},
};
};
...
@@ -234,6 +243,11 @@ function createAxios(opt?: Partial<CreateAxiosOptions>) {
...
@@ -234,6 +243,11 @@ function createAxios(opt?: Partial<CreateAxiosOptions>) {
ignoreCancelToken
:
true
,
ignoreCancelToken
:
true
,
// 是否携带token
// 是否携带token
withToken
:
true
,
withToken
:
true
,
retryRequest
:
{
isOpenRetry
:
true
,
count
:
5
,
waitTime
:
100
,
},
},
},
},
},
opt
||
{},
opt
||
{},
...
...
src/views/demo/feat/request-demo/index.vue
0 → 100644
浏览文件 @
136cbb1e
<
template
>
<div
class=
"request-box"
>
<a-button
@
click=
"handleClick"
color=
"primary"
>
点击会重新发起请求5次
</a-button>
<p>
打开浏览器的network面板,可以看到发出了六次请求
</p>
</div>
</
template
>
<
script
lang=
"ts"
setup
>
import
{
testRetry
}
from
'/@/api/sys/user'
;
// @ts-ignore
const
handleClick
=
async
()
=>
{
await
testRetry
();
};
</
script
>
<
style
lang=
"less"
>
.request-box
{
margin
:
50px
;
}
p
{
margin-top
:
10px
;
}
</
style
>
types/axios.d.ts
浏览文件 @
136cbb1e
...
@@ -23,8 +23,15 @@ export interface RequestOptions {
...
@@ -23,8 +23,15 @@ export interface RequestOptions {
ignoreCancelToken
?:
boolean
;
ignoreCancelToken
?:
boolean
;
// Whether to send token in header
// Whether to send token in header
withToken
?:
boolean
;
withToken
?:
boolean
;
// 请求重试机制
retryRequest
?:
RetryRequest
;
}
}
export
interface
RetryRequest
{
isOpenRetry
:
boolean
;
count
:
number
;
waitTime
:
number
;
}
export
interface
Result
<
T
=
any
>
{
export
interface
Result
<
T
=
any
>
{
code
:
number
;
code
:
number
;
type
:
'success'
|
'error'
|
'warning'
;
type
:
'success'
|
'error'
|
'warning'
;
...
...
编写
预览
Markdown
格式
0%
重试
或
添加新文件
添加附件
取消
您添加了
0
人
到此讨论。请谨慎行事。
请先完成此评论的编辑!
取消
请
注册
或者
登录
后发表评论