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 templateParams) { - try { - NotifySendSingleToUserReqDTO reqDTO = new NotifySendSingleToUserReqDTO(); - reqDTO.setUserId(userId); - reqDTO.setTemplateCode(templateCode); - reqDTO.setTemplateParams(templateParams); - - notifyMessageSendApi.sendSingleMessageToMember(reqDTO); - log.debug("[站内信发送成功] userId={}, templateCode={}", userId, templateCode); - - } catch (Exception e) { - log.error("[站内信发送失败] userId={}, templateCode={}", userId, templateCode, e); - } - } - - // ==================== 辅助方法 ==================== - - /** - * 获取区域名称 - */ - private String getAreaName(Long areaId) { - // TODO: 从区域服务获取区域名称 - return "某区域"; - } - /** * 工单状态变更时,更新 Redis 中的活跃工单状态标记 *

@@ -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); } // ==================== 作业时长计算 ====================