完善团课前后端交互

This commit is contained in:
2026-06-15 15:49:21 +08:00
parent 96b8fd2534
commit 4e69185c48
7 changed files with 880 additions and 83 deletions
+44 -40
View File
@@ -107,7 +107,6 @@
<view class="course-tags">
<view class="tags-label">
<uni-icons type="tag" size="20" color="#8A99B4" />
<text>课程标签</text>
</view>
<view class="tags-list">
<view
@@ -212,8 +211,8 @@
<!-- 免费课程或单一支付方式 -->
<view v-else class="price-display">
<text v-if="course.storedValueAmount === 0 && course.pointCardAmount === 0" class="price free">免费</text>
<text v-else-if="course.storedValueAmount > 0" class="price">
<text v-if="Number(course.storedValueAmount) === 0 && Number(course.pointCardAmount) === 0" class="price free">免费</text>
<text v-else-if="Number(course.storedValueAmount) > 0" class="price">
<text class="currency">¥</text>{{ course.storedValueAmount }}
</text>
<text v-else class="price">
@@ -233,7 +232,7 @@
<script setup>
import { ref, computed, onMounted } from 'vue'
import { groupCourseService } from '@/request_api/groupCourse.mock.js'
import { getGroupCourseDetail, bookGroupCourse } from '@/api/groupCourse.js'
import PageHeader from '@/components/index/PageHeader.vue'
// 加载状态
@@ -305,7 +304,9 @@ const canBook = computed(() => {
// 是否有多种支付方式
const hasMultiplePayment = computed(() => {
return course.value.storedValueAmount > 0 && course.value.pointCardAmount > 0
const storedValue = Number(course.value.storedValueAmount)
const pointCard = Number(course.value.pointCardAmount)
return storedValue > 0 && pointCard > 0
})
// 当前选中的支付方式
@@ -313,17 +314,20 @@ const selectedPayment = ref('storedValue')
// 当前选中的支付方式价格显示
const selectedPrice = computed(() => {
const storedValue = Number(course.value.storedValueAmount)
const pointCard = Number(course.value.pointCardAmount)
if (selectedPayment.value === 'storedValue') {
return { type: 'storedValue', amount: course.value.storedValueAmount }
return { type: 'storedValue', amount: storedValue }
} else if (selectedPayment.value === 'pointCard') {
return { type: 'pointCard', amount: course.value.pointCardAmount }
} else if (course.value.storedValueAmount > 0 && course.value.pointCardAmount > 0) {
return { type: 'pointCard', amount: pointCard }
} else if (storedValue > 0 && pointCard > 0) {
// 默认优先显示储值卡
return { type: 'storedValue', amount: course.value.storedValueAmount }
} else if (course.value.storedValueAmount > 0) {
return { type: 'storedValue', amount: course.value.storedValueAmount }
} else if (course.value.pointCardAmount > 0) {
return { type: 'pointCard', amount: course.value.pointCardAmount }
return { type: 'storedValue', amount: storedValue }
} else if (storedValue > 0) {
return { type: 'storedValue', amount: storedValue }
} else if (pointCard > 0) {
return { type: 'pointCard', amount: pointCard }
}
return { type: 'free', amount: 0 }
})
@@ -378,20 +382,29 @@ const handleBooking = () => {
success: (res) => {
if (res.confirm) {
uni.showLoading({ title: '预约中...' })
groupCourseService.book({
bookGroupCourse({
courseId: course.value.id,
memberId: '1' // 模拟会员ID
}).then(() => {
memberId: '1', // 模拟会员ID
memberCardRecordId: '1' // 模拟会员卡记录ID
}).then((result) => {
uni.hideLoading()
uni.showToast({
title: '预约成功',
icon: 'success'
})
setTimeout(() => {
uni.navigateBack()
}, 1500)
}).catch(() => {
if (result.success) {
uni.showToast({
title: '预约成功',
icon: 'success'
})
setTimeout(() => {
uni.navigateBack()
}, 1500)
} else {
uni.showToast({
title: result.message || '预约失败',
icon: 'none'
})
}
}).catch((error) => {
uni.hideLoading()
console.error('[detail.vue] 预约失败:', error)
uni.showToast({
title: '预约失败',
icon: 'none'
@@ -405,12 +418,16 @@ const handleBooking = () => {
// 获取课程详情
const fetchCourseDetail = async (id) => {
try {
const result = await groupCourseService.getDetail(id)
console.log('[detail.vue] 开始获取课程详情, id:', id)
const result = await getGroupCourseDetail(id)
course.value = result
console.log('[detail.vue] 课程详情获取成功:', course.value)
// 获取课程类型标签
await fetchCourseLabels(course.value.courseType)
// 从完整信息中提取标签
if (result.labels && Array.isArray(result.labels)) {
courseLabels.value = result.labels
}
console.log('[detail.vue] 课程标签获取成功:', courseLabels.value)
} catch (error) {
console.error('[detail.vue] 获取课程详情失败:', error)
uni.showToast({
@@ -422,19 +439,6 @@ const fetchCourseDetail = async (id) => {
}
}
// 获取课程标签
const fetchCourseLabels = async (courseType) => {
try {
const result = await groupCourseService.getLabelsByCourseType(courseType)
if (result.code === 0) {
courseLabels.value = result.data
}
console.log('[detail.vue] 课程标签获取成功:', courseLabels.value)
} catch (error) {
console.error('[detail.vue] 获取课程标签失败:', error)
}
}
// 页面挂载时获取课程详情
onMounted(() => {
const pages = getCurrentPages()
+30 -4
View File
@@ -18,7 +18,10 @@
:time-range-text="timeRangeText"
:sort-options="sortOptions"
v-model:sort-index="sortIndex"
:course-types="courseTypes"
:current-course-type-id="courseType"
@time-pick="showTimePicker = true"
@course-type-change="onCourseTypeChange"
ref="filterSectionRef"
/>
@@ -79,7 +82,7 @@ import TimePeriodSelector from '@/components/groupCourse/TimePeriodSelector.vue'
import TimeRangePicker from '@/components/groupCourse/TimeRangePicker.vue'
import PageHeader from '@/components/index/PageHeader.vue'
import { useGroupCourseList } from '@/composables/useGroupCourseList.js'
import { getTypeLabels } from '@/api/groupCourse.js'
import { getTypeLabels, getGroupCourseTypes } from '@/api/groupCourse.js'
// 组件引用
const searchBarRef = ref(null)
@@ -97,6 +100,8 @@ const {
hasMore,
searchKeyword,
hotKeywords,
courseType,
courseTypes,
sortOptions,
sortIndex,
timePeriodOptions,
@@ -112,6 +117,8 @@ const {
handleSearch,
onTimePeriodChange,
onTimeRangeConfirm,
onCourseTypeChange,
clearCourseType,
handleBooking,
goDetail,
fetchCourseList,
@@ -122,7 +129,11 @@ const {
// 组件挂载时调用接口获取团课列表
onMounted(async () => {
console.log('[list.vue] 页面组件已挂载,开始获取团课列表')
await fetchCourseList()
// 并行获取课程类型列表和课程列表
await Promise.all([
fetchCourseTypes(),
fetchCourseList()
])
// 获取所有团课的类型标签
await fetchAllCourseTypeLabels()
console.log('[list.vue] 可用的搜索参数获取方法:')
@@ -133,9 +144,24 @@ onMounted(async () => {
console.log(' - getAllSearchParams() 获取所有参数')
})
const fetchCourseTypes = async () => {
try {
const result = await getGroupCourseTypes()
if (result && Array.isArray(result)) {
courseTypes.value = result.map(type => ({
id: type.id,
label: type.typeName
}))
console.log('[list.vue] 获取课程类型成功:', courseTypes.value)
}
} catch (error) {
console.error('[list.vue] 获取课程类型失败:', error)
}
}
const fetchAllCourseTypeLabels = async () => {
const courseTypes = [...new Set(filteredCourseList.value.map(c => c.courseType))]
for (const type of courseTypes) {
const types = [...new Set(filteredCourseList.value.map(c => c.courseType))]
for (const type of types) {
if (!courseTypeLabelsCache.value[type]) {
try {
const result = await getTypeLabels(type)