# 患者管理身份证号验证功能实现说明 ## 一、功能概述 为患者管理模块添加了完整的身份证号验证功能,确保录入的患者身份证号真实有效,提高数据质量。 ## 二、功能特性 ### 1. 实时验证 - **必填验证**:身份证号必填 - **格式验证**:支持15位和18位身份证号 - **长度限制**:最大18位字符 - **字数提示**:显示当前输入字数/最大字数 ### 2. 校验规则 #### 2.1 基本格式校验 - 正则表达式:`/(^\d{15}$)|(^\d{18}$)|(^\d{17}(\d|X|x)$)/` - 支持15位纯数字身份证号 - 支持18位数字身份证号 - 支持18位末尾为X/x的身份证号 #### 2.2 校验码验证(18位身份证) - 使用国家标准GB 11643-1999《公民身份号码》 - 系数:`[7, 9, 10, 5, 8, 4, 2, 1, 6, 3, 7, 9, 10, 5, 8, 4, 2]` - 余数对照表:`['1', '0', 'X', '9', '8', '7', '6', '5', '4', '3', '2']` - 计算方法: ``` 加权和 = Σ(身份证号前17位 × 对应系数) 余数 = 加权和 % 11 校验码 = 余数对照表[余数] 比较身份证号第18位与校验码是否一致 ``` #### 2.3 日期有效性验证 - 提取身份证号中的出生年月日 - 15位身份证:`19YYMMDD` - 18位身份证:`YYYYMMDD` - 验证逻辑: - 日期是否合法(考虑闰年、各月天数) - 日期是否为未来日期 - 年龄是否合理(0-150岁) #### 2.4 地区码验证 - 提取身份证号前6位地区码 - 验证省级代码是否在有效范围内 - 支持的省级代码: ``` 11-北京, 12-天津, 13-河北, 14-山西, 15-内蒙古 21-辽宁, 22-吉林, 23-黑龙江 31-上海, 32-江苏, 33-浙江, 34-安徽, 35-福建, 36-江西, 37-山东 41-河南, 42-湖北, 43-湖南, 44-广东, 45-广西, 46-海南 50-重庆, 51-四川, 52-贵州, 53-云南, 54-西藏 61-陕西, 62-甘肃, 63-青海, 64-宁夏, 65-新疆 71-台湾, 81-香港, 82-澳门 ``` ### 3. 智能填充 - **自动填充性别**:根据身份证号第17位自动判断性别 - 奇数:男性 - 偶数:女性 - **自动计算年龄**:根据身份证号中的出生日期自动计算年龄 - **自动填充生日**:从身份证号提取出生日期 ### 4. 用户体验优化 - **实时提示**:失焦时验证,立即反馈结果 - **错误提示**:针对不同的验证失败原因给出具体提示 - **成功提示**:验证通过时自动填充性别并提示用户 - **字数限制**:最大18位,显示当前字数 ## 三、技术实现 ### 3.1 表单验证规则 ```javascript rules: { idCard: [ { required: true, message: '身份证号不能为空', trigger: 'blur' }, { validator: validateIdCard, trigger: 'blur' } ] } ``` ### 3.2 验证函数 #### validateIdCard(rule, value, callback) - 主要验证函数,由表单规则调用 - 依次执行: 1. 非空检查 2. 格式验证 3. 校验码验证 4. 日期验证 5. 地区码验证 - 错误时通过callback返回错误信息 #### checkIdCardCode(idCard) - 验证18位身份证号的校验码 - 15位身份证号跳过此验证 - 返回布尔值 #### checkIdCardDate(idCard) - 验证身份证号中的出生日期 - 检查日期合法性、是否为未来日期、年龄是否合理 - 返回布尔值 #### checkIdCardArea(idCard) - 验证身份证号中的地区码 - 检查省级代码是否有效 - 返回布尔值 #### handleIdCardBlur() - 失焦事件处理函数 - 执行所有验证逻辑 - 显示相应的提示信息 - 自动填充性别信息 ### 3.3 监听器 ```javascript watch( () => form.value.idCard, (newIdCard) => { if (newIdCard && newIdCard.length === 18) { // 自动计算年龄 const birthYear = parseInt(newIdCard.substring(6, 10)); const birthMonth = parseInt(newIdCard.substring(10, 12)); const birthDay = parseInt(newIdCard.substring(12, 14)); const today = new Date(); const currentYear = today.getFullYear(); const currentMonth = today.getMonth() + 1; const currentDay = today.getDate(); let age = currentYear - birthYear; if (currentMonth < birthMonth || (currentMonth === birthMonth && currentDay < birthDay)) { age--; } form.value.age = age; } } ) ``` ### 3.4 UI组件 ```vue ``` ## 四、验证流程图 ``` 用户输入身份证号 ↓ 失焦触发验证 ↓ 格式验证 ├─ 15位数字 ├─ 18位数字 └─ 18位末尾X/x ├─ 失败 → 提示"身份证号格式不正确" └─ 成功 → 继续 ↓ 校验码验证(18位) ├─ 失败 → 提示"身份证号校验码不正确" └─ 成功 → 继续 ↓ 日期验证 ├─ 失败 → 提示"身份证号中的日期不合法" └─ 成功 → 继续 ↓ 地区码验证 ├─ 失败 → 提示"身份证号中的地区码不合法" └─ 成功 → 继续 ↓ 验证通过 ├─ 自动填充性别 └─ 显示成功提示 ``` ## 五、错误提示说明 | 错误场景 | 提示信息 | 原因 | |---------|---------|------| | 身份证号为空 | "身份证号不能为空" | 必填验证 | | 格式不正确 | "身份证号格式不正确" | 不是15位或18位 | | 校验码错误 | "身份证号校验码不正确" | 最后一位与计算结果不符 | | 日期不合法 | "身份证号中的日期不合法" | 出生日期不存在或为未来日期 | | 地区码不合法 | "身份证号中的地区码不合法" | 省级代码不在有效范围内 | ## 六、使用示例 ### 6.1 正常使用 1. 在"证件号码"输入框中输入身份证号 2. 失焦后自动验证 3. 验证通过后自动填充性别和年龄 4. 显示成功提示:"身份证号验证通过,已自动填充性别信息" ### 6.2 错误处理 1. 输入错误的身份证号 2. 失焦后显示错误提示 3. 修改错误内容后重新验证 ## 七、注意事项 ### 7.1 兼容性 - 支持新旧两代身份证号(15位和18位) - 15位身份证号不进行校验码验证 - 18位身份证号进行完整的验证 ### 7.2 性能考虑 - 失焦时验证,避免频繁验证 - 地区码验证只检查省级代码,简化逻辑 - 使用正则表达式进行格式验证,性能较好 ### 7.3 安全性 - 前端验证仅作为辅助手段 - 后端应再次验证身份证号 - 敏感信息需要加密存储 ### 7.4 扩展性 - 可以根据需要添加更多验证规则 - 可以对接公安系统进行实时验证 - 可以添加身份证号重复检查 ## 八、后续优化建议 1. **后端验证**:在后端API中也添加身份证号验证逻辑 2. **重复检查**:检查身份证号是否已被其他患者使用 3. **OCR识别**:支持扫描身份证自动识别 4. **历史记录**:记录身份证号修改历史 5. **批量导入**:Excel导入时批量验证身份证号 ## 九、测试用例 ### 9.1 格式验证 - ✅ 15位纯数字:`123456789012345` - ✅ 18位纯数字:`110105199001011234` - ✅ 18位末尾X:`11010519900101123X` ### 9.2 校验码验证 - ✅ 正确的校验码:`11010519900101123X` - ❌ 错误的校验码:`11010519900101123Y` ### 9.3 日期验证 - ✅ 合法日期:`19900101` - ❌ 不存在日期:`19900230`(2月30日不存在) - ❌ 未来日期:`20991231` ### 9.4 地区码验证 - ✅ 有效地区:`110000`(北京)、`440000`(广东) - ❌ 无效地区:`990000`(不存在的省份) ## 十、更新记录 | 版本 | 日期 | 说明 | |------|------|------| | 1.0.0 | 2026-01-02 | 初始版本,实现基础验证功能 |