- 在SysLoginController中添加optionMap数据返回 - 添加JSQLParser依赖支持MyBatis Plus功能 - 实现selectMenuByPathExcludeId方法用于排除当前菜单的路径唯一性校验 - 在SysMenuServiceImpl中添加日志记录并优化路径唯一性判断逻辑 - 在SysMenuMapper.xml中添加LIMIT 1限制并实现排除ID查询 - 在前端路由中注释患者管理相关路由配置 - 在用户store中添加optionMap配置项并优先从optionMap获取医院名称 - 重构检查项目设置页面的操作按钮样式为统一的圆形按钮设计 - 更新检查项目设置页面的导航栏样式和交互体验 - 优化门诊记录页面的搜索条件和表格展示功能 - 添加性别和状态筛选条件并改进数据加载逻辑
271 lines
7.6 KiB
Markdown
271 lines
7.6 KiB
Markdown
# 患者管理身份证号验证功能实现说明
|
||
|
||
## 一、功能概述
|
||
|
||
为患者管理模块添加了完整的身份证号验证功能,确保录入的患者身份证号真实有效,提高数据质量。
|
||
|
||
## 二、功能特性
|
||
|
||
### 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
|
||
<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 正常使用
|
||
|
||
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 | 初始版本,实现基础验证功能 |
|