Files
cunkebao_v3/Store_vue/components/PackageDetail.vue

386 lines
7.6 KiB
Vue
Raw Normal View History

2025-04-09 09:34:27 +08:00
<template>
<view v-if="show" class="package-detail-container" style="margin-top: var(--status-bar-height);">
<!-- 头部 -->
<view class="header">
<view class="back-icon" @tap="closePage">
<u-icon name="arrow-left" color="#333" size="26"></u-icon>
</view>
<view class="title">{{packageData.name}}</view>
<view class="close-icon" @tap="closePage">
<u-icon name="close" color="#333" size="24"></u-icon>
</view>
</view>
<!-- 套餐价格 -->
<view class="price-card">
<view class="price-title">套餐价格</view>
<view class="price-content">
<view class="main-price">
<text class="price-symbol">¥</text>
<text class="price-value">{{packageData.price}}</text>
</view>
<view class="original-price-tag">原价</view>
</view>
<view class="original-price" v-if="packageData.originalPrice !== packageData.price">
<text class="crossed-price">¥{{packageData.originalPrice}}</text>
</view>
</view>
<!-- 套餐详情 -->
<view class="detail-card">
<view class="detail-title">套餐详情</view>
<view class="detail-item" v-for="item in packageData.details" :key="item.label">
<text class="detail-label">{{item.label}}</text>
<text class="detail-value">{{item.value}}</text>
</view>
</view>
<!-- 套餐特权 -->
<view class="privilege-card">
<view class="detail-title">套餐特权</view>
<view class="privilege-item" v-for="item in packageData.privileges" :key="item">
<view class="privilege-icon">
<u-icon name="checkmark" color="#0080ff" size="16"></u-icon>
</view>
<text class="privilege-text">{{item}}</text>
</view>
</view>
<!-- 立即购买按钮 -->
<view class="buy-button">
<u-button
type="primary"
text="立即购买"
shape="circle"
@click="handleBuy"
:custom-style="{
width: '90%',
height: '44px',
marginTop: '20px',
marginBottom: '30px'
}"
></u-button>
</view>
<!-- 购买说明 -->
<view class="purchase-info">
<text class="info-text">流量将在购买后24小时内接入</text>
</view>
</view>
</template>
<script>
import { trafficApi } from '../api/modules/traffic';
export default {
name: 'PackageDetail',
props: {
show: {
type: Boolean,
default: false
},
packageData: {
type: Object,
default: () => ({
id: 1,
name: '基础流量包',
price: 980,
originalPrice: 990,
specs: '20人/月·30天',
details: [
{ label: '每月流量', value: '20人/月' },
{ label: '套餐时长', value: '30天' },
{ label: '总流量', value: '600人' }
],
privileges: [
'引流到微信',
'每日流量报告',
'基础客户标签'
]
})
}
},
data() {
return {
// 订单信息
orderInfo: null,
// 购买状态
buying: false
}
},
methods: {
closePage() {
this.$emit('close');
},
async handleBuy() {
if (this.buying) return;
this.buying = true;
uni.showLoading({
title: '创建订单...',
mask: true
});
try {
// 调用创建订单接口
const response = await trafficApi.createOrder(this.packageData.id);
// 隐藏加载中
uni.hideLoading();
if (response.code === 200) {
this.orderInfo = response.data;
// 显示订单创建成功提示
uni.showToast({
title: '订单创建成功',
icon: 'success',
duration: 2000
});
// 模拟跳转到支付页面
setTimeout(() => {
this.showPaymentModal();
}, 1000);
} else {
// 显示错误信息
uni.showToast({
title: response.msg || '创建订单失败',
icon: 'none',
duration: 2000
});
}
} catch (err) {
// 隐藏加载中
uni.hideLoading();
// 显示错误信息
uni.showToast({
title: '网络异常,请稍后重试',
icon: 'none',
duration: 2000
});
console.error('创建订单错误:', err);
} finally {
this.buying = false;
}
},
// 显示支付弹窗
showPaymentModal() {
if (!this.orderInfo) return;
uni.showModal({
title: '订单支付',
content: `订单号: ${this.orderInfo.orderNo}\n金额: ¥${this.orderInfo.amount}\n支付方式: ${this.orderInfo.payType === 'wechat' ? '微信支付' : '其他支付方式'}`,
confirmText: '去支付',
cancelText: '取消',
success: (res) => {
if (res.confirm) {
// 模拟支付成功
uni.showLoading({
title: '支付处理中'
});
setTimeout(() => {
uni.hideLoading();
uni.showToast({
title: '支付成功',
icon: 'success',
duration: 2000
});
// 关闭页面
setTimeout(() => {
this.closePage();
// 触发购买成功事件,通知父组件刷新数据
this.$emit('buy-success');
}, 1500);
}, 2000);
}
}
});
}
}
}
</script>
<style lang="scss">
.package-detail-container {
position: fixed;
top: 0;
right: 0;
width: 100%;
height: 100%;
background-color: #f5f7fa;
z-index: 10000;
overflow-y: auto;
transform-origin: right;
animation: slideInFromRight 0.3s ease;
}
@keyframes slideInFromRight {
from {
transform: translateX(100%);
}
to {
transform: translateX(0);
}
}
.header {
display: flex;
justify-content: space-between;
align-items: center;
padding: 12px 15px;
background-color: #fff;
border-bottom: 1px solid #eee;
position: sticky;
top: 0;
z-index: 1;
}
.back-icon {
width: 60px;
display: flex;
align-items: center;
}
.title {
font-size: 17px;
font-weight: 500;
flex: 1;
text-align: center;
}
.close-icon {
width: 60px;
display: flex;
justify-content: flex-end;
}
.price-card {
margin: 15px;
padding: 15px;
background-color: #e6f4ff;
border-radius: 10px;
}
.price-title {
font-size: 15px;
font-weight: 500;
color: #333;
margin-bottom: 10px;
}
.price-content {
display: flex;
align-items: center;
}
.main-price {
display: flex;
align-items: baseline;
}
.price-symbol {
font-size: 18px;
font-weight: bold;
color: #0080ff;
}
.price-value {
font-size: 28px;
font-weight: bold;
color: #0080ff;
}
.original-price-tag {
margin-left: 15px;
padding: 2px 10px;
background-color: #fff;
border-radius: 4px;
font-size: 12px;
color: #666;
}
.original-price {
margin-top: 5px;
}
.crossed-price {
font-size: 14px;
color: #999;
text-decoration: line-through;
}
.detail-card, .privilege-card {
margin: 15px;
padding: 15px;
background-color: #fff;
border-radius: 10px;
box-shadow: 0 1px 3px rgba(0, 0, 0, 0.05);
}
.detail-title {
font-size: 15px;
font-weight: 500;
color: #333;
margin-bottom: 15px;
}
.detail-item {
display: flex;
justify-content: space-between;
padding: 10px 0;
border-bottom: 1px solid #f5f5f5;
}
.detail-item:last-child {
border-bottom: none;
}
.detail-label {
color: #333;
font-size: 14px;
}
.detail-value {
color: #666;
font-size: 14px;
}
.privilege-item {
display: flex;
align-items: center;
margin-bottom: 12px;
}
.privilege-icon {
margin-right: 8px;
display: flex;
align-items: center;
}
.privilege-text {
font-size: 14px;
color: #333;
}
.buy-button {
display: flex;
justify-content: center;
margin-top: 20px;
}
.purchase-info {
text-align: center;
margin-bottom: 30px;
}
.info-text {
font-size: 12px;
color: #999;
}
</style>