feat: 购买次数卡弹窗新增数量选择功能并同步更新购买接口。
This commit is contained in:
parent
4252a0ed61
commit
a8fa8bf557
@ -354,8 +354,9 @@ export function getGamePassPackages(activity_id) {
|
|||||||
/**
|
/**
|
||||||
* 购买次数卡套餐
|
* 购买次数卡套餐
|
||||||
* @param {number} package_id - 套餐ID
|
* @param {number} package_id - 套餐ID
|
||||||
|
* @param {number} count - 购买数量
|
||||||
*/
|
*/
|
||||||
export function purchaseGamePass(package_id) {
|
export function purchaseGamePass(package_id, count = 1) {
|
||||||
return authRequest({ url: '/api/app/game-passes/purchase', method: 'POST', data: { package_id } })
|
return authRequest({ url: '/api/app/game-passes/purchase', method: 'POST', data: { package_id, count } })
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@ -37,7 +37,17 @@
|
|||||||
<view class="pkg-original-price" v-if="pkg.original_price > pkg.price">
|
<view class="pkg-original-price" v-if="pkg.original_price > pkg.price">
|
||||||
¥{{ (pkg.original_price / 100).toFixed(2) }}
|
¥{{ (pkg.original_price / 100).toFixed(2) }}
|
||||||
</view>
|
</view>
|
||||||
<button class="btn-buy" :loading="purchasingId === pkg.id">购买</button>
|
|
||||||
|
<view class="action-row">
|
||||||
|
<view class="stepper" @tap.stop>
|
||||||
|
<text class="step-btn minus" @tap="updateCount(pkg.id, -1)">-</text>
|
||||||
|
<text class="step-val">{{ counts[pkg.id] || 1 }}</text>
|
||||||
|
<text class="step-btn plus" @tap="updateCount(pkg.id, 1)">+</text>
|
||||||
|
</view>
|
||||||
|
<button class="btn-buy" :loading="purchasingId === pkg.id" @tap.stop="handlePurchase(pkg)">
|
||||||
|
购买
|
||||||
|
</button>
|
||||||
|
</view>
|
||||||
</view>
|
</view>
|
||||||
</view>
|
</view>
|
||||||
</scroll-view>
|
</scroll-view>
|
||||||
@ -60,6 +70,15 @@ const emit = defineEmits(['update:visible', 'success'])
|
|||||||
const loading = ref(false)
|
const loading = ref(false)
|
||||||
const packages = ref([])
|
const packages = ref([])
|
||||||
const purchasingId = ref(null)
|
const purchasingId = ref(null)
|
||||||
|
const counts = ref({})
|
||||||
|
|
||||||
|
function updateCount(pkgId, delta) {
|
||||||
|
const current = counts.value[pkgId] || 1
|
||||||
|
const newVal = current + delta
|
||||||
|
if (newVal >= 1 && newVal <= 99) {
|
||||||
|
counts.value[pkgId] = newVal
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
watch(() => props.visible, (val) => {
|
watch(() => props.visible, (val) => {
|
||||||
if (val) {
|
if (val) {
|
||||||
@ -78,6 +97,11 @@ async function fetchPackages() {
|
|||||||
else if (res && Array.isArray(res.list)) list = res.list
|
else if (res && Array.isArray(res.list)) list = res.list
|
||||||
else if (res && Array.isArray(res.data)) list = res.data
|
else if (res && Array.isArray(res.data)) list = res.data
|
||||||
|
|
||||||
|
// 初始化counts
|
||||||
|
const countMap = {}
|
||||||
|
list.forEach(p => countMap[p.id] = 1)
|
||||||
|
counts.value = countMap
|
||||||
|
|
||||||
// 简单处理:给第一个或最优惠的打标签
|
// 简单处理:给第一个或最优惠的打标签
|
||||||
// 这里随机模拟一下 "热销" 或计算折扣力度
|
// 这里随机模拟一下 "热销" 或计算折扣力度
|
||||||
packages.value = list.map(p => {
|
packages.value = list.map(p => {
|
||||||
@ -112,7 +136,8 @@ async function handlePurchase(pkg) {
|
|||||||
// 如果返回 pay_params,则直接支付
|
// 如果返回 pay_params,则直接支付
|
||||||
|
|
||||||
// 假设 API 返回 { order_no, ... }
|
// 假设 API 返回 { order_no, ... }
|
||||||
const res = await purchaseGamePass(pkg.id)
|
const count = counts.value[pkg.id] || 1
|
||||||
|
const res = await purchaseGamePass(pkg.id, count)
|
||||||
const orderNo = res.order_no || res.orderNo
|
const orderNo = res.order_no || res.orderNo
|
||||||
if (!orderNo) throw new Error('下单失败')
|
if (!orderNo) throw new Error('下单失败')
|
||||||
|
|
||||||
@ -290,10 +315,10 @@ function handleClose() {
|
|||||||
background: linear-gradient(90deg, #FF6B00, #FF9F43);
|
background: linear-gradient(90deg, #FF6B00, #FF9F43);
|
||||||
color: #FFF;
|
color: #FFF;
|
||||||
font-size: 24rpx;
|
font-size: 24rpx;
|
||||||
padding: 0 24rpx;
|
padding: 0 20rpx;
|
||||||
height: 56rpx;
|
height: 52rpx;
|
||||||
line-height: 56rpx;
|
line-height: 52rpx;
|
||||||
border-radius: 28rpx;
|
border-radius: 26rpx;
|
||||||
border: none;
|
border: none;
|
||||||
font-weight: 600;
|
font-weight: 600;
|
||||||
|
|
||||||
@ -301,4 +326,41 @@ function handleClose() {
|
|||||||
opacity: 0.8;
|
opacity: 0.8;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
.action-row {
|
||||||
|
display: flex;
|
||||||
|
align-items: center;
|
||||||
|
gap: 12rpx;
|
||||||
|
margin-top: 8rpx;
|
||||||
|
}
|
||||||
|
|
||||||
|
.stepper {
|
||||||
|
display: flex;
|
||||||
|
align-items: center;
|
||||||
|
background: #F3F4F6;
|
||||||
|
border-radius: 12rpx;
|
||||||
|
padding: 2rpx;
|
||||||
|
|
||||||
|
.step-btn {
|
||||||
|
width: 44rpx;
|
||||||
|
height: 44rpx;
|
||||||
|
line-height: 40rpx;
|
||||||
|
text-align: center;
|
||||||
|
font-size: 32rpx;
|
||||||
|
color: #4B5563;
|
||||||
|
font-weight: 300;
|
||||||
|
}
|
||||||
|
|
||||||
|
.minus {
|
||||||
|
color: #9CA3AF;
|
||||||
|
}
|
||||||
|
|
||||||
|
.step-val {
|
||||||
|
width: 40rpx;
|
||||||
|
text-align: center;
|
||||||
|
font-size: 26rpx;
|
||||||
|
font-weight: bold;
|
||||||
|
color: #1F2937;
|
||||||
|
}
|
||||||
|
}
|
||||||
</style>
|
</style>
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user