b06cf69942
- 商城页改为Tab切换(储值卡/会员卡)+卡片列表,新增商品详情页 - 约课页合并会员卡/团课/门票三Tab,日期横滑选择器 - 会员卡预约新增详情页+二次确认弹窗 - 课程列表已预约状态改为后端返回booked/booking_id/booking_type - 前端移除冗余的loadBookings调用,直接读session.booked字段 - 导航栏仅首页custom,其余页面恢复原生导航栏 - membership API支持date参数筛选
191 lines
4.0 KiB
Vue
191 lines
4.0 KiB
Vue
<template>
|
|
<view class="home-container">
|
|
<view class="banner-wrapper">
|
|
<swiper
|
|
v-if="banners.length"
|
|
class="banner-swiper"
|
|
circular
|
|
autoplay
|
|
interval="4000"
|
|
duration="600"
|
|
indicator-dots
|
|
indicator-color="rgba(255, 255, 255, 0.4)"
|
|
indicator-active-color="#FFFFFF"
|
|
>
|
|
<swiper-item v-for="banner in banners" :key="banner.id">
|
|
<view class="banner-item">
|
|
<image :src="banner.image" mode="aspectFill" class="banner-img" />
|
|
</view>
|
|
</swiper-item>
|
|
</swiper>
|
|
</view>
|
|
|
|
<view class="content-wrapper">
|
|
<view class="section-container">
|
|
<view class="section-header">
|
|
<text class="section-title">公告活动</text>
|
|
</view>
|
|
|
|
<view v-if="articles.length" class="activity-grid">
|
|
<view v-for="article in articles" :key="article.id" class="activity-card" @tap="go(`/pages/comprehensive/activities/detail?id=${article.id}`)">
|
|
<image :src="article.cover_image" mode="aspectFill" class="activity-cover" />
|
|
<view class="activity-info">
|
|
<text class="activity-title">{{ article.title }}</text>
|
|
<text class="activity-date">{{ formatDate(article.published_at || article.created_at) }}</text>
|
|
</view>
|
|
</view>
|
|
</view>
|
|
<view v-else class="empty-placeholder">暂无公告活动</view>
|
|
</view>
|
|
|
|
<VenueSwitchHeader venue-name="综合场馆" />
|
|
</view>
|
|
</view>
|
|
</template>
|
|
|
|
<script setup>
|
|
import { ref, onMounted } from 'vue'
|
|
import { contentApi } from '@/modules/comprehensive/api/content'
|
|
import { formatDate } from '@/modules/comprehensive/utils/date'
|
|
import VenueSwitchHeader from '@/components/VenueSwitchHeader.vue'
|
|
|
|
const banners = ref([])
|
|
const articles = ref([])
|
|
|
|
onMounted(() => {
|
|
loadPage()
|
|
})
|
|
|
|
const loadPage = async () => {
|
|
const home = await contentApi.getHomeContent({ banner_limit: 5, article_limit: 3 })
|
|
banners.value = home.banners || []
|
|
articles.value = home.articles || []
|
|
}
|
|
|
|
const go = (url) => {
|
|
uni.navigateTo({ url })
|
|
}
|
|
|
|
defineExpose({ refresh: loadPage })
|
|
</script>
|
|
|
|
<style lang="scss" scoped>
|
|
.home-container {
|
|
min-height: 100vh;
|
|
background-color: $bg-color-soft;
|
|
}
|
|
|
|
.banner-wrapper {
|
|
width: 100%;
|
|
}
|
|
|
|
.banner-swiper {
|
|
width: 100%;
|
|
height: 33.33vh;
|
|
}
|
|
|
|
.banner-item {
|
|
position: relative;
|
|
width: 100%;
|
|
height: 100%;
|
|
}
|
|
|
|
.banner-img {
|
|
width: 100%;
|
|
height: 100%;
|
|
background-color: $bg-color-hover;
|
|
}
|
|
|
|
.content-wrapper {
|
|
padding: $spacing-lg $spacing-md;
|
|
}
|
|
|
|
.section-container {
|
|
margin-bottom: $spacing-lg;
|
|
}
|
|
|
|
.section-header {
|
|
display: flex;
|
|
align-items: center;
|
|
justify-content: space-between;
|
|
margin-bottom: $spacing-md;
|
|
padding: 0 4rpx;
|
|
}
|
|
|
|
.section-title {
|
|
position: relative;
|
|
padding-left: $spacing-sm;
|
|
color: $text-color-main;
|
|
font-size: 28rpx;
|
|
font-weight: 700;
|
|
letter-spacing: 0.5rpx;
|
|
}
|
|
|
|
.section-title::before {
|
|
content: '';
|
|
position: absolute;
|
|
left: 0;
|
|
top: 10%;
|
|
bottom: 10%;
|
|
width: 4rpx;
|
|
background-color: $text-color-main;
|
|
}
|
|
|
|
.activity-grid {
|
|
display: flex;
|
|
flex-direction: column;
|
|
gap: $spacing-sm;
|
|
}
|
|
|
|
.activity-card {
|
|
display: flex;
|
|
overflow: hidden;
|
|
border: 1rpx solid $bg-color-hover;
|
|
border-radius: $border-radius-base;
|
|
background-color: $bg-color-main;
|
|
transition: all 0.2s ease;
|
|
}
|
|
|
|
.activity-card:active {
|
|
background-color: $bg-color-hover;
|
|
}
|
|
|
|
.activity-cover {
|
|
width: 180rpx;
|
|
height: 130rpx;
|
|
background-color: $bg-color-hover;
|
|
}
|
|
|
|
.activity-info {
|
|
display: flex;
|
|
flex: 1;
|
|
flex-direction: column;
|
|
justify-content: space-between;
|
|
padding: $spacing-sm $spacing-md;
|
|
}
|
|
|
|
.activity-title {
|
|
display: block;
|
|
color: $text-color-main;
|
|
font-size: 26rpx;
|
|
font-weight: 600;
|
|
line-height: 1.3;
|
|
overflow: hidden;
|
|
display: -webkit-box;
|
|
-webkit-box-orient: vertical;
|
|
-webkit-line-clamp: 2;
|
|
}
|
|
|
|
.activity-date {
|
|
color: $text-color-light;
|
|
font-size: 20rpx;
|
|
}
|
|
|
|
.empty-placeholder {
|
|
padding: $spacing-xl 0;
|
|
color: $text-color-light;
|
|
font-size: 24rpx;
|
|
text-align: center;
|
|
}
|
|
</style>
|