401
门诊完诊审计日志错误:div_log 表中 pool_id 与 slot_id 存值与设计规范不符 400 门诊医生站点击【完诊】后,triage_queue_item 表 status 字段未按规范更新为 30 393 疾病报告管理-报告卡管理:状态为“审核失败”的报卡操作列缺失“审核”按钮 369 【住院管理】进入护理记录模块报错 361 三测单(体温单)住院第一日显示 1970-01-01,未正确获取入院日期
This commit is contained in:
@@ -153,4 +153,16 @@ public class CurrentDayEncounterDto {
|
|||||||
*/
|
*/
|
||||||
private Boolean isFromAppointment;
|
private Boolean isFromAppointment;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 号源槽位ID(关联 adm_schedule_slot.id)
|
||||||
|
*/
|
||||||
|
@JsonSerialize(using = ToStringSerializer.class)
|
||||||
|
private Long slotId;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 号源池ID(关联 adm_schedule_pool.id)
|
||||||
|
*/
|
||||||
|
@JsonSerialize(using = ToStringSerializer.class)
|
||||||
|
private Long poolId;
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -188,7 +188,7 @@ public class DoctorStationMainAppServiceImpl implements IDoctorStationMainAppSer
|
|||||||
encounterParticipant.setCreateTime(new Date());
|
encounterParticipant.setCreateTime(new Date());
|
||||||
iEncounterParticipantService.save(encounterParticipant);
|
iEncounterParticipantService.save(encounterParticipant);
|
||||||
|
|
||||||
// 更新 triage_queue_item 队列记录状态为 CALLING
|
// 更新 triage_queue_item 队列记录状态为 IN_CLINIC(诊中)
|
||||||
try {
|
try {
|
||||||
TriageQueueItem queueItem = triageQueueItemService.getOne(
|
TriageQueueItem queueItem = triageQueueItemService.getOne(
|
||||||
new LambdaQueryWrapper<TriageQueueItem>()
|
new LambdaQueryWrapper<TriageQueueItem>()
|
||||||
@@ -197,10 +197,10 @@ public class DoctorStationMainAppServiceImpl implements IDoctorStationMainAppSer
|
|||||||
.eq(TriageQueueItem::getDeleteFlag, "0")
|
.eq(TriageQueueItem::getDeleteFlag, "0")
|
||||||
);
|
);
|
||||||
if (queueItem != null) {
|
if (queueItem != null) {
|
||||||
queueItem.setStatus("CALLING");
|
queueItem.setStatus(20); // 20=IN_CLINIC(诊中),患者进入诊室接诊
|
||||||
queueItem.setUpdateTime(LocalDateTime.now().truncatedTo(ChronoUnit.SECONDS));
|
queueItem.setUpdateTime(LocalDateTime.now().truncatedTo(ChronoUnit.SECONDS));
|
||||||
triageQueueItemService.updateById(queueItem);
|
triageQueueItemService.updateById(queueItem);
|
||||||
log.info("接诊时更新队列状态为CALLING,encounterId={}, queueItemId={}", encounterId, queueItem.getId());
|
log.info("接诊时更新队列状态为IN_CLINIC(诊中),encounterId={}, queueItemId={}", encounterId, queueItem.getId());
|
||||||
} else {
|
} else {
|
||||||
log.warn("接诊时未找到队列记录,encounterId={}", encounterId);
|
log.warn("接诊时未找到队列记录,encounterId={}", encounterId);
|
||||||
}
|
}
|
||||||
@@ -263,10 +263,13 @@ public class DoctorStationMainAppServiceImpl implements IDoctorStationMainAppSer
|
|||||||
);
|
);
|
||||||
|
|
||||||
// 如果队列项存在,检查状态并更新
|
// 如果队列项存在,检查状态并更新
|
||||||
if (queueItem != null && "CALLING".equals(queueItem.getStatus())) {
|
// 允许从 CALLING(10) 或 IN_CLINIC(20) 完成就诊
|
||||||
|
if (queueItem != null &&
|
||||||
|
(Integer.valueOf(10).equals(queueItem.getStatus()) ||
|
||||||
|
Integer.valueOf(20).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("COMPLETED");
|
queueItem.setStatus(30); // 30=COMPLETED(已完成)
|
||||||
queueItem.setUpdateTime(nowLocal);
|
queueItem.setUpdateTime(nowLocal);
|
||||||
triageQueueItemService.updateById(queueItem);
|
triageQueueItemService.updateById(queueItem);
|
||||||
|
|
||||||
@@ -275,13 +278,15 @@ public class DoctorStationMainAppServiceImpl implements IDoctorStationMainAppSer
|
|||||||
Long userId = SecurityUtils.getLoginUser().getUserId();
|
Long userId = SecurityUtils.getLoginUser().getUserId();
|
||||||
String divLogSql = "INSERT INTO hisdev.div_log "
|
String divLogSql = "INSERT INTO hisdev.div_log "
|
||||||
+ "(pool_id, slot_id, queue_no, op_user_id, action, create_time) "
|
+ "(pool_id, slot_id, queue_no, op_user_id, action, create_time) "
|
||||||
+ "VALUES (?, ?, ?, ?, 'COMPLETE', NOW()::timestamp(0))";
|
+ "VALUES (?, ?, ?, ?, 30, NOW()::timestamp(0))";
|
||||||
|
// action=30 表示 COMPLETED(已完成),与 triage_queue_item.status 数字编码保持一致
|
||||||
|
// 0=WAITING, 10=CALLING, 20=IN_CLINIC, 30=COMPLETED, 40=SKIPPED, 50=REFUNDED, 60=FOLLOW
|
||||||
|
|
||||||
jdbcTemplate.update(divLogSql,
|
jdbcTemplate.update(divLogSql,
|
||||||
queueItem.getOrganizationId(), // pool_id: 候选池ID(科室)
|
queueItem.getPoolId(), // pool_id: 号源池ID(来自 adm_schedule_pool.id)
|
||||||
queueItem.getPractitionerId(), // slot_id: 槽位ID(医生)
|
queueItem.getSlotId(), // slot_id: 号源槽位ID(来自 adm_schedule_slot.id)
|
||||||
queueItem.getQueueOrder(), // queue_no: 队列号
|
queueItem.getQueueOrder(), // queue_no: 队列序号
|
||||||
userId); // op_user_id: 操作用户ID
|
userId); // op_user_id: 操作用户ID
|
||||||
} catch (Exception e) {
|
} catch (Exception e) {
|
||||||
log.error("写入div_log审计日志失败", e);
|
log.error("写入div_log审计日志失败", e);
|
||||||
// 审计日志失败不影响主流程
|
// 审计日志失败不影响主流程
|
||||||
|
|||||||
@@ -73,9 +73,21 @@ public class VitalSignsAppServiceImpl implements IVitalSignsAppService {
|
|||||||
|
|
||||||
VitalSignsMedicalRecordDto medicalRecord = new VitalSignsMedicalRecordDto();
|
VitalSignsMedicalRecordDto medicalRecord = new VitalSignsMedicalRecordDto();
|
||||||
|
|
||||||
// 处理日期
|
// 处理出院日期
|
||||||
if (!vitalSignsInfoPage.getRecords().isEmpty()) {
|
if (!vitalSignsInfoPage.getRecords().isEmpty()) {
|
||||||
medicalRecord.setHospDate(vitalSignsInfoPage.getRecords().get(0).getRecordingDate());
|
// 从第一条记录获取出院日期(如果存在)
|
||||||
|
Date dischargeDate = vitalSignsInfoPage.getRecords().get(0).getDischargeDate();
|
||||||
|
if (dischargeDate != null) {
|
||||||
|
medicalRecord.setOutdate(TimeUtils.dateToDateString(dischargeDate));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// 处理住院日期:优先使用第一条记录中的入院日期,如果没有则保持 null 让前端 fallback
|
||||||
|
if (!vitalSignsInfoPage.getRecords().isEmpty()) {
|
||||||
|
Date admissionDate = vitalSignsInfoPage.getRecords().get(0).getAdmissionDate();
|
||||||
|
if (admissionDate != null) {
|
||||||
|
medicalRecord.setHospDate(admissionDate);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// 处理生命体征数据
|
// 处理生命体征数据
|
||||||
|
|||||||
@@ -57,6 +57,10 @@ import com.openhis.web.paymentmanage.mapper.PaymentMapper;
|
|||||||
import com.openhis.web.personalization.dto.ActivityDeviceDto;
|
import com.openhis.web.personalization.dto.ActivityDeviceDto;
|
||||||
import com.openhis.triageandqueuemanage.domain.TriageQueueItem;
|
import com.openhis.triageandqueuemanage.domain.TriageQueueItem;
|
||||||
import com.openhis.triageandqueuemanage.service.TriageQueueItemService;
|
import com.openhis.triageandqueuemanage.service.TriageQueueItemService;
|
||||||
|
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.workflow.domain.ServiceRequest;
|
import com.openhis.workflow.domain.ServiceRequest;
|
||||||
import com.openhis.workflow.service.IDeviceDispenseService;
|
import com.openhis.workflow.service.IDeviceDispenseService;
|
||||||
import com.openhis.workflow.service.IDeviceRequestService;
|
import com.openhis.workflow.service.IDeviceRequestService;
|
||||||
@@ -70,6 +74,7 @@ import com.openhis.yb.service.IClinicSettleService;
|
|||||||
import com.openhis.yb.service.IInpatientSettleService;
|
import com.openhis.yb.service.IInpatientSettleService;
|
||||||
import com.openhis.yb.service.IRegService;
|
import com.openhis.yb.service.IRegService;
|
||||||
import com.openhis.yb.service.YbManager;
|
import com.openhis.yb.service.YbManager;
|
||||||
|
import com.openhis.web.triageandqueuemanage.appservice.impl.TriageQueueAppServiceImpl;
|
||||||
import lombok.extern.slf4j.Slf4j;
|
import lombok.extern.slf4j.Slf4j;
|
||||||
import org.apache.commons.lang3.StringUtils;
|
import org.apache.commons.lang3.StringUtils;
|
||||||
import org.apache.poi.util.StringUtil;
|
import org.apache.poi.util.StringUtil;
|
||||||
@@ -186,6 +191,10 @@ public class PaymentRecServiceImpl implements IPaymentRecService {
|
|||||||
private YbManager ybManager;
|
private YbManager ybManager;
|
||||||
@Autowired
|
@Autowired
|
||||||
private RedisCache redisCache;
|
private RedisCache redisCache;
|
||||||
|
@Autowired
|
||||||
|
private IOrderService iOrderService;
|
||||||
|
@Autowired
|
||||||
|
private ScheduleSlotMapper scheduleSlotMapper;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 【门诊预结算】
|
* 【门诊预结算】
|
||||||
@@ -1985,6 +1994,31 @@ public class PaymentRecServiceImpl implements IPaymentRecService {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// 创建队列项
|
// 创建队列项
|
||||||
|
// 尝试获取预约订单的 slot_id 和 pool_id
|
||||||
|
Long queuePoolId = null;
|
||||||
|
Long queueSlotId = null;
|
||||||
|
try {
|
||||||
|
// 查询患者当天的待签到预约订单(status = 1 或 2 表示已预约或已取号)
|
||||||
|
Order order = iOrderService.getOne(
|
||||||
|
new LambdaQueryWrapper<Order>()
|
||||||
|
.eq(Order::getPatientId, encounter.getPatientId())
|
||||||
|
.in(Order::getStatus, 1, 2) // 1=BOOKED 已预约, 2=CHECKED_IN 已取号
|
||||||
|
.eq(Order::getDeleteFlag, "0")
|
||||||
|
.orderByDesc(Order::getCreateTime)
|
||||||
|
.last("LIMIT 1")
|
||||||
|
);
|
||||||
|
if (order != null && order.getSlotId() != null) {
|
||||||
|
queueSlotId = order.getSlotId();
|
||||||
|
// 通过 slot_id 获取 pool_id
|
||||||
|
ScheduleSlot slot = scheduleSlotMapper.selectById(queueSlotId);
|
||||||
|
if (slot != null) {
|
||||||
|
queuePoolId = slot.getPoolId();
|
||||||
|
}
|
||||||
|
logger.info("挂号时找到预约订单,slotId={}, poolId={}, encounterId={}", queueSlotId, queuePoolId, encounterId);
|
||||||
|
}
|
||||||
|
} catch (Exception e) {
|
||||||
|
logger.warn("查询预约订单失败,不影响挂号流程,encounterId={}", encounterId, e);
|
||||||
|
}
|
||||||
TriageQueueItem queueItem = new TriageQueueItem()
|
TriageQueueItem queueItem = new TriageQueueItem()
|
||||||
.setTenantId(tenantId)
|
.setTenantId(tenantId)
|
||||||
.setQueueDate(queueDate)
|
.setQueueDate(queueDate)
|
||||||
@@ -1997,7 +2031,9 @@ public class PaymentRecServiceImpl implements IPaymentRecService {
|
|||||||
.setPractitionerId(queuePractitionerId)
|
.setPractitionerId(queuePractitionerId)
|
||||||
.setPractitionerName(practitionerName)
|
.setPractitionerName(practitionerName)
|
||||||
.setRoomNo(null)
|
.setRoomNo(null)
|
||||||
.setStatus("WAITING")
|
.setPoolId(queuePoolId)
|
||||||
|
.setSlotId(queueSlotId)
|
||||||
|
.setStatus(TriageQueueAppServiceImpl.STATUS_WAITING) // 0=WAITING(等待中)
|
||||||
.setQueueOrder(maxOrder + 1)
|
.setQueueOrder(maxOrder + 1)
|
||||||
.setDeleteFlag("0")
|
.setDeleteFlag("0")
|
||||||
.setCreateTime(LocalDateTime.now().truncatedTo(ChronoUnit.SECONDS))
|
.setCreateTime(LocalDateTime.now().truncatedTo(ChronoUnit.SECONDS))
|
||||||
|
|||||||
@@ -5,16 +5,12 @@ import cn.hutool.core.util.ObjectUtil;
|
|||||||
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
|
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
|
||||||
import com.core.common.core.domain.R;
|
import com.core.common.core.domain.R;
|
||||||
import com.core.common.utils.SecurityUtils;
|
import com.core.common.utils.SecurityUtils;
|
||||||
import com.openhis.triageandqueuemanage.domain.TriageQueueItem;
|
|
||||||
import com.openhis.triageandqueuemanage.domain.TriageCandidateExclusion;
|
import com.openhis.triageandqueuemanage.domain.TriageCandidateExclusion;
|
||||||
import com.openhis.triageandqueuemanage.service.TriageQueueItemService;
|
import com.openhis.triageandqueuemanage.domain.TriageQueueItem;
|
||||||
import com.openhis.triageandqueuemanage.service.TriageCandidateExclusionService;
|
import com.openhis.triageandqueuemanage.service.TriageCandidateExclusionService;
|
||||||
|
import com.openhis.triageandqueuemanage.service.TriageQueueItemService;
|
||||||
import com.openhis.web.triageandqueuemanage.appservice.TriageQueueAppService;
|
import com.openhis.web.triageandqueuemanage.appservice.TriageQueueAppService;
|
||||||
import com.openhis.web.triageandqueuemanage.dto.CallNumberDisplayResp;
|
import com.openhis.web.triageandqueuemanage.dto.*;
|
||||||
import com.openhis.web.triageandqueuemanage.dto.TriageQueueActionReq;
|
|
||||||
import com.openhis.web.triageandqueuemanage.dto.TriageQueueAddReq;
|
|
||||||
import com.openhis.web.triageandqueuemanage.dto.TriageQueueAdjustReq;
|
|
||||||
import com.openhis.web.triageandqueuemanage.dto.TriageQueueEncounterItem;
|
|
||||||
import com.openhis.web.triageandqueuemanage.sse.CallNumberSseManager;
|
import com.openhis.web.triageandqueuemanage.sse.CallNumberSseManager;
|
||||||
import org.springframework.stereotype.Service;
|
import org.springframework.stereotype.Service;
|
||||||
import org.springframework.transaction.annotation.Transactional;
|
import org.springframework.transaction.annotation.Transactional;
|
||||||
@@ -28,10 +24,18 @@ import java.util.stream.Collectors;
|
|||||||
@Service
|
@Service
|
||||||
public class TriageQueueAppServiceImpl implements TriageQueueAppService {
|
public class TriageQueueAppServiceImpl implements TriageQueueAppService {
|
||||||
|
|
||||||
private static final String STATUS_WAITING = "WAITING";
|
/**
|
||||||
private static final String STATUS_CALLING = "CALLING";
|
* 分诊队列状态常量(数字编码)
|
||||||
private static final String STATUS_SKIPPED = "SKIPPED";
|
* 0=WAITING(等待中), 10=CALLING(呼叫中), 20=IN_CLINIC(诊中),
|
||||||
private static final String STATUS_COMPLETED = "COMPLETED";
|
* 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;
|
||||||
|
|
||||||
@Resource
|
@Resource
|
||||||
private TriageQueueItemService triageQueueItemService;
|
private TriageQueueItemService triageQueueItemService;
|
||||||
@@ -127,6 +131,8 @@ public class TriageQueueAppServiceImpl implements TriageQueueAppService {
|
|||||||
.setPractitionerName(it.getPractitionerName())
|
.setPractitionerName(it.getPractitionerName())
|
||||||
.setPractitionerId(it.getPractitionerId()) // ✅ 新增字段(可选)
|
.setPractitionerId(it.getPractitionerId()) // ✅ 新增字段(可选)
|
||||||
.setRoomNo(it.getRoomNo()) // ✅ 新增字段(可选)
|
.setRoomNo(it.getRoomNo()) // ✅ 新增字段(可选)
|
||||||
|
.setPoolId(it.getPoolId()) // ✅ 号源池ID(用于div_log审计)
|
||||||
|
.setSlotId(it.getSlotId()) // ✅ 号源槽位ID(用于div_log审计)
|
||||||
.setStatus(STATUS_WAITING)
|
.setStatus(STATUS_WAITING)
|
||||||
.setQueueOrder(++maxOrder)
|
.setQueueOrder(++maxOrder)
|
||||||
.setDeleteFlag("0")
|
.setDeleteFlag("0")
|
||||||
|
|||||||
@@ -59,7 +59,7 @@ public class CallNumberDisplayResp {
|
|||||||
/** 患者姓名(脱敏) */
|
/** 患者姓名(脱敏) */
|
||||||
private String name;
|
private String name;
|
||||||
/** 状态:CALLING=就诊中,WAITING=等待 */
|
/** 状态:CALLING=就诊中,WAITING=等待 */
|
||||||
private String status;
|
private Integer status;
|
||||||
/** 排队号 */
|
/** 排队号 */
|
||||||
private Integer queueOrder;
|
private Integer queueOrder;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -15,6 +15,10 @@ public class TriageQueueEncounterItem {
|
|||||||
private Long practitionerId;
|
private Long practitionerId;
|
||||||
/** 诊室号(可选) */
|
/** 诊室号(可选) */
|
||||||
private String roomNo;
|
private String roomNo;
|
||||||
|
/** 号源池ID(关联 adm_schedule_pool.id,用于 div_log 审计日志) */
|
||||||
|
private Long poolId;
|
||||||
|
/** 号源槽位ID(关联 adm_schedule_slot.id,用于 div_log 审计日志) */
|
||||||
|
private Long slotId;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|||||||
@@ -68,7 +68,9 @@
|
|||||||
T9.picture_url AS pictureUrl,
|
T9.picture_url AS pictureUrl,
|
||||||
T9.birth_date AS birthDate,
|
T9.birth_date AS birthDate,
|
||||||
COALESCE(T9.identifier_no, T9.patient_bus_no, '') AS identifierNo,
|
COALESCE(T9.identifier_no, T9.patient_bus_no, '') AS identifierNo,
|
||||||
COALESCE(T9.order_id IS NOT NULL, false) AS isFromAppointment
|
COALESCE(T9.order_id IS NOT NULL, false) AS isFromAppointment,
|
||||||
|
T9.slot_id AS slotId,
|
||||||
|
T9.pool_id AS poolId
|
||||||
from (
|
from (
|
||||||
SELECT T1.tenant_id AS tenant_id,
|
SELECT T1.tenant_id AS tenant_id,
|
||||||
T1.id AS encounter_id,
|
T1.id AS encounter_id,
|
||||||
@@ -95,8 +97,12 @@
|
|||||||
T8.birth_date AS birth_date,
|
T8.birth_date AS birth_date,
|
||||||
T8.bus_no AS patient_bus_no,
|
T8.bus_no AS patient_bus_no,
|
||||||
T18.identifier_no AS identifier_no,
|
T18.identifier_no AS identifier_no,
|
||||||
T1.order_id AS order_id
|
T1.order_id AS order_id,
|
||||||
|
om.slot_id AS slot_id,
|
||||||
|
ss.pool_id AS pool_id
|
||||||
FROM adm_encounter AS T1
|
FROM adm_encounter AS T1
|
||||||
|
LEFT JOIN order_main AS om ON T1.order_id = om.id AND om.delete_flag = '0'
|
||||||
|
LEFT JOIN adm_schedule_slot AS ss ON om.slot_id = ss.id AND ss.delete_flag = '0'
|
||||||
LEFT JOIN adm_organization AS T2 ON T1.organization_id = T2.ID AND T2.delete_flag = '0'
|
LEFT JOIN adm_organization AS T2 ON T1.organization_id = T2.ID AND T2.delete_flag = '0'
|
||||||
LEFT JOIN adm_healthcare_service AS T3 ON T1.service_type_id = T3.ID AND T3.delete_flag = '0'
|
LEFT JOIN adm_healthcare_service AS T3 ON T1.service_type_id = T3.ID AND T3.delete_flag = '0'
|
||||||
LEFT JOIN (
|
LEFT JOIN (
|
||||||
|
|||||||
@@ -31,9 +31,15 @@ public class TriageQueueItem {
|
|||||||
private String practitionerName; // 医生姓名
|
private String practitionerName; // 医生姓名
|
||||||
private Long practitionerId; // 医生ID(新增字段)
|
private Long practitionerId; // 医生ID(新增字段)
|
||||||
private String roomNo; // 诊室号(新增字段)
|
private String roomNo; // 诊室号(新增字段)
|
||||||
|
private Long poolId; // 号源池ID (关联 adm_schedule_pool.id)
|
||||||
|
private Long slotId; // 号源槽位ID (关联 adm_schedule_slot.id)
|
||||||
|
|
||||||
/** WAITING / CALLING / SKIPPED / COMPLETED */
|
/**
|
||||||
private String status;
|
* 分诊队列状态
|
||||||
|
* 0=WAITING(等待中), 10=CALLING(呼叫中), 20=IN_CLINIC(诊中),
|
||||||
|
* 30=COMPLETED(已完成), 40=SKIPPED(已跳过), 50=REFUNDED(已退费), 60=FOLLOW(已随访)
|
||||||
|
*/
|
||||||
|
private Integer status;
|
||||||
private Integer queueOrder; //“排队序号”,也就是患者在当前科室、当天队列里的 顺序号(从 1 开始递增)。
|
private Integer queueOrder; //“排队序号”,也就是患者在当前科室、当天队列里的 顺序号(从 1 开始递增)。
|
||||||
|
|
||||||
private LocalDateTime createTime;
|
private LocalDateTime createTime;
|
||||||
|
|||||||
@@ -18,34 +18,33 @@ export const TOP_KEYS = [
|
|||||||
const timeNew = new Date((tieml / 1000 + 86400) * 1000);
|
const timeNew = new Date((tieml / 1000 + 86400) * 1000);
|
||||||
const todayDate = dayjs(timeNew).format('YYYY-MM-DD');
|
const todayDate = dayjs(timeNew).format('YYYY-MM-DD');
|
||||||
const endDate = dayjs(outdate).format('YYYY-MM-DD');
|
const endDate = dayjs(outdate).format('YYYY-MM-DD');
|
||||||
const startDate = dayjs(hospDate).format('YYYY-MM-DD');
|
let eachDate = dayjs(beginDate).add(i, 'day');
|
||||||
let eachTime = dayjs(beginDate).add(i, 'day').format('YYYY-MM-DD');
|
const eachTime = eachDate.format('YYYY-MM-DD');
|
||||||
if (eachTime === endDate || eachTime === todayDate) {
|
if (eachTime === endDate || eachTime === todayDate) {
|
||||||
dateClosed.stopTime = true;
|
dateClosed.stopTime = true;
|
||||||
}
|
}
|
||||||
if ((startDate === eachTime && i === 0) || dayjs(eachTime).format('MM-DD') === '01-01') {
|
// 统一补零格式:月份和日期都始终两位补零
|
||||||
eachTime = dayjs(eachTime).format('YYYY年MM月DD日');
|
const month = eachDate.format('MM'); // 月份始终两位补零
|
||||||
} else if (i === 0 || dayjs(eachTime).format('DD') === '01') {
|
const date = eachDate.format('DD'); // 日期始终两位补零
|
||||||
eachTime = dayjs(eachTime).format('MM月DD日');
|
// 每月1号显示 MM月DD日,其他日期只显示 DD日
|
||||||
} else {
|
return `${month}月${date}日`;
|
||||||
eachTime = dayjs(eachTime).format('DD日');
|
|
||||||
}
|
|
||||||
return dateClosed.stopTime ? eachTime : '';
|
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
name: '住院日数',
|
name: '住院日数',
|
||||||
getValue: (i, renderData) => {
|
getValue: (i, renderData) => {
|
||||||
const { beginDate, hospDays, outdate = '', dateClosed } = renderData.infoData;
|
const { beginDate, hospDays, outdate = '', dateClosed } = renderData.infoData;
|
||||||
const tieml = new Date();
|
const beginDayjs = dayjs(beginDate);
|
||||||
const timeNew = new Date((tieml / 1000 + 86400) * 1000);
|
let num = '';
|
||||||
const todayDate = dayjs(timeNew).format('YYYY-MM-DD');
|
// 只要 beginDate 有效,每一天都计算显示住院日数
|
||||||
const endDate = dayjs(outdate).add(1, 'day').format('YYYY-MM-DD');
|
if (beginDayjs.isValid()) {
|
||||||
const eachTime = dayjs(beginDate).add(i, 'day').format('YYYY-MM-DD');
|
if (hospDays !== undefined && hospDays !== null) {
|
||||||
if (eachTime === endDate || todayDate === eachTime) {
|
num = hospDays + i + 1;
|
||||||
dateClosed.stopNumber = false;
|
} else {
|
||||||
|
// hospDays 不存在时,从入院开始直接计算
|
||||||
|
num = i + 1;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
const num = dateClosed.stopNumber ? hospDays + i + 1 : '';
|
|
||||||
let hosNum = '';
|
let hosNum = '';
|
||||||
if (num !== '') {
|
if (num !== '') {
|
||||||
hosNum = '第' + '\xa0\xa0\xa0' + num + '\xa0\xa0\xa0' + '日';
|
hosNum = '第' + '\xa0\xa0\xa0' + num + '\xa0\xa0\xa0' + '日';
|
||||||
|
|||||||
@@ -215,7 +215,7 @@
|
|||||||
<el-table-column label="操作" width="180" fixed="right">
|
<el-table-column label="操作" width="180" fixed="right">
|
||||||
<template #default="{ row }">
|
<template #default="{ row }">
|
||||||
<el-button
|
<el-button
|
||||||
v-if="row.status === 1"
|
v-if="row.status === 1 || row.status === 5"
|
||||||
type="primary"
|
type="primary"
|
||||||
link
|
link
|
||||||
@click="handleAudit(row)"
|
@click="handleAudit(row)"
|
||||||
@@ -944,10 +944,10 @@ async function handleReturnCard() {
|
|||||||
|
|
||||||
// 批量审核
|
// 批量审核
|
||||||
function handleBatchAudit() {
|
function handleBatchAudit() {
|
||||||
// 检查是否包含非待审核状态的报卡
|
// 检查是否包含非可审核状态的报卡(只有待审核和审核失败可以批量审核)
|
||||||
const nonPendingCards = selectedRows.value.filter(row => row.status !== 1);
|
const nonPendingCards = selectedRows.value.filter(row => row.status !== 1 && row.status !== 5);
|
||||||
if (nonPendingCards.length > 0) {
|
if (nonPendingCards.length > 0) {
|
||||||
ElMessage.warning('只能选择待审核状态的报卡');
|
ElMessage.warning('只能选择待审核或审核失败状态的报卡');
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -992,10 +992,10 @@ async function confirmBatchAudit() {
|
|||||||
|
|
||||||
// 批量退回
|
// 批量退回
|
||||||
function handleBatchReturn() {
|
function handleBatchReturn() {
|
||||||
// 检查是否包含非待审核状态的报卡
|
// 检查是否包含非可审核状态的报卡(只有待审核和审核失败可以批量退回)
|
||||||
const nonPendingCards = selectedRows.value.filter(row => row.status !== 1);
|
const nonPendingCards = selectedRows.value.filter(row => row.status !== 1 && row.status !== 5);
|
||||||
if (nonPendingCards.length > 0) {
|
if (nonPendingCards.length > 0) {
|
||||||
ElMessage.warning('只能选择待审核状态的报卡');
|
ElMessage.warning('只能选择待审核或审核失败状态的报卡');
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -329,11 +329,53 @@ function getSignsCharts() {
|
|||||||
getVitalSignsInfo(params).then((response) => {
|
getVitalSignsInfo(params).then((response) => {
|
||||||
console.log('体温单返回值', response);
|
console.log('体温单返回值', response);
|
||||||
if (response.code === 200) {
|
if (response.code === 200) {
|
||||||
// data1.grParamBOS.hospDate = data1.grParamBOS.inDate.substring(0, 10)
|
// 计算最终住院起始日期,多级 fallback
|
||||||
data1.grParamBOS.hospDate =
|
let finalHospDate = null;
|
||||||
response.data.hospDate && response.data.hospDate.length > 10
|
|
||||||
? response.data.hospDate.substring(0, 10)
|
// 1. 优先用后端返回的入院日期
|
||||||
: response.data.hospDate;
|
if (response.data.hospDate) {
|
||||||
|
if (typeof response.data.hospDate === 'string' && response.data.hospDate.length > 0) {
|
||||||
|
let dateStr = String(response.data.hospDate).replace(/\//g, '-');
|
||||||
|
// 解析年月日补零,得到 YYYY-MM-DD
|
||||||
|
const parts = dateStr.split(/[ -]/);
|
||||||
|
if (parts.length >= 3) {
|
||||||
|
const year = parts[0].padStart(4, '0');
|
||||||
|
const month = parts[1].padStart(2, '0');
|
||||||
|
const day = parts[2].padStart(2, '0');
|
||||||
|
finalHospDate = `${year}-${month}-${day}`;
|
||||||
|
} else {
|
||||||
|
finalHospDate = dateStr.substring(0, 10);
|
||||||
|
}
|
||||||
|
} else if (response.data.hospDate instanceof Date) {
|
||||||
|
finalHospDate = new Date(response.data.hospDate).toISOString().substring(0, 10);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// 2. 如果后端为空,使用从患者列表获取的入院日期
|
||||||
|
if ((!finalHospDate || finalHospDate === 'null') && data1.grParamBOS.inDate) {
|
||||||
|
if (typeof data1.grParamBOS.inDate === 'string' && data1.grParamBOS.inDate.length > 0) {
|
||||||
|
let dateStr = String(data1.grParamBOS.inDate).replace(/\//g, '-');
|
||||||
|
// 解析年月日补零,得到 YYYY-MM-DD
|
||||||
|
const parts = dateStr.split(/[ -]/);
|
||||||
|
if (parts.length >= 3) {
|
||||||
|
const year = parts[0].padStart(4, '0');
|
||||||
|
const month = parts[1].padStart(2, '0');
|
||||||
|
const day = parts[2].padStart(2, '0');
|
||||||
|
finalHospDate = `${year}-${month}-${day}`;
|
||||||
|
} else {
|
||||||
|
finalHospDate = dateStr.substring(0, 10);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// 3. 如果都为空,使用今天日期作为默认值(绝对不会出现 Invalid Date)
|
||||||
|
if (!finalHospDate || finalHospDate === 'null' || finalHospDate === 'undefined' || finalHospDate === '') {
|
||||||
|
finalHospDate = getCurrentDate();
|
||||||
|
console.warn('入院日期为空,使用今天日期作为默认值:', finalHospDate);
|
||||||
|
}
|
||||||
|
|
||||||
|
console.log('最终住院起始日期:', finalHospDate);
|
||||||
|
data1.grParamBOS.hospDate = finalHospDate;
|
||||||
data1.grParamBOS.operaDate = response.data.operaDate;
|
data1.grParamBOS.operaDate = response.data.operaDate;
|
||||||
data1.grParamBOS.outdate = response.data.outdate;
|
data1.grParamBOS.outdate = response.data.outdate;
|
||||||
data1.rows = response.data.temperaturePulses.map((item) => ({
|
data1.rows = response.data.temperaturePulses.map((item) => ({
|
||||||
@@ -381,9 +423,18 @@ function setTemperatureComp(data) {
|
|||||||
if (data !== undefined) {
|
if (data !== undefined) {
|
||||||
inputData.value = data;
|
inputData.value = data;
|
||||||
}
|
}
|
||||||
const inDate = inputData.value.grParamBOS.hospDate;
|
let inDate = inputData.value.grParamBOS.hospDate;
|
||||||
const outdate = inputData.value.grParamBOS.outdate;
|
let outdate = inputData.value.grParamBOS.outdate;
|
||||||
const begin = moment(new Date(inDate))
|
// 统一格式化日期:将 / 替换为 -,确保 moment 能正确解析
|
||||||
|
if (inDate) {
|
||||||
|
inDate = String(inDate).replace(/\//g, '-').substring(0, 10);
|
||||||
|
inputData.value.grParamBOS.hospDate = inDate;
|
||||||
|
}
|
||||||
|
if (outdate) {
|
||||||
|
outdate = String(outdate).replace(/\//g, '-').substring(0, 10);
|
||||||
|
inputData.value.grParamBOS.outdate = outdate;
|
||||||
|
}
|
||||||
|
const begin = moment(inDate)
|
||||||
.add(week.value * 7, 'day')
|
.add(week.value * 7, 'day')
|
||||||
.format('YYYY-MM-DD HH:mm:ss');
|
.format('YYYY-MM-DD HH:mm:ss');
|
||||||
inputData.value.grParamBOS.weekNo = week.value;
|
inputData.value.grParamBOS.weekNo = week.value;
|
||||||
@@ -442,16 +493,38 @@ function sliceData(data) {
|
|||||||
}
|
}
|
||||||
// 计算时间差
|
// 计算时间差
|
||||||
function dateDiff(start, end) {
|
function dateDiff(start, end) {
|
||||||
let diffTime = start ? moment(new Date()).diff(moment(start.substring(0, 10))) / 1000 : start;
|
console.log('dateDiff start:', start, 'end:', end);
|
||||||
if (end) {
|
// 如果开始日期无效,返回 0
|
||||||
diffTime = moment(end.substring(0, 10)).diff(moment(start.substring(0, 10))) / 1000;
|
if (!start || start === 'null' || start === 'undefined') {
|
||||||
|
console.log('start is null, return 0');
|
||||||
|
return 0;
|
||||||
}
|
}
|
||||||
|
// 统一格式化日期:将 / 替换为 -,截取前10位
|
||||||
|
let startStr = String(start).replace(/\//g, '-').substring(0, 10);
|
||||||
|
const startMoment = moment(startStr);
|
||||||
|
if (!startMoment.isValid()) {
|
||||||
|
console.log('start is invalid, return 0');
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
let diffTime;
|
||||||
|
if (end && end !== 'null' && end !== 'undefined') {
|
||||||
|
let endStr = String(end).replace(/\//g, '-').substring(0, 10);
|
||||||
|
const endMoment = moment(endStr);
|
||||||
|
if (!endMoment.isValid()) {
|
||||||
|
diffTime = moment(new Date()).diff(startMoment) / 1000;
|
||||||
|
} else {
|
||||||
|
diffTime = endMoment.diff(startMoment) / 1000;
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
diffTime = moment(new Date()).diff(startMoment) / 1000;
|
||||||
|
}
|
||||||
|
console.log('diffTime:', diffTime);
|
||||||
if (diffTime > 24 * 3600) {
|
if (diffTime > 24 * 3600) {
|
||||||
return Math.floor(diffTime / (24 * 3600));
|
return Math.floor(diffTime / (24 * 3600));
|
||||||
} else if (diffTime > 3600) {
|
} else if (diffTime > 3600) {
|
||||||
return '0';
|
return 0;
|
||||||
} else {
|
} else {
|
||||||
return '0';
|
return 0;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
// 打印体温单 - 使用 hiprint
|
// 打印体温单 - 使用 hiprint
|
||||||
|
|||||||
@@ -67,7 +67,7 @@
|
|||||||
</div>
|
</div>
|
||||||
</template>
|
</template>
|
||||||
</div>
|
</div>
|
||||||
<el-drawer v-model="isOpenDraw" :direction="direction" size="100%" :with-header="false">
|
<el-drawer v-model="isOpenDraw" :direction="direction" size="100%" :with-header="false" :destroy-on-close="false">
|
||||||
<template #default>
|
<template #default>
|
||||||
<AddAttr ref="attrRef" @onSearcTem="onSearch"></AddAttr>
|
<AddAttr ref="attrRef" @onSearcTem="onSearch"></AddAttr>
|
||||||
</template>
|
</template>
|
||||||
@@ -576,16 +576,19 @@ function setTemperatureComp(data) {
|
|||||||
init(sliceData(inputData.value));
|
init(sliceData(inputData.value));
|
||||||
}
|
}
|
||||||
function dateDiff(start, end) {
|
function dateDiff(start, end) {
|
||||||
let diffTime = start ? moment(new Date()).diff(moment(start.substring(0, 10))) / 1000 : start;
|
if (!start) {
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
const startStr = start.substring(0, 10);
|
||||||
|
let diffTime = start ? moment(new Date()).diff(moment(startStr)) / 1000 : 0;
|
||||||
if (end) {
|
if (end) {
|
||||||
diffTime = moment(end.substring(0, 10)).diff(moment(start.substring(0, 10))) / 1000;
|
const endStr = end.substring(0, 10);
|
||||||
|
diffTime = moment(endStr).diff(moment(startStr)) / 1000;
|
||||||
}
|
}
|
||||||
if (diffTime > 24 * 3600) {
|
if (diffTime > 24 * 3600) {
|
||||||
return Math.floor(diffTime / (24 * 3600));
|
return Math.floor(diffTime / (24 * 3600));
|
||||||
} else if (diffTime > 3600) {
|
|
||||||
return '0';
|
|
||||||
} else {
|
} else {
|
||||||
return '0';
|
return 0;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
function getCurrentDate() {
|
function getCurrentDate() {
|
||||||
|
|||||||
@@ -817,7 +817,10 @@ const loadDataFromApi = async () => {
|
|||||||
doctor: item.practitionerName ?? '-',
|
doctor: item.practitionerName ?? '-',
|
||||||
// 当前接口返回的是 practitionerUserId,保存为 practitionerId 供入队使用
|
// 当前接口返回的是 practitionerUserId,保存为 practitionerId 供入队使用
|
||||||
practitionerId: item.practitionerUserId ?? null,
|
practitionerId: item.practitionerUserId ?? null,
|
||||||
matchingRule: '-' // 这里先不做智能规则匹配
|
matchingRule: '-', // 这里先不做智能规则匹配
|
||||||
|
// 号源池和槽位信息(用于分诊队列)
|
||||||
|
poolId: item.poolId ?? null,
|
||||||
|
slotId: item.slotId ?? null
|
||||||
}))
|
}))
|
||||||
console.log('【心内科】候选池已加载', originalCandidatePoolList.value.length, '条今天的数据')
|
console.log('【心内科】候选池已加载', originalCandidatePoolList.value.length, '条今天的数据')
|
||||||
} else {
|
} else {
|
||||||
@@ -1035,7 +1038,9 @@ const handleAddToQueue = async () => {
|
|||||||
healthcareName: c.appointmentType,
|
healthcareName: c.appointmentType,
|
||||||
practitionerName: c.doctor,
|
practitionerName: c.doctor,
|
||||||
practitionerId: c.practitionerId ?? null,
|
practitionerId: c.practitionerId ?? null,
|
||||||
roomNo: c.roomNo ?? c.room ?? null
|
roomNo: c.roomNo ?? c.room ?? null,
|
||||||
|
poolId: c.poolId ?? null,
|
||||||
|
slotId: c.slotId ?? null
|
||||||
})
|
})
|
||||||
})
|
})
|
||||||
|
|
||||||
@@ -1150,7 +1155,9 @@ const handleAddAllToQueue = async () => {
|
|||||||
healthcareName: c.appointmentType,
|
healthcareName: c.appointmentType,
|
||||||
practitionerName: c.doctor,
|
practitionerName: c.doctor,
|
||||||
practitionerId: c.practitionerId ?? null,
|
practitionerId: c.practitionerId ?? null,
|
||||||
roomNo: c.roomNo ?? c.room ?? null
|
roomNo: c.roomNo ?? c.room ?? null,
|
||||||
|
poolId: c.poolId ?? null,
|
||||||
|
slotId: c.slotId ?? null
|
||||||
})
|
})
|
||||||
})
|
})
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user