import DownSvg from '@/assets/icons/svg/down.svg'; import PlaceSvg from '@/assets/icons/svg/place.svg'; import ReturnArrowSvg from '@/assets/icons/svg/returnArrow.svg'; import SearchSvg from '@/assets/icons/svg/search.svg'; import { CascaderItem } from '@/components/cascader'; import ClassifyModal from '@/components/owner/classify'; import LocationModal from '@/components/owner/location'; import PodiumComponent from '@/components/owner/podium'; import RankList from '@/components/owner/rankList'; import { findInnermostElement } from '@/components/owner/utils'; import { ThemedText } from '@/components/ThemedText'; import { convertRegions } from '@/components/utils/cascaderData'; import { transformData } from '@/components/utils/objectToCascader'; import { fetchApi } from '@/lib/server-api-util'; import { GroupedData, RankingItem, TargetItem } from '@/types/user'; import { useRouter } from "expo-router"; import * as SecureStore from 'expo-secure-store'; import { useCallback, useEffect, useMemo, useRef, useState } from 'react'; import { Keyboard, LayoutChangeEvent, Platform, StyleSheet, TouchableOpacity, TouchableWithoutFeedback, View } from 'react-native'; import { TextInput } from 'react-native-gesture-handler'; import { useSafeAreaInsets } from "react-native-safe-area-context"; interface LocationData { id: number; name: string; children: LocationData[]; } export default function OwnerPage() { const insets = useSafeAreaInsets(); const router = useRouter(); const HOT_CITIES = [ ['北京', '上海', '广州', '深圳'], ['杭州', '成都', '乌鲁木齐', '武汉'], ['西安', '重庆', '西宁', '哈尔滨'], ['长沙', '南宁', '贵阳', '昆明'] ]; // 位置搜索数据 const [locationSearch, setLocationSearch] = useState(''); // 位置弹窗 const [locationModalVisible, setLocationModalVisible] = useState(false); // 分类弹窗 const [classifyModalVisible, setClassifyModalVisible] = useState(false); // 地区数据 const [locationData, setLocationData] = useState([]); // 在组件内部添加: const podiumRef = useRef(null); const [podiumPosition, setPodiumPosition] = useState({ x: 0, y: 0, width: 0, height: 0 }); // 获取分类 const [classify, setClassify] = useState([]); const getClassify = () => { fetchApi("/title-tags").then((res: GroupedData) => { setSelectedClassify([transformData(res)?.[0]?.children?.[0]]); setClassify(transformData(res)); }); } // 选择地区 const [selectedLocation, setSelectedLocation] = useState(); // 选择分类 const [selectedClassify, setSelectedClassify] = useState(); const onPodiumLayout = (event: LayoutChangeEvent) => { if (podiumRef.current) { podiumRef.current.measure((x, y, width, height, pageX, pageY) => { setPodiumPosition({ x: pageX, y: pageY, width, height }); }); } }; // 地区选择 const handleLocationChange = useCallback((selectedItems: CascaderItem[]) => { if (selectedItems.length > 0) { const lastItem = selectedItems[selectedItems.length - 1]; // 只有当选择完成时才更新状态 if (!lastItem.children || lastItem.children.length === 0) { setSelectedLocation(selectedItems); } } }, []); // 分类选择 const handleClassifyChange = useCallback((selectedItems: CascaderItem[]) => { if (selectedItems.length > 0) { const lastItem = selectedItems[selectedItems.length - 1]; // 只有当选择完成时才更新状态 if (!lastItem.children || lastItem.children.length === 0) { setSelectedClassify(selectedItems); } } }, []); // 获取本地存储的地址信息 const getLocation = async () => { let location; if (Platform.OS === 'web') { location = localStorage.getItem('location'); } else { location = await SecureStore.getItemAsync('location'); } return location; }; // 获取排名信息 const [ranking, setRanking] = useState([]); const getRanking = () => { fetchApi("/title-rank", { method: "POST", body: JSON.stringify({ "title_tag_id": selectedClassify?.length > 0 ? selectedClassify[selectedClassify?.length - 1].value : null, "area_id": selectedLocation?.length > 0 ? selectedLocation[selectedLocation?.length - 1].value : null }) }).then((res) => { setRanking(res); }); } // 当用户选择发生变化时,重新获取排名 useEffect(() => { if (selectedLocation?.length > 0 && selectedClassify?.length > 0) { getRanking(); } }, [selectedLocation, selectedClassify]) // 初始化获取分类 useEffect(() => { const start = async () => { await getClassify(); } start(); }, []) const fetchLocationData = useMemo(() => async () => { try { const res = await fetchApi("/area/tree"); const transformed = convertRegions(res?.children, { nameKey: 'name', // 源数据中表示"名称"的字段 valueKey: 'id', // 源数据中作为 value 的字段 regionsKey: 'children', // 源数据中表示"子级区域"的字段 childrenKey: 'children' // 输出结构中表示"子级区域"的字段 }); return transformed; } catch (error) { return []; } }, []); useEffect(() => { let isMounted = true; const loadLocationData = async () => { const data = await fetchLocationData(); if (isMounted) { setLocationData(data); // 获取本地存储的地址信息 const location = await getLocation(); const xuhuiElement = findInnermostElement(data?.filter((item) => { return item.name === JSON.parse(location || "").city }) || [], JSON.parse(location || "").district); if (location) { setSelectedLocation([xuhuiElement]); } } }; loadLocationData(); return () => { isMounted = false; }; }, [fetchLocationData]); useEffect(() => { // console.log(locationData); }, [locationSearch]) return ( { Keyboard.dismiss(); }}> {/* 导航栏 */} { router.push('/owner') }} style={{ padding: 16 }}> { setClassifyModalVisible(true) }}> {selectedClassify?.length > 0 ? selectedClassify[selectedClassify?.length - 1].name : "分类"} 123 { setLocationModalVisible(true) }} style={{ display: 'flex', flexDirection: 'row', alignItems: 'center', gap: 8 }}> 0 ? '#FFB645' : '#4C320C' }}> {selectedLocation?.length > 0 ? selectedLocation[selectedLocation?.length - 1].name : "地区"} {/* { selectedLocation?.length > 0 ? : } */} { setLocationSearch(text.nativeEvent.text) }} /> {/* { setClassifyModalVisible(true) }} style={{ display: 'flex', flexDirection: 'row', alignItems: 'center', gap: 8 }}> 0 ? '#FFB645' : '#4C320C' }}> {selectedClassify?.length > 0 ? selectedClassify[selectedClassify?.length - 1].name : "分类"} {selectedClassify?.length > 0 ? : } */} {/* 热门城市 */} 热门城市 {HOT_CITIES.map((row, rowIndex) => ( {row.map((city, cityIndex) => ( { setLocationSearch(city); }} > {city} ))} ))} {/* 颁奖台 */} {/* 排名区域 */} {/* 地区选择弹窗 */} {/* 分类选择弹窗 */} ); } const styles = StyleSheet.create({ container: { flex: 1, backgroundColor: 'white', }, header: { display: 'flex', flexDirection: 'row', justifyContent: 'space-between', alignItems: 'center', marginVertical: 16, }, headerTitle: { fontSize: 20, fontWeight: '700', color: '#4C320C', }, searchContainer: { position: 'relative', flex: 1, }, input: { backgroundColor: '#D9D9D9', borderRadius: 24, paddingLeft: 40, // 给图标留出空间 paddingVertical: 8, paddingRight: 16, fontSize: 14, lineHeight: 16, }, searchIcon: { position: 'absolute', left: 20, top: '50%', zIndex: 10, transform: [{ translateY: -6 }] }, item: { paddingVertical: 8, borderRadius: 12, fontSize: 14, backgroundColor: '#D9D9D9', width: '23%', textAlign: 'center', color: "#4C320C" }, hotCity: { backgroundColor: "#FBFBFB", padding: 16, borderRadius: 24 }, cityRow: { display: 'flex', flexDirection: 'row', flexWrap: 'wrap', justifyContent: 'space-between', marginBottom: 16 } });