版本更新

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

View File

@@ -3,6 +3,9 @@ package com.openhis.web.datadictionary.appservice;
import java.util.List;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import org.springframework.web.multipart.MultipartFile;
import com.core.common.core.domain.R;
import com.openhis.web.datadictionary.dto.DiagnosisTreatmentSelParam;
@@ -75,4 +78,18 @@ public interface IDiagTreatMAppService {
*/
R<?> addDiseaseTreatment(DiagnosisTreatmentUpDto diagnosisTreatmentUpDto);
/**
* 导入诊疗目录
*
* @param file 文件
* @return 结果
*/
R<?> importData(MultipartFile file);
/**
* 获取导入模板
*
* @param response 响应
*/
void importTemplate(HttpServletResponse response);
}

View File

@@ -3,7 +3,7 @@
*/
package com.openhis.web.datadictionary.appservice.impl;
import java.io.IOException;
import java.math.BigDecimal;
import java.util.*;
import java.util.concurrent.CopyOnWriteArrayList;
import java.util.stream.Collectors;
@@ -35,10 +35,14 @@ import com.openhis.administration.domain.ChargeItemDefinition;
import com.openhis.administration.domain.DeviceDefinition;
import com.openhis.administration.domain.Location;
import com.openhis.administration.domain.Supplier;
import com.openhis.administration.service.*;
import com.openhis.administration.service.IChargeItemDefinitionService;
import com.openhis.administration.service.IDeviceDefinitionService;
import com.openhis.administration.service.ILocationService;
import com.openhis.administration.service.ISupplierService;
import com.openhis.common.constant.CommonConstants;
import com.openhis.common.constant.PromptMsgConstant;
import com.openhis.common.enums.*;
import com.openhis.common.utils.CommonUtil;
import com.openhis.common.utils.EnumUtils;
import com.openhis.common.utils.HisQueryUtils;
import com.openhis.sys.service.IOperationRecordService;
@@ -65,10 +69,7 @@ public class DeviceManageAppServiceImpl implements IDeviceManageAppService {
private IDeviceDefinitionService deviceDefinitionService;
@Autowired
IChargeItemDefinitionService chargeItemDefinitionService;
@Autowired
IChargeItemDefDetailService chargeItemDefDetailService;
private IChargeItemDefinitionService chargeItemDefinitionService;
@Autowired
private ILocationService locationService;
@@ -386,7 +387,7 @@ public class DeviceManageAppServiceImpl implements IDeviceManageAppService {
@Override
public R<?> importData(MultipartFile file) {
// 读取文件
R<List<DeviceImportDto>> readResult = readExcelFile(file);
R<List<DeviceImportDto>> readResult = CommonUtil.readImportedExcelFile(file, DeviceImportDto.class);
if (R.SUCCESS != readResult.getCode()) {
return readResult;
}
@@ -396,9 +397,8 @@ public class DeviceManageAppServiceImpl implements IDeviceManageAppService {
if (R.SUCCESS != validateResult.getCode()) {
return validateResult;
}
// 查询机构ID、当前时间、位置信息供后续使用
// 查询机构ID、位置信息供后续使用
Long orgId = SecurityUtils.getLoginUser().getOrgId();
Date now = DateUtils.getNowDate();
List<Location> locationList = locationService.list(new LambdaQueryWrapper<Location>()
.eq(Location::getDeleteFlag, DeleteFlag.NOT_DELETED.getCode()).orderByAsc(Location::getId));
Long defaultLocationId = locationList.stream().findFirst().orElse(new Location()).getId();
@@ -406,7 +406,15 @@ public class DeviceManageAppServiceImpl implements IDeviceManageAppService {
locationList.stream().collect(Collectors.groupingBy(Location::getName));
// 创建表数据
for (DeviceImportDto importDto : importDtoList) {
// 创建器材定义
DeviceDefinition deviceDefinition =
createDeviceDefinitionEntity(importDto, orgId, defaultLocationId, locationNameMap);
deviceDefinitionService.save(deviceDefinition);
// 创建费用定价和详情
chargeItemDefinitionService.addChargeItemDefinitionAndDetail(importDto.getName(), importDto.getTypeCode(),
importDto.getYbType(), importDto.getUnitCode(), importDto.getPurchasePrice(),
importDto.getRetailPrice(), importDto.getMaximumRetailPrice(), orgId,
CommonConstants.TableName.ADM_DEVICE_DEFINITION, deviceDefinition.getId());
}
return R.ok(null, "导入成功!");
}
@@ -422,26 +430,6 @@ public class DeviceManageAppServiceImpl implements IDeviceManageAppService {
util.importTemplateExcel(response, "器材目录数据");
}
/**
* 读取Excel文件
*
* @param file 文件
* @return 读取结果
*/
private R<List<DeviceImportDto>> readExcelFile(MultipartFile file) {
ExcelUtil<DeviceImportDto> util = new ExcelUtil<>(DeviceImportDto.class);
List<DeviceImportDto> importDtoList;
try {
importDtoList = util.importExcel(file.getInputStream());
} catch (IOException e) {
return R.fail("导入失败!文件读取异常");
}
if (importDtoList.isEmpty()) {
return R.fail("导入失败!文件不能为空");
}
return R.ok(importDtoList);
}
/**
* 导入信息校验
*
@@ -449,11 +437,147 @@ public class DeviceManageAppServiceImpl implements IDeviceManageAppService {
*/
private R<?> validateImportDtoList(List<DeviceImportDto> importDtoList) {
// 字段校验(必填及数值类型)
List<String> fieldValidateMsgList = new ArrayList<>();
for (int i = 0; i < importDtoList.size(); i++) {
DeviceImportDto importDto = importDtoList.get(i);
importDto.setLineNumber(i + 2);
List<String> lineValidateMsgList = new ArrayList<>();
if (StringUtils.isEmpty(importDto.getName())) {
lineValidateMsgList.add("器材名称必填");
}
if (StringUtils.isEmpty(importDto.getCategoryCode())) {
lineValidateMsgList.add("器材分类必填");
}
if (StringUtils.isEmpty(importDto.getUnitCode())) {
lineValidateMsgList.add("包装单位必填");
}
if (StringUtils.isEmpty(importDto.getSize())) {
lineValidateMsgList.add("包装规格必填");
}
if (StringUtils.isEmpty(importDto.getItemMinQuantityStr())) {
lineValidateMsgList.add("最小库存警戒数量(常规单位)必填");
}
BigDecimal itemMinQuantity;
try {
itemMinQuantity = new BigDecimal(importDto.getItemMinQuantityStr());
importDto.setItemMinQuantity(itemMinQuantity);
} catch (Exception e) {
lineValidateMsgList.add("最小库存警戒数量(常规单位)应为数值类型");
}
if (StringUtils.isEmpty(importDto.getItemMaxQuantityStr())) {
lineValidateMsgList.add("最大库存警戒数量(常规单位)必填");
}
BigDecimal itemMaxQuantity;
try {
itemMaxQuantity = new BigDecimal(importDto.getItemMaxQuantityStr());
importDto.setItemMaxQuantity(itemMaxQuantity);
} catch (Exception e) {
lineValidateMsgList.add("最大库存警戒数量(常规单位)应为数值类型");
}
if (StringUtils.isEmpty(importDto.getPartPercentStr())) {
lineValidateMsgList.add("拆零比必填");
}
BigDecimal partPercent;
try {
partPercent = new BigDecimal(importDto.getPartPercentStr());
importDto.setPartPercent(partPercent);
} catch (Exception e) {
lineValidateMsgList.add("拆零比应为数值类型");
}
if (StringUtils.isEmpty(importDto.getLocationName())) {
lineValidateMsgList.add("所在位置名称必填");
}
if (StringUtils.isEmpty(importDto.getHvcmFlag())) {
lineValidateMsgList.add("高值器材标志必填");
}
if (StringUtils.isEmpty(importDto.getYbFlag())) {
lineValidateMsgList.add("医保标记必填");
}
if (StringUtils.isEmpty(importDto.getYbMatchFlag())) {
lineValidateMsgList.add("医保对码标记必填");
}
if (Whether.YES.getCode().equals(importDto.getYbMatchFlag()) && StringUtils.isEmpty(importDto.getYbNo())) {
lineValidateMsgList.add("医保对码时,医保编码必填");
}
if (StringUtils.isEmpty(importDto.getAllergenFlag())) {
lineValidateMsgList.add("过敏标记必填");
}
if (StringUtils.isEmpty(importDto.getRxFlag())) {
lineValidateMsgList.add("处方标志必填");
}
if (StringUtils.isEmpty(importDto.getTypeCode())) {
lineValidateMsgList.add("财务类别必填");
}
if (StringUtils.isEmpty(importDto.getYbType())) {
lineValidateMsgList.add("医保费用类别必填");
}
if (StringUtils.isEmpty(importDto.getPurchasePriceStr())) {
lineValidateMsgList.add("购入价必填");
}
BigDecimal purchasePrice;
try {
purchasePrice = new BigDecimal(importDto.getPurchasePriceStr());
importDto.setPurchasePrice(purchasePrice);
} catch (Exception e) {
lineValidateMsgList.add("购入价应为数值类型");
}
if (StringUtils.isEmpty(importDto.getRetailPriceStr())) {
lineValidateMsgList.add("零售价必填");
}
BigDecimal retailPrice;
try {
retailPrice = new BigDecimal(importDto.getRetailPriceStr());
importDto.setRetailPrice(retailPrice);
} catch (Exception e) {
lineValidateMsgList.add("零售价应为数值类型");
}
if (StringUtils.isEmpty(importDto.getMaximumRetailPriceStr())) {
lineValidateMsgList.add("最高零售价必填");
}
BigDecimal maximumRetailPrice;
try {
maximumRetailPrice = new BigDecimal(importDto.getMaximumRetailPriceStr());
importDto.setMaximumRetailPrice(maximumRetailPrice);
} catch (Exception e) {
lineValidateMsgList.add("最高零售价应为数值类型");
}
if (!lineValidateMsgList.isEmpty()) {
fieldValidateMsgList
.add("■ 第" + importDto.getLineNumber() + "行:" + String.join("", lineValidateMsgList) + "");
}
}
if (!fieldValidateMsgList.isEmpty()) {
return R.fail("导入失败!器材信息填写有误:" + String.join(" ", fieldValidateMsgList));
}
// 重复校验(文件行重复)
List<String> lineRepeatedValidateMsgList = new ArrayList<>();
List<List<DeviceImportDto>> importDtoGroupList = new ArrayList<>(importDtoList.stream()
.collect(Collectors.groupingBy(e -> e.getName() + e.getManufacturerText() + e.getSize())).values());
for (List<DeviceImportDto> importDtoGroup : importDtoGroupList) {
if (importDtoGroup.size() > 1) {
lineRepeatedValidateMsgList.add(
"■ 第" + importDtoGroup.stream().map(DeviceImportDto::getLineNumber).sorted().map(Object::toString)
.collect(Collectors.joining(",")) + "行的【" + importDtoGroup.get(0).getName() + "】重复;");
}
}
if (!lineRepeatedValidateMsgList.isEmpty()) {
return R.fail("导入失败!文件中存在重复器材:" + String.join(" ", lineRepeatedValidateMsgList));
}
// 重复校验(文件与数据库重复)
List<String> dbRepeatedValidateMsgList = new ArrayList<>();
for (DeviceImportDto importDto : importDtoList) {
List<DeviceDefinition> deviceDefinitionList = deviceDefinitionService
.list(new LambdaQueryWrapper<DeviceDefinition>().eq(DeviceDefinition::getName, importDto.getName())
.eq(DeviceDefinition::getManufacturerText, importDto.getManufacturerText())
.eq(DeviceDefinition::getSize, importDto.getSize()));
if (!deviceDefinitionList.isEmpty()) {
dbRepeatedValidateMsgList
.add("■ 第" + importDto.getLineNumber() + "行的【" + importDto.getName() + "】在系统中已存在;");
}
}
if (!dbRepeatedValidateMsgList.isEmpty()) {
return R.fail("导入失败!系统中存在重复器材:" + String.join(" ", dbRepeatedValidateMsgList));
}
return R.ok();
}
@@ -461,11 +585,37 @@ public class DeviceManageAppServiceImpl implements IDeviceManageAppService {
* 创建器材定义实体
*
* @param importDto 器材目录导入Dto
* @param orgId 机构ID
* @param defaultLocationId 默认位置ID
* @param locationNameMap 位置名称匹配分组Map
* @return 器材定义实体
*/
private DeviceDefinition createDeviceDefinitionEntity(DeviceImportDto importDto) {
return null;
private DeviceDefinition createDeviceDefinitionEntity(DeviceImportDto importDto, Long orgId, Long defaultLocationId,
Map<String, List<Location>> locationNameMap) {
DeviceDefinition deviceDefinition = new DeviceDefinition();
// 根据输入的所在位置名称获取位置ID
List<Location> mapLocationList = locationNameMap.get(importDto.getLocationName());
if (mapLocationList == null || mapLocationList.isEmpty()) {
deviceDefinition.setLocationId(defaultLocationId);
} else {
deviceDefinition.setLocationId(mapLocationList.get(0).getId());
}
deviceDefinition.setBusNo(assignSeqUtil.getSeq(AssignSeqEnum.DEVICE_NUM.getPrefix(), 10))
.setName(importDto.getName()).setPyStr(ChineseConvertUtils.toPinyinFirstLetter(importDto.getName()))
.setWbStr(ChineseConvertUtils.toWBFirstLetter(importDto.getName()))
.setCategoryCode(importDto.getCategoryCode()).setTypeCode(importDto.getTypeCode())
.setUnitCode(importDto.getUnitCode()).setSize(importDto.getSize())
.setItemMinQuantity(importDto.getItemMinQuantity()).setItemMaxQuantity(importDto.getItemMaxQuantity())
.setPartPercent(importDto.getPartPercent()).setMinUnitCode(importDto.getMinUnitCode()).setOrgId(orgId)
.setHvcmFlag(CommonUtil.tryParseInt(importDto.getHvcmFlag())).setSalesUnitCode(importDto.getSalesUnitCode())
.setApprovalNumber(importDto.getApprovalNumber()).setYbFlag(CommonUtil.tryParseInt(importDto.getYbFlag()))
.setYbNo(importDto.getYbNo()).setYbOrgNo(importDto.getYbOrgNo())
.setYbMatchFlag(CommonUtil.tryParseInt(importDto.getYbMatchFlag()))
.setChrgitmLv(CommonUtil.tryParseInt(importDto.getChrgitmLv()))
.setStatusEnum(PublicationStatus.ACTIVE.getValue()).setManufacturerText(importDto.getManufacturerText())
.setAllergenFlag(CommonUtil.tryParseInt(importDto.getAllergenFlag()))
.setRxFlag(CommonUtil.tryParseInt(importDto.getRxFlag()));
return deviceDefinition;
}
}

View File

@@ -1,5 +1,6 @@
package com.openhis.web.datadictionary.appservice.impl;
import java.math.BigDecimal;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.HashSet;
@@ -10,10 +11,11 @@ import java.util.stream.Stream;
import javax.annotation.Resource;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import com.openhis.yb.service.YbManager;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.web.multipart.MultipartFile;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
@@ -23,13 +25,16 @@ import com.core.common.core.domain.R;
import com.core.common.core.domain.entity.SysDictData;
import com.core.common.utils.*;
import com.core.common.utils.bean.BeanUtils;
import com.core.common.utils.poi.ExcelUtil;
import com.core.system.service.ISysDictTypeService;
import com.openhis.administration.domain.ChargeItemDefinition;
import com.openhis.administration.domain.Organization;
import com.openhis.administration.service.IChargeItemDefinitionService;
import com.openhis.administration.service.IOrganizationService;
import com.openhis.common.constant.CommonConstants;
import com.openhis.common.constant.PromptMsgConstant;
import com.openhis.common.enums.*;
import com.openhis.common.utils.CommonUtil;
import com.openhis.common.utils.EnumUtils;
import com.openhis.common.utils.HisQueryUtils;
import com.openhis.sys.service.IOperationRecordService;
@@ -41,6 +46,7 @@ import com.openhis.web.datadictionary.mapper.ActivityDefinitionManageMapper;
import com.openhis.workflow.domain.ActivityDefinition;
import com.openhis.workflow.mapper.ActivityDefinitionMapper;
import com.openhis.workflow.service.IActivityDefinitionService;
import com.openhis.yb.service.YbManager;
/**
* 诊疗实现类
@@ -52,7 +58,9 @@ import com.openhis.workflow.service.IActivityDefinitionService;
public class DiagTreatMAppServiceImpl implements IDiagTreatMAppService {
@Autowired
private IActivityDefinitionService iActivityDefinitionService;
private IActivityDefinitionService activityDefinitionService;
@Autowired
private IChargeItemDefinitionService chargeItemDefinitionService;
@Autowired
private ActivityDefinitionMapper activityDefinitionMapper;
@Autowired
@@ -110,15 +118,15 @@ public class DiagTreatMAppServiceImpl implements IDiagTreatMAppService {
.collect(Collectors.toList());
diagnosisTreatmentInitDto.setDiagnosisCategoryOptions(diagnosisCategories);
// // 查询医疗服务项类型
// List<SysDictData> medical_service_items =
// iSysDictTypeService.selectDictDataByType(ActivityDefCategory.MEDICAL_SERVICE_ITEM.getCode());
// // 获取医疗服务项List
// List<DiagnosisTreatmentInitDto.diseaseTreatmentType> diseaseTreatmentCategoryList = medical_service_items
// .stream().map(status -> new DiagnosisTreatmentInitDto.diseaseTreatmentType(status.getDictValue(),
// status.getDictLabel()))
// .toList();
// List<DiagnosisTreatmentInitDto.diseaseTreatmentCategory> diseaseTreatmentCategories = new ArrayList<>();
// // 查询医疗服务项类型
// List<SysDictData> medical_service_items =
// iSysDictTypeService.selectDictDataByType(ActivityDefCategory.MEDICAL_SERVICE_ITEM.getCode());
// // 获取医疗服务项List
// List<DiagnosisTreatmentInitDto.diseaseTreatmentType> diseaseTreatmentCategoryList = medical_service_items
// .stream().map(status -> new DiagnosisTreatmentInitDto.diseaseTreatmentType(status.getDictValue(),
// status.getDictLabel()))
// .toList();
// List<DiagnosisTreatmentInitDto.diseaseTreatmentCategory> diseaseTreatmentCategories = new ArrayList<>();
//
// //获取目录分类
// DiagnosisTreatmentInitDto.diseaseTreatmentCategory diseaseTreatmentCategory =
@@ -233,10 +241,10 @@ public class DiagTreatMAppServiceImpl implements IDiagTreatMAppService {
activityDefinition.setWbStr(ChineseConvertUtils.toWBFirstLetter(activityDefinition.getName()));
// 更新诊疗信息
if (iActivityDefinitionService.updateById(activityDefinition)) {
if (activityDefinitionService.updateById(activityDefinition)) {
// 调用医保目录对照接口
String ybSwitch = SecurityUtils.getLoginUser().getOptionJson().getString(CommonConstants.Option.YB_SWITCH); // 医保开关
if (Whether.YES.getCode().equals(ybSwitch) && StringUtils.isNotEmpty(activityDefinition.getYbNo()) ) {
if (Whether.YES.getCode().equals(ybSwitch) && StringUtils.isNotEmpty(activityDefinition.getYbNo())) {
R<?> r = ybService.directoryCheck(CommonConstants.TableName.WOR_ACTIVITY_DEFINITION,
activityDefinition.getId());
if (200 != r.getCode()) {
@@ -294,7 +302,7 @@ public class DiagTreatMAppServiceImpl implements IDiagTreatMAppService {
iOperationRecordService.addIdsOperationRecord(DbOpType.STOP.getCode(),
CommonConstants.TableName.WOR_ACTIVITY_DEFINITION, ids);
// 更新诊疗信息
return iActivityDefinitionService.updateBatchById(ActivityDefinitionList)
return activityDefinitionService.updateBatchById(ActivityDefinitionList)
? R.ok(null, MessageUtils.createMessage(PromptMsgConstant.Common.M00002, new Object[] {"诊疗目录"}))
: R.fail(null, MessageUtils.createMessage(PromptMsgConstant.Common.M00007, null));
@@ -322,7 +330,7 @@ public class DiagTreatMAppServiceImpl implements IDiagTreatMAppService {
iOperationRecordService.addIdsOperationRecord(DbOpType.START.getCode(),
CommonConstants.TableName.WOR_ACTIVITY_DEFINITION, ids);
// 更新诊疗信息
return iActivityDefinitionService.updateBatchById(ActivityDefinitionList)
return activityDefinitionService.updateBatchById(ActivityDefinitionList)
? R.ok(null, MessageUtils.createMessage(PromptMsgConstant.Common.M00002, new Object[] {"诊疗目录"}))
: R.fail(null, MessageUtils.createMessage(PromptMsgConstant.Common.M00007, null));
@@ -355,10 +363,10 @@ public class DiagTreatMAppServiceImpl implements IDiagTreatMAppService {
// 新增外来诊疗目录
activityDefinition.setStatusEnum(PublicationStatus.ACTIVE.getValue());
if (iActivityDefinitionService.addDiagnosisTreatment(activityDefinition)) {
if (activityDefinitionService.addDiagnosisTreatment(activityDefinition)) {
// 调用医保目录对照接口
String ybSwitch = SecurityUtils.getLoginUser().getOptionJson().getString(CommonConstants.Option.YB_SWITCH); // 医保开关
if (Whether.YES.getCode().equals(ybSwitch) && StringUtils.isNotEmpty(activityDefinition.getYbNo()) ) {
if (Whether.YES.getCode().equals(ybSwitch) && StringUtils.isNotEmpty(activityDefinition.getYbNo())) {
R<?> r = ybService.directoryCheck(CommonConstants.TableName.WOR_ACTIVITY_DEFINITION,
activityDefinition.getId());
if (200 != r.getCode()) {
@@ -387,4 +395,169 @@ public class DiagTreatMAppServiceImpl implements IDiagTreatMAppService {
}
/**
* 导入诊疗目录
*
* @param file 文件
* @return 结果
*/
@Override
public R<?> importData(MultipartFile file) {
// 读取文件
R<List<DiagnosisTreatmentImportDto>> readResult =
CommonUtil.readImportedExcelFile(file, DiagnosisTreatmentImportDto.class);
if (R.SUCCESS != readResult.getCode()) {
return readResult;
}
List<DiagnosisTreatmentImportDto> importDtoList = readResult.getData();
// 导入信息校验
R<?> validateResult = validateImportDtoList(importDtoList);
if (R.SUCCESS != validateResult.getCode()) {
return validateResult;
}
// 查询机构ID供后续使用
Long orgId = SecurityUtils.getLoginUser().getOrgId();
// 创建表数据
for (DiagnosisTreatmentImportDto importDto : importDtoList) {
// 创建诊疗定义
ActivityDefinition activityDefinition = createActivityDefinitionEntity(importDto, orgId);
activityDefinitionService.save(activityDefinition);
// 创建费用定价和详情
chargeItemDefinitionService.addChargeItemDefinitionAndDetail(importDto.getName(), importDto.getTypeCode(),
importDto.getYbType(), importDto.getPermittedUnitCode(), null, importDto.getRetailPrice(),
importDto.getMaximumRetailPrice(), orgId, CommonConstants.TableName.WOR_ACTIVITY_DEFINITION,
activityDefinition.getId());
}
return R.ok(null, "导入成功!");
}
/**
* 获取导入模板
*
* @param response 响应
*/
@Override
public void importTemplate(HttpServletResponse response) {
ExcelUtil<DiagnosisTreatmentImportDto> util = new ExcelUtil<>(DiagnosisTreatmentImportDto.class);
util.importTemplateExcel(response, "诊疗目录数据");
}
/**
* 导入信息校验
*
* @param importDtoList 器材目录导入数据列表
*/
private R<?> validateImportDtoList(List<DiagnosisTreatmentImportDto> importDtoList) {
// 字段校验(必填及数值类型)
List<String> fieldValidateMsgList = new ArrayList<>();
for (int i = 0; i < importDtoList.size(); i++) {
DiagnosisTreatmentImportDto importDto = importDtoList.get(i);
importDto.setLineNumber(i + 2);
List<String> lineValidateMsgList = new ArrayList<>();
if (StringUtils.isEmpty(importDto.getName())) {
lineValidateMsgList.add("诊疗名称必填");
}
if (StringUtils.isEmpty(importDto.getCategoryCode())) {
lineValidateMsgList.add("目录类别必填");
}
if (StringUtils.isEmpty(importDto.getPermittedUnitCode())) {
lineValidateMsgList.add("使用单位必填");
}
if (StringUtils.isEmpty(importDto.getYbFlag())) {
lineValidateMsgList.add("医保标记必填");
}
if (StringUtils.isEmpty(importDto.getYbMatchFlag())) {
lineValidateMsgList.add("医保对码标记必填");
}
if (Whether.YES.getCode().equals(importDto.getYbMatchFlag()) && StringUtils.isEmpty(importDto.getYbNo())) {
lineValidateMsgList.add("医保对码时,医保编码必填");
}
if (StringUtils.isEmpty(importDto.getChrgitmLv())) {
lineValidateMsgList.add("医保等级必填");
}
if (StringUtils.isEmpty(importDto.getTypeCode())) {
lineValidateMsgList.add("财务类别必填");
}
if (StringUtils.isEmpty(importDto.getYbType())) {
lineValidateMsgList.add("医保费用类别必填");
}
if (StringUtils.isEmpty(importDto.getRetailPriceStr())) {
lineValidateMsgList.add("零售价必填");
}
BigDecimal retailPrice;
try {
retailPrice = new BigDecimal(importDto.getRetailPriceStr());
importDto.setRetailPrice(retailPrice);
} catch (Exception e) {
lineValidateMsgList.add("零售价应为数值类型");
}
if (StringUtils.isEmpty(importDto.getMaximumRetailPriceStr())) {
lineValidateMsgList.add("最高零售价必填");
}
BigDecimal maximumRetailPrice;
try {
maximumRetailPrice = new BigDecimal(importDto.getMaximumRetailPriceStr());
importDto.setMaximumRetailPrice(maximumRetailPrice);
} catch (Exception e) {
lineValidateMsgList.add("最高零售价应为数值类型");
}
if (!lineValidateMsgList.isEmpty()) {
fieldValidateMsgList
.add("■ 第" + importDto.getLineNumber() + "行:" + String.join("", lineValidateMsgList) + "");
}
}
if (!fieldValidateMsgList.isEmpty()) {
return R.fail("导入失败!诊疗信息填写有误:" + String.join(" ", fieldValidateMsgList));
}
// 重复校验(文件行重复)
List<String> lineRepeatedValidateMsgList = new ArrayList<>();
List<List<DiagnosisTreatmentImportDto>> importDtoGroupList = new ArrayList<>(
importDtoList.stream().collect(Collectors.groupingBy(DiagnosisTreatmentImportDto::getName)).values());
for (List<DiagnosisTreatmentImportDto> importDtoGroup : importDtoGroupList) {
if (importDtoGroup.size() > 1) {
lineRepeatedValidateMsgList.add("■ 第"
+ importDtoGroup.stream().map(DiagnosisTreatmentImportDto::getLineNumber).sorted()
.map(Object::toString).collect(Collectors.joining(","))
+ "行的【" + importDtoGroup.get(0).getName() + "】重复;");
}
}
if (!lineRepeatedValidateMsgList.isEmpty()) {
return R.fail("导入失败!文件中存在重复诊疗:" + String.join(" ", lineRepeatedValidateMsgList));
}
// 重复校验(文件与数据库重复)
List<String> dbRepeatedValidateMsgList = new ArrayList<>();
for (DiagnosisTreatmentImportDto importDto : importDtoList) {
List<ActivityDefinition> deviceDefinitionList = activityDefinitionService.list(
new LambdaQueryWrapper<ActivityDefinition>().eq(ActivityDefinition::getName, importDto.getName()));
if (!deviceDefinitionList.isEmpty()) {
dbRepeatedValidateMsgList
.add("■ 第" + importDto.getLineNumber() + "行的【" + importDto.getName() + "】在系统中已存在;");
}
}
if (!dbRepeatedValidateMsgList.isEmpty()) {
return R.fail("导入失败!系统中存在重复诊疗:" + String.join(" ", dbRepeatedValidateMsgList));
}
return R.ok();
}
/**
* 创建诊疗定义实体
*
* @param importDto 器材目录导入Dto
* @param orgId 机构ID
* @return 诊疗定义实体
*/
private ActivityDefinition createActivityDefinitionEntity(DiagnosisTreatmentImportDto importDto, Long orgId) {
ActivityDefinition activityDefinition = new ActivityDefinition();
activityDefinition.setBusNo(assignSeqUtil.getSeq(AssignSeqEnum.ACTIVITY_DEFINITION_NUM.getPrefix(), 10))
.setName(importDto.getName()).setCategoryCode(importDto.getCategoryCode())
.setPyStr(ChineseConvertUtils.toPinyinFirstLetter(importDto.getName()))
.setWbStr(ChineseConvertUtils.toWBFirstLetter(importDto.getName()))
.setPermittedUnitCode(importDto.getPermittedUnitCode()).setOrgId(orgId)
.setYbFlag(CommonUtil.tryParseInt(importDto.getYbFlag())).setYbNo(importDto.getYbNo())
.setYbMatchFlag(CommonUtil.tryParseInt(importDto.getYbMatchFlag()))
.setStatusEnum(PublicationStatus.ACTIVE.getValue())
.setChrgitmLv(CommonUtil.tryParseInt(importDto.getChrgitmLv()));
return activityDefinition;
}
}

View File

@@ -3,7 +3,6 @@
*/
package com.openhis.web.datadictionary.appservice.impl;
import java.io.IOException;
import java.math.BigDecimal;
import java.util.*;
import java.util.stream.Collectors;
@@ -30,17 +29,16 @@ import com.core.common.utils.*;
import com.core.common.utils.bean.BeanUtils;
import com.core.common.utils.poi.ExcelUtil;
import com.core.system.service.ISysDictTypeService;
import com.openhis.administration.domain.ChargeItemDefDetail;
import com.openhis.administration.domain.ChargeItemDefinition;
import com.openhis.administration.domain.Location;
import com.openhis.administration.domain.Supplier;
import com.openhis.administration.service.IChargeItemDefDetailService;
import com.openhis.administration.service.IChargeItemDefinitionService;
import com.openhis.administration.service.ILocationService;
import com.openhis.administration.service.ISupplierService;
import com.openhis.common.constant.CommonConstants;
import com.openhis.common.constant.PromptMsgConstant;
import com.openhis.common.enums.*;
import com.openhis.common.utils.CommonUtil;
import com.openhis.common.utils.EnumUtils;
import com.openhis.common.utils.HisQueryUtils;
import com.openhis.medication.domain.Medication;
@@ -73,10 +71,7 @@ public class MedicationManageAppServiceImpl implements IMedicationManageAppServi
private IMedicationDefinitionService medicationDefinitionService;
@Autowired
IChargeItemDefinitionService chargeItemDefinitionService;
@Autowired
IChargeItemDefDetailService chargeItemDefDetailService;
private IChargeItemDefinitionService chargeItemDefinitionService;
@Autowired
private ILocationService locationService;
@@ -474,7 +469,7 @@ public class MedicationManageAppServiceImpl implements IMedicationManageAppServi
@Override
public R<?> importData(MultipartFile file) {
// 读取文件
R<List<MedicationImportDto>> readResult = readExcelFile(file);
R<List<MedicationImportDto>> readResult = CommonUtil.readImportedExcelFile(file, MedicationImportDto.class);
if (R.SUCCESS != readResult.getCode()) {
return readResult;
}
@@ -484,9 +479,8 @@ public class MedicationManageAppServiceImpl implements IMedicationManageAppServi
if (R.SUCCESS != validateResult.getCode()) {
return validateResult;
}
// 查询机构ID、当前时间、位置信息供后续使用
// 查询机构ID、位置信息供后续使用
Long orgId = SecurityUtils.getLoginUser().getOrgId();
Date now = DateUtils.getNowDate();
List<Location> locationList = locationService.list(new LambdaQueryWrapper<Location>()
.eq(Location::getDeleteFlag, DeleteFlag.NOT_DELETED.getCode()).orderByAsc(Location::getId));
Long defaultLocationId = locationList.stream().findFirst().orElse(new Location()).getId();
@@ -494,21 +488,18 @@ public class MedicationManageAppServiceImpl implements IMedicationManageAppServi
locationList.stream().collect(Collectors.groupingBy(Location::getName));
// 创建表数据
for (MedicationImportDto importDto : importDtoList) {
// 药品定义
// 创建药品定义
MedicationDefinition medicationDefinition = createMedicationDefinitionEntity(importDto);
medicationDefinitionService.save(medicationDefinition);
// 药品
// 创建药品
Medication medication =
createMedicationEntity(importDto, medicationDefinition.getId(), defaultLocationId, locationNameMap);
medicationService.save(medication);
// 费用定价
ChargeItemDefinition chargeItemDefinition =
createChargeItemDefinition(importDto, orgId, medicationDefinition.getId(), now);
chargeItemDefinitionService.save(chargeItemDefinition);
// 费用定价子表
List<ChargeItemDefDetail> chargeItemDefDetailList =
createChargeItemDefDetailList(importDto, chargeItemDefinition.getId());
chargeItemDefDetailService.saveBatch(chargeItemDefDetailList);
// 创建费用定价和详情
chargeItemDefinitionService.addChargeItemDefinitionAndDetail(importDto.getName(), importDto.getTypeCode(),
importDto.getYbType(), importDto.getUnitCode(), importDto.getPurchasePrice(),
importDto.getRetailPrice(), importDto.getMaximumRetailPrice(), orgId,
CommonConstants.TableName.MED_MEDICATION_DEFINITION, medicationDefinition.getId());
}
return R.ok(null, "导入成功!");
}
@@ -524,26 +515,6 @@ public class MedicationManageAppServiceImpl implements IMedicationManageAppServi
util.importTemplateExcel(response, "药品目录数据");
}
/**
* 读取Excel文件
*
* @param file 文件
* @return 读取结果
*/
private R<List<MedicationImportDto>> readExcelFile(MultipartFile file) {
ExcelUtil<MedicationImportDto> util = new ExcelUtil<>(MedicationImportDto.class);
List<MedicationImportDto> importDtoList;
try {
importDtoList = util.importExcel(file.getInputStream());
} catch (IOException e) {
return R.fail("导入失败!文件读取异常");
}
if (importDtoList.isEmpty()) {
return R.fail("导入失败!文件不能为空");
}
return R.ok(importDtoList);
}
/**
* 导入信息校验
*
@@ -797,23 +768,26 @@ public class MedicationManageAppServiceImpl implements IMedicationManageAppServi
.setMerchandisePyStr(ChineseConvertUtils.toPinyinFirstLetter(importDto.getMerchandiseName()))
.setMerchandiseWbStr(ChineseConvertUtils.toPinyinFirstLetter(importDto.getMerchandiseName()))
.setUnitCode(importDto.getUnitCode()).setMinUnitCode(importDto.getMinUnitCode())
.setPartPercent(importDto.getPartPercent()).setDoseFrom(tryParseInt(importDto.getDoseFrom()))
.setApprovalNumber(importDto.getApprovalNumber()).setYbMatchFlag(tryParseInt(importDto.getYbMatchFlag()))
.setYbNo(importDto.getYbNo()).setPharmacologyCategoryCode("1")
.setSkinTestFlag(tryParseInt(importDto.getSkinTestFlag()))
.setInjectFlag(tryParseInt(importDto.getInjectFlag())).setManufacturerText(importDto.getManufacturerText())
.setRestrictedFlag(tryParseInt(importDto.getRestrictedFlag()))
.setPartPercent(importDto.getPartPercent()).setDoseFrom(CommonUtil.tryParseInt(importDto.getDoseFrom()))
.setApprovalNumber(importDto.getApprovalNumber())
.setYbMatchFlag(CommonUtil.tryParseInt(importDto.getYbMatchFlag())).setYbNo(importDto.getYbNo())
.setPharmacologyCategoryCode("1").setSkinTestFlag(CommonUtil.tryParseInt(importDto.getSkinTestFlag()))
.setInjectFlag(CommonUtil.tryParseInt(importDto.getInjectFlag()))
.setManufacturerText(importDto.getManufacturerText())
.setRestrictedFlag(CommonUtil.tryParseInt(importDto.getRestrictedFlag()))
.setRestrictedScope(importDto.getRestrictedScope()).setActiveFlag(Whether.YES.getValue())
.setChildrenFlag(tryParseInt(importDto.getChildrenFlag()))
.setChildrenFlag(CommonUtil.tryParseInt(importDto.getChildrenFlag()))
.setNationalDrugCode(importDto.getNationalDrugCode())
.setPartAttributeEnum(tryParseInt(importDto.getPartAttributeEnum()))
.setAntibioticCode(importDto.getAntibioticCode()).setSelfFlag(tryParseInt(importDto.getSelfFlag()))
.setAntibioticFlag(tryParseInt(importDto.getAntibioticFlag()))
.setBasicFlag(tryParseInt(importDto.getBasicFlag()))
.setThoPartAttributeEnum(tryParseInt(importDto.getThoPartAttributeEnum()))
.setPartAttributeEnum(CommonUtil.tryParseInt(importDto.getPartAttributeEnum()))
.setAntibioticCode(importDto.getAntibioticCode())
.setSelfFlag(CommonUtil.tryParseInt(importDto.getSelfFlag()))
.setAntibioticFlag(CommonUtil.tryParseInt(importDto.getAntibioticFlag()))
.setBasicFlag(CommonUtil.tryParseInt(importDto.getBasicFlag()))
.setThoPartAttributeEnum(CommonUtil.tryParseInt(importDto.getThoPartAttributeEnum()))
.setUnitConversionRatio(importDto.getUnitConversionRatio())
.setChrgitmLv(tryParseInt(importDto.getChrgitmLv())).setRxFlag(tryParseInt(importDto.getRxFlag()))
.setItemMinQuantity(importDto.getItemMinQuantity()).setItemMaxQuantity(importDto.getItemMaxQuantity());
.setChrgitmLv(CommonUtil.tryParseInt(importDto.getChrgitmLv()))
.setRxFlag(CommonUtil.tryParseInt(importDto.getRxFlag())).setItemMinQuantity(importDto.getItemMinQuantity())
.setItemMaxQuantity(importDto.getItemMaxQuantity());
return medicationDefinition;
}
@@ -844,53 +818,4 @@ public class MedicationManageAppServiceImpl implements IMedicationManageAppServi
return medication;
}
/**
* 创建费用定价实体
*
* @param importDto 药品目录导入Dto
* @return 药品基本实体
*/
private ChargeItemDefinition createChargeItemDefinition(MedicationImportDto importDto, Long orgId,
Long medicationDefId, Date effectiveStart) {
ChargeItemDefinition chargeItemDefinition = new ChargeItemDefinition();
chargeItemDefinition.setChargeName(importDto.getName()).setStatusEnum(PublicationStatus.ACTIVE.getValue())
.setOrgId(orgId).setInstanceTable(CommonConstants.TableName.MED_MEDICATION_DEFINITION)
.setInstanceId(medicationDefId).setEffectiveStart(effectiveStart).setTypeCode(importDto.getTypeCode())
.setYbType(importDto.getYbType()).setConditionFlag(Whether.YES.getValue())
.setPrice(importDto.getRetailPrice());
return chargeItemDefinition;
}
/**
* 创建费用定价子实体列表
*
* @param importDto 药品目录导入Dto
* @param chargeItemDefId 费用定价ID
* @return 费用定价子实体列表
*/
private List<ChargeItemDefDetail> createChargeItemDefDetailList(MedicationImportDto importDto,
Long chargeItemDefId) {
ChargeItemDefDetail defDetailPurchase = new ChargeItemDefDetail().setDefinitionId(chargeItemDefId)
.setConditionCode(ConditionCode.PURCHASE.getCode()).setAmount(importDto.getPurchasePrice());
ChargeItemDefDetail defDetailRetail =
new ChargeItemDefDetail().setDefinitionId(chargeItemDefId).setConditionCode(ConditionCode.UNIT.getCode())
.setConditionValue(importDto.getUnitCode()).setAmount(importDto.getRetailPrice());
ChargeItemDefDetail defDetailMaximumRetail = new ChargeItemDefDetail().setDefinitionId(chargeItemDefId)
.setConditionCode(ConditionCode.LIMIT.getCode()).setAmount(importDto.getMaximumRetailPrice());
return Arrays.asList(defDetailPurchase, defDetailRetail, defDetailMaximumRetail);
}
/**
* 尝试转化为int
*
* @param intStr int字符串
* @return int值
*/
private Integer tryParseInt(String intStr) {
try {
return Integer.parseInt(intStr);
} catch (Exception e) {
return null;
}
}
}

View File

@@ -3,10 +3,12 @@ package com.openhis.web.datadictionary.controller;
import java.util.List;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.validation.annotation.Validated;
import org.springframework.web.bind.annotation.*;
import org.springframework.web.multipart.MultipartFile;
import com.core.common.core.domain.R;
import com.openhis.web.datadictionary.appservice.IDiagTreatMAppService;
@@ -56,8 +58,8 @@ public class DiagnosisTreatmentController {
@RequestParam(value = "searchKey", defaultValue = "") String searchKey,
@RequestParam(value = "pageNo", defaultValue = "1") Integer pageNo,
@RequestParam(value = "pageSize", defaultValue = "10") Integer pageSize, HttpServletRequest request) {
return diagTreatMAppService.getDiseaseTreatmentPage(DiagnosisTreatmentSelParam, searchKey, pageNo,
pageSize, request);
return diagTreatMAppService.getDiseaseTreatmentPage(DiagnosisTreatmentSelParam, searchKey, pageNo, pageSize,
request);
}
/**
@@ -136,4 +138,25 @@ public class DiagnosisTreatmentController {
public R<?> exportDiseaseTreatment(@RequestBody DiagnosisTreatmentDto diagnosisTreatmentDto) {
return null;
}
/**
* 导入诊疗目录
*
* @param file 文件
* @return 结果
*/
@PostMapping("/import-data")
public R<?> importData(MultipartFile file) {
return diagTreatMAppService.importData(file);
}
/**
* 获取导入模板
*
* @param response 响应
*/
@PostMapping("/import-template")
public void importTemplate(HttpServletResponse response) {
diagTreatMAppService.importTemplate(response);
}
}

View File

@@ -20,7 +20,7 @@ import lombok.AllArgsConstructor;
import lombok.extern.slf4j.Slf4j;
/**
* TODO:病种目录
* 病种目录
*
* @author lpt
* @date 2025-02-20

View File

@@ -57,10 +57,6 @@ public class DeviceImportDto {
@Excel(name = "最小使用单位", prompt = "必填", dictType = "unit_code", comboReadDict = true)
private String minUnitCode;
/** 所属科室名称orgId */
@Excel(name = "所属科室名称", prompt = "必填")
private String orgName;
/** 所在位置名称locationId */
@Excel(name = "所在位置名称", prompt = "必填")
private String locationName;
@@ -70,7 +66,7 @@ public class DeviceImportDto {
private String hvcmFlag;
/** 销售单位 */
@Excel(name = "最小使用单位", prompt = "必填", dictType = "unit_code", comboReadDict = true)
@Excel(name = "销售单位", prompt = "必填", dictType = "unit_code", comboReadDict = true)
private String salesUnitCode;
/** 批准文号 */
@@ -78,49 +74,61 @@ public class DeviceImportDto {
private String approvalNumber;
/** 医保标记 */
@Excel(name = "医保标记", prompt = "必填", readConverterExp = "0=否,1=是", combo = "否,是")
private String ybFlag;
/** 医保对码标记 */
@Excel(name = "医保对码标记", prompt = "必填", readConverterExp = "0=否,1=是", combo = "否,是")
private String ybMatchFlag;
/** 医保编码 */
@Excel(name = "医保编码", prompt = "医保对码时必填")
private String ybNo;
/** 医药机构目录编码 */
@Excel(name = "医药机构目录编码")
private String ybOrgNo;
/** 医保对码标记 */
private Integer ybMatchFlag;
/** 医保等级 */
private Integer chrgitmLv;
/** 状态 */
private Integer statusEnum;
/** 生产厂家 */
private Long manufacturerId;
@Excel(name = "医保等级", prompt = "必填", dictType = "chrgitm_lv", comboReadDict = true)
private String chrgitmLv;
/** 生产厂家 */
@Excel(name = "生产厂家文本", prompt = "必填")
private String manufacturerText;
/** 供应商 */
private Long supplyId;
/** 说明 */
private String description;
/** 适用范围 */
private String jurisdiction;
/** 器材版本 */
private String version;
/** 主要成分 */
private String substanceText;
/** 过敏标记 */
private Integer allergenFlag;
@Excel(name = "过敏标记", prompt = "必填", readConverterExp = "0=否,1=是", combo = "否,是")
private String allergenFlag;
/** 处方标志 */
private Integer rxFlag;
@Excel(name = "处方标志", prompt = "必填", readConverterExp = "0=否,1=是", combo = "否,是")
private String rxFlag;
// ---------------------- 费用定价 adm_charge_item_definition ----------------------------------------------
/** 财务类别 */
@Excel(name = "财务类别", prompt = "必填", dictType = "fin_type_code", comboReadDict = true)
private String typeCode;
/** 医保费用类别 */
@Excel(name = "医保费用类别", prompt = "必填", dictType = "med_chrgitm_type", comboReadDict = true)
private String ybType;
// ---------------------- 费用定价子表 adm_charge_item_def_detail ----------------------------------------------
/** 购入价 */
@Excel(name = "购入价", prompt = "必填,数值类型")
private String purchasePriceStr;
private BigDecimal purchasePrice;
/** 零售价 */
@Excel(name = "零售价", prompt = "必填,数值类型")
private String retailPriceStr;
private BigDecimal retailPrice;
/** 最高零售价 */
@Excel(name = "最高零售价", prompt = "必填,数值类型")
private String maximumRetailPriceStr;
private BigDecimal maximumRetailPrice;
}

View File

@@ -0,0 +1,75 @@
package com.openhis.web.datadictionary.dto;
import java.math.BigDecimal;
import com.core.common.annotation.Excel;
import lombok.Data;
import lombok.experimental.Accessors;
/**
* 诊疗目录导入Dto
*
* @author GuoRui
* @date 2025-09-29
*/
@Data
@Accessors(chain = true)
public class DiagnosisTreatmentImportDto {
/** 行号 */
private Integer lineNumber;
// ---------------------- 诊疗定义 wor_activity_definition -------------------------------------
/** 诊疗名称 */
@Excel(name = "诊疗名称", prompt = "必填")
private String name;
/** 目录类别 */
@Excel(name = "目录类别", prompt = "必填", dictType = "activity_category_code", comboReadDict = true)
private String categoryCode;
/** 使用单位 */
@Excel(name = "使用单位", prompt = "必填", dictType = "unit_code", comboReadDict = true)
private String permittedUnitCode;
/** 医保标记 */
@Excel(name = "医保标记", prompt = "必填", readConverterExp = "0=否,1=是", combo = "否,是")
private String ybFlag;
/** 医保对码标记 */
@Excel(name = "医保对码标记", prompt = "必填", readConverterExp = "0=否,1=是", combo = "否,是")
private String ybMatchFlag;
/** 医保编码 */
@Excel(name = "医保编码", prompt = "医保对码时必填")
private String ybNo;
/** 医保等级 */
@Excel(name = "医保等级", prompt = "必填", dictType = "chrgitm_lv", comboReadDict = true)
private String chrgitmLv;
// ---------------------- 费用定价 adm_charge_item_definition ----------------------------------------------
/** 财务类别 */
@Excel(name = "财务类别", prompt = "必填", dictType = "fin_type_code", comboReadDict = true)
private String typeCode;
/** 医保费用类别 */
@Excel(name = "医保费用类别", prompt = "必填", dictType = "med_chrgitm_type", comboReadDict = true)
private String ybType;
// ---------------------- 费用定价子表 adm_charge_item_def_detail ----------------------------------------------
/** 零售价 */
@Excel(name = "零售价", prompt = "必填,数值类型")
private String retailPriceStr;
private BigDecimal retailPrice;
/** 最高零售价 */
@Excel(name = "最高零售价", prompt = "必填,数值类型")
private String maximumRetailPriceStr;
private BigDecimal maximumRetailPrice;
}