Fix: 医生站getRequestBaseInfo接口报错,adm_charge_item表无content_json列导致UNION ALL查询失败

Bug #401: 门诊医生站完诊div_log审计日志修复,及getRequestBaseInfo SQL列引用错误修正
This commit is contained in:
wangjian963
2026-05-08 17:22:39 +08:00
parent 244703e6ac
commit 232261296f
2 changed files with 49 additions and 22 deletions

View File

@@ -18,6 +18,10 @@ import com.openhis.common.constant.CommonConstants;
import com.openhis.common.enums.*; import com.openhis.common.enums.*;
import com.openhis.common.utils.EnumUtils; import com.openhis.common.utils.EnumUtils;
import com.openhis.common.utils.HisQueryUtils; import com.openhis.common.utils.HisQueryUtils;
import com.openhis.appointmentmanage.domain.ScheduleSlot;
import com.openhis.appointmentmanage.mapper.ScheduleSlotMapper;
import com.openhis.clinical.domain.Order;
import com.openhis.clinical.service.IOrderService;
import com.openhis.triageandqueuemanage.domain.DivLog; import com.openhis.triageandqueuemanage.domain.DivLog;
import com.openhis.triageandqueuemanage.domain.TriageQueueItem; import com.openhis.triageandqueuemanage.domain.TriageQueueItem;
import com.openhis.triageandqueuemanage.service.DivLogService; import com.openhis.triageandqueuemanage.service.DivLogService;
@@ -78,6 +82,12 @@ public class DoctorStationMainAppServiceImpl implements IDoctorStationMainAppSer
@Resource @Resource
private DivLogService divLogService; private DivLogService divLogService;
@Resource
private IOrderService iOrderService;
@Resource
private ScheduleSlotMapper scheduleSlotMapper;
/** /**
* 查询就诊患者信息 * 查询就诊患者信息
* *
@@ -264,8 +274,27 @@ public class DoctorStationMainAppServiceImpl implements IDoctorStationMainAppSer
return R.fail("非就诊中患者不能完诊"); return R.fail("非就诊中患者不能完诊");
} }
// 2. 查找队列项(限定当天,避免复诊患者匹配到历史队列记录) // 2. 获取 pool_id 和 slot_id从 encounter → order_main → adm_schedule_slot 链路获取
// 确保 div_log 中的值与排班主表一致,不依赖 triage_queue_item队列项可能不存在或值错误
Integer tenantId = SecurityUtils.getLoginUser().getTenantId(); Integer tenantId = SecurityUtils.getLoginUser().getTenantId();
Long divPoolId = null;
Long divSlotId = null;
if (encounter.getOrderId() != null) {
try {
Order order = iOrderService.getById(encounter.getOrderId());
if (order != null && order.getSlotId() != null) {
divSlotId = order.getSlotId();
ScheduleSlot slot = scheduleSlotMapper.selectById(divSlotId);
if (slot != null) {
divPoolId = slot.getPoolId();
}
}
} catch (Exception e) {
log.warn("获取完诊div_log的pool_id/slot_id失败encounterId={}", encounterId, e);
}
}
// 3. 查找队列项(限定当天,避免复诊患者匹配到历史队列记录)
TriageQueueItem queueItem = triageQueueItemService.getOne( TriageQueueItem queueItem = triageQueueItemService.getOne(
new LambdaQueryWrapper<TriageQueueItem>() new LambdaQueryWrapper<TriageQueueItem>()
.eq(TriageQueueItem::getTenantId, tenantId) .eq(TriageQueueItem::getTenantId, tenantId)
@@ -278,31 +307,29 @@ public class DoctorStationMainAppServiceImpl implements IDoctorStationMainAppSer
// 使用排除法而非白名单:只要不是"已完成"就可以完诊,覆盖跳过、等待等非标准流转状态 // 使用排除法而非白名单:只要不是"已完成"就可以完诊,覆盖跳过、等待等非标准流转状态
if (queueItem != null && if (queueItem != null &&
!TriageQueueStatus.COMPLETED.getValue().equals(queueItem.getStatus())) { !TriageQueueStatus.COMPLETED.getValue().equals(queueItem.getStatus())) {
// 更新队列状态为已完成
java.time.LocalDateTime nowLocal = java.time.LocalDateTime.now().truncatedTo(ChronoUnit.SECONDS); java.time.LocalDateTime nowLocal = java.time.LocalDateTime.now().truncatedTo(ChronoUnit.SECONDS);
queueItem.setStatus(TriageQueueStatus.COMPLETED.getValue()); queueItem.setStatus(TriageQueueStatus.COMPLETED.getValue());
queueItem.setUpdateTime(nowLocal); queueItem.setUpdateTime(nowLocal);
triageQueueItemService.updateById(queueItem); triageQueueItemService.updateById(queueItem);
// 写入 div_log 审计日志(使用实体+Service替代原生JDBC SQL避免SQL注入风险便于维护
try {
LoginUser loginUser = SecurityUtils.getLoginUser();
DivLog divLog = new DivLog()
.setPoolId(queueItem.getPoolId())
.setSlotId(queueItem.getSlotId())
.setOpUserId(loginUser != null ? loginUser.getUserId() : null)
.setAction("COMPLETE")
.setCreateTime(LocalDateTime.now())
.setUpdateAt(LocalDateTime.now())
.setCreatedAt(LocalDateTime.now());
divLogService.save(divLog);
} catch (Exception e) {
log.error("写入div_log审计日志失败", e);
// 审计日志失败不影响主流程
}
} }
// 3. 更新状态、完成时间以及初复诊标识 // 写入 div_log 审计日志(独立于队列项,确保每次完诊都生成记录)
try {
LoginUser loginUser = SecurityUtils.getLoginUser();
DivLog divLog = new DivLog()
.setPoolId(divPoolId)
.setSlotId(divSlotId)
.setOpUserId(loginUser != null ? loginUser.getUserId() : null)
.setAction("COMPLETE")
.setCreateTime(LocalDateTime.now())
.setUpdateAt(LocalDateTime.now())
.setCreatedAt(LocalDateTime.now());
divLogService.save(divLog);
} catch (Exception e) {
log.error("写入div_log审计日志失败", e);
}
// 4. 更新状态、完成时间以及初复诊标识
Date now = new Date(); Date now = new Date();
int update = encounterMapper.update(null, int update = encounterMapper.update(null,
new LambdaUpdateWrapper<Encounter>() new LambdaUpdateWrapper<Encounter>()
@@ -315,7 +342,7 @@ public class DoctorStationMainAppServiceImpl implements IDoctorStationMainAppSer
if (update <= 0) return R.fail("完诊失败"); if (update <= 0) return R.fail("完诊失败");
// 4. 审计日志sys_oper_log // 5. 审计日志sys_oper_log
try { try {
String username = SecurityUtils.getUsernameSafe(); String username = SecurityUtils.getUsernameSafe();
String sql = "INSERT INTO sys_oper_log " String sql = "INSERT INTO sys_oper_log "

View File

@@ -547,7 +547,7 @@
CI.enterer_id AS requester_id, CI.enterer_id AS requester_id,
CI.entered_date AS request_time, CI.entered_date AS request_time,
CASE WHEN CI.enterer_id = #{practitionerId} THEN '1' ELSE '0' END AS biz_request_flag, CASE WHEN CI.enterer_id = #{practitionerId} THEN '1' ELSE '0' END AS biz_request_flag,
COALESCE(DR.content_json, CI.content_json) AS content_json, DR.content_json AS content_json,
NULL AS skin_test_flag, NULL AS skin_test_flag,
NULL AS inject_flag, NULL AS inject_flag,
NULL AS group_id, NULL AS group_id,