import { View, Text, Image } from "@tarojs/components"; import Taro from "@tarojs/taro"; import { useMemo } from "react"; import img from "../../config/images"; import { ListCardProps } from "../../../types/list/types"; import { formatGameTime, calculateDuration } from "@/utils/timeUtils"; import { navigateTo } from "@/utils/navigation"; import images from '@/config/images' import "./index.scss"; const ListCard: React.FC = ({ id, title, original_start_time, start_time, end_time, location, distance_km, current_players, max_players, skill_level_min, skill_level_max, play_type, image_list = [], court_type, key, participants, // 参与者图片 venue_image_list, // 场馆图片 venue_description, game_type, // 球局类型 }) => { // 参与者要前三个数据 const participantsImageList = participants?.slice(0, 3) || []; // 场地 要第一个数据 // const venueImageList = venue_image_list?.slice(0, 1) || []; const venueImage = venue_image_list?.[0]?.url || ""; // 是否显示畅打球局 const isShowSmoothPlayingGame = game_type === "畅打球局"; const renderItemImage = (src: string) => { return ( ); }; const handleViewDetail = () => { navigateTo({ url: `/game_pages/detail/index?id=${id}&from=list`, }); }; // 处理地点截断,确保固定信息始终显示 const displayLocation = useMemo(() => { if (!location) return null; // 直接返回 null,不渲染 // 获取屏幕宽度,用于计算实际容器宽度 const systemInfo = Taro.getSystemInfoSync(); const screenWidth = systemInfo.windowWidth || 375; // 容器宽度 = 屏幕宽度 - 左右 padding - 图片区域宽度 const containerWidthPx = screenWidth - 130; // 计算固定信息宽度 const extraInfo = `${court_type ? `・${court_type}` : ''}${distance_km ? `・${distance_km}km` : ''}`; // 估算字符宽度(基于 12px 字体) const getTextWidth = (text: string) => { let width = 0; for (let char of text) { if (/[\u4e00-\u9fa5\u3000-\u303f\uff00-\uffef]/.test(char)) { width += 12; // 中文字符 12px } else { width += 6; // 英文字符和数字 6px } } return width; }; const extraWidth = getTextWidth(extraInfo); const locationWidth = getTextWidth(location); // 可用宽度 = 容器宽度 - 固定信息宽度 - 省略号宽度(18px) const availableWidth = containerWidthPx - extraWidth - 18; // 如果地点宽度小于可用宽度,不需要截断 if (locationWidth <= availableWidth) { return location; } // 需要截断地点 let maxChars = 0; let currentWidth = 0; for (let i = 0; i < location.length; i++) { const char = location[i]; const charWidth = /[\u4e00-\u9fa5\u3000-\u303f\uff00-\uffef]/.test(char) ? 12 : 6; if (currentWidth + charWidth > availableWidth) { break; } currentWidth += charWidth; maxChars++; } return location.slice(0, maxChars) + '...'; }, [location, court_type, distance_km]); // 根据图片数量决定展示样式 const renderImages = () => { if (image_list?.length === 0) return null; if (image_list?.length === 1) { return ( {renderItemImage(image_list?.[0])} ); } if (image_list?.length === 2) { return ( {renderItemImage(image_list?.[0])} {renderItemImage(image_list?.[1])} ); } // 3张或更多图片 return ( {renderItemImage(image_list?.[0])} {renderItemImage(image_list?.[1])} {renderItemImage(image_list?.[2])} ); }; return ( {/* 左侧内容区域 */} {/* 标题 */} {title && ( {title} )} {/* 时间信息 */} {formatGameTime(original_start_time || start_time)} {/* 时长 如 2小时 */} {end_time && ( {" "} {calculateDuration(original_start_time || start_time, end_time)} )} {/* 地点,室内外,距离 */} {displayLocation && ( {displayLocation} )} {court_type && `・${court_type}`} {distance_km && `・${distance_km}km`} {/* 底部信息行:头像组、报名人数、技能等级、比赛类型 */} {participantsImageList && participantsImageList.length > 0 && ( {participantsImageList.map((item, index) => ( ))} )} 已加入 {current_players}/ {max_players} {Number(skill_level_min)?.toFixed(1)} - {Number(skill_level_max)?.toFixed(1)} {/* 分割线 */} {play_type} {/* {play_type && ( {play_type} )} */} {/* 右侧图片区域 */} {renderImages()} {/* 畅打球局 */} {isShowSmoothPlayingGame && ( {/* {game_type} */} { venue_description && () } { venue_description && ( 场馆方: {venue_description} ) } )} ); }; export default ListCard;