feat: 订单模块基本完成

This commit is contained in:
2025-09-16 14:34:11 +08:00
parent 4a00c7f1d8
commit a045b39580
13 changed files with 799 additions and 288 deletions

View File

@@ -1,14 +1,14 @@
import React, { useState, useEffect } from "react";
import React, { useState, useEffect, useRef } from "react";
import { View, Text, Button, Image, ScrollView } from "@tarojs/components";
import Taro, { useDidShow } from "@tarojs/taro";
import { Avatar, Dialog } from "@nutui/nutui-react-taro";
import dayjs from "dayjs";
import classnames from "classnames";
import orderService, { OrderStatus, CancelType } from "@/services/orderService";
import { withAuth } from "@/components";
import { payOrder } from "@/utils";
import { withAuth, RefundPopup } from "@/components";
import { payOrder, generateOrderActions } from "@/utils";
import styles from "./index.module.scss";
// import orderListArrowRight from "@/static/order/orderListArrowRight.svg";
dayjs.locale("zh-cn");
const PAGESIZE = 20;
@@ -45,11 +45,12 @@ function generateTimeMsg(game_info) {
return (
<>
<Text>
{diffDay <= 2
{diffDay <= 2 && diffDay >= 0
? diffDayMap.get(diffDay)
: startTime.format("YYYY-MM-DD")}
</Text>
<Text>({DayOfWeekMap.get(dayofWeek)})</Text>
<Text>{startTime.format('ah')}</Text>
<Text>{gameLength}</Text>
</>
);
@@ -58,6 +59,7 @@ function generateTimeMsg(game_info) {
const OrderList = () => {
const [list, setList] = useState<any[][]>([]);
const [total, setTotal] = useState(0);
const refundRef = useRef(null)
const end = list.length * PAGESIZE >= total;
@@ -118,48 +120,6 @@ const OrderList = () => {
});
}
function renderCancelContent(checkOrderInfo) {
const { refund_policy = [] } = checkOrderInfo;
const policyList = [
{
time: "申请退款时间",
rule: "退款规则",
},
...refund_policy.map((item, index) => {
const isLast = index === refund_policy.length - 1;
const theTimeObj = dayjs(
isLast
? refund_policy.at(-2).deadline_formatted
: item.deadline_formatted
);
const year = theTimeObj.format("YYYY");
const month = theTimeObj.format("M");
const day = theTimeObj.format("D");
const time = theTimeObj.format("HH:MM");
return {
time: `${year}${month}${day}${time} ${isLast ? "后" : "前"}`,
rule: item.refund_rule,
};
}),
];
return (
<View className={styles.refundPolicy}>
<View className={styles.moduleTitle}>
<Text>退</Text>
</View>
{/* 订单信息摘要 */}
<View className={styles.policyList}>
{policyList.map((item, index) => (
<View key={index} className={styles.policyItem}>
<View className={styles.time}>{item.time}</View>
<View className={styles.rule}>{item.rule}</View>
</View>
))}
</View>
</View>
);
}
async function handleDeleteOrder(item) {
const { id: order_id } = item
// TODO删除订单,刷新这一页,然后后面的全清除掉
@@ -211,90 +171,65 @@ const OrderList = () => {
}
async function handleCancelOrder(item) {
const { order_no, order_status, game_info, amount } = item;
if (order_status === OrderStatus.PENDING) {
const onCancel = () => {
Dialog.close("cancelOrder");
};
const onConfirm = async () => {
try {
const cancelRes = await orderService.cancelUnpaidOrder({
order_no,
cancel_reason: "用户主动取消",
});
if (cancelRes.code !== 0) {
throw new Error(cancelRes.message);
}
getOrders(item.page, false);
Taro.showToast({
title: "取消成功",
icon: "none",
})
} catch (e) {
Taro.showToast({
title: e.message,
icon: "error",
});
} finally {
Dialog.close("cancelOrder");
const { order_no } = item;
const onCancel = () => {
Dialog.close("cancelOrder");
};
const onConfirm = async () => {
try {
const cancelRes = await orderService.cancelUnpaidOrder({
order_no,
cancel_reason: "用户主动取消",
});
if (cancelRes.code !== 0) {
throw new Error(cancelRes.message);
}
};
Dialog.open("cancelOrder", {
title: "确定取消订单吗?",
content: "取消订单后,您将无法恢复订单。请确认是否继续取消?",
footer: (
<View className={styles.dialogFooter}>
<Button className={styles.cancel} onClick={onCancel}>
</Button>
<Button
className={styles.confirm}
type="primary"
onClick={onConfirm}
>
</Button>
</View>
),
onConfirm,
onCancel,
});
return;
}
const res = await orderService.getCheckOrderInfo(game_info.id);
getOrders(item.page, false);
Taro.showToast({
title: "取消成功",
icon: "none",
})
} catch (e) {
Taro.showToast({
title: e.message,
icon: "error",
});
} finally {
Dialog.close("cancelOrder");
}
};
Dialog.open("cancelOrder", {
title: "确定取消订单吗?",
content: renderCancelContent(res.data),
onConfirm: async () => {
try {
const refundRes = await orderService.applicateRefund({
order_no,
refund_amount: amount,
refund_reason: "用户主动退款",
});
if (refundRes.code !== 0) {
throw new Error(refundRes.message);
}
getOrders(item.page, false);
Taro.showToast({
title: "退出成功",
icon: "none",
})
} catch (e) {
Taro.showToast({
title: e.message,
icon: "error",
});
} finally {
Dialog.close("cancelOrder");
}
},
onCancel: () => {
Dialog.close("cancelOrder");
},
content: "取消订单后,您将无法恢复订单。请确认是否继续取消?",
footer: (
<View className={styles.dialogFooter}>
<Button className={styles.cancel} onClick={onCancel}>
</Button>
<Button
className={styles.confirm}
type="primary"
onClick={onConfirm}
>
</Button>
</View>
),
onConfirm,
onCancel,
});
}
function handleQuit (item) {
if (refundRef.current) {
refundRef.current.show(item, (result) => {
if (result) {
getOrders(item.page)
}
})
}
}
function handleViewOrderDetail(orderId) {
Taro.navigateTo({
url: `/order_pages/orderDetail/index?id=${orderId}`,
@@ -314,19 +249,7 @@ const OrderList = () => {
>
{/* <View className={styles.bg} /> */}
{list.flat().map((item) => {
const unPay = item.order_status === OrderStatus.PENDING;
const expired =
item.order_status === OrderStatus.FINISHED ||
[CancelType.TIMEOUT, CancelType.USER].includes(item.cancel_type);
// const expiredTime = dayjs(item.expire_time).isSame(dayjs(), "day")
// ? dayjs(item.expire_time).format("HH:mm:ss")
// : dayjs(item.expire_time).format("YYYY-MM-DD HH:mm:ss");
const showCancel =
item.order_status === OrderStatus.PENDING &&
item.cancel_type === CancelType.NONE;
const showQuit =
item.order_status === OrderStatus.PAID &&
item.cancel_type === CancelType.NONE;
const unPay = item.order_status === OrderStatus.PENDING && item.cancel_type === CancelType.NONE;
const {
game_info: {
@@ -352,10 +275,10 @@ const OrderList = () => {
<View
className={classnames(
styles.payNum,
styles[unPay && !expired ? "pending" : "paid"]
styles[unPay ? "pending" : "paid"]
)}
>
<Text>{unPay && !expired ? "待支付" : "已支付"}</Text> ¥{" "}
<Text>{unPay ? "待支付" : "已支付"}</Text> ¥{" "}
<Text>{item.amount}</Text>
</View>
</View>
@@ -372,18 +295,48 @@ const OrderList = () => {
<View className={styles.gameOtherInfo}>
{participants.length >= 0 ? (
<View className={styles.avatarCards}>
{/* participants */[{ user: { avatar_url: 'https://img.yzcdn.cn/vant/cat.jpeg', id: 1 } }, { user: { avatar_url: 'https://img.yzcdn.cn/vant/cat.jpeg', id: 2 } }, { user: { avatar_url: 'https://img.yzcdn.cn/vant/cat.jpeg', id: 3 } }].map((participant) => {
const {
user: { avatar_url, id },
} = participant;
return <Image className={styles.avatar} mode="aspectFill" key={id} src={avatar_url} />;
})}
{
/* participants */ [
{
user: {
avatar_url: "https://img.yzcdn.cn/vant/cat.jpeg",
id: 1,
},
},
{
user: {
avatar_url: "https://img.yzcdn.cn/vant/cat.jpeg",
id: 2,
},
},
{
user: {
avatar_url: "https://img.yzcdn.cn/vant/cat.jpeg",
id: 3,
},
},
].map((participant) => {
const {
user: { avatar_url, id },
} = participant;
return (
<Image
className={styles.avatar}
mode="aspectFill"
key={id}
src={avatar_url}
/>
);
})
}
</View>
) : (
""
)}
<View className={styles.participantProgress}>
<Text className={styles.current}> {current_players}</Text>
<Text className={styles.current}>
{current_players}
</Text>
<Text>/</Text>
<Text>{max_players}</Text>
</View>
@@ -400,45 +353,27 @@ const OrderList = () => {
<View className={styles.orderActions}>
<View className={styles.extraActions}></View>
<View className={styles.mainActions}>
{expired && (
{generateOrderActions(
item,
{
handleDeleteOrder,
handleCancelOrder,
handleQuit,
handlePayNow,
handleViewGame,
},
"list"
)?.map((obj) => (
<Button
className={classnames(styles.button, styles.cancelOrder)}
onClick={handleDeleteOrder.bind(null, item)}
className={classnames(
styles.button,
styles[obj.className]
)}
onClick={obj.action}
>
{obj.text}
</Button>
)}
{showCancel && (
<Button
className={classnames(styles.button, styles.cancelOrder)}
onClick={handleCancelOrder.bind(null, item)}
>
</Button>
)}
{showQuit && (
<Button
className={classnames(styles.button, styles.cancelOrder)}
onClick={handleCancelOrder.bind(null, item)}
>
退
</Button>
)}
{unPay && !expired ? (
<Button
className={classnames(styles.button, styles.payNow)}
onClick={handlePayNow.bind(null, item)}
>
</Button>
) : (
<Button
className={classnames(styles.button, styles.gameDetail)}
onClick={handleViewGame.bind(null, item.game_info.id)}
>
</Button>
)}
))}
</View>
</View>
</View>
@@ -447,6 +382,7 @@ const OrderList = () => {
{end && <View className={styles.endTips}></View>}
</ScrollView>
<Dialog id="cancelOrder" />
<RefundPopup ref={refundRef} />
</View>
);
};