import { View, ScrollView, Text } from '@tarojs/components' import { useQuery, useMutation, useQueryClient } from '@tanstack/react-query' import { useForm } from 'react-hook-form' import { zodResolver } from '@hookform/resolvers/zod' import { z } from 'zod' import { useState, useEffect } from 'react' import Taro from '@tarojs/taro' import { deliveryAddressClient, cityClient } from '@/api' import { InferResponseType, InferRequestType } from 'hono' import { Navbar } from '@/components/ui/navbar' import { Card } from '@/components/ui/card' import { Button } from '@/components/ui/button' import { Form, FormField, FormItem, FormLabel, FormControl, FormMessage } from '@/components/ui/form' import { Input } from '@/components/ui/input' import { useAuth } from '@/utils/auth' type Address = InferResponseType type CreateAddressRequest = InferRequestType['json'] type UpdateAddressRequest = InferRequestType['json'] const addressSchema = z.object({ name: z.string().min(1, '请输入收货人姓名'), phone: z.string().regex(/^1[3-9]\d{9}$/, '请输入正确的手机号'), province: z.number().positive('请选择省份'), city: z.number().positive('请选择城市'), district: z.number().positive('请选择区县'), address: z.string().min(1, '请输入详细地址'), isDefault: z.boolean().optional() }) type AddressFormData = z.infer export default function AddressEditPage() { const { user } = useAuth() const queryClient = useQueryClient() const [addressId, setAddressId] = useState(null) const [provinces, setProvinces] = useState([]) const [cities, setCities] = useState([]) const [districts, setDistricts] = useState([]) // 获取地址ID useEffect(() => { const params = Taro.getCurrentInstance().router?.params if (params?.id) { setAddressId(parseInt(params.id)) } }, []) // 获取地址详情 const { data: address } = useQuery({ queryKey: ['address', addressId], queryFn: async () => { if (!addressId) return null const response = await deliveryAddressClient[':id'].$get({ param: { id: addressId } }) if (response.status !== 200) { throw new Error('获取地址失败') } return response.json() }, enabled: !!addressId, }) // 获取省份 const { data: provinceData } = useQuery({ queryKey: ['provinces'], queryFn: async () => { const response = await cityClient.$get({ query: { page: 1, pageSize: 100, filters: JSON.stringify({ parentId: 0 }) } }) if (response.status !== 200) { throw new Error('获取省份失败') } return response.json() } }) // 获取城市 const fetchCities = async (provinceId: number) => { const response = await cityClient.$get({ query: { page: 1, pageSize: 100, filters: JSON.stringify({ parentId: provinceId }) } }) if (response.status !== 200) { throw new Error('获取城市失败') } return response.json() } // 获取区县 const fetchDistricts = async (cityId: number) => { const response = await cityClient.$get({ query: { page: 1, pageSize: 100, filters: JSON.stringify({ parentId: cityId }) } }) if (response.status !== 200) { throw new Error('获取区县失败') } return response.json() } // 表单设置 const form = useForm({ resolver: zodResolver(addressSchema), defaultValues: { name: '', phone: '', province: 0, city: 0, district: 0, address: '', isDefault: false } }) // 填充表单数据 useEffect(() => { if (address) { form.reset({ name: address.name, phone: address.phone, province: address.receiverProvince, city: address.receiverCity, district: address.receiverDistrict, address: address.address, isDefault: address.isDefault === 1 }) } }, [address, form]) // 创建/更新地址 const saveAddressMutation = useMutation({ mutationFn: async (data: AddressFormData) => { const addressData: any = { name: data.name, phone: data.phone, receiverProvince: data.province, receiverCity: data.city, receiverDistrict: data.district, address: data.address, userId: user?.id, isDefault: data.isDefault ? 1 : 0 } let response if (addressId) { response = await deliveryAddressClient[':id']['$put']({ param: { id: addressId }, json: addressData }) } else { response = await deliveryAddressClient.$post({ json: addressData }) } if (response.status !== 200 && response.status !== 201) { throw new Error('保存地址失败') } return response.json() }, onSuccess: () => { queryClient.invalidateQueries({ queryKey: ['delivery-addresses'] }) Taro.showToast({ title: addressId ? '更新成功' : '添加成功', icon: 'success' }) Taro.navigateBack() }, onError: (error) => { Taro.showToast({ title: error.message || '保存失败', icon: 'none' }) } }) // 处理省份变化 const handleProvinceChange = async (provinceId: number) => { if (provinceId) { const response = await fetchCities(provinceId) setCities(response.data || []) setDistricts([]) form.setValue('city', 0) form.setValue('district', 0) } } // 处理城市变化 const handleCityChange = async (cityId: number) => { if (cityId) { const response = await fetchDistricts(cityId) setDistricts(response.data || []) form.setValue('district', 0) } } // 初始化省份 useEffect(() => { if (provinceData?.data) { setProvinces(provinceData.data) } }, [provinceData]) // 加载城市数据 useEffect(() => { const provinceId = form.watch('province') if (provinceId) { handleProvinceChange(provinceId) } }, [form.watch('province')]) // 加载区县数据 useEffect(() => { const cityId = form.watch('city') if (cityId) { handleCityChange(cityId) } }, [form.watch('city')]) const onSubmit = (data: AddressFormData) => { saveAddressMutation.mutate(data) } return ( Taro.navigateBack()} />
( 收货人姓名 )} /> ( 手机号码 )} /> ( 省份