heli-mes/heli-app/src/utils/http.ts
2025-01-09 18:29:48 +08:00

130 lines
3.5 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.

/**
* 添加拦截器:
* 拦截 request 请求
* 拦截 uploadFile 文件上传
*
* TODO:
* 1. 非 http 开头需拼接地址
* 2. 请求超时
* 3. 添加小程序端请求头标识
* 4. 添加 token 请求头标识
*/
import { useLoginStore } from '@/stores/modules/login'
import { serviceDomain } from '@/services/constants'
const baseURL = serviceDomain + '/admin-api'
const loginStore = useLoginStore()
// 添加拦截器
const httpInterceptor = {
// 拦截前触发
invoke(options: UniApp.RequestOptions) {
// 1. 非 http 开头需拼接地址
if (!options.url.startsWith('http')) {
options.url = baseURL + options.url
}
// 2. 请求超时, 默认 60s
options.timeout = 10000
// 3. 添加小程序端请求头标识
options.header = {
...options.header,
// 'tenant-id': loginStore.userInfo?.userId || 2,
'tenant-id': 2,
}
// 4. 添加 token 请求头标识
const storage_token = uni.getStorageSync('storage_loginInfo')?.accessToken
const token = loginStore.userInfo?.accessToken || storage_token
if (token) {
options.header.Authorization = token
}
},
}
uni.addInterceptor('request', httpInterceptor)
uni.addInterceptor('uploadFile', httpInterceptor)
/**
* 请求函数
* @param UniApp.RequestOptions
* @returns Promise
* 1. 返回 Promise 对象
* 2. 获取数据成功
* 2.1 提取核心数据 res.data
* 2.2 添加类型,支持泛型
* 3. 获取数据失败
* 3.1 401错误 -> 清理用户信息,跳转到登录页
* 3.2 其他错误 -> 根据后端错误信息轻提示
* 3.3 网络错误 -> 提示用户换网络
*/
type Data<T> = {
code: string
msg: string
result: T
}
function ajaxError(data) {
uni.showToast({
title: data.msg || '请求出错,请重试',
duration: 3000,
icon: 'none',
complete() {
if (data.code === 600 || data.code === 601 || data.code === 602) {
const memberStore = useMemberStore()
memberStore.clearProfile()
uni.reLaunch({
url: '/pages/login/login'
})
}
}
})
}
// 2.2 添加类型,支持泛型
export const http = <T>(options: UniApp.RequestOptions) => {
// 1. 返回 Promise 对象
return new Promise<Data<T>>((resolve, reject) => {
uni.request({
...options,
// 响应成功
success(res) {
console.log(res)
// 状态码 2xx axios 就是这样设计的
if (res.statusCode >= 200 && res.statusCode < 300) {
if (res.data?.code == 0) {
resolve(res.data.data as Data<T>)
} else if (res.data?.code === 401) {
// 401错误 -> 清理用户信息,跳转到登录页
loginStore.clearInfo()
uni.navigateTo({ url: '/pages/login/login' })
reject(res)
} else {
const msg = (res.data as Data<T>).msg
uni.showToast({
icon: 'none',
duration: 3000,
title: msg || '请求错误',
})
reject(res)
}
} else {
// 其他错误 -> 根据后端错误信息轻提示
uni.showToast({
icon: 'none',
duration: 3000,
title: (res.data as Data<T>).msg || '请求错误',
})
reject(res)
}
},
// 响应失败
fail(err) {
uni.showToast({
icon: 'none',
duration: 3000,
title: '网络错误,换个网络试试',
})
reject(err)
},
})
})
}