# Story 13.17: 残疾人管理表单优化

Status: done

## Story

作为系统管理员，
我希望残疾人管理表单能够自动解析身份证号和残疾证号信息，并支持动态添加多个联系电话，
以减少数据录入工作量和提高数据准确性。

## Acceptance Criteria

### AC1: 身份证号自动解析功能
1. 当用户输入18位身份证号后，系统自动解析性别
   - 第17位为奇数 → 性别自动填充为"男"
   - 第17位为偶数 → 性别自动填充为"女"
2. 当用户输入18位身份证号后，系统自动解析出生日期
   - 从第7-14位提取出生日期（YYYYMMDD格式）
   - 自动填充到"出生日期"字段
3. 解析后用户可以手动修改解析结果
4. 当身份证号不满足18位时，不触发自动解析
5. 性别和出生日期字段在已填充后仍可手动修改

### AC2: 残疾证号自动解析功能
1. 残疾证号格式为 `[残疾类别代码][序列号][残疾等级代码]`
   - 残疾类别代码: `视力`/`听力`/`言语`/`肢体`/`智力`/`精神`/`多重`
   - 残疾等级代码: `一级`/`二级`/`三级`/`四级`
2. 当用户输入残疾证号后，系统自动解析并填充残疾类别和等级
   - 示例: `视力残疾123456一级` → 残疾类别填充"视力残疾"，等级填充"一级"
3. 解析后用户可以手动修改解析结果
4. 当残疾证号无法匹配标准格式时，不触发自动解析
5. 残疾类别和等级字段在已填充后仍可手动修改

### AC3: 联系电话字段改造
1. 将原有的"联系电话"字段改为"本人手机号"
2. 添加"监护人手机号"字段，支持动态添加多个（最多5个）
3. 本人和监护人手机号都支持手机号格式验证
4. 监护人手机号可添加/删除
5. 数据库schema需要相应调整（保留原有phone字段作为本人手机号，新增guardian_phones表）

### AC4: 用户体验
1. 自动解析时有视觉反馈（如短暂高亮或提示信息）
2. 解析失败时不会影响用户继续输入
3. 表单提交时所有必填字段验证正常

## Tasks / Subtasks

- [x] Task 1: 身份证号自动解析实现 (AC: #1, #4)
  - [x] Subtask 1.1: 创建身份证解析工具函数（parseIdCard函数）
  - [x] Subtask 1.2: 在DisabilityPersonManagement组件中添加身份证号变化监听
  - [x] Subtask 1.3: 实现性别和出生日期自动填充逻辑
  - [x] Subtask 1.4: 确保用户可手动修改解析结果

- [x] Task 2: 残疾证号自动解析实现 (AC: #2, #5)
  - [x] Subtask 2.1: 创建残疾证号解析工具函数（parseDisabilityId函数）
  - [x] Subtask 2.2: 在DisabilityPersonManagement组件中添加残疾证号变化监听
  - [x] Subtask 2.3: 实现残疾类别和等级自动填充逻辑
  - [x] Subtask 2.4: 处理解析失败的情况

- [x] Task 3: 联系电话字段改造 (AC: #3)
  - [x] Subtask 3.1: 修改数据库schema（保留phone字段，新增guardian_phones表）
  - [x] Subtask 3.2: 更新Zod schema定义
  - [x] Subtask 3.3: 修改DisabilityPersonManagement组件表单UI
  - [x] Subtask 3.4: 实现监护人手机号动态添加/删除功能
  - [x] Subtask 3.5: 添加手机号格式验证

- [x] Task 4: 单元测试 (AC: #1, #2, #3)
  - [x] Subtask 4.1: 测试身份证号解析功能（有效/无效身份证号）
  - [x] Subtask 4.2: 测试残疾证号解析功能
  - [ ] Subtask 4.3: 测试监护人手机号增删改功能

- [x] Task 5: 集成测试和验证
  - [x] Subtask 5.1: 手动测试表单完整流程（通过 Playwright MCP E2E 测试验证）
  - [x] Subtask 5.2: 验证数据保存和读取正确性

## Dev Notes

### 技术实现要点

#### 身份证解析规则
- 18位身份证号: 第7-14位为出生日期(YYYYMMDD)，第17位为性别代码(奇数=男，偶数=女)
- 15位身份证号: 第7-12位为出生日期(YYMMDD)，第15位为性别代码

#### 残疾证号解析规则
- 残疾证号通常包含残疾类别关键字，需要通过正则表达式匹配
- 示例格式: `[类别]残疾[序列号][等级]` 或 `[类别][序列号][等级]`
- 类别关键词: `视力`/`听力`/`言语`/`肢体`/`智力`/`精神`/`多重`
- 等级关键词: `一级`/`二级`/`三级`/`四级`

#### 联系电话数据结构
```typescript
// 新增监护人手机号实体
interface GuardianPhone {
  id?: number;
  personId: number;
  phone: string;
  relationship: string; // 监护人关系（可选）
  isPrimary: number; // 是否主要联系人: 1-是，0-否
}
```

### 相关文件路径

#### 前端组件
- `/mnt/code/188-179-template-6/allin-packages/disability-person-management-ui/src/components/DisabilityPersonManagement.tsx`
  - 需要添加身份证号和残疾证号变化监听
  - 需要修改联系电话UI为本人手机号+监护人手机号

#### Schema定义
- `/mnt/code/188-179-template-6/allin-packages/disability-module/src/schemas/disabled-person.schema.ts`
  - 需要添加监护人手机号相关的schema定义

#### 数据库实体
- `/mnt/code/188-179-template-6/allin-packages/disability-module/src/entities/disabled-person.entity.ts`
  - phone字段保留作为本人手机号
  - 需要新增GuardianPhone实体

### Project Structure Notes

- 本Story属于Epic 13（跨端数据同步测试），但实际是功能优化Story
- 遵循monorepo结构，修改位于allin-packages下
- 使用react-hook-form进行表单管理，使用zod进行验证
- 表单变化监听使用useEffect配合watch方法

### References

- [Source: /mnt/code/188-179-template-6/allin-packages/disability-person-management-ui/src/components/DisabilityPersonManagement.tsx]
- [Source: /mnt/code/188-179-template-6/allin-packages/disability-module/src/schemas/disabled-person.schema.ts]
- [Source: /mnt/code/188-179-template-6/allin-packages/disability-module/src/entities/disabled-person.entity.ts]
- [Source: /mnt/code/188-179-template-6/CLAUDE.md - 项目开发环境说明]
- [Source: /mnt/code/188-179-template-6/_bmad-output/project-context.md - 项目上下文]

## Dev Agent Record

### Agent Model Used

claude-opus-4-5-20251101

### Debug Log References

### Completion Notes List

### File List

#### 前端组件
- `allin-packages/disability-person-management-ui/src/utils/idCardParser.ts` - 身份证解析工具函数
- `allin-packages/disability-person-management-ui/src/utils/disabilityIdParser.ts` - 残疾证号解析工具函数
- `allin-packages/disability-person-management-ui/src/components/DisabilityPersonManagement.tsx` - 添加身份证号和残疾证号自动解析功能
- `allin-packages/disability-person-management-ui/src/components/GuardianPhoneManagement.tsx` - 监护人电话管理组件

#### 前端测试
- `allin-packages/disability-person-management-ui/tests/utils/idCardParser.test.ts` - 身份证解析单元测试（20个测试用例）
- `allin-packages/disability-person-management-ui/tests/utils/disabilityIdParser.test.ts` - 残疾证号解析单元测试（22个测试用例）

#### 后端实体
- `allin-packages/disability-module/src/entities/disabled-person-guardian-phone.entity.ts` - 监护人电话实体
- `allin-packages/disability-module/src/entities/disabled-person.entity.ts` - 添加监护人电话关系

#### 后端Schema
- `allin-packages/disability-module/src/schemas/disabled-person.schema.ts` - 添加监护人电话相关schema定义

#### 服务器配置（CRITICAL FIX）
- `packages/server/src/index.ts` - 修复 DisabledPersonGuardianPhone entity 未注册到 TypeORM 的问题
