2025-12-24 发版,具体内容见发版日志

This commit is contained in:
whm
2025-12-24 22:15:55 +08:00
parent 9ea7d46df0
commit 2f581b34ba
370 changed files with 94577 additions and 66778 deletions

View File

@@ -118,11 +118,11 @@ public enum TenantOptionDict {
*/
PACS_APP_SECRET("pacsAppSecret", "PACSAppSecret", 45),
/**
* PACSAppSecret
* 电子发票-中转服务的路径
*/
INVOICE_FORWARD_URL("invoiceUrl", "电子发票-中转服务的路径", 46),
/**
* PACSAppSecret
* 电子发票-中转服务开关
*/
FORWARD_SWITCH("forwardSwitch", "电子发票-中转服务开关", 47),
/**
@@ -316,7 +316,17 @@ public enum TenantOptionDict {
/**
* LIS查看报告地址
*/
LIS_REPORT_URL("lisReportUrl", "LIS查看报告地址", 92);
LIS_REPORT_URL("lisReportUrl", "LIS查看报告地址", 92),
/**
* 开药时药房允许多选开关
*/
PHARMACY_MULTIPLE_CHOICE_SWITCH("pharmacyMultipleChoiceSwitch", "开药时药房允许多选开关", 93),
/**
* PEIS服务地址
*/
PEIS_SERVER_URL("peisServerUrl", "PEIS服务地址", 94);
private final String code;
private final String name;

View File

@@ -18,7 +18,8 @@ public interface IOrganizationAppService {
* @param request 请求数据
* @return 机构树分页列表
*/
Page<OrganizationDto> getOrganizationTree(Integer pageNo, Integer pageSize, HttpServletRequest request);
Page<OrganizationDto> getOrganizationTree(Integer pageNo, Integer pageSize, String sortField, String sortOrder,
HttpServletRequest request);
/**
* 机构信息详情

View File

@@ -13,6 +13,7 @@ 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.enums.DelFlag;
import com.core.common.utils.*;
import com.openhis.administration.domain.EncounterLocation;
import com.openhis.administration.domain.Location;
@@ -77,7 +78,9 @@ public class LocationAppServiceImpl implements ILocationAppService {
*/
@Override
public R<?> enableLocation(List<Long> locationIdList) {
List<Location> locationList = locationService.getLocationList(locationIdList);
// 根据ID查询停用状态的
List<Location> locationList = locationService.getLocationList(locationIdList,
Collections.singletonList(LocationStatus.INACTIVE.getValue()));
if (locationIdList != null && !locationIdList.isEmpty()) {
for (Location location : locationList) {
if (LocationForm.HOUSE.getValue().equals(location.getFormEnum())
@@ -117,7 +120,8 @@ public class LocationAppServiceImpl implements ILocationAppService {
*/
@Override
public R<?> deactivateLocation(List<Long> locationIdList) {
List<Location> locationList = locationService.getLocationList(locationIdList);
List<Location> locationList = locationService.getLocationList(locationIdList,
Arrays.asList(LocationStatus.ACTIVE.getValue(), LocationStatus.IDLE.getValue()));
if (locationIdList != null && !locationIdList.isEmpty()) {
for (Location location : locationList) {
if (LocationForm.BED.getValue().equals(location.getFormEnum())) {
@@ -182,7 +186,7 @@ public class LocationAppServiceImpl implements ILocationAppService {
public R<?> deleteLocation(String busNo) {
// 删除位置信息(连同子集)
boolean result =
locationService.remove(new LambdaQueryWrapper<Location>().likeRight(Location::getBusNo, busNo));
locationService.remove(new LambdaQueryWrapper<Location>().likeRight(Location::getBusNo, busNo));
return result ? R.ok(null, MessageUtils.createMessage(PromptMsgConstant.Common.M00005, new Object[] {"位置信息删除"}))
: R.fail(MessageUtils.createMessage(PromptMsgConstant.Common.M00006, new Object[] {"位置信息删除"}));
}
@@ -231,6 +235,23 @@ public class LocationAppServiceImpl implements ILocationAppService {
// 启用停用
e.setStatusEnum_enumText(EnumUtils.getInfoByValue(LocationStatus.class, e.getStatusEnum()));
});
// 如果是查询病房
if (LocationForm.HOUSE.getValue().equals(locationPageParam.getFormEnum())) {
// 查询疗区
LambdaQueryWrapper<Location> wrapper = new LambdaQueryWrapper<>();
wrapper.eq(Location::getFormEnum, LocationForm.WARD.getValue()).eq(Location::getDeleteFlag,
DelFlag.NO.getCode());
List<Location> list = locationService.list(wrapper);
// 根据busNo拼接疗区
HashMap<String, String> map = list.stream().collect(Collectors.toMap(Location::getBusNo, Location::getName,
(oldValue, newValue) -> newValue, HashMap::new));
locationPage.getRecords().forEach(e -> {
String[] split = e.getBusNo().split("\\.");
if (split.length == 2) {
e.setParentName(map.get(split[0]));
}
});
}
return R.ok(locationPage);
}
@@ -242,7 +263,16 @@ public class LocationAppServiceImpl implements ILocationAppService {
*/
@Override
public R<?> addLocation(LocationAddOrEditDto locationAddOrEditDto) {
// 不能为空
if (StringUtils.isEmpty(locationAddOrEditDto.getName())) {
return R.fail(false, "名称不能为空");
}
// 去除空格
String name = locationAddOrEditDto.getName().replaceAll("[  ]", "");
// 判断是否存在同名
if (locationService.isExistName(name, locationAddOrEditDto.getBusNo(), locationAddOrEditDto.getId())) {
return R.fail(false, "" + name + "】已存在");
}
Location location = new Location();
BeanUtils.copyProperties(locationAddOrEditDto, location);
location.setFormEnum(Integer.valueOf(locationAddOrEditDto.getFormEnum()));
@@ -278,6 +308,16 @@ public class LocationAppServiceImpl implements ILocationAppService {
*/
@Override
public R<?> editLocation(LocationAddOrEditDto locationAddOrEditDto) {
// 不能为空
if (StringUtils.isEmpty(locationAddOrEditDto.getName())) {
return R.fail(false, "名称不能为空");
}
// 去除空格
String name = locationAddOrEditDto.getName().replaceAll("[  ]", "");
// 判断是否存在同名
if (locationService.isExistName(name, locationAddOrEditDto.getBusNo(), locationAddOrEditDto.getId())) {
return R.fail(false, "" + name + "】已存在");
}
Location location = new Location();
BeanUtils.copyProperties(locationAddOrEditDto, location);
// 拼音码
@@ -377,4 +417,4 @@ public class LocationAppServiceImpl implements ILocationAppService {
}
return tree;
}
}
}

View File

@@ -1,5 +1,6 @@
package com.openhis.web.basedatamanage.appservice.impl;
import java.lang.reflect.Field;
import java.util.*;
import java.util.stream.Collectors;
@@ -9,6 +10,7 @@ import javax.servlet.http.HttpServletRequest;
import org.springframework.beans.BeanUtils;
import org.springframework.stereotype.Service;
import com.baomidou.mybatisplus.core.metadata.OrderItem;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.core.common.core.domain.R;
import com.core.common.utils.AssignSeqUtil;
@@ -26,6 +28,8 @@ import com.openhis.common.utils.EnumUtils;
import com.openhis.web.basedatamanage.appservice.IOrganizationAppService;
import com.openhis.web.basedatamanage.dto.OrganizationDto;
import static com.baomidou.mybatisplus.core.toolkit.StringUtils.camelToUnderline;
@Service
public class OrganizationAppServiceImpl implements IOrganizationAppService {
@@ -36,9 +40,25 @@ public class OrganizationAppServiceImpl implements IOrganizationAppService {
private AssignSeqUtil assignSeqUtil;
@Override
public Page<OrganizationDto> getOrganizationTree(Integer pageNo, Integer pageSize, HttpServletRequest request) {
public Page<OrganizationDto> getOrganizationTree(Integer pageNo, Integer pageSize, String sortField,
String sortOrder, HttpServletRequest request) {
// 查询机构列表
Page<Organization> page = organizationService.page(new Page<>(pageNo, pageSize));
// 创建Page对象
Page<Organization> page = new Page<>(pageNo, pageSize);
// 处理动态排序(仅当排序字段有效时才添加排序条件)
if (sortField != null && !sortField.isEmpty()) {
// 校验排序字段是否为Organization实体中的有效字段防止非法字段
if (isValidField(Organization.class, sortField)) {
// 驼峰转下划线处理
String underlineField = camelToUnderline(sortField);
// 默认为升序若指定desc则按降序
boolean isAsc = sortOrder == null || "asc".equalsIgnoreCase(sortOrder);
page.addOrder(isAsc ? OrderItem.asc(underlineField) : OrderItem.desc(underlineField));
}
}
// 执行分页查询(此时排序条件会被应用)
page = organizationService.page(page);
List<Organization> organizationList = page.getRecords();
// 将机构列表转为树结构
List<OrganizationDto> orgTree = buildTree(organizationList);
@@ -188,4 +208,21 @@ public class OrganizationAppServiceImpl implements IOrganizationAppService {
: R.fail(MessageUtils.createMessage(PromptMsgConstant.Common.M00007, new Object[] {"机构信息停用"}));
}
/**
* 校验字段是否为指定类中的有效属性
*/
private boolean isValidField(Class<?> clazz, String fieldName) {
if (clazz == null || fieldName == null || fieldName.isEmpty()) {
return false;
}
try {
// 获取类中所有声明的字段(包括私有)
Field field = clazz.getDeclaredField(fieldName);
return field != null;
} catch (NoSuchFieldException e) {
// 字段不存在
return false;
}
}
}

View File

@@ -47,8 +47,11 @@ public class OrganizationController {
*/
@GetMapping(value = "/organization")
public R<?> getOrganizationPage(@RequestParam(value = "pageNo", defaultValue = "1") Integer pageNo,
@RequestParam(value = "pageSize", defaultValue = "100") Integer pageSize, HttpServletRequest request) {
Page<OrganizationDto> organizationTree = iOrganizationAppService.getOrganizationTree(pageNo, pageSize, request);
@RequestParam(value = "pageSize", defaultValue = "100") Integer pageSize,
@RequestParam(value = "sortField", required = false) String sortField,
@RequestParam(value = "sortOrder", required = false) String sortOrder, HttpServletRequest request) {
Page<OrganizationDto> organizationTree =
iOrganizationAppService.getOrganizationTree(pageNo, pageSize, sortField, sortOrder, request);
return R.ok(organizationTree,
MessageUtils.createMessage(PromptMsgConstant.Common.M00009, new Object[] {"机构信息"}));
}

View File

@@ -3,11 +3,10 @@
*/
package com.openhis.web.basedatamanage.dto;
import com.baomidou.mybatisplus.annotation.IdType;
import com.baomidou.mybatisplus.annotation.TableId;
import com.fasterxml.jackson.databind.annotation.JsonSerialize;
import com.fasterxml.jackson.databind.ser.std.ToStringSerializer;
import com.openhis.common.annotation.Dict;
import lombok.Data;
import lombok.experimental.Accessors;
@@ -31,6 +30,9 @@ public class LocationInfoDto {
/** 名称 */
private String name;
/** 父名称 */
private String parentName;
/** 状态编码 */
private Integer statusEnum;
private String statusEnum_enumText;
@@ -44,7 +46,7 @@ public class LocationInfoDto {
private String formEnum_enumText;
/** 机构编码 */
@Dict(dictCode = "id",dictText = "name",dictTable = "adm_organization")
@Dict(dictCode = "id", dictText = "name", dictTable = "adm_organization")
@JsonSerialize(using = ToStringSerializer.class)
private Long organizationId;
private String organizationId_dictText;

View File

@@ -89,7 +89,9 @@ public class InpatientChargeAppServiceImpl implements IInpatientChargeAppService
// 就诊患者分页列表
Page<EncounterPatientPageDto> encounterPatientPage = inpatientChargeAppMapper.selectEncounterPatientPage(
EncounterClass.IMP.getValue(), EncounterZyStatus.DISCHARGED_FROM_HOSPITAL.getValue(),
EncounterZyStatus.ALREADY_SETTLED.getValue(), new Page<>(pageNo, pageSize), queryWrapper);
EncounterZyStatus.ALREADY_SETTLED.getValue(), ChargeItemStatus.BILLABLE.getValue(),
ChargeItemStatus.BILLED.getValue(), ChargeItemStatus.REFUNDED.getValue(),
AccountType.PERSONAL_CASH_ACCOUNT.getCode(), new Page<>(pageNo, pageSize), queryWrapper);
encounterPatientPage.getRecords().forEach(e -> {
// 性别枚举

View File

@@ -3,7 +3,6 @@
*/
package com.openhis.web.chargemanage.mapper;
import java.util.Date;
import java.util.List;
import org.apache.ibatis.annotations.Param;
@@ -37,7 +36,9 @@ public interface InpatientChargeAppMapper {
*/
Page<EncounterPatientPageDto> selectEncounterPatientPage(@Param("classEnum") Integer classEnum,
@Param("dischargedFromHospital") Integer dischargedFromHospital,
@Param("alreadySettled") Integer alreadySettled, @Param("page") Page<EncounterPatientPageDto> page,
@Param("alreadySettled") Integer alreadySettled, @Param("billable") Integer billable,
@Param("billed") Integer billed, @Param("refunded") Integer refunded,
@Param("personalCashAccount") String personalCashAccount, @Param("page") Page<EncounterPatientPageDto> page,
@Param(Constants.WRAPPER) QueryWrapper<EncounterPatientPageParam> queryWrapper);
/**

View File

@@ -463,7 +463,8 @@ public class CommonServiceImpl implements ICommonService {
// 查询当前登录者管理的病区
Long practitionerId = SecurityUtils.getLoginUser().getPractitionerId();
List<Long> locationIds = practitionerRoleService.getLocationIdsByPractitionerId(practitionerId);
List<Location> locationList = locationService.getLocationList(locationIds);
List<Location> locationList =
locationService.getLocationList(locationIds, Collections.singletonList(LocationStatus.ACTIVE.getValue()));
List<Location> wardList = new ArrayList<>();
for (Location ward : locationList) {
if (LocationForm.WARD.getValue().equals(ward.getFormEnum())) {
@@ -515,6 +516,10 @@ public class CommonServiceImpl implements ICommonService {
EnumUtils.getInfoByValue(AdministrativeGender.class, advicePrintInfoDto.getGenderEnum()))
.setEncounterYbClass_enumText(
EnumUtils.getInfoByValue(EncounterYbClass.class, advicePrintInfoDto.getEncounterYbClass()));
if (advicePrintInfoDto.getChrgitmLv() != null) {
advicePrintInfoDto
.setChrgitmLv_enumText(EnumUtils.getInfoByValue(InsuranceLevel.class, advicePrintInfoDto.getChrgitmLv()));
}
return R.ok(advicePrintInfoDto);
}

View File

@@ -97,4 +97,14 @@ public class AdviceItemPrintInfoDto {
* 中药付数
*/
private BigDecimal chineseHerbsDoseQuantity;
/**
* 医保等级甲乙类
*/
private String chrgitmLv;
/**
* 是否基药
*/
private Integer basicFlag;
}

View File

@@ -3,13 +3,10 @@
*/
package com.openhis.web.common.dto;
import java.math.BigDecimal;
import java.util.Date;
import java.util.List;
import com.fasterxml.jackson.annotation.JsonFormat;
import com.fasterxml.jackson.databind.annotation.JsonSerialize;
import com.fasterxml.jackson.databind.ser.std.ToStringSerializer;
import com.openhis.common.annotation.Dict;
import lombok.Data;
@@ -94,6 +91,22 @@ public class AdvicePrintInfoDto {
private String unitCode;
private String unitCode_dictText;
/**
* 医保等级
*/
private Integer chrgitmLv;
private String chrgitmLv_enumText;
/**
* 地址
*/
private String address;
/**
* 患者id
*/
private String patientId;
/**
* 医嘱项目打印列表
*/

View File

@@ -248,7 +248,7 @@ public class DiagTreatMAppServiceImpl implements IDiagTreatMAppService {
.setTypeCode(diagnosisTreatmentUpDto.getItemTypeCode())
.setInstanceTable(CommonConstants.TableName.WOR_ACTIVITY_DEFINITION)
.setInstanceId(diagnosisTreatmentUpDto.getId()).setPrice(diagnosisTreatmentUpDto.getRetailPrice())
.setChargeName(diagnosisTreatmentUpDto.getName());
.setPriceCode(diagnosisTreatmentUpDto.getPriceCode()).setChargeName(diagnosisTreatmentUpDto.getName());
// 插入操作记录
operationRecordService.addEntityOperationRecord(DbOpType.UPDATE.getCode(),
CommonConstants.TableName.WOR_ACTIVITY_DEFINITION, activityDefinition);
@@ -375,7 +375,8 @@ public class DiagTreatMAppServiceImpl implements IDiagTreatMAppService {
.setInstanceTable(CommonConstants.TableName.WOR_ACTIVITY_DEFINITION)
.setEffectiveStart(DateUtils.getNowDate()).setStatusEnum(PublicationStatus.ACTIVE.getValue())
.setConditionFlag(Whether.YES.getValue()).setChargeName(diagnosisTreatmentUpDto.getName())
.setInstanceId(activityDefinition.getId()).setPrice(diagnosisTreatmentUpDto.getRetailPrice());
.setInstanceId(activityDefinition.getId()).setPrice(diagnosisTreatmentUpDto.getRetailPrice())
.setPriceCode(diagnosisTreatmentUpDto.getPriceCode());
return itemDefinitionService.addItem(itemUpFromDirectoryDto)
? R.ok(null, MessageUtils.createMessage(PromptMsgConstant.Common.M00002, new Object[] {"诊疗目录"}))
@@ -446,7 +447,7 @@ public class DiagTreatMAppServiceImpl implements IDiagTreatMAppService {
if (!serviceRequestList.isEmpty()) {
if (serviceRequestList.stream().anyMatch(
serviceRequest -> RequestStatus.COMPLETED.getValue().equals(serviceRequest.getStatusEnum()))) {
return R.ok(1,"医生开过该诊疗项目,不可编辑");
return R.ok(1, "医生开过该诊疗项目,不可编辑");
}
}
return R.ok();

View File

@@ -109,6 +109,7 @@ public class ItemDefinitionServiceImpl implements IItemDefinitionService {
.set(ChargeItemDefinition::getYbType, chargeItemDefinition.getYbType())
.set(ChargeItemDefinition::getTypeCode, chargeItemDefinition.getTypeCode())
.set(ChargeItemDefinition::getPrice, chargeItemDefinition.getPrice())
.set(ChargeItemDefinition::getPriceCode, chargeItemDefinition.getPriceCode())
.set(ChargeItemDefinition::getChargeName, chargeItemDefinition.getChargeName());
return chargeItemDefinitionService.update(null, updateWrapper);

View File

@@ -1,17 +1,14 @@
package com.openhis.web.datadictionary.dto;
import java.math.BigDecimal;
import com.fasterxml.jackson.databind.annotation.JsonSerialize;
import com.fasterxml.jackson.databind.ser.std.ToStringSerializer;
import com.openhis.common.annotation.Dict;
import com.openhis.common.enums.ActivityDefCategory;
import com.openhis.common.enums.PublicationStatus;
import lombok.Data;
import lombok.experimental.Accessors;
import javax.validation.constraints.NotNull;
import java.math.BigDecimal;
/**
* 诊疗目录分页检索
*
@@ -105,8 +102,8 @@ public class DiagnosisTreatmentDto {
private String ybType;
private String ybType_dictText;
// /** 购入价 */
// private BigDecimal purchasePrice;
// /** 购入价 */
// private BigDecimal purchasePrice;
/** 零售价 */
private BigDecimal retailPrice;
@@ -124,4 +121,9 @@ public class DiagnosisTreatmentDto {
private Integer pricingFlag;
private String pricingFlag_enumText;
/**
* 物价编码
*/
private String priceCode;
}

View File

@@ -1,18 +1,16 @@
package com.openhis.web.datadictionary.dto;
import java.math.BigDecimal;
import javax.validation.constraints.NotBlank;
import javax.validation.constraints.NotNull;
import com.fasterxml.jackson.databind.annotation.JsonSerialize;
import com.fasterxml.jackson.databind.ser.std.ToStringSerializer;
import com.openhis.common.annotation.Dict;
import com.openhis.common.enums.ActivityDefCategory;
import lombok.Data;
import lombok.experimental.Accessors;
import java.math.BigDecimal;
/**
* 诊疗目录分页更新
*
@@ -111,4 +109,9 @@ public class DiagnosisTreatmentUpDto {
/** 划价标记 */
private Integer pricingFlag;
/**
* 物价编码
*/
private String priceCode;
}

View File

@@ -3,7 +3,6 @@ package com.openhis.web.datadictionary.dto;
import java.math.BigDecimal;
import java.util.Date;
import com.openhis.common.annotation.Dict;
import lombok.Data;
import lombok.experimental.Accessors;
@@ -71,4 +70,9 @@ public class ItemUpFromDirectoryDto {
/** 价格 */
private BigDecimal amount;
/**
* 物价编码
*/
private String priceCode;
}

View File

@@ -294,4 +294,9 @@ public class MedicationManageDto {
*/
private String dosageInstruction;
/**
* 药品69码
*/
private String drug69Code;
}

View File

@@ -263,4 +263,9 @@ public class MedicationManageUpDto {
*/
private String dosageInstruction;
/**
* 药品69码
*/
private String drug69Code;
}

View File

@@ -9,6 +9,7 @@ import com.core.common.core.domain.R;
import com.openhis.web.doctorstation.dto.PatientInfoDto;
import com.openhis.web.doctorstation.dto.PrescriptionInfoBaseDto;
import com.openhis.web.doctorstation.dto.PrescriptionInfoDetailDto;
import com.openhis.web.doctorstation.dto.ReceptionStatisticsDto;
/**
* 医生站-主页面 应用Service
@@ -62,7 +63,7 @@ public interface IDoctorStationMainAppService {
* @return 处方号列表信息
*/
IPage<PrescriptionInfoBaseDto> getPrescriptionPageInfo(PrescriptionInfoBaseDto prescriptionInfoBaseDto,
String searchKey, Integer pageNo, Integer pageSize);
String searchKey, Integer pageNo, Integer pageSize, HttpServletRequest request);
/**
* 查询处方详情
@@ -72,4 +73,14 @@ public interface IDoctorStationMainAppService {
*/
List<PrescriptionInfoDetailDto> getPrescriptionDetailInfo(String prescriptionNo);
/**
* 查询接诊统计
*
* @param startTime 开始时间
* @param endTime 结束时间
* @param practitionerId 参与者id
* @return 接诊统计
*/
List<ReceptionStatisticsDto> getReceptionStatistics(String startTime,String endTime,Long practitionerId);
}

View File

@@ -126,6 +126,12 @@ public class DoctorStationAdviceAppServiceImpl implements IDoctorStationAdviceAp
} else if (StringUtils.isNotEmpty(orderPricing)) {
orderPricingSource = orderPricing;
}
// 开药时药房允许多选开关
String pharmacyMultipleChoiceSwitch =
TenantOptionUtil.getOptionContent(TenantOptionDict.PHARMACY_MULTIPLE_CHOICE_SWITCH);
// 药房允许多选
boolean pharmacyMultipleChoice = Whether.YES.getCode().equals(pharmacyMultipleChoiceSwitch);
// 构建查询条件
QueryWrapper<AdviceBaseDto> queryWrapper = HisQueryUtils.buildQueryWrapper(adviceBaseDto, searchKey,
new HashSet<>(Arrays.asList("advice_name", "py_str", "wb_str")), null);
@@ -135,6 +141,12 @@ public class DoctorStationAdviceAppServiceImpl implements IDoctorStationAdviceAp
CommonConstants.TableName.WOR_ACTIVITY_DEFINITION, pricingFlag, adviceDefinitionIdParamList, adviceTypes,
queryWrapper);
List<AdviceBaseDto> adviceBaseDtoList = adviceBaseInfo.getRecords();
// 如果searchKey不为null对查询结果进行排序adviceName以searchKey开头的排在前面
if (searchKey != null && !searchKey.trim().isEmpty()) {
sortAdviceListBySearchKey(adviceBaseDtoList, searchKey.trim());
}
// 医嘱定义ID集合
List<Long> adviceDefinitionIdList =
adviceBaseDtoList.stream().map(AdviceBaseDto::getAdviceDefinitionId).collect(Collectors.toList());
@@ -172,10 +184,11 @@ public class DoctorStationAdviceAppServiceImpl implements IDoctorStationAdviceAp
baseDto.setInjectFlag_enumText(EnumUtils.getInfoByValue(Whether.class, baseDto.getInjectFlag()));
case CommonConstants.TableName.ADM_DEVICE_DEFINITION: // 耗材
// 每一条医嘱的库存集合信息 , 包装单位库存前端计算
List<AdviceInventoryDto> inventoryList = adviceInventory.stream()
.filter(e -> baseDto.getAdviceDefinitionId().equals(e.getItemId())
&& baseDto.getAdviceTableName().equals(e.getItemTable())
&& (baseDto.getPositionId() == null || baseDto.getPositionId().equals(e.getLocationId())))
List<AdviceInventoryDto> inventoryList = adviceInventory.stream().filter(e -> baseDto
.getAdviceDefinitionId().equals(e.getItemId())
&& baseDto.getAdviceTableName().equals(e.getItemTable())
&& (pharmacyMultipleChoice
|| (baseDto.getPositionId() == null || baseDto.getPositionId().equals(e.getLocationId()))))
.collect(Collectors.toList());
// 库存信息
baseDto.setInventoryList(inventoryList);
@@ -287,6 +300,18 @@ public class DoctorStationAdviceAppServiceImpl implements IDoctorStationAdviceAp
* 保存时,校验库存
*/
if (AdviceOpType.SAVE_ADVICE.getCode().equals(adviceOpType)) {
List<AdviceSaveDto> medUpdateList =
medicineList.stream().filter(e -> e.getRequestId() != null).collect(Collectors.toList());
List<AdviceSaveDto> devUpdateList =
deviceList.stream().filter(e -> e.getRequestId() != null).collect(Collectors.toList());
// 编辑时,释放本身占用的库存发放
for (AdviceSaveDto adviceSaveDto : medUpdateList) {
iMedicationDispenseService.deleteMedicationDispense(adviceSaveDto.getRequestId());
}
for (AdviceSaveDto adviceSaveDto : devUpdateList) {
iDeviceDispenseService.deleteDeviceDispense(adviceSaveDto.getRequestId());
}
List<AdviceSaveDto> needCheckList =
adviceSaveList.stream().filter(e -> !DbOpType.DELETE.getCode().equals(e.getDbOpType())
&& !ItemType.ACTIVITY.getValue().equals(e.getAdviceType())).collect(Collectors.toList());
@@ -712,6 +737,7 @@ public class DoctorStationAdviceAppServiceImpl implements IDoctorStationAdviceAp
activityChildrenJsonParams.setAccountId(chargeItem.getAccountId()); // 账户id
activityChildrenJsonParams.setChargeItemId(chargeItem.getId()); // 费用项id
activityChildrenJsonParams.setParentId(serviceRequest.getId());// 子项诊疗的父id
activityChildrenJsonParams.setEncounterDiagnosisId(adviceSaveDto.getEncounterDiagnosisId());
adviceUtils.handleActivityChild(childrenJson, organizationId, activityChildrenJsonParams);
}
}
@@ -956,4 +982,64 @@ public class DoctorStationAdviceAppServiceImpl implements IDoctorStationAdviceAp
return R.ok(testResult);
}
/**
* 根据searchKey对医嘱列表进行排序adviceName以searchKey(汉字)开头的排在前面 | pyStr以searchKey(字母)开头的排在前面
*
* @param adviceList 医嘱列表
* @param searchKey 搜索关键字
*/
private void sortAdviceListBySearchKey(List<AdviceBaseDto> adviceList, String searchKey) {
if (adviceList == null || adviceList.isEmpty() || searchKey == null || searchKey.trim().isEmpty()) {
return;
}
// 判断searchKey是否包含字母拼音
boolean isPinyinSearch = isPinyinKey(searchKey);
adviceList.sort((a, b) -> {
// 根据searchKey类型选择不同的字段
String aValue =
isPinyinSearch ? (a.getPyStr() != null ? a.getPyStr() : a.getAdviceName()) : a.getAdviceName();
String bValue =
isPinyinSearch ? (b.getPyStr() != null ? b.getPyStr() : b.getAdviceName()) : b.getAdviceName();
// 处理可能的null值
if (aValue == null && bValue == null) {
return 0;
}
if (aValue == null) {
return 1;
}
if (bValue == null) {
return -1;
}
// 判断两个值是否以searchKey开头
boolean aStartsWith = aValue.toLowerCase().startsWith(searchKey.toLowerCase());
boolean bStartsWith = bValue.toLowerCase().startsWith(searchKey.toLowerCase());
// 如果a以searchKey开头而b不是a排在前面
if (aStartsWith && !bStartsWith) {
return -1;
}
// 如果b以searchKey开头而a不是b排在前面
if (bStartsWith && !aStartsWith) {
return 1;
}
// 如果两者都以searchKey开头或都不以searchKey开头保持原有顺序
return 0;
});
}
/**
* 判断searchKey是否为拼音是否只包含字母
*/
private boolean isPinyinKey(String searchKey) {
if (searchKey == null || searchKey.trim().isEmpty()) {
return false;
}
// 判断字符串是否只包含字母(拼音通常只包含字母)
return searchKey.matches("[a-zA-Z]+");
}
}

View File

@@ -187,29 +187,28 @@ public class DoctorStationChineseMedicalAppServiceImpl implements IDoctorStation
// 保存就诊诊断
EncounterDiagnosis encounterDiagnosis;
//中医获取排序号起始值
int startNo=0;
// 中医获取排序号起始值
int startNo = 0;
List<EncounterDiagnosis> diagnosisList = iEncounterDiagnosisService.getDiagnosisList(encounterId);
List<EncounterDiagnosis> newdiagnosisList = new ArrayList<>();
newdiagnosisList= diagnosisList.stream()
.filter(diagno -> diagno.getDeleteFlag().equals("0") && diagno.getDiagSrtNo()!=null)
newdiagnosisList =
diagnosisList.stream().filter(diagno -> diagno.getDeleteFlag().equals("0") && diagno.getDiagSrtNo() != null)
.collect(Collectors.toList());
newdiagnosisList = newdiagnosisList.stream()
.sorted((d1, d2) -> d2.getDiagSrtNo().compareTo(d1.getDiagSrtNo())) // 降序
.collect(Collectors.toList());
if (newdiagnosisList==null||newdiagnosisList.size()==0) {
startNo=1;
}else {
startNo=newdiagnosisList.get(0).getDiagSrtNo()+1;
newdiagnosisList = newdiagnosisList.stream().sorted((d1, d2) -> d2.getDiagSrtNo().compareTo(d1.getDiagSrtNo())) // 降序
.collect(Collectors.toList());
if (newdiagnosisList == null || newdiagnosisList.size() == 0) {
startNo = 1;
} else {
startNo = newdiagnosisList.get(0).getDiagSrtNo() + 1;
}
int i=0;//循环计数 用来区分 同组的 病 证
int i = 0;// 循环计数 用来区分 同组的 病 证
for (SaveDiagnosisChildParam saveDiagnosisChildParam : diagnosisChildList) {
encounterDiagnosis = new EncounterDiagnosis();
encounterDiagnosis.setId(saveDiagnosisChildParam.getEncounterDiagnosisId());
if(saveDiagnosisChildParam.getDiagSrtNo()!=null){
startNo=saveDiagnosisChildParam.getDiagSrtNo().intValue();
if (saveDiagnosisChildParam.getDiagSrtNo() != null) {
startNo = saveDiagnosisChildParam.getDiagSrtNo().intValue();
}
encounterDiagnosis.setEncounterId(encounterId);
encounterDiagnosis.setConditionId(saveDiagnosisChildParam.getConditionId());
@@ -221,11 +220,11 @@ public class DoctorStationChineseMedicalAppServiceImpl implements IDoctorStation
encounterDiagnosis.setTcmFlag(Whether.YES.getValue());// 中医标识
encounterDiagnosis.setSyndromeGroupNo(saveDiagnosisChildParam.getSyndromeGroupNo());// 中医证候组号
iEncounterDiagnosisService.saveOrUpdate(encounterDiagnosis);
if(saveDiagnosisChildParam.getDiagSrtNo()==null){
if (i==1){
if (saveDiagnosisChildParam.getDiagSrtNo() == null) {
if (i == 1) {
startNo++;
i--;
}else{
} else {
i++;
}
@@ -274,7 +273,7 @@ public class DoctorStationChineseMedicalAppServiceImpl implements IDoctorStation
encounterDiagnosis.setDiagnosisDesc(saveDiagnosisChildParam.getDiagnosisDesc()); // 诊断描述
encounterDiagnosis.setIptDiseTypeCode(saveDiagnosisChildParam.getIptDiseTypeCode()); // 患者疾病诊断类型代码
iEncounterDiagnosisService.saveOrUpdate(encounterDiagnosis);
}else {
} else {
}
}
@@ -342,8 +341,9 @@ public class DoctorStationChineseMedicalAppServiceImpl implements IDoctorStation
// 医嘱分类信息 (中草药)
List<AdviceSaveDto> medicineList = adviceSaveParam.getAdviceSaveList();
if (AdviceOpType.SAVE_ADVICE.getCode().equals(adviceOpType)) {
//保存时——中医处方去掉不修改的药方
medicineList=medicineList.stream().filter(e ->e.getAdviceDefinitionId()!=null).collect(Collectors.toUnmodifiableList());
// 保存时——中医处方去掉不修改的药方
medicineList = medicineList.stream().filter(e -> e.getAdviceDefinitionId() != null)
.collect(Collectors.toUnmodifiableList());
}
// 保存操作
boolean is_save = AdviceOpType.SAVE_ADVICE.getCode().equals(adviceOpType);
@@ -362,6 +362,12 @@ public class DoctorStationChineseMedicalAppServiceImpl implements IDoctorStation
iActivityDefinitionService.getAppointActivityDefinitionId(CommonConstants.BusinessName.SUFFERING_TCM);
// 保存时,校验库存
if (is_save) {
List<AdviceSaveDto> medUpdateList =
medicineList.stream().filter(e -> e.getRequestId() != null).collect(Collectors.toList());
// 编辑时,释放本身占用的库存发放
for (AdviceSaveDto adviceSaveDto : medUpdateList) {
iMedicationDispenseService.deleteMedicationDispense(adviceSaveDto.getRequestId());
}
List<AdviceSaveDto> needCheckList = medicineList.stream()
.filter(e -> !DbOpType.DELETE.getCode().equals(e.getDbOpType())).collect(Collectors.toList());
// 校验库存

View File

@@ -22,6 +22,7 @@ import com.openhis.administration.domain.Encounter;
import com.openhis.administration.domain.EncounterParticipant;
import com.openhis.administration.mapper.EncounterMapper;
import com.openhis.administration.service.IEncounterParticipantService;
import com.openhis.common.constant.CommonConstants;
import com.openhis.common.enums.*;
import com.openhis.common.utils.EnumUtils;
import com.openhis.common.utils.HisQueryUtils;
@@ -29,6 +30,7 @@ import com.openhis.web.doctorstation.appservice.IDoctorStationMainAppService;
import com.openhis.web.doctorstation.dto.PatientInfoDto;
import com.openhis.web.doctorstation.dto.PrescriptionInfoBaseDto;
import com.openhis.web.doctorstation.dto.PrescriptionInfoDetailDto;
import com.openhis.web.doctorstation.dto.ReceptionStatisticsDto;
import com.openhis.web.doctorstation.mapper.DoctorStationMainAppMapper;
/**
@@ -80,6 +82,8 @@ public class DoctorStationMainAppServiceImpl implements IDoctorStationMainAppSer
} else {
queryWrapper.orderByDesc("register_time");
}
// 只查询当前登录科室相关的患者
queryWrapper.eq(currentUserOrganizationId != null, CommonConstants.FieldName.OrgId, currentUserOrganizationId);
IPage<PatientInfoDto> patientInfo = doctorStationMainAppMapper.getPatientInfo(new Page<>(pageNo, pageSize),
ParticipantType.REGISTRATION_DOCTOR.getCode(), ParticipantType.ADMITTER.getCode(), userId,
currentUserOrganizationId, pricingFlag, EncounterStatus.PLANNED.getValue(),
@@ -165,10 +169,10 @@ public class DoctorStationMainAppServiceImpl implements IDoctorStationMainAppSer
*/
@Override
public IPage<PrescriptionInfoBaseDto> getPrescriptionPageInfo(PrescriptionInfoBaseDto prescriptionInfoBaseDto,
String searchKey, Integer pageNo, Integer pageSize) {
String searchKey, Integer pageNo, Integer pageSize, HttpServletRequest request) {
// 构建查询条件
QueryWrapper<PrescriptionInfoBaseDto> queryWrapper = HisQueryUtils.buildQueryWrapper(prescriptionInfoBaseDto,
searchKey, new HashSet<>(Arrays.asList("prescription_no", "patient_name", "practitioner_name")), null);
searchKey, new HashSet<>(Arrays.asList("prescription_no", "practitioner_name")), request);
IPage<PrescriptionInfoBaseDto> prescriptionPageInfo =
doctorStationMainAppMapper.getPrescriptionPageInfo(new Page<>(pageNo, pageSize), queryWrapper);
List<PrescriptionInfoBaseDto> PrescriptionInfo = prescriptionPageInfo.getRecords();
@@ -212,4 +216,18 @@ public class DoctorStationMainAppServiceImpl implements IDoctorStationMainAppSer
return prescriptionDetailInfo;
}
/**
* 查询接诊统计
*
* @param startTime 开始时间
* @param endTime 结束时间
* @param practitionerId 参与者id
* @return 接诊统计
*/
@Override
public List<ReceptionStatisticsDto> getReceptionStatistics(String startTime, String endTime, Long practitionerId) {
return doctorStationMainAppMapper.getReceptionStatistics(ParticipantType.ADMITTER.getCode(), startTime, endTime,
practitionerId);
}
}

View File

@@ -105,9 +105,9 @@ public class DoctorStationMainController {
public R<?> getPrescriptionPageInfo(PrescriptionInfoBaseDto prescriptionInfoBaseDto,
@RequestParam(value = "searchKey", defaultValue = "") String searchKey,
@RequestParam(value = "pageNo", defaultValue = "1") Integer pageNo,
@RequestParam(value = "pageSize", defaultValue = "20") Integer pageSize) {
return R.ok(
iDoctorStationMainAppService.getPrescriptionPageInfo(prescriptionInfoBaseDto, searchKey, pageNo, pageSize));
@RequestParam(value = "pageSize", defaultValue = "20") Integer pageSize, HttpServletRequest request) {
return R.ok(iDoctorStationMainAppService.getPrescriptionPageInfo(prescriptionInfoBaseDto, searchKey, pageNo,
pageSize, request));
}
/**
@@ -121,4 +121,19 @@ public class DoctorStationMainController {
return R.ok(iDoctorStationMainAppService.getPrescriptionDetailInfo(prescriptionNo));
}
/**
* 查询接诊统计
*
* @param startTime 开始时间
* @param endTime 结束时间
* @param practitionerId 参与者id
* @return 接诊统计
*/
@GetMapping(value = "/reception-statistics")
public R<?> getReceptionStatistics(@RequestParam("startTime") String startTime,
@RequestParam("endTime") String endTime,
@RequestParam(value = "practitionerId", required = false) Long practitionerId) {
return R.ok(iDoctorStationMainAppService.getReceptionStatistics(startTime, endTime, practitionerId));
}
}

View File

@@ -42,4 +42,9 @@ public class ActivityChildrenJsonParams {
@JsonSerialize(using = ToStringSerializer.class)
private Long parentId;
/**
* 诊断ID
*/
private Long encounterDiagnosisId;
}

View File

@@ -3,6 +3,8 @@ package com.openhis.web.doctorstation.dto;
import java.util.Date;
import java.util.List;
import org.springframework.format.annotation.DateTimeFormat;
import com.fasterxml.jackson.annotation.JsonFormat;
import com.fasterxml.jackson.databind.annotation.JsonSerialize;
import com.fasterxml.jackson.databind.ser.std.ToStringSerializer;
@@ -10,7 +12,6 @@ import com.openhis.common.annotation.Dict;
import lombok.Data;
import lombok.experimental.Accessors;
import org.springframework.format.annotation.DateTimeFormat;
/**
* 处方信息 dto
@@ -48,6 +49,12 @@ public class PrescriptionInfoBaseDto {
@JsonFormat(shape = JsonFormat.Shape.STRING, pattern = "yyyy-MM-dd HH:mm:ss")
private Date requestTime;
/**
* 开方医生id
*/
@JsonSerialize(using = ToStringSerializer.class)
private Long practitionerId;
/**
* 开方医生
*/

View File

@@ -0,0 +1,32 @@
package com.openhis.web.doctorstation.dto;
import com.fasterxml.jackson.databind.annotation.JsonSerialize;
import com.fasterxml.jackson.databind.ser.std.ToStringSerializer;
import lombok.Data;
import lombok.experimental.Accessors;
/**
* 接诊统计 dto
*/
@Data
@Accessors(chain = true)
public class ReceptionStatisticsDto {
/**
* 参与者id
*/
@JsonSerialize(using = ToStringSerializer.class)
private Long practitionerId;
/**
* 参与者
*/
private String practitionerName;
/**
* 接诊次数
*/
private Integer receptionNums;
}

View File

@@ -12,6 +12,7 @@ import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.openhis.web.doctorstation.dto.PatientInfoDto;
import com.openhis.web.doctorstation.dto.PrescriptionInfoBaseDto;
import com.openhis.web.doctorstation.dto.PrescriptionInfoDetailDto;
import com.openhis.web.doctorstation.dto.ReceptionStatisticsDto;
/**
* 医生站-主页面 应用Mapper
@@ -60,4 +61,17 @@ public interface DoctorStationMainAppMapper {
List<PrescriptionInfoDetailDto> getPrescriptionDetailInfo(@Param("prescriptionNo") String prescriptionNo,
@Param("encounterId") Long encounterId);
/**
* 查询接诊统计
*
* @param typeCode 类型 | 接诊医生
* @param startTime 开始时间
* @param endTime 结束时间
* @param practitionerId 参与者id
* @return 接诊统计
*/
List<ReceptionStatisticsDto> getReceptionStatistics(@Param("typeCode") String typeCode,
@Param("startTime") String startTime, @Param("endTime") String endTime,
@Param("practitionerId") Long practitionerId);
}

View File

@@ -375,7 +375,7 @@ public class AdviceUtils {
chargeItem.setProductTable(activityAdviceBaseDto.getAdviceTableName());// 产品所在表
chargeItem.setProductId(activityAdviceBaseDto.getAdviceDefinitionId());// 收费项id
chargeItem.setAccountId(activityChildrenJsonParams.getAccountId());// 关联账户ID
chargeItem.setEncounterDiagnosisId(activityChildrenJsonParams.getEncounterDiagnosisId());
chargeItem.setQuantityValue(quantity); // 数量
chargeItem.setQuantityUnit(activityAdviceBaseDto.getUnitCode()); // 单位
chargeItem.setUnitPrice(advicePriceDto.getPrice()); // 单价

View File

@@ -33,4 +33,11 @@ public interface IDocStatisticsAppService {
* @return 体温单信息
*/
List<DocStatisticsDto> getStatisticsListByEncounterIdAndPatientId(Long encounterId, Long patientId, Long tempId);
/**
* 保存/更新入院体征
*
* @param docStatisticsDtoList 入院体征list
*/
void saveOrUpdateAdmissionSigns(List<DocStatisticsDto> docStatisticsDtoList);
}

View File

@@ -318,16 +318,14 @@ public class DocDefinitionAppServiceImpl implements IDocDefinitionAppService {
log.warn("获取文书定义树形列表失败当前登录用户未关联医院ID");
return R.fail("获取文书定义树形列表失败:当前用户未关联医院,请重新登录");
}
if (menuEnum == null) {
return R.fail("来源类型不能为空");
}
// 2. 数据库查询文书定义列表
LambdaQueryWrapper<DocDefinition> queryWrapper = new LambdaQueryWrapper<>();
queryWrapper.eq(DocDefinition::getHospitalId, hospitalId);
queryWrapper.eq(DocDefinition::getPrimaryMenuEnum, menuEnum);
List<DocDefinition> docList = docDefinitionService.list(queryWrapper);
if (docList.isEmpty()) {
DocDefinition definition = new DocDefinition();
definition.setId(Long.valueOf(menuEnum));
docList.add(definition);
}
return R.ok(docList);
}
}

View File

@@ -4,7 +4,6 @@ import java.math.BigDecimal;
import java.sql.PreparedStatement;
import java.sql.SQLException;
import java.sql.Timestamp;
import java.text.SimpleDateFormat;
import java.time.LocalDate;
import java.time.LocalDateTime;
import java.time.LocalTime;
@@ -12,6 +11,7 @@ import java.time.ZoneId;
import java.time.format.DateTimeFormatter;
import java.time.temporal.ChronoUnit;
import java.util.*;
import java.util.regex.Pattern;
import java.util.stream.Collectors;
import javax.annotation.Resource;
@@ -233,17 +233,9 @@ public class DocRecordAppServiceImpl implements IDocRecordAppService {
* @return 返回结果 R对象
*/
public R<?> addRecord(DocRecordDto docRecordDto) {
// 来源类型集合
List<String> sourceCodes = Arrays.stream(DocDefinitionEnum.values()).map(DocDefinitionEnum::getValue).toList();
if (sourceCodes.contains(StringUtils.isBlank(docRecordDto.getSource()) ? "" : docRecordDto.getSource())) {
// 存在definition_id使用definition_id否则使用source
docRecordDto.setDefinitionId(docRecordDto.getDefinitionId() == null ? Long.valueOf(docRecordDto.getSource())
: docRecordDto.getDefinitionId());
} else {
String checkMsg = initRecordCheck(docRecordDto);
if (!checkMsg.isEmpty()) {
return R.fail(checkMsg);
}
String checkMsg = initRecordCheck(docRecordDto);
if (!checkMsg.isEmpty()) {
return R.fail(checkMsg);
}
DocRecord docRecord = new DocRecord();
docRecord.setDefinitionId(docRecordDto.getDefinitionId());
@@ -524,24 +516,23 @@ public class DocRecordAppServiceImpl implements IDocRecordAppService {
return R.fail("患者文书记录文书类型定义ID不能为空");
}
// 未传时间,按照当前时间
if (recordTime == null || recordTime.isEmpty()) {
// 将时间格式化
SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd");
recordTime = sdf.format(new Date());
}
Date recordDate = StringUtils.isBlank(recordTime) ? new Date()
: Date.from(LocalDate.parse(recordTime, DateTimeFormatter.ofPattern("yyyy-MM-dd")).atStartOfDay()
.atZone(ZoneId.systemDefault()).toInstant());
// 患者ID查询条件
LambdaQueryWrapper<DocRecord> queryWrapper = new LambdaQueryWrapper<>();
if (docRecordQueryParam.getPatientId() != null) {
queryWrapper.eq(DocRecord::getPatientId, docRecordQueryParam.getPatientId())
.eq(DocRecord::getEncounterId, docRecordQueryParam.getEncounterId())
.apply("to_char(record_time, 'YYYY-MM-DD') = {0}", recordTime);
.ge(DocRecord::getRecordTime, recordDate).lt(DocRecord::getRecordTime,
Date.from(recordDate.toInstant().atZone(ZoneId.systemDefault()).plusDays(1).toInstant()));
}
// 文书类型ID必传
queryWrapper.eq(DocRecord::getDefinitionId, docRecordQueryParam.getDefinitionId());
// 就诊ID查询条件修复原逻辑原代码字段匹配错误用EncounterId匹配DefinitionBusNo
if (docRecordQueryParam.getEncounterId() != null) {
queryWrapper.eq(DocRecord::getEncounterId, docRecordQueryParam.getEncounterId());
}
// if (docRecordQueryParam.getEncounterId() != null) {
// queryWrapper.eq(DocRecord::getEncounterId, docRecordQueryParam.getEncounterId());
// }
// 科室ID查询条件修复原逻辑原代码字段匹配错误用OrganizationId匹配EncounterId
if (docRecordQueryParam.getOrganizationId() != null) {
queryWrapper.eq(DocRecord::getOrganizationId, docRecordQueryParam.getOrganizationId());
@@ -604,9 +595,22 @@ public class DocRecordAppServiceImpl implements IDocRecordAppService {
*/
@Override
public R<?> temperatureChart(DocRecordQueryParam docRecordQueryParam) {
// 参数校验
if (docRecordQueryParam == null) {
return R.fail("患者文书记录:查询参数不能为空");
}
Long encounterId = docRecordQueryParam.getEncounterId();
Long patientId = docRecordQueryParam.getPatientId();
Long tempId = docRecordQueryParam.getDefinitionId();
if (encounterId == null) {
return R.fail("患者文书记录就诊ID不能为空");
}
if (patientId == null) {
return R.fail("患者文书记录患者ID不能为空");
}
if (tempId == null) {
return R.fail("患者文书记录文书类型定义ID不能为空");
}
// 根据病历ID和患者ID获取住院、出院时间
Map<String, Date> dateMap = getDateByEncounterId(encounterId, patientId);
Date hospDate = dateMap.get("hospDate");
@@ -639,7 +643,7 @@ public class DocRecordAppServiceImpl implements IDocRecordAppService {
// typeValue
String typeValue = docStatisticsDto.getValue();
// 如果typeValue为空数据不添加进list
if ("".equals(typeValue)) {
if (StringUtils.isBlank(typeValue)) {
continue;
}
// date
@@ -659,6 +663,9 @@ public class DocRecordAppServiceImpl implements IDocRecordAppService {
TemperatureChartEnum.BREATH.getCode(), TemperatureChartEnum.PAIN_SCORE.getCode());
if (temperatureChartCodes.contains(typeCode)) {
collectionMode = 1;
if (isChineseWithSpace(typeValue)) {
typeCode = TemperatureChartEnum.TEMPERATURE_CHINESE.getCode();
}
}
TrendChartsSmall trendChartsSmall =
new TrendChartsSmall(collectionMode, date, times, typeCode, typeValue, weekNo, orderByDateTimes, id);
@@ -682,14 +689,28 @@ public class DocRecordAppServiceImpl implements IDocRecordAppService {
*/
@Override
public R<?> summaryNursingRecords(DocRecordQueryParam docRecordQueryParam, String startTime, String endTime) {
// 参数校验
if (docRecordQueryParam == null) {
return R.fail("患者文书记录:查询参数不能为空");
}
Long encounterId = docRecordQueryParam.getEncounterId();
Long patientId = docRecordQueryParam.getPatientId();
Long definitionId = docRecordQueryParam.getDefinitionId();
if (encounterId == null) {
return R.fail("患者文书记录就诊ID不能为空");
}
if (patientId == null) {
return R.fail("患者文书记录患者ID不能为空");
}
if (definitionId == null) {
return R.fail("患者文书记录文书类型定义ID不能为空");
}
List<DocRecordDto> docRecordList = new ArrayList<>();
// 查询所有
LambdaQueryWrapper<DocRecord> wrapper = new LambdaQueryWrapper<>();
wrapper.eq(DocRecord::getEncounterId, docRecordQueryParam.getEncounterId());
wrapper.eq(DocRecord::getPatientId, docRecordQueryParam.getPatientId());
if (docRecordQueryParam.getDefinitionId() != null) {
wrapper.eq(DocRecord::getDefinitionId, docRecordQueryParam.getDefinitionId());
}
wrapper.eq(DocRecord::getEncounterId, encounterId);
wrapper.eq(DocRecord::getPatientId, patientId);
wrapper.eq(DocRecord::getDefinitionId, definitionId);
// 有时间就按时间条件查询
if (StringUtils.isNotBlank(startTime)) {
wrapper.ge(DocRecord::getRecordTime, LocalDate.parse(startTime));
@@ -762,21 +783,19 @@ public class DocRecordAppServiceImpl implements IDocRecordAppService {
// 获取others数据
List<TrendChartsSmall> others = new ArrayList<>(allTrendChartsSmalls.stream()
.filter(item -> (item.getCollectionMode() == null || item.getCollectionMode() != 1)).toList());
// 尿量、大便次数、小便次数、入量、其他 记录的是前一天的,时间要减一天
// isOneDayInAdvance(others);
// 移除others数据
allTrendChartsSmalls.removeAll(others);
// 根据病历ID获取入科时间
Date admissionDate = getDateByEncounterId(encounterId);
// 为入科 TrendChartsSmall 准备数据
String times = "";
if (!allTrendChartsSmalls.isEmpty()) {
times = allTrendChartsSmalls.get(0).getTimes();
}
int weekNo = calculateWeek(hospDate, admissionDate);
// 入科 TrendChartsSmall
TrendChartsSmall admissionSmall =
new TrendChartsSmall(null, admissionDate, times, TemperatureChartEnum.WARD_ADMISSION.getCode(),
TemperatureChartEnum.WARD_ADMISSION.getDescription() + "," + formatDate(admissionDate, "HH:mm"), weekNo,
formatDate(admissionDate, "yyyy-MM-dd HH:mm:ss"), "");
TrendChartsSmall admissionSmall = new TrendChartsSmall(null, admissionDate,
formatDate(admissionDate, "HH:mm:ss"), TemperatureChartEnum.WARD_ADMISSION.getCode(),
TemperatureChartEnum.WARD_ADMISSION.getDescription() + "," + formatDate(admissionDate, "HH:mm"), weekNo,
formatDate(admissionDate, "yyyy-MM-dd HH:mm:ss"), "");
ArrayList<TrendChartsSmall> admissionBig = new ArrayList<>();
admissionBig.add(admissionSmall);
// 先添加入科
@@ -806,6 +825,39 @@ public class DocRecordAppServiceImpl implements IDocRecordAppService {
return new TrendChartsOutput(hospDate, null, null, temperaturePulses, others);
}
/**
* 校验是否为汉字
*
* @param content 待校验字符串
* @return 校验结果
*/
public static boolean isChineseWithSpace(String content) {
Pattern regex = Pattern.compile("^[\\u4E00-\\u9FA5\\s]+$");
if (StringUtils.isBlank(content)) {
return false;
} else {
return regex.matcher(content).matches();
}
}
/**
* 提前一天
*
* @param others others集合
*/
private void isOneDayInAdvance(List<TrendChartsSmall> others) {
List<String> tiqian = Arrays.asList(TemperatureChartEnum.INPUT.getCode(),
TemperatureChartEnum.BOWEL_MOVEMENT_FREQUENCY.getCode(), TemperatureChartEnum.URINATION_FREQUENCY.getCode(),
TemperatureChartEnum.URINE_VOLUME.getCode(), TemperatureChartEnum.OTHERS.getCode());
others.forEach(item -> {
if (StringUtils.isBlank(item.getTypeCode()) && tiqian.contains(item.getTypeCode())) {
LocalDate date = item.getDate().toInstant().atZone(ZoneId.systemDefault()).toLocalDate();
date = date.plusDays(-1);
item.setDate(Date.from(date.atStartOfDay(ZoneId.systemDefault()).toInstant()));
}
});
}
/**
* 每一天的血压取上下午各最新的一条
*
@@ -813,34 +865,42 @@ public class DocRecordAppServiceImpl implements IDocRecordAppService {
* @return 每天上下午各最新一条的血压数据的集合
*/
private List<DocStatisticsDto> getLatestRecordsPerPeriod(List<DocStatisticsDto> list) {
// 安全校验:列表为空时直接返回空字符串
if (list == null) {
return List.of();
// 安全校验:列表为空或null时直接返回空列表
if (list == null || list.isEmpty()) {
return Collections.emptyList();
}
// 按上午和下午分组
Map<String, Optional<DocStatisticsDto>> latestByAmPm = list.stream().collect(Collectors.groupingBy(dto -> {
// 将 Date 转换为 LocalTime 判断上下午
LocalTime time = dto.getRecordTime().toInstant().atZone(ZoneId.systemDefault()).toLocalTime();
return time.isBefore(LocalTime.NOON) ? "AM" : "PM";
}, Collectors.maxBy(Comparator.comparing(DocStatisticsDto::getRecordTime))));
// 提取Optional中的值过滤掉空的分组并按血压数据按时间排序
List<DocStatisticsDto> collect = latestByAmPm.values().stream().filter(Optional::isPresent).map(Optional::get)
.sorted(Comparator.comparing(DocStatisticsDto::getRecordTime)).collect(Collectors.toList());
// 同一天 上下数据拼接在一起
List<DocStatisticsDto> collectPM = new ArrayList<>();
for (int i = 0; i < collect.size() - 1; i = i + 2) {
// 上午血压数据
DocStatisticsDto dtoAM = collect.get(i);
// 下午血压数据
DocStatisticsDto dtoPM = collect.get(i + 1);
// 下午数据集合
collectPM.add(dtoPM);
// 拼接到上午数据中
dtoAM.setValue(dtoAM.getValue() + "," + dtoPM.getValue());
// 按上午(AM)/下午(PM)分组,获取每组符合规则的最新数据
Map<String, Optional<DocStatisticsDto>> latestByAmPm =
list.stream().filter(item -> item.getValue() != null && !"/".equals(item.getValue().trim())) // 过滤无效值
.collect(Collectors.groupingBy(
// 按时间判断上下午12点前为上午12点及以后为下午
dto -> {
LocalTime time = dto.getRecordTime().toInstant().atZone(ZoneId.systemDefault()).toLocalTime();
return time.isBefore(LocalTime.NOON) ? "AM" : "PM";
}, Collectors.collectingAndThen(Collectors.toList(), groupList -> {
// 第一步:筛选出数值型数据(非汉字)
List<DocStatisticsDto> numericData = groupList.stream()
.filter(dto -> !isChineseWithSpace(dto.getValue())).collect(Collectors.toList());
// 第二步:如果有数值型数据,取最新的;否则取分组内最新的汉字数据
List<DocStatisticsDto> targetData = numericData.isEmpty() ? groupList : numericData;
return targetData.stream().max(Comparator.comparing(DocStatisticsDto::getRecordTime));
})));
// 提取有效数据并按时间排序
List<DocStatisticsDto> validData = latestByAmPm.values().stream().filter(Optional::isPresent).map(Optional::get)
.sorted(Comparator.comparing(DocStatisticsDto::getRecordTime)).toList();
// 拼接上下午数据(上午值 + 逗号 + 下午值)
List<DocStatisticsDto> result = new ArrayList<>();
if (validData.size() == 1) {
// 只有单条数据(上午/下午),直接保留
result.add(validData.get(0));
} else if (validData.size() >= 2) {
// 取前两条(上午+下午)拼接,上午作为主数据
DocStatisticsDto amDto = validData.get(0);
DocStatisticsDto pmDto = validData.get(1);
amDto.setValue(amDto.getValue() + "," + pmDto.getValue());
result.add(amDto);
}
// 移除下午数据
collect.removeAll(collectPM);
return collect;
return result;
}
/**
@@ -868,21 +928,36 @@ public class DocRecordAppServiceImpl implements IDocRecordAppService {
* @param postopDateList 手术时间list
*
*/
private void calculatePostopDay(TrendChartsOutput trendChartsOutput, List<LocalDate> postopDateList) {
// 统计术后天数的截至日期
LocalDate endDate;
if (trendChartsOutput.getOutDate() == null) {
endDate = LocalDate.now();
} else {
endDate = trendChartsOutput.getOutDate().toInstant().atZone(ZoneId.systemDefault()).toLocalDate();
}
// 计算术后天数
private void calculatePostopDay(TrendChartsOutput trendChartsOutput, List<LocalDateTime> postopDateList) {
if (!postopDateList.isEmpty()) {
for (LocalDate currentDate = postopDateList.get(0); !currentDate.isAfter(endDate);
// 统计术后天数的截至日期
LocalDate endDate;
if (trendChartsOutput.getOutDate() == null) {
endDate = LocalDate.now();
} else {
endDate = trendChartsOutput.getOutDate().toInstant().atZone(ZoneId.systemDefault()).toLocalDate();
}
// 添加手术信息
for (LocalDateTime dateTime : postopDateList) {
// 手术时间
Date postopDate = Date.from(dateTime.atZone(ZoneId.systemDefault()).toInstant());
String times = formatDate(postopDate, "HH:mm:ss");
String typeValue =
TemperatureChartEnum.OPERATION.getDescription() + "," + formatDate(postopDate, "HH:mm");
// 封装手术信息
TrendChartsSmall postopSmall =
new TrendChartsSmall(null, postopDate, times, TemperatureChartEnum.OPERATION.getCode(), typeValue,
calculateWeek(trendChartsOutput.getHospDate(), postopDate), null, null);
// 将收入信息添加到有入科信息的集合中
trendChartsOutput.getTemperaturePulses().get(0).getChartsSmalls().add(postopSmall);
}
// 计算术后天数
for (LocalDate currentDate = postopDateList.get(0).toLocalDate(); !currentDate.isAfter(endDate);
currentDate = currentDate.plusDays(1)) {
// 获取术后天数
String typeValue = OperationDayCalculator.calculateOperationDay(postopDateList, currentDate);
// 封装信息
String typeValue = OperationDayCalculator.calculateOperationDay(
postopDateList.stream().map(LocalDateTime::toLocalDate).toList(), currentDate);
// 封装[术后天数]信息
Date date = Date.from(currentDate.atStartOfDay(ZoneId.systemDefault()).toInstant());
TrendChartsSmall postopSmall =
new TrendChartsSmall(null, date, null, TemperatureChartEnum.POSTOP_DAYS.getCode(), typeValue,
@@ -932,14 +1007,14 @@ public class DocRecordAppServiceImpl implements IDocRecordAppService {
* @param patientId 患者ID
* @return 手术时间列表
*/
private List<LocalDate> getPostopDate(Long encounterId, Long patientId) {
private List<LocalDateTime> getPostopDate(Long encounterId, Long patientId) {
String sql =
"SELECT cpp.start_time FROM cli_procedure_performer cpp LEFT JOIN cli_procedure cp ON cpp.procedure_id=cp.ID LEFT JOIN adm_encounter ae ON ae.patient_id=cp.patient_id AND ae.ID=cp.encounter_id AND ae.status_enum=? AND ae.class_enum=? WHERE cp.patient_id=? AND cp.status_enum=? AND cp.encounter_id=? AND cpp.start_time> ae.start_time AND cpp.end_time <= ae.end_time ORDER BY cpp.start_time";
Object[] params = {EncounterZyStatus.ADMITTED_TO_THE_HOSPITAL.getValue(), EncounterClass.IMP.getValue(),
patientId, 5, encounterId};
List<Timestamp> dates = jdbcTemplate.queryForList(sql, Timestamp.class, params);
return dates.stream().map(date -> date.toLocalDateTime().toLocalDate()).toList();
return dates.stream().map(date -> date.toLocalDateTime()).toList();
}
/**

View File

@@ -185,4 +185,25 @@ public class DocStatisticsAppServiceImpl implements IDocStatisticsAppService {
}
return dtoList;
}
/**
* 保存/更新入院体征
*
* @param docStatisticsDtoList 入院体征list
*/
@Override
public void saveOrUpdateAdmissionSigns(List<DocStatisticsDto> docStatisticsDtoList) {
// 实体类 转换
List<DocStatistics> docStatisticsList = docStatisticsDtoList.stream().map(item -> {
DocStatistics statistics = new DocStatistics();
BeanUtils.copyProperties(item, statistics);
return statistics;
}).toList();
// 需要删除的
List<DocStatistics> removeList = docStatisticsList.stream().filter(item -> item.getId() != null).toList();
// 需要新增的
List<DocStatistics> addList = docStatisticsList.stream().filter(item -> item.getId() == null).toList();
docStatisticsService.removeBatchByIds(removeList.stream().map(DocStatistics::getId).toList());
docStatisticsService.saveBatch(addList);
}
}

View File

@@ -70,7 +70,7 @@ public class AdvancePaymentManageAppServiceImpl implements IAdvancePaymentManage
*/
@Override
public IPage<AdvancePaymentInfoDto> getAdvancePaymentInfo(AdvancePaymentInfoDto advancePaymentInfoDto,
String searchKey,Long wardLocationId, Integer pageNo, Integer pageSize, HttpServletRequest request) {
String searchKey, Long wardLocationId, Integer pageNo, Integer pageSize, HttpServletRequest request) {
// 构建查询条件
QueryWrapper<AdvancePaymentInfoDto> queryWrapper = HisQueryUtils.buildQueryWrapper(advancePaymentInfoDto,
searchKey, new HashSet<>(Arrays.asList("bus_no", "patient_name", "inHospital_org_name")), request);
@@ -80,7 +80,8 @@ public class AdvancePaymentManageAppServiceImpl implements IAdvancePaymentManage
LocationForm.HOUSE.getValue(), LocationForm.BED.getValue(), EncounterActivityStatus.ACTIVE.getValue(),
ChargeItemStatus.BILLABLE.getValue(), ChargeItemStatus.BILLED.getValue(),
ChargeItemStatus.REFUNDED.getValue(), EncounterClass.IMP.getValue(),
AccountType.PERSONAL_CASH_ACCOUNT.getCode(), wardLocationId,queryWrapper);
AccountType.PERSONAL_CASH_ACCOUNT.getCode(), wardLocationId, EncounterZyStatus.TO_BE_REGISTERED.getValue(),
queryWrapper);
advancePaymentInfo.getRecords().forEach(e -> {
// 性别
e.setGenderEnum_enumText(EnumUtils.getInfoByValue(AdministrativeGender.class, e.getGenderEnum()));
@@ -182,7 +183,7 @@ public class AdvancePaymentManageAppServiceImpl implements IAdvancePaymentManage
if (payEnum != null && payEnum != 0) {
paymentDetail.setPayEnum(payEnum); // 支付类型
paymentDetail.setPayLevelEnum(YbPayment.getByValue(payEnum).getLevel());// 支付类型等级
}else {
} else {
paymentDetail.setPayEnum(YbPayment.SELF_CASH_PAY.getValue()); // 支付类型
paymentDetail.setPayLevelEnum(YbPayment.SELF_CASH_PAY.getLevel()); // 支付类型等级
}

View File

@@ -35,7 +35,7 @@ import com.openhis.web.inhospitalcharge.appservice.IInHospitalRegisterAppService
import com.openhis.web.inhospitalcharge.dto.*;
import com.openhis.web.inhospitalcharge.mapper.InHospitalRegisterAppMapper;
import com.openhis.web.patientmanage.appservice.IPatientInformationService;
import com.openhis.web.patientmanage.dto.PatientInformationDto;
import com.openhis.web.patientmanage.dto.PatientBaseInfoDto;
import com.openhis.yb.service.YbManager;
import lombok.extern.slf4j.Slf4j;
@@ -306,7 +306,7 @@ public class InHospitalRegisterAppServiceImpl implements IInHospitalRegisterAppS
@Override
public R<?> noFilesRegister(NoFilesRegisterDto noFilesRegisterDto) {
// 患者信息
PatientInformationDto patientInformation = noFilesRegisterDto.getPatientInformation();
PatientBaseInfoDto patientInformation = noFilesRegisterDto.getPatientInformation();
// 新增患者
R<?> r = patientInformationService.addPatient(patientInformation);
if (r.getCode() == 200) {

View File

@@ -1,6 +1,6 @@
package com.openhis.web.inhospitalcharge.dto;
import com.openhis.web.patientmanage.dto.PatientInformationDto;
import com.openhis.web.patientmanage.dto.PatientBaseInfoDto;
import lombok.Data;
import lombok.experimental.Accessors;
@@ -15,7 +15,7 @@ public class NoFilesRegisterDto {
/**
* 患者信息
*/
private PatientInformationDto patientInformation;
private PatientBaseInfoDto patientInformation;
/**
* 住院信息

View File

@@ -3,7 +3,6 @@ package com.openhis.web.inhospitalcharge.mapper;
import java.util.List;
import org.apache.ibatis.annotations.Param;
import org.springframework.security.core.parameters.P;
import org.springframework.stereotype.Repository;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
@@ -32,6 +31,7 @@ public interface AdvancePaymentManageAppMapper {
* @param status3 已退费
* @param classEnum 住院
* @param accountTypeCode 个人现金账号
* @param registeredFlag 登记标识
* @return 预交金基本信息
*/
IPage<AdvancePaymentInfoDto> getAdvancePaymentInfo(@Param("page") Page<AdvancePaymentInfoDto> page,
@@ -39,7 +39,7 @@ public interface AdvancePaymentManageAppMapper {
@Param("bedEnum") Integer bedEnum, @Param("encounterActivityStatus") Integer encounterActivityStatus,
@Param("status1") Integer status1, @Param("status2") Integer status2, @Param("status3") Integer status3,
@Param("classEnum") Integer classEnum, @Param("accountTypeCode") String accountTypeCode,
@Param("wardLocationId") Long wardLocationId,
@Param("wardLocationId") Long wardLocationId, @Param("registeredFlag") Integer registeredFlag,
@Param(Constants.WRAPPER) QueryWrapper<AdvancePaymentInfoDto> queryWrapper);
/**

View File

@@ -16,6 +16,13 @@ import com.openhis.web.inhospitalnursestation.dto.MedicineSummaryParam;
*/
public interface IMedicineSummaryAppService {
/**
* 药品汇总单初始化
*
* @return 初始化信息
*/
R<?> getMedicineSummaryInit();
/**
* 查询发药单信息
*

View File

@@ -1,14 +1,17 @@
package com.openhis.web.inhospitalnursestation.appservice;
import java.time.LocalDateTime;
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.CostDetailSearchParam;
import com.openhis.web.inhospitalnursestation.dto.InpatientAdviceParam;
import com.openhis.web.regdoctorstation.dto.AdviceBatchOpParam;
import com.openhis.web.regdoctorstation.dto.RegAdviceSaveParam;
import java.time.LocalDateTime;
import java.util.Date;
import java.util.List;
public interface INurseBillingAppService {
/*
* 住院护士 划价添加
@@ -20,7 +23,7 @@ public interface INurseBillingAppService {
* 住院护士撤销划价
* @return
*/
public R<?> deleteInNurseBilling(List<AdviceBatchOpParam> paramList);
public R<?> deleteInNurseBilling(List<AdviceBatchOpParam> paramList);
/**
* 住院患者医嘱查询
@@ -30,18 +33,40 @@ public interface INurseBillingAppService {
* @param pageSize 查询条数
* @return 住院患者医
*/
R<?> getInNurseBillingPage(InpatientAdviceParam inpatientAdviceParam, Integer pageNo, Integer pageSize, LocalDateTime startTime, LocalDateTime endTime);
R<?> getInNurseBillingPage(InpatientAdviceParam inpatientAdviceParam, Integer pageNo, Integer pageSize,
LocalDateTime startTime, LocalDateTime endTime);
/*
* 医嘱计费添加 诊疗 耗材
*/
public R<?> addOrderBilling();
public R<?> addOrderBilling();
/*
* 医嘱计费删除 诊疗 耗材
*/
public R<?> deleteOrderBilling();
public R<?> deleteOrderBilling();
/*
* 医嘱计费修改 诊疗 耗材
*/
public R<?> updateOrderBilling();
public R<?> updateOrderBilling();
/**
* 费用明细查询
*
* @param costDetailSearchParam 查询条件
* @param request request请求
* @return 住院患者费用明细
*/
R<?> getCostDetails(CostDetailSearchParam costDetailSearchParam, HttpServletRequest request);
/**
* 费用明细导出
*
* @param costDetailSearchParam 查询条件
* @param request request请求
* @param response response响应
*/
void makeExcelFile(CostDetailSearchParam costDetailSearchParam, HttpServletRequest request,
HttpServletResponse response);
}

View File

@@ -20,6 +20,7 @@ import com.core.common.enums.DelFlag;
import com.core.common.utils.AgeCalculatorUtil;
import com.core.common.utils.DateUtils;
import com.core.common.utils.SecurityUtils;
import com.core.common.utils.StringUtils;
import com.openhis.administration.domain.Encounter;
import com.openhis.administration.domain.EncounterLocation;
import com.openhis.administration.service.IEncounterLocationService;
@@ -317,6 +318,8 @@ public class ATDManageAppServiceImpl implements IATDManageAppService {
admissionPatientInfoDto.getChiefDoctorId(), ParticipantType.CHIEF_DOCTOR.getCode());
}
}
// 更新入院体征
saveOrUpdateAdmissionSigns(encounterId, admissionPatientInfoDto, startTime);
return R.ok("患者信息更新成功");
}
@@ -416,7 +419,7 @@ public class ATDManageAppServiceImpl implements IATDManageAppService {
return R.fail("床位分配失败,请联系管理员");
}
// 保存入院体征
addAdmissionSigns(encounterId, admissionPatientInfoDto, startTime);
saveOrUpdateAdmissionSigns(encounterId, admissionPatientInfoDto, startTime);
return R.ok("床位分配成功");
}
@@ -509,6 +512,7 @@ public class ATDManageAppServiceImpl implements IATDManageAppService {
.ne(ServiceRequest::getCategoryEnum, ActivityDefCategory.TRANSFER.getValue())
.ne(ServiceRequest::getCategoryEnum, ActivityDefCategory.DISCHARGE.getValue())
.ne(ServiceRequest::getCategoryEnum, ActivityDefCategory.NURSING.getValue())
.eq(ServiceRequest::getParentId, null)
.eq(ServiceRequest::getDeleteFlag, DelFlag.NO.getCode()));
if (!medicationRequestList.isEmpty() || !serviceRequestList.isEmpty()) {
return R.fail("有待执行的医嘱,请执行完后再出院");
@@ -613,12 +617,15 @@ public class ATDManageAppServiceImpl implements IATDManageAppService {
dto.setTemperature(map.get(TemperatureChartEnum.TEMPERATURE.getTypeCode()));
dto.setPulse(map.get(TemperatureChartEnum.PULSE.getTypeCode()));
dto.setHertRate(map.get(TemperatureChartEnum.HEART_RATE.getTypeCode()));
String string = map.get(TemperatureChartEnum.BLOOD_PRESSURE.getTypeCode());
String[] split = string.split("/");
String endBloodPressure = split[0].trim();
String highBloodPressure = split[1].trim();
dto.setEndBloodPressure(endBloodPressure);
dto.setHighBloodPressure(highBloodPressure);
String bloodPressure = map.get(TemperatureChartEnum.BLOOD_PRESSURE.getTypeCode());
if (!StringUtils.isEmpty(bloodPressure)) {
String[] split = bloodPressure.split("/");
String endBloodPressure = split[0].strip();
String highBloodPressure = split[1].strip();
dto.setEndBloodPressure(endBloodPressure);
dto.setHighBloodPressure(highBloodPressure);
}
}
}
@@ -629,7 +636,7 @@ public class ATDManageAppServiceImpl implements IATDManageAppService {
* @param dto 入院患者信息
* @param recordTime 记录时间
*/
private void addAdmissionSigns(Long encounterId, AdmissionPatientInfoDto dto, Date recordTime) {
private void saveOrUpdateAdmissionSigns(Long encounterId, AdmissionPatientInfoDto dto, Date recordTime) {
// 创建入院体征map
HashMap<String, String> map = new HashMap<>();
map.put(TemperatureChartEnum.HEIGHT.getTypeCode(), dto.getHeight());
@@ -653,26 +660,27 @@ public class ATDManageAppServiceImpl implements IATDManageAppService {
// 获取患者ID
Encounter encounter = encounterService.getById(encounterId);
// 创建体温单统计列表
ArrayList<DocStatisticsDto> list = new ArrayList<>();
List<DocStatisticsDto> data =
((List<DocStatisticsDto>)docStatisticsAppService.queryByEncounterId(encounterId).getData()).stream()
.filter(item -> DocDefinitionEnum.ADMISSION_VITAL_SIGNS.getValue().equals(item.getSource())).toList();
List<DocStatisticsDto> list = new ArrayList<>(data);
map.keySet().forEach(key -> {
if (map.get(key) != null && !map.get(key).isEmpty()) {
if (map.get(key) != null && !map.get(key).isEmpty()) {
DocStatisticsDefinitionDto docStatisticsDefinitionDto = definitionDtoHashMap.get(key);
DocStatisticsDto statistics = new DocStatisticsDto();
statistics.setStatisticDefinitionCode(key);
statistics.setValue(map.get(key));
statistics.setEncounterId(encounterId);
statistics.setPatientId(encounter.getPatientId());
statistics.setStatisticDefinitionId(docStatisticsDefinitionDto.getId());
statistics.setRecordTime(recordTime);
statistics.setSource(DocDefinitionEnum.ADMISSION_VITAL_SIGNS.getValue());
list.add(statistics);
}
DocStatisticsDefinitionDto docStatisticsDefinitionDto = definitionDtoHashMap.get(key);
DocStatisticsDto statistics = new DocStatisticsDto();
statistics.setStatisticDefinitionCode(key);
statistics.setValue(map.get(key));
statistics.setEncounterId(encounterId);
statistics.setPatientId(encounter.getPatientId());
statistics.setStatisticDefinitionId(docStatisticsDefinitionDto.getId());
statistics.setRecordTime(recordTime);
statistics.setSource(DocDefinitionEnum.ADMISSION_VITAL_SIGNS.getValue());
list.add(statistics);
}
});
// 保存入院体征
if (!list.isEmpty()) {
docStatisticsAppService.createOrUpdte(list);
docStatisticsAppService.saveOrUpdateAdmissionSigns(list);
}
}
}

View File

@@ -3,6 +3,7 @@ package com.openhis.web.inhospitalnursestation.appservice.impl;
import java.math.BigDecimal;
import java.util.*;
import java.util.stream.Collectors;
import java.util.stream.Stream;
import javax.annotation.Resource;
import javax.servlet.http.HttpServletRequest;
@@ -29,6 +30,7 @@ import com.openhis.web.inhospitalnursestation.dto.MedicineDispenseFormDto;
import com.openhis.web.inhospitalnursestation.dto.MedicineSummaryFormDto;
import com.openhis.web.inhospitalnursestation.dto.MedicineSummaryParam;
import com.openhis.web.inhospitalnursestation.mapper.MedicineSummaryAppMapper;
import com.openhis.web.pharmacymanage.dto.DispenseInitDto;
import com.openhis.web.pharmacymanage.mapper.ReturnMedicineMapper;
import com.openhis.workflow.service.ISupplyDeliveryService;
import com.openhis.workflow.service.ISupplyRequestService;
@@ -63,6 +65,31 @@ public class MedicineSummaryAppServiceImpl implements IMedicineSummaryAppService
@Resource
private ReturnMedicineMapper returnMedicineMapper;
/**
* 药品汇总单初始化
*
* @return 初始化信息
*/
@Override
public R<?> getMedicineSummaryInit() {
DispenseInitDto initDto = new DispenseInitDto();
// 未发药原因下拉选列表
List<DispenseInitDto.NotPerformedReasonOption> notPerformedReasonOptions =
Stream.of(NotPerformedReasonEnum.values())
.map(notPerformedReason -> new DispenseInitDto.NotPerformedReasonOption(notPerformedReason.getValue(),
notPerformedReason.getInfo()))
.collect(Collectors.toList());
// 发药状态
List<DispenseInitDto.DispenseStatusOption> dispenseStatusOptions = new ArrayList<>();
dispenseStatusOptions.add(new DispenseInitDto.DispenseStatusOption(DispenseStatus.PREPARATION.getValue(),
DispenseStatus.PREPARATION.getInfo()));
dispenseStatusOptions.add(new DispenseInitDto.DispenseStatusOption(DispenseStatus.COMPLETED.getValue(),
DispenseStatus.COMPLETED.getInfo()));
initDto.setNotPerformedReasonOptions(notPerformedReasonOptions).setDispenseStatusOptions(dispenseStatusOptions);
return R.ok(initDto);
}
/**
* 查询发药单信息
*
@@ -133,7 +160,7 @@ public class MedicineSummaryAppServiceImpl implements IMedicineSummaryAppService
// 汇总单分页列表
Page<MedicineSummaryFormDto> medicineSummaryFormPage = medicineSummaryAppMapper.selectMedicineSummaryFormPage(
new Page<>(pageNo, pageSize), queryWrapper, DispenseStatus.COMPLETED.getValue(),
DispenseStatus.IN_PROGRESS.getValue(), SupplyType.SUMMARY_DISPENSE.getValue());
DispenseStatus.PREPARATION.getValue(), SupplyType.SUMMARY_DISPENSE.getValue());
medicineSummaryFormPage.getRecords().forEach(e -> {
// 发药状态
e.setStatusEnum_enumText(EnumUtils.getInfoByValue(DispenseStatus.class, e.getStatusEnum()));

View File

@@ -1,10 +1,13 @@
package com.openhis.web.inhospitalnursestation.appservice.impl;
import java.math.BigDecimal;
import java.time.LocalDateTime;
import java.util.*;
import java.util.stream.Collectors;
import javax.annotation.Resource;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
@@ -13,13 +16,14 @@ 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.core.domain.model.LoginUser;
import com.core.common.exception.NonCaptureException;
import com.core.common.exception.ServiceException;
import com.core.common.utils.AgeCalculatorUtil;
import com.core.common.utils.AssignSeqUtil;
import com.core.common.utils.MessageUtils;
import com.core.common.utils.SecurityUtils;
import com.core.common.utils.*;
import com.openhis.administration.domain.ChargeItem;
import com.openhis.administration.dto.CostDetailDto;
import com.openhis.administration.dto.CostDetailSearchParam;
import com.openhis.administration.service.IChargeItemService;
import com.openhis.administration.service.IOrganizationService;
import com.openhis.clinical.domain.Procedure;
import com.openhis.clinical.service.IProcedureService;
import com.openhis.common.constant.CommonConstants;
@@ -31,6 +35,7 @@ import com.openhis.web.doctorstation.dto.ActivityChildrenJsonParams;
import com.openhis.web.doctorstation.dto.AdviceSaveDto;
import com.openhis.web.doctorstation.utils.AdviceUtils;
import com.openhis.web.inhospitalnursestation.appservice.INurseBillingAppService;
import com.openhis.web.inhospitalnursestation.dto.CostDetailExcelOutDto;
import com.openhis.web.inhospitalnursestation.dto.InpatientAdviceDto;
import com.openhis.web.inhospitalnursestation.dto.InpatientAdviceParam;
import com.openhis.web.inhospitalnursestation.mapper.NurseBillingAppMapper;
@@ -130,6 +135,8 @@ public class NurseBillingAppService implements INurseBillingAppService {
private IProcedureService iProcedureService;
@Resource
private NurseBillingAppMapper nurseBillingAppMapper;
@Resource
private IOrganizationService organizationService;
// ======================== 核心业务方法(划价新增)========================
@@ -191,7 +198,7 @@ public class NurseBillingAppService implements INurseBillingAppService {
@Transactional(rollbackFor = Exception.class)
public R<?> deleteInNurseBilling(List<AdviceBatchOpParam> paramList) {
//TODO 撤销前校验
// TODO 撤销前校验
// 诊疗ids
List<Long> activityRequestIds = Collections.emptyList();
if (paramList != null && !paramList.isEmpty()) {
@@ -220,7 +227,8 @@ public class NurseBillingAppService implements INurseBillingAppService {
* @return 住院患者医
*/
@Override
public R<?> getInNurseBillingPage(InpatientAdviceParam inpatientAdviceParam, Integer pageNo, Integer pageSize, LocalDateTime startTime, LocalDateTime endTime) {
public R<?> getInNurseBillingPage(InpatientAdviceParam inpatientAdviceParam, Integer pageNo, Integer pageSize,
LocalDateTime startTime, LocalDateTime endTime) {
// 初始化查询参数
String encounterIds = inpatientAdviceParam.getEncounterIds();
inpatientAdviceParam.setEncounterIds(null);
@@ -244,7 +252,7 @@ public class NurseBillingAppService implements INurseBillingAppService {
ParticipantType.ADMITTING_DOCTOR.getCode(), AccountType.PERSONAL_CASH_ACCOUNT.getCode(),
ChargeItemStatus.BILLABLE.getValue(), ChargeItemStatus.BILLED.getValue(),
ChargeItemStatus.REFUNDED.getValue(), EncounterClass.IMP.getValue(),
GenerateSource.NURSE_PRICING.getValue(),startTime,endTime);
GenerateSource.NURSE_PRICING.getValue(), startTime, endTime);
inpatientAdvicePage.getRecords().forEach(e -> {
// 医嘱类型
e.setTherapyEnum_enumText(EnumUtils.getInfoByValue(TherapyTimeType.class, e.getTherapyEnum()));
@@ -471,7 +479,7 @@ public class NurseBillingAppService implements INurseBillingAppService {
deviceRequest.setQuantity(adviceDto.getQuantity()); // 耗材请求数量
deviceRequest.setUnitCode(adviceDto.getUnitCode()); // 单位编码(如"个"、"盒"
deviceRequest.setLotNumber(adviceDto.getLotNumber()); // 产品批号(可选,耗材批次管理)
deviceRequest.setStatusEnum(RequestStatus.ACTIVE.getValue()); // 状态:激活(划价即生效)
deviceRequest.setStatusEnum(RequestStatus.COMPLETED.getValue()); // 状态:已完成(划价即生效)
deviceRequest.setDeviceDefId(adviceDto.getAdviceDefinitionId()); // 耗材定义ID关联ADM_DEVICE_DEFINITION
// deviceRequest.setDeviceSpecifications(null)//器材规格
deviceRequest.setRequesterId(
@@ -579,7 +587,7 @@ public class NurseBillingAppService implements INurseBillingAppService {
activityChildrenJsonParams.setAccountId(activityDto.getAccountId()); // 患者账户ID关联费用结算
activityChildrenJsonParams.setChargeItemId(chargeItemId); // 父费用项ID关联子项费用
activityChildrenJsonParams.setParentId(serviceRequest.getId()); // 父诊疗请求ID关联子项与父项
activityChildrenJsonParams.setEncounterDiagnosisId(serviceRequest.getEncounterDiagnosisId());
// 调用工具类处理子项:递归生成子项的请求、执行记录、费用项
adviceUtils.handleActivityChild(childrenJson, organizationId, activityChildrenJsonParams);
}
@@ -740,4 +748,68 @@ public class NurseBillingAppService implements INurseBillingAppService {
return null;
}
/**
* 费用明细查询
*
* @param costDetailSearchParam 查询条件
* @param request request请求
* @return 住院患者费用明细
*/
@Override
public R<List<CostDetailDto>> getCostDetails(CostDetailSearchParam costDetailSearchParam,
HttpServletRequest request) {
List<Long> encounterIds = costDetailSearchParam.getEncounterIds();
if (encounterIds == null || encounterIds.isEmpty()) {
return R.fail("就诊ID不能为空");
}
costDetailSearchParam.setEncounterIds(null);
QueryWrapper<CostDetailSearchParam> queryWrapper =
HisQueryUtils.buildQueryWrapper(costDetailSearchParam, null, null, request);
queryWrapper.in(CommonConstants.FieldName.EncounterId, encounterIds);
List<CostDetailDto> list = iChargeItemService.getCostDetails(queryWrapper, ChargeItemStatus.BILLABLE.getValue(),
ChargeItemStatus.BILLED.getValue(), ChargeItemStatus.REFUNDED.getValue(),
EncounterActivityStatus.ACTIVE.getValue(), LocationForm.BED.getValue(),
ParticipantType.ADMITTING_DOCTOR.getCode(), AccountType.PERSONAL_CASH_ACCOUNT.getCode());
return R.ok(list);
}
/**
*
* @param costDetailSearchParam 查询条件
* @param request request请求
* @param response response响应
*/
@Override
public void makeExcelFile(CostDetailSearchParam costDetailSearchParam, HttpServletRequest request,
HttpServletResponse response) {
R<List<CostDetailDto>> costDetails = getCostDetails(costDetailSearchParam, request);
if (costDetails.getData() != null) {
List<CostDetailDto> dataList = costDetails.getData();
// 设置执行科室
dataList.forEach(costDetailDto -> {
Long orgId = costDetailDto.getOrgId();
costDetailDto.setOrgName(organizationService.getById(orgId).getName());
});
// 根据EncounterId分组
Map<Long, List<CostDetailDto>> map =
dataList.stream().collect(Collectors.groupingBy(CostDetailDto::getEncounterId));
map.forEach((key, value) -> {
// 新加一条小计
value.add(new CostDetailDto().setEncounterId(key).setChargeName("小计").setTotalPrice(
value.stream().map(CostDetailDto::getTotalPrice).reduce(BigDecimal.ZERO, BigDecimal::add)));
});
// 收集要导出的数据
List<CostDetailExcelOutDto> excelOutList =
map.entrySet().stream().map(entry -> new CostDetailExcelOutDto(entry.getKey(), entry.getValue(),
entry.getValue().get(0).getPatientName())).toList();
try {
// 住院记账-费用明细 导出
NewExcelUtil<CostDetailExcelOutDto> util = new NewExcelUtil<>(CostDetailExcelOutDto.class);
util.exportExcel(response, excelOutList, CommonConstants.SheetName.COST_DETAILS);
} catch (Exception e) {
throw new NonCaptureException(StringUtils.format("导出excel失败"), e);
}
}
}
}

View File

@@ -30,6 +30,16 @@ public class MedicineSummaryController {
@Resource
public IMedicineSummaryAppService medicineSummaryAppService;
/**
* 药品汇总单初始化
*
* @return 初始化信息
*/
@GetMapping(value = "/summary-init")
public R<?> getMedicineSummaryInit() {
return medicineSummaryAppService.getMedicineSummaryInit();
}
/**
* 查询发药单信息
*

View File

@@ -4,11 +4,14 @@ import java.time.LocalDateTime;
import java.util.List;
import javax.annotation.Resource;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import org.springframework.format.annotation.DateTimeFormat;
import org.springframework.web.bind.annotation.*;
import com.core.common.core.domain.R;
import com.openhis.administration.dto.CostDetailSearchParam;
import com.openhis.web.inhospitalnursestation.appservice.INurseBillingAppService;
import com.openhis.web.inhospitalnursestation.dto.InpatientAdviceParam;
import com.openhis.web.regdoctorstation.dto.AdviceBatchOpParam;
@@ -65,6 +68,31 @@ public class NurseBillingController {
endTime);
}
/**
* 费用明细查询
*
* @param costDetailSearchParam 查询条件
* @param request request请求
* @return 住院患者费用明细
*/
@GetMapping("/cost-detail")
public R<?> getCostDetails(CostDetailSearchParam costDetailSearchParam, HttpServletRequest request) {
return iNurseBillingAppService.getCostDetails(costDetailSearchParam, request);
}
/**
* 费用明细导出
*
* @param costDetailSearchParam 查询条件
* @param request request请求
* @param response response响应
*/
@GetMapping("/excel-out")
public void makeExcelFile(CostDetailSearchParam costDetailSearchParam, HttpServletRequest request,
HttpServletResponse response) {
iNurseBillingAppService.makeExcelFile(costDetailSearchParam, request, response);
}
/*
* 医嘱计费添加 诊疗 耗材
*/

View File

@@ -0,0 +1,38 @@
package com.openhis.web.inhospitalnursestation.dto;
import java.util.List;
import com.core.common.annotation.Excel;
import com.openhis.administration.dto.CostDetailDto;
import lombok.AllArgsConstructor;
import lombok.Data;
import lombok.NoArgsConstructor;
import lombok.experimental.Accessors;
/**
* 住院记账-费用明细导出专用DTO
*
* @author swb
* @date 2025/12/19
*/
@Data
@NoArgsConstructor
@AllArgsConstructor
@Accessors(chain = true)
public class CostDetailExcelOutDto {
/**
* 就诊ID
*/
private Long encounterId;
/**
* 费用明细列表
*/
@Excel()
private List<CostDetailDto> data;
/**
* 患者姓名
*/
@Excel(name = "姓名", sort = 1, needMerge = true)
private String name;
}

View File

@@ -45,4 +45,7 @@ public class DispenseFormSearchParam implements Serializable {
/** 汇总人id */
@JsonSerialize(using = ToStringSerializer.class)
private Long applicantId;
/** 发放状态 */
private Integer statusEnum;
}

View File

@@ -1,14 +1,16 @@
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;
import java.math.BigDecimal;
import com.fasterxml.jackson.databind.annotation.JsonSerialize;
import com.fasterxml.jackson.databind.ser.std.ToStringSerializer;
import lombok.Data;
import lombok.experimental.Accessors;
/**
就诊消费 dto
* 就诊消费 dto
*
* @author: 1x1
* @date: 2025/11/19 13:50
*/
@@ -17,18 +19,19 @@ import java.math.BigDecimal;
@Accessors(chain = true)
public class EncounterAccountDto {
//就诊ID
// 就诊ID
@JsonSerialize(using = ToStringSerializer.class)
private Long encounterId;
//预交金
// 预交金
private BigDecimal advanceAmount;
//总额
// 总额
private BigDecimal totalAmount;
//余额
// 余额
private BigDecimal balanceAmount;
// 险种类型
private String insutype;
}

View File

@@ -48,13 +48,13 @@ public interface MedicineSummaryAppMapper {
* @param page 分页信息
* @param queryWrapper 查询条件
* @param completed 发药状态:已完成
* @param inProgress 发药状态:待
* @param preparation 发药状态:待
* @param summaryDispense 单据类型:汇总发药
* @return 汇总单列表
*/
Page<MedicineSummaryFormDto> selectMedicineSummaryFormPage(@Param("page") Page<MedicineSummaryFormDto> page,
@Param(Constants.WRAPPER) QueryWrapper<DispenseFormSearchParam> queryWrapper,
@Param("completed") Integer completed, @Param("inProgress") Integer inProgress,
@Param("completed") Integer completed, @Param("preparation") Integer preparation,
@Param("summaryDispense") Integer summaryDispense);
/**

View File

@@ -1,60 +0,0 @@
package com.openhis.web.inpatientmanage.appservice;
import javax.servlet.http.HttpServletRequest;
import org.springframework.web.bind.annotation.RequestParam;
import com.core.common.core.domain.R;
import com.openhis.web.inpatientmanage.dto.AdmissionSearchParam;
import com.openhis.web.inpatientmanage.dto.AdmissionUpDto;
/**
* 住院登记 应用实现
*
* @author liuhr
* @since 2025/04/07
*/
public interface IAdmissionAppService {
/**
* 病获取住院信息初期数据列表
*
* @return 住院信息初期数据列表
*/
R<?> getAdmissionInfoInit();
/**
* 获取住院信息 分页显示
*
* @param admissionSearchParam 查询参数
* @param searchKey 模糊查询
* @param pageNo 当前页码
* @param pageSize 查询条数
* @return 住院信息
*/
R<?> getAdmissionInfoPage(AdmissionSearchParam admissionSearchParam, String searchKey, Integer pageNo,
Integer pageSize, HttpServletRequest request);
/**
* 住院无档登记
*
* @param admissionUpDto 住院登记信息
*/
R<?> addAdmissionInfo(AdmissionUpDto admissionUpDto);
/**
* 登记
*
* @param admissionUpDto 住院登记信息
*/
R<?> editAdmissionInfo(AdmissionUpDto admissionUpDto);
/**
* 住院登记详细查询
*
* @param id 查询条件
* @return 住院登记详细查询结果
*/
R<?> getAdmissionOne(@RequestParam Long id);
}

View File

@@ -1,268 +0,0 @@
package com.openhis.web.inpatientmanage.appservice.impl;
import java.util.Arrays;
import java.util.HashSet;
import java.util.List;
import java.util.stream.Collectors;
import java.util.stream.Stream;
import javax.annotation.Resource;
import javax.servlet.http.HttpServletRequest;
import org.springframework.stereotype.Service;
import org.springframework.web.bind.annotation.RequestParam;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.core.common.core.domain.R;
import com.core.common.utils.MessageUtils;
import com.core.common.utils.SecurityUtils;
import com.openhis.administration.domain.Account;
import com.openhis.administration.domain.Encounter;
import com.openhis.administration.domain.EncounterLocation;
import com.openhis.administration.service.IAccountService;
import com.openhis.administration.service.IEncounterLocationService;
import com.openhis.administration.service.IEncounterService;
import com.openhis.common.constant.CommonConstants;
import com.openhis.common.constant.PromptMsgConstant;
import com.openhis.common.enums.*;
import com.openhis.common.utils.EnumUtils;
import com.openhis.common.utils.HisQueryUtils;
import com.openhis.web.inpatientmanage.appservice.IAdmissionAppService;
import com.openhis.web.inpatientmanage.dto.AdmissionDto;
import com.openhis.web.inpatientmanage.dto.AdmissionInitPageDto;
import com.openhis.web.inpatientmanage.dto.AdmissionSearchParam;
import com.openhis.web.inpatientmanage.dto.AdmissionUpDto;
import com.openhis.web.inpatientmanage.mapper.AdmissionMapper;
import com.openhis.web.patientmanage.appservice.IPatientInformationService;
import com.openhis.web.patientmanage.dto.PatientInformationDto;
/**
* 住院管理 实现类
*
* @author liuhr
* @since 2025/04/07
*/
@Service
public class AdmissionAppServiceImpl implements IAdmissionAppService {
@Resource
private AdmissionMapper admissionMapper;
@Resource
private IPatientInformationService patientInformationService;
@Resource
private IEncounterService encounterService;
@Resource
private IEncounterLocationService encounterLocationService;
@Resource
private IAccountService accountService;
/**
* 病获取住院信息初期数据列表
*
* @return 住院信息初期数据列表
*/
@Override
public R<?> getAdmissionInfoInit() {
AdmissionInitPageDto initDto = new AdmissionInitPageDto();
// 入院类型列表
List<AdmissionInitPageDto.statusEnumOption> statusEnumOptions1 = Stream.of(AdmissionType.values())
.map(status -> new AdmissionInitPageDto.statusEnumOption(status.getValue(), status.getInfo()))
.collect(Collectors.toList());
initDto.setAdmissionTypeList(statusEnumOptions1);
// 入院方式列表
List<AdmissionInitPageDto.statusEnumOption> statusEnumOptions2 = Stream.of(AdmissionMethod.values())
.map(status -> new AdmissionInitPageDto.statusEnumOption(status.getValue(), status.getInfo()))
.collect(Collectors.toList());
initDto.setAdmissionMethodList(statusEnumOptions2);
// 优先级编码列表:患者病情下拉选
List<AdmissionInitPageDto.statusEnumOption> statusEnumOptions3 = Stream.of(PriorityLevel.values())
.map(status -> new AdmissionInitPageDto.statusEnumOption(status.getValue(), status.getInfo()))
.collect(Collectors.toList());
initDto.setPriorityEnumList(statusEnumOptions3);
return R.ok(initDto);
}
/**
* 获取住院信息 分页显示
*
* @param admissionSearchParam 查询参数
* @param searchKey 模糊查询
* @param pageNo 当前页码
* @param pageSize 查询条数
* @return 住院信息
*/
@Override
public R<?> getAdmissionInfoPage(AdmissionSearchParam admissionSearchParam, String searchKey, Integer pageNo,
Integer pageSize, HttpServletRequest request) {
// 构建查询条件
QueryWrapper<AdmissionDto> queryWrapper = HisQueryUtils.buildQueryWrapper(admissionSearchParam, searchKey,
new HashSet<>(Arrays.asList(CommonConstants.FieldName.Name, CommonConstants.FieldName.PyStr,
CommonConstants.FieldName.WbStr)),
request);
// 分页查询,查询住院
IPage<AdmissionDto> admissionInfoPage = admissionMapper.getPage(new Page<>(pageNo, pageSize),
EncounterClass.AMB.getValue(), LocationForm.WARD.getValue(), queryWrapper);
admissionInfoPage.getRecords().forEach(e -> {
// 性别枚举类回显赋值
e.setGenderEnum_enumText(EnumUtils.getInfoByValue(AdministrativeGender.class, e.getGenderEnum()));
// 计算年龄
// e.setAgeString(AgeCalculatorUtil.getAge(e.getBirthDate()));
});
// 返回【住院信息列表DTO】分页
return R.ok(admissionInfoPage);
}
/**
* 住院无档登记
*
* @param admissionUpDto 住院登记信息
*/
@Override
public R<?> addAdmissionInfo(AdmissionUpDto admissionUpDto) {
// 1.添加病人信息
PatientInformationDto patientInformationDto = convertToPatientInformationDto(admissionUpDto);
R<?> addPatientResult = patientInformationService.addPatient(patientInformationDto);
// 检查返回值的状态码
boolean insertPatientSuccess = (addPatientResult.getCode() == 200);
// 2.添加就诊信息,3.添加就诊账户,4.添加就诊病区
admissionUpDto.setYbClassEnum(EncounterYbClass.ORDINARY_HOSPITALIZATION.getValue());
boolean encounterLocationAndAccountSuccess = handleEncounterLocationAccount(admissionUpDto);
if (insertPatientSuccess && encounterLocationAndAccountSuccess) {
return R.ok(null, MessageUtils.createMessage(PromptMsgConstant.Common.M00001, new Object[] {"住院无档登记"}));
} else {
return R.fail(MessageUtils.createMessage(PromptMsgConstant.Common.M00003, null));
}
}
/**
* 登记
*
* @param admissionUpDto 住院登记信息
*/
@Override
public R<?> editAdmissionInfo(AdmissionUpDto admissionUpDto) {
// 1.修改病人信息
PatientInformationDto patientInformationDto = convertToPatientInformationDto(admissionUpDto);
R<?> editPatientResult = patientInformationService.editPatient(patientInformationDto);
// 检查返回值的状态码
boolean updatePatientSuccess = (editPatientResult.getCode() == 200);
// 2.修改就诊信息,3.添加就诊账户,4.添加就诊病区
boolean encounterLocationAndAccountSuccess = handleEncounterLocationAccount(admissionUpDto);
if (updatePatientSuccess && encounterLocationAndAccountSuccess) {
return R.ok(null, MessageUtils.createMessage(PromptMsgConstant.Common.M00002, new Object[] {"住院登记"}));
} else {
return R.fail(MessageUtils.createMessage(PromptMsgConstant.Common.M00007, null));
}
}
/**
* 住院登记,添加就诊账户和就诊病区
*
* @param admissionUpDto 住院登记信息
* @return 住院登记详细查询结果
*/
public boolean handleEncounterLocationAccount(AdmissionUpDto admissionUpDto) {
// 2.修改或者插入就诊信息
Encounter encounter = new Encounter();
encounter.setId(admissionUpDto.getId()).setPatientId(admissionUpDto.getPatientId())
.setStatusEnum(EncounterStatus.IN_PROGRESS.getValue()).setOrganizationId(admissionUpDto.getOrganizationId())
.setAdmitSourceCode(admissionUpDto.getAdmitSourceCode()).setInWayCode(admissionUpDto.getInWayCode())
.setStartTime(admissionUpDto.getStartTime()).setClassEnum(EncounterClass.IMP.getValue())
.setPriorityEnum(admissionUpDto.getPriorityEnum()).setYbClassEnum(admissionUpDto.getYbClassEnum())
.setSubjectStatusEnum(EncounterSubjectStatus.PLANNED.getValue());
boolean encounterSuccess = encounterService.saveOrUpdateEncounter(encounter);
// 3.添加就诊账户account
Account account = new Account();
account.setName(admissionUpDto.getName()).setPatientId(admissionUpDto.getPatientId())
.setEncounterId(admissionUpDto.getId())
// 账户状态是有效的
.setStatusEnum(AccountStatus.ACTIVE.getValue())
// 结账状态是可用的
.setBillingStatusEnum(AccountBillingStatus.OPEN.getValue());
boolean updateAccountSuccess = accountService.saveOrUpdateAccount(account);
// 4.添加就诊病区location
EncounterLocation encounterLocation = new EncounterLocation();
encounterLocation.setLocationId(admissionUpDto.getWardLocationId()).setEncounterId(admissionUpDto.getId())
.setFormEnum(LocationForm.WARD.getValue()).setStartTime(admissionUpDto.getStartTime())
.setStatusEnum(EncounterActivityStatus.ACTIVE.getValue());
boolean encounterLocationSuccess = encounterLocationService.saveOrUpdateEncounterLocation(encounterLocation);
return encounterSuccess && updateAccountSuccess && encounterLocationSuccess;
}
/**
* 住院登记详细查询
*
* @param id 就诊ID
* @return 住院登记详细查询结果
*/
@Override
public R<?> getAdmissionOne(@RequestParam Long id) {
// 获取租户ID
Integer tenantId = SecurityUtils.getLoginUser().getTenantId();
// 根据ID查询 住院登记详细
AdmissionUpDto admissionUpDto = admissionMapper.getAdmissionOne(EncounterClass.IMP.getValue(),
EncounterStatus.DISCHARGED.getValue(), LocationForm.BED.getValue(), LocationForm.WARD.getValue(),
ParticipantType.ADMITTER.getCode(), LocationBedStatus.O.getValue(), id, tenantId);
// 查询患者病情站诊断
// List<String> descriptionList = nurseStationPendAdmAppMapper.getDescriptionList(id);
// 诊断病情拼接
// if (descriptionList != null && !descriptionList.isEmpty()) {
// admissionUpDto.setDescriptions(String.join(CommonConstants.Common.COMMA, descriptionList));
// }
return R.ok(admissionUpDto);
}
/**
* 将 AdmissionUpDto 的字段值手动设置到 PatientInformationDto 中
*
* @param admissionUpDto 源对象
* @return 目标对象
*/
public PatientInformationDto convertToPatientInformationDto(AdmissionUpDto admissionUpDto) {
return new PatientInformationDto().setId(admissionUpDto.getPatientId()).setName(admissionUpDto.getName())
.setGenderEnum(admissionUpDto.getGenderEnum()).setBirthDate(admissionUpDto.getBirthDate())
.setMaritalStatusEnum(admissionUpDto.getMaritalStatusEnum()).setPrfsEnum(admissionUpDto.getPrfsEnum())
.setPhone(admissionUpDto.getPhone()).setAddress(admissionUpDto.getAddress())
.setNationalityCode(admissionUpDto.getNationalityCode()).setIdCard(admissionUpDto.getIdCard())
.setPyStr(admissionUpDto.getPyStr()).setWbStr(admissionUpDto.getWbStr())
.setWorkCompany(admissionUpDto.getWorkCompany()).setNativePlace(admissionUpDto.getNativePlace())
.setCountryCode(admissionUpDto.getCountryCode()).setLinkName(admissionUpDto.getLinkName())
.setLinkRelationCode(admissionUpDto.getLinkRelationCode()).setLinkTelcom(admissionUpDto.getLinkTelcom())
.setOrganizationId(admissionUpDto.getOrganizationId());
}
}

View File

@@ -1,90 +0,0 @@
package com.openhis.web.inpatientmanage.controller;
import javax.annotation.Resource;
import javax.servlet.http.HttpServletRequest;
import org.springframework.validation.annotation.Validated;
import org.springframework.web.bind.annotation.*;
import com.core.common.core.domain.R;
import com.openhis.web.inpatientmanage.appservice.IAdmissionAppService;
import com.openhis.web.inpatientmanage.dto.AdmissionSearchParam;
import com.openhis.web.inpatientmanage.dto.AdmissionUpDto;
import lombok.AllArgsConstructor;
import lombok.extern.slf4j.Slf4j;
@RestController
@RequestMapping("/inpatient-manage")
@Slf4j
@AllArgsConstructor
public class AdmissionController {
@Resource
private IAdmissionAppService admissionAppService;
/**
* 获取住院信息初期数据列表
*
* @return 住院信息初期数据列表
*/
@GetMapping("/init")
public R<?> getAdmissionInfoInit() {
return admissionAppService.getAdmissionInfoInit();
}
/**
* 获取住院信息 分页显示
*
* @param admissionSearchParam 查询参数
* @param searchKey 模糊查询
* @param pageNo 当前页码
* @param pageSize 查询条数
* @return 住院信息
*/
@GetMapping("/admission-page")
R<?> getAdmissionInfoPage(AdmissionSearchParam admissionSearchParam,
@RequestParam(value = "searchKey", defaultValue = "") String searchKey,
@RequestParam(value = "pageNo", defaultValue = "1") Integer pageNo,
@RequestParam(value = "pageSize", defaultValue = "10") Integer pageSize, HttpServletRequest request) {
return admissionAppService.getAdmissionInfoPage(admissionSearchParam, searchKey, pageNo, pageSize, request);
}
/**
* 住院无档登记
*
* @param admissionUpDto 住院登记详细信息
*/
@PostMapping("/admission-information")
public R<?> addAdmissionInfo(@Validated @RequestBody AdmissionUpDto admissionUpDto) {
return admissionAppService.addAdmissionInfo(admissionUpDto);
}
/**
* 登记
*
* @param admissionUpDto 住院登记详细信息
*/
@PutMapping("/admission-information")
public R<?> editAdmissionInfo(@Validated @RequestBody AdmissionUpDto admissionUpDto) {
// 调用服务层更新病人信息
return admissionAppService.editAdmissionInfo(admissionUpDto);
}
/**
* 根据id查询登记详情
*
* @param id 就诊ID
* @return 登记详情
*/
@GetMapping("/admission-one")
public R<?> getDeviceOne(@RequestParam Long id) {
return admissionAppService.getAdmissionOne(id);
}
}

View File

@@ -1,102 +0,0 @@
package com.openhis.web.inpatientmanage.dto;
import java.util.Date;
import com.fasterxml.jackson.annotation.JsonFormat;
import com.fasterxml.jackson.databind.annotation.JsonSerialize;
import com.fasterxml.jackson.databind.ser.std.ToStringSerializer;
import com.openhis.common.annotation.Dict;
import lombok.Data;
import lombok.experimental.Accessors;
/**
* 住院登记信息
*
* @author liuhr
* @since 2025/04/07
*/
@Data
@Accessors(chain = true)
public class AdmissionDto {
/** ID */
@JsonSerialize(using = ToStringSerializer.class)
private Long id;
/** 患者ID */
@JsonSerialize(using = ToStringSerializer.class)
private Long patientId;
/** 群组ID */
@JsonSerialize(using = ToStringSerializer.class)
private Long groupId;
/** 就诊编码 */
private String encounterBusNo;
/** 状态编码 */
private Integer statusEnum;
/** 类别编码 */
private Integer classEnum;
/** 类别医保编码 */
private Integer ybClassEnum;
/** 机构id(科室) */
@JsonSerialize(using = ToStringSerializer.class)
@Dict(dictTable = "adm_organization", dictCode = "id", dictText = "name")
private Long organizationId;
private String organizationId_dictText;
/** 入院类型 */
@Dict(dictCode = "admit_source_code")
private String admitSourceCode;
private String admitSourceCode_dictText;
/** 入院方式 */
@Dict(dictCode = "in_way_code")
private String inWayCode;
private String inWayCode_dictText;
/** 患者姓名 */
private String name;
/** 患者院内编码/病历号 */
private String patientBusNo;
/** 性别编码 */
private Integer genderEnum;
private String genderEnum_enumText;
/** 生日 */
@JsonFormat(shape = JsonFormat.Shape.STRING, pattern = "yyyy-MM-dd HH:mm:ss")
private Date birthDate;
/** 病人年龄 */
private String ageString;
/** 身份证号 */
private String idCard;
/** 拼音码 */
private String pyStr;
/** 五笔码 */
private String wbStr;
/** 入院病区 */
@JsonSerialize(using = ToStringSerializer.class)
@Dict(dictTable = "adm_location", dictCode = "id", dictText = "name")
private Long wardLocationId;
private String wardLocationId_dictText;
/** 登记员 */
private String createBy;
/** 创建时间 */
@JsonFormat(shape = JsonFormat.Shape.STRING, pattern = "yyyy-MM-dd HH:mm:ss")
private Date createTime;
}

View File

@@ -1,42 +0,0 @@
package com.openhis.web.inpatientmanage.dto;
import lombok.Data;
import lombok.experimental.Accessors;
import java.util.List;
/**
* 住院登记初始化页面信息
*
* @author liuhr
* @since 2025/04/07
*/
@Data
@Accessors(chain = true)
public class AdmissionInitPageDto {
//获取入院类型列表
private List<statusEnumOption> admissionTypeList;
//获取入院方式列表
private List<statusEnumOption> admissionMethodList;
//优先级编码列表
private List<statusEnumOption> priorityEnumList;
/**
* 状态
*/
@Data
public static class statusEnumOption {
private Integer value;
private String info;
public statusEnumOption(Integer value, String info) {
this.value = value;
this.info = info;
}
}
}

View File

@@ -1,17 +0,0 @@
package com.openhis.web.inpatientmanage.dto;
import lombok.Data;
/**
* 住院登记查询参数
*
* @author liuhr
* @since 2025/04/08
*/
@Data
public class AdmissionSearchParam {
/** 状态编码 */
private Integer statusEnum;
}

View File

@@ -1,179 +0,0 @@
package com.openhis.web.inpatientmanage.dto;
import java.util.Date;
import javax.validation.constraints.NotBlank;
import javax.validation.constraints.NotNull;
import javax.validation.constraints.Pattern;
import javax.validation.constraints.Size;
import com.fasterxml.jackson.annotation.JsonFormat;
import com.fasterxml.jackson.databind.annotation.JsonSerialize;
import com.fasterxml.jackson.databind.ser.std.ToStringSerializer;
import com.openhis.common.annotation.Dict;
import lombok.Data;
import lombok.experimental.Accessors;
/**
* 住院登记信息
*
* @author liuhr
* @since 2025/04/07
*/
@Data
@Accessors(chain = true)
public class AdmissionUpDto {
/** ID */
@JsonSerialize(using = ToStringSerializer.class)
@NotNull(message = "就诊ID不能为空")
private Long id;
/** 患者ID */
@JsonSerialize(using = ToStringSerializer.class)
private Long patientId;
/** 群组ID */
@JsonSerialize(using = ToStringSerializer.class)
private Long groupId;
/** 就诊编码 */
private String encounterBusNo;
/** 状态编码 */
private Integer statusEnum;
private String statusEnum_enumText;
/** 类别编码 */
private Integer classEnum;
/** 类别医保编码 */
private Integer ybClassEnum;
private String ybClassEnum_enumText;
/** 优先级编码 */
private Integer priorityEnum;
private String priorityEnum_enumText;
/** 分类编码 */
private Integer typeEnum;
/** 服务ID */
@JsonSerialize(using = ToStringSerializer.class)
private Long serviceTypeId;
/** 就诊对象状态 */
private Integer subjectStatusEnum;
/** 开始时间 */
@JsonFormat(shape = JsonFormat.Shape.STRING, pattern = "yyyy-MM-dd HH:mm:ss")
private Date startTime;
/** 结束时间 */
@JsonFormat(shape = JsonFormat.Shape.STRING, pattern = "yyyy-MM-dd HH:mm:ss")
private Date endTime;
/** 机构id(科室) */
@JsonSerialize(using = ToStringSerializer.class)
@Dict(dictTable = "adm_organization", dictCode = "id", dictText = "name")
private Long organizationId;
private String organizationId_dictText;
/** 入院类型 */
@Dict(dictCode = "admit_source_code")
private String admitSourceCode;
private String admitSourceCode_dictText;
/** 入院方式 */
@Dict(dictCode = "in_way_code")
private String inWayCode;
private String inWayCode_dictText;
/** 住院次数 */
private Integer hospitalizationCount;
/** 患者姓名 */
private String name;
/** 患者院内编码/病历号 */
private String patientBusNo;
/** 性别编码 */
private Integer genderEnum;
private String genderEnum_enumText;
/** 生日 */
@JsonFormat(shape = JsonFormat.Shape.STRING, pattern = "yyyy-MM-dd HH:mm:ss")
private Date birthDate;
/** 婚姻状态 */
private Integer maritalStatusEnum;
private String maritalStatusEnum_enumText;
/** 职业编码 */
private Integer prfsEnum;
private String prfsEnum_enumText;
/** 电话 */
@Size(min = 11, max = 11, message = "电话长度必须为11位")
@Pattern(regexp = "^1[3-9]\\d{9}$", message = "电话格式不正确")
private String phone;
/** 地址 */
private String address;
/** 民族 */
private String nationalityCode;
/** 身份证号 */
@NotBlank(message = "身份证号不能为空")
@Size(min = 18, max = 18, message = "身份证号必须是18位")
@Pattern(regexp = "^[0-9Xx]{18}$", message = "身份证号格式不正确")
private String idCard;
/** 拼音码 */
private String pyStr;
/** 五笔码 */
private String wbStr;
/** 工作单位 */
private String workCompany;
/** 籍贯 */
private String nativePlace;
/** 国家编码 */
private String countryCode;
/** 联系人 */
private String linkName;
/** 联系人关系 */
private Integer linkRelationCode;
/** 联系人电话 */
@Size(min = 11, max = 11, message = "电话长度必须为11位")
@Pattern(regexp = "^1[3-9]\\d{9}$", message = "电话格式不正确")
private String linkTelcom;
/** 病人年龄 */
private String ageString;
/** 门诊诊断 */
private String descriptions;
/** 接诊医生 */
private String doctorName;
/** 入院病区 */
@JsonSerialize(using = ToStringSerializer.class)
@Dict(dictTable = "adm_location", dictCode = "id", dictText = "name")
private Long wardLocationId;
private String wardLocationId_dictText;
/** 床位数 */
private String bedCount;
}

View File

@@ -1,50 +0,0 @@
package com.openhis.web.inpatientmanage.mapper;
import org.apache.ibatis.annotations.Param;
import org.springframework.stereotype.Repository;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.core.toolkit.Constants;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.openhis.web.inpatientmanage.dto.AdmissionDto;
import com.openhis.web.inpatientmanage.dto.AdmissionUpDto;
/**
* 住院登记
*
* @author liuhr
* @since 2025/04/08
*/
@Repository
public interface AdmissionMapper {
/**
* 住院登记信息分页查询
*
* @param page 分页
* @param classEnum 类别编码(1住院类型)
* @param formEnum 类别编码(1住院类型)
* @param queryWrapper 查询条件
* @return 住院登记信息
*/
IPage<AdmissionDto> getPage(@Param("page") Page<AdmissionDto> page, @Param("classEnum") Integer classEnum,
@Param("formEnum") Integer formEnum, @Param(Constants.WRAPPER) QueryWrapper<AdmissionDto> queryWrapper);
/**
* 住院登记详情
*
* @param classEnum 类别编码(1:住院类型)
* @param statusEnum 状态编码(4:出院状态)
* @param bedForm 床:8
* @param wardForm 病区:4
* @param operational 床位状态(4:占用)
* @param typeCode 就诊参与者身份类型 (1:接诊医生)
* @param id 就诊ID
* @param tenantId 租户
* @return 住院登记详情
*/
AdmissionUpDto getAdmissionOne(@Param("classEnum") Integer classEnum, @Param("statusEnum") Integer statusEnum,
@Param("bedForm") Integer bedForm, @Param("wardForm") Integer wardForm, @Param("typeCode") String typeCode,
@Param("operational") Integer operational, @Param("id") Long id, @Param("tenantId") Integer tenantId);
}

View File

@@ -8,6 +8,8 @@ import com.core.common.core.domain.R;
import com.openhis.web.inventorymanage.dto.ProductDetailPageDto;
import com.openhis.web.inventorymanage.dto.ProductDetailSearchParam;
import java.util.List;
/**
* 库存商品明细 appService
*
@@ -66,18 +68,18 @@ public interface IProductDetailAppService {
/**
* 操作:停供
*
* @param inventoryId 库存项目管理ID
* @param inventoryIdList 库存项目管理ID
* @return 操作结果
*/
R<?> stopSupplyById(Long inventoryId);
R<?> stopSupplyById(List<Long> inventoryIdList);
/**
* 操作:取消停供
*
* @param inventoryId 库存项目管理ID
* @param inventoryIdList 库存项目管理ID
* @return 操作结果
*/
R<?> cancelSupplyById(Long inventoryId);
R<?> cancelSupplyById(List<Long> inventoryIdList);
/**
* 库存明细表导出
@@ -89,4 +91,6 @@ public interface IProductDetailAppService {
*/
void makeExcelFile(ProductDetailSearchParam productDetailSearchParam, String searchKey, HttpServletRequest request,
HttpServletResponse response);
void exportExcel(ProductDetailSearchParam productDetailSearchParam, Integer pageNo, Integer pageSize, String searchKey, HttpServletRequest request, HttpServletResponse response);
}

View File

@@ -107,4 +107,15 @@ public interface IPurchaseInventoryAppService {
* @param response 响应数据
*/
void makeExcelFile(String busNo, HttpServletResponse response);
/**
* 入库单据列表导出
*
* @param inventorySearchParam 查询条件
* @param pageNo 当前页码
* @param pageSize 查询条数
* @param searchKey 模糊查询关键字
* @param request 请求数据
* @param response 响应数据
*/
void exportExcel(InventorySearchParam inventorySearchParam, Integer pageNo, Integer pageSize, String searchKey, HttpServletRequest request, HttpServletResponse response);
}

View File

@@ -107,4 +107,16 @@ public interface IRequisitionIssueAppService {
* @param response 响应数据
*/
void makeExcelFile(String busNo, HttpServletResponse response);
/**
* 领用出库单导出
*
* @param issueSearchParam 查询条件
* @param pageNo 当前页码
* @param pageSize 查询条数
* @param searchKey 模糊查询关键字
* @param request 请求数据
* @Param response 响应数据
*/
void exportExcel(IssueSearchParam issueSearchParam, Integer pageNo, Integer pageSize, String searchKey, HttpServletRequest request, HttpServletResponse response);
}

View File

@@ -66,4 +66,12 @@ public interface ITraceNoAppService {
* @return 操作结果
*/
boolean updateTraceNoList(List<SupplyItemDetailDto> supplyItemDetailList, Integer operationType);
/**
* 根据药品追溯患者
*
* @param traceNoId 追溯码ID
* @return 患者列表
*/
R<?> tracePatient(Long traceNoId);
}

View File

@@ -10,6 +10,8 @@ import javax.annotation.Resource;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import com.core.common.utils.*;
import com.openhis.web.inventorymanage.dto.ProductTransferPageDto;
import org.springframework.stereotype.Service;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
@@ -20,10 +22,6 @@ import com.core.common.core.domain.R;
import com.core.common.core.domain.model.LoginUser;
import com.core.common.enums.TenantOptionDict;
import com.core.common.exception.NonCaptureException;
import com.core.common.utils.DateUtils;
import com.core.common.utils.MessageUtils;
import com.core.common.utils.SecurityUtils;
import com.core.common.utils.StringUtils;
import com.core.common.utils.poi.ExcelUtil;
import com.core.web.util.TenantOptionUtil;
import com.openhis.administration.domain.ChargeItemDefDetail;
@@ -337,11 +335,11 @@ public class ProductDetailAppServiceImpl extends ServiceImpl<InventoryItemMapper
/**
* 操作:停供
*
* @param inventoryId 库存项目管理ID
* @param inventoryIdList 库存项目管理ID
* @return 操作结果
*/
@Override
public R<?> stopSupplyById(Long inventoryId) {
public R<?> stopSupplyById(List<Long> inventoryIdList) {
// 获取当前时间
Date now = DateUtils.getNowDate();
@@ -350,7 +348,7 @@ public class ProductDetailAppServiceImpl extends ServiceImpl<InventoryItemMapper
// 停供按钮压下,更新库存项目管理表的库存状态:已停供
int updateCount = baseMapper.update(null,
new LambdaUpdateWrapper<InventoryItem>().eq(InventoryItem::getId, inventoryId)
new LambdaUpdateWrapper<InventoryItem>().in(InventoryItem::getId, inventoryIdList)
.set(InventoryItem::getUpdateTime, now).set(InventoryItem::getUpdateBy, loginUser.getUserId())
.set(InventoryItem::getInventoryStatusEnum, PublicationStatus.RETIRED.getValue()));
@@ -361,11 +359,11 @@ public class ProductDetailAppServiceImpl extends ServiceImpl<InventoryItemMapper
/**
* 操作:取消停供
*
* @param inventoryId 库存项目管理ID
* @param inventoryIdList 库存项目管理ID
* @return 操作结果
*/
@Override
public R<?> cancelSupplyById(Long inventoryId) {
public R<?> cancelSupplyById(List<Long> inventoryIdList) {
// 获取当前时间
Date now = DateUtils.getNowDate();
@@ -374,7 +372,7 @@ public class ProductDetailAppServiceImpl extends ServiceImpl<InventoryItemMapper
// 取消停供按钮压下,更新库存项目管理表的库存状态:未停供
int updateCount = baseMapper.update(null,
new LambdaUpdateWrapper<InventoryItem>().eq(InventoryItem::getId, inventoryId)
new LambdaUpdateWrapper<InventoryItem>().in(InventoryItem::getId, inventoryIdList)
.set(InventoryItem::getUpdateTime, now).set(InventoryItem::getUpdateBy, loginUser.getUserId())
.set(InventoryItem::getInventoryStatusEnum, PublicationStatus.ACTIVE.getValue()));
@@ -415,29 +413,29 @@ public class ProductDetailAppServiceImpl extends ServiceImpl<InventoryItemMapper
productDetailPageDto.setQuantity_text(
productDetailPageDto.getQuantity().setScale(0, RoundingMode.HALF_UP) + minUnitCode);
// 金额字段拼接 ‘元’
// 金额字段拼接
BigDecimal purchasePrice = productDetailPageDto.getPurchasePrice();
BigDecimal salePrice = productDetailPageDto.getSalePrice();
BigDecimal totalPurchasePrice = productDetailPageDto.getTotalPurchasePrice();
BigDecimal totalSalePrice = productDetailPageDto.getTotalSalePrice();
if (salePrice != null) {
productDetailPageDto.setExcelSalePrice(
salePrice.setScale(2, RoundingMode.HALF_UP) + CommonConstants.ExcelOut.YUAN);
salePrice.setScale(2, RoundingMode.HALF_UP) + "");
}
if (purchasePrice != null) {
productDetailPageDto.setExcelPurchasePrice(
purchasePrice.setScale(2, RoundingMode.HALF_UP) + CommonConstants.ExcelOut.YUAN);
purchasePrice.setScale(2, RoundingMode.HALF_UP) + "");
}
if (totalPurchasePrice != null) {
productDetailPageDto.setExcelTotalPurchasePrice(
totalPurchasePrice.setScale(2, RoundingMode.HALF_UP) + CommonConstants.ExcelOut.YUAN);
totalPurchasePrice.setScale(2, RoundingMode.HALF_UP) + "");
}
if (totalSalePrice != null) {
productDetailPageDto.setExcelTotalSalePrice(
totalSalePrice.setScale(2, RoundingMode.HALF_UP) + CommonConstants.ExcelOut.YUAN);
totalSalePrice.setScale(2, RoundingMode.HALF_UP) + "");
}
// 判断项目类别
@@ -586,4 +584,72 @@ public class ProductDetailAppServiceImpl extends ServiceImpl<InventoryItemMapper
return R.ok(productDetailList);
}
@Override
public void exportExcel(ProductDetailSearchParam productDetailSearchParam, Integer pageNo, Integer pageSize, String searchKey, HttpServletRequest request, HttpServletResponse response) {
R<Page<ProductDetailPageDto>> result = this.getProductDetailBackupPage(productDetailSearchParam,1,100000,searchKey,request);
if (result.getData() != null){
Page<ProductDetailPageDto> pageData = result.getData();
List<ProductDetailPageDto> dataList = pageData.getRecords();
for (ProductDetailPageDto productDetailPageDto : dataList) {
// 获取单位
String unitCode = DictUtils.getDictLabel("unit_code",productDetailPageDto.getUnitCode());
String minUnitCode = DictUtils.getDictLabel("unit_code",productDetailPageDto.getMinUnitCode());
// 获取数量
BigDecimal number = productDetailPageDto.getNumber();
BigDecimal remainder = productDetailPageDto.getRemainder();
// 拼接
if (remainder.compareTo(BigDecimal.ZERO) > 0) {
productDetailPageDto.setNumber_text(number.setScale(0, RoundingMode.HALF_UP) + unitCode
+ remainder.setScale(0, RoundingMode.HALF_UP) + minUnitCode);
} else {
productDetailPageDto.setNumber_text(number.setScale(0, RoundingMode.HALF_UP) + unitCode);
}
productDetailPageDto.setQuantity_text(
productDetailPageDto.getQuantity().setScale(0, RoundingMode.HALF_UP) + minUnitCode);
// 金额字段拼接
BigDecimal purchasePrice = productDetailPageDto.getPurchasePrice();
BigDecimal salePrice = productDetailPageDto.getSalePrice();
BigDecimal totalPurchasePrice = productDetailPageDto.getTotalPurchasePrice();
BigDecimal totalSalePrice = productDetailPageDto.getTotalSalePrice();
if (salePrice != null) {
productDetailPageDto.setExcelSalePrice(
salePrice.setScale(2, RoundingMode.HALF_UP) + "");
}
if (purchasePrice != null) {
productDetailPageDto.setExcelPurchasePrice(
purchasePrice.setScale(2, RoundingMode.HALF_UP) + "");
}
if (totalPurchasePrice != null) {
productDetailPageDto.setExcelTotalPurchasePrice(
totalPurchasePrice.setScale(2, RoundingMode.HALF_UP) + "");
}
if (totalSalePrice != null) {
productDetailPageDto.setExcelTotalSalePrice(
totalSalePrice.setScale(2, RoundingMode.HALF_UP) + "");
}
// 判断项目类别
String devCategoryCodeDictText = DictUtils.getDictLabel("device_category_code",productDetailPageDto.getDevCategoryCode());
String medCategoryCodeDictText = DictUtils.getDictLabel("med_category_code",productDetailPageDto.getMedCategoryCode());
String categoryCodeDictText = StringUtils.isEmpty(devCategoryCodeDictText) ? medCategoryCodeDictText : devCategoryCodeDictText;
productDetailPageDto.setCategoryCodeDictText(categoryCodeDictText);
//剂型
String doseFormCodeDictText = DictUtils.getDictLabel("dose_form_code",productDetailPageDto.getDoseFormCode());
productDetailPageDto.setDoseFormCodeDictText(doseFormCodeDictText);
}
try {
// 导出
NewExcelUtil<ProductDetailPageDto> newExcelUtil =
new NewExcelUtil<>(ProductDetailPageDto.class);
newExcelUtil.exportExcel(response, dataList, CommonConstants.SheetName.INVENTORY_DETAIL_RECORD);
} catch (Exception e) {
throw new RuntimeException(e);
}
}
}
}

View File

@@ -3,6 +3,7 @@
*/
package com.openhis.web.inventorymanage.appservice.impl;
import java.math.BigDecimal;
import java.util.*;
import java.util.stream.Collectors;
import java.util.stream.Stream;
@@ -520,7 +521,7 @@ public class ProductTransferAppServiceImpl implements IProductTransferAppService
// 导出
NewExcelUtil<ProductTransferPageDto> newExcelUtil =
new NewExcelUtil<>(ProductTransferPageDto.class);
newExcelUtil.exportExcel(response, dataList, CommonConstants.SheetName.TRANSFER_DOCUMENT_DETAIL);
newExcelUtil.exportExcel(response, dataList, CommonConstants.SheetName.REQUISITION_DELIVERY_FORM);
} catch (Exception e) {
throw new RuntimeException(e);
}

View File

@@ -3,10 +3,9 @@
*/
package com.openhis.web.inventorymanage.appservice.impl;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.HashSet;
import java.util.List;
import java.math.BigDecimal;
import java.math.RoundingMode;
import java.util.*;
import java.util.stream.Collectors;
import java.util.stream.Stream;
@@ -14,6 +13,8 @@ import javax.annotation.Resource;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import com.openhis.administration.domain.Location;
import com.openhis.administration.service.impl.LocationServiceImpl;
import org.springframework.stereotype.Service;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
@@ -61,6 +62,9 @@ public class PurchaseInventoryAppServiceImpl implements IPurchaseInventoryAppSer
@Resource
private AssignSeqUtil assignSeqUtil;
@Resource
private LocationServiceImpl locationService;
/**
* 入库单据页面初始化
*
@@ -125,7 +129,7 @@ public class PurchaseInventoryAppServiceImpl implements IPurchaseInventoryAppSer
* @return 入库单据分页列表
*/
@Override
public R<?> getPage(InventorySearchParam inventorySearchParam, Integer pageNo, Integer pageSize, String searchKey,
public R<Page<ReceiptPageDto>> getPage(InventorySearchParam inventorySearchParam, Integer pageNo, Integer pageSize, String searchKey,
HttpServletRequest request) {
// 设置模糊查询的字段名
@@ -322,4 +326,57 @@ public class PurchaseInventoryAppServiceImpl implements IPurchaseInventoryAppSer
}
}
}
/**
* 入库单据列表导出
*
* @param inventorySearchParam 查询条件
* @param pageNo 当前页码
* @param pageSize 查询条数
* @param searchKey 模糊查询关键字
* @param request 请求数据
* @param response 响应数据
*/
@Override
public void exportExcel(InventorySearchParam inventorySearchParam, Integer pageNo, Integer pageSize, String searchKey, HttpServletRequest request, HttpServletResponse response) {
R<Page<ReceiptPageDto>> result = this.getPage(inventorySearchParam, 1, 10000, searchKey, request);
if (result != null && result.getData() != null) {
Page<ReceiptPageDto> pageData = result.getData();
List<ReceiptPageDto> dataList = pageData.getRecords();
List<Supplier> supplierList = supplierService.getList();
Map<Long, String> supplierToNameMap = supplierList.stream()
.collect(Collectors.toMap(Supplier::getId, Supplier::getName, (oldValue, newValue) -> oldValue // 冲突时保留旧值(第一个)
));
List<Practitioner> practitionerList = practitionerService.getList();
// 创建id到名字的映射
Map<Long, String> practitionerToNameMap = practitionerList.stream()
.collect(Collectors.toMap(Practitioner::getId, Practitioner::getName, (oldValue, newValue) -> oldValue // 冲突时保留旧值(第一个)
));
List<Location> locationList = locationService.getLocationList();
Map<Long, String> locationToNameMap = locationList.stream()
.collect(Collectors.toMap(Location::getId, Location::getName, (oldValue, newValue) -> oldValue // 冲突时保留旧值(第一个)
));
dataList.forEach(e -> {
// 经手人practitionerIdDictText
e.setPractitionerIdDictText(practitionerToNameMap.get(e.getPractitionerId()));
// 供应商supplierIdDictText
e.setSupplierIdDictText(supplierToNameMap.get(e.getSupplierId()));
// 目的仓库purposeLocationIdDictText
e.setPurposeLocationIdDictText(locationToNameMap.get(e.getPurposeLocationId()));
// 审批人approverIdDictText
e.setApproverIdDictText(practitionerToNameMap.get(e.getApproverId()));
// 申请人applicantIdDictText
e.setApplicantIdDictText(practitionerToNameMap.get(e.getApplicantId()));
});
try {
// 导出
NewExcelUtil<ReceiptPageDto> newExcelUtil = new NewExcelUtil<>(ReceiptPageDto.class);
newExcelUtil.hideColumn("purposeLocationIdDictText");
newExcelUtil.exportExcel(response, dataList, CommonConstants.SheetName.PURCHASE_RECEIPT_ORDER);
} catch (Exception e) {
throw new RuntimeException(e);
}
}
}
}

View File

@@ -16,6 +16,7 @@ import org.springframework.beans.factory.annotation.Autowired;
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;
@@ -864,63 +865,66 @@ public class ReceiptApprovalAppServiceImpl implements IReceiptApprovalAppService
if (!supplyItemDetailList.isEmpty()) {
// 根据项目id,产品批号源仓库id 查询源仓库库存表信息
List<InventoryItem> inventoryItemList =
inventoryItemService.list(new LambdaQueryWrapper<InventoryItem>().in(InventoryItem::getItemId,
supplyItemDetailList.stream().map(SupplyItemDetailDto::getItemId).toList()));
for (SupplyItemDetailDto supplyItemDetailDto : supplyItemDetailList) {
// 根据项目id,产品批号源仓库id 查询源仓库库存表信息
List<InventoryItem> inventoryItemList = inventoryItemService.selectInventoryByItemId(
supplyItemDetailDto.getItemId(), supplyItemDetailDto.getLotNumber(),
supplyItemDetailDto.getSourceLocationId(), SecurityUtils.getLoginUser().getTenantId());
InventoryItem inventoryItemSource = new InventoryItem();
if (!inventoryItemList.isEmpty()) {
inventoryItemSource = inventoryItemList.get(0);
// 最小数量(最小单位库存数量)
BigDecimal minQuantity = inventoryItemSource.getQuantity();
for (InventoryItem inventoryItem : inventoryItemList) {
if (inventoryItem.getItemId().equals(supplyItemDetailDto.getItemId())
&& inventoryItem.getLotNumber().equals(supplyItemDetailDto.getLotNumber())
&& inventoryItem.getLocationId().equals(supplyItemDetailDto.getSourceLocationId())) {
// 最小数量(最小单位库存数量)
BigDecimal minQuantity = inventoryItem.getQuantity();
// 供应申请的物品计量单位与包装单位相同
if (supplyItemDetailDto.getItemUnit().equals(supplyItemDetailDto.getUnitCode())) {
if (minQuantity.compareTo(supplyItemDetailDto.getItemQuantity()) < 0) {
// 库存数量不足
throw new ServiceException("操作失败,库存数量不足");
} else {
// 源仓库库存-(领用数量*拆零比)
minQuantity = minQuantity.subtract(
supplyItemDetailDto.getPartPercent().multiply(supplyItemDetailDto.getItemQuantity()));
}
} else if (supplyItemDetailDto.getItemUnit().equals(supplyItemDetailDto.getMinUnitCode())) {
if (minQuantity.compareTo(supplyItemDetailDto.getItemQuantity()) < 0) {
// 库存数量不足
throw new ServiceException("操作失败,库存数量不足");
} else {
// 供应申请的物品计量单位与最小单位相同
// 源仓库库存-领用数量
minQuantity = minQuantity.subtract(supplyItemDetailDto.getItemQuantity());
// 供应申请的物品计量单位与包装单位相同
if (supplyItemDetailDto.getItemUnit().equals(supplyItemDetailDto.getUnitCode())) {
if (minQuantity.compareTo(supplyItemDetailDto.getItemQuantity()) < 0) {
// 库存数量不足
throw new ServiceException("操作失败,库存数量不足");
} else {
// 源仓库库存-(领用数量*拆零比)
minQuantity = minQuantity.subtract(supplyItemDetailDto.getPartPercent()
.multiply(supplyItemDetailDto.getItemQuantity()));
}
} else if (supplyItemDetailDto.getItemUnit().equals(supplyItemDetailDto.getMinUnitCode())) {
if (minQuantity.compareTo(supplyItemDetailDto.getItemQuantity()) < 0) {
// 库存数量不足
throw new ServiceException("操作失败,库存数量不足");
} else {
// 供应申请的物品计量单位与最小单位相同
// 源仓库库存-领用数量
minQuantity = minQuantity.subtract(supplyItemDetailDto.getItemQuantity());
}
}
// 更新源仓库库存数量
Boolean aBoolean =
inventoryItemService.updateInventoryQuantity(inventoryItem.getId(), minQuantity, now);
if (!aBoolean) {
return R.fail(MessageUtils.createMessage(PromptMsgConstant.Common.M00007, null));
}
}
}
// 更新源仓库库存数量
Boolean aBoolean =
inventoryItemService.updateInventoryQuantity(inventoryItemSource.getId(), minQuantity, now);
if (!aBoolean) {
return R.fail(MessageUtils.createMessage(PromptMsgConstant.Common.M00007, null));
}
}
}
// 处理追溯码
traceNoAppService.addTraceNoManage(supplyItemDetailList, TraceNoStatus.OUT.getValue(),
SupplyType.ISSUE_INVENTORY.getValue());
// 返回信息
String returnMsg = null;
// 调用医保库存变更接口
String ybSwitch = SecurityUtils.getLoginUser().getOptionJson().getString(CommonConstants.Option.YB_SWITCH); // 医保开关
if (Whether.YES.getCode().equals(ybSwitch)) {
List<String> uploadFailedNoList =
this.ybInventoryIntegrated(supplyItemDetailList, YbInvChgType.OTHER_OUT, now, false);
if (!uploadFailedNoList.isEmpty()) {
returnMsg = "3502库存变更上传错误错误项目编码" + uploadFailedNoList;
}
}
}
// 处理追溯码
traceNoAppService.addTraceNoManage(supplyItemDetailList, TraceNoStatus.OUT.getValue(),
SupplyType.ISSUE_INVENTORY.getValue());
// 返回信息
String returnMsg = null;
// 调用医保库存变更接口
String ybSwitch = SecurityUtils.getLoginUser().getOptionJson().getString(CommonConstants.Option.YB_SWITCH); // 医保开关
if (Whether.YES.getCode().equals(ybSwitch)) {
List<String> uploadFailedNoList =
this.ybInventoryIntegrated(supplyItemDetailList, YbInvChgType.OTHER_OUT, now, false);
if (!uploadFailedNoList.isEmpty()) {
returnMsg = "3502库存变更上传错误错误项目编码" + uploadFailedNoList;
}
}
return R.ok(null, MessageUtils.createMessage(PromptMsgConstant.Common.M00004, null));
}
/**

View File

@@ -3,19 +3,6 @@
*/
package com.openhis.web.inventorymanage.appservice.impl;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.HashSet;
import java.util.List;
import java.util.stream.Collectors;
import java.util.stream.Stream;
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.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.core.common.core.domain.R;
@@ -34,6 +21,15 @@ import com.openhis.web.inventorymanage.dto.*;
import com.openhis.web.inventorymanage.mapper.RequisitionIssueMapper;
import com.openhis.workflow.domain.SupplyRequest;
import com.openhis.workflow.service.ISupplyRequestService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.math.BigDecimal;
import java.util.*;
import java.util.stream.Collectors;
import java.util.stream.Stream;
/**
* 领用出库 impl
@@ -69,22 +65,22 @@ public class RequisitionIssueAppServiceImpl implements IRequisitionIssueAppServi
List<Practitioner> practitionerList = practitionerService.getList();
// 经手人信息
List<IssueInitDto.practitionerListOption> practitionerListOptions = practitionerList.stream()
.map(practitioner -> new IssueInitDto.practitionerListOption(practitioner.getId(), practitioner.getName()))
.collect(Collectors.toList());
.map(practitioner -> new IssueInitDto.practitionerListOption(practitioner.getId(), practitioner.getName()))
.collect(Collectors.toList());
// 领用部门列表
List<IssueDepartmentDto> requisitionDepartmentDto =
requisitionIssueMapper.selectRequisitionDepartment(SupplyRequestType.DEPARTMENT.getValue());
requisitionIssueMapper.selectRequisitionDepartment(SupplyRequestType.DEPARTMENT.getValue());
// 药品类型
List<IssueInitDto.itemTypeOption> itemTypeOptions = Stream.of(ItemType.values())
.map(itemType -> new IssueInitDto.itemTypeOption(itemType.getValue(), itemType.getInfo()))
.collect(Collectors.toList());
.map(itemType -> new IssueInitDto.itemTypeOption(itemType.getValue(), itemType.getInfo()))
.collect(Collectors.toList());
// 审批状态
List<IssueInitDto.supplyStatusOption> supplyStatusOptions = Stream.of(SupplyStatus.values())
.map(supplyStatus -> new IssueInitDto.supplyStatusOption(supplyStatus.getValue(), supplyStatus.getInfo()))
.collect(Collectors.toList());
.map(supplyStatus -> new IssueInitDto.supplyStatusOption(supplyStatus.getValue(), supplyStatus.getInfo()))
.collect(Collectors.toList());
initDto.setItemTypeOptions(itemTypeOptions).setPractitionerListOptions(practitionerListOptions)
.setIssueDepartmentDto(requisitionDepartmentDto).setSupplyStatusOptions(supplyStatusOptions);
.setIssueDepartmentDto(requisitionDepartmentDto).setSupplyStatusOptions(supplyStatusOptions);
return R.ok(initDto);
}
@@ -106,15 +102,15 @@ public class RequisitionIssueAppServiceImpl implements IRequisitionIssueAppServi
* 领用出库单据列表
*
* @param issueSearchParam 查询条件
* @param pageNo 当前页码
* @param pageSize 查询条数
* @param searchKey 模糊查询关键字
* @param request 请求数据
* @param pageNo 当前页码
* @param pageSize 查询条数
* @param searchKey 模糊查询关键字
* @param request 请求数据
* @return 领用出库单据分页列表
*/
@Override
public R<?> getPage(IssueSearchParam issueSearchParam, Integer pageNo, Integer pageSize, String searchKey,
HttpServletRequest request) {
public R<Page<IssuePageDto>> getPage(IssueSearchParam issueSearchParam, Integer pageNo, Integer pageSize, String searchKey,
HttpServletRequest request) {
// 设置模糊查询的字段名
HashSet<String> searchFields = new HashSet<>();
@@ -122,10 +118,10 @@ public class RequisitionIssueAppServiceImpl implements IRequisitionIssueAppServi
// 构建查询条件
QueryWrapper<IssueSearchParam> queryWrapper =
HisQueryUtils.buildQueryWrapper(issueSearchParam, searchKey, searchFields, request);
HisQueryUtils.buildQueryWrapper(issueSearchParam, searchKey, searchFields, request);
// 查询领用出库单据分页列表
Page<IssuePageDto> inventoryReceiptPage = requisitionIssueMapper.selectRequisitionIssuePage(
new Page<>(pageNo, pageSize), queryWrapper, SupplyType.ISSUE_INVENTORY.getValue());
new Page<>(pageNo, pageSize), queryWrapper, SupplyType.ISSUE_INVENTORY.getValue());
inventoryReceiptPage.getRecords().forEach(e -> {
// 单据状态
@@ -143,8 +139,8 @@ public class RequisitionIssueAppServiceImpl implements IRequisitionIssueAppServi
@Override
public R<List<IssueDetailDto>> getDetail(String busNo) {
List<IssueDetailDto> requisitionIssueDetailList = requisitionIssueMapper.requisitionIssueDetail(busNo,
CommonConstants.TableName.MED_MEDICATION_DEFINITION, CommonConstants.TableName.ADM_DEVICE_DEFINITION,
ItemType.MEDICINE.getValue(), ItemType.DEVICE.getValue());
CommonConstants.TableName.MED_MEDICATION_DEFINITION, CommonConstants.TableName.ADM_DEVICE_DEFINITION,
ItemType.MEDICINE.getValue(), ItemType.DEVICE.getValue());
if (requisitionIssueDetailList.isEmpty()) {
return R.fail(MessageUtils.createMessage(PromptMsgConstant.Common.M00006, null));
}
@@ -188,16 +184,16 @@ public class RequisitionIssueAppServiceImpl implements IRequisitionIssueAppServi
BeanUtils.copyProperties(issueDto, supplyRequest);
// 生成待发送的领用出库单据
supplyRequest
// id
.setId(null)
// 单据分类:非库存供应
.setCategoryEnum(SupplyCategory.NON_STOCK.getValue())
// 单据类型:领用出库
.setTypeEnum(SupplyType.ISSUE_INVENTORY.getValue())
// 制单人
.setApplicantId(SecurityUtils.getLoginUser().getPractitionerId())
// 申请时间
.setApplyTime(DateUtils.getNowDate());
// id
.setId(null)
// 单据分类:非库存供应
.setCategoryEnum(SupplyCategory.NON_STOCK.getValue())
// 单据类型:领用出库
.setTypeEnum(SupplyType.ISSUE_INVENTORY.getValue())
// 制单人
.setApplicantId(SecurityUtils.getLoginUser().getPractitionerId())
// 申请时间
.setApplyTime(DateUtils.getNowDate());
supplyRequestList.add(supplyRequest);
}
@@ -228,7 +224,7 @@ public class RequisitionIssueAppServiceImpl implements IRequisitionIssueAppServi
// 删除单据
boolean result = supplyRequestService.removeByIds(supplyRequestIds);
return result ? R.ok(null, MessageUtils.createMessage(PromptMsgConstant.Common.M00004, null))
: R.fail(MessageUtils.createMessage(PromptMsgConstant.Common.M00007, null));
: R.fail(MessageUtils.createMessage(PromptMsgConstant.Common.M00007, null));
}
/**
@@ -242,7 +238,7 @@ public class RequisitionIssueAppServiceImpl implements IRequisitionIssueAppServi
// 单据提交审核
boolean result = supplyRequestService.submitApproval(busNo);
return result ? R.ok(null, MessageUtils.createMessage(PromptMsgConstant.Common.M00004, null))
: R.fail(MessageUtils.createMessage(PromptMsgConstant.Common.M00007, null));
: R.fail(MessageUtils.createMessage(PromptMsgConstant.Common.M00007, null));
}
/**
@@ -256,28 +252,28 @@ public class RequisitionIssueAppServiceImpl implements IRequisitionIssueAppServi
// 撤回审核
boolean result = supplyRequestService.withdrawApproval(busNo);
return result ? R.ok(null, MessageUtils.createMessage(PromptMsgConstant.Common.M00004, null))
: R.fail(MessageUtils.createMessage(PromptMsgConstant.Common.M00007, null));
: R.fail(MessageUtils.createMessage(PromptMsgConstant.Common.M00007, null));
}
/**
* 领用出库单据详情
*
* @param locationId 库房id
* @param startTime 开始时间
* @param endTime 结束时间
* @param pageNo 当前页码
* @param pageSize 查询条数
* @param startTime 开始时间
* @param endTime 结束时间
* @param pageNo 当前页码
* @param pageSize 查询条数
* @return 单据详情
*/
@Override
public R<?> getMonthlySettlementDetail(Long locationId, String startTime, String endTime, Integer pageNo,
Integer pageSize) {
Integer pageSize) {
Page<IssueDetailDto> receiptDetailList =
requisitionIssueMapper.getMonthlySettlementDetail(new Page<>(pageNo, pageSize), locationId, startTime,
endTime, ItemType.MEDICINE.getValue(), ItemType.DEVICE.getValue(),
CommonConstants.TableName.MED_MEDICATION_DEFINITION, CommonConstants.TableName.ADM_DEVICE_DEFINITION,
Arrays.asList(SupplyType.ISSUE_INVENTORY.getValue()), SupplyStatus.AGREE.getValue());
requisitionIssueMapper.getMonthlySettlementDetail(new Page<>(pageNo, pageSize), locationId, startTime,
endTime, ItemType.MEDICINE.getValue(), ItemType.DEVICE.getValue(),
CommonConstants.TableName.MED_MEDICATION_DEFINITION, CommonConstants.TableName.ADM_DEVICE_DEFINITION,
Arrays.asList(SupplyType.ISSUE_INVENTORY.getValue()), SupplyStatus.AGREE.getValue());
return R.ok(receiptDetailList);
}
@@ -285,11 +281,11 @@ public class RequisitionIssueAppServiceImpl implements IRequisitionIssueAppServi
/**
* 领用单据明细导出
*
* @param busNo 单据号
* @param busNo 单据号
* @param response 响应数据
*/
@Override
public void makeExcelFile( String busNo, HttpServletResponse response) {
public void makeExcelFile(String busNo, HttpServletResponse response) {
R<List<IssueDetailDto>> result = this.getDetail(busNo);
if (result != null && result.getData() != null) {
@@ -306,4 +302,31 @@ public class RequisitionIssueAppServiceImpl implements IRequisitionIssueAppServi
}
}
}
@Override
public void exportExcel(IssueSearchParam issueSearchParam, Integer pageNo, Integer pageSize, String searchKey, HttpServletRequest request, HttpServletResponse response) {
R<Page<IssuePageDto>> result = this.getPage(issueSearchParam, 1, 10000, searchKey, request);
if (result != null && result.getData() != null) {
Page<IssuePageDto> pageData = result.getData();
List<IssuePageDto> dataList = pageData.getRecords();
List<Practitioner> practitionerList = practitionerService.getList();
// 创建id到名字的映射
Map<Long, String> practitionerToNameMap = practitionerList.stream()
.collect(Collectors.toMap(Practitioner::getId, Practitioner::getName, (oldValue, newValue) -> oldValue // 冲突时保留旧值(第一个)
));
dataList.forEach(e -> {
e.setApproverId_dictText(practitionerToNameMap.get(e.getApproverId()));
e.setPractitionerId_dictText(practitionerToNameMap.get(e.getPractitionerId()));
e.setApplicantId_dictText(practitionerToNameMap.get(e.getApplicantId()));
});
try {
// 导出
NewExcelUtil<IssuePageDto> newExcelUtil =
new NewExcelUtil<>(IssuePageDto.class);
newExcelUtil.exportExcel(response, dataList, CommonConstants.SheetName.TRANSFER_DOCUMENT_DETAIL);
} catch (Exception e) {
throw new RuntimeException(e);
}
}
}
}

View File

@@ -10,24 +10,24 @@ import java.util.stream.Stream;
import javax.annotation.Resource;
import javax.servlet.http.HttpServletRequest;
import com.openhis.common.utils.PageUtils;
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.core.domain.R;
import com.core.common.utils.AgeCalculatorUtil;
import com.openhis.administration.domain.Location;
import com.openhis.administration.domain.TraceNoManage;
import com.openhis.administration.dto.TracePatientInfoDto;
import com.openhis.administration.mapper.TraceNoManageMapper;
import com.openhis.administration.service.ILocationService;
import com.openhis.administration.service.ITraceNoManageService;
import com.openhis.common.constant.CommonConstants;
import com.openhis.common.constant.PromptMsgConstant;
import com.openhis.common.enums.ItemType;
import com.openhis.common.enums.SupplyType;
import com.openhis.common.enums.TraceNoStatus;
import com.openhis.common.enums.*;
import com.openhis.common.utils.EnumUtils;
import com.openhis.common.utils.HisQueryUtils;
import com.openhis.common.utils.PageUtils;
import com.openhis.web.inventorymanage.appservice.ITraceNoAppService;
import com.openhis.web.inventorymanage.dto.*;
import com.openhis.web.inventorymanage.mapper.TraceNoAppMapper;
@@ -352,4 +352,45 @@ public class TraceNoAppServiceImpl implements ITraceNoAppService {
return traceNoManageService.saveBatch(traceNoManageList);
}
/**
* 根据药品追溯患者
*
* @param traceNoId 追溯码ID
* @return 患者列表
*/
@Override
public R<?> tracePatient(Long traceNoId) {
if (traceNoId == null) {
return R.fail("追溯码ID缺失");
}
// 回去追溯药品信息
TraceNoManage manage = traceNoManageService.getById(traceNoId);
List<TracePatientInfoDto> tracePatientInfoList = new ArrayList<>();
if (manage != null) {
if (SupplyType.DISPENSE_MEDICATION.getValue().equals(manage.getOperationType())) {
// 发药
tracePatientInfoList = traceNoManageMapper.tracePatient(manage.getItemId(),
DispenseStatus.COMPLETED.getValue(), manage.getTraceNo());
} else if (SupplyType.RETURN_MEDICATION.getValue().equals(manage.getOperationType())) {
// 退药
tracePatientInfoList = traceNoManageMapper.tracePatient(manage.getItemId(),
DispenseStatus.REFUNDED.getValue(), manage.getTraceNo());
} else {
// TODO 不知道是否会有其他状态,先写上
tracePatientInfoList = traceNoManageMapper.tracePatient(manage.getItemId(), null, manage.getTraceNo());
}
if (!tracePatientInfoList.isEmpty()) {
tracePatientInfoList.forEach(tracePatient -> {
// 性别
tracePatient.setGenderEnum_enumText(
EnumUtils.getInfoByValue(AdministrativeGender.class, tracePatient.getGenderEnum()));
// 计算年龄
tracePatient.setAge(tracePatient.getBirthDate() != null
? AgeCalculatorUtil.getAge(tracePatient.getBirthDate()) : "");
});
}
}
return R.ok(tracePatientInfoList);
}
}

View File

@@ -1,5 +1,7 @@
package com.openhis.web.inventorymanage.controller;
import java.util.List;
import javax.annotation.Resource;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
@@ -107,31 +109,29 @@ public class ProductDetailController {
/**
* 操作:停供
*
* @param inventoryId 库存项目管理ID
* @param inventoryIdList 库存项目管理ID
* @return 操作结果
*/
@PutMapping("/stop-supply")
public R<?> stopSupplyById(@RequestBody Long inventoryId) {
return productDetailsAppService.stopSupplyById(inventoryId);
public R<?> stopSupplyById(@RequestBody List<Long> inventoryIdList) {
return productDetailsAppService.stopSupplyById(inventoryIdList);
}
/**
* 操作:取消停供
*
* @param inventoryId 库存项目管理ID
* @param inventoryIdList 库存项目管理ID
* @return 操作结果
*/
@PutMapping("/cancel-supply")
public R<?> cancelSupplyById(@RequestBody Long inventoryId) {
return productDetailsAppService.cancelSupplyById(inventoryId);
public R<?> cancelSupplyById(@RequestBody List<Long> inventoryIdList) {
return productDetailsAppService.cancelSupplyById(inventoryIdList);
}
/**
* 库存明细表导出
*
* @param productDetailSearchParam 查询条件
* @param pageNo 当前页码
* @param pageSize 查询条数
* @param searchKey 模糊查询关键字
* @param request 请求数据
* @param response 响应数据
@@ -140,7 +140,23 @@ public class ProductDetailController {
public void makeExcelFile(ProductDetailSearchParam productDetailSearchParam,
@RequestParam(name = "searchKey", required = false) String searchKey, HttpServletRequest request,
HttpServletResponse response) {
productDetailsAppService.makeExcelFile(productDetailSearchParam, searchKey, request,
response);
productDetailsAppService.makeExcelFile(productDetailSearchParam, searchKey, request, response);
}
/**
* 库存明细表导出
*
* @param productDetailSearchParam 查询条件
* @param searchKey 模糊查询关键字
* @param request 请求数据
* @param response 响应数据
*/
@GetMapping(value = "/export-excel")
public void exportExcel(ProductDetailSearchParam productDetailSearchParam,
@RequestParam(value = "pageNo", defaultValue = "1") Integer pageNo,
@RequestParam(value = "pageSize", defaultValue = "1000") Integer pageSize,
@RequestParam(name = "searchKey", required = false) String searchKey, HttpServletRequest request,
HttpServletResponse response) {
productDetailsAppService.exportExcel(productDetailSearchParam, pageNo, pageSize, searchKey, request, response);
}
}

View File

@@ -153,4 +153,22 @@ public class PurchaseInventoryController {
public void exportExcel( @RequestParam String busNo, HttpServletResponse response) {
purchaseInventoryAppService.makeExcelFile(busNo, response);
}
/**
* 入库单据列表
*
* @param inventorySearchParam 查询条件
* @param pageNo 当前页码
* @param pageSize 查询条数
* @param searchKey 模糊查询关键字
* @param request 请求数据
* @param response 响应数据
*/
@GetMapping(value = "/export-excel")
public void exportExcelList(InventorySearchParam inventorySearchParam,
@RequestParam(value = "pageNo", defaultValue = "1") Integer pageNo,
@RequestParam(value = "pageSize", defaultValue = "10") Integer pageSize,
@RequestParam(name = "searchKey", required = false) String searchKey, HttpServletRequest request, HttpServletResponse response) {
purchaseInventoryAppService.exportExcel(inventorySearchParam, pageNo, pageSize, searchKey, request,response);
}
}

View File

@@ -154,4 +154,21 @@ public class RequisitionIssueController {
public void exportExcel(@RequestParam String busNo,HttpServletResponse response) {
requisitionIssueAppService.makeExcelFile( busNo, response);
}
/**
* 领用单据明细导出
*
* @param issueSearchParam 查询条件
* @param pageNo 当前页码
* @param pageSize 查询条数
* @param searchKey 模糊查询关键字
* @param request 请求数据
* @param response 响应数据
*/
@GetMapping(value = "/export-excel")
public void exportExcelList(IssueSearchParam issueSearchParam,
@RequestParam(value = "pageNo", defaultValue = "1") Integer pageNo,
@RequestParam(value = "pageSize", defaultValue = "10") Integer pageSize,
@RequestParam(name = "searchKey", required = false) String searchKey, HttpServletRequest request, HttpServletResponse response) {
requisitionIssueAppService.exportExcel(issueSearchParam, pageNo, pageSize, searchKey, request, response);
}
}

View File

@@ -60,6 +60,17 @@ public class TraceNoManageController {
return traceNoAppService.getPage(traceNoSearchParam, pageNo, pageSize, searchKey, request);
}
/**
* 根据药品追溯患者
*
* @param traceNoId 追溯码ID
* @return 患者列表
*/
@GetMapping(value = "/trace-patient")
public R<?> tracePatient(@RequestParam(value = "id") Long traceNoId) {
return traceNoAppService.tracePatient(traceNoId);
}
/**
* 添加追溯码信息
*

View File

@@ -43,4 +43,7 @@ public class InventorySearchParam {
/** 货位 */
private String locationStoreId;
/** 目的仓库 */
private Long purposeLocationId;
}

View File

@@ -3,11 +3,13 @@
*/
package com.openhis.web.inventorymanage.dto;
import com.core.common.annotation.Excel;
import com.fasterxml.jackson.databind.annotation.JsonSerialize;
import com.fasterxml.jackson.databind.ser.std.ToStringSerializer;
import com.openhis.common.annotation.Dict;
import lombok.Data;
import lombok.experimental.Accessors;
import org.springframework.format.annotation.NumberFormat;
import java.math.BigDecimal;
import java.util.Date;
@@ -23,10 +25,12 @@ import java.util.Date;
public class IssuePageDto {
/** 单据号 */
@Excel(name = "单据号", sort = 1)
private String supplyBusNo;
/** 状态 */
private Integer statusEnum;
@Excel(name = "审批状态", sort = 2)
private String statusEnum_enumText;
/** 类型 */
@@ -40,12 +44,14 @@ public class IssuePageDto {
private String supplierId_dictText;
/** 部门名称 */
@Excel(name = "领用部门", sort = 3)
private String locationName;
/** 经手人 */
@Dict(dictCode = "id", dictText = "name", dictTable = "adm_practitioner")
@JsonSerialize(using = ToStringSerializer.class)
private Long practitionerId;
@Excel(name = "经手人", sort = 5)
private String practitionerId_dictText;
/** 审批人 */
@@ -54,17 +60,20 @@ public class IssuePageDto {
private String approverId_dictText;
/** 审批时间 */
@Excel(name = "审批时间", dateFormat = "yyyy-MM-dd HH:mm:ss", sort = 7)
private Date approvalTime;
/** 申请人 */
@Dict(dictCode = "id", dictText = "name", dictTable = "adm_practitioner")
private Long applicantId;
@Excel(name = "制单人", sort = 6)
private String applicantId_dictText;
/** 申请时间 */
private Date applyTime;
/** 制单日期 */
@Excel(name = "制单日期", dateFormat = "yyyy-MM-dd HH:mm:ss", sort = 8)
private Date createTime;
/** 备注 */
@@ -77,4 +86,11 @@ public class IssuePageDto {
private Integer purposeTypeEnum;
private String purposeTypeEnum_enumText;
/**
* 总计金额
*/
@Excel(name = "总计金额",scale = 2, sort = 4)
@NumberFormat(pattern = "0.00")
private BigDecimal totalAmount;
}

View File

@@ -11,8 +11,9 @@ import com.fasterxml.jackson.databind.ser.std.ToStringSerializer;
import com.openhis.common.annotation.Dict;
import lombok.Data;
import lombok.experimental.Accessors;
import org.springframework.format.annotation.NumberFormat;
import java.io.Serializable;
import java.math.BigDecimal;
import java.util.Date;
/**
@@ -25,54 +26,83 @@ import java.util.Date;
@Accessors(chain = true)
public class ProductTransferPageDto {
/** ID */
/**
* ID
*/
@TableId(type = IdType.ASSIGN_ID)
@JsonSerialize(using = ToStringSerializer.class)
private Long id;
/** 单据号 */
@Excel(name = "单据号")
/**
* 单据号
*/
@Excel(name = "单据号", sort = 1)
private String supplyBusNo;
/** 状态 */
/**
* 状态
*/
private Integer statusEnum;
@Excel(name = "审批状态")
@Excel(name = "审批状态", sort = 2)
private String statusEnum_enumText;
/** 类型 */
/**
* 类型
*/
private Integer typeEnum;
@Excel(name = "单据类型")
@Excel(name = "单据类型", sort = 3)
private String typeEnum_enumText;
/** 项目(药品类型) */
/**
* 项目(药品类型)
*/
private String itemTable;
/** 源仓库名称 */
@Excel(name = "源仓库")
/**
* 源仓库名称
*/
@Excel(name = "源仓库", sort = 4)
private String sourceLocationName;
/** 目的仓库名称 */
@Excel(name = "目的仓库")
/**
* 目的仓库名称
*/
@Excel(name = "目的仓库", sort = 5)
private String purposeLocationName;
/** 审批人 */
/**
* 审批人
*/
@Dict(dictCode = "id", dictText = "name", dictTable = "adm_practitioner")
private Long approverId;
@Excel(name = "审批人")
@Excel(name = "审批人", sort = 7)
private String approverId_dictText;
/** 审批时间 */
@Excel(name = "审批时间")
/**
* 审批时间
*/
@Excel(name = "审批时间", dateFormat = "yyyy-MM-dd HH:mm:ss", sort = 9)
private Date approvalTime;
/** 申请人 */
/**
* 申请人
*/
@Dict(dictCode = "id", dictText = "name", dictTable = "adm_practitioner")
private Long applicantId;
@Excel(name = "制单人")
@Excel(name = "制单人", sort = 8)
private String applicantId_dictText;
/** 制单日期 */
@Excel(name = "制单日期")
/**
* 制单日期
*/
@Excel(name = "制单日期", dateFormat = "yyyy-MM-dd HH:mm:ss", sort = 10)
private Date createTime;
/**
* 总计金额
*/
@Excel(name = "总计金额",scale = 2, sort = 6)
@NumberFormat(pattern = "0.00")
private BigDecimal totalAmount;
}

View File

@@ -33,7 +33,7 @@ public class ReceiptPageDto {
/** 状态 */
private Integer statusEnum;
@Excel(name = "审批状态", sort = 2)
// @Excel(name = "审批状态", sort = 2)
private String statusEnum_enumText;
/** 退货状态 */
@@ -54,6 +54,7 @@ public class ReceiptPageDto {
/** 目的仓库 */
@Dict(dictCode = "id", dictText = "name", dictTable = "adm_location")
@JsonSerialize(using = ToStringSerializer.class)
private Long purposeLocationId;
private String purposeLocationId_dictText;
@Excel(name = "目的仓库", sort = 6)
@@ -61,6 +62,7 @@ public class ReceiptPageDto {
/** 目的仓位 */
@Dict(dictCode = "id", dictText = "name", dictTable = "adm_location")
@JsonSerialize(using = ToStringSerializer.class)
private Long purposeLocationStoreId;
private String purposeLocationStoreId_dictText;
@@ -88,6 +90,7 @@ public class ReceiptPageDto {
/** 申请人 */
@Dict(dictCode = "id", dictText = "name", dictTable = "adm_practitioner")
@JsonSerialize(using = ToStringSerializer.class)
private Long applicantId;
private String applicantId_dictText;
@Excel(name = "申请人", sort = 8)
@@ -96,12 +99,13 @@ public class ReceiptPageDto {
/** 申请时间 */
@JsonFormat(timezone = "GMT+8", pattern = "yyyy-MM-dd HH:mm:ss")
@DateTimeFormat(pattern = "yyyy-MM-dd HH:mm:ss")
@Excel(name = "申请时间", sort = 9, dateFormat = "yyyy-MM-dd HH:mm:ss")
// @Excel(name = "申请时间", sort = 9, dateFormat = "yyyy-MM-dd HH:mm:ss")
private Date applyTime;
/** 制单日期 */
@JsonFormat(timezone = "GMT+8", pattern = "yyyy-MM-dd HH:mm:ss")
@DateTimeFormat(pattern = "yyyy-MM-dd HH:mm:ss")
// @Excel(name = "申请时间", sort = 9, dateFormat = "yyyy-MM-dd HH:mm:ss")
private Date createTime;
/** 备注 */
@@ -128,8 +132,8 @@ public class ReceiptPageDto {
/*
* 总金额
*/
@Excel(name = "总金额", sort = 7,scale = 2)
private BigDecimal totalAmount;
@Excel(name = "总金额", sort = 7)
private String totalAmountText;
}

View File

@@ -3,19 +3,18 @@
*/
package com.openhis.web.inventorymanage.dto;
import java.util.Date;
import com.baomidou.mybatisplus.annotation.IdType;
import com.baomidou.mybatisplus.annotation.TableId;
import com.fasterxml.jackson.annotation.JsonFormat;
import com.fasterxml.jackson.databind.annotation.JsonSerialize;
import com.fasterxml.jackson.databind.ser.std.ToStringSerializer;
import com.openhis.common.annotation.Dict;
import lombok.Data;
import lombok.experimental.Accessors;
import java.io.Serializable;
import java.math.BigDecimal;
import java.util.Date;
/**
* 追溯码明细
*
@@ -24,10 +23,11 @@ import java.util.Date;
*/
@Data
@Accessors(chain = true)
public class TraceNoDetailsPageDto{
public class TraceNoDetailsPageDto {
/** ID */
@TableId(type = IdType.ASSIGN_ID)
@JsonSerialize(using = ToStringSerializer.class)
private Long id;
/** 药品名 */

View File

@@ -74,4 +74,10 @@ public interface IGfStudentListAppService {
* @param response 响应
*/
void importTemplate(HttpServletResponse response);
/**
* peis数据同步
*/
R<?> synPeis();
}

View File

@@ -1,11 +1,31 @@
package com.openhis.web.nenu.appservice.impl;
import java.io.IOException;
import java.time.format.DateTimeParseException;
import java.util.*;
import java.util.concurrent.atomic.AtomicInteger;
import java.util.stream.Collectors;
import java.util.stream.IntStream;
import javax.servlet.http.HttpServletResponse;
import com.alibaba.fastjson2.JSON;
import com.core.common.enums.TenantOptionDict;
import com.core.common.exception.ServiceException;
import com.core.web.util.TenantOptionUtil;
import com.openhis.web.nenu.dto.GfStudentPeisDto;
import com.openhis.web.nenu.dto.PeisStudentPatientDto;
import com.openhis.web.patientmanage.mapper.PatientManageMapper;
import com.openhis.yb.dto.BaseInfo;
import com.openhis.yb.dto.BaseParam;
import org.apache.http.client.config.RequestConfig;
import org.apache.http.client.methods.CloseableHttpResponse;
import org.apache.http.client.methods.HttpPost;
import org.apache.http.entity.ContentType;
import org.apache.http.entity.StringEntity;
import org.apache.http.impl.client.CloseableHttpClient;
import org.apache.http.impl.client.HttpClients;
import org.apache.http.util.EntityUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.web.multipart.MultipartFile;
@@ -440,4 +460,150 @@ public class GfStudentListAppServiceImpl implements IGfStudentListAppService {
return R.ok();
}
@Override
public R<?> synPeis() {
//List<GfStudentPeisDto> patientBusNoList = gfStudentListAppMapper.getPatientBusNoList();
try {
// 1. 获取总记录数
List<GfStudentPeisDto> patientBusNoList = gfStudentListAppMapper.getPatientBusNoList();
int totalCount = patientBusNoList.size();
if (totalCount == 0) {
return R.ok("未查询到数据");
}
//log.info("开始传输学生数据,总记录数: {}", totalCount);
// 2. 分批处理参数
int pageSize = 1000; // 每批大小
int pageNum = 1;
int totalPages = (int) Math.ceil((double) totalCount / pageSize);
AtomicInteger processedCount = new AtomicInteger(0);
List<Long> failedBatches = new ArrayList<>();
List<ArrayList<GfStudentPeisDto>> lists = IntStream.range(0, (totalCount + pageSize - 1) / pageSize)
.mapToObj(i -> {
int start = i * pageSize;
int end = Math.min(start + pageSize, totalCount);
return new ArrayList<>(patientBusNoList.subList(start, end));
})
.collect(Collectors.toList());
// 3. 分批处理
for (ArrayList<GfStudentPeisDto> list:lists) {
//log.info("开始处理第 {}/{} 批", pageNum, totalPages);
PeisStudentPatientDto peisStudentPatientDto = new PeisStudentPatientDto();
peisStudentPatientDto.setStudentList(list);
peisStudentPatientDto.setCustomerId("");
peisStudentPatientDto.setRequestType("");
// 发送请求
boolean success = sendBatchDataWithRetry(peisStudentPatientDto, 3); // 重试3次
if (success) {
int currentProcessed = processedCount.addAndGet(list.size());
//log.info("第 {} 批处理成功,当前累计处理: {} 条",
// pageNum, currentProcessed);
} else {
failedBatches.add((long) pageNum);
//log.error("第 {} 批处理失败,已记录到失败列表", pageNum);
}
// 进度控制
if (pageNum % 5 == 0) {
double progress = (double) pageNum / totalPages * 100;
//log.info("传输进度: {}/{} ({:.2f}%)",
// pageNum, totalPages, progress);
}
// 批次间隔,避免对接口造成压力
Thread.sleep(200);
pageNum++;
}
// 4. 返回结果
String message = String.format("数据传输完成。总记录数: %d成功处理: %d 条",
totalCount, processedCount.get());
if (!failedBatches.isEmpty()) {
message += String.format(",失败批次: %s", failedBatches);
// 可以在这里添加失败批次的重试逻辑
retryFailedBatches(failedBatches);
}
return R.ok(message);
} catch (Exception e) {
//log.error("数据传输异常", e);
return R.fail("数据传输失败: " + e.getMessage());
}
}
private boolean sendBatchDataWithRetry(PeisStudentPatientDto peisStudentPatientDto, int maxRetries) {
int retryCount = 0;
List<GfStudentPeisDto> studentList = peisStudentPatientDto.getStudentList();
while (retryCount <= maxRetries) {
try {
return sendSingleBatchHttpRequest(peisStudentPatientDto);
} catch (Exception e) {
retryCount++;
if (retryCount > maxRetries) {
//log.error("批次数据发送失败,已达最大重试次数: {}", maxRetries, e);
return false;
}
try {
// 指数退避
long delay = (long) Math.pow(2, retryCount) * 1000;
Thread.sleep(delay);
//log.info("第 {} 次重试批次数据", retryCount);
} catch (InterruptedException ie) {
Thread.currentThread().interrupt();
return false;
}
}
}
return false;
}
/**
* 发送http请求2025/05/02经测试若以自带的工具类发送请求失败故使用原peis系统中成功调用的写法重新封装
*
* @param peisStudentPatientDto 参数
* @return
*/
private boolean sendSingleBatchHttpRequest(PeisStudentPatientDto peisStudentPatientDto) {
RequestConfig requestConfig = RequestConfig.custom().setConnectTimeout(90000).setConnectionRequestTimeout(90000)
.setSocketTimeout(90000).build();
CloseableHttpClient httpClient = HttpClients.custom().setDefaultRequestConfig(requestConfig).build();
CloseableHttpResponse response = null;
// 发送请求
try {
HttpPost httpPost = new HttpPost(TenantOptionUtil.getOptionContent(TenantOptionDict.PEIS_SERVER_URL)+"/wx/auth/syncHisInfo");
StringEntity stringEntity = new StringEntity(JSON.toJSONString(peisStudentPatientDto), ContentType.APPLICATION_JSON);
httpPost.setEntity(stringEntity);
// 执行http请求
response = httpClient.execute(httpPost);
} catch (Exception e) {
e.printStackTrace();
throw new ServiceException("Http请求异常请稍后再试。");
} finally {
try {
response.close();
} catch (IOException e) {
e.printStackTrace();
}
}
return true;
}
private void retryFailedBatches(List<Long> failedBatchNumbers) {
// 实现失败批次的重试逻辑
// 可以根据业务需求决定是否重试
}
}

View File

@@ -105,4 +105,13 @@ public class GfStudentListController {
public void importTemplate(HttpServletResponse response) {
gfStudentListAppService.importTemplate(response);
}
/**
* peis同步
*
*/
@PostMapping("/sy-peis")
public R<?> synPeis() {
return gfStudentListAppService.synPeis();
}
}

View File

@@ -0,0 +1,40 @@
package com.openhis.web.nenu.dto;
import lombok.Data;
import java.io.Serializable;
/**
* 公费医疗-学生名单peis同步
*
* @author Thanking
* @date 2025-12-16
*/
@Data
public class GfStudentPeisDto implements Serializable {
/**
* 姓名
*/
private String name;
/**
* 学号
*/
private String studentId;
/**
* 身份证号码
*/
private String idNumber;
/**
* 患者编号
*/
private String busNo;
/**
* 状态
*/
private String status;
}

View File

@@ -0,0 +1,19 @@
package com.openhis.web.nenu.dto;
import lombok.Data;
import java.io.Serializable;
import java.util.List;
@Data
public class PeisStudentPatientDto implements Serializable {
private static final long serialVersionUID = 1L;
private String customerId;
private String requestType;
private List<GfStudentPeisDto> studentList;
}

View File

@@ -1,5 +1,6 @@
package com.openhis.web.nenu.mapper;
import com.openhis.web.nenu.dto.GfStudentPeisDto;
import org.apache.ibatis.annotations.Param;
import org.springframework.stereotype.Repository;
@@ -9,6 +10,8 @@ import com.baomidou.mybatisplus.core.toolkit.Constants;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.openhis.web.nenu.dto.GfStudentListDto;
import java.util.List;
/**
* 公费医疗-学生名单管理 Mapper
*
@@ -28,4 +31,24 @@ public interface GfStudentListAppMapper {
IPage<GfStudentListDto> selectGfStudentListPage(@Param("page") Page<GfStudentListDto> page,
@Param(Constants.WRAPPER) QueryWrapper<GfStudentListDto> queryWrapper);
/**
* 获取学生名单peis同步列表
*
* @return 学生名单peis同步列表
*/
List<GfStudentPeisDto> getPatientBusNoList(@Param("pageNum")int pageNum, @Param("pageSize")int pageSize);
/**
* 获取学生名单peis同步列表
*
* @return 学生名单peis同步列表
*/
List<GfStudentPeisDto> getPatientBusNoList();
/**
* 获取学生名单peis同步列表数量
*
* @return 学生名单peis同步列表数量
*/
Long getPatientBusNoCount();
}

View File

@@ -1,37 +0,0 @@
package com.openhis.web.patientmanage.appservice;
import javax.servlet.http.HttpServletRequest;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.core.common.core.domain.R;
import com.openhis.web.patientmanage.dto.OutpatientRecordDto;
import com.openhis.web.patientmanage.dto.OutpatientRecordSearchParam;
/**
* 门诊记录查询
*
* @author liuhr
* @date 2025/3/15
*/
public interface IOutpatientRecordService {
/**
* 分页查询门诊记录
*
* @param outpatientRecordSearchParam 门诊录查询参数
* @param searchKey 查询条件-模糊查询
* @param pageNo 页码默认为1
* @param pageSize 每页大小默认为10
* @return 分页查询
*/
IPage<OutpatientRecordDto> getPatient(OutpatientRecordSearchParam outpatientRecordSearchParam, String searchKey,
Integer pageNo, Integer pageSize, HttpServletRequest request);
/**
* 获取医生名字列表
*
* @return 医生名字列表
*/
R<?> getDoctorNames();
}

View File

@@ -4,9 +4,8 @@ import javax.servlet.http.HttpServletRequest;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.core.common.core.domain.R;
import com.openhis.web.patientmanage.dto.PatientBaseInfoDto;
import com.openhis.web.patientmanage.dto.PatientInfoInitDto;
import com.openhis.web.patientmanage.dto.PatientInfoSearchParam;
import com.openhis.web.patientmanage.dto.PatientInformationDto;
/**
* 病人管理——病人信息
@@ -26,28 +25,34 @@ public interface IPatientInformationService {
/**
* 分页查询门诊记录
*
* @param patientInfoSearchParam 病人查询参数
* @param patientBaseInfoDto 病人查询参数
* @param searchKey 查询条件-模糊查询
* @param pageNo 页码默认为1
* @param pageSize 每页大小默认为10
* @return 分页查询
*/
IPage<PatientInformationDto> getPatientInfo(PatientInfoSearchParam patientInfoSearchParam, String searchKey,
Integer pageNo, Integer pageSize, HttpServletRequest request);
IPage<PatientBaseInfoDto> getPatientInfo(PatientBaseInfoDto patientBaseInfoDto, String searchKey, Integer pageNo,
Integer pageSize, HttpServletRequest request);
/**
* 修改病人信息
*
* @param patientInformationDto 病人信息
* @param patientInfoDto 病人信息
* @return 更新结果
*/
R<?> editPatient(PatientInformationDto patientInformationDto);
R<?> editPatient(PatientBaseInfoDto patientInfoDto);
/**
* 添加病人信息
*
* @param patientInformationDto 病人信息
* @param patientInfoDto 病人信息
*/
R<?> addPatient(PatientInformationDto patientInformationDto);
R<?> addPatient(PatientBaseInfoDto patientInfoDto);
/**
* 更新患者手机号
*
* @param patientBaseInfoDto 患者信息
*/
R<?> updatePatientPhone(PatientBaseInfoDto patientBaseInfoDto);
}

View File

@@ -1,80 +0,0 @@
package com.openhis.web.patientmanage.appservice.impl;
import java.util.Arrays;
import java.util.HashSet;
import javax.annotation.Resource;
import javax.servlet.http.HttpServletRequest;
import org.springframework.stereotype.Service;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.core.common.core.domain.R;
import com.openhis.common.constant.CommonConstants;
import com.openhis.common.enums.AdministrativeGender;
import com.openhis.common.enums.EncounterSubjectStatus;
import com.openhis.common.enums.ParticipantType;
import com.openhis.common.utils.EnumUtils;
import com.openhis.common.utils.HisQueryUtils;
import com.openhis.web.patientmanage.appservice.IOutpatientRecordService;
import com.openhis.web.patientmanage.dto.OutpatientRecordDto;
import com.openhis.web.patientmanage.dto.OutpatientRecordSearchParam;
import com.openhis.web.patientmanage.mapper.PatientManageMapper;
/**
* 门诊记录查询 应用实现
*
* @author liuhr
* @date 2025/3/15
*/
@Service
public class OutpatientRecordServiceImpl implements IOutpatientRecordService {
@Resource
private PatientManageMapper patientManageMapper;
/**
* 分页查询门诊记录
*
* @param outpatientRecordSearchParam 门诊录查询参数
* @param pageNo 页码默认为1
* @param pageSize 每页大小默认为10
* @return 分页查询
*/
@Override
public IPage<OutpatientRecordDto> getPatient(OutpatientRecordSearchParam outpatientRecordSearchParam,
String searchKey, Integer pageNo, Integer pageSize, HttpServletRequest request) {
// 构建查询条件
QueryWrapper<OutpatientRecordDto> queryWrapper =
HisQueryUtils.buildQueryWrapper(outpatientRecordSearchParam, searchKey,
new HashSet<>(Arrays.asList(CommonConstants.FieldName.IdCard, CommonConstants.FieldName.Name,
CommonConstants.FieldName.PatientBusNo, CommonConstants.FieldName.EncounterBusNo)),
request);
IPage<OutpatientRecordDto> outpatientRecordPage = patientManageMapper
.getOutpatientRecord(ParticipantType.ADMITTER.getCode(), new Page<>(pageNo, pageSize), queryWrapper);
outpatientRecordPage.getRecords().forEach(e -> {
// 性别枚举类回显赋值
e.setGenderEnum_enumText(EnumUtils.getInfoByValue(AdministrativeGender.class, e.getGenderEnum()));
// 就诊对象状态枚举类回显赋值
e.setSubjectStatusEnum_enumText(
EnumUtils.getInfoByValue(EncounterSubjectStatus.class, e.getSubjectStatusEnum()));
});
return outpatientRecordPage;
}
/**
* 获取医生名字列表
*
* @return 医生名字列表
*/
public R<?> getDoctorNames() {
return R.ok(patientManageMapper.getDoctorNames());
}
}

View File

@@ -1,6 +1,9 @@
package com.openhis.web.patientmanage.appservice.impl;
import java.util.*;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.HashSet;
import java.util.List;
import java.util.stream.Collectors;
import java.util.stream.Stream;
@@ -9,18 +12,20 @@ import javax.servlet.http.HttpServletRequest;
import org.springframework.beans.factory.annotation.Autowired;
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.core.metadata.IPage;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.core.common.core.domain.R;
import com.core.common.core.domain.model.LoginUser;
import com.core.common.exception.ServiceException;
import com.core.common.utils.AssignSeqUtil;
import com.core.common.utils.DateUtils;
import com.core.common.utils.ChineseConvertUtils;
import com.core.common.utils.MessageUtils;
import com.core.common.utils.bean.BeanUtils;
import com.core.common.utils.SecurityUtils;
import com.openhis.administration.domain.Patient;
import com.openhis.administration.domain.PatientIdentifier;
import com.openhis.administration.mapper.PatientMapper;
import com.openhis.administration.service.IPatientIdentifierService;
import com.openhis.administration.service.IPatientService;
import com.openhis.common.constant.CommonConstants;
@@ -30,9 +35,9 @@ import com.openhis.common.utils.EnumUtils;
import com.openhis.common.utils.HisQueryUtils;
import com.openhis.common.utils.IdCardUtil;
import com.openhis.web.patientmanage.appservice.IPatientInformationService;
import com.openhis.web.patientmanage.dto.PatientBaseInfoDto;
import com.openhis.web.patientmanage.dto.PatientIdInfoDto;
import com.openhis.web.patientmanage.dto.PatientInfoInitDto;
import com.openhis.web.patientmanage.dto.PatientInfoSearchParam;
import com.openhis.web.patientmanage.dto.PatientInformationDto;
import com.openhis.web.patientmanage.mapper.PatientManageMapper;
/**
@@ -47,15 +52,13 @@ public class PatientInformationServiceImpl implements IPatientInformationService
@Autowired
PatientManageMapper patientManageMapper;
@Autowired
private PatientMapper patientMapper;
@Autowired
private IPatientService patientService;
@Autowired
private IPatientIdentifierService patientIdentifierService;
@Autowired(required = false)
@Autowired
private AssignSeqUtil assignSeqUtil;
/**
@@ -118,25 +121,29 @@ public class PatientInformationServiceImpl implements IPatientInformationService
/**
* 分页查询门诊记录
*
* @param patientInfoSearchParam 病人查询参数
* @param patientBaseInfoDto 病人查询参数
* @param searchKey 查询条件-模糊查询
* @param pageNo 页码默认为1
* @param pageSize 每页大小默认为10
* @return 分页查询
*/
@Override
public IPage<PatientInformationDto> getPatientInfo(PatientInfoSearchParam patientInfoSearchParam, String searchKey,
public IPage<PatientBaseInfoDto> getPatientInfo(PatientBaseInfoDto patientBaseInfoDto, String searchKey,
Integer pageNo, Integer pageSize, HttpServletRequest request) {
// 构建查询条件
QueryWrapper<PatientInformationDto> queryWrapper = HisQueryUtils.buildQueryWrapper(
patientInfoSearchParam, searchKey, new HashSet<>(Arrays.asList(CommonConstants.FieldName.Name,
QueryWrapper<PatientBaseInfoDto> queryWrapper = HisQueryUtils.buildQueryWrapper(
patientBaseInfoDto, searchKey, new HashSet<>(Arrays.asList(CommonConstants.FieldName.Name,
CommonConstants.FieldName.BusNo, CommonConstants.FieldName.PyStr, CommonConstants.FieldName.WbStr)),
request);
IPage<PatientInformationDto> patientInformationPage =
IPage<PatientBaseInfoDto> patientInformationPage =
patientManageMapper.getPatientPage(new Page<>(pageNo, pageSize), queryWrapper);
// 患者id集合
List<Long> patientIdList =
patientInformationPage.getRecords().stream().map(PatientBaseInfoDto::getId).collect(Collectors.toList());
// 患者身份信息
List<PatientIdInfoDto> patientIdInfo = patientManageMapper.getPatientIdInfo(patientIdList);
// 获取登录者信息
LoginUser loginUser = SecurityUtils.getLoginUser();
patientInformationPage.getRecords().forEach(e -> {
// 性别枚举类回显赋值
e.setGenderEnum_enumText(EnumUtils.getInfoByValue(AdministrativeGender.class, e.getGenderEnum()));
@@ -151,109 +158,170 @@ public class PatientInformationServiceImpl implements IPatientInformationService
// 家庭关系枚举类回显赋值
e.setLinkRelationCode_enumText(
EnumUtils.getInfoByValue(FamilyRelationshipType.class, e.getLinkRelationCode()));
// 患者身份子表信息
List<PatientIdInfoDto> idInfo = patientIdInfo.stream()
.filter(idInfoDto -> idInfoDto.getPatientId().equals(e.getId())).collect(Collectors.toList());
e.setPatientIdInfoList(idInfo);
// 登记医院
e.setOrganizationId(loginUser.getOrgId());
});
return patientInformationPage;
}
/**
* 修改病人信息
*
* @param patientInformationDto 病人信息
* @param patientInfoDto 病人信息
* @return 更新结果
*/
@Override
public R<?> editPatient(PatientInformationDto patientInformationDto) {
public R<?> editPatient(PatientBaseInfoDto patientInfoDto) {
// 如果患者没有输入身份证号则根据年龄自动生成
String idCard = patientInformationDto.getIdCard();
String idCard = patientInfoDto.getIdCard();
if (idCard == null || CommonConstants.Common.AREA_CODE.equals(idCard.substring(0, 6))) {
if (patientInformationDto.getAge() != null) {
idCard = IdCardUtil.generateIdByAge(patientInformationDto.getAge());
Date birthday = IdCardUtil.extractBirthdayFromIdCard(idCard);
patientInformationDto.setIdCard(idCard).setBirthDate(birthday);
if (patientInfoDto.getAge() != null) {
idCard = IdCardUtil.generateIdByAge(patientInfoDto.getAge());
patientInfoDto.setIdCard(idCard);
}
}
Patient patient = new Patient();
BeanUtils.copyProperties(patientInformationDto, patient);
// 当死亡时间不为空,检查死亡时间
if (patient.getDeceasedDate() != null) {
// 检验死亡时间未来时报错
if (DateUtils.isFuture(patient.getDeceasedDate())) {
R.fail(MessageUtils.createMessage(PromptMsgConstant.Common.M00011, new Object[] {"死亡时间未来时!"}));
// 身份证号是否存在
List<Patient> idCardList =
patientService.list(new LambdaQueryWrapper<Patient>().eq(Patient::getIdCard, patientInfoDto.getIdCard())
.ne(patientInfoDto.getId() != null, Patient::getId, patientInfoDto.getId()));
if (!idCardList.isEmpty()) {
Patient patient = idCardList.get(0);
if (patientInfoDto.getIdCard().equals(patient.getIdCard())
&& !patientInfoDto.getId().equals(patientInfoDto.getId())) {
throw new ServiceException("身份证号:" + patientInfoDto.getIdCard() + "已经存在");
}
}
// 调用服务层更新病人信息
boolean resPatient = patientService.updatePatient(patient);
// 根据患者的标识,判断是否需要修改
List<PatientIdentifier> patientIdentifierList = patientIdentifierService.selectByPatientId(patient.getId());
List<String> identifierNoList =
patientIdentifierList.stream().map(PatientIdentifier::getIdentifierNo).collect(Collectors.toList());
boolean resPatId = true;
if (patientIdentifierList.isEmpty()) {
PatientIdentifier newIdentifier = new PatientIdentifier();
newIdentifier.setPatientId(patient.getId()).setTypeCode(patientInformationDto.getTypeCode())
.setIdentifierNo(patientInformationDto.getIdentifierNo())
// 标识状态默认:常规
.setStateEnum(IdentifierStatusEnum.USUAL.getValue());
resPatId = patientIdentifierService.save(newIdentifier);
} else if (!identifierNoList.isEmpty() && !identifierNoList.contains(patientInformationDto.getIdentifierNo())) {
PatientIdentifier newIdentifier = new PatientIdentifier();
newIdentifier.setPatientId(patient.getId()).setTypeCode(patientInformationDto.getTypeCode())
.setIdentifierNo(patientInformationDto.getIdentifierNo())
// 标识状态默认:常规
.setStateEnum(IdentifierStatusEnum.USUAL.getValue());
resPatId = patientIdentifierService.save(newIdentifier);
// 处理患者信息
Patient patient = this.handlePatientInfo(patientInfoDto);
// 患者身份子表信息,先删除再新增
patientIdentifierService
.remove(new LambdaQueryWrapper<PatientIdentifier>().eq(PatientIdentifier::getPatientId, patient.getId()));
if (patientInfoDto.getPatientIdInfoList() != null) {
// 新增患者身份子表信息
List<PatientIdInfoDto> patientIdInfoList = patientInfoDto.getPatientIdInfoList();
PatientIdentifier patientIdentifier;
for (PatientIdInfoDto patientIdInfoDto : patientIdInfoList) {
patientIdentifier = new PatientIdentifier();
patientIdentifier.setPatientId(patient.getId());// 患者ID
patientIdentifier.setTypeCode(patientIdInfoDto.getTypeCode()); // 标识类型编码
patientIdentifier.setIdentifierNo(patientIdInfoDto.getIdentifierNo()); // 标识号
patientIdentifier.setStartTime(patientIdInfoDto.getStartTime()); // 有效时间Start
patientIdentifier.setEndTime(patientIdInfoDto.getEndTime()); // 有效时间end
patientIdentifierService.save(patientIdentifier);
}
}
return resPatient && resPatId
? R.ok(idCard, MessageUtils.createMessage(PromptMsgConstant.Common.M00001, new Object[] {"病人信息"}))
: R.fail(MessageUtils.createMessage(PromptMsgConstant.Common.M00007, null));
return R.ok(patient.getIdCard(),
MessageUtils.createMessage(PromptMsgConstant.Common.M00002, new Object[] {"病人信息"}));
}
/**
* 添加病人信息
*
* @param patientInformationDto 病人信息
* @param patientInfoDto 病人信息
*/
@Override
public R<?> addPatient(PatientInformationDto patientInformationDto) {
public R<?> addPatient(PatientBaseInfoDto patientInfoDto) {
// 如果患者没有输入身份证号则根据年龄自动生成
String idCard = patientInformationDto.getIdCard();
String idCard = patientInfoDto.getIdCard();
if (idCard == null || CommonConstants.Common.AREA_CODE.equals(idCard.substring(0, 6))) {
if (patientInformationDto.getAge() != null) {
idCard = IdCardUtil.generateIdByAge(patientInformationDto.getAge());
Date birthday = IdCardUtil.extractBirthdayFromIdCard(idCard);
patientInformationDto.setIdCard(idCard).setBirthDate(birthday);
if (patientInfoDto.getAge() != null) {
idCard = IdCardUtil.generateIdByAge(patientInfoDto.getAge());
patientInfoDto.setIdCard(idCard);
}
}
Patient patient = new Patient();
BeanUtils.copyProperties(patientInformationDto, patient);
patient.setBusNo(assignSeqUtil.getSeq(AssignSeqEnum.PATIENT_NUM.getPrefix(), 10));
// 当死亡时间不为空,检查死亡时间
if (patient.getDeceasedDate() != null) {
// 检验死亡时间未来时报错
if (DateUtils.isFuture(patient.getDeceasedDate())) {
R.fail(MessageUtils.createMessage(PromptMsgConstant.Common.M00011, new Object[] {"死亡时间未来时!"}));
// 身份证号是否存在
List<Patient> idCardList =
patientService.list(new LambdaQueryWrapper<Patient>().eq(Patient::getIdCard, patientInfoDto.getIdCard()));
if (!idCardList.isEmpty()) {
throw new ServiceException("身份证号:" + patientInfoDto.getIdCard() + "已经存在");
}
// 处理患者信息
Patient patient = this.handlePatientInfo(patientInfoDto);
// 新增患者身份子表信息
if (patientInfoDto.getPatientIdInfoList() != null) {
List<PatientIdInfoDto> patientIdInfoList = patientInfoDto.getPatientIdInfoList();
PatientIdentifier patientIdentifier;
for (PatientIdInfoDto patientIdInfoDto : patientIdInfoList) {
patientIdentifier = new PatientIdentifier();
patientIdentifier.setPatientId(patient.getId());// 患者ID
patientIdentifier.setTypeCode(patientIdInfoDto.getTypeCode()); // 标识类型编码
patientIdentifier.setIdentifierNo(patientIdInfoDto.getIdentifierNo()); // 标识号
patientIdentifier.setStartTime(patientIdInfoDto.getStartTime()); // 有效时间Start
patientIdentifier.setEndTime(patientIdInfoDto.getEndTime()); // 有效时间end
patientIdentifierService.save(patientIdentifier);
}
}
// 调用服务层,添加病人
boolean resPatient = patientService.addPatient(patient);
if (!resPatient) {
throw new ServiceException("身份证号已存在");
}
// 调用服务层,添加病人标识
PatientIdentifier patientIdentifier = new PatientIdentifier();
patientIdentifier.setPatientId(patient.getId()).setTypeCode(patientInformationDto.getTypeCode())
.setIdentifierNo(patientInformationDto.getIdentifierNo())
// 标识状态默认:常规
.setStateEnum(IdentifierStatusEnum.USUAL.getValue());
boolean result = patientIdentifierService.save(patientIdentifier);
return result
? R.ok(patient, MessageUtils.createMessage(PromptMsgConstant.Common.M00001, new Object[] {"病人信息"}))
: R.fail(MessageUtils.createMessage(PromptMsgConstant.Common.M00003, new Object[] {"病人信息"}));
return R.ok(patient, MessageUtils.createMessage(PromptMsgConstant.Common.M00001, new Object[] {"患者信息"}));
}
/**
* 处理患者信息
*
* @param patientInfoDto 患者信息dto
* @return 患者信息
*/
private Patient handlePatientInfo(PatientBaseInfoDto patientInfoDto) {
Patient patient = new Patient();
patient.setId(patientInfoDto.getId());
if (patientInfoDto.getId() == null) {
patient.setBusNo(assignSeqUtil.getSeq(AssignSeqEnum.PATIENT_NUM.getPrefix(), 10));
patientInfoDto.setActiveFlag(PublicationStatus.ACTIVE.getValue()); // 默认启用
}
patient.setName(patientInfoDto.getName()); // 患者姓名
patient.setPyStr(ChineseConvertUtils.toPinyinFirstLetter(patientInfoDto.getName())); // 拼音首拼
patient.setWbStr(ChineseConvertUtils.toWBFirstLetter(patientInfoDto.getName())); // 五笔首拼
patient.setIdCard(patientInfoDto.getIdCard()); // 身份证号
patient.setBirthDate(IdCardUtil.extractBirthdayFromIdCard(patientInfoDto.getIdCard())); // 生日
patient.setGenderEnum(patientInfoDto.getGenderEnum()); // 性别
patient.setPhone(patientInfoDto.getPhone()); // 联系方式
patient.setPrfsEnum(patientInfoDto.getPrfsEnum()); // 职业
patient.setWorkCompany(patientInfoDto.getWorkCompany()); // 工作单位
patient.setLinkName(patientInfoDto.getLinkName()); // 联系人
patient.setLinkRelationCode(patientInfoDto.getLinkRelationCode()); // 联系人关系
patient.setLinkTelcom(patientInfoDto.getLinkTelcom()); // 联系人电话
patient.setAddress(patientInfoDto.getAddress()); // 地址
patient.setAddressProvince(patientInfoDto.getAddressProvince()); // 地址省
patient.setAddressCity(patientInfoDto.getAddressCity()); // 地址市
patient.setAddressDistrict(patientInfoDto.getAddressDistrict()); // 地址区
patient.setAddressStreet(patientInfoDto.getAddressStreet()); // 地址街道
patient.setBloodAbo(patientInfoDto.getBloodAbo()); // 血型ABO
patient.setBloodRh(patientInfoDto.getBloodRh()); // 血型RH
patient.setMaritalStatusEnum(patientInfoDto.getMaritalStatusEnum()); // 婚姻状态
patient.setDeceasedDate(patientInfoDto.getDeceasedDate()); // 死亡时间
patient.setNationalityCode(patientInfoDto.getNationalityCode());// 民族
patient.setActiveFlag(patientInfoDto.getActiveFlag());// 活动标识
patientService.saveOrUpdate(patient);
return patient;
}
/**
* 更新患者手机号
*
* @param patientBaseInfoDto 患者信息
*/
@Override
public R<?> updatePatientPhone(PatientBaseInfoDto patientBaseInfoDto) {
if (patientBaseInfoDto != null) {
if (patientBaseInfoDto.getId() != null && patientBaseInfoDto.getPhone() != null) {
LambdaUpdateWrapper<Patient> updateWrapper = new LambdaUpdateWrapper<>();
updateWrapper.set(Patient::getPhone, patientBaseInfoDto.getPhone());
updateWrapper.eq(Patient::getId, patientBaseInfoDto.getId());
// 手机号码不相等时更新号码
updateWrapper.ne(Patient::getPhone, patientBaseInfoDto.getPhone()).or().isNull(Patient::getPhone);
patientService.update(updateWrapper);
return R.ok();
}
}
return R.fail("更新患者手机号失败");
}
}

View File

@@ -1,62 +0,0 @@
package com.openhis.web.patientmanage.controller;
import com.openhis.web.datadictionary.dto.DeviceManageSelParam;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.RestController;
import com.core.common.core.domain.R;
import com.openhis.web.patientmanage.appservice.IOutpatientRecordService;
import com.openhis.web.patientmanage.dto.OutpatientRecordSearchParam;
import lombok.AllArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import javax.servlet.http.HttpServletRequest;
/**
* 门诊记录
*
* @author liuhr
* @date 2025/2/28
*/
@RestController
@RequestMapping("/patient-manage/records")
@Slf4j
@AllArgsConstructor
public class OutpatientRecordController {
@Autowired
IOutpatientRecordService outpatientRecordService;
/**
* 门诊记录初期数据
*
* @return
*/
@GetMapping("/init")
public R<?> getDoctorNames() {
// 获取医生名字列表
return outpatientRecordService.getDoctorNames();
}
/**
* 分页查询门诊记录,可选条件
*
* @param outpatientRecordSearchParam 查询条件
* @param searchKey 查询条件-模糊查询
* @param pageNo 页码默认为1
* @param pageSize 每页大小默认为10
*/
@GetMapping("/outpatient-record-page")
public R<?> getPatient(OutpatientRecordSearchParam outpatientRecordSearchParam,
@RequestParam(value = "searchKey", defaultValue = "") String searchKey,
@RequestParam(value = "pageNo", defaultValue = "1") Integer pageNo,
@RequestParam(value = "pageSize", defaultValue = "10") Integer pageSize, HttpServletRequest request) {
return R.ok(outpatientRecordService.getPatient(outpatientRecordSearchParam,searchKey, pageNo, pageSize,request));
}
}

View File

@@ -3,13 +3,11 @@ package com.openhis.web.patientmanage.controller;
import javax.servlet.http.HttpServletRequest;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.validation.annotation.Validated;
import org.springframework.web.bind.annotation.*;
import com.core.common.core.domain.R;
import com.openhis.web.patientmanage.appservice.IPatientInformationService;
import com.openhis.web.patientmanage.dto.PatientInfoSearchParam;
import com.openhis.web.patientmanage.dto.PatientInformationDto;
import com.openhis.web.patientmanage.dto.PatientBaseInfoDto;
import lombok.AllArgsConstructor;
import lombok.extern.slf4j.Slf4j;
@@ -42,40 +40,47 @@ public class PatientInformationController {
/**
* 添加病人信息
*
* @param patientInformationDto 病人信息
* @param patientInfoDto 病人信息
*/
@PostMapping("/patient-information")
public R<?> addPatient(@Validated @RequestBody PatientInformationDto patientInformationDto) {
return patientInformationService.addPatient(patientInformationDto);
public R<?> addPatient(@RequestBody PatientBaseInfoDto patientInfoDto) {
return patientInformationService.addPatient(patientInfoDto);
}
/**
* 修改病人信息
*
* @param patientInformationDto 病人信息
* @param patientInfoDto 病人信息
*/
@PutMapping("/patient-information")
public R<?> editPatient(@Validated @RequestBody PatientInformationDto patientInformationDto) {
// 调用服务层更新病人信息
return patientInformationService.editPatient(patientInformationDto);
public R<?> editPatient(@RequestBody PatientBaseInfoDto patientInfoDto) {
return patientInformationService.editPatient(patientInfoDto);
}
/**
* 分页查询病人信息,可选条件
*
* @param patientInfoSearchParam 患者查询参数
* @param patientBaseInfoDto 患者查询参数
* @param searchKey 查询条件-模糊查询
* @param pageNo 页码默认为1
* @param pageSize 每页大小默认为10
*/
@GetMapping("/patient-information-page")
public R<?> getPatient(PatientInfoSearchParam patientInfoSearchParam,
public R<?> getPatient(PatientBaseInfoDto patientBaseInfoDto,
@RequestParam(value = "searchKey", defaultValue = "") String searchKey,
@RequestParam(value = "pageNo", defaultValue = "1") Integer pageNo,
@RequestParam(value = "pageSize", defaultValue = "10") Integer pageSize, HttpServletRequest request) {
return R
.ok(patientInformationService.getPatientInfo(patientInfoSearchParam, searchKey, pageNo, pageSize, request));
return R.ok(patientInformationService.getPatientInfo(patientBaseInfoDto, searchKey, pageNo, pageSize, request));
}
/**
* 更新患者手机号
*
* @param patientBaseInfoDto 患者信息
*/
@PostMapping("/update-patient-phone")
public R<?> updatePatientPhone(@RequestBody PatientBaseInfoDto patientBaseInfoDto) {
return patientInformationService.updatePatientPhone(patientBaseInfoDto);
}
}

View File

@@ -1,59 +0,0 @@
package com.openhis.web.patientmanage.dto;
import com.fasterxml.jackson.annotation.JsonFormat;
import lombok.Data;
import lombok.experimental.Accessors;
import java.util.Date;
/**
* 门诊记录Dto
*
* @author liuhr
* @date 2025/2/28
*/
@Data
@Accessors(chain = true)
public class OutpatientRecordDto {
/** 患者姓名 */
private String name;
/** 身份证号 */
private String idCard;
/** 疾病与诊断描述 */
private String description;
/** 患者院内编码/病历号 */
private String patientBusNo;
/** 就诊号 */
private String encounterBusNo;
/** 性别编码 */
private Integer genderEnum;
private String genderEnum_enumText;
/** 就诊时间 */
@JsonFormat(shape = JsonFormat.Shape.STRING, pattern = "yyyy-MM-dd HH:mm:ss")
private Date encounterTime;
/** 就诊对象状态 */
private Integer subjectStatusEnum;
private String subjectStatusEnum_enumText;
/** 机构名称/接诊医院 */
private String organizationName;
/** 接诊医生姓名 */
private String doctorName;
/** 手机号码 */
private String phone;
/** 就诊开始时间 */
@JsonFormat(shape = JsonFormat.Shape.STRING, pattern = "yyyy-MM-dd HH:mm:ss")
private Date StartTime;
}

View File

@@ -1,22 +0,0 @@
package com.openhis.web.patientmanage.dto;
import lombok.Data;
import lombok.experimental.Accessors;
/**
* 门诊记录查询参数
*
* @author liuhr
* @date 2025/2/28
*/
@Data
@Accessors(chain = true)
public class OutpatientRecordSearchParam {
/** 手机号码 */
private String phone;
/** 医生姓名 */
private String doctorName;
}

View File

@@ -1,11 +1,7 @@
package com.openhis.web.patientmanage.dto;
import java.util.Date;
import javax.validation.constraints.NotBlank;
import javax.validation.constraints.NotNull;
import javax.validation.constraints.Pattern;
import javax.validation.constraints.Size;
import java.util.List;
import com.fasterxml.jackson.annotation.JsonFormat;
import com.fasterxml.jackson.databind.annotation.JsonSerialize;
@@ -16,14 +12,14 @@ import lombok.Data;
import lombok.experimental.Accessors;
/**
* 病人信息Dto
* 病人信息 Dto
*
* @author liuhr
* @date 2025/2/22
*/
@Data
@Accessors(chain = true)
public class PatientInformationDto {
public class PatientBaseInfoDto {
/**
* ID
@@ -31,34 +27,38 @@ public class PatientInformationDto {
@JsonSerialize(using = ToStringSerializer.class)
private Long id;
/**
* 临时标识
*/
private Integer tempFlag;
/**
* 患者姓名
*/
@NotBlank(message = "患者姓名不能为空")
private String name;
/**
* 患者其他名称
* 民族编码
*/
private String nameJson;
/**
* 患者院内编码/病历号
*/
private String busNo;
@Dict(dictCode = "nationality_code")
private String nationalityCode;
private String nationalityCode_dictText;
/**
* 性别编码
*/
@NotNull
private Integer genderEnum;
private String genderEnum_enumText;
/** 活动标记 */
private Integer activeFlag;
private Integer activeFlag_enumText;
/**
* 身份证号码
*/
private String idCard;
/**
* 年龄
*/
private Integer age;
/**
* 生日
*/
@@ -66,16 +66,9 @@ public class PatientInformationDto {
private Date birthDate;
/**
* 死亡时间
* 联系方式
*/
@JsonFormat(shape = JsonFormat.Shape.STRING, pattern = "yyyy-MM-dd HH:mm:ss")
private Date deceasedDate;
/**
* 婚姻状态
*/
private Integer maritalStatusEnum;
private String maritalStatusEnum_enumText;
private String phone;
/**
* 职业编码
@@ -84,10 +77,25 @@ public class PatientInformationDto {
private String prfsEnum_enumText;
/**
* 电话
* 工作单位
*/
@Pattern(regexp = "^$|^1[3-9]\\d{9}$", message = "电话格式不正确必须为11位有效手机号")
private String phone;
private String workCompany;
/**
* 联系人
*/
private String linkName;
/**
* 联系人关系
*/
private Integer linkRelationCode;
private String linkRelationCode_enumText;
/**
* 联系人电话
*/
private String linkTelcom;
/**
* 地址
@@ -114,43 +122,6 @@ public class PatientInformationDto {
*/
private String addressStreet;
/**
* 患者其他地址
*/
private String addressJson;
/**
* 民族
*/
private String nationalityCode;
/**
* 证件号码
*/
private String idCard;
/**
* 证件类型
*/
@Dict(dictCode = "sys_idtype")
private String typeCode;
private String typeCode_dictText;
/**
* 标识号
*/
private String identifierNo;
/**
* 拼音码
*/
private String pyStr;
/**
* 五笔码
*/
private String wbStr;
/**
* 血型ABO
*/
@@ -164,63 +135,36 @@ public class PatientInformationDto {
private String bloodRh_enumText;
/**
* 工作单位
* 婚姻状态
*/
private String workCompany;
private Integer maritalStatusEnum;
private String maritalStatusEnum_enumText;
/**
* 籍贯
* 死亡时间
*/
private String nativePlace;
@JsonFormat(shape = JsonFormat.Shape.STRING, pattern = "yyyy-MM-dd HH:mm:ss")
private Date deceasedDate;
/**
* 国家编码
* 病人证件信息集合
*/
private String countryCode;
private List<PatientIdInfoDto> patientIdInfoList;
/**
* 联系人
* 患者院内编码/病历号
*/
private String linkName;
private String busNo;
/**
* 联系人关系
*/
private Integer linkRelationCode;
private String linkRelationCode_enumText;
/**
* 联系人电话
*/
// @Size(min = 11, max = 11, message = "电话长度必须为11位")
// @Pattern(regexp = "^1[3-9]\\d{9}$", message = "电话格式不正确")
@Pattern(regexp = "^$|^1[3-9]\\d{9}$", message = "联系人电话格式不正确必须为11位有效手机号")
private String linkTelcom;
/**
* 其他联系人
*/
private String linkJsons;
/**
* 机构Id
* 登记医院ID
*/
@JsonSerialize(using = ToStringSerializer.class)
private Long organizationId;
/**
* 机构名
*/
private String organizationName;
/**
* 创建时间
* 登记时间
*/
@JsonFormat(shape = JsonFormat.Shape.STRING, pattern = "yyyy-MM-dd HH:mm:ss")
private Date createTime;
/**
* 年龄
*/
private Integer age;
}

View File

@@ -0,0 +1,42 @@
package com.openhis.web.patientmanage.dto;
import java.util.Date;
import com.fasterxml.jackson.annotation.JsonFormat;
import com.fasterxml.jackson.databind.annotation.JsonSerialize;
import com.fasterxml.jackson.databind.ser.std.ToStringSerializer;
import lombok.Data;
import lombok.experimental.Accessors;
/**
* 病人证件信息 Dto
*
* @author liuhr
* @date 2025/2/22
*/
@Data
@Accessors(chain = true)
public class PatientIdInfoDto {
/**
* 患者id
*/
@JsonSerialize(using = ToStringSerializer.class)
private Long patientId;
/** 标识类型编码 */
private String typeCode;
/** 标识号 */
private String identifierNo;
/** 有效时间Start */
@JsonFormat(shape = JsonFormat.Shape.STRING, pattern = "yyyy-MM-dd HH:mm:ss")
private Date startTime;
/** 有效时间end */
@JsonFormat(shape = JsonFormat.Shape.STRING, pattern = "yyyy-MM-dd HH:mm:ss")
private Date endTime;
}

View File

@@ -1,18 +0,0 @@
package com.openhis.web.patientmanage.dto;
import lombok.Data;
import lombok.experimental.Accessors;
/**
* 病人信息查询参数Dto
*
* @author liuhr
* @date 2025/3/31
*/
@Data
@Accessors(chain = true)
public class PatientInfoSearchParam {
/** 病人编号 */
private String busNo;
}

View File

@@ -11,9 +11,8 @@ import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.core.toolkit.Constants;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.openhis.administration.domain.Patient;
import com.openhis.web.patientmanage.dto.OutpatientRecordDto;
import com.openhis.web.patientmanage.dto.OutpatientRecordSearchParam;
import com.openhis.web.patientmanage.dto.PatientInformationDto;
import com.openhis.web.patientmanage.dto.PatientBaseInfoDto;
import com.openhis.web.patientmanage.dto.PatientIdInfoDto;
/**
* 病人信息管理
@@ -31,26 +30,15 @@ public interface PatientManageMapper extends BaseMapper<Patient> {
* @param queryWrapper 查询条件
* @return 病人信息列表
*/
IPage<PatientInformationDto> getPatientPage(@Param("page") Page<PatientInformationDto> page,
@Param(Constants.WRAPPER) QueryWrapper<PatientInformationDto> queryWrapper);
IPage<PatientBaseInfoDto> getPatientPage(@Param("page") Page<PatientBaseInfoDto> page,
@Param(Constants.WRAPPER) QueryWrapper<PatientBaseInfoDto> queryWrapper);
/**
* 门诊信息分页查询
*
* @param typeCode 参与者身份类型枚举类ParticipantType
* @param page 分页参数
* @param queryWrapper 查询条件
* @return 门诊信息列表
* 查询患者身份信息
*
* @param patientIdList 患者id集合
* @return 患者身份信息
*/
IPage<OutpatientRecordDto> getOutpatientRecord(@Param("typeCode") String typeCode,
@Param("page") Page<OutpatientRecordDto> page,
@Param(Constants.WRAPPER) QueryWrapper<OutpatientRecordDto> queryWrapper);
/**
* 获取医生名字列表
*
* @return 医生名字列表
*/
List<String> getDoctorNames();
List<PatientIdInfoDto> getPatientIdInfo(@Param("patientIdList") List<Long> patientIdList);
}

View File

@@ -72,4 +72,6 @@ public interface IChargeBillService {
*/
R<?> checkYbNo();
}

View File

@@ -70,4 +70,10 @@ public interface ThreePartPayService {
*/
R<?> getPage(String searchKey, Integer pageNo, Integer pageSize, HttpServletRequest request);
/**
* 付款(师大中银)
* @param threePartPayDto 前台参数
* @return 结果
*/
R<?> payForNenu(ThreePartPayDto threePartPayDto);
}

View File

@@ -1326,14 +1326,20 @@ public class EleInvoiceServiceImpl implements IEleInvoiceService {
clinicSettle.setAcctPay(clinicSettle.getAcctPay() == null ? ZERO : clinicSettle.getAcctPay());
// 医保统筹基金支付
clinicSettle.setHifpPay(clinicSettle.getHifpPay() == null ? ZERO : clinicSettle.getHifpPay());
// 自费金额
// 自费金额2025/12/25 朝阳红旗中医院:电子发票个人自费=医保丙类+超限价)
//BigDecimal fulamtOwnPayAmt = clinicSettle.getFulamtOwnpayAmt()==null?ZERO:clinicSettle.getFulamtOwnpayAmt();
//BigDecimal overLmtSelfpay = clinicSettle.getOverlmtSelfpay()==null?ZERO:clinicSettle.getOverlmtSelfpay();
//全自费
clinicSettle
.setFulamtOwnpayAmt(clinicSettle.getFulamtOwnpayAmt() == null ? ZERO : clinicSettle.getFulamtOwnpayAmt());
// 个人自负
clinicSettle.setPsnPartAmt(clinicSettle.getPsnPartAmt() == null ? ZERO : clinicSettle.getPsnPartAmt());
// 个人自付
// 超限价
clinicSettle
.setOverlmtSelfpay(clinicSettle.getOverlmtSelfpay() == null ? ZERO : clinicSettle.getOverlmtSelfpay());
//先行自付
clinicSettle
.setPreselfpayAmt(clinicSettle.getPreselfpayAmt() == null ? ZERO : clinicSettle.getPreselfpayAmt());
// 个人现金支付
clinicSettle.setPsnCashPay(clinicSettle.getPsnCashPay() == null ? ZERO : clinicSettle.getPsnCashPay());
// 医保报销总金额
@@ -1343,10 +1349,17 @@ public class EleInvoiceServiceImpl implements IEleInvoiceService {
bill.put("accountPay", df.format(clinicSettle.getAcctPay()));
// fundPay 医保统筹基金支付 Number 14,2 是
bill.put("fundPay", df.format(clinicSettle.getHifpPay()));
// ownPay 自费金额 Number 14,2 是
bill.put("ownPay", df.format(clinicSettle.getFulamtOwnpayAmt()));
// selfConceitedAmt 个人自负 Number 14,2 是
bill.put("selfConceitedAmt", df.format(clinicSettle.getPsnPartAmt()));
// ownPay 自费金额 Number 14,2 是 2025/12/25 朝阳红旗中医院:电子发票个人自费=医保丙类+超限价)
// 2021-12-15 医保回复:个人自付 = PAY_COST医保账户+psn_part_amt个人现金+ (HIFMI_PAY)大病 -(fulamt_ownpay_amt)个人自费
BigDecimal acctPay = clinicSettle.getAcctPay()==null?ZERO:clinicSettle.getAcctPay();
BigDecimal psnPartAmt = clinicSettle.getPsnPartAmt()==null?ZERO:clinicSettle.getPsnPartAmt();
BigDecimal hifmiPay = clinicSettle.getHifmiPay()==null?ZERO:clinicSettle.getHifmiPay();
BigDecimal fulamtOwnpayAmt = clinicSettle.getFulamtOwnpayAmt()==null?ZERO:clinicSettle.getFulamtOwnpayAmt();
bill.put("ownPay", df.format(acctPay.add(psnPartAmt).add(hifmiPay).subtract(fulamtOwnpayAmt)));
// selfConceitedAmt 个人自负 Number 14,2 是 2025/12/25 朝阳红旗中医院:电子发票个人自付=医保乙类后患者自付的部分)
// 2021-12-15 医保回复:个人自费:全自费金额
bill.put("selfConceitedAmt", df.format(clinicSettle.getFulamtOwnpayAmt()));
// selfPayAmt 个人自付 Number 14,2 是
bill.put("selfPayAmt", df.format(clinicSettle.getOverlmtSelfpay()));
// selfCashPay 个人现金支付 Number 14,2 是
@@ -1635,7 +1648,7 @@ public class EleInvoiceServiceImpl implements IEleInvoiceService {
*/
private InvoiceBaseInfoDto getClinicSettleByPaymentId(Long paymentId) {
PaymentReconciliation paymentReconciliation = paymentReconciliationService.getById(paymentId);
//PaymentReconciliation paymentReconciliation = paymentReconciliationService.getById(paymentId);
List<PaymentRecDetail> details = paymentRecDetailService
.list(new LambdaQueryWrapper<PaymentRecDetail>().eq(PaymentRecDetail::getReconciliationId, paymentId));
@@ -1646,6 +1659,14 @@ public class EleInvoiceServiceImpl implements IEleInvoiceService {
if (YbPayment.SELF_CASH_PAY.getValue().equals(detail.getPayEnum())) {
invoiceBaseInfoDto.setPsnCashPay(detail.getAmount());
}
// 个人现金
if (YbPayment.SELF_PAY.getValue().equals(detail.getPayEnum())) {
invoiceBaseInfoDto.setPsnPartAmt(detail.getAmount());
}
// 居民大病保险资金支出
if (YbPayment.YB_BC_JM_DB_VALUE.getValue().equals(detail.getPayEnum())) {
invoiceBaseInfoDto.setHifmiPay(detail.getAmount());
}
// 公务员补助
if (YbPayment.YB_BC_GWY_BZ_VALUE.getValue().equals(detail.getPayEnum())) {
invoiceBaseInfoDto.setCvlservPay(detail.getAmount());
@@ -1660,12 +1681,12 @@ public class EleInvoiceServiceImpl implements IEleInvoiceService {
}
// 全自费金额
if (YbPayment.FULAMT_OWNPAY_AMT.getValue().equals(detail.getPayEnum())) {
invoiceBaseInfoDto.setPsnPartAmt(detail.getAmount());
}
// 个人负担总金额
if (YbPayment.SELF_PAY.getValue().equals(detail.getPayEnum())) {
invoiceBaseInfoDto.setFulamtOwnpayAmt(detail.getAmount());
}
// 个人负担总金额
//if (YbPayment.SELF_PAY.getValue().equals(detail.getPayEnum())) {
// invoiceBaseInfoDto.setFulamtOwnpayAmt(detail.getAmount());
//}
// 基金支付总额
if (YbPayment.YB_FUND_PAY.getValue().equals(detail.getPayEnum())) {
invoiceBaseInfoDto.setFundPaySumamt(detail.getAmount());
@@ -1682,6 +1703,10 @@ public class EleInvoiceServiceImpl implements IEleInvoiceService {
if (YbPayment.OVERLMT_SELFPAY.getValue().equals(detail.getPayEnum())) {
invoiceBaseInfoDto.setOverlmtSelfpay(detail.getAmount());
}
// 先行自付费用
if (YbPayment.PRESELFPAY_AMT.getValue().equals(detail.getPayEnum())) {
invoiceBaseInfoDto.setPreselfpayAmt(detail.getAmount());
}
// 学校垫支
if (YbPayment.SCHOOL_GF_PAY.getValue().equals(detail.getPayEnum())) {
invoiceBaseInfoDto.setGfRatio(detail.getAmount());

View File

@@ -2209,8 +2209,12 @@ public class PaymentRecServiceImpl implements IPaymentRecService {
if (!PaymentStatus.DRAFT.getValue().equals(paymentReconciliation.getStatusEnum())) {
return R.fail("该账单不是待支付账单");
}
if (!paymentDto.getChargeItemIds().stream().map(String::valueOf).collect(Collectors.joining(","))
.equals(paymentReconciliation.getChargeItemIds())) {
// 收费项一致校验
List<Long> chargeItemIds = paymentDto.getChargeItemIds().stream().sorted().toList();
List<Long> chargeItemIdList = Arrays.stream(paymentReconciliation.getChargeItemIds().split(","))
.map(String::trim).filter(s -> !s.isEmpty()).map(Long::valueOf).sorted().toList();
if (!chargeItemIds.equals(chargeItemIdList)) {
return R.fail("收费项目变动,请重新预结算");
}
@@ -2224,17 +2228,14 @@ public class PaymentRecServiceImpl implements IPaymentRecService {
}
// 校验金额:前台输入金额与仍需支付的现金部分进行比较
if (newPayment != null) {
BigDecimal sum = newPayment.getTenderedAmount();
BigDecimal chargeAmount = BigDecimal.ZERO;
for (PaymentDetailDto paymentDetail : paymentDto.getPaymentDetails()) {
chargeAmount = chargeAmount.add(paymentDetail.getAmount());
}
// 前台传入数据可能会精度丢失,后台临时处理使用近似
if (sum.setScale(2, BigDecimal.ROUND_HALF_UP)
.compareTo(chargeAmount.setScale(2, BigDecimal.ROUND_HALF_UP)) != 0) {
throw new ServiceException("交款金额与预结算金额不相等");
}
BigDecimal sum = paymentReconciliation.getTenderedAmount();
BigDecimal chargeAmount = BigDecimal.ZERO;
for (PaymentDetailDto paymentDetail : paymentDto.getPaymentDetails()) {
chargeAmount = chargeAmount.add(paymentDetail.getAmount());
}
// 前台传入数据可能会精度丢失,后台临时处理使用近似
if (sum.setScale(2, RoundingMode.HALF_UP).compareTo(chargeAmount.setScale(2, RoundingMode.HALF_UP)) != 0) {
throw new ServiceException("交款金额与预结算金额不相等");
}
// <2> 查询基础数据
@@ -2337,14 +2338,12 @@ public class PaymentRecServiceImpl implements IPaymentRecService {
if (minAmountResult != null) {
// 账户余额
BigDecimal balc = minAmountResult.getBalc();
if (balc != null) {
PaymentRecDetail paymentRecDetail = new PaymentRecDetail();
paymentRecDetail.setReconciliationId(paymentReconciliation.getId())
.setPayEnum(YbPayment.BALC.getValue()).setPayLevelEnum(YbPayment.BALC.getLevel()).setAmount(balc)
.setPayTransNo(minAmountResult.getChrgBchno()).setResultEnum(PaymentResult.PAID.getValue())
.setAccountId(minAmountResult.getAccountId()).setPayTransText(minAmountResult.getSetlId());
iPaymentRecDetailService.save(paymentRecDetail);
}
PaymentRecDetail paymentRecDetail = new PaymentRecDetail();
paymentRecDetail.setReconciliationId(paymentReconciliation.getId()).setPayEnum(YbPayment.BALC.getValue())
.setPayLevelEnum(YbPayment.BALC.getLevel()).setAmount(balc)
.setPayTransNo(minAmountResult.getChrgBchno()).setResultEnum(PaymentResult.PAID.getValue())
.setAccountId(minAmountResult.getAccountId()).setPayTransText(minAmountResult.getSetlId());
iPaymentRecDetailService.save(paymentRecDetail);
}
// 更改chargeItem的状态
@@ -2795,43 +2794,44 @@ public class PaymentRecServiceImpl implements IPaymentRecService {
@Override
public List<PaymentDetailDto> cancelPreReg(Long encounterId) {
List<PaymentReconciliation> paymentReconciliationList = paymentReconciliationService.list(new LambdaQueryWrapper<PaymentReconciliation>().eq(PaymentReconciliation::getEncounterId, encounterId)
.eq(PaymentReconciliation::getDeleteFlag, DelFlag.NO.getCode()).eq(PaymentReconciliation::getStatusEnum, PaymentStatus.SUCCESS.getValue()));
List<PaymentReconciliation> paymentReconciliationList = paymentReconciliationService
.list(new LambdaQueryWrapper<PaymentReconciliation>().eq(PaymentReconciliation::getEncounterId, encounterId)
.eq(PaymentReconciliation::getDeleteFlag, DelFlag.NO.getCode())
.eq(PaymentReconciliation::getStatusEnum, PaymentStatus.SUCCESS.getValue()));
List<Long> chargeItemIdList = paymentReconciliationList.stream()
.map(item -> item.getChargeItemIds()) // 获取逗号分隔的字符串属性
.filter(str -> str != null && !str.trim().isEmpty()) // 过滤空值
.flatMap(str -> Arrays.stream(str.split(","))) // 按逗号分割并扁平化
.map(String::trim) // 去除空格
.filter(s -> !s.isEmpty()) // 过滤空字符串
.map(Long::valueOf) // 转换为Long
.collect(Collectors.toList());
List<Long> chargeItemIdList = paymentReconciliationList.stream().map(item -> item.getChargeItemIds()) // 获取逗号分隔的字符串属性
.filter(str -> str != null && !str.trim().isEmpty()) // 过滤空值
.flatMap(str -> Arrays.stream(str.split(","))) // 按逗号分割并扁平化
.map(String::trim) // 去除空格
.filter(s -> !s.isEmpty()) // 过滤空字符串
.map(Long::valueOf) // 转换为Long
.collect(Collectors.toList());
List<ChargeItemBaseInfoDto> chargeItemBaseInfoByIds = chargeItemService.getChargeItemBaseInfoByIds(chargeItemIdList);
List<ChargeItemBaseInfoDto> chargeItemBaseInfoByIds =
chargeItemService.getChargeItemBaseInfoByIds(chargeItemIdList);
// 查找第一个匹配的对象
Optional<ChargeItemBaseInfoDto> targetObject = chargeItemBaseInfoByIds.stream()
.filter(item -> CommonConstants.TableName.ADM_HEALTHCARE_SERVICE.equals(item.getServiceTable()))
.findFirst();
.filter(item -> CommonConstants.TableName.ADM_HEALTHCARE_SERVICE.equals(item.getServiceTable()))
.findFirst();
// 使用方式
long foundItemId;
if (targetObject.isPresent()) {
foundItemId = targetObject.get().getId();
} else {
throw new ServiceException("未找到挂号的付款记录提示信息encounterId"+encounterId);
throw new ServiceException("未找到挂号的付款记录提示信息encounterId" + encounterId);
}
long finalFoundItemId = foundItemId;
Optional<PaymentReconciliation> paymentReconciliation = paymentReconciliationList.stream()
.filter(item -> item.getChargeItemIds().contains(String.valueOf(finalFoundItemId)))
.findFirst();
.filter(item -> item.getChargeItemIds().contains(String.valueOf(finalFoundItemId))).findFirst();
long paymentId;
if (paymentReconciliation.isPresent()) {
paymentId = paymentReconciliation.get().getId();
} else {
throw new ServiceException("未找到挂号的付款记录提示信息encounterId"+encounterId);
throw new ServiceException("未找到挂号的付款记录提示信息encounterId" + encounterId);
}
List<PaymentDetailDto> detail = this.getDetail(new PaymentDto().setId(paymentId));

View File

@@ -612,4 +612,12 @@ public class ThreePartPayServiceImpl implements ThreePartPayService {
}
return resultString;
}
@Override
public R<?> payForNenu(ThreePartPayDto threePartPayDto) {
return null;
}
}

View File

@@ -70,6 +70,17 @@ public class ThreePartPayController {
return threePartPayService.payFor(threePartPayDto);
}
/**
* 扫码付款(师大)
* @return
*/
@PostMapping("/pay-for-nenu")
public R<?> payForNenu(@RequestBody ThreePartPayDto threePartPayDto){
return threePartPayService.payForNenu(threePartPayDto);
}
/**
* 扫码付款结果查询(预结算窗口)
* @return

View File

@@ -237,7 +237,7 @@ public class MedicalDeviceDispenseAppServiceImpl implements IMedicalDeviceDispen
List<UnDispenseInventoryDto> inventoryList = entry.getValue();
if (!inventoryList.isEmpty()) {
if (inventoryList.stream().map(UnDispenseInventoryDto::getInventoryStatusEnum)
.anyMatch(x -> x.equals(PublicationStatus.RETIRED.getValue()))) {
.allMatch(x -> x.equals(PublicationStatus.RETIRED.getValue()))) {
// 停供库存校验
return R.fail(inventoryList.get(0).getItemName() + "库存已停供");
}
@@ -426,7 +426,7 @@ public class MedicalDeviceDispenseAppServiceImpl implements IMedicalDeviceDispen
List<UnDispenseInventoryDto> inventoryList = entry.getValue();
if (!inventoryList.isEmpty()) {
if (inventoryList.stream().map(UnDispenseInventoryDto::getInventoryStatusEnum)
.anyMatch(x -> x.equals(PublicationStatus.RETIRED.getValue()))) {
.allMatch(x -> x.equals(PublicationStatus.RETIRED.getValue()))) {
// 停供库存校验
return R.fail(inventoryList.get(0).getItemName() + "库存已停供");
}

Some files were not shown because too many files have changed in this diff Show More