App.vue 2.1 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980
  1. <template>
  2. <router-view v-slot="{ Component }">
  3. <keep-alive :include="keepAliveIncludes">
  4. <component :is="Component" />
  5. </keep-alive>
  6. </router-view>
  7. <Login v-if="useUserInfoStore.loginShow" v-model:dialogVisible="useUserInfoStore.loginShow" />
  8. <!-- 全局唯一的设备状态弹窗,避免多页面同时挂载时重复弹出 -->
  9. <DeviceStatusDialog />
  10. </template>
  11. <script setup lang="ts">
  12. import { useRoute, useRouter } from 'vue-router'
  13. import { onMounted, onUnmounted } from 'vue'
  14. import Login from '@/components/login/index.vue';
  15. import DeviceStatusDialog from '@/components/device-status-dialog/index.vue';
  16. import useUserInfo from "@/stores/modules/user";
  17. import useDeviceStatusStore from '@/stores/modules/deviceStatus';
  18. const useUserInfoStore = useUserInfo();
  19. const deviceStatusStore = useDeviceStatusStore();
  20. import { listenerOnline } from '@/composables/online';
  21. listenerOnline();
  22. const router = useRouter()
  23. const route = useRoute()
  24. /* keep alive 的路由名称 */
  25. const keepAliveIncludes = router
  26. .getRoutes()
  27. .filter((router) => router.meta?.keepAlive)
  28. .map((router) => router.name as string)
  29. /* 监听企业过期事件 */
  30. const handleCompanyExpired = (event: CustomEvent) => {
  31. const { message } = event.detail
  32. console.log('企业过期事件触发:', message)
  33. // 如果当前不在过期页面,进行跳转
  34. if (route.path !== '/photography/expired') {
  35. console.log('跳转到过期页面')
  36. router.replace('/photography/expired')
  37. }
  38. }
  39. onMounted(() => {
  40. window.addEventListener('companyExpired', handleCompanyExpired as EventListener)
  41. // 在 App 级别初始化设备状态监听,整个会话只初始化一次
  42. deviceStatusStore.initListener();
  43. })
  44. onUnmounted(() => {
  45. window.removeEventListener('companyExpired', handleCompanyExpired as EventListener)
  46. deviceStatusStore.cleanup();
  47. })
  48. </script>
  49. <style scoped>
  50. .logo {
  51. height: 6em;
  52. padding: 1.5em;
  53. will-change: filter;
  54. transition: filter 300ms;
  55. }
  56. .logo:hover {
  57. filter: drop-shadow(0 0 2em #646cffaa);
  58. }
  59. .logo.vue:hover {
  60. filter: drop-shadow(0 0 2em #42b883aa);
  61. }
  62. </style>