Files
pj_h5_cloud/src/sheep/utils/request.ts
T
2025-03-25 13:28:49 +08:00

328 lines
8.4 KiB
TypeScript

import Request from "luch-request"
import { isEmpty } from "radash"
import isDevEnv from "./isDevEnv"
import { router, constant } from "@@/index"
import { userApi } from "../api"
// 定义常量
const TOKEN_KEY = constant.storageConstant.TOKEN
const USER_INFO_KEY = constant.storageConstant.USERINFO
// Loading 管理
const LoadingInstance: { target: any; count: number } = {
target: null,
count: 0,
}
// 关闭 loading
function closeLoading() {
if (LoadingInstance.count > 0) LoadingInstance.count--
if (LoadingInstance.count === 0) uni.hideLoading()
}
// 创建请求实例
const http = new Request({
baseURL: import.meta.env.VITE_API_URL,
timeout: 8000,
method: "GET",
header: {
Accept: "*/*",
"Content-Type": "application/json;charset=UTF-8",
},
withCredentials: true,
custom: {
showSuccess: false,
// 成功提醒 默认使用后端返回值
successMsg: "",
// 显示失败消息 默认显示
showError: true,
// 失败提醒 默认使用后端返回信息
errorMsg: "",
// 显示请求时loading模态框 默认显示
showLoading: true,
// loading提醒文字
loadingMsg: "加载中",
// 需要授权才能请求 默认放开
auth: false,
},
})
// 处理请求头 Authorization
const getAuthHeader = (tokenStorage: any) => {
if (isDevEnv()) {
return tokenStorage?.access_token ? `Bearer ${tokenStorage.access_token}` : null
}
return tokenStorage?.accessToken?.tokenValue ? `Bearer ${tokenStorage.accessToken.tokenValue}` : null
}
// token过期刷新检查
const checkAndRefreshToken = async (tokenStorage: any) => {
const { accessToken } = tokenStorage
if (!accessToken) return
const expiresDate = new Date(accessToken.expiresAt).getTime()
console.log("现在的时间大于过期时间吗:", new Date().getTime() >= expiresDate)
if (new Date().getTime() >= expiresDate) {
// try {
// const refreshData: any = await request({
// url: "/auth/oauth2/token",
// method: "POST",
// params: { grant_type: "refresh_token" },
// data: JSON.stringify({
// scope: "server",
// refresh_token: tokenStorage.refreshToken.tokenValue,
// }),
// header: {
// skipToken: true,
// Authorization: "Basic " + window.btoa(import.meta.env.VITE_OAUTH2_APP_CLIENT),
// "content-type": "application/x-www-form-urlencoded",
// },
// })
// if (refreshData.code === 0 && !isEmpty(refreshData.data)) {
// console.log("refreshData.data", refreshData.data)
// // 刷新成功,更新token并重试请求
// uni.setStorageSync(TOKEN_KEY, refreshData.data)
// }
// } catch (refreshError) {
// console.error("Token refresh failed:", refreshError)
// }
try {
uni.showLoading({ title: "加载中...", mask: true })
const params = new URL(window.location.href).searchParams
const token = params.get("uabaseToken")
if (token) {
const res = await userApi.auth(token)
if (res?.code === 0) {
uni.setStorageSync(TOKEN_KEY, res.data)
} else {
uni.removeStorageSync(TOKEN_KEY)
uni.removeStorageSync(USER_INFO_KEY)
uni.showToast({ title: res.msg, icon: "none" })
}
}
} catch (error) {
uni.showToast({ title: "错误", icon: "none" })
} finally {
uni.hideLoading()
}
}
}
// 请求拦截器
http.interceptors.request.use(async (config) => {
console.log("请求之前")
const tokenStorage = uni.getStorageSync(TOKEN_KEY)
const config_header: any = config?.header || {}
// 设置租户请求头
config_header["TENANT-ID"] = "1"
if (import.meta.env.VITE_IS_TOC === "true") {
config_header["CLIENT-TOC"] = "Y"
}
// 处理 loading
if (config.custom?.showLoading) {
LoadingInstance.count++
if (LoadingInstance.count === 1) {
uni.showLoading({
title: config.custom.loadingMsg,
mask: true,
fail: () => uni.hideLoading(),
})
}
}
// 设置认证头
if (
!config.url?.startsWith("/thirdparty/thirdPartyOAth2/zzdsso") &&
config.url !== "/sys/auth/refresh-token" &&
config.url !== "/auth/oauth2/token"
) {
if (!isEmpty(tokenStorage)) {
// token过期刷新检查
checkAndRefreshToken(tokenStorage)
const authHeader = getAuthHeader(tokenStorage)
if (authHeader) {
config_header.Authorization = authHeader
}
} else {
// token不存在,则发起登录
const params = new URL(window.location.href).searchParams
const token = params.get("uabaseToken")
if (token) {
try {
uni.showLoading({ title: "加载中...", mask: true })
const res = await userApi.auth(token)
if (res.code == 0) {
uni.setStorageSync(TOKEN_KEY, res.data)
const { data: userData } = await userApi.userInfo()
uni.setStorageSync(USER_INFO_KEY, userData)
const authHeader = getAuthHeader(tokenStorage)
if (authHeader) {
config_header.Authorization = authHeader
}
} else {
uni.showToast({ title: "获取浙政钉用户信息失败", icon: "none" })
}
} catch (error) {
uni.showToast({ title: "错误", icon: "none" })
} finally {
uni.hideLoading()
}
}
}
}
return config
}, Promise.reject)
// 处理错误响应
const handleErrorResponse = (response: any) => {
if (!response.config?.custom?.showError) return
switch (response.data.code) {
case 401:
// 处理未授权情况
setTimeout(() => {
uni.removeStorageSync(TOKEN_KEY)
uni.removeStorageSync(USER_INFO_KEY)
console.log("未授权")
}, 500)
break
case 424:
try {
const params = new URL(window.location.href).searchParams
const token = params.get("uabaseToken")
if (token) {
userApi.auth(token).then((res) => {
if (res?.code === 0) {
uni.setStorageSync(TOKEN_KEY, res.data)
} else {
uni.removeStorageSync(TOKEN_KEY)
uni.removeStorageSync(USER_INFO_KEY)
// uni.showToast({ title: "登录已过期", icon: "none" })
return Promise.resolve({
code: 1,
data: "登录已过期",
msg: "登录已过期",
})
}
})
}
} catch (error) {
uni.hideLoading()
uni.showToast({ title: "错误", icon: "none" })
}
break
default:
uni.showToast({
title: response.data.msg || "服务器开小差啦,请稍后再试~",
icon: "none",
mask: true,
})
}
}
// 处理成功提示
const handleSuccessMessage = (response: any) => {
const { data, config } = response
if (data.code === 0 && data.message && config?.custom?.showSuccess) {
uni.showToast({
title: config.custom.successMsg || data.message,
icon: "none",
})
}
}
// 响应拦截器
http.interceptors.response.use(
async (response) => {
// 关闭loading
if (response.config?.custom?.showLoading) {
closeLoading()
}
// OAuth2 token请求特殊处理
if (response.config.url === "/auth/oauth2/token") {
return Promise.resolve({
code: 0,
data: response.data,
msg: null,
})
}
// 错误处理和错误提示
if (response.data.code !== 0) {
handleErrorResponse(response)
return Promise.resolve(response.data)
}
// 成功提示
handleSuccessMessage(response)
return Promise.resolve(response.data)
},
(error) => {
// 处理 424 错误(token过期)
if (error.statusCode === 424) {
if (isDevEnv()) {
// 开发环境直接清除token并跳转登录
uni.removeStorageSync(TOKEN_KEY)
uni.removeStorageSync(USER_INFO_KEY)
uni.showToast({ title: "登录已过期,请重新登录", icon: "none" })
router.jump("/pages/test/login")
return false
} else {
try {
uni.showLoading({ title: "加载中...", mask: true })
const params = new URL(window.location.href).searchParams
const token = params.get("uabaseToken")
if (token) {
userApi.auth(token).then((res) => {
if (res?.code === 0) {
uni.setStorageSync(TOKEN_KEY, res.data)
} else {
uni.removeStorageSync(TOKEN_KEY)
uni.removeStorageSync(USER_INFO_KEY)
// uni.showToast({ title: "登录已过期", icon: "none" })
return Promise.resolve({
code: 1,
data: "登录已过期",
msg: "登录已过期",
})
}
})
}
} catch (error) {
uni.showToast({ title: "错误", icon: "none" })
} finally {
uni.hideLoading()
}
}
}
// 显示错误信息
if (error?.data?.msg) {
uni.showToast({
title: error.data.msg,
icon: "none",
mask: true,
})
}
return false
},
)
const request = (config: any) => {
return http.middleware(config)
}
export default request