فهرست منبع

fix(disability-person-ui): 重构表单布局,大字段完全脱离网格独占一行

- 将表单分为两部分:小字段使用网格布局,大字段脱离网格布局
- 身份证地址、居住地址、照片上传字段各自独占一行
- 居住地址字段包含省市区选择器和详细地址输入框
- 编辑表单同步调整相同布局结构
- 解决中等屏幕下col-span-full不独占一行的问题

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

Co-Authored-By: Claude <noreply@anthropic.com>
Co-Authored-By: Happy <yesreply@happy.engineering>
yourname 2 روز پیش
والد
کامیت
6f76232acc
1فایلهای تغییر یافته به همراه252 افزوده شده و 242 حذف شده
  1. 252 242
      allin-packages/disability-person-management-ui/src/components/DisabilityPersonManagement.tsx

+ 252 - 242
allin-packages/disability-person-management-ui/src/components/DisabilityPersonManagement.tsx

@@ -335,9 +335,245 @@ const DisabilityPersonManagement: React.FC = () => {
             {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>
+                      )}
+                    />
+
+                    <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>
@@ -351,7 +587,7 @@ const DisabilityPersonManagement: React.FC = () => {
                   />
 
                   <FormField
-                    control={createForm.control}
+                    control={updateForm.control}
                     name="gender"
                     render={({ field }) => (
                       <FormItem>
@@ -372,7 +608,7 @@ const DisabilityPersonManagement: React.FC = () => {
                   />
 
                   <FormField
-                    control={createForm.control}
+                    control={updateForm.control}
                     name="idCard"
                     render={({ field }) => (
                       <FormItem>
@@ -386,7 +622,7 @@ const DisabilityPersonManagement: React.FC = () => {
                   />
 
                   <FormField
-                    control={createForm.control}
+                    control={updateForm.control}
                     name="disabilityId"
                     render={({ field }) => (
                       <FormItem>
@@ -400,7 +636,7 @@ const DisabilityPersonManagement: React.FC = () => {
                   />
 
                   <FormField
-                    control={createForm.control}
+                    control={updateForm.control}
                     name="disabilityType"
                     render={({ field }) => (
                       <FormItem>
@@ -408,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>
@@ -425,7 +661,7 @@ const DisabilityPersonManagement: React.FC = () => {
                   />
 
                   <FormField
-                    control={createForm.control}
+                    control={updateForm.control}
                     name="disabilityLevel"
                     render={({ field }) => (
                       <FormItem>
@@ -433,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>
@@ -450,7 +686,7 @@ const DisabilityPersonManagement: React.FC = () => {
                   />
 
                   <FormField
-                    control={createForm.control}
+                    control={updateForm.control}
                     name="phone"
                     render={({ field }) => (
                       <FormItem>
@@ -464,52 +700,7 @@ const DisabilityPersonManagement: React.FC = () => {
                   />
 
                   <FormField
-                    control={createForm.control}
-                    name="idAddress"
-                    render={({ field }) => (
-                      <FormItem className="col-span-full">
-                        <FormLabel>身份证地址 *</FormLabel>
-                        <FormControl>
-                          <Input placeholder="请输入身份证地址" {...field} />
-                        </FormControl>
-                        <FormMessage />
-                      </FormItem>
-                    )}
-                  />
-
-                  <div className="col-span-full">
-                    <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>
@@ -523,7 +714,7 @@ const DisabilityPersonManagement: React.FC = () => {
                   />
 
                   <FormField
-                    control={createForm.control}
+                    control={updateForm.control}
                     name="isMarried"
                     render={({ field }) => (
                       <FormItem>
@@ -543,160 +734,15 @@ const DisabilityPersonManagement: React.FC = () => {
                       </FormItem>
                     )}
                   />
-
-                  <div className="col-span-full">
-                    <FormLabel>照片上传</FormLabel>
-                    <FileSelector
-                      value={null}
-                      onChange={() => {
-                        // 这里需要处理文件ID的存储
-                        // 由于后端Schema没有photoFileId字段,暂时注释
-                        // createForm.setValue('photoFileId', fileId as number);
-                      }}
-                      accept="image/*"
-                      filterType="image"
-                      placeholder="选择或上传照片"
-                    />
-                  </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={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-full">
+                      <FormItem>
                         <FormLabel>身份证地址 *</FormLabel>
                         <FormControl>
                           <Input placeholder="请输入身份证地址" {...field} />
@@ -706,9 +752,9 @@ const DisabilityPersonManagement: React.FC = () => {
                     )}
                   />
 
-                  <div className="col-span-full">
+                  <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,
@@ -736,42 +782,6 @@ 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>
               </form>
             </Form>