diff --git a/miniprogram/package.json b/miniprogram/package.json
index 744f6d0..5674bbb 100644
--- a/miniprogram/package.json
+++ b/miniprogram/package.json
@@ -12,6 +12,7 @@
"verify:startup": "node scripts/verify-venue-startup.mjs",
"verify:home-switch": "node scripts/verify-home-venue-switch.mjs",
"verify:comprehensive-auth": "node scripts/verify-comprehensive-auth-state.mjs",
+ "verify:comprehensive-session": "node scripts/verify-comprehensive-session-contract.mjs",
"verify:auth-agreements": "node scripts/verify-auth-agreements.mjs"
},
"dependencies": {
diff --git a/miniprogram/scripts/verify-comprehensive-session-contract.mjs b/miniprogram/scripts/verify-comprehensive-session-contract.mjs
new file mode 100644
index 0000000..4742895
--- /dev/null
+++ b/miniprogram/scripts/verify-comprehensive-session-contract.mjs
@@ -0,0 +1,34 @@
+import { readFileSync } from 'node:fs'
+import { fileURLToPath } from 'node:url'
+import { dirname, resolve } from 'node:path'
+
+const root = resolve(dirname(fileURLToPath(import.meta.url)), '..')
+const srcRoot = resolve(root, 'src')
+const failures = []
+
+const expectIncludes = (content, expected, label) => {
+ if (!content.includes(expected)) failures.push(`${label} is missing: ${expected}`)
+}
+
+const expectExcludes = (content, unexpected, label) => {
+ if (content.includes(unexpected)) failures.push(`${label} should not contain: ${unexpected}`)
+}
+
+const courseApi = readFileSync(resolve(srcRoot, 'modules/comprehensive/api/course.js'), 'utf8')
+const bookingApi = readFileSync(resolve(srcRoot, 'modules/comprehensive/api/booking.js'), 'utf8')
+
+expectIncludes(courseApi, "url: '/api/sessions'", 'session list endpoint')
+expectIncludes(courseApi, 'url: `/api/sessions/${id}`', 'session detail endpoint')
+expectIncludes(courseApi, 'data: { session_id: sessionId }', 'booking payload')
+expectExcludes(courseApi, "url: '/api/courses'", 'legacy course endpoint')
+expectIncludes(bookingApi, 'session_id: backendBooking.session_id', 'booking session id')
+expectIncludes(bookingApi, 'session: toBookingSession(backendBooking.session)', 'booking session mapper')
+expectExcludes(bookingApi, 'course: toBookingCourse(backendBooking.course)', 'legacy booking course')
+
+if (failures.length) {
+ console.error(`Comprehensive session contract verification failed with ${failures.length} issue(s):`)
+ for (const failure of failures) console.error(`- ${failure}`)
+ process.exit(1)
+}
+
+console.log('Comprehensive session contract verification passed.')
diff --git a/miniprogram/src/modules/comprehensive/api/booking.js b/miniprogram/src/modules/comprehensive/api/booking.js
index b0b105e..6a150b9 100644
--- a/miniprogram/src/modules/comprehensive/api/booking.js
+++ b/miniprogram/src/modules/comprehensive/api/booking.js
@@ -2,18 +2,26 @@ import { request } from './request'
import { toArray, toNumber, toPageQuery, toPagination } from './mappers'
import { toOrderBrief } from './order'
-const toBookingCourse = (backendCourse = {}) => ({
- id: backendCourse.id ?? null,
- title: backendCourse.title || '',
- cover_image: backendCourse.cover_image || '',
- coach_name: backendCourse.coach_name || '',
- start_at: backendCourse.start_at || '',
- end_at: backendCourse.end_at || '',
- capacity: toNumber(backendCourse.capacity),
- booked_count: toNumber(backendCourse.booked_count),
- remaining_count: toNumber(backendCourse.remaining_count),
- price: backendCourse.price || '0.00',
- courts: toArray(backendCourse.courts)
+const toBookingCourt = (backendCourt = {}) => ({
+ id: backendCourt.id ?? null,
+ name: backendCourt.name || '',
+ court_type: backendCourt.court_type || '',
+ court_type_label: backendCourt.court_type_label || ''
+})
+
+const toBookingSession = (backendSession = {}) => ({
+ id: backendSession.id ?? null,
+ course_id: backendSession.course_id ?? null,
+ title: backendSession.title || '',
+ cover_image: backendSession.cover_image || '',
+ coach_name: backendSession.coach_name || '',
+ start_at: backendSession.start_at || '',
+ end_at: backendSession.end_at || '',
+ capacity: toNumber(backendSession.capacity),
+ booked_count: toNumber(backendSession.booked_count),
+ remaining_count: toNumber(backendSession.remaining_count),
+ price: backendSession.price || '0.00',
+ courts: toArray(backendSession.courts).map(toBookingCourt)
})
const toPrivateCourt = (backendCourt = {}) => ({
@@ -25,7 +33,7 @@ const toPrivateCourt = (backendCourt = {}) => ({
const toCourseBooking = (backendBooking = {}) => ({
id: backendBooking.id ?? null,
- course_id: backendBooking.course_id ?? null,
+ session_id: backendBooking.session_id ?? null,
order_id: backendBooking.order_id ?? null,
status: backendBooking.status || '',
status_label: backendBooking.status_label || backendBooking.status || '',
@@ -37,7 +45,7 @@ const toCourseBooking = (backendBooking = {}) => ({
can_cancel: backendBooking.can_cancel === true,
cancel_deadline_at: backendBooking.cancel_deadline_at || null,
created_at: backendBooking.created_at || '',
- course: toBookingCourse(backendBooking.course),
+ session: toBookingSession(backendBooking.session),
order: toOrderBrief(backendBooking.order)
})
diff --git a/miniprogram/src/modules/comprehensive/api/content.js b/miniprogram/src/modules/comprehensive/api/content.js
index fa367c6..7862ede 100644
--- a/miniprogram/src/modules/comprehensive/api/content.js
+++ b/miniprogram/src/modules/comprehensive/api/content.js
@@ -1,6 +1,6 @@
import { request } from './request'
import { compactParams, toArray, toNumber, toPageQuery, toPagination } from './mappers'
-import { toCourse } from './course'
+import { toSession } from './course'
const toBanner = (backendBanner = {}) => ({
id: backendBanner.id ?? null,
@@ -22,7 +22,7 @@ const toArticle = (backendArticle = {}) => ({
const toHomeContent = (backendData = {}) => ({
banners: toArray(backendData.banners).map(toBanner),
articles: toArray(backendData.articles).map(toArticle),
- upcoming_courses: toArray(backendData.upcoming_courses).map(toCourse),
+ upcoming_courses: toArray(backendData.upcoming_courses).map(toSession),
venue: {
name: backendData.venue?.name || ''
}
diff --git a/miniprogram/src/modules/comprehensive/api/course.js b/miniprogram/src/modules/comprehensive/api/course.js
index 738f073..70bf863 100644
--- a/miniprogram/src/modules/comprehensive/api/course.js
+++ b/miniprogram/src/modules/comprehensive/api/course.js
@@ -8,27 +8,28 @@ const toCourseCourt = (backendCourt = {}) => ({
court_type_label: backendCourt.court_type_label || ''
})
-export const toCourse = (backendCourse = {}) => ({
- id: backendCourse.id ?? null,
- title: backendCourse.title || '',
- cover_image: backendCourse.cover_image || '',
- coach_id: backendCourse.coach_id ?? null,
- coach_name: backendCourse.coach_name || '',
- start_at: backendCourse.start_at || '',
- end_at: backendCourse.end_at || '',
- capacity: toNumber(backendCourse.capacity),
- booked_count: toNumber(backendCourse.booked_count),
- remaining_count: toNumber(backendCourse.remaining_count),
- price: backendCourse.price || '0.00',
- status: backendCourse.status || '',
- status_label: backendCourse.status_label || backendCourse.status || '',
- courts: toArray(backendCourse.courts).map(toCourseCourt),
- detail_html: backendCourse.detail_html || '',
- created_at: backendCourse.created_at || '',
- updated_at: backendCourse.updated_at || ''
+export const toSession = (backendSession = {}) => ({
+ id: backendSession.id ?? null,
+ course_id: backendSession.course_id ?? null,
+ title: backendSession.title || '',
+ cover_image: backendSession.cover_image || '',
+ coach_id: backendSession.coach_id ?? null,
+ coach_name: backendSession.coach_name || '',
+ start_at: backendSession.start_at || '',
+ end_at: backendSession.end_at || '',
+ capacity: toNumber(backendSession.capacity),
+ booked_count: toNumber(backendSession.booked_count),
+ remaining_count: toNumber(backendSession.remaining_count),
+ price: backendSession.price || '0.00',
+ status: backendSession.status || '',
+ status_label: backendSession.status_label || backendSession.status || '',
+ courts: toArray(backendSession.courts).map(toCourseCourt),
+ detail_html: backendSession.detail_html || '',
+ created_at: backendSession.created_at || '',
+ updated_at: backendSession.updated_at || ''
})
-const toCourseQuery = (params = {}) => compactParams({
+const toSessionQuery = (params = {}) => compactParams({
...toPageQuery(params),
date: params.date,
coach_id: params.coachId || params.coach_id,
@@ -36,22 +37,22 @@ const toCourseQuery = (params = {}) => compactParams({
})
export const courseApi = {
- getCourses(params = {}) {
+ getSessions(params = {}) {
return request({
- url: '/api/courses',
- data: toCourseQuery(params)
- }).then((data) => toPagination(data, toCourse))
+ url: '/api/sessions',
+ data: toSessionQuery(params)
+ }).then((data) => toPagination(data, toSession))
},
- getCourseDetail(id) {
+ getSessionDetail(id) {
return request({
- url: `/api/courses/${id}`
- }).then(toCourse)
+ url: `/api/sessions/${id}`
+ }).then(toSession)
},
- createCourseBooking(courseId) {
+ createCourseBooking(sessionId) {
return request({
url: '/api/bookings/course',
method: 'POST',
- data: { course_id: courseId }
+ data: { session_id: sessionId }
})
}
}
diff --git a/miniprogram/src/pages/comprehensive/bookings/course-detail.vue b/miniprogram/src/pages/comprehensive/bookings/course-detail.vue
index b2ba88a..7b7ef7a 100644
--- a/miniprogram/src/pages/comprehensive/bookings/course-detail.vue
+++ b/miniprogram/src/pages/comprehensive/bookings/course-detail.vue
@@ -6,11 +6,11 @@
-
+
- {{ booking.course.title }}
- {{ formatTimeRange(booking.course.start_at, booking.course.end_at) }}
- {{ booking.course.coach_name }} · {{ booking.course.courts.map(item => item.name).join('、') }}
+ {{ booking.session.title }}
+ {{ formatTimeRange(booking.session.start_at, booking.session.end_at) }}
+ {{ booking.session.coach_name }} · {{ booking.session.courts.map(item => item.name).join('、') }}
diff --git a/miniprogram/src/pages/comprehensive/bookings/index.vue b/miniprogram/src/pages/comprehensive/bookings/index.vue
index 83e2ddc..df50cc7 100644
--- a/miniprogram/src/pages/comprehensive/bookings/index.vue
+++ b/miniprogram/src/pages/comprehensive/bookings/index.vue
@@ -99,19 +99,19 @@ const loadItems = async () => {
}
const getItemTitle = (item) => {
- if (businessType.value === 'course') return item.course?.title || '课程预约'
+ if (businessType.value === 'course') return item.session?.title || '课程预约'
if (businessType.value === 'private') return item.courts?.map((court) => court.name).join('、') || '包场预约'
return `篮球门票 ${item.order_no}`
}
const getItemTime = (item) => {
- if (businessType.value === 'course') return formatTimeRange(item.course?.start_at, item.course?.end_at)
+ if (businessType.value === 'course') return formatTimeRange(item.session?.start_at, item.session?.end_at)
if (businessType.value === 'private') return formatTimeRange(item.start_at, item.end_at)
return item.checked_in_at ? `核销时间 ${formatDateTime(item.checked_in_at)}` : `生成时间 ${formatDateTime(item.created_at)}`
}
const getItemDesc = (item) => {
- if (businessType.value === 'course') return `${item.course?.coach_name || ''} · ${item.course?.courts?.map((court) => court.name).join('、') || ''}`
+ if (businessType.value === 'course') 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
}
diff --git a/miniprogram/src/pages/comprehensive/courses/confirm.vue b/miniprogram/src/pages/comprehensive/courses/confirm.vue
index 3d692a4..866ac65 100644
--- a/miniprogram/src/pages/comprehensive/courses/confirm.vue
+++ b/miniprogram/src/pages/comprehensive/courses/confirm.vue
@@ -1,29 +1,29 @@
-
+
- {{ course.title }}
+ {{ session.title }}
上课时间
- {{ formatTimeRange(course.start_at, course.end_at) }}
+ {{ formatTimeRange(session.start_at, session.end_at) }}
授课教练
- {{ course.coach_name }}
+ {{ session.coach_name }}
上课场地
- {{ course.courts.map(item => item.name).join('、') }}
+ {{ session.courts.map(item => item.name).join('、') }}
课程价格
- ¥{{ course.price }}
+ ¥{{ session.price }}
应付金额
- ¥{{ course.price }}
+ ¥{{ session.price }}