HaniBlindBox/honey_box/components/order-confirm-popup/order-confirm-popup.vue
2026-02-03 22:58:58 +08:00

381 lines
8.3 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>
<uni-popup ref="popup" type="bottom">
<view class="order-popup">
<!-- 头部 -->
<view class="popup-header">
<text class="title">确认订单</text>
<view class="close-btn" @click="$emit('close')">×</view>
</view>
<!-- 商品信息 -->
<view class="goods-card">
<view class="goods-img">
<image :src="orderData.goods.imgurl_detail" mode="aspectFill"></image>
</view>
<view class="goods-info">
<view class="goods-title">{{ orderData.goods.title }}</view>
<view class="goods-meta">
<text>类型明信片</text>
<text class="qty">×{{ orderData.goods.prize_num }}</text>
</view>
<view class="goods-price">
<template v-if="pageData.goods.type != 5">¥</template>
<text>{{ orderData.goods.is_shou_zhe == 1 ? orderData.goods.shou_zhe_price : orderData.goods.price }}</text>
<template v-if="pageData.goods.type == 5">{{ currencyName2 }}</template>
</view>
</view>
</view>
<!-- 优惠券 -->
<view v-if="pay_coupon" class="option-row" @click="toCoupon">
<text class="label">优惠券</text>
<view class="row-right">
<text class="value">{{ couponData && orderData.coupon_price > 0 ? `-¥${couponData.price}` : '未选择' }}</text>
<text class="arrow"></text>
</view>
</view>
<!-- 货币选项 -->
<view v-if="pay_currency" class="option-row" @click="changePayMethod('useIntegral')">
<view class="label-with-tip">
<text class="label">{{ currencyName }}</text>
<text class="tip">(剩余{{ orderData.integral }}个)</text>
</view>
<view class="radio" :class="{ active: useIntegral }"></view>
</view>
<view v-if="pay_balance" class="option-row" @click="changePayMethod('useMoney')">
<view class="label-with-tip">
<text class="label">使用{{ balanceName }}抵扣</text>
<text class="tip">(剩余{{ orderData.money }}个)</text>
</view>
<view class="radio" :class="{ active: useMoney }"></view>
</view>
<view v-if="pay_currency2" class="option-row" @click="changePayMethod('useMoney2')">
<view class="label-with-tip">
<text class="label">使用{{ currencyName2 }}抵扣</text>
<text class="tip">(剩余{{ orderData.score }}个)</text>
</view>
<view class="radio" :class="{ active: useMoney2 }"></view>
</view>
<!-- 售前售后须知 -->
<view class="notice-row" @click="showRule">
<text class="notice-text">售前·售后须知</text>
<text class="arrow"></text>
</view>
<!-- 支付按钮 -->
<view class="pay-btn" @click="$emit('confirm')">
<text>确认支付</text>
<text v-if="pageData.goods.type != 5"> ¥{{ orderData.price }}</text>
<text v-else> {{ (orderData.use_score / 100).toFixed(2) }}{{ currencyName2 }}</text>
</view>
<!-- 协议 -->
<view class="agree-row" @click="$emit('toggle-agree')">
<view class="check-icon" :class="{ active: isAgree }"></view>
<text class="agree-text">我已满18岁阅读即同意用户协议隐私政策</text>
</view>
</view>
</uni-popup>
</template>
<script>
export default {
name: "OrderConfirmPopup",
props: {
orderData: { type: Object, required: true },
pageData: { type: Object, required: true },
useMoney: { type: Boolean, default: true },
useMoney2: { type: Boolean, default: true },
useIntegral: { type: Boolean, default: true },
couponData: { type: [Object, String], default: () => null },
isAgree: { type: Boolean, default: true },
sendRuleData: { type: String, default: '' },
buyNum: { type: Number, default: 1 },
effectSwitch: { type: Boolean, default: false }
},
data() {
return {
currencyName: '',
currencyName2: '',
balanceName: '',
pay_balance: 1,
pay_coupon: 1,
pay_currency: 1,
pay_currency2: 1,
pay_wechat: 1,
is_deduction: 1
}
},
created() {
this.currencyName = this.$config.getAppSetting('currency1_name') || 'HH币';
this.currencyName2 = this.$config.getAppSetting('currency2_name') || '哈尼券';
this.balanceName = this.$config.getAppSetting('balance_name') || '钻石';
let goodType = this.$config.getGoodTypeFind(this.pageData.goods.type);
this.setPayType(goodType);
},
methods: {
setPayType(good_extend) {
if (good_extend) {
this.pay_balance = good_extend.pay_balance;
this.pay_coupon = good_extend.pay_coupon;
this.pay_currency = good_extend.pay_currency;
this.pay_currency2 = good_extend.pay_currency2;
this.pay_wechat = good_extend.pay_wechat;
this.is_deduction = good_extend.is_deduction;
}
},
toCoupon() {
if (this.pageData?.limitInfo?.coupon_limit > 0 && this.pageData.limitInfo.user_coupon_remaining <= 0) {
this.$c.msg("今日使用优惠券已达到上限");
return;
}
this.$emit('to-coupon');
},
showRule() {
this.$c.to({ url: '/pages/guize/guize?type=6' });
},
open() {
if (this.orderData?.goods_extend) {
this.setPayType(this.orderData.goods_extend);
}
this.$refs.popup.open();
},
close() {
this.$refs.popup.close();
},
changePayMethod(method) {
if (this.is_deduction == 0) {
let count = [this.pay_balance, this.pay_currency, this.pay_currency2, this.pay_wechat].filter(v => v).length;
if (count <= 1) return;
}
this.$emit('change-pay', method);
}
}
}
</script>
<style lang="scss" scoped>
.order-popup {
background: #FFFFFF;
border-radius: 24rpx 24rpx 0 0;
padding: 0 32rpx 60rpx;
}
.popup-header {
display: flex;
align-items: center;
justify-content: center;
padding: 32rpx 0;
position: relative;
.title {
font-size: 32rpx;
font-weight: 500;
color: #333;
}
.close-btn {
position: absolute;
right: 0;
font-size: 48rpx;
color: #999;
line-height: 1;
}
}
.goods-card {
display: flex;
padding: 24rpx;
background: #F7F7F7;
border-radius: 16rpx;
margin-bottom: 24rpx;
.goods-img {
width: 160rpx;
height: 160rpx;
border-radius: 12rpx;
overflow: hidden;
background: #EEE;
image {
width: 100%;
height: 100%;
}
}
.goods-info {
flex: 1;
margin-left: 24rpx;
display: flex;
flex-direction: column;
justify-content: space-between;
.goods-title {
font-size: 28rpx;
color: #333;
font-weight: 500;
}
.goods-meta {
font-size: 24rpx;
color: #999;
display: flex;
justify-content: space-between;
.qty {
color: #666;
}
}
.goods-price {
font-size: 32rpx;
color: #333;
font-weight: 600;
}
}
}
.option-row {
display: flex;
align-items: center;
justify-content: space-between;
padding: 28rpx 0;
border-bottom: 1rpx solid #F0F0F0;
.label {
font-size: 28rpx;
color: #333;
}
.label-with-tip {
display: flex;
align-items: center;
.label {
font-size: 28rpx;
color: #333;
}
.tip {
font-size: 24rpx;
color: #999;
margin-left: 8rpx;
}
}
.row-right {
display: flex;
align-items: center;
.value {
font-size: 28rpx;
color: #999;
}
.arrow {
font-size: 32rpx;
color: #CCC;
margin-left: 8rpx;
}
}
.radio {
width: 40rpx;
height: 40rpx;
border: 2rpx solid #DDD;
border-radius: 50%;
&.active {
border-color: #03D8F4;
background: #03D8F4;
position: relative;
&::after {
content: '';
position: absolute;
top: 50%;
left: 50%;
transform: translate(-50%, -50%);
width: 16rpx;
height: 16rpx;
background: #FFF;
border-radius: 50%;
}
}
}
}
.notice-row {
display: flex;
align-items: center;
justify-content: space-between;
padding: 24rpx;
background: #E8F9E9;
border-radius: 12rpx;
margin: 24rpx 0;
.notice-text {
font-size: 28rpx;
color: #2DB84D;
}
.arrow {
font-size: 32rpx;
color: #2DB84D;
}
}
.pay-btn {
width: 100%;
height: 96rpx;
background: #03D8F4;
border-radius: 14rpx;
display: flex;
align-items: center;
justify-content: center;
font-size: 32rpx;
font-weight: 500;
color: #404040;
margin-bottom: 24rpx;
}
.agree-row {
display: flex;
align-items: center;
justify-content: center;
.check-icon {
width: 32rpx;
height: 32rpx;
border: 2rpx solid #DDD;
border-radius: 50%;
margin-right: 12rpx;
&.active {
border-color: #03D8F4;
background: #03D8F4;
position: relative;
&::after {
content: '✓';
position: absolute;
top: 50%;
left: 50%;
transform: translate(-50%, -50%);
font-size: 20rpx;
color: #FFF;
}
}
}
.agree-text {
font-size: 24rpx;
color: #999;
}
}
</style>