Files
ai-agent-admin/web/apps/web-ele/src/bootstrap.ts
T

147 lines
4.8 KiB
TypeScript
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
import { createApp, watchEffect } from 'vue';
import { registerAccessDirective } from '@vben/access';
import { registerLoadingDirective } from '@vben/common-ui';
import { preferences } from '@vben/preferences';
import { initStores } from '@vben/stores';
import '@vben/styles';
import '@vben/styles/ele';
import { useTitle } from '@vueuse/core';
import { $t, setupI18n } from '#/locales';
import App from './app.vue';
import { setupElementPlus } from './plugins/element-plus';
import { router } from './router';
async function bootstrap(namespace: string) {
// // 设置弹窗的默认配置
// setDefaultModalProps({
// fullscreenButton: false,
// });
// // 设置抽屉的默认配置
// setDefaultDrawerProps({
// zIndex: 2000,
// });
const app = createApp(App);
setupElementPlus(app);
// 注册Element Plus提供的v-loading指令
// 注册Vben提供的v-loading和v-spinning指令
registerLoadingDirective(app, {
loading: false, // Vben提供的v-loading指令和Element Plus提供的v-loading指令二选一即可,此处false表示不注册Vben提供的v-loading指令
spinning: 'spinning',
});
// 国际化 i18n 配置
await setupI18n(app);
// 配置 pinia-tore
await initStores(app, { namespace });
// 初始化跨tab的token同步机制
const { useAccessStore } = await import('@vben/stores');
const accessStore = useAccessStore();
// 从共享存储加载 token(主应用和子应用共享)
const SHARED_TOKEN_KEY = 'vben-shared-auth-tokens';
try {
const stored = localStorage.getItem(SHARED_TOKEN_KEY);
if (stored) {
const tokens = JSON.parse(stored);
console.log('[Bootstrap] 从共享存储加载token:', {
hasAccessToken: !!tokens.accessToken,
hasRefreshToken: !!tokens.refreshToken,
});
// 直接修改 $state,避免触发 saveSharedTokens(因为数据本来就是从 localStorage 读取的)
if (tokens.accessToken) {
accessStore.$state.accessToken = tokens.accessToken;
}
if (tokens.refreshToken) {
accessStore.$state.refreshToken = tokens.refreshToken;
}
}
} catch (error) {
console.error('[Bootstrap] 加载共享token失败:', error);
}
// 监听 localStorage 的变化(跨tab通信)
// Token 使用固定 key 'vben-shared-auth-tokens' 存储,主应用和子应用共享
window.addEventListener('storage', (event) => {
// 只处理共享的 token key 的变化
if (event.key === 'vben-shared-auth-tokens') {
try {
// 当其他 tab 更新了 token,同步到当前 tab 的 Pinia Store
const newValue = event.newValue ? JSON.parse(event.newValue) : null;
if (newValue) {
// 直接修改 $state,避免触发 saveSharedTokens 导致循环
if (
newValue.accessToken !== undefined &&
newValue.accessToken !== accessStore.accessToken
) {
console.log(
'[跨Tab同步] 检测到其他tab更新了accessToken,同步中...',
);
accessStore.$state.accessToken = newValue.accessToken;
}
if (
newValue.refreshToken !== undefined &&
newValue.refreshToken !== accessStore.refreshToken
) {
console.log(
'[跨Tab同步] 检测到其他tab更新了refreshToken,同步中...',
);
accessStore.$state.refreshToken = newValue.refreshToken;
}
} else {
// token 被清除(退出登录),同步清除当前 tab 的 token
if (accessStore.accessToken) {
console.log('[跨Tab同步] 检测到其他tab退出登录,同步清除token...');
accessStore.$state.accessToken = null;
accessStore.$state.refreshToken = null;
}
}
} catch (error) {
console.error('[跨Tab同步] 解析localStorage数据失败:', error);
}
}
});
// 初始化应用上下文(从 URL 参数中获取 appCode
const { useAppContextStore } = await import('#/store/app-context');
const appContextStore = useAppContextStore();
await appContextStore.initFromUrl();
// 安装权限指令
registerAccessDirective(app);
// 初始化 tippy
const { initTippy } = await import('@vben/common-ui/es/tippy');
initTippy(app);
// 配置路由及路由守卫
app.use(router);
// 配置Motion插件
const { MotionPlugin } = await import('@vben/plugins/motion');
app.use(MotionPlugin);
// 动态更新标题
watchEffect(() => {
if (preferences.app.dynamicTitle) {
const routeTitle = router.currentRoute.value.meta?.title;
const pageTitle =
(routeTitle ? `${$t(routeTitle)} - ` : '') + preferences.app.name;
useTitle(pageTitle);
}
});
app.mount('#app');
}
export { bootstrap };