| | |
| | | <template> |
| | | <view class="page-shell"> |
| | | <view class="page-shell" :class="{ landscape: isLandscapeLayout }"> |
| | | <view class="bg-glow"></view> |
| | | |
| | | <view class="header-bar"> |
| | |
| | | <slot /> |
| | | </view> |
| | | |
| | | <view class="footer-info-wrap"> |
| | | <view class="footer-info-wrap" :class="{ landscape: isLandscapeLayout }"> |
| | | <slot name="footer-info" /> |
| | | </view> |
| | | |
| | | <slot v-if="showBottomNav" name="bottom-nav" /> |
| | | <view v-if="showBottomNav" class="bottom-nav-wrap" :class="{ landscape: isLandscapeLayout }"> |
| | | <slot name="bottom-nav" /> |
| | | </view> |
| | | |
| | | <!-- 全局弹窗/遮罩插槽 --> |
| | | <slot name="overlay" /> |
| | |
| | | </template> |
| | | |
| | | <script setup> |
| | | import { onMounted, onUnmounted, ref } from 'vue'; |
| | | import titleIcon from '../../static/admin-home/PpVQg.png'; |
| | | import backArrowIcon from '../../static/admin-home/Dgd7x.png'; |
| | | |
| | |
| | | }, |
| | | }); |
| | | |
| | | const isLandscapeLayout = ref(false); |
| | | let shellWindowResizeHandler = null; |
| | | |
| | | const updateLayoutMode = () => { |
| | | try { |
| | | const windowInfo = uni.getWindowInfo ? uni.getWindowInfo() : uni.getSystemInfoSync(); |
| | | const viewportWidth = Number(windowInfo?.windowWidth || windowInfo?.screenWidth || 0); |
| | | const viewportHeight = Number(windowInfo?.windowHeight || windowInfo?.screenHeight || 0); |
| | | isLandscapeLayout.value = Boolean(viewportWidth && viewportHeight && viewportWidth > viewportHeight); |
| | | } catch (error) { |
| | | console.error('管理端外壳读取窗口尺寸失败:', error); |
| | | isLandscapeLayout.value = false; |
| | | } |
| | | }; |
| | | |
| | | const registerShellWindowResize = () => { |
| | | if (shellWindowResizeHandler || !uni.onWindowResize) { |
| | | return; |
| | | } |
| | | |
| | | shellWindowResizeHandler = () => { |
| | | updateLayoutMode(); |
| | | }; |
| | | uni.onWindowResize(shellWindowResizeHandler); |
| | | }; |
| | | |
| | | const unregisterShellWindowResize = () => { |
| | | if (!shellWindowResizeHandler || !uni.offWindowResize) { |
| | | shellWindowResizeHandler = null; |
| | | return; |
| | | } |
| | | |
| | | uni.offWindowResize(shellWindowResizeHandler); |
| | | shellWindowResizeHandler = null; |
| | | }; |
| | | |
| | | const goHome = () => { |
| | | uni.reLaunch({ |
| | | url: '/pages/home/index', |
| | | }); |
| | | }; |
| | | |
| | | onMounted(() => { |
| | | updateLayoutMode(); |
| | | registerShellWindowResize(); |
| | | }); |
| | | |
| | | onUnmounted(() => { |
| | | unregisterShellWindowResize(); |
| | | }); |
| | | </script> |
| | | |
| | | <style scoped> |
| | |
| | | flex-direction: column; |
| | | } |
| | | |
| | | .page-shell.landscape { |
| | | width: 1920px; |
| | | height: 1080px; |
| | | padding: 28px 40px 26px; |
| | | } |
| | | |
| | | .bg-glow { |
| | | position: absolute; |
| | | left: -128px; |
| | |
| | | pointer-events: none; |
| | | } |
| | | |
| | | .page-shell.landscape .bg-glow { |
| | | left: -86px; |
| | | top: 220px; |
| | | width: 420px; |
| | | height: 420px; |
| | | background: rgba(127, 177, 255, 0.16); |
| | | filter: blur(76px); |
| | | } |
| | | |
| | | .header-bar { |
| | | position: relative; |
| | | z-index: 1; |
| | |
| | | align-items: center; |
| | | justify-content: space-between; |
| | | margin-bottom: 24px; |
| | | } |
| | | |
| | | .page-shell.landscape .header-bar { |
| | | height: 96px; |
| | | margin-bottom: 18px; |
| | | } |
| | | |
| | | .title-zone { |
| | |
| | | color: #FFFFFF; |
| | | } |
| | | |
| | | .page-shell.landscape .title-zone { |
| | | gap: 14px; |
| | | } |
| | | |
| | | .page-shell.landscape .title-icon { |
| | | width: 28px; |
| | | height: 28px; |
| | | } |
| | | |
| | | .page-shell.landscape .page-title { |
| | | font-size: 38px; |
| | | } |
| | | |
| | | .back-btn { |
| | | height: 46px; |
| | | padding: 0 20px; |
| | |
| | | gap: 8px; |
| | | } |
| | | |
| | | .page-shell.landscape .back-btn { |
| | | height: 54px; |
| | | padding: 0 24px; |
| | | border-radius: 27px; |
| | | gap: 10px; |
| | | } |
| | | |
| | | .back-arrow { |
| | | width: 20px; |
| | | height: 20px; |
| | | } |
| | | |
| | | .page-shell.landscape .back-arrow { |
| | | width: 22px; |
| | | height: 22px; |
| | | } |
| | | |
| | | .back-btn-text { |
| | |
| | | font-size: 16px; |
| | | font-weight: 600; |
| | | color: #FFFFFF; |
| | | } |
| | | |
| | | .page-shell.landscape .back-btn-text { |
| | | font-size: 18px; |
| | | } |
| | | |
| | | .content-wrap { |
| | |
| | | flex: 1; |
| | | } |
| | | |
| | | .page-shell.landscape .content-wrap { |
| | | min-height: 0; |
| | | gap: 18px; |
| | | } |
| | | |
| | | .footer-info-wrap { |
| | | position: relative; |
| | | min-height: 22px; |
| | | margin-top: 24px; |
| | | } |
| | | |
| | | .page-shell.landscape .footer-info-wrap { |
| | | width: 100%; |
| | | min-height: 44px; |
| | | margin-top: 14px; |
| | | display: flex; |
| | | align-items: center; |
| | | justify-content: space-between; |
| | | } |
| | | |
| | | .bottom-nav-wrap { |
| | | width: 100%; |
| | | } |
| | | |
| | | .page-shell.landscape .bottom-nav-wrap { |
| | | display: flex; |
| | | justify-content: center; |
| | | padding-top: 10px; |
| | | } |
| | | </style> |