145 lines
3.5 KiB
JavaScript
145 lines
3.5 KiB
JavaScript
import { ref } from "vue";
|
||
import { defineStore } from "pinia";
|
||
import { miniAppLogin, logout as logoutApi, refreshToken as refreshTokenApi } from "@/utils/auth";
|
||
|
||
/**
|
||
* JWT 认证状态管理
|
||
* 管理小程序的 token 和认证状态
|
||
*/
|
||
export default defineStore("authStore", () => {
|
||
// Token 状态
|
||
const accessToken = ref(uni.getStorageSync("accessToken") || "");
|
||
const refreshToken = ref(uni.getStorageSync("refreshToken") || "");
|
||
const jwtUserInfo = ref(uni.getStorageSync("jwtUserInfo") || null);
|
||
const isLoggingIn = ref(false);
|
||
const isRefreshing = ref(false);
|
||
|
||
/**
|
||
* 小程序授权登录
|
||
* @param {Object} params - 登录参数 { authCode, platform, corpId }
|
||
* @returns {Promise}
|
||
*/
|
||
async function login({ authCode, platform = "alipay", corpId }) {
|
||
if (isLoggingIn.value) {
|
||
return { success: false, message: "正在登录中..." };
|
||
}
|
||
|
||
isLoggingIn.value = true;
|
||
|
||
try {
|
||
const result = await miniAppLogin({ authCode, platform, corpId });
|
||
|
||
if (result.success && result.data) {
|
||
// 保存 token 和用户信息
|
||
accessToken.value = result.data.accessToken;
|
||
refreshToken.value = result.data.refreshToken;
|
||
jwtUserInfo.value = result.data.userInfo;
|
||
|
||
// 持久化到 storage
|
||
uni.setStorageSync("accessToken", result.data.accessToken);
|
||
uni.setStorageSync("refreshToken", result.data.refreshToken);
|
||
uni.setStorageSync("jwtUserInfo", result.data.userInfo);
|
||
|
||
return { success: true, message: result.message, data: result.data };
|
||
} else {
|
||
return { success: false, message: result.message || "登录失败" };
|
||
}
|
||
} catch (error) {
|
||
console.error("登录失败:", error);
|
||
return { success: false, message: "登录失败,请稍后再试" };
|
||
} finally {
|
||
isLoggingIn.value = false;
|
||
}
|
||
}
|
||
|
||
/**
|
||
* 刷新 Token
|
||
* @returns {Promise<string|null>} 返回新的 accessToken,失败返回 null
|
||
*/
|
||
async function refreshAccessToken() {
|
||
if (!refreshToken.value) {
|
||
console.warn("没有 refreshToken,无法刷新");
|
||
return null;
|
||
}
|
||
|
||
if (isRefreshing.value) {
|
||
// 避免并发刷新,等待一下
|
||
await new Promise((resolve) => setTimeout(resolve, 100));
|
||
return accessToken.value;
|
||
}
|
||
|
||
isRefreshing.value = true;
|
||
|
||
try {
|
||
const result = await refreshTokenApi(refreshToken.value);
|
||
|
||
if (result.success && result.data) {
|
||
// 更新 token
|
||
accessToken.value = result.data.accessToken;
|
||
uni.setStorageSync("accessToken", result.data.accessToken);
|
||
|
||
return result.data.accessToken;
|
||
} else {
|
||
// 刷新失败,清除登录状态
|
||
console.error("Token 刷新失败:", result.message);
|
||
clearAuth();
|
||
return null;
|
||
}
|
||
} catch (error) {
|
||
console.error("Token 刷新异常:", error);
|
||
clearAuth();
|
||
return null;
|
||
} finally {
|
||
isRefreshing.value = false;
|
||
}
|
||
}
|
||
|
||
/**
|
||
* 退出登录
|
||
*/
|
||
async function logout() {
|
||
try {
|
||
if (accessToken.value) {
|
||
await logoutApi(accessToken.value);
|
||
}
|
||
} catch (error) {
|
||
console.error("退出登录请求失败:", error);
|
||
} finally {
|
||
clearAuth();
|
||
}
|
||
}
|
||
|
||
/**
|
||
* 清除认证信息
|
||
*/
|
||
function clearAuth() {
|
||
accessToken.value = "";
|
||
refreshToken.value = "";
|
||
jwtUserInfo.value = null;
|
||
|
||
uni.removeStorageSync("accessToken");
|
||
uni.removeStorageSync("refreshToken");
|
||
uni.removeStorageSync("jwtUserInfo");
|
||
}
|
||
|
||
/**
|
||
* 获取认证状态
|
||
*/
|
||
const isAuthenticated = () => !!accessToken.value;
|
||
|
||
return {
|
||
accessToken,
|
||
refreshToken,
|
||
jwtUserInfo,
|
||
isLoggingIn,
|
||
isRefreshing,
|
||
|
||
login,
|
||
logout,
|
||
refreshAccessToken,
|
||
clearAuth,
|
||
isAuthenticated,
|
||
};
|
||
});
|
||
|