Files
mini-programs/src/components/refundPopup/index.tsx

180 lines
5.1 KiB
TypeScript
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.
import React, {
useState,
useRef,
forwardRef,
useImperativeHandle,
} from "react";
import { View, Text, Button, Image } from "@tarojs/components";
import Taro from "@tarojs/taro";
import classnames from "classnames";
import dayjs from "dayjs";
import { CommonPopup } from "@/components";
import orderService from "@/services/orderService";
import styles from "./index.module.scss";
import closeIcon from "@/static/order/orderListClose.svg";
function genRefundNotice(refund_policy) {
if (refund_policy.length === 0) {
return {};
}
const now = dayjs();
const deadlines = refund_policy.map((item) => dayjs(item.deadline_formatted));
let matchPolicyIndex = deadlines.findIndex((d) => d.isAfter(now));
if (matchPolicyIndex === -1) {
matchPolicyIndex = refund_policy.length - 1;
}
const { deadline_formatted, price, refund_rate } =
refund_policy[matchPolicyIndex];
if (refund_rate === 1) {
return {
refundPrice: price,
notice: `本次可全额退款, ¥${price} 将原路退回,请查收`,
};
} else if (refund_rate === 0) {
return {
refundPrice: 0,
notice: `当前退出不可退款,后续流程未明确,@麻真瑜`,
};
}
const refundPrice = Number(Math.ceil(price * refund_rate * 100) / 100);
const leftHours = dayjs(deadline_formatted).diff(dayjs(), "hour");
return {
refundPrice,
notice: `距活动开始已不足${leftHours}h当前退出您需扣除${
Math.floor((price - refundPrice) * 100) / 100
}`,
};
}
function renderCancelContent(refund_policy = []) {
const current = dayjs();
const policyList = [
{
time: "申请退款时间",
rule: "退款规则",
},
...refund_policy.map((item, index) => {
const isLast = index === refund_policy.length - 1;
return {
time: item.application_time,
rule: item.refund_rule,
beforeCurrent: isLast
? true
: current.isBefore(dayjs(item.deadline_formatted)),
};
}),
];
const targetIndex = policyList.findIndex((item) => item.beforeCurrent);
const { notice } = genRefundNotice(refund_policy);
return (
<View className={styles.refundPolicy}>
{/* <View className={styles.moduleTitle}>
<Text>退款政策</Text>
</View> */}
{<View className={styles.specTips}>{notice}</View>}
{/* 订单信息摘要 */}
<View className={styles.policyList}>
{policyList.map((item, index) => (
<View
key={index}
className={classnames(
styles.policyItem,
targetIndex > index && index !== 0 ? styles.pastItem : "",
targetIndex === index ? styles.currentItem : ""
)}
>
<View className={styles.time}>
{targetIndex === index && (
<View className={styles.currentTag}>
<Text></Text>
</View>
)}
<Text>{item.time}</Text>
</View>
<View className={styles.rule}>{item.rule}</View>
</View>
))}
</View>
</View>
);
}
export type RefundRef = {
show: (item: any, callback: (result: boolean) => void) => void;
};
export default forwardRef<RefundRef>(function RefundPopup(_props, ref) {
const [visible, setVisible] = useState(false);
const [refundPolicy, setRefundPolicy] = useState([]);
const [orderData, setOrderData] = useState({});
const onDown = useRef<((result: boolean) => void) | null>(null);
useImperativeHandle(ref, () => ({
show: onShow,
}));
async function onShow(orderItem, onFinish: (result: boolean) => void) {
const { refund_policy } = orderItem;
onDown.current = onFinish;
setOrderData(orderItem);
setRefundPolicy(refund_policy);
setVisible(true);
}
function onClose() {
setVisible(false);
onDown.current?.(false);
}
async function handleConfirmQuit() {
const { order_no, amount } = orderData;
try {
const refundRes = await orderService.applicateRefund({
order_no,
refund_amount: amount,
refund_reason: "用户主动退款",
});
if (refundRes.code !== 0) {
throw new Error(refundRes.message);
}
Taro.showToast({
title: "退出成功",
icon: "none",
});
onDown.current?.(true);
} catch (e) {
Taro.showToast({
title: e.message,
icon: "error",
});
} finally {
onClose();
}
}
return (
<CommonPopup
visible={visible}
onClose={onClose}
// title="退出活动"
enableDragToClose={false}
zIndex={1001}
hideFooter
>
<View className={styles.container}>
<View className={styles.header}>
<Text className={styles.title}>退</Text>
<Image
className={styles.closeIcon}
src={closeIcon}
onClick={onClose}
/>
</View>
{renderCancelContent(refundPolicy)}
<Button className={styles.action} onClick={handleConfirmQuit}>
退
</Button>
</View>
</CommonPopup>
);
});