import React, { useState, useEffect } from 'react' import { View, Text, Picker, Button } from '@tarojs/components' import { useQuery } from '@tanstack/react-query' import { areaClient } from '../api' interface AreaInfo { id: number name: string type: 'province' | 'city' | 'district' } interface AreaPickerProps { visible: boolean onClose: () => void onConfirm: (areaIds: number[], areaInfos: AreaInfo[]) => void value?: number[] title?: string } export const AreaPicker: React.FC = ({ visible, onClose, onConfirm, value = [], title = '选择地区' }) => { const [selectedProvince, setSelectedProvince] = useState(value[0]) const [selectedCity, setSelectedCity] = useState(value[1]) const [selectedDistrict, setSelectedDistrict] = useState(value[2]) // 获取省份列表 const { data: provincesResponse } = useQuery({ queryKey: ['areas', 'provinces'], queryFn: async () => { const res = await areaClient.provinces.$get({ query: { page: 1, pageSize: 50 } }) if (res.status !== 200) throw new Error('获取省份列表失败') return await res.json() } }) // 获取城市列表 const { data: citiesResponse } = useQuery({ queryKey: ['areas', 'cities', selectedProvince], queryFn: async () => { if (!selectedProvince) return { success: true, data: { cities: [] }, message: '' } const res = await areaClient.cities.$get({ query: { provinceId: selectedProvince, page: 1, pageSize: 50 } }) if (res.status !== 200) throw new Error('获取城市列表失败') return await res.json() }, enabled: !!selectedProvince }) // 获取区县列表 const { data: districtsResponse } = useQuery({ queryKey: ['areas', 'districts', selectedCity], queryFn: async () => { if (!selectedCity) return { success: true, data: { districts: [] }, message: '' } const res = await areaClient.districts.$get({ query: { cityId: selectedCity, page: 1, pageSize: 50 } }) if (res.status !== 200) throw new Error('获取区县列表失败') return await res.json() }, enabled: !!selectedCity }) // 提取数据 const provinces = provincesResponse?.data?.provinces || [] const cities = citiesResponse?.data?.cities || [] const districts = districtsResponse?.data?.districts || [] // 初始化选择值 - 只在组件首次显示时初始化 const [hasInitialized, setHasInitialized] = useState(false) useEffect(() => { if (visible && !hasInitialized) { setSelectedProvince(value[0]) setSelectedCity(value[1]) setSelectedDistrict(value[2]) setHasInitialized(true) } else if (!visible) { setHasInitialized(false) } }, [visible, value, hasInitialized]) // 处理省份选择 const handleProvinceChange = (e: any) => { const provinceIndex = Number(e.detail.value) const selectedProvinceObj = provinces[provinceIndex] if (selectedProvinceObj) { setSelectedProvince(selectedProvinceObj.id) setSelectedCity(undefined) setSelectedDistrict(undefined) } } // 处理城市选择 const handleCityChange = (e: any) => { const cityIndex = Number(e.detail.value) const selectedCityObj = cities[cityIndex] if (selectedCityObj) { setSelectedCity(selectedCityObj.id) setSelectedDistrict(undefined) } } // 处理区县选择 const handleDistrictChange = (e: any) => { const districtIndex = Number(e.detail.value) const selectedDistrictObj = districts[districtIndex] if (selectedDistrictObj) { setSelectedDistrict(selectedDistrictObj.id) } } // 确认选择 const handleConfirm = () => { const areaIds: number[] = [] const areaInfos: AreaInfo[] = [] if (selectedProvince) { const province = provinces.find(p => p.id === selectedProvince) if (province) { areaIds.push(selectedProvince) areaInfos.push({ id: province.id, name: province.name, type: 'province' }) } } if (selectedCity) { const city = cities.find(c => c.id === selectedCity) if (city) { areaIds.push(selectedCity) areaInfos.push({ id: city.id, name: city.name, type: 'city' }) } } if (selectedDistrict) { const district = districts.find(d => d.id === selectedDistrict) if (district) { areaIds.push(selectedDistrict) areaInfos.push({ id: district.id, name: district.name, type: 'district' }) } } onConfirm(areaIds, areaInfos) onClose() } // 取消选择 const handleCancel = () => { onClose() } // 获取显示文本 const getDisplayText = () => { if (!selectedProvince) return '请选择省市区' const province = provinces.find(p => p.id === selectedProvince) const city = cities.find(c => c.id === selectedCity) const district = districts.find(d => d.id === selectedDistrict) if (district && city && province) { return `${province.name} ${city.name} ${district.name}` } else if (city && province) { return `${province.name} ${city.name}` } else if (province) { return province.name } return '请选择省市区' } if (!visible) return null return ( {/* 标题栏 */} {title} {/* 选择器区域 */} {/* 当前选择显示 */} 已选择: {getDisplayText()} {/* 三级选择器 */} {/* 省份选择器 */} 省份 p.id === selectedProvince) : -1} onChange={handleProvinceChange} > {selectedProvince ? provinces.find(p => p.id === selectedProvince)?.name : '请选择省份'} {/* 城市选择器 */} 城市 c.id === selectedCity) : -1} onChange={handleCityChange} disabled={!selectedProvince} > {selectedCity ? cities.find(c => c.id === selectedCity)?.name : '请选择城市'} {/* 区县选择器 */} 区县 d.id === selectedDistrict) : -1} onChange={handleDistrictChange} disabled={!selectedCity} > {selectedDistrict ? districts.find(d => d.id === selectedDistrict)?.name : '请选择区县'} {/* 按钮区域 */} ) }