Files
gym-manage/gym-manage-uniapp/pages/groupCourse/list.vue
T

172 lines
4.1 KiB
Vue

<template>
<view class="group-course-page">
<!-- 搜索区域 -->
<view class="search-section">
<!-- 搜索框组件 -->
<SearchBar
v-model="searchKeyword"
:hot-keywords="hotKeywords"
@search="handleSearch"
ref="searchBarRef"
/>
<!-- 筛选条件组件 -->
<FilterSection
:time-range-text="timeRangeText"
:sort-options="sortOptions"
v-model:sort-index="sortIndex"
@time-pick="showTimePicker = true"
ref="filterSectionRef"
/>
<!-- 时间段选择组件 -->
<TimePeriodSelector
:time-period-options="timePeriodOptions"
v-model="timePeriodIndex"
@change="onTimePeriodChange"
ref="timePeriodRef"
/>
</view>
<!-- 团课列表 -->
<scroll-view
scroll-y
class="course-list"
@scrolltolower="onScrollToLower"
scroll-with-animation
>
<GroupCourseCard
v-for="course in filteredCourseList"
:key="course.id"
:course="course"
@booking="handleBooking"
@detail="goDetail"
></GroupCourseCard>
<!-- 加载更多提示 -->
<view class="load-more">
<text v-if="loading">加载中...</text>
<text v-else-if="!hasMore">没有更多数据了</text>
<text v-else class="load-more-text" @tap="loadMore">点击加载更多</text>
</view>
</scroll-view>
<!-- 底部导航 -->
<TabBar :active-tab="1" />
<!-- 时间选择器组件 -->
<TimeRangePicker
v-model:visible="showTimePicker"
v-model:start-date="startDate"
v-model:end-date="endDate"
@confirm="onTimeRangeConfirm"
ref="timeRangePickerRef"
/>
</view>
</template>
<script setup>
import { ref, onMounted } from 'vue'
import TabBar from '@/components/TabBar.vue'
import GroupCourseCard from '@/components/groupCourse/CourseCard.vue'
import SearchBar from '@/components/groupCourse/SearchBar.vue'
import FilterSection from '@/components/groupCourse/FilterSection.vue'
import TimePeriodSelector from '@/components/groupCourse/TimePeriodSelector.vue'
import TimeRangePicker from '@/components/groupCourse/TimeRangePicker.vue'
import { useGroupCourseList } from '@/composables/useGroupCourseList.js'
// 组件引用
const searchBarRef = ref(null)
const filterSectionRef = ref(null)
const timePeriodRef = ref(null)
const timeRangePickerRef = ref(null)
// 使用组合式函数
const {
// 状态
loading,
hasMore,
searchKeyword,
hotKeywords,
sortOptions,
sortIndex,
timePeriodOptions,
timePeriodIndex,
showTimePicker,
startDate,
endDate,
timeRangeText,
filteredCourseList,
// 方法
getAllSearchParams,
handleSearch,
onTimePeriodChange,
onTimeRangeConfirm,
handleBooking,
goDetail,
fetchCourseList,
loadMore,
onScrollToLower
} = useGroupCourseList()
// 组件挂载时调用接口获取团课列表
onMounted(() => {
console.log('[list.vue] 页面组件已挂载,开始获取团课列表')
fetchCourseList()
console.log('[list.vue] 可用的搜索参数获取方法:')
console.log(' - searchBarRef.getSearchParams()')
console.log(' - filterSectionRef.getFilterParams()')
console.log(' - timePeriodRef.getTimePeriodParams()')
console.log(' - timeRangePickerRef.getTimeRangeParams()')
console.log(' - getAllSearchParams() 获取所有参数')
})
// 暴露方法供外部调用
defineExpose({
getAllSearchParams: () => getAllSearchParams(searchBarRef.value, filterSectionRef.value, timePeriodRef.value, timeRangePickerRef.value),
searchBarRef,
filterSectionRef,
timePeriodRef,
timeRangePickerRef
})
</script>
<style lang="scss" scoped>
.group-course-page {
min-height: 100vh;
background: #F5F7FA;
}
/* 搜索区域 */
.search-section {
background: #ffffff;
padding: 24rpx;
box-shadow: 0 2rpx 12rpx rgba(0, 0, 0, 0.05);
display: flex;
flex-direction: column;
gap: 24rpx;
}
/* 课程列表 */
.course-list {
height: calc(100vh - 380rpx);
padding: 24rpx 24rpx;
padding-bottom: calc(160rpx + constant(safe-area-inset-bottom));
padding-bottom: calc(160rpx + env(safe-area-inset-bottom));
box-sizing: border-box;
}
/* 加载更多提示 */
.load-more {
text-align: center;
padding: 30rpx 0;
color: #999999;
font-size: 26rpx;
}
.load-more-text {
color: #1890ff;
}
</style>