217 lines
5.0 KiB
Vue
217 lines
5.0 KiB
Vue
<template>
|
||
<uni-popup ref="popupRef" type="center" @maskClick="handleClose">
|
||
<view class="refund-popup">
|
||
<!-- 头部卡通形象 -->
|
||
<image
|
||
src="@/static/dh.png"
|
||
class="refund-popup__avatar"
|
||
mode="widthFix"
|
||
/>
|
||
|
||
<!-- 内容区域 -->
|
||
<view class="refund-popup__content">
|
||
<!-- 主标题 -->
|
||
<view class="refund-popup__title">{{ currentTitle }}</view>
|
||
|
||
<!-- 金额显示 -->
|
||
<view class="refund-popup__amount" v-if="showAmount">
|
||
<text class="amount-symbol">¥</text>
|
||
<text class="amount-value">{{ refundAmount }}</text>
|
||
<text class="amount-unit">元</text>
|
||
</view>
|
||
<view class="refund-popup__amount-label" v-if="showAmount"
|
||
>可退金额</view
|
||
>
|
||
|
||
<!-- 描述信息 -->
|
||
<view class="refund-popup__description" v-if="currentDescription">
|
||
{{ currentDescription }}
|
||
</view>
|
||
|
||
<!-- 退款政策详情 -->
|
||
<view class="refund-popup__policy" v-if="showPolicy">
|
||
<view class="policy-title">退订政策:</view>
|
||
<view class="policy-list">
|
||
<view
|
||
class="policy-item"
|
||
v-for="(rule, index) in currentRules"
|
||
:key="index"
|
||
>
|
||
{{ rule }}
|
||
</view>
|
||
</view>
|
||
</view>
|
||
</view>
|
||
|
||
<!-- 按钮区域 -->
|
||
<view class="refund-popup__actions">
|
||
<view class="action-btn secondary-btn" @click="handlePolicyClick">
|
||
{{ leftButtonText }}
|
||
</view>
|
||
<view class="action-btn primary-btn" @click="handleConfirmClick">
|
||
{{ rightButtonText }}
|
||
</view>
|
||
</view>
|
||
</view>
|
||
</uni-popup>
|
||
</template>
|
||
|
||
<script setup>
|
||
import { ref, computed, watch, shallowRef } from "vue";
|
||
|
||
// Props定义
|
||
const props = defineProps({
|
||
// 弹窗显示状态
|
||
modelValue: {
|
||
type: Boolean,
|
||
default: false,
|
||
},
|
||
// 退款类型
|
||
refundType: {
|
||
type: String,
|
||
default: "no_refund",
|
||
validator: (value) =>
|
||
["no_refund", "all_refund", "anytime_refund"].includes(value),
|
||
},
|
||
// 可退金额
|
||
refundAmount: {
|
||
type: Number,
|
||
default: 0,
|
||
},
|
||
// 退款规则列表
|
||
refundRules: {
|
||
type: Array,
|
||
default: () => [],
|
||
},
|
||
// 自定义标题
|
||
title: {
|
||
type: String,
|
||
default: "",
|
||
},
|
||
// 自定义描述
|
||
description: {
|
||
type: String,
|
||
default: "",
|
||
},
|
||
});
|
||
|
||
// Events定义
|
||
const emit = defineEmits([
|
||
"update:modelValue",
|
||
"policy-click",
|
||
"confirm-click",
|
||
"close",
|
||
]);
|
||
|
||
// 弹窗引用
|
||
const popupRef = ref(null);
|
||
|
||
// 退款场景配置(使用shallowRef优化性能)
|
||
const refundScenarios = shallowRef({
|
||
no_refund: {
|
||
title: "您在入住日期12小时以内申请退款,不可退款,如有疑问请咨询客服",
|
||
description: "",
|
||
showAmount: false,
|
||
showPolicy: false,
|
||
leftButton: "退订政策",
|
||
rightButton: "我知道了",
|
||
rules: [],
|
||
},
|
||
all_refund: {
|
||
title: "您在入住日期24小时内申请退款,可退还100%金额",
|
||
description: "",
|
||
showAmount: true,
|
||
showPolicy: true,
|
||
leftButton: "退订政策",
|
||
rightButton: "点击退款",
|
||
rules: [],
|
||
},
|
||
anytime_refund: {
|
||
title: "该商品未使用随时可退",
|
||
description: "",
|
||
showAmount: true,
|
||
showPolicy: false,
|
||
leftButton: "退订政策",
|
||
rightButton: "点击退款",
|
||
rules: [],
|
||
},
|
||
});
|
||
|
||
// 计算属性
|
||
const currentScenario = computed(
|
||
() =>
|
||
refundScenarios.value[props.refundType] || refundScenarios.value.no_refund
|
||
);
|
||
|
||
const currentTitle = computed(() => props.title || currentScenario.value.title);
|
||
|
||
const currentDescription = computed(
|
||
() => props.description || currentScenario.value.description
|
||
);
|
||
|
||
const currentRules = computed(() => {
|
||
if (props.refundRules.length) {
|
||
return props.refundRules;
|
||
}
|
||
return currentScenario.value.rules;
|
||
});
|
||
|
||
const showAmount = computed(
|
||
() => currentScenario.value.showAmount && props.refundAmount > 0
|
||
);
|
||
|
||
const showPolicy = computed(
|
||
() => currentScenario.value.showPolicy && currentRules.value.length > 0
|
||
);
|
||
|
||
const leftButtonText = computed(() => currentScenario.value.leftButton);
|
||
|
||
const rightButtonText = computed(() => currentScenario.value.rightButton);
|
||
|
||
// 方法定义
|
||
const show = () => popupRef.value.open();
|
||
|
||
const hide = () => popupRef.value.close();
|
||
|
||
// 监听modelValue变化
|
||
watch(
|
||
() => props.modelValue,
|
||
(newVal) => {
|
||
if (newVal) {
|
||
show();
|
||
} else {
|
||
hide();
|
||
}
|
||
},
|
||
{ immediate: true }
|
||
);
|
||
|
||
// 监听退款金额变化,进行数据验证
|
||
watch(
|
||
() => props.refundAmount,
|
||
(newVal) => {
|
||
if (newVal < 0) {
|
||
console.warn("RefundPopup: 退款金额不能为负数");
|
||
}
|
||
},
|
||
{ immediate: true }
|
||
);
|
||
|
||
const handleClose = () => {
|
||
emit("update:modelValue", false);
|
||
emit("close");
|
||
};
|
||
|
||
const handlePolicyClick = () => {
|
||
emit("policy-click");
|
||
};
|
||
|
||
const handleConfirmClick = () => {
|
||
emit("confirm-click");
|
||
handleClose();
|
||
};
|
||
</script>
|
||
|
||
<style lang="scss" scoped>
|
||
@import "./styles/index.scss";
|
||
</style> |