import { useState, useEffect, useRef } from "react"; import { View, Text, Image, ScrollView } from "@tarojs/components"; import Taro, { useRouter, useDidShow } from "@tarojs/taro"; import classnames from "classnames"; import { throttle } from "@tarojs/runtime"; // 导入API服务 import { withAuth, Comments } from "@/components"; import DetailService from "@/services/detailService"; import * as LoginService from "@/services/loginService"; import { getCurrentLocation } from "@/utils/locationUtils"; import { useUserInfo, useUserActions } from "@/store/userStore"; import { useGlobalState } from "@/store/global"; import { waitForAuthInit } from "@/utils/authInit"; import { requireLoginWithPhone } from "@/utils/helper"; import GameTags from "./components/GameTags"; import Carousel from "./components/Carousel"; import StickyBottom from "./components/StickyBottom"; import GameInfo from "./components/GameInfo"; import VenueInfo from "./components/VenueInfo"; import GamePlayAndRequirement from "./components/GamePlayAndReq"; import Participants from "./components/Participants"; import SupplementalNotes from "./components/SupplementalNotes"; import OrganizerInfo from "./components/OrganizerInfo"; import SharePopup from "./components/SharePopup"; import { navto, toast } from "@/utils/helper"; import { delay } from "@/utils"; import ArrowLeft from "@/static/detail/icon-arrow-left.svg"; // import Logo from "@/static/detail/icon-logo-go.svg"; import styles from "./index.module.scss"; function Index() { const [detail, setDetail] = useState({}); const { params } = useRouter(); const [currentLocation, setCurrentLocation] = useState<[number, number]>([ 0, 0, ]); const { id, from, message_id } = params; const [userInfo, setUserInfo] = useState({}); // 组织者的userInfo const { fetchUserInfo } = useUserActions(); // 获取登录用户的userInfo const myInfo = useUserInfo(); const { statusNavbarHeightInfo } = useGlobalState(); const { statusBarHeight, navBarHeight, totalHeight } = statusNavbarHeightInfo; const isMyOwn = userInfo.id === myInfo.id; const sharePopupRef = useRef(null); const commentRef = useRef(); useEffect(() => { const init = async () => { updateLocation(); // 先等待静默登录完成 await waitForAuthInit(); // 然后再获取用户信息 await fetchUserInfo(); }; init(); }, []); useDidShow(() => { // await updateLocation(); // await fetchUserInfo(); if (id) { // Taro.showLoading(); fetchDetail(); } }); const updateLocation = async () => { try { const { address, ...location } = await getCurrentLocation(); setCurrentLocation([location.latitude, location.longitude]); // 使用 userStore 中的统一位置更新方法 // await updateUserInfo({ latitude: location.latitude, longitude: location.longitude }) await DetailService.updateLocation({ latitude: Number(location.latitude), longitude: Number(location.longitude), }); // 位置更新后,重新获取详情页数据(因为距离等信息可能发生变化) // 注意:这里不调用 fetchDetail,避免与 useDidShow 中的调用重复 // 如果需要更新距离信息,可以在 fetchDetail 成功后根据当前位置重新计算 // if (from === "publish") { // handleShare(true); // } } catch (error) { console.error("用户位置更新失败", error); } }; const fetchDetail = async () => { if (!id) return; const res = await DetailService.getDetail(Number(id)).catch((e) => { // 跳转到空状态页面 (Taro as any).redirectTo({ url: "/other_pages/emptyState/index", }); return e; }); if (res.code === 0) { setDetail(res.data); fetchUserInfoById(res.data.publisher_id); } // Taro.hideLoading(); }; const onUpdateUserInfo = () => { fetchUserInfoById(detail.publisher_id); }; async function fetchUserInfoById(user_id) { const userDetailInfo = await LoginService.getUserInfoById(user_id); if (userDetailInfo.code === 0) { setUserInfo(userDetailInfo.data); } } function handleShare() { if (!detail.id) { toast("球局未加载完成,请稍后再试"); return false; } sharePopupRef.current.show(); } const handleJoinGame = async () => { // 检查登录状态和手机号 if (!requireLoginWithPhone()) { return; // 未登录或未绑定手机号,已跳转到登录页 } if (isMyOwn) { const res = await DetailService.organizerJoin(Number(id)); if (res.code === 0) { toast("加入成功"); fetchDetail(); } return; } navto(`/order_pages/orderDetail/index?gameId=${id}`); }; function onStatusChange(result) { if (result) { fetchDetail(); } } function handleBack() { const pages = Taro.getCurrentPages(); if (pages.length <= 1) { Taro.redirectTo({ url: "/main_pages/index", }); } else { Taro.navigateBack(); } } function handleViewUserInfo(userId) { navto( userId === myInfo.id ? "/user_pages/myself/index" : `/user_pages/other/index?userid=${userId}`, ); } const backgroundImage = detail?.image_list?.[0] ? { opacity: 1, backgroundImage: `url(${detail?.image_list?.[0]})` } : { opacity: 0 }; const [glass, setGlass] = useState(false); const onScroll = throttle((e) => { const top = e.detail.scrollTop; setGlass(top > 20); }, 16); const [scrollToTarget, setScrollToTarget] = useState(""); return ( { setGlass(false); }} enhanced showScrollbar={false} scrollIntoView={scrollToTarget} // scroll-with-animation > {/* custom navbar */} {/* */} {/* swiper */} {/* content */} {/* avatar and tags */} {/* title */} {detail.title} {/* Date and Place and weather */} {/* detail */} {/* gameplay requirements */} {/* participants */} {/* supplemental notes */} {/* organizer and recommend games by organizer */} { commentRef.current && commentRef.current.addComment(); }} /> {/* sticky bottom action bar */} { commentRef.current && commentRef.current.addComment(); }} getCommentCount={ commentRef.current && commentRef.current.getCommentCount } currentUserInfo={myInfo} /> {/* share popup */} {detail.id && myInfo.id && ( )} ); } export default Index;