package cn.lihu.jh.module.ecg.service.jobrecord; import cn.lihu.jh.module.ecg.controller.admin.appointment.vo.AppointmentRespVO; import cn.lihu.jh.module.ecg.dal.dataobject.appointment.AppointmentDO; import cn.lihu.jh.module.ecg.dal.dataobject.devrent.DevRentDO; import cn.lihu.jh.module.ecg.dal.dataobject.jobrecord.JobRecordStatisticDO; import cn.lihu.jh.module.ecg.dal.mysql.appointment.AppointmentMapper; import cn.lihu.jh.module.ecg.dal.mysql.devrent.DevRentMapper; import org.springframework.stereotype.Service; import org.springframework.validation.annotation.Validated; import org.springframework.transaction.annotation.Transactional; import java.time.LocalDateTime; import java.util.*; import cn.lihu.jh.module.ecg.controller.admin.jobrecord.vo.*; import cn.lihu.jh.module.ecg.dal.dataobject.jobrecord.JobRecordDO; import cn.lihu.jh.framework.common.pojo.PageResult; import cn.lihu.jh.framework.common.pojo.PageParam; import cn.lihu.jh.framework.common.util.object.BeanUtils; import cn.lihu.jh.module.ecg.dal.mysql.jobrecord.JobRecordMapper; import javax.annotation.Resource; import static cn.lihu.jh.framework.common.exception.util.ServiceExceptionUtil.exception; import static cn.lihu.jh.framework.common.pojo.CommonResult.success; import static cn.lihu.jh.module.ecg.enums.ErrorCodeConstants.*; /** * 工作记录 Service 实现类 * * @author 芋道源码 */ @Service @Validated public class JobRecordServiceImpl implements JobRecordService { @Resource private JobRecordMapper jobRecordMapper; @Resource private DevRentMapper devRentMapper; @Resource private AppointmentMapper appointmentMapper; @Override public Long createJobRecord(JobRecordSaveReqVO createReqVO) { // 插入 JobRecordDO jobRecord = BeanUtils.toBean(createReqVO, JobRecordDO.class); jobRecordMapper.insert(jobRecord); // 返回 return jobRecord.getId(); } @Override public void updateJobRecord(JobRecordSaveReqVO updateReqVO) { // 校验存在 validateJobRecordExists(updateReqVO.getId()); // 更新 JobRecordDO updateObj = BeanUtils.toBean(updateReqVO, JobRecordDO.class); jobRecordMapper.updateById(updateObj); } @Override public void deleteJobRecord(Long id) { // 校验存在 validateJobRecordExists(id); // 删除 jobRecordMapper.deleteById(id); } private void validateJobRecordExists(Long id) { if (jobRecordMapper.selectById(id) == null) { throw exception(JOB_RECORD_NOT_EXISTS); } } @Override public JobRecordDO getJobRecord(Long id) { JobRecordDO jobRecordDO = jobRecordMapper.selectById(id); if (null != jobRecordDO) { fillPatientInfo(java.util.Collections.singletonList(jobRecordDO)); } return jobRecordDO; } @Override public PageResult getJobRecordPage(JobRecordPageReqVO pageReqVO) { PageResult pageResult = jobRecordMapper.selectPage(pageReqVO); List jobRecordDOList = pageResult.getList(); if ( !jobRecordDOList.isEmpty() ) { List rentIdList = jobRecordDOList.stream().map(item -> item.getRentId()).toList(); List paidInfoList = devRentMapper.getPaidInfo(rentIdList); for (int i = 0; i < jobRecordDOList.size(); i++) { jobRecordDOList.get(i).setPaid(paidInfoList.get(i)); } // 需求1:回填患者信息(批量,避免 N+1) fillPatientInfo(jobRecordDOList); } return pageResult; } // ==================== 需求1:回填患者信息 18 项 ==================== // 回填链路(三级): // job_record.rentId → dev_rent.applyNo → appointment // 之所以不用逐条 getByApplyNo:job_record 列表页一次可能返回几十条, // 逐条查会形成 N+1。这里改为「批量取 dev_rent」+「批量取 appointment」。 private void fillPatientInfo(List jobRecordDOList) { if (null == jobRecordDOList || jobRecordDOList.isEmpty()) { return; } // 1) 批量取 dev_rent,拿到 applyNo List rentIdList = jobRecordDOList.stream() .map(JobRecordDO::getRentId) .filter(java.util.Objects::nonNull) .distinct() .toList(); if (rentIdList.isEmpty()) { return; } Map applyNoByRentId = new HashMap<>(); // 一次 IN 查询取全部 applyNo(原先逐条 selectById → N 次查询) List devRentDOList = devRentMapper.getApplyNoByIdList(rentIdList); if (null != devRentDOList) { devRentDOList.forEach(d -> { if (null != d && null != d.getId() && org.springframework.util.StringUtils.hasText(d.getApplyNo())) { applyNoByRentId.put(d.getId(), d.getApplyNo()); } }); } if (applyNoByRentId.isEmpty()) { return; } // 2) 批量取 appointment(一次 IN 查询) List applyNoList = applyNoByRentId.values().stream().distinct().toList(); Map appointmentByApplyNo = new HashMap<>(); List appointmentDOList = appointmentMapper.getByApplyNoList(applyNoList); if (null != appointmentDOList) { appointmentDOList.forEach(a -> { if (null != a && org.springframework.util.StringUtils.hasText(a.getApplyNo())) { appointmentByApplyNo.put(a.getApplyNo(), a); } }); } // 3) 回填 jobRecordDOList.forEach(jobRecordDO -> { if (null == jobRecordDO || null == jobRecordDO.getRentId()) { return; } String applyNo = applyNoByRentId.get(jobRecordDO.getRentId()); if (null == applyNo) { return; } AppointmentDO appointment = appointmentByApplyNo.get(applyNo); if (null == appointment) { return; } jobRecordDO.setApplyNo(applyNo); jobRecordDO.setEpisodeId(appointment.getEpisodeId()); jobRecordDO.setPatGender(appointment.getPatGender()); jobRecordDO.setPatBirthday(appointment.getPatBirthday()); jobRecordDO.setRegisterDate(appointment.getRegisterDate()); jobRecordDO.setDoctor(appointment.getDoctor()); jobRecordDO.setDoctorTime(appointment.getDoctorTime()); jobRecordDO.setPatSrc(appointment.getPatSrc()); jobRecordDO.setPatMobile(appointment.getPatMobile()); jobRecordDO.setPatPhone(appointment.getPatPhone()); jobRecordDO.setPatWardDesc(appointment.getPatWardDesc()); jobRecordDO.setPatBedNo(appointment.getPatBedNo()); jobRecordDO.setMedicalCard(appointment.getMedicalCard()); jobRecordDO.setDoctorAdviceNo(appointment.getDoctorAdviceNo()); jobRecordDO.setOutpatientNo(appointment.getOutpatientNo()); jobRecordDO.setPatIdentityId(appointment.getPatIdentityId()); jobRecordDO.setTolerance(appointment.getTolerance()); }); } @Override public List getJobStatistic(LocalDateTime jobTimeFrom, LocalDateTime jobTimeTo) { return jobRecordMapper.getJobStatistic(jobTimeFrom, jobTimeTo); } }