版本更新

This commit is contained in:
Zhang.WH
2025-10-16 17:17:24 +08:00
parent d23a594a4b
commit f515bb8fbb
600 changed files with 7881 additions and 35954 deletions

View File

@@ -71,16 +71,16 @@ public interface IAdviceProcessAppService {
/**
* 医嘱取消执行
*
* @param performInfoList 医嘱信息集合
* @param adviceExecuteParam 取消执行参数
* @return 操作结果
*/
R<?> adviceCancel(List<PerformInfoDto> performInfoList);
R<?> adviceCancel(AdviceExecuteParam adviceExecuteParam);
/**
* 医嘱不执行
*
* @param performInfoList 医嘱信息集合
* @param adviceExecuteParam 不执行参数
* @return 操作结果
*/
R<?> adviceVoid(List<PerformInfoDto> performInfoList);
R<?> adviceVoid(AdviceExecuteParam adviceExecuteParam);
}

View File

@@ -7,7 +7,6 @@ import javax.servlet.http.HttpServletRequest;
import com.core.common.core.domain.R;
import com.openhis.web.inhospitalnursestation.dto.InpatientMedicinePrescriptionInfoDto;
import com.openhis.web.inhospitalnursestation.dto.InpatientMedicineSearchParam;
import com.openhis.workflow.domain.InventoryItem;
/**
* 住院领药 应用实现接口
@@ -15,7 +14,7 @@ import com.openhis.workflow.domain.InventoryItem;
* @author yuxj
* @date 2025/8/18
*/
public interface IInpatientMedicineCollectionAppService {
public interface IMedicineSummaryAppService {
/**
* 分页查询在科病人列表

View File

@@ -4,6 +4,10 @@
package com.openhis.web.inhospitalnursestation.appservice.impl;
import java.math.BigDecimal;
import java.math.RoundingMode;
import java.time.LocalDateTime;
import java.time.ZoneId;
import java.time.format.DateTimeFormatter;
import java.util.*;
import java.util.stream.Collectors;
@@ -14,13 +18,17 @@ import org.springframework.stereotype.Service;
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.extension.plugins.pagination.Page;
import com.core.common.core.domain.R;
import com.core.common.utils.AgeCalculatorUtil;
import com.core.common.utils.MessageUtils;
import com.core.common.utils.SecurityUtils;
import com.core.common.utils.bean.BeanUtils;
import com.openhis.administration.domain.ChargeItem;
import com.openhis.administration.service.IChargeItemService;
import com.openhis.administration.service.IEncounterService;
import com.openhis.clinical.domain.Procedure;
import com.openhis.clinical.service.IProcedureService;
import com.openhis.common.constant.CommonConstants;
import com.openhis.common.constant.PromptMsgConstant;
@@ -28,17 +36,24 @@ import com.openhis.common.enums.*;
import com.openhis.common.utils.EnumUtils;
import com.openhis.common.utils.HisQueryUtils;
import com.openhis.medication.domain.MedicationDefinition;
import com.openhis.medication.domain.MedicationDispense;
import com.openhis.medication.domain.MedicationRequest;
import com.openhis.medication.service.IMedicationDefinitionService;
import com.openhis.medication.service.IMedicationDispenseService;
import com.openhis.medication.service.IMedicationRequestService;
import com.openhis.web.common.dto.PerformInfoDto;
import com.openhis.web.common.dto.PerformRecordDto;
import com.openhis.web.doctorstation.appservice.IDoctorStationAdviceAppService;
import com.openhis.web.doctorstation.dto.AdviceBaseDto;
import com.openhis.web.doctorstation.dto.AdvicePriceDto;
import com.openhis.web.doctorstation.utils.AdviceUtils;
import com.openhis.web.inhospitalnursestation.appservice.IAdviceProcessAppService;
import com.openhis.web.inhospitalnursestation.dto.*;
import com.openhis.web.inhospitalnursestation.mapper.AdviceProcessAppMapper;
import com.openhis.web.outpatientmanage.mapper.OutpatientTreatmentAppMapper;
import com.openhis.workflow.domain.DeviceDispense;
import com.openhis.workflow.domain.ServiceRequest;
import com.openhis.workflow.service.IDeviceDispenseService;
import com.openhis.workflow.service.IServiceRequestService;
/**
@@ -68,12 +83,24 @@ public class AdviceProcessAppServiceImpl implements IAdviceProcessAppService {
@Resource
private IMedicationDispenseService medicationDispenseService;
@Resource
private IDeviceDispenseService deviceDispenseService;
@Resource
private IEncounterService encounterService;
@Resource
private IMedicationDefinitionService medicationDefinitionService;
@Resource
private IChargeItemService chargeItemService;
@Resource
private AdviceUtils adviceUtils;
@Resource
private IDoctorStationAdviceAppService iDoctorStationAdviceAppService;
/**
* 住院患者分页列表
*
@@ -140,7 +167,6 @@ public class AdviceProcessAppServiceImpl implements IAdviceProcessAppService {
Arrays.stream(encounterIds.split(CommonConstants.Common.COMMA)).map(Long::parseLong).toList();
queryWrapper.in(CommonConstants.FieldName.EncounterId, encounterIdList);
}
// 入院患者分页列表
Page<InpatientAdviceDto> inpatientAdvicePage =
adviceProcessAppMapper.selectInpatientAdvicePage(new Page<>(pageNo, pageSize), queryWrapper,
@@ -339,65 +365,27 @@ public class AdviceProcessAppServiceImpl implements IAdviceProcessAppService {
// 诊疗
List<AdviceExecuteDetailParam> activityList = adviceExecuteDetailList.stream()
.filter(e -> CommonConstants.TableName.WOR_SERVICE_REQUEST.equals(e.getAdviceTable())).toList();
// -------------------------------------------整体校验药品库存
// -------------------------------------------药品
if (!medicineList.isEmpty()) {
// 药品请求id集合
List<Long> medicineRequestIdList =
medicineList.stream().map(AdviceExecuteDetailParam::getRequestId).collect(Collectors.toList());
// 药品请求集合
List<MedicationRequest> MedicationRequestList = medicationRequestService
.list(new LambdaQueryWrapper<MedicationRequest>().in(MedicationRequest::getId, medicineRequestIdList));
// 药品定义id集合
List<Long> medicationDefinitionIdList =
MedicationRequestList.stream().map(MedicationRequest::getMedicationId).collect(Collectors.toList());
// 药品定义集合
List<MedicationDefinition> medicationDefinitionList =
medicationDefinitionService.list(new LambdaQueryWrapper<MedicationDefinition>()
.in(MedicationDefinition::getId, medicationDefinitionIdList));
// 组装MedicationRequestUseExe数据结构
List<MedicationRequestUseExe> MedUseExeList = MedicationRequestList.stream().map(medicationRequest -> {
// 创建 MedicationRequestUseExe 对象,并复制 MedicationRequest 的属性
MedicationRequestUseExe useExe = new MedicationRequestUseExe();
BeanUtils.copyProperties(medicationRequest, useExe);
// 匹配 executeTimes根据 medicationRequest 的 id 在 medicineList 中查找匹配的 executeTimes
List<String> matchedExecuteTimes =
medicineList.stream().filter(medicine -> medicine.getRequestId().equals(medicationRequest.getId()))
.findFirst().map(AdviceExecuteDetailParam::getExecuteTimes).orElse(null);
useExe.setExecuteTimes(matchedExecuteTimes);
// 计算 executeTimesNumexecuteTimes 的集合大小,转换为 BigDecimal
if (matchedExecuteTimes != null) {
useExe.setExecuteTimesNum(BigDecimal.valueOf(matchedExecuteTimes.size()));
} else {
useExe.setExecuteTimesNum(BigDecimal.ZERO);
// 组装药品请求用于执行的数据结构
List<MedicationRequestUseExe> medUseExeList = this.assemblyMedication(medicineList);
// 校验药品库存
if (!medUseExeList.isEmpty()) {
String tipRes = adviceUtils.checkExeMedInventory(medUseExeList);
if (tipRes != null) {
return R.fail(null, tipRes);
}
// 匹配 minUnitQuantity根据 medicationId 在 medicationDefinitionList 中查找匹配的药品定义
MedicationDefinition matchedDefinition = medicationDefinitionList.stream()
.filter(definition -> definition.getId().equals(medicationRequest.getMedicationId())).findFirst()
.orElse(null);
if (matchedDefinition != null) {
// 判断 minUnitCode 是否等于 unitCode
if (matchedDefinition.getMinUnitCode().equals(medicationRequest.getUnitCode())) {
useExe.setMinUnitQuantity(medicationRequest.getQuantity());
} else {
// 若不相等,则计算 quantity * partPercent
BigDecimal partPercent = matchedDefinition.getPartPercent();
if (partPercent == null) {
partPercent = BigDecimal.ONE; // 避免空指针默认设为1
}
useExe.setMinUnitQuantity(medicationRequest.getQuantity().multiply(partPercent));
}
} else {
// 若未找到匹配的药品定义,设为 null 或默认值
useExe.setMinUnitQuantity(null);
}
return useExe;
}).toList();
// -------------------------------------------处理药品执行
}
// 处理药品执行
this.exeMedication(medUseExeList);
}
// -------------------------------------------诊疗
if (!activityList.isEmpty()) {
// 组装诊疗请求用于执行的数据结构
List<ServiceRequestUseExe> actUseExeList = this.assemblyActivity(activityList);
// 处理诊疗执行
this.exeActivity(actUseExeList);
}
// -------------------------------------------处理诊疗执行
return R.ok(null, MessageUtils.createMessage(PromptMsgConstant.Common.M00004, new Object[] {"医嘱执行"}));
}
@@ -405,22 +393,135 @@ public class AdviceProcessAppServiceImpl implements IAdviceProcessAppService {
/**
* 医嘱取消执行
*
* @param performInfoList 医嘱信息集合
* @param adviceExecuteParam 取消执行参数
* @return 操作结果
*/
@Override
public R<?> adviceCancel(List<PerformInfoDto> performInfoList) {
return null;
public R<?> adviceCancel(AdviceExecuteParam adviceExecuteParam) {
// 长期医嘱执行id
List<Long> longProcIdList = adviceExecuteParam.getAdviceExecuteDetailList().stream()
.filter(x -> x.getTherapyEnum().equals(TherapyTimeType.LONG_TERM.getValue()))
.map(AdviceExecuteDetailParam::getProcedureId).distinct().toList();
// 药品临时医嘱执行id
List<Long> tempProcIdList = adviceExecuteParam.getAdviceExecuteDetailList().stream()
.filter(x -> x.getTherapyEnum().equals(TherapyTimeType.TEMPORARY.getValue()))
.map(AdviceExecuteDetailParam::getProcedureId).distinct().toList();
// 分别处理长期和临时的医嘱
// 长期已发放药品
List<MedicationDispense> longMedDispensedList = new ArrayList<>();
// 长期未发放药品
List<MedicationDispense> longMedUndispenseList = new ArrayList<>();
// 长期已发放耗材
List<DeviceDispense> longDevDispensedList = new ArrayList<>();
// 长期未发放耗材
List<DeviceDispense> longDevUndispenseList = new ArrayList<>();
// 处理长期医嘱
if (!longProcIdList.isEmpty()) {
// 长期药品
List<MedicationDispense> longMedDispenseList =
medicationDispenseService.getMedDispenseByProcedureId(longProcIdList);
// 长期耗材
List<DeviceDispense> longDevDispenseList =
deviceDispenseService.getDevDispenseByProcedureId(longProcIdList);
// 分离已发药发药单和未发药发药单
for (MedicationDispense medicationDispense : longMedDispenseList) {
if (DispenseStatus.COMPLETED.getValue().equals(medicationDispense.getDispenseEnum())) {
longMedDispensedList.add(medicationDispense);
} else if (DispenseStatus.PREPARATION.getValue().equals(medicationDispense.getDispenseEnum())) {
longMedUndispenseList.add(medicationDispense);
}
}
// 分离已发耗材单和未发耗材单
for (DeviceDispense deviceDispense : longDevDispenseList) {
if (DispenseStatus.COMPLETED.getValue().equals(deviceDispense.getStatusEnum())) {
longDevDispensedList.add(deviceDispense);
} else if (DispenseStatus.PREPARATION.getValue().equals(deviceDispense.getStatusEnum())) {
longDevUndispenseList.add(deviceDispense);
}
}
// 查询账单
List<ChargeItem> chargeItemList = chargeItemService.getChargeItemByProcedureId(longProcIdList);
if (chargeItemList != null && !chargeItemList.isEmpty()) {
for (ChargeItem chargeItem : chargeItemList) {
// 因执行医嘱时创建了账单,取消执行时需要软删除账单
chargeItemService.removeById(chargeItem);
}
}
}
// 临时已发放药品
List<MedicationDispense> tempMedDispensedList = new ArrayList<>();
// 临时未发放药品
List<MedicationDispense> tempMedUndispenseList = new ArrayList<>();
// 临时已发放耗材
List<DeviceDispense> tempDevDispensedList = new ArrayList<>();
// 临时未发放耗材
List<DeviceDispense> tempDevUndispenseList = new ArrayList<>();
// 处理临时医嘱
if (!tempProcIdList.isEmpty()) {
// 长期药品
List<MedicationDispense> tempMedDispenseList =
medicationDispenseService.getMedDispenseByProcedureId(tempProcIdList);
// 长期耗材
List<DeviceDispense> tempDevDispenseList =
deviceDispenseService.getDevDispenseByProcedureId(tempProcIdList);
// 分离已发药发药单和未发药发药单
for (MedicationDispense medicationDispense : tempMedDispenseList) {
if (DispenseStatus.COMPLETED.getValue().equals(medicationDispense.getDispenseEnum())) {
tempMedDispensedList.add(medicationDispense);
} else if (DispenseStatus.PREPARATION.getValue().equals(medicationDispense.getDispenseEnum())) {
tempMedUndispenseList.add(medicationDispense);
}
}
// 分离已发耗材单和未发耗材单
for (DeviceDispense deviceDispense : tempDevDispenseList) {
if (DispenseStatus.COMPLETED.getValue().equals(deviceDispense.getStatusEnum())) {
tempDevDispensedList.add(deviceDispense);
} else if (DispenseStatus.PREPARATION.getValue().equals(deviceDispense.getStatusEnum())) {
tempDevUndispenseList.add(deviceDispense);
}
}
// 查询账单
List<ChargeItem> chargeItemList = chargeItemService.getChargeItemByProcedureId(tempProcIdList);
if (chargeItemList != null && !chargeItemList.isEmpty()) {
// 临时医嘱取消执行时,将临时医嘱的收费项目状态改为待收费
chargeItemService
.updatePlannedChargeStatus(chargeItemList.stream().map(ChargeItem::getProcedureId).toList());
}
}
// 统一处理已发放药品或耗材
List<MedicationDispense> medDispensedList = new ArrayList<>(tempMedDispensedList);
medDispensedList.addAll(longMedDispensedList);
// 统一处理已发放药品或耗材
List<DeviceDispense> devDispensedList = new ArrayList<>(tempDevDispensedList);
devDispensedList.addAll(longDevDispensedList);
// 合并长期和临时的执行记录
List<Long> procedureIdList = new ArrayList<>(longProcIdList);
procedureIdList.addAll(tempProcIdList);
// 查询执行记录
List<Procedure> procedureList = procedureService.listByIds(procedureIdList);
if (procedureList != null && !procedureList.isEmpty()) {
for (Procedure procedure : procedureList) {
// 根据执行记录新增取消执行记录
procedureService.addProcedureRecord(procedure.getEncounterId(), procedure.getPatientId(),
procedure.getRequestId(), procedure.getRequestTable(), EventStatus.CANCEL,
ProcedureCategory.INPATIENT_ADVICE, null, procedure.getOccurrenceTime(), procedure.getGroupId(),
procedure.getId());
}
}
return R.ok("取消执行成功");
}
/**
* 医嘱不执行
*
* @param performInfoList 医嘱信息集合
* @param adviceExecuteParam 不执行参数
* @return 操作结果
*/
@Override
public R<?> adviceVoid(List<PerformInfoDto> performInfoList) {
public R<?> adviceVoid(AdviceExecuteParam adviceExecuteParam) {
// 长期临时都可以不执行长期不执行的是某一时间点也可以不执行这一整个医嘱更新serviceRequest状态为7
// 已执行的时间点不能不执行,需要先取消
// 增加不执行记录
@@ -428,4 +529,375 @@ public class AdviceProcessAppServiceImpl implements IAdviceProcessAppService {
return null;
}
/**
* 执行药品医嘱
*
* @param medUseExeList 药品医嘱
*/
private void exeMedication(List<MedicationRequestUseExe> medUseExeList) {
// 长期医嘱
List<MedicationRequestUseExe> longMedication = medUseExeList.stream()
.filter(e -> TherapyTimeType.LONG_TERM.getValue().equals(e.getTherapyEnum())).collect(Collectors.toList());
// 临时医嘱
List<MedicationRequestUseExe> tempMedication = medUseExeList.stream()
.filter(e -> TherapyTimeType.TEMPORARY.getValue().equals(e.getTherapyEnum())).collect(Collectors.toList());
// 药品定义id集合
List<Long> medicationDefinitionIdList =
medUseExeList.stream().map(MedicationRequestUseExe::getMedicationId).collect(Collectors.toList());
// 医嘱详细信息
List<AdviceBaseDto> medicationInfos = iDoctorStationAdviceAppService.getAdviceBaseInfo(null, null, null,
medicationDefinitionIdList, 0L, 1, 500, Whether.NO.getValue(), List.of(1)).getRecords();
// 当前时间
Date curDate = new Date();
// 参与者id
Long practitionerId = SecurityUtils.getLoginUser().getPractitionerId();
// 当前登录账号的科室id
Long orgId = SecurityUtils.getLoginUser().getOrgId();
// 长期
MedicationRequest longMedicationRequest;
ChargeItem chargeItem;
for (MedicationRequestUseExe medicationRequestUseExe : longMedication) {
for (String executeTime : medicationRequestUseExe.getExecuteTimes()) {
longMedicationRequest = new MedicationRequest();
BeanUtils.copyProperties(medicationRequestUseExe, longMedicationRequest);
// 生成执行记录
DateTimeFormatter formatter = DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss");
// 转换为 LocalDateTime
LocalDateTime localDateTime = LocalDateTime.parse(executeTime, formatter);
// 转换为 Date
Date exeDate = Date.from(localDateTime.atZone(ZoneId.systemDefault()).toInstant());
// 执行记录id
Long procedureId = procedureService.addProcedureRecord(longMedicationRequest.getEncounterId(),
longMedicationRequest.getPatientId(), longMedicationRequest.getId(),
CommonConstants.TableName.MED_MEDICATION_REQUEST, EventStatus.COMPLETED,
ProcedureCategory.INPATIENT_ADVICE, null, exeDate, longMedicationRequest.getGroupId(), null);
// 生成药品发放
medicationDispenseService.generateMedicationDispense(longMedicationRequest, procedureId);
// 生成账单
chargeItem = new ChargeItem();
chargeItem.setStatusEnum(ChargeItemStatus.BILLABLE.getValue()); // 收费状态
chargeItem.setBusNo(AssignSeqEnum.CHARGE_ITEM_NO.getPrefix().concat(longMedicationRequest.getBusNo()));
chargeItem.setPrescriptionNo(longMedicationRequest.getPrescriptionNo()); // 处方号
chargeItem.setPatientId(longMedicationRequest.getPatientId()); // 患者
chargeItem.setContextEnum(ChargeItemContext.MEDICATION.getValue()); // 类型
chargeItem.setEncounterId(longMedicationRequest.getEncounterId()); // 就诊id
chargeItem.setEntererId(practitionerId);// 开立人ID
chargeItem.setRequestingOrgId(orgId); // 开立科室
chargeItem.setEnteredDate(curDate); // 开立时间
chargeItem.setServiceTable(CommonConstants.TableName.MED_MEDICATION_REQUEST);// 医疗服务类型
chargeItem.setServiceId(longMedicationRequest.getId()); // 医疗服务ID
chargeItem.setProductTable(CommonConstants.TableName.MED_MEDICATION_DEFINITION);// 产品所在表
chargeItem.setProductId(longMedicationRequest.getMedicationId());// 收费项id
chargeItem.setAccountId(medicationRequestUseExe.getAccountId());// 关联账户ID
chargeItem.setConditionId(longMedicationRequest.getConditionId()); // 诊断id
chargeItem.setEncounterDiagnosisId(longMedicationRequest.getEncounterDiagnosisId()); // 就诊诊断id
chargeItem.setProcedureId(procedureId);
// ------------------------------ 匹配定价信息
// 根据 medicationId 查找对应的医嘱信息
MedicationRequest finalLongMedicationRequest = longMedicationRequest;
Optional<AdviceBaseDto> matchedAdvice = medicationInfos.stream()
.filter(
advice -> finalLongMedicationRequest.getMedicationId().equals(advice.getAdviceDefinitionId()))
.findFirst();
if (!matchedAdvice.isPresent()) {
throw new RuntimeException(
"未找到对应的医嘱信息medicationId: " + finalLongMedicationRequest.getMedicationId());
}
AdviceBaseDto advice = matchedAdvice.get();
// 获取拆零比
BigDecimal partPercent = advice.getPartPercent();
// 在 priceList 中查找匹配的定价信息
Optional<AdvicePriceDto> matchedPrice = advice.getPriceList().stream()
.filter(price -> finalLongMedicationRequest.getLotNumber().equals(price.getConditionValue()))
.findFirst();
if (!matchedPrice.isPresent()) {
throw new RuntimeException("未找到匹配的定价信息lotNumber: " + finalLongMedicationRequest.getLotNumber());
}
AdvicePriceDto priceDto = matchedPrice.get();
// 计算价格
BigDecimal price;
if (finalLongMedicationRequest.getUnitCode().equals(priceDto.getUnitCode())) {
// unitCode 匹配,直接取 price
price = priceDto.getPrice();
} else {
// unitCode 不匹配,计算 price / partPercent
price = priceDto.getPrice().divide(partPercent, RoundingMode.HALF_UP);
}
chargeItem.setDefinitionId(priceDto.getDefinitionId()); // 费用定价ID
chargeItem.setDefDetailId(priceDto.getDefinitionDetailId()); // 定价子表主键
chargeItem.setQuantityValue(longMedicationRequest.getQuantity()); // 数量
chargeItem.setQuantityUnit(longMedicationRequest.getUnitCode()); // 单位
chargeItem.setUnitPrice(price); // 单价
chargeItem.setTotalPrice(
longMedicationRequest.getQuantity().multiply(price).setScale(4, RoundingMode.HALF_UP)); // 总价
chargeItemService.saveOrUpdate(chargeItem);
}
}
// 临时
MedicationRequest tempMedicationRequest;
for (MedicationRequestUseExe medicationRequestUseExe : tempMedication) {
for (String executeTime : medicationRequestUseExe.getExecuteTimes()) {
tempMedicationRequest = new MedicationRequest();
BeanUtils.copyProperties(medicationRequestUseExe, tempMedicationRequest);
// 生成执行记录
DateTimeFormatter formatter = DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss");
// 转换为 LocalDateTime
LocalDateTime localDateTime = LocalDateTime.parse(executeTime, formatter);
// 转换为 Date
Date exeDate = Date.from(localDateTime.atZone(ZoneId.systemDefault()).toInstant());
// 执行记录id
Long procedureId = procedureService.addProcedureRecord(tempMedicationRequest.getEncounterId(),
tempMedicationRequest.getPatientId(), tempMedicationRequest.getId(),
CommonConstants.TableName.MED_MEDICATION_REQUEST, EventStatus.COMPLETED,
ProcedureCategory.INPATIENT_ADVICE, null, exeDate, tempMedicationRequest.getGroupId(), null);
// 更新药品放发状态
medicationDispenseService.update(new LambdaUpdateWrapper<MedicationDispense>()
.eq(MedicationDispense::getMedReqId, tempMedicationRequest.getId())
.set(MedicationDispense::getStatusEnum, DispenseStatus.PREPARATION.getValue()));
// 更新账单状态
chargeItemService.update(
new LambdaUpdateWrapper<ChargeItem>().eq(ChargeItem::getServiceId, tempMedicationRequest.getId())
.set(ChargeItem::getProcedureId, procedureId)
.set(ChargeItem::getStatusEnum, ChargeItemStatus.BILLABLE.getValue()));
}
}
}
/**
* 执行诊疗医嘱
*
* @param actUseExeList 诊疗医嘱
*/
private void exeActivity(List<ServiceRequestUseExe> actUseExeList) {
// 长期医嘱
List<ServiceRequestUseExe> longActivity = actUseExeList.stream()
.filter(e -> TherapyTimeType.LONG_TERM.getValue().equals(e.getTherapyEnum())).collect(Collectors.toList());
// 临时医嘱
List<ServiceRequestUseExe> tempActivity = actUseExeList.stream()
.filter(e -> TherapyTimeType.TEMPORARY.getValue().equals(e.getTherapyEnum())).collect(Collectors.toList());
// 诊疗定义id集合
List<Long> activityDefinitionIdList =
actUseExeList.stream().map(ServiceRequestUseExe::getActivityId).collect(Collectors.toList());
// 医嘱详细信息
List<AdviceBaseDto> activityInfos = iDoctorStationAdviceAppService.getAdviceBaseInfo(null, null, null,
activityDefinitionIdList, 0L, 1, 500, Whether.NO.getValue(), List.of(3)).getRecords();
// 当前时间
Date curDate = new Date();
// 参与者id
Long practitionerId = SecurityUtils.getLoginUser().getPractitionerId();
// 当前登录账号的科室id
Long orgId = SecurityUtils.getLoginUser().getOrgId();
// 长期
ServiceRequest longServiceRequest;
ChargeItem chargeItem;
for (ServiceRequestUseExe serviceRequestUseExe : longActivity) {
for (String executeTime : serviceRequestUseExe.getExecuteTimes()) {
longServiceRequest = new ServiceRequest();
BeanUtils.copyProperties(serviceRequestUseExe, longServiceRequest);
// 生成执行记录
DateTimeFormatter formatter = DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss");
// 转换为 LocalDateTime
LocalDateTime localDateTime = LocalDateTime.parse(executeTime, formatter);
// 转换为 Date
Date exeDate = Date.from(localDateTime.atZone(ZoneId.systemDefault()).toInstant());
// 执行记录id
Long procedureId = procedureService.addProcedureRecord(longServiceRequest.getEncounterId(),
longServiceRequest.getPatientId(), longServiceRequest.getId(),
CommonConstants.TableName.WOR_SERVICE_REQUEST, EventStatus.COMPLETED,
ProcedureCategory.INPATIENT_ADVICE, null, exeDate, null, null);
// 生成账单
chargeItem = new ChargeItem();
chargeItem.setStatusEnum(ChargeItemStatus.BILLABLE.getValue()); // 收费状态
chargeItem.setBusNo(AssignSeqEnum.CHARGE_ITEM_NO.getPrefix().concat(longServiceRequest.getBusNo()));
chargeItem.setPatientId(longServiceRequest.getPatientId()); // 患者
chargeItem.setContextEnum(ChargeItemContext.ACTIVITY.getValue()); // 类型
chargeItem.setEncounterId(longServiceRequest.getEncounterId()); // 就诊id
chargeItem.setEntererId(practitionerId);// 开立人ID
chargeItem.setRequestingOrgId(orgId); // 开立科室
chargeItem.setEnteredDate(curDate); // 开立时间
chargeItem.setServiceTable(CommonConstants.TableName.WOR_SERVICE_REQUEST);// 医疗服务类型
chargeItem.setServiceId(longServiceRequest.getId()); // 医疗服务ID
chargeItem.setProductTable(CommonConstants.TableName.WOR_ACTIVITY_DEFINITION);// 产品所在表
chargeItem.setProductId(longServiceRequest.getActivityId());// 收费项id
chargeItem.setAccountId(serviceRequestUseExe.getAccountId());// 关联账户ID
chargeItem.setConditionId(longServiceRequest.getConditionId()); // 诊断id
chargeItem.setEncounterDiagnosisId(longServiceRequest.getEncounterDiagnosisId()); // 就诊诊断id
chargeItem.setProcedureId(procedureId);
// ------------------------------ 匹配定价信息
// 根据 activityId 查找对应的医嘱信息
ServiceRequest finalLongServiceRequest = longServiceRequest;
Optional<AdviceBaseDto> matchedAdvice = activityInfos.stream()
.filter(advice -> finalLongServiceRequest.getActivityId().equals(advice.getAdviceDefinitionId()))
.findFirst();
if (!matchedAdvice.isPresent()) {
throw new RuntimeException("未找到对应的医嘱信息activityId: " + finalLongServiceRequest.getActivityId());
}
// 医嘱信息
AdviceBaseDto advice = matchedAdvice.get();
// 定价信息
AdvicePriceDto priceDto = advice.getPriceList().get(0);
// 计算价格
BigDecimal price = priceDto.getPrice();
chargeItem.setDefinitionId(priceDto.getDefinitionId()); // 费用定价ID
chargeItem.setQuantityValue(longServiceRequest.getQuantity()); // 数量
chargeItem.setQuantityUnit(longServiceRequest.getUnitCode()); // 单位
chargeItem.setUnitPrice(price); // 单价
chargeItem
.setTotalPrice(longServiceRequest.getQuantity().multiply(price).setScale(4, RoundingMode.HALF_UP)); // 总价
chargeItemService.saveOrUpdate(chargeItem);
}
}
// 临时
ServiceRequest tempServiceRequest;
for (ServiceRequestUseExe serviceRequestUseExe : tempActivity) {
for (String executeTime : serviceRequestUseExe.getExecuteTimes()) {
tempServiceRequest = new ServiceRequest();
BeanUtils.copyProperties(serviceRequestUseExe, tempServiceRequest);
// 生成执行记录
DateTimeFormatter formatter = DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss");
// 转换为 LocalDateTime
LocalDateTime localDateTime = LocalDateTime.parse(executeTime, formatter);
// 转换为 Date
Date exeDate = Date.from(localDateTime.atZone(ZoneId.systemDefault()).toInstant());
// 执行记录id
Long procedureId = procedureService.addProcedureRecord(tempServiceRequest.getEncounterId(),
tempServiceRequest.getPatientId(), tempServiceRequest.getId(),
CommonConstants.TableName.WOR_SERVICE_REQUEST, EventStatus.COMPLETED,
ProcedureCategory.INPATIENT_ADVICE, null, exeDate, null, null);
// 更新账单状态
chargeItemService.update(
new LambdaUpdateWrapper<ChargeItem>().eq(ChargeItem::getServiceId, tempServiceRequest.getId())
.set(ChargeItem::getProcedureId, procedureId)
.set(ChargeItem::getStatusEnum, ChargeItemStatus.BILLABLE.getValue()));
}
}
}
/**
* 组装药品请求用于执行的数据结构
*
* @param medicineList 药品执行参数
* @return 用于执行的药品请求
*/
private List<MedicationRequestUseExe> assemblyMedication(List<AdviceExecuteDetailParam> medicineList) {
// 药品请求id集合
List<Long> medicineRequestIdList =
medicineList.stream().map(AdviceExecuteDetailParam::getRequestId).collect(Collectors.toList());
// 药品请求集合
List<MedicationRequest> medicationRequestList = medicationRequestService
.list(new LambdaQueryWrapper<MedicationRequest>().in(MedicationRequest::getId, medicineRequestIdList));
// 药品定义id集合
List<Long> medicationDefinitionIdList =
medicationRequestList.stream().map(MedicationRequest::getMedicationId).collect(Collectors.toList());
// 药品定义集合
List<MedicationDefinition> medicationDefinitionList = medicationDefinitionService.list(
new LambdaQueryWrapper<MedicationDefinition>().in(MedicationDefinition::getId, medicationDefinitionIdList));
// 组装MedicationRequestUseExe数据结构
List<MedicationRequestUseExe> medUseExeList = medicationRequestList.stream().map(medicationRequest -> {
// 创建 MedicationRequestUseExe 对象,并复制 MedicationRequest 的属性
MedicationRequestUseExe useExe = new MedicationRequestUseExe();
// 账号id赋值
AdviceExecuteDetailParam adviceExecuteDetailParam = medicineList.stream()
.filter(param -> medicationRequest.getId().equals(param.getRequestId())).findFirst().orElse(null);
if (adviceExecuteDetailParam != null) {
useExe.setAccountId(adviceExecuteDetailParam.getAccountId());
}
BeanUtils.copyProperties(medicationRequest, useExe);
// 匹配 executeTimes根据 medicationRequest 的 id 在 medicineList 中查找匹配的 executeTimes
List<String> matchedExecuteTimes =
medicineList.stream().filter(medicine -> medicine.getRequestId().equals(medicationRequest.getId()))
.findFirst().map(AdviceExecuteDetailParam::getExecuteTimes).orElse(null);
useExe.setExecuteTimes(matchedExecuteTimes);
// 计算 executeTimesNumexecuteTimes 的集合大小,转换为 BigDecimal
if (matchedExecuteTimes != null) {
useExe.setExecuteTimesNum(BigDecimal.valueOf(matchedExecuteTimes.size()));
} else {
useExe.setExecuteTimesNum(BigDecimal.ZERO);
}
// 匹配 minUnitQuantity根据 medicationId 在 medicationDefinitionList 中查找匹配的药品定义
MedicationDefinition matchedDefinition = medicationDefinitionList.stream()
.filter(definition -> definition.getId().equals(medicationRequest.getMedicationId())).findFirst()
.orElse(null);
if (matchedDefinition != null) {
// 判断 minUnitCode 是否等于 unitCode
if (matchedDefinition.getMinUnitCode().equals(medicationRequest.getUnitCode())) {
useExe.setMinUnitQuantity(medicationRequest.getQuantity());
} else {
// 若不相等,则计算 quantity * partPercent
BigDecimal partPercent = matchedDefinition.getPartPercent();
if (partPercent == null) {
partPercent = BigDecimal.ONE; // 避免空指针默认设为1
}
useExe.setMinUnitQuantity(medicationRequest.getQuantity().multiply(partPercent));
}
} else {
// 若未找到匹配的药品定义,设为 null 或默认值
useExe.setMinUnitQuantity(null);
}
return useExe;
}).toList();
return medUseExeList;
}
/**
* 组装诊疗请求用于执行的数据结构
*
* @param activityList 诊疗执行参数
* @return 用于执行的诊疗请求
*/
private List<ServiceRequestUseExe> assemblyActivity(List<AdviceExecuteDetailParam> activityList) {
// 诊疗请求id集合
List<Long> activityRequestIdList =
activityList.stream().map(AdviceExecuteDetailParam::getRequestId).collect(Collectors.toList());
// 诊疗请求集合
List<ServiceRequest> activityRequestList = serviceRequestService
.list(new LambdaQueryWrapper<ServiceRequest>().in(ServiceRequest::getId, activityRequestIdList));
// 组装ServiceRequestUseExe数据结构
List<ServiceRequestUseExe> actUseExeList = activityRequestList.stream().map(serviceRequest -> {
// 创建 ServiceRequestUseExe 对象,并复制 ServiceRequest 的属性
ServiceRequestUseExe useExe = new ServiceRequestUseExe();
// 账号id赋值
AdviceExecuteDetailParam adviceExecuteDetailParam = activityList.stream()
.filter(param -> serviceRequest.getId().equals(param.getRequestId())).findFirst().orElse(null);
if (adviceExecuteDetailParam != null) {
useExe.setAccountId(adviceExecuteDetailParam.getAccountId());
}
BeanUtils.copyProperties(serviceRequest, useExe);
// 匹配 executeTimes根据 serviceRequest 的 id 在 activityList 中查找匹配的 executeTimes
List<String> matchedExecuteTimes =
activityList.stream().filter(activity -> activity.getRequestId().equals(serviceRequest.getId()))
.findFirst().map(AdviceExecuteDetailParam::getExecuteTimes).orElse(null);
useExe.setExecuteTimes(matchedExecuteTimes);
// 计算 executeTimesNumexecuteTimes 的集合大小,转换为 BigDecimal
if (matchedExecuteTimes != null) {
useExe.setExecuteTimesNum(BigDecimal.valueOf(matchedExecuteTimes.size()));
} else {
useExe.setExecuteTimesNum(BigDecimal.ZERO);
}
return useExe;
}).toList();
return actUseExeList;
}
}

View File

@@ -7,20 +7,15 @@ import java.util.stream.Collectors;
import javax.annotation.Resource;
import javax.servlet.http.HttpServletRequest;
import com.core.common.constant.HttpStatus;
import com.core.common.utils.*;
import com.openhis.web.inhospitalnursestation.appservice.IInpatientMedicineCollectionAppService;
import com.openhis.web.pharmacymanage.dto.InventoryDto;
import com.openhis.workflow.domain.SupplyDelivery;
import com.openhis.workflow.domain.SupplyRequest;
import com.openhis.workflow.service.IDeviceDispenseService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.core.common.constant.HttpStatus;
import com.core.common.core.domain.R;
import com.core.common.exception.ServiceException;
import com.core.common.utils.*;
import com.openhis.common.constant.CommonConstants;
import com.openhis.common.constant.PromptMsgConstant;
import com.openhis.common.enums.*;
@@ -28,10 +23,17 @@ import com.openhis.common.enums.ybenums.YbDrordType;
import com.openhis.common.utils.EnumUtils;
import com.openhis.common.utils.HisQueryUtils;
import com.openhis.medication.service.IMedicationDispenseService;
import com.openhis.web.inhospitalnursestation.dto.*;
import com.openhis.web.inhospitalnursestation.appservice.IMedicineSummaryAppService;
import com.openhis.web.inhospitalnursestation.dto.InpatientMedicineEncounterInfoDto;
import com.openhis.web.inhospitalnursestation.dto.InpatientMedicinePrescriptionInfoDto;
import com.openhis.web.inhospitalnursestation.dto.InpatientMedicineSearchParam;
import com.openhis.web.inhospitalnursestation.mapper.InpatientMedicineCollectionMapper;
import com.openhis.web.pharmacymanage.dto.InventoryDto;
import com.openhis.web.pharmacymanage.mapper.ReturnMedicineMapper;
import com.openhis.workflow.domain.InventoryItem;
import com.openhis.workflow.domain.SupplyDelivery;
import com.openhis.workflow.domain.SupplyRequest;
import com.openhis.workflow.service.IDeviceDispenseService;
import com.openhis.workflow.service.ISupplyDeliveryService;
import com.openhis.workflow.service.ISupplyRequestService;
@@ -42,7 +44,7 @@ import com.openhis.workflow.service.ISupplyRequestService;
* @date 2025/8/18
*/
@Service
public class InpatientMedicineCollectionAppServiceImpl implements IInpatientMedicineCollectionAppService {
public class MedicineSummaryAppServiceImpl implements IMedicineSummaryAppService {
@Resource
private AssignSeqUtil assignSeqUtil;

View File

@@ -75,7 +75,7 @@ public class AdviceProcessController {
* @return 操作结果
*/
@PutMapping(value = "/advice-verify")
public R<?> adviceVerify(List<PerformInfoDto> performInfoList) {
public R<?> adviceVerify(@RequestBody List<PerformInfoDto> performInfoList) {
return adviceProcessAppService.adviceVerify(performInfoList);
}
@@ -86,7 +86,7 @@ public class AdviceProcessController {
* @return 操作结果
*/
@PutMapping(value = "/advice-reject")
public R<?> adviceReject(List<PerformInfoDto> performInfoList) {
public R<?> adviceReject(@RequestBody List<PerformInfoDto> performInfoList) {
return adviceProcessAppService.adviceReject(performInfoList);
}
@@ -104,22 +104,22 @@ public class AdviceProcessController {
/**
* 医嘱取消执行
*
* @param performInfoList 医嘱信息集合
* @param adviceExecuteParam 取消执行参数
* @return 操作结果
*/
@PostMapping(value = "/advice-cancel")
public R<?> adviceCancel(List<PerformInfoDto> performInfoList) {
return adviceProcessAppService.adviceCancel(performInfoList);
public R<?> adviceCancel(@RequestBody AdviceExecuteParam adviceExecuteParam) {
return adviceProcessAppService.adviceCancel(adviceExecuteParam);
}
/**
* 医嘱不执行
*
* @param performInfoList 医嘱信息集合
* @param adviceExecuteParam 不执行参数
* @return 操作结果
*/
@PostMapping(value = "/advice-void")
public R<?> adviceVoid(List<PerformInfoDto> performInfoList) {
return adviceProcessAppService.adviceVoid(performInfoList);
public R<?> adviceVoid(AdviceExecuteParam adviceExecuteParam) {
return adviceProcessAppService.adviceVoid(adviceExecuteParam);
}
}

View File

@@ -5,7 +5,7 @@ import java.util.List;
import javax.annotation.Resource;
import javax.servlet.http.HttpServletRequest;
import com.openhis.web.inhospitalnursestation.appservice.IInpatientMedicineCollectionAppService;
import com.openhis.web.inhospitalnursestation.appservice.IMedicineSummaryAppService;
import com.openhis.web.inhospitalnursestation.dto.InpatientMedicinePrescriptionInfoDto;
import org.springframework.web.bind.annotation.*;
@@ -22,13 +22,13 @@ import lombok.extern.slf4j.Slf4j;
* @date 2025/8/18
*/
@RestController
@RequestMapping("/nurse-station/inpatient-medicine-collection")
@RequestMapping("/nurse-station/medicine-summary")
@Slf4j
@AllArgsConstructor
public class InpatientMedicineCollectionController {
public class MedicineSummaryController {
@Resource
public IInpatientMedicineCollectionAppService medicineCollectionService;
public IMedicineSummaryAppService medicineCollectionService;
/**
* 分页查询在科病人列表
@@ -56,7 +56,7 @@ public class InpatientMedicineCollectionController {
* @param pageSize 查询条数
* @param request 请求数据
*/
@GetMapping("/prescription-list")
@GetMapping("/advice-list")
public R<?> getPatientInfoList(InpatientMedicineSearchParam searchParam, String searchKey,
@RequestParam(value = "pageNo", defaultValue = "1") Integer pageNo,
@RequestParam(value = "pageSize", defaultValue = "10") Integer pageSize, HttpServletRequest request) {

View File

@@ -25,6 +25,17 @@ public class AdviceExecuteDetailParam {
@JsonSerialize(using = ToStringSerializer.class)
private Long requestId;
/** 账号id */
@JsonSerialize(using = ToStringSerializer.class)
private Long accountId;
/** 执行id */
@JsonSerialize(using = ToStringSerializer.class)
private Long procedureId;
/** 医嘱类型 */
private Integer therapyEnum;
/** 医嘱请求所在表 */
private String adviceTable;

View File

@@ -30,6 +30,10 @@ public class InpatientAdviceDto {
@JsonSerialize(using = ToStringSerializer.class)
private Long encounterId;
/** 患者id */
@JsonSerialize(using = ToStringSerializer.class)
private Long patientId;
/** 医嘱所在表 */
private String adviceTable; // 1:药品 , 2: 耗材 , 3:项目
/**
@@ -199,7 +203,7 @@ public class InpatientAdviceDto {
private String patientName;
/** 床位名称 */
private String badName;
private String bedName;
/** 性别 */
private Integer genderEnum;
@@ -226,4 +230,16 @@ public class InpatientAdviceDto {
/** 余额 */
private BigDecimal balanceAmount;
/**
* 账号id
*/
@JsonSerialize(using = ToStringSerializer.class)
private Long accountId;
/**
* 校对人id
*/
@JsonSerialize(using = ToStringSerializer.class)
private Long performerCheckId;
}

View File

@@ -3,6 +3,8 @@
*/
package com.openhis.web.inhospitalnursestation.dto;
import com.fasterxml.jackson.databind.annotation.JsonSerialize;
import com.fasterxml.jackson.databind.ser.std.ToStringSerializer;
import lombok.Data;
import lombok.experimental.Accessors;

View File

@@ -6,6 +6,8 @@ package com.openhis.web.inhospitalnursestation.dto;
import java.math.BigDecimal;
import java.util.List;
import com.fasterxml.jackson.databind.annotation.JsonSerialize;
import com.fasterxml.jackson.databind.ser.std.ToStringSerializer;
import com.openhis.medication.domain.MedicationRequest;
import lombok.Data;
@@ -21,6 +23,12 @@ import lombok.experimental.Accessors;
@Accessors(chain = true)
public class MedicationRequestUseExe extends MedicationRequest {
/**
* 账号id
*/
@JsonSerialize(using = ToStringSerializer.class)
private Long accountId;
/** 执行时间点集合 */
private List<String> executeTimes;

View File

@@ -0,0 +1,40 @@
/*
* Copyright ©2023 CJB-CNIT Team. All rights reserved
*/
package com.openhis.web.inhospitalnursestation.dto;
import java.math.BigDecimal;
import java.util.List;
import com.fasterxml.jackson.databind.annotation.JsonSerialize;
import com.fasterxml.jackson.databind.ser.std.ToStringSerializer;
import com.openhis.workflow.domain.ServiceRequest;
import lombok.Data;
import lombok.experimental.Accessors;
/**
* 诊疗请求用于执行
*
* @author zwh
* @date 2025-07-28
*/
@Data
@Accessors(chain = true)
public class ServiceRequestUseExe extends ServiceRequest {
/**
* 账号id
*/
@JsonSerialize(using = ToStringSerializer.class)
private Long accountId;
/** 执行时间点集合 */
private List<String> executeTimes;
/**
* 执行时间点集合数量
*/
private BigDecimal executeTimesNum;
}