feat: add membership card course booking flow
This commit is contained in:
@@ -12,18 +12,24 @@
|
||||
{{ tab.label }}
|
||||
</view>
|
||||
</view>
|
||||
<view v-if="businessType === 'course'" class="sub-tabs">
|
||||
<view v-for="sub in courseSubTabs" :key="sub.value" class="sub-tab" :class="{ active: courseSubType === sub.value }" @tap="selectCourseSub(sub.value)">
|
||||
{{ sub.label }}
|
||||
</view>
|
||||
</view>
|
||||
</view>
|
||||
|
||||
<view class="list">
|
||||
<view v-for="item in bookedItems" :key="`${businessType}-${item.id}`" class="booking-card card" @tap="goDetail(item)">
|
||||
<view v-for="item in bookedItems" :key="`${businessType}-${courseSubType}-${item.id}`" class="booking-card card" @tap="goDetail(item)">
|
||||
<view class="card-top">
|
||||
<text class="item-title">{{ getItemTitle(item) }}</text>
|
||||
</view>
|
||||
<text class="item-meta primary">{{ getItemTime(item) }}</text>
|
||||
<text class="item-meta">{{ getItemDesc(item) }}</text>
|
||||
<view class="card-bottom">
|
||||
<text class="item-meta">订单金额</text>
|
||||
<text class="amount">¥{{ item.order?.amount || '--' }}</text>
|
||||
<text class="item-meta">{{ isMembershipCourse ? '次卡预约' : '订单金额' }}</text>
|
||||
<text v-if="isMembershipCourse" class="amount tag-amount">次卡预约</text>
|
||||
<text v-else class="amount">¥{{ item.order?.amount || '--' }}</text>
|
||||
</view>
|
||||
</view>
|
||||
<view v-if="!isLoading && bookedItems.length === 0" class="empty-state">暂无已预约记录</view>
|
||||
@@ -38,6 +44,7 @@
|
||||
import { computed, onMounted, ref } from 'vue'
|
||||
import { bookingApi } from '@/modules/comprehensive/api/booking'
|
||||
import { ticketApi } from '@/modules/comprehensive/api/ticket'
|
||||
import { membershipApi } from '@/modules/comprehensive/api/membership'
|
||||
import { useComprehensiveSessionStore } from '@/modules/comprehensive/stores/session'
|
||||
import { formatDateTime, formatTimeRange } from '@/modules/comprehensive/utils/date'
|
||||
import VenueTabBar from '@/components/VenueTabBar.vue'
|
||||
@@ -45,6 +52,7 @@ import UnauthLoginPanel from '@/components/UnauthLoginPanel.vue'
|
||||
|
||||
const session = useComprehensiveSessionStore()
|
||||
const businessType = ref('course')
|
||||
const courseSubType = ref('regular')
|
||||
const items = ref([])
|
||||
const isLoading = ref(false)
|
||||
|
||||
@@ -54,6 +62,13 @@ const businessTabs = [
|
||||
{ label: '门票', value: 'ticket' }
|
||||
]
|
||||
|
||||
const courseSubTabs = [
|
||||
{ label: '普通预约', value: 'regular' },
|
||||
{ label: '次卡预约', value: 'membership' }
|
||||
]
|
||||
|
||||
const isMembershipCourse = computed(() => businessType.value === 'course' && courseSubType.value === 'membership')
|
||||
|
||||
const bookedItems = computed(() => {
|
||||
return items.value.filter((item) => ['booked', 'available'].includes(item.status))
|
||||
})
|
||||
@@ -70,6 +85,12 @@ const login = async () => {
|
||||
|
||||
const selectBusiness = (value) => {
|
||||
businessType.value = value
|
||||
if (value !== 'course') courseSubType.value = 'regular'
|
||||
loadItems()
|
||||
}
|
||||
|
||||
const selectCourseSub = (value) => {
|
||||
courseSubType.value = value
|
||||
loadItems()
|
||||
}
|
||||
|
||||
@@ -77,8 +98,13 @@ const loadItems = async () => {
|
||||
isLoading.value = true
|
||||
try {
|
||||
if (businessType.value === 'course') {
|
||||
const data = await bookingApi.getCourseBookings({ page: 1, pageSize: 50 })
|
||||
items.value = data.items
|
||||
if (courseSubType.value === 'membership') {
|
||||
const data = await membershipApi.getCardBookings({ page: 1, pageSize: 50 })
|
||||
items.value = data.items
|
||||
} else {
|
||||
const data = await bookingApi.getCourseBookings({ page: 1, pageSize: 50 })
|
||||
items.value = data.items
|
||||
}
|
||||
} else if (businessType.value === 'private') {
|
||||
const data = await bookingApi.getPrivateBookings({ page: 1, pageSize: 50 })
|
||||
items.value = data.items
|
||||
@@ -111,14 +137,21 @@ const getItemTime = (item) => {
|
||||
}
|
||||
|
||||
const getItemDesc = (item) => {
|
||||
if (businessType.value === 'course') return `${item.session?.coach_name || ''} · ${item.session?.courts?.map((court) => court.name).join('、') || ''}`
|
||||
if (businessType.value === 'course') {
|
||||
if (courseSubType.value === 'membership') return `${item.session?.coach_name || ''}`
|
||||
return `${item.session?.coach_name || ''} · ${item.session?.courts?.map((court) => court.name).join('、') || ''}`
|
||||
}
|
||||
if (businessType.value === 'private') return `共 ${item.courts?.length || 0} 个场地`
|
||||
return item.status === 'available' ? '可到馆核销使用' : item.status_label
|
||||
}
|
||||
|
||||
const goDetail = (item) => {
|
||||
if (businessType.value === 'course') {
|
||||
uni.navigateTo({ url: `/pages/comprehensive/bookings/course-detail?id=${item.id}` })
|
||||
if (courseSubType.value === 'membership') {
|
||||
uni.navigateTo({ url: `/pages/comprehensive/membership/booking-detail?id=${item.id}` })
|
||||
} else {
|
||||
uni.navigateTo({ url: `/pages/comprehensive/bookings/course-detail?id=${item.id}` })
|
||||
}
|
||||
} else if (businessType.value === 'private') {
|
||||
uni.navigateTo({ url: `/pages/comprehensive/bookings/private-detail?id=${item.id}` })
|
||||
} else if (item.order_id) {
|
||||
@@ -165,6 +198,30 @@ const goDetail = (item) => {
|
||||
color: #FFFFFF;
|
||||
}
|
||||
|
||||
.sub-tabs {
|
||||
display: flex;
|
||||
gap: $spacing-sm;
|
||||
margin-top: $spacing-sm;
|
||||
}
|
||||
|
||||
.sub-tab {
|
||||
flex: 1;
|
||||
height: 56rpx;
|
||||
border-radius: $border-radius-base;
|
||||
background: $bg-color-hover;
|
||||
color: $text-color-muted;
|
||||
font-size: 24rpx;
|
||||
font-weight: 800;
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
}
|
||||
|
||||
.sub-tab.active {
|
||||
background: $color-primary;
|
||||
color: #FFFFFF;
|
||||
}
|
||||
|
||||
.list {
|
||||
padding: $spacing-md;
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user