memowake-front/components/owner/locationPicker.tsx
jinyaqiu 828e84710f
All checks were successful
Dev Deploy / Explore-Gitea-Actions (push) Successful in 24s
feat: 个人中心
2025-07-14 10:42:59 +08:00

148 lines
4.4 KiB
TypeScript

import locationData from '@/assets/json/location.json';
import React, { useEffect, useState } from 'react';
import { ScrollView, StyleSheet, TouchableOpacity, View } from 'react-native';
import { ThemedText } from '../ThemedText';
type Region = {
name: string;
regions?: Region[];
};
const GlobalRegionPicker = () => {
const [selectedRegions, setSelectedRegions] = useState<Region[]>([]);
const [allLevelsData, setAllLevelsData] = useState<Region[][]>([]);
// 初始化第一级数据
useEffect(() => {
setAllLevelsData([locationData as Region[]]);
}, []);
// 处理地区选择
const handleSelectRegion = (region: Region, level: number) => {
// 更新选中的地区
const newSelectedRegions = [...selectedRegions.slice(0, level), region];
setSelectedRegions(newSelectedRegions);
// 如果有子区域,添加下一级数据
if (region.regions && region.regions.length > 0) {
// 创建新的层级数据数组
const newAllLevelsData = [...allLevelsData.slice(0, level + 1)];
// 添加新的子区域数据
newAllLevelsData.push(region.regions);
setAllLevelsData(newAllLevelsData);
} else {
// 如果没有子区域,截断到当前级别
setAllLevelsData(allLevelsData.slice(0, level + 1));
}
};
// 渲染某一级的地区列表
const renderLevel = (regions: Region[], level: number) => {
return (
<View style={styles.levelContainer}>
{regions.map((region, index) => (
<TouchableOpacity
key={`${level}-${index}`}
style={[
styles.regionItem,
selectedRegions[level]?.name === region.name && styles.selectedItem
]}
onPress={() => handleSelectRegion(region, level)}
>
<ThemedText
style={[
styles.regionText,
selectedRegions[level]?.name === region.name && styles.selectedText
]}
>
{region.name}
</ThemedText>
</TouchableOpacity>
))}
</View>
);
};
// 递归渲染地区列
const renderRegionColumns = (data: Region[][], level: number = 0) => {
if (!data[level]) return null;
return (
<React.Fragment key={`level-${level}`}>
<View style={[
styles.column,
data[level + 1] && styles.hasNextLevel
]}>
{level > 0 && <View style={styles.divider} />}
{renderLevel(data[level], level)}
</View>
{data[level + 1] && renderRegionColumns(data, level + 1)}
</React.Fragment>
);
};
return (
<View style={styles.container}>
<ScrollView
horizontal
showsHorizontalScrollIndicator={false}
contentContainerStyle={styles.scrollContent}
>
{renderRegionColumns(allLevelsData)}
</ScrollView>
</View>
);
};
const styles = StyleSheet.create({
container: {
flex: 1,
backgroundColor: '#fff',
},
scrollContent: {
flexGrow: 1,
},
column: {
width: 120, // 每列固定宽度
},
hasNextLevel: {
borderRightWidth: 1,
borderRightColor: '#f0f0f0',
},
levelContainer: {
width: '100%',
},
divider: {
position: 'absolute',
left: 0,
top: 0,
bottom: 0,
width: 1,
backgroundColor: '#e0e0e0',
},
regionItem: {
flexDirection: 'row',
justifyContent: 'space-between',
alignItems: 'center',
paddingVertical: 12,
paddingHorizontal: 16
},
selectedItem: {
backgroundColor: '#F6F6F6',
},
regionText: {
fontSize: 15,
color: '#333',
},
selectedText: {
color: '#AC7E35',
fontWeight: '500',
},
arrow: {
fontSize: 18,
color: '#999',
marginLeft: 8,
},
});
export default GlobalRegionPicker;