From b06cf699428079ca190062e0d8363f79a2e3f2e1 Mon Sep 17 00:00:00 2001
From: gqt <3217233537@qq.com>
Date: Mon, 13 Jul 2026 20:37:31 +0800
Subject: [PATCH] =?UTF-8?q?feat:=20=E5=95=86=E5=9F=8E=E6=94=B9=E7=89=88?=
=?UTF-8?q?=E3=80=81=E7=BA=A6=E8=AF=BE=E9=A1=B5=E5=90=88=E5=B9=B6=E4=B8=89?=
=?UTF-8?q?Tab=E3=80=81=E8=AF=BE=E7=A8=8B=E5=B7=B2=E9=A2=84=E7=BA=A6?=
=?UTF-8?q?=E7=8A=B6=E6=80=81=E5=90=8E=E7=AB=AF=E6=B3=A8=E5=85=A5?=
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit
- 商城页改为Tab切换(储值卡/会员卡)+卡片列表,新增商品详情页
- 约课页合并会员卡/团课/门票三Tab,日期横滑选择器
- 会员卡预约新增详情页+二次确认弹窗
- 课程列表已预约状态改为后端返回booked/booking_id/booking_type
- 前端移除冗余的loadBookings调用,直接读session.booked字段
- 导航栏仅首页custom,其余页面恢复原生导航栏
- membership API支持date参数筛选
---
miniprogram/.env | 4 +-
miniprogram/src/App.vue | 1 -
.../src/modules/comprehensive/api/course.js | 3 +
.../modules/comprehensive/api/membership.js | 12 +-
miniprogram/src/pages.json | 14 +-
.../src/pages/comprehensive/courses/index.vue | 506 ++++++++++++++----
.../courses/membership-detail.vue | 352 ++++++++++++
.../src/pages/comprehensive/home/index.vue | 1 -
.../src/pages/comprehensive/mall/detail.vue | 195 +++++++
.../src/pages/comprehensive/mall/index.vue | 230 +++-----
miniprogram/src/pages/ice/home/index.vue | 1 -
11 files changed, 1063 insertions(+), 256 deletions(-)
create mode 100644 miniprogram/src/pages/comprehensive/courses/membership-detail.vue
create mode 100644 miniprogram/src/pages/comprehensive/mall/detail.vue
diff --git a/miniprogram/.env b/miniprogram/.env
index b890dc6..42285b5 100644
--- a/miniprogram/.env
+++ b/miniprogram/.env
@@ -1,2 +1,2 @@
-VITE_ICE_API_BASE_URL=https://venue.test.chatgqt.top
-VITE_COMPREHENSIVE_API_BASE_URL=https://venue2.test.chatgqt.top
+VITE_ICE_API_BASE_URL=https://8002.frp.chatgqt.top
+VITE_COMPREHENSIVE_API_BASE_URL=https://8002.frp.chatgqt.top
\ No newline at end of file
diff --git a/miniprogram/src/App.vue b/miniprogram/src/App.vue
index 4b92b52..5943dd9 100644
--- a/miniprogram/src/App.vue
+++ b/miniprogram/src/App.vue
@@ -21,7 +21,6 @@ page {
line-height: 1.5;
box-sizing: border-box;
-webkit-text-size-adjust: 100%;
- padding-top: var(--status-bar-height, 0px);
}
view,
diff --git a/miniprogram/src/modules/comprehensive/api/course.js b/miniprogram/src/modules/comprehensive/api/course.js
index 70bf863..63fe995 100644
--- a/miniprogram/src/modules/comprehensive/api/course.js
+++ b/miniprogram/src/modules/comprehensive/api/course.js
@@ -25,6 +25,9 @@ export const toSession = (backendSession = {}) => ({
status_label: backendSession.status_label || backendSession.status || '',
courts: toArray(backendSession.courts).map(toCourseCourt),
detail_html: backendSession.detail_html || '',
+ booked: backendSession.booked === true,
+ booking_id: backendSession.booking_id ?? null,
+ booking_type: backendSession.booking_type || null,
created_at: backendSession.created_at || '',
updated_at: backendSession.updated_at || ''
})
diff --git a/miniprogram/src/modules/comprehensive/api/membership.js b/miniprogram/src/modules/comprehensive/api/membership.js
index 320e849..3e4d76b 100644
--- a/miniprogram/src/modules/comprehensive/api/membership.js
+++ b/miniprogram/src/modules/comprehensive/api/membership.js
@@ -1,5 +1,5 @@
import { request } from './request'
-import { toArray, toNumber, toPageQuery, toPagination } from './mappers'
+import { toArray, toNumber, toPageQuery, toPagination, compactParams } from './mappers'
import { toOrderBrief } from './order'
const toPlan = (item = {}) => ({
@@ -51,7 +51,10 @@ const toAvailableSession = (backendSession = {}) => ({
booked_count: toNumber(backendSession.booked_count),
remaining_count: toNumber(backendSession.remaining_count),
price: backendSession.price || '0.00',
- available_card_ids: toArray(backendSession.available_card_ids).map(toNumber)
+ available_card_ids: toArray(backendSession.available_card_ids).map(toNumber),
+ booked: backendSession.booked === true,
+ booking_id: backendSession.booking_id ?? null,
+ booking_type: backendSession.booking_type || null
})
const toCardBookingSession = (backendSession = {}) => ({
@@ -116,7 +119,10 @@ export const membershipApi = {
getAvailableSessions(params = {}) {
return request({
url: '/api/membership/available-courses',
- data: toPageQuery(params)
+ data: compactParams({
+ ...toPageQuery(params),
+ date: params.date
+ })
}).then((data) => toPagination(data, toAvailableSession))
},
createCardBooking({ cardId, sessionId }) {
diff --git a/miniprogram/src/pages.json b/miniprogram/src/pages.json
index c35d829..58d514b 100644
--- a/miniprogram/src/pages.json
+++ b/miniprogram/src/pages.json
@@ -20,6 +20,7 @@
"path": "pages/home/index",
"style": {
"navigationBarTitleText": "首页",
+ "navigationStyle": "custom",
"enablePullDownRefresh": true
}
},
@@ -92,6 +93,12 @@
"navigationBarTitleText": "课程详情"
}
},
+ {
+ "path": "pages/comprehensive/courses/membership-detail",
+ "style": {
+ "navigationBarTitleText": "次卡预约"
+ }
+ },
{
"path": "pages/comprehensive/courses/confirm",
"style": {
@@ -174,6 +181,12 @@
"enablePullDownRefresh": true
}
},
+ {
+ "path": "pages/comprehensive/mall/detail",
+ "style": {
+ "navigationBarTitleText": "商品详情"
+ }
+ },
{
"path": "pages/comprehensive/membership/cards",
"style": {
@@ -317,7 +330,6 @@
]
},
"globalStyle": {
- "navigationStyle": "custom",
"navigationBarTextStyle": "black",
"navigationBarBackgroundColor": "#FFFFFF",
"backgroundColor": "#F8FAFC",
diff --git a/miniprogram/src/pages/comprehensive/courses/index.vue b/miniprogram/src/pages/comprehensive/courses/index.vue
index 2a93d7a..95f7aee 100644
--- a/miniprogram/src/pages/comprehensive/courses/index.vue
+++ b/miniprogram/src/pages/comprehensive/courses/index.vue
@@ -1,86 +1,158 @@
-
-
-
- 日期
- {{ selectedDate || '全部日期' }}
-
-
-
-
- 教练
- {{ selectedCoachName }}
-
-
-
-
- 类型
- {{ selectedCourtTypeLabel }}
-
-
-
+
-
-
-
-
-
- {{ session.title }}
-
- {{ formatTimeRange(session.start_at, session.end_at) }}
- {{ session.coach_name }}
-
- 已约 {{ session.booked_count }}/{{ session.capacity }}
- ¥{{ session.price }}
-
-
+
+
+ 会员卡
+ 团课
+ 门票
- 加载中...
- 当前筛选条件下暂无课程
- 已加载全部
-
+
+
+
+
+
+ 篮球门票
+ 购买后进入会员权益账户,到馆由前台核销。
+
+
+
+ ¥{{ ticketProduct.unit_price }}
+ / 次
+
+
+
+
+ 购买次数
+
+
+ {{ ticketQty }}
+
+
+
+ 合计金额
+ ¥{{ ticketTotal }}
+
+
+
+
+
+ 合计
+ ¥{{ ticketTotal }}
+
+
+
+
+ 加载中...
+
+
+
+
+
+
+ {{ d.label }}
+ {{ d.date }}
+
+
+
+
+
+
+
+
+
+ {{ item.title }}
+ 已预约
+
+ {{ formatTimeRange(item.start_at, item.end_at) }}
+ {{ item.coach_name }}
+
+ 剩余 {{ item.remaining_count }}/{{ item.capacity }}
+ ¥{{ item.price }}
+
+
+
+
+ 加载中...
+ 当天暂无课程
+
+
+
@@ -142,35 +273,93 @@ defineExpose({ refresh, loadMore })
background: $bg-color-soft;
}
-.filter-bar {
+.tab-bar {
position: sticky;
top: 0;
z-index: 10;
- display: grid;
- grid-template-columns: repeat(3, 1fr);
- height: 94rpx;
+ display: flex;
+ height: 88rpx;
background: $bg-color-main;
border-bottom: 1rpx solid $border-color;
}
-.filter-inner {
- height: 94rpx;
+.tab-item {
+ flex: 1;
+ display: flex;
+ align-items: center;
+ justify-content: center;
+ font-size: 28rpx;
+ font-weight: 700;
+ color: $text-color-muted;
+ transition: all 0.2s ease;
+}
+
+.tab-item.active {
+ color: $text-color-main;
+ font-weight: 900;
+ position: relative;
+}
+
+.tab-item.active::after {
+ content: '';
+ position: absolute;
+ bottom: 0;
+ left: 50%;
+ transform: translateX(-50%);
+ width: 48rpx;
+ height: 4rpx;
+ border-radius: 2rpx;
+ background: $text-color-main;
+}
+
+.date-bar {
+ position: sticky;
+ top: 88rpx;
+ z-index: 9;
+ background: $bg-color-main;
+ border-bottom: 1rpx solid $border-color;
+ white-space: nowrap;
+}
+
+.date-list {
+ display: inline-flex;
+ padding: $spacing-sm $spacing-xs;
+ gap: $spacing-xs;
+}
+
+.date-chip {
display: flex;
flex-direction: column;
align-items: center;
justify-content: center;
+ width: 96rpx;
+ height: 88rpx;
+ border-radius: $border-radius-sm;
+ gap: 4rpx;
}
-.filter-label {
- color: $text-color-light;
- font-size: 20rpx;
+.date-chip.active {
+ background: $text-color-main;
}
-.filter-value {
- margin-top: 4rpx;
- color: $text-color-main;
+.date-label {
+ font-size: 22rpx;
+ font-weight: 700;
+ color: $text-color-muted;
+}
+
+.date-chip.active .date-label {
+ color: #FFFFFF;
+}
+
+.date-day {
font-size: 24rpx;
font-weight: 800;
+ color: $text-color-main;
+}
+
+.date-chip.active .date-day {
+ color: #FFFFFF;
}
.course-list {
@@ -181,7 +370,6 @@ defineExpose({ refresh, loadMore })
}
.course-card {
- @include minimal-card;
display: flex;
gap: $spacing-md;
}
@@ -199,19 +387,31 @@ defineExpose({ refresh, loadMore })
min-width: 0;
}
-.course-top,
-.course-bottom {
- display: flex;
- justify-content: space-between;
- gap: $spacing-sm;
-}
-
.course-title {
flex: 1;
color: $text-color-main;
font-size: 30rpx;
font-weight: 900;
line-height: 1.35;
+ display: block;
+}
+
+.course-top {
+ display: flex;
+ align-items: center;
+ justify-content: space-between;
+ gap: $spacing-sm;
+}
+
+.booked-badge {
+ flex-shrink: 0;
+ padding: 4rpx 14rpx;
+ border-radius: $border-radius-sm;
+ background: $color-success-light;
+ color: $color-success;
+ font-size: 20rpx;
+ font-weight: 800;
+ white-space: nowrap;
}
.time-line {
@@ -229,9 +429,117 @@ defineExpose({ refresh, loadMore })
font-size: 23rpx;
}
+.course-bottom {
+ display: flex;
+ justify-content: space-between;
+ gap: $spacing-sm;
+ margin-top: 6rpx;
+}
+
.course-price {
color: $text-color-main;
font-size: 28rpx;
font-weight: 900;
}
+
+/* 篮球门票 */
+.ticket-section {
+ padding: $spacing-md;
+ padding-bottom: calc(160rpx + env(safe-area-inset-bottom));
+}
+
+.product-card,
+.count-card {
+ margin-bottom: $spacing-md;
+}
+
+.product-head,
+.amount-row,
+.stepper-row {
+ display: flex;
+ align-items: center;
+ justify-content: space-between;
+ gap: $spacing-md;
+}
+
+.product-title,
+.card-title {
+ display: block;
+ color: $text-color-main;
+ font-size: 34rpx;
+ font-weight: 900;
+}
+
+.product-subtitle {
+ display: block;
+ margin-top: $spacing-xs;
+ color: $text-color-muted;
+ font-size: 24rpx;
+ line-height: 1.6;
+}
+
+.price-block {
+ margin-top: $spacing-xl;
+}
+
+.unit-price {
+ color: $text-color-main;
+ font-size: 64rpx;
+ font-weight: 900;
+}
+
+.unit-label {
+ color: $text-color-muted;
+ font-size: 26rpx;
+}
+
+.stepper-row {
+ margin: $spacing-lg 0;
+}
+
+.step-btn {
+ width: 86rpx;
+ height: 70rpx;
+ border-radius: $border-radius-base;
+ background: $text-color-main;
+ color: #FFFFFF;
+ font-size: 38rpx;
+ font-weight: 900;
+ display: flex;
+ align-items: center;
+ justify-content: center;
+}
+
+.quantity {
+ color: $text-color-main;
+ font-size: 42rpx;
+ font-weight: 900;
+}
+
+.amount-row {
+ padding-top: $spacing-md;
+ border-top: 1rpx solid $bg-color-hover;
+ color: $text-color-muted;
+ font-size: 26rpx;
+}
+
+.amount-row text:last-child {
+ color: $text-color-main;
+ font-size: 34rpx;
+ font-weight: 900;
+}
+
+.bar-price {
+ flex: 1;
+}
+
+.bar-label {
+ display: block;
+ color: $text-color-light;
+ font-size: 22rpx;
+}
+
+.submit-btn {
+ width: 320rpx;
+}
diff --git a/miniprogram/src/pages/comprehensive/courses/membership-detail.vue b/miniprogram/src/pages/comprehensive/courses/membership-detail.vue
new file mode 100644
index 0000000..e6ff895
--- /dev/null
+++ b/miniprogram/src/pages/comprehensive/courses/membership-detail.vue
@@ -0,0 +1,352 @@
+
+
+
+
+
+
+ {{ sessionData.title }}
+
+
+ ¥{{ sessionData.price }}
+
+
+
+
+
+ {{ item.label }}
+ {{ item.value }}
+
+
+
+
+
+
+
+
+
+ 选择次卡
+
+
+
+ {{ card.plan_name }}
+ 剩余 {{ card.remaining_count }} 次
+
+ ✓
+
+
+ 暂无可用次卡
+
+
+
+
+
+
+
+
+
+ 确认预约
+
+
+ 课程
+ {{ sessionData.title }}
+
+
+ 时间
+ {{ formatTimeRange(sessionData.start_at, sessionData.end_at) }}
+
+
+ 次卡
+ {{ selectedCardLabel }}
+
+
+
+
+
+
+
+
+
+
+ 加载中...
+
+
+
+
+
diff --git a/miniprogram/src/pages/comprehensive/home/index.vue b/miniprogram/src/pages/comprehensive/home/index.vue
index ba8e1d2..a54802a 100644
--- a/miniprogram/src/pages/comprehensive/home/index.vue
+++ b/miniprogram/src/pages/comprehensive/home/index.vue
@@ -73,7 +73,6 @@ defineExpose({ refresh: loadPage })
.home-container {
min-height: 100vh;
background-color: $bg-color-soft;
- margin-top: calc(-1 * var(--status-bar-height, 0px));
}
.banner-wrapper {
diff --git a/miniprogram/src/pages/comprehensive/mall/detail.vue b/miniprogram/src/pages/comprehensive/mall/detail.vue
new file mode 100644
index 0000000..aca7890
--- /dev/null
+++ b/miniprogram/src/pages/comprehensive/mall/detail.vue
@@ -0,0 +1,195 @@
+
+
+ 加载中...
+
+
+
+ {{ item.name }}
+ ¥{{ item.price }}
+
+
+
+
+ 总次数
+ {{ item.total_count }} 次
+
+
+ 适用课程
+
+ {{ course.title }}
+
+
+
+
+
+
+ 支付金额
+ ¥{{ item.price }}
+
+
+ 到账金额
+ ¥{{ item.face_value }}
+
+
+
+
+
+
+
+
+ 商品不存在或已下架
+
+
+
+
+
+
diff --git a/miniprogram/src/pages/comprehensive/mall/index.vue b/miniprogram/src/pages/comprehensive/mall/index.vue
index 14e7556..5b08c0f 100644
--- a/miniprogram/src/pages/comprehensive/mall/index.vue
+++ b/miniprogram/src/pages/comprehensive/mall/index.vue
@@ -1,74 +1,59 @@
- 加载中...
-
-
-