Files
mini-yu/pages/index/index.vue

184 lines
3.8 KiB
Vue
Raw Normal View History

2026-02-10 08:05:03 +08:00
<template>
<view class="container">
<!-- 轮播图 -->
<view class="swiper-container">
<swiper
class="swiper"
:indicator-dots="true"
:autoplay="true"
:interval="3000"
:duration="500"
indicator-color="rgba(255, 255, 255, 0.5)"
indicator-active-color="#FF7A00"
>
<swiper-item v-for="(item, index) in banners" :key="index" class="swiper-item">
<image :src="item.image" class="banner-image" mode="aspectFill" lazy-load />
</swiper-item>
</swiper>
</view>
<!-- 九宫格导航 -->
<view class="grid-scroll">
<view class="grid-container">
<view
v-for="(item, index) in menuItems"
:key="item.path"
class="grid-item"
@click="navigateTo(item.path)"
>
<view class="grid-icon">{{ item.icon }}</view>
<text class="grid-text">{{ item.text }}</text>
</view>
</view>
</view>
<!-- FAB 悬浮退出登录按钮 -->
<t-fab
icon="caret-right"
aria-label="退出"
@click="logout"
/>
</view>
</template>
<script setup lang="ts">
import { ref, onMounted } from 'vue'
import { api, type User } from '@/utils/api'
const user = ref<User | null>(null)
// 轮播图数据
const banners = ref([
{ image: 'https://picsum.photos/800/400?random=1', title: '专业美容服务' },
{ image: 'https://picsum.photos/800/400?random=2', title: '预约更便捷' },
{ image: 'https://picsum.photos/800/400?random=3', title: '优惠活动' }
])
// 九宫格菜单数据
const menuItems = ref([
{ icon: '📅', text: '我要预约', path: '/pages/booking/booking' },
{ icon: '📋', text: '我的预约', path: '/pages/appointments/appointments' }
])
// 检查登录状态
onMounted(() => {
const token = uni.getStorageSync('token')
if (!token) {
uni.redirectTo({ url: '/pages/login/login' })
} else {
user.value = uni.getStorageSync('user')
}
})
// 导航跳转
const navigateTo = (path: string) => {
uni.navigateTo({ url: path })
}
// 退出登录
const logout = () => {
uni.showModal({
title: '提示',
content: '确定要退出登录吗?',
success: (res) => {
if (res.confirm) {
uni.removeStorageSync('token')
uni.removeStorageSync('user')
uni.redirectTo({ url: '/pages/login/login' })
}
}
})
}
</script>
<style scoped>
.container {
height: calc(100vh - var(--window-top));
display: flex;
flex-direction: column;
background: #f5f5f5;
overflow: hidden;
}
.welcome-section {
flex-shrink: 0;
background: linear-gradient(135deg, #FF7A00 0%, #FF9500 100%);
padding: 32rpx;
}
.welcome-text {
font-size: 36rpx;
font-weight: bold;
color: #ffffff;
}
/* 轮播图样式 */
.swiper-container {
flex-shrink: 0;
margin: 24rpx 32rpx;
border-radius: 16rpx;
overflow: hidden;
box-shadow: 0 4rpx 12rpx rgba(0, 0, 0, 0.1);
}
.swiper {
width: 100%;
height: 360rpx;
}
.swiper-item {
width: 100%;
height: 100%;
}
.banner-image {
width: 100%;
height: 100%;
background: linear-gradient(135deg, #FF7A00 0%, #FF9500 100%);
}
/* 九宫格样式 */
.grid-scroll {
flex: 1;
overflow: hidden;
}
.grid-container {
display: grid;
grid-template-columns: repeat(3, 1fr);
gap: 24rpx;
padding: 0 32rpx;
width: 100%;
align-content: center;
}
.grid-item {
display: flex;
flex-direction: column;
align-items: center;
justify-content: center;
background: #ffffff;
border-radius: 16rpx;
padding: 40rpx 20rpx;
box-shadow: 0 2rpx 12rpx rgba(0, 0, 0, 0.06);
transition: all 0.3s ease;
}
.grid-item:active {
transform: scale(0.95);
box-shadow: 0 2rpx 8rpx rgba(0, 0, 0, 0.1);
}
.grid-icon {
font-size: 64rpx;
margin-bottom: 16rpx;
}
.grid-text {
font-size: 28rpx;
color: #333;
font-weight: 500;
}
</style>