feat: 订单模块基本完成
This commit is contained in:
@@ -1,26 +1,9 @@
|
|||||||
import React, { useEffect, useState } from "react";
|
import React, { useEffect, useState } from "react";
|
||||||
import { View } from "@tarojs/components";
|
import { View } from "@tarojs/components";
|
||||||
import Taro from "@tarojs/taro";
|
import Taro from "@tarojs/taro";
|
||||||
|
import { getCurrentFullPath } from '@/utils';
|
||||||
import { check_login_status } from "@/services/loginService";
|
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<P extends object>(
|
export default function withAuth<P extends object>(
|
||||||
WrappedComponent: React.ComponentType<P>,
|
WrappedComponent: React.ComponentType<P>,
|
||||||
) {
|
) {
|
||||||
|
|||||||
@@ -16,6 +16,7 @@ import EditModal from "./EditModal/index";
|
|||||||
import withAuth from "./Auth";
|
import withAuth from "./Auth";
|
||||||
import { CustomPicker, PopupPicker } from "./Picker";
|
import { CustomPicker, PopupPicker } from "./Picker";
|
||||||
import NTRPEvaluatePopup from "./NTRPEvaluatePopup";
|
import NTRPEvaluatePopup from "./NTRPEvaluatePopup";
|
||||||
|
import RefundPopup from "./refundPopup";
|
||||||
|
|
||||||
export {
|
export {
|
||||||
ActivityTypeSwitch,
|
ActivityTypeSwitch,
|
||||||
@@ -37,4 +38,5 @@ export {
|
|||||||
CustomPicker,
|
CustomPicker,
|
||||||
PopupPicker,
|
PopupPicker,
|
||||||
NTRPEvaluatePopup,
|
NTRPEvaluatePopup,
|
||||||
|
RefundPopup,
|
||||||
};
|
};
|
||||||
|
|||||||
132
src/components/refundPopup/index.module.scss
Normal file
132
src/components/refundPopup/index.module.scss
Normal file
@@ -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;
|
||||||
|
}
|
||||||
|
}
|
||||||
139
src/components/refundPopup/index.tsx
Normal file
139
src/components/refundPopup/index.tsx
Normal file
@@ -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 (
|
||||||
|
<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={styles.policyItem}>
|
||||||
|
<View className={styles.time}>{item.time}</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 [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 (
|
||||||
|
<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(checkOrderInfo)}
|
||||||
|
<Button className={styles.action} onClick={handleConfirmQuit}>确认并退出</Button>
|
||||||
|
</View>
|
||||||
|
</CommonPopup>
|
||||||
|
)
|
||||||
|
})
|
||||||
@@ -229,7 +229,34 @@
|
|||||||
|
|
||||||
.gameInfoActions {
|
.gameInfoActions {
|
||||||
min-height: 12px;
|
min-height: 12px;
|
||||||
|
padding: 0 12px;
|
||||||
border-top: 0.5px solid rgba(0, 0, 0, 0.06);
|
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;
|
font-weight: 600;
|
||||||
line-height: normal;
|
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;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|||||||
@@ -1,31 +1,80 @@
|
|||||||
import React, { useState } from "react";
|
import React, { useState, useRef } from "react";
|
||||||
import { View, Text, Button, Image } from "@tarojs/components";
|
import { View, Text, Button, Image } from "@tarojs/components";
|
||||||
|
import { Dialog } from "@nutui/nutui-react-taro";
|
||||||
import Taro, { useDidShow, useRouter } from "@tarojs/taro";
|
import Taro, { useDidShow, useRouter } from "@tarojs/taro";
|
||||||
import dayjs from "dayjs";
|
import dayjs from "dayjs";
|
||||||
|
import classnames from "classnames";
|
||||||
import orderService, {
|
import orderService, {
|
||||||
|
CancelType,
|
||||||
GameOrderRes,
|
GameOrderRes,
|
||||||
OrderStatus,
|
OrderStatus,
|
||||||
|
RefundStatus,
|
||||||
} from "@/services/orderService";
|
} from "@/services/orderService";
|
||||||
import {
|
import {
|
||||||
payOrder,
|
payOrder,
|
||||||
delay,
|
delay,
|
||||||
calculateDistance,
|
calculateDistance,
|
||||||
getCurrentLocation,
|
getCurrentLocation,
|
||||||
|
getOrderStatus,
|
||||||
|
generateOrderActions,
|
||||||
|
reloadPage,
|
||||||
} from "@/utils";
|
} from "@/utils";
|
||||||
import detailService, { GameData } from "@/services/detailService";
|
import detailService, { GameData } from "@/services/detailService";
|
||||||
import { withAuth } from "@/components";
|
import { withAuth, RefundPopup } from "@/components";
|
||||||
import img from "@/config/images";
|
import img from "@/config/images";
|
||||||
import { DECLAIMER } from "./config";
|
import { DECLAIMER } from "./config";
|
||||||
import styles from "./index.module.scss";
|
import styles from "./index.module.scss";
|
||||||
|
|
||||||
dayjs.locale("zh-cn");
|
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) {
|
function GameInfo(props) {
|
||||||
const { detail, currentLocation, orderDetail } = 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 } =
|
const { latitude, longitude, location, location_name, start_time, end_time } =
|
||||||
detail || {};
|
detail || {};
|
||||||
|
|
||||||
|
const refundRef = useRef(null);
|
||||||
|
|
||||||
const openMap = () => {
|
const openMap = () => {
|
||||||
Taro.openLocation({
|
Taro.openLocation({
|
||||||
latitude, // 纬度(必填)
|
latitude, // 纬度(必填)
|
||||||
@@ -52,14 +101,129 @@ function GameInfo(props) {
|
|||||||
const startDate = `${startMonth}月${startDay}日 ${theDayOfWeek}`;
|
const startDate = `${startMonth}月${startDay}日 ${theDayOfWeek}`;
|
||||||
const gameRange = `${startTime.format("HH:mm")} - ${endTime.format("HH:mm")}`;
|
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: (
|
||||||
|
<View className={styles.dialogFooter}>
|
||||||
|
<Button className={styles.cancel} onClick={onCancel}>
|
||||||
|
取消
|
||||||
|
</Button>
|
||||||
|
<Button className={styles.confirm} type="primary" onClick={onConfirm}>
|
||||||
|
确认
|
||||||
|
</Button>
|
||||||
|
</View>
|
||||||
|
),
|
||||||
|
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: (
|
||||||
|
<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) {
|
||||||
|
reloadPage();
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<View className={styles.gameInfoContainer}>
|
<View className={styles.gameInfoContainer}>
|
||||||
{Boolean(order_status) && order_status !== OrderStatus.PENDING && (
|
{["progress", "expired"].includes(orderStatus) && (
|
||||||
<>
|
<>
|
||||||
<View className={styles.paidInfo}>已支付 ¥ 90</View>
|
<View className={styles.paidInfo}>
|
||||||
|
{refundTextMap.get(refund_status)} ¥ 90
|
||||||
|
</View>
|
||||||
<View className={styles.gameStatus}>
|
<View className={styles.gameStatus}>
|
||||||
<Text className={styles.statusText}>球局暂未开始</Text>
|
<Text className={styles.statusText}>{gameNotice.title}</Text>
|
||||||
<Text>球局开始前2小时,我们将通过短信通知你</Text>
|
{gameNotice.content && <Text>{gameNotice.content}</Text>}
|
||||||
</View>
|
</View>
|
||||||
</>
|
</>
|
||||||
)}
|
)}
|
||||||
@@ -122,13 +286,36 @@ function GameInfo(props) {
|
|||||||
</View>
|
</View>
|
||||||
</View>
|
</View>
|
||||||
{/* Action bar */}
|
{/* Action bar */}
|
||||||
<View className={styles.gameInfoActions}></View>
|
<View className={styles.gameInfoActions}>
|
||||||
|
{orderDetail.order_id
|
||||||
|
? generateOrderActions(
|
||||||
|
orderDetail,
|
||||||
|
{
|
||||||
|
handleDeleteOrder,
|
||||||
|
handleCancelOrder,
|
||||||
|
handleQuit,
|
||||||
|
handlePayNow: () => {},
|
||||||
|
handleViewGame,
|
||||||
|
},
|
||||||
|
"detail"
|
||||||
|
)?.map((obj) => (
|
||||||
|
<Button
|
||||||
|
className={classnames(styles.button, styles[obj.className])}
|
||||||
|
onClick={obj.action}
|
||||||
|
>
|
||||||
|
{obj.text}
|
||||||
|
</Button>
|
||||||
|
))
|
||||||
|
: ""}
|
||||||
|
</View>
|
||||||
|
<Dialog id="detailCancelOrder" />
|
||||||
|
<RefundPopup ref={refundRef} />
|
||||||
</View>
|
</View>
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
function OrderMsg(props) {
|
function OrderMsg(props) {
|
||||||
const { detail, checkOrderInfo } = props;
|
const { detail, orderDetail, checkOrderInfo } = props;
|
||||||
const {
|
const {
|
||||||
start_time,
|
start_time,
|
||||||
end_time,
|
end_time,
|
||||||
@@ -137,7 +324,8 @@ function OrderMsg(props) {
|
|||||||
wechat_contact,
|
wechat_contact,
|
||||||
price,
|
price,
|
||||||
} = detail;
|
} = 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 startTime = dayjs(start_time);
|
||||||
const endTime = dayjs(end_time);
|
const endTime = dayjs(end_time);
|
||||||
const startYear = startTime.format("YYYY");
|
const startYear = startTime.format("YYYY");
|
||||||
@@ -159,18 +347,30 @@ function OrderMsg(props) {
|
|||||||
</View>
|
</View>
|
||||||
),
|
),
|
||||||
},
|
},
|
||||||
{
|
|
||||||
title: "报名人昵称",
|
|
||||||
content: registrant_nickname,
|
|
||||||
},
|
|
||||||
{
|
{
|
||||||
title: "报名人电话",
|
title: "报名人电话",
|
||||||
content: registrant_phone,
|
content: registrant_phone,
|
||||||
},
|
},
|
||||||
|
{
|
||||||
|
title: "组织人微信号",
|
||||||
|
content: wechat_contact,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
title: "组织人电话",
|
||||||
|
content: wechat_contact,
|
||||||
|
},
|
||||||
{
|
{
|
||||||
title: "费用",
|
title: "费用",
|
||||||
content: `${price} 元 / 人`,
|
content: `${price} 元 / 人`,
|
||||||
},
|
},
|
||||||
|
...(order_no
|
||||||
|
? [
|
||||||
|
{
|
||||||
|
title: "订单号",
|
||||||
|
content: order_no,
|
||||||
|
},
|
||||||
|
]
|
||||||
|
: []),
|
||||||
];
|
];
|
||||||
return (
|
return (
|
||||||
<View className={styles.orderSummary}>
|
<View className={styles.orderSummary}>
|
||||||
@@ -199,8 +399,12 @@ function RefundPolicy(props) {
|
|||||||
rule: "退款规则",
|
rule: "退款规则",
|
||||||
},
|
},
|
||||||
...refund_policy.map((item, index) => {
|
...refund_policy.map((item, index) => {
|
||||||
const isLast = index === refund_policy.length - 1
|
const isLast = index === refund_policy.length - 1;
|
||||||
const theTimeObj = dayjs(isLast ? refund_policy.at(-2).deadline_formatted : item.deadline_formatted);
|
const theTimeObj = dayjs(
|
||||||
|
isLast
|
||||||
|
? refund_policy.at(-2).deadline_formatted
|
||||||
|
: item.deadline_formatted
|
||||||
|
);
|
||||||
const year = theTimeObj.format("YYYY");
|
const year = theTimeObj.format("YYYY");
|
||||||
const month = theTimeObj.format("M");
|
const month = theTimeObj.format("M");
|
||||||
const day = theTimeObj.format("D");
|
const day = theTimeObj.format("D");
|
||||||
@@ -332,6 +536,9 @@ const OrderCheck = () => {
|
|||||||
</View>
|
</View>
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
const { order_status, cancel_type } = orderDetail;
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<View className={styles.container}>
|
<View className={styles.container}>
|
||||||
{/* Game Date and Address */}
|
{/* Game Date and Address */}
|
||||||
@@ -341,14 +548,20 @@ const OrderCheck = () => {
|
|||||||
currentLocation={location}
|
currentLocation={location}
|
||||||
/>
|
/>
|
||||||
{/* Order message */}
|
{/* Order message */}
|
||||||
<OrderMsg detail={detail} checkOrderInfo={checkOrderInfo} />
|
<OrderMsg
|
||||||
|
detail={detail}
|
||||||
|
orderDetail={orderDetail}
|
||||||
|
checkOrderInfo={checkOrderInfo}
|
||||||
|
/>
|
||||||
{/* Refund policy */}
|
{/* Refund policy */}
|
||||||
<RefundPolicy checkOrderInfo={checkOrderInfo} />
|
<RefundPolicy checkOrderInfo={checkOrderInfo} />
|
||||||
{/* Disclaimer */}
|
{/* Disclaimer */}
|
||||||
<Disclaimer />
|
<Disclaimer />
|
||||||
{(!id || orderDetail.order_status === OrderStatus.PENDING) && (
|
{(!id ||
|
||||||
|
(order_status === OrderStatus.PENDING &&
|
||||||
|
cancel_type === CancelType.NONE)) && (
|
||||||
<Button className={styles.payButton} onClick={handlePay}>
|
<Button className={styles.payButton} onClick={handlePay}>
|
||||||
{orderDetail.order_status === OrderStatus.PENDING ? "继续" : "确认"}
|
{order_status === OrderStatus.PENDING ? "继续" : "确认"}
|
||||||
支付
|
支付
|
||||||
</Button>
|
</Button>
|
||||||
)}
|
)}
|
||||||
|
|||||||
@@ -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 {
|
.dialogFooter {
|
||||||
// width: 100%;
|
// width: 100%;
|
||||||
width: calc(100% + 1px);
|
width: calc(100% + 1px);
|
||||||
|
|||||||
@@ -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 { View, Text, Button, Image, ScrollView } from "@tarojs/components";
|
||||||
import Taro, { useDidShow } from "@tarojs/taro";
|
import Taro, { useDidShow } from "@tarojs/taro";
|
||||||
import { Avatar, Dialog } from "@nutui/nutui-react-taro";
|
import { Avatar, Dialog } from "@nutui/nutui-react-taro";
|
||||||
import dayjs from "dayjs";
|
import dayjs from "dayjs";
|
||||||
import classnames from "classnames";
|
import classnames from "classnames";
|
||||||
import orderService, { OrderStatus, CancelType } from "@/services/orderService";
|
import orderService, { OrderStatus, CancelType } from "@/services/orderService";
|
||||||
import { withAuth } from "@/components";
|
import { withAuth, RefundPopup } from "@/components";
|
||||||
import { payOrder } from "@/utils";
|
import { payOrder, generateOrderActions } from "@/utils";
|
||||||
import styles from "./index.module.scss";
|
import styles from "./index.module.scss";
|
||||||
// import orderListArrowRight from "@/static/order/orderListArrowRight.svg";
|
|
||||||
dayjs.locale("zh-cn");
|
dayjs.locale("zh-cn");
|
||||||
|
|
||||||
const PAGESIZE = 20;
|
const PAGESIZE = 20;
|
||||||
@@ -45,11 +45,12 @@ function generateTimeMsg(game_info) {
|
|||||||
return (
|
return (
|
||||||
<>
|
<>
|
||||||
<Text>
|
<Text>
|
||||||
{diffDay <= 2
|
{diffDay <= 2 && diffDay >= 0
|
||||||
? diffDayMap.get(diffDay)
|
? diffDayMap.get(diffDay)
|
||||||
: startTime.format("YYYY-MM-DD")}
|
: startTime.format("YYYY-MM-DD")}
|
||||||
</Text>
|
</Text>
|
||||||
<Text>({DayOfWeekMap.get(dayofWeek)})</Text>
|
<Text>({DayOfWeekMap.get(dayofWeek)})</Text>
|
||||||
|
<Text>{startTime.format('ah')}点</Text>
|
||||||
<Text>{gameLength}</Text>
|
<Text>{gameLength}</Text>
|
||||||
</>
|
</>
|
||||||
);
|
);
|
||||||
@@ -58,6 +59,7 @@ function generateTimeMsg(game_info) {
|
|||||||
const OrderList = () => {
|
const OrderList = () => {
|
||||||
const [list, setList] = useState<any[][]>([]);
|
const [list, setList] = useState<any[][]>([]);
|
||||||
const [total, setTotal] = useState(0);
|
const [total, setTotal] = useState(0);
|
||||||
|
const refundRef = useRef(null)
|
||||||
|
|
||||||
const end = list.length * PAGESIZE >= total;
|
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) {
|
async function handleDeleteOrder(item) {
|
||||||
const { id: order_id } = item
|
const { id: order_id } = item
|
||||||
// TODO:删除订单,刷新这一页,然后后面的全清除掉
|
// TODO:删除订单,刷新这一页,然后后面的全清除掉
|
||||||
@@ -211,90 +171,65 @@ const OrderList = () => {
|
|||||||
}
|
}
|
||||||
|
|
||||||
async function handleCancelOrder(item) {
|
async function handleCancelOrder(item) {
|
||||||
const { order_no, order_status, game_info, amount } = item;
|
const { order_no } = item;
|
||||||
if (order_status === OrderStatus.PENDING) {
|
const onCancel = () => {
|
||||||
const onCancel = () => {
|
Dialog.close("cancelOrder");
|
||||||
Dialog.close("cancelOrder");
|
};
|
||||||
};
|
const onConfirm = async () => {
|
||||||
const onConfirm = async () => {
|
try {
|
||||||
try {
|
const cancelRes = await orderService.cancelUnpaidOrder({
|
||||||
const cancelRes = await orderService.cancelUnpaidOrder({
|
order_no,
|
||||||
order_no,
|
cancel_reason: "用户主动取消",
|
||||||
cancel_reason: "用户主动取消",
|
});
|
||||||
});
|
if (cancelRes.code !== 0) {
|
||||||
if (cancelRes.code !== 0) {
|
throw new Error(cancelRes.message);
|
||||||
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");
|
|
||||||
}
|
}
|
||||||
};
|
getOrders(item.page, false);
|
||||||
Dialog.open("cancelOrder", {
|
Taro.showToast({
|
||||||
title: "确定取消订单吗?",
|
title: "取消成功",
|
||||||
content: "取消订单后,您将无法恢复订单。请确认是否继续取消?",
|
icon: "none",
|
||||||
footer: (
|
})
|
||||||
<View className={styles.dialogFooter}>
|
} catch (e) {
|
||||||
<Button className={styles.cancel} onClick={onCancel}>
|
Taro.showToast({
|
||||||
取消
|
title: e.message,
|
||||||
</Button>
|
icon: "error",
|
||||||
<Button
|
});
|
||||||
className={styles.confirm}
|
} finally {
|
||||||
type="primary"
|
Dialog.close("cancelOrder");
|
||||||
onClick={onConfirm}
|
}
|
||||||
>
|
};
|
||||||
确认
|
|
||||||
</Button>
|
|
||||||
</View>
|
|
||||||
),
|
|
||||||
onConfirm,
|
|
||||||
onCancel,
|
|
||||||
});
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
const res = await orderService.getCheckOrderInfo(game_info.id);
|
|
||||||
Dialog.open("cancelOrder", {
|
Dialog.open("cancelOrder", {
|
||||||
title: "确定取消订单吗?",
|
title: "确定取消订单吗?",
|
||||||
content: renderCancelContent(res.data),
|
content: "取消订单后,您将无法恢复订单。请确认是否继续取消?",
|
||||||
onConfirm: async () => {
|
footer: (
|
||||||
try {
|
<View className={styles.dialogFooter}>
|
||||||
const refundRes = await orderService.applicateRefund({
|
<Button className={styles.cancel} onClick={onCancel}>
|
||||||
order_no,
|
取消
|
||||||
refund_amount: amount,
|
</Button>
|
||||||
refund_reason: "用户主动退款",
|
<Button
|
||||||
});
|
className={styles.confirm}
|
||||||
if (refundRes.code !== 0) {
|
type="primary"
|
||||||
throw new Error(refundRes.message);
|
onClick={onConfirm}
|
||||||
}
|
>
|
||||||
getOrders(item.page, false);
|
确认
|
||||||
Taro.showToast({
|
</Button>
|
||||||
title: "退出成功",
|
</View>
|
||||||
icon: "none",
|
),
|
||||||
})
|
onConfirm,
|
||||||
} catch (e) {
|
onCancel,
|
||||||
Taro.showToast({
|
|
||||||
title: e.message,
|
|
||||||
icon: "error",
|
|
||||||
});
|
|
||||||
} finally {
|
|
||||||
Dialog.close("cancelOrder");
|
|
||||||
}
|
|
||||||
},
|
|
||||||
onCancel: () => {
|
|
||||||
Dialog.close("cancelOrder");
|
|
||||||
},
|
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
function handleQuit (item) {
|
||||||
|
if (refundRef.current) {
|
||||||
|
refundRef.current.show(item, (result) => {
|
||||||
|
if (result) {
|
||||||
|
getOrders(item.page)
|
||||||
|
}
|
||||||
|
})
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
function handleViewOrderDetail(orderId) {
|
function handleViewOrderDetail(orderId) {
|
||||||
Taro.navigateTo({
|
Taro.navigateTo({
|
||||||
url: `/order_pages/orderDetail/index?id=${orderId}`,
|
url: `/order_pages/orderDetail/index?id=${orderId}`,
|
||||||
@@ -314,19 +249,7 @@ const OrderList = () => {
|
|||||||
>
|
>
|
||||||
{/* <View className={styles.bg} /> */}
|
{/* <View className={styles.bg} /> */}
|
||||||
{list.flat().map((item) => {
|
{list.flat().map((item) => {
|
||||||
const unPay = item.order_status === OrderStatus.PENDING;
|
const unPay = item.order_status === OrderStatus.PENDING && item.cancel_type === CancelType.NONE;
|
||||||
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 {
|
const {
|
||||||
game_info: {
|
game_info: {
|
||||||
@@ -352,10 +275,10 @@ const OrderList = () => {
|
|||||||
<View
|
<View
|
||||||
className={classnames(
|
className={classnames(
|
||||||
styles.payNum,
|
styles.payNum,
|
||||||
styles[unPay && !expired ? "pending" : "paid"]
|
styles[unPay ? "pending" : "paid"]
|
||||||
)}
|
)}
|
||||||
>
|
>
|
||||||
<Text>{unPay && !expired ? "待支付" : "已支付"}</Text> ¥{" "}
|
<Text>{unPay ? "待支付" : "已支付"}</Text> ¥{" "}
|
||||||
<Text>{item.amount}</Text>
|
<Text>{item.amount}</Text>
|
||||||
</View>
|
</View>
|
||||||
</View>
|
</View>
|
||||||
@@ -372,18 +295,48 @@ const OrderList = () => {
|
|||||||
<View className={styles.gameOtherInfo}>
|
<View className={styles.gameOtherInfo}>
|
||||||
{participants.length >= 0 ? (
|
{participants.length >= 0 ? (
|
||||||
<View className={styles.avatarCards}>
|
<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 {
|
/* participants */ [
|
||||||
user: { avatar_url, id },
|
{
|
||||||
} = participant;
|
user: {
|
||||||
return <Image className={styles.avatar} mode="aspectFill" key={id} src={avatar_url} />;
|
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>
|
||||||
) : (
|
) : (
|
||||||
""
|
""
|
||||||
)}
|
)}
|
||||||
<View className={styles.participantProgress}>
|
<View className={styles.participantProgress}>
|
||||||
<Text className={styles.current}>报名人数 {current_players}</Text>
|
<Text className={styles.current}>
|
||||||
|
报名人数 {current_players}
|
||||||
|
</Text>
|
||||||
<Text>/</Text>
|
<Text>/</Text>
|
||||||
<Text>{max_players}</Text>
|
<Text>{max_players}</Text>
|
||||||
</View>
|
</View>
|
||||||
@@ -400,45 +353,27 @@ const OrderList = () => {
|
|||||||
<View className={styles.orderActions}>
|
<View className={styles.orderActions}>
|
||||||
<View className={styles.extraActions}></View>
|
<View className={styles.extraActions}></View>
|
||||||
<View className={styles.mainActions}>
|
<View className={styles.mainActions}>
|
||||||
{expired && (
|
{generateOrderActions(
|
||||||
|
item,
|
||||||
|
{
|
||||||
|
handleDeleteOrder,
|
||||||
|
handleCancelOrder,
|
||||||
|
handleQuit,
|
||||||
|
handlePayNow,
|
||||||
|
handleViewGame,
|
||||||
|
},
|
||||||
|
"list"
|
||||||
|
)?.map((obj) => (
|
||||||
<Button
|
<Button
|
||||||
className={classnames(styles.button, styles.cancelOrder)}
|
className={classnames(
|
||||||
onClick={handleDeleteOrder.bind(null, item)}
|
styles.button,
|
||||||
|
styles[obj.className]
|
||||||
|
)}
|
||||||
|
onClick={obj.action}
|
||||||
>
|
>
|
||||||
删除订单
|
{obj.text}
|
||||||
</Button>
|
</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>
|
</View>
|
||||||
</View>
|
</View>
|
||||||
@@ -447,6 +382,7 @@ const OrderList = () => {
|
|||||||
{end && <View className={styles.endTips}>已经到底了~</View>}
|
{end && <View className={styles.endTips}>已经到底了~</View>}
|
||||||
</ScrollView>
|
</ScrollView>
|
||||||
<Dialog id="cancelOrder" />
|
<Dialog id="cancelOrder" />
|
||||||
|
<RefundPopup ref={refundRef} />
|
||||||
</View>
|
</View>
|
||||||
);
|
);
|
||||||
};
|
};
|
||||||
|
|||||||
@@ -22,6 +22,12 @@ export enum CancelType {
|
|||||||
TIMEOUT, // 超时
|
TIMEOUT, // 超时
|
||||||
}
|
}
|
||||||
|
|
||||||
|
export enum RefundStatus {
|
||||||
|
NONE = 0, // 无退款
|
||||||
|
PENDING, // 退款中
|
||||||
|
SUCCESS, // 已退款
|
||||||
|
}
|
||||||
|
|
||||||
export interface PayMentParams {
|
export interface PayMentParams {
|
||||||
order_id: number;
|
order_id: number;
|
||||||
order_no: string;
|
order_no: string;
|
||||||
|
|||||||
4
src/static/order/orderListClose.svg
Normal file
4
src/static/order/orderListClose.svg
Normal file
@@ -0,0 +1,4 @@
|
|||||||
|
<svg width="20" height="20" viewBox="0 0 20 20" fill="none" xmlns="http://www.w3.org/2000/svg">
|
||||||
|
<path d="M5.83325 5.83325L14.1666 14.1666" stroke="#A0A0A0" stroke-width="1.66667" stroke-linecap="round" stroke-linejoin="round"/>
|
||||||
|
<path d="M5.83325 14.1666L14.1666 5.83325" stroke="#A0A0A0" stroke-width="1.66667" stroke-linecap="round" stroke-linejoin="round"/>
|
||||||
|
</svg>
|
||||||
|
After Width: | Height: | Size: 367 B |
@@ -5,3 +5,5 @@ export * from "./processImage";
|
|||||||
export * from "./timeUtils";
|
export * from "./timeUtils";
|
||||||
export * from "./tokenManager";
|
export * from "./tokenManager";
|
||||||
export * from "./order.pay";
|
export * from "./order.pay";
|
||||||
|
export * from './orderActions';
|
||||||
|
export * from './routeUtil';
|
||||||
|
|||||||
68
src/utils/orderActions.ts
Normal file
68
src/utils/orderActions.ts
Normal file
@@ -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)
|
||||||
|
}
|
||||||
|
}
|
||||||
23
src/utils/routeUtil.ts
Normal file
23
src/utils/routeUtil.ts
Normal file
@@ -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() })
|
||||||
|
}
|
||||||
Reference in New Issue
Block a user