107 lines
4.4 KiB
Vue
107 lines
4.4 KiB
Vue
<template>
|
||
<view class="page">
|
||
<!-- 订单信息卡片 -->
|
||
<view class="order-card">
|
||
<text class="card-title">订单信息</text>
|
||
<view class="order-row">
|
||
<text class="label">年卡名称</text>
|
||
<text class="value">{{ cardName }}</text>
|
||
</view>
|
||
<view class="order-row">
|
||
<text class="label">有效期</text>
|
||
<text class="value">365天</text>
|
||
</view>
|
||
<view class="order-row">
|
||
<text class="label">价格</text>
|
||
<text class="value price">¥{{ price }}</text>
|
||
</view>
|
||
</view>
|
||
<!-- 支付方式 -->
|
||
<view class="pay-card">
|
||
<text class="card-title">支付方式</text>
|
||
<view class="pay-option active">
|
||
<text class="pay-icon">💳</text>
|
||
<text class="pay-name">模拟支付(测试)</text>
|
||
<text class="pay-check">✓</text>
|
||
</view>
|
||
</view>
|
||
<!-- 底部支付栏 -->
|
||
<view class="bottom-bar">
|
||
<view class="bottom-price">
|
||
<text class="label">应付金额</text>
|
||
<text class="value">¥{{ price }}</text>
|
||
</view>
|
||
<button class="btn-pay" @click="handlePay" :disabled="paying">
|
||
{{ paying ? '支付中...' : '确认支付' }}
|
||
</button>
|
||
</view>
|
||
</view>
|
||
</template>
|
||
|
||
<script setup lang="ts">
|
||
import { ref } from 'vue'
|
||
import { onLoad } from '@dcloudio/uni-app'
|
||
import { createOrder, mockPay } from '../../api/order'
|
||
import { showToast } from '../../../../utils'
|
||
|
||
const cardId = ref('')
|
||
const cardName = ref('')
|
||
const price = ref(0)
|
||
const paying = ref(false)
|
||
|
||
/** 页面加载时解析路由参数 */
|
||
onLoad((options) => {
|
||
cardId.value = options?.id || ''
|
||
cardName.value = decodeURIComponent(options?.name || '')
|
||
price.value = Number(options?.price || 0)
|
||
})
|
||
|
||
/** 执行支付流程 */
|
||
async function handlePay() {
|
||
if (!cardId.value) return
|
||
paying.value = true
|
||
try {
|
||
// 1. 创建订单
|
||
const order = await createOrder({ cardId: cardId.value })
|
||
// 2. 模拟支付
|
||
const payResult = await mockPay(order.id)
|
||
if (payResult.success) {
|
||
showToast('支付成功', 'success')
|
||
// 3. 支付成功后跳转激活页
|
||
setTimeout(() => {
|
||
uni.redirectTo({
|
||
url: `/packages/user/pages/card/activate?cardId=${cardId.value}&name=${encodeURIComponent(cardName.value)}`
|
||
})
|
||
}, 1500)
|
||
} else {
|
||
showToast('支付失败')
|
||
}
|
||
} catch (err: any) {
|
||
showToast(err.message || '支付失败')
|
||
} finally {
|
||
paying.value = false
|
||
}
|
||
}
|
||
</script>
|
||
|
||
<style lang="scss" scoped>
|
||
.page { min-height: 100vh; background: $color-background; padding: $spacing-3; padding-bottom: 140rpx; box-sizing: border-box; font-family: $font-family-display; }
|
||
.order-card, .pay-card { background: $color-card; border-radius: $radius-lg; padding: $spacing-3 $spacing-4; margin-bottom: $spacing-3; }
|
||
.card-title { font-size: $font-size-lg; font-weight: $font-weight-bold; color: $uv-content-color; display: block; margin-bottom: $spacing-3; padding-bottom: $spacing-2; border-bottom: $border-width solid $uv-border-color; }
|
||
.order-row { display: flex; justify-content: space-between; align-items: center; padding: $spacing-2 0; }
|
||
.label { font-size: $font-size-base; color: $uv-tips-color; }
|
||
.value { font-size: $font-size-base; color: $uv-content-color; }
|
||
.value.price { color: $color-price; font-weight: $font-weight-bold; font-size: $font-size-xl; }
|
||
.pay-option { display: flex; align-items: center; padding: $spacing-3 0; }
|
||
.pay-option.active { color: $uv-primary; }
|
||
.pay-icon { font-size: $font-size-xl; margin-right: $spacing-2; }
|
||
.pay-name { flex: 1; font-size: $font-size-base; }
|
||
.pay-check { font-size: $font-size-lg; color: $uv-primary; font-weight: $font-weight-bold; }
|
||
.bottom-bar { position: fixed; bottom: 0; left: 0; right: 0; background: $color-card; display: flex; align-items: center; padding: $spacing-2 $spacing-4; padding-bottom: calc(#{$spacing-2} + env(safe-area-inset-bottom)); border-top: $border-width solid $uv-border-color; }
|
||
.bottom-price { flex: 1; display: flex; flex-direction: column; }
|
||
.bottom-price .label { font-size: $font-size-xs; color: $uv-placeholder-color; }
|
||
.bottom-price .value { font-size: $font-size-2xl; color: $color-price; font-weight: $font-weight-bold; }
|
||
.btn-pay { background: $color-price; color: #fff; font-size: $font-size-lg; padding: $spacing-3 $spacing-8; border-radius: $radius-2xl; border: none; }
|
||
.btn-pay[disabled] { background: $uv-bg-color; }
|
||
</style>
|