240 lines
6.7 KiB
TypeScript
240 lines
6.7 KiB
TypeScript
import React, {
|
||
useState,
|
||
forwardRef,
|
||
useImperativeHandle,
|
||
useRef,
|
||
} from "react";
|
||
import Taro from "@tarojs/taro";
|
||
import { View, Text, Input } from "@tarojs/components";
|
||
import CommonPopup from "../CommonPopup";
|
||
import styles from "./index.module.scss";
|
||
import detailService, { MATCH_STATUS } from "@/services/detailService";
|
||
import { useUserInfo } from "@/store/userStore";
|
||
import dayjs from "dayjs";
|
||
|
||
const CancelPopup = forwardRef((props, ref) => {
|
||
const { detail } = props;
|
||
const [visible, setVisible] = useState(false);
|
||
const [cancelReason, setCancelReason] = useState("");
|
||
const onFinish = useRef(null);
|
||
const inputRef = useRef(null);
|
||
|
||
const { current_players, participants = [], publisher_id } = detail;
|
||
const realParticipants = participants
|
||
.filter((item) => item.status === "joined")
|
||
.map((item) => item.user.id);
|
||
const hasOtherJoin =
|
||
current_players > 1 ||
|
||
realParticipants.some((id) => id !== Number(publisher_id));
|
||
// const hasOtherJoin = true;
|
||
|
||
useImperativeHandle(ref, () => ({
|
||
show: (onAct) => {
|
||
onFinish.current = onAct;
|
||
setVisible(true);
|
||
// 使用 requestAnimationFrame 替代 setTimeout(0),性能更好
|
||
requestAnimationFrame(() => {
|
||
requestAnimationFrame(() => {
|
||
inputRef.current && inputRef.current.focus();
|
||
});
|
||
});
|
||
},
|
||
}));
|
||
|
||
function onClose() {
|
||
setVisible(false);
|
||
setCancelReason("");
|
||
}
|
||
|
||
async function handleConfirm() {
|
||
if (!cancelReason && hasOtherJoin) {
|
||
Taro.showToast({ title: "请输入取消原因", icon: "none" });
|
||
return;
|
||
}
|
||
try {
|
||
await onFinish.current(hasOtherJoin ? cancelReason : "无责取消");
|
||
onClose();
|
||
} catch (e) {
|
||
console.log(e, 1221);
|
||
}
|
||
}
|
||
|
||
return (
|
||
<>
|
||
<CommonPopup
|
||
visible={visible}
|
||
showHeader={false}
|
||
hideFooter
|
||
zIndex={1002}
|
||
enableDragToClose={false}
|
||
onClose={onClose}
|
||
position="center"
|
||
style={{
|
||
width: hasOtherJoin ? "360px" : "300px",
|
||
borderRadius: "16px",
|
||
}}
|
||
>
|
||
<View className={styles.centerContainer}>
|
||
<View className={styles.title}>确定要取消活动吗?</View>
|
||
<View className={styles.content}>
|
||
<Text className={styles.tips}>
|
||
{hasOtherJoin
|
||
? "已有球友报名,取消后将为他们自动退款"
|
||
: "有100+球友正在浏览您的球局哦~"}
|
||
</Text>
|
||
{hasOtherJoin && (
|
||
<View className={styles.cancelReason}>
|
||
<Input
|
||
ref={inputRef}
|
||
className={styles.input}
|
||
placeholder="请输入取消理由"
|
||
focus
|
||
value={cancelReason}
|
||
onInput={(e) => setCancelReason(e.detail.value)}
|
||
maxlength={100}
|
||
/>
|
||
</View>
|
||
)}
|
||
</View>
|
||
<View className={styles.actions}>
|
||
<View className={styles.confirm} onClick={handleConfirm}>
|
||
确认取消
|
||
</View>
|
||
<View className={styles.cancel} onClick={onClose}>
|
||
再想想
|
||
</View>
|
||
</View>
|
||
</View>
|
||
</CommonPopup>
|
||
</>
|
||
);
|
||
});
|
||
|
||
export default forwardRef(function GameManagePopup(props, ref) {
|
||
const [visible, setVisible] = useState(false);
|
||
const [detail, setDetail] = useState({});
|
||
const onStatusChange = useRef(null);
|
||
const cancelRef = useRef(null);
|
||
const userInfo = useUserInfo();
|
||
|
||
useImperativeHandle(ref, () => ({
|
||
show: (gameDetail, onChange) => {
|
||
onStatusChange.current = onChange;
|
||
setDetail(gameDetail);
|
||
setVisible(true);
|
||
},
|
||
}));
|
||
|
||
function handleEditGame() {
|
||
Taro.navigateTo({
|
||
url: `/publish_pages/publishBall/index?gameId=${detail.id}&republish=0`,
|
||
});
|
||
onClose();
|
||
}
|
||
|
||
function handleRepubGame() {
|
||
Taro.navigateTo({
|
||
url: `/publish_pages/publishBall/index?gameId=${detail.id}&republish=1`,
|
||
});
|
||
onClose();
|
||
}
|
||
|
||
async function handleCancelGame() {
|
||
cancelRef.current.show(async (result) => {
|
||
if (result) {
|
||
try {
|
||
const res = await detailService.disbandGame({
|
||
game_id: detail.id,
|
||
settle_reason: result,
|
||
});
|
||
if (res.code === 0) {
|
||
Taro.showToast({ title: "活动取消成功" });
|
||
onStatusChange.current?.(true);
|
||
}
|
||
} catch (e) {
|
||
Taro.showToast({ title: e.message, icon: "error" });
|
||
return e;
|
||
}
|
||
}
|
||
});
|
||
onClose();
|
||
}
|
||
|
||
async function handleQuitGame() {
|
||
try {
|
||
const res = await detailService.organizerQuit({
|
||
game_id: detail.id,
|
||
quit_reason: "组织者主动退出",
|
||
});
|
||
if (res.code === 0) {
|
||
Taro.showToast({ title: "活动退出成功" });
|
||
onStatusChange.current?.(true);
|
||
}
|
||
} catch (e) {
|
||
Taro.showToast({ title: e.message, icon: "error" });
|
||
} finally {
|
||
onClose();
|
||
}
|
||
}
|
||
|
||
function onClose() {
|
||
setVisible(false);
|
||
}
|
||
|
||
const hasJoin = (detail.participants || [])
|
||
.filter((item) => item.status === "joined")
|
||
.some((item) => item.user.id === userInfo.id);
|
||
|
||
const finished = [MATCH_STATUS.FINISHED, MATCH_STATUS.CANCELED].includes(
|
||
detail.match_status,
|
||
);
|
||
|
||
// const inTwoHours = dayjs(detail.start_time).diff(dayjs(), "hour") < 2;
|
||
const beforeStart = dayjs(detail.start_time).isAfter(dayjs());
|
||
|
||
const hasOtherParticiappants = (detail.participants || [])
|
||
.filter((item) => item.status === "joined")
|
||
.some((item) => item.user.id !== userInfo.id);
|
||
|
||
return (
|
||
<>
|
||
<CommonPopup
|
||
visible={visible}
|
||
showHeader={false}
|
||
hideFooter
|
||
zIndex={1001}
|
||
enableDragToClose={false}
|
||
onClose={onClose}
|
||
style={{ minHeight: "unset" }}
|
||
>
|
||
<View className={styles.container}>
|
||
{!finished && !hasOtherParticiappants && beforeStart && (
|
||
<View className={styles.button} onClick={handleEditGame}>
|
||
编辑活动
|
||
</View>
|
||
)}
|
||
{finished && (
|
||
<View className={styles.button} onClick={handleRepubGame}>
|
||
重新发布
|
||
</View>
|
||
)}
|
||
{!finished && beforeStart && (
|
||
<View className={styles.button} onClick={handleCancelGame}>
|
||
取消活动
|
||
</View>
|
||
)}
|
||
{!finished && beforeStart && hasJoin && (
|
||
<View className={styles.button} onClick={handleQuitGame}>
|
||
退出活动
|
||
</View>
|
||
)}
|
||
<View className={styles.button} onClick={onClose}>
|
||
取消
|
||
</View>
|
||
</View>
|
||
</CommonPopup>
|
||
<CancelPopup ref={cancelRef} detail={detail} />
|
||
</>
|
||
);
|
||
});
|