105 lines
2.6 KiB
TypeScript

import { defineStore } from "pinia";
import { computed, ref } from "vue";
import { devLogin, getCurrentUser, login } from "@/api/auth";
import { authenticateWithDingTalk } from "@/api/dingtalk";
import type { User } from "@/types/auth";
const TOKEN_KEY = "risk_prediction_token";
export const useAuthStore = defineStore("auth", () => {
const token = ref<string | null>(localStorage.getItem(TOKEN_KEY));
const user = ref<User | null>(null);
const loading = ref(false);
const error = ref<string | null>(null);
const isAuthenticated = computed(() => Boolean(token.value && user.value));
function saveToken(value: string) {
token.value = value;
localStorage.setItem(TOKEN_KEY, value);
}
function clear() {
token.value = null;
user.value = null;
localStorage.removeItem(TOKEN_KEY);
}
async function authenticate(
username: string,
password: string,
development = false,
) {
loading.value = true;
error.value = null;
try {
const response = development
? await devLogin(username, password)
: await login(username, password);
if (!response.data.data) throw new Error("登录响应为空");
saveToken(response.data.data.accessToken);
user.value = response.data.data.user;
} catch (reason) {
clear();
error.value =
reason instanceof Error ? reason.message : "登录失败,请检查账号或密码";
throw reason;
} finally {
loading.value = false;
}
}
async function restore() {
if (!token.value) return false;
try {
const response = await getCurrentUser();
user.value = response.data.data;
return Boolean(user.value);
} catch {
clear();
return false;
}
}
async function dingTalkLogin(preserveSessionOnFailure = false) {
loading.value = true;
error.value = null;
try {
const response = await authenticateWithDingTalk();
saveToken(response.accessToken);
user.value = response.user;
} catch (reason) {
if (!preserveSessionOnFailure) clear();
error.value = reason instanceof Error ? reason.message : "钉钉免登失败";
throw reason;
} finally {
loading.value = false;
}
}
function logout() {
clear();
}
function hasPermission(permission: string) {
return (
user.value?.role === "admin" ||
Boolean(user.value?.permissions.includes(permission))
);
}
return {
token,
user,
loading,
error,
isAuthenticated,
authenticate,
dingTalkLogin,
restore,
clear,
logout,
hasPermission,
};
});