| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249 |
- 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 { useEffect } from 'react'
- import Taro, { useRouter } from '@tarojs/taro'
- import { deliveryAddressClient } from '@/api'
- 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 { Switch } from '@/components/ui/switch'
- import { CitySelector } from '@/components/ui/city-selector'
- const addressSchema = z.object({
- name: z.string().min(1, '请输入收货人姓名'),
- phone: z.string().regex(/^1[3-9]\d{9}$/, '请输入正确的手机号'),
- province: z.number().min(1, '请选择省份'),
- city: z.number().min(1, '请选择城市'),
- district: z.number().min(1, '请选择区县'),
- town: z.number().min(1).optional(),
- address: z.string().min(1, '请输入详细地址'),
- isDefault: z.boolean().optional()
- })
- type AddressFormData = z.infer<typeof addressSchema>
- export default function AddressEditPage() {
- const queryClient = useQueryClient()
- // 使用useRouter钩子获取路由参数
- const router = useRouter()
- const params = router.params
- const addressId = params?.id ? parseInt(params.id) : null
- // 获取地址详情
- 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 form = useForm<AddressFormData>({
- resolver: zodResolver(addressSchema),
- defaultValues: {
- name: '',
- phone: '',
- province: undefined, // 设为undefined,让CitySelector自动选择第一个省份
- city: undefined, // 设为undefined,让CitySelector自动选择第一个城市
- district: undefined, // 设为undefined,让CitySelector自动选择第一个区县
- town: undefined, // 设为undefined,让CitySelector自动选择第一个乡镇
- address: '',
- isDefault: false
- }
- })
- // 填充表单数据
- useEffect(() => {
- if (address) {
- form.reset({
- name: address.name,
- phone: address.phone,
- province: address.receiverProvince || undefined,
- city: address.receiverCity || undefined,
- district: address.receiverDistrict || undefined,
- town: address.receiverTown || undefined,
- 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,
- receiverTown: data.town || 0,
- address: data.address,
- isDefault: data.isDefault ? 1 : 0
- }
- let response
- //console.log("addressId:",addressId)
- //console.log("addressData:",addressData)
- if (addressId) {
- response = await deliveryAddressClient[':id'].$put({
- param: { id: addressId },
- json: addressData
- })
- //console.log("response:",response)
- return response.json()
- } 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 onSubmit = (data: AddressFormData) => {
- console.debug('表单提交数据:', data)
- console.debug('表单验证状态:', form.formState.isValid)
- console.debug('表单错误:', form.formState.errors)
- saveAddressMutation.mutate(data)
- }
- return (
- <View className="min-h-screen bg-gray-50">
- <Navbar
- title={addressId ? '编辑地址' : '添加地址'}
- leftIcon="i-heroicons-chevron-left-20-solid"
- onClickLeft={() => Taro.navigateBack()}
- />
-
- <ScrollView className="h-screen pt-12 pb-20">
- <View className="px-4 py-4">
- <Form {...form}>
- <View className="space-y-4">
- <Card>
- <View className="p-4 space-y-4">
- <FormField
- name="name"
- render={({ field }) => (
- <FormItem>
- <FormLabel>收货人姓名</FormLabel>
- <FormControl>
- <Input placeholder="请输入收货人姓名" {...field} />
- </FormControl>
- <FormMessage />
- </FormItem>
- )}
- />
- <FormField
- name="phone"
- render={({ field }) => (
- <FormItem>
- <FormLabel>手机号码</FormLabel>
- <FormControl>
- <Input placeholder="请输入手机号码" {...field} />
- </FormControl>
- <FormMessage />
- </FormItem>
- )}
- />
- <View className="mb-4" style={{ display: 'none' }}>
- <Text className="text-sm font-medium text-gray-700 mb-2">所在地区</Text>
- <CitySelector
- provinceValue={form.watch('province')}
- cityValue={form.watch('city')}
- districtValue={form.watch('district')}
- townValue={form.watch('town')}
- onProvinceChange={(value) => value !== undefined && form.setValue('province', value)}
- onCityChange={(value) => value !== undefined && form.setValue('city', value)}
- onDistrictChange={(value) => value !== undefined && form.setValue('district', value)}
- onTownChange={(value) => value !== undefined && form.setValue('town', value)}
- showLabels={false}
- />
- </View>
- <FormField
- name="address"
- render={({ field }) => (
- <FormItem>
- <FormLabel>详细地址</FormLabel>
- <FormControl>
- <Input
- placeholder="请输入详细地址,如街道、门牌号等"
- {...field}
- />
- </FormControl>
- <FormMessage />
- </FormItem>
- )}
- />
- <FormField
- name="isDefault"
- render={({ field }) => (
- <FormItem>
- <View className="flex items-center justify-between">
- <FormLabel>设为默认地址</FormLabel>
- <FormControl>
- <Switch
- checked={field.value}
- onChange={field.onChange}
- color="#1976D2"
- />
- </FormControl>
- </View>
- </FormItem>
- )}
- />
- </View>
- </Card>
- <Button
- className="w-full"
- onClick={() => form.handleSubmit(onSubmit, (errors) => console.debug('表单验证错误:', errors))()}
- disabled={saveAddressMutation.isPending}
- >
- {saveAddressMutation.isPending ? '保存中...' : '保存地址'}
- </Button>
- </View>
- </Form>
- </View>
- </ScrollView>
- </View>
- )
- }
|