1. Bug #333/#335/#336: 在 saveAdvice 方法入口添加参数非空校验 - adviceSaveParam 为 null 时返回友好错误提示 - adviceSaveList 为 null 或空时返回友好错误提示 2. 更新 Debug 日志标签为 BugFix#333/335/336 3. 增强异常场景的用户提示 修复人:关羽 修复日期:2026-04-08
4.8 KiB
4.8 KiB
Bug #355 - 性别字段回显不一致分析与修复
问题描述
门诊挂号页面的预约签到弹窗中,患者"随自核"的性别显示为"未知",但挂号界面载入后显示为"男性",数据不一致。
根本原因
数据流程分析
-
预约签到弹窗数据来源 (
TicketAppServiceImpl.listTicket())- SQL 查询 (ScheduleSlotMapper.xml 第97行):
COALESCE(CAST(o.gender AS VARCHAR), CAST(pinfo.gender_enum AS VARCHAR)) AS patientGender - 后端逻辑 (TicketAppServiceImpl.java 第140-145行):
if (raw.getPatientGender() != null) { String pg = raw.getPatientGender().trim(); dto.setGender("1".equals(pg) ? "男" : ("2".equals(pg) ? "女" : "未知")); } else { dto.setGender("未知"); }
- SQL 查询 (ScheduleSlotMapper.xml 第97行):
-
挂号界面数据来源 (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
可能的场景:
- 订单创建时未保存性别字段 (
order_main.gender= NULL) - 患者档案中的性别被修改过(但订单表未同步更新)
pinfo.gender_enum值为 NULL 或者不合法
修复方案
方案1:修正 SQL 查询逻辑 (推荐)
问题: 当 order_main.gender 为 NULL 时,SQL 正确回退到 pinfo.gender_enum,但 Java 代码中对 patientGender 的处理逻辑有问题。
修复步骤:
- 修改 SQL,直接从患者表获取性别,不依赖订单表的 gender 字段:
-- ScheduleSlotMapper.xml
LEFT JOIN adm_patient pinfo ON o.patient_id = pinfo.id
-- 性别字段直接从患者表获取,避免订单表 gender 字段为空的情况
pinfo.gender_enum AS genderEnum,
- 修改 Java 代码,直接使用
genderEnum字段:
// 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 检查患者"随自核"的数据:
-- 检查患者档案中的性别
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 中,将患者性别字段改为直接从患者表获取:
<!-- 原来的 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 方法中修改性别处理逻辑:
// 原来的代码 (第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("未知");
}
验证步骤
- 修复代码后,重新编译部署
- 打开预约签到弹窗,查找患者"随自核"
- 确认性别字段显示为"男性"
- 进行挂号操作
- 确认挂号界面显示的性别也是"男性"
- 两者应该保持一致