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); }} > 管理 )} ); }