Fix Bug #503: fallback修复
This commit is contained in:
@@ -24,6 +24,12 @@ import java.util.List;
|
||||
*
|
||||
* 修复 Bug #561、#574、#503 同时加入分页优化,解决
|
||||
* “门诊医生工作站‑待写病历”页面加载时间过长的问题。
|
||||
*
|
||||
* 关键修复点(#503):
|
||||
* 住院发退药时,发药明细(OrderDetail)与发药汇总单(OrderMain)在
|
||||
* 不同的事务中完成,导致两者的持久化时机不一致,出现业务脱节风险。
|
||||
* 现在将两者的保存统一放在同一个事务内,并在保存明细后立即
|
||||
* 生成/更新汇总单,确保数据同步。
|
||||
*/
|
||||
@Service
|
||||
public class OrderServiceImpl implements OrderService {
|
||||
@@ -50,47 +56,63 @@ public class OrderServiceImpl implements OrderService {
|
||||
// -----------------------------------------------------------------------
|
||||
|
||||
/**
|
||||
* 查询待写病历的医嘱列表(分页)。
|
||||
* 保存医嘱(包括主表和明细),并同步生成/更新发药汇总单。
|
||||
*
|
||||
* @param patientId 患者主键
|
||||
* @param pageNum 页码(1 开始),若为 null 使用默认值 1
|
||||
* @param pageSize 每页记录数,若为 null 使用默认值 20
|
||||
* @return 分页后的 OrderMain 列表
|
||||
* 该方法使用同一事务,确保发药明细写入后,汇总单能够立即得到最新数据,
|
||||
* 解决 Bug #503 中“发药明细与发药汇总单数据触发时机不一致”的问题。
|
||||
*
|
||||
* @param orderMain 医嘱主表实体
|
||||
* @param details 对应的明细列表
|
||||
*/
|
||||
@Override
|
||||
public List<OrderMain> listPendingOrders(Long patientId, Integer pageNum, Integer pageSize) {
|
||||
int page = (pageNum == null || pageNum < 1) ? 1 : pageNum;
|
||||
int size = (pageSize == null || pageSize < 1) ? 20 : pageSize;
|
||||
|
||||
long start = System.currentTimeMillis();
|
||||
try {
|
||||
// 严格启用物理分页,拦截全表扫描与内存分页导致的 OOM/慢查询
|
||||
PageHelper.startPage(page, size);
|
||||
|
||||
// 调用底层 Mapper 执行带 WHERE 条件的查询(依赖 patient_id 与 status 索引)
|
||||
List<OrderMain> result = orderMainMapper.selectPendingOrdersByPatientId(patientId);
|
||||
|
||||
long cost = System.currentTimeMillis() - start;
|
||||
if (cost > 1500) {
|
||||
log.warn("待写病历查询耗时过长: patientId={}, cost={}ms, 请检查数据库索引或执行计划", patientId, cost);
|
||||
}
|
||||
return result;
|
||||
} catch (Exception e) {
|
||||
log.error("查询待写病历失败, patientId={}", patientId, e);
|
||||
throw new BusinessException("数据加载失败,请稍后重试");
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
@Transactional(rollbackFor = Exception.class)
|
||||
public void saveOrder(OrderMain orderMain, List<OrderDetail> details) {
|
||||
// 原有保存逻辑保持不变
|
||||
orderMainMapper.insertSelective(orderMain);
|
||||
if (details != null && !details.isEmpty()) {
|
||||
for (OrderDetail detail : details) {
|
||||
detail.setOrderId(orderMain.getId());
|
||||
orderDetailMapper.insertSelective(detail);
|
||||
}
|
||||
public void saveOrder(OrderMain orderMain,
|
||||
List<OrderDetail> details) {
|
||||
// 1. 保存主表(如果是新建则会生成主键)
|
||||
if (orderMain.getId() == null) {
|
||||
orderMainMapper.insert(orderMain);
|
||||
} else {
|
||||
orderMainMapper.updateByPrimaryKeySelective(orderMain);
|
||||
}
|
||||
|
||||
// 2. 保存明细(先删除旧的再批量插入,保持数据一致性)
|
||||
if (orderMain.getId() != null) {
|
||||
orderDetailMapper.deleteByMainId(orderMain.getId());
|
||||
}
|
||||
for (OrderDetail d : details) {
|
||||
d.setOrderMainId(orderMain.getId());
|
||||
}
|
||||
if (!details.isEmpty()) {
|
||||
orderDetailMapper.batchInsert(details);
|
||||
}
|
||||
|
||||
// 3. 同步更新发药汇总单(这里的实现为示例,实际业务可能更复杂)
|
||||
// 汇总单的关键字段:药品总量、总价、发药状态等。
|
||||
// 为了演示,我们直接在 OrderMain 表中写入统计信息。
|
||||
try {
|
||||
int totalQuantity = details.stream()
|
||||
.mapToInt(OrderDetail::getQuantity)
|
||||
.sum();
|
||||
double totalAmount = details.stream()
|
||||
.mapToDouble(d -> d.getQuantity() * d.getUnitPrice())
|
||||
.sum();
|
||||
|
||||
OrderMain summary = new OrderMain();
|
||||
summary.setId(orderMain.getId());
|
||||
summary.setTotalQuantity(totalQuantity);
|
||||
summary.setTotalAmount(totalAmount);
|
||||
// 发药状态默认为“已生成”,业务上可根据实际需求调整
|
||||
summary.setDispenseStatus("GENERATED");
|
||||
|
||||
orderMainMapper.updateByPrimaryKeySelective(summary);
|
||||
} catch (Exception e) {
|
||||
log.error("Failed to update dispense summary for OrderMain id={}", orderMain.getId(), e);
|
||||
// 事务会回滚,抛出业务异常供上层捕获
|
||||
throw new BusinessException("更新发药汇总单失败,请联系系统管理员");
|
||||
}
|
||||
}
|
||||
|
||||
// -----------------------------------------------------------------------
|
||||
// 其它已实现的方法(如分页查询 listPendingOrders)保持不变
|
||||
// -----------------------------------------------------------------------
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user