142 lines
4.8 KiB
Vue
142 lines
4.8 KiB
Vue
<template>
|
||
<el-config-provider :size="getGlobalComponentSize" :locale="getGlobalI18n">
|
||
<router-view v-show="setLockScreen" />
|
||
<LockScreen v-if="themeConfig.isLockScreen" />
|
||
<Settings ref="settingsRef" v-show="themeConfig.lockScreenTime > 1" />
|
||
<CloseFull v-if="!themeConfig.isLockScreen" />
|
||
<ChangeRole ref="changeRoleFirRef" title="请选择角色" :require-select-to-close="true" />
|
||
</el-config-provider>
|
||
</template>
|
||
|
||
<script setup lang="ts" name="app">
|
||
import { useI18n } from 'vue-i18n';
|
||
import { useTagsViewRoutes } from '/@/stores/tagsViewRoutes';
|
||
import { useThemeConfig } from '/@/stores/themeConfig';
|
||
import other from '/@/utils/other';
|
||
import { Local, Session } from '/@/utils/storage';
|
||
import mittBus from '/@/utils/mitt';
|
||
import { needRoleSelection, isRoleDialogTriggered, setRoleDialogTriggered } from '/@/utils/roleSelect';
|
||
import setIntroduction from '/@/utils/setIconfont';
|
||
import { listAllRole } from '/@/api/admin/role';
|
||
|
||
// 引入组件
|
||
const LockScreen = defineAsyncComponent(() => import('/@/layout/lockScreen/index.vue'));
|
||
const Settings = defineAsyncComponent(() => import('./layout/navBars/breadcrumb/settings.vue'));
|
||
const CloseFull = defineAsyncComponent(() => import('/@/layout/navBars/breadcrumb/closeFull.vue'));
|
||
const ChangeRole = defineAsyncComponent(() => import('/@/views/admin/system/role/change-role.vue'));
|
||
|
||
// 定义变量内容
|
||
const { messages, locale } = useI18n();
|
||
const settingsRef = ref();
|
||
const changeRoleFirRef = ref<{ open: () => void }>();
|
||
const route = useRoute();
|
||
const stores = useTagsViewRoutes();
|
||
const storesThemeConfig = useThemeConfig();
|
||
const { themeConfig } = storeToRefs(storesThemeConfig);
|
||
|
||
// 设置锁屏时组件显示隐藏
|
||
const setLockScreen = computed(() => {
|
||
// 防止锁屏后,刷新出现不相关界面
|
||
// https://gitee.com/lyt-top/vue-next-admin/issues/I6AF8P
|
||
return themeConfig.value.isLockScreen ? themeConfig.value.lockScreenTime > 1 : themeConfig.value.lockScreenTime >= 0;
|
||
});
|
||
|
||
// 获取全局组件大小
|
||
const getGlobalComponentSize = computed(() => {
|
||
return other.globalComponentSize();
|
||
});
|
||
// 获取全局 i18n
|
||
const getGlobalI18n = computed(() => {
|
||
return messages.value[locale.value];
|
||
});
|
||
|
||
// 设置初始化,防止刷新时恢复默认
|
||
onBeforeMount(() => {
|
||
// 设置批量第三方 icon 图标
|
||
setIntroduction.cssCdn();
|
||
// 设置批量第三方 js
|
||
setIntroduction.jsCdn();
|
||
});
|
||
// 角色选择弹框是否已在本轮打开过(防止事件被触发两次)
|
||
let roleDialogOpenedThisSession = false
|
||
|
||
/** 校验缓存中的 roleId 是否仍在 listAllRole 结果中;若不存在则清除 roleId/roleCode/roleName 并返回 true(需要弹框) */
|
||
async function validateCachedRoleId(): Promise<boolean> {
|
||
const cachedRoleId = Local.get('roleId');
|
||
if (cachedRoleId == null || cachedRoleId === '') return false;
|
||
try {
|
||
const res = await listAllRole();
|
||
const data = res?.data;
|
||
const allRoles: any[] = Array.isArray(data)
|
||
? data
|
||
: data && typeof data === 'object'
|
||
? (Object.values(data) as any[]).flat()
|
||
: [];
|
||
const exists = allRoles.some(
|
||
(r: any) => r && String(r.roleId) === String(cachedRoleId)
|
||
);
|
||
if (!exists) {
|
||
Local.remove('roleId');
|
||
Local.remove('roleCode');
|
||
Local.remove('roleName');
|
||
return true;
|
||
}
|
||
return false;
|
||
} catch {
|
||
return false;
|
||
}
|
||
}
|
||
|
||
onMounted(() => {
|
||
// 唯一入口:只通过事件打开,且只打开一次;延迟打开以等待异步组件挂载
|
||
mittBus.on('openRoleSelectDialog', () => {
|
||
if (roleDialogOpenedThisSession) return
|
||
roleDialogOpenedThisSession = true
|
||
setTimeout(() => {
|
||
changeRoleFirRef.value?.open()
|
||
}, 300)
|
||
})
|
||
nextTick(async () => {
|
||
// 监听布局配置弹窗点击打开
|
||
mittBus.on('openSettingsDrawer', () => {
|
||
settingsRef.value.openDrawer();
|
||
});
|
||
// 获取缓存中的布局配置
|
||
if (Local.get('themeConfig')) {
|
||
storesThemeConfig.setThemeConfig({ themeConfig: Local.get('themeConfig') });
|
||
document.documentElement.style.cssText = Local.get('themeConfigStyle');
|
||
}
|
||
// 获取缓存中的全屏配置
|
||
if (Session.get('isTagsViewCurrenFull')) {
|
||
stores.setCurrenFullscreen(Session.get('isTagsViewCurrenFull'));
|
||
}
|
||
// 有 token 时:先校验缓存 roleId 是否仍有效,无效则清缓存并弹框选角色
|
||
if (Session.getToken()) {
|
||
const needOpenByInvalidRole = await validateCachedRoleId();
|
||
if (needOpenByInvalidRole && !isRoleDialogTriggered()) {
|
||
setRoleDialogTriggered(true);
|
||
mittBus.emit('openRoleSelectDialog');
|
||
} else if (!needOpenByInvalidRole && needRoleSelection() && !isRoleDialogTriggered()) {
|
||
setRoleDialogTriggered(true);
|
||
mittBus.emit('openRoleSelectDialog');
|
||
}
|
||
}
|
||
})
|
||
});
|
||
// 页面销毁时,关闭监听
|
||
onUnmounted(() => {
|
||
mittBus.off('openSettingsDrawer', () => {});
|
||
mittBus.off('openRoleSelectDialog');
|
||
});
|
||
// 监听路由的变化,设置网站标题
|
||
watch(
|
||
() => route.path,
|
||
() => {
|
||
other.useTitle();
|
||
},
|
||
{
|
||
deep: true,
|
||
}
|
||
);
|
||
</script>
|