import { useEffect, useRef, useState } from "react";
import Taro from "@tarojs/taro";
import classnames from "classnames";
import dayjs from "dayjs";
import { debounce } from "@tarojs/runtime";
import { Text, View, Image } from "@tarojs/components";
import OrderService from "@/services/orderService";
import { EvaluateCallback, EvaluateScene } from "@/store/evaluateStore";
import { MATCH_STATUS, IsSubstituteSupported } from "@/services/detailService";
import { GameManagePopup, NTRPEvaluatePopup } from "@/components";
import { useUserInfo } from "@/store/userStore";
import img from "@/config/images";
// import RMB_ICON from "@/static/detail/rmb.svg";
import { toast, navto } from "@/utils/helper";
import styles from "./index.module.scss";
function isFull(counts) {
const {
max_players,
current_players,
max_substitute_players,
current_substitute_count,
is_substitute_supported,
} = counts;
if (
current_players >= max_players &&
is_substitute_supported === IsSubstituteSupported.NOTSUPPORT
) {
return true;
} else if (
current_players >= max_players &&
is_substitute_supported === IsSubstituteSupported.SUPPORT
) {
return max_substitute_players === current_substitute_count;
}
return false;
}
function RmbIcon() {
return ¥;
}
function matchNtrpRequestment(
target?: string,
min?: string,
max?: string,
): boolean {
// 目标值为空或 undefined
if (!target?.trim()) return true;
// 提取目标值中的第一个数字
const match = target.match(/-?\d+(\.\d+)?/);
if (!match) return true;
const value = parseFloat(match[0]);
const minNum = min !== undefined ? parseFloat(min) : undefined;
const maxNum = max !== undefined ? parseFloat(max) : undefined;
// min 和 max 都未定义 → 直接通过
if (minNum === undefined && maxNum === undefined) return true;
// min = max 或只有一边 undefined → 参考值判断,包含端点
if (minNum === undefined || maxNum === undefined || minNum === maxNum) {
return value >= (minNum ?? maxNum!);
}
// 正常区间判断,包含端点
return value >= minNum && value <= maxNum;
}
// 底部操作栏
export default function StickyButton(props) {
const {
handleShare,
handleJoinGame,
detail,
onStatusChange,
handleAddComment,
getCommentCount,
currentUserInfo,
} = props;
const [commentCount, setCommentCount] = useState(0);
const userInfo = useUserInfo();
const ntrpRef = useRef<{
show: (evaluateCallback: EvaluateCallback) => void;
}>({ show: () => {} });
const {
id,
price,
user_action_status,
match_status,
start_time,
end_time,
is_organizer,
skill_level_max,
skill_level_min,
} = detail || {};
const { ntrp_level } = currentUserInfo || {};
// 检查手机号绑定的包装函数
const checkPhoneAndExecute = (action: () => void) => {
return () => {
if (!userInfo?.phone) {
Taro.showModal({
title: "提示",
content: "该功能需要绑定手机号",
confirmText: "去绑定",
cancelText: "取消",
success: (res) => {
if (res.confirm) {
const currentPath = Taro.getCurrentInstance().router?.path || "";
const currentParams =
Taro.getCurrentInstance().router?.params || {};
const queryString = Object.keys(currentParams)
.map((key) => `${key}=${currentParams[key]}`)
.join("&");
const fullPath = queryString
? `${currentPath}?${queryString}`
: currentPath;
Taro.navigateTo({
url: `/login_pages/index/index?redirect=${encodeURIComponent(
fullPath,
)}`,
});
}
},
});
return;
}
action();
};
};
const matchNtrpReq = matchNtrpRequestment(
ntrp_level,
skill_level_min,
skill_level_max,
);
const gameManageRef = useRef();
function handleSelfEvaluate() {
ntrpRef?.current?.show({
type: EvaluateScene.detail,
next: ({ flag, score }) => {
if (!matchNtrpRequestment(score, skill_level_min, skill_level_max)) {
toast("您当前不符合此球局NTRP水平要求,去看看其他活动吧~");
return;
}
if (flag) {
Taro.navigateTo({
url: `/order_pages/orderDetail/index?gameId=${id}`,
});
return;
}
Taro.redirectTo({ url: `/order_pages/orderDetail/index?gameId=${id}` });
},
onCancel: () => {
// Taro.redirectTo({ url: `/game_pages/detail/index?id=${id}` });
Taro.navigateBack();
},
});
}
useEffect(() => {
getCommentCount?.((count) => {
setCommentCount(count);
});
}, [getCommentCount]);
function generateTextAndAction(
user_action_status: null | { [key: string]: boolean },
):
| undefined
| { text: string | React.FC; action?: () => void; available?: boolean } {
if (!user_action_status) {
return;
}
const priceStrArr = price.toString().split(".");
const displayPrice = is_organizer ? (
<>
0
{/* .00 */}
>
) : (
<>
{priceStrArr[0]}
.{priceStrArr[1]}
>
);
// user_action_status.can_assess = true;
// user_action_status.can_join = false;
// console.log(user_action_status, "user_action");
const {
can_assess,
can_join,
can_substitute,
can_pay,
is_substituting,
waiting_start,
} = user_action_status || {};
if (MATCH_STATUS.CANCELED === match_status) {
return {
text: "活动已取消",
available: false,
action: () => toast("活动已取消,去看看其他活动吧~"),
};
} else if (MATCH_STATUS.FINISHED === match_status) {
return {
text: "活动已结束",
available: false,
action: () => toast("活动已结束,去看看其他活动吧~"),
};
} else if (dayjs(end_time).isBefore(dayjs())) {
return {
text: "活动已结束",
available: false,
action: () => toast("活动已结束,去看看其他活动吧~"),
};
} else if (dayjs(start_time).isBefore(dayjs())) {
return {
text: "活动已开始",
available: false,
action: () => toast("活动已开始,去看看其他活动吧~"),
};
} else if (isFull(detail)) {
return {
text: "活动已满员",
available: false,
action: () => toast("活动已满员,去看看其他活动吧~"),
};
}
if (waiting_start) {
return {
text: () => (
<>
{/* */}
{displayPrice}
已加入
>
),
action: () => toast("您已参与了本次活动"),
};
} else if (is_substituting) {
return {
text: () => (
<>
{displayPrice}
已加入候补
>
),
action: () => toast("您已加入候补,候补失败会全额退款~"),
};
} else if (can_pay) {
return {
text: () => (
<>
{displayPrice}
继续支付
>
),
action: checkPhoneAndExecute(async () => {
const res = await OrderService.getUnpaidOrder(id);
if (res.code === 0) {
navto(
`/order_pages/orderDetail/index?id=${res.data.order_info.order_id}`,
);
}
}),
};
} else if (!matchNtrpReq) {
return {
text: () => (
<>
{displayPrice}
立即加入
>
),
available: false,
action: () =>
toast("您当前不符合此球局NTRP水平要求,去看看其他活动吧~"),
};
} else if (can_substitute) {
return {
text: () => (
<>
{displayPrice}
我要候补
>
),
action: checkPhoneAndExecute(handleJoinGame),
};
} else if (can_join) {
return {
text: () => {
return (
<>
{displayPrice}
立即加入
>
);
},
action: checkPhoneAndExecute(handleJoinGame),
};
} else if (can_assess) {
return {
text: () => (
<>
{displayPrice}
立即加入
>
),
action: checkPhoneAndExecute(handleSelfEvaluate),
};
}
return {
text: "球局无法加入",
available: false,
};
}
if (!user_action_status) {
return "";
}
const {
text,
available = true,
action = () => {},
} = generateTextAndAction(user_action_status)!;
let ActionText: React.FC | string = text;
if (typeof ActionText === "string") {
ActionText = () => {
return {text as string};
};
}
const debounceAction = debounce(action, 300);
return (
<>
handleShare()}
>
分享
{
// Taro.showToast({ title: "To be continued", icon: "none" });
handleAddComment();
}}
>
{commentCount > 0 ? commentCount : "评论"}
{is_organizer && (
{
gameManageRef.current.show(detail, onStatusChange);
}}
>
管理
)}
>
);
}