11
This commit is contained in:
@@ -61,6 +61,10 @@ const handleIdCardLogin = async (idCard) => {
|
||||
|
||||
if (res.token) {
|
||||
// 登录成功,存储token并获取用户信息
|
||||
if (res.refreshToken) {
|
||||
userStore.setRefreshToken(res.refreshToken)
|
||||
}
|
||||
userStore.setLoginTime(Date.now())
|
||||
await userStore.loginSetToken(res.token)
|
||||
|
||||
// 获取用户详细信息
|
||||
|
||||
@@ -337,6 +337,10 @@ const submitVerification = async () => {
|
||||
|
||||
if (res.token && res.code === 200) {
|
||||
// 登录成功,存储token
|
||||
if (res.refreshToken) {
|
||||
userStore.setRefreshToken(res.refreshToken)
|
||||
}
|
||||
userStore.setLoginTime(Date.now())
|
||||
await userStore.loginSetToken(res.token).then((resume) => {
|
||||
// 更新用户类型到缓存
|
||||
if (res.isCompanyUser !== undefined) {
|
||||
|
||||
@@ -373,6 +373,10 @@ const wxLogin = () => {
|
||||
// 调用后端接口进行登录
|
||||
$api.createRequest('/app/appLogin', loginParams, 'post').then((resData) => {
|
||||
if (resData.token) {
|
||||
if (resData.refreshToken) {
|
||||
userStore.setRefreshToken(resData.refreshToken)
|
||||
}
|
||||
userStore.setLoginTime(Date.now())
|
||||
userStore.loginSetToken(resData.token).then((resume) => {
|
||||
// 更新用户类型到缓存
|
||||
if (resData.isCompanyUser !== undefined) {
|
||||
@@ -442,6 +446,10 @@ const testLogin = () => {
|
||||
$api.createRequest('/app/login', params, 'post').then((resData) => {
|
||||
uni.hideLoading();
|
||||
|
||||
if (resData.refreshToken) {
|
||||
userStore.setRefreshToken(resData.refreshToken)
|
||||
}
|
||||
userStore.setLoginTime(Date.now())
|
||||
userStore.loginSetToken(resData.token).then((resume) => {
|
||||
// 更新用户类型到缓存
|
||||
if (resData.isCompanyUser !== undefined) {
|
||||
|
||||
@@ -49,9 +49,12 @@ const useUserStore = defineStore("user", () => {
|
||||
const userInfo = ref({});
|
||||
const role = ref({});
|
||||
const token = ref('')
|
||||
const refreshToken = ref('')
|
||||
const loginTime = ref(0)
|
||||
const resume = ref({})
|
||||
const Completion = ref('0%')
|
||||
const seesionId = ref(uni.getStorageSync('seesionId') || '')
|
||||
const SEVEN_DAYS = 7 * 24 * 60 * 60 * 1000
|
||||
|
||||
const login = (value) => {
|
||||
hasLogin.value = true;
|
||||
@@ -67,11 +70,15 @@ const useUserStore = defineStore("user", () => {
|
||||
const logOut = (showLoginModal = true) => {
|
||||
hasLogin.value = false;
|
||||
token.value = ''
|
||||
refreshToken.value = ''
|
||||
loginTime.value = 0
|
||||
resume.value = {}
|
||||
userInfo.value = {}
|
||||
role.value = {}
|
||||
uni.removeStorageSync('userInfo')
|
||||
uni.removeStorageSync('token')
|
||||
uni.removeStorageSync('refreshToken')
|
||||
uni.removeStorageSync('loginTime')
|
||||
uni.removeStorageSync('Padmin-Token')
|
||||
// 如果需要显示登录弹窗,则通过事件通知页面显示微信登录弹窗
|
||||
// if (showLoginModal) {
|
||||
@@ -122,6 +129,73 @@ const useUserStore = defineStore("user", () => {
|
||||
return getUserResume()
|
||||
}
|
||||
|
||||
const setRefreshToken = (refreshTokenVal) => {
|
||||
refreshToken.value = refreshTokenVal
|
||||
uni.setStorageSync('refreshToken', refreshTokenVal)
|
||||
}
|
||||
|
||||
const setLoginTime = (time) => {
|
||||
loginTime.value = time
|
||||
uni.setStorageSync('loginTime', time.toString())
|
||||
}
|
||||
|
||||
const isLoginExpired = () => {
|
||||
if (!loginTime.value) {
|
||||
const storedTime = uni.getStorageSync('loginTime')
|
||||
if (storedTime) {
|
||||
loginTime.value = parseInt(storedTime)
|
||||
}
|
||||
}
|
||||
if (!loginTime.value) return true
|
||||
return Date.now() - loginTime.value > SEVEN_DAYS
|
||||
}
|
||||
|
||||
const refreshAccessToken = async () => {
|
||||
if (isLoginExpired()) {
|
||||
logOut(false)
|
||||
return Promise.reject(new Error('登录已过期'))
|
||||
}
|
||||
|
||||
const storedRefreshToken = uni.getStorageSync('refreshToken') || refreshToken.value
|
||||
if (!storedRefreshToken) {
|
||||
logOut(false)
|
||||
return Promise.reject(new Error('没有刷新token'))
|
||||
}
|
||||
|
||||
return new Promise((resolve, reject) => {
|
||||
uni.request({
|
||||
url: 'http://ks.zhaopinzao8dian.com/api/ks/refreshToken',
|
||||
method: 'POST',
|
||||
data: {
|
||||
refreshToken: storedRefreshToken
|
||||
},
|
||||
success: (resData) => {
|
||||
if (resData.statusCode === 200) {
|
||||
const { code, msg, token: newToken } = resData.data
|
||||
if (code === 200 && newToken) {
|
||||
token.value = newToken
|
||||
uni.setStorageSync('token', newToken)
|
||||
resolve(newToken)
|
||||
} else if (code === 401) {
|
||||
logOut(false)
|
||||
reject(new Error(msg || '认证失败'))
|
||||
} else {
|
||||
logOut(false)
|
||||
reject(new Error(msg || '刷新token失败'))
|
||||
}
|
||||
} else {
|
||||
logOut(false)
|
||||
reject(new Error('网络请求失败'))
|
||||
}
|
||||
},
|
||||
fail: (err) => {
|
||||
logOut(false)
|
||||
reject(err)
|
||||
}
|
||||
})
|
||||
})
|
||||
}
|
||||
|
||||
const setUserInfo = (values) => {
|
||||
userInfo.value = values.data;
|
||||
resume.value = values.data; // 将用户信息同时存储到resume中
|
||||
@@ -156,10 +230,14 @@ const useUserStore = defineStore("user", () => {
|
||||
const restoreUserInfo = () => {
|
||||
const cachedUserInfo = uni.getStorageSync('userInfo');
|
||||
const cachedToken = uni.getStorageSync('token');
|
||||
const cachedRefreshToken = uni.getStorageSync('refreshToken');
|
||||
const cachedLoginTime = uni.getStorageSync('loginTime');
|
||||
if (cachedUserInfo && cachedToken) {
|
||||
userInfo.value = cachedUserInfo;
|
||||
resume.value = cachedUserInfo;
|
||||
token.value = cachedToken;
|
||||
refreshToken.value = cachedRefreshToken || '';
|
||||
loginTime.value = cachedLoginTime ? parseInt(cachedLoginTime) : 0;
|
||||
hasLogin.value = true;
|
||||
Completion.value = getResumeCompletionPercentage(cachedUserInfo);
|
||||
return true;
|
||||
@@ -172,10 +250,16 @@ const useUserStore = defineStore("user", () => {
|
||||
hasLogin,
|
||||
userInfo,
|
||||
token,
|
||||
refreshToken,
|
||||
loginTime,
|
||||
resume,
|
||||
login,
|
||||
logOut,
|
||||
loginSetToken,
|
||||
setRefreshToken,
|
||||
setLoginTime,
|
||||
isLoginExpired,
|
||||
refreshAccessToken,
|
||||
getUserResume,
|
||||
initSeesionId,
|
||||
seesionId,
|
||||
|
||||
@@ -2,6 +2,9 @@ import config from "@/config.js"
|
||||
import { sm4Encrypt, sm4Decrypt } from '@/utils/crypto';
|
||||
import useUserStore from '@/stores/useUserStore';
|
||||
|
||||
let isRefreshing = false;
|
||||
let refreshSubscribers = [];
|
||||
|
||||
const needToEncryptSet = new Set([
|
||||
'POST:/app/login',
|
||||
'GET:/app/user/resume',
|
||||
@@ -36,6 +39,20 @@ const encryptPathPrefixes = [
|
||||
'/refreshToken',
|
||||
];
|
||||
|
||||
const addRefreshSubscriber = (callback) => {
|
||||
refreshSubscribers.push(callback);
|
||||
};
|
||||
|
||||
const notifyRefreshSubscribers = (token) => {
|
||||
refreshSubscribers.forEach((callback) => callback(token));
|
||||
refreshSubscribers = [];
|
||||
};
|
||||
|
||||
const resetRefreshState = () => {
|
||||
isRefreshing = false;
|
||||
refreshSubscribers = [];
|
||||
};
|
||||
|
||||
const noEncryptSet = new Set([
|
||||
'DELETE:/app/job/applyJobCencal',
|
||||
]);
|
||||
@@ -172,6 +189,8 @@ export function createRequest(url, data = {}, method = 'GET', loading = false, h
|
||||
header["Authorization"] = Authorization;
|
||||
}
|
||||
const requestData = isEncryptNeeded(method, url) ? encryptRequestData(data) : data;
|
||||
|
||||
const doRequest = () => {
|
||||
return new Promise((resolve, reject) => {
|
||||
uni.request({
|
||||
url: config.baseUrl + url,
|
||||
@@ -182,8 +201,8 @@ export function createRequest(url, data = {}, method = 'GET', loading = false, h
|
||||
// 响应拦截
|
||||
if (resData.statusCode === 200) {
|
||||
const responseData = handleResponseData(resData.data)
|
||||
console.log('[请求] 接口地址:', config.baseUrl + url)
|
||||
console.log('[请求] 解密后数据:', responseData)
|
||||
// console.log('[请求] 接口地址:', config.baseUrl + url)
|
||||
// console.log('[请求] 解密后数据:', responseData)
|
||||
const {
|
||||
code,
|
||||
msg
|
||||
@@ -194,14 +213,11 @@ export function createRequest(url, data = {}, method = 'GET', loading = false, h
|
||||
}
|
||||
// 处理业务错误
|
||||
if (responseData?.code === 401 || responseData?.code === 402) {
|
||||
useUserStore().logOut()
|
||||
handleTokenExpired(resolve, reject, doRequest, loading)
|
||||
return
|
||||
}
|
||||
// 显示具体的错误信息
|
||||
const errorMsg = msg || '请求出现异常,请联系工作人员'
|
||||
// uni.showToast({
|
||||
// title: errorMsg,
|
||||
// icon: 'none'
|
||||
// })
|
||||
const err = new Error(errorMsg)
|
||||
err.error = resData
|
||||
reject(err)
|
||||
@@ -222,6 +238,40 @@ export function createRequest(url, data = {}, method = 'GET', loading = false, h
|
||||
}
|
||||
});
|
||||
})
|
||||
}
|
||||
|
||||
return doRequest()
|
||||
}
|
||||
|
||||
const handleTokenExpired = (resolve, reject, retryRequest, loading) => {
|
||||
if (isRefreshing) {
|
||||
addRefreshSubscriber((token) => {
|
||||
if (token) {
|
||||
retryRequest().then(resolve).catch(reject)
|
||||
} else {
|
||||
reject(new Error('刷新token失败'))
|
||||
}
|
||||
})
|
||||
return
|
||||
}
|
||||
|
||||
isRefreshing = true
|
||||
|
||||
useUserStore().refreshAccessToken().then((newToken) => {
|
||||
notifyRefreshSubscribers(newToken)
|
||||
retryRequest().then(resolve).catch(reject)
|
||||
}).catch((error) => {
|
||||
resetRefreshState()
|
||||
uni.showToast({
|
||||
title: '登录过期,请重新登录',
|
||||
icon: 'none'
|
||||
})
|
||||
reject(error)
|
||||
}).finally(() => {
|
||||
if (loading) {
|
||||
uni.hideLoading()
|
||||
}
|
||||
})
|
||||
}
|
||||
|
||||
|
||||
|
||||
Reference in New Issue
Block a user