2021-05-13 10:56:04 +08:00
|
|
|
|
// import Vue from 'vue';
|
2021-06-22 17:36:07 +08:00
|
|
|
|
import axios from 'axios';
|
|
|
|
|
import https from 'https';
|
|
|
|
|
import { Message, Spin, Modal } from 'view-design';
|
|
|
|
|
import Storage from './storage';
|
|
|
|
|
import config from '@/config';
|
|
|
|
|
import router from '../router/index.js';
|
|
|
|
|
import store from '../vuex/store';
|
|
|
|
|
import { handleRefreshToken } from '@/api/index';
|
|
|
|
|
const qs = require('qs');
|
2021-06-10 18:31:54 +08:00
|
|
|
|
export const buyerUrl =
|
2021-06-22 17:36:07 +08:00
|
|
|
|
process.env.NODE_ENV === 'development'
|
2021-06-10 18:31:54 +08:00
|
|
|
|
? config.api_dev.buyer
|
|
|
|
|
: config.api_prod.buyer;
|
|
|
|
|
export const commonUrl =
|
2021-06-22 17:36:07 +08:00
|
|
|
|
process.env.NODE_ENV === 'development'
|
2021-06-10 18:31:54 +08:00
|
|
|
|
? config.api_dev.common
|
|
|
|
|
: config.api_prod.common;
|
|
|
|
|
export const managerUrl =
|
2021-06-22 17:36:07 +08:00
|
|
|
|
process.env.NODE_ENV === 'development'
|
2021-06-10 18:31:54 +08:00
|
|
|
|
? config.api_dev.manager
|
|
|
|
|
: config.api_prod.manager;
|
|
|
|
|
export const sellerUrl =
|
2021-06-22 17:36:07 +08:00
|
|
|
|
process.env.NODE_ENV === 'development'
|
2021-06-10 18:31:54 +08:00
|
|
|
|
? config.api_dev.seller
|
|
|
|
|
: config.api_prod.seller;
|
2021-05-13 10:56:04 +08:00
|
|
|
|
// 创建axios实例
|
|
|
|
|
var isRefreshToken = 0;
|
2021-06-10 18:31:54 +08:00
|
|
|
|
const refreshToken = getTokenDebounce();
|
2021-05-13 10:56:04 +08:00
|
|
|
|
const service = axios.create({
|
|
|
|
|
timeout: 10000, // 请求超时时间
|
|
|
|
|
baseURL: buyerUrl, // API
|
|
|
|
|
httpsAgent: new https.Agent({
|
|
|
|
|
rejectUnauthorized: false
|
|
|
|
|
}),
|
2021-06-10 18:31:54 +08:00
|
|
|
|
paramsSerializer: params =>
|
|
|
|
|
qs.stringify(params, {
|
2021-06-22 17:36:07 +08:00
|
|
|
|
arrayFormat: 'repeat'
|
2021-06-10 18:31:54 +08:00
|
|
|
|
})
|
2021-05-13 10:56:04 +08:00
|
|
|
|
});
|
|
|
|
|
|
|
|
|
|
// request拦截器
|
2021-06-10 18:31:54 +08:00
|
|
|
|
service.interceptors.request.use(
|
|
|
|
|
config => {
|
|
|
|
|
const { loading } = config;
|
|
|
|
|
// 如果是put/post请求,用qs.stringify序列化参数
|
2021-06-22 17:36:07 +08:00
|
|
|
|
const isPutPost = config.method === 'put' || config.method === 'post';
|
|
|
|
|
const isJson = config.headers['Content-Type'] === 'application/json';
|
|
|
|
|
const isFile = config.headers['Content-Type'] === 'multipart/form-data';
|
2021-06-10 18:31:54 +08:00
|
|
|
|
if (isPutPost && isJson) {
|
|
|
|
|
config.data = JSON.stringify(config.data);
|
|
|
|
|
}
|
|
|
|
|
if (isPutPost && !isFile && !isJson) {
|
|
|
|
|
config.data = qs.stringify(config.data, {
|
2021-06-22 17:36:07 +08:00
|
|
|
|
arrayFormat: 'repeat'
|
2021-06-10 18:31:54 +08:00
|
|
|
|
});
|
|
|
|
|
}
|
|
|
|
|
/** 配置全屏加载 */
|
|
|
|
|
if (process.client && loading !== false) {
|
|
|
|
|
config.loading = Spin.show();
|
|
|
|
|
}
|
2021-05-13 10:56:04 +08:00
|
|
|
|
|
2021-06-22 17:36:07 +08:00
|
|
|
|
const uuid = Storage.getItem('uuid');
|
|
|
|
|
config.headers['uuid'] = uuid;
|
2021-05-13 10:56:04 +08:00
|
|
|
|
|
2021-06-10 18:31:54 +08:00
|
|
|
|
// 获取访问Token
|
2021-06-22 17:36:07 +08:00
|
|
|
|
let accessToken = Storage.getItem('accessToken');
|
2021-06-10 18:31:54 +08:00
|
|
|
|
if (accessToken && config.needToken) {
|
2021-06-22 17:36:07 +08:00
|
|
|
|
config.headers['accessToken'] = accessToken;
|
2021-06-10 18:31:54 +08:00
|
|
|
|
// 解析当前token时间
|
|
|
|
|
let jwtData = JSON.parse(
|
2021-06-25 19:15:27 +08:00
|
|
|
|
decodeURIComponent(escape(window.atob(accessToken.split('.')[1].replace(/-/g, '+').replace(/_/g, '/'))))
|
2021-06-10 18:31:54 +08:00
|
|
|
|
);
|
2021-06-11 19:01:05 +08:00
|
|
|
|
if (jwtData.exp < Math.round(new Date() / 1000)) {
|
2021-06-23 10:48:54 +08:00
|
|
|
|
refresh(config)
|
2021-06-10 18:31:54 +08:00
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
return config;
|
|
|
|
|
},
|
|
|
|
|
error => {
|
|
|
|
|
Promise.reject(error);
|
2021-05-13 10:56:04 +08:00
|
|
|
|
}
|
2021-06-10 18:31:54 +08:00
|
|
|
|
);
|
|
|
|
|
|
2021-06-23 10:45:05 +08:00
|
|
|
|
async function refresh (error) {
|
2021-06-10 18:31:54 +08:00
|
|
|
|
const getTokenRes = await refreshToken();
|
2021-06-22 17:36:07 +08:00
|
|
|
|
if (getTokenRes === 'success') {
|
2021-06-10 18:31:54 +08:00
|
|
|
|
// 刷新token
|
|
|
|
|
if (isRefreshToken === 1) {
|
|
|
|
|
error.response.config.headers.accessToken = Storage.getItem(
|
2021-06-22 17:36:07 +08:00
|
|
|
|
'accessToken'
|
2021-06-10 18:31:54 +08:00
|
|
|
|
);
|
|
|
|
|
return service(error.response.config);
|
|
|
|
|
} else {
|
|
|
|
|
router.go(0);
|
|
|
|
|
}
|
|
|
|
|
} else {
|
2021-06-22 17:36:07 +08:00
|
|
|
|
Storage.removeItem('accessToken');
|
|
|
|
|
Storage.removeItem('refreshToken');
|
|
|
|
|
Storage.removeItem('userInfo');
|
|
|
|
|
Storage.setItem('cartNum', 0);
|
|
|
|
|
store.commit('SET_CARTNUM', 0);
|
2021-06-10 18:31:54 +08:00
|
|
|
|
Modal.confirm({
|
2021-06-22 17:36:07 +08:00
|
|
|
|
title: '请登录',
|
|
|
|
|
content: '<p>请登录后执行此操作</p>',
|
|
|
|
|
okText: '立即登录',
|
|
|
|
|
cancelText: '继续浏览',
|
2021-06-10 18:31:54 +08:00
|
|
|
|
onOk: () => {
|
|
|
|
|
router.push({
|
2021-06-22 17:36:07 +08:00
|
|
|
|
path: '/login',
|
2021-06-10 18:31:54 +08:00
|
|
|
|
query: {
|
|
|
|
|
rePath: router.history.current.path,
|
|
|
|
|
query: JSON.stringify(router.history.current.query)
|
|
|
|
|
}
|
|
|
|
|
});
|
|
|
|
|
},
|
|
|
|
|
onCancel: () => {
|
|
|
|
|
Modal.remove();
|
|
|
|
|
}
|
|
|
|
|
});
|
|
|
|
|
}
|
|
|
|
|
}
|
2021-05-13 10:56:04 +08:00
|
|
|
|
|
|
|
|
|
// respone拦截器
|
|
|
|
|
service.interceptors.response.use(
|
|
|
|
|
async response => {
|
|
|
|
|
await closeLoading(response);
|
2021-06-10 18:31:54 +08:00
|
|
|
|
|
2021-05-13 10:56:04 +08:00
|
|
|
|
return response.data;
|
|
|
|
|
},
|
|
|
|
|
async error => {
|
|
|
|
|
if (process.server) return Promise.reject(error);
|
|
|
|
|
await closeLoading(error);
|
|
|
|
|
const errorResponse = error.response || {};
|
|
|
|
|
const errorData = errorResponse.data || {};
|
|
|
|
|
|
|
|
|
|
if (errorResponse.status === 403) {
|
|
|
|
|
isRefreshToken++;
|
|
|
|
|
|
|
|
|
|
if (isRefreshToken === 1) {
|
2021-06-23 10:45:05 +08:00
|
|
|
|
refresh(error)
|
2021-06-10 18:31:54 +08:00
|
|
|
|
isRefreshToken = 0;
|
2021-05-13 10:56:04 +08:00
|
|
|
|
}
|
2021-06-23 16:49:35 +08:00
|
|
|
|
} else if (errorResponse.status === 404) {
|
|
|
|
|
// 避免刷新token时也提示报错信息
|
2021-05-13 10:56:04 +08:00
|
|
|
|
} else {
|
|
|
|
|
if (error.message) {
|
2021-06-10 18:31:54 +08:00
|
|
|
|
let _message =
|
2021-06-22 17:36:07 +08:00
|
|
|
|
error.code === 'ECONNABORTED'
|
|
|
|
|
? '连接超时,请稍候再试!'
|
|
|
|
|
: '网络错误,请稍后再试!';
|
2021-05-13 10:56:04 +08:00
|
|
|
|
Message.error(errorData.message || _message);
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
return Promise.reject(error);
|
|
|
|
|
}
|
|
|
|
|
);
|
|
|
|
|
|
|
|
|
|
/**
|
|
|
|
|
* 关闭全局加载
|
|
|
|
|
* @param target
|
|
|
|
|
*/
|
2021-06-10 18:31:54 +08:00
|
|
|
|
const closeLoading = target => {
|
2021-05-13 10:56:04 +08:00
|
|
|
|
if (!target.config || !target.config.loading) return true;
|
|
|
|
|
return new Promise((resolve, reject) => {
|
|
|
|
|
setTimeout(() => {
|
|
|
|
|
target.config.loading.hide();
|
|
|
|
|
resolve();
|
|
|
|
|
}, 200);
|
|
|
|
|
});
|
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
export const Method = {
|
2021-06-22 17:36:07 +08:00
|
|
|
|
GET: 'get',
|
|
|
|
|
POST: 'post',
|
|
|
|
|
PUT: 'put',
|
|
|
|
|
DELETE: 'delete'
|
2021-05-13 10:56:04 +08:00
|
|
|
|
};
|
|
|
|
|
|
2021-06-22 17:36:07 +08:00
|
|
|
|
export default function request (options) {
|
2021-05-13 10:56:04 +08:00
|
|
|
|
// 如果是服务端或者是请求的刷新token,不需要检查token直接请求。
|
|
|
|
|
// if (process.server || options.url.indexOf('passport/token') !== -1) {
|
|
|
|
|
return service(options);
|
|
|
|
|
// }
|
|
|
|
|
// service(options).then(resolve).catch(reject)
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// 防抖闭包来一波
|
2021-06-22 17:36:07 +08:00
|
|
|
|
function getTokenDebounce () {
|
2021-06-10 18:31:54 +08:00
|
|
|
|
let lock = false;
|
|
|
|
|
let success = false;
|
2021-06-22 17:36:07 +08:00
|
|
|
|
return function () {
|
2021-05-13 10:56:04 +08:00
|
|
|
|
if (!lock) {
|
2021-06-10 18:31:54 +08:00
|
|
|
|
lock = true;
|
2021-06-22 17:36:07 +08:00
|
|
|
|
let oldRefreshToken = Storage.getItem('refreshToken');
|
2021-06-10 18:31:54 +08:00
|
|
|
|
handleRefreshToken(oldRefreshToken)
|
|
|
|
|
.then(res => {
|
|
|
|
|
if (res.success) {
|
|
|
|
|
let { accessToken, refreshToken } = res.result;
|
2021-06-22 17:36:07 +08:00
|
|
|
|
Storage.setItem('accessToken', accessToken);
|
|
|
|
|
Storage.setItem('refreshToken', refreshToken);
|
2021-05-13 10:56:04 +08:00
|
|
|
|
|
2021-06-10 18:31:54 +08:00
|
|
|
|
success = true;
|
|
|
|
|
lock = false;
|
|
|
|
|
} else {
|
|
|
|
|
success = false;
|
|
|
|
|
lock = false;
|
|
|
|
|
// router.push('/login')
|
|
|
|
|
}
|
|
|
|
|
})
|
|
|
|
|
.catch(err => {
|
|
|
|
|
console.log(err);
|
|
|
|
|
success = false;
|
|
|
|
|
lock = false;
|
|
|
|
|
});
|
2021-05-13 10:56:04 +08:00
|
|
|
|
}
|
|
|
|
|
return new Promise(resolve => {
|
|
|
|
|
// 一直看lock,直到请求失败或者成功
|
|
|
|
|
const timer = setInterval(() => {
|
|
|
|
|
if (!lock) {
|
2021-06-10 18:31:54 +08:00
|
|
|
|
clearInterval(timer);
|
2021-05-13 10:56:04 +08:00
|
|
|
|
if (success) {
|
2021-06-22 17:36:07 +08:00
|
|
|
|
resolve('success');
|
2021-05-13 10:56:04 +08:00
|
|
|
|
} else {
|
2021-06-22 17:36:07 +08:00
|
|
|
|
resolve('fail');
|
2021-05-13 10:56:04 +08:00
|
|
|
|
}
|
|
|
|
|
}
|
2021-06-10 18:31:54 +08:00
|
|
|
|
}, 500); // 轮询时间间隔
|
|
|
|
|
});
|
|
|
|
|
};
|
2021-05-13 10:56:04 +08:00
|
|
|
|
}
|