From a8fa8bf557e8156078679b1b33a88dd5ec0674d2 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E9=82=B9=E6=96=B9=E6=88=90?= Date: Fri, 2 Jan 2026 16:32:12 +0800 Subject: [PATCH] =?UTF-8?q?feat:=20=E8=B4=AD=E4=B9=B0=E6=AC=A1=E6=95=B0?= =?UTF-8?q?=E5=8D=A1=E5=BC=B9=E7=AA=97=E6=96=B0=E5=A2=9E=E6=95=B0=E9=87=8F?= =?UTF-8?q?=E9=80=89=E6=8B=A9=E5=8A=9F=E8=83=BD=E5=B9=B6=E5=90=8C=E6=AD=A5?= =?UTF-8?q?=E6=9B=B4=E6=96=B0=E8=B4=AD=E4=B9=B0=E6=8E=A5=E5=8F=A3=E3=80=82?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- api/appUser.js | 5 +- components/GamePassPurchasePopup.vue | 74 +++++++++++++++++++++++++--- 2 files changed, 71 insertions(+), 8 deletions(-) diff --git a/api/appUser.js b/api/appUser.js index 1621d76..bd238f3 100644 --- a/api/appUser.js +++ b/api/appUser.js @@ -354,8 +354,9 @@ export function getGamePassPackages(activity_id) { /** * 购买次数卡套餐 * @param {number} package_id - 套餐ID + * @param {number} count - 购买数量 */ -export function purchaseGamePass(package_id) { - return authRequest({ url: '/api/app/game-passes/purchase', method: 'POST', data: { package_id } }) +export function purchaseGamePass(package_id, count = 1) { + return authRequest({ url: '/api/app/game-passes/purchase', method: 'POST', data: { package_id, count } }) } diff --git a/components/GamePassPurchasePopup.vue b/components/GamePassPurchasePopup.vue index 908f060..0cb7bd7 100644 --- a/components/GamePassPurchasePopup.vue +++ b/components/GamePassPurchasePopup.vue @@ -37,7 +37,17 @@ ¥{{ (pkg.original_price / 100).toFixed(2) }} - + + + + - + {{ counts[pkg.id] || 1 }} + + + + + @@ -60,6 +70,15 @@ const emit = defineEmits(['update:visible', 'success']) const loading = ref(false) const packages = ref([]) 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) => { 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.data)) list = res.data + // 初始化counts + const countMap = {} + list.forEach(p => countMap[p.id] = 1) + counts.value = countMap + // 简单处理:给第一个或最优惠的打标签 // 这里随机模拟一下 "热销" 或计算折扣力度 packages.value = list.map(p => { @@ -112,7 +136,8 @@ async function handlePurchase(pkg) { // 如果返回 pay_params,则直接支付 // 假设 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 if (!orderNo) throw new Error('下单失败') @@ -290,10 +315,10 @@ function handleClose() { background: linear-gradient(90deg, #FF6B00, #FF9F43); color: #FFF; font-size: 24rpx; - padding: 0 24rpx; - height: 56rpx; - line-height: 56rpx; - border-radius: 28rpx; + padding: 0 20rpx; + height: 52rpx; + line-height: 52rpx; + border-radius: 26rpx; border: none; font-weight: 600; @@ -301,4 +326,41 @@ function handleClose() { 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; + } +}