fuliqi
2024-01-24 29c1e7eb5ac16e90d8991a86c1c071bc312ec8d9
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
import axios from 'axios'
import { Message, MessageBox, Loading } from 'element-ui'
import Vue from 'vue'
import store from '../store'
import errorCode from '@/utils/errorCode'
import {
    codeHeaders,
    encryptBody
} from './sm'
// 是否显示重新登录
let isReloginShow
// 创建axios实例
const service = axios.create({
    timeout: 120000,
    withCredentials: true
})
 
let loading = null
/**
 * loading开始时
 * @param {*} config
 */
function startLoading(config) {
    loading = Loading.service({
        target: '.loading-mask',
        lock: true,
        text: '加载中……',
        customClass: 'customLoading'
        // background: 'rgba(0, 0, 0, 0.7)'
    })
}
/**
 * loading结束时
 */
function endLoading() {
    loading.close()
}
 
let needLoadingRequestCount = 0
export function showFullScreenLoading(config) {
    if (!config.showLoading && !config[0]) {
        return
    }
    if (needLoadingRequestCount === 0) {
        startLoading(config)
    }
    needLoadingRequestCount++
}
 
export function tryHideFullScreenLoading() {
    if (needLoadingRequestCount <= 0) return
    needLoadingRequestCount--
    if (needLoadingRequestCount === 0) {
        endLoading()
    }
}
 
// request拦截器
service.interceptors.request.use((config) => {
    config.baseURL = process.env.VUE_APP_CURRENTMODE === 'development' ? '/api' : window.API_BASE_URL
    // 如果没有设置Content-Type,默认application/json
    if (!config.headers['Content-Type']) {
        config.headers['Content-Type'] = 'application/json'
    }
    // 方法做防重返和防篡改
    if (process.env.VUE_APP_ENCRYPTION === '1') {
        config = codeHeaders(config)
        config = encryptBody(config)
    }
    // 每次发送请求之前判断vuex中是否存在token
    // 如果存在,则统一在http请求的header都加上token
    const token = store.state.token
    // const token = 'a71a73f84475dcb3c61dbd9c4905858f'
    if (token) {
        config.headers.Authorization = 'Bearer ' + token
    }
    config.headers.bizId = 'B02'
    showFullScreenLoading(config)
    return config
}, (error) => {
    Promise.reject(error)
    tryHideFullScreenLoading()
})
 
// respone拦截器
service.interceptors.response.use((res) => {
    const code = res.data.code ? String(res.data.code) : '0'
    // 获取错误信息
    const msg = errorCode[code] || res.data.msg || res.data.message || errorCode.default
    tryHideFullScreenLoading()
    // 二进制数据则直接返回
    if (res.request.responseType === 'blob' || res.request.responseType === 'arraybuffer') {
        return res.data
    }
    if (code === '401' || code === '4001' || code === '4000') {
        if (!isReloginShow) {
            isReloginShow = true
            MessageBox.confirm('登录状态已过期,您可以继续留在该页面,或者重新登录', '系统提示', {
                confirmButtonText: '重新登录',
                cancelButtonText: '取消',
                type: 'warning'
            }).then(() => {
                isReloginShow = false
                Vue.prototype.$mainStore.commit('logout')
                Vue.prototype.$mainRouter.replace('/')
            }).catch(() => {
                isReloginShow = false
            })
        }
        const msg = '无效的会话,或者会话已过期,请重新登录。'
        return Promise.reject(msg)
    } else if (code === '999') {
        //token过期
        Message.warning('认证 token 已过期,请重新登录')
        Vue.prototype.$mainStore.commit('logout');
        Vue.prototype.$mainRouter.replace('/');
    } else if (code === '500') {
        Message({
            message: msg,
            type: 'error'
        })
        return Promise.reject(msg)
    } else if (code !== '0') {
        Message.warning(msg)
        return Promise.reject(msg)
    } else {
        return res.data
    }
}, (error) => {
    let { message } = error
    tryHideFullScreenLoading()
    if (message === 'Network Error') {
        message = '后端接口连接异常'
    } else if (message.includes('timeout')) {
        message = '系统接口请求超时'
    } else {
        message = error.response.data.error_description || error.response.data.message
    }
    message && Message({
        message: message,
        type: 'error',
        duration: 3 * 1000
    })
    switch (String(error.response.data.status)) {
        case '401':
            Vue.prototype.$mainStore.dispatch('clearLoginInfo')
            Vue.prototype.$mainRouter.replace('/')
            break
        case '403':
            Vue.prototype.$mainRouter.push({ name: '404' })
            break
    }
    return Promise.reject(error)
})
export default service