feat(分诊队列): 实现分诊队列核心功能与日志记录
新增分诊队列相关服务接口与实现,包括队列管理、叫号操作和日志记录 添加DivLogService和CallRecordService用于记录分诊操作和叫号历史 在CurrentDayEncounterDto和TriageQueueItem中增加seqNo字段用于显示预约序号 实现分诊操作日志记录功能,包括添加队列、移除队列、叫号、完成等操作 新增CallType枚举定义叫号类型,并实现叫号记录功能 优化队列状态映射逻辑,支持更多状态类型显示
This commit is contained in:
@@ -3,8 +3,14 @@ package com.openhis.web.triageandqueuemanage.appservice.impl;
|
||||
import cn.hutool.core.collection.CollUtil;
|
||||
import cn.hutool.core.util.ObjectUtil;
|
||||
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
|
||||
import com.baomidou.mybatisplus.core.conditions.update.LambdaUpdateWrapper;
|
||||
import com.core.common.core.domain.R;
|
||||
import com.core.common.utils.SecurityUtils;
|
||||
import com.openhis.administration.domain.Encounter;
|
||||
import com.openhis.administration.mapper.EncounterMapper;
|
||||
import com.openhis.common.enums.EncounterStatus;
|
||||
import com.openhis.common.enums.EncounterSubjectStatus;
|
||||
import com.openhis.common.enums.TriageQueueStatus;
|
||||
import com.openhis.triageandqueuemanage.domain.CallRecord;
|
||||
import com.openhis.triageandqueuemanage.domain.DivLog;
|
||||
import com.openhis.triageandqueuemanage.domain.TriageCandidateExclusion;
|
||||
@@ -34,18 +40,8 @@ import java.util.stream.Collectors;
|
||||
@Service
|
||||
public class TriageQueueAppServiceImpl implements TriageQueueAppService {
|
||||
|
||||
/**
|
||||
* 分诊队列状态常量(数字编码)
|
||||
* 0=WAITING(等待中), 10=CALLING(呼叫中), 20=IN_CLINIC(诊中),
|
||||
* 30=COMPLETED(已完成), 40=SKIPPED(已跳过), 50=REFUNDED(已退费), 60=FOLLOW(已随访)
|
||||
*/
|
||||
public static final Integer STATUS_WAITING = 0;
|
||||
public static final Integer STATUS_CALLING = 10;
|
||||
public static final Integer STATUS_IN_CLINIC = 20;
|
||||
public static final Integer STATUS_COMPLETED = 30;
|
||||
public static final Integer STATUS_SKIPPED = 40;
|
||||
public static final Integer STATUS_REFUNDED = 50;
|
||||
public static final Integer STATUS_FOLLOW = 60;
|
||||
// 状态常量已迁移至 TriageQueueStatus 枚举,原硬编码 STATU_WAITING/STATU_CALLING 等已删除,
|
||||
// 避免散落在多个 Service 类中的魔法数字造成不一致
|
||||
|
||||
@Resource
|
||||
private TriageQueueItemService triageQueueItemService;
|
||||
@@ -65,6 +61,9 @@ public class TriageQueueAppServiceImpl implements TriageQueueAppService {
|
||||
@Resource
|
||||
private ScheduleSlotMapper scheduleSlotMapper;
|
||||
|
||||
@Resource
|
||||
private EncounterMapper encounterMapper;
|
||||
|
||||
@Override
|
||||
public R<?> list(Long organizationId, LocalDate date) {
|
||||
Integer tenantId = SecurityUtils.getLoginUser().getTenantId();
|
||||
@@ -75,7 +74,7 @@ public class TriageQueueAppServiceImpl implements TriageQueueAppService {
|
||||
.eq(TriageQueueItem::getTenantId, tenantId)
|
||||
.eq(TriageQueueItem::getQueueDate, qd)
|
||||
.eq(TriageQueueItem::getDeleteFlag, "0")
|
||||
.ne(TriageQueueItem::getStatus, STATUS_COMPLETED)
|
||||
.ne(TriageQueueItem::getStatus, TriageQueueStatus.COMPLETED.getValue())
|
||||
.orderByAsc(TriageQueueItem::getQueueOrder);
|
||||
|
||||
// 如果指定了科室,按科室过滤;否则查询所有科室(全科模式)
|
||||
@@ -98,7 +97,7 @@ public class TriageQueueAppServiceImpl implements TriageQueueAppService {
|
||||
if (list != null && !list.isEmpty()) {
|
||||
int beforeSize = list.size();
|
||||
list = list.stream()
|
||||
.filter(item -> !STATUS_COMPLETED.equals(item.getStatus()))
|
||||
.filter(item -> !TriageQueueStatus.COMPLETED.getValue().equals(item.getStatus()))
|
||||
.collect(java.util.stream.Collectors.toList());
|
||||
}
|
||||
return R.ok(list);
|
||||
@@ -130,7 +129,7 @@ public class TriageQueueAppServiceImpl implements TriageQueueAppService {
|
||||
.eq(TriageQueueItem::getOrganizationId, orgId)
|
||||
.eq(TriageQueueItem::getQueueDate, qd)
|
||||
.eq(TriageQueueItem::getDeleteFlag, "0")
|
||||
.ne(TriageQueueItem::getStatus, STATUS_COMPLETED));
|
||||
.ne(TriageQueueItem::getStatus, TriageQueueStatus.COMPLETED.getValue()));
|
||||
|
||||
int maxOrder = existing.stream().map(TriageQueueItem::getQueueOrder).filter(Objects::nonNull).max(Integer::compareTo).orElse(0);
|
||||
|
||||
@@ -155,7 +154,7 @@ public class TriageQueueAppServiceImpl implements TriageQueueAppService {
|
||||
.setPoolId(it.getPoolId()) // ✅ 号源池ID(用于div_log审计)
|
||||
.setSlotId(it.getSlotId()) // ✅ 号源槽位ID(用于div_log审计)
|
||||
.setSeqNo(it.getSeqNo()) // ✅ 预约序号(用于叫号显示)
|
||||
.setStatus(STATUS_WAITING)
|
||||
.setStatus(TriageQueueStatus.WAITING.getValue())
|
||||
.setQueueOrder(++maxOrder)
|
||||
.setDeleteFlag("0")
|
||||
.setCreateTime(LocalDateTime.now())
|
||||
@@ -285,8 +284,8 @@ public class TriageQueueAppServiceImpl implements TriageQueueAppService {
|
||||
if (selected == null) return R.fail("队列项不存在");
|
||||
|
||||
// 只将"等待"状态的患者转为"叫号中",允许有多个"叫号中"的患者
|
||||
if (STATUS_WAITING.equals(selected.getStatus())) {
|
||||
selected.setStatus(STATUS_CALLING).setUpdateTime(LocalDateTime.now());
|
||||
if (TriageQueueStatus.WAITING.getValue().equals(selected.getStatus())) {
|
||||
selected.setStatus(TriageQueueStatus.CALLING.getValue()).setUpdateTime(LocalDateTime.now());
|
||||
triageQueueItemService.updateById(selected);
|
||||
|
||||
// 叫号后推送 SSE 消息(实时通知显示屏刷新)
|
||||
@@ -295,7 +294,7 @@ public class TriageQueueAppServiceImpl implements TriageQueueAppService {
|
||||
writeDivLog(selected.getPoolId(), selected.getSlotId(), "CALL");
|
||||
writeCallRecord(selected.getId(), selected.getPractitionerId(), CallType.CALL, selected.getRoomNo());
|
||||
return R.ok(true);
|
||||
} else if (STATUS_CALLING.equals(selected.getStatus())) {
|
||||
} else if (TriageQueueStatus.CALLING.getValue().equals(selected.getStatus())) {
|
||||
// 如果已经是"叫号中"状态,直接返回成功(不做任何操作)
|
||||
return R.ok(true);
|
||||
} else {
|
||||
@@ -324,7 +323,7 @@ public class TriageQueueAppServiceImpl implements TriageQueueAppService {
|
||||
return R.fail("队列项不存在");
|
||||
}
|
||||
// 验证状态
|
||||
if (!STATUS_CALLING.equals(calling.getStatus())) {
|
||||
if (!TriageQueueStatus.CALLING.getValue().equals(calling.getStatus())) {
|
||||
return R.fail("只能完成\"叫号中\"状态的患者,当前患者状态为:" + calling.getStatus());
|
||||
}
|
||||
} else {
|
||||
@@ -334,7 +333,7 @@ public class TriageQueueAppServiceImpl implements TriageQueueAppService {
|
||||
LambdaQueryWrapper<TriageQueueItem> callingWrapper = new LambdaQueryWrapper<TriageQueueItem>()
|
||||
.eq(TriageQueueItem::getTenantId, tenantId)
|
||||
.eq(TriageQueueItem::getDeleteFlag, "0")
|
||||
.eq(TriageQueueItem::getStatus, STATUS_CALLING)
|
||||
.eq(TriageQueueItem::getStatus, TriageQueueStatus.CALLING.getValue())
|
||||
.orderByAsc(TriageQueueItem::getQueueOrder)
|
||||
.last("LIMIT 1");
|
||||
|
||||
@@ -353,16 +352,33 @@ public class TriageQueueAppServiceImpl implements TriageQueueAppService {
|
||||
Long actualOrgId = calling.getOrganizationId();
|
||||
|
||||
// 1) 叫号中 -> 完成(移出列表)
|
||||
calling.setStatus(STATUS_COMPLETED).setUpdateTime(LocalDateTime.now());
|
||||
calling.setStatus(TriageQueueStatus.COMPLETED.getValue()).setUpdateTime(LocalDateTime.now());
|
||||
triageQueueItemService.updateById(calling);
|
||||
|
||||
// 同步更新就诊状态为诊毕
|
||||
// 分诊台完诊原只更新队列状态,未同步encounter表,导致与医生站完诊行为不一致
|
||||
if (calling.getEncounterId() != null) {
|
||||
try {
|
||||
java.util.Date now = new java.util.Date();
|
||||
encounterMapper.update(null,
|
||||
new LambdaUpdateWrapper<Encounter>()
|
||||
.eq(Encounter::getId, calling.getEncounterId())
|
||||
.set(Encounter::getStatusEnum, EncounterStatus.DISCHARGED.getValue())
|
||||
.set(Encounter::getSubjectStatusEnum, EncounterSubjectStatus.DEPARTED.getValue())
|
||||
.set(Encounter::getEndTime, now)
|
||||
.set(Encounter::getUpdateTime, now));
|
||||
} catch (Exception e) {
|
||||
log.error("更新就诊状态为诊毕失败, encounterId={}", calling.getEncounterId(), e);
|
||||
}
|
||||
}
|
||||
|
||||
// 2) 自动推进下一个等待为叫号中(同一科室,包含跳过状态,不限制日期)
|
||||
LambdaQueryWrapper<TriageQueueItem> nextWrapper = new LambdaQueryWrapper<TriageQueueItem>()
|
||||
.eq(TriageQueueItem::getTenantId, tenantId)
|
||||
.eq(TriageQueueItem::getDeleteFlag, "0")
|
||||
.and(w -> w.eq(TriageQueueItem::getStatus, STATUS_WAITING)
|
||||
.and(w -> w.eq(TriageQueueItem::getStatus, TriageQueueStatus.WAITING.getValue())
|
||||
.or()
|
||||
.eq(TriageQueueItem::getStatus, STATUS_SKIPPED))
|
||||
.eq(TriageQueueItem::getStatus, TriageQueueStatus.SKIPPED.getValue()))
|
||||
.orderByAsc(TriageQueueItem::getQueueOrder)
|
||||
.last("LIMIT 1");
|
||||
|
||||
@@ -374,7 +390,7 @@ public class TriageQueueAppServiceImpl implements TriageQueueAppService {
|
||||
TriageQueueItem next = triageQueueItemService.getOne(nextWrapper, false);
|
||||
|
||||
if (next != null) {
|
||||
next.setStatus(STATUS_CALLING).setUpdateTime(LocalDateTime.now());
|
||||
next.setStatus(TriageQueueStatus.CALLING.getValue()).setUpdateTime(LocalDateTime.now());
|
||||
triageQueueItemService.updateById(next);
|
||||
}
|
||||
|
||||
@@ -428,7 +444,7 @@ public class TriageQueueAppServiceImpl implements TriageQueueAppService {
|
||||
return R.fail("队列项不存在");
|
||||
}
|
||||
// 验证状态
|
||||
if (!STATUS_CALLING.equals(calling.getStatus())) {
|
||||
if (!TriageQueueStatus.CALLING.getValue().equals(calling.getStatus())) {
|
||||
return R.fail("只能对\"叫号中\"状态的患者进行" + ("SKIP".equals(action) ? "跳过" : "过号重排") + ",当前患者状态为:" + calling.getStatus());
|
||||
}
|
||||
} else {
|
||||
@@ -438,7 +454,7 @@ public class TriageQueueAppServiceImpl implements TriageQueueAppService {
|
||||
LambdaQueryWrapper<TriageQueueItem> callingWrapper = new LambdaQueryWrapper<TriageQueueItem>()
|
||||
.eq(TriageQueueItem::getTenantId, tenantId)
|
||||
.eq(TriageQueueItem::getDeleteFlag, "0")
|
||||
.eq(TriageQueueItem::getStatus, STATUS_CALLING)
|
||||
.eq(TriageQueueItem::getStatus, TriageQueueStatus.CALLING.getValue())
|
||||
.orderByAsc(TriageQueueItem::getQueueOrder)
|
||||
.last("LIMIT 1");
|
||||
|
||||
@@ -458,9 +474,9 @@ public class TriageQueueAppServiceImpl implements TriageQueueAppService {
|
||||
LambdaQueryWrapper<TriageQueueItem> nextWrapper = new LambdaQueryWrapper<TriageQueueItem>()
|
||||
.eq(TriageQueueItem::getTenantId, tenantId)
|
||||
.eq(TriageQueueItem::getDeleteFlag, "0")
|
||||
.and(w -> w.eq(TriageQueueItem::getStatus, STATUS_WAITING)
|
||||
.and(w -> w.eq(TriageQueueItem::getStatus, TriageQueueStatus.WAITING.getValue())
|
||||
.or()
|
||||
.eq(TriageQueueItem::getStatus, STATUS_SKIPPED))
|
||||
.eq(TriageQueueItem::getStatus, TriageQueueStatus.SKIPPED.getValue()))
|
||||
.orderByAsc(TriageQueueItem::getQueueOrder)
|
||||
.last("LIMIT 1");
|
||||
|
||||
@@ -479,7 +495,7 @@ public class TriageQueueAppServiceImpl implements TriageQueueAppService {
|
||||
.eq(TriageQueueItem::getTenantId, tenantId)
|
||||
.eq(TriageQueueItem::getOrganizationId, actualOrgId)
|
||||
.eq(TriageQueueItem::getDeleteFlag, "0")
|
||||
.ne(TriageQueueItem::getStatus, STATUS_COMPLETED))
|
||||
.ne(TriageQueueItem::getStatus, TriageQueueStatus.COMPLETED.getValue()))
|
||||
.stream()
|
||||
.map(TriageQueueItem::getQueueOrder)
|
||||
.filter(Objects::nonNull)
|
||||
@@ -487,11 +503,11 @@ public class TriageQueueAppServiceImpl implements TriageQueueAppService {
|
||||
.orElse(0);
|
||||
|
||||
// 1) 叫号中 -> 跳过,并移到末尾
|
||||
calling.setStatus(STATUS_SKIPPED).setQueueOrder(maxOrder + 1).setUpdateTime(LocalDateTime.now());
|
||||
calling.setStatus(TriageQueueStatus.SKIPPED.getValue()).setQueueOrder(maxOrder + 1).setUpdateTime(LocalDateTime.now());
|
||||
triageQueueItemService.updateById(calling);
|
||||
|
||||
// 2) 自动推进下一个等待为叫号中
|
||||
next.setStatus(STATUS_CALLING).setUpdateTime(LocalDateTime.now());
|
||||
next.setStatus(TriageQueueStatus.CALLING.getValue()).setUpdateTime(LocalDateTime.now());
|
||||
triageQueueItemService.updateById(next);
|
||||
|
||||
recalcOrders(actualOrgId, null);
|
||||
@@ -517,7 +533,7 @@ public class TriageQueueAppServiceImpl implements TriageQueueAppService {
|
||||
return R.fail("队列项不存在");
|
||||
}
|
||||
// 验证状态:必须是"叫号中"状态
|
||||
if (!STATUS_CALLING.equals(calling.getStatus())) {
|
||||
if (!TriageQueueStatus.CALLING.getValue().equals(calling.getStatus())) {
|
||||
return R.fail("只能对\"叫号中\"状态的患者执行\"下一患者\"操作,当前患者状态为:" + calling.getStatus());
|
||||
}
|
||||
} else {
|
||||
@@ -527,7 +543,7 @@ public class TriageQueueAppServiceImpl implements TriageQueueAppService {
|
||||
LambdaQueryWrapper<TriageQueueItem> callingWrapper = new LambdaQueryWrapper<TriageQueueItem>()
|
||||
.eq(TriageQueueItem::getTenantId, tenantId)
|
||||
.eq(TriageQueueItem::getDeleteFlag, "0")
|
||||
.eq(TriageQueueItem::getStatus, STATUS_CALLING)
|
||||
.eq(TriageQueueItem::getStatus, TriageQueueStatus.CALLING.getValue())
|
||||
.orderByAsc(TriageQueueItem::getQueueOrder)
|
||||
.last("LIMIT 1");
|
||||
|
||||
@@ -542,7 +558,7 @@ public class TriageQueueAppServiceImpl implements TriageQueueAppService {
|
||||
|
||||
// 当前叫号中 -> 完成(如果不存在,就当作从头找第一位等待)
|
||||
if (calling != null) {
|
||||
calling.setStatus(STATUS_COMPLETED).setUpdateTime(LocalDateTime.now());
|
||||
calling.setStatus(TriageQueueStatus.COMPLETED.getValue()).setUpdateTime(LocalDateTime.now());
|
||||
triageQueueItemService.updateById(calling);
|
||||
actualOrgId = calling.getOrganizationId(); // 使用叫号中患者所在的科室
|
||||
} else {
|
||||
@@ -557,9 +573,9 @@ public class TriageQueueAppServiceImpl implements TriageQueueAppService {
|
||||
LambdaQueryWrapper<TriageQueueItem> nextWrapper = new LambdaQueryWrapper<TriageQueueItem>()
|
||||
.eq(TriageQueueItem::getTenantId, tenantId)
|
||||
.eq(TriageQueueItem::getDeleteFlag, "0")
|
||||
.and(w -> w.eq(TriageQueueItem::getStatus, STATUS_WAITING)
|
||||
.and(w -> w.eq(TriageQueueItem::getStatus, TriageQueueStatus.WAITING.getValue())
|
||||
.or()
|
||||
.eq(TriageQueueItem::getStatus, STATUS_SKIPPED))
|
||||
.eq(TriageQueueItem::getStatus, TriageQueueStatus.SKIPPED.getValue()))
|
||||
.orderByAsc(TriageQueueItem::getQueueOrder)
|
||||
.last("LIMIT 1");
|
||||
|
||||
@@ -576,7 +592,7 @@ public class TriageQueueAppServiceImpl implements TriageQueueAppService {
|
||||
return R.fail("当前没有等待的患者");
|
||||
}
|
||||
|
||||
next.setStatus(STATUS_CALLING).setUpdateTime(LocalDateTime.now());
|
||||
next.setStatus(TriageQueueStatus.CALLING.getValue()).setUpdateTime(LocalDateTime.now());
|
||||
triageQueueItemService.updateById(next);
|
||||
|
||||
if (next.getOrganizationId() != null) {
|
||||
@@ -598,7 +614,7 @@ public class TriageQueueAppServiceImpl implements TriageQueueAppService {
|
||||
.eq(TriageQueueItem::getTenantId, tenantId)
|
||||
.eq(TriageQueueItem::getOrganizationId, orgId)
|
||||
.eq(TriageQueueItem::getDeleteFlag, "0")
|
||||
.ne(TriageQueueItem::getStatus, STATUS_COMPLETED);
|
||||
.ne(TriageQueueItem::getStatus, TriageQueueStatus.COMPLETED.getValue());
|
||||
// 如果 qd 不为 null,才添加日期限制
|
||||
if (qd != null) {
|
||||
wrapper.eq(TriageQueueItem::getQueueDate, qd);
|
||||
@@ -613,7 +629,7 @@ public class TriageQueueAppServiceImpl implements TriageQueueAppService {
|
||||
.eq(TriageQueueItem::getOrganizationId, orgId)
|
||||
.eq(TriageQueueItem::getQueueDate, qd)
|
||||
.eq(TriageQueueItem::getDeleteFlag, "0")
|
||||
.eq(TriageQueueItem::getStatus, STATUS_CALLING)
|
||||
.eq(TriageQueueItem::getStatus, TriageQueueStatus.CALLING.getValue())
|
||||
.last("LIMIT 1"), false);
|
||||
}
|
||||
|
||||
@@ -658,7 +674,7 @@ public class TriageQueueAppServiceImpl implements TriageQueueAppService {
|
||||
.eq(TriageQueueItem::getQueueDate, qd)
|
||||
.eq(TriageQueueItem::getOrganizationId, organizationId)
|
||||
.eq(TriageQueueItem::getTenantId, tenantId)
|
||||
.in(TriageQueueItem::getStatus, STATUS_WAITING, STATUS_CALLING)
|
||||
.in(TriageQueueItem::getStatus, TriageQueueStatus.WAITING.getValue(), TriageQueueStatus.CALLING.getValue())
|
||||
.eq(TriageQueueItem::getDeleteFlag, "0")
|
||||
.orderByAsc(TriageQueueItem::getQueueOrder)
|
||||
);
|
||||
@@ -677,7 +693,7 @@ public class TriageQueueAppServiceImpl implements TriageQueueAppService {
|
||||
|
||||
// 2. 查找当前叫号中的患者(CALLING 状态)
|
||||
TriageQueueItem callingItem = allItems.stream()
|
||||
.filter(item -> STATUS_CALLING.equals(item.getStatus()))
|
||||
.filter(item -> TriageQueueStatus.CALLING.getValue().equals(item.getStatus()))
|
||||
.findFirst()
|
||||
.orElse(null);
|
||||
|
||||
@@ -742,7 +758,7 @@ public class TriageQueueAppServiceImpl implements TriageQueueAppService {
|
||||
patients.add(patient);
|
||||
|
||||
// 统计等待人数(不包括 CALLING 状态)
|
||||
if (STATUS_WAITING.equals(item.getStatus())) {
|
||||
if (TriageQueueStatus.WAITING.getValue().equals(item.getStatus())) {
|
||||
totalWaiting++;
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user