import React, { useState, useEffect, useRef, useImperativeHandle, forwardRef } from 'react' import { View, Text, Button, Swiper, SwiperItem, Image, Map, ScrollView } from '@tarojs/components' import { Cell, Avatar, Progress, Popover } from '@nutui/nutui-react-taro' import Taro, { useRouter, useShareAppMessage, useShareTimeline, useDidShow } from '@tarojs/taro' import dayjs, { locale } from 'dayjs' import 'dayjs/locale/zh-cn' // 导入API服务 import DetailService, { MATCH_STATUS} from '../../services/detailService' import { updateUserProfile, get_user_info } from '../../services/loginService' import { getCurrentLocation, calculateDistance } from '../../utils/locationUtils' import { useUserInfo, useUserActions, } from '../../store/userStore' import img from '../../config/images' import { getTextColorOnImage } from '../../utils' import './index.scss' import { CommonPopup } from '@/components' dayjs.locale('zh-cn') const images = [ 'http://bimwe.oss-cn-shanghai.aliyuncs.com/front/ball/images/1a35ebbf-2361-44da-b338-7608561d0b31.png', 'http://bimwe.oss-cn-shanghai.aliyuncs.com/front/ball/images/cf5a82ba-90af-4138-a1b3-9119adcde9e0.png', 'http://bimwe.oss-cn-shanghai.aliyuncs.com/front/ball/images/49d7cdf0-b03c-4a0f-91c6-e7778080cfcd.png' ] function insertDotInTags(tags: string[]) { return tags.join('-·-').split('-') } // 分享弹窗 const SharePopup = forwardRef(({ id, from }: { id: string, from: string }, ref) => { const [visible, setVisible] = useState(false) useImperativeHandle(ref, () => ({ show: () => { setVisible(true) } })) function handleShareToWechat() { useShareAppMessage(() => { return { title: '分享', path: `/pages/detail/index?id=${id}&from=${from}`, } }) } function handleShareToWechatMoments() { useShareTimeline(() => { return { title: '分享', path: `/pages/detail/index?id=${id}&from=${from}`, } }) } function handleSaveToLocal() { Taro.saveImageToPhotosAlbum({ filePath: images[0], success: () => { Taro.showToast({ title: '保存成功', icon: 'success' }) }, fail: () => { Taro.showToast({ title: '保存失败', icon: 'none' }) }, }) } return ( { setVisible(false) }} hideFooter style={{ minHeight: '100px' }} > 分享到微信 分享朋友圈 保存到本地 ) }) // 底部操作栏 function StickyButton(props) { const { handleShare, handleJoinGame, detail } = props const userInfo = useUserInfo() const { id } = userInfo const { publisher_id, match_status, price } = detail || {} const role = Number(publisher_id) === id ? 'ownner' : 'visitor' console.log(match_status, role) return ( 分享 { Taro.showToast({ title: 'To be continued', icon: 'none' }) }}> 32 🎾 立即加入 ¥ {price} ) } // 球局信息 function GameInfo(props) { const { detail, currentLocation } = props const { latitude, longitude, location, location_name, start_time, end_time } = detail || {} const openMap = () => { Taro.openLocation({ latitude, // 纬度(必填) longitude, // 经度(必填) name: location_name, // 位置名(可选) address: location, // 地址详情(可选) scale: 15, // 地图缩放级别(1-28) }) } const [c_latitude, c_longitude] = currentLocation const distance = calculateDistance(c_latitude, c_longitude, latitude, longitude) / 1000 const startTime = dayjs(start_time) const endTime = dayjs(end_time) const game_length = endTime.diff(startTime, 'minutes') / 60 const startMonth = startTime.format('M') const startDay = startTime.format('D') const theDayOfWeek = startTime.format('dddd') const startDate = `${startMonth}月${startDay}日 ${theDayOfWeek}` const gameRange = `${startTime.format('HH:mm')} - ${endTime.format('HH:mm')}` return ( {/* Date and Weather */} {/* Calendar and Date time */} {/* Calendar */} {startMonth}月 {startDay} {/* Date time */} {startDate} {gameRange} ({game_length}小时) {/* Weather */} {/* Weather icon */} {/* Weather text and temperature */} 28℃ - 32℃ {/* Place */} {/* venue location message */} {/* location icon */} {/* location message */} {/* venue name and distance */} {location_name || '-'} · {distance.toFixed(1)}km {/* venue address */} {location || '-'} {/* venue map */} {longitude && latitude && ( {}} // hide business msg showLocation theme='dark' /> )} ) } function Index() { // 使用Zustand store // const userStats = useUserStats() // const { incrementRequestCount, resetUserStats } = useUserActions() const [current, setCurrent] = useState(0) // const [textColor, setTextColor] = useState([]) const [detail, setDetail] = useState(null) const { params } = useRouter() const [currentLocation, setCurrentLocation] = useState<[number, number]>([0, 0]) const { id, autoShare, from } = params const { fetchUserInfo, updateUserInfo } = useUserActions() console.group('params') console.log(params) console.groupEnd() // 本地状态管理 const [loading, setLoading] = useState(false) const sharePopupRef = useRef(null) // 页面加载时获取数据 // useEffect(() => { // fetchDetail() // calcBgMainColors() // }, []) useDidShow(async () => { await updateLocation() await fetchUserInfo() await fetchDetail() // calcBgMainColors() }) const updateLocation = async () => { try { const location = await getCurrentLocation() setCurrentLocation([location.latitude, location.longitude]) await updateUserInfo({ latitude: location.latitude, longitude: location.longitude }) console.log('用户位置更新成功') } catch (error) { console.error('用户位置更新失败', error) } } const fetchDetail = async () => { const res = await DetailService.getDetail(243/* Number(id) */) if (res.code === 0) { console.log(res.data) setDetail(res.data) } } // const calcBgMainColors = async () => { // const textcolors: string[] = [] // // for (const index in images) { // // const { textColor } = await getTextColorOnImage(images[index]) // // textcolors[index] = textColor // // } // if (detail?.image_list?.length > 0) { // const { textColor } = await getTextColorOnImage(detail.image_list[0]) // textcolors[0] = textColor // } // setColors(textcolors) // } function handleShare() { sharePopupRef.current.show() } const handleJoinGame = () => { Taro.navigateTo({ url: `/pages/orderCheck/index?gameId=${243/* id */}`, }) } const tags = [{ name: '🕙 急招', icon: '', }, { name: '🔥 本周热门', icon: '', }, { name: '🎉 新活动', icon: '', }, { name: '官方组织', icon: '', }] const detailTags = ['室内', '硬地', '2号场', '有停车场', '有淋浴间', '有更衣室'] const { title, longitude, latitude } = detail || {} console.log(longitude, latitude, 2222) const requirements = [{ title: 'NTRP水平要求', desc: '2.0 - 4.5 之间', }, { title: '活动玩法', desc: '双打', }, { title: '人员构成', desc: '个人球局 · 组织者参与活动', }] const participants = detail?.participants || [] const supplementalNotesTags = ['仅限男生', '装备自备', '其他'] const recommendGames = [ { title: '黄浦日场对拉', time: '2025-08-25 9:00', timeLength: '2小时', venue: '上海体育场', veuneType: '室外', distance: '1.2km', avatar: 'https://img.yzcdn.cn/vant/cat.jpeg', applications: 10, checkedApplications: 3, levelRequirements: 'NTRP 3.5', playType: '双打', }, { title: '黄浦夜场对拉', time: '2025-08-25 19:00', timeLength: '2小时', venue: '上海体育场', veuneType: '室外', distance: '1.2km', avatar: 'https://img.yzcdn.cn/vant/cat.jpeg', applications: 10, checkedApplications: 3, levelRequirements: 'NTRP 3.5', playType: '双打', }, { title: '黄浦全天对拉', time: '2025-08-25 9:00', timeLength: '12小时', venue: '上海体育场', veuneType: '室外', distance: '1.2km', avatar: 'https://img.yzcdn.cn/vant/cat.jpeg', applications: 10, checkedApplications: 3, levelRequirements: 'NTRP 3.5', playType: '双打', }, ] console.log('detail', detail) return ( {/* custom navbar */} { Taro.navigateBack() }}> {/* swiper */} { detail?.image_list?.length > 0 && detail?.image_list.map((item, index) => { return ( ) }) } {/* { setCurrent(e.detail.current) }} > {images.map((imageUrl, index) => ( ))} */} {/* content */} {/* avatar and tags */} {/* network image mock */} {tags.map((tag, index) => ( {tag.icon && } {tag.name} ))} {/* title */} {title} {/* Date and Place and weather */} {/* detail */} {/* venue detail title and venue ordered status */} 场馆详情 · 已订场 } location='top' visible={false} > {/* venue detail content */} {/* venue detail tags */} {insertDotInTags(detailTags).map((tag, index) => ( {tag} ))} {/* venue remarks */} 其他这是用户在场地补充描述里自己写的东西啦啦啦啦啦啦啦啦啦啦啦啦 {/* gameplay requirements */} {/* title */} 玩法要求 {/* requirements */} {requirements.map((item, index) => ( {item.title} {item.desc} ))} {/* participants */} 参与者 · 剩余空位 3 {/* application */} { Taro.showToast({ title: 'To be continued', icon: 'none' }) }}> 申请加入 {/* participants list */} {participants.map((participant) => ( {/* */} {/* network image mock random */} {participant.user.nickname || '未知'} {participant.level || '未知'} {participant.role || '参与者'} ))} {/* supplemental notes */} 补充说明 {/* supplemental notes tags */} {insertDotInTags(supplementalNotesTags).map((tag, index) => ( {tag} ))} {/* supplemental notes content */} 其他这是用户在补充说明里自己写的东西啦啦啦啦啦啦啦啦啦啦啦啦其他这是用户在补充说明里自己写的东西啦啦啦啦啦啦啦啦啦啦啦啦 {/* organizer and recommend games by organizer */} {/* orgnizer title */} 组织者 {/* organizer avatar and name */} Light 已组织 8 次 NTRP 3.5 关注 {/* recommend games by organizer */} TA的更多活动 {recommendGames.map((game, index) => ( {/* game title */} {game.title} {/* game time and range */} {game.time} {game.timeLength} {/* game location、vunue、distance */} {game.venue} · {game.veuneType} · {game.distance} {/* organizer avatar、applications、level requirements、play type */} 报名人数 {game.checkedApplications}/{game.applications} {game.levelRequirements} {game.playType} ))} {/* sticky bottom action bar */} {/* share popup */} ) } export default Index