8 Commit-ok c91533cbf8 ... e51887bf9b

Szerző SHA1 Üzenet Dátum
  yourname e51887bf9b 🗑️ chore(components): 移除残疾人选择器组件 2 napja
  yourname 6f76232acc fix(disability-person-ui): 重构表单布局,大字段完全脱离网格独占一行 2 napja
  yourname e38542191c fix(disability-person-ui): 使用col-span-full确保大字段独占一行 2 napja
  yourname dae4320942 fix(disability-person-ui): 调整表单布局,让大字段独占一行 2 napja
  yourname 7ab4aacc3f feat(disability-person-ui): 添加暂无数据提示功能 2 napja
  yourname 486c75318c fix(ui-packages): 删除重复的残疾人管理UI包并整合功能 2 napja
  yourname 4ace77d5d5 fix(disability-ui): 修复表单滚动问题和添加移动端适配 2 napja
  yourname b19e8d6bc1 fix(salary-module): 修复列表路由缺少parseWithAwait的问题 2 napja
27 módosított fájl, 360 hozzáadás és 2904 törlés
  1. 0 87
      allin-packages/disability-management-ui/package.json
  2. 0 44
      allin-packages/disability-management-ui/src/api/disabilityClient.ts
  3. 0 2
      allin-packages/disability-management-ui/src/api/index.ts
  4. 0 697
      allin-packages/disability-management-ui/src/components/DisabilityManagement.tsx
  5. 0 2
      allin-packages/disability-management-ui/src/components/index.ts
  6. 0 3
      allin-packages/disability-management-ui/src/index.ts
  7. 0 460
      allin-packages/disability-management-ui/tests/integration/disability.integration.test.tsx
  8. 0 308
      allin-packages/disability-management-ui/tests/integration/disabled-person-selector.integration.test.tsx
  9. 0 12
      allin-packages/disability-management-ui/tests/setup.ts
  10. 0 36
      allin-packages/disability-management-ui/tsconfig.json
  11. 0 24
      allin-packages/disability-management-ui/vitest.config.ts
  12. 2 1
      allin-packages/disability-person-management-ui/src/api/index.ts
  13. 0 0
      allin-packages/disability-person-management-ui/src/api/types.ts
  14. 319 304
      allin-packages/disability-person-management-ui/src/components/DisabilityPersonManagement.tsx
  15. 0 0
      allin-packages/disability-person-management-ui/src/components/DisabledPersonSelector.tsx
  16. 2 1
      allin-packages/disability-person-management-ui/src/components/index.ts
  17. 22 0
      allin-packages/disability-person-management-ui/tests/integration/disability-person.integration.test.tsx
  18. 1 1
      allin-packages/order-management-ui/package.json
  19. 4 4
      allin-packages/order-management-ui/src/components/PersonSelector.tsx
  20. 1 1
      allin-packages/order-management-ui/tests/integration/order.integration.test.tsx
  21. 0 800
      allin-packages/order-management-ui/tests/integration/order.integration.test.tsx.backup
  22. 6 1
      allin-packages/salary-module/src/routes/salary-custom.routes.ts
  23. 2 99
      pnpm-lock.yaml
  24. 0 1
      web/package.json
  25. 1 3
      web/src/client/admin/api_init.ts
  26. 0 7
      web/src/client/admin/menu.tsx
  27. 0 6
      web/src/client/admin/routes.tsx

+ 0 - 87
allin-packages/disability-management-ui/package.json

@@ -1,87 +0,0 @@
-{
-  "name": "@d8d/allin-disability-management-ui",
-  "version": "1.0.0",
-  "description": "残疾人管理界面包 - 提供残疾人管理的完整前端界面,包括残疾人CRUD操作、区域信息管理、残疾类型管理等功能",
-  "type": "module",
-  "main": "src/index.ts",
-  "types": "src/index.ts",
-  "exports": {
-    ".": {
-      "types": "./src/index.ts",
-      "import": "./src/index.ts",
-      "require": "./src/index.ts"
-    },
-    "./components": {
-      "types": "./src/components/index.ts",
-      "import": "./src/components/index.ts",
-      "require": "./src/components/index.ts"
-    },
-    "./api": {
-      "types": "./src/api/index.ts",
-      "import": "./src/api/index.ts",
-      "require": "./src/api/index.ts"
-    }
-  },
-  "files": [
-    "src"
-  ],
-  "scripts": {
-    "build": "unbuild",
-    "dev": "tsc --watch",
-    "test": "vitest run",
-    "test:watch": "vitest",
-    "test:coverage": "vitest run --coverage",
-    "lint": "eslint src --ext .ts,.tsx",
-    "typecheck": "tsc --noEmit"
-  },
-  "dependencies": {
-    "@d8d/shared-types": "workspace:*",
-    "@d8d/shared-ui-components": "workspace:*",
-    "@d8d/allin-disability-module": "workspace:*",
-    "@d8d/area-management-ui": "workspace:*",
-    "@hookform/resolvers": "^5.2.1",
-    "@tanstack/react-query": "^5.90.9",
-    "class-variance-authority": "^0.7.1",
-    "clsx": "^2.1.1",
-    "date-fns": "^4.1.0",
-    "hono": "^4.8.5",
-    "lucide-react": "^0.536.0",
-    "react": "^19.1.0",
-    "react-dom": "^19.1.0",
-    "react-hook-form": "^7.61.1",
-    "sonner": "^2.0.7",
-    "tailwind-merge": "^3.3.1",
-    "zod": "^4.0.15"
-  },
-  "devDependencies": {
-    "@testing-library/jest-dom": "^6.8.0",
-    "@testing-library/react": "^16.3.0",
-    "@testing-library/user-event": "^14.6.1",
-    "@types/node": "^22.10.2",
-    "@types/react": "^19.2.2",
-    "@types/react-dom": "^19.2.3",
-    "@typescript-eslint/eslint-plugin": "^8.18.1",
-    "@typescript-eslint/parser": "^8.18.1",
-    "eslint": "^9.17.0",
-    "jsdom": "^26.0.0",
-    "typescript": "^5.8.3",
-    "unbuild": "^3.4.0",
-    "vitest": "^4.0.9"
-  },
-  "peerDependencies": {
-    "react": "^19.1.0",
-    "react-dom": "^19.1.0"
-  },
-  "keywords": [
-    "disability",
-    "management",
-    "admin",
-    "ui",
-    "react",
-    "crud",
-    "allin",
-    "area"
-  ],
-  "author": "D8D Team",
-  "license": "MIT"
-}

+ 0 - 44
allin-packages/disability-management-ui/src/api/disabilityClient.ts

@@ -1,44 +0,0 @@
-import { disabledPersonRoutes } from '@d8d/allin-disability-module';
-import { rpcClient } from '@d8d/shared-ui-components/utils/hc'
-
-export class DisabilityClientManager {
-  private static instance: DisabilityClientManager;
-  private client: ReturnType<typeof rpcClient<typeof disabledPersonRoutes>> | null = null;
-
-  private constructor() {}
-
-  public static getInstance(): DisabilityClientManager {
-    if (!DisabilityClientManager.instance) {
-      DisabilityClientManager.instance = new DisabilityClientManager();
-    }
-    return DisabilityClientManager.instance;
-  }
-
-  // 初始化客户端
-  public init(baseUrl: string = '/'): ReturnType<typeof rpcClient<typeof disabledPersonRoutes>> {
-    return this.client = rpcClient<typeof disabledPersonRoutes>(baseUrl);
-  }
-
-  // 获取客户端实例
-  public get(): ReturnType<typeof rpcClient<typeof disabledPersonRoutes>> {
-    if (!this.client) {
-      return this.init()
-    }
-    return this.client;
-  }
-
-  // 重置客户端(用于测试或重新初始化)
-  public reset(): void {
-    this.client = null;
-  }
-}
-
-// 导出单例实例
-const disabilityClientManager = DisabilityClientManager.getInstance();
-
-// 导出默认客户端实例(延迟初始化)
-export const disabilityClient = disabilityClientManager.get()
-
-export {
-  disabilityClientManager
-}

+ 0 - 2
allin-packages/disability-management-ui/src/api/index.ts

@@ -1,2 +0,0 @@
-export * from './disabilityClient';
-export * from './types';

+ 0 - 697
allin-packages/disability-management-ui/src/components/DisabilityManagement.tsx

@@ -1,697 +0,0 @@
-import React, { useState } from 'react';
-import { useQuery, useMutation } from '@tanstack/react-query';
-import { Plus, Edit, Trash2, Search } from 'lucide-react';
-import { format } from 'date-fns';
-import { Input } from '@d8d/shared-ui-components/components/ui/input';
-import { Button } from '@d8d/shared-ui-components/components/ui/button';
-import { Card, CardContent, CardDescription, CardHeader, CardTitle } from '@d8d/shared-ui-components/components/ui/card';
-import { Table, TableBody, TableCell, TableHead, TableHeader, TableRow } from '@d8d/shared-ui-components/components/ui/table';
-import { Skeleton } from '@d8d/shared-ui-components/components/ui/skeleton';
-import { Dialog, DialogContent, DialogDescription, DialogFooter, DialogHeader, DialogTitle } from '@d8d/shared-ui-components/components/ui/dialog';
-import { Form, FormControl, FormField, FormItem, FormLabel, FormMessage } from '@d8d/shared-ui-components/components/ui/form';
-import { useForm } from 'react-hook-form';
-import { zodResolver } from '@hookform/resolvers/zod';
-import { toast } from 'sonner';
-import { DataTablePagination } from '@d8d/shared-ui-components/components/admin/DataTablePagination';
-import { AreaSelect } from '@d8d/area-management-ui';
-import { disabilityClientManager } from '../api/disabilityClient';
-import { CreateDisabledPersonSchema, UpdateDisabledPersonSchema } from '@d8d/allin-disability-module/schemas';
-import type { CreateDisabledPersonRequest, UpdateDisabledPersonRequest, DisabledPersonData } from '../api/types';
-
-interface DisabilitySearchParams {
-  page: number;
-  limit: number;
-  search: string;
-}
-
-const DisabilityManagement: React.FC = () => {
-  const [searchParams, setSearchParams] = useState<DisabilitySearchParams>({ page: 1, limit: 10, search: '' });
-  const [isModalOpen, setIsModalOpen] = useState(false);
-  const [isCreateForm, setIsCreateForm] = useState(true);
-  const [deleteDialogOpen, setDeleteDialogOpen] = useState(false);
-  const [personToDelete, setPersonToDelete] = useState<number | null>(null);
-
-  // 表单实例 - 创建表单
-  const createForm = useForm<CreateDisabledPersonRequest>({
-    resolver: zodResolver(CreateDisabledPersonSchema),
-    defaultValues: {
-      name: '',
-      gender: '男',
-      idCard: '',
-      disabilityId: '',
-      disabilityType: '',
-      disabilityLevel: '',
-      idAddress: '',
-      phone: '',
-      province: '',
-      city: '',
-    }
-  });
-
-  // 表单实例 - 更新表单
-  const updateForm = useForm<UpdateDisabledPersonRequest>({
-    resolver: zodResolver(UpdateDisabledPersonSchema),
-    defaultValues: {}
-  });
-
-  // 查询残疾人列表
-  const { data: disabilityList, isLoading, refetch } = useQuery({
-    queryKey: ['disabled-persons', searchParams],
-    queryFn: async () => {
-      const res = await disabilityClientManager.get().getAllDisabledPersons.$get({
-        query: {
-          skip: (searchParams.page - 1) * searchParams.limit,
-          take: searchParams.limit
-        }
-      });
-      if (res.status !== 200) throw new Error('获取残疾人列表失败');
-      return await res.json();
-    },
-    initialData: {
-      data: [],
-      total: 0
-    }
-  });
-
-  // 搜索残疾人
-  const { data: searchResults } = useQuery({
-    queryKey: ['search-disabled-persons', searchParams.search],
-    queryFn: async () => {
-      if (!searchParams.search.trim()) return null;
-      const res = await disabilityClientManager.get().searchDisabledPersons.$get({
-        query: {
-          keyword: searchParams.search,
-          skip: 0,
-          take: searchParams.limit
-        }
-      });
-      if (res.status !== 200) throw new Error('搜索残疾人失败');
-      return await res.json();
-    },
-    initialData: {
-      data: [],
-      total: 0
-    },
-    enabled: !!searchParams.search.trim()
-  });
-
-  // 创建残疾人
-  const createMutation = useMutation({
-    mutationFn: async (data: CreateDisabledPersonRequest) => {
-      const res = await disabilityClientManager.get().createDisabledPerson.$post({
-        json: data
-      });
-      return res;
-    },
-    onSuccess: () => {
-      toast.success('残疾人创建成功');
-      createForm.reset();
-      setIsModalOpen(false);
-      refetch();
-    },
-    onError: (error: any) => {
-      toast.error(error.message || '创建残疾人失败');
-    }
-  });
-
-  // 更新残疾人
-  const updateMutation = useMutation({
-    mutationFn: async (data: UpdateDisabledPersonRequest) => {
-      const res = await disabilityClientManager.get().updateDisabledPerson.$post({
-        json: data
-      });
-      return res;
-    },
-    onSuccess: () => {
-      toast.success('残疾人更新成功');
-      updateForm.reset();
-      setIsModalOpen(false);
-      refetch();
-    },
-    onError: (error: any) => {
-      toast.error(error.message || '更新残疾人失败');
-    }
-  });
-
-  // 删除残疾人
-  const deleteMutation = useMutation({
-    mutationFn: async (id: number) => {
-      const res = await disabilityClientManager.get().deleteDisabledPerson.$post({
-        json: { id }
-      });
-      return res;
-    },
-    onSuccess: () => {
-      toast.success('残疾人删除成功');
-      setDeleteDialogOpen(false);
-      setPersonToDelete(null);
-      refetch();
-    },
-    onError: (error: any) => {
-      toast.error(error.message || '删除残疾人失败');
-    }
-  });
-
-  // 处理区域选择变化
-  const handleAreaChange = (form: any, areaValue: { provinceId?: number; cityId?: number; districtId?: number }) => {
-    // 这里需要将区域ID转换为区域名称
-    // 实际实现中需要调用区域服务获取名称
-    form.setValue('province', areaValue.provinceId?.toString() || '');
-    form.setValue('city', areaValue.cityId?.toString() || '');
-    if (areaValue.districtId) {
-      form.setValue('district', areaValue.districtId.toString());
-    }
-  };
-
-  // 打开创建模态框
-  const handleOpenCreateModal = () => {
-    setIsCreateForm(true);
-    createForm.reset();
-    setIsModalOpen(true);
-  };
-
-  // 打开更新模态框
-  const handleOpenUpdateModal = (person: DisabledPersonData) => {
-    setIsCreateForm(false);
-    updateForm.reset({
-      id: person.id,
-      name: person.name,
-      gender: person.gender,
-      idCard: person.idCard,
-      disabilityId: person.disabilityId,
-      disabilityType: person.disabilityType,
-      disabilityLevel: person.disabilityLevel,
-      idAddress: person.idAddress,
-      phone: person.phone,
-      province: person.province,
-      city: person.city,
-      district: person.district || '',
-      detailedAddress: person.detailedAddress || '',
-      nation: person.nation || '',
-      isMarried: person.isMarried || 0,
-      canDirectContact: person.canDirectContact,
-      jobStatus: person.jobStatus,
-    });
-    setIsModalOpen(true);
-  };
-
-  // 打开删除确认对话框
-  const handleOpenDeleteDialog = (id: number) => {
-    setPersonToDelete(id);
-    setDeleteDialogOpen(true);
-  };
-
-  // 处理创建表单提交
-  const handleCreateSubmit = createForm.handleSubmit((data) => {
-    createMutation.mutate(data);
-  }, (errors) => console.debug('创建表单验证错误:', errors));
-
-  // 处理更新表单提交
-  const handleUpdateSubmit = updateForm.handleSubmit((data) => {
-    updateMutation.mutate(data);
-  }, (errors) => console.debug('更新表单验证错误:', errors));
-
-  // 处理删除
-  const handleDelete = () => {
-    if (personToDelete) {
-      deleteMutation.mutate(personToDelete);
-    }
-  };
-
-  // 处理搜索
-  const handleSearch = (e: React.FormEvent) => {
-    e.preventDefault();
-    refetch();
-  };
-
-  const displayData = searchParams.search.trim() ? searchResults?.data : disabilityList?.data;
-  const displayTotal = (searchParams.search.trim() ? searchResults?.total : disabilityList?.total) as number;
-
-  return (
-    <div className="space-y-6">
-      <Card>
-        <CardHeader>
-          <CardTitle>残疾人管理</CardTitle>
-          <CardDescription>管理残疾人信息,包括创建、更新、删除和查询功能</CardDescription>
-        </CardHeader>
-        <CardContent>
-          <div className="flex justify-between items-center mb-6">
-            <form onSubmit={handleSearch} className="flex items-center space-x-2">
-              <Input
-                placeholder="搜索姓名或身份证号..."
-                value={searchParams.search}
-                onChange={(e) => setSearchParams({ ...searchParams, search: e.target.value })}
-                className="w-64"
-                data-testid="search-input"
-              />
-              <Button type="submit" size="sm" data-testid="search-button">
-                <Search className="h-4 w-4 mr-2" />
-                搜索
-              </Button>
-            </form>
-            <Button onClick={handleOpenCreateModal} data-testid="create-button">
-              <Plus className="h-4 w-4 mr-2" />
-              新增残疾人
-            </Button>
-          </div>
-
-          {isLoading ? (
-            <div className="space-y-2">
-              {Array.from({ length: 5 }).map((_, i) => (
-                <Skeleton key={i} className="h-12 w-full" />
-              ))}
-            </div>
-          ) : (
-            <>
-              <Table>
-                <TableHeader>
-                  <TableRow>
-                    <TableHead>姓名</TableHead>
-                    <TableHead>性别</TableHead>
-                    <TableHead>身份证号</TableHead>
-                    <TableHead>残疾证号</TableHead>
-                    <TableHead>残疾类型</TableHead>
-                    <TableHead>联系电话</TableHead>
-                    <TableHead>创建时间</TableHead>
-                    <TableHead>操作</TableHead>
-                  </TableRow>
-                </TableHeader>
-                <TableBody>
-                  {displayData?.map((person) => (
-                    <TableRow key={person.id} data-testid={`person-row-${person.id}`}>
-                      <TableCell>{person.name}</TableCell>
-                      <TableCell>{person.gender}</TableCell>
-                      <TableCell>{person.idCard}</TableCell>
-                      <TableCell>{person.disabilityId}</TableCell>
-                      <TableCell>{person.disabilityType}</TableCell>
-                      <TableCell>{person.phone}</TableCell>
-                      <TableCell>{format(new Date(person.createTime), 'yyyy-MM-dd HH:mm')}</TableCell>
-                      <TableCell>
-                        <div className="flex space-x-2">
-                          <Button
-                            variant="outline"
-                            size="sm"
-                            onClick={() => handleOpenUpdateModal(person)}
-                            data-testid={`edit-button-${person.id}`}
-                          >
-                            <Edit className="h-4 w-4" />
-                          </Button>
-                          <Button
-                            variant="outline"
-                            size="sm"
-                            onClick={() => handleOpenDeleteDialog(person.id)}
-                            data-testid={`delete-button-${person.id}`}
-                          >
-                            <Trash2 className="h-4 w-4" />
-                          </Button>
-                        </div>
-                      </TableCell>
-                    </TableRow>
-                  ))}
-                </TableBody>
-              </Table>
-
-              {displayData?.length === 0 && (
-                <div className="text-center py-8 text-muted-foreground">
-                  暂无数据
-                </div>
-              )}
-
-              { displayTotal > 0 && (
-                <DataTablePagination
-                  totalCount={displayTotal}
-                  pageSize={searchParams.limit}
-                  currentPage={searchParams.page}
-                  onPageChange={(page, pageSize) => setSearchParams({ ...searchParams, page, limit: pageSize })}
-                />
-              )}
-            </>
-          )}
-        </CardContent>
-      </Card>
-
-      {/* 创建/更新模态框 */}
-      <Dialog open={isModalOpen} onOpenChange={setIsModalOpen}>
-        <DialogContent className="max-w-2xl">
-          <DialogHeader>
-            <DialogTitle>{isCreateForm ? '新增残疾人' : '编辑残疾人'}</DialogTitle>
-            <DialogDescription>
-              {isCreateForm ? '填写残疾人信息' : '修改残疾人信息'}
-            </DialogDescription>
-          </DialogHeader>
-          {isCreateForm ? (
-            <Form {...createForm}>
-              <form onSubmit={handleCreateSubmit} className="space-y-4">
-                <div className="grid grid-cols-2 gap-4">
-                  <FormField
-                    control={createForm.control}
-                    name="name"
-                    render={({ field }) => (
-                      <FormItem>
-                        <FormLabel>姓名 *</FormLabel>
-                        <FormControl>
-                          <Input placeholder="请输入姓名" {...field} data-testid="name-input" />
-                        </FormControl>
-                        <FormMessage />
-                      </FormItem>
-                    )}
-                  />
-                  <FormField
-                    control={createForm.control}
-                    name="gender"
-                    render={({ field }) => (
-                      <FormItem>
-                        <FormLabel>性别 *</FormLabel>
-                        <FormControl>
-                          <select
-                            className="flex h-10 w-full rounded-md border border-input bg-background px-3 py-2 text-sm ring-offset-background file:border-0 file:bg-transparent file:text-sm file:font-medium placeholder:text-muted-foreground focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-ring focus-visible:ring-offset-2 disabled:cursor-not-allowed disabled:opacity-50"
-                            {...field}
-                            data-testid="gender-select"
-                          >
-                            <option value="男">男</option>
-                            <option value="女">女</option>
-                          </select>
-                        </FormControl>
-                        <FormMessage />
-                      </FormItem>
-                    )}
-                  />
-                  <FormField
-                    control={createForm.control}
-                    name="idCard"
-                    render={({ field }) => (
-                      <FormItem>
-                        <FormLabel>身份证号 *</FormLabel>
-                        <FormControl>
-                          <Input placeholder="请输入身份证号" {...field} data-testid="id-card-input" />
-                        </FormControl>
-                        <FormMessage />
-                      </FormItem>
-                    )}
-                  />
-                  <FormField
-                    control={createForm.control}
-                    name="disabilityId"
-                    render={({ field }) => (
-                      <FormItem>
-                        <FormLabel>残疾证号 *</FormLabel>
-                        <FormControl>
-                          <Input placeholder="请输入残疾证号" {...field} data-testid="disability-id-input" />
-                        </FormControl>
-                        <FormMessage />
-                      </FormItem>
-                    )}
-                  />
-                  <FormField
-                    control={createForm.control}
-                    name="disabilityType"
-                    render={({ field }) => (
-                      <FormItem>
-                        <FormLabel>残疾类型 *</FormLabel>
-                        <FormControl>
-                          <Input placeholder="请输入残疾类型" {...field} data-testid="disability-type-input" />
-                        </FormControl>
-                        <FormMessage />
-                      </FormItem>
-                    )}
-                  />
-                  <FormField
-                    control={createForm.control}
-                    name="disabilityLevel"
-                    render={({ field }) => (
-                      <FormItem>
-                        <FormLabel>残疾等级 *</FormLabel>
-                        <FormControl>
-                          <Input placeholder="请输入残疾等级" {...field} data-testid="disability-level-input" />
-                        </FormControl>
-                        <FormMessage />
-                      </FormItem>
-                    )}
-                  />
-                  <FormField
-                    control={createForm.control}
-                    name="phone"
-                    render={({ field }) => (
-                      <FormItem>
-                        <FormLabel>联系电话 *</FormLabel>
-                        <FormControl>
-                          <Input placeholder="请输入联系电话" {...field} data-testid="phone-input" />
-                        </FormControl>
-                        <FormMessage />
-                      </FormItem>
-                    )}
-                  />
-                  <FormField
-                    control={createForm.control}
-                    name="idAddress"
-                    render={({ field }) => (
-                      <FormItem>
-                        <FormLabel>身份证地址 *</FormLabel>
-                        <FormControl>
-                          <Input placeholder="请输入身份证地址" {...field} data-testid="id-address-input" />
-                        </FormControl>
-                        <FormMessage />
-                      </FormItem>
-                    )}
-                  />
-                  <FormItem>
-                    <FormLabel>所在地区 *</FormLabel>
-                    <FormControl>
-                      <AreaSelect
-                        value={{}}
-                        onChange={(value) => handleAreaChange(createForm, value)}
-                        required
-                        data-testid="area-select"
-                      />
-                    </FormControl>
-                    <FormMessage />
-                  </FormItem>
-                  <FormField
-                    control={createForm.control}
-                    name="detailedAddress"
-                    render={({ field }) => (
-                      <FormItem>
-                        <FormLabel>详细地址</FormLabel>
-                        <FormControl>
-                          <Input placeholder="请输入详细地址" {...field} data-testid="detailed-address-input" />
-                        </FormControl>
-                        <FormMessage />
-                      </FormItem>
-                    )}
-                  />
-                  <FormField
-                    control={createForm.control}
-                    name="nation"
-                    render={({ field }) => (
-                      <FormItem>
-                        <FormLabel>民族</FormLabel>
-                        <FormControl>
-                          <Input placeholder="请输入民族" {...field} data-testid="nation-input" />
-                        </FormControl>
-                        <FormMessage />
-                      </FormItem>
-                    )}
-                  />
-                </div>
-                <DialogFooter>
-                  <Button type="button" variant="outline" onClick={() => setIsModalOpen(false)}>
-                    取消
-                  </Button>
-                  <Button type="submit" disabled={createMutation.isPending} data-testid="create-submit-button">
-                    {createMutation.isPending ? '创建中...' : '创建'}
-                  </Button>
-                </DialogFooter>
-              </form>
-            </Form>
-          ) : (
-            <Form {...updateForm}>
-              <form onSubmit={handleUpdateSubmit} className="space-y-4">
-                <div className="grid grid-cols-2 gap-4">
-                  <FormField
-                    control={updateForm.control}
-                    name="name"
-                    render={({ field }) => (
-                      <FormItem>
-                        <FormLabel>姓名 *</FormLabel>
-                        <FormControl>
-                          <Input placeholder="请输入姓名" {...field} data-testid="update-name-input" />
-                        </FormControl>
-                        <FormMessage />
-                      </FormItem>
-                    )}
-                  />
-                  <FormField
-                    control={updateForm.control}
-                    name="gender"
-                    render={({ field }) => (
-                      <FormItem>
-                        <FormLabel>性别 *</FormLabel>
-                        <FormControl>
-                          <select
-                            className="flex h-10 w-full rounded-md border border-input bg-background px-3 py-2 text-sm ring-offset-background file:border-0 file:bg-transparent file:text-sm file:font-medium placeholder:text-muted-foreground focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-ring focus-visible:ring-offset-2 disabled:cursor-not-allowed disabled:opacity-50"
-                            {...field}
-                            data-testid="update-gender-select"
-                          >
-                            <option value="男">男</option>
-                            <option value="女">女</option>
-                          </select>
-                        </FormControl>
-                        <FormMessage />
-                      </FormItem>
-                    )}
-                  />
-                  <FormField
-                    control={updateForm.control}
-                    name="idCard"
-                    render={({ field }) => (
-                      <FormItem>
-                        <FormLabel>身份证号 *</FormLabel>
-                        <FormControl>
-                          <Input placeholder="请输入身份证号" {...field} data-testid="update-id-card-input" />
-                        </FormControl>
-                        <FormMessage />
-                      </FormItem>
-                    )}
-                  />
-                  <FormField
-                    control={updateForm.control}
-                    name="disabilityId"
-                    render={({ field }) => (
-                      <FormItem>
-                        <FormLabel>残疾证号 *</FormLabel>
-                        <FormControl>
-                          <Input placeholder="请输入残疾证号" {...field} data-testid="update-disability-id-input" />
-                        </FormControl>
-                        <FormMessage />
-                      </FormItem>
-                    )}
-                  />
-                  <FormField
-                    control={updateForm.control}
-                    name="disabilityType"
-                    render={({ field }) => (
-                      <FormItem>
-                        <FormLabel>残疾类型 *</FormLabel>
-                        <FormControl>
-                          <Input placeholder="请输入残疾类型" {...field} data-testid="update-disability-type-input" />
-                        </FormControl>
-                        <FormMessage />
-                      </FormItem>
-                    )}
-                  />
-                  <FormField
-                    control={updateForm.control}
-                    name="disabilityLevel"
-                    render={({ field }) => (
-                      <FormItem>
-                        <FormLabel>残疾等级 *</FormLabel>
-                        <FormControl>
-                          <Input placeholder="请输入残疾等级" {...field} data-testid="update-disability-level-input" />
-                        </FormControl>
-                        <FormMessage />
-                      </FormItem>
-                    )}
-                  />
-                  <FormField
-                    control={updateForm.control}
-                    name="phone"
-                    render={({ field }) => (
-                      <FormItem>
-                        <FormLabel>联系电话 *</FormLabel>
-                        <FormControl>
-                          <Input placeholder="请输入联系电话" {...field} data-testid="update-phone-input" />
-                        </FormControl>
-                        <FormMessage />
-                      </FormItem>
-                    )}
-                  />
-                  <FormField
-                    control={updateForm.control}
-                    name="idAddress"
-                    render={({ field }) => (
-                      <FormItem>
-                        <FormLabel>身份证地址 *</FormLabel>
-                        <FormControl>
-                          <Input placeholder="请输入身份证地址" {...field} data-testid="update-id-address-input" />
-                        </FormControl>
-                        <FormMessage />
-                      </FormItem>
-                    )}
-                  />
-                  <FormItem>
-                    <FormLabel>所在地区 *</FormLabel>
-                    <FormControl>
-                      <AreaSelect
-                        value={{}}
-                        onChange={(value) => handleAreaChange(updateForm, value)}
-                        required
-                        data-testid="update-area-select"
-                      />
-                    </FormControl>
-                    <FormMessage />
-                  </FormItem>
-                  <FormField
-                    control={updateForm.control}
-                    name="detailedAddress"
-                    render={({ field }) => (
-                      <FormItem>
-                        <FormLabel>详细地址</FormLabel>
-                        <FormControl>
-                          <Input placeholder="请输入详细地址" {...field} data-testid="update-detailed-address-input" />
-                        </FormControl>
-                        <FormMessage />
-                      </FormItem>
-                    )}
-                  />
-                  <FormField
-                    control={updateForm.control}
-                    name="nation"
-                    render={({ field }) => (
-                      <FormItem>
-                        <FormLabel>民族</FormLabel>
-                        <FormControl>
-                          <Input placeholder="请输入民族" {...field} data-testid="update-nation-input" />
-                        </FormControl>
-                        <FormMessage />
-                      </FormItem>
-                    )}
-                  />
-                </div>
-                <DialogFooter>
-                  <Button type="button" variant="outline" onClick={() => setIsModalOpen(false)}>
-                    取消
-                  </Button>
-                  <Button type="submit" disabled={updateMutation.isPending} data-testid="update-submit-button">
-                    {updateMutation.isPending ? '更新中...' : '更新'}
-                  </Button>
-                </DialogFooter>
-              </form>
-            </Form>
-          )}
-        </DialogContent>
-      </Dialog>
-
-      {/* 删除确认对话框 */}
-      <Dialog open={deleteDialogOpen} onOpenChange={setDeleteDialogOpen}>
-        <DialogContent>
-          <DialogHeader>
-            <DialogTitle>确认删除</DialogTitle>
-            <DialogDescription>
-              确定要删除这个残疾人记录吗?此操作不可恢复。
-            </DialogDescription>
-          </DialogHeader>
-          <DialogFooter>
-            <Button variant="outline" onClick={() => setDeleteDialogOpen(false)}>
-              取消
-            </Button>
-            <Button variant="destructive" onClick={handleDelete} disabled={deleteMutation.isPending} data-testid="confirm-delete-button">
-              {deleteMutation.isPending ? '删除中...' : '确认删除'}
-            </Button>
-          </DialogFooter>
-        </DialogContent>
-      </Dialog>
-    </div>
-  );
-};
-
-export default DisabilityManagement;

+ 0 - 2
allin-packages/disability-management-ui/src/components/index.ts

@@ -1,2 +0,0 @@
-export { default as DisabilityManagement } from './DisabilityManagement';
-export { default as DisabledPersonSelector } from './DisabledPersonSelector';

+ 0 - 3
allin-packages/disability-management-ui/src/index.ts

@@ -1,3 +0,0 @@
-// 残疾人管理UI包入口文件
-export * from './components';
-export * from './api';

+ 0 - 460
allin-packages/disability-management-ui/tests/integration/disability.integration.test.tsx

@@ -1,460 +0,0 @@
-import { describe, it, expect, vi, beforeEach } from 'vitest';
-import { render, screen, fireEvent, waitFor } from '@testing-library/react';
-import { QueryClient, QueryClientProvider } from '@tanstack/react-query';
-import DisabilityManagement from '../../src/components/DisabilityManagement';
-import { disabilityClientManager } from '../../src/api/disabilityClient';
-
-// 完整的mock响应对象
-const createMockResponse = (status: number, data?: any) => ({
-  status,
-  ok: status >= 200 && status < 300,
-  body: null,
-  bodyUsed: false,
-  statusText: status === 200 ? 'OK' : status === 201 ? 'Created' : status === 204 ? 'No Content' : 'Error',
-  headers: new Headers(),
-  url: '',
-  redirected: false,
-  type: 'basic' as ResponseType,
-  json: async () => data || {},
-  text: async () => '',
-  blob: async () => new Blob(),
-  arrayBuffer: async () => new ArrayBuffer(0),
-  formData: async () => new FormData(),
-  clone: function() { return this; }
-});
-
-// Mock API client
-vi.mock('../../src/api/disabilityClient', () => {
-  const mockDisabilityClient = {
-    getAllDisabledPersons: {
-      $get: vi.fn(() => Promise.resolve(createMockResponse(200, {
-        data: [
-          {
-            id: 1,
-            name: '张三',
-            gender: '男',
-            idCard: '110101199001011234',
-            disabilityId: 'CJZ20240001',
-            disabilityType: '视力残疾',
-            disabilityLevel: '一级',
-            idAddress: '北京市东城区',
-            phone: '13800138000',
-            province: '北京市',
-            city: '北京市',
-            district: '东城区',
-            createTime: '2024-01-01T00:00:00Z',
-            updateTime: '2024-01-01T00:00:00Z'
-          },
-          {
-            id: 2,
-            name: '李四',
-            gender: '女',
-            idCard: '110101199002021234',
-            disabilityId: 'CJZ20240002',
-            disabilityType: '听力残疾',
-            disabilityLevel: '二级',
-            idAddress: '上海市黄浦区',
-            phone: '13900139000',
-            province: '上海市',
-            city: '上海市',
-            district: '黄浦区',
-            createTime: '2024-01-02T00:00:00Z',
-            updateTime: '2024-01-02T00:00:00Z'
-          }
-        ],
-        total: 2
-      }))),
-    },
-    searchDisabledPersons: {
-      $get: vi.fn(() => Promise.resolve(createMockResponse(200, {
-        data: [
-          {
-            id: 1,
-            name: '张三',
-            gender: '男',
-            idCard: '110101199001011234',
-            disabilityId: 'CJZ20240001',
-            disabilityType: '视力残疾',
-            disabilityLevel: '一级',
-            idAddress: '北京市东城区',
-            phone: '13800138000',
-            province: '北京市',
-            city: '北京市',
-            district: '东城区',
-            createTime: '2024-01-01T00:00:00Z',
-            updateTime: '2024-01-01T00:00:00Z'
-          }
-        ],
-        total: 1
-      }))),
-    },
-    createDisabledPerson: {
-      $post: vi.fn(() => Promise.resolve(createMockResponse(200, {
-        id: 3,
-        name: '王五',
-        gender: '男',
-        idCard: '110101199003031234',
-        disabilityId: 'CJZ20240003',
-        disabilityType: '肢体残疾',
-        disabilityLevel: '三级',
-        idAddress: '广州市天河区',
-        phone: '13700137000',
-        province: '广东省',
-        city: '广州市',
-        district: '天河区',
-        createTime: '2024-01-03T00:00:00Z',
-        updateTime: '2024-01-03T00:00:00Z'
-      }))),
-    },
-    updateDisabledPerson: {
-      $post: vi.fn(() => Promise.resolve(createMockResponse(200, {
-        id: 1,
-        name: '张三(已更新)',
-        gender: '男',
-        idCard: '110101199001011234',
-        disabilityId: 'CJZ20240001',
-        disabilityType: '视力残疾',
-        disabilityLevel: '一级',
-        idAddress: '北京市东城区',
-        phone: '13800138000',
-        province: '北京市',
-        city: '北京市',
-        district: '东城区',
-        createTime: '2024-01-01T00:00:00Z',
-        updateTime: '2024-01-03T00:00:00Z'
-      }))),
-    },
-    deleteDisabledPerson: {
-      $post: vi.fn(() => Promise.resolve(createMockResponse(200, { success: true }))),
-    },
-    getDisabledPerson: {
-      ':id': {
-        $get: vi.fn(() => Promise.resolve(createMockResponse(200, {
-          id: 1,
-          name: '张三',
-          gender: '男',
-          idCard: '110101199001011234',
-          disabilityId: 'CJZ20240001',
-          disabilityType: '视力残疾',
-          disabilityLevel: '一级',
-          idAddress: '北京市东城区',
-          phone: '13800138000',
-          province: '北京市',
-          city: '北京市',
-          district: '东城区',
-          createTime: '2024-01-01T00:00:00Z',
-          updateTime: '2024-01-01T00:00:00Z'
-        }))),
-      }
-    },
-    findByIdCard: {
-      ':idCard': {
-        $get: vi.fn(() => Promise.resolve(createMockResponse(200, null))),
-      }
-    },
-    batchCreateDisabledPersons: {
-      $post: vi.fn(() => Promise.resolve(createMockResponse(200, {
-        success: true,
-        createdCount: 2,
-        failedItems: []
-      }))),
-    }
-  };
-
-  const mockDisabilityClientManager = {
-    get: vi.fn(() => mockDisabilityClient),
-    init: vi.fn(() => mockDisabilityClient),
-    reset: vi.fn(),
-  };
-
-  return {
-    disabilityClientManager: mockDisabilityClientManager,
-    disabilityClient: mockDisabilityClient,
-  };
-});
-
-// Mock AreaSelect组件
-vi.mock('@d8d/area-management-ui', () => ({
-  AreaSelect: ({ onChange, value, disabled, 'data-testid': testId }: any) => (
-    <div data-testid={testId || 'area-select'}>
-      <select
-        data-testid="area-province-select"
-        onChange={(e) => onChange && onChange({ provinceId: e.target.value ? 1 : undefined })}
-        value={value?.provinceId || ''}
-        disabled={disabled}
-      >
-        <option value="">选择省份</option>
-        <option value="1">北京市</option>
-      </select>
-      <select
-        data-testid="area-city-select"
-        onChange={(e) => onChange && onChange({ provinceId: 1, cityId: e.target.value ? 2 : undefined })}
-        value={value?.cityId || ''}
-        disabled={disabled}
-      >
-        <option value="">选择城市</option>
-        <option value="2">北京市</option>
-      </select>
-      <select
-        data-testid="area-district-select"
-        onChange={(e) => onChange && onChange({ provinceId: 1, cityId: 2, districtId: e.target.value ? 3 : undefined })}
-        value={value?.districtId || ''}
-        disabled={disabled}
-      >
-        <option value="">选择区县</option>
-        <option value="3">东城区</option>
-      </select>
-    </div>
-  ),
-}));
-
-describe('残疾人管理集成测试', () => {
-  let queryClient: QueryClient;
-
-  beforeEach(() => {
-    queryClient = new QueryClient({
-      defaultOptions: {
-        queries: {
-          retry: false,
-        },
-      },
-    });
-    vi.clearAllMocks();
-  });
-
-  const renderComponent = () => {
-    return render(
-      <QueryClientProvider client={queryClient}>
-        <DisabilityManagement />
-      </QueryClientProvider>
-    );
-  };
-
-  it('应该正确渲染残疾人管理组件', async () => {
-    renderComponent();
-
-    // 验证标题
-    expect(screen.getByText('残疾人管理')).toBeInTheDocument();
-    expect(screen.getByText('管理残疾人信息,包括创建、更新、删除和查询功能')).toBeInTheDocument();
-
-    // 验证搜索框
-    expect(screen.getByTestId('search-input')).toBeInTheDocument();
-    expect(screen.getByTestId('search-button')).toBeInTheDocument();
-
-    // 验证新增按钮
-    expect(screen.getByTestId('create-button')).toBeInTheDocument();
-
-    // 等待数据加载
-    await waitFor(() => {
-      expect(screen.getByText('张三')).toBeInTheDocument();
-      expect(screen.getByText('李四')).toBeInTheDocument();
-    });
-
-    // 验证表格列
-    expect(screen.getByText('姓名')).toBeInTheDocument();
-    expect(screen.getByText('性别')).toBeInTheDocument();
-    expect(screen.getByText('身份证号')).toBeInTheDocument();
-    expect(screen.getByText('残疾证号')).toBeInTheDocument();
-    expect(screen.getByText('残疾类型')).toBeInTheDocument();
-    expect(screen.getByText('联系电话')).toBeInTheDocument();
-    expect(screen.getByText('创建时间')).toBeInTheDocument();
-    expect(screen.getByText('操作')).toBeInTheDocument();
-  });
-
-  it('应该能够搜索残疾人', async () => {
-    renderComponent();
-
-    // 等待初始数据加载
-    await waitFor(() => {
-      expect(screen.getByText('张三')).toBeInTheDocument();
-    });
-
-    // 输入搜索关键词
-    const searchInput = screen.getByTestId('search-input');
-    fireEvent.change(searchInput, { target: { value: '张三' } });
-
-    // 点击搜索按钮
-    const searchButton = screen.getByTestId('search-button');
-    fireEvent.click(searchButton);
-
-    // 验证搜索功能被调用
-    await waitFor(() => {
-      expect(screen.getByText('张三')).toBeInTheDocument();
-      expect(screen.queryByText('李四')).not.toBeInTheDocument();
-    });
-  });
-
-  it('应该能够打开创建模态框并填写表单', async () => {
-    renderComponent();
-
-    // 等待初始数据加载
-    await waitFor(() => {
-      expect(screen.getByText('张三')).toBeInTheDocument();
-    });
-
-    // 点击新增按钮
-    const createButton = screen.getByTestId('create-button');
-    fireEvent.click(createButton);
-
-    // 验证模态框打开 - 检查对话框标题
-    await waitFor(() => {
-      const elements = screen.getAllByText('新增残疾人');
-      expect(elements.length).toBeGreaterThan(1); // 按钮和对话框标题
-    });
-
-    // 填写表单
-    fireEvent.change(screen.getByTestId('name-input'), { target: { value: '王五' } });
-    fireEvent.change(screen.getByTestId('gender-select'), { target: { value: '男' } });
-    fireEvent.change(screen.getByTestId('id-card-input'), { target: { value: '110101199003031234' } });
-    fireEvent.change(screen.getByTestId('disability-id-input'), { target: { value: 'CJZ20240003' } });
-    fireEvent.change(screen.getByTestId('disability-type-input'), { target: { value: '肢体残疾' } });
-    fireEvent.change(screen.getByTestId('disability-level-input'), { target: { value: '三级' } });
-    fireEvent.change(screen.getByTestId('phone-input'), { target: { value: '13700137000' } });
-    fireEvent.change(screen.getByTestId('id-address-input'), { target: { value: '广州市天河区' } });
-
-    // 选择地区
-    fireEvent.change(screen.getByTestId('area-province-select'), { target: { value: '1' } });
-    fireEvent.change(screen.getByTestId('area-city-select'), { target: { value: '2' } });
-    fireEvent.change(screen.getByTestId('area-district-select'), { target: { value: '3' } });
-
-    // 验证表单字段
-    expect(screen.getByTestId('name-input')).toHaveValue('王五');
-    expect(screen.getByTestId('gender-select')).toHaveValue('男');
-    expect(screen.getByTestId('id-card-input')).toHaveValue('110101199003031234');
-  });
-
-  it('应该能够编辑残疾人信息', async () => {
-    renderComponent();
-
-    // 等待初始数据加载
-    await waitFor(() => {
-      expect(screen.getByText('张三')).toBeInTheDocument();
-    });
-
-    // 点击编辑按钮
-    const editButton = screen.getByTestId('edit-button-1');
-    fireEvent.click(editButton);
-
-    // 验证编辑模态框打开
-    await waitFor(() => {
-      expect(screen.getByText('编辑残疾人')).toBeInTheDocument();
-    });
-
-    // 验证表单已填充数据
-    expect(screen.getByTestId('update-name-input')).toHaveValue('张三');
-    expect(screen.getByTestId('update-gender-select')).toHaveValue('男');
-    expect(screen.getByTestId('update-id-card-input')).toHaveValue('110101199001011234');
-
-    // 修改姓名
-    fireEvent.change(screen.getByTestId('update-name-input'), { target: { value: '张三(已更新)' } });
-
-    // 点击更新按钮
-    const updateButton = screen.getByTestId('update-submit-button');
-    fireEvent.click(updateButton);
-
-    // 验证更新API被调用
-    await waitFor(() => {
-      expect(screen.queryByText('编辑残疾人')).not.toBeInTheDocument();
-    });
-  });
-
-  it('应该能够删除残疾人', async () => {
-    renderComponent();
-
-    // 等待初始数据加载
-    await waitFor(() => {
-      expect(screen.getByText('张三')).toBeInTheDocument();
-    });
-
-    // 点击删除按钮
-    const deleteButton = screen.getByTestId('delete-button-1');
-    fireEvent.click(deleteButton);
-
-    // 验证删除确认对话框打开
-    await waitFor(() => {
-      const elements = screen.getAllByText('确认删除');
-      expect(elements.length).toBeGreaterThan(1); // 对话框标题和按钮
-    });
-
-    // 点击确认删除按钮
-    const confirmButton = screen.getByTestId('confirm-delete-button');
-    fireEvent.click(confirmButton);
-
-    // 验证删除API被调用
-    await waitFor(() => {
-      expect(screen.queryByText('确认删除')).not.toBeInTheDocument();
-    });
-  });
-
-  it('应该处理表单验证错误', async () => {
-    renderComponent();
-
-    // 等待初始数据加载
-    await waitFor(() => {
-      expect(screen.getByText('张三')).toBeInTheDocument();
-    });
-
-    // 点击新增按钮
-    const createButton = screen.getByTestId('create-button');
-    fireEvent.click(createButton);
-
-    // 验证模态框打开 - 检查对话框标题
-    await waitFor(() => {
-      const elements = screen.getAllByText('新增残疾人');
-      expect(elements.length).toBeGreaterThan(1); // 按钮和对话框标题
-    });
-
-    // 尝试提交空表单
-    const submitButton = screen.getByTestId('create-submit-button');
-    fireEvent.click(submitButton);
-
-    // 验证验证错误信息
-    await waitFor(() => {
-      expect(screen.getByText('姓名不能为空')).toBeInTheDocument();
-      expect(screen.getByText('身份证号不能为空')).toBeInTheDocument();
-      expect(screen.getByText('残疾证号不能为空')).toBeInTheDocument();
-    });
-  });
-
-  it('应该处理API错误', async () => {
-    // Mock API错误 - 使用mockImplementationOnce
-    const mockCreate = disabilityClientManager.get().createDisabledPerson.$post as any;
-    mockCreate.mockImplementationOnce(() => Promise.reject(new Error('创建失败')));
-
-    renderComponent();
-
-    // 等待初始数据加载
-    await waitFor(() => {
-      expect(screen.getByText('张三')).toBeInTheDocument();
-    });
-
-    // 打开创建模态框
-    const createButton = screen.getByTestId('create-button');
-    fireEvent.click(createButton);
-
-    // 等待模态框打开 - 检查对话框标题
-    await waitFor(() => {
-      const dialogTitles = screen.getAllByText('新增残疾人');
-      expect(dialogTitles.length).toBeGreaterThan(1); // 按钮和对话框标题
-    });
-
-    fireEvent.change(screen.getByTestId('name-input'), { target: { value: '测试用户' } });
-    fireEvent.change(screen.getByTestId('gender-select'), { target: { value: '男' } });
-    fireEvent.change(screen.getByTestId('id-card-input'), { target: { value: '110101199001011234' } });
-    fireEvent.change(screen.getByTestId('disability-id-input'), { target: { value: 'CJZ20240001' } });
-    fireEvent.change(screen.getByTestId('disability-type-input'), { target: { value: '视力残疾' } });
-    fireEvent.change(screen.getByTestId('disability-level-input'), { target: { value: '一级' } });
-    fireEvent.change(screen.getByTestId('phone-input'), { target: { value: '13800138000' } });
-    fireEvent.change(screen.getByTestId('id-address-input'), { target: { value: '北京市东城区' } });
-
-    // 提交表单
-    const submitButton = screen.getByTestId('create-submit-button');
-    fireEvent.click(submitButton);
-
-    // 验证错误处理(toast错误消息由sonner处理,这里我们验证表单没有关闭)
-    await waitFor(() => {
-      const elements = screen.getAllByText('新增残疾人');
-      expect(elements.length).toBeGreaterThan(1); // 按钮和对话框标题
-    });
-  });
-});

+ 0 - 308
allin-packages/disability-management-ui/tests/integration/disabled-person-selector.integration.test.tsx

@@ -1,308 +0,0 @@
-import { describe, it, expect, vi, beforeEach } from 'vitest';
-import { render, screen, fireEvent, waitFor } from '@testing-library/react';
-import { QueryClient, QueryClientProvider } from '@tanstack/react-query';
-import DisabledPersonSelector from '../../src/components/DisabledPersonSelector';
-import { disabilityClientManager } from '../../src/api/disabilityClient';
-import type { DisabledPersonData } from '../../src/api/types';
-
-// 完整的mock响应对象
-const createMockResponse = (status: number, data?: any) => ({
-  status,
-  ok: status >= 200 && status < 300,
-  body: null,
-  bodyUsed: false,
-  statusText: status === 200 ? 'OK' : status === 201 ? 'Created' : status === 204 ? 'No Content' : 'Error',
-  headers: new Headers(),
-  url: '',
-  redirected: false,
-  type: 'basic' as ResponseType,
-  json: async () => data || {},
-  text: async () => '',
-  blob: async () => new Blob(),
-  arrayBuffer: async () => new ArrayBuffer(0),
-  formData: async () => new FormData(),
-  clone: function() { return this; }
-});
-
-// Mock API client
-vi.mock('../../src/api/disabilityClient', () => {
-  const mockDisabilityClient = {
-    searchDisabledPersons: {
-      $get: vi.fn(() => Promise.resolve(createMockResponse(200, {
-        data: [
-          {
-            id: 1,
-            name: '张三',
-            gender: '男',
-            idCard: '110101199001011234',
-            disabilityId: 'CJZ20240001',
-            disabilityType: '视力残疾',
-            disabilityLevel: '一级',
-            idAddress: '北京市东城区',
-            phone: '13800138000',
-            province: '北京市',
-            city: '北京市',
-            district: '东城区',
-            isInBlackList: 0,
-            createTime: '2024-01-01T00:00:00Z',
-            updateTime: '2024-01-01T00:00:00Z'
-          },
-          {
-            id: 2,
-            name: '李四',
-            gender: '女',
-            idCard: '110101199001011235',
-            disabilityId: 'CJZ20240002',
-            disabilityType: '听力残疾',
-            disabilityLevel: '二级',
-            idAddress: '上海市黄浦区',
-            phone: '13800138001',
-            province: '上海市',
-            city: '上海市',
-            district: '黄浦区',
-            isInBlackList: 1, // 黑名单人员
-            createTime: '2024-01-01T00:00:00Z',
-            updateTime: '2024-01-01T00:00:00Z'
-          }
-        ],
-        total: 2
-      })))
-    },
-    getAllDisabledPersons: {
-      $get: vi.fn(() => Promise.resolve(createMockResponse(200, {
-        data: [
-          {
-            id: 3,
-            name: '王五',
-            gender: '男',
-            idCard: '110101199001011236',
-            disabilityId: 'CJZ20240003',
-            disabilityType: '肢体残疾',
-            disabilityLevel: '三级',
-            idAddress: '广州市天河区',
-            phone: '13800138002',
-            province: '广东省',
-            city: '广州市',
-            district: '天河区',
-            isInBlackList: 0,
-            createTime: '2024-01-01T00:00:00Z',
-            updateTime: '2024-01-01T00:00:00Z'
-          }
-        ],
-        total: 1
-      })))
-    }
-  };
-
-  const mockClientManager = {
-    get: vi.fn(() => mockDisabilityClient),
-    init: vi.fn(() => mockDisabilityClient),
-    reset: vi.fn(),
-    getInstance: vi.fn(() => mockClientManager)
-  };
-
-  return {
-    disabilityClientManager: mockClientManager,
-    disabilityClient: mockDisabilityClient
-  };
-});
-
-// Mock AreaSelect组件(与现有测试保持一致)
-vi.mock('@d8d/area-management-ui', () => ({
-  AreaSelect: ({ onChange, value, disabled, 'data-testid': testId }: any) => (
-    <div data-testid={testId || 'area-select'}>
-      <select
-        data-testid="area-province-select"
-        onChange={(e) => onChange && onChange({ provinceId: e.target.value ? 1 : undefined })}
-        value={value?.provinceId || ''}
-        disabled={disabled}
-      >
-        <option value="">选择省份</option>
-        <option value="1">北京市</option>
-      </select>
-      <select
-        data-testid="area-city-select"
-        onChange={(e) => onChange && onChange({ provinceId: 1, cityId: e.target.value ? 2 : undefined })}
-        value={value?.cityId || ''}
-        disabled={disabled}
-      >
-        <option value="">选择城市</option>
-        <option value="2">北京市</option>
-      </select>
-      <select
-        data-testid="area-district-select"
-        onChange={(e) => onChange && onChange({ provinceId: 1, cityId: 2, districtId: e.target.value ? 3 : undefined })}
-        value={value?.districtId || ''}
-        disabled={disabled}
-      >
-        <option value="">选择区县</option>
-        <option value="3">东城区</option>
-      </select>
-    </div>
-  ),
-}));
-
-
-describe('DisabledPersonSelector', () => {
-  let queryClient: QueryClient;
-  let onOpenChange: ReturnType<typeof vi.fn>;
-  let onSelect: ReturnType<typeof vi.fn>;
-
-  beforeEach(() => {
-    queryClient = new QueryClient({
-      defaultOptions: {
-        queries: {
-          retry: false,
-        },
-      },
-    });
-    onOpenChange = vi.fn();
-    onSelect = vi.fn();
-    vi.clearAllMocks();
-  });
-
-  const renderComponent = (props = {}) => {
-    return render(
-      <QueryClientProvider client={queryClient}>
-        <DisabledPersonSelector
-          open={true}
-          onOpenChange={onOpenChange}
-          onSelect={onSelect}
-          {...props}
-        />
-      </QueryClientProvider>
-    );
-  };
-
-  it('应该渲染对话框和搜索区域', async () => {
-    renderComponent();
-
-    // 等待数据加载
-    await waitFor(() => {
-      expect(screen.getByText('选择残疾人')).toBeInTheDocument();
-    });
-
-    // 检查搜索字段
-    expect(screen.getByTestId('search-name-input')).toBeInTheDocument();
-    expect(screen.getByTestId('area-select')).toBeInTheDocument();
-    expect(screen.getByText('搜索')).toBeInTheDocument();
-    expect(screen.getByText('重置')).toBeInTheDocument();
-  });
-
-  it('应该显示残疾人列表', async () => {
-    renderComponent();
-
-    // 等待数据加载 - 应该调用 getAllDisabledPersons 因为没有搜索关键词
-    await waitFor(() => {
-      expect(disabilityClientManager.get().getAllDisabledPersons.$get).toHaveBeenCalled();
-    });
-
-    // 检查表格数据
-    await waitFor(() => {
-      expect(screen.getByText('王五')).toBeInTheDocument();
-    });
-  });
-
-  it('应该处理搜索功能', async () => {
-    renderComponent();
-
-    // 输入搜索关键词
-    const searchInput = screen.getByTestId('search-name-input');
-    fireEvent.change(searchInput, { target: { value: '张三' } });
-
-    // 点击搜索按钮
-    const searchButton = screen.getByText('搜索');
-    fireEvent.click(searchButton);
-
-    // 验证搜索API被调用
-    await waitFor(() => {
-      expect(disabilityClientManager.get().searchDisabledPersons.$get).toHaveBeenCalledWith({
-        query: {
-          keyword: '张三',
-          skip: 0,
-          take: 10
-        }
-      });
-    });
-  });
-
-  it('应该处理重置搜索', async () => {
-    renderComponent();
-
-    // 等待组件渲染
-    await waitFor(() => {
-      expect(screen.getByTestId('search-name-input')).toBeInTheDocument();
-    });
-
-    // 输入搜索关键词
-    const searchInput = screen.getByTestId('search-name-input');
-    fireEvent.change(searchInput, { target: { value: '张三' } });
-
-    // 点击重置按钮
-    const resetButton = screen.getByText('重置');
-    fireEvent.click(resetButton);
-
-    // 验证搜索输入被清空
-    expect(searchInput).toHaveValue('');
-  });
-
-  it('应该处理单选模式', async () => {
-    renderComponent({ mode: 'single' });
-
-    // 等待数据加载
-    await waitFor(() => {
-      expect(disabilityClientManager.get().getAllDisabledPersons.$get).toHaveBeenCalled();
-    });
-
-    // 等待表格数据渲染
-    await waitFor(() => {
-      expect(screen.getByText('王五')).toBeInTheDocument();
-    });
-
-    // 点击表格行选择人员
-    const firstRow = screen.getByText('王五').closest('tr');
-    expect(firstRow).toBeInTheDocument();
-
-    if (firstRow) {
-      fireEvent.click(firstRow);
-    }
-
-    // 验证选择回调被调用
-    expect(onSelect).toHaveBeenCalledWith(expect.objectContaining({
-      id: 3,
-      name: '王五'
-    }));
-    expect(onOpenChange).toHaveBeenCalledWith(false);
-  });
-
-  it('应该处理多选模式', async () => {
-    renderComponent({ mode: 'multiple' });
-
-    // 等待数据加载
-    await waitFor(() => {
-      expect(disabilityClientManager.get().getAllDisabledPersons.$get).toHaveBeenCalled();
-    });
-
-    // 等待表格数据渲染
-    await waitFor(() => {
-      expect(screen.getByText('王五')).toBeInTheDocument();
-    });
-
-    // 应该显示多选相关的UI
-    expect(screen.getByText('已选择 0 人')).toBeInTheDocument();
-  });
-
-  it('应该处理对话框关闭', async () => {
-    renderComponent();
-
-    await waitFor(() => {
-      expect(screen.getByText('取消')).toBeInTheDocument();
-    });
-
-    // 点击取消按钮
-    const cancelButton = screen.getByText('取消');
-    fireEvent.click(cancelButton);
-
-    expect(onOpenChange).toHaveBeenCalledWith(false);
-  });
-});

+ 0 - 12
allin-packages/disability-management-ui/tests/setup.ts

@@ -1,12 +0,0 @@
-import '@testing-library/jest-dom';
-import { vi } from 'vitest';
-
-// Mock sonner
-vi.mock('sonner', () => ({
-  toast: {
-    success: vi.fn(),
-    error: vi.fn(),
-    warning: vi.fn(),
-    info: vi.fn()
-  }
-}));

+ 0 - 36
allin-packages/disability-management-ui/tsconfig.json

@@ -1,36 +0,0 @@
-{
-  "compilerOptions": {
-    "target": "ES2022",
-    "lib": ["ES2022", "DOM", "DOM.Iterable"],
-    "module": "ESNext",
-    "skipLibCheck": true,
-    "moduleResolution": "bundler",
-    "allowImportingTsExtensions": true,
-    "resolveJsonModule": true,
-    "isolatedModules": true,
-    "noEmit": true,
-    "jsx": "react-jsx",
-    "strict": true,
-    "noUnusedLocals": true,
-    "noUnusedParameters": true,
-    "noFallthroughCasesInSwitch": true,
-    "experimentalDecorators": true,
-    "emitDecoratorMetadata": true,
-    "declaration": true,
-    "declarationMap": true,
-    "sourceMap": true,
-    "outDir": "./dist",
-    "baseUrl": ".",
-    "paths": {
-      "@/*": ["./src/*"]
-    }
-  },
-  "include": [
-    "src/**/*",
-    "tests/**/*"
-  ],
-  "exclude": [
-    "node_modules",
-    "dist"
-  ]
-}

+ 0 - 24
allin-packages/disability-management-ui/vitest.config.ts

@@ -1,24 +0,0 @@
-import { defineConfig } from 'vitest/config';
-
-export default defineConfig({
-  test: {
-    globals: true,
-    environment: 'jsdom',
-    setupFiles: ['./tests/setup.ts'],
-    coverage: {
-      provider: 'v8',
-      reporter: ['text', 'json', 'html'],
-      exclude: [
-        'node_modules/',
-        'tests/',
-        '**/*.d.ts',
-        '**/*.config.*'
-      ]
-    }
-  },
-  resolve: {
-    alias: {
-      '@': './src'
-    }
-  }
-});

+ 2 - 1
allin-packages/disability-person-management-ui/src/api/index.ts

@@ -1 +1,2 @@
-export { disabilityClientManager } from './disabilityClient';
+export { disabilityClientManager } from './disabilityClient';
+export * from './types';

+ 0 - 0
allin-packages/disability-management-ui/src/api/types.ts → allin-packages/disability-person-management-ui/src/api/types.ts


+ 319 - 304
allin-packages/disability-person-management-ui/src/components/DisabilityPersonManagement.tsx

@@ -254,46 +254,54 @@ const DisabilityPersonManagement: React.FC = () => {
                   </TableRow>
                 </TableHeader>
                 <TableBody>
-                  {data?.data?.map((person: any) => (
-                    <TableRow key={person.id}>
-                      <TableCell>{person.name}</TableCell>
-                      <TableCell>{person.gender}</TableCell>
-                      <TableCell>{person.idCard}</TableCell>
-                      <TableCell>{person.disabilityId}</TableCell>
-                      <TableCell>{person.disabilityType}</TableCell>
-                      <TableCell>{person.disabilityLevel}</TableCell>
-                      <TableCell>{person.phone}</TableCell>
-                      <TableCell>{format(new Date(person.createTime), 'yyyy-MM-dd HH:mm')}</TableCell>
-                      <TableCell className="text-right">
-                        <div className="flex justify-end space-x-2">
-                          <Button
-                            variant="ghost"
-                            size="sm"
-                            onClick={() => handleViewOpen(person.id)}
-                            data-testid={`view-person-${person.id}`}
-                          >
-                            <Eye className="h-4 w-4" />
-                          </Button>
-                          <Button
-                            variant="ghost"
-                            size="sm"
-                            onClick={() => handleEditOpen(person)}
-                            data-testid={`edit-person-${person.id}`}
-                          >
-                            <Edit className="h-4 w-4" />
-                          </Button>
-                          <Button
-                            variant="ghost"
-                            size="sm"
-                            onClick={() => handleDeleteOpen(person.id)}
-                            data-testid={`delete-person-${person.id}`}
-                          >
-                            <Trash2 className="h-4 w-4" />
-                          </Button>
-                        </div>
+                  {data?.data && data.data.length > 0 ? (
+                    data.data.map((person: any) => (
+                      <TableRow key={person.id}>
+                        <TableCell>{person.name}</TableCell>
+                        <TableCell>{person.gender}</TableCell>
+                        <TableCell>{person.idCard}</TableCell>
+                        <TableCell>{person.disabilityId}</TableCell>
+                        <TableCell>{person.disabilityType}</TableCell>
+                        <TableCell>{person.disabilityLevel}</TableCell>
+                        <TableCell>{person.phone}</TableCell>
+                        <TableCell>{format(new Date(person.createTime), 'yyyy-MM-dd HH:mm')}</TableCell>
+                        <TableCell className="text-right">
+                          <div className="flex justify-end space-x-2">
+                            <Button
+                              variant="ghost"
+                              size="sm"
+                              onClick={() => handleViewOpen(person.id)}
+                              data-testid={`view-person-${person.id}`}
+                            >
+                              <Eye className="h-4 w-4" />
+                            </Button>
+                            <Button
+                              variant="ghost"
+                              size="sm"
+                              onClick={() => handleEditOpen(person)}
+                              data-testid={`edit-person-${person.id}`}
+                            >
+                              <Edit className="h-4 w-4" />
+                            </Button>
+                            <Button
+                              variant="ghost"
+                              size="sm"
+                              onClick={() => handleDeleteOpen(person.id)}
+                              data-testid={`delete-person-${person.id}`}
+                            >
+                              <Trash2 className="h-4 w-4" />
+                            </Button>
+                          </div>
+                        </TableCell>
+                      </TableRow>
+                    ))
+                  ) : (
+                    <TableRow>
+                      <TableCell colSpan={9} className="text-center py-8">
+                        <p className="text-muted-foreground">暂无数据</p>
                       </TableCell>
                     </TableRow>
-                  ))}
+                  )}
                 </TableBody>
               </Table>
 
@@ -314,7 +322,7 @@ const DisabilityPersonManagement: React.FC = () => {
 
       {/* 创建/编辑模态框 */}
       <Dialog open={isModalOpen} onOpenChange={setIsModalOpen}>
-        <DialogContent className="max-w-4xl max-h-[90vh] overflow-y-auto">
+        <DialogContent className="w-[95vw] max-w-4xl max-h-[80vh] flex flex-col">
           <DialogHeader>
             <DialogTitle data-testid={isCreateForm ? 'create-disabled-person-dialog-title' : 'edit-disabled-person-dialog-title'}>
               {isCreateForm ? '新增残疾人' : '编辑残疾人信息'}
@@ -323,13 +331,249 @@ const DisabilityPersonManagement: React.FC = () => {
               {isCreateForm ? '填写残疾人基本信息,带*的为必填项' : '修改残疾人信息'}
             </DialogDescription>
           </DialogHeader>
+          <div className="flex-1 overflow-y-auto pr-2 overscroll-contain touch-auto">
+            {isCreateForm ? (
+              <Form {...createForm}>
+                <form id="create-form" onSubmit={createForm.handleSubmit(onSubmitCreate, (errors) => console.debug('创建表单验证错误:', errors))} className="space-y-4">
+                  {/* 第一部分:小字段使用网格布局 */}
+                  <div className="grid grid-cols-1 md:grid-cols-2 lg:grid-cols-3 gap-4">
+                    <FormField
+                      control={createForm.control}
+                      name="name"
+                      render={({ field }) => (
+                        <FormItem>
+                          <FormLabel>姓名 *</FormLabel>
+                          <FormControl>
+                            <Input placeholder="请输入姓名" {...field} />
+                          </FormControl>
+                          <FormMessage />
+                        </FormItem>
+                      )}
+                    />
+
+                    <FormField
+                      control={createForm.control}
+                      name="gender"
+                      render={({ field }) => (
+                        <FormItem>
+                          <FormLabel>性别 *</FormLabel>
+                          <FormControl>
+                            <select
+                              className="flex h-10 w-full rounded-md border border-input bg-background px-3 py-2 text-sm ring-offset-background file:border-0 file:bg-transparent file:text-sm file:font-medium placeholder:text-muted-foreground focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-ring focus-visible:ring-offset-2 disabled:cursor-not-allowed disabled:opacity-50"
+                              data-testid="gender-select"
+                              {...field}
+                            >
+                              <option value="男">男</option>
+                              <option value="女">女</option>
+                            </select>
+                          </FormControl>
+                          <FormMessage />
+                        </FormItem>
+                      )}
+                    />
+
+                    <FormField
+                      control={createForm.control}
+                      name="idCard"
+                      render={({ field }) => (
+                        <FormItem>
+                          <FormLabel>身份证号 *</FormLabel>
+                          <FormControl>
+                            <Input placeholder="请输入身份证号" {...field} />
+                          </FormControl>
+                          <FormMessage />
+                        </FormItem>
+                      )}
+                    />
+
+                    <FormField
+                      control={createForm.control}
+                      name="disabilityId"
+                      render={({ field }) => (
+                        <FormItem>
+                          <FormLabel>残疾证号 *</FormLabel>
+                          <FormControl>
+                            <Input placeholder="请输入残疾证号" {...field} />
+                          </FormControl>
+                          <FormMessage />
+                        </FormItem>
+                      )}
+                    />
+
+                    <FormField
+                      control={createForm.control}
+                      name="disabilityType"
+                      render={({ field }) => (
+                        <FormItem>
+                          <FormLabel>残疾类型 *</FormLabel>
+                          <FormControl>
+                            <select
+                              className="flex h-10 w-full rounded-md border border-input bg-background px-3 py-2 text-sm ring-offset-background file:border-0 file:bg-transparent file:text-sm file:font-medium placeholder:text-muted-foreground focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-ring focus-visible:ring-offset-2 disabled:cursor-not-allowed disabled:opacity-50"
+                              data-testid="disability-type-select"
+                              {...field}
+                            >
+                              <option value="">请选择残疾类型</option>
+                              {DISABILITY_TYPES.map((type) => (
+                                <option key={type} value={getDisabilityTypeLabel(type)}>
+                                  {getDisabilityTypeLabel(type)}
+                                </option>
+                              ))}
+                            </select>
+                          </FormControl>
+                          <FormMessage />
+                        </FormItem>
+                      )}
+                    />
+
+                    <FormField
+                      control={createForm.control}
+                      name="disabilityLevel"
+                      render={({ field }) => (
+                        <FormItem>
+                          <FormLabel>残疾等级 *</FormLabel>
+                          <FormControl>
+                            <select
+                              className="flex h-10 w-full rounded-md border border-input bg-background px-3 py-2 text-sm ring-offset-background file:border-0 file:bg-transparent file:text-sm file:font-medium placeholder:text-muted-foreground focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-ring focus-visible:ring-offset-2 disabled:cursor-not-allowed disabled:opacity-50"
+                              data-testid="disability-level-select"
+                              {...field}
+                            >
+                              <option value="">请选择残疾等级</option>
+                              {DISABILITY_LEVELS.map((level) => (
+                                <option key={level} value={getDisabilityLevelLabel(level)}>
+                                  {getDisabilityLevelLabel(level)}
+                                </option>
+                              ))}
+                            </select>
+                          </FormControl>
+                          <FormMessage />
+                        </FormItem>
+                      )}
+                    />
+
+                    <FormField
+                      control={createForm.control}
+                      name="phone"
+                      render={({ field }) => (
+                        <FormItem>
+                          <FormLabel>联系电话 *</FormLabel>
+                          <FormControl>
+                            <Input placeholder="请输入联系电话" {...field} />
+                          </FormControl>
+                          <FormMessage />
+                        </FormItem>
+                      )}
+                    />
 
-          {isCreateForm ? (
-            <Form {...createForm}>
-              <form onSubmit={createForm.handleSubmit(onSubmitCreate, (errors) => console.debug('创建表单验证错误:', errors))} className="space-y-4">
-                <div className="grid grid-cols-2 gap-4">
+                    <FormField
+                      control={createForm.control}
+                      name="nation"
+                      render={({ field }) => (
+                        <FormItem>
+                          <FormLabel>民族</FormLabel>
+                          <FormControl>
+                            <Input placeholder="请输入民族" {...field} />
+                          </FormControl>
+                          <FormMessage />
+                        </FormItem>
+                      )}
+                    />
+
+                    <FormField
+                      control={createForm.control}
+                      name="isMarried"
+                      render={({ field }) => (
+                        <FormItem>
+                          <FormLabel>婚姻状况</FormLabel>
+                          <FormControl>
+                            <select
+                              className="flex h-10 w-full rounded-md border border-input bg-background px-3 py-2 text-sm ring-offset-background file:border-0 file:bg-transparent file:text-sm file:font-medium placeholder:text-muted-foreground focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-ring focus-visible:ring-offset-2 disabled:cursor-not-allowed disabled:opacity-50"
+                              {...field}
+                              value={field.value?.toString()}
+                              onChange={(e) => field.onChange(Number(e.target.value))}
+                            >
+                              <option value="0">未婚</option>
+                              <option value="1">已婚</option>
+                            </select>
+                          </FormControl>
+                          <FormMessage />
+                        </FormItem>
+                      )}
+                    />
+                  </div>
+
+                  {/* 第二部分:大字段脱离网格布局,各自独占一行 */}
+                  <div className="space-y-4">
+                    <FormField
+                      control={createForm.control}
+                      name="idAddress"
+                      render={({ field }) => (
+                        <FormItem>
+                          <FormLabel>身份证地址 *</FormLabel>
+                          <FormControl>
+                            <Input placeholder="请输入身份证地址" {...field} />
+                          </FormControl>
+                          <FormMessage />
+                        </FormItem>
+                      )}
+                    />
+
+                    <div>
+                      <FormLabel>居住地址 *</FormLabel>
+                      <div className="space-y-4 mt-2">
+                        <AreaSelect
+                          value={{
+                            provinceId: createForm.watch('province') ? Number(createForm.watch('province')) : undefined,
+                            cityId: createForm.watch('city') ? Number(createForm.watch('city')) : undefined,
+                            districtId: createForm.watch('district') ? Number(createForm.watch('district')) : undefined
+                          }}
+                          onChange={(value) => {
+                            createForm.setValue('province', value.provinceId?.toString() || '');
+                            createForm.setValue('city', value.cityId?.toString() || '');
+                            createForm.setValue('district', value.districtId?.toString() || '');
+                          }}
+                        />
+
+                        <FormField
+                          control={createForm.control}
+                          name="detailedAddress"
+                          render={({ field }) => (
+                            <FormItem>
+                              <FormControl>
+                                <Input placeholder="详细地址(街道、门牌号等)" {...field} />
+                              </FormControl>
+                              <FormMessage />
+                            </FormItem>
+                          )}
+                        />
+                      </div>
+                    </div>
+
+                    <div>
+                      <FormLabel>照片上传</FormLabel>
+                      <div className="mt-2">
+                        <FileSelector
+                          value={null}
+                          onChange={() => {
+                            // 这里需要处理文件ID的存储
+                            // 由于后端Schema没有photoFileId字段,暂时注释
+                            // createForm.setValue('photoFileId', fileId as number);
+                          }}
+                          accept="image/*"
+                          filterType="image"
+                          placeholder="选择或上传照片"
+                        />
+                      </div>
+                    </div>
+                  </div>
+                </form>
+            </Form>
+          ) : (
+            <Form {...updateForm}>
+              <form id="update-form" onSubmit={updateForm.handleSubmit(onSubmitUpdate)} className="space-y-4">
+                {/* 第一部分:小字段使用网格布局 */}
+                <div className="grid grid-cols-1 md:grid-cols-2 lg:grid-cols-3 gap-4">
                   <FormField
-                    control={createForm.control}
+                    control={updateForm.control}
                     name="name"
                     render={({ field }) => (
                       <FormItem>
@@ -343,7 +587,7 @@ const DisabilityPersonManagement: React.FC = () => {
                   />
 
                   <FormField
-                    control={createForm.control}
+                    control={updateForm.control}
                     name="gender"
                     render={({ field }) => (
                       <FormItem>
@@ -364,7 +608,7 @@ const DisabilityPersonManagement: React.FC = () => {
                   />
 
                   <FormField
-                    control={createForm.control}
+                    control={updateForm.control}
                     name="idCard"
                     render={({ field }) => (
                       <FormItem>
@@ -378,7 +622,7 @@ const DisabilityPersonManagement: React.FC = () => {
                   />
 
                   <FormField
-                    control={createForm.control}
+                    control={updateForm.control}
                     name="disabilityId"
                     render={({ field }) => (
                       <FormItem>
@@ -392,7 +636,7 @@ const DisabilityPersonManagement: React.FC = () => {
                   />
 
                   <FormField
-                    control={createForm.control}
+                    control={updateForm.control}
                     name="disabilityType"
                     render={({ field }) => (
                       <FormItem>
@@ -400,7 +644,7 @@ const DisabilityPersonManagement: React.FC = () => {
                         <FormControl>
                           <select
                             className="flex h-10 w-full rounded-md border border-input bg-background px-3 py-2 text-sm ring-offset-background file:border-0 file:bg-transparent file:text-sm file:font-medium placeholder:text-muted-foreground focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-ring focus-visible:ring-offset-2 disabled:cursor-not-allowed disabled:opacity-50"
-                            data-testid="disability-type-select"
+                            data-testid="gender-select"
                             {...field}
                           >
                             <option value="">请选择残疾类型</option>
@@ -417,7 +661,7 @@ const DisabilityPersonManagement: React.FC = () => {
                   />
 
                   <FormField
-                    control={createForm.control}
+                    control={updateForm.control}
                     name="disabilityLevel"
                     render={({ field }) => (
                       <FormItem>
@@ -425,7 +669,7 @@ const DisabilityPersonManagement: React.FC = () => {
                         <FormControl>
                           <select
                             className="flex h-10 w-full rounded-md border border-input bg-background px-3 py-2 text-sm ring-offset-background file:border-0 file:bg-transparent file:text-sm file:font-medium placeholder:text-muted-foreground focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-ring focus-visible:ring-offset-2 disabled:cursor-not-allowed disabled:opacity-50"
-                            data-testid="disability-level-select"
+                            data-testid="gender-select"
                             {...field}
                           >
                             <option value="">请选择残疾等级</option>
@@ -442,7 +686,7 @@ const DisabilityPersonManagement: React.FC = () => {
                   />
 
                   <FormField
-                    control={createForm.control}
+                    control={updateForm.control}
                     name="phone"
                     render={({ field }) => (
                       <FormItem>
@@ -456,52 +700,7 @@ const DisabilityPersonManagement: React.FC = () => {
                   />
 
                   <FormField
-                    control={createForm.control}
-                    name="idAddress"
-                    render={({ field }) => (
-                      <FormItem className="col-span-2">
-                        <FormLabel>身份证地址 *</FormLabel>
-                        <FormControl>
-                          <Input placeholder="请输入身份证地址" {...field} />
-                        </FormControl>
-                        <FormMessage />
-                      </FormItem>
-                    )}
-                  />
-
-                  <div className="col-span-2">
-                    <FormLabel>居住地址 *</FormLabel>
-                    <div className="space-y-4">
-                      <AreaSelect
-                        value={{
-                          provinceId: createForm.watch('province') ? Number(createForm.watch('province')) : undefined,
-                          cityId: createForm.watch('city') ? Number(createForm.watch('city')) : undefined,
-                          districtId: createForm.watch('district') ? Number(createForm.watch('district')) : undefined
-                        }}
-                        onChange={(value) => {
-                          createForm.setValue('province', value.provinceId?.toString() || '');
-                          createForm.setValue('city', value.cityId?.toString() || '');
-                          createForm.setValue('district', value.districtId?.toString() || '');
-                        }}
-                      />
-
-                      <FormField
-                        control={createForm.control}
-                        name="detailedAddress"
-                        render={({ field }) => (
-                          <FormItem>
-                            <FormControl>
-                              <Input placeholder="详细地址(街道、门牌号等)" {...field} />
-                            </FormControl>
-                            <FormMessage />
-                          </FormItem>
-                        )}
-                      />
-                    </div>
-                  </div>
-
-                  <FormField
-                    control={createForm.control}
+                    control={updateForm.control}
                     name="nation"
                     render={({ field }) => (
                       <FormItem>
@@ -515,7 +714,7 @@ const DisabilityPersonManagement: React.FC = () => {
                   />
 
                   <FormField
-                    control={createForm.control}
+                    control={updateForm.control}
                     name="isMarried"
                     render={({ field }) => (
                       <FormItem>
@@ -535,169 +734,15 @@ const DisabilityPersonManagement: React.FC = () => {
                       </FormItem>
                     )}
                   />
-
-                  <div className="col-span-2">
-                    <FormLabel>照片上传</FormLabel>
-                    <FileSelector
-                      value={null}
-                      onChange={() => {
-                        // 这里需要处理文件ID的存储
-                        // 由于后端Schema没有photoFileId字段,暂时注释
-                        // createForm.setValue('photoFileId', fileId as number);
-                      }}
-                      accept="image/*"
-                      filterType="image"
-                      placeholder="选择或上传照片"
-                    />
-                  </div>
                 </div>
 
-                <DialogFooter>
-                  <Button type="button" variant="outline" onClick={() => setIsModalOpen(false)}>
-                    取消
-                  </Button>
-                  <Button type="submit" disabled={createMutation.isPending}>
-                    {createMutation.isPending ? '创建中...' : '创建'}
-                  </Button>
-                </DialogFooter>
-              </form>
-            </Form>
-          ) : (
-            <Form {...updateForm}>
-              <form onSubmit={updateForm.handleSubmit(onSubmitUpdate)} className="space-y-4">
-                <div className="grid grid-cols-2 gap-4">
-                  <FormField
-                    control={updateForm.control}
-                    name="name"
-                    render={({ field }) => (
-                      <FormItem>
-                        <FormLabel>姓名 *</FormLabel>
-                        <FormControl>
-                          <Input placeholder="请输入姓名" {...field} />
-                        </FormControl>
-                        <FormMessage />
-                      </FormItem>
-                    )}
-                  />
-
-                  <FormField
-                    control={updateForm.control}
-                    name="gender"
-                    render={({ field }) => (
-                      <FormItem>
-                        <FormLabel>性别 *</FormLabel>
-                        <FormControl>
-                          <select
-                            className="flex h-10 w-full rounded-md border border-input bg-background px-3 py-2 text-sm ring-offset-background file:border-0 file:bg-transparent file:text-sm file:font-medium placeholder:text-muted-foreground focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-ring focus-visible:ring-offset-2 disabled:cursor-not-allowed disabled:opacity-50"
-                            data-testid="gender-select"
-                            {...field}
-                          >
-                            <option value="男">男</option>
-                            <option value="女">女</option>
-                          </select>
-                        </FormControl>
-                        <FormMessage />
-                      </FormItem>
-                    )}
-                  />
-
-                  <FormField
-                    control={updateForm.control}
-                    name="idCard"
-                    render={({ field }) => (
-                      <FormItem>
-                        <FormLabel>身份证号 *</FormLabel>
-                        <FormControl>
-                          <Input placeholder="请输入身份证号" {...field} />
-                        </FormControl>
-                        <FormMessage />
-                      </FormItem>
-                    )}
-                  />
-
-                  <FormField
-                    control={updateForm.control}
-                    name="disabilityId"
-                    render={({ field }) => (
-                      <FormItem>
-                        <FormLabel>残疾证号 *</FormLabel>
-                        <FormControl>
-                          <Input placeholder="请输入残疾证号" {...field} />
-                        </FormControl>
-                        <FormMessage />
-                      </FormItem>
-                    )}
-                  />
-
-                  <FormField
-                    control={updateForm.control}
-                    name="disabilityType"
-                    render={({ field }) => (
-                      <FormItem>
-                        <FormLabel>残疾类型 *</FormLabel>
-                        <FormControl>
-                          <select
-                            className="flex h-10 w-full rounded-md border border-input bg-background px-3 py-2 text-sm ring-offset-background file:border-0 file:bg-transparent file:text-sm file:font-medium placeholder:text-muted-foreground focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-ring focus-visible:ring-offset-2 disabled:cursor-not-allowed disabled:opacity-50"
-                            data-testid="gender-select"
-                            {...field}
-                          >
-                            <option value="">请选择残疾类型</option>
-                            {DISABILITY_TYPES.map((type) => (
-                              <option key={type} value={getDisabilityTypeLabel(type)}>
-                                {getDisabilityTypeLabel(type)}
-                              </option>
-                            ))}
-                          </select>
-                        </FormControl>
-                        <FormMessage />
-                      </FormItem>
-                    )}
-                  />
-
-                  <FormField
-                    control={updateForm.control}
-                    name="disabilityLevel"
-                    render={({ field }) => (
-                      <FormItem>
-                        <FormLabel>残疾等级 *</FormLabel>
-                        <FormControl>
-                          <select
-                            className="flex h-10 w-full rounded-md border border-input bg-background px-3 py-2 text-sm ring-offset-background file:border-0 file:bg-transparent file:text-sm file:font-medium placeholder:text-muted-foreground focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-ring focus-visible:ring-offset-2 disabled:cursor-not-allowed disabled:opacity-50"
-                            data-testid="gender-select"
-                            {...field}
-                          >
-                            <option value="">请选择残疾等级</option>
-                            {DISABILITY_LEVELS.map((level) => (
-                              <option key={level} value={getDisabilityLevelLabel(level)}>
-                                {getDisabilityLevelLabel(level)}
-                              </option>
-                            ))}
-                          </select>
-                        </FormControl>
-                        <FormMessage />
-                      </FormItem>
-                    )}
-                  />
-
-                  <FormField
-                    control={updateForm.control}
-                    name="phone"
-                    render={({ field }) => (
-                      <FormItem>
-                        <FormLabel>联系电话 *</FormLabel>
-                        <FormControl>
-                          <Input placeholder="请输入联系电话" {...field} />
-                        </FormControl>
-                        <FormMessage />
-                      </FormItem>
-                    )}
-                  />
-
+                {/* 第二部分:大字段脱离网格布局,各自独占一行 */}
+                <div className="space-y-4">
                   <FormField
                     control={updateForm.control}
                     name="idAddress"
                     render={({ field }) => (
-                      <FormItem className="col-span-2">
+                      <FormItem>
                         <FormLabel>身份证地址 *</FormLabel>
                         <FormControl>
                           <Input placeholder="请输入身份证地址" {...field} />
@@ -707,9 +752,9 @@ const DisabilityPersonManagement: React.FC = () => {
                     )}
                   />
 
-                  <div className="col-span-2">
+                  <div>
                     <FormLabel>居住地址 *</FormLabel>
-                    <div className="space-y-4">
+                    <div className="space-y-4 mt-2">
                       <AreaSelect
                         value={{
                           provinceId: updateForm.watch('province') ? Number(updateForm.watch('province')) : undefined,
@@ -737,55 +782,25 @@ const DisabilityPersonManagement: React.FC = () => {
                       />
                     </div>
                   </div>
-
-                  <FormField
-                    control={updateForm.control}
-                    name="nation"
-                    render={({ field }) => (
-                      <FormItem>
-                        <FormLabel>民族</FormLabel>
-                        <FormControl>
-                          <Input placeholder="请输入民族" {...field} />
-                        </FormControl>
-                        <FormMessage />
-                      </FormItem>
-                    )}
-                  />
-
-                  <FormField
-                    control={updateForm.control}
-                    name="isMarried"
-                    render={({ field }) => (
-                      <FormItem>
-                        <FormLabel>婚姻状况</FormLabel>
-                        <FormControl>
-                          <select
-                            className="flex h-10 w-full rounded-md border border-input bg-background px-3 py-2 text-sm ring-offset-background file:border-0 file:bg-transparent file:text-sm file:font-medium placeholder:text-muted-foreground focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-ring focus-visible:ring-offset-2 disabled:cursor-not-allowed disabled:opacity-50"
-                            {...field}
-                            value={field.value?.toString()}
-                            onChange={(e) => field.onChange(Number(e.target.value))}
-                          >
-                            <option value="0">未婚</option>
-                            <option value="1">已婚</option>
-                          </select>
-                        </FormControl>
-                        <FormMessage />
-                      </FormItem>
-                    )}
-                  />
                 </div>
-
-                <DialogFooter>
-                  <Button type="button" variant="outline" onClick={() => setIsModalOpen(false)}>
-                    取消
-                  </Button>
-                  <Button type="submit" disabled={updateMutation.isPending}>
-                    {updateMutation.isPending ? '更新中...' : '更新'}
-                  </Button>
-                </DialogFooter>
               </form>
             </Form>
           )}
+          </div>
+          <DialogFooter className="mt-4">
+            <Button type="button" variant="outline" onClick={() => setIsModalOpen(false)}>
+              取消
+            </Button>
+            {isCreateForm ? (
+              <Button type="submit" form="create-form" disabled={createMutation.isPending}>
+                {createMutation.isPending ? '创建中...' : '创建'}
+              </Button>
+            ) : (
+              <Button type="submit" form="update-form" disabled={updateMutation.isPending}>
+                {updateMutation.isPending ? '更新中...' : '更新'}
+              </Button>
+            )}
+          </DialogFooter>
         </DialogContent>
       </Dialog>
 
@@ -832,7 +847,7 @@ const DisabilityPersonManagement: React.FC = () => {
                   <label className="text-sm font-medium">身份证地址</label>
                   <p className="text-sm text-muted-foreground">{viewData.idAddress}</p>
                 </div>
-                <div className="col-span-2">
+                <div className="col-span-1 md:col-span-2">
                   <label className="text-sm font-medium">居住地址</label>
                   <p className="text-sm text-muted-foreground">
                     {viewData.province} {viewData.city} {viewData.district} {viewData.detailedAddress}

+ 0 - 0
allin-packages/disability-management-ui/src/components/DisabledPersonSelector.tsx → allin-packages/disability-person-management-ui/src/components/DisabledPersonSelector.tsx


+ 2 - 1
allin-packages/disability-person-management-ui/src/components/index.ts

@@ -1 +1,2 @@
-export { default as DisabilityPersonManagement } from './DisabilityPersonManagement';
+export { default as DisabilityPersonManagement } from './DisabilityPersonManagement';
+export { default as DisabledPersonSelector } from './DisabledPersonSelector';

+ 22 - 0
allin-packages/disability-person-management-ui/tests/integration/disability-person.integration.test.tsx

@@ -604,4 +604,26 @@ describe('残疾人个人管理集成测试', () => {
       expect(disabilityLevelSelect).toBeInTheDocument();
     }
   });
+
+  it('应该显示暂无数据提示', async () => {
+    // 修改mock返回空数据
+    const mockClient = (disabilityClientManager.get as any)();
+    mockClient.getAllDisabledPersons.$get.mockResolvedValueOnce(
+      createMockResponse(200, {
+        data: [],
+        total: 0
+      })
+    );
+
+    renderComponent();
+
+    // 等待暂无数据提示出现
+    await waitFor(() => {
+      expect(screen.getByText('暂无数据')).toBeInTheDocument();
+    });
+
+    // 验证暂无数据提示的样式
+    const noDataElement = screen.getByText('暂无数据');
+    expect(noDataElement).toHaveClass('text-muted-foreground');
+  });
 });

+ 1 - 1
allin-packages/order-management-ui/package.json

@@ -38,7 +38,7 @@
     "@d8d/shared-types": "workspace:*",
     "@d8d/shared-ui-components": "workspace:*",
     "@d8d/allin-order-module": "workspace:*",
-    "@d8d/allin-disability-management-ui": "workspace:*",
+    "@d8d/allin-disability-person-management-ui": "workspace:*",
     "@d8d/area-management-ui": "workspace:*",
     "@d8d/file-management-ui": "workspace:*",
     "@d8d/allin-enums": "workspace:*",

+ 4 - 4
allin-packages/order-management-ui/src/components/PersonSelector.tsx

@@ -24,10 +24,10 @@ import { zodResolver } from '@hookform/resolvers/zod';
 import { z } from 'zod';
 import { toast } from 'sonner';
 import { User, Users, X } from 'lucide-react';
-import { DisabledPersonSelector } from '@d8d/allin-disability-management-ui';
+import { DisabledPersonSelector } from '@d8d/allin-disability-person-management-ui';
 import { WorkStatus } from '@d8d/allin-enums';
 import { orderClient } from '../api/orderClient';
-import type { DisabledPersonData } from '@d8d/allin-disability-management-ui';
+import type { DisabledPersonData } from '@d8d/allin-disability-person-management-ui';
 
 // 批量添加人员表单Schema
 // 根据后端API,需要包含joinDate、salaryDetail等字段
@@ -125,7 +125,7 @@ export const PersonSelector: React.FC<PersonSelectorProps> = ({
         joinDate: new Date().toISOString(), // 默认当前时间
         salaryDetail: '待定', // 默认值
         leaveDate: undefined,
-        workStatus: '在职',
+        workStatus: WorkStatus.WORKING,
         role: '',
         remark: ''
       }));
@@ -145,7 +145,7 @@ export const PersonSelector: React.FC<PersonSelectorProps> = ({
             joinDate: new Date().toISOString(), // 默认当前时间
             salaryDetail: '待定', // 默认值
             leaveDate: undefined,
-            workStatus: '在职',
+            workStatus: WorkStatus.WORKING,
             role: '',
             remark: ''
           }

+ 1 - 1
allin-packages/order-management-ui/tests/integration/order.integration.test.tsx

@@ -64,7 +64,7 @@ vi.mock('@d8d/file-management-ui', () => ({
 }));
 
 // Mock 残疾人选择器组件
-vi.mock('@d8d/allin-disability-management-ui', () => ({
+vi.mock('@d8d/allin-disability-person-management-ui', () => ({
   DisabledPersonSelector: vi.fn(({ open, onOpenChange, onSelect, mode, disabledIds }) => {
     if (!open) return null;
 

+ 0 - 800
allin-packages/order-management-ui/tests/integration/order.integration.test.tsx.backup

@@ -1,800 +0,0 @@
-import { describe, it, expect, vi, beforeEach } from 'vitest';
-import { render, screen, fireEvent, waitFor } from '@testing-library/react';
-import userEvent from '@testing-library/user-event';
-import { QueryClient, QueryClientProvider } from '@tanstack/react-query';
-import OrderManagement from '../../src/components/OrderManagement';
-import { orderClientManager } from '../../src/api/orderClient';
-import { OrderStatus, WorkStatus } from '@d8d/allin-enums';
-
-// Mock 区域选择器组件
-vi.mock('@d8d/area-management-ui', () => ({
-  AreaSelect: vi.fn(({ value, onChange }) => {
-    return (
-      <div data-testid="area-select-mock">
-        <select
-          data-testid="area-select-province"
-          value={value?.provinceId || ''}
-          onChange={(e) => onChange && onChange({ provinceId: e.target.value ? parseInt(e.target.value) : undefined, cityId: undefined, districtId: undefined })}
-        >
-          <option value="">选择省份</option>
-          <option value="1">省份1</option>
-          <option value="2">省份2</option>
-        </select>
-        <select
-          data-testid="area-select-city"
-          value={value?.cityId || ''}
-          onChange={(e) => onChange && onChange({ ...value, cityId: e.target.value ? parseInt(e.target.value) : undefined, districtId: undefined })}
-        >
-          <option value="">选择城市</option>
-          <option value="3">城市1</option>
-          <option value="4">城市2</option>
-        </select>
-        <select
-          data-testid="area-select-district"
-          value={value?.districtId || ''}
-          onChange={(e) => onChange && onChange({ ...value, districtId: e.target.value ? parseInt(e.target.value) : undefined })}
-        >
-          <option value="">选择区县</option>
-          <option value="5">区县1</option>
-          <option value="6">区县2</option>
-        </select>
-      </div>
-    );
-  })
-}));
-
-// Mock 文件选择器组件
-vi.mock('@d8d/file-management-ui', () => ({
-  FileSelector: vi.fn(({ value, onChange }) => {
-    return (
-      <div data-testid="file-selector-mock">
-        <input
-          type="file"
-          data-testid="file-input"
-          onChange={(e) => {
-            if (onChange && e.target.files?.[0]) {
-              onChange('mock-file-id-123');
-            }
-          }}
-        />
-        {value && <div data-testid="selected-file">已选择文件: {value}</div>}
-      </div>
-    );
-  })
-}));
-
-// Mock 残疾人选择器组件
-vi.mock('@d8d/allin-disability-management-ui', () => ({
-  DisabledPersonSelector: vi.fn(({ open, onOpenChange, onSelect, mode, disabledIds }) => {
-    if (!open) return null;
-
-    return (
-      <div data-testid="disabled-person-selector-mock">
-        <div>残疾人选择器模拟</div>
-        <button
-          data-testid="select-person-button"
-          onClick={() => {
-            const mockPerson = {
-              id: 1,
-              name: '测试残疾人',
-              gender: '男',
-              disabilityId: 'D123456',
-              disabilityType: '肢体残疾',
-              disabilityLevel: '三级',
-              phone: '13800138000'
-            };
-            onSelect(mode === 'multiple' ? [mockPerson] : mockPerson);
-            onOpenChange(false);
-          }}
-        >
-          选择测试人员
-        </button>
-        <button
-          data-testid="close-selector-button"
-          onClick={() => onOpenChange(false)}
-        >
-          关闭
-        </button>
-      </div>
-    );
-  })
-}));
-
-// 完整的mock响应对象
-const createMockResponse = (status: number, data?: any) => ({
-  status,
-  ok: status >= 200 && status < 300,
-  body: null,
-  bodyUsed: false,
-  statusText: status === 200 ? 'OK' : status === 201 ? 'Created' : status === 204 ? 'No Content' : 'Error',
-  headers: new Headers(),
-  url: '',
-  redirected: false,
-  type: 'basic' as ResponseType,
-  json: async () => data || {},
-  text: async () => '',
-  blob: async () => new Blob(),
-  arrayBuffer: async () => new ArrayBuffer(0),
-  formData: async () => new FormData(),
-  clone: function() { return this; }
-});
-
-// Mock API client
-let mockOrderClient: any;
-vi.mock('../../src/api/orderClient', async (importOriginal) => {
-  const actual = await importOriginal() as any;
-
-  return {
-    ...actual,
-    orderClient: mockOrderClient,
-    orderClientManager: {
-      getInstance: vi.fn(() => ({
-        get: vi.fn(() => mockOrderClient),
-        reset: vi.fn(),
-      })),
-    },
-  };
-});
-
-// Mock toast
-vi.mock('sonner', () => ({
-  toast: {
-    success: vi.fn(),
-    error: vi.fn(),
-  },
-}));
-
-describe('订单管理集成测试', () => {
-  let queryClient: QueryClient;
-
-  beforeEach(() => {
-    queryClient = new QueryClient({
-      defaultOptions: {
-        queries: {
-          retry: false,
-        },
-      },
-    });
-    vi.clearAllMocks();
-
-    // 重新创建mockOrderClient
-    mockOrderClient = {
-      list: {
-        $get: vi.fn(() => Promise.resolve(createMockResponse(200, {
-          data: [
-            {
-              id: 1,
-              orderName: '测试订单1',
-              platformId: 1,
-              companyId: 1,
-              channelId: 1,
-              expectedStartDate: '2024-01-01T00:00:00Z',
-              expectedEndDate: '2024-12-31T00:00:00Z',
-              orderStatus: OrderStatus.DRAFT,
-              workStatus: WorkStatus.NOT_WORKING,
-              provinceId: 1,
-              cityId: 2,
-              districtId: 3,
-              address: '测试地址',
-              contactPerson: '张三',
-              contactPhone: '13800138001',
-              remark: '测试备注',
-              createTime: '2024-01-01T00:00:00Z',
-              updateTime: '2024-01-01T00:00:00Z'
-            },
-            {
-              id: 2,
-              orderName: '测试订单2',
-              platformId: 2,
-              companyId: 2,
-              channelId: 2,
-              expectedStartDate: '2024-02-01T00:00:00Z',
-              expectedEndDate: '2024-12-31T00:00:00Z',
-              orderStatus: OrderStatus.CONFIRMED,
-              workStatus: WorkStatus.PRE_WORKING,
-              provinceId: 4,
-              cityId: 5,
-              districtId: 6,
-              address: '测试地址2',
-              contactPerson: '李四',
-              contactPhone: '13800138002',
-              remark: '测试备注2',
-              createTime: '2024-02-01T00:00:00Z',
-              updateTime: '2024-02-01T00:00:00Z'
-            }
-          ],
-          total: 2
-        }))),
-      },
-      create: {
-        $post: vi.fn(() => Promise.resolve(createMockResponse(200, {
-          id: 3,
-          orderName: '新订单',
-          platformId: 3,
-          companyId: 3,
-          channelId: 3,
-          expectedStartDate: '2024-03-01T00:00:00Z',
-          expectedEndDate: '2024-12-31T00:00:00Z',
-          orderStatus: OrderStatus.DRAFT,
-          workStatus: WorkStatus.NOT_WORKING,
-          provinceId: 7,
-          cityId: 8,
-          districtId: 9,
-          address: '新地址',
-          contactPerson: '王五',
-          contactPhone: '13800138003',
-          remark: '新备注',
-          createTime: '2024-03-01T00:00:00Z',
-          updateTime: '2024-03-01T00:00:00Z'
-        }))),
-      },
-      update: {
-        ':id': {
-          $put: vi.fn(() => Promise.resolve(createMockResponse(200, {
-            id: 1,
-            orderName: '更新后的订单',
-            platformId: 1,
-            companyId: 1,
-            channelId: 1,
-            expectedStartDate: '2024-01-01T00:00:00Z',
-            expectedEndDate: '2024-12-31T00:00:00Z',
-            orderStatus: OrderStatus.CONFIRMED,
-            workStatus: WorkStatus.PRE_WORKING,
-            provinceId: 1,
-            cityId: 2,
-            districtId: 3,
-            address: '更新后的地址',
-            contactPerson: '张三',
-            contactPhone: '13800138001',
-            remark: '更新后的备注',
-            createTime: '2024-01-01T00:00:00Z',
-            updateTime: '2024-03-01T00:00:00Z'
-          }))),
-        },
-      },
-      delete: {
-        ':id': {
-          $delete: vi.fn(() => Promise.resolve(createMockResponse(200, { success: true }))),
-        },
-      },
-      detail: {
-        ':id': {
-          $get: vi.fn(() => Promise.resolve(createMockResponse(200, {
-            id: 1,
-            orderName: '测试订单1',
-            platformId: 1,
-            companyId: 1,
-            channelId: 1,
-            expectedStartDate: '2024-01-01T00:00:00Z',
-            expectedEndDate: '2024-12-31T00:00:00Z',
-            orderStatus: OrderStatus.DRAFT,
-            workStatus: WorkStatus.NOT_WORKING,
-            provinceId: 1,
-            cityId: 2,
-            districtId: 3,
-            address: '测试地址',
-            contactPerson: '张三',
-            contactPhone: '13800138001',
-            remark: '测试备注',
-            createTime: '2024-01-01T00:00:00Z',
-            updateTime: '2024-01-01T00:00:00Z'
-          }))),
-        },
-      },
-      activate: {
-        ':orderId': {
-          $post: vi.fn(() => Promise.resolve(createMockResponse(200, { success: true }))),
-        },
-      },
-      close: {
-        ':orderId': {
-          $post: vi.fn(() => Promise.resolve(createMockResponse(200, { success: true }))),
-        },
-      },
-      ':orderId': {
-        persons: {
-          batch: {
-            $post: vi.fn(() => Promise.resolve(createMockResponse(200, {
-              success: true,
-              message: '批量添加人员成功',
-              addedCount: 2
-            }))),
-          },
-        },
-      },
-      assets: {
-        create: {
-          $post: vi.fn(() => Promise.resolve(createMockResponse(200, {
-            id: 1,
-            orderId: 1,
-            personId: 1,
-            assetType: 'ID_CARD',
-            assetFileType: 'IMAGE',
-            fileId: 1,
-            relatedTime: '2024-01-01T00:00:00Z',
-            createTime: '2024-01-01T00:00:00Z',
-            updateTime: '2024-01-01T00:00:00Z'
-          }))),
-        },
-        query: {
-          $get: vi.fn(() => Promise.resolve(createMockResponse(200, {
-            data: [],
-            total: 0
-          }))),
-        },
-        delete: {
-          ':id': {
-            $delete: vi.fn(() => Promise.resolve(createMockResponse(200, {
-              success: true,
-              message: '删除成功'
-            }))),
-          },
-        },
-      },
-    };
-  });
-
-  const renderOrderManagement = () => {
-    return render(
-      <QueryClientProvider client={queryClient}>
-        <OrderManagement />
-      </QueryClientProvider>
-    );
-  };
-
-  describe('CRUD流程测试', () => {
-    it('应该成功加载订单列表', async () => {
-      renderOrderManagement();
-
-      // 等待数据加载
-      await waitFor(() => {
-        expect(screen.getByText('测试订单1')).toBeInTheDocument();
-        expect(screen.getByText('测试订单2')).toBeInTheDocument();
-      });
-
-      // 验证表格渲染
-      expect(screen.getByTestId('order-row-1')).toBeInTheDocument();
-      expect(screen.getByTestId('order-row-2')).toBeInTheDocument();
-
-      // 验证状态徽章
-      expect(screen.getByText('草稿')).toBeInTheDocument();
-      expect(screen.getByText('已确认')).toBeInTheDocument();
-      expect(screen.getByText('未就业')).toBeInTheDocument();
-      expect(screen.getByText('待就业')).toBeInTheDocument();
-    });
-
-    it('应该成功创建订单', async () => {
-      renderOrderManagement();
-
-      // 点击创建订单按钮
-      const createButton = screen.getByTestId('create-order-button');
-      fireEvent.click(createButton);
-
-      // 验证订单表单模态框打开
-      await waitFor(() => {
-        expect(screen.getByTestId('create-order-dialog-title')).toBeInTheDocument();
-      });
-
-      // 这里可以添加表单填写和提交的测试
-      // 由于表单组件比较复杂,这里只验证模态框能正常打开
-    });
-
-    it('应该成功编辑订单', async () => {
-      renderOrderManagement();
-
-      // 等待数据加载
-      await waitFor(() => {
-        expect(screen.getByTestId('order-row-1')).toBeInTheDocument();
-      });
-
-      // 调试:打印所有test ID
-      const allElements = screen.getAllByTestId(/.*/);
-      console.debug('所有test ID:', allElements.map(el => el.getAttribute('data-testid')));
-
-      // 先点击下拉菜单触发器,然后点击编辑按钮
-      const menuTrigger = screen.getByTestId('order-menu-trigger-1');
-      expect(menuTrigger).toBeInTheDocument();
-
-      // 使用userEvent.click代替fireEvent.click,更好地模拟用户交互
-      await userEvent.click(menuTrigger);
-
-      // 等待下拉菜单打开,然后点击编辑按钮
-      await waitFor(() => {
-        // 检查下拉菜单内容是否渲染 - 使用更精确的选择器
-        // 下拉菜单中的"操作"是DropdownMenuLabel,而表格中的"操作"是表头
-        // 我们可以检查下拉菜单中的特定元素
-        const editButton = screen.getByTestId('edit-order-button-1');
-        expect(editButton).toBeInTheDocument();
-      });
-
-      const editButton = screen.getByTestId('edit-order-button-1');
-      await userEvent.click(editButton);
-
-      // 验证编辑表单模态框打开
-      await waitFor(() => {
-        expect(screen.getByText('编辑订单')).toBeInTheDocument();
-      });
-    });
-
-    it('应该成功删除订单', async () => {
-      renderOrderManagement();
-
-      // 等待数据加载
-      await waitFor(() => {
-        expect(screen.getByTestId('order-row-1')).toBeInTheDocument();
-      });
-
-      // 先点击下拉菜单触发器,然后点击删除按钮
-      const menuTrigger = screen.getByTestId('order-menu-trigger-1');
-      expect(menuTrigger).toBeInTheDocument();
-      await userEvent.click(menuTrigger);
-
-      // 等待下拉菜单打开,然后点击删除按钮
-      await waitFor(() => {
-        const deleteButton = screen.getByTestId('delete-order-button-1');
-        expect(deleteButton).toBeInTheDocument();
-      });
-
-      const deleteButton = screen.getByTestId('delete-order-button-1');
-      await userEvent.click(deleteButton);
-
-      // 验证删除确认对话框显示
-      await waitFor(() => {
-        expect(screen.getByTestId('delete-confirm-dialog')).toBeInTheDocument();
-        expect(screen.getByTestId('delete-confirm-dialog-title')).toHaveTextContent('删除订单');
-        expect(screen.getByTestId('delete-confirm-dialog-description')).toHaveTextContent('确定要删除这个订单吗?此操作不可撤销。');
-      });
-
-      // 点击确认按钮
-      const confirmButton = screen.getByTestId('delete-confirm-dialog-confirm');
-      await userEvent.click(confirmButton);
-
-      // 验证API调用
-      await waitFor(() => {
-        expect(mockOrderClient.delete[':id'].$delete).toHaveBeenCalledWith({
-          param: { id: 1 },
-        });
-      });
-    });
-
-    it('应该成功激活订单', async () => {
-      renderOrderManagement();
-
-      // 等待数据加载
-      await waitFor(() => {
-        expect(screen.getByTestId('order-row-1')).toBeInTheDocument();
-      });
-
-      // 先打开下拉菜单,然后点击激活按钮(只有草稿状态的订单才有激活按钮)
-      const menuTrigger = screen.getByTestId('order-menu-trigger-1');
-      expect(menuTrigger).toBeInTheDocument();
-      await userEvent.click(menuTrigger);
-
-      // 等待下拉菜单打开,然后点击激活按钮
-      await waitFor(() => {
-        const activateButton = screen.getByTestId('activate-order-button-1');
-        expect(activateButton).toBeInTheDocument();
-      });
-
-      const activateButton = screen.getByTestId('activate-order-button-1');
-      await userEvent.click(activateButton);
-
-      // 验证激活确认对话框显示
-      await waitFor(() => {
-        expect(screen.getByTestId('activate-confirm-dialog')).toBeInTheDocument();
-        expect(screen.getByTestId('activate-confirm-dialog-title')).toHaveTextContent('激活订单');
-        expect(screen.getByTestId('activate-confirm-dialog-description')).toHaveTextContent('确定要激活这个订单吗?订单激活后将进入进行中状态。');
-      });
-
-      // 点击确认按钮
-      const confirmButton = screen.getByTestId('activate-confirm-dialog-confirm');
-      await userEvent.click(confirmButton);
-
-      // 验证API调用
-      await waitFor(() => {
-        expect(mockOrderClient.activate[':orderId'].$post).toHaveBeenCalledWith({
-          param: { orderId: 1 },
-        });
-      });
-    });
-
-    it('应该成功关闭订单', async () => {
-      renderOrderManagement();
-
-      // 等待数据加载
-      await waitFor(() => {
-        expect(screen.getByTestId('order-row-2')).toBeInTheDocument();
-      });
-
-      // 先打开下拉菜单,然后点击关闭按钮(只有已确认或进行中的订单有关闭按钮)
-      const menuTrigger = screen.getByTestId('order-menu-trigger-2');
-      expect(menuTrigger).toBeInTheDocument();
-      await userEvent.click(menuTrigger);
-
-      // 等待下拉菜单打开,然后点击关闭按钮
-      await waitFor(() => {
-        const closeButton = screen.getByTestId('close-order-button-2');
-        expect(closeButton).toBeInTheDocument();
-      });
-
-      const closeButton = screen.getByTestId('close-order-button-2');
-      await userEvent.click(closeButton);
-
-      // 验证关闭确认对话框显示
-      await waitFor(() => {
-        expect(screen.getByTestId('close-confirm-dialog')).toBeInTheDocument();
-        expect(screen.getByTestId('close-confirm-dialog-title')).toHaveTextContent('关闭订单');
-        expect(screen.getByTestId('close-confirm-dialog-description')).toHaveTextContent('确定要关闭这个订单吗?订单关闭后将无法再添加人员或资产。');
-      });
-
-      // 点击确认按钮
-      const confirmButton = screen.getByTestId('close-confirm-dialog-confirm');
-      await userEvent.click(confirmButton);
-
-      // 验证API调用
-      await waitFor(() => {
-        expect(mockOrderClient.close[':orderId'].$post).toHaveBeenCalledWith({
-          param: { orderId: 2 },
-        });
-      });
-    });
-
-    it('应该可以取消删除操作', async () => {
-      renderOrderManagement();
-
-      // 等待数据加载
-      await waitFor(() => {
-        expect(screen.getByTestId('order-row-1')).toBeInTheDocument();
-      });
-
-      // 先点击下拉菜单触发器,然后点击删除按钮
-      const menuTrigger = screen.getByTestId('order-menu-trigger-1');
-      expect(menuTrigger).toBeInTheDocument();
-      await userEvent.click(menuTrigger);
-
-      // 等待下拉菜单打开,然后点击删除按钮
-      await waitFor(() => {
-        const deleteButton = screen.getByTestId('delete-order-button-1');
-        expect(deleteButton).toBeInTheDocument();
-      });
-
-      const deleteButton = screen.getByTestId('delete-order-button-1');
-      await userEvent.click(deleteButton);
-
-      // 验证删除确认对话框显示
-      await waitFor(() => {
-        expect(screen.getByTestId('delete-confirm-dialog')).toBeInTheDocument();
-      });
-
-      // 点击取消按钮
-      const cancelButton = screen.getByTestId('delete-confirm-dialog-cancel');
-      await userEvent.click(cancelButton);
-
-      // 验证对话框关闭
-      await waitFor(() => {
-        expect(screen.queryByTestId('delete-confirm-dialog')).not.toBeInTheDocument();
-      });
-
-      // 验证API没有被调用
-      expect(mockOrderClient.delete[':id'].$delete).not.toHaveBeenCalled();
-    });
-  });
-
-  describe('文件上传集成测试', () => {
-    it('应该成功打开资产关联模态框', async () => {
-      renderOrderManagement();
-
-      // 等待数据加载
-      await waitFor(() => {
-        expect(screen.getByTestId('order-row-1')).toBeInTheDocument();
-      });
-
-      // 点击添加资产按钮
-      const addAssetButton = screen.getByTestId('add-asset-button-1');
-      fireEvent.click(addAssetButton);
-
-      // 验证资产关联模态框打开
-      await waitFor(() => {
-        expect(screen.getByText('添加资产关联')).toBeInTheDocument();
-      });
-
-      // 验证文件选择器组件存在
-      expect(screen.getByTestId('file-selector')).toBeInTheDocument();
-    });
-  });
-
-  describe('区域选择器集成测试', () => {
-    it('应该成功打开订单表单并显示区域选择器', async () => {
-      renderOrderManagement();
-
-      // 点击创建订单按钮
-      const createButton = screen.getByTestId('create-order-button');
-      fireEvent.click(createButton);
-
-      // 验证订单表单模态框打开
-      await waitFor(() => {
-        expect(screen.getByTestId('create-order-dialog-title')).toBeInTheDocument();
-      });
-
-      // 验证区域选择器组件存在
-      expect(screen.getByTestId('area-select')).toBeInTheDocument();
-    });
-  });
-
-  describe('枚举常量集成测试', () => {
-    it('应该正确显示订单状态枚举', async () => {
-      renderOrderManagement();
-
-      // 等待数据加载 - 验证表格中的订单状态Badge
-      await waitFor(() => {
-        // 使用更精确的选择器,避免与Select选项冲突
-        const orderRow = screen.getByTestId('order-row-1');
-        expect(orderRow).toBeInTheDocument();
-        // 验证表格中有订单状态显示
-        expect(screen.getByText('测试订单1')).toBeInTheDocument();
-      });
-
-      // 验证订单状态筛选器
-      const statusFilter = screen.getByTestId('filter-order-status-select');
-      expect(statusFilter).toBeInTheDocument();
-
-      // 点击筛选器查看选项
-      fireEvent.click(statusFilter);
-
-      // 验证枚举选项存在
-      await waitFor(() => {
-        // 使用test ID验证枚举选项
-        expect(screen.getByTestId('order-status-option-all')).toBeInTheDocument();
-        expect(screen.getByTestId('order-status-option-draft')).toBeInTheDocument();
-        expect(screen.getByTestId('order-status-option-confirmed')).toBeInTheDocument();
-        expect(screen.getByTestId('order-status-option-in-progress')).toBeInTheDocument();
-        expect(screen.getByTestId('order-status-option-completed')).toBeInTheDocument();
-        expect(screen.getByTestId('order-status-option-cancelled')).toBeInTheDocument();
-      });
-    });
-
-    it('应该正确显示工作状态枚举', async () => {
-      renderOrderManagement();
-
-      // 等待数据加载 - 验证表格中的工作状态Badge
-      await waitFor(() => {
-        // 使用更精确的选择器,避免与Select选项冲突
-        const orderRow = screen.getByTestId('order-row-1');
-        expect(orderRow).toBeInTheDocument();
-        // 验证表格中有工作状态显示
-        expect(screen.getByText('测试订单1')).toBeInTheDocument();
-      });
-
-      // 验证工作状态筛选器
-      const workStatusFilter = screen.getByTestId('filter-work-status-select');
-      expect(workStatusFilter).toBeInTheDocument();
-
-      // 点击筛选器查看选项
-      fireEvent.click(workStatusFilter);
-
-      // 验证枚举选项存在
-      await waitFor(() => {
-        // 使用test ID验证枚举选项
-        expect(screen.getByTestId('work-status-option-all')).toBeInTheDocument();
-        expect(screen.getByTestId('work-status-option-not-working')).toBeInTheDocument();
-        expect(screen.getByTestId('work-status-option-pre-working')).toBeInTheDocument();
-        expect(screen.getByTestId('work-status-option-working')).toBeInTheDocument();
-        expect(screen.getByTestId('work-status-option-resigned')).toBeInTheDocument();
-      });
-    });
-  });
-
-  describe('人员管理测试', () => {
-    it('应该成功打开人员选择器', async () => {
-      renderOrderManagement();
-
-      // 等待数据加载
-      await waitFor(() => {
-        expect(screen.getByTestId('order-row-1')).toBeInTheDocument();
-      });
-
-      // 点击添加人员按钮
-      const addPersonsButton = screen.getByTestId('add-persons-button-1');
-      fireEvent.click(addPersonsButton);
-
-      // 验证人员选择器模态框打开
-      await waitFor(() => {
-        expect(screen.getByText('批量添加人员到订单')).toBeInTheDocument();
-      });
-    });
-  });
-
-  describe('搜索和筛选测试', () => {
-    it('应该支持按订单名称搜索', async () => {
-      renderOrderManagement();
-
-      // 等待数据加载
-      await waitFor(() => {
-        expect(screen.getByTestId('search-order-name-input')).toBeInTheDocument();
-      });
-
-      // 输入搜索关键词
-      const searchInput = screen.getByTestId('search-order-name-input');
-      fireEvent.change(searchInput, { target: { value: '测试订单1' } });
-
-      // 点击搜索按钮
-      const searchButton = screen.getByTestId('search-button');
-      fireEvent.click(searchButton);
-
-      // 验证API调用
-      // 实际测试中应该验证API调用参数
-    });
-
-    it('应该支持按订单状态筛选', async () => {
-      renderOrderManagement();
-
-      // 等待数据加载
-      await waitFor(() => {
-        expect(screen.getByTestId('filter-order-status-select')).toBeInTheDocument();
-      });
-
-      // 选择订单状态
-      const statusFilter = screen.getByTestId('filter-order-status-select');
-      fireEvent.click(statusFilter);
-
-      // 选择"草稿"状态
-      await waitFor(() => {
-        const draftOption = screen.getByText('草稿');
-        fireEvent.click(draftOption);
-      });
-
-      // 点击搜索按钮
-      const searchButton = screen.getByTestId('search-button');
-      fireEvent.click(searchButton);
-
-      // 验证API调用
-      // 实际测试中应该验证API调用参数
-    });
-
-    it('应该支持按工作状态筛选', async () => {
-      renderOrderManagement();
-
-      // 等待数据加载
-      await waitFor(() => {
-        expect(screen.getByTestId('filter-work-status-select')).toBeInTheDocument();
-      });
-
-      // 选择工作状态
-      const workStatusFilter = screen.getByTestId('filter-work-status-select');
-      fireEvent.click(workStatusFilter);
-
-      // 选择"未就业"状态
-      await waitFor(() => {
-        const notWorkingOption = screen.getByText('未就业');
-        fireEvent.click(notWorkingOption);
-      });
-
-      // 点击搜索按钮
-      const searchButton = screen.getByTestId('search-button');
-      fireEvent.click(searchButton);
-
-      // 验证API调用
-      // 实际测试中应该验证API调用参数
-    });
-  });
-
-  describe('错误处理测试', () => {
-    it('应该处理API错误', async () => {
-      // Mock API错误
-      const mockOrderClient = orderClientManager.getInstance().get();
-      mockOrderClient.list.$get.mockImplementationOnce(() =>
-        Promise.resolve(createMockResponse(500, {
-          code: 500,
-          message: '服务器错误'
-        }))
-      );
-
-      renderOrderManagement();
-
-      // 验证错误处理
-      await waitFor(() => {
-        expect(screen.getByText(/加载失败/)).toBeInTheDocument();
-      });
-    });
-  });
-});

+ 6 - 1
allin-packages/salary-module/src/routes/salary-custom.routes.ts

@@ -383,7 +383,12 @@ const app = new OpenAPIHono<AuthContext>()
         districtId
       );
 
-      return c.json(result, 200);
+      // 使用parseWithAwait验证每个薪资记录
+      const validatedData = await Promise.all(
+        result.data.map(item => parseWithAwait(SalaryLevelSchema, item))
+      );
+
+      return c.json({ data: validatedData, total: result.total }, 200);
     } catch (error) {
       return c.json({
         code: 500,

+ 2 - 99
pnpm-lock.yaml

@@ -310,100 +310,6 @@ importers:
         specifier: ^3.2.4
         version: 3.2.4(@types/debug@4.1.12)(@types/node@22.19.1)(happy-dom@18.0.1)(jiti@2.6.1)(jsdom@26.1.0)(lightningcss@1.30.2)(sass@1.93.2)(stylus@0.64.0)(terser@5.44.0)(tsx@4.20.6)(yaml@2.8.1)
 
-  allin-packages/disability-management-ui:
-    dependencies:
-      '@d8d/allin-disability-module':
-        specifier: workspace:*
-        version: link:../disability-module
-      '@d8d/area-management-ui':
-        specifier: workspace:*
-        version: link:../../packages/area-management-ui
-      '@d8d/shared-types':
-        specifier: workspace:*
-        version: link:../../packages/shared-types
-      '@d8d/shared-ui-components':
-        specifier: workspace:*
-        version: link:../../packages/shared-ui-components
-      '@hookform/resolvers':
-        specifier: ^5.2.1
-        version: 5.2.2(react-hook-form@7.65.0(react@19.2.0))
-      '@tanstack/react-query':
-        specifier: ^5.90.9
-        version: 5.90.11(react@19.2.0)
-      class-variance-authority:
-        specifier: ^0.7.1
-        version: 0.7.1
-      clsx:
-        specifier: ^2.1.1
-        version: 2.1.1
-      date-fns:
-        specifier: ^4.1.0
-        version: 4.1.0
-      hono:
-        specifier: ^4.8.5
-        version: 4.8.5
-      lucide-react:
-        specifier: ^0.536.0
-        version: 0.536.0(react@19.2.0)
-      react:
-        specifier: ^19.1.0
-        version: 19.2.0
-      react-dom:
-        specifier: ^19.1.0
-        version: 19.2.0(react@19.2.0)
-      react-hook-form:
-        specifier: ^7.61.1
-        version: 7.65.0(react@19.2.0)
-      sonner:
-        specifier: ^2.0.7
-        version: 2.0.7(react-dom@19.2.0(react@19.2.0))(react@19.2.0)
-      tailwind-merge:
-        specifier: ^3.3.1
-        version: 3.3.1
-      zod:
-        specifier: ^4.0.15
-        version: 4.1.12
-    devDependencies:
-      '@testing-library/jest-dom':
-        specifier: ^6.8.0
-        version: 6.9.1
-      '@testing-library/react':
-        specifier: ^16.3.0
-        version: 16.3.0(@testing-library/dom@10.4.1)(@types/react-dom@19.2.3(@types/react@19.2.2))(@types/react@19.2.2)(react-dom@19.2.0(react@19.2.0))(react@19.2.0)
-      '@testing-library/user-event':
-        specifier: ^14.6.1
-        version: 14.6.1(@testing-library/dom@10.4.1)
-      '@types/node':
-        specifier: ^22.10.2
-        version: 22.19.1
-      '@types/react':
-        specifier: ^19.2.2
-        version: 19.2.2
-      '@types/react-dom':
-        specifier: ^19.2.3
-        version: 19.2.3(@types/react@19.2.2)
-      '@typescript-eslint/eslint-plugin':
-        specifier: ^8.18.1
-        version: 8.46.2(@typescript-eslint/parser@8.46.2(eslint@9.38.0(jiti@2.6.1))(typescript@5.8.3))(eslint@9.38.0(jiti@2.6.1))(typescript@5.8.3)
-      '@typescript-eslint/parser':
-        specifier: ^8.18.1
-        version: 8.46.2(eslint@9.38.0(jiti@2.6.1))(typescript@5.8.3)
-      eslint:
-        specifier: ^9.17.0
-        version: 9.38.0(jiti@2.6.1)
-      jsdom:
-        specifier: ^26.0.0
-        version: 26.1.0
-      typescript:
-        specifier: ^5.8.3
-        version: 5.8.3
-      unbuild:
-        specifier: ^3.4.0
-        version: 3.6.1(sass@1.93.2)(typescript@5.8.3)(vue@3.5.22(typescript@5.8.3))
-      vitest:
-        specifier: ^4.0.9
-        version: 4.0.14(@types/node@22.19.1)(happy-dom@18.0.1)(jiti@2.6.1)(jsdom@26.1.0)(lightningcss@1.30.2)(sass@1.93.2)(stylus@0.64.0)(terser@5.44.0)(tsx@4.20.6)(yaml@2.8.1)
-
   allin-packages/disability-module:
     dependencies:
       '@d8d/auth-module':
@@ -576,9 +482,9 @@ importers:
 
   allin-packages/order-management-ui:
     dependencies:
-      '@d8d/allin-disability-management-ui':
+      '@d8d/allin-disability-person-management-ui':
         specifier: workspace:*
-        version: link:../disability-management-ui
+        version: link:../disability-person-management-ui
       '@d8d/allin-enums':
         specifier: workspace:*
         version: link:../enums
@@ -5499,9 +5405,6 @@ importers:
       '@d8d/allin-company-management-ui':
         specifier: workspace:*
         version: link:../allin-packages/company-management-ui
-      '@d8d/allin-disability-management-ui':
-        specifier: workspace:*
-        version: link:../allin-packages/disability-management-ui
       '@d8d/allin-disability-person-management-ui':
         specifier: workspace:*
         version: link:../allin-packages/disability-person-management-ui

+ 0 - 1
web/package.json

@@ -45,7 +45,6 @@
     "@d8d/area-management-ui": "workspace:*",
     "@d8d/allin-channel-management-ui": "workspace:*",
     "@d8d/allin-company-management-ui": "workspace:*",
-    "@d8d/allin-disability-management-ui": "workspace:*",
     "@d8d/allin-disability-person-management-ui": "workspace:*",
     "@d8d/allin-order-management-ui": "workspace:*",
     "@d8d/allin-platform-management-ui": "workspace:*",

+ 1 - 3
web/src/client/admin/api_init.ts

@@ -7,8 +7,7 @@ import { areaClientManager } from '@d8d/area-management-ui/api';
 // Allin系统UI包API客户端初始化
 import { channelClientManager } from '@d8d/allin-channel-management-ui/api';
 import { companyClientManager } from '@d8d/allin-company-management-ui/api';
-import { disabilityClientManager } from '@d8d/allin-disability-management-ui/api';
-import { disabilityClientManager as disabilityPersonClientManager } from '@d8d/allin-disability-person-management-ui/api';
+import { disabilityClientManager } from '@d8d/allin-disability-person-management-ui/api';
 import { orderClientManager } from '@d8d/allin-order-management-ui/api';
 import { platformClientManager } from '@d8d/allin-platform-management-ui/api';
 import { salaryClientManager } from '@d8d/allin-salary-management-ui/api';
@@ -24,7 +23,6 @@ areaClientManager.init('/api/v1/admin/areas');
 channelClientManager.init('/api/v1/channel');
 companyClientManager.init('/api/v1/company');
 disabilityClientManager.init('/api/v1/disability');
-disabilityPersonClientManager.init('/api/v1/disability');
 orderClientManager.init('/api/v1/order');
 platformClientManager.init('/api/v1/platform');
 salaryClientManager.init('/api/v1/salary');

+ 0 - 7
web/src/client/admin/menu.tsx

@@ -140,13 +140,6 @@ export const useMenu = () => {
       path: '/admin/disabilities',
       permission: 'disability:manage'
     },
-    {
-      key: 'disability-persons',
-      label: '残疾人个人管理',
-      icon: <Users className="h-4 w-4" />,
-      path: '/admin/disability-persons',
-      permission: 'disability:manage'
-    },
     {
       key: 'orders',
       label: '订单管理',

+ 0 - 6
web/src/client/admin/routes.tsx

@@ -15,7 +15,6 @@ import { AreaManagement } from '@d8d/area-management-ui';
 // Allin系统UI包导入
 import { ChannelManagement } from '@d8d/allin-channel-management-ui';
 import { CompanyManagement } from '@d8d/allin-company-management-ui';
-import { DisabilityManagement } from '@d8d/allin-disability-management-ui';
 import { DisabilityPersonManagement } from '@d8d/allin-disability-person-management-ui';
 import { OrderManagement } from '@d8d/allin-order-management-ui';
 import { PlatformManagement } from '@d8d/allin-platform-management-ui';
@@ -81,11 +80,6 @@ export const router = createBrowserRouter([
       },
       {
         path: 'disabilities',
-        element: <DisabilityManagement />,
-        errorElement: <ErrorPage />
-      },
-      {
-        path: 'disability-persons',
         element: <DisabilityPersonManagement />,
         errorElement: <ErrorPage />
       },