1. Bug #333/#335/#336: 在 saveAdvice 方法入口添加参数非空校验 - adviceSaveParam 为 null 时返回友好错误提示 - adviceSaveList 为 null 或空时返回友好错误提示 2. 更新 Debug 日志标签为 BugFix#333/335/336 3. 增强异常场景的用户提示 修复人:关羽 修复日期:2026-04-08
164 lines
4.8 KiB
Markdown
164 lines
4.8 KiB
Markdown
# Bug #355 - 性别字段回显不一致分析与修复
|
||
|
||
## 问题描述
|
||
门诊挂号页面的预约签到弹窗中,患者"随自核"的性别显示为"未知",但挂号界面载入后显示为"男性",数据不一致。
|
||
|
||
## 根本原因
|
||
|
||
### 数据流程分析
|
||
|
||
1. **预约签到弹窗数据来源** (`TicketAppServiceImpl.listTicket()`)
|
||
- SQL 查询 (ScheduleSlotMapper.xml 第97行):
|
||
```sql
|
||
COALESCE(CAST(o.gender AS VARCHAR), CAST(pinfo.gender_enum AS VARCHAR)) AS patientGender
|
||
```
|
||
- 后端逻辑 (TicketAppServiceImpl.java 第140-145行):
|
||
```java
|
||
if (raw.getPatientGender() != null) {
|
||
String pg = raw.getPatientGender().trim();
|
||
dto.setGender("1".equals(pg) ? "男" : ("2".equals(pg) ? "女" : "未知"));
|
||
} else {
|
||
dto.setGender("未知");
|
||
}
|
||
```
|
||
|
||
2. **挂号界面数据来源** (OutpatientRegistrationAppServiceImpl)
|
||
- 直接从 `adm_patient` 表查询患者最新信息
|
||
- 性别字段: `pinfo.gender_enum`
|
||
- 翻译为文本: `EnumUtils.getInfoByValue(AdministrativeGender.class, genderEnum)`
|
||
|
||
### 问题定位
|
||
|
||
**关键 SQL 逻辑问题:**
|
||
- `order_main.gender` 字段存储的是订单创建时的性别值(varchar 类型)
|
||
- `adm_patient.gender_enum` 字段存储的是患者最新性别(integer 类型)
|
||
- 当 `order_main.gender` 为 `NULL` 时,SQL 会回退到 `pinfo.gender_enum`
|
||
|
||
**可能的场景:**
|
||
1. 订单创建时未保存性别字段 (`order_main.gender` = NULL)
|
||
2. 患者档案中的性别被修改过(但订单表未同步更新)
|
||
3. `pinfo.gender_enum` 值为 NULL 或者不合法
|
||
|
||
## 修复方案
|
||
|
||
### 方案1:修正 SQL 查询逻辑 (推荐)
|
||
|
||
**问题:** 当 `order_main.gender` 为 NULL 时,SQL 正确回退到 `pinfo.gender_enum`,但 Java 代码中对 `patientGender` 的处理逻辑有问题。
|
||
|
||
**修复步骤:**
|
||
|
||
1. 修改 SQL,直接从患者表获取性别,不依赖订单表的 gender 字段:
|
||
|
||
```sql
|
||
-- ScheduleSlotMapper.xml
|
||
LEFT JOIN adm_patient pinfo ON o.patient_id = pinfo.id
|
||
-- 性别字段直接从患者表获取,避免订单表 gender 字段为空的情况
|
||
pinfo.gender_enum AS genderEnum,
|
||
```
|
||
|
||
2. 修改 Java 代码,直接使用 `genderEnum` 字段:
|
||
|
||
```java
|
||
// TicketAppServiceImpl.java
|
||
// 性别处理:直接使用患者表中的 gender_enum
|
||
Integer genderEnum = raw.getGenderEnum();
|
||
if (genderEnum != null) {
|
||
if (Integer.valueOf(1).equals(genderEnum)) {
|
||
dto.setGender("男");
|
||
} else if (Integer.valueOf(2).equals(genderEnum)) {
|
||
dto.setGender("女");
|
||
} else {
|
||
dto.setGender("未知");
|
||
}
|
||
} else {
|
||
dto.setGender("未知");
|
||
}
|
||
```
|
||
|
||
### 方案2:确保订单表 gender 字段不为空
|
||
|
||
在订单创建时,确保将患者的性别同步到订单表的 `gender` 字段。
|
||
|
||
## 临时验证方案
|
||
|
||
在数据库中执行以下 SQL 检查患者"随自核"的数据:
|
||
|
||
```sql
|
||
-- 检查患者档案中的性别
|
||
SELECT id, name, gender_enum,
|
||
CASE gender_enum
|
||
WHEN 1 THEN '男'
|
||
WHEN 2 THEN '女'
|
||
ELSE '未知'
|
||
END as gender_text
|
||
FROM adm_patient
|
||
WHERE name = '随自核';
|
||
|
||
-- 检查订单表中的性别
|
||
SELECT o.id, o.patient_id, o.patient_name, o.gender, p.gender_enum
|
||
FROM order_main o
|
||
LEFT JOIN adm_patient p ON o.patient_id = p.id
|
||
WHERE o.patient_name = '随自核';
|
||
|
||
-- 检查号源数据
|
||
SELECT s.id, s.pool_id, s.status as slot_status
|
||
FROM adm_schedule_slot s
|
||
WHERE EXISTS (
|
||
SELECT 1 FROM order_main o WHERE o.slot_id = s.id
|
||
AND o.patient_name = '随自核'
|
||
);
|
||
```
|
||
|
||
## 修复代码
|
||
|
||
### 修改 ScheduleSlotMapper.xml
|
||
|
||
在 `selectTicketSlotsPage` SQL 中,将患者性别字段改为直接从患者表获取:
|
||
|
||
```xml
|
||
<!-- 原来的 SQL (第97行) -->
|
||
COALESCE(CAST(o.gender AS VARCHAR), CAST(pinfo.gender_enum AS VARCHAR)) AS patientGender,
|
||
|
||
<!-- 修改后的 SQL -->
|
||
pinfo.gender_enum AS genderEnum,
|
||
```
|
||
|
||
### 修改 TicketAppServiceImpl.java
|
||
|
||
在 `listTicket` 方法中修改性别处理逻辑:
|
||
|
||
```java
|
||
// 原来的代码 (第140-145行)
|
||
// 性别处理:直接读取优先级最高的订单性别字段 (SQL 已处理优先级)
|
||
if (raw.getPatientGender() != null) {
|
||
String pg = raw.getPatientGender().trim();
|
||
dto.setGender("1".equals(pg) ? "男" : ("2".equals(pg) ? "女" : "未知"));
|
||
} else {
|
||
dto.setGender("未知");
|
||
}
|
||
|
||
// 修改后的代码
|
||
// 性别处理:直接使用患者表中的 gender_enum
|
||
Integer genderEnum = raw.getGenderEnum();
|
||
if (genderEnum != null) {
|
||
if (Integer.valueOf(1).equals(genderEnum)) {
|
||
dto.setGender("男");
|
||
} else if (Integer.valueOf(2).equals(genderEnum)) {
|
||
dto.setGender("女");
|
||
} else {
|
||
dto.setGender("未知");
|
||
}
|
||
} else {
|
||
dto.setGender("未知");
|
||
}
|
||
```
|
||
|
||
## 验证步骤
|
||
|
||
1. 修复代码后,重新编译部署
|
||
2. 打开预约签到弹窗,查找患者"随自核"
|
||
3. 确认性别字段显示为"男性"
|
||
4. 进行挂号操作
|
||
5. 确认挂号界面显示的性别也是"男性"
|
||
6. 两者应该保持一致
|