7.6 KiB
7.6 KiB
患者管理身份证号验证功能实现说明
一、功能概述
为患者管理模块添加了完整的身份证号验证功能,确保录入的患者身份证号真实有效,提高数据质量。
二、功能特性
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 表单验证规则
rules: {
idCard: [
{ required: true, message: '身份证号不能为空', trigger: 'blur' },
{ validator: validateIdCard, trigger: 'blur' }
]
}
3.2 验证函数
validateIdCard(rule, value, callback)
- 主要验证函数,由表单规则调用
- 依次执行:
- 非空检查
- 格式验证
- 校验码验证
- 日期验证
- 地区码验证
- 错误时通过callback返回错误信息
checkIdCardCode(idCard)
- 验证18位身份证号的校验码
- 15位身份证号跳过此验证
- 返回布尔值
checkIdCardDate(idCard)
- 验证身份证号中的出生日期
- 检查日期合法性、是否为未来日期、年龄是否合理
- 返回布尔值
checkIdCardArea(idCard)
- 验证身份证号中的地区码
- 检查省级代码是否有效
- 返回布尔值
handleIdCardBlur()
- 失焦事件处理函数
- 执行所有验证逻辑
- 显示相应的提示信息
- 自动填充性别信息
3.3 监听器
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组件
<el-input
v-model="form.idCard"
clearable
:disabled="isViewMode"
placeholder="请输入18位身份证号"
maxlength="18"
show-word-limit
@blur="handleIdCardBlur"
/>
四、验证流程图
用户输入身份证号
↓
失焦触发验证
↓
格式验证
├─ 15位数字
├─ 18位数字
└─ 18位末尾X/x
├─ 失败 → 提示"身份证号格式不正确"
└─ 成功 → 继续
↓
校验码验证(18位)
├─ 失败 → 提示"身份证号校验码不正确"
└─ 成功 → 继续
↓
日期验证
├─ 失败 → 提示"身份证号中的日期不合法"
└─ 成功 → 继续
↓
地区码验证
├─ 失败 → 提示"身份证号中的地区码不合法"
└─ 成功 → 继续
↓
验证通过
├─ 自动填充性别
└─ 显示成功提示
五、错误提示说明
| 错误场景 | 提示信息 | 原因 |
|---|---|---|
| 身份证号为空 | "身份证号不能为空" | 必填验证 |
| 格式不正确 | "身份证号格式不正确" | 不是15位或18位 |
| 校验码错误 | "身份证号校验码不正确" | 最后一位与计算结果不符 |
| 日期不合法 | "身份证号中的日期不合法" | 出生日期不存在或为未来日期 |
| 地区码不合法 | "身份证号中的地区码不合法" | 省级代码不在有效范围内 |
六、使用示例
6.1 正常使用
- 在"证件号码"输入框中输入身份证号
- 失焦后自动验证
- 验证通过后自动填充性别和年龄
- 显示成功提示:"身份证号验证通过,已自动填充性别信息"
6.2 错误处理
- 输入错误的身份证号
- 失焦后显示错误提示
- 修改错误内容后重新验证
七、注意事项
7.1 兼容性
- 支持新旧两代身份证号(15位和18位)
- 15位身份证号不进行校验码验证
- 18位身份证号进行完整的验证
7.2 性能考虑
- 失焦时验证,避免频繁验证
- 地区码验证只检查省级代码,简化逻辑
- 使用正则表达式进行格式验证,性能较好
7.3 安全性
- 前端验证仅作为辅助手段
- 后端应再次验证身份证号
- 敏感信息需要加密存储
7.4 扩展性
- 可以根据需要添加更多验证规则
- 可以对接公安系统进行实时验证
- 可以添加身份证号重复检查
八、后续优化建议
- 后端验证:在后端API中也添加身份证号验证逻辑
- 重复检查:检查身份证号是否已被其他患者使用
- OCR识别:支持扫描身份证自动识别
- 历史记录:记录身份证号修改历史
- 批量导入: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 | 初始版本,实现基础验证功能 |