PatientInfoImportServiceImpl.java 16 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343
  1. package com.kcim.service.impl;
  2. import cn.afterturn.easypoi.excel.ExcelExportUtil;
  3. import cn.afterturn.easypoi.excel.ExcelImportUtil;
  4. import cn.afterturn.easypoi.excel.entity.ExportParams;
  5. import cn.afterturn.easypoi.excel.entity.ImportParams;
  6. import cn.afterturn.easypoi.excel.entity.enmus.ExcelType;
  7. import cn.afterturn.easypoi.excel.entity.result.ExcelVerifyHandlerResult;
  8. import cn.afterturn.easypoi.handler.inter.IExcelVerifyHandler;
  9. import cn.hutool.core.util.StrUtil;
  10. import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
  11. import com.kcim.common.constants.NumberConstant;
  12. import com.kcim.common.enums.DateStyleEnum;
  13. import com.kcim.common.exception.CostException;
  14. import com.kcim.common.util.*;
  15. import com.kcim.common.util.excel.ExcelStyleUtil;
  16. import com.kcim.common.util.excel.entity.PatientInfoImportEntity;
  17. import com.kcim.dao.model.CostIncomeFile;
  18. import com.kcim.dao.model.ImportPatientInfo;
  19. import com.kcim.dao.repository.DiseaseTypeDiagMapRepository;
  20. import com.kcim.dao.repository.ImportPatientInfoRepository;
  21. import com.kcim.service.CostIncomeFileService;
  22. import com.kcim.service.PatientInfoImportService;
  23. import lombok.AllArgsConstructor;
  24. import lombok.SneakyThrows;
  25. import lombok.extern.slf4j.Slf4j;
  26. import org.apache.poi.ss.usermodel.Workbook;
  27. import org.springframework.stereotype.Service;
  28. import org.springframework.util.CollectionUtils;
  29. import org.springframework.util.ObjectUtils;
  30. import org.springframework.util.StringUtils;
  31. import org.springframework.web.multipart.MultipartFile;
  32. import javax.servlet.http.HttpServletResponse;
  33. import java.io.FileNotFoundException;
  34. import java.io.IOException;
  35. import java.io.InputStream;
  36. import java.net.URLEncoder;
  37. import java.util.ArrayList;
  38. import java.util.Date;
  39. import java.util.List;
  40. import java.util.stream.Collectors;
  41. /**
  42. * @program: CostAccount
  43. * @description: 患者信息导入接口实现类
  44. * @author: Wang.YS
  45. * @create: 2023-10-19 18:09
  46. **/
  47. @Service("PatientInfoImportService")
  48. @AllArgsConstructor
  49. @Slf4j
  50. public class PatientInfoImportServiceImpl implements PatientInfoImportService {
  51. ImportPatientInfoRepository repository;
  52. DiseaseTypeDiagMapRepository diagMapRepository;
  53. CostIncomeGroupServiceImpl costIncomeGroupService;
  54. CostIncomeFileService costIncomeFileService;
  55. /**
  56. * 月度信息采集-患者信息导入-获取导入列表
  57. *
  58. * @param current 当前页
  59. * @param pageSize 页容量
  60. * @param computeDate 核算年月
  61. * @param departmentName 科室名称
  62. * @param patientName 患者姓名
  63. * @param filter
  64. * @param departmentCode
  65. * @return 导入列表
  66. */
  67. @Override
  68. public Object getPatientInfoList(Integer current, Integer pageSize, String computeDate, String departmentName, String patientName, String filter, String departmentCode) {
  69. Page<ImportPatientInfo> page = repository.getPage(current, pageSize, computeDate, departmentName, patientName,filter,departmentCode);
  70. List<ImportPatientInfo> records = page.getRecords();
  71. if(!CollectionUtils.isEmpty(records)){
  72. // for (ImportPatientInfo record : records) {
  73. // Integer bedDays = calculateBedDays(record.getInHospitalTime(), record.getOutHospitalTime());
  74. // Integer bedDays1 = calculateCurrentBedDays(record.getInHospitalTime(), record.getOutHospitalTime(), computeDate);
  75. // System.out.println("visitNo:"+record.getVisitNo()+"床日数:"+bedDays+"|当前床日数:"+bedDays1);
  76. // }
  77. return new PageUtils(records, Math.toIntExact(page.getTotal()),pageSize,current);
  78. }
  79. return new PageUtils(new ArrayList<>(), NumberConstant.ZERO,pageSize,current);
  80. }
  81. /**
  82. * 月度信息采集-患者信息导入-获取导出模版
  83. *
  84. * @param response 出参
  85. * @return 导出模版
  86. */
  87. @Override
  88. @SneakyThrows
  89. public Object exportPatientInfo(HttpServletResponse response) {
  90. try {
  91. //配置excel 文件信息
  92. ExportParams params = new ExportParams();
  93. params.setTitle("说明:1、为了保证成功导入,请勿修改模板格式\n" +
  94. " 2、住院号/门诊号为患者就诊的唯一标识\n" +
  95. " 3、多个次诊断及次手术/操作需用|拼接,样式:次诊断代码1|次诊断代码2\n" +
  96. " 4、次诊断代码、次诊断名称、主手术/操作代码、主手术/操作名称、次手术/操作代码、次手术/操作名称、DRG/DIP分组代码、DRG/DIP分组名称、临床路径代码、临床路径名称没有可留空\n" +
  97. " 5、门急诊患者出院时间和住院天数可不填");
  98. //设置导出样式
  99. params.setStyle(ExcelStyleUtil.class);
  100. params.setTitleHeight(Short.parseShort("25"));
  101. params.setHeight((short)10);
  102. // params.setSecondTitleHeight(Short.parseShort("1"));
  103. // params.setHeaderHeight(1);
  104. //设置sheetName
  105. params.setSheetName("患者信息");
  106. params.setType(ExcelType.XSSF);
  107. // params.setHeaderColor();
  108. // params.setFreezeCol(2);
  109. // FileOutputStream outputStream = new FileOutputStream("E:\\患者信息导入模版.xlsx");
  110. Workbook workbook = ExcelExportUtil.exportExcel(params, PatientInfoImportEntity.class,new ArrayList<>());
  111. response.setCharacterEncoding("UTF-8");
  112. response.setContentType("application/vnd.ms-excel");
  113. String fileName ="患者信息导入模版";
  114. response.setHeader("Content-Disposition", URLEncoder.encode(fileName, "UTF-8"));
  115. workbook.write(response.getOutputStream());
  116. // workbook.write(outputStream);
  117. // outputStream.close();
  118. workbook.close();
  119. } catch (FileNotFoundException e) {
  120. throw new CostException(e.getMessage());
  121. } catch (IOException e) {
  122. throw new RuntimeException(e);
  123. }
  124. return response.getOutputStream();
  125. }
  126. /**
  127. * 月度信息采集-患者信息导入-导入数据
  128. *
  129. * @param computeDate 核算年月
  130. * @param file 文件
  131. */
  132. @SneakyThrows
  133. @Override
  134. public void importPatientInfo(String computeDate, MultipartFile file) {
  135. // try {
  136. if (ObjectUtils.isEmpty(file) || file.getSize() == 0){
  137. throw new CostException("未获取到导入的excel文件内容");
  138. }
  139. log.info("接收到文件:{}",file.getOriginalFilename());
  140. // 参数1:文件流
  141. InputStream stream = file.getInputStream();
  142. // 参数2:导入类型
  143. ImportParams params = new ImportParams();
  144. //校验Excel 去掉空行
  145. params.setNeedVerify(true);
  146. IExcelVerifyHandler<PatientInfoImportEntity> handler = val ->{
  147. if(StringUtils.isEmpty(val.getVisitNo())){
  148. return new ExcelVerifyHandlerResult(false,"住院号/门诊号不能为空");
  149. }
  150. return new ExcelVerifyHandlerResult(true);
  151. };
  152. params.setVerifyHandler(handler);
  153. // 标题占用多少行
  154. params.setTitleRows(1);
  155. // 头部属性占用多少行
  156. params.setHeadRows(1);
  157. List<PatientInfoImportEntity> patientInfoImportEntities = ExcelImportUtil.importExcel(stream, PatientInfoImportEntity.class,params);
  158. if(!CollectionUtils.isEmpty(patientInfoImportEntities)){
  159. //获取病种对照
  160. // Map<String, String> diagDiseaseMap = diagMapRepository.getDiagDiseaseMap();
  161. List<ImportPatientInfo> saveList = new ArrayList<>();
  162. ImportPatientInfo importPatientInfo = new ImportPatientInfo();
  163. importPatientInfo.setHospId(UserContext.getHospId());
  164. importPatientInfo.setComputeDate(computeDate);
  165. importPatientInfo.setCreateTime(new Date());
  166. importPatientInfo.setCreateUser(String.valueOf(UserContext.getCurrentUser().getId()));
  167. for (PatientInfoImportEntity entity : patientInfoImportEntities) {
  168. ImportPatientInfo patientInfo = BeanUtil.convertObj(importPatientInfo, ImportPatientInfo.class);
  169. patientInfo.setVisitNo(entity.getVisitNo());
  170. patientInfo.setPatientNo(entity.getPatientNo());
  171. patientInfo.setName(entity.getName());
  172. patientInfo.setDepartmentCode(entity.getDepartmentCode());
  173. patientInfo.setDepartmentName(entity.getDepartmentName());
  174. patientInfo.setType(entity.getType());
  175. patientInfo.setPrimaryDiagCode(entity.getPrimaryDiagCode());
  176. // if(!CollectionUtils.isEmpty(diagDiseaseMap)){
  177. // if(!StringUtils.isEmpty(patientInfo.getPrimaryDiagCode())){
  178. // String diseaseType = diagDiseaseMap.get(patientInfo.getPrimaryDiagCode());
  179. // if(!StringUtils.isEmpty(diseaseType)){
  180. // patientInfo.setDiseaseTypeCode(diseaseType);
  181. // }
  182. // }
  183. // }
  184. patientInfo.setPrimaryDiagName(entity.getPrimaryDiagName());
  185. patientInfo.setSecondaryDiagCode(entity.getSecondaryDiagCode());
  186. patientInfo.setSecondaryDiagName(entity.getSecondaryDiagName());
  187. patientInfo.setPrimaryOperationCode(entity.getPrimaryOperationCode());
  188. patientInfo.setPrimaryOperationName(entity.getPrimaryOperationName());
  189. patientInfo.setSecondaryOperationCode(entity.getSecondaryOperationCode());
  190. patientInfo.setSecondaryOperationName(entity.getSecondaryOperationName());
  191. patientInfo.setGroupCode(entity.getGroupCode());
  192. patientInfo.setGroupName(entity.getGroupName());
  193. patientInfo.setClinicalPathwayCode(entity.getClinicalPathwayCode());
  194. patientInfo.setClinicalPathwayName(entity.getClinicalPathwayName());
  195. patientInfo.setInHospitalTime(entity.getInHospitalTime());
  196. patientInfo.setOutHospitalTime(entity.getOutHospitalTime());
  197. patientInfo.setInHospitalDays(entity.getInHospitalDays());
  198. patientInfo.setInpatientWardCode(entity.getInpatientWardCode());
  199. patientInfo.setInpatientWardName(entity.getInpatientWardName());
  200. //添加计算床日数
  201. if(patientInfo.getOutHospitalTime() !=null){
  202. Integer bedDays = calculateBedDays(patientInfo.getInHospitalTime(), patientInfo.getOutHospitalTime());
  203. patientInfo.setBedDays(bedDays);
  204. }
  205. Integer currentBedDays = calculateCurrentBedDays(patientInfo.getInHospitalTime(), patientInfo.getOutHospitalTime(), computeDate);
  206. patientInfo.setCurrentBedDays(currentBedDays);
  207. saveList.add(patientInfo);
  208. }
  209. // 文件上传
  210. String uploadFile = costIncomeGroupService.uploadFile(file);
  211. // 上传记录保存
  212. if (StrUtil.isBlank(uploadFile)) {
  213. throw new CostException(500, "文件上传异常");
  214. }
  215. CostIncomeFile costIncomeFile = costIncomeFileService.saveFile(saveList.size(), file, UserContext.getHospId(), new ArrayList<>(), uploadFile, NumberConstant.FIVE, ComputeDateUtils.getComputeYear(computeDate), ComputeDateUtils.getComputeMonth(computeDate));
  216. Long id = costIncomeFile.getId();
  217. if(!CollectionUtils.isEmpty(saveList)){
  218. // check(computeDate);
  219. saveList.forEach(f->f.setFileId(id));
  220. repository.saveBatch(saveList,50);
  221. }
  222. // if(!CollectionUtils.isEmpty(saveList)){
  223. // check(computeDate);
  224. // repository.saveBatch(saveList,50);
  225. // }
  226. }
  227. // }catch (Exception e){
  228. // throw new RuntimeException(e);
  229. // }
  230. }
  231. @Override
  232. public Object getPatientInfoDepartment(Integer type, String filter, String computeDate) {
  233. return repository.getPatientInfoDepartment(type,filter,computeDate);
  234. }
  235. @Override
  236. public void removePatientInfo(String computeDate) {
  237. check(computeDate);
  238. }
  239. /**
  240. * 按文件id移除记录
  241. * @param computeDate
  242. * @param fileId
  243. */
  244. @Override
  245. public void removePatientInfoByFileId(String computeDate, Long fileId) {
  246. repository.removePatientInfoByFileId(computeDate,fileId);
  247. }
  248. /**
  249. * 按文件id还原记录
  250. * @param computeDate
  251. * @param fileId
  252. */
  253. @Override
  254. public void reducingPatientInfoByFileId(String computeDate, Long fileId) {
  255. repository.reducingPatientInfoByFileId(computeDate,fileId);
  256. }
  257. private void check(String computeDate) {
  258. List<ImportPatientInfo> byComputeDate = repository.getByComputeDate(computeDate);
  259. if(!CollectionUtils.isEmpty(byComputeDate)){
  260. for (ImportPatientInfo patientInfo : byComputeDate) {
  261. patientInfo.setDeleteTime(new Date());
  262. patientInfo.setDeleteUser(String.valueOf(UserContext.getCurrentUser().getId()));
  263. }
  264. repository.updateBatchById(byComputeDate);
  265. List<Integer> collect = byComputeDate.stream().map(ImportPatientInfo::getId).collect(Collectors.toList());
  266. repository.removeBatchByIds(collect);
  267. }
  268. }
  269. private Integer calculateBedDays(Date inHospitalDate,Date outHospitalDate){
  270. int intervalDays = DateUtils.getIntervalDays(inHospitalDate, outHospitalDate);
  271. if(intervalDays == NumberConstant.ZERO){
  272. intervalDays = NumberConstant.ONE;
  273. }
  274. return intervalDays;
  275. }
  276. private Integer calculateCurrentBedDays(Date inHospitalDate,Date outHospitalDate,String computeDate){
  277. // 入院日期=实际入院日期>当月最小日期?实际入院日期:当月最小日期
  278. // 出院日期=实际出院日期>当月最大日期?当月最大日期:实际出院日期
  279. // 床日数=出院日期-入院日期,如果是当日入出院算1天(算出来的床日数为0时算1天)
  280. // 实际出院日期>当月最大日期或没有出院日期时,床日数需+1
  281. Date date = DateUtils.StringToDate(computeDate, DateStyleEnum.YYYY_MM);
  282. Date firstDateOfMonth = DateUtils.getFirstDateOfMonth(date);
  283. Date lastDateOfMonth = DateUtils.getLastDateOfMonth(date);
  284. Date currentOutHospitalDate ;
  285. int currentBedDays ;
  286. Date currentInHospitalDate = inHospitalDate.compareTo(firstDateOfMonth) >= 0 ? inHospitalDate : firstDateOfMonth;
  287. if(outHospitalDate == null){
  288. currentOutHospitalDate = lastDateOfMonth;
  289. currentBedDays = DateUtils.getIntervalDays(currentOutHospitalDate,currentInHospitalDate) + 1;
  290. }else {
  291. boolean last = false;
  292. if(outHospitalDate.compareTo(firstDateOfMonth)>=0){
  293. if (outHospitalDate.compareTo(lastDateOfMonth) >= 0) {
  294. currentOutHospitalDate = lastDateOfMonth;
  295. last = true;
  296. }else {
  297. currentOutHospitalDate = outHospitalDate;
  298. }
  299. currentBedDays = DateUtils.getIntervalDays(currentOutHospitalDate,currentInHospitalDate) ;
  300. if(last){
  301. currentBedDays += 1;
  302. }
  303. }else {
  304. //出院日期小于当前核算年月最小日期 按原出入院日期算
  305. currentBedDays = calculateBedDays(inHospitalDate, outHospitalDate);
  306. }
  307. }
  308. if(currentBedDays==NumberConstant.ZERO){
  309. currentBedDays = NumberConstant.ONE;
  310. }
  311. return currentBedDays;
  312. }
  313. }