4 Commits 1195f3117f ... 211e56a3bd

Autor SHA1 Mensaje Fecha
  yourname 211e56a3bd 🔧 fix(disability-person): 修复残疾人选择器客户端管理器使用方式 hace 2 días
  yourname 7d8c1cf274 ♿ fix(disability-person): 为残疾人选择器添加垂直滚动控制,优化表格显示 hace 2 días
  yourname 37f48f6d39 🎨 feat(disability-person): 为残疾人选择器添加响应式设计,优化移动端体验 hace 2 días
  yourname 6f3ca31254 🔧 fix(disability-person): 修复残疾人选择器区域选择器布局,脱离网格单独一行 hace 2 días

+ 100 - 78
allin-packages/disability-person-management-ui/src/components/DisabledPersonSelector.tsx

@@ -25,7 +25,7 @@ import { AlertCircle } from 'lucide-react';
 import { AreaSelect } from '@d8d/area-management-ui';
 import { Form } from '@d8d/shared-ui-components/components/ui/form';
 import { useForm } from 'react-hook-form';
-import { disabilityClient } from '../api/disabilityClient';
+import { disabilityClientManager } from '../api/disabilityClient';
 import type {
   DisabledPersonData,
   AreaSelection,
@@ -68,7 +68,7 @@ const DisabledPersonSelector: React.FC<DisabledPersonSelectorProps> = ({
   const { data, isLoading, refetch } = useQuery({
     queryKey: ['disabled-persons-search', searchParams],
     queryFn: async () => {
-      const response = await disabilityClient.searchDisabledPersons.$get({
+      const response = await disabilityClientManager.get().searchDisabledPersons.$get({
         query: {
           keyword: searchParams.keyword || '',
           skip: ((searchParams.page || 1) - 1) * (searchParams.pageSize || 10),
@@ -85,7 +85,7 @@ const DisabledPersonSelector: React.FC<DisabledPersonSelectorProps> = ({
   const { data: allData, isLoading: isLoadingAll } = useQuery({
     queryKey: ['disabled-persons-all', searchParams.page, searchParams.pageSize],
     queryFn: async () => {
-      const response = await disabilityClient.getAllDisabledPersons.$get({
+      const response = await disabilityClientManager.get().getAllDisabledPersons.$get({
         query: {
           skip: ((searchParams.page || 1) - 1) * (searchParams.pageSize || 10),
           take: searchParams.pageSize || 10,
@@ -210,14 +210,15 @@ const DisabledPersonSelector: React.FC<DisabledPersonSelectorProps> = ({
   return (
     <>
       <Dialog open={open} onOpenChange={onOpenChange}>
-        <DialogContent className="max-w-6xl max-h-[80vh] overflow-hidden flex flex-col">
+        <DialogContent className="max-w-6xl max-h-[90vh] overflow-hidden flex flex-col w-[95vw] sm:w-full h-[90vh] sm:h-auto">
           <DialogHeader>
             <DialogTitle>选择残疾人</DialogTitle>
           </DialogHeader>
 
-          {/* 搜索区域 */}
+          {/* 搜索区域 - 响应式设计 */}
           <div className="space-y-4 p-4 border rounded-lg">
-            <div className="grid grid-cols-4 gap-4">
+            {/* 第一行:基本信息搜索 - 响应式网格 */}
+            <div className="grid grid-cols-1 sm:grid-cols-2 lg:grid-cols-4 gap-4">
               <div className="space-y-2">
                 <Label htmlFor="name">姓名</Label>
                 <Input
@@ -272,19 +273,21 @@ const DisabledPersonSelector: React.FC<DisabledPersonSelectorProps> = ({
               </div>
             </div>
 
-            <div className="grid grid-cols-4 gap-4">
-              <div className="space-y-2">
-                <Label>省份/城市</Label>
-                {/* AreaSelect需要Form上下文,所以包装在Form中 */}
-                <Form {...form}>
-                  <AreaSelect
-                    value={areaSelection}
-                    onChange={setAreaSelection}
-                    data-testid="area-select"
-                  />
-                </Form>
-              </div>
+            {/* 第二行:区域选择器单独一行 */}
+            <div className="space-y-2">
+              <Label>省份/城市/区县</Label>
+              {/* AreaSelect需要Form上下文,所以包装在Form中 */}
+              <Form {...form}>
+                <AreaSelect
+                  value={areaSelection}
+                  onChange={setAreaSelection}
+                  data-testid="area-select"
+                />
+              </Form>
+            </div>
 
+            {/* 第三行:其他筛选条件和操作按钮 - 响应式网格 */}
+            <div className="grid grid-cols-1 sm:grid-cols-2 lg:grid-cols-4 gap-4">
               <div className="space-y-2">
                 <Label htmlFor="disabilityType">残疾类型</Label>
                 <Select
@@ -332,90 +335,109 @@ const DisabledPersonSelector: React.FC<DisabledPersonSelectorProps> = ({
                 </Select>
               </div>
 
-              <div className="flex items-end space-x-2">
-                <Button onClick={handleSearch} data-testid="search-button">
+              {/* 在移动端隐藏空列 */}
+              <div className="hidden lg:block"></div>
+
+              <div className="flex items-end space-x-2 sm:col-span-2 lg:col-span-1">
+                <Button onClick={handleSearch} data-testid="search-button" className="flex-1 sm:flex-none">
                   搜索
                 </Button>
-                <Button variant="outline" onClick={handleResetSearch} data-testid="reset-button">
+                <Button variant="outline" onClick={handleResetSearch} data-testid="reset-button" className="flex-1 sm:flex-none">
                   重置
                 </Button>
               </div>
             </div>
           </div>
 
-          {/* 表格区域 */}
-          <div className="flex-1 overflow-auto">
+          {/* 表格区域 - 响应式设计 */}
+          <div className="flex-1 flex flex-col min-h-0">
             {isLoadingData ? (
               <div className="flex items-center justify-center h-64">
                 <div className="text-center">加载中...</div>
               </div>
             ) : personsData?.data && personsData.data.length > 0 ? (
               <>
-                <div className="border rounded-md">
-                  <Table data-testid="disabled-persons-table">
-                    <TableHeader>
-                      <TableRow>
-                        {mode === 'multiple' && (
-                          <TableHead className="w-12">
-                            <Checkbox
-                              checked={selectedPersons.length === personsData.data.length}
-                              onCheckedChange={(checked) => {
-                                if (checked) {
-                                  const selectablePersons = personsData.data.filter(
-                                    (person: DisabledPersonData) => !disabledIds.includes(person.id)
-                                  );
-                                  setSelectedPersons(selectablePersons);
-                                } else {
-                                  setSelectedPersons([]);
-                                }
-                              }}
-                              aria-label="全选"
-                            />
-                          </TableHead>
-                        )}
-                        {columns.map((column) => (
-                          <TableHead key={column.key}>{column.label}</TableHead>
-                        ))}
-                      </TableRow>
-                    </TableHeader>
-                    <TableBody>
-                      {personsData.data.map((person: DisabledPersonData) => (
-                        <TableRow
-                          key={person.id}
-                          onClick={() => mode === 'single' && handleSelectPerson(person)}
-                          className={mode === 'single' ? 'cursor-pointer hover:bg-muted' : ''}
-                          data-testid={`table-row-${person.id}`}
-                        >
+                {/* 移动端提示 */}
+                <div className="lg:hidden mb-2 text-sm text-muted-foreground">
+                  <p>提示:表格可以左右滑动查看所有列</p>
+                </div>
+
+                {/* 表格容器 - 支持水平和垂直滚动 */}
+                <div className="flex-1 border rounded-md overflow-hidden flex flex-col min-h-0">
+                  <div className="overflow-x-auto overflow-y-auto flex-1">
+                    <Table data-testid="disabled-persons-table" className="min-w-full">
+                      <TableHeader>
+                        <TableRow>
                           {mode === 'multiple' && (
-                            <TableCell>
+                            <TableHead className="w-12 sticky left-0 bg-background z-10">
                               <Checkbox
-                                checked={selectedPersons.some(p => p.id === person.id)}
+                                checked={selectedPersons.length === personsData.data.length}
                                 onCheckedChange={(checked) => {
                                   if (checked) {
-                                    setSelectedPersons([...selectedPersons, person]);
+                                    const selectablePersons = personsData.data.filter(
+                                      (person: DisabledPersonData) => !disabledIds.includes(person.id)
+                                    );
+                                    setSelectedPersons(selectablePersons);
                                   } else {
-                                    setSelectedPersons(selectedPersons.filter(p => p.id !== person.id));
+                                    setSelectedPersons([]);
                                   }
                                 }}
-                                disabled={disabledIds.includes(person.id)}
-                                aria-label="选择"
+                                aria-label="全选"
                               />
-                            </TableCell>
+                            </TableHead>
                           )}
-                          <TableCell>{person.name}</TableCell>
-                          <TableCell>{person.gender}</TableCell>
-                          <TableCell>{person.idCard}</TableCell>
-                          <TableCell>{person.disabilityId}</TableCell>
-                          <TableCell>{person.phone}</TableCell>
-                          <TableCell>{person.province}</TableCell>
-                          <TableCell>{person.city}</TableCell>
-                          <TableCell>{person.disabilityType}</TableCell>
-                          <TableCell>{person.disabilityLevel}</TableCell>
-                          <TableCell>{person.isInBlackList === 1 ? '是' : '否'}</TableCell>
+                          {columns.map((column, index) => (
+                            <TableHead
+                              key={column.key}
+                              className={`
+                                ${index === 0 ? 'sticky left-0 bg-background z-10' : ''}
+                                ${['province', 'city', 'disabilityType', 'disabilityLevel', 'blacklist'].includes(column.key) ? 'hidden lg:table-cell' : ''}
+                              `}
+                            >
+                              {column.label}
+                            </TableHead>
+                          ))}
                         </TableRow>
-                      ))}
-                    </TableBody>
-                  </Table>
+                      </TableHeader>
+                      <TableBody>
+                        {personsData.data.map((person: DisabledPersonData) => (
+                          <TableRow
+                            key={person.id}
+                            onClick={() => mode === 'single' && handleSelectPerson(person)}
+                            className={mode === 'single' ? 'cursor-pointer hover:bg-muted' : ''}
+                            data-testid={`table-row-${person.id}`}
+                          >
+                            {mode === 'multiple' && (
+                              <TableCell className="sticky left-0 bg-background z-10">
+                                <Checkbox
+                                  checked={selectedPersons.some(p => p.id === person.id)}
+                                  onCheckedChange={(checked) => {
+                                    if (checked) {
+                                      setSelectedPersons([...selectedPersons, person]);
+                                    } else {
+                                      setSelectedPersons(selectedPersons.filter(p => p.id !== person.id));
+                                    }
+                                  }}
+                                  disabled={disabledIds.includes(person.id)}
+                                  aria-label="选择"
+                                />
+                              </TableCell>
+                            )}
+                            <TableCell className="sticky left-0 bg-background z-10">{person.name}</TableCell>
+                            <TableCell>{person.gender}</TableCell>
+                            <TableCell>{person.idCard}</TableCell>
+                            <TableCell>{person.disabilityId}</TableCell>
+                            <TableCell>{person.phone}</TableCell>
+                            <TableCell className="hidden lg:table-cell">{person.province}</TableCell>
+                            <TableCell className="hidden lg:table-cell">{person.city}</TableCell>
+                            <TableCell className="hidden lg:table-cell">{person.disabilityType}</TableCell>
+                            <TableCell className="hidden lg:table-cell">{person.disabilityLevel}</TableCell>
+                            <TableCell className="hidden lg:table-cell">{person.isInBlackList === 1 ? '是' : '否'}</TableCell>
+                          </TableRow>
+                        ))}
+                      </TableBody>
+                    </Table>
+                  </div>
                 </div>
                 <DataTablePagination
                   currentPage={searchParams.page || 1}