diff --git a/viewsh-module-ops/viewsh-module-environment-biz/src/main/java/com/viewsh/module/ops/environment/integration/listener/CleanOrderEventListener.java b/viewsh-module-ops/viewsh-module-environment-biz/src/main/java/com/viewsh/module/ops/environment/integration/listener/CleanOrderEventListener.java index df3e0db3..b0a8e1ca 100644 --- a/viewsh-module-ops/viewsh-module-environment-biz/src/main/java/com/viewsh/module/ops/environment/integration/listener/CleanOrderEventListener.java +++ b/viewsh-module-ops/viewsh-module-environment-biz/src/main/java/com/viewsh/module/ops/environment/integration/listener/CleanOrderEventListener.java @@ -11,12 +11,16 @@ import com.viewsh.module.ops.core.event.OrderCreatedEvent; import com.viewsh.module.ops.core.event.OrderStateChangedEvent; import com.viewsh.module.ops.dal.dataobject.workorder.OpsOrderDO; import com.viewsh.module.ops.dal.mysql.workorder.OpsOrderMapper; +import com.viewsh.module.ops.enums.OperatorTypeEnum; import com.viewsh.module.ops.enums.PriorityEnum; +import com.viewsh.module.ops.enums.WorkOrderStatusEnum; +import com.viewsh.module.ops.enums.WorkOrderTypeEnum; import com.viewsh.module.ops.environment.constants.CleanNotificationConstants; import com.viewsh.module.ops.environment.dal.dataobject.workorder.OpsOrderCleanExtDO; import com.viewsh.module.ops.environment.dal.mysql.workorder.OpsOrderCleanExtMapper; import com.viewsh.module.ops.environment.dal.redis.TrafficActiveOrderRedisDAO; import com.viewsh.module.ops.environment.service.cleanorder.CleanOrderService; +import com.viewsh.module.ops.environment.service.notification.CleanOrderNotificationService; import com.viewsh.module.ops.environment.service.voice.TtsQueueMessage; import com.viewsh.module.ops.environment.service.voice.VoiceBroadcastService; import com.viewsh.module.ops.infrastructure.log.enumeration.EventDomain; @@ -24,8 +28,6 @@ import com.viewsh.module.ops.infrastructure.log.enumeration.LogModule; import com.viewsh.module.ops.infrastructure.log.enumeration.LogType; import com.viewsh.module.ops.infrastructure.log.recorder.EventLogRecord; import com.viewsh.module.ops.infrastructure.log.recorder.EventLogRecorder; -import com.viewsh.module.system.api.notify.NotifyMessageSendApi; -import com.viewsh.module.system.api.notify.dto.NotifySendSingleToUserReqDTO; import jakarta.annotation.Resource; import lombok.extern.slf4j.Slf4j; import org.springframework.context.event.EventListener; @@ -79,14 +81,9 @@ public class CleanOrderEventListener { @Resource private VoiceBroadcastService voiceBroadcastService; - @Resource - private NotifyMessageSendApi notifyMessageSendApi; - @Resource private EventLogRecorder eventLogRecorder; - @Resource - private OrderQueueService orderQueueService; @Resource private TrafficActiveOrderRedisDAO trafficActiveOrderRedisDAO; @@ -94,6 +91,9 @@ public class CleanOrderEventListener { @Resource private IotDeviceControlApi iotDeviceControlApi; + @Resource + private CleanOrderNotificationService cleanOrderNotificationService; + // ==================== 工单创建事件 ==================== /** @@ -105,7 +105,7 @@ public class CleanOrderEventListener { */ @org.springframework.transaction.event.TransactionalEventListener(phase = org.springframework.transaction.event.TransactionPhase.AFTER_COMMIT) public void onOrderCreated(OrderCreatedEvent event) { - if (!"CLEAN".equals(event.getOrderType())) { + if (!WorkOrderTypeEnum.CLEAN.getType().equals(event.getOrderType())) { return; } @@ -166,7 +166,7 @@ public class CleanOrderEventListener { */ @EventListener public void onOrderStateChanged(OrderStateChangedEvent event) { - if (!"CLEAN".equals(event.getOrderType())) { + if (!WorkOrderTypeEnum.CLEAN.getType().equals(event.getOrderType())) { return; } @@ -229,11 +229,14 @@ public class CleanOrderEventListener { } if (deviceId != null) { // 发送新工单通知(语音+站内信) - sendNewOrderNotification(deviceId, orderId); + cleanOrderNotificationService.sendNewOrderNotification(deviceId, orderId); } else { log.warn("[CleanOrderEventListener] DISPATCHED 事件缺少 assigneeId 和 operatorId: orderId={}", orderId); } + + // 4. 记录派单业务日志 + recordDispatchedLog(orderId, deviceId, event); } /** @@ -248,10 +251,29 @@ public class CleanOrderEventListener { deviceId = event.getOperatorId(); } - if (deviceId != null) { - // TODO 入队语音播报暂时关闭,后续按需开启 - log.info("[CleanOrderEventListener] 工单入队: deviceId={}, orderId={}", deviceId, orderId); + // 1. 业务日志 + String assigneeName = (String) event.getPayload().get("assigneeName"); + String message = assigneeName != null + ? String.format("工单已入队,分配给 %s,等待派发", assigneeName) + : "工单已入队等待派发"; + try { + EventLogRecord.EventLogRecordBuilder builder = EventLogRecord.builder() + .module(LogModule.CLEAN) + .domain(EventDomain.DISPATCH) + .eventType(LogType.ORDER_QUEUED.getCode()) + .message(message) + .targetId(orderId) + .targetType("order"); + if (deviceId != null) { + builder.deviceId(deviceId).personId(deviceId); + } + eventLogRecorder.record(builder.build()); + } catch (Exception e) { + log.warn("[CleanOrderEventListener] 记录入队业务日志失败: orderId={}", orderId, e); } + + // 2. TODO 入队语音播报暂时关闭,后续按需开启 + log.info("[CleanOrderEventListener] 工单入队: deviceId={}, orderId={}", deviceId, orderId); } /** @@ -349,6 +371,34 @@ public class CleanOrderEventListener { // 2. 记录暂停开始时间到扩展表 recordPauseStartTime(orderId); + // 3. 业务日志 + String remark = event.getRemark(); + Long urgentOrderId = event.getPayloadLong("urgentOrderId"); + String message; + if (urgentOrderId != null) { + message = "P0紧急任务打断,工单暂停"; + } else { + message = "工单已暂停"; + } + if (remark != null && !remark.isEmpty()) { + message += "(" + remark + ")"; + } + try { + EventLogRecord.EventLogRecordBuilder builder = EventLogRecord.builder() + .module(LogModule.CLEAN) + .domain(EventDomain.DISPATCH) + .eventType(LogType.ORDER_PAUSED.getCode()) + .message(message) + .targetId(orderId) + .targetType("order"); + if (deviceId != null) { + builder.deviceId(deviceId).personId(deviceId); + } + eventLogRecorder.record(builder.build()); + } catch (Exception e) { + log.warn("[CleanOrderEventListener] 记录暂停业务日志失败: orderId={}", orderId, e); + } + // 设备状态由 BadgeDeviceStatusEventListener 统一处理 log.info("[CleanOrderEventListener] 暂停处理完成: orderId={}, deviceId={}", orderId, deviceId); } @@ -441,7 +491,10 @@ public class CleanOrderEventListener { TtsQueueMessage.TTS_FLAG_URGENT, orderId); } - // 3. 自动调度下一个等待任务(如果有 assignee) + // 3. 记录取消业务日志 + recordCancelledLog(orderId, deviceId, event); + + // 4. 自动调度下一个等待任务(如果有 assignee) if (deviceId != null) { try { cleanOrderService.autoDispatchNextOrder(orderId, deviceId); @@ -463,7 +516,7 @@ public class CleanOrderEventListener { */ @EventListener public void onOrderCompleted(OrderCompletedEvent event) { - if (!"CLEAN".equals(event.getOrderType())) { + if (!WorkOrderTypeEnum.CLEAN.getType().equals(event.getOrderType())) { return; } @@ -491,238 +544,6 @@ public class CleanOrderEventListener { cleanOrderService.autoDispatchNextOrder(orderId, deviceId); } - // ==================== 通知方法 ==================== - - /** - * 发送新工单通知(循环语音播报 + 站内信) - */ - @Async("ops-task-executor") - public void sendNewOrderNotification(Long deviceId, Long orderId) { - try { - OpsOrderDO order = opsOrderMapper.selectById(orderId); - if (order == null) { - log.warn("[新工单通知] 工单不存在: orderId={}", orderId); - return; - } - - log.info("[新工单通知] deviceId={}, orderId={}", deviceId, orderId); - - // 1. 启动循环语音播报"工单来了" - voiceBroadcastService.broadcastLoop(deviceId, - CleanNotificationConstants.VoiceTemplate.NEW_ORDER_RING, orderId); - - // 2. 发送站内信(暂时发送到管理员) - sendNotifyMessage(1L, - CleanNotificationConstants.TemplateCode.NEW_ORDER, - CleanNotificationConstants.NotifyParamsBuilder.newOrderParams( - order.getOrderCode(), - order.getTitle(), - CleanNotificationConstants.VoiceBuilder.getAreaName(order.getLocation()))); - - } catch (Exception e) { - log.error("[新工单通知] 发送失败: deviceId={}, orderId={}", deviceId, orderId, e); - } - } - - /** - * 发送待办增加通知 - */ - @Async("ops-task-executor") - public void sendQueuedOrderNotification(Long deviceId, int queueCount, Long orderId) { - try { - log.info("[待办增加通知] deviceId={}, queueCount={}", deviceId, queueCount); - - // 1. 语音播报(使用统一模板构建器) - String voiceMessage = CleanNotificationConstants.VoiceBuilder.buildQueuedOrder(queueCount); - playVoice(deviceId, voiceMessage, orderId); - - // 2. 发送站内信(待办数量较多时) - if (queueCount >= 3) { - sendNotifyMessage(1L, - CleanNotificationConstants.TemplateCode.QUEUED_ORDER, - CleanNotificationConstants.NotifyParamsBuilder.queuedOrderParams(queueCount, 1)); - } - - } catch (Exception e) { - log.error("[待办增加通知] 发送失败: deviceId={}", deviceId, e); - } - } - - /** - * 发送下一个任务通知 - */ - @Async("ops-task-executor") - public void sendNextTaskNotification(Long deviceId, int queueCount, String orderTitle) { - try { - log.info("[下一任务通知] deviceId={}, queueCount={}, title={}", deviceId, queueCount, orderTitle); - - // 1. 语音播报(使用统一模板构建器) - String voiceMessage = CleanNotificationConstants.VoiceBuilder.buildNextTask(orderTitle); - playVoice(deviceId, voiceMessage); - - // 2. 发送站内信 - sendNotifyMessage(1L, - CleanNotificationConstants.TemplateCode.NEXT_TASK, - CleanNotificationConstants.NotifyParamsBuilder.nextTaskParams(queueCount, orderTitle)); - - } catch (Exception e) { - log.error("[下一任务通知] 发送失败: deviceId={}", deviceId, e); - } - } - - /** - * 发送P0紧急任务插队通知 - */ - @Async("ops-task-executor") - public void sendPriorityUpgradeNotification(Long deviceId, String orderCode, Long orderId) { - try { - log.warn("[P0紧急通知] deviceId={}, orderCode={}", deviceId, orderCode); - - // 1. 语音播报(P0紧急,插队到队列头部) - String voiceMessage = CleanNotificationConstants.VoiceBuilder.buildPriorityUpgrade(orderCode); - playVoiceUrgent(deviceId, voiceMessage, orderId); - - // 2. 发送站内信 - sendNotifyMessage(1L, - CleanNotificationConstants.TemplateCode.PRIORITY_UPGRADE, - CleanNotificationConstants.NotifyParamsBuilder.priorityUpgradeParams(orderCode, "P0紧急任务")); - - } catch (Exception e) { - log.error("[P0紧急通知] 发送失败: deviceId={}", deviceId, e); - } - } - - /** - * 发送任务恢复通知 - */ - @Async("ops-task-executor") - public void sendTaskResumedNotification(Long deviceId, String areaName) { - try { - log.info("[任务恢复通知] deviceId={}, areaName={}", deviceId, areaName); - - // 1. 语音播报(使用统一模板构建器) - String voiceMessage = CleanNotificationConstants.VoiceBuilder.buildTaskResumed(areaName); - playVoice(deviceId, voiceMessage); - - // 2. 发送站内信 - sendNotifyMessage(1L, - CleanNotificationConstants.TemplateCode.TASK_RESUMED, - CleanNotificationConstants.NotifyParamsBuilder.taskResumedParams(areaName)); - - } catch (Exception e) { - log.error("[任务恢复通知] 发送失败: deviceId={}", deviceId, e); - } - } - - /** - * 发送工单完成通知(语音播报 + 站内信) - */ - public void sendOrderCompletedNotification(Long orderId, Long deviceId) { - try { - OpsOrderDO order = opsOrderMapper.selectById(orderId); - if (order == null) { - return; - } - - log.info("[工单完成通知] orderId={}, orderCode={}, areaId={}, deviceId={}", - orderId, order.getOrderCode(), order.getAreaId(), deviceId); - - // 1. 语音播报 - 通知保洁员工单已完成 - if (deviceId != null) { - playVoice(deviceId, CleanNotificationConstants.VoiceTemplate.ORDER_COMPLETED, orderId); - } - - // 2. 发送站内信(给管理员) - sendNotifyMessage(1L, - CleanNotificationConstants.TemplateCode.ORDER_COMPLETED, - CleanNotificationConstants.NotifyParamsBuilder.orderCompletedParams( - order.getOrderCode(), - CleanNotificationConstants.VoiceBuilder.getAreaName(order.getLocation()), - order.getTitle())); - - } catch (Exception e) { - log.error("[工单完成通知] 发送失败: orderId={}, deviceId={}", orderId, deviceId, e); - } - } - - /** - * 播放语音(供外部调用) - */ - @Async("ops-task-executor") - public void playVoiceForNewOrder(Long deviceId) { - playVoice(deviceId, CleanNotificationConstants.VoiceTemplate.NEW_ORDER_SHORT); - } - - // ==================== 设备操作方法 ==================== - - /** - * 语音播报 - */ - private void playVoice(Long deviceId, String message) { - playVoice(deviceId, message, null); - } - - /** - * 语音播报(带工单ID,按序入队 FIFO) - *
- * 大多数业务通知使用此方法,保证同一设备上的播报按入队顺序播放。 - * 仅 P0 紧急插队场景使用 {@link #playVoiceUrgent}。 - */ - private void playVoice(Long deviceId, String message, Long orderId) { - try { - voiceBroadcastService.broadcastInOrder(deviceId, message, orderId); - log.debug("[语音播报] 调用成功: deviceId={}, message={}", deviceId, message); - - } catch (Exception e) { - log.error("[语音播报] 调用失败: deviceId={}, message={}", deviceId, message, e); - } - } - - /** - * 紧急语音播报(插队到队列头部) - *
- * 仅用于 P0 紧急任务打断等需要立即播报的场景
- */
- private void playVoiceUrgent(Long deviceId, String message, Long orderId) {
- try {
- voiceBroadcastService.broadcastUrgent(deviceId, message, orderId);
- log.debug("[语音播报-紧急] 调用成功: deviceId={}, message={}", deviceId, message);
-
- } catch (Exception e) {
- log.error("[语音播报-紧急] 调用失败: deviceId={}, message={}", deviceId, message, e);
- }
- }
-
- // ==================== 站内信发送方法 ====================
-
- /**
- * 发送站内信
- */
- private void sendNotifyMessage(Long userId, String templateCode, Map
@@ -1047,4 +868,95 @@ public class CleanOrderEventListener {
log.warn("[CleanOrderEventListener] 记录完成业务日志失败: orderId={}", orderId, e);
}
}
+
+ /**
+ * 记录工单派单业务日志
+ */
+ private void recordDispatchedLog(Long orderId, Long deviceId, OrderStateChangedEvent event) {
+ try {
+ OperatorTypeEnum operatorType = event.getOperatorType();
+ Long operatorId = event.getOperatorId();
+ String assigneeName = (String) event.getPayload().get("assigneeName");
+ String message;
+
+ if (event.getOldStatus() == WorkOrderStatusEnum.PAUSED) {
+ message = "工单从暂停恢复,重新派发";
+ } else if (operatorType == OperatorTypeEnum.ADMIN && operatorId != null) {
+ // 尝试从 event payload 获取操作人姓名
+ String opName = (String) event.getPayload().get("operatorName");
+ String opLabel = opName != null ? opName : "操作人";
+ String targetLabel = assigneeName != null ? assigneeName : "设备";
+ message = String.format("%s 将工单派发给 %s", opLabel, targetLabel);
+ } else {
+ message = assigneeName != null
+ ? String.format("工单已派发给 %s", assigneeName)
+ : "工单已自动派发";
+ }
+
+ EventLogRecord.EventLogRecordBuilder builder = EventLogRecord.builder()
+ .module(LogModule.CLEAN)
+ .domain(EventDomain.DISPATCH)
+ .eventType(LogType.ORDER_DISPATCHED.getCode())
+ .message(message)
+ .targetId(orderId)
+ .targetType("order");
+
+ if (deviceId != null) {
+ builder.deviceId(deviceId);
+ }
+ if (operatorType == OperatorTypeEnum.ADMIN && operatorId != null) {
+ builder.personId(operatorId);
+ } else if (deviceId != null) {
+ builder.personId(deviceId);
+ }
+
+ eventLogRecorder.record(builder.build());
+ } catch (Exception e) {
+ log.warn("[CleanOrderEventListener] 记录派单业务日志失败: orderId={}", orderId, e);
+ }
+ }
+
+ /**
+ * 记录工单取消业务日志
+ */
+ private void recordCancelledLog(Long orderId, Long deviceId, OrderStateChangedEvent event) {
+ try {
+ OperatorTypeEnum operatorType = event.getOperatorType();
+ Long operatorId = event.getOperatorId();
+ String remark = event.getRemark();
+
+ String message;
+ if (operatorType == OperatorTypeEnum.SYSTEM) {
+ message = "系统自动取消";
+ } else if (operatorType == OperatorTypeEnum.ADMIN) {
+ String opName = (String) event.getPayload().get("operatorName");
+ String opLabel = opName != null ? opName : "操作人";
+ message = opLabel + " 取消了工单";
+ } else {
+ message = "保洁工单已取消";
+ }
+ if (remark != null && !remark.isEmpty()) {
+ message += "(" + remark + ")";
+ }
+
+ EventLogRecord.EventLogRecordBuilder builder = EventLogRecord.builder()
+ .module(LogModule.CLEAN)
+ .domain(EventDomain.DISPATCH)
+ .eventType(LogType.ORDER_CANCELLED.getCode())
+ .message(message)
+ .targetId(orderId)
+ .targetType("order");
+
+ // personId: 管理员取消时为 operatorId,系统取消时为设备/人员 ID
+ if (operatorType == OperatorTypeEnum.ADMIN && operatorId != null) {
+ builder.personId(operatorId);
+ } else if (deviceId != null) {
+ builder.personId(deviceId);
+ }
+
+ eventLogRecorder.record(builder.build());
+ } catch (Exception e) {
+ log.warn("[CleanOrderEventListener] 记录取消业务日志失败: orderId={}", orderId, e);
+ }
+ }
}
diff --git a/viewsh-module-ops/viewsh-module-environment-biz/src/main/java/com/viewsh/module/ops/environment/service/cleanorder/CleanOrderServiceImpl.java b/viewsh-module-ops/viewsh-module-environment-biz/src/main/java/com/viewsh/module/ops/environment/service/cleanorder/CleanOrderServiceImpl.java
index a2287bfc..d14f7f8c 100644
--- a/viewsh-module-ops/viewsh-module-environment-biz/src/main/java/com/viewsh/module/ops/environment/service/cleanorder/CleanOrderServiceImpl.java
+++ b/viewsh-module-ops/viewsh-module-environment-biz/src/main/java/com/viewsh/module/ops/environment/service/cleanorder/CleanOrderServiceImpl.java
@@ -15,10 +15,11 @@ import com.viewsh.module.ops.dal.mysql.workorder.OpsOrderMapper;
import com.viewsh.module.ops.enums.OperatorTypeEnum;
import com.viewsh.module.ops.enums.PriorityEnum;
import com.viewsh.module.ops.enums.WorkOrderStatusEnum;
-import com.viewsh.module.ops.environment.service.cleanorder.dto.CleanOrderAutoCreateReqDTO;
+import com.viewsh.module.ops.enums.WorkOrderTypeEnum;
import com.viewsh.module.ops.environment.dal.dataobject.workorder.OpsOrderCleanExtDO;
import com.viewsh.module.ops.environment.dal.mysql.workorder.OpsOrderCleanExtMapper;
-import com.viewsh.module.ops.environment.integration.listener.CleanOrderEventListener;
+import com.viewsh.module.ops.environment.service.cleanorder.dto.CleanOrderAutoCreateReqDTO;
+import com.viewsh.module.ops.environment.service.notification.CleanOrderNotificationService;
import com.viewsh.module.ops.infrastructure.area.AreaPathBuilder;
import com.viewsh.module.ops.infrastructure.code.OrderCodeGenerator;
import com.viewsh.module.ops.infrastructure.id.OrderIdGenerator;
@@ -77,7 +78,7 @@ public class CleanOrderServiceImpl implements CleanOrderService {
private OrderLifecycleManager orderLifecycleManager;
@Resource
- private CleanOrderEventListener cleanOrderEventListener;
+ private CleanOrderNotificationService cleanOrderNotificationService;
@Resource
private ObjectMapper objectMapper;
@@ -92,13 +93,13 @@ public class CleanOrderServiceImpl implements CleanOrderService {
public Long createAutoCleanOrder(CleanOrderAutoCreateReqDTO createReq) {
// 1. 生成ID和编号
Long orderId = orderIdGenerator.generate();
- String orderCode = orderCodeGenerator.generate("CLEAN");
+ String orderCode = orderCodeGenerator.generate(WorkOrderTypeEnum.CLEAN.getType());
// 2. 构建主表数据
OpsOrderDO.OpsOrderDOBuilder orderBuilder = OpsOrderDO.builder()
.id(orderId)
.orderCode(orderCode)
- .orderType("CLEAN")
+ .orderType(WorkOrderTypeEnum.CLEAN.getType())
.title(createReq.getTitle())
.description(createReq.getDescription())
.priority(createReq.getPriority() != null ? createReq.getPriority() : PriorityEnum.P2.getPriority())
@@ -144,7 +145,7 @@ public class CleanOrderServiceImpl implements CleanOrderService {
// 5. 发布工单创建事件
OrderCreatedEvent event = OrderCreatedEvent.builder()
.orderId(orderId)
- .orderType("CLEAN")
+ .orderType(WorkOrderTypeEnum.CLEAN.getType())
.orderCode(orderCode)
.title(createReq.getTitle())
.areaId(createReq.getAreaId())
@@ -244,7 +245,7 @@ public class CleanOrderServiceImpl implements CleanOrderService {
orderQueueService.rebuildWaitingTasksByUserId(queueDTO.getUserId(), order.getAreaId());
// 6. 发送优先级升级通知
- cleanOrderEventListener.sendPriorityUpgradeNotification(queueDTO.getUserId(), order.getOrderCode(), orderId);
+ cleanOrderNotificationService.sendPriorityUpgradeNotification(queueDTO.getUserId(), order.getOrderCode(), orderId);
return true;
}
@@ -287,7 +288,7 @@ public class CleanOrderServiceImpl implements CleanOrderService {
// 6. 如果升级到 P0,仅重算等待队列,不再触发打断
if (newPriority == PriorityEnum.P0) {
orderQueueService.rebuildWaitingTasksByUserId(queueDTO.getUserId(), order.getAreaId());
- cleanOrderEventListener.sendPriorityUpgradeNotification(queueDTO.getUserId(), order.getOrderCode(), orderId);
+ cleanOrderNotificationService.sendPriorityUpgradeNotification(queueDTO.getUserId(), order.getOrderCode(), orderId);
log.warn("客流升级到P0,已重算等待队列: orderId={}", orderId);
}
}
@@ -384,17 +385,17 @@ public class CleanOrderServiceImpl implements CleanOrderService {
@Override
public void playVoiceForNewOrder(Long deviceId) {
- cleanOrderEventListener.sendNewOrderNotification(deviceId, null);
+ cleanOrderNotificationService.sendNewOrderNotification(deviceId, null);
}
@Override
public void playVoiceForQueuedOrder(Long deviceId, int queueCount, Long orderId) {
- cleanOrderEventListener.sendQueuedOrderNotification(deviceId, queueCount, orderId);
+ cleanOrderNotificationService.sendQueuedOrderNotification(deviceId, queueCount, orderId);
}
@Override
public void playVoiceForNextTask(Long deviceId, int queueCount, String nextTaskTitle) {
- cleanOrderEventListener.sendNextTaskNotification(deviceId, queueCount, nextTaskTitle);
+ cleanOrderNotificationService.sendNextTaskNotification(deviceId, queueCount, nextTaskTitle);
}
// ==================== 作业时长计算 ====================