Commit 3eb11e2658e9cbe112793dd189833ab1aabb3b95

Authored by xingyu4j
1 parent 9adc84c3

refactor: refactor axios

Showing 49 changed files with 314 additions and 412 deletions
yudao-ui-admin-vue3/src/api/bpm/form/index.ts
1   -import { useAxios } from '@/hooks/web/useAxios'
  1 +import request from '@/config/axios'
2 2 import { FormVO } from './types'
3   -const request = useAxios()
4 3  
5 4 // 创建工作流的表单定义
6 5 export const createFormApi = async (data: FormVO) => {
... ...
yudao-ui-admin-vue3/src/api/bpm/leave/index.ts
1   -import { useAxios } from '@/hooks/web/useAxios'
  1 +import request from '@/config/axios'
2 2 import { LeaveVO } from './types'
3   -const request = useAxios()
4 3  
5 4 // 创建请假申请
6 5 export const createLeaveApi = async (data: LeaveVO) => {
... ...
yudao-ui-admin-vue3/src/api/bpm/model/index.ts
1   -import { useAxios } from '@/hooks/web/useAxios'
  1 +import request from '@/config/axios'
2 2 import { ModelVO } from './types'
3   -const request = useAxios()
4 3  
5 4 export const getModelPageApi = async (params) => {
6 5 return await request.get({ url: '/bpm/model/page', params })
... ...
yudao-ui-admin-vue3/src/api/bpm/processInstance/index.ts
1   -import { useAxios } from '@/hooks/web/useAxios'
  1 +import request from '@/config/axios'
2 2 import { ProcessInstanceVO } from './types'
3   -const request = useAxios()
4 3  
5 4 export const getMyProcessInstancePageApi = async (params) => {
6 5 return await request.get({ url: '/bpm/process-instance/my-page', params })
... ...
yudao-ui-admin-vue3/src/api/bpm/task/index.ts
1   -import { useAxios } from '@/hooks/web/useAxios'
2   -
3   -const request = useAxios()
  1 +import request from '@/config/axios'
4 2  
5 3 export const getTodoTaskPage = async (params) => {
6 4 return await request.get({ url: '/bpm/task/todo-page', params })
... ...
yudao-ui-admin-vue3/src/api/bpm/taskAssignRule/index.ts
1   -import { useAxios } from '@/hooks/web/useAxios'
  1 +import request from '@/config/axios'
2 2 import { TaskAssignVO } from './types'
3   -const request = useAxios()
4 3  
5 4 export const getTaskAssignRuleList = async (params) => {
6 5 return await request.get({ url: '/bpm/task-assign-rule/list', params })
... ...
yudao-ui-admin-vue3/src/api/bpm/userGroup/index.ts
1   -import { useAxios } from '@/hooks/web/useAxios'
  1 +import request from '@/config/axios'
2 2 import { UserGroupVO } from './types'
3   -const request = useAxios()
4 3  
5 4 // 创建用户组
6 5 export const createUserGroupApi = async (data: UserGroupVO) => {
... ...
yudao-ui-admin-vue3/src/api/infra/apiAccessLog/index.ts
1   -import { useAxios } from '@/hooks/web/useAxios'
2   -
3   -const request = useAxios()
  1 +import request from '@/config/axios'
4 2  
5 3 // 查询列表API 访问日志
6 4 export const getApiAccessLogPageApi = (params) => {
... ...
yudao-ui-admin-vue3/src/api/infra/apiErrorLog/index.ts
1   -import { useAxios } from '@/hooks/web/useAxios'
2   -
3   -const request = useAxios()
  1 +import request from '@/config/axios'
4 2  
5 3 // 查询列表API 访问日志
6 4 export const getApiErrorLogPageApi = (params) => {
... ...
yudao-ui-admin-vue3/src/api/infra/codegen/index.ts
1   -import { useAxios } from '@/hooks/web/useAxios'
  1 +import request from '@/config/axios'
2 2 import type { CodegenUpdateReqVO, CodegenCreateListReqVO } from './types'
3 3  
4   -const request = useAxios()
5   -
6 4 // 查询列表代码生成表定义
7 5 export const getCodegenTablePageApi = (params) => {
8 6 return request.get({ url: '/infra/codegen/table/page', params })
... ...
yudao-ui-admin-vue3/src/api/infra/config/index.ts
1   -import { useAxios } from '@/hooks/web/useAxios'
  1 +import request from '@/config/axios'
2 2 import type { ConfigVO } from './types'
3 3  
4   -const request = useAxios()
5   -
6 4 // 查询参数列表
7 5 export const getConfigPageApi = (params) => {
8 6 return request.get({ url: '/infra/config/page', params })
... ...
yudao-ui-admin-vue3/src/api/infra/dataSourceConfig/index.ts
1   -import { useAxios } from '@/hooks/web/useAxios'
  1 +import request from '@/config/axios'
2 2 import type { DataSourceConfigVO } from './types'
3 3  
4   -const request = useAxios()
5   -
6 4 // 查询数据源配置列表
7 5 export const getDataSourceConfigListApi = () => {
8 6 return request.get({ url: '/infra/data-source-config/list' })
... ...
yudao-ui-admin-vue3/src/api/infra/dbDoc/index.ts
1   -import { useAxios } from '@/hooks/web/useAxios'
2   -
3   -const request = useAxios()
  1 +import request from '@/config/axios'
4 2  
5 3 // 导出Html
6 4 export const exportHtmlApi = () => {
... ...
yudao-ui-admin-vue3/src/api/infra/fileConfig/index.ts
1   -import { useAxios } from '@/hooks/web/useAxios'
  1 +import request from '@/config/axios'
2 2 import type { FileConfigVO } from './types'
3 3  
4   -const request = useAxios()
5   -
6 4 // 查询文件配置列表
7 5 export const getFileConfigPageApi = (params) => {
8 6 return request.get({ url: '/infra/file-config/page', params })
... ...
yudao-ui-admin-vue3/src/api/infra/fileList/index.ts
1   -import { useAxios } from '@/hooks/web/useAxios'
2   -
3   -const request = useAxios()
  1 +import request from '@/config/axios'
4 2  
5 3 // 查询文件列表
6 4 export const getFilePageApi = (params) => {
... ...
yudao-ui-admin-vue3/src/api/infra/job/index.ts
1   -import { useAxios } from '@/hooks/web/useAxios'
  1 +import request from '@/config/axios'
2 2 import type { JobVO } from './types'
3 3  
4   -const request = useAxios()
5   -
6 4 // 任务列表
7 5 export const getJobPageApi = (params) => {
8 6 return request.get({ url: '/infra/job/page', params })
... ...
yudao-ui-admin-vue3/src/api/infra/jobLog/index.ts
1   -import { useAxios } from '@/hooks/web/useAxios'
2   -
3   -const request = useAxios()
  1 +import request from '@/config/axios'
4 2  
5 3 // 任务日志列表
6 4 export const getJobLogPageApi = (params) => {
... ...
yudao-ui-admin-vue3/src/api/infra/redis/index.ts
1   -import { useAxios } from '@/hooks/web/useAxios'
2   -
3   -const request = useAxios()
  1 +import request from '@/config/axios'
4 2  
5 3 /**
6 4 * 获取redis 监控信息
... ...
yudao-ui-admin-vue3/src/api/login/index.ts
1   -import { useAxios } from '@/hooks/web/useAxios'
  1 +import request from '@/config/axios'
2 2 import { getRefreshToken } from '@/utils/auth'
3 3 import type { UserLoginVO } from './types'
4 4  
5   -const request = useAxios()
6   -
7 5 export interface CodeImgResult {
8 6 captchaOnOff: boolean
9 7 img: string
... ...
yudao-ui-admin-vue3/src/api/pay/app/index.ts
1   -import { useAxios } from '@/hooks/web/useAxios'
  1 +import request from '@/config/axios'
2 2 import type { AppVO } from './types'
3 3  
4   -const request = useAxios()
5   -
6 4 // 查询列表支付应用
7 5 export const getAppPageApi = (params) => {
8 6 return request.get({ url: '/pay/app/page', params })
... ...
yudao-ui-admin-vue3/src/api/pay/channel/index.ts
1   -import { useAxios } from '@/hooks/web/useAxios'
  1 +import request from '@/config/axios'
2 2 import type { ChannelVO } from './types'
3 3  
4   -const request = useAxios()
5   -
6 4 // 查询列表支付渠道
7 5 export const getChannelPageApi = (params) => {
8 6 return request.get({ url: '/pay/channel/page', params })
... ...
yudao-ui-admin-vue3/src/api/pay/merchant/index.ts
1   -import { useAxios } from '@/hooks/web/useAxios'
  1 +import request from '@/config/axios'
2 2 import type { MerchantVO } from './types'
3 3  
4   -const request = useAxios()
5   -
6 4 // 查询列表支付商户
7 5 export const getMerchantPageApi = (params) => {
8 6 return request.get({ url: '/pay/merchant/page', params })
... ...
yudao-ui-admin-vue3/src/api/pay/order/index.ts
1   -import { useAxios } from '@/hooks/web/useAxios'
  1 +import request from '@/config/axios'
2 2 import type { OrderVO } from './types'
3 3  
4   -const request = useAxios()
5   -
6 4 // 查询列表支付订单
7 5 export const getOrderPageApi = async (params) => {
8 6 return await request.get({ url: '/pay/order/page', params })
... ...
yudao-ui-admin-vue3/src/api/pay/refund/index.ts
1   -import { useAxios } from '@/hooks/web/useAxios'
  1 +import request from '@/config/axios'
2 2 import type { RefundVO } from './types'
3 3  
4   -const request = useAxios()
5   -
6 4 // 查询列表退款订单
7 5 export const getRefundPageApi = (params) => {
8 6 return request.get({ url: '/pay/refund/page', params })
... ...
yudao-ui-admin-vue3/src/api/system/dept/index.ts
1   -import { useAxios } from '@/hooks/web/useAxios'
  1 +import request from '@/config/axios'
2 2 import type { DeptVO, DeptListReqVO } from './types'
3 3  
4   -const request = useAxios()
5   -
6 4 // 查询部门(精简)列表
7 5 export const listSimpleDeptApi = () => {
8 6 return request.get({ url: '/system/dept/list-all-simple' })
... ...
yudao-ui-admin-vue3/src/api/system/dict/dict.data.ts
1   -import { useAxios } from '@/hooks/web/useAxios'
  1 +import request from '@/config/axios'
2 2 import type { DictDataVO, DictDataPageReqVO, DictDataExportReqVO } from './types'
3 3  
4   -const request = useAxios()
5   -
6 4 // 查询字典数据(精简)列表
7 5 export const listSimpleDictDataApi = () => {
8 6 return request.get({ url: '/system/dict-data/list-all-simple' })
... ...
yudao-ui-admin-vue3/src/api/system/dict/dict.type.ts
1   -import { useAxios } from '@/hooks/web/useAxios'
  1 +import request from '@/config/axios'
2 2 import type { DictTypeVO, DictTypePageReqVO, DictTypeExportReqVO } from './types'
3 3  
4   -const request = useAxios()
5   -
6 4 // 查询字典(精简)列表
7 5 export const listSimpleDictTypeApi = () => {
8 6 return request.get({ url: '/system/dict-type/list-all-simple' })
... ...
yudao-ui-admin-vue3/src/api/system/errorCode/index.ts
1   -import { useAxios } from '@/hooks/web/useAxios'
  1 +import request from '@/config/axios'
2 2 import type { ErrorCodeVO } from './types'
3 3  
4   -const request = useAxios()
5   -
6 4 // 查询错误码列表
7 5 export const getErrorCodePageApi = (params) => {
8 6 return request.get({ url: '/system/error-code/page', params })
... ...
yudao-ui-admin-vue3/src/api/system/loginLog/index.ts
1   -import { useAxios } from '@/hooks/web/useAxios'
2   -
3   -const request = useAxios()
  1 +import request from '@/config/axios'
4 2  
5 3 // 查询登录日志列表
6 4 export const getLoginLogPageApi = (params) => {
... ...
yudao-ui-admin-vue3/src/api/system/menu/index.ts
1   -import { useAxios } from '@/hooks/web/useAxios'
  1 +import request from '@/config/axios'
2 2 import type { MenuVO } from './types'
3 3  
4   -const request = useAxios()
5   -
6 4 // 查询菜单(精简)列表
7 5 export const listSimpleMenusApi = () => {
8 6 return request.get({ url: '/system/menu/list-all-simple' })
... ...
yudao-ui-admin-vue3/src/api/system/notice/index.ts
1   -import { useAxios } from '@/hooks/web/useAxios'
  1 +import request from '@/config/axios'
2 2 import type { NoticeVO } from './types'
3 3  
4   -const request = useAxios()
5   -
6 4 // 查询公告列表
7 5 export const getNoticePageApi = (params) => {
8 6 return request.get({ url: '/system/notice/page', params })
... ...
yudao-ui-admin-vue3/src/api/system/oauth2/client.ts
1   -import { useAxios } from '@/hooks/web/useAxios'
  1 +import request from '@/config/axios'
2 2 import { OAuth2ClientVo } from './client.types'
3 3  
4   -const request = useAxios()
5   -
6 4 // 查询 OAuth2列表
7 5 export const getOAuth2ClientPageApi = (params) => {
8 6 return request.get({ url: '/system/oauth2-client/page', params })
... ...
yudao-ui-admin-vue3/src/api/system/oauth2/token.ts
1   -import { useAxios } from '@/hooks/web/useAxios'
2   -
3   -const request = useAxios()
  1 +import request from '@/config/axios'
4 2  
5 3 // 查询 token列表
6 4 export const getAccessTokenPageApi = (params) => {
... ...
yudao-ui-admin-vue3/src/api/system/operatelog/index.ts
1   -import { useAxios } from '@/hooks/web/useAxios'
2   -
3   -const request = useAxios()
  1 +import request from '@/config/axios'
4 2  
5 3 // 查询操作日志列表
6 4 export const getOperateLogPageApi = (params) => {
... ...
yudao-ui-admin-vue3/src/api/system/permission/index.ts
1   -import { useAxios } from '@/hooks/web/useAxios'
  1 +import request from '@/config/axios'
2 2 import type {
3 3 PermissionAssignRoleDataScopeReqVO,
4 4 PermissionAssignRoleMenuReqVO,
5 5 PermissionAssignUserRoleReqVO
6 6 } from './types'
7 7  
8   -const request = useAxios()
9   -
10 8 // 查询角色拥有的菜单权限
11 9 export const listRoleMenusApi = async (roleId: number) => {
12 10 return await request.get({ url: '/system/permission/list-role-resources?roleId=' + roleId })
... ...
yudao-ui-admin-vue3/src/api/system/post/index.ts
1   -import { useAxios } from '@/hooks/web/useAxios'
  1 +import request from '@/config/axios'
2 2 import type { PostVO, PostPageReqVO, PostExportReqVO } from './types'
3 3  
4   -const request = useAxios()
5   -
6 4 // 查询岗位列表
7 5 export const getPostPageApi = async (params: PostPageReqVO) => {
8 6 return await request.get({ url: '/system/post/page', params })
... ...
yudao-ui-admin-vue3/src/api/system/role/index.ts
1   -import { useAxios } from '@/hooks/web/useAxios'
  1 +import request from '@/config/axios'
2 2 import type { RoleVO } from './types'
3 3  
4   -const request = useAxios()
5   -
6 4 // 查询角色列表
7 5 export const getRolePageApi = async (params) => {
8 6 return await request.get({ url: '/system/role/page', params })
... ...
yudao-ui-admin-vue3/src/api/system/sensitiveWord/index.ts
1   -import { useAxios } from '@/hooks/web/useAxios'
  1 +import request from '@/config/axios'
2 2 import type { SensitiveWordVO } from './types'
3 3  
4   -const request = useAxios()
5   -
6 4 // 查询敏感词列表
7 5 export const getSensitiveWordPageApi = (params) => {
8 6 return request.get({ url: '/system/sensitive-word/page', params })
... ...
yudao-ui-admin-vue3/src/api/system/sms/smsChannel/index.ts
1   -import { useAxios } from '@/hooks/web/useAxios'
  1 +import request from '@/config/axios'
2 2 import type { SmsChannelVO } from './types'
3 3  
4   -const request = useAxios()
5   -
6 4 // 查询短信渠道列表
7 5 export const getSmsChannelPageApi = (params) => {
8 6 return request.get({ url: '/system/sms-channel/page', params })
... ...
yudao-ui-admin-vue3/src/api/system/sms/smsLog/index.ts
1   -import { useAxios } from '@/hooks/web/useAxios'
2   -
3   -const request = useAxios()
  1 +import request from '@/config/axios'
4 2  
5 3 // 查询短信日志列表
6 4 export const getSmsLogPageApi = (params) => {
... ...
yudao-ui-admin-vue3/src/api/system/sms/smsTemplate/index.ts
1   -import { useAxios } from '@/hooks/web/useAxios'
  1 +import request from '@/config/axios'
2 2 import type { SmsTemplateVO } from './types'
3 3  
4   -const request = useAxios()
5   -
6 4 // 查询短信模板列表
7 5 export const getSmsTemplatePageApi = (params) => {
8 6 return request.get({ url: '/system/sms-template/page', params })
... ...
yudao-ui-admin-vue3/src/api/system/tenant/index.ts
1   -import { useAxios } from '@/hooks/web/useAxios'
  1 +import request from '@/config/axios'
2 2 import type { TenantVO } from './types'
3 3  
4   -const request = useAxios()
5   -
6 4 // 查询租户列表
7 5 export const getTenantPageApi = (params) => {
8 6 return request.get({ url: '/system/tenant/page', params })
... ...
yudao-ui-admin-vue3/src/api/system/tenantPackage/index.ts
1   -import { useAxios } from '@/hooks/web/useAxios'
  1 +import request from '@/config/axios'
2 2 import type { TenantPackageVO } from './types'
3 3  
4   -const request = useAxios()
5   -
6 4 // 查询租户套餐列表
7 5 export const getTenantPackageTypePageApi = (params) => {
8 6 return request.get({ url: '/system/tenant-package/page', params })
... ...
yudao-ui-admin-vue3/src/api/system/user/index.ts
1   -import { useAxios } from '@/hooks/web/useAxios'
  1 +import request from '@/config/axios'
2 2 import type { UserVO } from './types'
3 3  
4   -const request = useAxios()
5   -
6 4 // 查询用户管理列表
7 5 export const getUserPageApi = (params) => {
8 6 return request.get({ url: '/system/user/page', params })
... ...
yudao-ui-admin-vue3/src/api/system/user/profile/index.ts
1   -import { useAxios } from '@/hooks/web/useAxios'
2   -
3   -const request = useAxios()
  1 +import request from '@/config/axios'
4 2  
5 3 // 查询用户个人信息
6 4 export const getUserProfileApi = () => {
... ...
yudao-ui-admin-vue3/src/config/axios/index.ts
1   -import axios, {
2   - AxiosInstance,
3   - AxiosRequestConfig,
4   - AxiosRequestHeaders,
5   - AxiosResponse,
6   - AxiosError
7   -} from 'axios'
8   -import { ElMessage, ElMessageBox, ElNotification } from 'element-plus'
9   -import qs from 'qs'
10   -import { config } from '@/config/axios/config'
11   -import { getAccessToken, getRefreshToken, getTenantId, removeToken, setToken } from '@/utils/auth'
12   -import errorCode from './errorCode'
13   -import { useI18n } from '@/hooks/web/useI18n'
14   -import { resetRouter } from '@/router'
15   -import { useCache } from '@/hooks/web/useCache'
  1 +import { service } from './service'
16 2  
17   -const tenantEnable = import.meta.env.VITE_APP_TENANT_ENABLE
18   -const { result_code, base_url, request_timeout } = config
  3 +import { config } from './config'
19 4  
20   -// 需要忽略的提示。忽略后,自动 Promise.reject('error')
21   -const ignoreMsgs = [
22   - '无效的刷新令牌', // 刷新令牌被删除时,不用提示
23   - '刷新令牌已过期' // 使用刷新令牌,刷新获取新的访问令牌时,结果因为过期失败,此时需要忽略。否则,会导致继续 401,无法跳转到登出界面
24   -]
25   -// 是否显示重新登录
26   -export const isRelogin = { show: false }
27   -// Axios 无感知刷新令牌,参考 https://www.dashingdog.cn/article/11 与 https://segmentfault.com/a/1190000020210980 实现
28   -// 请求队列
29   -let requestList: any[] = []
30   -// 是否正在刷新中
31   -let isRefreshToken = false
  5 +const { default_headers } = config
32 6  
33   -// 创建axios实例
34   -const service: AxiosInstance = axios.create({
35   - baseURL: base_url, // api 的 base_url
36   - timeout: request_timeout, // 请求超时时间
37   - withCredentials: false // 禁用 Cookie 等信息
38   -})
39   -
40   -// request拦截器
41   -service.interceptors.request.use(
42   - (config: AxiosRequestConfig) => {
43   - // 是否需要设置 token
44   - const isToken = (config!.headers || {}).isToken === false
45   - if (getAccessToken() && !isToken) {
46   - ;(config as Recordable).headers.Authorization = 'Bearer ' + getAccessToken() // 让每个请求携带自定义token
47   - }
48   - // 设置租户
49   - if (tenantEnable) {
50   - const tenantId = getTenantId()
51   - if (tenantId) (config as Recordable).headers.common['tenant-id'] = tenantId
52   - }
53   - const params = config.params || {}
54   - const data = config.data || false
55   - if (
56   - config.method?.toUpperCase() === 'POST' &&
57   - (config.headers as AxiosRequestHeaders)['Content-Type'] ===
58   - 'application/x-www-form-urlencoded'
59   - ) {
60   - config.data = qs.stringify(data)
61   - }
62   - // get参数编码
63   - if (config.method?.toUpperCase() === 'GET' && params) {
64   - let url = config.url + '?'
65   - for (const propName of Object.keys(params)) {
66   - const value = params[propName]
67   - if (value !== void 0 && value !== null && typeof value !== 'undefined') {
68   - if (typeof value === 'object') {
69   - for (const val of Object.keys(value)) {
70   - const params = propName + '[' + val + ']'
71   - const subPart = encodeURIComponent(params) + '='
72   - url += subPart + encodeURIComponent(value[val]) + '&'
73   - }
74   - } else {
75   - url += `${propName}=${encodeURIComponent(value)}&`
76   - }
77   - }
78   - }
79   - // 给 get 请求加上时间戳参数,避免从缓存中拿数据
80   - // const now = new Date().getTime()
81   - // params = params.substring(0, url.length - 1) + `?_t=${now}`
82   - url = url.slice(0, -1)
83   - config.params = {}
84   - config.url = url
85   - }
86   - return config
  7 +const request = (option: any) => {
  8 + const { url, method, params, data, headersType, responseType } = option
  9 + return service({
  10 + url: url,
  11 + method,
  12 + params,
  13 + data,
  14 + responseType: responseType,
  15 + headers: {
  16 + 'Content-Type': headersType || default_headers
  17 + }
  18 + })
  19 +}
  20 +export default {
  21 + get: async <T = any>(option: any) => {
  22 + const res = await request({ method: 'GET', ...option })
  23 + return res.data as unknown as T
87 24 },
88   - (error: AxiosError) => {
89   - // Do something with request error
90   - console.log(error) // for debug
91   - Promise.reject(error)
92   - }
93   -)
94   -
95   -// response 拦截器
96   -service.interceptors.response.use(
97   - async (response: AxiosResponse<Recordable>) => {
98   - const { data } = response
99   - const config = response.config
100   - if (!data) {
101   - // 返回“[HTTP]请求没有返回值”;
102   - throw new Error()
103   - }
104   - const { t } = useI18n()
105   - // 未设置状态码则默认成功状态
106   - const code = data.code || result_code
107   - // 二进制数据则直接返回
108   - if (
109   - response.request.responseType === 'blob' ||
110   - response.request.responseType === 'arraybuffer'
111   - ) {
112   - return response.data
113   - }
114   - // 获取错误信息
115   - const msg = data.msg || errorCode[code] || errorCode['default']
116   - if (ignoreMsgs.indexOf(msg) !== -1) {
117   - // 如果是忽略的错误码,直接返回 msg 异常
118   - return Promise.reject(msg)
119   - } else if (code === 401) {
120   - // 如果未认证,并且未进行刷新令牌,说明可能是访问令牌过期了
121   - if (!isRefreshToken) {
122   - isRefreshToken = true
123   - // 1. 如果获取不到刷新令牌,则只能执行登出操作
124   - if (!getRefreshToken()) {
125   - return handleAuthorized()
126   - }
127   - // 2. 进行刷新访问令牌
128   - try {
129   - const refreshTokenRes = await refreshToken()
130   - // 2.1 刷新成功,则回放队列的请求 + 当前请求
131   - setToken(refreshTokenRes.data.data)
132   - config.headers!.Authorization = 'Bearer ' + getAccessToken()
133   - requestList.forEach((cb: any) => {
134   - cb()
135   - })
136   - requestList = []
137   - return service(config)
138   - } catch (e) {
139   - // 为什么需要 catch 异常呢?刷新失败时,请求因为 Promise.reject 触发异常。
140   - // 2.2 刷新失败,只回放队列的请求
141   - requestList.forEach((cb: any) => {
142   - cb()
143   - })
144   - // 提示是否要登出。即不回放当前请求!不然会形成递归
145   - return handleAuthorized()
146   - } finally {
147   - requestList = []
148   - isRefreshToken = false
149   - }
150   - } else {
151   - // 添加到队列,等待刷新获取到新的令牌
152   - return new Promise((resolve) => {
153   - requestList.push(() => {
154   - config.headers!.Authorization = 'Bearer ' + getAccessToken() // 让每个请求携带自定义token 请根据实际情况自行修改
155   - resolve(service(config))
156   - })
157   - })
158   - }
159   - } else if (code === 500) {
160   - ElMessage.error(t('sys.api.errMsg500'))
161   - return Promise.reject(new Error(msg))
162   - } else if (code === 901) {
163   - ElMessage.error(
164   - '<div>' +
165   - t('sys.api.errMsg901') +
166   - '</div>' +
167   - '<div> &nbsp; </div>' +
168   - '<div>参考 https://doc.iocoder.cn/ 教程</div>' +
169   - '<div> &nbsp; </div>' +
170   - '<div>5 分钟搭建本地环境</div>'
171   - )
172   - return Promise.reject(new Error(msg))
173   - } else if (code !== 200) {
174   - if (msg === '无效的刷新令牌') {
175   - // hard coding:忽略这个提示,直接登出
176   - console.log(msg)
177   - } else {
178   - ElNotification.error({
179   - title: msg
180   - })
181   - }
182   - return Promise.reject('error')
183   - } else {
184   - return data
185   - }
  25 + post: async <T = any>(option: any) => {
  26 + const res = await request({ method: 'POST', ...option })
  27 + return res.data as unknown as T
186 28 },
187   - (error: AxiosError) => {
188   - console.log('err' + error) // for debug
189   - let { message } = error
190   - const { t } = useI18n()
191   - if (message === 'Network Error') {
192   - message = t('sys.api.errorMessage')
193   - } else if (message.includes('timeout')) {
194   - message = t('sys.api.apiTimeoutMessage')
195   - } else if (message.includes('Request failed with status code')) {
196   - message = t('sys.api.apiRequestFailed') + message.substr(message.length - 3)
197   - }
198   - ElMessage.error(message)
199   - return Promise.reject(error)
200   - }
201   -)
202   -
203   -const refreshToken = async () => {
204   - return await axios.post(base_url + '/system/auth/refresh-token?refreshToken=' + getRefreshToken())
205   -}
206   -const handleAuthorized = () => {
207   - const { t } = useI18n()
208   - if (!isRelogin.show) {
209   - isRelogin.show = true
210   - ElMessageBox.confirm(t('sys.api.timeoutMessage'), t('common.confirmTitle'), {
211   - confirmButtonText: t('login.relogin'),
212   - cancelButtonText: t('common.cancel'),
213   - type: 'warning'
214   - })
215   - .then(() => {
216   - const { wsCache } = useCache()
217   - resetRouter() // 重置静态路由表
218   - wsCache.clear()
219   - removeToken()
220   - isRelogin.show = false
221   - window.location.href = '/'
222   - })
223   - .catch(() => {
224   - isRelogin.show = false
225   - })
  29 + delete: async <T = any>(option: any) => {
  30 + const res = await request({ method: 'DELETE', ...option })
  31 + return res.data as unknown as T
  32 + },
  33 + put: async <T = any>(option: any) => {
  34 + const res = await request({ method: 'PUT', ...option })
  35 + return res.data as unknown as T
  36 + },
  37 + download: async <T = any>(option: any) => {
  38 + const res = await request({ method: 'GET', responseType: 'blob', ...option })
  39 + return res as unknown as Promise<T>
  40 + },
  41 + upload: async <T = any>(option: any) => {
  42 + option.headersType = 'multipart/form-data'
  43 + const res = await request({ method: 'PUT', ...option })
  44 + return res as unknown as Promise<T>
226 45 }
227   - return Promise.reject(t('sys.api.timeoutMessage'))
228 46 }
229   -export { service }
... ...
yudao-ui-admin-vue3/src/config/axios/service.ts 0 → 100644
  1 +import axios, {
  2 + AxiosInstance,
  3 + AxiosRequestConfig,
  4 + AxiosRequestHeaders,
  5 + AxiosResponse,
  6 + AxiosError
  7 +} from 'axios'
  8 +import { ElMessage, ElMessageBox, ElNotification } from 'element-plus'
  9 +import qs from 'qs'
  10 +import { config } from '@/config/axios/config'
  11 +import { getAccessToken, getRefreshToken, getTenantId, removeToken, setToken } from '@/utils/auth'
  12 +import errorCode from './errorCode'
  13 +import { useI18n } from '@/hooks/web/useI18n'
  14 +import { resetRouter } from '@/router'
  15 +import { useCache } from '@/hooks/web/useCache'
  16 +
  17 +const tenantEnable = import.meta.env.VITE_APP_TENANT_ENABLE
  18 +const { result_code, base_url, request_timeout } = config
  19 +
  20 +// 需要忽略的提示。忽略后,自动 Promise.reject('error')
  21 +const ignoreMsgs = [
  22 + '无效的刷新令牌', // 刷新令牌被删除时,不用提示
  23 + '刷新令牌已过期' // 使用刷新令牌,刷新获取新的访问令牌时,结果因为过期失败,此时需要忽略。否则,会导致继续 401,无法跳转到登出界面
  24 +]
  25 +// 是否显示重新登录
  26 +export const isRelogin = { show: false }
  27 +// Axios 无感知刷新令牌,参考 https://www.dashingdog.cn/article/11 与 https://segmentfault.com/a/1190000020210980 实现
  28 +// 请求队列
  29 +let requestList: any[] = []
  30 +// 是否正在刷新中
  31 +let isRefreshToken = false
  32 +
  33 +// 创建axios实例
  34 +const service: AxiosInstance = axios.create({
  35 + baseURL: base_url, // api 的 base_url
  36 + timeout: request_timeout, // 请求超时时间
  37 + withCredentials: false // 禁用 Cookie 等信息
  38 +})
  39 +
  40 +// request拦截器
  41 +service.interceptors.request.use(
  42 + (config: AxiosRequestConfig) => {
  43 + // 是否需要设置 token
  44 + const isToken = (config!.headers || {}).isToken === false
  45 + if (getAccessToken() && !isToken) {
  46 + ;(config as Recordable).headers.Authorization = 'Bearer ' + getAccessToken() // 让每个请求携带自定义token
  47 + }
  48 + // 设置租户
  49 + if (tenantEnable) {
  50 + const tenantId = getTenantId()
  51 + if (tenantId) (config as Recordable).headers.common['tenant-id'] = tenantId
  52 + }
  53 + const params = config.params || {}
  54 + const data = config.data || false
  55 + if (
  56 + config.method?.toUpperCase() === 'POST' &&
  57 + (config.headers as AxiosRequestHeaders)['Content-Type'] ===
  58 + 'application/x-www-form-urlencoded'
  59 + ) {
  60 + config.data = qs.stringify(data)
  61 + }
  62 + // get参数编码
  63 + if (config.method?.toUpperCase() === 'GET' && params) {
  64 + let url = config.url + '?'
  65 + for (const propName of Object.keys(params)) {
  66 + const value = params[propName]
  67 + if (value !== void 0 && value !== null && typeof value !== 'undefined') {
  68 + if (typeof value === 'object') {
  69 + for (const val of Object.keys(value)) {
  70 + const params = propName + '[' + val + ']'
  71 + const subPart = encodeURIComponent(params) + '='
  72 + url += subPart + encodeURIComponent(value[val]) + '&'
  73 + }
  74 + } else {
  75 + url += `${propName}=${encodeURIComponent(value)}&`
  76 + }
  77 + }
  78 + }
  79 + // 给 get 请求加上时间戳参数,避免从缓存中拿数据
  80 + // const now = new Date().getTime()
  81 + // params = params.substring(0, url.length - 1) + `?_t=${now}`
  82 + url = url.slice(0, -1)
  83 + config.params = {}
  84 + config.url = url
  85 + }
  86 + return config
  87 + },
  88 + (error: AxiosError) => {
  89 + // Do something with request error
  90 + console.log(error) // for debug
  91 + Promise.reject(error)
  92 + }
  93 +)
  94 +
  95 +// response 拦截器
  96 +service.interceptors.response.use(
  97 + async (response: AxiosResponse<Recordable>) => {
  98 + const { data } = response
  99 + const config = response.config
  100 + if (!data) {
  101 + // 返回“[HTTP]请求没有返回值”;
  102 + throw new Error()
  103 + }
  104 + const { t } = useI18n()
  105 + // 未设置状态码则默认成功状态
  106 + const code = data.code || result_code
  107 + // 二进制数据则直接返回
  108 + if (
  109 + response.request.responseType === 'blob' ||
  110 + response.request.responseType === 'arraybuffer'
  111 + ) {
  112 + return response.data
  113 + }
  114 + // 获取错误信息
  115 + const msg = data.msg || errorCode[code] || errorCode['default']
  116 + if (ignoreMsgs.indexOf(msg) !== -1) {
  117 + // 如果是忽略的错误码,直接返回 msg 异常
  118 + return Promise.reject(msg)
  119 + } else if (code === 401) {
  120 + // 如果未认证,并且未进行刷新令牌,说明可能是访问令牌过期了
  121 + if (!isRefreshToken) {
  122 + isRefreshToken = true
  123 + // 1. 如果获取不到刷新令牌,则只能执行登出操作
  124 + if (!getRefreshToken()) {
  125 + return handleAuthorized()
  126 + }
  127 + // 2. 进行刷新访问令牌
  128 + try {
  129 + const refreshTokenRes = await refreshToken()
  130 + // 2.1 刷新成功,则回放队列的请求 + 当前请求
  131 + setToken(refreshTokenRes.data.data)
  132 + config.headers!.Authorization = 'Bearer ' + getAccessToken()
  133 + requestList.forEach((cb: any) => {
  134 + cb()
  135 + })
  136 + requestList = []
  137 + return service(config)
  138 + } catch (e) {
  139 + // 为什么需要 catch 异常呢?刷新失败时,请求因为 Promise.reject 触发异常。
  140 + // 2.2 刷新失败,只回放队列的请求
  141 + requestList.forEach((cb: any) => {
  142 + cb()
  143 + })
  144 + // 提示是否要登出。即不回放当前请求!不然会形成递归
  145 + return handleAuthorized()
  146 + } finally {
  147 + requestList = []
  148 + isRefreshToken = false
  149 + }
  150 + } else {
  151 + // 添加到队列,等待刷新获取到新的令牌
  152 + return new Promise((resolve) => {
  153 + requestList.push(() => {
  154 + config.headers!.Authorization = 'Bearer ' + getAccessToken() // 让每个请求携带自定义token 请根据实际情况自行修改
  155 + resolve(service(config))
  156 + })
  157 + })
  158 + }
  159 + } else if (code === 500) {
  160 + ElMessage.error(t('sys.api.errMsg500'))
  161 + return Promise.reject(new Error(msg))
  162 + } else if (code === 901) {
  163 + ElMessage.error(
  164 + '<div>' +
  165 + t('sys.api.errMsg901') +
  166 + '</div>' +
  167 + '<div> &nbsp; </div>' +
  168 + '<div>参考 https://doc.iocoder.cn/ 教程</div>' +
  169 + '<div> &nbsp; </div>' +
  170 + '<div>5 分钟搭建本地环境</div>'
  171 + )
  172 + return Promise.reject(new Error(msg))
  173 + } else if (code !== 200) {
  174 + if (msg === '无效的刷新令牌') {
  175 + // hard coding:忽略这个提示,直接登出
  176 + console.log(msg)
  177 + } else {
  178 + ElNotification.error({
  179 + title: msg
  180 + })
  181 + }
  182 + return Promise.reject('error')
  183 + } else {
  184 + return data
  185 + }
  186 + },
  187 + (error: AxiosError) => {
  188 + console.log('err' + error) // for debug
  189 + let { message } = error
  190 + const { t } = useI18n()
  191 + if (message === 'Network Error') {
  192 + message = t('sys.api.errorMessage')
  193 + } else if (message.includes('timeout')) {
  194 + message = t('sys.api.apiTimeoutMessage')
  195 + } else if (message.includes('Request failed with status code')) {
  196 + message = t('sys.api.apiRequestFailed') + message.substr(message.length - 3)
  197 + }
  198 + ElMessage.error(message)
  199 + return Promise.reject(error)
  200 + }
  201 +)
  202 +
  203 +const refreshToken = async () => {
  204 + return await axios.post(base_url + '/system/auth/refresh-token?refreshToken=' + getRefreshToken())
  205 +}
  206 +const handleAuthorized = () => {
  207 + const { t } = useI18n()
  208 + if (!isRelogin.show) {
  209 + isRelogin.show = true
  210 + ElMessageBox.confirm(t('sys.api.timeoutMessage'), t('common.confirmTitle'), {
  211 + confirmButtonText: t('login.relogin'),
  212 + cancelButtonText: t('common.cancel'),
  213 + type: 'warning'
  214 + })
  215 + .then(() => {
  216 + const { wsCache } = useCache()
  217 + resetRouter() // 重置静态路由表
  218 + wsCache.clear()
  219 + removeToken()
  220 + isRelogin.show = false
  221 + window.location.href = '/'
  222 + })
  223 + .catch(() => {
  224 + isRelogin.show = false
  225 + })
  226 + }
  227 + return Promise.reject(t('sys.api.timeoutMessage'))
  228 +}
  229 +export { service }
... ...
yudao-ui-admin-vue3/src/hooks/web/useAxios.ts deleted
1   -import { service } from '@/config/axios'
2   -
3   -import { config } from '@/config/axios/config'
4   -
5   -const { default_headers } = config
6   -
7   -const request = (option: AxiosConfig) => {
8   - const { url, method, params, data, headersType, responseType } = option
9   - return service({
10   - url: url,
11   - method,
12   - params,
13   - data,
14   - responseType: responseType,
15   - headers: {
16   - 'Content-Type': headersType || default_headers
17   - }
18   - })
19   -}
20   -
21   -async function getFn<T = any>(option: AxiosConfig): Promise<T> {
22   - const res = await request({ method: 'GET', ...option })
23   - return res.data
24   -}
25   -
26   -async function postFn<T = any>(option: AxiosConfig): Promise<T> {
27   - const res = await request({ method: 'POST', ...option })
28   - return res.data
29   -}
30   -
31   -async function deleteFn<T = any>(option: AxiosConfig): Promise<T> {
32   - const res = await request({ method: 'DELETE', ...option })
33   - return res.data
34   -}
35   -
36   -async function putFn<T = any>(option: AxiosConfig): Promise<T> {
37   - const res = await request({ method: 'PUT', ...option })
38   - return res.data
39   -}
40   -async function downloadFn<T = any>(option: AxiosConfig): Promise<T> {
41   - const res = await request({ method: 'GET', responseType: 'blob', ...option })
42   - return res as unknown as Promise<T>
43   -}
44   -
45   -async function uploadFn<T = any>(option: AxiosConfig): Promise<T> {
46   - option.headersType = 'multipart/form-data'
47   - const res = await request({ method: 'PUT', ...option })
48   - return res as unknown as Promise<T>
49   -}
50   -
51   -export const useAxios = () => {
52   - return {
53   - get: getFn,
54   - post: postFn,
55   - delete: deleteFn,
56   - put: putFn,
57   - download: downloadFn,
58   - upload: uploadFn
59   - }
60   -}
yudao-ui-admin-vue3/src/router/index.ts
... ... @@ -10,7 +10,7 @@ import { usePermissionStoreWithOut } from &#39;@/store/modules/permission&#39;
10 10 import { useDictStoreWithOut } from '@/store/modules/dict'
11 11 import { useUserStoreWithOut } from '@/store/modules/user'
12 12 import { listSimpleDictDataApi } from '@/api/system/dict/dict.data'
13   -import { isRelogin } from '@/config/axios'
  13 +import { isRelogin } from '@/config/axios/service'
14 14 import { getInfoApi } from '@/api/login'
15 15  
16 16 const { start, done } = useNProgress()
... ...