import store from "@/store/index.js"; import utils from '@/utils/utils.js' import functions from '@/utils/functions.js' import { host, APPKEY } from "@/config/host"; import base64 from '@/utils/base64.js'; import { hexMD5 } from '@/utils/md5.js' import { nextTick } from 'vue'; /** * 刷新token */ const HandleRefreshToken = (header, urlhd, refresh_token, user) => { _isRefreshToken._isRefreshToken = new Promise((resolve, reject) => { console.log('user :>> ', user); const data = { "grant_type": 'refresh_token', 'scope': 'all', "refresh_token": user.refresh_token, // "refresh_token": 123, 'tenantId': user.tenant_id } header['Content-Type'] = 'application/x-www-form-urlencoded' header['Tenant-Id'] = user.tenant_id uni.request({ url: urlhd + `blade-auth/oauth/token`, data, method: 'post', header }).then((res) => { console.log('请求res :>> ', res); // 请求成功 if (res.statusCode === 200) { const userinfo = res.data uni.setStorageSync('access_token', userinfo.access_token) uni.setStorageSync('refresh_token', userinfo.refresh_token) uni.setStorageSync('userinfo', userinfo) resolve(res) } else { // 刷新token失败, 退出登录 uni.reLaunch({ url: '/pages/login/login' }) const res = uni.getStorageInfoSync(); res.keys.map(item => { if (item == 'loginuser' || item == 'HistoryDate' || item == 'setip' || item == 'checkname' || item.indexOf('IMAGE_CACHE_INFO') != -1) { return } uni.removeStorageSync(item) }) uni.reLaunch({ url: '/pages/login/login' }) requestObj = {} _isRefreshToken._isRefreshToken = null functions.error('请登录') reject({ code: 4000 }) } }).catch((err) => { // 刷新token失败, 退出登录 uni.reLaunch({ url: '/pages/login/login' }) const res = uni.getStorageInfoSync(); res.keys.map(item => { if (item == 'loginuser' || item == 'HistoryDate' || item == 'setip' || item == 'checkname' || item.indexOf('IMAGE_CACHE_INFO') != -1) { return } uni.removeStorageSync(item) }) uni.reLaunch({ url: '/pages/login/login' }) requestObj = {} _isRefreshToken._isRefreshToken = null functions.error('请登录') reject(err) }) }) return _isRefreshToken._isRefreshToken } /** * 请求函数 */ const HandleRequest = (params, key, loadingObj) => { return new Promise(async (relove, reject) => { let refresh_token = uni.getStorageSync('refresh_token') let token = uni.getStorageSync('access_token') let user = uni.getStorageSync('userinfo') let header = {}; if (user && token && refresh_token) { store.commit('updateislog', true) store.commit('updaterftk', refresh_token) store.commit('updatetk', token) store.commit('updatauser', user) header['Blade-Auth'] = `bearer ${store.state.access_token}` } else { if (!token && params.url.indexOf('oauth/token') == -1) { } } header.Authorization = `Basic ${base64.encode(APPKEY)}` // return if (params.url.indexOf('blade-auth/oauth/token') != -1) { header['Content-Type'] = 'application/x-www-form-urlencoded' header['Tenant-Id'] = params.data.tenantId // 登录请求时, 加密密码 if (params.data.password) params.data.password = hexMD5(params.data.password) } let content = '' if (loadingObj.title) content = loadingObj.title // 开启loading if (loadingObj.isShowLoading !== false) uni.showLoading({ title: content, mask: true }) let urlhd = '' if (uni.getStorageSync('setip')) { urlhd = uni.getStorageSync('setip') } else { urlhd = host } let version = '' if (!version) { // #ifdef APP version = await utils.getversion() version = version.version // #endif } let submitData = { url: urlhd + params.url, data: params.data, method: params.method, header } // 当程序在app上运行时, 带上版本号 // #ifdef APP submitData = { url: urlhd + params.url, data: { ...params.data, version }, method: params.method, // dataType: "json", header } // #endif const request = uni.request(submitData) request.then(res => { // console.log(res); console.log('请求res :>> ', res); if (res.statusCode == 200) { let data = res.data; // #ifdef APP utils.ttsspke(data.audio || '') // #endif if (data.code != 200 && data?.msg) { uni.showToast({ title: data?.msg || '', icon: 'none' }) } else if (data.audio) { uni.showToast({ title: data.msg, icon: 'none' }) } // 请求成功, 删除请求记录 delete requestObj[key] switch (data.code) { case 200: relove(data); break; case 203: relove(data); break; default: relove(data); break; } } else { if (res.statusCode == 400) { delete requestObj[key] relove({}); return } else if (res.statusCode == 500) { delete requestObj[key] functions.error('接口出错,请联系后端开发人员') // #ifdef APP utils.ttsspke('接口出错,请联系后端开发人员') // #endif return } else if (res.statusCode == 401) { // 登录失败时 if (isLogin) { return uni.showToast({ title: "登录失败", icon: 'none' }) } // 当token在刷新时, 等待 if (_isRefreshToken._isRefreshToken) { _isRefreshToken._isRefreshToken.then(() => { // 递归重新请求 HandleRequest(requestObj[key], key, loadingObj).then((res) => { relove(res) }) }) } else { console.log('header :>> ', header); // 发起刷新请求 const refreshFn = HandleRefreshToken(header, urlhd, refresh_token, user) refreshFn.then(res => { // 递归重新请求 HandleRequest(requestObj[key], key, loadingObj).then((res) => { relove(res) }) }).catch(() => { }).finally(() => { // 关闭刷新token状态 _isRefreshToken._isRefreshToken = null }) } } else { delete requestObj[key] functions.error('连接服务器失败') // #ifdef APP utils.ttsspke('连接服务器失败') // #endif } } }).catch(async err => { console.log(err); // uni.reLaunch({ // url: '/pages/index/index' // }) delete requestObj[key] functions.error('请检查是否连接到无线网络') // #ifdef APP utils.ttsspke('请检查是否连接到无线网络') // #endif }).finally(async res => { await nextTick() uni.hideLoading() }) }) } /** * 存储请求 */ let requestObj = {} /** * 是否正在进行刷新token */ let _isRefreshToken = { _isRefreshToken: null } let isLogin = false const service = async (params, loadingObj) => { if (params.data.isLogin) { isLogin = true delete params.data.isLogin } else isLogin = false console.log('params :>> ', params); const _key = params.url + JSON.stringify(params.data) // 防止重复请求 if (requestObj[_key]) return new Promise(resolve => resolve({ code: 4000 })) // 记录请求参数 requestObj[_key] = params // 如果正在刷新token则不请求, 等token刷新成功后再请求 console.log('_isRefreshToken :>> ', _isRefreshToken); if (_isRefreshToken._isRefreshToken) { await _isRefreshToken._isRefreshToken return HandleRequest(params, _key, loadingObj) } else return HandleRequest(params, _key, loadingObj) } export default service;