This commit is contained in:
FengHui
2026-05-15 14:16:31 +08:00
parent 5910b19131
commit e857c008b4
5 changed files with 197 additions and 47 deletions

View File

@@ -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)
// 获取用户详细信息

View File

@@ -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) {

View File

@@ -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) {

View File

@@ -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,

View File

@@ -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()
}
})
}