移除前端中的会员卡和支付相关,新增微信一键登录
This commit is contained in:
@@ -1,4 +1,4 @@
|
||||
<template>
|
||||
<template>
|
||||
<view class="course-detail-page">
|
||||
<!-- 页面头部 -->
|
||||
<PageHeader title="课程详情" subtitle="团课预约" :show-back="true" />
|
||||
@@ -188,39 +188,6 @@
|
||||
|
||||
<!-- 底部操作栏 -->
|
||||
<view class="bottom-bar">
|
||||
<!-- 左侧:支付方式选择(包含价格) -->
|
||||
<view v-if="hasMultiplePayment" class="payment-card">
|
||||
<!-- 左侧:滑块支付选择 -->
|
||||
<view class="payment-slider" @click="togglePayment">
|
||||
<view class="slider-bg" :class="{ right: selectedPayment === 'pointCard' }"></view>
|
||||
<view class="tab-item" :class="{ active: selectedPayment === 'storedValue' }">
|
||||
<text class="tab-label">储值卡</text>
|
||||
</view>
|
||||
<view class="tab-item" :class="{ active: selectedPayment === 'pointCard' }">
|
||||
<text class="tab-label">次卡</text>
|
||||
</view>
|
||||
</view>
|
||||
<!-- 右侧:当前选中价格 -->
|
||||
<view class="payment-price">
|
||||
<text class="price" :class="selectedPrice.type">
|
||||
<text class="currency">¥</text><text class="amount">{{ course.storedValueAmount }}</text>
|
||||
<text class="point-text"><text class="point-icon">⚡</text>{{ course.pointCardAmount }}次</text>
|
||||
</text>
|
||||
</view>
|
||||
</view>
|
||||
|
||||
<!-- 免费课程或单一支付方式 -->
|
||||
<view v-else class="price-display">
|
||||
<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">
|
||||
<text class="point-icon">⚡</text>
|
||||
<text>{{ course.pointCardAmount }}次</text>
|
||||
</text>
|
||||
</view>
|
||||
|
||||
<!-- 右侧:预约按钮 -->
|
||||
<view :class="['booking-btn', { disabled: !canBook }]" @click="handleBooking">
|
||||
<text>{{ canBook ? '立即预约' : (course.currentMembers >= course.maxMembers ? '已满员' : statusText) }}</text>
|
||||
@@ -228,17 +195,6 @@
|
||||
</view>
|
||||
</view>
|
||||
</view>
|
||||
|
||||
<!-- 支付密码弹窗 -->
|
||||
<PayPasswordModal
|
||||
:visible="showPayPwd"
|
||||
title="支付验证"
|
||||
:subtitle="course.courseName"
|
||||
:amount="course.storedValueAmount || 0"
|
||||
amount-label="课程金额"
|
||||
@confirm="onPayPasswordConfirm"
|
||||
@cancel="onPayPasswordCancel"
|
||||
/>
|
||||
</template>
|
||||
|
||||
<script setup>
|
||||
@@ -246,19 +202,12 @@ import { ref, computed } from 'vue'
|
||||
import { onLoad } from '@dcloudio/uni-app'
|
||||
import { getGroupCourseDetail, bookGroupCourse } from '@/api/groupCourse.js'
|
||||
import { getCourseCoverUrl } from '@/utils/request.js'
|
||||
import { getPrimaryMemberCard } from '@/api/main.js'
|
||||
import { getMemberId } from '@/utils/request.js'
|
||||
import PageHeader from '@/components/index/PageHeader.vue'
|
||||
import PayPasswordModal from '@/components/global/PayPasswordModal.vue'
|
||||
|
||||
// 加载状态
|
||||
const loading = ref(true)
|
||||
|
||||
// 支付密码弹窗状态
|
||||
const showPayPwd = ref(false)
|
||||
const payPwdLoading = ref(false)
|
||||
let payPwdResolve = null
|
||||
|
||||
// 课程详情数据
|
||||
const course = ref({
|
||||
id: '',
|
||||
@@ -323,46 +272,6 @@ const canBook = computed(() => {
|
||||
return status === '0' && !isFull
|
||||
})
|
||||
|
||||
// 是否有多种支付方式
|
||||
const hasMultiplePayment = computed(() => {
|
||||
const storedValue = Number(course.value.storedValueAmount)
|
||||
const pointCard = Number(course.value.pointCardAmount)
|
||||
return storedValue > 0 && pointCard > 0
|
||||
})
|
||||
|
||||
// 当前选中的支付方式
|
||||
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: storedValue }
|
||||
} else if (selectedPayment.value === 'pointCard') {
|
||||
return { type: 'pointCard', amount: pointCard }
|
||||
} else if (storedValue > 0 && pointCard > 0) {
|
||||
// 默认优先显示储值卡
|
||||
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 }
|
||||
})
|
||||
|
||||
// 选择/切换支付方式
|
||||
const selectPayment = (type) => {
|
||||
selectedPayment.value = type
|
||||
}
|
||||
|
||||
// 切换支付方式(滑块点击)
|
||||
const togglePayment = () => {
|
||||
selectedPayment.value = selectedPayment.value === 'storedValue' ? 'pointCard' : 'storedValue'
|
||||
}
|
||||
|
||||
// 格式化日期
|
||||
const formatDate = (dateStr) => {
|
||||
if (!dateStr) return ''
|
||||
@@ -405,29 +314,15 @@ const handleBooking = async () => {
|
||||
|
||||
uni.showModal({
|
||||
title: '确认预约',
|
||||
content: `确定要预约「${course.value.courseName}」吗?${course.value.storedValueAmount > 0 ? '\n金额: ¥' + course.value.storedValueAmount : ''}`,
|
||||
content: `确定要预约「${course.value.courseName}」吗?`,
|
||||
success: async (res) => {
|
||||
if (!res.confirm) return
|
||||
|
||||
// 弹出支付密码输入
|
||||
const payPassword = await requestPayPassword()
|
||||
if (!payPassword) return
|
||||
|
||||
uni.showLoading({ title: '预约中...' })
|
||||
try {
|
||||
const cardRes = await getPrimaryMemberCard(memberId)
|
||||
const memberCardRecordId = cardRes?.id || cardRes?.data?.id
|
||||
if (!memberCardRecordId) {
|
||||
uni.hideLoading()
|
||||
uni.showToast({ title: '请先购买会员卡', icon: 'none' })
|
||||
return
|
||||
}
|
||||
|
||||
const result = await bookGroupCourse({
|
||||
courseId: Number(course.value.id),
|
||||
memberId: Number(memberId),
|
||||
memberCardRecordId: Number(memberCardRecordId),
|
||||
payPassword: payPassword
|
||||
memberId: Number(memberId)
|
||||
})
|
||||
uni.hideLoading()
|
||||
if (result.success) {
|
||||
@@ -459,24 +354,6 @@ const handleBooking = async () => {
|
||||
})
|
||||
}
|
||||
|
||||
// 弹出支付密码输入框,返回 Promise<string|null>
|
||||
function requestPayPassword() {
|
||||
return new Promise((resolve) => {
|
||||
payPwdResolve = resolve
|
||||
showPayPwd.value = true
|
||||
})
|
||||
}
|
||||
|
||||
function onPayPasswordConfirm(password) {
|
||||
payPwdResolve?.(password)
|
||||
showPayPwd.value = false
|
||||
}
|
||||
|
||||
function onPayPasswordCancel() {
|
||||
payPwdResolve?.(null)
|
||||
showPayPwd.value = false
|
||||
}
|
||||
|
||||
// 获取课程详情
|
||||
const fetchCourseDetail = async (id) => {
|
||||
try {
|
||||
@@ -751,71 +628,6 @@ onLoad((options) => {
|
||||
text-align: right;
|
||||
}
|
||||
|
||||
.payment-options {
|
||||
display: flex;
|
||||
gap: 20rpx;
|
||||
flex: 1;
|
||||
justify-content: flex-end;
|
||||
}
|
||||
|
||||
.payment-item {
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
align-items: center;
|
||||
padding: 16rpx 28rpx;
|
||||
background: linear-gradient(135deg, #F9FAFB 0%, #F3F4F6 100%);
|
||||
border-radius: 16rpx;
|
||||
border: 2rpx solid transparent;
|
||||
position: relative;
|
||||
transition: all 0.3s cubic-bezier(0.4, 0, 0.2, 1);
|
||||
|
||||
&:active {
|
||||
transform: scale(0.97);
|
||||
}
|
||||
|
||||
&.active {
|
||||
background: linear-gradient(135deg, #FF6B35 0%, #FF8C5A 100%);
|
||||
border-color: #FF6B35;
|
||||
|
||||
.payment-label,
|
||||
.payment-value {
|
||||
color: #ffffff;
|
||||
}
|
||||
}
|
||||
|
||||
&.free {
|
||||
background: linear-gradient(135deg, #ECFDF5 0%, #D1FAE5 100%);
|
||||
}
|
||||
}
|
||||
|
||||
.payment-label {
|
||||
font-size: 20rpx;
|
||||
color: #6B7280;
|
||||
}
|
||||
|
||||
.payment-value {
|
||||
font-size: 28rpx;
|
||||
font-weight: 600;
|
||||
color: #FF6B35;
|
||||
|
||||
.free & {
|
||||
color: #059669;
|
||||
}
|
||||
}
|
||||
|
||||
.payment-check {
|
||||
position: absolute;
|
||||
top: -8rpx;
|
||||
right: -8rpx;
|
||||
width: 36rpx;
|
||||
height: 36rpx;
|
||||
background: #059669;
|
||||
border-radius: 50%;
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
}
|
||||
|
||||
/* 预约须知 */
|
||||
.notice-card {
|
||||
background: #ffffff;
|
||||
@@ -857,152 +669,7 @@ onLoad((options) => {
|
||||
z-index: 100;
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: space-between;
|
||||
gap: 16rpx;
|
||||
}
|
||||
|
||||
/* 支付卡片(包含选择器和价格) */
|
||||
.payment-card {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
background: linear-gradient(135deg, #FFF7F5 0%, #FFF0EC 100%);
|
||||
border-radius: 52rpx;
|
||||
padding: 8rpx;
|
||||
height: 88rpx;
|
||||
flex: 1;
|
||||
min-width: 0;
|
||||
border: 2rpx solid rgba(255, 107, 53, 0.15);
|
||||
}
|
||||
|
||||
/* 支付滑块选择器 */
|
||||
.payment-slider {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
background: #F5F7FA;
|
||||
border-radius: 44rpx;
|
||||
padding: 6rpx;
|
||||
position: relative;
|
||||
overflow: hidden;
|
||||
flex: 1;
|
||||
height: 72rpx;
|
||||
}
|
||||
|
||||
/* 滑动背景指示器 */
|
||||
.payment-slider .slider-bg {
|
||||
position: absolute;
|
||||
top: 6rpx;
|
||||
left: 6rpx;
|
||||
width: calc(50% - 6rpx);
|
||||
height: calc(100% - 12rpx);
|
||||
background: linear-gradient(135deg, #FF6B35 0%, #FF8C5A 100%);
|
||||
border-radius: 38rpx;
|
||||
box-shadow: 0 4rpx 12rpx rgba(255, 107, 53, 0.35);
|
||||
transition: all 0.3s cubic-bezier(0.4, 0, 0.2, 1);
|
||||
z-index: 0;
|
||||
}
|
||||
|
||||
.payment-slider .slider-bg.right {
|
||||
transform: translateX(100%);
|
||||
}
|
||||
|
||||
.payment-slider .tab-item {
|
||||
flex: 1;
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
height: 100%;
|
||||
border-radius: 38rpx;
|
||||
transition: all 0.3s ease;
|
||||
position: relative;
|
||||
z-index: 1;
|
||||
}
|
||||
|
||||
.payment-slider .tab-item.active .tab-label {
|
||||
color: #ffffff;
|
||||
}
|
||||
|
||||
.payment-slider .tab-label {
|
||||
font-size: 24rpx;
|
||||
font-weight: 600;
|
||||
color: #6B7280;
|
||||
transition: color 0.3s ease;
|
||||
}
|
||||
|
||||
/* 支付卡片中的价格 */
|
||||
.payment-price {
|
||||
min-width: 140rpx;
|
||||
padding: 0 16rpx;
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
}
|
||||
|
||||
.payment-price .price {
|
||||
font-size: 34rpx;
|
||||
font-weight: 700;
|
||||
color: #FF6B35;
|
||||
display: flex;
|
||||
align-items: baseline;
|
||||
gap: 4rpx;
|
||||
white-space: nowrap;
|
||||
justify-content: center;
|
||||
}
|
||||
|
||||
.payment-price .price .currency,
|
||||
.payment-price .price .amount,
|
||||
.payment-price .price .point-text {
|
||||
display: none;
|
||||
}
|
||||
|
||||
.payment-price .price.storedValue .currency,
|
||||
.payment-price .price.storedValue .amount {
|
||||
display: inline;
|
||||
}
|
||||
|
||||
.payment-price .price.pointCard .point-text {
|
||||
display: inline;
|
||||
}
|
||||
|
||||
.payment-price .currency {
|
||||
font-size: 22rpx;
|
||||
font-weight: 600;
|
||||
}
|
||||
|
||||
.payment-price .point-icon {
|
||||
font-size: 22rpx;
|
||||
}
|
||||
|
||||
/* 价格展示(单一支付方式或免费) */
|
||||
.price-display {
|
||||
flex: 1;
|
||||
display: flex;
|
||||
align-items: center;
|
||||
padding-left: 8rpx;
|
||||
}
|
||||
|
||||
.price-display .price {
|
||||
font-size: 40rpx;
|
||||
font-weight: 700;
|
||||
display: flex;
|
||||
align-items: baseline;
|
||||
gap: 4rpx;
|
||||
}
|
||||
|
||||
.price-display .price.free {
|
||||
color: #10B981;
|
||||
}
|
||||
|
||||
.price-display .price:not(.free) {
|
||||
color: #FF6B35;
|
||||
}
|
||||
|
||||
.price-display .currency {
|
||||
font-size: 26rpx;
|
||||
font-weight: 600;
|
||||
}
|
||||
|
||||
.price-display .point-icon {
|
||||
font-size: 26rpx;
|
||||
}
|
||||
|
||||
/* 预约按钮 */
|
||||
@@ -1014,7 +681,6 @@ onLoad((options) => {
|
||||
font-weight: 600;
|
||||
color: #ffffff;
|
||||
box-shadow: 0 8rpx 24rpx rgba(255, 107, 53, 0.3);
|
||||
flex-shrink: 0;
|
||||
}
|
||||
|
||||
.booking-btn.disabled {
|
||||
|
||||
Reference in New Issue
Block a user