Browse Source

fix(disability-ui): 修复表单滚动问题和添加移动端适配

## 修复内容
1. **表单滚动问题**:
   - 添加滚动区域:`flex-1 overflow-y-auto pr-2`
   - 设置最大高度:`max-h-[80vh]`
   - 按钮固定在底部,不随内容滚动

2. **移动端适配**:
   - 添加移动端滚动支持:`overscroll-contain touch-auto`
   - 响应式网格布局:`grid-cols-1 md:grid-cols-2 lg:grid-cols-3`
   - 移动端宽度适配:`w-[95vw]`
   - 跨列元素响应式:`col-span-1 md:col-span-2`

3. **添加缺失字段**:
   - 婚姻状况(isMarried)
   - 是否可直接联系(canDirectContact)
   - 就业状态(jobStatus)

## 修复的组件
- `DisabilityManagement.tsx` (disability-management-ui)
- `DisabilityPersonManagement.tsx` (disability-person-management-ui)

## 测试结果
- 所有单元测试和集成测试通过
- 表单现在可以在移动端正常滚动
- 布局在不同屏幕尺寸下自适应

🤖 Generated with [Claude Code](https://claude.ai/code)
via [Happy](https://happy.engineering)

Co-Authored-By: Claude <noreply@anthropic.com>
Co-Authored-By: Happy <yesreply@happy.engineering>
yourname 2 days ago
parent
commit
4ace77d5d5

+ 155 - 23
allin-packages/disability-management-ui/src/components/DisabilityManagement.tsx

@@ -332,17 +332,18 @@ const DisabilityManagement: React.FC = () => {
 
       {/* 创建/更新模态框 */}
       <Dialog open={isModalOpen} onOpenChange={setIsModalOpen}>
-        <DialogContent className="max-w-2xl">
+        <DialogContent className="w-[95vw] max-w-4xl max-h-[80vh] flex flex-col">
           <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">
+          <div className="flex-1 overflow-y-auto pr-2 overscroll-contain touch-auto">
+            {isCreateForm ? (
+              <Form {...createForm}>
+                <form id="create-form" onSubmit={handleCreateSubmit} 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"
@@ -492,21 +493,79 @@ const DisabilityManagement: React.FC = () => {
                       </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}
+                            data-testid="is-married-select"
+                            value={field.value?.toString() || '0'}
+                            onChange={(e) => field.onChange(parseInt(e.target.value))}
+                          >
+                            <option value="0">未婚</option>
+                            <option value="1">已婚</option>
+                          </select>
+                        </FormControl>
+                        <FormMessage />
+                      </FormItem>
+                    )}
+                  />
+                  <FormField
+                    control={createForm.control}
+                    name="canDirectContact"
+                    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="can-direct-contact-select"
+                            value={field.value?.toString() || '0'}
+                            onChange={(e) => field.onChange(parseInt(e.target.value))}
+                          >
+                            <option value="0">否</option>
+                            <option value="1">是</option>
+                          </select>
+                        </FormControl>
+                        <FormMessage />
+                      </FormItem>
+                    )}
+                  />
+                  <FormField
+                    control={createForm.control}
+                    name="jobStatus"
+                    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="job-status-select"
+                            value={field.value?.toString() || '0'}
+                            onChange={(e) => field.onChange(parseInt(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={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">
+              <form id="update-form" onSubmit={handleUpdateSubmit} className="space-y-4">
+                <div className="grid grid-cols-1 md:grid-cols-2 lg:grid-cols-3 gap-4">
                   <FormField
                     control={updateForm.control}
                     name="name"
@@ -656,18 +715,91 @@ const DisabilityManagement: React.FC = () => {
                       </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}
+                            data-testid="update-is-married-select"
+                            value={field.value?.toString() || '0'}
+                            onChange={(e) => field.onChange(parseInt(e.target.value))}
+                          >
+                            <option value="0">未婚</option>
+                            <option value="1">已婚</option>
+                          </select>
+                        </FormControl>
+                        <FormMessage />
+                      </FormItem>
+                    )}
+                  />
+                  <FormField
+                    control={updateForm.control}
+                    name="canDirectContact"
+                    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-can-direct-contact-select"
+                            value={field.value?.toString() || '0'}
+                            onChange={(e) => field.onChange(parseInt(e.target.value))}
+                          >
+                            <option value="0">否</option>
+                            <option value="1">是</option>
+                          </select>
+                        </FormControl>
+                        <FormMessage />
+                      </FormItem>
+                    )}
+                  />
+                  <FormField
+                    control={updateForm.control}
+                    name="jobStatus"
+                    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-job-status-select"
+                            value={field.value?.toString() || '0'}
+                            onChange={(e) => field.onChange(parseInt(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} data-testid="update-submit-button">
-                    {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} data-testid="create-submit-button">
+                {createMutation.isPending ? '创建中...' : '创建'}
+              </Button>
+            ) : (
+              <Button type="submit" form="update-form" disabled={updateMutation.isPending} data-testid="update-submit-button">
+                {updateMutation.isPending ? '更新中...' : '更新'}
+              </Button>
+            )}
+          </DialogFooter>
         </DialogContent>
       </Dialog>
 

+ 29 - 32
allin-packages/disability-person-management-ui/src/components/DisabilityPersonManagement.tsx

@@ -314,7 +314,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,11 +323,11 @@ const DisabilityPersonManagement: React.FC = () => {
               {isCreateForm ? '填写残疾人基本信息,带*的为必填项' : '修改残疾人信息'}
             </DialogDescription>
           </DialogHeader>
-
-          {isCreateForm ? (
-            <Form {...createForm}>
-              <form onSubmit={createForm.handleSubmit(onSubmitCreate, (errors) => console.debug('创建表单验证错误:', errors))} className="space-y-4">
-                <div className="grid grid-cols-2 gap-4">
+          <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"
@@ -459,7 +459,7 @@ const DisabilityPersonManagement: React.FC = () => {
                     control={createForm.control}
                     name="idAddress"
                     render={({ field }) => (
-                      <FormItem className="col-span-2">
+                      <FormItem className="col-span-1 md:col-span-2">
                         <FormLabel>身份证地址 *</FormLabel>
                         <FormControl>
                           <Input placeholder="请输入身份证地址" {...field} />
@@ -469,7 +469,7 @@ const DisabilityPersonManagement: React.FC = () => {
                     )}
                   />
 
-                  <div className="col-span-2">
+                  <div className="col-span-1 md:col-span-2">
                     <FormLabel>居住地址 *</FormLabel>
                     <div className="space-y-4">
                       <AreaSelect
@@ -536,7 +536,7 @@ const DisabilityPersonManagement: React.FC = () => {
                     )}
                   />
 
-                  <div className="col-span-2">
+                  <div className="col-span-1 md:col-span-2">
                     <FormLabel>照片上传</FormLabel>
                     <FileSelector
                       value={null}
@@ -551,21 +551,12 @@ const DisabilityPersonManagement: React.FC = () => {
                     />
                   </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">
+              <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={updateForm.control}
                     name="name"
@@ -697,7 +688,7 @@ const DisabilityPersonManagement: React.FC = () => {
                     control={updateForm.control}
                     name="idAddress"
                     render={({ field }) => (
-                      <FormItem className="col-span-2">
+                      <FormItem className="col-span-1 md:col-span-2">
                         <FormLabel>身份证地址 *</FormLabel>
                         <FormControl>
                           <Input placeholder="请输入身份证地址" {...field} />
@@ -707,7 +698,7 @@ const DisabilityPersonManagement: React.FC = () => {
                     )}
                   />
 
-                  <div className="col-span-2">
+                  <div className="col-span-1 md:col-span-2">
                     <FormLabel>居住地址 *</FormLabel>
                     <div className="space-y-4">
                       <AreaSelect
@@ -774,18 +765,24 @@ const DisabilityPersonManagement: React.FC = () => {
                     )}
                   />
                 </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 +829,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}