hbsmUniapp/src/utils/request.ts
2025-08-19 23:31:48 +08:00

186 lines
4.8 KiB
TypeScript
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

import { useMemberStore } from '@/stores'
import type { token } from '@/types/member'
import { apiName, apiUrl } from '@/config'
import _, { reject } from 'lodash'
import { pageUrl } from '@/utils/constants'
import { ref } from 'vue'
//配置拦截器
const Interceptor = {
//拦截前触发
invoke(options: UniApp.RequestOptions) {
//拼接请求地址
if (!/^https?:\/\//.test(options.url)) {
// /api是系统保留的接口不代理
if (options.url.startsWith('/api')) {
options.url = apiUrl + options.url
} else {
options.url = apiUrl + apiName + options.url
}
}
//请求超时 10s
options.timeout = 10000
//请求头
let sourceClient = ''
switch (uni.getSystemInfoSync().uniPlatform) {
case 'web':
sourceClient = 'h5'
break
case 'mp-weixin':
sourceClient = 'miniapp'
break
default:
sourceClient = ''
}
options.header = {
'source-client': sourceClient,
server: true,
...options.header,
}
const memberStore = useMemberStore()
const token = memberStore?.profile?.token || ''
const refreshToken = memberStore.profile?.refresh_token || ''
if (options.url.endsWith('/login/refresh')) {
options.header['Ba-User-Refresh'] = refreshToken
} else {
options.header['Ba-User-Token'] = token
}
},
}
//拦截request请求
uni.addInterceptor('request', Interceptor)
//拦截文件上传请求
uni.addInterceptor('uploadFile', Interceptor)
//定义接口请求类型
interface Data<T> {
msg: string
result: T
}
const loginFail = (res: any) => {
useMemberStore().clearProfile()
uni.showModal({
title: '温馨提示',
content: '登录解锁更多精彩,是否继续?',
confirmText: '去登录',
cancelText: '再看看',
success: function (res) {
if (res.confirm) {
uni.navigateTo({ url: pageUrl['login'] })
} else {
uni.navigateBack()
}
},
})
return reject(res)
}
const requestLoading = ref(false)
export const request = <T>(
options: UniApp.RequestOptions,
showBackModal = true,
showLoading = true,
) => {
return new Promise<Data<T>>((resolve, reject) => {
if (showLoading) {
wx.showLoading({
title: '数据加载中…',
mask: true,
})
requestLoading.value = true
}
uni.request({
...options,
success(res) {
if (requestLoading.value) {
wx.hideLoading()
}
//成功
if (res.statusCode === 200) {
return resolve(res.data as Data<T>)
}
//服务器错误
if (res.statusCode === 500) {
if (requestLoading.value) {
wx.hideLoading()
}
if (showBackModal) {
uni.showModal({
title: '',
content: (res.data as Data<T>).msg || '服务器内部错误',
success: function (res) {
uni.navigateBack()
},
})
uni.$emit('z-paging-error-emit')
}
return reject(res)
}
//参数错误
if (res.statusCode === 400) {
if (requestLoading.value) {
wx.hideLoading()
}
uni.showToast({
title: (res.data as Data<T>).msg || '请求数据异常',
icon: 'none',
mask: true,
duration: 2500,
})
uni.$emit('z-paging-error-emit')
return reject(res)
}
//登录态过期
if (res.statusCode === 409) {
const memberStore = useMemberStore()
if (!memberStore.profile?.refresh_token) {
return loginFail(res)
}
//通过refresh_token刷新token
uni.request({
url: '/login/refresh',
method: 'POST',
success(res) {
if (res.statusCode != 200) {
return loginFail(res)
}
//更新token
memberStore.updateToken((res.data as Data<T>).result as token)
//重新发起请求
request<T>(options)
.then((res) => {
return resolve(res)
})
.catch((err) => {
return reject(err)
})
},
fail(err) {
return loginFail(err)
},
})
}
//登录失效
if (res.statusCode === 401) {
if (requestLoading.value) {
wx.hideLoading()
}
useMemberStore().clearProfile()
return loginFail(res)
}
},
//失败
fail(err) {
uni.showToast({
title: '网络请求异常',
icon: 'error',
})
uni.$emit('z-paging-error-emit')
return reject(err)
},
})
})
}