feat: 订单退款功能对接
This commit is contained in:
@@ -39,12 +39,7 @@
|
||||
|
||||
<script setup>
|
||||
import { defineProps, computed, ref, defineEmits } from "vue";
|
||||
import {
|
||||
preOrder,
|
||||
orderPayNow,
|
||||
orderCancel,
|
||||
orderRefund,
|
||||
} from "@/request/api/OrderApi";
|
||||
import { orderPayNow } from "@/request/api/OrderApi";
|
||||
|
||||
// 支付方式映射常量
|
||||
const PAY_WAY_MAP = {
|
||||
@@ -57,7 +52,7 @@ const PAY_WAY_MAP = {
|
||||
const isLoading = ref(false);
|
||||
|
||||
// 定义事件发射器
|
||||
const emit = defineEmits(['show-refund-popup']);
|
||||
const emit = defineEmits(["show-refund-popup"]);
|
||||
|
||||
const props = defineProps({
|
||||
orderData: {
|
||||
@@ -116,7 +111,7 @@ const handleButtonClick = async () => {
|
||||
|
||||
if (status === "2") {
|
||||
// 情况2:待使用状态,显示退款弹窗
|
||||
emit('show-refund-popup');
|
||||
emit("show-refund-popup");
|
||||
return; // 直接返回,不执行后续代码
|
||||
}
|
||||
|
||||
|
||||
@@ -3,61 +3,68 @@
|
||||
<view class="refund-popup">
|
||||
<!-- 头部卡通形象 -->
|
||||
<image
|
||||
src="@/static/dh.png"
|
||||
:src="commodityPurchaseInstruction.refundLogo"
|
||||
class="refund-popup__avatar"
|
||||
mode="widthFix"
|
||||
mode="aspectFill"
|
||||
/>
|
||||
|
||||
<!-- 内容区域 -->
|
||||
<view class="refund-popup__content">
|
||||
<!-- 主标题 -->
|
||||
<view class="refund-popup__title">{{ currentTitle }}</view>
|
||||
<view class="refund-popup__title">
|
||||
{{ commodityPurchaseInstruction.refundTitle }}
|
||||
</view>
|
||||
|
||||
<!-- 金额显示 -->
|
||||
<view class="refund-popup__amount" v-if="showAmount">
|
||||
<view class="refund-popup__amount" v-if="isRefundable">
|
||||
<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 class="refund-popup__amount-label" v-if="isRefundable"
|
||||
>可退金额</view
|
||||
>
|
||||
|
||||
<!-- 描述信息 -->
|
||||
<view class="refund-popup__description" v-if="currentDescription">
|
||||
{{ currentDescription }}
|
||||
</view>
|
||||
|
||||
<!-- 退款政策详情 -->
|
||||
<view class="refund-popup__policy" v-if="showPolicy">
|
||||
<view class="refund-popup__policy" v-if="showRefundPolicy">
|
||||
<view class="policy-title">退订政策:</view>
|
||||
<view class="policy-list">
|
||||
<view
|
||||
class="policy-item"
|
||||
v-for="(rule, index) in currentRules"
|
||||
:key="index"
|
||||
>
|
||||
{{ rule }}
|
||||
</view>
|
||||
<view class="policy-content">
|
||||
{{ commodityPurchaseInstruction.refundContent }}
|
||||
</view>
|
||||
</view>
|
||||
</view>
|
||||
|
||||
<!-- 按钮区域 -->
|
||||
<view class="refund-popup__actions">
|
||||
<view class="action-btn secondary-btn" @click="handlePolicyClick">
|
||||
{{ leftButtonText }}
|
||||
<view
|
||||
v-if="!showRefundPolicy"
|
||||
class="action-btn secondary-btn"
|
||||
@click="handlePolicyClick"
|
||||
>
|
||||
退订政策
|
||||
</view>
|
||||
<view class="action-btn primary-btn" @click="handleConfirmClick">
|
||||
{{ rightButtonText }}
|
||||
<view
|
||||
class="action-btn primary-btn"
|
||||
@click="handleConfirmClick(btnText)"
|
||||
>
|
||||
{{ btnText }}
|
||||
</view>
|
||||
</view>
|
||||
|
||||
<!-- 关闭按钮 -->
|
||||
<uni-icons
|
||||
class="refund-popup__close"
|
||||
type="close"
|
||||
size="40"
|
||||
color="#fff"
|
||||
@click="handleClose"
|
||||
/>
|
||||
</view>
|
||||
</uni-popup>
|
||||
</template>
|
||||
|
||||
<script setup>
|
||||
import { ref, computed, watch, shallowRef } from "vue";
|
||||
import { ref, computed, watch } from "vue";
|
||||
|
||||
// Props定义
|
||||
const props = defineProps({
|
||||
@@ -66,107 +73,44 @@ const props = defineProps({
|
||||
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: "",
|
||||
// 订单数据
|
||||
orderData: {
|
||||
type: Object,
|
||||
default: () => {},
|
||||
},
|
||||
});
|
||||
|
||||
// Events定义
|
||||
const emit = defineEmits([
|
||||
"update:modelValue",
|
||||
"policy-click",
|
||||
"confirm-click",
|
||||
"close",
|
||||
]);
|
||||
const emit = defineEmits(["update:modelValue", "confirm", "close"]);
|
||||
|
||||
// 弹窗引用
|
||||
const popupRef = ref(null);
|
||||
// 退款政策是否显示
|
||||
const showRefundPolicy = ref(false);
|
||||
|
||||
// 退款场景配置(使用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;
|
||||
// 退款金额
|
||||
const refundAmount = computed(() => {
|
||||
if (props.orderData.payAmt) {
|
||||
return parseFloat(Number(props.orderData.payAmt) || 0);
|
||||
}
|
||||
return currentScenario.value.rules;
|
||||
|
||||
return 0;
|
||||
});
|
||||
|
||||
const showAmount = computed(
|
||||
() => currentScenario.value.showAmount && props.refundAmount > 0
|
||||
);
|
||||
// 是否可退款
|
||||
const isRefundable = computed(() => !props.orderData.refundable);
|
||||
|
||||
const showPolicy = computed(
|
||||
() => currentScenario.value.showPolicy && currentRules.value.length > 0
|
||||
);
|
||||
// 按钮文件
|
||||
const btnText = computed(() => (isRefundable.value ? "点击退款" : "我知道了"));
|
||||
|
||||
const leftButtonText = computed(() => currentScenario.value.leftButton);
|
||||
// 获取退款模板
|
||||
const commodityPurchaseInstruction = computed(() => {
|
||||
if (props.orderData.commodityPurchaseInstruction) {
|
||||
return props.orderData.commodityPurchaseInstruction;
|
||||
}
|
||||
|
||||
const rightButtonText = computed(() => currentScenario.value.rightButton);
|
||||
return {};
|
||||
});
|
||||
|
||||
// 方法定义
|
||||
const show = () => popupRef.value.open();
|
||||
@@ -186,28 +130,21 @@ watch(
|
||||
{ immediate: true }
|
||||
);
|
||||
|
||||
// 监听退款金额变化,进行数据验证
|
||||
watch(
|
||||
() => props.refundAmount,
|
||||
(newVal) => {
|
||||
if (newVal < 0) {
|
||||
console.warn("RefundPopup: 退款金额不能为负数");
|
||||
}
|
||||
},
|
||||
{ immediate: true }
|
||||
);
|
||||
|
||||
const handleClose = () => {
|
||||
showRefundPolicy.value = false;
|
||||
emit("update:modelValue", false);
|
||||
emit("close");
|
||||
};
|
||||
|
||||
const handlePolicyClick = () => {
|
||||
emit("policy-click");
|
||||
showRefundPolicy.value = true;
|
||||
};
|
||||
|
||||
const handleConfirmClick = () => {
|
||||
emit("confirm-click");
|
||||
const handleConfirmClick = (text) => {
|
||||
if (text === "点击退款") {
|
||||
emit("confirm", props.orderData);
|
||||
}
|
||||
|
||||
handleClose();
|
||||
};
|
||||
</script>
|
||||
|
||||
@@ -13,7 +13,7 @@
|
||||
width: 132px;
|
||||
height: 132px;
|
||||
position: absolute;
|
||||
top: -45px;
|
||||
top: -75px;
|
||||
left: 50%;
|
||||
transform: translateX(-50%);
|
||||
}
|
||||
@@ -62,14 +62,6 @@
|
||||
margin-bottom: 16px;
|
||||
}
|
||||
|
||||
&__description {
|
||||
font-size: 14px;
|
||||
color: #333333;
|
||||
line-height: 1.5;
|
||||
margin-bottom: 16px;
|
||||
text-align: left;
|
||||
}
|
||||
|
||||
&__policy {
|
||||
text-align: left;
|
||||
margin-bottom: 16px;
|
||||
@@ -81,17 +73,11 @@
|
||||
margin-bottom: 8px;
|
||||
}
|
||||
|
||||
.policy-list {
|
||||
.policy-item {
|
||||
.policy-content {
|
||||
font-size: 12px;
|
||||
color: #333333;
|
||||
line-height: 22px;
|
||||
text-align: justify;
|
||||
|
||||
&:last-child {
|
||||
margin-bottom: 0;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -133,6 +119,16 @@
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// 关闭按钮
|
||||
&__close {
|
||||
position: absolute;
|
||||
bottom: -60px;
|
||||
left: 50%;
|
||||
transform: translateX(-50%);
|
||||
width: 40px;
|
||||
height: 40px;
|
||||
}
|
||||
}
|
||||
|
||||
// 动画效果
|
||||
|
||||
@@ -17,10 +17,8 @@
|
||||
<!-- 退款状态显示 -->
|
||||
<RefundPopup
|
||||
v-model="refundVisible"
|
||||
:refund-type="refundType"
|
||||
:refund-amount="refundAmount"
|
||||
@policy-click="viewRefundPolicy"
|
||||
@confirm-click="handleRefundConfirm"
|
||||
:orderData="orderData"
|
||||
@confirm="handleRefundConfirm"
|
||||
/>
|
||||
</view>
|
||||
</template>
|
||||
@@ -38,15 +36,12 @@ import OrderInfo from "./components/OrderInfo/index.vue";
|
||||
import RefundPopup from "./components/RefundPopup/index.vue";
|
||||
|
||||
const refundVisible = ref(false);
|
||||
const refundType = ref("free_cancel"); // 默认退款类型
|
||||
const refundAmount = ref(0); // 退款金额
|
||||
const orderData = ref({});
|
||||
|
||||
onLoad(async ({ orderId }) => {
|
||||
const res = await userOrderDetail({ orderId });
|
||||
|
||||
orderData.value = res.data;
|
||||
// 设置退款金额为订单支付金额
|
||||
refundAmount.value = parseFloat(res.data.payAmt || 0);
|
||||
console.log(res);
|
||||
});
|
||||
|
||||
@@ -62,17 +57,11 @@ const showRefundPopup = () => {
|
||||
refundVisible.value = true;
|
||||
};
|
||||
|
||||
// 查看退款政策
|
||||
const viewRefundPolicy = () => {
|
||||
console.log("查看退款政策");
|
||||
// 这里可以跳转到退款政策页面或显示详细政策
|
||||
};
|
||||
|
||||
// 确认退款
|
||||
const handleRefundConfirm = async () => {
|
||||
const handleRefundConfirm = async ({ orderId }) => {
|
||||
try {
|
||||
// 调用退款API
|
||||
await orderRefund({ orderId: orderData.value.orderId });
|
||||
await orderRefund({ orderId });
|
||||
|
||||
uni.showToast({
|
||||
title: "退款申请已提交",
|
||||
@@ -80,10 +69,8 @@ const handleRefundConfirm = async () => {
|
||||
});
|
||||
|
||||
// 刷新订单状态
|
||||
const res = await userOrderDetail({ orderId: orderData.value.orderId });
|
||||
const res = await userOrderDetail({ orderId });
|
||||
orderData.value = res.data;
|
||||
// 更新退款金额
|
||||
refundAmount.value = parseFloat(res.data.payAmt || 0);
|
||||
} catch (error) {
|
||||
console.error("退款失败:", error);
|
||||
uni.showToast({
|
||||
|
||||
@@ -41,9 +41,7 @@
|
||||
|
||||
.wrapper {
|
||||
box-sizing: border-box;
|
||||
padding-left: 12px;
|
||||
padding-right: 12px;
|
||||
padding-top: 12px;
|
||||
padding: 12px;
|
||||
}
|
||||
|
||||
.good-info-wrapper {
|
||||
@@ -160,7 +158,7 @@
|
||||
box-sizing: border-box;
|
||||
padding-left: 12px;
|
||||
padding-right: 12px;
|
||||
padding-bottom: var(--safe-area-inset-bottom);
|
||||
padding-bottom: 24px;
|
||||
|
||||
.left {
|
||||
display: flex;
|
||||
|
||||
Reference in New Issue
Block a user