package com.smartor.service.impl; import com.ruoyi.common.utils.DateUtils; import com.ruoyi.common.utils.DtoConversionUtils; import com.ruoyi.common.utils.StringUtils; import com.smartor.domain.*; import com.smartor.domain.entity.ServiceSubtaskEntity; import com.smartor.mapper.*; import com.smartor.service.IPatMedOuthospService; import lombok.extern.slf4j.Slf4j; import org.apache.commons.lang3.ObjectUtils; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.stereotype.Service; import org.springframework.util.CollectionUtils; import javax.sql.DataSource; import java.sql.Connection; import java.sql.Statement; import java.time.LocalDate; import java.time.Period; import java.time.ZoneId; import java.time.temporal.ChronoUnit; import java.util.*; /** * 患者门诊记录Service业务层处理 * * @author smartor * @date 2023-03-04 */ @Slf4j @Service public class PatMedOuthospServiceImpl implements IPatMedOuthospService { @Autowired private PatMedOuthospMapper patMedOuthospMapper; @Autowired private DataSource dataSource; @Autowired private ServiceSubtaskMapper serviceSubtaskMapper; @Autowired private ServiceTaskMapper serviceTaskMapper; @Autowired private ServiceTaskdiagMapper serviceTaskdiagMapper; @Autowired private ServiceTaskdeptMapper serviceTaskdeptMapper; @Autowired private PatArchiveMapper patArchiveMapper; /** * 查询患者门诊记录 * * @param id 患者门诊记录主键 * @return 患者门诊记录 */ @Override public PatMedOuthosp selectPatMedOuthospById(Long id) { // return patMedOuthospMapper.selectPatMedOuthospById(id); return null; } /** * 查询患者门诊记录列表 * * @param patMedOuthosp 患者门诊记录 * @return 患者门诊记录 */ @Override public List selectPatMedOuthospList(PatMedOuthosp patMedOuthosp) { PatMedOuthospQueryReq patMedOuthospQueryReq = DtoConversionUtils.sourceToTarget(patMedOuthosp, PatMedOuthospQueryReq.class); List patMedOuthospQueryResps = patMedOuthospMapper.callSpQueryOuthosp(patMedOuthospQueryReq); if (patMedOuthosp.getPageNum() != null) { for (PatMedOuthosp patMedOuthosp1 : patMedOuthospQueryResps) { PatArchive patArchive = patArchiveMapper.selectPatArchiveByPatid(patMedOuthosp1.getPatid()); if (patArchive.getBirthdate() != null) { Map map = calculateAge(patArchive.getBirthdate().toInstant().atZone(ZoneId.systemDefault()).toLocalDate(), LocalDate.now()); patArchive.setAge(ObjectUtils.isNotEmpty(map.get("age")) ? Long.valueOf(map.get("age")) : null); patArchive.setAgeUnit(map.get("ageUnit")); patArchive.setAge2(ObjectUtils.isNotEmpty(map.get("age2")) ? Long.valueOf(map.get("age2")) : null); patArchive.setAgeUnit2(map.get("ageUnit2")); patMedOuthosp1.setAge(patArchive.getAge() + patArchive.getAgeUnit() + patArchive.getAge2() + patArchive.getAgeUnit2()); patMedOuthosp1.setSex(patArchive.getSex()); patMedOuthosp1.setTelcode(patArchive.getTelcode()); patMedOuthosp1.setIdcardno(patArchive.getIdcardno()); } ServiceSubtaskEntity serviceSubtaskVO = new ServiceSubtaskEntity(); serviceSubtaskVO.setPatid(patMedOuthosp1.getPatid()); List sendstates = new ArrayList<>(); sendstates.add(1L); sendstates.add(2L); sendstates.add(3L); serviceSubtaskVO.setSendstates(sendstates); serviceSubtaskVO.setServiceType("3"); List serviceSubtaskList = serviceSubtaskMapper.selectServiceSubtaskBySendstate(serviceSubtaskVO); if (!CollectionUtils.isEmpty(serviceSubtaskList)) patMedOuthosp1.setServerState("1"); } } return patMedOuthospQueryResps; } public Map calculateAge(LocalDate birthdate, LocalDate today) { if (birthdate == null || today.isBefore(birthdate)) { return null; } Map ageMap = new HashMap<>(); Period period = Period.between(birthdate, today); long totalDays = ChronoUnit.DAYS.between(birthdate, today); long totalMonths = ChronoUnit.MONTHS.between(birthdate, today); int years = period.getYears(); int months = period.getMonths(); int days = period.getDays(); String ageUnit; Integer age; String ageUnit2 = null; Integer age2 = null; if (totalDays < 30) { // 小于 1 个月,按天计算 ageUnit = "天"; age = (int) totalDays; ageMap.put("age", age != null ? age.toString() : null); ageMap.put("ageUnit", ageUnit); ageMap.put("age2", null); ageMap.put("ageUnit2", null); } else if (totalMonths < 12) { // 小于 一年,按月 + 天计算 ageUnit = "月"; age = (int) totalMonths; ageUnit2 = "天"; age2 = days; ageMap.put("age", age != null ? age.toString() : null); ageMap.put("ageUnit", ageUnit); ageMap.put("age2", age2 != null ? age2.toString() : null); ageMap.put("ageUnit2", ageUnit2); } else { // 大于等于 一年,按年 + 月计算 ageUnit = "岁"; age = years; ageUnit2 = "月"; age2 = months; ageMap.put("age", age != null ? age.toString() : null); ageMap.put("ageUnit", ageUnit); ageMap.put("age2", age2 != null ? age2.toString() : null); ageMap.put("ageUnit2", ageUnit2); } return ageMap; } /** * 新增患者门诊记录 * 根据 admitdate 路由到对应分表;若分表不存在则写入主表 * * @param patMedOuthosp 患者门诊记录 * @return 结果 */ @Override public int insertPatMedOuthosp(PatMedOuthosp patMedOuthosp) { if (patMedOuthosp.getAdmitdate() != null) { log.error("门急就诊时间不能为空"); return 0; } patMedOuthosp.setCreateTime(DateUtils.getNowDate()); patMedOuthosp.setUpdateTime(DateUtils.getNowDate()); patMedOuthosp.setGuid(UUID.randomUUID().toString()); //需要插入到哪个表,根据就诊时间的日期来定,如果根据就诊时间来确定的表不存在,则存在pat_med_outhosp表中 String targetTable = resolveTargetTable(patMedOuthosp.getAdmitdate()); if (targetTable != null) { log.info("[insert] 路由到分表: {}", targetTable); return patMedOuthospMapper.insertIntoTable(targetTable, patMedOuthosp); } return 0; } /** * 修改患者门诊记录 * 根据 admitdate 路由到对应分表;若分表不存在则改主表 * * @param patMedOuthosp 患者门诊记录 * @return 结果 */ @Override public int updatePatMedOuthosp(PatMedOuthosp patMedOuthosp) { if (patMedOuthosp.getSerialnum() == null) { log.error("流水号不能为空"); return 0; } PatMedOuthospQueryReq patMedOuthospQueryReq = new PatMedOuthospQueryReq(); patMedOuthospQueryReq.setSerialnum(patMedOuthosp.getSerialnum()); patMedOuthospQueryReq.setGuid(patMedOuthosp.getGuid()); patMedOuthospQueryReq.setOuthospno(patMedOuthosp.getOuthospno()); List patMedOuthosps = patMedOuthospMapper.callSpQueryOuthosp(patMedOuthospQueryReq); if (patMedOuthosps == null || patMedOuthosps.size() == 0) { insertPatMedOuthosp(patMedOuthosp); } else { patMedOuthosp.setUpdateTime(DateUtils.getNowDate()); String targetTable = resolveTargetTable(patMedOuthosp.getAdmitdate()); if (targetTable != null) { log.info("[update] 路由到分表: {}", targetTable); return patMedOuthospMapper.updateInTable(targetTable, patMedOuthosp); } } return 0; } /** * 根据 create_time 推算目标分表名,与建表策略保持一致 *
    *
  • 6位后缀(YYYYMM)→ 按月分表
  • *
  • 8位后缀(YYYYMMdd)→ 按季度分表,季度后缀固定为 0103/0406/0709/1012
  • *
  • 4位后缀(YYYY) → 按年分表
  • *
* 推算出表名后校验表是否存在,不存在返回 null(回落主表) * * @param createTime 创建时间,为 null 时返回 null * @return 目标分表名,或 null */ private String resolveTargetTable(java.util.Date createTime) { if (createTime == null) return null; List allTables = patMedOuthospMapper.getAllOuthospTableNames(); if (allTables == null || allTables.isEmpty()) return null; // 判断当前分表后缀长度(以第一张表为准) String sample = allTables.get(0); String suffix = sample.replaceFirst("pat_med_outhosp_", ""); int suffixLen = suffix.length(); java.util.Calendar cal = java.util.Calendar.getInstance(); cal.setTime(createTime); int year = cal.get(java.util.Calendar.YEAR); int month = cal.get(java.util.Calendar.MONTH) + 1; // 1-based String targetTable; if (suffixLen == 4) { // 按年 targetTable = "pat_med_outhosp_" + year; } else if (suffixLen == 6) { // 按月 targetTable = String.format("pat_med_outhosp_%d%02d", year, month); } else { // 按季度(8位后缀,如 20260103) String quarterSuffix; if (month <= 3) quarterSuffix = "0103"; else if (month <= 6) quarterSuffix = "0406"; else if (month <= 9) quarterSuffix = "0709"; else quarterSuffix = "1012"; targetTable = "pat_med_outhosp_" + year + quarterSuffix; } boolean exists = allTables.contains(targetTable); log.info("[路由] createTime={} → 目标表={} exists={}", createTime, targetTable, exists); return exists ? targetTable : "pat_med_outhosp"; } /** * 批量删除患者门诊记录 * * @param ids 需要删除的患者门诊记录主键 * @return 结果 */ @Override public int deletePatMedOuthospByIds(Long[] ids) { // return patMedOuthospMapper.deletePatMedOuthospByIds(ids); return 0; } /** * 删除患者门诊记录信息 * * @param id 患者门诊记录主键 * @return 结果 */ @Override public int deletePatMedOuthospById(Long id) { // return patMedOuthospMapper.deletePatMedOuthospById(id); return 0; } @Override public PatMedRes selectPatMedOuthospCount(PatMedReq patMedReq) { //获取门诊病人信息,并统计人数和人次 PatMedOuthospQueryReq req = new PatMedOuthospQueryReq(); String deptcodes = CollectionUtils.isEmpty(patMedReq.getDeptcodeList()) ? null : String.join(",", patMedReq.getDeptcodeList()); req.setBeginAdmitdate(patMedReq.getStartDate()); req.setEndAdmitdate(patMedReq.getEndDate()); req.setDeptcode(deptcodes); req.setOrgid(patMedReq.getOrgid()); // req.setCampusid(patMedReq.getCampusid()); Long count = patMedOuthospMapper.callSpQueryOuthospCount(req); //查询随访人次和人数 PatMedRes patMedRes = serviceSubtaskMapper.selectVisitCount(patMedReq); patMedRes.setRc(count == null ? 0 : count.intValue()); return patMedRes; } @Override public PatMedOuthosp getDeptCodeByPatId(PatMedOuthosp patMedOuthosp) { List patMedOuthosps = selectPatMedOuthospList(patMedOuthosp); if (!CollectionUtils.isEmpty(patMedOuthosps)) { Collections.sort(patMedOuthosps, Comparator.comparing(PatMedOuthosp::getAdmitdate).reversed()); } return patMedOuthosps.get(0); } /** * 门诊病人信息处理 * * @return */ @Override public Integer dealOutpatientInfo() { PatMedOuthosp patMedOuthosp = new PatMedOuthosp(); patMedOuthosp.setDiagcheckFlag("0"); List patMedOuthosps = selectPatMedOuthospList(patMedOuthosp); for (PatMedOuthosp patMedOuthosp1 : patMedOuthosps) { PatArchive patArchive = patArchiveMapper.selectPatArchiveByPatid(patMedOuthosp1.getPatid()); //根据患者科室,获取该疾病的长期任务 ServiceTaskdept serviceTaskdept = new ServiceTaskdept(); serviceTaskdept.setLongtask(1L); serviceTaskdept.setDeptCode(patMedOuthosp1.getDeptcode()); serviceTaskdept.setServiceType("3"); List serviceTaskdeptList = serviceTaskdeptMapper.selectServiceTaskdeptList(serviceTaskdept); if (org.apache.commons.collections4.CollectionUtils.isEmpty(serviceTaskdeptList) || serviceTaskdeptList.size() == 0) { patMedOuthosp1.setDeptcheckFlag("2"); patMedOuthosp1.setRemark("通过部门,没有找到门诊随访任务ID"); updatePatMedOuthosp(patMedOuthosp1); } else { for (ServiceTaskdept serviceTaskdept1 : serviceTaskdeptList) { writeInSubTask(serviceTaskdept1.getTaskId(), true, patMedOuthosp1, patArchive, 1); } } // 根据患者的疾病,获取该疾病的长期任务 ServiceTaskdiag serviceTaskdiag = new ServiceTaskdiag(); serviceTaskdiag.setLongtask(1L); serviceTaskdiag.setIcd10code(patMedOuthosp1.getIcd10code()); List serviceTaskdiags = serviceTaskdiagMapper.selectServiceTaskdiagList(serviceTaskdiag); //如果部门模板为空(将deptIsNull设置为true) if (org.apache.commons.collections4.CollectionUtils.isEmpty(serviceTaskdiags) || serviceTaskdiags.size() == 0) { patMedOuthosp1.setDiagcheckFlag("2"); patMedOuthosp1.setRemark("通过icd10,没有找到门诊随访任务ID"); updatePatMedOuthosp(patMedOuthosp1); } else { for (ServiceTaskdiag serviceTaskdept1 : serviceTaskdiags) { writeInSubTask(serviceTaskdept1.getTaskId(), true, patMedOuthosp1, patArchive, 2); } } } return 1; } /** * @param taskid * @param check * @param patMedOuthosp * @param patArchive * @param type 1 科室 2 疾病 */ private void writeInSubTask(Long taskid, Boolean check, PatMedOuthosp patMedOuthosp, PatArchive patArchive, Integer type) { ServiceTask st = new ServiceTask(); st.setTaskid(taskid); st.setSendState(2L); List serviceTasks = serviceTaskMapper.selectServiceTaskList(st); if (org.apache.commons.collections4.CollectionUtils.isEmpty(serviceTasks)) { log.info("该患者疾病随访长期任务不存在,任务ID为:{}", taskid); if (type == 1) patMedOuthosp.setDiagcheckFlag("2"); if (type == 2) patMedOuthosp.setDeptcheckFlag("2"); patMedOuthosp.setRemark("该患者门诊随访长期任务不存在,任务ID为:" + taskid); updatePatMedOuthosp(patMedOuthosp); return; } ServiceTask serviceTask = serviceTasks.get(0); //封装serviceSubtask ServiceSubtask serviceSubtask = boxedServiceSubtask(serviceTask, patMedOuthosp, patArchive); Integer i = 0; //先判断一下,是否需要校验 if (check) { //在新增之前,先通过患者ID,sendstate=2查询一下,在所有长期任务中,是不是还有该患者待执行的任务,有的话,比较之前的endtime是否小于当前的endtaime,如果之前的小于现在的,则直接将之前的停掉(原因再入院) ServiceSubtaskEntity subtask = new ServiceSubtaskEntity(); subtask.setPatid(patArchive.getId()); subtask.setSendstate(2L); subtask.setTaskid(taskid); List selectServiceSubtaskList = serviceSubtaskMapper.selectServiceSubtaskList(subtask); log.info("该患者待执行的任务:{}", CollectionUtils.isEmpty(selectServiceSubtaskList) ? null : selectServiceSubtaskList.size()); if (org.apache.commons.collections4.CollectionUtils.isNotEmpty(selectServiceSubtaskList) && selectServiceSubtaskList.size() > 0) { for (ServiceSubtask serviceSubtask1 : selectServiceSubtaskList) { if (Objects.isNull(serviceSubtask1.getLongSendTime())) { //不是长期任务,不处理 continue; } //将之前的停掉 serviceSubtask1.setSendstate(6L); serviceSubtask1.setRemark("患者已经回院复诊"); serviceSubtask1.setResult("success"); serviceSubtask1.setFinishtime(new Date()); serviceSubtask1.setUpdateBy(serviceTask.getUpdateBy()); serviceSubtaskMapper.updateServiceSubtask(serviceSubtask1); //重新新增子任务 i = serviceSubtaskMapper.insertServiceSubtask(serviceSubtask); } } else { if (StringUtils.isEmpty(serviceSubtask.getPhone())) { serviceSubtask.setRemark("手机号为空"); serviceSubtask.setSendstate(4L); serviceSubtask.setResult("error"); // serviceSubtask.setFinishtime(new Date()); } serviceSubtask.setCreateBy(serviceTask.getCreateBy()); serviceSubtask.setCreateTime(new Date()); i = serviceSubtaskMapper.insertServiceSubtask(serviceSubtask); } } else { if (StringUtils.isEmpty(serviceSubtask.getPhone())) { serviceSubtask.setRemark("手机号为空"); serviceSubtask.setSendstate(4L); serviceSubtask.setResult("error"); // serviceSubtask.setFinishtime(new Date()); } serviceSubtask.setCreateBy(serviceTask.getCreateBy()); serviceSubtask.setCreateTime(new Date()); i = serviceSubtaskMapper.insertServiceSubtask(serviceSubtask); } if (i == 1) { //将check_flag改成1(已处理) PatMedOuthosp patMedOuthosp1 = new PatMedOuthosp(); patMedOuthosp1.setId(patMedOuthosp.getId()); if (type == 1) patMedOuthosp1.setDiagcheckFlag("2"); if (type == 2) patMedOuthosp1.setDeptcheckFlag("2"); updatePatMedOuthosp(patMedOuthosp1); } else { //生成子任务失败, log.info("生成子任务失败serviceSubtask的taskid为:{},patid为:{}", serviceSubtask.getTaskid(), serviceSubtask.getPatid()); PatMedOuthosp pmo = new PatMedOuthosp(); pmo.setGuid(patMedOuthosp.getGuid()); pmo.setSerialnum(patMedOuthosp.getSerialnum()); if (type == 1) pmo.setDiagcheckFlag("2"); if (type == 2) pmo.setDeptcheckFlag("2"); pmo.setRemark("生成子任务失败"); updatePatMedOuthosp(pmo); } } //封装serviceSubtask private ServiceSubtask boxedServiceSubtask(ServiceTask serviceTask, PatMedOuthosp patMedOuthosp, PatArchive patArchive) { ServiceSubtask serviceSubtask = DtoConversionUtils.sourceToTarget(serviceTask, ServiceSubtask.class); serviceSubtask.setTaskid(serviceTask.getTaskid()); if (StringUtils.isNotEmpty(serviceTask.getLibtemplateid())) serviceSubtask.setLibtemplateid(Long.valueOf(serviceTask.getLibtemplateid())); serviceSubtask.setDrcode(patMedOuthosp.getDrcode()); serviceSubtask.setDrname(patMedOuthosp.getDrname()); serviceSubtask.setDeptcode(patMedOuthosp.getDeptcode()); serviceSubtask.setInhospid(patMedOuthosp.getId()); serviceSubtask.setHospno(patMedOuthosp.getOuthospno()); serviceSubtask.setDeptname(patMedOuthosp.getDeptname()); serviceSubtask.setTemplateid(serviceTask.getTemplateid()); serviceSubtask.setTemplatename(serviceTask.getTemplatename()); serviceSubtask.setPatid(patArchive.getId()); serviceSubtask.setSendname(patArchive.getName()); serviceSubtask.setSfzh(patArchive.getIdcardno()); serviceSubtask.setLeavediagname(patMedOuthosp.getDiagname()); serviceSubtask.setLeaveicd10code(patMedOuthosp.getIcd10code()); serviceSubtask.setSfzh(patArchive.getIdcardno()); serviceSubtask.setPhone(patArchive.getTelcode()); if (StringUtils.isBlank(patArchive.getTelcode())) serviceSubtask.setPhone(patArchive.getRelativetelcode()); serviceSubtask.setSex(patArchive.getSex()); serviceSubtask.setAge(patArchive.getAge()); serviceSubtask.setSendstate(2L); serviceSubtask.setServiceType(serviceTask.getServiceType()); serviceSubtask.setPreachform(serviceTask.getPreachform()); serviceSubtask.setHospType("1"); serviceSubtask.setCreateTime(new Date()); serviceSubtask.setUpdateTime(new Date()); serviceSubtask.setUpdateBy(serviceTask.getUpdateBy()); serviceSubtask.setUpdateTime(new Date()); serviceSubtask.setVisitDeptCode(patMedOuthosp.getDeptcode()); serviceSubtask.setVisitDeptName(patMedOuthosp.getDeptname()); serviceSubtask.setUpdateTime(new Date()); //设置发送时间 if (serviceTask.getSendDay() == null) serviceTask.setSendDay(1L); Date newDate = addDays(patMedOuthosp.getAdmitdate(), serviceTask.getSendDay().intValue()); if (patMedOuthosp.getFudate() != null) { //如果门诊表有指定随访时间,那就用指定的 newDate = patMedOuthosp.getFudate(); } serviceSubtask.setLongSendTime(newDate); serviceSubtask.setVisitTime(newDate); //患者发送时间 if (StringUtils.isNotEmpty(patArchive.getNotrequiredFlag()) && patArchive.getNotrequiredFlag().equals("1")) { String remark = patArchive.getNotrequiredreason(); serviceSubtask.setRemark(remark); serviceSubtask.setResult("error"); // serviceSubtask.setFinishtime(new Date()); //不执行 serviceSubtask.setSendstate(4L); } return serviceSubtask; } private Date addDays(Date date, Integer days) { if (days == null) { days = 1; } Calendar calendar = Calendar.getInstance(); calendar.setTime(date); calendar.add(Calendar.DAY_OF_MONTH, days); return calendar.getTime(); } }