feat: 合并 upstream/v1.3 新增功能模块(安全合并策略)
新增功能模块:
- 药房管理:住院退药、处方审核功能
- 报表管理:门诊管理报表、药房结算报表、医嘱统计报表
- 支付管理:三方对账功能
- 新增枚举类:电子处方类型、频次类型、病历状态等10个
- 新增实体类:处方审核记录、第三方支付请求、中医结算目录
- 工具类增强:年龄计算、Excel工具
合并策略:仅合并低风险新增文件,保留现有业务功能
上游版本:v1.3 (2025-03-06发版)
合并分支:merge-upstream-v1.3-0310
🤖 Auto-generated by Claude Code
This commit is contained in:
@@ -0,0 +1,59 @@
|
||||
/*
|
||||
* Copyright ©2023 CJB-CNIT Team. All rights reserved
|
||||
*/
|
||||
package com.openhis.web.pharmacymanage.appservice;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
import javax.servlet.http.HttpServletRequest;
|
||||
|
||||
import com.core.common.core.domain.R;
|
||||
import com.openhis.web.pharmacymanage.dto.EncounterInfoDto;
|
||||
import com.openhis.web.pharmacymanage.dto.ReturnMedicineDto;
|
||||
|
||||
/**
|
||||
* TODO:概括描述当前类的主要用途和注意事项
|
||||
*
|
||||
* @author zwh
|
||||
* @date 2025-12-29
|
||||
*/
|
||||
public interface IInHospitalReturnMedicineAppService {
|
||||
|
||||
/**
|
||||
* 页面初始化
|
||||
*
|
||||
* @return 初始化信息
|
||||
*/
|
||||
R<?> init();
|
||||
|
||||
/**
|
||||
* 查询退药患者分页列表
|
||||
*
|
||||
* @param encounterInfoDto 查询条件
|
||||
* @param searchKey 模糊查询关键字
|
||||
* @param pageNo 当前页码
|
||||
* @param pageSize 查询条数
|
||||
* @param request 请求数据
|
||||
* @return 退药患者分页列表
|
||||
*/
|
||||
R<?> getReturnMedicinePatientPage(EncounterInfoDto encounterInfoDto, String searchKey, Integer pageNo,
|
||||
Integer pageSize, HttpServletRequest request);
|
||||
|
||||
/**
|
||||
* 查询退药信息
|
||||
*
|
||||
* @param encounterId 就诊ID
|
||||
* @param refundStatus 退药id
|
||||
* @param itemTable 项目类型
|
||||
* @return 退药信息
|
||||
*/
|
||||
R<?> getReturnMedicineInfo(Long encounterId, Integer refundStatus, String itemTable);
|
||||
|
||||
/**
|
||||
* 退药处理
|
||||
*
|
||||
* @param medicineReturnList 退药清单
|
||||
* @return 处理结果
|
||||
*/
|
||||
R<?> medicineReturn(List<ReturnMedicineDto> medicineReturnList);
|
||||
}
|
||||
@@ -0,0 +1,62 @@
|
||||
package com.openhis.web.pharmacymanage.appservice;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
import javax.servlet.http.HttpServletRequest;
|
||||
import javax.servlet.http.HttpServletResponse;
|
||||
|
||||
import com.core.common.core.domain.R;
|
||||
import com.openhis.administration.dto.PrescriptionReviewRecordDto;
|
||||
|
||||
/**
|
||||
* 处方审方 应用实现接口
|
||||
*
|
||||
* @author swb
|
||||
* @date 2026/01/29
|
||||
*/
|
||||
public interface IPrescriptionReviewAppService {
|
||||
|
||||
/**
|
||||
* 审方
|
||||
*
|
||||
* @param recordDto 处方审方记录dto
|
||||
* @return 是否成功
|
||||
*/
|
||||
R<?> review(PrescriptionReviewRecordDto recordDto);
|
||||
|
||||
/**
|
||||
* 查询处方审方记录
|
||||
*
|
||||
* @param prescriptionNoList 处方号集合
|
||||
* @param reviewStatus 审核状态
|
||||
* @return 处方审方记录
|
||||
*/
|
||||
List<PrescriptionReviewRecordDto> getPrescriptionReviewRecords(List<String> prescriptionNoList,
|
||||
Integer reviewStatus);
|
||||
|
||||
/**
|
||||
* 查询处方审核信息
|
||||
*
|
||||
* @param practitionerId 参与者id
|
||||
* @param reviewStatus 审核状态
|
||||
* @param patientName 患者姓名
|
||||
* @param pageNo 当前页
|
||||
* @param pageSize 每页多少条
|
||||
* @param request 请求
|
||||
* @return 处方审核信息
|
||||
*/
|
||||
R<?> getPrescriptionReviewPageInfo(Long practitionerId, Integer reviewStatus, String patientName, Integer pageNo,
|
||||
Integer pageSize, HttpServletRequest request);
|
||||
|
||||
/**
|
||||
* 导出处方审核信息
|
||||
*
|
||||
* @param practitionerId 参与者id
|
||||
* @param reviewStatus 审核状态
|
||||
* @param patientName 患者姓名
|
||||
* @param request 请求
|
||||
* @param response 响应
|
||||
*/
|
||||
void makeFile(Long practitionerId, Integer reviewStatus, String patientName, HttpServletRequest request,
|
||||
HttpServletResponse response);
|
||||
}
|
||||
@@ -0,0 +1,686 @@
|
||||
/*
|
||||
* Copyright ©2023 CJB-CNIT Team. All rights reserved
|
||||
*/
|
||||
package com.openhis.web.pharmacymanage.appservice.impl;
|
||||
|
||||
import java.math.BigDecimal;
|
||||
import java.util.*;
|
||||
import java.util.function.Function;
|
||||
import java.util.stream.Collectors;
|
||||
|
||||
import javax.annotation.Resource;
|
||||
import javax.servlet.http.HttpServletRequest;
|
||||
|
||||
import org.apache.commons.lang3.tuple.Pair;
|
||||
import org.springframework.stereotype.Service;
|
||||
|
||||
import com.alibaba.fastjson.JSONArray;
|
||||
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
|
||||
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
|
||||
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
|
||||
import com.core.common.core.domain.R;
|
||||
import com.core.common.exception.ServiceException;
|
||||
import com.core.common.utils.AgeCalculatorUtil;
|
||||
import com.core.common.utils.DateUtils;
|
||||
import com.core.common.utils.MessageUtils;
|
||||
import com.core.common.utils.SecurityUtils;
|
||||
import com.openhis.administration.domain.*;
|
||||
import com.openhis.administration.service.*;
|
||||
import com.openhis.common.constant.CommonConstants;
|
||||
import com.openhis.common.constant.PromptMsgConstant;
|
||||
import com.openhis.common.enums.*;
|
||||
import com.openhis.common.enums.ybenums.YbInvChgType;
|
||||
import com.openhis.common.enums.ybenums.YbMdtrtCertType;
|
||||
import com.openhis.common.enums.ybenums.YbRxFlag;
|
||||
import com.openhis.common.utils.EnumUtils;
|
||||
import com.openhis.common.utils.HisQueryUtils;
|
||||
import com.openhis.financial.domain.Contract;
|
||||
import com.openhis.financial.domain.PaymentReconciliation;
|
||||
import com.openhis.financial.service.IContractService;
|
||||
import com.openhis.financial.service.IPaymentReconciliationService;
|
||||
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.inventorymanage.appservice.impl.ReceiptApprovalAppServiceImpl;
|
||||
import com.openhis.web.inventorymanage.dto.SupplyItemDetailDto;
|
||||
import com.openhis.web.pharmacymanage.appservice.IInHospitalReturnMedicineAppService;
|
||||
import com.openhis.web.pharmacymanage.dto.*;
|
||||
import com.openhis.web.pharmacymanage.mapper.InHospitalReturnMedicineAppMapper;
|
||||
import com.openhis.web.pharmacymanage.mapper.ReturnMedicineMapper;
|
||||
import com.openhis.workflow.domain.DeviceDispense;
|
||||
import com.openhis.workflow.domain.InventoryItem;
|
||||
import com.openhis.workflow.service.IDeviceDispenseService;
|
||||
import com.openhis.workflow.service.IDeviceRequestService;
|
||||
import com.openhis.workflow.service.IInventoryItemService;
|
||||
import com.openhis.yb.domain.ClinicSettle;
|
||||
import com.openhis.yb.dto.Medical3506Param;
|
||||
import com.openhis.yb.dto.MedicalInventory3511Param;
|
||||
import com.openhis.yb.service.IClinicSettleService;
|
||||
import com.openhis.yb.service.YbManager;
|
||||
|
||||
/**
|
||||
* TODO:概括描述当前类的主要用途和注意事项
|
||||
*
|
||||
* @author zwh
|
||||
* @date 2025-12-29
|
||||
*/
|
||||
@Service
|
||||
public class InHospitalReturnMedicineAppServiceImpl implements IInHospitalReturnMedicineAppService {
|
||||
|
||||
@Resource
|
||||
private ITraceNoManageService traceNoManageService;
|
||||
|
||||
@Resource
|
||||
private IOrganizationService iOrganizationService;
|
||||
|
||||
@Resource
|
||||
private IInventoryItemService iInventoryItemService;
|
||||
|
||||
@Resource
|
||||
private InHospitalReturnMedicineAppMapper inHospitalReturnMedicineAppMapper;
|
||||
|
||||
@Resource
|
||||
private ReturnMedicineMapper returnMedicineMapper;
|
||||
|
||||
@Resource
|
||||
private IMedicationRequestService medicationRequestService;
|
||||
|
||||
@Resource
|
||||
private IMedicationDispenseService medicationDispenseService;
|
||||
|
||||
@Resource
|
||||
private IDeviceDispenseService deviceDispenseService;
|
||||
|
||||
@Resource
|
||||
private IDeviceRequestService deviceRequestService;
|
||||
|
||||
@Resource
|
||||
private YbManager ybService;
|
||||
|
||||
@Resource
|
||||
private IChargeItemService iChargeItemService;
|
||||
|
||||
@Resource
|
||||
private IPaymentReconciliationService iPaymentReconciliationService;
|
||||
|
||||
@Resource
|
||||
private IContractService iContractService;
|
||||
|
||||
@Resource
|
||||
private IClinicSettleService clinicSettleService;
|
||||
|
||||
@Resource
|
||||
private IEncounterDiagnosisService encounterDiagnosisService;
|
||||
|
||||
@Resource
|
||||
private IAccountService accountService;
|
||||
|
||||
@Resource
|
||||
private IDeviceDefinitionService deviceDefinitionService;
|
||||
|
||||
@Resource
|
||||
private IMedicationDefinitionService medicationDefinitionService;
|
||||
|
||||
@Resource
|
||||
private ReceiptApprovalAppServiceImpl receiptApprovalAppService;
|
||||
|
||||
/**
|
||||
* 获取页面初始化信息
|
||||
*
|
||||
* @return 初始化信息
|
||||
*/
|
||||
@Override
|
||||
public R<?> init() {
|
||||
|
||||
ReturnMedicineInitDto initDto = new ReturnMedicineInitDto();
|
||||
|
||||
// 获取科室下拉选列表
|
||||
List<Organization> organizationList =
|
||||
iOrganizationService.getList(OrganizationType.DEPARTMENT.getValue(), String.valueOf(OrganizationClass.CLINIC.getValue()));
|
||||
List<ReturnMedicineInitDto.DepartmentOption> organizationOptions = organizationList.stream().map(
|
||||
organization -> new ReturnMedicineInitDto.DepartmentOption(organization.getId(), organization.getName()))
|
||||
.collect(Collectors.toList());
|
||||
|
||||
// 发药状态
|
||||
List<ReturnMedicineInitDto.RefundStatusOption> refundStatusOptions = new ArrayList<>();
|
||||
refundStatusOptions.add(new ReturnMedicineInitDto.RefundStatusOption(DispenseStatus.PENDING_REFUND.getValue(),
|
||||
DispenseStatus.PENDING_REFUND.getInfo()));
|
||||
refundStatusOptions.add(new ReturnMedicineInitDto.RefundStatusOption(DispenseStatus.REFUNDED.getValue(),
|
||||
DispenseStatus.REFUNDED.getInfo()));
|
||||
initDto.setDepartmentOptions(organizationOptions).setRefundStatusOptions(refundStatusOptions);
|
||||
return R.ok(initDto);
|
||||
}
|
||||
|
||||
/**
|
||||
* 查询退药患者分页列表
|
||||
*
|
||||
* @param encounterInfoDto 查询条件
|
||||
* @param searchKey 模糊查询关键字
|
||||
* @param pageNo 当前页码
|
||||
* @param pageSize 查询条数
|
||||
* @param request 请求数据
|
||||
* @return 退药患者分页列表
|
||||
*/
|
||||
@Override
|
||||
public R<?> getReturnMedicinePatientPage(EncounterInfoDto encounterInfoDto, String searchKey, Integer pageNo,
|
||||
Integer pageSize, HttpServletRequest request) {
|
||||
Integer refundEnum = encounterInfoDto.getRefundEnum();
|
||||
encounterInfoDto.setRefundEnum(null);
|
||||
// 构建查询条件
|
||||
QueryWrapper<EncounterInfoDto> queryWrapper = HisQueryUtils.buildQueryWrapper(encounterInfoDto, searchKey,
|
||||
new HashSet<>(Arrays.asList(CommonConstants.FieldName.PatientName, CommonConstants.FieldName.IdCard,
|
||||
CommonConstants.FieldName.PatientPyStr, CommonConstants.FieldName.PatientWbStr)),
|
||||
request);
|
||||
// 查询退药患者分页列表
|
||||
Page<EncounterInfoDto> encounterInfoPage = inHospitalReturnMedicineAppMapper.selectEncounterInfoListPage(
|
||||
new Page<>(pageNo, pageSize), queryWrapper, refundEnum, DispenseStatus.PENDING_REFUND.getValue(),
|
||||
DispenseStatus.REFUNDED.getValue(), EncounterClass.IMP.getValue(),
|
||||
CommonConstants.TableName.MED_MEDICATION_DEFINITION, CommonConstants.TableName.ADM_DEVICE_DEFINITION);
|
||||
encounterInfoPage.getRecords().forEach(encounterInfo -> {
|
||||
// 性别
|
||||
encounterInfo.setGenderEnum_enumText(
|
||||
EnumUtils.getInfoByValue(AdministrativeGender.class, encounterInfo.getGenderEnum()));
|
||||
// 年龄
|
||||
encounterInfo.setAge(AgeCalculatorUtil.getAge(encounterInfo.getBirthDate()));
|
||||
// 退药状态
|
||||
encounterInfo
|
||||
.setRefundEnum_enumText(EnumUtils.getInfoByValue(DispenseStatus.class, encounterInfo.getRefundEnum()));
|
||||
});
|
||||
return R.ok(encounterInfoPage);
|
||||
}
|
||||
|
||||
/**
|
||||
* 查询退药信息
|
||||
*
|
||||
* @param encounterId 就诊ID
|
||||
* @param refundStatus 退药id
|
||||
* @param itemTable 项目类型
|
||||
* @return 退药信息
|
||||
*/
|
||||
@Override
|
||||
public R<?> getReturnMedicineInfo(Long encounterId, Integer refundStatus, String itemTable) {
|
||||
// 获取退药信息
|
||||
List<ReturnMedicineInfoDto> returnMedicineInfoList = inHospitalReturnMedicineAppMapper.selectReturnMedicineInfo(
|
||||
encounterId, CommonConstants.TableName.WOR_DEVICE_REQUEST, CommonConstants.TableName.MED_MEDICATION_REQUEST,
|
||||
CommonConstants.TableName.MED_MEDICATION_DEFINITION, CommonConstants.TableName.ADM_DEVICE_DEFINITION,
|
||||
itemTable, refundStatus, DispenseStatus.PENDING_REFUND.getValue(), DispenseStatus.REFUNDED.getValue());
|
||||
returnMedicineInfoList.forEach(returnMedicineInfoDto -> {
|
||||
// 退药状态
|
||||
returnMedicineInfoDto.setRefundEnum_enumText(
|
||||
EnumUtils.getInfoByValue(DispenseStatus.class, returnMedicineInfoDto.getRefundEnum()));
|
||||
// 退药请求状态
|
||||
returnMedicineInfoDto.setReqStatus_enumText(
|
||||
EnumUtils.getInfoByValue(RequestStatus.class, returnMedicineInfoDto.getReqStatus()));
|
||||
});
|
||||
return R.ok(returnMedicineInfoList);
|
||||
}
|
||||
|
||||
/**
|
||||
* 退药处理
|
||||
*
|
||||
* @param medicineReturnList 退药清单
|
||||
* @return 处理结果
|
||||
*/
|
||||
@Override
|
||||
public R<?> medicineReturn(List<ReturnMedicineDto> medicineReturnList) {
|
||||
if (medicineReturnList == null || medicineReturnList.isEmpty()) {
|
||||
return R.ok();
|
||||
}
|
||||
// 分别处理退药与退耗材的请求
|
||||
List<ReturnMedicineDto> returnMedicineList = new ArrayList<>();
|
||||
List<ReturnMedicineDto> returnDeviceList = new ArrayList<>();
|
||||
// 追溯码列表
|
||||
List<TraceNoManage> traceNoManageList = new ArrayList<>();
|
||||
TraceNoManage traceNoManage;
|
||||
|
||||
medicineReturnList.forEach(item -> {
|
||||
switch (item.getTableName()) {
|
||||
case CommonConstants.TableName.MED_MEDICATION_REQUEST -> returnMedicineList
|
||||
.add(new ReturnMedicineDto().setDispenseId(item.getDispenseId()).setRequestId(item.getRequestId()));
|
||||
case CommonConstants.TableName.WOR_DEVICE_REQUEST -> returnDeviceList
|
||||
.add(new ReturnMedicineDto().setDispenseId(item.getDispenseId()).setRequestId(item.getRequestId()));
|
||||
}
|
||||
});
|
||||
// 进销存参数
|
||||
List<SupplyItemDetailDto> supplyItemDetailList = new ArrayList<>();
|
||||
|
||||
// 处理退药
|
||||
// 获取药品退药id列表
|
||||
List<Long> medReturnIdList = new ArrayList<>();
|
||||
if (!returnMedicineList.isEmpty()) {
|
||||
// 获取药品退药id列表
|
||||
medReturnIdList =
|
||||
returnMedicineList.stream().map(ReturnMedicineDto::getDispenseId).collect(Collectors.toList());
|
||||
// 获取药品退药请求id列表
|
||||
List<Long> medRequestIdList =
|
||||
returnMedicineList.stream().map(ReturnMedicineDto::getRequestId).collect(Collectors.toList());
|
||||
if (medReturnIdList.isEmpty()) {
|
||||
throw new ServiceException("请选择要退的药品");
|
||||
}
|
||||
if (medRequestIdList.isEmpty()) {
|
||||
throw new ServiceException("请选择要退的药品");
|
||||
}
|
||||
// 药品退药信息查询
|
||||
List<MedicationDispense> refundMedList = medicationDispenseService.listByIds(medReturnIdList);
|
||||
// 药品退药请求查询
|
||||
List<MedicationRequest> refundMedRequestList = medicationRequestService.listByIds(medRequestIdList);
|
||||
if (refundMedList == null || refundMedList.isEmpty()) {
|
||||
throw new ServiceException("请选择要退的药品");
|
||||
}
|
||||
// 重复退药校验
|
||||
if (refundMedList.stream().map(MedicationDispense::getStatusEnum)
|
||||
.anyMatch(x -> x.equals(DispenseStatus.REFUNDED.getValue()))) {
|
||||
throw new ServiceException("药品已退药,请勿重复退药");
|
||||
}
|
||||
|
||||
// 更新退药单
|
||||
for (MedicationDispense medicationDispense : refundMedList) {
|
||||
// 退药状态
|
||||
medicationDispense.setStatusEnum(DispenseStatus.REFUNDED.getValue());
|
||||
// 退药数量
|
||||
medicationDispense.setDispenseQuantity(medicationDispense.getQuantity());
|
||||
// 状态变更时间
|
||||
medicationDispense.setStatusChangedTime(DateUtils.getNowDate());
|
||||
// 退药时间
|
||||
medicationDispense.setDispenseTime(DateUtils.getNowDate());
|
||||
// 退药人
|
||||
medicationDispense.setPractitionerId(SecurityUtils.getLoginUser().getPractitionerId());
|
||||
|
||||
// 设置库存变更参数
|
||||
SupplyItemDetailDto supplyItemDetailDto = new SupplyItemDetailDto();
|
||||
for (MedicationRequest medicationRequest : refundMedRequestList) {
|
||||
// 根据退药id查询退药请求id(用于医保关联)
|
||||
if (medicationDispense.getMedReqId().equals(medicationRequest.getId())) {
|
||||
supplyItemDetailDto.setRequestId(medicationRequest.getRefundMedicineId());
|
||||
}
|
||||
}
|
||||
supplyItemDetailDto.setItemTable(CommonConstants.TableName.MED_MEDICATION_DEFINITION)
|
||||
.setItemId(medicationDispense.getMedicationId()).setLotNumber(medicationDispense.getLotNumber());
|
||||
supplyItemDetailList.add(supplyItemDetailDto);
|
||||
|
||||
// 追溯码表相关处理
|
||||
if (medicationDispense.getTraceNo() != null) {
|
||||
// 使用逗号分割追溯码并转换为List
|
||||
String[] traceNoList = medicationDispense.getTraceNo().split(CommonConstants.Common.COMMA);
|
||||
for (String item : traceNoList) {
|
||||
traceNoManage = new TraceNoManage();
|
||||
// 追溯码处理
|
||||
traceNoManage.setItemTable(CommonConstants.TableName.MED_MEDICATION_DEFINITION)
|
||||
// 项目id
|
||||
.setItemId(medicationDispense.getMedicationId())
|
||||
// 仓库类型
|
||||
.setLocationTypeEnum(null)
|
||||
// 仓库
|
||||
.setLocationId(medicationDispense.getLocationId())
|
||||
// 仓位
|
||||
.setLocationStoreId(null)
|
||||
// 产品批号
|
||||
.setLotNumber(medicationDispense.getLotNumber())
|
||||
// 追溯码
|
||||
.setTraceNo(item)
|
||||
// 追溯码状态
|
||||
.setStatusEnum(TraceNoStatus.IN.getValue())
|
||||
// 追溯码单位
|
||||
.setUnitCode(medicationDispense.getUnitCode())
|
||||
// 操作类型
|
||||
.setOperationType(SupplyType.RETURN_MEDICATION.getValue());
|
||||
traceNoManageList.add(traceNoManage);
|
||||
}
|
||||
}
|
||||
}
|
||||
// 退药更新
|
||||
medicationDispenseService.updateBatchById(refundMedList);
|
||||
}
|
||||
|
||||
// 处理退耗材
|
||||
// 获取退耗材id列表
|
||||
List<Long> devReturnIdList = new ArrayList<>();
|
||||
if (!returnDeviceList.isEmpty()) {
|
||||
// 获取退耗材id列表
|
||||
devReturnIdList =
|
||||
returnDeviceList.stream().map(ReturnMedicineDto::getDispenseId).collect(Collectors.toList());
|
||||
// 获取退耗材请求id列表
|
||||
List<Long> devRequestIdList = returnDeviceList.stream().map(ReturnMedicineDto::getRequestId).toList();
|
||||
if (devReturnIdList.isEmpty()) {
|
||||
throw new ServiceException("请选择要退的耗材");
|
||||
}
|
||||
if (devRequestIdList.isEmpty()) {
|
||||
throw new ServiceException("请选择要退的耗材");
|
||||
}
|
||||
// 退耗材信息查询
|
||||
List<DeviceDispense> refundDevList = deviceDispenseService.listByIds(devReturnIdList);
|
||||
if (refundDevList == null || refundDevList.isEmpty()) {
|
||||
throw new ServiceException("请选择要退的耗材");
|
||||
}
|
||||
// 重复退耗材校验
|
||||
if (refundDevList.stream().map(DeviceDispense::getStatusEnum)
|
||||
.anyMatch(x -> x.equals(DispenseStatus.REFUNDED.getValue()))) {
|
||||
throw new ServiceException("耗材已退,请勿重复操作");
|
||||
}
|
||||
// 更新退耗材单状态
|
||||
for (DeviceDispense deviceDispense : refundDevList) {
|
||||
// 退药时间
|
||||
deviceDispense.setDispenseTime(DateUtils.getNowDate());
|
||||
// 退药数量
|
||||
deviceDispense.setDispenseQuantity(deviceDispense.getQuantity());
|
||||
// 退药状态
|
||||
deviceDispense.setStatusEnum(DispenseStatus.REFUNDED.getValue());
|
||||
// 设置库存变更参数
|
||||
supplyItemDetailList
|
||||
.add(new SupplyItemDetailDto().setItemTable(CommonConstants.TableName.ADM_DEVICE_DEFINITION)
|
||||
.setItemId(deviceDispense.getDeviceDefId()).setLotNumber(deviceDispense.getLotNumber()));
|
||||
// // 使用逗号分割追溯码并转换为List
|
||||
// String[] traceNoList = deviceDispense.getTraceNo().split(CommonConstants.Common.COMMA);
|
||||
// for (String item : traceNoList) {
|
||||
// traceNoManage = new TraceNoManage();
|
||||
// // 追溯码处理
|
||||
// traceNoManage.setItemTable(CommonConstants.TableName.ADM_DEVICE_DEFINITION)
|
||||
// // 项目id
|
||||
// .setItemId(deviceDispense.getDeviceDefId())
|
||||
// // 仓库类型
|
||||
// .setLocationTypeEnum(LocationForm.PHARMACY.getValue())
|
||||
// // 仓库
|
||||
// .setLocationId(deviceDispense.getLocationId())
|
||||
// // 产品批号
|
||||
// .setLotNumber(deviceDispense.getLotNumber())
|
||||
// // 追溯码
|
||||
// .setTraceNo(item)
|
||||
// // 追溯码状态
|
||||
// .setStatusEnum(TraceNoStatus.IN.getValue())
|
||||
// // 追溯码单位
|
||||
// .setUnitCode(deviceDispense.getUnitCode())
|
||||
// // 操作类型
|
||||
// .setOperationType(SupplyType.RETURN_MEDICATION.getValue());
|
||||
// traceNoManageList.add(traceNoManage);
|
||||
// }
|
||||
}
|
||||
deviceDispenseService.updateBatchById(refundDevList);
|
||||
}
|
||||
|
||||
// 追溯码管理表数据追加
|
||||
traceNoManageService.saveBatch(traceNoManageList);
|
||||
|
||||
// 处理退库存
|
||||
// 获取库存信息
|
||||
List<UnDispenseInventoryDto> unDispenseInventoryList =
|
||||
returnMedicineMapper.selectInventoryInfoList(devReturnIdList, medReturnIdList,
|
||||
CommonConstants.TableName.MED_MEDICATION_DEFINITION, CommonConstants.TableName.ADM_DEVICE_DEFINITION);
|
||||
// 库存待更新列表
|
||||
List<InventoryItem> inventoryItemList = new ArrayList<>();
|
||||
// 根据批号,发放项目,发放药房进行分组处理
|
||||
Map<String, List<UnDispenseInventoryDto>> unDispenseInventoryMap =
|
||||
unDispenseInventoryList.stream().collect(Collectors.groupingBy(x -> x.getItemId()
|
||||
+ CommonConstants.Common.DASH + x.getLotNumber() + CommonConstants.Common.DASH + x.getLocationId()));
|
||||
if (!unDispenseInventoryMap.isEmpty()) {
|
||||
for (Map.Entry<String, List<UnDispenseInventoryDto>> entry : unDispenseInventoryMap.entrySet()) {
|
||||
List<UnDispenseInventoryDto> inventoryList = entry.getValue();
|
||||
if (!inventoryList.isEmpty()) {
|
||||
// 最小单位数量
|
||||
BigDecimal minQuantity = BigDecimal.ZERO;
|
||||
|
||||
for (UnDispenseInventoryDto unDispenseInventoryDto : inventoryList) {
|
||||
BigDecimal quantity = unDispenseInventoryDto.getQuantity();
|
||||
if (!unDispenseInventoryDto.getDispenseUnit()
|
||||
.equals(unDispenseInventoryDto.getInventoryUnitCode())) {
|
||||
// 转换为小单位进行累加
|
||||
quantity =
|
||||
unDispenseInventoryDto.getQuantity().multiply(unDispenseInventoryDto.getPartPercent());
|
||||
}
|
||||
minQuantity = minQuantity.add(quantity);
|
||||
}
|
||||
// 理论上不出bug的情况下以项目id,批号,仓库进行分组处理库存一定唯一所以get(0)
|
||||
// 设置待更新的库存信息
|
||||
inventoryItemList.add(new InventoryItem().setId(inventoryList.get(0).getInventoryId())
|
||||
.setQuantity(inventoryList.get(0).getInventoryQuantity().add(minQuantity)));
|
||||
}
|
||||
}
|
||||
// 库存更新
|
||||
iInventoryItemService.updateBatchById(inventoryItemList);
|
||||
} else {
|
||||
throw new ServiceException("请检查库存信息");
|
||||
}
|
||||
|
||||
// 处理退药医保
|
||||
// 返回信息
|
||||
String returnMsg = null;
|
||||
List<String> uploadFailedNoList;
|
||||
// 调用医保商品销售退货接口
|
||||
String ybSwitch = SecurityUtils.getLoginUser().getOptionJson().getString(CommonConstants.Option.YB_SWITCH); // 医保开关
|
||||
if (Whether.YES.getCode().equals(ybSwitch)) {
|
||||
List<DeviceDefinition> deviceDefinitions = new ArrayList<>();
|
||||
List<MedicationDefinition> medicationDefinitions = new ArrayList<>();
|
||||
if (!returnMedicineList.isEmpty()) {
|
||||
// 设置进销存参数
|
||||
medicationDefinitions = medicationDefinitionService.listByIds(supplyItemDetailList.stream()
|
||||
.filter(x -> x.getItemTable().equals(CommonConstants.TableName.MED_MEDICATION_DEFINITION))
|
||||
.map(SupplyItemDetailDto::getItemId).collect(Collectors.toList()));
|
||||
}
|
||||
if (!returnDeviceList.isEmpty()) {
|
||||
deviceDefinitions = deviceDefinitionService.listByIds(supplyItemDetailList.stream()
|
||||
.filter(x -> x.getItemTable().equals(CommonConstants.TableName.ADM_DEVICE_DEFINITION))
|
||||
.map(SupplyItemDetailDto::getItemId).collect(Collectors.toList()));
|
||||
}
|
||||
|
||||
// 创建映射表,添加空集合保护
|
||||
Map<Long, MedicationDefinition> medicationMap =
|
||||
medicationDefinitions != null ? medicationDefinitions.stream().filter(Objects::nonNull)
|
||||
.collect(Collectors.toMap(MedicationDefinition::getId, Function.identity())) : new HashMap<>();
|
||||
|
||||
Map<Long, DeviceDefinition> deviceMap =
|
||||
deviceDefinitions != null ? deviceDefinitions.stream().filter(Objects::nonNull)
|
||||
.collect(Collectors.toMap(DeviceDefinition::getId, Function.identity())) : new HashMap<>();
|
||||
|
||||
// 设置库存变更参数,添加完整判空
|
||||
for (SupplyItemDetailDto supplyItemDetailDto : supplyItemDetailList) {
|
||||
if (supplyItemDetailDto == null)
|
||||
continue;
|
||||
if (CommonConstants.TableName.MED_MEDICATION_DEFINITION.equals(supplyItemDetailDto.getItemTable())) {
|
||||
if (supplyItemDetailDto.getItemId() != null) {
|
||||
MedicationDefinition med = medicationMap.get(supplyItemDetailDto.getItemId());
|
||||
if (med != null) {
|
||||
supplyItemDetailDto.setItemBusNo(med.getBusNo()).setPartPercent(med.getPartPercent())
|
||||
.setRxFlag(med.getRxFlag()).setYbNo(med.getYbNo());
|
||||
}
|
||||
}
|
||||
} else if (CommonConstants.TableName.ADM_DEVICE_DEFINITION.equals(supplyItemDetailDto.getItemTable())) {
|
||||
if (supplyItemDetailDto.getItemId() != null) {
|
||||
DeviceDefinition dev = deviceMap.get(supplyItemDetailDto.getItemId());
|
||||
if (dev != null) {
|
||||
supplyItemDetailDto.setItemBusNo(dev.getBusNo()).setPartPercent(dev.getPartPercent())
|
||||
.setRxFlag(dev.getRxFlag()).setYbNo(dev.getYbNo());
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
uploadFailedNoList = this.ybReturnIntegrated(medReturnIdList, null);
|
||||
uploadFailedNoList = receiptApprovalAppService.ybInventoryIntegrated(supplyItemDetailList,
|
||||
YbInvChgType.OTHER_OUT, DateUtils.getNowDate(), true);
|
||||
if (uploadFailedNoList != null) {
|
||||
returnMsg = "3506商品销售退货上传错误,错误项目编码" + uploadFailedNoList;
|
||||
} else {
|
||||
returnMsg = "3506商品销售退货上传成功";
|
||||
}
|
||||
}
|
||||
// 返回退药成功信息
|
||||
return R.ok(returnMsg, MessageUtils.createMessage(PromptMsgConstant.Common.M00004, new Object[] {"退药"}));
|
||||
}
|
||||
|
||||
/**
|
||||
* 医保退药相关进销存接口
|
||||
*
|
||||
* @param dispenseMedIdList 退药id列表
|
||||
* @param dispenseDevIdList 退耗材id列表
|
||||
* @return 上传失败的编号集合
|
||||
*/
|
||||
public List<String> ybReturnIntegrated(List<Long> dispenseMedIdList, List<Long> dispenseDevIdList) {
|
||||
List<String> uploadFailedNoList = new ArrayList<>();
|
||||
R<?> result;
|
||||
if (!dispenseMedIdList.isEmpty() || !dispenseDevIdList.isEmpty()) {
|
||||
// 查询退药项目相关信息
|
||||
List<DispenseInventoryDto> dispenseInventoryList = returnMedicineMapper.selectReturnItemDetail(
|
||||
dispenseDevIdList, dispenseMedIdList, CommonConstants.TableName.MED_MEDICATION_DEFINITION,
|
||||
CommonConstants.TableName.ADM_DEVICE_DEFINITION);
|
||||
for (DispenseInventoryDto dispenseInventoryDto : dispenseInventoryList) {
|
||||
if (dispenseInventoryDto.getYbNo() == null) {
|
||||
continue;
|
||||
}
|
||||
Pair<Medical3506Param, Contract> medical3506Pair = getMedical3506Param(dispenseInventoryDto);
|
||||
// 如果自费则自动取省医保
|
||||
Contract contract = medical3506Pair.getRight();
|
||||
if (contract != null) {
|
||||
if (CommonConstants.BusinessName.DEFAULT_CONTRACT_NO
|
||||
.equals(medical3506Pair.getRight().getBusNo())) {
|
||||
contract = null;
|
||||
}
|
||||
}
|
||||
result = ybService.cancelMerchandise(medical3506Pair.getLeft(), contract);
|
||||
if (result.getCode() != 200) {
|
||||
uploadFailedNoList.add(dispenseInventoryDto.getDispenseNo());
|
||||
}
|
||||
}
|
||||
}
|
||||
return uploadFailedNoList;
|
||||
}
|
||||
|
||||
private Pair<Medical3506Param, Contract> getMedical3506Param(DispenseInventoryDto dispenseInventoryDto) {
|
||||
Medical3506Param medical3506Param = new Medical3506Param();
|
||||
ChargeItem chargeItem = null;
|
||||
if (CommonConstants.TableName.MED_MEDICATION_DEFINITION.equals(dispenseInventoryDto.getItemTable())) {
|
||||
// 查询费用结算信息
|
||||
chargeItem = iChargeItemService.getOne(new LambdaQueryWrapper<ChargeItem>()
|
||||
.eq(ChargeItem::getServiceTable, CommonConstants.TableName.MED_MEDICATION_REQUEST)
|
||||
.eq(ChargeItem::getServiceId, dispenseInventoryDto.getRefundId())
|
||||
.eq(ChargeItem::getTenantId, SecurityUtils.getLoginUser().getTenantId()));
|
||||
} else if (CommonConstants.TableName.ADM_DEVICE_DEFINITION.equals(dispenseInventoryDto.getItemTable())) {
|
||||
chargeItem = iChargeItemService.getOne(new LambdaQueryWrapper<ChargeItem>()
|
||||
.eq(ChargeItem::getServiceTable, CommonConstants.TableName.WOR_DEVICE_REQUEST)
|
||||
.eq(ChargeItem::getServiceId, dispenseInventoryDto.getRefundId())
|
||||
.eq(ChargeItem::getTenantId, SecurityUtils.getLoginUser().getTenantId()));
|
||||
}
|
||||
if (chargeItem == null) {
|
||||
throw new ServiceException("未查询到收费项");
|
||||
}
|
||||
// 查询就诊诊断信息
|
||||
EncounterDiagnosis encounterDiagnosis = encounterDiagnosisService.getById(chargeItem.getEncounterDiagnosisId());
|
||||
if (encounterDiagnosis == null) {
|
||||
throw new ServiceException("未查找到就诊诊断信息");
|
||||
}
|
||||
// 查询付款信息
|
||||
PaymentReconciliation paymentReconciliation =
|
||||
iPaymentReconciliationService.getOne(new LambdaQueryWrapper<PaymentReconciliation>()
|
||||
.eq(PaymentReconciliation::getEncounterId, chargeItem.getEncounterId())
|
||||
.like(PaymentReconciliation::getChargeItemIds, chargeItem.getId())
|
||||
.eq(PaymentReconciliation::getStatusEnum, PaymentStatus.SUCCESS.getValue())
|
||||
.eq(PaymentReconciliation::getPatientId, chargeItem.getPatientId())
|
||||
.eq(PaymentReconciliation::getPaymentEnum, PaymentType.PAY.getValue()));
|
||||
if (paymentReconciliation == null) {
|
||||
throw new ServiceException("未查询到收费");
|
||||
}
|
||||
|
||||
// 查询账户信息
|
||||
Account account = accountService
|
||||
.getOne(new LambdaQueryWrapper<Account>().eq(Account::getEncounterId, chargeItem.getEncounterId())
|
||||
.eq(Account::getEncounterFlag, Whether.YES.getValue()));
|
||||
if (account == null) {
|
||||
throw new ServiceException("未查询到账户");
|
||||
}
|
||||
// 查询合同实体
|
||||
Contract contract =
|
||||
iContractService.getOne(new LambdaQueryWrapper<Contract>().eq(Contract::getBusNo, account.getContractNo()));
|
||||
if (contract == null) {
|
||||
throw new ServiceException("未查询到合同信息");
|
||||
}
|
||||
YbMdtrtCertType mdtrtCertType;
|
||||
if (AccountType.PERSONAL_CASH_ACCOUNT.getCode().equals(account.getTypeCode())) {
|
||||
mdtrtCertType = YbMdtrtCertType.MDTRT_CERT_TYPE02;
|
||||
} else {
|
||||
mdtrtCertType = YbMdtrtCertType.getByValue(account.getTypeCode());// 2025/05/28 该值存01/02/03
|
||||
}
|
||||
if (mdtrtCertType == null) {
|
||||
throw new ServiceException("未查询到电子凭证");
|
||||
}
|
||||
// 查询就诊id
|
||||
if (contract.getCategoryEnum().equals(Category.SELF.getValue())
|
||||
|| contract.getCategoryEnum().equals(Category.PUBLIC.getValue())) {
|
||||
medical3506Param.setMdtrtSn(dispenseInventoryDto.getEncounterNo());
|
||||
} else {
|
||||
ClinicSettle clinicSettle = clinicSettleService.getOne(new LambdaQueryWrapper<ClinicSettle>()
|
||||
.in(ClinicSettle::getSetlId, List.of(paymentReconciliation.getYbSettleIds()))
|
||||
.eq(ClinicSettle::getMedType, encounterDiagnosis.getMedTypeCode()).last(" LIMIT 1"));
|
||||
if (clinicSettle != null) {
|
||||
medical3506Param.setMdtrtSn(clinicSettle.getMdtrtId());
|
||||
} else {
|
||||
medical3506Param.setMdtrtSn(dispenseInventoryDto.getEncounterNo());
|
||||
}
|
||||
}
|
||||
// // 查询发票信息
|
||||
// Invoice invoice = iInvoiceService.getById(paymentReconciliation.getInvoiceId());
|
||||
// if (invoice == null) {
|
||||
// throw new ServiceException("未查询到发票信息");
|
||||
// }
|
||||
// 转换为JSON
|
||||
JSONArray medicalTraceNo = new JSONArray();
|
||||
// 获取追溯码信息
|
||||
if (dispenseInventoryDto.getTraceNo() != null) {
|
||||
List<String> traceNoList =
|
||||
Arrays.stream(dispenseInventoryDto.getTraceNo().split(CommonConstants.Common.COMMA)).map(String::trim)
|
||||
.filter(s -> !s.isEmpty()).toList();
|
||||
for (String traceNo : traceNoList) {
|
||||
Map<String, String> traceNoMap = new HashMap<>();
|
||||
traceNoMap.put("drug_trac_codg", traceNo);
|
||||
medicalTraceNo.add(traceNoMap);
|
||||
}
|
||||
}
|
||||
medical3506Param.setMedListCodg(dispenseInventoryDto.getYbNo())
|
||||
.setFixmedinsBchno(dispenseInventoryDto.getRefundId().toString())
|
||||
.setFixmedinsHilistId(dispenseInventoryDto.getItemNo())
|
||||
.setFixmedinsHilistName(CommonConstants.TableName.MED_MEDICATION_DEFINITION)
|
||||
.setPsnCertType(mdtrtCertType.getValue()).setManuLotnum(dispenseInventoryDto.getLotNumber())
|
||||
.setManuDate(dispenseInventoryDto.getProductionDate())
|
||||
.setSelRetnCnt(new BigDecimal(dispenseInventoryDto.getDispenseQuantity().toString()))
|
||||
.setSelRetnTime(dispenseInventoryDto.getDispenseTime()).setExpyEnd(dispenseInventoryDto.getExpirationDate())
|
||||
.setDrugtracinfo(medicalTraceNo).setCertno(dispenseInventoryDto.getIdCard());
|
||||
// 查看所属医院
|
||||
String fixmedinsCode =
|
||||
SecurityUtils.getLoginUser().getOptionJson().getString(CommonConstants.Option.FIXMEDINS_CODE);
|
||||
if (dispenseInventoryDto.getPreparerName() == null && HospitalCodeEnum.CCU.getCode().equals(fixmedinsCode)) {
|
||||
medical3506Param.setSelRetnOpterName(CommonConstants.CCU.DisDeviceDoctorName);
|
||||
} else {
|
||||
medical3506Param.setSelRetnOpterName(dispenseInventoryDto.getPreparerName());
|
||||
}
|
||||
if (dispenseInventoryDto.getInventoryUnitCode().equals(dispenseInventoryDto.getDispenseUnitCode())) {
|
||||
medical3506Param.setTrdnFlag(Whether.YES.getCode());
|
||||
} else {
|
||||
medical3506Param.setTrdnFlag(Whether.NO.getCode());
|
||||
}
|
||||
if (YbRxFlag.IMPORTANT_HERBAL_SLICES.getCode() == dispenseInventoryDto.getRxFlag()) {
|
||||
medical3506Param.setRxFlag(YbRxFlag.IMPORTANT_HERBAL_SLICES.getName());
|
||||
} else if (YbRxFlag.WESTERN_AND_CHINESE_PATENT_MEDICINE.getCode() == dispenseInventoryDto.getRxFlag()) {
|
||||
medical3506Param.setRxFlag(YbRxFlag.WESTERN_AND_CHINESE_PATENT_MEDICINE.getName());
|
||||
} else if (YbRxFlag.SELF_PREPARED_MEDICATION.getCode() == dispenseInventoryDto.getRxFlag()) {
|
||||
medical3506Param.setRxFlag(YbRxFlag.WESTERN_AND_CHINESE_PATENT_MEDICINE.getName());
|
||||
}
|
||||
if (CommonConstants.TableName.MED_MEDICATION_DEFINITION.equals(dispenseInventoryDto.getItemTable())) {
|
||||
medical3506Param.setFixmedinsHilistName(CommonConstants.TableName.MED_MEDICATION_DEFINITION);
|
||||
} else if (CommonConstants.TableName.ADM_DEVICE_DEFINITION.equals(dispenseInventoryDto.getItemTable())) {
|
||||
medical3506Param.setFixmedinsHilistName(CommonConstants.TableName.ADM_DEVICE_DEFINITION);
|
||||
}
|
||||
return Pair.of(medical3506Param, contract);
|
||||
}
|
||||
|
||||
private MedicalInventory3511Param getMedical3511Param(DispenseInventoryDto dispenseInventoryDto) {
|
||||
MedicalInventory3511Param medicalInventory3511Param = new MedicalInventory3511Param();
|
||||
|
||||
String fixmedinsCode =
|
||||
SecurityUtils.getLoginUser().getOptionJson().getString(CommonConstants.Option.FIXMEDINS_CODE);
|
||||
// TODO
|
||||
medicalInventory3511Param.setFixmedinsCode(fixmedinsCode).setMedinsListCodg(dispenseInventoryDto.getYbNo())
|
||||
.setFixmedinsBchno(dispenseInventoryDto.getLotNumber()).setBegndate(dispenseInventoryDto.getDispenseTime())
|
||||
.setEnddate(dispenseInventoryDto.getDispenseTime());
|
||||
|
||||
return medicalInventory3511Param;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,266 @@
|
||||
package com.openhis.web.pharmacymanage.appservice.impl;
|
||||
|
||||
import java.math.BigDecimal;
|
||||
import java.util.*;
|
||||
import java.util.stream.Collectors;
|
||||
|
||||
import javax.servlet.http.HttpServletRequest;
|
||||
import javax.servlet.http.HttpServletResponse;
|
||||
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
import org.springframework.stereotype.Service;
|
||||
|
||||
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
|
||||
import com.core.common.core.domain.R;
|
||||
import com.core.common.utils.AgeCalculatorUtil;
|
||||
import com.core.common.utils.NewExcelUtil;
|
||||
import com.core.common.utils.SecurityUtils;
|
||||
import com.core.common.utils.StringUtils;
|
||||
import com.core.common.utils.bean.BeanUtils;
|
||||
import com.openhis.administration.domain.PrescriptionReviewRecord;
|
||||
import com.openhis.administration.dto.PrescriptionReviewRecordDto;
|
||||
import com.openhis.administration.service.IPrescriptionReviewRecordService;
|
||||
import com.openhis.common.enums.AdministrativeGender;
|
||||
import com.openhis.common.enums.EncounterClass;
|
||||
import com.openhis.common.enums.ReviewReasonEnum;
|
||||
import com.openhis.common.enums.ReviewReasonableStatus;
|
||||
import com.openhis.common.utils.EnumUtils;
|
||||
import com.openhis.common.utils.HisQueryUtils;
|
||||
import com.openhis.common.utils.PageUtils;
|
||||
import com.openhis.web.doctorstation.dto.PrescriptionInfoBaseDto;
|
||||
import com.openhis.web.doctorstation.dto.PrescriptionInfoDetailDto;
|
||||
import com.openhis.web.doctorstation.mapper.DoctorStationMainAppMapper;
|
||||
import com.openhis.web.pharmacymanage.appservice.IPrescriptionReviewAppService;
|
||||
|
||||
import lombok.extern.slf4j.Slf4j;
|
||||
|
||||
/**
|
||||
* 处方审方 应用实现类
|
||||
*
|
||||
* @author swb
|
||||
* @date 2026/1/30
|
||||
*/
|
||||
@Slf4j
|
||||
@Service
|
||||
public class PrescriptionReviewAppServiceImpl implements IPrescriptionReviewAppService {
|
||||
|
||||
@Autowired
|
||||
IPrescriptionReviewRecordService prescriptionReviewRecordService;
|
||||
|
||||
@Autowired
|
||||
DoctorStationMainAppMapper doctorStationMainAppMapper;
|
||||
|
||||
/**
|
||||
* 审方
|
||||
*
|
||||
* @param recordDto 处方审方记录dto
|
||||
* @return 是否成功
|
||||
*/
|
||||
@Override
|
||||
public R<?> review(PrescriptionReviewRecordDto recordDto) {
|
||||
if (recordDto.getEncounterId() == null) {
|
||||
return R.fail("就诊id不能为空");
|
||||
}
|
||||
if (recordDto.getPrescriptionNo() == null) {
|
||||
return R.fail("处方号不能为空");
|
||||
}
|
||||
if (recordDto.getReasonableFlag() == null) {
|
||||
return R.fail("是否合理标识不能为空");
|
||||
}
|
||||
List<PrescriptionInfoDetailDto> prescriptionDetailInfo = doctorStationMainAppMapper
|
||||
.getPrescriptionDetailInfo(recordDto.getPrescriptionNo(), recordDto.getEncounterId());
|
||||
List<Long> requestIds = prescriptionDetailInfo.stream().map(PrescriptionInfoDetailDto::getRequestId).toList();
|
||||
recordDto.setMedRequestIds(StringUtils.join(requestIds, ","));
|
||||
recordDto.setPractitioner(SecurityUtils.getLoginUser().getPractitionerId());
|
||||
boolean review = prescriptionReviewRecordService.review(recordDto);
|
||||
if (!review) {
|
||||
return R.fail("审方失败");
|
||||
}
|
||||
return R.ok("审方成功");
|
||||
}
|
||||
|
||||
/**
|
||||
* 获取处方审方记录列表
|
||||
*
|
||||
* @param prescriptionNoList 处方号集合
|
||||
* @param reviewStatus 审方状态
|
||||
* @return 处方审方记录列表
|
||||
*/
|
||||
@Override
|
||||
public List<PrescriptionReviewRecordDto> getPrescriptionReviewRecords(List<String> prescriptionNoList,
|
||||
Integer reviewStatus) {
|
||||
List<PrescriptionReviewRecord> prescriptionReviewRecords =
|
||||
prescriptionReviewRecordService.getPrescriptionReviewRecords(prescriptionNoList, null, null, reviewStatus);
|
||||
return prescriptionReviewRecords.stream().map(e -> {
|
||||
PrescriptionReviewRecordDto prescriptionReviewRecordDto = new PrescriptionReviewRecordDto();
|
||||
prescriptionReviewRecordDto.setPractitioner(e.getPractitionerId());
|
||||
BeanUtils.copyProperties(e, prescriptionReviewRecordDto);
|
||||
return prescriptionReviewRecordDto;
|
||||
}).toList();
|
||||
}
|
||||
|
||||
/**
|
||||
* 获取处方审方记录分页列表
|
||||
*
|
||||
* @param doctorId 医生id
|
||||
* @param reviewStatus 审方状态
|
||||
* @param patientName 患者姓名
|
||||
* @param request 请求
|
||||
* @return 处方审方记录分页列表
|
||||
*/
|
||||
public List<PrescriptionInfoBaseDto> getPrescriptionReviewInfo(Long doctorId, Integer reviewStatus,
|
||||
String patientName, HttpServletRequest request) {
|
||||
QueryWrapper<PrescriptionInfoBaseDto> queryWrapper =
|
||||
HisQueryUtils.buildQueryWrapper(new PrescriptionInfoBaseDto().setPractitionerId(doctorId), patientName,
|
||||
new HashSet<>(List.of("patient_name")), request);
|
||||
List<PrescriptionInfoBaseDto> prescriptionInfos =
|
||||
doctorStationMainAppMapper.getPrescriptionInfos(queryWrapper, EncounterClass.AMB.getValue());
|
||||
// 处方列表为空时直接返回空集合
|
||||
if (prescriptionInfos == null || prescriptionInfos.isEmpty()) {
|
||||
return List.of();
|
||||
}
|
||||
// 处方号列表
|
||||
List<String> prescriptionNoList =
|
||||
prescriptionInfos.stream().map(PrescriptionInfoBaseDto::getPrescriptionNo).toList();
|
||||
// 本次就诊的处方信息
|
||||
List<PrescriptionInfoDetailDto> prescriptionDetailInfo =
|
||||
doctorStationMainAppMapper.getPrescriptionDetailInfoByPrescriptionNo(prescriptionNoList);
|
||||
for (PrescriptionInfoBaseDto infoBaseDto : prescriptionInfos) {
|
||||
// 性别
|
||||
infoBaseDto.setGenderEnum_enumText(
|
||||
EnumUtils.getInfoByValue(AdministrativeGender.class, infoBaseDto.getGenderEnum()));
|
||||
// 计算年龄
|
||||
infoBaseDto
|
||||
.setAge(infoBaseDto.getBirthDate() != null ? AgeCalculatorUtil.getAge(infoBaseDto.getBirthDate()) : "");
|
||||
// 处方单详情
|
||||
List<PrescriptionInfoDetailDto> prescriptionInfoDetailList = prescriptionDetailInfo.stream()
|
||||
.filter(e -> infoBaseDto.getPrescriptionNo().equals(e.getPrescriptionNo()))
|
||||
.collect(Collectors.toList());
|
||||
infoBaseDto.setPrescriptionInfoDetailList(prescriptionInfoDetailList);
|
||||
}
|
||||
|
||||
if (!prescriptionInfos.isEmpty()) {
|
||||
List<PrescriptionReviewRecordDto> prescriptionReviewRecords =
|
||||
getPrescriptionReviewRecords(prescriptionNoList, reviewStatus);
|
||||
if (reviewStatus != null) {
|
||||
// 处方审方记录
|
||||
if (prescriptionReviewRecords != null && !prescriptionReviewRecords.isEmpty()) {
|
||||
List<String> prescriptionNos =
|
||||
prescriptionReviewRecords.stream().map(PrescriptionReviewRecordDto::getPrescriptionNo).toList();
|
||||
// 根据是否合理筛选
|
||||
prescriptionInfos = prescriptionInfos.stream()
|
||||
.filter(e -> prescriptionNos.contains(e.getPrescriptionNo())).toList();
|
||||
}
|
||||
}
|
||||
// 根据处方号分组
|
||||
Map<String, List<PrescriptionReviewRecordDto>> prescriptionMap;
|
||||
if (prescriptionReviewRecords != null && !prescriptionReviewRecords.isEmpty()) {
|
||||
prescriptionMap = prescriptionReviewRecords.stream()
|
||||
.collect(Collectors.groupingBy(PrescriptionReviewRecordDto::getPrescriptionNo));
|
||||
} else {
|
||||
prescriptionMap = null;
|
||||
}
|
||||
prescriptionInfos.forEach(record -> {
|
||||
if (prescriptionMap != null && prescriptionMap.containsKey(record.getPrescriptionNo())) {
|
||||
PrescriptionReviewRecordDto prescription = prescriptionMap.get(record.getPrescriptionNo()).get(0);
|
||||
// 审方ID
|
||||
record.setPrescriberReviewId(prescription.getId());
|
||||
// 审方人
|
||||
record.setReviewer(prescription.getPractitioner());
|
||||
// 是否合理
|
||||
record.setIsReasonable(prescription.getReasonableFlag());
|
||||
// 存在问题
|
||||
record.setReasonEnum(prescription.getReasonEnum());
|
||||
record.setReasonEnum_enumText(ReviewReasonEnum.getByValue(prescription.getReasonEnum()));
|
||||
// 其他问题
|
||||
record.setReason(prescription.getReasonText());
|
||||
} else {
|
||||
// 是否合理:设置为待点评
|
||||
record.setIsReasonable(ReviewReasonableStatus.TO_BE_COMMENTED.getValue());
|
||||
// 审方人
|
||||
// record.setReviewer(SecurityUtils.getLoginUser().getPractitionerId());
|
||||
}
|
||||
List<PrescriptionInfoDetailDto> detailList = record.getPrescriptionInfoDetailList();
|
||||
if (detailList != null && !detailList.isEmpty()) {
|
||||
// 基药数量
|
||||
int baseDrugQuantity = detailList.stream().filter(e -> e.getBasicFlag() == 1).toList().size();
|
||||
// 抗菌药数量
|
||||
int antibioticQuantity =
|
||||
detailList.stream().filter(e -> e.getAntibioticFlag() == 1).toList().size();
|
||||
// 注射剂数量
|
||||
int injectionQuantity = detailList.stream().filter(e -> e.getInjectFlag() == 1).toList().size();
|
||||
// 是否包含抗菌药
|
||||
boolean antibioticFlag = antibioticQuantity > 0;
|
||||
// 是否包含注射剂
|
||||
boolean injectFlag = injectionQuantity > 0;
|
||||
// 药品品种数量
|
||||
int drugVarietyQuantity = detailList.stream()
|
||||
.collect(Collectors.groupingBy(PrescriptionInfoDetailDto::getAdviceName)).size();
|
||||
// 处方总金额
|
||||
BigDecimal totalAmount = detailList.stream().map(PrescriptionInfoDetailDto::getTotalPrice)
|
||||
.filter(Objects::nonNull).reduce(BigDecimal.ZERO, BigDecimal::add);
|
||||
|
||||
// 是否包含注射药品
|
||||
record.setIsIncludeInjections(injectFlag);
|
||||
// 是否包含抗生素
|
||||
record.setIsContainAntibiotics(antibioticFlag);
|
||||
// 基药数量
|
||||
record.setBaseDrugQuantity(baseDrugQuantity);
|
||||
// 抗菌药数量
|
||||
record.setAntibioticQuantity(antibioticQuantity);
|
||||
// 注射剂数量
|
||||
record.setInjectionQuantity(injectionQuantity);
|
||||
// 药品品种数量
|
||||
record.setDrugVarietyQuantity(drugVarietyQuantity);
|
||||
// 处方总金额
|
||||
record.setTotalAmount(totalAmount);
|
||||
}
|
||||
});
|
||||
}
|
||||
return prescriptionInfos;
|
||||
}
|
||||
|
||||
/**
|
||||
* 查询处方审核信息(分页)
|
||||
*
|
||||
* @param doctorId 医生id
|
||||
* @param reviewStatus 审核状态
|
||||
* @param patientName 患者姓名
|
||||
* @param pageNo 当前页
|
||||
* @param pageSize 每页多少条
|
||||
* @param request 请求
|
||||
* @return 处方审核信息
|
||||
*/
|
||||
@Override
|
||||
public R<?> getPrescriptionReviewPageInfo(Long doctorId, Integer reviewStatus, String patientName, Integer pageNo,
|
||||
Integer pageSize, HttpServletRequest request) {
|
||||
List<PrescriptionInfoBaseDto> prescriptionInfos =
|
||||
getPrescriptionReviewInfo(doctorId, reviewStatus, patientName, request);
|
||||
prescriptionInfos.sort(Comparator.comparing(PrescriptionInfoBaseDto::getRequestTime).reversed());
|
||||
return R.ok(PageUtils.buildPage(prescriptionInfos, pageNo, pageSize));
|
||||
}
|
||||
|
||||
/**
|
||||
* 导出处方审核信息
|
||||
*
|
||||
* @param doctorId 医生id
|
||||
* @param reviewStatus 审核状态
|
||||
* @param patientName 患者姓名
|
||||
* @param request 请求
|
||||
* @param response 响应
|
||||
*/
|
||||
@Override
|
||||
public void makeFile(Long doctorId, Integer reviewStatus, String patientName, HttpServletRequest request,
|
||||
HttpServletResponse response) {
|
||||
List<PrescriptionInfoBaseDto> prescriptionInfos =
|
||||
getPrescriptionReviewInfo(doctorId, reviewStatus, patientName, request);
|
||||
if (prescriptionInfos != null && !prescriptionInfos.isEmpty()) {
|
||||
try {
|
||||
NewExcelUtil<PrescriptionInfoBaseDto> excelUtil = new NewExcelUtil<>(PrescriptionInfoBaseDto.class);
|
||||
excelUtil.exportExcel(response, prescriptionInfos, "处方审核信息");
|
||||
} catch (Exception e) {
|
||||
throw new RuntimeException(e);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,89 @@
|
||||
/*
|
||||
* Copyright ©2023 CJB-CNIT Team. All rights reserved
|
||||
*/
|
||||
package com.openhis.web.pharmacymanage.controller;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
import javax.annotation.Resource;
|
||||
import javax.servlet.http.HttpServletRequest;
|
||||
|
||||
import org.springframework.web.bind.annotation.*;
|
||||
|
||||
import com.core.common.core.domain.R;
|
||||
import com.openhis.web.pharmacymanage.appservice.IInHospitalReturnMedicineAppService;
|
||||
import com.openhis.web.pharmacymanage.dto.EncounterInfoDto;
|
||||
import com.openhis.web.pharmacymanage.dto.ReturnMedicineDto;
|
||||
|
||||
import lombok.AllArgsConstructor;
|
||||
import lombok.extern.slf4j.Slf4j;
|
||||
|
||||
/**
|
||||
* TODO:概括描述当前类的主要用途和注意事项
|
||||
*
|
||||
* @author zwh
|
||||
* @date 2025-12-29
|
||||
*/
|
||||
@RestController
|
||||
@RequestMapping("/pharmacy-manage/inHospital-return-medicine")
|
||||
@Slf4j
|
||||
@AllArgsConstructor
|
||||
public class InHospitalReturnMedicineController {
|
||||
|
||||
@Resource
|
||||
public IInHospitalReturnMedicineAppService inHospitalReturnMedicineAppService;
|
||||
|
||||
/**
|
||||
* 获取页面初始化信息
|
||||
*
|
||||
* @return 初始化信息
|
||||
*/
|
||||
@GetMapping(value = "/init")
|
||||
public R<?> returnMedicineInit() {
|
||||
return inHospitalReturnMedicineAppService.init();
|
||||
}
|
||||
|
||||
/**
|
||||
* 查询退药患者分页列表
|
||||
*
|
||||
* @param encounterInfoDto 查询条件
|
||||
* @param searchKey 模糊查询关键字
|
||||
* @param pageNo 当前页码
|
||||
* @param pageSize 查询条数
|
||||
* @param request 请求数据
|
||||
* @return 退药患者分页列表
|
||||
*/
|
||||
@GetMapping(value = "/return-patient-page")
|
||||
public R<?> getReturnMedicinePatientPage(EncounterInfoDto encounterInfoDto,
|
||||
@RequestParam(value = "searchKey", defaultValue = "") String searchKey,
|
||||
@RequestParam(value = "pageNo", defaultValue = "1") Integer pageNo,
|
||||
@RequestParam(value = "pageSize", defaultValue = "10") Integer pageSize, HttpServletRequest request) {
|
||||
return inHospitalReturnMedicineAppService.getReturnMedicinePatientPage(encounterInfoDto, searchKey, pageNo,
|
||||
pageSize, request);
|
||||
}
|
||||
|
||||
/**
|
||||
* 查询退药信息
|
||||
*
|
||||
* @param encounterId 就诊ID
|
||||
* @param refundStatus 退药id
|
||||
* @param itemTable 项目类型
|
||||
* @return 退药信息
|
||||
*/
|
||||
@GetMapping("/medicine-return-list")
|
||||
public R<?> getReturnMedicineInfo(@RequestParam Long encounterId, @RequestParam Integer refundStatus,
|
||||
String itemTable) {
|
||||
return inHospitalReturnMedicineAppService.getReturnMedicineInfo(encounterId, refundStatus, itemTable);
|
||||
}
|
||||
|
||||
/**
|
||||
* 退药处理
|
||||
*
|
||||
* @param medicineReturnList 退药清单
|
||||
* @return 处理结果
|
||||
*/
|
||||
@PutMapping("/medicine-return")
|
||||
public R<?> medicineReturn(@RequestBody List<ReturnMedicineDto> medicineReturnList) {
|
||||
return inHospitalReturnMedicineAppService.medicineReturn(medicineReturnList);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,80 @@
|
||||
package com.openhis.web.pharmacymanage.controller;
|
||||
|
||||
/**
|
||||
* 处方审方Controller
|
||||
*
|
||||
* @author swb
|
||||
* @date 2026/1/30
|
||||
*/
|
||||
|
||||
import javax.servlet.http.HttpServletRequest;
|
||||
import javax.servlet.http.HttpServletResponse;
|
||||
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
import org.springframework.web.bind.annotation.*;
|
||||
|
||||
import com.core.common.core.domain.R;
|
||||
import com.openhis.administration.dto.PrescriptionReviewRecordDto;
|
||||
import com.openhis.web.pharmacymanage.appservice.IPrescriptionReviewAppService;
|
||||
|
||||
import lombok.AllArgsConstructor;
|
||||
import lombok.extern.slf4j.Slf4j;
|
||||
|
||||
/**
|
||||
* 处方审方Controller
|
||||
*/
|
||||
@RestController
|
||||
@RequestMapping("/pharmacy-manage/prescription-review")
|
||||
@Slf4j
|
||||
@AllArgsConstructor
|
||||
public class PrescriptionReviewController {
|
||||
@Autowired
|
||||
private IPrescriptionReviewAppService prescriptionReviewAppService;
|
||||
|
||||
/**
|
||||
* 审方
|
||||
*
|
||||
* @param recordDto 审方记录dto
|
||||
* @return 是否成功
|
||||
*/
|
||||
@PostMapping("/review")
|
||||
public R<?> review(@RequestBody PrescriptionReviewRecordDto recordDto) {
|
||||
return prescriptionReviewAppService.review(recordDto);
|
||||
}
|
||||
|
||||
/**
|
||||
* 查询处方审核信息
|
||||
*
|
||||
* @param practitionerId 参与者id
|
||||
* @param reviewStatus 审核状态
|
||||
* @param patientName 患者姓名
|
||||
* @param pageNo 当前页
|
||||
* @param pageSize 每页多少条
|
||||
* @param request 请求
|
||||
* @return 处方审核信息
|
||||
*/
|
||||
@GetMapping(value = "/info")
|
||||
public R<?> getPrescriptionReviewInfo(@RequestParam(required = false) Long practitionerId,
|
||||
@RequestParam(required = false) Integer reviewStatus, @RequestParam(required = false) String patientName,
|
||||
@RequestParam(value = "pageNo", defaultValue = "1") Integer pageNo,
|
||||
@RequestParam(value = "pageSize", defaultValue = "10") Integer pageSize, HttpServletRequest request) {
|
||||
return prescriptionReviewAppService.getPrescriptionReviewPageInfo(practitionerId, reviewStatus, patientName,
|
||||
pageNo, pageSize, request);
|
||||
}
|
||||
|
||||
/**
|
||||
* 处方点评导出
|
||||
*
|
||||
* @param practitionerId 参与者id
|
||||
* @param reviewStatus 审核状态
|
||||
* @param patientName 患者姓名
|
||||
* @param request 请求
|
||||
* @param response 响应
|
||||
*/
|
||||
@GetMapping(value = "/export")
|
||||
public void makeFile(@RequestParam(required = false) Long practitionerId,
|
||||
@RequestParam(required = false) Integer reviewStatus, @RequestParam(required = false) String patientName,
|
||||
HttpServletRequest request, HttpServletResponse response) {
|
||||
prescriptionReviewAppService.makeFile(practitionerId, reviewStatus, patientName, request, response);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,33 @@
|
||||
/*
|
||||
* Copyright ©2023 CJB-CNIT Team. All rights reserved
|
||||
*/
|
||||
package com.openhis.web.pharmacymanage.dto;
|
||||
|
||||
import java.util.Date;
|
||||
import java.util.List;
|
||||
|
||||
import com.fasterxml.jackson.annotation.JsonFormat;
|
||||
|
||||
import lombok.Data;
|
||||
import lombok.experimental.Accessors;
|
||||
|
||||
/**
|
||||
* 农大门诊配/发药 参数类
|
||||
*
|
||||
*/
|
||||
@Data
|
||||
@Accessors(chain = true)
|
||||
public class JlauDispenseParam {
|
||||
|
||||
/**
|
||||
* 配/发药信息
|
||||
*/
|
||||
private List<DispenseItemDto> dispenseMedicineList;
|
||||
|
||||
/**
|
||||
* UI选择的发药时间
|
||||
*/
|
||||
@JsonFormat(pattern = "yyyy-MM-dd HH:mm:ss")
|
||||
private Date dispenseTime;
|
||||
|
||||
}
|
||||
@@ -0,0 +1,66 @@
|
||||
/*
|
||||
* Copyright ©2023 CJB-CNIT Team. All rights reserved
|
||||
*/
|
||||
package com.openhis.web.pharmacymanage.mapper;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
import org.apache.ibatis.annotations.Param;
|
||||
import org.springframework.stereotype.Repository;
|
||||
|
||||
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
|
||||
import com.baomidou.mybatisplus.core.toolkit.Constants;
|
||||
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
|
||||
import com.openhis.web.pharmacymanage.dto.EncounterInfoDto;
|
||||
import com.openhis.web.pharmacymanage.dto.ReturnMedicineInfoDto;
|
||||
|
||||
/**
|
||||
* TODO:概括描述当前类的主要用途和注意事项
|
||||
*
|
||||
* @author zwh
|
||||
* @date 2025-12-29
|
||||
*/
|
||||
@Repository
|
||||
public interface InHospitalReturnMedicineAppMapper {
|
||||
|
||||
/**
|
||||
* 查询退药患者分页列表
|
||||
*
|
||||
* @param page 分页
|
||||
* @param queryWrapper 查询条件
|
||||
* @param refundStatus 退药状态
|
||||
* @param pendingRefund 退药状态:待退药
|
||||
* @param refunded 退药状态:已退药
|
||||
* @param imp 患者类型:住院
|
||||
* @param medMedicationDefinition 药品表
|
||||
* @param admDeviceDefinition 耗材表
|
||||
* @return 退药患者分页列表
|
||||
*/
|
||||
Page<EncounterInfoDto> selectEncounterInfoListPage(@Param("page") Page<EncounterInfoDto> page,
|
||||
@Param(Constants.WRAPPER) QueryWrapper<EncounterInfoDto> queryWrapper,
|
||||
@Param("refundStatus") Integer refundStatus, @Param("pendingRefund") Integer pendingRefund,
|
||||
@Param("refunded") Integer refunded, @Param("imp") Integer imp,
|
||||
@Param("medMedicationDefinition") String medMedicationDefinition,
|
||||
@Param("admDeviceDefinition") String admDeviceDefinition);
|
||||
|
||||
/**
|
||||
* 申请退药清单查询
|
||||
*
|
||||
* @param encounterId 就诊ID
|
||||
* @param medMedicationRequest 药品请求表
|
||||
* @param worDeviceRequest 耗材请求表
|
||||
* @param medMedicationDefinition 药品表
|
||||
* @param admDeviceDefinition 耗材表
|
||||
* @param itemTable 项目所在表
|
||||
* @param refundStatus 退药状态
|
||||
* @param pendingRefund 退药状态:待退药
|
||||
* @param refunded 退药状态:已退药
|
||||
* @return 申请退药清单
|
||||
*/
|
||||
List<ReturnMedicineInfoDto> selectReturnMedicineInfo(@Param("encounterId") Long encounterId,
|
||||
@Param("worDeviceRequest") String worDeviceRequest, @Param("medMedicationRequest") String medMedicationRequest,
|
||||
@Param("medMedicationDefinition") String medMedicationDefinition,
|
||||
@Param("admDeviceDefinition") String admDeviceDefinition, @Param("itemTable") String itemTable,
|
||||
@Param("refundStatus") Integer refundStatus, @Param("pendingRefund") Integer pendingRefund,
|
||||
@Param("refunded") Integer refunded);
|
||||
}
|
||||
Reference in New Issue
Block a user