76 lines
2.1 KiB
JavaScript
76 lines
2.1 KiB
JavaScript
import { onMounted, ref } from "vue";
|
|
|
|
export function useAppShell() {
|
|
const setupState = ref(null);
|
|
const authenticated = ref(null);
|
|
const isAdmin = ref(null);
|
|
const bootstrapping = ref(true);
|
|
const error = ref("");
|
|
const routePath = window.location.pathname.replace(/\/+$/, "") || "/";
|
|
const standalonePaths = ["/login", "/password-reset", "/reset"];
|
|
|
|
async function bootstrap() {
|
|
bootstrapping.value = true;
|
|
error.value = "";
|
|
try {
|
|
const response = await fetch("/api/v1/setup/status");
|
|
const result = await response.json().catch(() => ({}));
|
|
if (!response.ok) throw new Error(result.error || "读取初始化状态失败");
|
|
setupState.value = result;
|
|
if (result.initialized) {
|
|
await checkAuth();
|
|
} else {
|
|
authenticated.value = false;
|
|
isAdmin.value = false;
|
|
}
|
|
} catch (err) {
|
|
setupState.value = null;
|
|
authenticated.value = null;
|
|
isAdmin.value = null;
|
|
error.value = err.message || "无法连接核心服务,请先启动 scert serve";
|
|
} finally {
|
|
bootstrapping.value = false;
|
|
}
|
|
}
|
|
|
|
async function checkAuth() {
|
|
const response = await fetch("/api/v1/auth/session", {
|
|
credentials: "include",
|
|
});
|
|
if (response.status === 401) {
|
|
authenticated.value = false;
|
|
isAdmin.value = false;
|
|
return;
|
|
}
|
|
const result = await response.json().catch(() => ({}));
|
|
if (!response.ok) throw new Error(result.error || "读取登录状态失败");
|
|
authenticated.value = result.authenticated === true;
|
|
isAdmin.value = result.is_admin === true || ["super_admin", "admin"].includes(result.role);
|
|
}
|
|
|
|
function handleInitialized() {
|
|
setupState.value = { ...setupState.value, initialized: true };
|
|
authenticated.value = false;
|
|
isAdmin.value = false;
|
|
}
|
|
|
|
onMounted(() => {
|
|
if (standalonePaths.includes(routePath)) {
|
|
bootstrapping.value = false;
|
|
return;
|
|
}
|
|
bootstrap();
|
|
});
|
|
|
|
return {
|
|
setupState,
|
|
authenticated,
|
|
isAdmin,
|
|
bootstrapping,
|
|
error,
|
|
routePath,
|
|
bootstrap,
|
|
handleInitialized,
|
|
};
|
|
}
|