package org.jeecg.modules.eam.job; import cn.hutool.core.collection.CollectionUtil; import lombok.extern.slf4j.Slf4j; import org.jeecg.common.constant.CommonConstant; import org.jeecg.common.util.DateUtils; import org.jeecg.modules.eam.constant.BusinessCodeConst; import org.jeecg.modules.eam.constant.MaintenanceCategoryEnum; import org.jeecg.modules.eam.constant.OrderCreationMethodEnum; import org.jeecg.modules.eam.entity.EamEquipment; import org.jeecg.modules.eam.entity.EamMaintenanceStandard; import org.jeecg.modules.eam.entity.EamMaintenanceStandardDetail; import org.jeecg.modules.eam.entity.EamSecondMaintenanceOrderDetail; import org.jeecg.modules.eam.request.EamSecondMaintenanceRequest; import org.jeecg.modules.eam.service.*; import org.jeecg.modules.quartz.entity.QuartzJob; import org.jeecg.modules.quartz.entity.SysQuartzLog; import org.jeecg.modules.quartz.service.IQuartzJobService; import org.jeecg.modules.quartz.service.ISysQuartzLogService; import org.jeecg.modules.system.service.ISysBusinessCodeRuleService; import org.quartz.Job; import org.quartz.JobExecutionContext; import org.quartz.JobExecutionException; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.stereotype.Component; import org.springframework.transaction.annotation.Transactional; import java.util.Calendar; import java.util.Date; import java.util.List; import java.util.concurrent.atomic.AtomicInteger; import java.util.stream.Collectors; /** * @Author: Lyh * @CreateTime: 2025-09-01 * @Description: 二保工单生成 */ @Component @Slf4j public class SecondMaintenanceOrderGenerateJob implements Job { @Autowired private IEamEquipmentService equipmentService; @Autowired private IEamSecondMaintenanceOrderService eamSecondMaintenanceOrderService; @Autowired private IEamMaintenanceStandardService eamMaintenanceStandardService; @Autowired private IEamMaintenanceStandardDetailService eamMaintenanceStandardDetailService; @Autowired private ISysBusinessCodeRuleService businessCodeRuleService; @Autowired private ISysQuartzLogService sysQuartzLogService; @Autowired private IQuartzJobService quartzJobService; @Autowired private IEamEquipmentExtendService equipmentExtendService; @Override @Transactional(rollbackFor = Exception.class) public void execute(JobExecutionContext jobExecutionContext) throws JobExecutionException { // 任务日志初始化 SysQuartzLog quartzLog = new SysQuartzLog(); quartzLog.setCreateTime(new Date()); List byJobClassName = quartzJobService.findByJobClassName(this.getClass().getName()); if (byJobClassName != null && !byJobClassName.isEmpty()) { quartzLog.setJobId(byJobClassName.get(0).getId()); } long startTime = System.currentTimeMillis(); // 获取需要二保的设备列表 List equipmentList = equipmentService.selectSecondMaintenanceEquipmentList(); if (CollectionUtil.isEmpty(equipmentList)) { log.warn("没有需要生成二保工单的设备!日期:{}", DateUtils.date2Str(DateUtils.date_sdf.get())); quartzLog.setIsSuccess(-1); quartzLog.setExceptionDetail("没有需要生成二保工单的设备"); saveQuartzLog(quartzLog, startTime); return; } AtomicInteger successCount = new AtomicInteger(0); AtomicInteger failCount = new AtomicInteger(0); StringBuilder sb = new StringBuilder(); // 遍历设备生成工单 for (EamEquipment equipment : equipmentList) { generateSecondMaintenanceOrder( equipment, successCount, failCount, sb ); } // 保存任务日志 quartzLog.setIsSuccess(failCount.get() > 0 ? -1 : 0); sb.insert(0, "二保工单生成结果:"); sb.append("\n成功:").append(successCount.get()).append(",失败:").append(failCount.get()); quartzLog.setExceptionDetail(sb.toString()); saveQuartzLog(quartzLog, startTime); } private void saveQuartzLog(SysQuartzLog quartzLog, long startTime) { long endTime = System.currentTimeMillis(); quartzLog.setExecutionTime(Integer.parseInt(String.valueOf(endTime - startTime))); sysQuartzLogService.save(quartzLog); } private void generateSecondMaintenanceOrder(EamEquipment equipment, AtomicInteger successCount, AtomicInteger failCount, StringBuilder sb) { Date nextMaintenanceDate=equipment.getNextSecondMaintenance(); //检查是否满足生成条件,提前一天生成 Calendar cal = Calendar.getInstance(); cal.setTime(nextMaintenanceDate); cal.add(Calendar.DAY_OF_MONTH, -1); Date targetDate = cal.getTime(); // 获取当前日期(不含时间部分) Calendar today = Calendar.getInstance(); today.set(Calendar.HOUR_OF_DAY, 0); today.set(Calendar.MINUTE, 0); today.set(Calendar.SECOND, 0); today.set(Calendar.MILLISECOND, 0); // 比较日期是否匹配 if (targetDate.equals(today.getTime())) { // 生成二保工单 EamMaintenanceStandard standard = eamMaintenanceStandardService.queryByEquipmentIdAndCategory( equipment.getId(), MaintenanceCategoryEnum.SECOND_MAINTENANCE.name() ); if (standard == null) { handleFailure(equipment, "未配置二级保养规范", failCount, sb); return; } // 获取规范明细 List details = eamMaintenanceStandardDetailService.selectByStandardId(standard.getId()); if (CollectionUtil.isEmpty(details)) { handleFailure(equipment, "未配置二级保养规范明细", failCount, sb); return; } // 构建工单请求 EamSecondMaintenanceRequest request = new EamSecondMaintenanceRequest(); request.setOrderNum(businessCodeRuleService.generateBusinessCodeSeq(BusinessCodeConst.SECOND_MAINTENANCE_CODE_RULE)); request.setEquipmentId(equipment.getId()); request.setStandardId(standard.getId()); request.setMaintenanceDate(nextMaintenanceDate); request.setCreationMethod(OrderCreationMethodEnum.AUTO.name()); // 转换规范明细 List orderDetails = details.stream() .map(EamSecondMaintenanceOrderDetail::new) .collect(Collectors.toList()); request.setTableDetailList(orderDetails); try { // 创建工单 eamSecondMaintenanceOrderService.addMaintenance(request); // 更新设备状态 equipmentExtendService.updateSecondMaintenanceParam( equipment.getId(), null, CommonConstant.STATUS_1 ); successCount.incrementAndGet(); log.info("设备 {} 二保工单生成成功", equipment.getEquipmentCode()); } catch (Exception e) { handleFailure(equipment, "生成失败: " + e.getMessage(), failCount, sb); log.error("设备 {} 二保工单生成异常", equipment.getEquipmentCode(), e); } } } private void handleFailure(EamEquipment equipment, String reason, AtomicInteger failCount, StringBuilder sb) { failCount.incrementAndGet(); sb.append("\n设备 ") .append(equipment.getEquipmentCode()) .append(":") .append(reason); log.warn("设备 {} 二保工单生成失败:{}", equipment.getEquipmentCode(), reason); } }