91 分诊排队管理-》门诊医生站:【完诊】患者队列状态的变化
This commit is contained in:
@@ -1,6 +1,7 @@
|
||||
package com.openhis.web.doctorstation.appservice.impl;
|
||||
|
||||
import cn.hutool.core.util.ObjectUtil;
|
||||
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
|
||||
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
|
||||
import com.baomidou.mybatisplus.core.conditions.update.LambdaUpdateWrapper;
|
||||
import com.baomidou.mybatisplus.core.metadata.IPage;
|
||||
@@ -16,21 +17,23 @@ import com.openhis.common.constant.CommonConstants;
|
||||
import com.openhis.common.enums.*;
|
||||
import com.openhis.common.utils.EnumUtils;
|
||||
import com.openhis.common.utils.HisQueryUtils;
|
||||
import com.openhis.triageandqueuemanage.domain.TriageQueueItem;
|
||||
import com.openhis.triageandqueuemanage.service.TriageQueueItemService;
|
||||
import com.openhis.web.doctorstation.appservice.*;
|
||||
import com.openhis.web.doctorstation.dto.PatientInfoDto;
|
||||
import com.openhis.web.doctorstation.dto.PrescriptionInfoBaseDto;
|
||||
import com.openhis.web.doctorstation.dto.PrescriptionInfoDetailDto;
|
||||
import com.openhis.web.doctorstation.dto.ReceptionStatisticsDto;
|
||||
import com.openhis.web.doctorstation.mapper.DoctorStationMainAppMapper;
|
||||
import lombok.extern.slf4j.Slf4j;
|
||||
import org.springframework.jdbc.core.JdbcTemplate;
|
||||
import org.springframework.stereotype.Service;
|
||||
|
||||
import lombok.extern.slf4j.Slf4j;
|
||||
import org.springframework.transaction.annotation.Transactional;
|
||||
|
||||
import javax.annotation.Resource;
|
||||
import javax.servlet.http.HttpServletRequest;
|
||||
import java.time.LocalDateTime;
|
||||
import java.time.temporal.ChronoUnit;
|
||||
import java.util.*;
|
||||
import java.util.stream.Collectors;
|
||||
|
||||
@@ -64,6 +67,9 @@ public class DoctorStationMainAppServiceImpl implements IDoctorStationMainAppSer
|
||||
|
||||
@Resource
|
||||
private JdbcTemplate jdbcTemplate;
|
||||
|
||||
@Resource
|
||||
private TriageQueueItemService triageQueueItemService;
|
||||
/**
|
||||
* 查询就诊患者信息
|
||||
*
|
||||
@@ -124,14 +130,40 @@ public class DoctorStationMainAppServiceImpl implements IDoctorStationMainAppSer
|
||||
* @return 结果
|
||||
*/
|
||||
@Override
|
||||
@Transactional(rollbackFor = Exception.class)
|
||||
public R<?> receiveEncounter(Long encounterId) {
|
||||
Integer tenantId = SecurityUtils.getLoginUser().getTenantId();
|
||||
String currentUsername = SecurityUtils.getUsername();
|
||||
|
||||
// 检查就诊记录是否存在
|
||||
Encounter encounter = encounterMapper.selectById(encounterId);
|
||||
if (encounter == null) {
|
||||
return R.fail("就诊记录不存在");
|
||||
}
|
||||
|
||||
// 检查患者状态,防止重复接诊
|
||||
Integer currentStatus = encounter.getStatusEnum();
|
||||
if (EncounterStatus.IN_PROGRESS.getValue().equals(currentStatus)) {
|
||||
return R.fail("已接诊,请勿重复点击,已为您刷新");
|
||||
}
|
||||
|
||||
int update = encounterMapper.update(null,
|
||||
new LambdaUpdateWrapper<Encounter>().eq(Encounter::getId, encounterId)
|
||||
.eq(Encounter::getStatusEnum, EncounterStatus.PLANNED.getValue()) // 只更新待诊状态的患者
|
||||
.set(Encounter::getReceptionTime, new Date())
|
||||
.set(Encounter::getStatusEnum, EncounterStatus.IN_PROGRESS.getValue())
|
||||
.set(Encounter::getSubjectStatusEnum, EncounterSubjectStatus.RECEIVING_CARE.getValue()));
|
||||
|
||||
// 如果更新失败,说明状态已被其他医生修改
|
||||
if (update <= 0) {
|
||||
// 重新查询当前状态
|
||||
encounter = encounterMapper.selectById(encounterId);
|
||||
if (EncounterStatus.IN_PROGRESS.getValue().equals(encounter.getStatusEnum())) {
|
||||
return R.fail("已接诊,请勿重复接诊");
|
||||
}
|
||||
return R.fail("接诊失败,请刷新后重试");
|
||||
}
|
||||
|
||||
// 先把之前的接诊记录更新为已完成
|
||||
iEncounterParticipantService.update(new LambdaUpdateWrapper<EncounterParticipant>()
|
||||
.eq(EncounterParticipant::getTypeCode, ParticipantType.ADMITTER.getCode())
|
||||
@@ -148,7 +180,28 @@ public class DoctorStationMainAppServiceImpl implements IDoctorStationMainAppSer
|
||||
encounterParticipant.setCreateBy(currentUsername);
|
||||
encounterParticipant.setCreateTime(new Date());
|
||||
iEncounterParticipantService.save(encounterParticipant);
|
||||
return update > 0 ? R.ok() : R.fail();
|
||||
|
||||
// 更新 triage_queue_item 队列记录状态为 CALLING
|
||||
try {
|
||||
TriageQueueItem queueItem = triageQueueItemService.getOne(
|
||||
new LambdaQueryWrapper<TriageQueueItem>()
|
||||
.eq(TriageQueueItem::getTenantId, tenantId)
|
||||
.eq(TriageQueueItem::getEncounterId, encounterId)
|
||||
.eq(TriageQueueItem::getDeleteFlag, "0")
|
||||
);
|
||||
if (queueItem != null) {
|
||||
queueItem.setStatus("CALLING");
|
||||
queueItem.setUpdateTime(LocalDateTime.now().truncatedTo(ChronoUnit.SECONDS));
|
||||
triageQueueItemService.updateById(queueItem);
|
||||
log.info("接诊时更新队列状态为CALLING,encounterId={}, queueItemId={}", encounterId, queueItem.getId());
|
||||
} else {
|
||||
log.warn("接诊时未找到队列记录,encounterId={}", encounterId);
|
||||
}
|
||||
} catch (Exception e) {
|
||||
log.error("接诊时更新队列状态失败,encounterId={}", encounterId, e);
|
||||
}
|
||||
|
||||
return R.ok();
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -181,11 +234,54 @@ public class DoctorStationMainAppServiceImpl implements IDoctorStationMainAppSer
|
||||
return R.fail("就诊记录不存在");
|
||||
}
|
||||
|
||||
if (!EncounterStatus.IN_PROGRESS.getValue().equals(encounter.getStatusEnum())) {
|
||||
return R.fail("当前患者不在就诊中状态");
|
||||
// 检查患者状态,防止重复完诊
|
||||
Integer currentStatus = encounter.getStatusEnum();
|
||||
if (EncounterStatus.DISCHARGED.getValue().equals(currentStatus) ||
|
||||
EncounterStatus.COMPLETED.getValue().equals(currentStatus)) {
|
||||
// 患者已完成就诊,返回特定提示
|
||||
return R.fail("患者已完成就诊,已为您自动刷新患者列表");
|
||||
}
|
||||
|
||||
// 2. 更新状态、完成时间以及初复诊标识
|
||||
if (!EncounterStatus.IN_PROGRESS.getValue().equals(currentStatus)) {
|
||||
return R.fail("非就诊中患者不能完诊");
|
||||
}
|
||||
|
||||
// 2. 查找队列项
|
||||
Integer tenantId = SecurityUtils.getLoginUser().getTenantId();
|
||||
TriageQueueItem queueItem = triageQueueItemService.getOne(
|
||||
new LambdaQueryWrapper<TriageQueueItem>()
|
||||
.eq(TriageQueueItem::getTenantId, tenantId)
|
||||
.eq(TriageQueueItem::getEncounterId, encounterId)
|
||||
.eq(TriageQueueItem::getDeleteFlag, "0")
|
||||
);
|
||||
|
||||
// 如果队列项存在,检查状态并更新
|
||||
if (queueItem != null && "CALLING".equals(queueItem.getStatus())) {
|
||||
// 更新队列状态为已完成
|
||||
java.time.LocalDateTime nowLocal = java.time.LocalDateTime.now().truncatedTo(ChronoUnit.SECONDS);
|
||||
queueItem.setStatus("COMPLETED");
|
||||
queueItem.setUpdateTime(nowLocal);
|
||||
triageQueueItemService.updateById(queueItem);
|
||||
|
||||
// 写入 div_log 审计日志
|
||||
try {
|
||||
Long userId = SecurityUtils.getLoginUser().getUserId();
|
||||
String divLogSql = "INSERT INTO hisdev.div_log "
|
||||
+ "(pool_id, slot_id, queue_no, op_user_id, action, create_time) "
|
||||
+ "VALUES (?, ?, ?, ?, 'COMPLETE', NOW()::timestamp(0))";
|
||||
|
||||
jdbcTemplate.update(divLogSql,
|
||||
queueItem.getOrganizationId(), // pool_id: 候选池ID(科室)
|
||||
queueItem.getPractitionerId(), // slot_id: 槽位ID(医生)
|
||||
queueItem.getQueueOrder(), // queue_no: 队列号
|
||||
userId); // op_user_id: 操作用户ID
|
||||
} catch (Exception e) {
|
||||
log.error("写入div_log审计日志失败", e);
|
||||
// 审计日志失败不影响主流程
|
||||
}
|
||||
}
|
||||
|
||||
// 3. 更新状态、完成时间以及初复诊标识
|
||||
Date now = new Date();
|
||||
int update = encounterMapper.update(null,
|
||||
new LambdaUpdateWrapper<Encounter>()
|
||||
@@ -198,7 +294,7 @@ public class DoctorStationMainAppServiceImpl implements IDoctorStationMainAppSer
|
||||
|
||||
if (update <= 0) return R.fail("完诊失败");
|
||||
|
||||
// 3. 审计日志
|
||||
// 4. 审计日志(sys_oper_log)
|
||||
try {
|
||||
String username = SecurityUtils.getUsernameSafe();
|
||||
String sql = "INSERT INTO sys_oper_log "
|
||||
|
||||
@@ -55,6 +55,8 @@ import com.openhis.web.paymentmanage.dto.CancelPaymentDto;
|
||||
import com.openhis.web.paymentmanage.dto.Clinic2207OrderResultDto;
|
||||
import com.openhis.web.paymentmanage.mapper.PaymentMapper;
|
||||
import com.openhis.web.personalization.dto.ActivityDeviceDto;
|
||||
import com.openhis.triageandqueuemanage.domain.TriageQueueItem;
|
||||
import com.openhis.triageandqueuemanage.service.TriageQueueItemService;
|
||||
import com.openhis.workflow.domain.ServiceRequest;
|
||||
import com.openhis.workflow.service.IDeviceDispenseService;
|
||||
import com.openhis.workflow.service.IDeviceRequestService;
|
||||
@@ -81,9 +83,11 @@ import javax.annotation.Resource;
|
||||
import javax.servlet.http.HttpServletRequest;
|
||||
import java.math.BigDecimal;
|
||||
import java.math.RoundingMode;
|
||||
import java.time.LocalDate;
|
||||
import java.time.LocalDateTime;
|
||||
import java.time.ZoneId;
|
||||
import java.time.format.DateTimeFormatter;
|
||||
import java.time.temporal.ChronoUnit;
|
||||
import java.util.*;
|
||||
import java.util.stream.Collectors;
|
||||
|
||||
@@ -149,6 +153,8 @@ public class PaymentRecServiceImpl implements IPaymentRecService {
|
||||
@Resource
|
||||
private OutpatientRegistrationAppMapper outpatientRegistrationAppMapper;
|
||||
@Resource
|
||||
private TriageQueueItemService triageQueueItemService;
|
||||
@Resource
|
||||
private IRegService iRegService;
|
||||
@Resource
|
||||
private IPatientService iPatientService;
|
||||
@@ -1928,6 +1934,80 @@ public class PaymentRecServiceImpl implements IPaymentRecService {
|
||||
|
||||
// 就诊ID
|
||||
Long encounterId = iEncounterService.saveEncounterByRegister(encounter);
|
||||
|
||||
// 创建 triage_queue_item 队列记录
|
||||
try {
|
||||
Integer tenantId = encounter.getTenantId() != null ? encounter.getTenantId() : SecurityUtils.getLoginUser().getTenantId();
|
||||
LocalDate queueDate = LocalDate.now();
|
||||
|
||||
// 查询当前科室当天的最大排队序号
|
||||
Integer maxOrder = triageQueueItemService.list(
|
||||
new LambdaQueryWrapper<TriageQueueItem>()
|
||||
.eq(TriageQueueItem::getTenantId, tenantId)
|
||||
.eq(TriageQueueItem::getOrganizationId, encounter.getOrganizationId())
|
||||
.eq(TriageQueueItem::getQueueDate, queueDate)
|
||||
.eq(TriageQueueItem::getDeleteFlag, "0")
|
||||
.ne(TriageQueueItem::getStatus, "COMPLETED")
|
||||
).stream()
|
||||
.map(TriageQueueItem::getQueueOrder)
|
||||
.filter(Objects::nonNull)
|
||||
.max(Integer::compareTo)
|
||||
.orElse(0);
|
||||
|
||||
// 获取患者信息
|
||||
Patient patient = iPatientService.getById(encounter.getPatientId());
|
||||
String patientName = patient != null ? patient.getName() : null;
|
||||
|
||||
// 获取挂号医生信息
|
||||
String practitionerName = null;
|
||||
Long queuePractitionerId = null;
|
||||
if (encounterParticipantFormData.getPractitionerId() != null) {
|
||||
Practitioner practitioner = iPractitionerService.getById(encounterParticipantFormData.getPractitionerId());
|
||||
if (practitioner != null) {
|
||||
practitionerName = practitioner.getName();
|
||||
queuePractitionerId = practitioner.getId();
|
||||
}
|
||||
}
|
||||
|
||||
// 获取科室信息
|
||||
Organization organization = iOrganizationService.getById(encounter.getOrganizationId());
|
||||
String organizationName = organization != null ? organization.getName() : null;
|
||||
|
||||
// 获取服务项目信息(挂号类型)
|
||||
String healthcareName = null;
|
||||
if (encounter.getServiceTypeId() != null) {
|
||||
HealthcareService healthcareService = healthcareServiceService.getById(encounter.getServiceTypeId());
|
||||
if (healthcareService != null) {
|
||||
healthcareName = healthcareService.getName();
|
||||
}
|
||||
}
|
||||
|
||||
// 创建队列项
|
||||
TriageQueueItem queueItem = new TriageQueueItem()
|
||||
.setTenantId(tenantId)
|
||||
.setQueueDate(queueDate)
|
||||
.setOrganizationId(encounter.getOrganizationId())
|
||||
.setOrganizationName(organizationName)
|
||||
.setEncounterId(encounterId)
|
||||
.setPatientId(encounter.getPatientId())
|
||||
.setPatientName(patientName)
|
||||
.setHealthcareName(healthcareName)
|
||||
.setPractitionerId(queuePractitionerId)
|
||||
.setPractitionerName(practitionerName)
|
||||
.setRoomNo(null)
|
||||
.setStatus("WAITING")
|
||||
.setQueueOrder(maxOrder + 1)
|
||||
.setDeleteFlag("0")
|
||||
.setCreateTime(LocalDateTime.now().truncatedTo(ChronoUnit.SECONDS))
|
||||
.setUpdateTime(LocalDateTime.now().truncatedTo(ChronoUnit.SECONDS));
|
||||
|
||||
triageQueueItemService.save(queueItem);
|
||||
logger.info("挂号时创建队列记录成功,encounterId={}, queueItemId={}", encounterId, queueItem.getId());
|
||||
} catch (Exception e) {
|
||||
logger.error("挂号时创建队列记录失败,encounterId={}", encounterId, e);
|
||||
// 队列记录创建失败不影响挂号流程
|
||||
}
|
||||
|
||||
// 保存就诊位置信息
|
||||
// 挂号时不选Location了
|
||||
// encounterLocationFormData.setEncounterId(encounterId);
|
||||
|
||||
@@ -140,6 +140,12 @@ function handleReceive(row) {
|
||||
// }
|
||||
receiveEncounter(row.encounterId).then(() => {
|
||||
emits('toCurrent', row);
|
||||
}).catch(error => {
|
||||
// 如果接诊失败,检查是否是"已接诊"的错误
|
||||
if (error && error.message && error.message.includes('已接诊')) {
|
||||
// 自动刷新列表,移除已接诊的患者
|
||||
getPatientList();
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
|
||||
@@ -168,7 +168,7 @@
|
||||
<div class="overlay" :class="{ 'overlay-disabled': disabled }" v-if="disabled"></div>
|
||||
</div>
|
||||
</div>
|
||||
<el-drawer v-model="drawer" title="患者队列" direction="ltr" @open="handleOpen">
|
||||
<el-drawer v-model="drawer" title="患者队列" direction="ltr" @open="handleOpen" @closed="handleDrawerClosed">
|
||||
<PatientList ref="patientDrawerRef" @toCurrent="handleReceive" />
|
||||
</el-drawer>
|
||||
<RefundListDialog :open="openRefundListDialog" :encounterId="currentEncounterId"
|
||||
@@ -562,6 +562,13 @@ function handleOpen() {
|
||||
patientDrawerRef.value.refreshList();
|
||||
}
|
||||
|
||||
function handleDrawerClosed() {
|
||||
// 关闭患者队列抽屉时,刷新现诊患者列表和待诊患者数量
|
||||
// 这样可以确保如果有其他医生接诊了患者,当前医生能看到最新状态
|
||||
getPatientList();
|
||||
getWaitPatient();
|
||||
}
|
||||
|
||||
function handleCardClick(item, index) {
|
||||
console.log('handleCardClick 被调用');
|
||||
console.log('点击的患者项目:', item);
|
||||
@@ -709,6 +716,12 @@ async function handleFinish(encounterId) {
|
||||
firstEnum.value = 1; // 重置为初诊
|
||||
getPatientList();
|
||||
}
|
||||
}).catch(error => {
|
||||
// 如果完诊失败,检查是否是"已完成"的错误
|
||||
if (error && error.message && (error.message.includes('已完成') || error.message.includes('完诊'))) {
|
||||
// 自动刷新现诊患者列表
|
||||
getPatientList();
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user