update modules/ticket: add 1 mod 4 del 1 files

This commit is contained in:
jack ning
2025-02-16 08:51:05 +08:00
parent 9b64c97270
commit d0de057f92
6 changed files with 219 additions and 103 deletions

View File

@@ -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<String, Object> 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: 流程流转时的处理逻辑
}
}

View File

@@ -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());
}
}

View File

@@ -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: 可以在这里添加任务删除后的处理逻辑
// 例如:记录删除原因、更新相关统计等
}
}

View File

@@ -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; // 已取消
}

View File

@@ -1,6 +1,10 @@
<?xml version="1.0" encoding="UTF-8"?>
<definitions xmlns="http://www.omg.org/spec/BPMN/20100524/MODEL" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:flowable="http://flowable.org/bpmn" xmlns:bpmndi="http://www.omg.org/spec/BPMN/20100524/DI" xmlns:omgdc="http://www.omg.org/spec/DD/20100524/DC" xmlns:omgdi="http://www.omg.org/spec/DD/20100524/DI" typeLanguage="http://www.w3.org/2001/XMLSchema" expressionLanguage="http://www.w3.org/1999/XPath" targetNamespace="BytedeskTicket" exporter="Flowable Open Source Modeler" exporterVersion="6.8.0">
<process id="groupTicketProcess" name="工作组工单流程" isExecutable="true">
<extensionElements>
<flowable:executionListener event="start" delegateExpression="${ticketExecutionListener}"></flowable:executionListener>
<flowable:executionListener event="end" delegateExpression="${ticketExecutionListener}"></flowable:executionListener>
</extensionElements>
<startEvent id="start" name="创建工单" flowable:formFieldValidation="true"></startEvent>
<userTask id="createTicket" name="创建工单" flowable:assignee="${creatorUser}" flowable:formFieldValidation="true">
<documentation>创建新工单并填写详细信息</documentation>
@@ -31,6 +35,11 @@
<flowable:value id="pending" name="处理中"></flowable:value>
<flowable:value id="escalated" name="已升级"></flowable:value>
</flowable:formProperty>
<flowable:executionListener event="start" delegateExpression="${ticketExecutionListener}"></flowable:executionListener>
<flowable:executionListener event="end" delegateExpression="${ticketExecutionListener}"></flowable:executionListener>
<flowable:taskListener event="create" delegateExpression="${ticketTaskListener}"></flowable:taskListener>
<flowable:taskListener event="assignment" delegateExpression="${ticketTaskListener}"></flowable:taskListener>
<flowable:taskListener event="complete" delegateExpression="${ticketTaskListener}"></flowable:taskListener>
</extensionElements>
</userTask>
<boundaryEvent id="slaTimer" attachedToRef="assignToGroup" cancelActivity="true">

View File

@@ -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<String, Object> 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<String, Object> 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<String, Object> 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<String, Object> 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<String, Object> verifyVariables = new HashMap<>();
verifyVariables.put("satisfied", true);
verifyVariables.put("comment", "服务很好");
taskService.complete(verifyTask.getId(), verifyVariables);
}
@Test
void testTaskListener() {
// 准备流程变量
Map<String, Object> 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<String, Object> 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<String, Object> groupVariables = new HashMap<>();
groupVariables.put("solution", "问题已修复");
groupVariables.put("status", "resolved");
taskService.complete(groupTask.getId(), groupVariables);
}
}