Files
uni-fans-score/pages/purchase/index.vue
T
2026-01-22 10:52:58 +08:00

1086 lines
24 KiB
Vue
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
<template>
<view class="purchase-page">
<!-- Tab 切换 -->
<view class="tab-container">
<view class="tab-item" :class="{ active: currentTab === 'card' }" @click="switchTab('card')">
<text class="tab-text">{{ $t('purchase.memberCard') }}</text>
</view>
<view class="tab-item" :class="{ active: currentTab === 'coupon' }" @click="switchTab('coupon')">
<text class="tab-text">{{ $t('purchase.coupon') }}</text>
</view>
</view>
<!-- 内容区域 -->
<scroll-view class="content-area" scroll-y>
<!-- 会员卡列表 -->
<view v-if="currentTab === 'card'" class="product-list">
<view v-for="item in memberCards" :key="item.id" class="product-card"
:class="{ selected: selectedProduct?.id === item.id }" @click="selectProduct(item)">
<view class="card-content">
<view class="card-left">
<view class="card-title-row">
<text class="card-name">{{ item.name }}</text>
<view class="card-type-tag" :class="{ 'type-time': item.type === 'TIME', 'type-count': item.type === 'COUNT' }">
<text class="card-type-text">{{ item.type === 'TIME' ? $t('myCard.durationCard') : $t('myCard.timesCard') }}</text>
</view>
</view>
<text class="card-desc">{{ item.description }}</text>
<!-- 使用限制信息 -->
<view class="card-limits">
<!-- 时长卡展示每日限用次数和单次限时 -->
<view v-if="item.type === 'TIME'" class="limit-tags">
<view class="limit-tag" v-if="item.dailyLimitCount > 0">
<text class="limit-label">{{ $t('myCard.dailyLimit') }}:</text>
<text class="limit-value">{{ item.dailyLimitCount }}{{ $t('myCard.times') }}</text>
</view>
<view class="limit-tag">
<text class="limit-label">{{ $t('myCard.singleTimeLimit') }}:</text>
<text class="limit-value" :class="{ unlimited: item.singleLimitMinutes === 0 }">
{{ item.singleLimitMinutes > 0 ? item.singleLimitMinutes + $t('myCard.minutes') : $t('myCard.unlimited') }}
</text>
</view>
<view class="limit-tag validity-tag" v-if="item.cycleDays">
<text class="limit-value">{{ item.cycleDays }}{{ $t('myCard.daysValid') }}</text>
</view>
</view>
<!-- 次卡展示总次数和单次限时 -->
<view v-if="item.type === 'COUNT'" class="limit-tags">
<view class="limit-tag count-tag" v-if="item.totalCount > 0">
<text class="limit-label">{{ $t('myCard.totalCount') }}:</text>
<text class="limit-value">{{ item.totalCount }}{{ $t('myCard.times') }}</text>
</view>
<view class="limit-tag">
<text class="limit-label">{{ $t('myCard.singleTimeLimit') }}:</text>
<text class="limit-value" :class="{ unlimited: item.singleLimitMinutesForCount === 0 }">
{{ item.singleLimitMinutesForCount > 0 ? item.singleLimitMinutesForCount + $t('myCard.minutes') : $t('myCard.unlimited') }}
</text>
</view>
<view class="limit-tag validity-tag" v-if="item.validDays">
<text class="limit-value">{{ item.validDays }}{{ $t('myCard.daysValid') }}</text>
</view>
</view>
</view>
</view>
<view class="card-right">
<view class="card-price">
<text class="price-currency">¥</text>
<text class="price-value">{{ item.price }}</text>
</view>
<view class="card-original-price" v-if="item.originalPrice">
<text class="original-currency">¥</text>
<text class="original-value">{{ item.originalPrice }}</text>
</view>
</view>
</view>
</view>
<!-- 空数据提示 -->
<uv-empty v-if="memberCards.length === 0" mode="car" :text="$t('purchase.noCards')"></uv-empty>
</view>
<!-- 优惠券列表 -->
<view v-if="currentTab === 'coupon'" class="product-list">
<view v-for="item in coupons" :key="item.id" class="coupon-card-wrapper">
<view class="coupon-card" :class="{ selected: selectedProduct?.id === item.id }"
@click="selectProduct(item)">
<!-- 左侧圆形缺口 -->
<view class="coupon-circle-left"></view>
<!-- 右侧圆形缺口 -->
<view class="coupon-circle-right"></view>
<view class="coupon-left">
<view class="coupon-value-wrapper">
<text class="coupon-value-num">{{ item.type === 'discount' ? item.discount : item.value
}}</text>
<text class="coupon-value-unit">{{ item.type === 'discount' ? '折' : '¥' }}</text>
</view>
<view style="display: flex;flex-direction: column;">
<text class="coupon-condition">{{ item.condition }}</text>
<text class="coupon-validity">{{ item.validity }}</text>
</view>
</view>
<view class="coupon-divider"></view>
<view class="coupon-right">
<view class="coupon-price">
<text class="price-label">¥</text>
<text class="price-value">{{ item.price }}</text>
</view>
</view>
</view>
</view>
<!-- 空数据提示 -->
<uv-empty v-if="coupons.length === 0" mode="coupon" :text="$t('purchase.noCoupons')"></uv-empty>
</view>
<!-- 说明部分 -->
<view class="description-section">
<text class="description-title">{{ currentTab === 'card' ? $t('purchase.cardDescription') :
$t('purchase.couponDescription') }}</text>
<view class="description-content">
<view v-for="(desc, index) in descriptions" :key="index" class="description-item">
<text class="description-subtitle">{{ desc.title }}</text>
<text class="description-text">{{ desc.content }}</text>
</view>
</view>
</view>
</scroll-view>
<!-- 底部操作栏 -->
<view class="bottom-bar">
<view class="my-products-wrapper" @click="goToMyProducts">
<view class="" style="display: flex;">
<view class="my-products">
<image class="my-products-icon" src="/static/couponList.png" mode="aspectFit">
</image>
<text class="my-products-text">{{ currentTab === 'card' ? $t('purchase.myCards') :
$t('purchase.myCoupons') }}</text>
</view>
</view>
<view class="" style="width: 40rpx;height: 40rpx;">
<image src="/static/gotoBuy.png" mode="aspectFill" style="width: 40rpx;height: 40rpx;"></image>
</view>
</view>
<view class="action-wrapper">
<view class="price-info">
<text class="current-price">¥{{ selectedProduct?.price || '0.00' }}</text>
<text class="original-price" v-if="selectedProduct?.originalPrice">¥{{
selectedProduct?.originalPrice
}}</text>
</view>
<view class="buy-button" :class="{ disabled: !selectedProduct }" @click="handleBuy">
<text class="buy-button-text">{{ $t('purchase.buyNow') }}</text>
</view>
</view>
</view>
</view>
</template>
<script setup>
import {
ref,
computed,
onMounted
} from 'vue'
import {
onLoad
} from '@dcloudio/uni-app'
import {
useI18n
} from '@/utils/i18n.js'
import {
getCouponsByPosition,
createCouponPayment,
cancelCouponPayment
} from '@/config/api/coupon.js'
// import {
// cancelMemberCardPayment
// } from '@/config/api/member.js'
import {
createMemberCardPayment,
getMemberCardsByPosition,
cancelMemberCardPayment
} from '@/config/api/member.js'
const {
t
} = useI18n()
// 当前选中的 Tab
const currentTab = ref('card') // 'card' 或 'coupon'
// 选中的商品
const selectedProduct = ref(null)
// 当前场地ID(从路由参数获取)
const positionId = ref(null)
// 生命周期 onLoad 钩子 - 获取路由参数
onLoad((options) => {
if (options.positionId) {
positionId.value = options.positionId
console.log('获取到场地ID:', positionId.value)
}
})
// 会员卡列表(从后端加载)
const memberCards = ref([])
// 优惠券列表(从后端加载)
const coupons = ref([])
// 说明内容
const descriptions = computed(() => {
if (currentTab.value === 'card') {
return [
{
title: t('purchase.cardUseInstruction'),
content: t('purchase.cardUseDescription')
},
{
title: t('purchase.cardValidityPeriod'),
content: t('purchase.cardValidityDescription')
},
{
title: t('purchase.cardRefundPolicy'),
content: t('purchase.cardRefundDescription')
}
]
} else {
return [
{
title: t('purchase.couponUseInstruction'),
content: t('purchase.couponUseDescription')
},
{
title: t('purchase.couponValidityPeriod'),
content: t('purchase.couponValidityDescription')
},
{
title: t('purchase.couponUsageScope'),
content: t('purchase.couponUsageDescription')
}
]
}
})
// 加载会员卡列表
const loadMemberCards = async () => {
try {
uni.showLoading({
title: '加载中...'
})
const res = await getMemberCardsByPosition(positionId.value)
uni.hideLoading()
if (res.code === 200 && res.data) {
// 转换为页面需要的格式
memberCards.value = res.data.map(item => ({
id: item.memberCardId,
name: item.cardName,
type: item.cardType,
description: item.positionName || '无描述',
price: item.purchasePrice ? item.purchasePrice.toString() : '0.00',
originalPrice: null,
availablePositions: item.positionName,
cycleDays: item.cycleDays,
dailyLimitCount: item.dailyLimitCount || 0,
singleLimitMinutes: item.singleLimitMinutes || 0,
singleLimitMinutesForCount: item.singleLimitMinutesForCount || 0,
validDays: item.validDays,
totalCount: item.totalCount,
purchaseQuantity: item.purchaseQuantity
}))
}
} catch (error) {
uni.hideLoading()
console.error('加载会员卡失败:', error)
uni.showToast({
title: '加载会员卡失败',
icon: 'none'
})
}
}
// 加载优惠券列表
const loadCoupons = async () => {
try {
uni.showLoading({
title: '加载中...'
})
const res = await getCouponsByPosition(positionId.value)
uni.hideLoading()
if (res.code === 200 && res.data) {
// 转换为页面需要的格式
coupons.value = res.data.map(item => ({
id: item.couponId,
couponId: item.couponId,
name: item.couponName,
type: item.couponType === 'discount_coupon' ? 'discount' : 'cash',
discount: item.discountRate ? (item.discountRate * 10).toFixed(0) : null,
value: item.deductAmount ? item.deductAmount.toString() : null,
condition: item.usableCondition > 0 ? `满${item.usableCondition}元可用` : '无门槛',
validity: item.validDays > 0 ? `从购买日起 有效期${item.validDays}天` : '永久有效',
price: item.purchasePrice ? item.purchasePrice.toString() : '0.00',
originalPrice: null,
usablePositions: item.usablePositionNameMap,
remark: item.remark
}))
}
} catch (error) {
uni.hideLoading()
console.error('加载优惠券失败:', error)
uni.showToast({
title: '加载优惠券失败',
icon: 'none'
})
}
}
// 初始化
onMounted(async () => {
// 加载会员卡列表
if (positionId.value) {
await loadMemberCards()
}
// 加载优惠券列表
if (positionId.value) {
await loadCoupons()
}
// 默认选中第一个会员卡(如果有的话)
if (memberCards.value.length > 0) {
selectedProduct.value = memberCards.value[0]
}
})
const switchTab = (tab) => {
currentTab.value = tab
selectedProduct.value = null
}
// 选择商品
const selectProduct = (product) => {
selectedProduct.value = product
}
const orderNo = ref('')
// 处理购买
const handleBuy = async () => {
if (!selectedProduct.value) {
uni.showToast({
title: t('purchase.pleaseSelect'),
icon: 'none'
})
return
}
// 会员卡购买
if (currentTab.value === 'card') {
try {
uni.showLoading({
title: '正在创建订单...'
})
const res = await createMemberCardPayment(selectedProduct.value.id)
uni.hideLoading()
if (res.code === 200 && res.data) {
orderNo.value = res.data.OutOrderNo;
// 调起微信支付
uni.requestPayment({
timeStamp: res.data.timeStamp,
nonceStr: res.data.nonceStr,
package: res.data.packageValue || res.data.package,
signType: res.data.signType || 'MD5',
paySign: res.data.paySign,
success: (payRes) => {
uni.showToast({
title: '支付成功',
icon: 'success'
})
// 支付成功后,跳转到我的会员卡页面
setTimeout(() => {
uni.navigateTo({
url: '/pages/my/card'
})
}, 1500)
},
fail: (err) => {
console.error('支付失败:', err)
console.log('支付失败详细信息:', err.errMsg.includes('cancel'));
if (err.errMsg && err.errMsg.includes('cancel')) {
if (orderNo.value) {
cancelMemberCardPayment(orderNo.value)
.then(cancelRes => {
console.log('取消支付订单成功:', cancelRes);
})
.catch(cancelErr => {
console.error('取消支付订单失败:', cancelErr);
});
}
uni.showToast({
title: '已取消支付',
icon: 'none'
})
} else {
uni.showToast({
title: '支付失败',
icon: 'none'
})
}
}
})
} else {
uni.showToast({
title: res.msg || '创建订单失败',
icon: 'none'
})
}
} catch (error) {
uni.hideLoading()
console.error('购买失败:', error)
uni.showToast({
title: '购买失败,请稍后重试',
icon: 'none'
})
}
return
}
// 优惠券购买
if (currentTab.value === 'coupon') {
try {
uni.showLoading({
title: '正在创建订单...'
})
const res = await createCouponPayment(selectedProduct.value.couponId)
uni.hideLoading()
if (res.code === 200 && res.data) {
// 调起微信支付
uni.requestPayment({
timeStamp: res.data.timeStamp,
nonceStr: res.data.nonceStr,
package: res.data.packageValue || res.data.package,
signType: res.data.signType || 'MD5',
paySign: res.data.paySign,
success: (payRes) => {
uni.showToast({
title: '支付成功',
icon: 'success'
})
// 支付成功后,跳转到我的优惠券页面
setTimeout(() => {
uni.navigateTo({
url: '/pages/my/coupon'
})
}, 1500)
},
fail: (err) => {
console.error('支付失败:', err)
if (err.errMsg && err.errMsg.includes('cancel')) {
// 用户取消支付,调用取消接口
const orderNo = res.data.OutOrderNo;
if (orderNo) {
cancelCouponPayment(orderNo)
.then(cancelRes => {
console.log('取消支付订单成功:', cancelRes);
})
.catch(cancelErr => {
console.error('取消支付订单失败:', cancelErr);
});
}
uni.showToast({
title: '已取消支付',
icon: 'none'
})
} else {
uni.showToast({
title: '支付失败',
icon: 'none'
})
}
}
})
} else {
uni.showToast({
title: res.msg || '创建订单失败',
icon: 'none'
})
}
} catch (error) {
uni.hideLoading()
console.error('购买失败:', error)
uni.showToast({
title: '购买失败,请稍后重试',
icon: 'none'
})
}
}
}
// 查看我的商品
const goToMyProducts = () => {
if (currentTab.value === 'card') {
uni.navigateTo({
url: '/pages/my/card'
})
} else if (currentTab.value === 'coupon') {
uni.navigateTo({
url: '/pages/my/coupon'
})
}
}
</script>
<style lang="scss" scoped>
.purchase-page {
min-height: 100vh;
background-color: #f5f5f5;
padding-bottom: 180rpx;
}
/* Tab 切换 */
.tab-container {
top: 20rpx;
position: fixed;
left: 0;
right: 0;
display: flex;
background-color: #ffffff;
width: 500rpx;
z-index: 999;
padding: 5rpx 0;
margin: 0 auto;
border-radius: 26rpx;
}
.tab-item {
flex: 1;
text-align: center;
padding: 10rpx 30rpx;
margin: 0 10rpx;
width: 120rpx;
position: relative;
.tab-text {
font-size: 28rpx;
color: #A6A6A6;
font-weight: 500;
}
&.active {
background:#FFE2B8;
border-radius: 26rpx;
.tab-text {
color: #A16300;
font-weight: 600;
}
// &::after {
// content: '';
// position: absolute;
// bottom: 0;
// left: 50%;
// transform: translateX(-50%);
// width: 60rpx;
// height: 6rpx;
// background-color: #FFA928;
// border-radius: 3rpx;
// }
}
}
/* 内容区域 */
.content-area {
height: calc(100vh - 180rpx);
padding: 20rpx;
padding-top: 80rpx;
box-sizing: border-box;
}
/* 商品列表 */
.product-list {
margin-bottom: 20rpx;
margin-top: 20rpx;
}
/* 会员卡卡片 */
.product-card {
background-color: #ffffff;
border-radius: 20rpx;
padding: 30rpx;
margin-bottom: 20rpx;
border: 2rpx solid transparent;
transition: all 0.3s;
box-sizing: border-box;
&:last-child {
margin-bottom: 0;
}
&.selected {
border-color: #FFA928;
box-shadow: 0 4rpx 20rpx rgba(255, 169, 40, 0.2);
}
.card-content {
display: flex;
justify-content: space-between;
align-items: flex-start;
}
.card-left {
flex: 1;
display: flex;
flex-direction: column;
gap: 10rpx;
}
.card-title-row {
display: flex;
align-items: center;
gap: 12rpx;
}
.card-name {
font-size: 32rpx;
font-weight: 600;
color: #333;
}
.card-type-tag {
display: inline-flex;
align-items: center;
padding: 4rpx 12rpx;
border-radius: 8rpx;
flex-shrink: 0;
&.type-time {
background-color: #E6F7FF;
border: 1rpx solid #91D5FF;
}
&.type-count {
background-color: #FFF1F0;
border: 1rpx solid #FFCCC7;
}
.card-type-text {
font-size: 20rpx;
font-weight: 500;
}
}
.type-time .card-type-text {
color: #1890FF;
}
.type-count .card-type-text {
color: #FF4D4F;
}
.card-desc {
font-size: 24rpx;
color: #999;
line-height: 1.6;
}
/* 会员卡限制信息样式 */
.card-limits {
margin-top: 12rpx;
}
.limit-tags {
display: flex;
flex-wrap: wrap;
gap: 8rpx;
align-items: center;
}
.limit-tag {
display: inline-flex;
align-items: center;
gap: 4rpx;
padding: 6rpx 12rpx;
background-color: #FFF4E6;
border-radius: 8rpx;
border: 1rpx solid #FFE8CC;
.limit-label {
font-size: 22rpx;
color: #B8741A;
// font-weight: 500;
}
.limit-value {
font-size: 22rpx;
color: #FF6B00;
// font-weight: 600;
&.unlimited {
color: #07c160;
}
}
/* 有效期标签特殊样式 */
&.validity-tag {
background-color: #F0F5FF;
border: 1rpx solid #D6E4FF;
.limit-value {
color: #1890FF;
}
}
/* 总次数标签特殊样式 */
&.count-tag {
background-color: #FFF1F0;
border: 1rpx solid #FFCCC7;
.limit-label {
color: #CF1322;
}
.limit-value {
color: #FF4D4F;
font-weight: 600;
}
}
}
.card-right {
display: flex;
flex-direction: column;
align-items: flex-end;
gap: 8rpx;
}
.card-price {
display: flex;
align-items: baseline;
gap: 2rpx;
.price-currency {
font-size: 24rpx;
font-weight: 500;
color: #FF6B00;
}
.price-value {
font-size: 36rpx;
font-weight: 600;
color: #FF6B00;
}
}
.card-original-price {
display: flex;
align-items: baseline;
gap: 2rpx;
text-decoration: line-through;
.original-currency {
font-size: 20rpx;
font-weight: 400;
color: #999;
}
.original-value {
font-size: 24rpx;
font-weight: 400;
color: #999;
}
}
}
/* 优惠券卡片 */
.coupon-card-wrapper {
position: relative;
margin-bottom: 20rpx;
&:last-child {
margin-bottom: 0;
}
}
.coupon-card {
background: linear-gradient(135deg, #FFF4E6 0%, #FFE8CC 100%);
border-radius: 20rpx;
padding: 40rpx 30rpx;
display: flex;
align-items: stretch;
position: relative;
box-sizing: border-box;
border: 2rpx solid transparent;
transition: all 0.3s;
overflow: visible;
min-height: 180rpx;
&.selected {
border-color: #B8741A;
box-shadow: 0 4rpx 20rpx rgba(184, 116, 26, 0.2);
.coupon-circle-left,
.coupon-circle-right {
background-color: #FFF4E6;
border: 2rpx solid #B8741A;
}
}
}
/* 左侧圆形缺口 */
.coupon-circle-left {
position: absolute;
left: -16rpx;
top: 50%;
transform: translateY(-50%);
width: 32rpx;
height: 32rpx;
border-radius: 50%;
background-color: #f5f5f5;
z-index: 10;
transition: all 0.3s;
box-sizing: border-box;
}
/* 右侧圆形缺口 */
.coupon-circle-right {
position: absolute;
right: -16rpx;
top: 50%;
transform: translateY(-50%);
width: 32rpx;
height: 32rpx;
border-radius: 50%;
background-color: #f5f5f5;
z-index: 10;
transition: all 0.3s;
box-sizing: border-box;
}
.coupon-left {
flex: 1;
display: flex;
flex-direction: row;
gap: 8rpx;
align-items: center;
}
/* 优惠券金额显示包裹器 */
.coupon-value-wrapper {
width: 180rpx;
text-align: center;
}
/* 优惠券实际值(数字) */
.coupon-value-num {
font-size: 52rpx;
font-weight: 700;
color: #B8741A;
}
/* 优惠券单位(折/¥) */
.coupon-value-unit {
font-size: 26rpx;
font-weight: 600;
color: #B8741A;
}
.coupon-value {
font-size: 48rpx;
font-weight: 700;
color: #B8741A;
}
.coupon-condition {
font-size: 28rpx;
color: #333;
}
.coupon-validity {
font-size: 24rpx;
color: #999;
}
.coupon-divider {
width: 2rpx;
height: 100%;
position: absolute;
left: 65%;
transform: translateX(-50%);
top: 0;
bottom: 0;
// min-height: 160rpx;
align-self: stretch;
background: repeating-linear-gradient(to bottom,
#B8741A 0rpx,
#B8741A 8rpx,
transparent 8rpx,
transparent 16rpx);
margin: 0 30rpx;
}
.coupon-right {
display: flex;
align-items: center;
justify-content: center;
.coupon-price {
display: flex;
align-items: baseline;
gap: 4rpx;
.price-label {
font-size: 24rpx;
color: #B8741A;
font-weight: 600;
}
.price-value {
font-size: 36rpx;
color: #B8741A;
font-weight: 700;
}
}
}
/* 说明部分 */
.description-section {
background-color: #ffffff;
border-radius: 20rpx;
padding: 30rpx;
margin-top: 20rpx;
box-sizing: border-box;
}
.description-title {
font-size: 32rpx;
font-weight: 600;
color: #333;
margin-bottom: 20rpx;
display: block;
}
.description-content {
display: flex;
flex-direction: column;
gap: 20rpx;
}
.description-item {
display: flex;
flex-direction: column;
gap: 10rpx;
}
.description-subtitle {
font-size: 28rpx;
font-weight: 600;
color: #333;
}
.description-text {
font-size: 24rpx;
color: #666;
line-height: 1.8;
}
/* 底部操作栏 */
.bottom-bar {
position: fixed;
bottom: 0;
left: 0;
right: 0;
background-color: #ffffff;
padding-bottom: 20rpx;
border-radius: 40rpx 40rpx 0 0;
// padding: 20rpx 30rpx;
padding-bottom: calc(20rpx + env(safe-area-inset-bottom));
box-shadow: 0 -4rpx 20rpx rgba(0, 0, 0, 0.05);
z-index: 1000;
}
.my-products-wrapper {
display: flex;
justify-content: space-between;
flex-direction: row;
background: #FFF4E3;
border-radius: 40rpx;
padding: 16rpx 32rpx;
border-radius: 40rpx 40rpx 0 0;
}
.action-wrapper {
display: flex;
justify-content: space-between;
align-items: center;
flex: 1;
margin-left: 20rpx;
margin-right: 20rpx;
padding-top: 20rpx;
}
.my-products {
display: flex;
// flex-direction: column;
align-items: center;
justify-content: center;
gap: 4rpx;
min-width: 120rpx;
cursor: pointer;
&.full {
flex-direction: row;
gap: 8rpx;
padding: 16rpx 32rpx;
background-color: #f5f5f5;
border-radius: 40rpx;
}
.my-products-icon {
width: 40rpx;
height: 40rpx;
flex-shrink: 0;
}
.my-products-text {
margin-left: 10rpx;
font-size: 22rpx;
color: #A16300;
white-space: nowrap;
}
}
.price-info {
display: flex;
flex-direction: column;
// align-items: flex-end;
gap: 4rpx;
flex: 1;
margin: 0 20rpx;
}
.current-price {
font-size: 36rpx;
font-weight: 600;
color: #FF6B00;
}
.original-price {
font-size: 24rpx;
color: #999;
text-decoration: line-through;
}
.buy-button {
padding: 24rpx 60rpx;
background-color: #B8741A;
border-radius: 48rpx;
transition: all 0.3s;
&.disabled {
background-color: #ccc;
opacity: 0.6;
}
.buy-button-text {
font-size: 32rpx;
color: #ffffff;
font-weight: 600;
}
}
</style>