Quellcode durchsuchen

✨ feat(location): 实现省市区三级联动选择功能

- 移除单个区域选择,新增省市区三级联动选择组件AreaSelect
- 表单验证Schema更新,由areaId改为provinceId、cityId和districtId三个字段
- 调整表单默认值和初始数据处理逻辑,适配新的区域选择结构
- 移除Locations页面中不再使用的areas数据传递
- 更新表单标签和描述文本,明确为省市区选择功能
yourname vor 4 Monaten
Ursprung
Commit
911a898be4
2 geänderte Dateien mit 35 neuen und 42 gelöschten Zeilen
  1. 35 40
      src/client/admin/components/LocationForm.tsx
  2. 0 2
      src/client/admin/pages/Locations.tsx

+ 35 - 40
src/client/admin/components/LocationForm.tsx

@@ -5,30 +5,25 @@ import { Button } from '@/client/components/ui/button';
 import { Form, FormControl, FormDescription, FormField, FormItem, FormLabel, FormMessage } from '@/client/components/ui/form';
 import { Input } from '@/client/components/ui/input';
 import { Textarea } from '@/client/components/ui/textarea';
-import { Select, SelectContent, SelectItem, SelectTrigger, SelectValue } from '@/client/components/ui/select';
 import { DialogFooter } from '@/client/components/ui/dialog';
+import { AreaSelect } from './AreaSelect';
 
 // 表单验证Schema
 const locationFormSchema = z.object({
   name: z.string().min(1, '地点名称不能为空').max(100, '地点名称不能超过100个字符'),
   address: z.string().min(1, '地址不能为空').max(200, '地址不能超过200个字符'),
-  areaId: z.coerce.number<number>().int().positive('请选择所属区域'),
+  provinceId: z.coerce.number<number>().int().positive('请选择省份'),
+  cityId: z.coerce.number<number>().int().positive('请选择城市'),
+  districtId: z.coerce.number<number>().int().positive('请选择区县'),
   latitude: z.coerce.number<number>().optional(),
   longitude: z.coerce.number<number>().optional(),
 });
 
 type LocationFormValues = z.infer<typeof locationFormSchema>;
 
-interface Area {
-  id: number;
-  name: string;
-  code: string;
-}
-
 interface LocationFormProps {
   onSubmit: (data: LocationFormValues) => void;
   isLoading?: boolean;
-  areas: Area[];
   initialData?: any;
 }
 
@@ -38,7 +33,6 @@ interface LocationFormProps {
 export const LocationForm = ({
   onSubmit,
   isLoading = false,
-  areas,
   initialData,
 }: LocationFormProps) => {
   const form = useForm({
@@ -46,13 +40,17 @@ export const LocationForm = ({
     defaultValues: initialData ? {
       name: initialData.name,
       address: initialData.address,
-      areaId: initialData.area?.id || initialData.areaId,
+      provinceId: initialData.provinceId,
+      cityId: initialData.cityId,
+      districtId: initialData.districtId,
       latitude: initialData.latitude || undefined,
       longitude: initialData.longitude || undefined,
     } : {
       name: '',
       address: '',
-      areaId: undefined,
+      provinceId: 0,
+      cityId: 0,
+      districtId: 0,
       latitude: undefined,
       longitude: undefined,
     },
@@ -106,34 +104,31 @@ export const LocationForm = ({
             )}
           />
 
-          {/* 所属区域 */}
-          <FormField
-            control={form.control}
-            name="areaId"
-            render={({ field }) => (
-              <FormItem>
-                <FormLabel>所属区域</FormLabel>
-                <Select onValueChange={field.onChange} defaultValue={field.value?.toString()}>
-                  <FormControl>
-                    <SelectTrigger>
-                      <SelectValue placeholder="请选择所属区域" />
-                    </SelectTrigger>
-                  </FormControl>
-                  <SelectContent>
-                    {areas.map((area) => (
-                      <SelectItem key={area.id} value={area.id.toString()}>
-                        {area.name}
-                      </SelectItem>
-                    ))}
-                  </SelectContent>
-                </Select>
-                <FormDescription>
-                  选择地点所属的省市区区域
-                </FormDescription>
-                <FormMessage />
-              </FormItem>
-            )}
-          />
+          {/* 省市区三级联动 */}
+          <div className="col-span-full">
+            <FormItem>
+              <FormLabel>省市区选择</FormLabel>
+              <FormControl>
+                <AreaSelect
+                  value={{
+                    provinceId: form.watch('provinceId') === 0 ? undefined : form.watch('provinceId'),
+                    cityId: form.watch('cityId') === 0 ? undefined : form.watch('cityId'),
+                    districtId: form.watch('districtId') === 0 ? undefined : form.watch('districtId')
+                  }}
+                  onChange={(value) => {
+                    form.setValue('provinceId', value.provinceId || 0);
+                    form.setValue('cityId', value.cityId || 0);
+                    form.setValue('districtId', value.districtId || 0);
+                  }}
+                  required={true}
+                />
+              </FormControl>
+              <FormDescription>
+                请选择地点所在的省份、城市和区县
+              </FormDescription>
+              <FormMessage />
+            </FormItem>
+          </div>
 
           {/* 坐标信息 */}
           <div className="grid grid-cols-2 gap-4">

+ 0 - 2
src/client/admin/pages/Locations.tsx

@@ -218,7 +218,6 @@ export const LocationsPage = () => {
             <LocationForm
               onSubmit={handleCreate}
               isLoading={createMutation.isPending}
-              areas={areasData?.data || []}
             />
           </DialogContent>
         </Dialog>
@@ -418,7 +417,6 @@ export const LocationsPage = () => {
             <LocationForm
               onSubmit={handleUpdate}
               isLoading={updateMutation.isPending}
-              areas={areasData?.data || []}
               initialData={editingLocation}
             />
           )}