diff --git a/src/components/Auth/index.tsx b/src/components/Auth/index.tsx
index 9044f41..6cbf848 100644
--- a/src/components/Auth/index.tsx
+++ b/src/components/Auth/index.tsx
@@ -1,26 +1,9 @@
import React, { useEffect, useState } from "react";
import { View } from "@tarojs/components";
import Taro from "@tarojs/taro";
+import { getCurrentFullPath } from '@/utils';
import { check_login_status } from "@/services/loginService";
-export function getCurrentFullPath(): string {
- const pages = Taro.getCurrentPages();
- const currentPage = pages.at(-1);
-
- if (currentPage) {
- console.log(currentPage, "currentPage get");
- const route = currentPage.route;
- const options = currentPage.options || {};
-
- const query = Object.keys(options)
- .map((key) => `${key}=${options[key]}`)
- .join("&");
-
- return query ? `/${route}?${query}` : `/${route}`;
- }
- return "";
-}
-
export default function withAuth
(
WrappedComponent: React.ComponentType
,
) {
diff --git a/src/components/index.ts b/src/components/index.ts
index 2918423..abc1c4a 100644
--- a/src/components/index.ts
+++ b/src/components/index.ts
@@ -16,6 +16,7 @@ import EditModal from "./EditModal/index";
import withAuth from "./Auth";
import { CustomPicker, PopupPicker } from "./Picker";
import NTRPEvaluatePopup from "./NTRPEvaluatePopup";
+import RefundPopup from "./refundPopup";
export {
ActivityTypeSwitch,
@@ -37,4 +38,5 @@ export {
CustomPicker,
PopupPicker,
NTRPEvaluatePopup,
+ RefundPopup,
};
diff --git a/src/components/refundPopup/index.module.scss b/src/components/refundPopup/index.module.scss
new file mode 100644
index 0000000..adbfc5a
--- /dev/null
+++ b/src/components/refundPopup/index.module.scss
@@ -0,0 +1,132 @@
+.refundPolicy {
+ padding-top: 20px;
+ // .moduleTitle {
+ // display: flex;
+ // padding: 15px 0 8px;
+ // justify-content: space-between;
+ // align-items: center;
+ // align-self: stretch;
+ // color: #000;
+ // font-feature-settings:
+ // "liga" off,
+ // "clig" off;
+ // font-family: "PingFang SC";
+ // font-size: 14px;
+ // font-style: normal;
+ // font-weight: 600;
+ // line-height: 20px;
+ // letter-spacing: -0.23px;
+ // }
+
+ .specTips {
+ padding-bottom: 20px;
+ color: rgba(60, 60, 67, 0.60);
+ text-align: center;
+ font-feature-settings: 'liga' off, 'clig' off;
+ font-family: "PingFang SC";
+ font-size: 16px;
+ font-style: normal;
+ font-weight: 400;
+ line-height: 18px;
+ }
+
+ .policyList {
+ border-radius: 12px;
+ border: 1px solid rgba(0, 0, 0, 0.06);
+ background: #fff;
+ box-shadow: 0 4px 36px 0 rgba(0, 0, 0, 0.06);
+
+ .policyItem {
+ display: flex;
+ justify-content: space-around;
+ align-items: center;
+ color: #000;
+ text-align: center;
+ font-feature-settings:
+ "liga" off,
+ "clig" off;
+ font-family: "PingFang SC";
+ font-size: 12px;
+ font-style: normal;
+ font-weight: 400;
+ line-height: 20px;
+ border-top: 1px solid rgba(0, 0, 0, 0.06);
+
+ &:nth-child(1) {
+ color: #000;
+ text-align: center;
+ font-feature-settings:
+ "liga" off,
+ "clig" off;
+ font-family: "PingFang SC";
+ font-size: 14px;
+ font-style: normal;
+ font-weight: 600;
+ line-height: 20px;
+ border: none;
+ }
+
+ .time,
+ .rule {
+ width: 50%;
+ padding: 10px 12px;
+ }
+
+ .rule {
+ border-left: 1px solid rgba(0, 0, 0, 0.06);
+ }
+ }
+ }
+}
+
+.container {
+ padding: 0 15px 40px;
+
+ .header {
+ padding: 24px 15px 0;
+ height: 24px;
+ display: flex;
+ align-items: center;
+ justify-content: center;
+
+ .title {
+ color: #000;
+ text-align: center;
+ font-feature-settings: 'liga' off, 'clig' off;
+ font-family: "PingFang SC";
+ font-size: 16px;
+ font-style: normal;
+ font-weight: 600;
+ line-height: 20px;
+ margin-left: auto;
+ }
+
+ .closeIcon {
+ margin-left: auto;
+ width: 20px;
+ height: 20px;
+ }
+ }
+
+ .action {
+ display: flex;
+ align-items: center;
+ justify-content: center;
+ margin-top: 20px;
+ padding: 2px 6px;
+ height: 52px;
+ border-radius: 16px;
+ border: 1px solid rgba(0, 0, 0, 0.06);
+ box-shadow: 0 8px 64px 0 rgba(0, 0, 0, 0.10);
+ backdrop-filter: blur(16px);
+ color: #fff;
+ background-color: #000;
+ font-feature-settings: 'liga' off, 'clig' off;
+ font-family: "PingFang SC";
+ font-size: 16px;
+ font-style: normal;
+ font-weight: 600;
+ line-height: 20px;
+ letter-spacing: -0.23px;
+ }
+}
\ No newline at end of file
diff --git a/src/components/refundPopup/index.tsx b/src/components/refundPopup/index.tsx
new file mode 100644
index 0000000..b7354d9
--- /dev/null
+++ b/src/components/refundPopup/index.tsx
@@ -0,0 +1,139 @@
+import React, { useState, useRef, forwardRef, useImperativeHandle } from 'react';
+import { View, Text, Button, Image } from '@tarojs/components'
+import Taro from '@tarojs/taro';
+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 = price * refund_rate
+ const leftHours = dayjs(deadline_formatted).diff(dayjs(), 'hour')
+ return { refundPrice, notice: `距活动开始已不足${leftHours}h,当前退出您需扣除${price - refundPrice}元` }
+}
+
+function renderCancelContent(checkOrderInfo) {
+ const { refund_policy = [] } = checkOrderInfo;
+ const policyList = [
+ {
+ time: "申请退款时间",
+ rule: "退款规则",
+ },
+ ...refund_policy.map((item) => {
+ return {
+ time: item.application_time,
+ rule: item.refund_rule,
+ };
+ }),
+ ];
+ const { notice } = genRefundNotice(refund_policy)
+ return (
+
+ {/*
+ 退款政策
+ */}
+ {{notice}}
+ {/* 订单信息摘要 */}
+
+ {policyList.map((item, index) => (
+
+ {item.time}
+ {item.rule}
+
+ ))}
+
+
+ );
+}
+
+export type RefundRef = {
+ show: (item: any, callback: (result: boolean) => void) => void
+}
+
+export default forwardRef(function RefundPopup(_props, ref) {
+ const [visible, setVisible] = useState(false)
+ const [checkOrderInfo, setCheckOrderInfo] = 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 {
+ game_info,
+ } = orderItem
+ onDown.current = onFinish
+ setOrderData(orderItem)
+ const res = await orderService.getCheckOrderInfo(game_info.id);
+ setCheckOrderInfo(res.data);
+ 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 (
+
+
+
+ 退出活动
+
+
+ {renderCancelContent(checkOrderInfo)}
+
+
+
+ )
+})
\ No newline at end of file
diff --git a/src/order_pages/orderDetail/index.module.scss b/src/order_pages/orderDetail/index.module.scss
index d7aed40..3c518c1 100644
--- a/src/order_pages/orderDetail/index.module.scss
+++ b/src/order_pages/orderDetail/index.module.scss
@@ -229,7 +229,34 @@
.gameInfoActions {
min-height: 12px;
+ padding: 0 12px;
border-top: 0.5px solid rgba(0, 0, 0, 0.06);
+ display: flex;
+ align-items: center;
+ justify-content: flex-start;
+ gap: 10px;
+
+ & > .button {
+ margin: 12px 0;
+ padding: 4px 10px;
+ height: 28px;
+ border-radius: 999px;
+ border: 0.5px solid rgba(0, 0, 0, 0.06);
+ color: #000;
+ font-size: 12px;
+ font-style: normal;
+ font-weight: 600;
+ line-height: 20px;
+ letter-spacing: -0.23px;
+
+ &:first-child {
+ background: #000;
+ color: #fff;
+ &.payNow {
+ background-color: #ff3b30;
+ }
+ }
+ }
}
}
@@ -432,3 +459,47 @@
font-weight: 600;
line-height: normal;
}
+
+.dialogFooter {
+ // width: 100%;
+ width: calc(100% + 1px);
+ height: 44px;
+ box-sizing: border-box;
+ display: flex;
+ align-items: center;
+ justify-content: flex-end;
+ position: absolute;
+ // margin: 0 -24px -24px;
+ bottom: 0;
+ left: 0;
+ border-top: 1px solid rgba(0, 0, 0, 0.06);
+ border-bottom-left-radius: 16px;
+ border-bottom-right-radius: 16px;
+ overflow: hidden;
+
+ & > .cancel, & > .confirm {
+ padding: 12px 10px;
+ height: 44px;
+ width: 50%;
+ text-align: center;
+ // border: 0.5px solid rgba(0, 0, 0, 0.06);
+ color: #000;
+ font-size: 16px;
+ font-style: normal;
+ font-weight: 600;
+ line-height: 20px;
+
+ &:last-child {
+ background: #000;
+ color: #fff;
+ }
+ }
+
+ & > .cancel {
+ border-radius: 0;
+ }
+
+ & > .confirm {
+ border-radius: 0;
+ }
+}
diff --git a/src/order_pages/orderDetail/index.tsx b/src/order_pages/orderDetail/index.tsx
index 922e08f..0bfacfa 100644
--- a/src/order_pages/orderDetail/index.tsx
+++ b/src/order_pages/orderDetail/index.tsx
@@ -1,31 +1,80 @@
-import React, { useState } from "react";
+import React, { useState, useRef } from "react";
import { View, Text, Button, Image } from "@tarojs/components";
+import { Dialog } from "@nutui/nutui-react-taro";
import Taro, { useDidShow, useRouter } from "@tarojs/taro";
import dayjs from "dayjs";
+import classnames from "classnames";
import orderService, {
+ CancelType,
GameOrderRes,
OrderStatus,
+ RefundStatus,
} from "@/services/orderService";
import {
payOrder,
delay,
calculateDistance,
getCurrentLocation,
+ getOrderStatus,
+ generateOrderActions,
+ reloadPage,
} from "@/utils";
import detailService, { GameData } from "@/services/detailService";
-import { withAuth } from "@/components";
+import { withAuth, RefundPopup } from "@/components";
import img from "@/config/images";
import { DECLAIMER } from "./config";
import styles from "./index.module.scss";
dayjs.locale("zh-cn");
+const refundTextMap = new Map([
+ [RefundStatus.NONE, "已支付"],
+ [RefundStatus.PENDING, "退款中"],
+ [RefundStatus.SUCCESS, "已退款"],
+]);
+
+const gameNoticeMap = new Map([
+ [
+ "pending",
+ { title: "球局暂未开始", content: "球局开始前2小时,我们将通过短信通知你" },
+ ],
+ [
+ "pendinging",
+ {
+ title: "球局即将开始,请按时抵达球局",
+ content: "球局开始前2小时,我们将通过短信通知你",
+ },
+ ],
+ ["progress", { title: "球局已开始", content: "友谊第一,比赛第二" }],
+ ["finish", { title: "球局已结束", content: "" }],
+]);
+
+function genGameNotice(order_status, start_time) {
+ const startTime = dayjs(start_time);
+ let key = "";
+ if (order_status === OrderStatus.FINISHED) {
+ key = "finish";
+ }
+ const leftHour = startTime.diff(dayjs(), "hour");
+ const start = startTime.isBefore(dayjs());
+ if (start) {
+ key = "progress";
+ } else if (leftHour > 2) {
+ key = "pending";
+ } else if (leftHour < 2) {
+ key = "pendinging";
+ }
+ return gameNoticeMap.get(key) || {};
+}
+
function GameInfo(props) {
const { detail, currentLocation, orderDetail } = props;
- const { order_status } = orderDetail;
+ const { order_status, refund_status } = orderDetail;
const { latitude, longitude, location, location_name, start_time, end_time } =
detail || {};
+ const refundRef = useRef(null);
+
const openMap = () => {
Taro.openLocation({
latitude, // 纬度(必填)
@@ -52,14 +101,129 @@ function GameInfo(props) {
const startDate = `${startMonth}月${startDay}日 ${theDayOfWeek}`;
const gameRange = `${startTime.format("HH:mm")} - ${endTime.format("HH:mm")}`;
+ const orderStatus = getOrderStatus(orderDetail);
+
+ const gameNotice = genGameNotice(order_status, start_time);
+
+ function handleViewGame(gameId) {
+ Taro.navigateTo({
+ url: `/game_pages/detail/index?id=${gameId}&from=orderList`,
+ });
+ }
+
+ async function handleDeleteOrder(item) {
+ const { order_id } = item;
+ // TODO:删除订单,刷新这一页,然后后面的全清除掉
+ const onCancel = () => {
+ Dialog.close("detailCancelOrder");
+ };
+ const onConfirm = async () => {
+ try {
+ const deleteRes = await orderService.deleteOrder({
+ order_id,
+ });
+ if (deleteRes.code !== 0) {
+ throw new Error(deleteRes.message);
+ }
+ Taro.showToast({
+ title: "删除成功",
+ icon: "none",
+ });
+ delay(2000);
+ Taro.redirectTo({ url: "/order_pages/orderList/index" });
+ } catch (e) {
+ Taro.showToast({
+ title: e.message,
+ icon: "error",
+ });
+ } finally {
+ Dialog.close("detailCancelOrder");
+ }
+ };
+ Dialog.open("detailCancelOrder", {
+ title: "确定删除订单吗?",
+ content: "删除订单后,您将无法恢复订单。请确认是否继续取消?",
+ footer: (
+
+
+
+
+ ),
+ onConfirm,
+ onCancel,
+ });
+ }
+
+ async function handleCancelOrder(item) {
+ const { order_no } = item;
+ const onCancel = () => {
+ Dialog.close("detailCancelOrder");
+ };
+ const onConfirm = async () => {
+ try {
+ const cancelRes = await orderService.cancelUnpaidOrder({
+ order_no,
+ cancel_reason: "用户主动取消",
+ });
+ if (cancelRes.code !== 0) {
+ throw new Error(cancelRes.message);
+ }
+ reloadPage();
+ Taro.showToast({
+ title: "取消成功",
+ icon: "none",
+ });
+ } catch (e) {
+ Taro.showToast({
+ title: e.message,
+ icon: "error",
+ });
+ } finally {
+ Dialog.close("detailCancelOrder");
+ }
+ };
+ Dialog.open("detailCancelOrder", {
+ title: "确定取消订单吗?",
+ content: "取消订单后,您将无法恢复订单。请确认是否继续取消?",
+ footer: (
+
+
+
+
+ ),
+ onConfirm,
+ onCancel,
+ });
+ }
+
+ function handleQuit(item) {
+ if (refundRef.current) {
+ refundRef.current.show(item, (result) => {
+ if (result) {
+ reloadPage();
+ }
+ });
+ }
+ }
+
return (
- {Boolean(order_status) && order_status !== OrderStatus.PENDING && (
+ {["progress", "expired"].includes(orderStatus) && (
<>
- 已支付 ¥ 90
+
+ {refundTextMap.get(refund_status)} ¥ 90
+
- 球局暂未开始
- 球局开始前2小时,我们将通过短信通知你
+ {gameNotice.title}
+ {gameNotice.content && {gameNotice.content}}
>
)}
@@ -122,13 +286,36 @@ function GameInfo(props) {
{/* Action bar */}
-
+
+ {orderDetail.order_id
+ ? generateOrderActions(
+ orderDetail,
+ {
+ handleDeleteOrder,
+ handleCancelOrder,
+ handleQuit,
+ handlePayNow: () => {},
+ handleViewGame,
+ },
+ "detail"
+ )?.map((obj) => (
+
+ ))
+ : ""}
+
+
+
);
}
function OrderMsg(props) {
- const { detail, checkOrderInfo } = props;
+ const { detail, orderDetail, checkOrderInfo } = props;
const {
start_time,
end_time,
@@ -137,7 +324,8 @@ function OrderMsg(props) {
wechat_contact,
price,
} = detail;
- const { order_info: { registrant_nickname, registrant_phone } = {} } = checkOrderInfo;
+ const { order_no } = orderDetail;
+ const { order_info: { registrant_phone } = {} } = checkOrderInfo;
const startTime = dayjs(start_time);
const endTime = dayjs(end_time);
const startYear = startTime.format("YYYY");
@@ -159,18 +347,30 @@ function OrderMsg(props) {
),
},
- {
- title: "报名人昵称",
- content: registrant_nickname,
- },
{
title: "报名人电话",
content: registrant_phone,
},
+ {
+ title: "组织人微信号",
+ content: wechat_contact,
+ },
+ {
+ title: "组织人电话",
+ content: wechat_contact,
+ },
{
title: "费用",
content: `${price} 元 / 人`,
},
+ ...(order_no
+ ? [
+ {
+ title: "订单号",
+ content: order_no,
+ },
+ ]
+ : []),
];
return (
@@ -199,8 +399,12 @@ function RefundPolicy(props) {
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 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");
@@ -332,6 +536,9 @@ const OrderCheck = () => {
);
}
+
+ const { order_status, cancel_type } = orderDetail;
+
return (
{/* Game Date and Address */}
@@ -341,14 +548,20 @@ const OrderCheck = () => {
currentLocation={location}
/>
{/* Order message */}
-
+
{/* Refund policy */}
{/* Disclaimer */}
- {(!id || orderDetail.order_status === OrderStatus.PENDING) && (
+ {(!id ||
+ (order_status === OrderStatus.PENDING &&
+ cancel_type === CancelType.NONE)) && (
)}
diff --git a/src/order_pages/orderList/index.module.scss b/src/order_pages/orderList/index.module.scss
index 3426f13..b7474e2 100644
--- a/src/order_pages/orderList/index.module.scss
+++ b/src/order_pages/orderList/index.module.scss
@@ -311,74 +311,6 @@
}
}
-.refundPolicy {
- .moduleTitle {
- display: flex;
- padding: 15px 0 8px;
- justify-content: space-between;
- align-items: center;
- align-self: stretch;
- color: #000;
- font-feature-settings:
- "liga" off,
- "clig" off;
- font-family: "PingFang SC";
- font-size: 14px;
- font-style: normal;
- font-weight: 600;
- line-height: 20px;
- letter-spacing: -0.23px;
- }
-
- .policyList {
- border-radius: 12px;
- border: 1px solid rgba(0, 0, 0, 0.06);
- background: #fff;
- box-shadow: 0 4px 36px 0 rgba(0, 0, 0, 0.06);
-
- .policyItem {
- display: flex;
- justify-content: space-around;
- align-items: center;
- color: #000;
- text-align: center;
- font-feature-settings:
- "liga" off,
- "clig" off;
- font-family: "PingFang SC";
- font-size: 12px;
- font-style: normal;
- font-weight: 400;
- line-height: 20px;
- border-top: 1px solid rgba(0, 0, 0, 0.06);
-
- &:nth-child(1) {
- color: #000;
- text-align: center;
- font-feature-settings:
- "liga" off,
- "clig" off;
- font-family: "PingFang SC";
- font-size: 14px;
- font-style: normal;
- font-weight: 600;
- line-height: 20px;
- border: none;
- }
-
- .time,
- .rule {
- width: 50%;
- padding: 10px 12px;
- }
-
- .rule {
- border-left: 1px solid rgba(0, 0, 0, 0.06);
- }
- }
- }
-}
-
.dialogFooter {
// width: 100%;
width: calc(100% + 1px);
diff --git a/src/order_pages/orderList/index.tsx b/src/order_pages/orderList/index.tsx
index 8f9adcd..fbc749a 100644
--- a/src/order_pages/orderList/index.tsx
+++ b/src/order_pages/orderList/index.tsx
@@ -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 (
<>
- {diffDay <= 2
+ {diffDay <= 2 && diffDay >= 0
? diffDayMap.get(diffDay)
: startTime.format("YYYY-MM-DD")}
({DayOfWeekMap.get(dayofWeek)})
+ {startTime.format('ah')}点
{gameLength}
>
);
@@ -58,6 +59,7 @@ function generateTimeMsg(game_info) {
const OrderList = () => {
const [list, setList] = useState([]);
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 (
-
-
- 退款政策
-
- {/* 订单信息摘要 */}
-
- {policyList.map((item, index) => (
-
- {item.time}
- {item.rule}
-
- ))}
-
-
- );
- }
-
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: (
-
-
-
-
- ),
- 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: (
+
+
+
+
+ ),
+ 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 = () => {
>
{/* */}
{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 = () => {
- {unPay && !expired ? "待支付" : "已支付"} ¥{" "}
+ {unPay ? "待支付" : "已支付"} ¥{" "}
{item.amount}
@@ -372,18 +295,48 @@ const OrderList = () => {
{participants.length >= 0 ? (
- {/* 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 ;
- })}
+ {
+ /* 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 (
+
+ );
+ })
+ }
) : (
""
)}
- 报名人数 {current_players}
+
+ 报名人数 {current_players}
+
/
{max_players}
@@ -400,45 +353,27 @@ const OrderList = () => {
- {expired && (
+ {generateOrderActions(
+ item,
+ {
+ handleDeleteOrder,
+ handleCancelOrder,
+ handleQuit,
+ handlePayNow,
+ handleViewGame,
+ },
+ "list"
+ )?.map((obj) => (
- )}
- {showCancel && (
-
- )}
- {showQuit && (
-
- )}
- {unPay && !expired ? (
-
- ) : (
-
- )}
+ ))}
@@ -447,6 +382,7 @@ const OrderList = () => {
{end && 已经到底了~}
+
);
};
diff --git a/src/services/orderService.ts b/src/services/orderService.ts
index fbf6a05..787267e 100644
--- a/src/services/orderService.ts
+++ b/src/services/orderService.ts
@@ -22,6 +22,12 @@ export enum CancelType {
TIMEOUT, // 超时
}
+export enum RefundStatus {
+ NONE = 0, // 无退款
+ PENDING, // 退款中
+ SUCCESS, // 已退款
+}
+
export interface PayMentParams {
order_id: number;
order_no: string;
diff --git a/src/static/order/orderListClose.svg b/src/static/order/orderListClose.svg
new file mode 100644
index 0000000..5cde120
--- /dev/null
+++ b/src/static/order/orderListClose.svg
@@ -0,0 +1,4 @@
+
diff --git a/src/utils/index.ts b/src/utils/index.ts
index af30b5d..08ea333 100644
--- a/src/utils/index.ts
+++ b/src/utils/index.ts
@@ -5,3 +5,5 @@ export * from "./processImage";
export * from "./timeUtils";
export * from "./tokenManager";
export * from "./order.pay";
+export * from './orderActions';
+export * from './routeUtil';
diff --git a/src/utils/orderActions.ts b/src/utils/orderActions.ts
new file mode 100644
index 0000000..49f4e4b
--- /dev/null
+++ b/src/utils/orderActions.ts
@@ -0,0 +1,68 @@
+import { OrderStatus, CancelType } from "@/services/orderService";
+
+export function getOrderStatus(orderData) {
+ const { order_status, cancel_type } = orderData
+ const unPay = order_status === OrderStatus.PENDING && cancel_type === CancelType.NONE;
+ const expired =
+ order_status === OrderStatus.FINISHED ||
+ [CancelType.TIMEOUT, CancelType.USER].includes(cancel_type);
+
+ return unPay ? 'unpay' : expired ? 'expired' : 'progress'
+}
+
+// scene: list、detail
+export function generateOrderActions(orderData, actions, scene) {
+
+
+ const { handleDeleteOrder, handleCancelOrder, handleQuit, handlePayNow, handleViewGame } = actions
+
+ const deleteOrder = {
+ text: '删除订单',
+ className: 'cancelOrder',
+ action: handleDeleteOrder.bind(null, orderData),
+ }
+
+ const cancelOrder = {
+ text: '取消订单',
+ className: 'cancelOrder',
+ action: handleCancelOrder.bind(null, orderData),
+ }
+
+ const quitGame = {
+ text: '退出活动',
+ className: 'cancelOrder',
+ action: handleQuit.bind(null, orderData),
+ }
+
+ const payNow = {
+ text: '立即支付',
+ className: 'payNow',
+ action: handlePayNow.bind(null, orderData),
+ }
+
+ const gameDetail = {
+ text: '球局详情',
+ className: 'gameDetail',
+ action: handleViewGame.bind(null, orderData.game_info.id),
+ }
+
+ const key = getOrderStatus(orderData)
+
+ if (scene === 'list') {
+ const actionMap = new Map([
+ ['expired', [deleteOrder, gameDetail]],
+ ['progress', [quitGame, gameDetail]],
+ ['unpay', [cancelOrder, payNow]]
+ ])
+ return actionMap.get(key)
+ }
+
+ if (scene === 'detail') {
+ const actionMap = new Map([
+ ['expired', [gameDetail, deleteOrder]],
+ ['progress', [gameDetail, quitGame]],
+ ['unpay', [cancelOrder]]
+ ])
+ return actionMap.get(key)
+ }
+}
diff --git a/src/utils/routeUtil.ts b/src/utils/routeUtil.ts
new file mode 100644
index 0000000..178655e
--- /dev/null
+++ b/src/utils/routeUtil.ts
@@ -0,0 +1,23 @@
+import Taro from "@tarojs/taro";
+
+export function getCurrentFullPath(): string {
+ const pages = Taro.getCurrentPages();
+ const currentPage = pages.at(-1);
+
+ if (currentPage) {
+ console.log(currentPage, "currentPage get");
+ const route = currentPage.route;
+ const options = currentPage.options || {};
+
+ const query = Object.keys(options)
+ .map((key) => `${key}=${options[key]}`)
+ .join("&");
+
+ return query ? `/${route}?${query}` : `/${route}`;
+ }
+ return "";
+}
+
+export function reloadPage() {
+ Taro.reLaunch({ url: getCurrentFullPath() })
+}