feat: migrate comprehensive venue module
This commit is contained in:
@@ -0,0 +1,171 @@
|
||||
<template>
|
||||
<view class="tickets-page container page-bottom-safe" v-if="product">
|
||||
<view class="product-card card">
|
||||
<view class="product-head">
|
||||
<view>
|
||||
<text class="product-title">篮球门票</text>
|
||||
<text class="product-subtitle">购买后进入会员权益账户,到馆由前台核销。</text>
|
||||
</view>
|
||||
</view>
|
||||
<view class="price-block">
|
||||
<text class="unit-price">¥{{ product.unit_price }}</text>
|
||||
<text class="unit-label">/ 次</text>
|
||||
</view>
|
||||
</view>
|
||||
|
||||
<view class="card count-card">
|
||||
<text class="card-title">购买次数</text>
|
||||
<view class="stepper-row">
|
||||
<button class="step-btn" @tap="decrease">-</button>
|
||||
<text class="quantity">{{ quantity }}</text>
|
||||
<button class="step-btn" @tap="increase">+</button>
|
||||
</view>
|
||||
<view class="amount-row">
|
||||
<text>合计金额</text>
|
||||
<text>¥{{ totalAmount }}</text>
|
||||
</view>
|
||||
</view>
|
||||
|
||||
<view class="fixed-action-bar">
|
||||
<view class="bar-price">
|
||||
<text class="bar-label">合计</text>
|
||||
<text class="price-text">¥{{ totalAmount }}</text>
|
||||
</view>
|
||||
<button class="primary-button submit-btn" :disabled="isSubmitting || !product.is_active" @tap="submit">
|
||||
立即购买
|
||||
</button>
|
||||
</view>
|
||||
</view>
|
||||
</template>
|
||||
|
||||
<script setup>
|
||||
import { computed, onMounted, ref } from 'vue'
|
||||
import { ticketApi } from '@/modules/comprehensive/api/ticket'
|
||||
import { multiplyAmount } from '@/modules/comprehensive/utils/money'
|
||||
|
||||
const product = ref(null)
|
||||
const quantity = ref(1)
|
||||
const isSubmitting = ref(false)
|
||||
|
||||
const totalAmount = computed(() => product.value ? multiplyAmount(product.value.unit_price, quantity.value) : '0.00')
|
||||
|
||||
onMounted(async () => {
|
||||
product.value = await ticketApi.getTicketProduct()
|
||||
})
|
||||
|
||||
const decrease = () => {
|
||||
quantity.value = Math.max(1, quantity.value - 1)
|
||||
}
|
||||
|
||||
const increase = () => {
|
||||
quantity.value += 1
|
||||
}
|
||||
|
||||
const submit = async () => {
|
||||
if (isSubmitting.value || !product.value?.is_active) return
|
||||
isSubmitting.value = true
|
||||
try {
|
||||
const data = await ticketApi.createTicketOrder(quantity.value)
|
||||
uni.navigateTo({ url: `/pages/comprehensive/pay/index?order_id=${data.order.id}` })
|
||||
} finally {
|
||||
isSubmitting.value = false
|
||||
}
|
||||
}
|
||||
</script>
|
||||
|
||||
<style lang="scss" scoped>
|
||||
.product-card,
|
||||
.count-card {
|
||||
margin-bottom: $spacing-md;
|
||||
}
|
||||
|
||||
.product-head,
|
||||
.amount-row,
|
||||
.stepper-row {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: space-between;
|
||||
gap: $spacing-md;
|
||||
}
|
||||
|
||||
.product-title,
|
||||
.card-title {
|
||||
display: block;
|
||||
color: $text-color-main;
|
||||
font-size: 34rpx;
|
||||
font-weight: 900;
|
||||
}
|
||||
|
||||
.product-subtitle {
|
||||
display: block;
|
||||
margin-top: $spacing-xs;
|
||||
color: $text-color-muted;
|
||||
font-size: 24rpx;
|
||||
line-height: 1.6;
|
||||
}
|
||||
|
||||
.price-block {
|
||||
margin-top: $spacing-xl;
|
||||
}
|
||||
|
||||
.unit-price {
|
||||
color: $text-color-main;
|
||||
font-size: 64rpx;
|
||||
font-weight: 900;
|
||||
}
|
||||
|
||||
.unit-label {
|
||||
color: $text-color-muted;
|
||||
font-size: 26rpx;
|
||||
}
|
||||
|
||||
.stepper-row {
|
||||
margin: $spacing-lg 0;
|
||||
}
|
||||
|
||||
.step-btn {
|
||||
width: 86rpx;
|
||||
height: 70rpx;
|
||||
border-radius: $border-radius-base;
|
||||
background: $text-color-main;
|
||||
color: #FFFFFF;
|
||||
font-size: 38rpx;
|
||||
font-weight: 900;
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
}
|
||||
|
||||
.quantity {
|
||||
color: $text-color-main;
|
||||
font-size: 42rpx;
|
||||
font-weight: 900;
|
||||
}
|
||||
|
||||
.amount-row {
|
||||
padding-top: $spacing-md;
|
||||
border-top: 1rpx solid $bg-color-hover;
|
||||
color: $text-color-muted;
|
||||
font-size: 26rpx;
|
||||
}
|
||||
|
||||
.amount-row text:last-child {
|
||||
color: $text-color-main;
|
||||
font-size: 34rpx;
|
||||
font-weight: 900;
|
||||
}
|
||||
|
||||
.bar-price {
|
||||
flex: 1;
|
||||
}
|
||||
|
||||
.bar-label {
|
||||
display: block;
|
||||
color: $text-color-light;
|
||||
font-size: 22rpx;
|
||||
}
|
||||
|
||||
.submit-btn {
|
||||
width: 320rpx;
|
||||
}
|
||||
</style>
|
||||
Reference in New Issue
Block a user