import { Controller, useFormContext, Control, FieldValues, Path } from 'react-hook-form'; import { useQuery } from '@tanstack/react-query'; import { Select, SelectContent, SelectItem, SelectTrigger, SelectValue } from '@d8d/shared-ui-components/components/ui/select'; import { FormDescription, FormLabel } from '@d8d/shared-ui-components/components/ui/form'; import { areaClient, areaClientManager } from '../api/areaClient'; import type { InferResponseType } from 'hono/client'; interface AreaSelectFormProps { provinceName: Path; cityName: Path; districtName?: Path; label?: string; description?: string; required?: boolean; disabled?: boolean; className?: string; control?: Control; } // 类型定义 type AreaResponse = InferResponseType['data'][0]; export const AreaSelectForm = ({ provinceName, cityName, districtName, label = '地区选择', description, required = false, disabled = false, className, control: propControl }: AreaSelectFormProps) => { // 使用传入的 control,或者从上下文中获取 const formContext = useFormContext(); const control = propControl || formContext?.control; if (!control) { console.error('AreaSelectForm: 缺少 react-hook-form 上下文或 control prop'); return null; } // 获取表单值 const provinceValue = control._getWatch(provinceName); const cityValue = control._getWatch(cityName); // districtValue 变量未使用,移除 // 查询省份列表 const { data: provinces, isLoading: isLoadingProvinces } = useQuery({ queryKey: ['areas', 'provinces'], queryFn: async () => { const res = await areaClientManager.get().index.$get({ query: { page: 1, pageSize: 100, filters: JSON.stringify({ level: 1, isDisabled: 0 }), sortBy: 'id', sortOrder: 'ASC' } }); if (res.status !== 200) throw new Error('获取省份列表失败'); return await res.json(); }, staleTime: 10 * 60 * 1000, gcTime: 30 * 60 * 1000, }); // 查询城市列表 const { data: cities, isLoading: isLoadingCities } = useQuery({ queryKey: ['areas', 'cities', provinceValue], queryFn: async () => { if (!provinceValue) return { data: [] }; const res = await areaClientManager.get().index.$get({ query: { page: 1, pageSize: 100, filters: JSON.stringify({ level: 2, parentId: Number(provinceValue), isDisabled: 0 }), sortBy: 'id', sortOrder: 'ASC' } }); if (res.status !== 200) throw new Error('获取城市列表失败'); return await res.json(); }, staleTime: 10 * 60 * 1000, gcTime: 30 * 60 * 1000, enabled: !!provinceValue, }); // 查询区县列表(如果提供districtName) const { data: districts, isLoading: isLoadingDistricts } = useQuery({ queryKey: ['areas', 'districts', cityValue], queryFn: async () => { if (!cityValue || !districtName) return { data: [] }; const res = await areaClientManager.get().index.$get({ query: { page: 1, pageSize: 100, filters: JSON.stringify({ level: 3, parentId: Number(cityValue), isDisabled: 0 }), sortBy: 'id', sortOrder: 'ASC' } }); if (res.status !== 200) throw new Error('获取区县列表失败'); return await res.json(); }, staleTime: 10 * 60 * 1000, gcTime: 30 * 60 * 1000, enabled: !!cityValue && !!districtName, }); return (
{label && ( {label}{required && *} )}
{/* 省份选择 */} (
{provinceFieldState.error && (
{provinceFieldState.error.message}
)}
)} /> {/* 城市选择 */} (
{cityFieldState.error && (
{cityFieldState.error.message}
)}
)} /> {/* 区县选择(可选) */} {districtName && ( (
{districtFieldState.error && (
{districtFieldState.error.message}
)}
)} /> )}
{description && ( {description} )}
); };