184 lines
3.8 KiB
Vue
184 lines
3.8 KiB
Vue
|
|
<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>
|