105 lines
2.6 KiB
TypeScript
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,
|
|
};
|
|
});
|