package com.kcim.service.impl; import cn.afterturn.easypoi.excel.ExcelExportUtil; import cn.afterturn.easypoi.excel.ExcelImportUtil; import cn.afterturn.easypoi.excel.entity.ExportParams; import cn.afterturn.easypoi.excel.entity.ImportParams; import cn.afterturn.easypoi.excel.entity.enmus.ExcelType; import cn.afterturn.easypoi.excel.entity.result.ExcelVerifyHandlerResult; import cn.afterturn.easypoi.handler.inter.IExcelVerifyHandler; import cn.hutool.core.util.StrUtil; import com.baomidou.mybatisplus.extension.plugins.pagination.Page; import com.kcim.common.constants.NumberConstant; import com.kcim.common.enums.DateStyleEnum; import com.kcim.common.exception.CostException; import com.kcim.common.util.*; import com.kcim.common.util.excel.ExcelStyleUtil; import com.kcim.common.util.excel.entity.PatientInfoImportEntity; import com.kcim.dao.model.CostIncomeFile; import com.kcim.dao.model.ImportPatientInfo; import com.kcim.dao.repository.DiseaseTypeDiagMapRepository; import com.kcim.dao.repository.ImportPatientInfoRepository; import com.kcim.service.CostIncomeFileService; import com.kcim.service.PatientInfoImportService; import lombok.AllArgsConstructor; import lombok.SneakyThrows; import lombok.extern.slf4j.Slf4j; import org.apache.poi.ss.usermodel.Workbook; import org.springframework.stereotype.Service; import org.springframework.util.CollectionUtils; import org.springframework.util.ObjectUtils; import org.springframework.util.StringUtils; import org.springframework.web.multipart.MultipartFile; import javax.servlet.http.HttpServletResponse; import java.io.FileNotFoundException; import java.io.IOException; import java.io.InputStream; import java.net.URLEncoder; import java.util.ArrayList; import java.util.Date; import java.util.List; import java.util.stream.Collectors; /** * @program: CostAccount * @description: 患者信息导入接口实现类 * @author: Wang.YS * @create: 2023-10-19 18:09 **/ @Service("PatientInfoImportService") @AllArgsConstructor @Slf4j public class PatientInfoImportServiceImpl implements PatientInfoImportService { ImportPatientInfoRepository repository; DiseaseTypeDiagMapRepository diagMapRepository; CostIncomeGroupServiceImpl costIncomeGroupService; CostIncomeFileService costIncomeFileService; /** * 月度信息采集-患者信息导入-获取导入列表 * * @param current 当前页 * @param pageSize 页容量 * @param computeDate 核算年月 * @param departmentName 科室名称 * @param patientName 患者姓名 * @param filter * @param departmentCode * @return 导入列表 */ @Override public Object getPatientInfoList(Integer current, Integer pageSize, String computeDate, String departmentName, String patientName, String filter, String departmentCode) { Page page = repository.getPage(current, pageSize, computeDate, departmentName, patientName,filter,departmentCode); List records = page.getRecords(); if(!CollectionUtils.isEmpty(records)){ // for (ImportPatientInfo record : records) { // Integer bedDays = calculateBedDays(record.getInHospitalTime(), record.getOutHospitalTime()); // Integer bedDays1 = calculateCurrentBedDays(record.getInHospitalTime(), record.getOutHospitalTime(), computeDate); // System.out.println("visitNo:"+record.getVisitNo()+"床日数:"+bedDays+"|当前床日数:"+bedDays1); // } return new PageUtils(records, Math.toIntExact(page.getTotal()),pageSize,current); } return new PageUtils(new ArrayList<>(), NumberConstant.ZERO,pageSize,current); } /** * 月度信息采集-患者信息导入-获取导出模版 * * @param response 出参 * @return 导出模版 */ @Override @SneakyThrows public Object exportPatientInfo(HttpServletResponse response) { try { //配置excel 文件信息 ExportParams params = new ExportParams(); params.setTitle("说明:1、为了保证成功导入,请勿修改模板格式\n" + " 2、住院号/门诊号为患者就诊的唯一标识\n" + " 3、多个次诊断及次手术/操作需用|拼接,样式:次诊断代码1|次诊断代码2\n" + " 4、次诊断代码、次诊断名称、主手术/操作代码、主手术/操作名称、次手术/操作代码、次手术/操作名称、DRG/DIP分组代码、DRG/DIP分组名称、临床路径代码、临床路径名称没有可留空\n" + " 5、门急诊患者出院时间和住院天数可不填"); //设置导出样式 params.setStyle(ExcelStyleUtil.class); params.setTitleHeight(Short.parseShort("25")); params.setHeight((short)10); // params.setSecondTitleHeight(Short.parseShort("1")); // params.setHeaderHeight(1); //设置sheetName params.setSheetName("患者信息"); params.setType(ExcelType.XSSF); // params.setHeaderColor(); // params.setFreezeCol(2); // FileOutputStream outputStream = new FileOutputStream("E:\\患者信息导入模版.xlsx"); Workbook workbook = ExcelExportUtil.exportExcel(params, PatientInfoImportEntity.class,new ArrayList<>()); response.setCharacterEncoding("UTF-8"); response.setContentType("application/vnd.ms-excel"); String fileName ="患者信息导入模版"; response.setHeader("Content-Disposition", URLEncoder.encode(fileName, "UTF-8")); workbook.write(response.getOutputStream()); // workbook.write(outputStream); // outputStream.close(); workbook.close(); } catch (FileNotFoundException e) { throw new CostException(e.getMessage()); } catch (IOException e) { throw new RuntimeException(e); } return response.getOutputStream(); } /** * 月度信息采集-患者信息导入-导入数据 * * @param computeDate 核算年月 * @param file 文件 */ @SneakyThrows @Override public void importPatientInfo(String computeDate, MultipartFile file) { // try { if (ObjectUtils.isEmpty(file) || file.getSize() == 0){ throw new CostException("未获取到导入的excel文件内容"); } log.info("接收到文件:{}",file.getOriginalFilename()); // 参数1:文件流 InputStream stream = file.getInputStream(); // 参数2:导入类型 ImportParams params = new ImportParams(); //校验Excel 去掉空行 params.setNeedVerify(true); IExcelVerifyHandler handler = val ->{ if(StringUtils.isEmpty(val.getVisitNo())){ return new ExcelVerifyHandlerResult(false,"住院号/门诊号不能为空"); } return new ExcelVerifyHandlerResult(true); }; params.setVerifyHandler(handler); // 标题占用多少行 params.setTitleRows(1); // 头部属性占用多少行 params.setHeadRows(1); List patientInfoImportEntities = ExcelImportUtil.importExcel(stream, PatientInfoImportEntity.class,params); if(!CollectionUtils.isEmpty(patientInfoImportEntities)){ //获取病种对照 // Map diagDiseaseMap = diagMapRepository.getDiagDiseaseMap(); List saveList = new ArrayList<>(); ImportPatientInfo importPatientInfo = new ImportPatientInfo(); importPatientInfo.setHospId(UserContext.getHospId()); importPatientInfo.setComputeDate(computeDate); importPatientInfo.setCreateTime(new Date()); importPatientInfo.setCreateUser(String.valueOf(UserContext.getCurrentUser().getId())); for (PatientInfoImportEntity entity : patientInfoImportEntities) { ImportPatientInfo patientInfo = BeanUtil.convertObj(importPatientInfo, ImportPatientInfo.class); patientInfo.setVisitNo(entity.getVisitNo()); patientInfo.setPatientNo(entity.getPatientNo()); patientInfo.setName(entity.getName()); patientInfo.setDepartmentCode(entity.getDepartmentCode()); patientInfo.setDepartmentName(entity.getDepartmentName()); patientInfo.setType(entity.getType()); patientInfo.setPrimaryDiagCode(entity.getPrimaryDiagCode()); // if(!CollectionUtils.isEmpty(diagDiseaseMap)){ // if(!StringUtils.isEmpty(patientInfo.getPrimaryDiagCode())){ // String diseaseType = diagDiseaseMap.get(patientInfo.getPrimaryDiagCode()); // if(!StringUtils.isEmpty(diseaseType)){ // patientInfo.setDiseaseTypeCode(diseaseType); // } // } // } patientInfo.setPrimaryDiagName(entity.getPrimaryDiagName()); patientInfo.setSecondaryDiagCode(entity.getSecondaryDiagCode()); patientInfo.setSecondaryDiagName(entity.getSecondaryDiagName()); patientInfo.setPrimaryOperationCode(entity.getPrimaryOperationCode()); patientInfo.setPrimaryOperationName(entity.getPrimaryOperationName()); patientInfo.setSecondaryOperationCode(entity.getSecondaryOperationCode()); patientInfo.setSecondaryOperationName(entity.getSecondaryOperationName()); patientInfo.setGroupCode(entity.getGroupCode()); patientInfo.setGroupName(entity.getGroupName()); patientInfo.setClinicalPathwayCode(entity.getClinicalPathwayCode()); patientInfo.setClinicalPathwayName(entity.getClinicalPathwayName()); patientInfo.setInHospitalTime(entity.getInHospitalTime()); patientInfo.setOutHospitalTime(entity.getOutHospitalTime()); patientInfo.setInHospitalDays(entity.getInHospitalDays()); patientInfo.setInpatientWardCode(entity.getInpatientWardCode()); patientInfo.setInpatientWardName(entity.getInpatientWardName()); //添加计算床日数 if(patientInfo.getOutHospitalTime() !=null){ Integer bedDays = calculateBedDays(patientInfo.getInHospitalTime(), patientInfo.getOutHospitalTime()); patientInfo.setBedDays(bedDays); } Integer currentBedDays = calculateCurrentBedDays(patientInfo.getInHospitalTime(), patientInfo.getOutHospitalTime(), computeDate); patientInfo.setCurrentBedDays(currentBedDays); saveList.add(patientInfo); } // 文件上传 String uploadFile = costIncomeGroupService.uploadFile(file); // 上传记录保存 if (StrUtil.isBlank(uploadFile)) { throw new CostException(500, "文件上传异常"); } CostIncomeFile costIncomeFile = costIncomeFileService.saveFile(saveList.size(), file, UserContext.getHospId(), new ArrayList<>(), uploadFile, NumberConstant.FIVE, ComputeDateUtils.getComputeYear(computeDate), ComputeDateUtils.getComputeMonth(computeDate)); Long id = costIncomeFile.getId(); if(!CollectionUtils.isEmpty(saveList)){ // check(computeDate); saveList.forEach(f->f.setFileId(id)); repository.saveBatch(saveList,50); } // if(!CollectionUtils.isEmpty(saveList)){ // check(computeDate); // repository.saveBatch(saveList,50); // } } // }catch (Exception e){ // throw new RuntimeException(e); // } } @Override public Object getPatientInfoDepartment(Integer type, String filter, String computeDate) { return repository.getPatientInfoDepartment(type,filter,computeDate); } @Override public void removePatientInfo(String computeDate) { check(computeDate); } /** * 按文件id移除记录 * @param computeDate * @param fileId */ @Override public void removePatientInfoByFileId(String computeDate, Long fileId) { repository.removePatientInfoByFileId(computeDate,fileId); } /** * 按文件id还原记录 * @param computeDate * @param fileId */ @Override public void reducingPatientInfoByFileId(String computeDate, Long fileId) { repository.reducingPatientInfoByFileId(computeDate,fileId); } private void check(String computeDate) { List byComputeDate = repository.getByComputeDate(computeDate); if(!CollectionUtils.isEmpty(byComputeDate)){ for (ImportPatientInfo patientInfo : byComputeDate) { patientInfo.setDeleteTime(new Date()); patientInfo.setDeleteUser(String.valueOf(UserContext.getCurrentUser().getId())); } repository.updateBatchById(byComputeDate); List collect = byComputeDate.stream().map(ImportPatientInfo::getId).collect(Collectors.toList()); repository.removeBatchByIds(collect); } } private Integer calculateBedDays(Date inHospitalDate,Date outHospitalDate){ int intervalDays = DateUtils.getIntervalDays(inHospitalDate, outHospitalDate); if(intervalDays == NumberConstant.ZERO){ intervalDays = NumberConstant.ONE; } return intervalDays; } private Integer calculateCurrentBedDays(Date inHospitalDate,Date outHospitalDate,String computeDate){ // 入院日期=实际入院日期>当月最小日期?实际入院日期:当月最小日期 // 出院日期=实际出院日期>当月最大日期?当月最大日期:实际出院日期 // 床日数=出院日期-入院日期,如果是当日入出院算1天(算出来的床日数为0时算1天) // 实际出院日期>当月最大日期或没有出院日期时,床日数需+1 Date date = DateUtils.StringToDate(computeDate, DateStyleEnum.YYYY_MM); Date firstDateOfMonth = DateUtils.getFirstDateOfMonth(date); Date lastDateOfMonth = DateUtils.getLastDateOfMonth(date); Date currentOutHospitalDate ; int currentBedDays ; Date currentInHospitalDate = inHospitalDate.compareTo(firstDateOfMonth) >= 0 ? inHospitalDate : firstDateOfMonth; if(outHospitalDate == null){ currentOutHospitalDate = lastDateOfMonth; currentBedDays = DateUtils.getIntervalDays(currentOutHospitalDate,currentInHospitalDate) + 1; }else { boolean last = false; if(outHospitalDate.compareTo(firstDateOfMonth)>=0){ if (outHospitalDate.compareTo(lastDateOfMonth) >= 0) { currentOutHospitalDate = lastDateOfMonth; last = true; }else { currentOutHospitalDate = outHospitalDate; } currentBedDays = DateUtils.getIntervalDays(currentOutHospitalDate,currentInHospitalDate) ; if(last){ currentBedDays += 1; } }else { //出院日期小于当前核算年月最小日期 按原出入院日期算 currentBedDays = calculateBedDays(inHospitalDate, outHospitalDate); } } if(currentBedDays==NumberConstant.ZERO){ currentBedDays = NumberConstant.ONE; } return currentBedDays; } }