文件
shanghaipeiwan/pwuniapp/App.vue

323 行
10 KiB
Vue

此文件含有模棱两可的 Unicode 字符

此文件含有可能会与其他字符混淆的 Unicode 字符。 如果您是想特意这样的,可以安全地忽略该警告。 使用 Escape 按钮显示他们。

<script>
import { getCurrentThemeKey, applyThemeToNativeUI } from './common/theme.js';
import { installRoleGuard } from './common/role.js';
export default {
onLaunch: function () {
// #ifdef H5
if (typeof window !== 'undefined' && window.addEventListener) {
window.addEventListener('unhandledrejection', (event) => {
const reason = event && event.reason;
const errMsg = reason && (reason.errMsg || reason.message || '');
if (
typeof errMsg === 'string' && (
errMsg.includes('setNavigationBarColor') ||
errMsg.includes('setTabBarStyle') ||
errMsg.includes('hideTabBar') ||
errMsg.includes('not tabBar page') ||
errMsg.includes('page not found')
)
) {
event.preventDefault();
}
});
}
// #endif
// #ifdef MP-WEIXIN
if (typeof wx !== 'undefined' && wx.onUnhandledRejection) {
wx.onUnhandledRejection((event) => {
const reason = event && event.reason;
const errMsg = (reason && (reason.errMsg || reason.message)) || (typeof reason === 'string' ? reason : '');
if (
typeof errMsg === 'string' && (
errMsg.includes('hideTabBar') ||
errMsg.includes('not TabBar page') ||
errMsg.includes('setNavigationBarColor') ||
errMsg.includes('setTabBarStyle')
)
) {
// 自定义 TabBar 场景下,对非原生 TabBar 页面尝试隐藏 TabBar 的报错静默兜底
return;
}
});
}
// #endif
const currentTheme = getCurrentThemeKey();
applyThemeToNativeUI(currentTheme);
// 注册全流程角色权限守卫拦截器 (Role Guard)
installRoleGuard();
// 注册全局路由切换拦截器,在跳转目标页面前预先同步 Native 导航栏与窗口背景,消除切页黑屏闪烁
const routeMethods = ['navigateTo', 'redirectTo', 'reLaunch', 'switchTab'];
routeMethods.forEach((method) => {
try {
if (typeof uni !== 'undefined' && typeof uni.addInterceptor === 'function') {
uni.addInterceptor(method, {
invoke() {
applyThemeToNativeUI(getCurrentThemeKey());
}
});
}
} catch (e) {}
});
console.log('App Launch: 电竞陪玩小程序初始化, 当前主题:', currentTheme);
},
onShow: function () {
const currentTheme = getCurrentThemeKey();
applyThemeToNativeUI(currentTheme);
},
onHide: function () {
console.log('App Hide');
},
};
</script>
<style lang="scss">
/* 双主题 Design Tokens (CSS Variables 全局动态驱动) */
:root, page {
--bg-primary: #0A0F1D;
--bg-surface: #151D30;
--bg-surface-elevated: #1E2942;
--bg-surface-glass: rgba(21, 29, 48, 0.85);
--color-brand: #6366F1;
--color-brand-light: #818CF8;
--color-brand-gold: #F59E0B;
--color-brand-glow: rgba(99, 102, 241, 0.35);
--color-brand-gradient: linear-gradient(135deg, #6366F1, #8B5CF6);
--border-subtle: #1E293B;
--border-focus: #4F46E5;
--text-primary: #F8FAFC;
--text-secondary: #94A3B8;
--text-muted: #64748B;
--shadow-brand: 0 8rpx 24rpx rgba(99, 102, 241, 0.35);
--nav-bg: #0A0F1D;
--nav-color: #F8FAFC;
--tab-bg: #151D30;
--tab-color: #94A3B8;
--tab-active: #6366F1;
/* 顶部与多端安全区变量 (小程序状态栏 / 原生胶囊避让 / H5 沉浸式自然留白) */
--safe-header-gap: calc(var(--status-bar-height, 0px) + 36rpx);
--capsule-right-space: 0rpx;
--capsule-height: 72rpx;
/* #ifdef MP-WEIXIN */
/* 微信小程序端静态 CSS 兜底:状态栏加上胶囊行对齐留白 (避开灵动岛与状态栏遮挡) */
--safe-header-gap: calc(var(--status-bar-height, 25px) + 58rpx);
--capsule-right-space: 210rpx;
--capsule-height: 64rpx;
/* #endif */
}
/* 浅色暖阳晨曦主题 (Light Warm Sunset Morning) */
page:has(.theme-warm), page.theme-warm, .theme-warm {
--bg-primary: #FDFBF7;
--bg-surface: #FFFFFF;
--bg-surface-elevated: #F8F5F0;
--bg-surface-glass: rgba(255, 255, 255, 0.90);
--color-brand: #EA580C;
--color-brand-light: #F97316;
--color-brand-gold: #F59E0B;
--color-brand-glow: rgba(234, 88, 12, 0.18);
--color-brand-gradient: linear-gradient(135deg, #F97316, #FB923C);
--border-subtle: #F0ECE4;
--border-focus: #EA580C;
--text-primary: #1C1917;
--text-secondary: #57534E;
--text-muted: #78716C;
--shadow-brand: 0 8rpx 24rpx rgba(234, 88, 12, 0.25);
--nav-bg: #FDFBF7;
--nav-color: #1C1917;
--tab-bg: #FFFFFF;
--tab-color: #78716C;
--tab-active: #EA580C;
background-color: #FDFBF7;
color: #1C1917;
}
page:has(.theme-warm) {
background-color: #FDFBF7 !important;
}
/* 全局暗黑电竞基础重置 (严格符合 UI/UX Pro Max 规范) */
page {
background-color: var(--bg-primary, #0A0F1D);
color: var(--text-primary, #F8FAFC);
font-family: -apple-system, BlinkMacSystemFont, 'Segoe UI', Roboto, 'Helvetica Neue', Arial, 'PingFang SC', sans-serif;
box-sizing: border-box;
-webkit-font-smoothing: antialiased;
-webkit-tap-highlight-color: transparent;
}
view, text, image, input, button {
box-sizing: border-box;
}
/* 触控交互微反馈:80-120ms 弹性缩放,无布局位移 (CLS < 0.1) */
.btn-active:active, .card-active:active {
transform: scale(0.975);
opacity: 0.88;
transition: transform 100ms cubic-bezier(0.2, 0.8, 0.2, 1), opacity 100ms ease-out;
}
/* 纯数字等宽排版 (避免金额、核销码、倒计时跳动) */
.tabular-num {
font-variant-numeric: tabular-nums;
font-feature-settings: "tnum";
}
/* 隐藏移动端原生滚动条 */
::-webkit-scrollbar {
display: none;
width: 0;
height: 0;
color: transparent;
}
/* 移动端与 H5 响应式体验优化 */
/* #ifdef H5 */
html, body {
background-color: #0A0F1D;
margin: 0;
padding: 0;
-webkit-tap-highlight-color: transparent;
touch-action: manipulation;
}
/* 在 PC 宽屏上以 iPhone 15 Pro 仿真机壳居中展示,兼顾专业质感 */
@media screen and (min-width: 481px) {
html, body {
background-color: #050811 !important;
transition: background-color 0.3s ease;
}
body:has(.theme-warm) {
background-color: #EDE8E0 !important;
}
uni-app {
max-width: 450px !important;
margin: 20px auto !important;
min-height: calc(100vh - 40px) !important;
box-shadow: 0 0 60rpx rgba(0, 0, 0, 0.4), 0 0 0 2rpx var(--color-brand-glow, rgba(99, 102, 241, 0.25)) !important;
border-radius: 40rpx !important;
overflow: hidden !important;
position: relative !important;
background-color: var(--bg-primary, #0A0F1D) !important;
}
uni-page-head, .uni-page-head {
max-width: 450px !important;
left: 0 !important;
right: 0 !important;
margin: 0 auto !important;
top: 20px !important;
border-top-left-radius: 40rpx !important;
border-top-right-radius: 40rpx !important;
overflow: hidden !important;
}
uni-tabbar, .uni-tabbar {
position: fixed !important;
bottom: 20px !important;
left: 0 !important;
right: 0 !important;
margin: 0 auto !important;
max-width: 450px !important;
width: 100% !important;
z-index: 9999 !important;
border-bottom-left-radius: 40rpx !important;
border-bottom-right-radius: 40rpx !important;
overflow: hidden !important;
}
}
/* 在手机移动浏览器上 100% 原生沉浸贴合,适配动态视口与底部安全区 */
@media screen and (max-width: 480px) {
uni-app {
width: 100% !important;
min-height: 100vh !important;
min-height: 100dvh !important;
}
uni-tabbar, .uni-tabbar {
position: fixed !important;
bottom: 0 !important;
left: 0 !important;
right: 0 !important;
width: 100% !important;
z-index: 9999 !important;
padding-bottom: env(safe-area-inset-bottom) !important;
}
}
uni-tabbar .uni-tabbar__bd {
background-color: var(--tab-bg, var(--bg-surface, #151D30)) !important;
border-top: 1px solid var(--border-subtle, rgba(255, 255, 255, 0.08)) !important;
transition: background-color 0.2s ease;
}
/* 顶部导航栏 (H5 端 uni-page-head 动态浅色/暗黑主题自适应) */
uni-page-head, .uni-page-head {
background-color: var(--nav-bg, var(--bg-primary, #0A0F1D)) !important;
color: var(--nav-color, var(--text-primary, #F8FAFC)) !important;
border-bottom: 1px solid var(--border-subtle, rgba(255, 255, 255, 0.08)) !important;
transition: background-color 0.2s ease, color 0.2s ease;
}
uni-page-head .uni-page-head__title {
color: var(--nav-color, var(--text-primary, #F8FAFC)) !important;
}
/* 浅色暖阳晨曦模式下强制确保 TabBar 与 PageHead 呈现高质感浅色 */
body:has(.theme-warm) uni-page-head,
body:has(.theme-warm) .uni-page-head,
page.theme-warm ~ uni-page-head,
.theme-warm uni-page-head {
background-color: #FDFBF7 !important;
border-bottom: 1px solid #F0ECE4 !important;
}
body:has(.theme-warm) uni-page-head .uni-page-head__title,
body:has(.theme-warm) .uni-page-head .uni-page-head__title,
page.theme-warm ~ uni-page-head .uni-page-head__title,
.theme-warm uni-page-head .uni-page-head__title,
body:has(.theme-warm) uni-page-head *,
.theme-warm uni-page-head * {
color: #1C1917 !important;
}
body:has(.theme-warm) uni-tabbar .uni-tabbar__bd,
page.theme-warm ~ uni-tabbar .uni-tabbar__bd,
.theme-warm ~ uni-tabbar .uni-tabbar__bd {
background-color: #FFFFFF !important;
border-top: 1px solid #F0ECE4 !important;
box-shadow: 0 -4rpx 20rpx rgba(28, 25, 23, 0.04) !important;
}
body:has(.theme-warm) uni-tabbar .uni-tabbar__label,
page.theme-warm ~ uni-tabbar .uni-tabbar__label,
body:has(.theme-warm) uni-tabbar span {
color: #78716C !important;
font-size: 13px !important;
font-weight: 500 !important;
}
body:has(.theme-warm) uni-tabbar .uni-tabbar-item.active .uni-tabbar__label,
page.theme-warm ~ uni-tabbar .uni-tabbar-item.active .uni-tabbar__label,
body:has(.theme-warm) uni-tabbar .uni-tabbar__item.active .uni-tabbar__label,
page.theme-warm ~ uni-tabbar .uni-tabbar__item.active .uni-tabbar__label,
body:has(.theme-warm) uni-tabbar .active .uni-tabbar__label,
body:has(.theme-warm) uni-tabbar [class*="active"] .uni-tabbar__label,
body:has(.theme-warm) uni-tabbar [class*="active"] span {
color: #EA580C !important;
font-weight: 700 !important;
}
/* #endif */
</style>