From d0de057f92cb914fbb0476aec7e53b6d2f5bd6c8 Mon Sep 17 00:00:00 2001 From: jack ning Date: Sun, 16 Feb 2025 08:51:05 +0800 Subject: [PATCH] update modules/ticket: add 1 mod 4 del 1 files --- .../listener/TicketExecutionListener.java | 39 ++++++-- .../ticket/listener/TicketTaskListener.java | 85 ++++++++++++++++ .../ticket/task/TicketTaskListener.java | 89 ----------------- .../ticket/ticket/TicketStatusEnum.java | 3 +- .../processes/group-ticket-process.bpmn20.xml | 9 ++ .../ticket/GroupTicketProcessTests.java | 97 ++++++++++++++++++- 6 files changed, 219 insertions(+), 103 deletions(-) create mode 100644 modules/ticket/src/main/java/com/bytedesk/ticket/listener/TicketTaskListener.java delete mode 100644 modules/ticket/src/main/java/com/bytedesk/ticket/task/TicketTaskListener.java diff --git a/modules/ticket/src/main/java/com/bytedesk/ticket/listener/TicketExecutionListener.java b/modules/ticket/src/main/java/com/bytedesk/ticket/listener/TicketExecutionListener.java index f264263d8f..3a20e2789d 100644 --- a/modules/ticket/src/main/java/com/bytedesk/ticket/listener/TicketExecutionListener.java +++ b/modules/ticket/src/main/java/com/bytedesk/ticket/listener/TicketExecutionListener.java @@ -2,7 +2,7 @@ * @Author: jackning 270580156@qq.com * @Date: 2025-01-28 10:20:46 * @LastEditors: jackning 270580156@qq.com - * @LastEditTime: 2025-01-28 11:18:06 + * @LastEditTime: 2025-02-16 08:47:37 * @Description: bytedesk.com https://github.com/Bytedesk/bytedesk * Please be aware of the BSL license restrictions before installing Bytedesk IM – * selling, reselling, or hosting Bytedesk IM as a service is a breach of the terms and automatically terminates your rights under the license. @@ -19,9 +19,22 @@ import org.springframework.stereotype.Component; import lombok.extern.slf4j.Slf4j; -// 使用 ExecutionListener 处理流程执行和变量相关事件 +import java.util.Map; + +/** + * 使用 ExecutionListener 处理流程执行和变量相关事件 + * + * ExecutionListener (执行监听器): + * 监听流程执行事件 + * 事件类型:start、end、take + * 可以绑定到流程、活动、连线上 + * + * 关注流程执行的生命周期 + * 可以访问和修改流程变量 + * 适合处理流程级别的业务逻辑 + */ @Slf4j -@Component +@Component("ticketExecutionListener") public class TicketExecutionListener implements ExecutionListener { private static final long serialVersionUID = 1L; @@ -30,8 +43,15 @@ public class TicketExecutionListener implements ExecutionListener { public void notify(DelegateExecution execution) { String eventName = execution.getEventName(); String processInstanceId = execution.getProcessInstanceId(); + String activityId = execution.getCurrentActivityId(); + String activityName = execution.getCurrentActivityName(); - log.info("Execution event: {}, processInstanceId: {}", eventName, processInstanceId); + log.info("Execution event: {}, processInstanceId: {}, activityId: {}, activityName: {}", + eventName, processInstanceId, activityId, activityName); + + // 获取流程变量 + Map variables = execution.getVariables(); + log.info("Process variables: {}", variables); switch (eventName) { case EVENTNAME_START: @@ -50,19 +70,20 @@ public class TicketExecutionListener implements ExecutionListener { } private void handleProcessStart(DelegateExecution execution) { - log.info("Process started: {}", execution.getProcessInstanceId()); - // TODO: 流程开始时的处理逻辑 + // 可以在这里添加流程开始时的业务逻辑 + String creatorUser = (String) execution.getVariable("creatorUser"); + log.info("Process started by user: {}", creatorUser); } private void handleProcessEnd(DelegateExecution execution) { + // 可以在这里添加流程结束时的业务逻辑 log.info("Process ended: {}", execution.getProcessInstanceId()); - // TODO: 流程结束时的处理逻辑 } private void handleProcessTake(DelegateExecution execution) { - log.info("Process transition taken: {} -> {}", + // 可以在这里添加流程流转时的业务逻辑 + log.info("Process transition from {} to {}", execution.getCurrentActivityId(), execution.getCurrentActivityName()); - // TODO: 流程流转时的处理逻辑 } } \ No newline at end of file diff --git a/modules/ticket/src/main/java/com/bytedesk/ticket/listener/TicketTaskListener.java b/modules/ticket/src/main/java/com/bytedesk/ticket/listener/TicketTaskListener.java new file mode 100644 index 0000000000..0e55a704bb --- /dev/null +++ b/modules/ticket/src/main/java/com/bytedesk/ticket/listener/TicketTaskListener.java @@ -0,0 +1,85 @@ +/* + * @Author: jackning 270580156@qq.com + * @Date: 2025-02-16 08:41:28 + * @LastEditors: jackning 270580156@qq.com + * @LastEditTime: 2025-02-16 08:49:14 + * @Description: bytedesk.com https://github.com/Bytedesk/bytedesk + * Please be aware of the BSL license restrictions before installing Bytedesk IM – + * selling, reselling, or hosting Bytedesk IM as a service is a breach of the terms and automatically terminates your rights under the license. + * Business Source License 1.1: https://github.com/Bytedesk/bytedesk/blob/main/LICENSE + * contact: 270580156@qq.com + * + * Copyright (c) 2025 by bytedesk.com, All Rights Reserved. + */ +package com.bytedesk.ticket.listener; + +import lombok.extern.slf4j.Slf4j; +import org.flowable.engine.delegate.TaskListener; +import org.flowable.task.service.delegate.DelegateTask; +import org.springframework.stereotype.Component; + +/** + * TaskListener (任务监听器): + * 监听任务相关事件 + * 事件类型:create、assignment、complete、delete + * 只能绑定到用户任务上 + * + * 关注任务的生命周期 + * 可以访问和修改任务相关信息 + * 适合处理任务级别的业务逻辑 + */ +@Slf4j +@Component("ticketTaskListener") +public class TicketTaskListener implements TaskListener { + + private static final long serialVersionUID = 1L; + + @Override + public void notify(DelegateTask delegateTask) { + String eventName = delegateTask.getEventName(); + String taskId = delegateTask.getId(); + String taskName = delegateTask.getName(); + String assignee = delegateTask.getAssignee(); + + log.info("Task event: {}, taskId: {}, taskName: {}, assignee: {}", + eventName, taskId, taskName, assignee); + + switch (eventName) { + case EVENTNAME_CREATE: + // 任务创建时触发 + handleTaskCreate(delegateTask); + break; + case EVENTNAME_ASSIGNMENT: + // 任务分配时触发 + handleTaskAssignment(delegateTask); + break; + case EVENTNAME_COMPLETE: + // 任务完成时触发 + handleTaskComplete(delegateTask); + break; + case EVENTNAME_DELETE: + // 任务删除时触发 + handleTaskDelete(delegateTask); + break; + default: + log.warn("Unhandled task event: {}", eventName); + break; + } + } + + private void handleTaskCreate(DelegateTask task) { + log.info("Task created: {}, name: {}", task.getId(), task.getName()); + } + + private void handleTaskAssignment(DelegateTask task) { + log.info("Task assigned: {}, assignee: {}", task.getId(), task.getAssignee()); + } + + private void handleTaskComplete(DelegateTask task) { + log.info("Task completed: {}, assignee: {}", task.getId(), task.getAssignee()); + } + + private void handleTaskDelete(DelegateTask task) { + log.info("Task deleted: {}", task.getId()); + } +} \ No newline at end of file diff --git a/modules/ticket/src/main/java/com/bytedesk/ticket/task/TicketTaskListener.java b/modules/ticket/src/main/java/com/bytedesk/ticket/task/TicketTaskListener.java deleted file mode 100644 index d95f62d0ec..0000000000 --- a/modules/ticket/src/main/java/com/bytedesk/ticket/task/TicketTaskListener.java +++ /dev/null @@ -1,89 +0,0 @@ -/* - * @Author: jackning 270580156@qq.com - * @Date: 2025-01-28 09:44:18 - * @LastEditors: jackning 270580156@qq.com - * @LastEditTime: 2025-01-28 12:50:07 - * @Description: bytedesk.com https://github.com/Bytedesk/bytedesk - * Please be aware of the BSL license restrictions before installing Bytedesk IM – - * selling, reselling, or hosting Bytedesk IM as a service is a breach of the terms and automatically terminates your rights under the license. - * Business Source License 1.1: https://github.com/Bytedesk/bytedesk/blob/main/LICENSE - * contact: 270580156@qq.com - * - * Copyright (c) 2025 by bytedesk.com, All Rights Reserved. - */ -package com.bytedesk.ticket.task; - -import org.flowable.task.service.delegate.TaskListener; -import org.flowable.task.service.delegate.DelegateTask; -import org.springframework.stereotype.Component; - -import lombok.extern.slf4j.Slf4j; - -// 使用 TaskListener 处理任务相关事件 -@Slf4j -@Component -public class TicketTaskListener implements TaskListener { - - private static final long serialVersionUID = 1L; - - @Override - public void notify(DelegateTask delegateTask) { - String eventName = delegateTask.getEventName(); - String taskId = delegateTask.getId(); - String processInstanceId = delegateTask.getProcessInstanceId(); - - log.info("Task event: {}, taskId: {}, processInstanceId: {}", - eventName, taskId, processInstanceId); - - switch (eventName) { - case EVENTNAME_CREATE: - // 任务创建时触发 - handleTaskCreated(delegateTask); - break; - case EVENTNAME_ASSIGNMENT: - // 任务分配时触发 - handleTaskAssigned(delegateTask); - break; - case EVENTNAME_COMPLETE: - // 任务完成时触发 - handleTaskCompleted(delegateTask); - break; - case EVENTNAME_DELETE: - // 任务删除时触发 - handleTaskDeleted(delegateTask); - break; - default: - log.warn("Unhandled task event: {}", eventName); - break; - } - } - - private void handleTaskCreated(DelegateTask delegateTask) { - // 处理任务创建事件 - log.info("Task created: {}", delegateTask.getId()); - // TODO: 可以在这里添加任务创建后的处理逻辑 - // 例如:发送通知、更新统计数据等 - } - - private void handleTaskAssigned(DelegateTask delegateTask) { - // 处理任务分配事件 - String assignee = delegateTask.getAssignee(); - log.info("Task assigned to: {}", assignee); - // TODO: 可以在这里添加任务分配后的处理逻辑 - // 例如:发送通知给被分配人 - } - - private void handleTaskCompleted(DelegateTask delegateTask) { - // 处理任务完成事件 - log.info("Task completed: {}", delegateTask.getId()); - // TODO: 可以在这里添加任务完成后的处理逻辑 - // 例如:更新工单状态、发送完成通知等 - } - - private void handleTaskDeleted(DelegateTask delegateTask) { - // 处理任务删除事件 - log.info("Task deleted: {}", delegateTask.getId()); - // TODO: 可以在这里添加任务删除后的处理逻辑 - // 例如:记录删除原因、更新相关统计等 - } -} diff --git a/modules/ticket/src/main/java/com/bytedesk/ticket/ticket/TicketStatusEnum.java b/modules/ticket/src/main/java/com/bytedesk/ticket/ticket/TicketStatusEnum.java index 8235ebcc1f..e88c659125 100644 --- a/modules/ticket/src/main/java/com/bytedesk/ticket/ticket/TicketStatusEnum.java +++ b/modules/ticket/src/main/java/com/bytedesk/ticket/ticket/TicketStatusEnum.java @@ -2,7 +2,7 @@ * @Author: jackning 270580156@qq.com * @Date: 2025-01-23 15:21:08 * @LastEditors: jackning 270580156@qq.com - * @LastEditTime: 2025-01-23 16:19:45 + * @LastEditTime: 2025-02-16 08:26:37 * @Description: bytedesk.com https://github.com/Bytedesk/bytedesk * Please be aware of the BSL license restrictions before installing Bytedesk IM – * selling, reselling, or hosting Bytedesk IM as a service is a breach of the terms and automatically terminates your rights under the license. @@ -22,6 +22,7 @@ public enum TicketStatusEnum { ON_HOLD, // 挂起(暂停处理) REOPENED, // 重新打开 RESOLVED, // 已解决 + ESCALATED, // 已升级 CLOSED, // 已关闭 CANCELLED; // 已取消 } diff --git a/modules/ticket/src/main/resources/processes/group-ticket-process.bpmn20.xml b/modules/ticket/src/main/resources/processes/group-ticket-process.bpmn20.xml index 66e39e88a4..9f70b30b0d 100644 --- a/modules/ticket/src/main/resources/processes/group-ticket-process.bpmn20.xml +++ b/modules/ticket/src/main/resources/processes/group-ticket-process.bpmn20.xml @@ -1,6 +1,10 @@ + + + + 创建新工单并填写详细信息 @@ -31,6 +35,11 @@ + + + + + diff --git a/modules/ticket/src/test/java/com/bytedesk/ticket/GroupTicketProcessTests.java b/modules/ticket/src/test/java/com/bytedesk/ticket/GroupTicketProcessTests.java index 348b4c1c53..71561a2a87 100644 --- a/modules/ticket/src/test/java/com/bytedesk/ticket/GroupTicketProcessTests.java +++ b/modules/ticket/src/test/java/com/bytedesk/ticket/GroupTicketProcessTests.java @@ -2,7 +2,7 @@ * @Author: jackning 270580156@qq.com * @Date: 2025-02-14 15:48:59 * @LastEditors: jackning 270580156@qq.com - * @LastEditTime: 2025-02-16 08:14:37 + * @LastEditTime: 2025-02-16 08:32:18 * @Description: bytedesk.com https://github.com/Bytedesk/bytedesk * Please be aware of the BSL license restrictions before installing Bytedesk IM – * selling, reselling, or hosting Bytedesk IM as a service is a breach of the terms and automatically terminates your rights under the license. @@ -100,11 +100,11 @@ public class GroupTicketProcessTests { .taskCandidateGroup("support") .singleResult(); assertNotNull(groupTask); - assertEquals("Group Handle", groupTask.getName()); + assertEquals("工作组处理", groupTask.getName()); // 完成工作组处理 Map groupVariables = new HashMap<>(); - groupVariables.put("solution", "Problem solved"); + groupVariables.put("solution", "问题已修复"); groupVariables.put("status", "resolved"); taskService.complete(groupTask.getId(), groupVariables); @@ -114,7 +114,7 @@ public class GroupTicketProcessTests { .taskAssignee("user1") .singleResult(); assertNotNull(verifyTask); - assertEquals("Customer Verify", verifyTask.getName()); + assertEquals("客户确认", verifyTask.getName()); } // 测试工单创建者查询 @@ -551,5 +551,94 @@ public class GroupTicketProcessTests { return processInstance; } + @Test + void testExecutionListener() { + // 准备流程变量 + Map variables = new HashMap<>(); + variables.put("creatorUser", "user1"); + variables.put("workgroupUid", "support"); + variables.put("slaTime", "PT4H"); + + // 启动流程实例 - 会触发 start 事件 + ProcessInstance processInstance = runtimeService.startProcessInstanceByKey( + TicketConsts.TICKET_PROCESS_KEY_GROUP, variables); + assertNotNull(processInstance); + + // 完成创建工单任务 + Task createTask = taskService.createTaskQuery() + .processInstanceId(processInstance.getId()) + .taskAssignee("user1") + .singleResult(); + + Map ticketVariables = new HashMap<>(); + ticketVariables.put("title", "Test Execution Listener"); + ticketVariables.put("description", "Testing execution listeners"); + ticketVariables.put("priority", "medium"); + taskService.complete(createTask.getId(), ticketVariables); + + // 认领并完成工作组任务 - 会触发 assignToGroup 任务的 start 和 end 事件 + Task groupTask = taskService.createTaskQuery() + .processInstanceId(processInstance.getId()) + .taskCandidateGroup("support") + .singleResult(); + + taskService.claim(groupTask.getId(), "agent1"); + + Map groupVariables = new HashMap<>(); + groupVariables.put("solution", "问题已修复"); + groupVariables.put("status", "resolved"); + taskService.complete(groupTask.getId(), groupVariables); + + // 完成客户确认任务 - 会触发流程的 end 事件 + Task verifyTask = taskService.createTaskQuery() + .processInstanceId(processInstance.getId()) + .taskAssignee("user1") + .singleResult(); + + Map verifyVariables = new HashMap<>(); + verifyVariables.put("satisfied", true); + verifyVariables.put("comment", "服务很好"); + taskService.complete(verifyTask.getId(), verifyVariables); + } + + @Test + void testTaskListener() { + // 准备流程变量 + Map variables = new HashMap<>(); + variables.put("creatorUser", "user1"); + variables.put("workgroupUid", "support"); + variables.put("slaTime", "PT4H"); + + // 启动流程实例 + ProcessInstance processInstance = runtimeService.startProcessInstanceByKey( + TicketConsts.TICKET_PROCESS_KEY_GROUP, variables); + assertNotNull(processInstance); + + // 完成创建工单任务 - 会触发 create 和 complete 事件 + Task createTask = taskService.createTaskQuery() + .processInstanceId(processInstance.getId()) + .taskAssignee("user1") + .singleResult(); + + Map ticketVariables = new HashMap<>(); + ticketVariables.put("title", "Test Task Listener"); + ticketVariables.put("description", "Testing task listeners"); + ticketVariables.put("priority", "medium"); + taskService.complete(createTask.getId(), ticketVariables); + + // 认领工作组任务 - 会触发 assignment 事件 + Task groupTask = taskService.createTaskQuery() + .processInstanceId(processInstance.getId()) + .taskCandidateGroup("support") + .singleResult(); + + taskService.claim(groupTask.getId(), "agent1"); + + // 完成工作组任务 - 会触发 complete 事件 + Map groupVariables = new HashMap<>(); + groupVariables.put("solution", "问题已修复"); + groupVariables.put("status", "resolved"); + taskService.complete(groupTask.getId(), groupVariables); + } }