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;
+ }
+}