peixue-dev/peidu/uniapp/user-package/pages/package/detail.vue

248 lines
5.2 KiB
Vue
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

<template>
<view class="detail-page">
<view class="package-header">
<text class="package-name">{{ pkg.packageName }}</text>
<view class="package-price">
<text class="price-symbol">¥</text>
<text class="price-value">{{ pkg.price }}</text>
</view>
</view>
<view class="package-info-card">
<view class="info-item">
<text class="label">套餐类型</text>
<text class="value">{{ getPackageTypeName(pkg.packageType) }}</text>
</view>
<view class="info-item" v-if="pkg.totalHours">
<text class="label">总时长</text>
<text class="value">{{ pkg.totalHours }}小时</text>
</view>
<view class="info-item" v-if="pkg.serviceCount">
<text class="label">服务次数</text>
<text class="value">{{ pkg.serviceCount }}</text>
</view>
<view class="info-item">
<text class="label">有效期</text>
<text class="value">{{ pkg.validDays }}</text>
</view>
</view>
<view class="package-desc-card">
<view class="card-title">套餐说明</view>
<text class="desc-text">{{ pkg.description }}</text>
</view>
<view class="bottom-bar">
<view class="price-info">
<text class="label">价格</text>
<text class="price">¥{{ pkg.price }}</text>
</view>
<button class="btn-purchase" @click="handlePurchase">立即购买</button>
</view>
</view>
</template>
<script>
import { packageApi } from '@/api/index.js'
export default {
data() {
return {
packageId: null,
pkg: {}
}
},
onLoad(options) {
this.packageId = options.id
this.loadPackageDetail()
},
methods: {
async loadPackageDetail() {
try {
uni.showLoading({ title: '加载中...' })
const res = await packageApi.getPackageDetail(this.packageId)
console.log('套餐详情响应:', res)
// 智能判断数据结构
let data = null
if (res.data) {
data = res.data
} else if (res.code === 200) {
data = res
} else {
data = res
}
if (data) {
this.pkg = data
} else {
throw new Error('数据格式错误')
}
} catch (e) {
console.error('加载套餐详情失败', e)
uni.showToast({
title: '加载失败',
icon: 'none'
})
} finally {
uni.hideLoading()
}
},
getPackageTypeName(type) {
const names = {
'trial': '体验套餐',
'newuser': '新用户套餐',
'time': '时长套餐',
'service': '服务套餐',
'combo': '组合套餐'
}
return names[type] || type
},
async handlePurchase() {
try {
uni.showLoading({ title: '处理中...' })
const res = await packageApi.purchasePackage({ packageId: this.packageId })
if (res.code === 200 || res.success) {
uni.showToast({
title: '购买成功',
icon: 'success'
})
setTimeout(() => {
uni.navigateBack()
}, 1500)
} else {
throw new Error(res.message || '购买失败')
}
} catch (e) {
console.error('购买失败', e)
uni.showToast({
title: e.message || '购买失败',
icon: 'none'
})
} finally {
uni.hideLoading()
}
}
}
}
</script>
<style lang="scss" scoped>
.detail-page {
min-height: 100vh;
background: #f5f5f5;
padding-bottom: 160rpx;
}
.package-header {
background: linear-gradient(135deg, #4a9b9f 0%, #3d8185 100%);
padding: 60rpx 40rpx;
color: #fff;
.package-name {
display: block;
font-size: 36rpx;
font-weight: bold;
margin-bottom: 20rpx;
}
.package-price {
.price-symbol {
font-size: 40rpx;
}
.price-value {
font-size: 72rpx;
font-weight: bold;
}
}
}
.package-info-card, .package-desc-card {
background: #fff;
margin: 20rpx 30rpx;
padding: 30rpx;
border-radius: 16rpx;
}
.info-item {
display: flex;
justify-content: space-between;
padding: 20rpx 0;
border-bottom: 1rpx solid #f0f0f0;
&:last-child {
border-bottom: none;
}
.label {
font-size: 28rpx;
color: #666;
}
.value {
font-size: 28rpx;
color: #333;
font-weight: 500;
}
}
.card-title {
font-size: 32rpx;
font-weight: bold;
color: #333;
margin-bottom: 20rpx;
}
.desc-text {
font-size: 28rpx;
color: #666;
line-height: 1.6;
}
.bottom-bar {
position: fixed;
bottom: 0;
left: 0;
right: 0;
background: #fff;
padding: 20rpx 30rpx;
box-shadow: 0 -4rpx 12rpx rgba(0, 0, 0, 0.05);
display: flex;
align-items: center;
.price-info {
flex: 1;
.label {
font-size: 28rpx;
color: #666;
}
.price {
font-size: 40rpx;
font-weight: bold;
color: #ff4d4f;
}
}
.btn-purchase {
width: 280rpx;
height: 88rpx;
line-height: 88rpx;
background: linear-gradient(135deg, #4a9b9f 0%, #3d8185 100%);
color: #fff;
border-radius: 44rpx;
font-size: 32rpx;
font-weight: bold;
border: none;
}
}
</style>