package org.dromara.eims.service.impl; import com.alibaba.excel.EasyExcel; import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper; import org.dromara.common.core.exception.ServiceException; import org.dromara.common.core.utils.DateUtils; import org.dromara.common.core.utils.MapstructUtils; import org.dromara.common.core.utils.StringUtils; import org.dromara.common.mybatis.core.page.TableDataInfo; import org.dromara.common.mybatis.core.page.PageQuery; import com.baomidou.mybatisplus.extension.plugins.pagination.Page; import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper; import com.baomidou.mybatisplus.core.toolkit.Wrappers; import lombok.RequiredArgsConstructor; import org.dromara.eims.domain.EimsEqu; import org.dromara.eims.domain.vo.EimsEquVo; import org.dromara.eims.domain.vo.MaintCheckItemVo; import org.dromara.eims.listener.EasyExcelCellListener; import org.dromara.eims.listener.MaintCheckItemImportListener; import org.dromara.eims.mapper.EimsEquMapper; import org.dromara.system.domain.SysDept; import org.dromara.system.domain.vo.SysDeptVo; import org.dromara.system.mapper.SysDeptMapper; import org.springframework.stereotype.Service; import org.dromara.eims.domain.bo.EimsMaintPlanBo; import org.dromara.eims.domain.vo.EimsMaintPlanVo; import org.dromara.eims.domain.EimsMaintPlan; import org.dromara.eims.mapper.EimsMaintPlanMapper; import org.dromara.eims.service.IEimsMaintPlanService; import org.springframework.web.multipart.MultipartFile; import java.io.IOException; import java.util.*; /** * 保养计划Service业务层处理 * * @author zhuguifei * @date 2025-03-04 */ @RequiredArgsConstructor @Service public class EimsMaintPlanServiceImpl implements IEimsMaintPlanService { private final EimsMaintPlanMapper baseMapper; private final SysDeptMapper sysDeptMapper; private final EimsEquMapper equMapper; /** * 查询保养计划 * * @param id 主键 * @return 保养计划 */ @Override public EimsMaintPlanVo queryById(Long id) { return baseMapper.selectVoById(id); } /** * 分页查询保养计划列表 * * @param bo 查询条件 * @param pageQuery 分页参数 * @return 保养计划分页列表 */ @Override public TableDataInfo queryPageList(EimsMaintPlanBo bo, PageQuery pageQuery) { LambdaQueryWrapper lqw = buildQueryWrapper(bo); Page result = baseMapper.selectVoPage(pageQuery.build(), lqw); return TableDataInfo.build(result); } @Override public TableDataInfo queryPageListCustom(EimsMaintPlanBo bo, PageQuery pageQuery) { Page page = baseMapper.selectMaintPlanList(pageQuery.build(), buildWrapper(bo)); return TableDataInfo.build(page); } /** * 查询符合条件的保养计划列表 * * @param bo 查询条件 * @return 保养计划列表 */ @Override public List queryList(EimsMaintPlanBo bo) { LambdaQueryWrapper lqw = buildQueryWrapper(bo); return baseMapper.selectVoList(lqw); } private LambdaQueryWrapper buildQueryWrapper(EimsMaintPlanBo bo) { Map params = bo.getParams(); LambdaQueryWrapper lqw = Wrappers.lambdaQuery(); lqw.eq(bo.getEquId() != null, EimsMaintPlan::getEquId, bo.getEquId()); lqw.eq(StringUtils.isNotBlank(bo.getMaintType()), EimsMaintPlan::getMaintType, bo.getMaintType()); lqw.eq(StringUtils.isNotBlank(bo.getMaintCycleUnit()), EimsMaintPlan::getMaintCycleUnit, bo.getMaintCycleUnit()); lqw.eq(StringUtils.isNotBlank(bo.getMaintRule()), EimsMaintPlan::getMaintRule, bo.getMaintRule()); lqw.eq(bo.getMaintUser() != null, EimsMaintPlan::getMaintUser, bo.getMaintUser()); lqw.eq(bo.getMaintDept() != null, EimsMaintPlan::getMaintDept, bo.getMaintDept()); lqw.eq(bo.getStatus() != null, EimsMaintPlan::getStatus, bo.getStatus()); // 按创建时间倒序 lqw.orderByDesc(EimsMaintPlan::getCreateTime); return lqw; } private QueryWrapper buildWrapper(EimsMaintPlanBo bo) { Map params = bo.getParams(); QueryWrapper qw = Wrappers.query(); qw.eq(bo.getEquId() != null, "mp.equ_id", bo.getEquId()); qw.like(bo.getEquName() != null, "equ.equ_name", bo.getEquName()); qw.like(bo.getAssetNo() != null, "equ.asset_no", bo.getAssetNo()); qw.eq(StringUtils.isNotBlank(bo.getMaintType()), "mp.maint_type", bo.getMaintType()); qw.eq(StringUtils.isNotBlank(bo.getMaintCycleUnit()), "mp.maint_cycle_unit", bo.getMaintCycleUnit()); qw.eq(StringUtils.isNotBlank(bo.getMaintRule()), "mp.maint_rule", bo.getMaintRule()); qw.eq(bo.getMaintUser() != null, "mp.maint_user", bo.getMaintUser()); qw.in(bo.getMaintDept() != null, "mp.maint_dept", getAllDescendantIds(bo.getMaintDept())); qw.eq(bo.getStatus() != null, "mp.status", bo.getStatus()); qw.orderByDesc("mp.create_time"); return qw; } /** * 根据id,获取所有后代id * * @param rootId * @return */ public List getAllDescendantIds(Long rootId) { List result = new ArrayList<>(); result.add(rootId); collectDescendants(rootId, result); return result; } private void collectDescendants(Long currentId, List collector) { QueryWrapper sysDeptWrapper = new QueryWrapper<>(); sysDeptWrapper.lambda().eq(SysDept::getParentId, currentId); List children = sysDeptMapper.selectVoList(sysDeptWrapper); if (children != null && !children.isEmpty()) { for (SysDeptVo child : children) { Long childId = child.getDeptId(); collector.add(childId); collectDescendants(childId, collector); } } } /** * 新增保养计划 * * @param bo 保养计划 * @return 是否新增成功 */ @Override public Boolean insertByBo(EimsMaintPlanBo bo) { //setMaintNextTime(bo); EimsMaintPlan add = MapstructUtils.convert(bo, EimsMaintPlan.class); validEntityBeforeSave(add); boolean flag = baseMapper.insert(add) > 0; if (flag) { bo.setId(add.getId()); } return flag; } /** * 修改保养计划 * * @param bo 保养计划 * @return 是否修改成功 */ @Override public Boolean updateByBo(EimsMaintPlanBo bo) { //setMaintNextTime(bo); EimsMaintPlan update = MapstructUtils.convert(bo, EimsMaintPlan.class); validEntityBeforeSave(update); return baseMapper.updateById(update) > 0; } /** * 保存前的数据校验 */ private void validEntityBeforeSave(EimsMaintPlan entity) { //TODO 做一些数据校验,如唯一约束 } /** * 校验并批量删除保养计划信息 * * @param ids 待删除的主键集合 * @param isValid 是否进行有效性校验 * @return 是否删除成功 */ @Override public Boolean deleteWithValidByIds(Collection ids, Boolean isValid) { if (isValid) { //TODO 做一些业务上的校验,判断是否需要校验 } return baseMapper.deleteByIds(ids) > 0; } public String importData(MultipartFile is, boolean updateSupport) { try { int successNum = 0; int failureNum = 0; // 保养项目列表 MaintCheckItemImportListener checkItemImportListener = new MaintCheckItemImportListener(updateSupport); EasyExcel.read(is.getInputStream(), MaintCheckItemVo.class, checkItemImportListener).headRowNumber(4).sheet().doRead(); List successList = checkItemImportListener.getSuccessList(); // 读取固定资产编号 EasyExcelCellListener readListener = new EasyExcelCellListener(3, 1); EasyExcel.read(is.getInputStream(), readListener).headRowNumber(0).sheet().doReadSync(); String assetNo = Optional.ofNullable(readListener.getCellValue()) .map(value -> { int colonIndex = Math.max(value.indexOf(":"), value.indexOf(":")); // 合并冒号处理 return colonIndex != -1 ? value.substring(colonIndex + 1) : value; }) .map(String::trim) .orElse(""); if (assetNo.isEmpty()) { return is.getOriginalFilename() + " 导入失败,无法读取固定资产编号"; } // 读取保养计划年份 EasyExcelCellListener readYearListener = new EasyExcelCellListener(2, 3); EasyExcel.read(is.getInputStream(), readYearListener).headRowNumber(0).sheet().doReadSync(); String yearStr = readYearListener.getCellValue(); if (yearStr == null || yearStr.isEmpty()) { yearStr = ""; } String year = yearStr.replaceAll("[^\\d]", ""); // 去除非数字字符 year = (year.length() == 4) ? year : DateUtils.getDate().substring(0,4); QueryWrapper queryWrapper = new QueryWrapper<>(); queryWrapper.eq("asset_no", assetNo); EimsEquVo eimsEquVo = equMapper.selectVoOne(queryWrapper); if (eimsEquVo == null) { return is.getOriginalFilename() + " 设备未找到,请先在设备台帐中添加"; } // 月份字段处理优化 String[] monthFields = {"january","february","march","april","may","june", "july","august","september","october","november","december"}; for (MaintCheckItemVo itemVo : successList) { if ("执行人签名".equals(itemVo.getItemName())) break; EimsMaintPlanBo maintPlanBo = new EimsMaintPlanBo(); maintPlanBo.setEquId(eimsEquVo.getEquId()); maintPlanBo.setMaintName(itemVo.getItemName()); maintPlanBo.setStatus("0"); maintPlanBo.setMaintType("1"); maintPlanBo.setMaintRule("0"); // 添加period校验 String period = itemVo.getPeriod(); if (StringUtils.isBlank(period)) { failureNum++; continue; } if (period.length() == 1) { period = "1"+period; } try { if (period.length() > 1) { String num = period.replaceAll("[^\\d]", ""); if ("".equals(num)) { switch (period) { case "一个月": maintPlanBo.setMaintCycle(1L); maintPlanBo.setMaintCycleUnit("3"); break; case "两个月": maintPlanBo.setMaintCycle(2L); maintPlanBo.setMaintCycleUnit("3"); break; case "二个月": maintPlanBo.setMaintCycle(2L); maintPlanBo.setMaintCycleUnit("3"); break; case "三个月": maintPlanBo.setMaintCycle(3L); maintPlanBo.setMaintCycleUnit("3"); break; case "六个月": maintPlanBo.setMaintCycle(6L); maintPlanBo.setMaintCycleUnit("3"); break; default: break; } }else { maintPlanBo.setMaintCycle(Long.parseLong(num)); String substring = period.replace(num, ""); // 转换周期单位,M转换为3,D转换为1,Y转换为5,W转换为2,Q转换为4 switch (substring) { case "M": substring = "3"; break; case "D": substring = "1"; break; case "Y": substring = "5"; break; case "W": substring = "2"; break; case "Q": substring = "4"; break; case "个月": substring = "3"; break; case "天": substring = "1"; break; case "年": substring = "5"; break; case "周": substring = "2"; break; case "季度": substring = "4"; break; default: } maintPlanBo.setMaintCycleUnit(substring); } } else { maintPlanBo.setMaintCycle(Long.parseLong(period)); maintPlanBo.setMaintCycleUnit(""); } } catch (NumberFormatException e) { failureNum++; continue; } // 月份判断优化 boolean monthFound = false; for (int i = 0; i < monthFields.length; i++) { try { String monthValue = (String) MaintCheckItemVo.class .getMethod("get" + StringUtils.capitalize(monthFields[i])) .invoke(itemVo); if (StringUtils.isNotBlank(monthValue)) { String month = String.format("%02d", i+1); // 保证两位月份 maintPlanBo.setMaintFirstTime(DateUtils.parseDate(year + "-" + month + "-01")); monthFound = true; break; } } catch (Exception e) { // 反射异常处理,继续下一个月份 continue; } } if (!monthFound) { failureNum++; continue; } if (maintPlanBo.getMaintFirstTime() != null) { Date firstTime = maintPlanBo.getMaintFirstTime(); Date nextTime = calcNextTime(firstTime, maintPlanBo.getMaintCycle().intValue(), 1); maintPlanBo.setMaintNextTime(nextTime); } // 如果允许覆盖,则删除已存在的相同条件记录 if (updateSupport) { LambdaQueryWrapper deleteWrapper = Wrappers.lambdaQuery(); deleteWrapper.eq(EimsMaintPlan::getEquId, maintPlanBo.getEquId()) .eq(EimsMaintPlan::getMaintName, maintPlanBo.getMaintName()) .eq(EimsMaintPlan::getStatus, maintPlanBo.getStatus()) .eq(EimsMaintPlan::getMaintCycle, maintPlanBo.getMaintCycle()) .eq(EimsMaintPlan::getMaintCycleUnit, maintPlanBo.getMaintCycleUnit()); baseMapper.delete(deleteWrapper); } if (!insertByBo(maintPlanBo)) { failureNum++; } else { successNum++; } } // 如果失败条件小于1则不打印信息 if (failureNum <= 0) { return "成功!"; } else { return is.getOriginalFilename() + " 导入成功:" + successNum + "条,导入失败:" + failureNum + "条"; } } catch (Exception e) { return is.getOriginalFilename() + " 导入异常:" + e.getMessage(); } } private Date calcNextTime(Date firstTime, int intervalMonths, int initialOffset) { if (intervalMonths <= 0) { throw new IllegalArgumentException("Interval months must be positive"); } if (firstTime == null) { throw new IllegalArgumentException("First time cannot be null"); } Date current = new Date(); int adjustmentCount = initialOffset; Date workingDate = (Date) firstTime.clone(); while (workingDate.before(current)) { adjustmentCount++; workingDate = DateUtils.addMonths(workingDate, intervalMonths); } return (Date) workingDate.clone(); } }