371 lines
		
	
	
		
			5.7 KiB
		
	
	
	
		
			Vue
		
	
	
	
	
	
			
		
		
	
	
			371 lines
		
	
	
		
			5.7 KiB
		
	
	
	
		
			Vue
		
	
	
	
	
	
| <template>
 | |
|   <view id="app">
 | |
|     <!-- 全局组件可以在这里添加 -->
 | |
|   </view>
 | |
| </template>
 | |
| 
 | |
| <script>
 | |
| import { useAuthStore } from "./src/store/authStore.js";
 | |
| import { initRouteGuard } from "./src/utils/routeGuard.js";
 | |
| 
 | |
| export default {
 | |
|   globalData: {
 | |
|     isWarmStart: false,
 | |
|     userInfo: null,
 | |
|     appConfig: {},
 | |
|     isMobile: false, // 是否为移动设备
 | |
|     systemInfo: null, // 系统信息
 | |
|   },
 | |
|   onLaunch: function () {
 | |
|     console.log("App启动");
 | |
|     this.initApp();
 | |
|   },
 | |
|   onShow: function () {
 | |
|     console.log("App显示");
 | |
|   },
 | |
|   onHide: function () {
 | |
|     console.log("App隐藏");
 | |
|   },
 | |
|   methods: {
 | |
|     initApp() {
 | |
|       // 初始化应用
 | |
|       this.detectDevice();
 | |
|       this.initAuth();
 | |
|       this.initRouteGuard();
 | |
|       this.initTheme();
 | |
|     },
 | |
| 
 | |
|     initAuth() {
 | |
|       // 初始化认证状态
 | |
|       const authStore = useAuthStore();
 | |
|       authStore.initAuth();
 | |
|     },
 | |
| 
 | |
|     initRouteGuard() {
 | |
|       // 初始化路由守卫
 | |
|       initRouteGuard();
 | |
|     },
 | |
| 
 | |
|     initTheme() {
 | |
|       // 初始化主题
 | |
|       // 这里可以设置全局主题
 | |
|     },
 | |
| 
 | |
|     detectDevice() {
 | |
|       // 全局设备检测
 | |
|       try {
 | |
|         const systemInfo = uni.getSystemInfoSync();
 | |
|         this.globalData.systemInfo = systemInfo;
 | |
|         
 | |
|         // 判断是否为移动设备
 | |
|         this.globalData.isMobile = systemInfo.platform !== 'devtools' && 
 | |
|                                  (systemInfo.platform === 'ios' || 
 | |
|                                   systemInfo.platform === 'android');
 | |
|         
 | |
|         console.log('设备信息:', systemInfo);
 | |
|         console.log('是否为移动设备:', this.globalData.isMobile);
 | |
|       } catch (e) {
 | |
|         // 备用检测方案
 | |
|         const userAgent = navigator.userAgent.toLowerCase();
 | |
|         this.globalData.isMobile = /android|webos|iphone|ipad|ipod|blackberry|iemobile|opera mini/i.test(userAgent);
 | |
|         console.log('使用备用检测方案,是否为移动设备:', this.globalData.isMobile);
 | |
|       }
 | |
|     },
 | |
|   },
 | |
| };
 | |
| </script>
 | |
| 
 | |
| <style lang="scss">
 | |
| /* 引入 FontAwesome */
 | |
| @import "./static/css/all.css";
 | |
| @import "./static/css/style.scss";
 | |
| @import "./static/css/iconfont.css";
 | |
| @import "./static/css/index.css";
 | |
| 
 | |
| /* 全局样式 */
 | |
| page {
 | |
|   background-color: #f5f6fa;
 | |
|   font-family: -apple-system, BlinkMacSystemFont, "Segoe UI", "PingFang SC",
 | |
|     "Hiragino Sans GB", "Microsoft YaHei", "Helvetica Neue", Helvetica, Arial,
 | |
|     sans-serif;
 | |
| }
 | |
| 
 | |
| /* 通用样式类 */
 | |
| .container {
 | |
|   padding: 30rpx;
 | |
| }
 | |
| 
 | |
| .section {
 | |
|   margin-bottom: 40rpx;
 | |
| }
 | |
| 
 | |
| .section-title {
 | |
|   font-size: 32rpx;
 | |
|   font-weight: 600;
 | |
|   color: #333;
 | |
|   margin-bottom: 20rpx;
 | |
| }
 | |
| 
 | |
| .card {
 | |
|   background: #fff;
 | |
|   border-radius: 16rpx;
 | |
|   padding: 30rpx;
 | |
|   box-shadow: 0 2rpx 12rpx rgba(0, 0, 0, 0.08);
 | |
| }
 | |
| 
 | |
| .btn {
 | |
|   display: flex;
 | |
|   align-items: center;
 | |
|   justify-content: center;
 | |
|   padding: 20rpx 40rpx;
 | |
|   border-radius: 12rpx;
 | |
|   font-size: 28rpx;
 | |
|   font-weight: 500;
 | |
|   border: none;
 | |
|   outline: none;
 | |
|   cursor: pointer;
 | |
|   transition: all 0.3s ease;
 | |
| }
 | |
| 
 | |
| .btn-primary {
 | |
|   background: linear-gradient(135deg, #2b7ce9 0%, #1e5f99 100%);
 | |
|   color: #fff;
 | |
| }
 | |
| 
 | |
| .btn-primary:active {
 | |
|   transform: scale(0.98);
 | |
|   opacity: 0.9;
 | |
| }
 | |
| 
 | |
| .btn-secondary {
 | |
|   background: #f5f6fa;
 | |
|   color: #666;
 | |
|   border: 1rpx solid #e0e0e0;
 | |
| }
 | |
| 
 | |
| .btn-secondary:active {
 | |
|   background: #e8e8e8;
 | |
| }
 | |
| 
 | |
| .text-primary {
 | |
|   color: #2b7ce9;
 | |
| }
 | |
| 
 | |
| .text-secondary {
 | |
|   color: #666;
 | |
| }
 | |
| 
 | |
| .text-muted {
 | |
|   color: #999;
 | |
| }
 | |
| 
 | |
| .text-success {
 | |
|   color: #4ecdc4;
 | |
| }
 | |
| 
 | |
| .text-warning {
 | |
|   color: #feca57;
 | |
| }
 | |
| 
 | |
| .text-danger {
 | |
|   color: #ff6b6b;
 | |
| }
 | |
| 
 | |
| .flex {
 | |
|   display: flex;
 | |
| }
 | |
| 
 | |
| .flex-center {
 | |
|   display: flex;
 | |
|   align-items: center;
 | |
|   justify-content: center;
 | |
| }
 | |
| 
 | |
| .flex-between {
 | |
|   display: flex;
 | |
|   align-items: center;
 | |
|   justify-content: space-between;
 | |
| }
 | |
| 
 | |
| .flex-column {
 | |
|   display: flex;
 | |
|   flex-direction: column;
 | |
| }
 | |
| 
 | |
| .flex-1 {
 | |
|   flex: 1;
 | |
| }
 | |
| 
 | |
| .text-center {
 | |
|   text-align: center;
 | |
| }
 | |
| 
 | |
| .text-left {
 | |
|   text-align: left;
 | |
| }
 | |
| 
 | |
| .text-right {
 | |
|   text-align: right;
 | |
| }
 | |
| 
 | |
| .mt-10 {
 | |
|   margin-top: 10rpx;
 | |
| }
 | |
| .mt-20 {
 | |
|   margin-top: 20rpx;
 | |
| }
 | |
| .mt-30 {
 | |
|   margin-top: 30rpx;
 | |
| }
 | |
| .mt-40 {
 | |
|   margin-top: 40rpx;
 | |
| }
 | |
| 
 | |
| .mb-10 {
 | |
|   margin-bottom: 10rpx;
 | |
| }
 | |
| .mb-20 {
 | |
|   margin-bottom: 20rpx;
 | |
| }
 | |
| .mb-30 {
 | |
|   margin-bottom: 30rpx;
 | |
| }
 | |
| .mb-40 {
 | |
|   margin-bottom: 40rpx;
 | |
| }
 | |
| 
 | |
| .ml-10 {
 | |
|   margin-left: 10rpx;
 | |
| }
 | |
| .ml-20 {
 | |
|   margin-left: 20rpx;
 | |
| }
 | |
| .ml-30 {
 | |
|   margin-left: 30rpx;
 | |
| }
 | |
| 
 | |
| .mr-10 {
 | |
|   margin-right: 10rpx;
 | |
| }
 | |
| .mr-20 {
 | |
|   margin-right: 20rpx;
 | |
| }
 | |
| .mr-30 {
 | |
|   margin-right: 30rpx;
 | |
| }
 | |
| 
 | |
| .p-10 {
 | |
|   padding: 10rpx;
 | |
| }
 | |
| .p-20 {
 | |
|   padding: 20rpx;
 | |
| }
 | |
| .p-30 {
 | |
|   padding: 30rpx;
 | |
| }
 | |
| 
 | |
| .pt-10 {
 | |
|   padding-top: 10rpx;
 | |
| }
 | |
| .pt-20 {
 | |
|   padding-top: 20rpx;
 | |
| }
 | |
| .pt-30 {
 | |
|   padding-top: 30rpx;
 | |
| }
 | |
| 
 | |
| .pb-10 {
 | |
|   padding-bottom: 10rpx;
 | |
| }
 | |
| .pb-20 {
 | |
|   padding-bottom: 20rpx;
 | |
| }
 | |
| .pb-30 {
 | |
|   padding-bottom: 30rpx;
 | |
| }
 | |
| 
 | |
| .pl-10 {
 | |
|   padding-left: 10rpx;
 | |
| }
 | |
| .pl-20 {
 | |
|   padding-left: 20rpx;
 | |
| }
 | |
| .pl-30 {
 | |
|   padding-left: 30rpx;
 | |
| }
 | |
| 
 | |
| .pr-10 {
 | |
|   padding-right: 10rpx;
 | |
| }
 | |
| .pr-20 {
 | |
|   padding-right: 20rpx;
 | |
| }
 | |
| .pr-30 {
 | |
|   padding-right: 30rpx;
 | |
| }
 | |
| 
 | |
| /* 滚动条样式 */
 | |
| ::-webkit-scrollbar {
 | |
|   width: 0;
 | |
|   background: transparent;
 | |
| }
 | |
| 
 | |
| /* 安全区域适配 */
 | |
| .safe-area-top {
 | |
|   padding-top: constant(safe-area-inset-top);
 | |
|   padding-top: env(safe-area-inset-top);
 | |
| }
 | |
| 
 | |
| .safe-area-bottom {
 | |
|   padding-bottom: constant(safe-area-inset-bottom);
 | |
|   padding-bottom: env(safe-area-inset-bottom);
 | |
| }
 | |
| 
 | |
| /* 动画 */
 | |
| .fade-in {
 | |
|   animation: fadeIn 0.3s ease-in-out;
 | |
| }
 | |
| 
 | |
| @keyframes fadeIn {
 | |
|   from {
 | |
|     opacity: 0;
 | |
|     transform: translateY(20rpx);
 | |
|   }
 | |
|   to {
 | |
|     opacity: 1;
 | |
|     transform: translateY(0);
 | |
|   }
 | |
| }
 | |
| 
 | |
| .slide-in-right {
 | |
|   animation: slideInRight 0.3s ease-out;
 | |
| }
 | |
| 
 | |
| @keyframes slideInRight {
 | |
|   from {
 | |
|     opacity: 0;
 | |
|     transform: translateX(100%);
 | |
|   }
 | |
|   to {
 | |
|     opacity: 1;
 | |
|     transform: translateX(0);
 | |
|   }
 | |
| }
 | |
| 
 | |
| /* 响应式设计 */
 | |
| @media screen and (max-width: 750rpx) {
 | |
|   .container {
 | |
|     padding: 20rpx;
 | |
|   }
 | |
| 
 | |
|   .section {
 | |
|     margin-bottom: 30rpx;
 | |
|   }
 | |
| 
 | |
|   .section-title {
 | |
|     font-size: 28rpx;
 | |
|     margin-bottom: 15rpx;
 | |
|   }
 | |
| }
 | |
| </style>
 |