Files
cashier_wx/components/paymentMethod.vue

301 lines
7.0 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="paymentMethod">
<view class="paymentMethod_content">
<view class="paymentMethod_title">支付方式</view>
<up-radio-group v-model="radiovalue.type" iconPlacement="right" @change="groupChanges" :size="28"
placement="column">
<block v-for="(item, index) in paymentMethodList" :key="index">
<view class="method_list" @click="groupChanges(item.type)"
:class="{ disabled: returnDisabled(item) }">
<view class="method_list_top">
<view class="method_list_top_left">
<image class="icon" :src="item.url" mode="aspectFill" />
<view class="method_list_top_cen">
<view class="name"> {{ item.name }} </view>
<view class="method_list_bom" v-if="item.name == '余额支付'">
<text class="balance">
当前余额{{ shopUserInfo ? shopUserInfo.amount || 0 : 0 }}</text>
<text class="topUpNow" @click="goRecharge">去充值</text>
</view>
</view>
</view>
<up-radio :disabled="returnDisabled(item)" activeColor="#E8AD7B" icon-size="18" size="18"
:name="item.type">
</up-radio>
</view>
</view>
</block>
</up-radio-group>
</view>
<slot name="bottom"></slot>
</view>
</template>
<script setup>
import {
ref,
reactive,
defineProps,
computed,
defineEmits,
watch,
watchEffect,
defineExpose,
onMounted // 新增:用于初始化默认值
} from "vue";
const props = defineProps({
rechargeFreeChecked: {
type: Boolean,
default: false,
},
payAmount: {
type: Number,
default: 0,
},
freeCheck: {
type: Boolean,
default: false,
},
changeFreeenable: {
type: Boolean,
default: false,
},
disablePayType: {
type: Array,
default: () => [],
},
shopUserInfo:{
type: Object,
default: () => {
return{
amount:0
}
},
}
});
// 工具函数 - 深拷贝对象(切断引用)
const deepClone = (obj) => {
return JSON.parse(JSON.stringify(obj));
};
function returnDisabled(item) {
return props.disablePayType.includes(item.name);
}
const emits = defineEmits(["customevent", "groupChange"]);
// 支付方式列表(保持不变)
const paymentMethodList = ref([
// #ifdef MP-WEIXIN
{
name: "微信支付",
type: 2,
url: "https://czg-qr-order.oss-cn-beijing.aliyuncs.com/confirmOrder/weChat.png",
payType: "wechatPay",
},
// #endif
// #ifdef MP-ALIPAY
{
name: "支付宝支付",
type: 3,
url: "https://czg-qr-order.oss-cn-beijing.aliyuncs.com/confirmOrder/alipay.png",
payType: "aliPay",
},
// #endif
{
name: "余额支付",
type: 1,
url: "https://czg-qr-order.oss-cn-beijing.aliyuncs.com/drder/wechat.png",
payType: "accountPay",
},
]);
// 修复核心defineModel 先声明为空对象(无本地变量依赖)
const radiovalue = defineModel({
type: Object,
default: () => ({}), // 基础默认值,不引用任何本地变量
});
// 新增:在 onMounted 中初始化 defineModel 的真实默认值
onMounted(() => {
// 1. 找到默认的微信支付项(兼容不同平台)
let defaultItem = paymentMethodList.value.find(item => item.type === 2);
// 兜底:如果没有微信支付(如支付宝平台),取第一个可用项
if (!defaultItem) {
defaultItem = paymentMethodList.value[0];
}
// 2. 深拷贝后赋值,避免引用污染
if (defaultItem) {
radiovalue.value = deepClone(defaultItem);
}
// 3. 触发一次 disablePayType 的监听逻辑(确保初始值符合禁用规则)
const canUsePayType = paymentMethodList.value.filter((item) => {
return !props.disablePayType.includes(item.name);
});
if (canUsePayType.length > 0 && !canUsePayType.find(v => v.type === radiovalue.value.type)) {
radiovalue.value = deepClone(canUsePayType[0]);
}
});
// 修复watch 监听 disablePayType调整逻辑依赖 radiovalue 已初始化)
watch(
() => props.disablePayType,
(newval) => {
// 加兜底radiovalue 未初始化时不处理
if (Object.keys(radiovalue.value).length === 0) return;
const canUsePayType = paymentMethodList.value.filter((item) => {
return !newval.includes(item.name);
});
if (canUsePayType.length === 0) return;
const currentValid = canUsePayType.find((v) => v.type === radiovalue.value.type);
if (!currentValid) {
radiovalue.value = deepClone(canUsePayType[0]);
}
},
{
immediate: false, // 改为 false避免在 radiovalue 初始化前执行
deep: true,
}
);
// 支付方式切换逻辑(保持之前的修复)
const groupChanges = (type) => {
console.log('type原始入参', type);
const typeNum = Number(type);
if (isNaN(typeNum)) {
uni.showToast({ title: "支付方式选择异常", icon: "none" });
return;
}
if (props.freeCheck && typeNum === 1) {
return;
}
console.log('paymentMethodList', paymentMethodList.value);
const item = paymentMethodList.value.find((v) => v.type === typeNum);
console.log('匹配到的item', item);
if (!item) {
uni.showToast({ title: "当前支付方式不存在", icon: "none" });
return;
}
if (returnDisabled(item)) {
uni.showToast({ title: "当前支付方式不可用", icon: "none" });
return;
}
radiovalue.value = deepClone(item);
};
// 监听 radiovalue 变化触发事件
watch(() => radiovalue.value.type, (newval) => {
if (newval) { // 加兜底:避免初始值为空时触发
emits("groupChange", radiovalue.value);
}
});
// 去充值
const goRecharge = () => {
if (props.disablePayType.includes("余额支付")) {
return;
}
uni.navigateTo({
url: `/pages/user/member/czzx?shopId=${props.shopUserInfo?.shopId || ''}`,
});
};
defineExpose({
groupChanges,
});
</script>
<style lang="scss">
.paymentMethod {
box-sizing: border-box;
margin-top: 30rpx;
background-color: #fff;
border-radius: 20rpx;
.paymentMethod_content {
padding: 30rpx 30rpx 0 30rpx;
box-sizing: border-box;
.paymentMethod_title {
font-weight: 500;
font-size: 32rpx;
color: #333333;
box-sizing: border-box;
}
.method_list {
padding: 40rpx 0;
box-sizing: border-box;
&.disabled {
opacity: 0.6;
}
.method_list_top {
display: flex;
justify-content: space-between;
.method_list_top_left {
display: flex;
align-items: center;
.icon {
width: 54.67rpx !important;
height: 48rpx !important;
margin-right: 22rpx;
}
.name {
font-size: 32rpx;
font-weight: 500;
color: #333;
}
.method_list_top_cen {
display: flex;
flex-direction: column;
}
}
}
.method_list_bom {
display: flex;
align-items: center;
.balance {
margin-right: 20rpx;
font-size: 24rpx;
}
.topUpNow {
color: #ff803d;
font-size: 28rpx;
}
}
}
.method_list:nth-child(odd) {
border-bottom: 2rpx solid #e5e5e5;
}
.method_list:nth-child(2) {
padding-bottom: 22rpx;
}
}
}
</style>