diff --git a/miniprogram/scripts/verify-comprehensive-session-contract.mjs b/miniprogram/scripts/verify-comprehensive-session-contract.mjs index 4742895..00cfea0 100644 --- a/miniprogram/scripts/verify-comprehensive-session-contract.mjs +++ b/miniprogram/scripts/verify-comprehensive-session-contract.mjs @@ -16,6 +16,10 @@ const expectExcludes = (content, unexpected, label) => { const courseApi = readFileSync(resolve(srcRoot, 'modules/comprehensive/api/course.js'), 'utf8') const bookingApi = readFileSync(resolve(srcRoot, 'modules/comprehensive/api/booking.js'), 'utf8') +const comprehensiveHome = readFileSync(resolve(srcRoot, 'pages/comprehensive/home/index.vue'), 'utf8') +const comprehensiveContentApi = readFileSync(resolve(srcRoot, 'modules/comprehensive/api/content.js'), 'utf8') +const iceHome = readFileSync(resolve(srcRoot, 'pages/ice/home/index.vue'), 'utf8') +const iceHomeApi = readFileSync(resolve(srcRoot, 'modules/ice/api/home.js'), 'utf8') expectIncludes(courseApi, "url: '/api/sessions'", 'session list endpoint') expectIncludes(courseApi, 'url: `/api/sessions/${id}`', 'session detail endpoint') @@ -25,6 +29,15 @@ expectIncludes(bookingApi, 'session_id: backendBooking.session_id', 'booking ses expectIncludes(bookingApi, 'session: toBookingSession(backendBooking.session)', 'booking session mapper') expectExcludes(bookingApi, 'course: toBookingCourse(backendBooking.course)', 'legacy booking course') +expectExcludes(comprehensiveHome, '近期课程', 'comprehensive recent courses section') +expectExcludes(comprehensiveHome, 'upcomingCourses', 'comprehensive recent course state') +expectExcludes(comprehensiveContentApi, 'upcoming_courses', 'legacy comprehensive home mapping') +expectExcludes(comprehensiveContentApi, 'upcoming_sessions', 'unused comprehensive home mapping') +expectExcludes(iceHome, '近期课程', 'ice recent courses section') +expectExcludes(iceHome, 'upcomingCourses', 'ice recent course state') +expectExcludes(iceHomeApi, 'course_limit', 'ice recent course request') +expectExcludes(iceHomeApi, 'upcoming_courses', 'ice recent course mapping') + if (failures.length) { console.error(`Comprehensive session contract verification failed with ${failures.length} issue(s):`) for (const failure of failures) console.error(`- ${failure}`) diff --git a/miniprogram/src/modules/comprehensive/api/content.js b/miniprogram/src/modules/comprehensive/api/content.js index 7862ede..24a5ee0 100644 --- a/miniprogram/src/modules/comprehensive/api/content.js +++ b/miniprogram/src/modules/comprehensive/api/content.js @@ -1,6 +1,5 @@ import { request } from './request' import { compactParams, toArray, toNumber, toPageQuery, toPagination } from './mappers' -import { toSession } from './course' const toBanner = (backendBanner = {}) => ({ id: backendBanner.id ?? null, @@ -22,7 +21,6 @@ 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(toSession), venue: { name: backendData.venue?.name || '' } diff --git a/miniprogram/src/modules/ice/api/home.js b/miniprogram/src/modules/ice/api/home.js index 84b4f8b..ca89b42 100644 --- a/miniprogram/src/modules/ice/api/home.js +++ b/miniprogram/src/modules/ice/api/home.js @@ -1,5 +1,4 @@ import { request } from './request' -import { toCourseViewModel } from './course' const toNumber = (value) => { const numberValue = Number(value) @@ -24,9 +23,6 @@ const toActivitySummary = (backendActivity = {}) => ({ const toHomeViewModel = (backendData = {}) => ({ banners: Array.isArray(backendData.banners) ? backendData.banners.map(toBanner) : [], - upcomingCourses: Array.isArray(backendData.upcoming_courses) - ? backendData.upcoming_courses.map(toCourseViewModel) - : [], activities: Array.isArray(backendData.activities) ? backendData.activities.map(toActivitySummary) : [], venue: { name: backendData.venue?.name || '奥林匹克滑冰中心', @@ -36,13 +32,11 @@ const toHomeViewModel = (backendData = {}) => ({ export const homeApi = { getHome(options = {}) { const data = { - course_limit: options.courseLimit || 2, banner_limit: options.bannerLimit || 5 } if (options.activityLimit !== undefined) { data.activity_limit = options.activityLimit } - if (options.courseDate) data.course_date = options.courseDate return request({ url: '/api/contents/home', diff --git a/miniprogram/src/pages/comprehensive/home/index.vue b/miniprogram/src/pages/comprehensive/home/index.vue index e022cfe..02be68e 100644 --- a/miniprogram/src/pages/comprehensive/home/index.vue +++ b/miniprogram/src/pages/comprehensive/home/index.vue @@ -25,29 +25,6 @@ - - - 近期课程 - - - - - - - - {{ course.title }} - - 时间:{{ formatTimeRange(course.start_at, course.end_at) }} - - • 教练:{{ course.coach_name }} - • 人数:已约 {{ course.booked_count }}/{{ course.capacity }}人 - - - - - 今日暂无课程排期 - - 公告活动 @@ -72,12 +49,11 @@ import { ref, onMounted } from 'vue' import { onPullDownRefresh } from '@dcloudio/uni-app' import { contentApi } from '@/modules/comprehensive/api/content' -import { formatDate, formatTimeRange } from '@/modules/comprehensive/utils/date' +import { formatDate } from '@/modules/comprehensive/utils/date' import VenueTabBar from '@/components/VenueTabBar.vue' import VenueSwitchHeader from '@/components/VenueSwitchHeader.vue' const banners = ref([]) -const upcomingCourses = ref([]) const articles = ref([]) onMounted(() => { @@ -91,7 +67,6 @@ onPullDownRefresh(() => { const loadPage = async () => { const home = await contentApi.getHomeContent({ banner_limit: 5, article_limit: 3 }) banners.value = home.banners || [] - upcomingCourses.value = (home.upcoming_courses || []).slice(0, 2) articles.value = home.articles || [] } @@ -182,14 +157,12 @@ const go = (url) => { background-color: $text-color-main; } -.course-list, .activity-grid { display: flex; flex-direction: column; gap: $spacing-sm; } -.course-item, .activity-card { display: flex; overflow: hidden; @@ -199,67 +172,10 @@ const go = (url) => { transition: all 0.2s ease; } -.course-item:active, .activity-card:active { background-color: $bg-color-hover; } -.course-cover { - width: 180rpx; - height: 130rpx; - flex-shrink: 0; - background-color: $bg-color-hover; -} - -.course-info-wrap { - flex: 1; - min-width: 0; - display: flex; - flex-direction: column; - justify-content: space-between; - padding: $spacing-sm $spacing-md; -} - -.course-title-row { - display: flex; - justify-content: space-between; - gap: $spacing-sm; -} - -.course-name { - flex: 1; - 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: 1; -} - -.course-time { - color: $text-color-muted; - font-size: 22rpx; - font-weight: 500; -} - -.course-time.highlight-blue { - color: $color-primary; - font-weight: 600; -} - -.course-bottom-meta { - display: flex; - align-items: center; - gap: $spacing-xl; -} - -.course-meta-text { - color: $text-color-muted; - font-size: 22rpx; -} - .activity-cover { width: 180rpx; height: 130rpx; diff --git a/miniprogram/src/pages/ice/home/index.vue b/miniprogram/src/pages/ice/home/index.vue index 81d7138..84bd9e5 100644 --- a/miniprogram/src/pages/ice/home/index.vue +++ b/miniprogram/src/pages/ice/home/index.vue @@ -35,35 +35,6 @@ - - - - 近期课程 - - - - - - - {{ course.title }} - 时间:{{ formatCourseDate(course.start_time, course.end_time) }} - - • 教练:{{ course.coach_name }} - • 人数:已约 {{ course.booked_count }}/{{ course.capacity }}人 - - - - - 今日暂无课程排期 - - - - @@ -101,7 +72,6 @@ import StatePanel from '@/components/ice/StatePanel.vue' const todayStr = ref('') const banners = ref([]) -const upcomingCourses = ref([]) const activities = ref([]) const pageState = ref('ready') const pageMessage = ref('') @@ -122,11 +92,9 @@ onPullDownRefresh(() => { const loadHome = async () => { try { const data = await homeApi.getHome({ - courseLimit: 2, bannerLimit: 5 }) banners.value = data.banners - upcomingCourses.value = data.upcomingCourses activities.value = data.activities pageState.value = 'ready' pageMessage.value = '' @@ -148,17 +116,6 @@ const onTapBanner = (banner) => { } } -const formatCourseDate = (startStr, endStr) => { - const start = new Date(startStr) - const end = new Date(endStr) - const pad = (n) => String(n).padStart(2, '0') - const mm = pad(start.getMonth() + 1) - const dd = pad(start.getDate()) - const startHhMm = `${pad(start.getHours())}:${pad(start.getMinutes())}` - const endHhMm = `${pad(end.getHours())}:${pad(end.getMinutes())}` - return `${mm}-${dd} ${startHhMm} - ${endHhMm}` -} - const formatDate = (dateStr) => { const date = new Date(dateStr) return `${date.getFullYear()}-${String(date.getMonth() + 1).padStart(2, '0')}-${String(date.getDate()).padStart(2, '0')}` @@ -353,76 +310,6 @@ const formatDate = (dateStr) => { } } -/* 课程卡片 */ -.course-list { - display: flex; - flex-direction: column; - gap: $spacing-sm; -} - -.course-item { - display: flex; - background-color: $bg-color-main; - border-radius: $border-radius-base; - border: 1rpx solid $bg-color-hover; - overflow: hidden; - transition: all 0.2s ease; - - &:active { - background-color: $bg-color-hover; - } - - .course-cover { - width: 180rpx; - height: 130rpx; - background-color: $bg-color-hover; - flex-shrink: 0; - } - - .course-info-wrap { - flex: 1; - padding: $spacing-sm $spacing-md; - display: flex; - flex-direction: column; - justify-content: space-between; - } - - .course-name { - font-size: 26rpx; - font-weight: 600; - color: $text-color-main; - line-height: 1.3; - display: -webkit-box; - -webkit-box-orient: vertical; - -webkit-line-clamp: 1; - overflow: hidden; - } - - .course-time { - font-size: 22rpx; - color: $text-color-muted; - font-weight: 500; - - &.highlight-blue { - color: $color-primary; - font-weight: 600; - } - } - - .course-bottom-meta { - display: flex; - align-items: center; - gap: $spacing-xl; - } - - .course-meta-text { - font-size: 22rpx; - color: $text-color-muted; - display: flex; - align-items: center; - } -} - /* 极简活动卡片(两列横向拼图排版) */ .activity-grid { display: grid;