diff --git a/nflg-qms-admin/src/main/java/com/nflg/qms/admin/service/QmsPdiInspectionResultsControllerService.java b/nflg-qms-admin/src/main/java/com/nflg/qms/admin/service/QmsPdiInspectionResultsControllerService.java index 5a5e3cbd..97b45dc0 100644 --- a/nflg-qms-admin/src/main/java/com/nflg/qms/admin/service/QmsPdiInspectionResultsControllerService.java +++ b/nflg-qms-admin/src/main/java/com/nflg/qms/admin/service/QmsPdiInspectionResultsControllerService.java @@ -229,12 +229,18 @@ public class QmsPdiInspectionResultsControllerService { // 6. 根据整体判定+检测项结果设置状态:有不合格则=3(待流转),全合格则=2(已完成) boolean hasDefect = !overallResult || !failedItems.isEmpty(); - boolean overdue = taskRecord.getRequiredCompletionTime() != null - && now.isAfter(taskRecord.getRequiredCompletionTime()); + + // 校验 overdue 字段:无值时根据完成时间与要求完成时间比较设置,有值则保持原值 + Boolean overdueValue = taskRecord.getOverdue(); + if (overdueValue == null) { + overdueValue = taskRecord.getRequiredCompletionTime() != null + && now.isAfter(taskRecord.getRequiredCompletionTime()); + } + taskRecordService.lambdaUpdate() .eq(QmsPdiTaskRecord::getId, taskRecord.getId()) .set(QmsPdiTaskRecord::getDetectionCompletionTime, now) - .set(QmsPdiTaskRecord::getOverdue, overdue) + .set(QmsPdiTaskRecord::getOverdue, overdueValue) .set(QmsPdiTaskRecord::getInspectionEnable, hasDefect ? 3 : 2) .update(); diff --git a/nflg-wms-repository/src/main/java/com/nflg/wms/repository/entity/QmsPdiTaskRecord.java b/nflg-wms-repository/src/main/java/com/nflg/wms/repository/entity/QmsPdiTaskRecord.java index 610c224d..914b43e6 100644 --- a/nflg-wms-repository/src/main/java/com/nflg/wms/repository/entity/QmsPdiTaskRecord.java +++ b/nflg-wms-repository/src/main/java/com/nflg/wms/repository/entity/QmsPdiTaskRecord.java @@ -77,6 +77,11 @@ public class QmsPdiTaskRecord implements Serializable { */ private Boolean overdue; + /** + * 信息推送记录:0=未推送,1=已推送即将超时信息,2=已推送超时信息 + */ + private Short pushRecords; + /** * 工厂编号 */ diff --git a/nflg-wms-scheduled/src/main/java/com/nflg/wms/scheduled/processor/PdiTaskOverdueNotifyProcessor.java b/nflg-wms-scheduled/src/main/java/com/nflg/wms/scheduled/processor/PdiTaskOverdueNotifyProcessor.java new file mode 100644 index 00000000..9b380b8b --- /dev/null +++ b/nflg-wms-scheduled/src/main/java/com/nflg/wms/scheduled/processor/PdiTaskOverdueNotifyProcessor.java @@ -0,0 +1,251 @@ +package com.nflg.wms.scheduled.processor; + +import cn.hutool.core.collection.CollectionUtil; +import cn.hutool.core.util.StrUtil; +import com.nflg.wms.repository.entity.Department; +import com.nflg.wms.repository.entity.DictionaryItem; +import com.nflg.wms.repository.entity.QmsPdiDetectionRules; +import com.nflg.wms.repository.entity.QmsPdiTaskRecord; +import com.nflg.wms.repository.entity.QmsTodoItem; +import com.nflg.wms.repository.entity.UserInterior; +import com.nflg.wms.repository.service.IDepartmentService; +import com.nflg.wms.repository.service.IDictionaryItemService; +import com.nflg.wms.repository.service.IQmsPdiDetectionRulesService; +import com.nflg.wms.repository.service.IQmsPdiTaskRecordService; +import com.nflg.wms.repository.service.IQmsTodoItemService; +import com.nflg.wms.repository.service.IUserInteriorService; +import jakarta.annotation.Resource; +import org.springframework.stereotype.Component; +import tech.powerjob.worker.core.processor.ProcessResult; +import tech.powerjob.worker.core.processor.TaskContext; +import tech.powerjob.worker.core.processor.sdk.BasicProcessor; +import tech.powerjob.worker.log.OmsLogger; + +import java.time.Duration; +import java.time.LocalDateTime; +import java.util.*; +import java.util.stream.Collectors; + +/** + * PDI检测任务超期通知定时任务 + * 每分钟执行一次,检测未完成的任务是否超期或即将超期,并推送消息 + */ +@Component(value = "PdiTaskOverdueNotifyProcessor") +public class PdiTaskOverdueNotifyProcessor implements BasicProcessor { + + @Resource + private IQmsPdiTaskRecordService taskRecordService; + + @Resource + private IQmsPdiDetectionRulesService detectionRulesService; + + @Resource + private IUserInteriorService userInteriorService; + + @Resource + private IDepartmentService departmentService; + + @Resource + private IQmsTodoItemService todoItemService; + + @Resource + private IDictionaryItemService dictionaryItemService; + + @Override + public ProcessResult process(TaskContext context) { + OmsLogger omsLogger = context.getOmsLogger(); + omsLogger.info("开始执行PDI检测任务超期通知定时任务"); + + try { + // 查询字典ID + DictionaryItem dictItem = dictionaryItemService.lambdaQuery() + .eq(DictionaryItem::getCode, "PDIDetectionTaskTimeoutReminder") + .one(); + if (dictItem == null) { + omsLogger.error("未找到字典项:PDIDetectionTaskTimeoutReminder"); + return new ProcessResult(false, "未找到字典项"); + } + Long sourceTypeId = dictItem.getId(); + + // 查询所有未完成检测的任务 + List tasks = taskRecordService.lambdaQuery() + .isNull(QmsPdiTaskRecord::getDetectionCompletionTime) + .list(); + + omsLogger.info("共查询到【{}】条未完成任务", tasks.size()); + + LocalDateTime now = LocalDateTime.now(); + int notifyCount = 0; + + for (QmsPdiTaskRecord task : tasks) { + try { + if (task.getRequiredCompletionTime() == null) { + continue; + } + + // 计算时间差(分钟) + long minutes = Duration.between(now, task.getRequiredCompletionTime()).toMinutes(); + long hours = Math.abs(minutes) / 60; + + if (minutes < 0) { + // 已超期 + if (task.getPushRecords() == null || task.getPushRecords() != 2) { + // 更新超期状态和推送记录 + taskRecordService.lambdaUpdate() + .eq(QmsPdiTaskRecord::getId, task.getId()) + .set(QmsPdiTaskRecord::getOverdue, true) + .set(QmsPdiTaskRecord::getPushRecords, (short) 2) + .update(); + + // 查询质检人和帮办人 + QmsPdiDetectionRules rules = detectionRulesService.getById(task.getDetectionRulesId()); + if (rules == null || rules.getInspectorId() == null) { + omsLogger.warn("任务【{}】未找到质检人", task.getTaskNo()); + continue; + } + + Long inspectorId = rules.getInspectorId(); + Long assistantId = task.getAssistantId(); + + // 查询质检人信息 + UserInterior inspector = userInteriorService.lambdaQuery() + .eq(UserInterior::getUserId, inspectorId) + .one(); + + String inspectorName = inspector != null ? inspector.getUserName() : "未知"; + String assistantName = ""; + + if (assistantId != null) { + UserInterior assistant = userInteriorService.lambdaQuery() + .eq(UserInterior::getUserId, assistantId) + .one(); + assistantName = assistant != null ? assistant.getUserName() : "未知"; + } + + String assistantText = StrUtil.isNotBlank(assistantName) ? "+" + assistantName : ""; + + // 查询部门领导 + Set leaderIds = new HashSet<>(); + + // 质检人的部门领导 + if (inspector != null && inspector.getDeptId() != null) { + Department dept = departmentService.getById(inspector.getDeptId()); + if (dept != null && dept.getHeadUserId() != null) { + leaderIds.add(dept.getHeadUserId()); + } + } + + // 帮办人的部门领导 + if (assistantId != null) { + UserInterior assistant = userInteriorService.lambdaQuery() + .eq(UserInterior::getUserId, assistantId) + .one(); + if (assistant != null && assistant.getDeptId() != null) { + Department dept = departmentService.getById(assistant.getDeptId()); + if (dept != null && dept.getHeadUserId() != null) { + leaderIds.add(dept.getHeadUserId()); + } + } + } + + // 给部门领导推送消息 + String messageContent = String.format("PDI检测任务[%s]已超期,检测人为[%s%s]", + task.getTaskNo(), inspectorName, assistantText); + + for (Long leaderId : leaderIds) { + UserInterior leader = userInteriorService.lambdaQuery() + .eq(UserInterior::getUserId, leaderId) + .one(); + + QmsTodoItem todo = new QmsTodoItem() + .setCode(task.getTaskNo()) + .setSourceTypeId(sourceTypeId) + .setSourceId(task.getId()) + .setIsRead(false) + .setCreateUserId(leaderId) + .setCreateUserName(leader != null ? leader.getUserName() : "未知") + .setCreateTime(now); + todoItemService.save(todo); + + omsLogger.info("向部门领导【{}】推送超期消息:{}", leaderId, messageContent); + } + + notifyCount++; + } + } else if (hours <= 24) { + // 即将超期(24小时内) + if (task.getPushRecords() == null || task.getPushRecords() == 0) { + // 更新推送记录 + taskRecordService.lambdaUpdate() + .eq(QmsPdiTaskRecord::getId, task.getId()) + .set(QmsPdiTaskRecord::getPushRecords, (short) 1) + .update(); + + // 查询质检人和帮办人 + QmsPdiDetectionRules rules = detectionRulesService.getById(task.getDetectionRulesId()); + if (rules == null || rules.getInspectorId() == null) { + omsLogger.warn("任务【{}】未找到质检人", task.getTaskNo()); + continue; + } + + Long inspectorId = rules.getInspectorId(); + Long assistantId = task.getAssistantId(); + + // 给质检人推送消息 + long remainingHours = hours + (minutes % 60 != 0 ? 1 : 0); + String messageContent = String.format("PDI检测任务[%s]将在%d小时内到期,请尽快完成", + task.getTaskNo(), remainingHours); + + UserInterior inspector = userInteriorService.lambdaQuery() + .eq(UserInterior::getUserId, inspectorId) + .one(); + + QmsTodoItem todoInspector = new QmsTodoItem() + .setCode(task.getTaskNo()) + .setSourceTypeId(sourceTypeId) + .setSourceId(task.getId()) + .setIsRead(false) + .setCreateUserId(inspectorId) + .setCreateUserName(inspector != null ? inspector.getUserName() : "未知") + .setCreateTime(now); + todoItemService.save(todoInspector); + + omsLogger.info("向质检人【{}】推送即将超期消息:{}", inspectorId, messageContent); + + // 给帮办人推送消息 + if (assistantId != null) { + UserInterior assistant = userInteriorService.lambdaQuery() + .eq(UserInterior::getUserId, assistantId) + .one(); + + QmsTodoItem todoAssistant = new QmsTodoItem() + .setCode(task.getTaskNo()) + .setSourceTypeId(sourceTypeId) + .setSourceId(task.getId()) + .setIsRead(false) + .setCreateUserId(assistantId) + .setCreateUserName(assistant != null ? assistant.getUserName() : "未知") + .setCreateTime(now); + todoItemService.save(todoAssistant); + + omsLogger.info("向帮办人【{}】推送即将超期消息:{}", assistantId, messageContent); + } + + notifyCount++; + } + } + } catch (Exception e) { + omsLogger.error("处理任务【{}】异常", task.getTaskNo(), e); + } + } + + omsLogger.info("执行完成,共推送【{}】条消息", notifyCount); + return new ProcessResult(true, "执行完成,推送" + notifyCount + "条消息"); + } catch (Exception e) { + omsLogger.error("执行异常", e); + return new ProcessResult(false, "执行异常: " + e.getMessage()); + } finally { + omsLogger.info("执行结束"); + } + } +}