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,
|
|||
|
|
};
|
|||
|
|
});
|
|||
|
|
|