Files
workspace/code/fms/fms-vue/src/App.vue
T
2026-09-21 23:13:14 +08:00

76 lines
2.8 KiB
Vue
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.
<script setup>
import { defineAsyncComponent, onBeforeUnmount, onMounted, ref, watch } from 'vue'
import { setUIConfig } from '@/components/ui'
import { useAuthStore } from '@/stores/auth'
import { useI18nStore } from '@/stores/i18n'
import ErrorBoundary from '@/views/fallback/ErrorBoundary.vue'
import FallbackPage from '@/views/fallback/FallbackPage.vue'
// 业务应用入口:仅渲染当前路由页面
// FPS 性能监控浮层全环境挂载(生产环境同样用于现场性能排查);
// 仍走异步组件,单独分包,不进主包
const FpsMonitor = defineAsyncComponent(() => import('@/components/FpsMonitor.vue'))
// 表单布局随语言:中文横排(label 在左、控件在右,节省纵向空间),
// 其他语言标签更长,竖排(label 在上)避免 label 挤压控件。
// 写在应用根上,locale 已持久化,刷新后由 immediate 立即同步一次。
const i18nStore = useI18nStore()
const authStore = useAuthStore()
function formLayoutOf(locale) {
const isChinese = /^zh/i.test(String(locale || ''))
return isChinese ? 'horizontal' : 'vertical'
}
watch(
() => i18nStore.locale,
(locale) => {
setUIConfig({ form: { layout: formLayoutOf(locale) } })
// 译文跟着语言走:内置文案兜底,接口失败也不阻断渲染。
// 未登录(停留在登录页 / 缺省页)不发请求 —— s_i18n 需要鉴权,401 会把尚在
// 公共页面的用户一路踢到登录页(登录后的译文由路由守卫统一加载)
if (authStore.isAuthenticated) i18nStore.loadMessages(locale).catch(() => {})
},
{ immediate: true },
)
/* 离线兜底:断网时在应用上层盖一页离线缺省页,恢复后自动移除。
* 用覆盖层而非 v-if 替换 —— 原页面组件始终不卸载,断网前后的表单状态、
* 滚动位置全部保留;覆盖层 z-index 高于弹窗 / 浮层 / 提示,断网时全域可见。
* 局限:navigator.onLine 只反映本机是否连上网络,连着局域网但服务不可达不会触发。 */
const offline = ref(!navigator.onLine)
function syncOnline() {
offline.value = !navigator.onLine
}
onMounted(() => {
window.addEventListener('online', syncOnline)
window.addEventListener('offline', syncOnline)
})
onBeforeUnmount(() => {
window.removeEventListener('online', syncOnline)
window.removeEventListener('offline', syncOnline)
})
</script>
<template>
<!-- 错误边界包住整个路由视图(含布局):渲染错误就地兜 500 页,不出白屏 -->
<ErrorBoundary>
<router-view />
</ErrorBoundary>
<FpsMonitor />
<!-- 离线覆盖层:断网时盖在最上层(含弹窗 / 提示),恢复网络自动消失 -->
<FallbackPage v-if="offline" status="offline" class="fms-app-offline" />
</template>
<style lang="scss" scoped>
.fms-app-offline {
position: fixed;
inset: 0;
z-index: 5000;
}
</style>